diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2dd5fb46ad9..c80676c01cb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -36,6 +36,10 @@ **/*.geojson @villebro @rusackas /superset-frontend/plugins/legacy-plugin-chart-country-map/ @villebro @rusackas +# Notify translation maintainers of changes to translations + +/superset/translations/ @sfirke + # Notify PMC members of changes to extension-related files /docs/developer_portal/extensions/ @michael-s-molina @villebro @rusackas diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 86feb412782..5560dc56af6 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -37,6 +37,10 @@ updates: # `just-handlerbars-helpers` library in plugin-chart-handlebars requires `currencyformatter`` to be < 2 - dependency-name: "currencyformatter.js" update-types: ["version-update:semver-major"] + # TODO: remove below clause once https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/940 lands onto a future release + # and confirm the issue https://github.com/apache/superset/issues/39600 is fixed + - dependency-name: "react-checkbox-tree" + update-types: ["version-update:semver-major"] groups: storybook: applies-to: version-updates @@ -55,15 +59,13 @@ updates: versioning-strategy: increase - # NOTE: `uv` support is in beta, more details here: - # https://github.com/dependabot/dependabot-core/pull/10040#issuecomment-2696978430 - - package-ecosystem: "uv" - directory: "requirements/" + - package-ecosystem: "pip" + directory: "/" open-pull-requests-limit: 10 schedule: interval: "weekly" labels: - - uv + - pip - dependabot - package-ecosystem: "npm" diff --git a/.github/labeler.yml b/.github/labeler.yml index 9cb7f3aad4c..2b08039ae5b 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -77,6 +77,11 @@ - any-glob-to-any-file: - 'superset/translations/zh/**' +"i18n:czech": +- changed-files: + - any-glob-to-any-file: + - 'superset/translations/cs/**' + "i18n:traditional-chinese": - changed-files: - any-glob-to-any-file: @@ -122,6 +127,11 @@ - any-glob-to-any-file: - 'superset/translations/sk/**' +"i18n:latvian": +- changed-files: + - any-glob-to-any-file: + - 'superset/translations/lv/**' + "i18n:ukrainian": - changed-files: - any-glob-to-any-file: diff --git a/.github/workflows/bashlib.sh b/.github/workflows/bashlib.sh index 91a131d4562..76f44d28f1b 100644 --- a/.github/workflows/bashlib.sh +++ b/.github/workflows/bashlib.sh @@ -127,6 +127,20 @@ playwright_testdata() { superset load_test_users superset load_examples superset init + # Enable DML on the examples database so Playwright tests can create/drop + # temporary tables via SQL Lab without depending on external data sources. + superset shell <<'PYEOF' +import sys +from superset.extensions import db +from superset.models.core import Database +examples_db = db.session.query(Database).filter_by(database_name='examples').first() +if not examples_db: + sys.exit('ERROR: examples database not found. load_examples may have failed.') + +examples_db.allow_dml = True +db.session.commit() +print('Enabled allow_dml on examples database') +PYEOF say "::endgroup::" } diff --git a/.github/workflows/embedded-sdk-release.yml b/.github/workflows/embedded-sdk-release.yml index ad6c8a485b7..8bcf42a56be 100644 --- a/.github/workflows/embedded-sdk-release.yml +++ b/.github/workflows/embedded-sdk-release.yml @@ -31,7 +31,7 @@ jobs: working-directory: superset-embedded-sdk steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './superset-embedded-sdk/.nvmrc' registry-url: 'https://registry.npmjs.org' diff --git a/.github/workflows/embedded-sdk-test.yml b/.github/workflows/embedded-sdk-test.yml index bc7940c7dbf..9d5237fce34 100644 --- a/.github/workflows/embedded-sdk-test.yml +++ b/.github/workflows/embedded-sdk-test.yml @@ -19,7 +19,7 @@ jobs: working-directory: superset-embedded-sdk steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './superset-embedded-sdk/.nvmrc' registry-url: 'https://registry.npmjs.org' diff --git a/.github/workflows/ephemeral-env-pr-close.yml b/.github/workflows/ephemeral-env-pr-close.yml index 9defe4db1b5..b7f79c69283 100644 --- a/.github/workflows/ephemeral-env-pr-close.yml +++ b/.github/workflows/ephemeral-env-pr-close.yml @@ -58,7 +58,7 @@ jobs: - name: Login to Amazon ECR if: steps.describe-services.outputs.active == 'true' id: login-ecr - uses: aws-actions/amazon-ecr-login@376925c9d111252e87ae59691e5a442dd100ef6a # v2 + uses: aws-actions/amazon-ecr-login@fa648b43de3d4d023bcb3f89ed6940096949c419 # v2 - name: Delete ECR image tag if: steps.describe-services.outputs.active == 'true' diff --git a/.github/workflows/ephemeral-env.yml b/.github/workflows/ephemeral-env.yml index 7815ddb09b3..8dd91b80c98 100644 --- a/.github/workflows/ephemeral-env.yml +++ b/.github/workflows/ephemeral-env.yml @@ -199,7 +199,7 @@ jobs: - name: Login to Amazon ECR id: login-ecr - uses: aws-actions/amazon-ecr-login@376925c9d111252e87ae59691e5a442dd100ef6a # v2 + uses: aws-actions/amazon-ecr-login@fa648b43de3d4d023bcb3f89ed6940096949c419 # v2 - name: Load, tag and push image to ECR id: push-image @@ -235,7 +235,7 @@ jobs: - name: Login to Amazon ECR id: login-ecr - uses: aws-actions/amazon-ecr-login@376925c9d111252e87ae59691e5a442dd100ef6a # v2 + uses: aws-actions/amazon-ecr-login@fa648b43de3d4d023bcb3f89ed6940096949c419 # v2 - name: Check target image exists in ECR id: check-image @@ -265,7 +265,7 @@ jobs: - name: Fill in the new image ID in the Amazon ECS task definition id: task-def - uses: aws-actions/amazon-ecs-render-task-definition@77954e213ba1f9f9cb016b86a1d4f6fcdea0d57e # v1 + uses: aws-actions/amazon-ecs-render-task-definition@6853cfae8c3a7d978fbf68b5a55453395541dfbb # v1 with: task-definition: .github/workflows/ecs-task-definition.json container-name: superset-ci @@ -300,7 +300,7 @@ jobs: --tags key=pr,value=$PR_NUMBER key=github_user,value=${{ github.actor }} - name: Deploy Amazon ECS task definition id: deploy-task - uses: aws-actions/amazon-ecs-deploy-task-definition@fc8fc60f3a60ffd500fcb13b209c59d221ac8c8c # v2 + uses: aws-actions/amazon-ecs-deploy-task-definition@a310a830f5c14e583e35d84e4e1ec7dd177c3c9c # v2 with: task-definition: ${{ steps.task-def.outputs.task-definition }} service: pr-${{ github.event.inputs.issue_number || github.event.pull_request.number }}-service diff --git a/.github/workflows/github-action-validator.yml b/.github/workflows/github-action-validator.yml index 95ae62ea7bc..9a341871c76 100644 --- a/.github/workflows/github-action-validator.yml +++ b/.github/workflows/github-action-validator.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: '20' diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 0e38e9220cb..d16a729bd21 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -42,7 +42,7 @@ jobs: echo "HOMEBREW_REPOSITORY=$HOMEBREW_REPOSITORY" >>"${GITHUB_ENV}" brew install norwoodj/tap/helm-docs - name: Setup Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: '20' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ccacee43dc4..23e2c0175d3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: - name: Install Node.js if: env.HAS_TAGS - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './superset-frontend/.nvmrc' diff --git a/.github/workflows/superset-docs-deploy.yml b/.github/workflows/superset-docs-deploy.yml index f8e5cd206e7..dbe4deb1839 100644 --- a/.github/workflows/superset-docs-deploy.yml +++ b/.github/workflows/superset-docs-deploy.yml @@ -17,6 +17,16 @@ on: workflow_dispatch: {} +# Serialize deploys: the action pushes to apache/superset-site without +# rebasing, so concurrent runs race on the final push and the loser fails +# with `! [rejected] asf-site -> asf-site (fetch first)`. Cancel any +# in-progress run as soon as a newer one starts — the destination repo +# isn't touched until the final push step, so canceling mid-build is safe, +# and the freshest content always wins. +concurrency: + group: docs-deploy-asf-site + cancel-in-progress: true + jobs: config: runs-on: ubuntu-24.04 @@ -46,7 +56,7 @@ jobs: persist-credentials: false submodules: recursive - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './docs/.nvmrc' - name: Setup Python @@ -70,7 +80,7 @@ jobs: yarn install --check-cache - name: Download database diagnostics (if triggered by integration tests) if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' - uses: dawidd6/action-download-artifact@8305c0f1062bb0d184d09ef4493ecb9288447732 # v20 + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 continue-on-error: true with: workflow: superset-python-integrationtest.yml @@ -79,7 +89,7 @@ jobs: path: docs/src/data/ - name: Try to download latest diagnostics (for push/dispatch triggers) if: github.event_name != 'workflow_run' - uses: dawidd6/action-download-artifact@8305c0f1062bb0d184d09ef4493ecb9288447732 # v20 + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 continue-on-error: true with: workflow: superset-python-integrationtest.yml diff --git a/.github/workflows/superset-docs-verify.yml b/.github/workflows/superset-docs-verify.yml index 9d7420080dd..d9892b1620b 100644 --- a/.github/workflows/superset-docs-verify.yml +++ b/.github/workflows/superset-docs-verify.yml @@ -72,7 +72,7 @@ jobs: persist-credentials: false submodules: recursive - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './docs/.nvmrc' - name: yarn install @@ -104,14 +104,14 @@ jobs: persist-credentials: false submodules: recursive - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './docs/.nvmrc' - name: yarn install run: | yarn install --check-cache - name: Download database diagnostics from integration tests - uses: dawidd6/action-download-artifact@8305c0f1062bb0d184d09ef4493ecb9288447732 # v20 + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 with: workflow: superset-python-integrationtest.yml run_id: ${{ github.event.workflow_run.id }} diff --git a/.github/workflows/superset-e2e.yml b/.github/workflows/superset-e2e.yml index 1ab0d5aa7b7..43aea2833e3 100644 --- a/.github/workflows/superset-e2e.yml +++ b/.github/workflows/superset-e2e.yml @@ -109,7 +109,7 @@ jobs: run: testdata - name: Setup Node.js if: steps.check.outputs.python || steps.check.outputs.frontend - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './superset-frontend/.nvmrc' - name: Install npm dependencies @@ -226,7 +226,7 @@ jobs: run: playwright_testdata - name: Setup Node.js if: steps.check.outputs.python || steps.check.outputs.frontend - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './superset-frontend/.nvmrc' - name: Install npm dependencies diff --git a/.github/workflows/superset-playwright.yml b/.github/workflows/superset-playwright.yml index cef3ed14068..915833fe3ce 100644 --- a/.github/workflows/superset-playwright.yml +++ b/.github/workflows/superset-playwright.yml @@ -100,7 +100,7 @@ jobs: run: playwright_testdata - name: Setup Node.js if: steps.check.outputs.python || steps.check.outputs.frontend - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './superset-frontend/.nvmrc' - name: Install npm dependencies diff --git a/.github/workflows/superset-python-unittest.yml b/.github/workflows/superset-python-unittest.yml index 4065e81d86c..18077700bd2 100644 --- a/.github/workflows/superset-python-unittest.yml +++ b/.github/workflows/superset-python-unittest.yml @@ -54,6 +54,7 @@ jobs: SUPERSET_SECRET_KEY: not-a-secret run: | pytest --durations-min=0.5 --cov=superset/sql/ ./tests/unit_tests/sql/ --cache-clear --cov-fail-under=100 + pytest --durations-min=0.5 --cov=superset/semantic_layers/ ./tests/unit_tests/semantic_layers/ --cache-clear --cov-fail-under=100 - name: Upload code coverage uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5 with: diff --git a/.github/workflows/superset-translations.yml b/.github/workflows/superset-translations.yml index 8155b675aaf..3223eb5fa88 100644 --- a/.github/workflows/superset-translations.yml +++ b/.github/workflows/superset-translations.yml @@ -31,7 +31,7 @@ jobs: - name: Setup Node.js if: steps.check.outputs.frontend - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './superset-frontend/.nvmrc' - name: Install dependencies diff --git a/.github/workflows/tag-release.yml b/.github/workflows/tag-release.yml index cbbe1d46283..f97d9aaa449 100644 --- a/.github/workflows/tag-release.yml +++ b/.github/workflows/tag-release.yml @@ -62,7 +62,7 @@ jobs: build: "true" - name: Use Node.js 20 - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: 20 @@ -117,7 +117,7 @@ jobs: fetch-depth: 0 - name: Use Node.js 20 - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: 20 diff --git a/.github/workflows/tech-debt.yml b/.github/workflows/tech-debt.yml index 20c9e4f35ac..d11ae6d3e1e 100644 --- a/.github/workflows/tech-debt.yml +++ b/.github/workflows/tech-debt.yml @@ -35,7 +35,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: './superset-frontend/.nvmrc' diff --git a/.gitignore b/.gitignore index 60d5c99513c..6f1b2261d8a 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,7 @@ rat-results.txt superset/app/ superset-websocket/config.json .direnv +*.log # Node.js, webpack artifacts, storybook *.entry.js diff --git a/Dockerfile b/Dockerfile index f441e613f3b..d77b73b547a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ ARG BUILD_TRANSLATIONS="false" ###################################################################### # superset-node-ci used as a base for building frontend assets and CI ###################################################################### -FROM --platform=${BUILDPLATFORM} node:20-trixie-slim AS superset-node-ci +FROM --platform=${BUILDPLATFORM} node:22-trixie-slim AS superset-node-ci ARG BUILD_TRANSLATIONS ENV BUILD_TRANSLATIONS=${BUILD_TRANSLATIONS} ARG DEV_MODE="false" # Skip frontend build in dev mode diff --git a/RELEASING/verify_release.py b/RELEASING/verify_release.py index 61bbf073ab0..9e0347bc146 100755 --- a/RELEASING/verify_release.py +++ b/RELEASING/verify_release.py @@ -56,8 +56,33 @@ def verify_sha512(filename: str) -> str: # Part 2: Verify RSA key - this is the same as running `gpg --verify {release}.asc {release}` and comparing the RSA key and email address against the KEYS file # noqa: E501 +KEYS_URL = "https://downloads.apache.org/superset/KEYS" + + +def ensure_keys_imported() -> None: + """Import the Apache Superset KEYS file into the local GPG keyring. + + Without this, `gpg --verify` returns "No public key" and the signature + cannot actually be verified — only the key ID in the signature metadata + is visible. + """ + try: + keys = requests.get(KEYS_URL, timeout=30) + except requests.RequestException as exc: + print(f"Warning: could not fetch KEYS file for import: {exc}") + return + if keys.status_code != 200: + print(f"Warning: could not fetch KEYS file (HTTP {keys.status_code})") + return + subprocess.run( # noqa: S603 + ["gpg", "--import"], # noqa: S607 + input=keys.content, + capture_output=True, + ) + + def get_gpg_info(filename: str) -> tuple[Optional[str], Optional[str]]: - """Run the GPG verify command and extract RSA key and email address.""" + """Run the GPG verify command and extract RSA/EDDSA key and email address.""" asc_filename = filename + ".asc" result = subprocess.run( # noqa: S603 ["gpg", "--verify", asc_filename, filename], # noqa: S607 @@ -65,25 +90,50 @@ def get_gpg_info(filename: str) -> tuple[Optional[str], Optional[str]]: ) output = result.stderr.decode() + # If no public key was available, import KEYS and retry so that + # `Good signature from "Name "` appears in the output. + if "No public key" in output: + ensure_keys_imported() + result = subprocess.run( # noqa: S603 + ["gpg", "--verify", asc_filename, filename], # noqa: S607 + capture_output=True, # noqa: S607 + ) + output = result.stderr.decode() + rsa_key = re.search(r"RSA key ([0-9A-F]+)", output) eddsa_key = re.search(r"EDDSA key ([0-9A-F]+)", output) - email = re.search(r'issuer "([^"]+)"', output) + + # Try multiple patterns — `Good signature from` is the most reliable + # source of the email; `issuer` is a fallback for older gpg output. + email_patterns = ( + r'Good signature from ".*?<([^>]+)>"', + r'aka ".*?<([^>]+)>"', + r'issuer "([^"]+)"', + ) + email_result: Optional[str] = None + for pattern in email_patterns: + match = re.search(pattern, output) + if match: + email_result = match.group(1) + break rsa_key_result = rsa_key.group(1) if rsa_key else None eddsa_key_result = eddsa_key.group(1) if eddsa_key else None - email_result = email.group(1) if email else None - key_result = rsa_key_result or eddsa_key_result - # Debugging: if key_result: print("RSA or EDDSA Key found") else: print("Warning: No RSA or EDDSA key found in GPG verification output.") if email_result: - print("email found") + print(f"Email found: {email_result}") else: print("Warning: No email address found in GPG verification output.") + if "No public key" in output: + print( + "Hint: public key is not in your keyring. Import it with:\n" + f" curl -s {KEYS_URL} | gpg --import" + ) return key_result, email_result diff --git a/RESOURCES/INTHEWILD.yaml b/RESOURCES/INTHEWILD.yaml index fa193318769..55bf2df6cfc 100644 --- a/RESOURCES/INTHEWILD.yaml +++ b/RESOURCES/INTHEWILD.yaml @@ -58,6 +58,10 @@ categories: url: https://www.ontruck.com/ Financial Services: + - name: Aadhar Housing Finance Limited + url: https://www.aadharhousing.com + contributors: ["@thakerhardiks"] + - name: Aktia Bank plc url: https://www.aktia.com diff --git a/UPDATING.md b/UPDATING.md index 27fc3428b9e..3d42f2b3d4e 100644 --- a/UPDATING.md +++ b/UPDATING.md @@ -46,6 +46,13 @@ The Deck.gl MapBox chart's **Opacity**, **Default longitude**, **Default latitud **To restore fit-to-data behavior:** Open the chart in Explore, clear the **Default longitude**, **Default latitude**, and **Zoom** fields in the Viewport section, and re-save the chart. +### Combined datasource list endpoint + +Added a new combined datasource list endpoint at `GET /api/v1/datasource/` to serve datasets and semantic views in one response. + +- The endpoint is available to users with at least one of `can_read` on `Dataset` or `SemanticView`. +- Semantic views are included only when the `SEMANTIC_LAYERS` feature flag is enabled. +- The endpoint enforces strict `order_column` validation and returns `400` for invalid sort columns. ### ClickHouse minimum driver version bump The minimum required version of `clickhouse-connect` has been raised to `>=0.13.0`. If you are using the ClickHouse connector, please upgrade your `clickhouse-connect` package. The `_mutate_label` workaround that appended hash suffixes to column aliases has also been removed, as it is no longer needed with modern versions of the driver. diff --git a/docker/pythonpath_dev/superset_config.py b/docker/pythonpath_dev/superset_config.py index 108305cf900..ce7f1998708 100644 --- a/docker/pythonpath_dev/superset_config.py +++ b/docker/pythonpath_dev/superset_config.py @@ -105,7 +105,13 @@ class CeleryConfig: CELERY_CONFIG = CeleryConfig -FEATURE_FLAGS = {"ALERT_REPORTS": True, "DATASET_FOLDERS": True} +FEATURE_FLAGS = { + "ALERT_REPORTS": True, + "DATASET_FOLDERS": True, + "ENABLE_EXTENSIONS": True, + "SEMANTIC_LAYERS": True, +} +EXTENSIONS_PATH = "/app/docker/extensions" ALERT_REPORTS_NOTIFICATION_DRY_RUN = True WEBDRIVER_BASEURL = f"http://superset_app{os.environ.get('SUPERSET_APP_ROOT', '/')}/" # When using docker compose baseurl should be http://superset_nginx{ENV{BASEPATH}}/ # noqa: E501 # The base URL for the email report hyperlinks. diff --git a/docs/admin_docs/configuration/alerts-reports.mdx b/docs/admin_docs/configuration/alerts-reports.mdx index b66f641e290..f5c4efc42ed 100644 --- a/docs/admin_docs/configuration/alerts-reports.mdx +++ b/docs/admin_docs/configuration/alerts-reports.mdx @@ -81,6 +81,87 @@ SLACK_CACHE_TIMEOUT = int(timedelta(days=2).total_seconds()) SLACK_API_RATE_LIMIT_RETRY_COUNT = 5 ``` +### Webhook integration + +Superset can send alert and report notifications to any HTTP endpoint — useful for chat platforms, incident management tools, or custom automation. + +#### Enabling Webhooks + +Enable the feature flag in `superset_config.py`: + +```python +FEATURE_FLAGS = { + "ALERT_REPORTS": True, + "ALERT_REPORT_WEBHOOK": True, +} +``` + +#### Configuring a Webhook Recipient + +When creating or editing an alert or report, select **Webhook** as the notification method and enter your endpoint URL. + +#### Payload Format + +Superset sends an HTTP POST with `Content-Type: application/json`: + +```json +{ + "name": "My Alert", + "header": { + "notification_format": "JSON", + "notification_type": "Alert", + "notification_source": "Alert", + "chart_id": 42, + "dashboard_id": null + }, + "text": "Alert condition met: value exceeded threshold", + "description": "Monthly revenue dropped below target", + "url": "https://your-superset-host/superset/dashboard/1/" +} +``` + +When a report includes file attachments (CSV, PDF, or PNG screenshots), the request is sent as `multipart/form-data` instead. In that case, each top-level payload field (`name`, `text`, `description`, `url`) becomes its own form field, and nested structures like `header` are serialized as a JSON-encoded string in their own field. Every attachment is added as a repeated form field named `files`: + +``` +POST /webhook HTTP/1.1 +Content-Type: multipart/form-data; boundary=... + +--... +Content-Disposition: form-data; name="name" + +My Alert +--... +Content-Disposition: form-data; name="header" + +{"notification_format": "JSON", "notification_type": "Alert", ...} +--... +Content-Disposition: form-data; name="text" + +Alert condition met: value exceeded threshold +--... +Content-Disposition: form-data; name="files"; filename="report.csv" +Content-Type: text/csv + + +--... +``` + +Webhook consumers should branch on `Content-Type`: parse the body as JSON when `application/json`, or read the individual form fields (decoding `header` as JSON) when `multipart/form-data`. + +#### HTTPS Enforcement + +To require HTTPS webhook URLs (recommended for production), set: + +```python +ALERT_REPORTS_WEBHOOK_HTTPS_ONLY = True +``` + +When enabled, Superset rejects webhook configurations that use `http://` URLs. + +#### Retry Behavior + +Superset automatically retries webhook deliveries on `429 Too Many Requests` and `5xx` server errors using exponential backoff. + ### Kubernetes-specific - You must have a `celery beat` pod running. If you're using the chart included in the GitHub repository under [helm/superset](https://github.com/apache/superset/tree/master/helm/superset), you need to put `supersetCeleryBeat.enabled = true` in your values override. diff --git a/docs/admin_docs/configuration/aws-iam.mdx b/docs/admin_docs/configuration/aws-iam.mdx new file mode 100644 index 00000000000..e3fac57508f --- /dev/null +++ b/docs/admin_docs/configuration/aws-iam.mdx @@ -0,0 +1,162 @@ +{/* +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. +*/} + +--- +title: AWS IAM Authentication +sidebar_label: AWS IAM Authentication +sidebar_position: 15 +--- + +# AWS IAM Authentication for AWS Databases + +Superset supports IAM-based authentication for **Amazon Aurora** (PostgreSQL and MySQL) and **Amazon Redshift**. IAM auth eliminates the need for database passwords — Superset generates a short-lived auth token using temporary AWS credentials instead. + +Cross-account IAM role assumption via STS `AssumeRole` is supported, allowing a Superset deployment in one AWS account to connect to databases in a different account. + +## Prerequisites + +- Enable the `AWS_DATABASE_IAM_AUTH` feature flag in `superset_config.py`. IAM authentication is gated behind this flag; if it is disabled, connections using `aws_iam` fail with *"AWS IAM database authentication is not enabled."* + ```python + FEATURE_FLAGS = { + "AWS_DATABASE_IAM_AUTH": True, + } + ``` +- `boto3` must be installed in your Superset environment: + ```bash + pip install boto3 + ``` +- The Superset server's IAM role (or static credentials) must have permission to call `sts:AssumeRole` (for cross-account) or the same-account permissions for the target service: + - **Aurora (RDS)**: `rds-db:connect` + - **Redshift provisioned**: `redshift:GetClusterCredentials` + - **Redshift Serverless**: `redshift-serverless:GetCredentials` and `redshift-serverless:GetWorkgroup` +- SSL must be enabled on the Aurora / Redshift endpoint (required for IAM token auth). + +## Configuration + +IAM authentication is configured via the **encrypted_extra** field of the database connection. Access this field in the **Advanced** → **Security** section of the database connection form, under **Secure Extra**. + +### Aurora PostgreSQL or Aurora MySQL + +```json +{ + "aws_iam": { + "enabled": true, + "role_arn": "arn:aws:iam::222222222222:role/SupersetDatabaseAccess", + "external_id": "superset-prod-12345", + "region": "us-east-1", + "db_username": "superset_iam_user", + "session_duration": 3600 + } +} +``` + +| Field | Required | Description | +|-------|----------|-------------| +| `enabled` | Yes | Set to `true` to activate IAM auth | +| `role_arn` | No | ARN of the cross-account IAM role to assume via STS. Omit for same-account auth | +| `external_id` | No | External ID for the STS `AssumeRole` call, if required by the target role's trust policy | +| `region` | Yes | AWS region of the database cluster | +| `db_username` | Yes | The database username associated with the IAM identity | +| `session_duration` | No | STS session duration in seconds (default: `3600`) | + +### Redshift (Serverless) + +```json +{ + "aws_iam": { + "enabled": true, + "role_arn": "arn:aws:iam::222222222222:role/SupersetRedshiftAccess", + "region": "us-east-1", + "workgroup_name": "my-workgroup", + "db_name": "dev" + } +} +``` + +### Redshift (Provisioned Cluster) + +```json +{ + "aws_iam": { + "enabled": true, + "role_arn": "arn:aws:iam::222222222222:role/SupersetRedshiftAccess", + "region": "us-east-1", + "cluster_identifier": "my-cluster", + "db_username": "superset_iam_user", + "db_name": "dev" + } +} +``` + +## Cross-Account IAM Setup + +To connect to a database in Account B from a Superset deployment in Account A: + +**1. In Account B — create a database-access role:** + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": ["rds-db:connect"], + "Resource": "arn:aws:rds-db:us-east-1:222222222222:dbuser/db-XXXXXXXXXXXX/superset_iam_user" + } + ] +} +``` + +**Trust policy** (allows Account A's Superset role to assume it): + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::111111111111:role/SupersetInstanceRole" + }, + "Action": "sts:AssumeRole", + "Condition": { + "StringEquals": { + "sts:ExternalId": "superset-prod-12345" + } + } + } + ] +} +``` + +**2. In Account A — grant Superset's role permission to assume the Account B role:** + +```json +{ + "Effect": "Allow", + "Action": "sts:AssumeRole", + "Resource": "arn:aws:iam::222222222222:role/SupersetDatabaseAccess" +} +``` + +**3. Configure the database connection in Superset** using the `role_arn` and `external_id` from the trust policy (as shown in the configuration example above). + +## Credential Caching + +STS credentials are cached in memory keyed by `(role_arn, region, external_id)` with a 10-minute TTL. This reduces the number of STS API calls when multiple queries are executed with the same connection. Tokens are refreshed automatically before expiry. diff --git a/docs/admin_docs/configuration/cache.mdx b/docs/admin_docs/configuration/cache.mdx index be1459f09f1..ef3fbe1161c 100644 --- a/docs/admin_docs/configuration/cache.mdx +++ b/docs/admin_docs/configuration/cache.mdx @@ -138,14 +138,33 @@ THUMBNAIL_CACHE_CONFIG = init_thumbnail_cache ``` Using the above example cache keys for dashboards will be `superset_thumb__dashboard__{ID}`. You can -override the base URL for selenium using: +override the base URL for Selenium using: ``` WEBDRIVER_BASEURL = "https://superset.company.com" ``` -Additional selenium web drive configuration can be set using `WEBDRIVER_CONFIGURATION`. You can -implement a custom function to authenticate selenium. The default function uses the `flask-login` +To control which user account is used for rendering thumbnails and warming up caches, configure +`THUMBNAIL_EXECUTORS` and `CACHE_WARMUP_EXECUTORS`. Each accepts a list of executor types (which +resolve to an owner, creator, modifier, or the currently-logged-in user) and/or a `FixedExecutor` +pinned to a specific username. By default, thumbnails render as the current user +(`ExecutorType.CURRENT_USER`) and cache warmup runs as the chart/dashboard owner +(`ExecutorType.OWNER`). + +To force both to run as a dedicated service account (`admin` in this example): + +```python +from superset.tasks.types import ExecutorType, FixedExecutor + +THUMBNAIL_EXECUTORS = [FixedExecutor("admin")] +CACHE_WARMUP_EXECUTORS = [FixedExecutor("admin")] +``` + +Use a dedicated read-only service account here rather than a personal admin account, so that +thumbnail rendering and cache warmup tasks don't fail if a specific user's credentials change. + +Additional Selenium WebDriver configuration can be set using `WEBDRIVER_CONFIGURATION`. You can +implement a custom function to authenticate Selenium. The default function uses the `flask-login` session cookie. Here's an example of a custom function signature: ```python @@ -159,6 +178,20 @@ Then on configuration: WEBDRIVER_AUTH_FUNC = auth_driver ``` +## ETag Support for Thumbnails + +Thumbnail and screenshot endpoints return `ETag` response headers based on the cached content digest. Clients can use conditional requests to avoid downloading unchanged images: + +``` +GET /api/v1/chart/42/thumbnail/ +If-None-Match: "abc123..." + +→ 304 Not Modified (if unchanged) +→ 200 OK (with new image if changed) +``` + +This is particularly useful for embedded dashboards and external integrations that periodically poll for updated screenshots — unchanged thumbnails return immediately with no payload. + ## Distributed Coordination Backend Superset supports an optional distributed coordination (`DISTRIBUTED_COORDINATION_CONFIG`) for diff --git a/docs/admin_docs/configuration/configuring-superset.mdx b/docs/admin_docs/configuration/configuring-superset.mdx index 657d5d4dc75..daf92b1c943 100644 --- a/docs/admin_docs/configuration/configuring-superset.mdx +++ b/docs/admin_docs/configuration/configuring-superset.mdx @@ -109,6 +109,14 @@ SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY' You can generate a strong secure key with `openssl rand -base64 42`. +Alternatively, you can set the secret key using `SUPERSET_SECRET_KEY` environment variable: + +On a Unix-based system, such as Linux or macOS, you can do so by running the following command in your terminal: + +```bash +export SUPERSET_SECRET_KEY=$(openssl rand -base64 42) +``` + :::caution Use a strong secret key This key will be used for securely signing session cookies and encrypting sensitive information stored in Superset's application metadata database. Your deployment must use a complex, unique key. @@ -364,6 +372,26 @@ CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager ] ``` +### PKCE Support + +For public OAuth2 clients that cannot securely store a client secret, enable Proof Key for Code Exchange (PKCE) by adding `code_challenge_method` to the `remote_app` configuration: + +```python +OAUTH_PROVIDERS = [ + { + 'name': 'myProvider', + 'remote_app': { + 'client_id': 'myClientId', + 'client_secret': 'mySecret', # may be empty for pure public clients + 'code_challenge_method': 'S256', # enables PKCE + 'server_metadata_url': 'https://myAuthorizationServer/.well-known/openid-configuration' + } + } +] +``` + +PKCE (`S256`) is recommended for all OAuth2 flows, even when a client secret is present, as it protects against authorization code interception attacks. + ## LDAP Authentication FAB supports authenticating user credentials against an LDAP server. @@ -444,6 +472,38 @@ FEATURE_FLAGS = { A current list of feature flags can be found in the [Feature Flags](/admin-docs/configuration/feature-flags) documentation. +## Security Configuration + +### HASH_ALGORITHM + +Controls the hashing algorithm used for internal checksums and cache keys (thumbnails, cache keys, etc.). The default is `sha256`, which satisfies environments with stricter compliance requirements (e.g., FedRAMP). Set it to `md5` to retain the legacy behavior from older Superset deployments: + +```python +HASH_ALGORITHM = "sha256" # default; set to "md5" for legacy behavior +``` + +A companion `HASH_ALGORITHM_FALLBACKS` list (default: `["md5"]`) lets UUID lookups fall back to older algorithms, which enables gradual migration without breaking existing entries. Set it to `[]` for strict mode (use only `HASH_ALGORITHM`). + +:::note +This setting affects internal Superset operations only, not user passwords or authentication tokens. Changing it in an existing deployment may invalidate cached values but does not require a database migration. +::: + +## SQL Lab Query History Pruning + +SQL Lab query history is stored in the metadata database and is **not** pruned by default. To trim older rows, enable the `prune_query` Celery beat task by uncommenting it in `CELERY_BEAT_SCHEDULE` and choosing a retention window: + +```python +CELERY_BEAT_SCHEDULE = { + "prune_query": { + "task": "prune_query", + "schedule": crontab(minute=0, hour=0, day_of_month=1), + "kwargs": {"retention_period_days": 180}, + }, +} +``` + +Adjust `retention_period_days` to control how long query rows are kept. Companion opt-in tasks (`prune_logs`, `prune_tasks`) exist for pruning the logs and tasks tables; see the commented-out examples in `superset/config.py`. Without enabling these tasks, the metadata database will grow unbounded over time. + :::resources - [Blog: Feature Flags in Apache Superset](https://preset.io/blog/feature-flags-in-apache-superset-and-preset/) ::: diff --git a/docs/admin_docs/configuration/importing-exporting-datasources.mdx b/docs/admin_docs/configuration/importing-exporting-datasources.mdx index 400d64590ad..6fc7ceea9ff 100644 --- a/docs/admin_docs/configuration/importing-exporting-datasources.mdx +++ b/docs/admin_docs/configuration/importing-exporting-datasources.mdx @@ -10,6 +10,10 @@ version: 1 The superset cli allows you to import and export datasources from and to YAML. Datasources include databases. The data is expected to be organized in the following hierarchy: +:::info +Superset's ZIP-based import/export also covers **dashboards**, **charts**, and **saved queries**, exercised through the UI and REST API. The [Dashboard Import Overwrite Behavior](#dashboard-import-overwrite-behavior) and [UUIDs in API Responses](#uuids-in-api-responses) sections below document the behavior shared across all asset types. +::: + ```text ├──databases | ├──database_1 @@ -26,6 +30,10 @@ databases. The data is expected to be organized in the following hierarchy: | └── ... (more databases) ``` +:::note +When you export a database connection, the `masked_encrypted_extra` field (used for sensitive connection parameters such as service account JSON, OAuth tokens, and other encrypted credentials) is included in the export. When importing on another instance, these values are decrypted and re-encrypted using the destination instance's `SECRET_KEY`. Ensure the receiving instance has a valid `SECRET_KEY` configured before importing. +::: + ## Exporting Datasources to YAML You can print your current datasources to stdout by running: @@ -75,6 +83,29 @@ The optional username flag **-u** sets the user used for the datasource import. superset import_datasources -p -u 'admin' ``` +## Dashboard Import Overwrite Behavior + +When importing a dashboard ZIP with the **overwrite** option enabled, any existing charts that are part of the dashboard are **replaced** rather than duplicated. This applies to: + +- Charts whose UUID matches a chart already present in the target instance +- The full chart configuration (query, visualization type, columns, metrics) is replaced by the imported version + +If you import without the overwrite flag, existing charts with conflicting UUIDs are left unchanged and the import skips those objects. Use overwrite when you want to push a fully updated dashboard (including chart definitions) from a development or staging environment to production. + +## UUIDs in API Responses + +The REST API POST endpoints for **datasets**, **charts**, and **dashboards** include the auto-generated `uuid` field in the response body: + +```json +{ + "id": 42, + "uuid": "b8a8d5c3-1234-4abc-8def-0123456789ab", + ... +} +``` + +UUIDs remain stable across import/export cycles and can be used for cross-environment workflows — for example, recording a UUID when creating a chart in development and using it to identify the matching chart after importing into production. + ## Legacy Importing Datasources ### From older versions of Superset to current version diff --git a/docs/admin_docs/configuration/mcp-server.mdx b/docs/admin_docs/configuration/mcp-server.mdx index 22a80d645b3..df299acaf8d 100644 --- a/docs/admin_docs/configuration/mcp-server.mdx +++ b/docs/admin_docs/configuration/mcp-server.mdx @@ -501,6 +501,7 @@ All MCP settings go in `superset_config.py`. Defaults are defined in `superset/m | `MCP_SERVICE_URL` | `None` | Public base URL for MCP-generated links (set this when behind a reverse proxy) | | `MCP_DEBUG` | `False` | Enable debug logging | | `MCP_DEV_USERNAME` | -- | Superset username for development mode (no auth) | +| `MCP_RBAC_ENABLED` | `True` | Enforce Superset's role-based access control on MCP tool calls. When `True`, each tool checks that the authenticated user has the required FAB permission before executing. Disable only for testing or trusted-network deployments. | ### Authentication @@ -516,6 +517,7 @@ All MCP settings go in `superset_config.py`. Defaults are defined in `superset/m | `MCP_REQUIRED_SCOPES` | `[]` | Required JWT scopes | | `MCP_JWT_DEBUG_ERRORS` | `False` | Log detailed JWT errors server-side (never exposed in HTTP responses per RFC 6750) | | `MCP_AUTH_FACTORY` | `None` | Custom auth provider factory `(flask_app) -> auth_provider`. Takes precedence over built-in JWT | +| `MCP_USER_RESOLVER` | `None` | Custom function `(app, access_token) -> username` to extract a Superset username from a validated JWT token. When `None`, the default resolver checks `preferred_username`, `username`, `email`, and `sub` claims in that order. | ### Response Size Guard @@ -599,6 +601,43 @@ MCP_STORE_CONFIG = { | `event_store_max_events` | `100` | Maximum events retained per session | | `event_store_ttl` | `3600` | Event TTL in seconds | +### Tool Search + +By default the MCP server exposes a lightweight tool-search interface instead of advertising every tool at once. This reduces the initial context sent to the LLM by ~70%, which lowers cost and latency. The AI client discovers tools on demand by calling `search_tools` and then invokes them via `call_tool`. + +```python +MCP_TOOL_SEARCH_CONFIG = { + "enabled": True, + "strategy": "bm25", # "bm25" (natural language) or "regex" + "max_results": 5, + "always_visible": [ # Tools always listed (pinned) + "health_check", + "get_instance_info", + ], + "search_tool_name": "search_tools", + "call_tool_name": "call_tool", + "include_schemas": False, # False=summary mode (name + parameters_hint) + "compact_schemas": True, # Strip $defs (only applies when include_schemas=True) + "max_description_length": 300, +} +``` + +| Key | Default | Description | +|-----|---------|-------------| +| `enabled` | `True` | Enable tool search. When `False`, all tools are listed upfront | +| `strategy` | `"bm25"` | Search ranking algorithm. `"bm25"` supports natural language; `"regex"` supports pattern matching | +| `max_results` | `5` | Maximum tools returned per search query | +| `always_visible` | See above | Tools that always appear in `list_tools`, regardless of search | +| `include_schemas` | `False` | When `False` (default, "summary mode"), search results omit `inputSchema` entirely and include a lightweight `parameters_hint` listing top-level parameter names. Set to `True` to include the full `inputSchema` in search results. Full schemas are always used when a tool is actually invoked via `call_tool`. | +| `compact_schemas` | `True` | Strip `$defs` / `$ref` and replace with `{"type": "object"}` in search results to reduce token cost. Only takes effect when `include_schemas=True` — ignored in summary mode. | +| `max_description_length` | `300` | Truncate tool descriptions in search results (0 = no truncation). Applies in both summary and full-schema modes. | + +:::tip +Set `enabled: False` to revert to the traditional "show all tools at once" behavior, which some clients or workflows may prefer. +::: + +Tool search reduces the initial token cost from ~15–20K tokens (full catalog) down to ~4–5K tokens (pinned tools + search interface) — roughly 85% savings at the start of each conversation. + ### Session & CSRF These values are flat-merged into the Flask app config used by the MCP server process: @@ -620,6 +659,102 @@ MCP_CSRF_CONFIG = { --- +## Access Control + +### RBAC Enforcement + +The MCP server respects Superset's full role-based access control (RBAC). Every authenticated user can only access the data and operations their Superset roles permit — the same rules that apply in the Superset UI apply through MCP. + +Each tool declares one or more required FAB permissions. The table below maps tool groups to their permission requirements: + +| Tool group | Required FAB permission | +|------------|------------------------| +| `list_charts`, `get_chart_info`, `get_chart_data`, `get_chart_preview`, `generate_chart`, `update_chart` | `can_read` on `Chart` (read), `can_write` on `Chart` (mutate) | +| `list_dashboards`, `get_dashboard_info`, `generate_dashboard`, `add_chart_to_existing_dashboard` | `can_read` on `Dashboard` (read), `can_write` on `Dashboard` (mutate) | +| `list_datasets`, `get_dataset_info`, `create_virtual_dataset` | `can_read` on `Dataset` (read), `can_write` on `Dataset` (mutate) | +| `list_databases`, `get_database_info` | `can_read` on `Database` | +| `execute_sql` | `can_execute_sql_query` on `SQLLab` | +| `open_sql_lab_with_context` | `can_read` on `SQLLab` | +| `save_sql_query` | `can_write` on `SavedQuery` | +| `health_check` | None (public) | + +To disable RBAC checking globally (for trusted-network deployments or testing), set: + +```python +# superset_config.py +MCP_RBAC_ENABLED = False +``` + +:::warning +Disabling RBAC removes all permission checks from MCP tool calls. Only do this on isolated, internal deployments where all MCP users are trusted admins. +::: + +### Audit Log + +All MCP tool calls are recorded in Superset's action log. You can view them at **Settings → Action Log** (admin only). Each log entry records: + +- The tool name (e.g., `mcp.generate_chart.db_write`) +- The authenticated user +- A timestamp + +This makes MCP activity fully auditable alongside regular Superset activity. The action log uses the same event logger as the rest of Superset, so existing log ingestion pipelines (e.g., sending logs to Elasticsearch or a SIEM) capture MCP events automatically. + +### Middleware Pipeline + +Every MCP request passes through a middleware stack before reaching the tool function. The default stack (assembled in `build_middleware_list()` in `server.py`) is: + +| Middleware | Purpose | Default | +|------------|---------|---------| +| `StructuredContentStripperMiddleware` | Strips `structuredContent` from responses for Claude.ai bridge compatibility | Enabled | +| `LoggingMiddleware` | Logs each tool call with user, parameters, and duration | Enabled | +| `GlobalErrorHandlerMiddleware` | Catches unhandled exceptions and sanitizes sensitive data before it reaches the client | Enabled | +| `ResponseSizeGuardMiddleware` | Estimates token count, warns at 80% of limit, blocks at limit | Enabled (configurable via `MCP_RESPONSE_SIZE_CONFIG`) | +| `ResponseCachingMiddleware` | Caches read-heavy tool responses (in-memory or Redis) | Disabled (enable via `MCP_CACHE_CONFIG`) | + +Additional middleware classes (`RateLimitMiddleware`, `FieldPermissionsMiddleware`, `PrivateToolMiddleware`) are implemented in `superset/mcp_service/middleware.py` but are not added to the default pipeline. They are available for operators who want to layer them in via a custom startup path. + +### Error Sanitization + +The `GlobalErrorHandlerMiddleware` automatically redacts sensitive information from all error messages before they reach the LLM client. The following are replaced with generic messages: + +- **Database connection strings** — replaced with a generic connection error message +- **API keys and tokens** — redacted from error traces +- **File system paths** — stripped to prevent information disclosure +- **IP addresses** — removed from error context + +This ensures that a misconfigured database connection or an unexpected exception never leaks credentials or internal topology to the LLM or its users. All regex patterns used for redaction are bounded to prevent ReDoS attacks. + +--- + +## Performance + +### Connection Pooling + +Each MCP server process maintains its own SQLAlchemy connection pool to the database. For multi-worker deployments, total open connections = **workers × pool size**. + +```python +# superset_config.py +SQLALCHEMY_POOL_SIZE = 5 +SQLALCHEMY_MAX_OVERFLOW = 10 +SQLALCHEMY_POOL_TIMEOUT = 30 +SQLALCHEMY_POOL_RECYCLE = 3600 # Recycle connections after 1 hour +``` + +For a 3-pod Kubernetes deployment with the defaults above, expect up to 3 × (5 + 10) = 45 connections. Size your database's `max_connections` accordingly. + +### Response Caching + +Enable response caching for read-heavy workloads (dashboards/datasets that don't change frequently). With the in-memory backend (default when `MCP_STORE_CONFIG` is disabled), caching is per-process. Use Redis-backed caching for consistent cache hits across multiple pods: + +```python +MCP_CACHE_CONFIG = {"enabled": True, "call_tool_ttl": 3600} +MCP_STORE_CONFIG = {"enabled": True, "CACHE_REDIS_URL": "redis://redis:6379/0"} +``` + +Mutating tools (`generate_chart`, `update_chart`, `execute_sql`, `generate_dashboard`) are always excluded from caching regardless of this setting. + +--- + ## Troubleshooting ### Server won't start @@ -664,6 +799,32 @@ MCP_CSRF_CONFIG = { --- +## Audit Events + +All MCP tool calls are logged to Superset's event logger, the same system used by the web UI (viewable at **Settings → Action Log**). Each event captures: + +- **Action**: `mcp..` (e.g., `mcp.list_databases.query`) +- **User**: the resolved Superset username from the JWT or dev config +- **Timestamp**: when the operation ran + +This means MCP activity is auditable alongside normal user activity. No additional configuration is required — logging is on by default whenever the event logger is enabled in your Superset deployment. + +## Tool Pagination + +MCP list tools (`list_datasets`, `list_charts`, `list_dashboards`, `list_databases`) use **offset pagination** via `page` (1-based) and `page_size` parameters. Responses include `page`, `page_size`, `total_count`, `total_pages`, `has_previous`, and `has_next`. To iterate through all results: + +```python +# Example: fetch all charts across pages +all_charts = [] +page = 1 +while True: + result = mcp.list_charts(page=page, page_size=50) + all_charts.extend(result["charts"]) + if not result.get("has_next"): + break + page += 1 +``` + ## Security Best Practices - **Use TLS** for all production MCP endpoints -- place the server behind a reverse proxy with HTTPS diff --git a/docs/admin_docs/configuration/networking-settings.mdx b/docs/admin_docs/configuration/networking-settings.mdx index f1af8a87ab6..b37d93bedcc 100644 --- a/docs/admin_docs/configuration/networking-settings.mdx +++ b/docs/admin_docs/configuration/networking-settings.mdx @@ -64,7 +64,7 @@ There are two approaches to making dashboards publicly accessible: 3. Edit each dashboard's properties and add the "Public" role 4. Only dashboards with the Public role explicitly assigned are visible to anonymous users -See the [Public role documentation](/admin-docs/security/security#public) for more details. +See the [Public role documentation](/admin-docs/security/#public) for more details. #### Embedding a Public Dashboard @@ -111,7 +111,7 @@ FEATURE_FLAGS = { This flag only hides the logout button when Superset detects it is running inside an iframe. Users accessing Superset directly (not embedded) will still see the logout button regardless of this setting. :::note -When embedding with SSO, also set `SESSION_COOKIE_SAMESITE = 'None'` and `SESSION_COOKIE_SECURE = True`. See [Security documentation](/docs/security/securing_superset) for details. +When embedding with SSO, also set `SESSION_COOKIE_SAMESITE = 'None'` and `SESSION_COOKIE_SECURE = True`. See [Security documentation](/admin-docs/security/securing_superset) for details. ::: ## CSRF settings diff --git a/docs/admin_docs/configuration/theming.mdx b/docs/admin_docs/configuration/theming.mdx index 8f88ec8fda3..92e4fcd8e59 100644 --- a/docs/admin_docs/configuration/theming.mdx +++ b/docs/admin_docs/configuration/theming.mdx @@ -84,6 +84,35 @@ THEME_DARK = { # - OS preference detection is automatically enabled ``` +### App Branding + +The application name shown in the browser title bar and navigation can be +set via the `brandAppName` theme token: + +```python +THEME_DEFAULT = { + "token": { + "brandAppName": "Acme Analytics", + # ... other tokens + } +} +``` + +Or in the theme CRUD UI JSON editor: + +```json +{ + "token": { + "brandAppName": "Acme Analytics" + } +} +``` + +The existing `APP_NAME` Python config key continues to work for backward compatibility. +`brandAppName` takes precedence when both are set, and allows different themes to carry different brand names. +Email and alert/report notification subjects are driven by backend settings such as +`EMAIL_REPORTS_SUBJECT_PREFIX` and `APP_NAME`, not by this theme token. + ### Migration from Configuration to UI When `ENABLE_UI_THEME_ADMINISTRATION = True`: @@ -93,6 +122,17 @@ When `ENABLE_UI_THEME_ADMINISTRATION = True`: 3. Administrators can change system themes without restarting Superset 4. Configuration file themes serve as fallbacks when no UI themes are set +### Theme Validation and Fallback + +Superset validates theme JSON when it is saved, either through the UI or via configuration. If a theme contains invalid tokens or an unrecognized structure, Superset logs a warning and falls back to the built-in default theme rather than applying a broken configuration. This prevents a bad theme from rendering the application unusable. + +The fallback order is: +1. **UI-configured system theme** (highest priority, if `ENABLE_UI_THEME_ADMINISTRATION = True`) +2. **`THEME_DEFAULT` / `THEME_DARK`** from `superset_config.py` +3. **Built-in Superset default theme** (always present as a safety net) + +If you see unexpected styling after a config change, check the Superset server logs for theme validation warnings. + ### Copying Themes Between Systems To export a theme for use in configuration files or another instance: @@ -114,7 +154,11 @@ Superset supports custom fonts through the theme configuration, allowing you to ### Default Fonts -By default, Superset uses Inter and Fira Code fonts which are bundled with the application via `@fontsource` packages. These fonts work offline and require no external network calls. +By default, Superset uses **Inter** for UI text and **IBM Plex Mono** for code (SQL editors, JSON fields, and other monospace contexts). Both fonts are bundled with the application via `@fontsource` packages and work offline without any external network calls. + +:::note +IBM Plex Mono replaced Fira Code as the default code font in Superset 6.1. If you have an existing theme that explicitly sets `fontFamilyCode: "Fira Code, ..."`, you may want to update it. +::: ### Configuring Custom Fonts @@ -312,11 +356,25 @@ Available chart types for `echartsOptionsOverridesByChartType`: - `echarts_heatmap` - Heatmaps - `echarts_mixed_timeseries` - Mixed time series +### Array Property Overrides + +Array properties (such as color palettes) are fully supported in overrides. Arrays are **replaced entirely** rather than merged, so specify the complete array: + +```python +THEME_DEFAULT = { + "token": { ... }, + "echartsOptionsOverrides": { + # Replace the default color palette for all ECharts visualizations + "color": ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b"] + } +} +``` + ### Best Practices 1. **Start with global overrides** for consistent styling across all charts 2. **Use chart-specific overrides** for unique requirements per visualization type -3. **Test thoroughly** as overrides use deep merge - nested objects are combined, but arrays are completely replaced +3. **Test thoroughly** as overrides use deep merge for objects, but arrays are completely replaced — always specify the full array value 4. **Document your overrides** to help team members understand custom styling 5. **Consider performance** - complex overrides may impact chart rendering speed diff --git a/docs/admin_docs/configuration/timezones.mdx b/docs/admin_docs/configuration/timezones.mdx index db53fcc6f46..2e2a239f1e2 100644 --- a/docs/admin_docs/configuration/timezones.mdx +++ b/docs/admin_docs/configuration/timezones.mdx @@ -20,7 +20,7 @@ To help make the problem somewhat tractable—given that Apache Superset has no To strive for data consistency (regardless of the timezone of the client) the Apache Superset backend tries to ensure that any timestamp sent to the client has an explicit (or semi-explicit as in the case with [Epoch time](https://en.wikipedia.org/wiki/Unix_time) which is always in reference to UTC) timezone encoded within. -The challenge however lies with the slew of [database engines](/admin-docs/databases#installing-drivers-in-docker) which Apache Superset supports and various inconsistencies between their [Python Database API (DB-API)](https://www.python.org/dev/peps/pep-0249/) implementations combined with the fact that we use [Pandas](https://pandas.pydata.org/) to read SQL into a DataFrame prior to serializing to JSON. Regrettably Pandas ignores the DB-API [type_code](https://www.python.org/dev/peps/pep-0249/#type-objects) relying by default on the underlying Python type returned by the DB-API. Currently only a subset of the supported database engines work correctly with Pandas, i.e., ensuring timestamps without an explicit timestamp are serializd to JSON with the server timezone, thus guaranteeing the client will display timestamps in a consistent manner irrespective of the client's timezone. +The challenge however lies with the slew of [database engines](/user-docs/databases#installing-drivers-in-docker) which Apache Superset supports and various inconsistencies between their [Python Database API (DB-API)](https://www.python.org/dev/peps/pep-0249/) implementations combined with the fact that we use [Pandas](https://pandas.pydata.org/) to read SQL into a DataFrame prior to serializing to JSON. Regrettably Pandas ignores the DB-API [type_code](https://www.python.org/dev/peps/pep-0249/#type-objects) relying by default on the underlying Python type returned by the DB-API. Currently only a subset of the supported database engines work correctly with Pandas, i.e., ensuring timestamps without an explicit timestamp are serialized to JSON with the server timezone, thus guaranteeing the client will display timestamps in a consistent manner irrespective of the client's timezone. For example the following is a comparison of MySQL and Presto, diff --git a/docs/admin_docs/installation/kubernetes.mdx b/docs/admin_docs/installation/kubernetes.mdx index e54cf47cd2e..c18bf803f92 100644 --- a/docs/admin_docs/installation/kubernetes.mdx +++ b/docs/admin_docs/installation/kubernetes.mdx @@ -149,7 +149,7 @@ For production clusters it's recommended to build own image with this step done Superset requires a Python DB-API database driver and a SQLAlchemy dialect to be installed for each datastore you want to connect to. -See [Install Database Drivers](/admin-docs/databases#installing-database-drivers) for more information. +See [Install Database Drivers](/user-docs/databases#installing-database-drivers) for more information. It is recommended that you refer to versions listed in [pyproject.toml](https://github.com/apache/superset/blob/master/pyproject.toml) instead of hard-coding them in your bootstrap script, as seen below. diff --git a/docs/admin_docs/security/security.mdx b/docs/admin_docs/security/security.mdx index 867e3f87986..6190925d8ab 100644 --- a/docs/admin_docs/security/security.mdx +++ b/docs/admin_docs/security/security.mdx @@ -52,6 +52,15 @@ only see the objects that they have access to. The **sql_lab** role grants access to SQL Lab. Note that while **Admin** users have access to all databases by default, both **Alpha** and **Gamma** users need to be given access on a per database basis. +Beyond the base `sql_lab` role, two additional SQL Lab permissions must be explicitly granted for users who need these capabilities: + +| Permission | Feature | +|------------|---------| +| `can_estimate_query_cost` on `SQLLab` | Estimate query cost before running | +| `can_format_sql` on `SQLLab` | Format SQL using the database's dialect | + +Grant these in **Security → List Roles** by adding the permissions to the relevant role. + ### Public The **Public** role is the most restrictive built-in role, designed specifically for anonymous/unauthenticated @@ -182,6 +191,8 @@ However, it is crucial to understand the following: By combining Superset's configurable safeguards with strong database-level security practices, you can achieve a more robust and layered security posture. +**Dataset Sample Access**: The `get_samples()` endpoint now enforces datasource-level access control. Users can only fetch sample rows from datasets they have been explicitly granted access to — the same permission check applied when running chart queries. This closes a prior gap where unauthenticated or under-privileged access could retrieve sample data. + ### REST API for user & role management Flask-AppBuilder supports a REST API for user CRUD, @@ -194,6 +205,57 @@ FAB_ADD_SECURITY_API = True Once configured, the documentation for additional "Security" endpoints will be visible in Swagger for you to explore. +### API Key Authentication + +Superset supports long-lived API keys for service accounts, CI/CD pipelines, and programmatic integrations (including MCP clients). + +#### Enabling API Key Authentication + +API key authentication is **disabled by default**. To turn it on, set the Flask-AppBuilder config value in `superset_config.py` and also enable the matching feature flag so the management UI is exposed: + +```python +FAB_API_KEY_ENABLED = True + +FEATURE_FLAGS = { + "FAB_API_KEY_ENABLED": True, +} +``` + +The config value registers the `ApiKeyApi` blueprint on the backend; the feature flag controls whether the UI for managing keys appears for the user. See the [Feature Flags](/admin-docs/configuration/feature-flags) documentation for more on feature flag configuration. + +#### Creating an API Key + +Once enabled, each user manages their own keys from their profile page: + +1. Open the user menu (top-right) and click **Info** to navigate to the User Info page +2. Expand the **API Keys** section +3. Click **+ API Key** +4. Enter a name and (optionally) an expiration date +5. Copy the generated token — it is shown only once + +Only users with the `can_read` and `can_write` permissions on `ApiKey` (granted by default to Admins) can manage API keys. + +#### Using an API Key + +Pass the key as a Bearer token in the `Authorization` header: + +``` +Authorization: Bearer +``` + +This works for all REST API endpoints and the MCP server. The request is executed with the permissions of the user who created the key. + +#### Use Cases + +- **CI/CD pipelines** — automated chart/dashboard exports and imports +- **MCP integrations** — connect AI assistants without interactive login +- **External services** — dashboards embedded in other applications +- **Service accounts** — long-lived credentials that don't expire with session cookies + +:::caution +Store API keys securely. Anyone with a valid key can make requests on behalf of the creating user. Revoke keys promptly if they are compromised by deleting them from the **API Keys** section of your User Info page. +::: + ### Customizing Permissions The permissions exposed by FAB are very granular and allow for a great level of @@ -239,26 +301,143 @@ based on the roles and permissions that were attributed. ### Row Level Security Using Row Level Security filters (under the **Security** menu) you can create filters -that are assigned to a particular table, as well as a set of roles. +that are assigned to a particular dataset, as well as a set of roles. If you want members of the Finance team to only have access to rows where `department = "finance"`, you could: - Create a Row Level Security filter with that clause (`department = "finance"`) -- Then assign the clause to the **Finance** role and the table it applies to +- Then assign the clause to the **Finance** role and the dataset it applies to The **clause** field, which can contain arbitrary text, is then added to the generated -SQL statement’s WHERE clause. So you could even do something like create a filter +SQL statement's WHERE clause. So you could even do something like create a filter for the last 30 days and apply it to a specific role, with a clause like `date_field > DATE_SUB(NOW(), INTERVAL 30 DAY)`. It can also support multiple conditions: `client_id = 6` AND `advertiser="foo"`, etc. -All relevant Row level security filters will be combined together (under the hood, -the different SQL clauses are combined using AND statements). This means it's -possible to create a situation where two roles conflict in such a way as to limit a table subset to empty. +RLS clauses also support **Jinja templating** when `ENABLE_TEMPLATE_PROCESSING` is enabled, so you can write dynamic filters such as +`user_id = '{{ current_username() }}'` to restrict rows based on the logged-in user. -For example, the filters `client_id=4` and `client_id=5`, applied to a role, -will result in users of that role having `client_id=4` AND `client_id=5` -added to their query, which can never be true. +#### Filter Types + +There are two types of RLS filters: + +- **Regular** — The filter clause is applied when the querying user belongs to one of the + roles assigned to the filter. Use this to restrict what specific roles can see. +- **Base** — The filter clause is applied to **all** users _except_ those in the assigned + roles. Use this to define a default restriction that privileged roles (e.g. Admin) are + exempt from. For example, a Base filter with clause `1 = 0` and the Admin role would + hide all rows from everyone except Admin — useful as a deny-by-default baseline. + +#### Group Keys and Filter Combination + +All applicable RLS filters are combined before being added to the query. The combination +rules are: + +- Filters that share the **same group key** are combined with **OR** (any match within + the group is sufficient). +- Different filter groups (different group keys, or no group key) are combined with + **AND** (all groups must match). +- Filters with **no group key** are each treated as their own group and are always AND'd. + +For example, if a dataset has three filters: + +| Filter | Clause | Group Key | +|--------|--------|-----------| +| F1 | `department = 'Finance'` | `department` | +| F2 | `department = 'Marketing'` | `department` | +| F3 | `region = 'Europe'` | `region` | + +The resulting WHERE clause would be: + +```sql +(department = 'Finance' OR department = 'Marketing') AND (region = 'Europe') +``` + +:::caution Conflicting filters +It is possible to create filters that conflict and produce an empty result set. For +example, the filters `client_id = 4` and `client_id = 5` **without a shared group key** +will be AND'd together, producing `client_id = 4 AND client_id = 5`, which can never +be true. + +If you intend for these to be alternatives, assign them the **same group key** so they +are OR'd instead. +::: + +#### RLS and Virtual (SQL-Based) Datasets + +RLS filters are assigned to **datasets**, not to underlying database tables directly. This +has important implications when working with virtual (SQL-based) datasets: + +- **Physical datasets** (backed directly by a table or view) — RLS filters assigned to + the dataset are added as WHERE clauses to the query. +- **Virtual datasets** (defined by a custom SQL query) — RLS filters assigned directly to + the virtual dataset are applied to the _outer_ query that wraps the dataset's SQL. + Additionally, RLS filters on the **underlying physical datasets** referenced by the + virtual dataset's SQL are injected into the inner subquery for each referenced table. + +For example, if you have: + +1. A physical dataset `orders` with RLS filter `region = 'US'` +2. A virtual dataset defined as `SELECT * FROM orders WHERE status = 'active'` + +A user affected by the RLS filter will effectively see: + +```sql +SELECT * FROM ( + SELECT * FROM orders WHERE (region = 'US') AND status = 'active' +) ... +``` + +**Key considerations for virtual datasets:** + +- You generally do **not** need to duplicate RLS filters on both the physical and virtual + dataset — filters on the physical dataset are applied automatically at query time. +- If you assign an RLS filter directly to a virtual dataset, the clause must reference + columns available in the virtual dataset's _output_, not necessarily the underlying + table's columns. +- In **SQL Lab**, RLS is enforced only when the `RLS_IN_SQLLAB` feature flag is enabled: + queries run against tables that have associated datasets with RLS filters will then have + the appropriate predicates injected automatically. + +#### Checking RLS Filters via the API + +You can use the RLS REST API to audit which filters are configured and which datasets +they affect. This requires the `can_read` permission on the `Row Level Security` resource. + +**List all RLS rules:** + +``` +GET /api/v1/rowlevelsecurity/ +``` + +**Filter RLS rules for a specific dataset** (using [Rison](https://github.com/Nanonid/rison) query syntax): + +``` +GET /api/v1/rowlevelsecurity/?q=(filters:!((col:tables,opr:rel_m_m,value:))) +``` + +**Filter RLS rules by role:** + +``` +GET /api/v1/rowlevelsecurity/?q=(filters:!((col:roles,opr:rel_m_m,value:))) +``` + +**View details of a specific rule** (including clause, assigned datasets, and roles): + +``` +GET /api/v1/rowlevelsecurity/ +``` + +The response includes the filter's `name`, `filter_type` (Regular or Base), `clause`, +`group_key`, assigned `tables` (with id, schema, and table\_name), and assigned `roles` +(with id and name). + +:::tip Auditing RLS for virtual datasets +To find all RLS rules that could affect a particular virtual dataset, query the list +endpoint filtered by that dataset's ID for any directly-assigned rules. Then also check +the physical datasets referenced in the virtual dataset's SQL, since their RLS filters +are applied at query time too. +::: ### User Sessions diff --git a/docs/developer_docs/api.mdx b/docs/developer_docs/api.mdx index 6793408388c..64f1b28b885 100644 --- a/docs/developer_docs/api.mdx +++ b/docs/developer_docs/api.mdx @@ -59,7 +59,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ #### Core Resources
-Dashboards (26 endpoints) — Create, read, update, and delete dashboards. +Dashboards (28 endpoints) — Create, read, update, and delete dashboards. | Method | Endpoint | Description | |--------|----------|-------------| @@ -68,23 +68,25 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ | `POST` | [Create a new dashboard](/developer-docs/api/create-a-new-dashboard) | `/api/v1/dashboard/` | | `GET` | [Get metadata information about this API resource (dashboard--info)](/developer-docs/api/get-metadata-information-about-this-api-resource-dashboard-info) | `/api/v1/dashboard/_info` | | `GET` | [Get a dashboard detail information](/developer-docs/api/get-a-dashboard-detail-information) | `/api/v1/dashboard/{id_or_slug}` | -| `GET` | [Get a dashboard's chart definitions.](/developer-docs/api/get-a-dashboard-s-chart-definitions) | `/api/v1/dashboard/{id_or_slug}/charts` | +| `GET` | [Get a dashboard's chart definitions.](/developer-docs/api/get-a-dashboards-chart-definitions) | `/api/v1/dashboard/{id_or_slug}/charts` | | `POST` | [Create a copy of an existing dashboard](/developer-docs/api/create-a-copy-of-an-existing-dashboard) | `/api/v1/dashboard/{id_or_slug}/copy/` | -| `GET` | [Get dashboard's datasets](/developer-docs/api/get-dashboard-s-datasets) | `/api/v1/dashboard/{id_or_slug}/datasets` | -| `DELETE` | [Delete a dashboard's embedded configuration](/developer-docs/api/delete-a-dashboard-s-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` | -| `GET` | [Get the dashboard's embedded configuration](/developer-docs/api/get-the-dashboard-s-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` | -| `POST` | [Set a dashboard's embedded configuration](/developer-docs/api/set-a-dashboard-s-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` | +| `GET` | [Get dashboard's datasets](/developer-docs/api/get-dashboards-datasets) | `/api/v1/dashboard/{id_or_slug}/datasets` | +| `DELETE` | [Delete a dashboard's embedded configuration](/developer-docs/api/delete-a-dashboards-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` | +| `GET` | [Get the dashboard's embedded configuration](/developer-docs/api/get-the-dashboards-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` | +| `POST` | [Set a dashboard's embedded configuration](/developer-docs/api/set-a-dashboards-embedded-configuration) | `/api/v1/dashboard/{id_or_slug}/embedded` | | `PUT` | [Update dashboard by id_or_slug embedded](/developer-docs/api/update-dashboard-by-id-or-slug-embedded) | `/api/v1/dashboard/{id_or_slug}/embedded` | -| `GET` | [Get dashboard's tabs](/developer-docs/api/get-dashboard-s-tabs) | `/api/v1/dashboard/{id_or_slug}/tabs` | +| `GET` | [Get dashboard's tabs](/developer-docs/api/get-dashboards-tabs) | `/api/v1/dashboard/{id_or_slug}/tabs` | | `DELETE` | [Delete a dashboard](/developer-docs/api/delete-a-dashboard) | `/api/v1/dashboard/{pk}` | | `PUT` | [Update a dashboard](/developer-docs/api/update-a-dashboard) | `/api/v1/dashboard/{pk}` | | `POST` | [Compute and cache a screenshot (dashboard-pk-cache-dashboard-screenshot)](/developer-docs/api/compute-and-cache-a-screenshot-dashboard-pk-cache-dashboard-screenshot) | `/api/v1/dashboard/{pk}/cache_dashboard_screenshot/` | +| `PUT` | [Update chart customizations configuration for a dashboard.](/developer-docs/api/update-chart-customizations-configuration-for-a-dashboard) | `/api/v1/dashboard/{pk}/chart_customizations` | | `PUT` | [Update colors configuration for a dashboard.](/developer-docs/api/update-colors-configuration-for-a-dashboard) | `/api/v1/dashboard/{pk}/colors` | +| `GET` | [Export dashboard as example bundle](/developer-docs/api/export-dashboard-as-example-bundle) | `/api/v1/dashboard/{pk}/export_as_example/` | | `DELETE` | [Remove the dashboard from the user favorite list](/developer-docs/api/remove-the-dashboard-from-the-user-favorite-list) | `/api/v1/dashboard/{pk}/favorites/` | | `POST` | [Mark the dashboard as favorite for the current user](/developer-docs/api/mark-the-dashboard-as-favorite-for-the-current-user) | `/api/v1/dashboard/{pk}/favorites/` | | `PUT` | [Update native filters configuration for a dashboard.](/developer-docs/api/update-native-filters-configuration-for-a-dashboard) | `/api/v1/dashboard/{pk}/filters` | | `GET` | [Get a computed screenshot from cache (dashboard-pk-screenshot-digest)](/developer-docs/api/get-a-computed-screenshot-from-cache-dashboard-pk-screenshot-digest) | `/api/v1/dashboard/{pk}/screenshot/{digest}/` | -| `GET` | [Get dashboard's thumbnail](/developer-docs/api/get-dashboard-s-thumbnail) | `/api/v1/dashboard/{pk}/thumbnail/{digest}/` | +| `GET` | [Get dashboard's thumbnail](/developer-docs/api/get-dashboards-thumbnail) | `/api/v1/dashboard/{pk}/thumbnail/{digest}/` | | `GET` | [Download multiple dashboards as YAML files](/developer-docs/api/download-multiple-dashboards-as-yaml-files) | `/api/v1/dashboard/export/` | | `GET` | [Check favorited dashboards for current user](/developer-docs/api/check-favorited-dashboards-for-current-user) | `/api/v1/dashboard/favorite_status/` | | `POST` | [Import dashboard(s) with associated charts/datasets/databases](/developer-docs/api/import-dashboard-s-with-associated-charts-datasets-databases) | `/api/v1/dashboard/import/` | @@ -101,8 +103,8 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ | `GET` | [Get a list of charts](/developer-docs/api/get-a-list-of-charts) | `/api/v1/chart/` | | `POST` | [Create a new chart](/developer-docs/api/create-a-new-chart) | `/api/v1/chart/` | | `GET` | [Get metadata information about this API resource (chart--info)](/developer-docs/api/get-metadata-information-about-this-api-resource-chart-info) | `/api/v1/chart/_info` | +| `GET` | [Get a chart detail information](/developer-docs/api/get-a-chart-detail-information) | `/api/v1/chart/{id_or_uuid}` | | `DELETE` | [Delete a chart](/developer-docs/api/delete-a-chart) | `/api/v1/chart/{pk}` | -| `GET` | [Get a chart detail information](/developer-docs/api/get-a-chart-detail-information) | `/api/v1/chart/{pk}` | | `PUT` | [Update a chart](/developer-docs/api/update-a-chart) | `/api/v1/chart/{pk}` | | `GET` | [Compute and cache a screenshot (chart-pk-cache-screenshot)](/developer-docs/api/compute-and-cache-a-screenshot-chart-pk-cache-screenshot) | `/api/v1/chart/{pk}/cache_screenshot/` | | `GET` | [Return payload data response for a chart](/developer-docs/api/return-payload-data-response-for-a-chart) | `/api/v1/chart/{pk}/data/` | @@ -121,7 +123,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-Datasets (18 endpoints) — Manage datasets (tables) used for building charts. +Datasets (19 endpoints) — Manage datasets (tables) used for building charts. | Method | Endpoint | Description | |--------|----------|-------------| @@ -129,13 +131,14 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ | `GET` | [Get a list of datasets](/developer-docs/api/get-a-list-of-datasets) | `/api/v1/dataset/` | | `POST` | [Create a new dataset](/developer-docs/api/create-a-new-dataset) | `/api/v1/dataset/` | | `GET` | [Get metadata information about this API resource (dataset--info)](/developer-docs/api/get-metadata-information-about-this-api-resource-dataset-info) | `/api/v1/dataset/_info` | +| `GET` | [Get a dataset](/developer-docs/api/get-a-dataset) | `/api/v1/dataset/{id_or_uuid}` | +| `GET` | [Get charts and dashboards count associated to a dataset](/developer-docs/api/get-charts-and-dashboards-count-associated-to-a-dataset) | `/api/v1/dataset/{id_or_uuid}/related_objects` | | `DELETE` | [Delete a dataset](/developer-docs/api/delete-a-dataset) | `/api/v1/dataset/{pk}` | -| `GET` | [Get a dataset](/developer-docs/api/get-a-dataset) | `/api/v1/dataset/{pk}` | | `PUT` | [Update a dataset](/developer-docs/api/update-a-dataset) | `/api/v1/dataset/{pk}` | | `DELETE` | [Delete a dataset column](/developer-docs/api/delete-a-dataset-column) | `/api/v1/dataset/{pk}/column/{column_id}` | +| `GET` | [Get dataset drill info](/developer-docs/api/get-dataset-drill-info) | `/api/v1/dataset/{pk}/drill_info/` | | `DELETE` | [Delete a dataset metric](/developer-docs/api/delete-a-dataset-metric) | `/api/v1/dataset/{pk}/metric/{metric_id}` | | `PUT` | [Refresh and update columns of a dataset](/developer-docs/api/refresh-and-update-columns-of-a-dataset) | `/api/v1/dataset/{pk}/refresh` | -| `GET` | [Get charts and dashboards count associated to a dataset](/developer-docs/api/get-charts-and-dashboards-count-associated-to-a-dataset) | `/api/v1/dataset/{pk}/related_objects` | | `GET` | [Get distinct values from field data (dataset-distinct-column-name)](/developer-docs/api/get-distinct-values-from-field-data-dataset-distinct-column-name) | `/api/v1/dataset/distinct/{column_name}` | | `POST` | [Duplicate a dataset](/developer-docs/api/duplicate-a-dataset) | `/api/v1/dataset/duplicate` | | `GET` | [Download multiple datasets as YAML files](/developer-docs/api/download-multiple-datasets-as-yaml-files) | `/api/v1/dataset/export/` | @@ -147,7 +150,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-Database (31 endpoints) — Manage database connections and metadata. +Database (30 endpoints) — Manage database connections and metadata. | Method | Endpoint | Description | |--------|----------|-------------| @@ -165,7 +168,6 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ | `GET` | [Get all schemas from a database](/developer-docs/api/get-all-schemas-from-a-database) | `/api/v1/database/{pk}/schemas/` | | `GET` | [Get database select star for table (database-pk-select-star-table-name)](/developer-docs/api/get-database-select-star-for-table-database-pk-select-star-table-name) | `/api/v1/database/{pk}/select_star/{table_name}/` | | `GET` | [Get database select star for table (database-pk-select-star-table-name-schema-name)](/developer-docs/api/get-database-select-star-for-table-database-pk-select-star-table-name-schema-name) | `/api/v1/database/{pk}/select_star/{table_name}/{schema_name}/` | -| `DELETE` | [Delete a SSH tunnel](/developer-docs/api/delete-a-ssh-tunnel) | `/api/v1/database/{pk}/ssh_tunnel/` | | `POST` | [Re-sync all permissions for a database connection](/developer-docs/api/re-sync-all-permissions-for-a-database-connection) | `/api/v1/database/{pk}/sync_permissions/` | | `GET` | [Get table extra metadata (database-pk-table-extra-table-name-schema-name)](/developer-docs/api/get-table-extra-metadata-database-pk-table-extra-table-name-schema-name) | `/api/v1/database/{pk}/table_extra/{table_name}/{schema_name}/` | | `GET` | [Get table metadata](/developer-docs/api/get-table-metadata) | `/api/v1/database/{pk}/table_metadata/` | @@ -177,7 +179,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ | `GET` | [Get names of databases currently available](/developer-docs/api/get-names-of-databases-currently-available) | `/api/v1/database/available/` | | `GET` | [Download database(s) and associated dataset(s) as a zip file](/developer-docs/api/download-database-s-and-associated-dataset-s-as-a-zip-file) | `/api/v1/database/export/` | | `POST` | [Import database(s) with associated datasets](/developer-docs/api/import-database-s-with-associated-datasets) | `/api/v1/database/import/` | -| `GET` | [Receive personal access tokens from OAuth2](/developer-docs/api/receive-personal-access-tokens-from-oauth2) | `/api/v1/database/oauth2/` | +| `GET` | [Receive personal access tokens from OAuth2](/developer-docs/api/receive-personal-access-tokens-from-o-auth-2) | `/api/v1/database/oauth2/` | | `GET` | [Get related fields data (database-related-column-name)](/developer-docs/api/get-related-fields-data-database-related-column-name) | `/api/v1/database/related/{column_name}` | | `POST` | [Test a database connection](/developer-docs/api/test-a-database-connection) | `/api/v1/database/test_connection/` | | `POST` | [Upload a file and returns file metadata](/developer-docs/api/upload-a-file-and-returns-file-metadata) | `/api/v1/database/upload_metadata/` | @@ -197,13 +199,14 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-SQL Lab (6 endpoints) — Execute SQL queries and manage SQL Lab sessions. +SQL Lab (7 endpoints) — Execute SQL queries and manage SQL Lab sessions. | Method | Endpoint | Description | |--------|----------|-------------| -| `GET` | [Get the bootstrap data for SqlLab page](/developer-docs/api/get-the-bootstrap-data-for-sqllab-page) | `/api/v1/sqllab/` | +| `GET` | [Get the bootstrap data for SqlLab page](/developer-docs/api/get-the-bootstrap-data-for-sql-lab-page) | `/api/v1/sqllab/` | | `POST` | [Estimate the SQL query execution cost](/developer-docs/api/estimate-the-sql-query-execution-cost) | `/api/v1/sqllab/estimate/` | | `POST` | [Execute a SQL query](/developer-docs/api/execute-a-sql-query) | `/api/v1/sqllab/execute/` | +| `POST` | [Export SQL query results to CSV with streaming](/developer-docs/api/export-sql-query-results-to-csv-with-streaming) | `/api/v1/sqllab/export_streaming/` | | `GET` | [Export the SQL query results to a CSV](/developer-docs/api/export-the-sql-query-results-to-a-csv) | `/api/v1/sqllab/export/{client_id}/` | | `POST` | [Format SQL code](/developer-docs/api/format-sql-code) | `/api/v1/sqllab/format_sql/` | | `GET` | [Get the result of a SQL query execution](/developer-docs/api/get-the-result-of-a-sql-query-execution) | `/api/v1/sqllab/results/` | @@ -236,20 +239,21 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-Datasources (1 endpoints) — Query datasource metadata and column values. +Datasources (2 endpoints) — Query datasource metadata and column values. | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | [Get possible values for a datasource column](/developer-docs/api/get-possible-values-for-a-datasource-column) | `/api/v1/datasource/{datasource_type}/{datasource_id}/column/{column_name}/values/` | +| `POST` | [Validate a SQL expression against a datasource](/developer-docs/api/validate-a-sql-expression-against-a-datasource) | `/api/v1/datasource/{datasource_type}/{datasource_id}/validate_expression/` |
-Advanced Data Type (2 endpoints) — Endpoints for advanced data type operations and conversions. +Advanced Data Type (2 endpoints) — Advanced data type operations and conversions. | Method | Endpoint | Description | |--------|----------|-------------| -| `GET` | [Return an AdvancedDataTypeResponse](/developer-docs/api/return-an-advanceddatatyperesponse) | `/api/v1/advanced_data_type/convert` | +| `GET` | [Return an AdvancedDataTypeResponse](/developer-docs/api/return-an-advanced-data-type-response) | `/api/v1/advanced_data_type/convert` | | `GET` | [Return a list of available advanced data types](/developer-docs/api/return-a-list-of-available-advanced-data-types) | `/api/v1/advanced_data_type/types` |
@@ -320,32 +324,32 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ #### Sharing & Embedding
-Dashboard Permanent Link (2 endpoints) — Create and retrieve permanent links to dashboard states. +Dashboard Permanent Link (2 endpoints) — Permanent links to dashboard states. | Method | Endpoint | Description | |--------|----------|-------------| -| `POST` | [Create a new dashboard's permanent link](/developer-docs/api/create-a-new-dashboard-s-permanent-link) | `/api/v1/dashboard/{pk}/permalink` | -| `GET` | [Get dashboard's permanent link state](/developer-docs/api/get-dashboard-s-permanent-link-state) | `/api/v1/dashboard/permalink/{key}` | +| `POST` | [Create a new dashboard's permanent link](/developer-docs/api/create-a-new-dashboards-permanent-link) | `/api/v1/dashboard/{pk}/permalink` | +| `GET` | [Get dashboard's permanent link state](/developer-docs/api/get-dashboards-permanent-link-state) | `/api/v1/dashboard/permalink/{key}` |
-Explore Permanent Link (2 endpoints) — Create and retrieve permanent links to chart explore states. +Explore Permanent Link (2 endpoints) — Permanent links to chart explore states. | Method | Endpoint | Description | |--------|----------|-------------| | `POST` | [Create a new permanent link (explore-permalink)](/developer-docs/api/create-a-new-permanent-link-explore-permalink) | `/api/v1/explore/permalink` | -| `GET` | [Get chart's permanent link state](/developer-docs/api/get-chart-s-permanent-link-state) | `/api/v1/explore/permalink/{key}` | +| `GET` | [Get chart's permanent link state](/developer-docs/api/get-charts-permanent-link-state) | `/api/v1/explore/permalink/{key}` |
-SQL Lab Permanent Link (2 endpoints) — Create and retrieve permanent links to SQL Lab states. +SQL Lab Permanent Link (2 endpoints) — Permanent links to SQL Lab states. | Method | Endpoint | Description | |--------|----------|-------------| | `POST` | [Create a new permanent link (sqllab-permalink)](/developer-docs/api/create-a-new-permanent-link-sqllab-permalink) | `/api/v1/sqllab/permalink` | -| `GET` | [Get permanent link state for SQLLab editor.](/developer-docs/api/get-permanent-link-state-for-sqllab-editor) | `/api/v1/sqllab/permalink/{key}` | +| `GET` | [Get permanent link state for SQLLab editor.](/developer-docs/api/get-permanent-link-state-for-sql-lab-editor) | `/api/v1/sqllab/permalink/{key}` |
@@ -363,10 +367,10 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ | Method | Endpoint | Description | |--------|----------|-------------| -| `POST` | [Create a dashboard's filter state](/developer-docs/api/create-a-dashboard-s-filter-state) | `/api/v1/dashboard/{pk}/filter_state` | -| `DELETE` | [Delete a dashboard's filter state value](/developer-docs/api/delete-a-dashboard-s-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` | -| `GET` | [Get a dashboard's filter state value](/developer-docs/api/get-a-dashboard-s-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` | -| `PUT` | [Update a dashboard's filter state value](/developer-docs/api/update-a-dashboard-s-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` | +| `POST` | [Create a dashboard's filter state](/developer-docs/api/create-a-dashboards-filter-state) | `/api/v1/dashboard/{pk}/filter_state` | +| `DELETE` | [Delete a dashboard's filter state value](/developer-docs/api/delete-a-dashboards-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` | +| `GET` | [Get a dashboard's filter state value](/developer-docs/api/get-a-dashboards-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` | +| `PUT` | [Update a dashboard's filter state value](/developer-docs/api/update-a-dashboards-filter-state-value) | `/api/v1/dashboard/{pk}/filter_state/{key}` | @@ -406,16 +410,17 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ #### Security & Access Control
-Security Roles (10 endpoints) — Manage security roles and their permissions. +Security Roles (11 endpoints) — Manage security roles and their permissions. | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | [Get security roles](/developer-docs/api/get-security-roles) | `/api/v1/security/roles/` | | `POST` | [Create security roles](/developer-docs/api/create-security-roles) | `/api/v1/security/roles/` | -| `GET` | [Get security roles info](/developer-docs/api/get-security-roles-info) | `/api/v1/security/roles/_info` | +| `GET` | [Get security roles info](/developer-docs/api/get-security-roles-info) | `/api/v1/security/roles/_info` | | `DELETE` | [Delete security roles by pk](/developer-docs/api/delete-security-roles-by-pk) | `/api/v1/security/roles/{pk}` | | `GET` | [Get security roles by pk](/developer-docs/api/get-security-roles-by-pk) | `/api/v1/security/roles/{pk}` | | `PUT` | [Update security roles by pk](/developer-docs/api/update-security-roles-by-pk) | `/api/v1/security/roles/{pk}` | +| `PUT` | [Update security roles by role_id groups](/developer-docs/api/update-security-roles-by-role-id-groups) | `/api/v1/security/roles/{role_id}/groups` | | `POST` | [Create security roles by role_id permissions](/developer-docs/api/create-security-roles-by-role-id-permissions) | `/api/v1/security/roles/{role_id}/permissions` | | `GET` | [Get security roles by role_id permissions](/developer-docs/api/get-security-roles-by-role-id-permissions) | `/api/v1/security/roles/{role_id}/permissions/` | | `PUT` | [Update security roles by role_id users](/developer-docs/api/update-security-roles-by-role-id-users) | `/api/v1/security/roles/{role_id}/users` | @@ -430,7 +435,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ |--------|----------|-------------| | `GET` | [Get security users](/developer-docs/api/get-security-users) | `/api/v1/security/users/` | | `POST` | [Create security users](/developer-docs/api/create-security-users) | `/api/v1/security/users/` | -| `GET` | [Get security users info](/developer-docs/api/get-security-users-info) | `/api/v1/security/users/_info` | +| `GET` | [Get security users info](/developer-docs/api/get-security-users-info) | `/api/v1/security/users/_info` | | `DELETE` | [Delete security users by pk](/developer-docs/api/delete-security-users-by-pk) | `/api/v1/security/users/{pk}` | | `GET` | [Get security users by pk](/developer-docs/api/get-security-users-by-pk) | `/api/v1/security/users/{pk}` | | `PUT` | [Update security users by pk](/developer-docs/api/update-security-users-by-pk) | `/api/v1/security/users/{pk}` | @@ -443,7 +448,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | [Get security permissions](/developer-docs/api/get-security-permissions) | `/api/v1/security/permissions/` | -| `GET` | [Get security permissions info](/developer-docs/api/get-security-permissions-info) | `/api/v1/security/permissions/_info` | +| `GET` | [Get security permissions info](/developer-docs/api/get-security-permissions-info) | `/api/v1/security/permissions/_info` | | `GET` | [Get security permissions by pk](/developer-docs/api/get-security-permissions-by-pk) | `/api/v1/security/permissions/{pk}` |
@@ -455,7 +460,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ |--------|----------|-------------| | `GET` | [Get security resources](/developer-docs/api/get-security-resources) | `/api/v1/security/resources/` | | `POST` | [Create security resources](/developer-docs/api/create-security-resources) | `/api/v1/security/resources/` | -| `GET` | [Get security resources info](/developer-docs/api/get-security-resources-info) | `/api/v1/security/resources/_info` | +| `GET` | [Get security resources info](/developer-docs/api/get-security-resources-info) | `/api/v1/security/resources/_info` | | `DELETE` | [Delete security resources by pk](/developer-docs/api/delete-security-resources-by-pk) | `/api/v1/security/resources/{pk}` | | `GET` | [Get security resources by pk](/developer-docs/api/get-security-resources-by-pk) | `/api/v1/security/resources/{pk}` | | `PUT` | [Update security resources by pk](/developer-docs/api/update-security-resources-by-pk) | `/api/v1/security/resources/{pk}` | @@ -463,13 +468,13 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-Security Permissions on Resources (View Menus) (6 endpoints) — Manage permission-resource mappings. +Security Permissions on Resources (View Menus) (6 endpoints) — Permission-resource mappings. | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | [Get security permissions resources](/developer-docs/api/get-security-permissions-resources) | `/api/v1/security/permissions-resources/` | | `POST` | [Create security permissions resources](/developer-docs/api/create-security-permissions-resources) | `/api/v1/security/permissions-resources/` | -| `GET` | [Get security permissions resources info](/developer-docs/api/get-security-permissions-resources-info) | `/api/v1/security/permissions-resources/_info` | +| `GET` | [Get security permissions resources info](/developer-docs/api/get-security-permissions-resources-info) | `/api/v1/security/permissions-resources/_info` | | `DELETE` | [Delete security permissions resources by pk](/developer-docs/api/delete-security-permissions-resources-by-pk) | `/api/v1/security/permissions-resources/{pk}` | | `GET` | [Get security permissions resources by pk](/developer-docs/api/get-security-permissions-resources-by-pk) | `/api/v1/security/permissions-resources/{pk}` | | `PUT` | [Update security permissions resources by pk](/developer-docs/api/update-security-permissions-resources-by-pk) | `/api/v1/security/permissions-resources/{pk}` | @@ -477,7 +482,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-Row Level Security (8 endpoints) — Manage row-level security rules for data access control. +Row Level Security (8 endpoints) — Manage row-level security rules for data access. | Method | Endpoint | Description | |--------|----------|-------------| @@ -495,7 +500,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ #### Import/Export & Administration
-Import/export (2 endpoints) — Import and export Superset assets (dashboards, charts, databases). +Import/export (2 endpoints) — Import and export Superset assets. | Method | Endpoint | Description | |--------|----------|-------------| @@ -528,11 +533,12 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ #### User & System
-Current User (2 endpoints) — Get information about the currently authenticated user. +Current User (3 endpoints) — Get information about the authenticated user. | Method | Endpoint | Description | |--------|----------|-------------| | `GET` | [Get the user object](/developer-docs/api/get-the-user-object) | `/api/v1/me/` | +| `PUT` | [Update the current user](/developer-docs/api/update-the-current-user) | `/api/v1/me/` | | `GET` | [Get the user roles](/developer-docs/api/get-the-user-roles) | `/api/v1/me/roles/` |
@@ -578,7 +584,23 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ | Method | Endpoint | Description | |--------|----------|-------------| -| `GET` | [Get api by version openapi](/developer-docs/api/get-api-by-version-openapi) | `/api/{version}/_openapi` | +| `GET` | [Get api by version openapi](/developer-docs/api/get-api-by-version-openapi) | `/api/{version}/_openapi` | + +
+ +#### Other + +
+Security Groups (6 endpoints) — Endpoints related to Security Groups. + +| Method | Endpoint | Description | +|--------|----------|-------------| +| `GET` | [Get security groups](/developer-docs/api/get-security-groups) | `/api/v1/security/groups/` | +| `POST` | [Create security groups](/developer-docs/api/create-security-groups) | `/api/v1/security/groups/` | +| `GET` | [Get security groups info](/developer-docs/api/get-security-groups-info) | `/api/v1/security/groups/_info` | +| `DELETE` | [Delete security groups by pk](/developer-docs/api/delete-security-groups-by-pk) | `/api/v1/security/groups/{pk}` | +| `GET` | [Get security groups by pk](/developer-docs/api/get-security-groups-by-pk) | `/api/v1/security/groups/{pk}` | +| `PUT` | [Update security groups by pk](/developer-docs/api/update-security-groups-by-pk) | `/api/v1/security/groups/{pk}` |
@@ -590,7 +612,7 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ | `DELETE` | [Bulk delete themes](/developer-docs/api/bulk-delete-themes) | `/api/v1/theme/` | | `GET` | [Get a list of themes](/developer-docs/api/get-a-list-of-themes) | `/api/v1/theme/` | | `POST` | [Create a theme](/developer-docs/api/create-a-theme) | `/api/v1/theme/` | -| `GET` | [Get metadata information about this API resource (theme-info)](/developer-docs/api/get-metadata-information-about-this-api-resource-theme-info) | `/api/v1/theme/_info` | +| `GET` | [Get metadata information about this API resource (theme--info)](/developer-docs/api/get-metadata-information-about-this-api-resource-theme-info) | `/api/v1/theme/_info` | | `DELETE` | [Delete a theme](/developer-docs/api/delete-a-theme) | `/api/v1/theme/{pk}` | | `GET` | [Get a theme](/developer-docs/api/get-a-theme) | `/api/v1/theme/{pk}` | | `PUT` | [Update a theme](/developer-docs/api/update-a-theme) | `/api/v1/theme/{pk}` | @@ -604,6 +626,22 @@ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
+
+UserRegistrationsRestAPI (8 endpoints) — Endpoints related to UserRegistrationsRestAPI. + +| Method | Endpoint | Description | +|--------|----------|-------------| +| `GET` | [Get security user registrations](/developer-docs/api/get-security-user-registrations) | `/api/v1/security/user_registrations/` | +| `POST` | [Create security user registrations](/developer-docs/api/create-security-user-registrations) | `/api/v1/security/user_registrations/` | +| `GET` | [Get security user registrations info](/developer-docs/api/get-security-user-registrations-info) | `/api/v1/security/user_registrations/_info` | +| `DELETE` | [Delete security user registrations by pk](/developer-docs/api/delete-security-user-registrations-by-pk) | `/api/v1/security/user_registrations/{pk}` | +| `GET` | [Get security user registrations by pk](/developer-docs/api/get-security-user-registrations-by-pk) | `/api/v1/security/user_registrations/{pk}` | +| `PUT` | [Update security user registrations by pk](/developer-docs/api/update-security-user-registrations-by-pk) | `/api/v1/security/user_registrations/{pk}` | +| `GET` | [Get distinct values from field data (security-user-registrations-distinct-column-name)](/developer-docs/api/get-distinct-values-from-field-data-security-user-registrations-distinct-column-name) | `/api/v1/security/user_registrations/distinct/{column_name}` | +| `GET` | [Get related fields data (security-user-registrations-related-column-name)](/developer-docs/api/get-related-fields-data-security-user-registrations-related-column-name) | `/api/v1/security/user_registrations/related/{column_name}` | + +
+ --- ### Additional Resources diff --git a/docs/developer_docs/components/design-system/dropdowncontainer.mdx b/docs/developer_docs/components/design-system/dropdowncontainer.mdx index 205a209a5fd..1d6b5e20772 100644 --- a/docs/developer_docs/components/design-system/dropdowncontainer.mdx +++ b/docs/developer_docs/components/design-system/dropdowncontainer.mdx @@ -156,7 +156,7 @@ function SelectFilters() { ## Import ```tsx -import { DropdownContainer } from '@superset/components'; +import { DropdownContainer } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/design-system/flex.mdx b/docs/developer_docs/components/design-system/flex.mdx index 6b6d674a859..b74f06c7f4e 100644 --- a/docs/developer_docs/components/design-system/flex.mdx +++ b/docs/developer_docs/components/design-system/flex.mdx @@ -186,7 +186,7 @@ function JustifyAlign() { ## Import ```tsx -import { Flex } from '@superset/components'; +import { Flex } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/design-system/grid.mdx b/docs/developer_docs/components/design-system/grid.mdx index 6400917f88c..a7fea3d3dc1 100644 --- a/docs/developer_docs/components/design-system/grid.mdx +++ b/docs/developer_docs/components/design-system/grid.mdx @@ -181,7 +181,7 @@ function AlignmentDemo() { ## Import ```tsx -import Grid from '@superset/components'; +import { Grid } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/design-system/layout.mdx b/docs/developer_docs/components/design-system/layout.mdx index 9fe934308a5..1b0d76e0ad1 100644 --- a/docs/developer_docs/components/design-system/layout.mdx +++ b/docs/developer_docs/components/design-system/layout.mdx @@ -128,7 +128,7 @@ function RightSidebar() { ## Import ```tsx -import { Layout } from '@superset/components'; +import { Layout } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/design-system/metadatabar.mdx b/docs/developer_docs/components/design-system/metadatabar.mdx index a8064c23a91..2f667cfae4e 100644 --- a/docs/developer_docs/components/design-system/metadatabar.mdx +++ b/docs/developer_docs/components/design-system/metadatabar.mdx @@ -163,7 +163,7 @@ function FullMetadata() { ## Import ```tsx -import MetadataBar from '@superset/components'; +import { MetadataBar } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/design-system/space.mdx b/docs/developer_docs/components/design-system/space.mdx index cbbef161fbf..264667a9fb0 100644 --- a/docs/developer_docs/components/design-system/space.mdx +++ b/docs/developer_docs/components/design-system/space.mdx @@ -157,7 +157,7 @@ function SpaceSizes() { ## Import ```tsx -import { Space } from '@superset/components'; +import { Space } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/design-system/table.mdx b/docs/developer_docs/components/design-system/table.mdx index 16451533f44..db0be495173 100644 --- a/docs/developer_docs/components/design-system/table.mdx +++ b/docs/developer_docs/components/design-system/table.mdx @@ -300,7 +300,7 @@ function LoadingTable() { ## Import ```tsx -import { Table } from '@superset/components'; +import { Table } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/index.mdx b/docs/developer_docs/components/index.mdx index 26cf64e1cdc..270e24163c4 100644 --- a/docs/developer_docs/components/index.mdx +++ b/docs/developer_docs/components/index.mdx @@ -23,7 +23,16 @@ sidebar_position: 0 under the License. --> -# Superset Design System +import { ComponentIndex } from '@site/src/components/ui-components'; +import componentData from '@site/static/data/components.json'; + +# UI Components + + + +--- + +## Design System A design system is a complete set of standards intended to manage design at scale using reusable components and patterns. @@ -35,19 +44,6 @@ The Superset Design System uses [Atomic Design](https://bradfrost.com/blog/post/ Atoms = Foundations, Molecules = Components, Organisms = Patterns, Templates = Templates, Pages / Screens = Features ---- - -## Component Library - -Interactive documentation for Superset's UI component library. **53 components** documented across 2 categories. - -### [Core Components](./ui/) -46 components — Buttons, inputs, modals, selects, and other fundamental UI elements. - -### [Layout Components](./design-system/) -7 components — Grid, Layout, Table, Flex, Space, and container components for page structure. - - ## Usage All components are exported from `@superset-ui/core/components`: diff --git a/docs/developer_docs/components/ui/autocomplete.mdx b/docs/developer_docs/components/ui/autocomplete.mdx index e0d721a7b9a..789883dbb4c 100644 --- a/docs/developer_docs/components/ui/autocomplete.mdx +++ b/docs/developer_docs/components/ui/autocomplete.mdx @@ -204,7 +204,7 @@ function Demo() { ## Import ```tsx -import { AutoComplete } from '@superset/components'; +import { AutoComplete } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/avatar.mdx b/docs/developer_docs/components/ui/avatar.mdx index 96c438d3721..b2b7458cd4b 100644 --- a/docs/developer_docs/components/ui/avatar.mdx +++ b/docs/developer_docs/components/ui/avatar.mdx @@ -129,7 +129,7 @@ function Demo() { ## Import ```tsx -import { Avatar } from '@superset/components'; +import { Avatar } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/badge.mdx b/docs/developer_docs/components/ui/badge.mdx index 5381fb76fb3..69531a428b1 100644 --- a/docs/developer_docs/components/ui/badge.mdx +++ b/docs/developer_docs/components/ui/badge.mdx @@ -149,7 +149,7 @@ function ColorGallery() { ## Import ```tsx -import { Badge } from '@superset/components'; +import { Badge } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/breadcrumb.mdx b/docs/developer_docs/components/ui/breadcrumb.mdx index 60081b937cf..5591b2e089f 100644 --- a/docs/developer_docs/components/ui/breadcrumb.mdx +++ b/docs/developer_docs/components/ui/breadcrumb.mdx @@ -82,7 +82,7 @@ function Demo() { ## Import ```tsx -import { Breadcrumb } from '@superset/components'; +import { Breadcrumb } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/button.mdx b/docs/developer_docs/components/ui/button.mdx index d36acbbf680..0b704f4b666 100644 --- a/docs/developer_docs/components/ui/button.mdx +++ b/docs/developer_docs/components/ui/button.mdx @@ -43,7 +43,7 @@ The Button component from Superset's UI library. Button! @@ -124,14 +124,14 @@ function Demo() { | Prop | Type | Default | Description | |------|------|---------|-------------| -| `buttonStyle` | `string` | `"default"` | The style variant of the button. | +| `buttonStyle` | `string` | `"primary"` | The style variant of the button. | | `buttonSize` | `string` | `"default"` | The size of the button. | | `children` | `string` | `"Button!"` | The button text or content. | ## Import ```tsx -import { Button } from '@superset/components'; +import { Button } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/buttongroup.mdx b/docs/developer_docs/components/ui/buttongroup.mdx index 6f35bea6159..233993c4d19 100644 --- a/docs/developer_docs/components/ui/buttongroup.mdx +++ b/docs/developer_docs/components/ui/buttongroup.mdx @@ -77,7 +77,7 @@ function Demo() { ## Import ```tsx -import { ButtonGroup } from '@superset/components'; +import { ButtonGroup } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/cachedlabel.mdx b/docs/developer_docs/components/ui/cachedlabel.mdx index 65a83d5a7c7..7f115914456 100644 --- a/docs/developer_docs/components/ui/cachedlabel.mdx +++ b/docs/developer_docs/components/ui/cachedlabel.mdx @@ -68,7 +68,7 @@ function Demo() { ## Import ```tsx -import { CachedLabel } from '@superset/components'; +import { CachedLabel } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/card.mdx b/docs/developer_docs/components/ui/card.mdx index 989706ed940..50bf93dbf6e 100644 --- a/docs/developer_docs/components/ui/card.mdx +++ b/docs/developer_docs/components/ui/card.mdx @@ -131,7 +131,7 @@ function CardStates() { ## Import ```tsx -import { Card } from '@superset/components'; +import { Card } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/checkbox.mdx b/docs/developer_docs/components/ui/checkbox.mdx index a7b76e5b5ca..13709c36130 100644 --- a/docs/developer_docs/components/ui/checkbox.mdx +++ b/docs/developer_docs/components/ui/checkbox.mdx @@ -130,7 +130,7 @@ function SelectAllDemo() { ## Import ```tsx -import { Checkbox } from '@superset/components'; +import { Checkbox } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/collapse.mdx b/docs/developer_docs/components/ui/collapse.mdx index 1bfef9f2868..4e35c7b4353 100644 --- a/docs/developer_docs/components/ui/collapse.mdx +++ b/docs/developer_docs/components/ui/collapse.mdx @@ -95,7 +95,7 @@ function Demo() { ## Import ```tsx -import { Collapse } from '@superset/components'; +import { Collapse } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/datepicker.mdx b/docs/developer_docs/components/ui/datepicker.mdx index 0daebc8058a..4fc45cb6ecb 100644 --- a/docs/developer_docs/components/ui/datepicker.mdx +++ b/docs/developer_docs/components/ui/datepicker.mdx @@ -99,7 +99,7 @@ function Demo() { ## Import ```tsx -import { DatePicker } from '@superset/components'; +import { DatePicker } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/divider.mdx b/docs/developer_docs/components/ui/divider.mdx index 73bf9aa5b3f..0ea8c54bb6e 100644 --- a/docs/developer_docs/components/ui/divider.mdx +++ b/docs/developer_docs/components/ui/divider.mdx @@ -133,7 +133,7 @@ function Demo() { ## Import ```tsx -import { Divider } from '@superset/components'; +import { Divider } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/editabletitle.mdx b/docs/developer_docs/components/ui/editabletitle.mdx index d5e3e2a20c5..bea676b0401 100644 --- a/docs/developer_docs/components/ui/editabletitle.mdx +++ b/docs/developer_docs/components/ui/editabletitle.mdx @@ -161,7 +161,7 @@ function Demo() { ## Import ```tsx -import { EditableTitle } from '@superset/components'; +import { EditableTitle } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/emptystate.mdx b/docs/developer_docs/components/ui/emptystate.mdx index aeb7938f311..b0e8171c16d 100644 --- a/docs/developer_docs/components/ui/emptystate.mdx +++ b/docs/developer_docs/components/ui/emptystate.mdx @@ -136,7 +136,7 @@ function Demo() { ## Import ```tsx -import { EmptyState } from '@superset/components'; +import { EmptyState } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/favestar.mdx b/docs/developer_docs/components/ui/favestar.mdx index 263659ac4a6..adb610620d8 100644 --- a/docs/developer_docs/components/ui/favestar.mdx +++ b/docs/developer_docs/components/ui/favestar.mdx @@ -85,7 +85,7 @@ function Demo() { ## Import ```tsx -import { FaveStar } from '@superset/components'; +import { FaveStar } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/iconbutton.mdx b/docs/developer_docs/components/ui/iconbutton.mdx index 387b937e2e7..5cfc6e90f55 100644 --- a/docs/developer_docs/components/ui/iconbutton.mdx +++ b/docs/developer_docs/components/ui/iconbutton.mdx @@ -95,7 +95,7 @@ function Demo() { ## Import ```tsx -import { IconButton } from '@superset/components'; +import { IconButton } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/icons.mdx b/docs/developer_docs/components/ui/icons.mdx index 97b0b023862..ac90f06c7e7 100644 --- a/docs/developer_docs/components/ui/icons.mdx +++ b/docs/developer_docs/components/ui/icons.mdx @@ -241,7 +241,7 @@ function IconWithText() { ## Import ```tsx -import { Icons } from '@superset/components'; +import { Icons } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/icontooltip.mdx b/docs/developer_docs/components/ui/icontooltip.mdx index df7e0445e94..4d1fdde8699 100644 --- a/docs/developer_docs/components/ui/icontooltip.mdx +++ b/docs/developer_docs/components/ui/icontooltip.mdx @@ -89,7 +89,7 @@ function Demo() { ## Import ```tsx -import { IconTooltip } from '@superset/components'; +import { IconTooltip } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/infotooltip.mdx b/docs/developer_docs/components/ui/infotooltip.mdx index 28d0514bdc9..42e6341ea90 100644 --- a/docs/developer_docs/components/ui/infotooltip.mdx +++ b/docs/developer_docs/components/ui/infotooltip.mdx @@ -95,7 +95,7 @@ function Demo() { ## Import ```tsx -import { InfoTooltip } from '@superset/components'; +import { InfoTooltip } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/input.mdx b/docs/developer_docs/components/ui/input.mdx index 1fa8fd59073..2bc8706fe63 100644 --- a/docs/developer_docs/components/ui/input.mdx +++ b/docs/developer_docs/components/ui/input.mdx @@ -151,7 +151,7 @@ function Demo() { ## Import ```tsx -import { Input } from '@superset/components'; +import { Input } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/label.mdx b/docs/developer_docs/components/ui/label.mdx index a0c8ee6bd48..816d449770f 100644 --- a/docs/developer_docs/components/ui/label.mdx +++ b/docs/developer_docs/components/ui/label.mdx @@ -94,7 +94,7 @@ function Demo() { ## Import ```tsx -import { Label } from '@superset/components'; +import { Label } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/list.mdx b/docs/developer_docs/components/ui/list.mdx index 3ff0c30cd2d..06a3b028965 100644 --- a/docs/developer_docs/components/ui/list.mdx +++ b/docs/developer_docs/components/ui/list.mdx @@ -106,7 +106,7 @@ function Demo() { ## Import ```tsx -import { List } from '@superset/components'; +import { List } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/listviewcard.mdx b/docs/developer_docs/components/ui/listviewcard.mdx index 4d2ea55d81b..63af1c14f34 100644 --- a/docs/developer_docs/components/ui/listviewcard.mdx +++ b/docs/developer_docs/components/ui/listviewcard.mdx @@ -121,7 +121,7 @@ function Demo() { ## Import ```tsx -import { ListViewCard } from '@superset/components'; +import { ListViewCard } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/loading.mdx b/docs/developer_docs/components/ui/loading.mdx index 4033746d776..0326c19e90a 100644 --- a/docs/developer_docs/components/ui/loading.mdx +++ b/docs/developer_docs/components/ui/loading.mdx @@ -176,7 +176,7 @@ function ContextualDemo() { ## Import ```tsx -import { Loading } from '@superset/components'; +import { Loading } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/menu.mdx b/docs/developer_docs/components/ui/menu.mdx index 7dd4baac68d..c088eb538c7 100644 --- a/docs/developer_docs/components/ui/menu.mdx +++ b/docs/developer_docs/components/ui/menu.mdx @@ -163,7 +163,7 @@ function MenuWithIcons() { ## Import ```tsx -import { Menu } from '@superset/components'; +import { Menu } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/modal.mdx b/docs/developer_docs/components/ui/modal.mdx index 67a984dabb2..d1ed9b48234 100644 --- a/docs/developer_docs/components/ui/modal.mdx +++ b/docs/developer_docs/components/ui/modal.mdx @@ -196,7 +196,7 @@ function ConfirmationDialogs() { ## Import ```tsx -import { Modal } from '@superset/components'; +import { Modal } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/modaltrigger.mdx b/docs/developer_docs/components/ui/modaltrigger.mdx index 1c3eddd84fc..b9f5bd81b7d 100644 --- a/docs/developer_docs/components/ui/modaltrigger.mdx +++ b/docs/developer_docs/components/ui/modaltrigger.mdx @@ -181,7 +181,7 @@ function DraggableModal() { ## Import ```tsx -import { ModalTrigger } from '@superset/components'; +import { ModalTrigger } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/popover.mdx b/docs/developer_docs/components/ui/popover.mdx index 12f04d65700..0a3ad4b2d10 100644 --- a/docs/developer_docs/components/ui/popover.mdx +++ b/docs/developer_docs/components/ui/popover.mdx @@ -188,7 +188,7 @@ function RichPopover() { ## Import ```tsx -import { Popover } from '@superset/components'; +import { Popover } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/progressbar.mdx b/docs/developer_docs/components/ui/progressbar.mdx index 7bfd4d17491..4b68653ee11 100644 --- a/docs/developer_docs/components/ui/progressbar.mdx +++ b/docs/developer_docs/components/ui/progressbar.mdx @@ -195,7 +195,7 @@ function CustomColors() { ## Import ```tsx -import { ProgressBar } from '@superset/components'; +import { ProgressBar } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/radio.mdx b/docs/developer_docs/components/ui/radio.mdx index ee5c2a67bf7..69cdfcf2c06 100644 --- a/docs/developer_docs/components/ui/radio.mdx +++ b/docs/developer_docs/components/ui/radio.mdx @@ -126,7 +126,7 @@ function VerticalDemo() { ## Import ```tsx -import { Radio } from '@superset/components'; +import { Radio } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/safemarkdown.mdx b/docs/developer_docs/components/ui/safemarkdown.mdx index ab41307b235..8cb741b962c 100644 --- a/docs/developer_docs/components/ui/safemarkdown.mdx +++ b/docs/developer_docs/components/ui/safemarkdown.mdx @@ -74,7 +74,7 @@ function Demo() { ## Import ```tsx -import { SafeMarkdown } from '@superset/components'; +import { SafeMarkdown } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/select.mdx b/docs/developer_docs/components/ui/select.mdx index f84be6b30b0..262196d4ccc 100644 --- a/docs/developer_docs/components/ui/select.mdx +++ b/docs/developer_docs/components/ui/select.mdx @@ -297,7 +297,7 @@ function OneLineDemo() { ## Import ```tsx -import { Select } from '@superset/components'; +import { Select } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/skeleton.mdx b/docs/developer_docs/components/ui/skeleton.mdx index 71ea44a41d9..c4c0190babe 100644 --- a/docs/developer_docs/components/ui/skeleton.mdx +++ b/docs/developer_docs/components/ui/skeleton.mdx @@ -129,7 +129,7 @@ function Demo() { ## Import ```tsx -import { Skeleton } from '@superset/components'; +import { Skeleton } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/slider.mdx b/docs/developer_docs/components/ui/slider.mdx index bbcbbbffc4a..3edeeda4aa2 100644 --- a/docs/developer_docs/components/ui/slider.mdx +++ b/docs/developer_docs/components/ui/slider.mdx @@ -242,7 +242,7 @@ function VerticalDemo() { ## Import ```tsx -import { Slider } from '@superset/components'; +import { Slider } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/steps.mdx b/docs/developer_docs/components/ui/steps.mdx index bf76e0681c9..7d905a54131 100644 --- a/docs/developer_docs/components/ui/steps.mdx +++ b/docs/developer_docs/components/ui/steps.mdx @@ -261,7 +261,7 @@ function DotAndSmall() { ## Import ```tsx -import { Steps } from '@superset/components'; +import { Steps } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/switch.mdx b/docs/developer_docs/components/ui/switch.mdx index dc87c617f46..e0408c9b9d8 100644 --- a/docs/developer_docs/components/ui/switch.mdx +++ b/docs/developer_docs/components/ui/switch.mdx @@ -182,7 +182,7 @@ function SettingsPanel() { ## Import ```tsx -import { Switch } from '@superset/components'; +import { Switch } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/tablecollection.mdx b/docs/developer_docs/components/ui/tablecollection.mdx index 83d7ca23933..049a9cebeca 100644 --- a/docs/developer_docs/components/ui/tablecollection.mdx +++ b/docs/developer_docs/components/ui/tablecollection.mdx @@ -52,12 +52,6 @@ function Demo() { -## Import - -```tsx -import { TableCollection } from '@superset/components'; -``` - --- :::tip[Improve this page] diff --git a/docs/developer_docs/components/ui/tableview.mdx b/docs/developer_docs/components/ui/tableview.mdx index 6904495d91f..b560e0b0249 100644 --- a/docs/developer_docs/components/ui/tableview.mdx +++ b/docs/developer_docs/components/ui/tableview.mdx @@ -283,7 +283,7 @@ function SortingDemo() { ## Import ```tsx -import { TableView } from '@superset/components'; +import { TableView } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/tabs.mdx b/docs/developer_docs/components/ui/tabs.mdx index aa31a094801..895aa63282b 100644 --- a/docs/developer_docs/components/ui/tabs.mdx +++ b/docs/developer_docs/components/ui/tabs.mdx @@ -212,7 +212,7 @@ function IconTabs() { ## Import ```tsx -import { Tabs } from '@superset/components'; +import { Tabs } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/timer.mdx b/docs/developer_docs/components/ui/timer.mdx index 1f8123cf60a..2562205e872 100644 --- a/docs/developer_docs/components/ui/timer.mdx +++ b/docs/developer_docs/components/ui/timer.mdx @@ -161,7 +161,7 @@ function StartStop() { ## Import ```tsx -import { Timer } from '@superset/components'; +import { Timer } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/tooltip.mdx b/docs/developer_docs/components/ui/tooltip.mdx index 6c958d2baa2..72620d7c0cf 100644 --- a/docs/developer_docs/components/ui/tooltip.mdx +++ b/docs/developer_docs/components/ui/tooltip.mdx @@ -160,7 +160,7 @@ function Triggers() { ## Import ```tsx -import { Tooltip } from '@superset/components'; +import { Tooltip } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/tree.mdx b/docs/developer_docs/components/ui/tree.mdx index 6ea5caf46a8..70bfbb173bd 100644 --- a/docs/developer_docs/components/ui/tree.mdx +++ b/docs/developer_docs/components/ui/tree.mdx @@ -257,7 +257,7 @@ function LinesAndIcons() { ## Import ```tsx -import { Tree } from '@superset/components'; +import { Tree } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/treeselect.mdx b/docs/developer_docs/components/ui/treeselect.mdx index e9c0e5583ab..9bdb8b61a2f 100644 --- a/docs/developer_docs/components/ui/treeselect.mdx +++ b/docs/developer_docs/components/ui/treeselect.mdx @@ -275,7 +275,7 @@ function TreeLinesDemo() { ## Import ```tsx -import { TreeSelect } from '@superset/components'; +import { TreeSelect } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/typography.mdx b/docs/developer_docs/components/ui/typography.mdx index 56e7ecbf559..5b441405972 100644 --- a/docs/developer_docs/components/ui/typography.mdx +++ b/docs/developer_docs/components/ui/typography.mdx @@ -225,7 +225,7 @@ function TextStyles() { ## Import ```tsx -import { Typography } from '@superset/components'; +import { Typography } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/unsavedchangesmodal.mdx b/docs/developer_docs/components/ui/unsavedchangesmodal.mdx index 8c7b855a8fd..5a4ba17618f 100644 --- a/docs/developer_docs/components/ui/unsavedchangesmodal.mdx +++ b/docs/developer_docs/components/ui/unsavedchangesmodal.mdx @@ -115,7 +115,7 @@ function CustomTitle() { ## Import ```tsx -import { UnsavedChangesModal } from '@superset/components'; +import { UnsavedChangesModal } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/components/ui/upload.mdx b/docs/developer_docs/components/ui/upload.mdx index d41d2ed2e28..2499f342c6c 100644 --- a/docs/developer_docs/components/ui/upload.mdx +++ b/docs/developer_docs/components/ui/upload.mdx @@ -125,7 +125,7 @@ function DragDrop() { ## Import ```tsx -import { Upload } from '@superset/components'; +import { Upload } from '@superset-ui/core/components'; ``` --- diff --git a/docs/developer_docs/contributing/development-setup.md b/docs/developer_docs/contributing/development-setup.md index dc1e9c4ed17..07d07eebb2b 100644 --- a/docs/developer_docs/contributing/development-setup.md +++ b/docs/developer_docs/contributing/development-setup.md @@ -485,7 +485,7 @@ Frontend assets (TypeScript, JavaScript, CSS, and images) must be compiled in or First, be sure you are using the following versions of Node.js and npm: -- `Node.js`: Version 20 +- `Node.js`: Version 22 (LTS) - `npm`: Version 10 We recommend using [nvm](https://github.com/nvm-sh/nvm) to manage your node environment: diff --git a/docs/developer_docs/extensions/contribution-types.md b/docs/developer_docs/extensions/contribution-types.md index 6fa8bf7f9a5..6e66aa8a67c 100644 --- a/docs/developer_docs/extensions/contribution-types.md +++ b/docs/developer_docs/extensions/contribution-types.md @@ -224,3 +224,52 @@ async def analysis_guide(ctx: Context) -> str: ``` See [MCP Integration](./mcp) for implementation details. + +### Semantic Layers + +Extensions can register custom semantic layer implementations that allow Superset to connect to external data modeling frameworks. Each semantic layer defines how to authenticate, discover semantic views (tables/metrics/dimensions), and execute queries against the external system. + +```python +from superset_core.semantic_layers.decorators import semantic_layer +from superset_core.semantic_layers.layer import SemanticLayer + +from my_extension.config import MyConfig +from my_extension.view import MySemanticView + + +@semantic_layer( + id="my_platform", + name="My Data Platform", + description="Connect to My Data Platform's semantic layer", +) +class MySemanticLayer(SemanticLayer[MyConfig, MySemanticView]): + configuration_class = MyConfig + + @classmethod + def from_configuration(cls, configuration: dict) -> "MySemanticLayer": + config = MyConfig.model_validate(configuration) + return cls(config) + + @classmethod + def get_configuration_schema(cls, configuration=None) -> dict: + return MyConfig.model_json_schema() + + @classmethod + def get_runtime_schema(cls, configuration=None, runtime_data=None) -> dict: + return {"type": "object", "properties": {}} + + def get_semantic_views(self, runtime_configuration: dict) -> set[MySemanticView]: + # Return available views from the external platform + ... + + def get_semantic_view(self, name: str, additional_configuration: dict) -> MySemanticView: + # Return a specific view by name + ... +``` + +**Note**: The `@semantic_layer` decorator automatically detects context and applies appropriate ID prefixing: + +- **Extension context**: ID prefixed as `extensions.{publisher}.{name}.{id}` +- **Host context**: Original ID used as-is + +The decorator registers the class in the semantic layers registry, making it available in the UI for users to create connections. The `configuration_class` should be a Pydantic model that defines the fields needed to connect (credentials, project, database, etc.). Superset uses the model's JSON schema to render the configuration form dynamically. diff --git a/docs/developer_docs/extensions/overview.md b/docs/developer_docs/extensions/overview.md index 74ee7ac98c3..c5ef59f428b 100644 --- a/docs/developer_docs/extensions/overview.md +++ b/docs/developer_docs/extensions/overview.md @@ -43,7 +43,7 @@ Extensions can provide: ## UI Components for Extensions -Extension developers have access to pre-built UI components via `@apache-superset/core/components`. Browse all available components on the [UI Components](/docs/components/) page and filter by **Extension Compatible** to see components available to extensions. +Extension developers have access to pre-built UI components via `@apache-superset/core/components`. Browse all available components on the [UI Components](/developer-docs/components/) page and filter by **Extension Compatible** to see components available to extensions. ## Next Steps diff --git a/docs/docs/using-superset/creating-your-first-dashboard.mdx b/docs/docs/using-superset/creating-your-first-dashboard.mdx index febf3395a6f..f83982385c4 100644 --- a/docs/docs/using-superset/creating-your-first-dashboard.mdx +++ b/docs/docs/using-superset/creating-your-first-dashboard.mdx @@ -63,6 +63,12 @@ by clicking the **Connect** button in the bottom right corner of the modal windo Congratulations, you've just added a new data source in Superset! +### Sharing a Database Connection + +When adding a new database, you can share the connection with other Superset users. Shared connections appear in other users' database lists, making it easier to collaborate on the same data without requiring each user to configure the same connection separately. + +To share a connection, enable the **Share connection with other users** option in the **Advanced** tab of the database connection modal before saving. You can change sharing settings later by editing the database connection. + ### Registering a new table Now that you’ve configured a data source, you can select specific tables (called **Datasets** in Superset) @@ -80,6 +86,22 @@ we register the **cleaned_sales_data** table from the **examples** database. To finish, click the **Add** button in the bottom right corner. You should now see your dataset in the list of datasets. +### Organizing Datasets into Folders + +The Datasets list view supports **folders** for organizing datasets into groups. To create and manage folders: + +1. In the **Datasets** list, click the **Folders** panel on the left sidebar. +2. Click **+ New Folder** to create a top-level folder, or drag an existing folder to nest it. +3. Drag dataset rows onto a folder to move them in, or right-click a dataset and select **Move to folder**. + +Folders are per-user organizational aids — they do not affect dataset access permissions or how other users see the datasets. + +### Uploading Files via the OS File Manager (PWA) + +When Superset is installed as a **Progressive Web App (PWA)** from your browser, your operating system will offer Superset as an option when opening CSV, Excel (`.xls`/`.xlsx`), and Parquet files. Double-clicking or right-clicking a supported file and selecting "Open with Superset" navigates directly to the upload workflow for that file. + +To install Superset as a PWA, look for the install icon in your browser's address bar (Chrome, Edge) when visiting your Superset instance over HTTPS. PWA installation requires HTTPS and a valid manifest — your admin needs to confirm the app manifest is served correctly. + ### Customizing column properties Now that you've registered your dataset, you can configure column properties @@ -193,7 +215,7 @@ Access to dashboards is managed via owners and permissions. Non-owner access can through dataset permissions or dashboard-level roles (using the `DASHBOARD_RBAC` feature flag). For detailed information on configuring dashboard access, see the -[Dashboard Access Control](/admin-docs/security/security#dashboard-access-control) section in the +[Dashboard Access Control](/admin-docs/security/#dashboard-access-control) section in the Security documentation. @@ -234,6 +256,112 @@ For example, when running the local development build, the following will disabl Top Nav and remove the Filter Bar: `http://localhost:8088/superset/dashboard/my-dashboard/?standalone=1&show_filters=0` +### Table Chart Features + +The **Table** chart type has several advanced capabilities worth knowing: + +#### Conditional Formatting + +Conditional formatting rules highlight cells based on their values. Rules can be applied to: +- **Numeric columns** — color cells above/below a threshold, or use a gradient across a range +- **String columns** — highlight cells matching specific text values or patterns +- **Boolean columns** — color cells that are `true` or `false`, or `null`/`not null` + +Each rule has a **"Use gradient"** toggle: enabled applies a varying opacity (lighter = further from threshold), disabled applies a solid fill at full opacity regardless of value. + +#### HTML Rendering in Table Cells + +Table chart cells can render raw HTML, enabling rich formatting such as hyperlinks, colored badges, and icons directly in the data. Enable this per-column in the chart's **Column Configuration** panel by toggling **Render HTML**. + +:::caution +Only enable HTML rendering for columns sourced from data you control. Rendering untrusted HTML can expose users to cross-site scripting (XSS) risks. +::: + +#### Column Header Tooltips + +Column headers display a tooltip with the column's **Description** from the dataset editor when the user hovers over them. Keep dataset column descriptions up to date to improve chart discoverability. + +#### Display Controls + +In dashboard view mode (without entering Edit mode), charts with configurable display options expose a **Display Controls** panel accessible from the chart's context menu. This surfaces controls such as Time Grain, Time Column, and layer visibility for applicable chart types — making it easy to adjust a chart's view without going to Explore. +### AG Grid Interactive Table + +The **AG Grid Interactive Table** chart type is Superset's fully-featured data grid, suitable for large paginated datasets where the standard Table chart is not enough. + +#### Server-Side Column Filters + +AG Grid supports server-side column filters that query the full dataset — not just the loaded page. Filters are applied before data is sent to the browser, so results are correct even across millions of rows. + +**Available filter types:** + +| Column type | Filter options | +|---|---| +| Text | Contains, equals, starts with, ends with | +| Number | Equals, not equal, less than, greater than, between | +| Date | Before, after, between, blank | +| Set | Select from a list of distinct values | + +**AND / OR logic:** Each column supports combining multiple conditions with AND or OR. Filters from different columns are always combined with AND. + +**Interaction with pagination:** Server-side filters run as WHERE clauses in the underlying SQL query, so pagination always operates over the already-filtered result set. + +#### Time Shift (Time Comparison) + +AG Grid Interactive Table supports **Time Shift** (time comparison), matching the behavior of the standard Table chart. In the **Advanced Analytics** → **Time Comparison** section of the chart configuration, enter a shift expression (e.g., `1 year ago`, `minus 7 days`) to add comparison columns showing values from the offset period. Dashboard-level time range overrides apply to both the base and comparison periods. + +### Dynamic Currency Formatting + +Chart metric values can display currencies dynamically rather than using a fixed currency code. To enable: + +1. Open the dataset editor for your dataset (**Datasets → Edit**). +2. In the **Advanced** tab, set **Currency Code Column** to the name of a column in your dataset that contains ISO 4217 currency codes (e.g., `USD`, `EUR`, `GBP`). +3. In the Explore chart configuration, open the metric's **Number format** section and select **Auto-detect** for currency. + +When Auto-detect is active, each row uses the currency code from the designated column, so a single chart can display values in multiple currencies — each formatted correctly for its currency. + +### ECharts Option Editor + +For ECharts-based chart types (line, bar, area, scatter, pie, and others), Explore includes an advanced **ECharts Option Editor** that accepts raw JSON overrides for the underlying ECharts configuration. + +Access it via the **Customize** tab → **ECharts Options** section at the bottom of the panel. The JSON you enter is deep-merged on top of Superset's generated ECharts config, so you can override specific options without rewriting the entire config. + +**Example:** override the legend position and add a custom title: + +```json +{ + "legend": { "orient": "vertical", "right": "5%", "top": "middle" }, + "title": { "text": "My Custom Title", "left": "center" } +} +``` + +:::caution +ECharts option overrides bypass Superset's validation layer. Invalid option keys are silently ignored by ECharts. Overrides that conflict with Superset-generated options (e.g., `series`) may produce unexpected results. +::: + +### Table Chart: Exporting Filtered Data + +When the **Search Box** is visible in a Table chart, the **Download** action exports only the rows currently visible after the search filter is applied — not the full underlying dataset. This matches the visual output and is intentional. To export the full dataset regardless of search state, use the **Download as CSV** option from the chart's three-dot menu in the dashboard or from the Explore chart toolbar before applying a search filter. + +### Sharing a Specific Tab + +When a dashboard has tabs, each tab gets its own shareable URL. Navigate to the tab you want to share and copy the URL from your browser's address bar — the tab anchor is encoded in the URL so that anyone opening the link lands directly on that tab. + +### Auto-Refresh + +Dashboards can be configured to refresh automatically at a fixed interval without user interaction. Open a dashboard, click the **⋮** (more options) menu in the top-right, and select **Set auto-refresh interval**. Choose an interval (e.g., every 10 seconds, 1 minute, or 10 minutes). The setting is per-session and resets when you close the tab. + +:::note +Auto-refresh triggers a full data reload for all charts on the dashboard. For dashboards with expensive queries, choose longer intervals to avoid overloading your database. +::: + +### Last Queried Timestamp + +Charts can display a "Last queried at" timestamp showing when the chart data was last fetched. This is useful on auto-refreshing dashboards to confirm data freshness. Enable it in **Dashboard Properties → Styling → Show last queried time**. + +### Saving a Chart to a Specific Tab + +When saving or adding a chart to a dashboard from Explore, you can select which tab it should land on using the tab tree-select dropdown in the "Add to dashboard" modal. + :::resources - [Dashboard Customization](https://docs.preset.io/docs/dashboard-customization) - Advanced dashboard styling and layout options - [Blog: BI Dashboard Best Practices](https://preset.io/blog/bi-dashboard-best-practices/) diff --git a/docs/docs/using-superset/embedding.mdx b/docs/docs/using-superset/embedding.mdx new file mode 100644 index 00000000000..f03c931e331 --- /dev/null +++ b/docs/docs/using-superset/embedding.mdx @@ -0,0 +1,131 @@ +--- +title: Embedding Superset +sidebar_position: 6 +--- + +{/* +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. +*/} + + +# Embedding Superset + +Superset dashboards can be embedded directly in host applications using the `@superset-ui/embedded-sdk` package. + +:::info Prerequisites +- The `EMBEDDED_SUPERSET` feature flag must be enabled. +- The embedding domain and allowed origins must be configured by an admin. +::: + +## Quick Start + +Install the SDK: + +```bash +npm install @superset-ui/embedded-sdk +``` + +Embed a dashboard: + +```javascript +import { embedDashboard } from '@superset-ui/embedded-sdk'; + +embedDashboard({ + id: 'dashboard-uuid-here', // from Dashboard → Embed + supersetDomain: 'https://superset.example.com', + mountPoint: document.getElementById('superset-container'), + fetchGuestToken: () => fetchTokenFromYourBackend(), + dashboardUiConfig: { + hideTitle: true, + filters: { expanded: false }, + }, +}); +``` + +`fetchGuestToken` must return a **guest token** obtained from your server by calling Superset's `/api/v1/security/guest_token/` endpoint with a service account. Do not call this endpoint from client-side code. + +--- + +## Callbacks + +### `resolvePermalinkUrl` + +When a user copies a permalink from an embedded dashboard, Superset generates a URL on its own domain. In an embedded context this URL is usually not meaningful to the host application's users — the dashboard is rendered inside the host app, not at the Superset URL. + +The `resolvePermalinkUrl` callback lets the host app intercept permalink generation and return a URL on the host domain instead: + +```javascript +embedDashboard({ + id: 'my-dashboard-uuid', + supersetDomain: 'https://superset.example.com', + mountPoint: document.getElementById('superset-container'), + fetchGuestToken: () => fetchGuestToken(), + /** + * Called when Superset generates a permalink. + * @param {Object} args - { key: string } — the permalink key + * @returns {string | null} - your host URL, or null to use Superset's default + */ + resolvePermalinkUrl: ({ key }) => { + return `https://myapp.example.com/dashboard?permalink=${key}`; + }, +}); +``` + +If the callback returns `null` or is not provided, Superset uses its own permalink URL as a fallback. + +--- + +## Feature Flags for Embedded Mode + +### `DISABLE_EMBEDDED_SUPERSET_LOGOUT` + +Hides the logout button when Superset is embedded in a host application. This is useful when the host application manages the session lifecycle and you do not want users to accidentally log out of the embedded Superset session: + +```python +# superset_config.py +FEATURE_FLAGS = { + "EMBEDDED_SUPERSET": True, + "DISABLE_EMBEDDED_SUPERSET_LOGOUT": True, +} +``` + +When enabled, the **Logout** menu item is removed from the user avatar dropdown in the embedded view. The session can still be invalidated server-side by revoking the guest token. + +### `EMBEDDED_SUPERSET` + +Must be `True` to enable the embedded SDK and the guest token endpoint. Without this flag, `embedDashboard` will fail to load. + +--- + +## URL Parameters + +The following URL parameters can be passed through the `urlParams` option in `dashboardUiConfig` or appended to the embedded iframe URL: + +| Parameter | Values | Effect | +|-----------|--------|--------| +| `standalone` | `0`, `1`, `2`, `3` | `0`: normal; `1`: hide nav; `2`: hide nav + title; `3`: hide nav + title + tabs | +| `show_filters` | `0`, `1` | Show or hide the native filter bar | +| `expand_filters` | `0`, `1` | Start with filter bar expanded or collapsed | + +--- + +## Security Notes + +- **Guest tokens expire** — their lifetime is controlled by the `GUEST_TOKEN_JWT_EXP_SECONDS` config (default: 5 minutes). Refresh tokens before they expire using a token refresh mechanism in your host app. +- **Row-level security** — pass `rls` rules in the guest token request to restrict which rows are visible to the embedded user. +- **Allowed domains** — restrict which host origins can embed a dashboard by setting **Allowed Domains** per-dashboard in the *Embed* settings modal. Superset checks the request's `Referer` header against this list before serving the embedded view; an empty list allows any origin, so configure this explicitly for production. diff --git a/docs/docs/using-superset/exploring-data.mdx b/docs/docs/using-superset/exploring-data.mdx index 0cc812382aa..8d83a0c2c63 100644 --- a/docs/docs/using-superset/exploring-data.mdx +++ b/docs/docs/using-superset/exploring-data.mdx @@ -329,6 +329,27 @@ various options in this section, refer to the Lastly, save your chart as Tutorial Resample and add it to the Tutorial Dashboard. Go to the tutorial dashboard to see the four charts side by side and compare the different outputs. +### SQL Lab Tips + +**Schema and table browser**: The left-side table browser uses a collapsible treeview — click a schema to expand its tables, and click a table to see its columns and sample data inline. This makes navigating large schemas much faster than the previous flat list. + +**Find in editor**: Press **Ctrl+F** (or **Cmd+F** on Mac) to open the Monaco find/replace widget inside the SQL editor without leaving the editor. + +**Resizable panels**: The dividers between the SQL editor, schema browser, and results pane are draggable. Adjust them to match your workflow and screen size. + +**Dialect-aware Format SQL**: The **Format SQL** button applies the SQL dialect of the currently selected database — Trino, Presto, MySQL, PostgreSQL, etc. — rather than a generic formatter. Switch to a different database in the toolbar and re-format to get dialect-specific output. Jinja template syntax (`{{ }}`, `{% %}`) is preserved during formatting and will not cause format errors. + +### Time Range Natural Language Expressions + +The **Custom** time range picker accepts natural language expressions alongside specific dates: + +- **Relative**: `Last 7 days`, `Last month`, `Last quarter`, `Last year` +- **Anchored**: `previous calendar week`, `previous calendar month` +- **"First of" expressions**: `first day of this week`, `first day of this month`, `first day of this quarter`, `first day of this year`, `first week of this year` +- **Offsets**: `30 days ago`, `1 year ago`, `next week` + +These expressions are evaluated at query time, so saved charts always display data relative to the current date. + :::resources - [Chart Walkthroughs](https://docs.preset.io/docs/chart-walkthroughs) - Detailed guides for most chart types - [Blog: Why Apache ECharts is the Future of Apache Superset](https://preset.io/blog/2021-4-1-why-echarts/) diff --git a/docs/docs/using-superset/handlebars-chart.mdx b/docs/docs/using-superset/handlebars-chart.mdx new file mode 100644 index 00000000000..f560f923f51 --- /dev/null +++ b/docs/docs/using-superset/handlebars-chart.mdx @@ -0,0 +1,143 @@ +--- +title: Handlebars Chart +hide_title: true +sidebar_position: 10 +version: 1 +--- + +## Handlebars Chart + +The Handlebars chart lets you render query results using a custom [Handlebars](https://handlebarsjs.com/) template. This gives you full control over how your data is displayed — from simple tables to rich HTML layouts. + +### Basic Usage + +In the chart editor, write a Handlebars template in the **Template** field. Your query results are available as `data`, an array of row objects. + +```handlebars +{{#each data}} +

{{this.name}}: {{this.value}}

+{{/each}} +``` + +### Built-in Helpers + +Superset registers several custom helpers on top of the standard Handlebars built-ins. + +#### `dateFormat` + +Formats a date value using [Day.js](https://day.js.org/) format strings. + +```handlebars +{{dateFormat my_date format="MMMM YYYY"}} +``` + +| Option | Default | Description | +|--------|---------|-------------| +| `format` | `YYYY-MM-DD` | A Day.js-compatible format string | + +--- + +#### `stringify` + +Converts an object to a JSON string, or any other value to its string representation. + +```handlebars +{{stringify myObj}} +``` + +--- + +#### `formatNumber` + +Formats a number using locale-aware formatting. + +```handlebars +{{formatNumber myNumber "en-US"}} +``` + +| Option | Default | Description | +|--------|---------|-------------| +| `locale` | `en-US` | A BCP 47 language tag | + +--- + +#### `parseJson` + +Parses a JSON string into an object that can be used in your template. + +```handlebars +{{parseJson myJsonString}} +``` + +--- + +#### `groupBy` + +Groups an array of objects by a key, powered by [handlebars-group-by](https://github.com/nicktindall/handlebars-group-by). + +```handlebars +{{#groupBy data "department"}} +

{{value}}

+ {{#each items}} +

{{this.name}}

+ {{/each}} +{{/groupBy}} +``` + +--- + +### Helpers from just-handlebars-helpers + +Superset also registers all helpers from the [just-handlebars-helpers](https://github.com/leapfrogtechnology/just-handlebars-helpers) library. These include a wide range of comparison, math, string, and conditional helpers. Commonly used ones include: + +#### Comparison + +| Helper | Description | Example | +|--------|-------------|---------| +| `eq` | Strict equality | `{{#if (eq status "active")}}` | +| `eqw` | Weak equality | `{{#if (eqw count "5")}}` | +| `neq` | Strict inequality | `{{#if (neq role "admin")}}` | +| `lt` | Less than | `{{#if (lt score 50)}}` | +| `lte` | Less than or equal | `{{#if (lte score 100)}}` | +| `gt` | Greater than | `{{#if (gt price 0)}}` | +| `gte` | Greater than or equal | `{{#if (gte age 18)}}` | + +#### Logical + +| Helper | Description | Example | +|--------|-------------|---------| +| `and` | Logical AND | `{{#if (and isActive isVerified)}}` | +| `or` | Logical OR | `{{#if (or isAdmin isMod)}}` | +| `not` | Logical NOT | `{{#if (not isDisabled)}}` | +| `ifx` | Inline conditional | `{{ifx isActive "Yes" "No"}}` | +| `coalesce` | Returns first non-falsy value | `{{coalesce nickname name "Anonymous"}}` | + +#### String + +| Helper | Description | Example | +|--------|-------------|---------| +| `capitalize` | Capitalizes first letter | `{{capitalize name}}` | +| `uppercase` | Converts to uppercase | `{{uppercase status}}` | +| `lowercase` | Converts to lowercase | `{{lowercase email}}` | +| `truncate` | Truncates a string | `{{truncate description 100}}` | +| `contains` | Checks if string contains substring | `{{#if (contains tag "urgent")}}` | + +#### Math + +| Helper | Description | Example | +|--------|-------------|---------| +| `add` | Addition | `{{add a b}}` | +| `subtract` | Subtraction | `{{subtract total discount}}` | +| `multiply` | Multiplication | `{{multiply price quantity}}` | +| `divide` | Division | `{{divide total count}}` | +| `ceil` | Ceiling | `{{ceil value}}` | +| `floor` | Floor | `{{floor value}}` | +| `round` | Round | `{{round value}}` | + +For the full list of available helpers, see the [just-handlebars-helpers documentation](https://github.com/leapfrogtechnology/just-handlebars-helpers). + +### Tips + +- Use raw blocks to escape Handlebars syntax if you need to display double curly braces literally. +- Comparison helpers like `eq` must be wrapped in a subexpression when used with `#if`: `{{#if (eq myVal "foo")}}`. +- HTML output is sanitized by default based on your Superset configuration (`HTML_SANITIZATION`). diff --git a/docs/docs/using-superset/sql-templating.mdx b/docs/docs/using-superset/sql-templating.mdx index 4791c8357e0..44566604565 100644 --- a/docs/docs/using-superset/sql-templating.mdx +++ b/docs/docs/using-superset/sql-templating.mdx @@ -33,6 +33,29 @@ SQL templating must be enabled by your administrator via the `ENABLE_TEMPLATE_PR For advanced configuration options, see the [SQL Templating Configuration Guide](/admin-docs/configuration/sql-templating). ::: +## Using Jinja in Calculated Columns + +Jinja template macros are available in calculated column expressions in the dataset editor — not just in SQL Lab queries and virtual datasets. This allows column expressions to reference the current user or dynamic context. + +**Example: User-scoped calculated column** + +```sql +CASE WHEN sales_rep = '{{ current_username() }}' THEN amount ELSE 0 END +``` + +**Example: Conditional display based on role** + +Because `current_user_roles()` returns a Python list, test role membership with a Jinja +conditional at template time rather than matching against the list's string representation: + +```sql +{% if 'Finance' in current_user_roles() %}revenue{% else %}NULL{% endif %} AS finance_revenue +``` + +:::note +The `ENABLE_TEMPLATE_PROCESSING` feature flag must be enabled by your administrator for Jinja in calculated columns to work. +::: + ## Basic Usage Jinja templates use double curly braces `{{ }}` for expressions and `{% %}` for logic blocks. @@ -243,6 +266,7 @@ Using `remove_filter=True` applies the filter in the inner query for better perf - Use `|tojson` to serialize arrays as JSON strings - Test queries with explicit parameter values before relying on filter context - For complex templating needs, ask your administrator about custom Jinja macros +- **Format SQL is Jinja-aware**: The "Format SQL" button in SQL Lab correctly preserves `{{ }}` and `{% %}` template syntax and applies your selected database's SQL dialect when formatting. :::resources - [Admin Guide: SQL Templating Configuration](/admin-docs/configuration/sql-templating) diff --git a/docs/docs/using-superset/using-ai-with-superset.mdx b/docs/docs/using-superset/using-ai-with-superset.mdx index 3969042bcd2..b419ccc9269 100644 --- a/docs/docs/using-superset/using-ai-with-superset.mdx +++ b/docs/docs/using-superset/using-ai-with-superset.mdx @@ -55,9 +55,10 @@ Ask your AI assistant to browse what's available in your Superset instance: Describe the visualization you want and AI creates it for you: +- **Preview-first workflow** -- by default AI generates an Explore link so you can review the chart before it is saved. Say "save it" to commit permanently - **Create charts from natural language** -- describe what you want to see and AI picks the right chart type, metrics, and dimensions -- **Preview before saving** -- AI generates a preview so you can review before committing -- **Modify existing charts** -- update filters, change chart types, add metrics +- **Preview before saving** -- `generate_chart` defaults to `save_chart=False`, showing the chart in Explore before it's committed. Ask AI to save once you're satisfied. +- **Modify existing charts** -- `update_chart` also supports preview mode so you can review changes before saving (update filters, change chart types, add metrics) - **Get Explore links** -- open any chart in Superset's Explore view for further refinement **Example prompts:** @@ -65,6 +66,16 @@ Describe the visualization you want and AI creates it for you: > "Update chart 42 to use a line chart instead" > "Give me a link to explore this chart further" +:::tip Preview-first workflow +Charts are **not saved by default**. The workflow is intentionally iterative: + +1. **Explore** — AI generates an Explore link so you can see the chart before it exists in Superset +2. **Iterate** — ask the AI to adjust the chart; changes are previewed without touching the database +3. **Save** — when you're happy, say "save it" and the chart is permanently stored + +To skip the preview and save immediately, include "and save it" in your prompt. +::: + ### Create Dashboards Build dashboards from a collection of charts: @@ -76,16 +87,40 @@ Build dashboards from a collection of charts: > "Create a dashboard called 'Q4 Sales Overview' with charts 10, 15, and 22" > "Add the revenue trend chart to the executive dashboard" +### Browse Databases + +Discover what database connections are configured in your Superset instance: + +- **List databases** -- see all database connections you have access to +- **Get database details** -- name, backend type (PostgreSQL, Snowflake, etc.), and connection status + +**Example prompts:** +> "What databases are connected to Superset?" +> "Show me details about the data warehouse connection" + +### Create Virtual Datasets + +Build ad-hoc SQL datasets that can be used as the basis for charts: + +- **Create virtual datasets** -- write a SQL query and save it as a reusable dataset +- **Use immediately in charts** -- the returned dataset ID can be passed directly to chart creation + +**Example prompts:** +> "Create a dataset from: SELECT region, SUM(revenue) as total_revenue FROM orders GROUP BY region" +> "Make a virtual dataset called 'monthly_signups' from the users table filtered to last 12 months" + ### Run SQL Queries Execute SQL directly through your AI assistant: - **Run queries** -- execute SQL with full Superset RBAC enforcement (you can only query data your roles allow) - **Open SQL Lab** -- get a link to SQL Lab pre-populated with a query, ready to run and explore +- **Save queries** -- save a SQL query to SQL Lab's Saved Queries for later reuse **Example prompts:** > "Run this query: SELECT region, SUM(revenue) FROM sales GROUP BY region" > "Open SQL Lab with a query to show the top 10 customers by order count" +> "Save this query as 'Weekly Revenue Report'" ### Analyze Chart Data @@ -195,27 +230,59 @@ Ask your admin for the MCP server URL and any authentication tokens you need. ## Available Tools Reference +### Exploration & Discovery + | Tool | Description | |------|-------------| | `health_check` | Verify the MCP server is running and connected | | `get_instance_info` | Get instance statistics (dataset, chart, dashboard counts) | | `get_schema` | Discover available charts, datasets, and dashboards with schema info | + +### Datasets + +| Tool | Description | +|------|-------------| | `list_datasets` | List datasets with filtering and search | | `get_dataset_info` | Get dataset metadata (columns, metrics, filters) | +| `create_virtual_dataset` | Create a virtual dataset from a SQL query | + +### Charts + +| Tool | Description | +|------|-------------| | `list_charts` | List charts with filtering and search | | `get_chart_info` | Get chart metadata and configuration | | `get_chart_data` | Retrieve chart data (JSON, CSV, or Excel) | | `get_chart_preview` | Generate a chart preview (URL, ASCII, table, or Vega-Lite) | -| `generate_chart` | Create a new chart from a specification | -| `update_chart` | Modify an existing chart's configuration | +| `get_chart_type_schema` | Get the configuration schema for a chart type | +| `generate_chart` | Create a new chart from a specification (defaults to preview mode — review before saving) | +| `update_chart` | Modify an existing chart's configuration (pass `generate_preview=False` to persist immediately instead of returning a preview URL) | | `update_chart_preview` | Update a cached chart preview without saving | +| `generate_explore_link` | Generate an Explore URL for interactive visualization | + +### Dashboards + +| Tool | Description | +|------|-------------| | `list_dashboards` | List dashboards with filtering and search | | `get_dashboard_info` | Get dashboard metadata and layout | | `generate_dashboard` | Create a new dashboard with specified charts | | `add_chart_to_existing_dashboard` | Add a chart to an existing dashboard | + +### SQL + +| Tool | Description | +|------|-------------| | `execute_sql` | Run a SQL query with RBAC enforcement | +| `save_sql_query` | Persist a SQL query to SQL Lab's saved queries | | `open_sql_lab_with_context` | Open SQL Lab with a pre-populated query | -| `generate_explore_link` | Generate an Explore URL for interactive visualization | + +### Databases + +| Tool | Description | +|------|-------------| +| `list_databases` | List configured database connections | +| `get_database_info` | Get details about a specific database connection | --- diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 898bf3ff1c8..babacfe43d8 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -178,7 +178,7 @@ if (!versionsConfig.admin_docs.disabled) { }, { label: 'Security', - to: '/admin-docs/security/security', + to: '/admin-docs/security/', activeBaseRegex: '^/admin-docs/security/', }, ], @@ -227,35 +227,28 @@ if (!versionsConfig.developer_docs.disabled && !versionsConfig.developer_docs.hi }); } -// Docusaurus Faster: Rspack bundler, SWC transpilation, and other build -// optimizations. Only enabled for local development — CI runners (GitHub -// Actions, Netlify) have ~8GB RAM and these features push memory usage over -// the limit. See https://docusaurus.io/blog/releases/3.6#docusaurus-faster -const isCI = process.env.CI === 'true'; const config: Config = { - ...(!isCI && { - future: { - v4: { - removeLegacyPostBuildHeadAttribute: true, - // Disabled: CSS cascade layers change specificity and cause antd - // styles (from Storybook component pages) to override theme styles - useCssCascadeLayers: false, - }, - experimental_faster: { - swcJsLoader: true, - swcJsMinimizer: true, - swcHtmlMinimizer: true, - lightningCssMinimizer: true, - rspackBundler: true, - mdxCrossCompilerCache: true, - rspackPersistentCache: true, - // SSG worker threads spawn parallel Node processes, each consuming - // significant memory. Disabled to keep total usage reasonable. - ssgWorkerThreads: false, - }, + future: { + v4: { + removeLegacyPostBuildHeadAttribute: true, + // Disabled: CSS cascade layers change specificity and cause antd + // styles (from Storybook component pages) to override theme styles + useCssCascadeLayers: false, }, - }), + faster: { + swcJsLoader: false, + swcJsMinimizer: true, + swcHtmlMinimizer: true, + lightningCssMinimizer: true, + rspackBundler: true, + mdxCrossCompilerCache: true, + rspackPersistentCache: true, + // SSG worker threads spawn parallel Node processes, each consuming + // significant memory. Disabled to keep total usage reasonable. + ssgWorkerThreads: false, + }, + }, title: 'Superset', tagline: 'Apache Superset is a modern data exploration and visualization platform', @@ -892,10 +885,8 @@ const config: Config = { ], }, { - href: '/user-docs/', + type: 'custom-getStartedSplit', position: 'right', - className: 'default-button-theme get-started-button', - label: 'Get Started', }, { href: 'https://github.com/apache/superset', diff --git a/docs/package.json b/docs/package.json index 99dc34427e8..2265d323926 100644 --- a/docs/package.json +++ b/docs/package.json @@ -40,13 +40,13 @@ "version:remove:components": "node scripts/manage-versions.mjs remove components" }, "dependencies": { - "@ant-design/icons": "^6.1.1", - "@docusaurus/core": "^3.10.0", - "@docusaurus/faster": "^3.10.0", - "@docusaurus/plugin-client-redirects": "^3.10.0", - "@docusaurus/preset-classic": "3.10.0", - "@docusaurus/theme-live-codeblock": "^3.10.0", - "@docusaurus/theme-mermaid": "^3.10.0", + "@ant-design/icons": "^6.2.2", + "@docusaurus/core": "^3.10.1", + "@docusaurus/faster": "^3.10.1", + "@docusaurus/plugin-client-redirects": "^3.10.1", + "@docusaurus/preset-classic": "3.10.1", + "@docusaurus/theme-live-codeblock": "^3.10.1", + "@docusaurus/theme-mermaid": "^3.10.1", "@emotion/core": "^11.0.0", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.14.1", @@ -67,12 +67,12 @@ "@storybook/preview-api": "^8.6.18", "@storybook/theming": "^8.6.15", "@superset-ui/core": "^0.20.4", - "@swc/core": "^1.15.26", - "antd": "^6.3.5", - "baseline-browser-mapping": "^2.10.19", - "caniuse-lite": "^1.0.30001788", - "docusaurus-plugin-openapi-docs": "^5.0.1", - "docusaurus-theme-openapi-docs": "^5.0.1", + "@swc/core": "^1.15.33", + "antd": "^6.3.7", + "baseline-browser-mapping": "^2.10.29", + "caniuse-lite": "^1.0.30001792", + "docusaurus-plugin-openapi-docs": "^5.0.2", + "docusaurus-theme-openapi-docs": "^5.0.2", "js-yaml": "^4.1.1", "js-yaml-loader": "^1.2.2", "json-bigint": "^1.0.0", @@ -86,27 +86,27 @@ "remark-import-partial": "^0.0.2", "reselect": "^5.1.1", "storybook": "^8.6.18", - "swagger-ui-react": "^5.32.4", + "swagger-ui-react": "^5.32.5", "swc-loader": "^0.2.7", "tinycolor2": "^1.4.2", "unist-util-visit": "^5.1.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "^3.10.0", - "@docusaurus/tsconfig": "^3.10.0", + "@docusaurus/module-type-aliases": "^3.10.1", + "@docusaurus/tsconfig": "^3.10.1", "@eslint/js": "^9.39.2", "@types/js-yaml": "^4.0.9", "@types/react": "^19.1.8", "@typescript-eslint/eslint-plugin": "^8.52.0", - "@typescript-eslint/parser": "^8.56.1", + "@typescript-eslint/parser": "^8.59.0", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-react": "^7.37.5", - "globals": "^17.4.0", + "globals": "^17.6.0", "prettier": "^3.8.3", - "typescript": "~5.9.3", - "typescript-eslint": "^8.58.2", + "typescript": "~6.0.3", + "typescript-eslint": "^8.59.2", "webpack": "^5.106.2" }, "browserslist": { @@ -124,8 +124,7 @@ "resolutions": { "react-redux": "^9.2.0", "@reduxjs/toolkit": "^2.5.0", - "baseline-browser-mapping": "^2.9.19", - "webpackbar": "^7.0.0" + "baseline-browser-mapping": "^2.9.19" }, "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610" } diff --git a/docs/scripts/generate-database-docs.mjs b/docs/scripts/generate-database-docs.mjs index 0491683b951..93cb5d766b8 100644 --- a/docs/scripts/generate-database-docs.mjs +++ b/docs/scripts/generate-database-docs.mjs @@ -141,6 +141,47 @@ def eval_node(node): return "" return None +def static_return_bool(func_node): + """ + Statically resolve a method's return value to a bool when possible. + + Returns True/False for functions whose body is (effectively) a single + \`return True\` / \`return False\` — allowing a leading docstring and + ignoring pure-comment/pass statements. Returns None for anything more + complex (conditional returns, computed values, no return, etc.). + + Used by \`has_implicit_cancel\` handling: \`diagnose()\` in lib.py calls + the method and checks the return value, so an override that explicitly + returns False must NOT be treated as enabling query cancelation. + """ + returns = [] + other_logic = False + docstring_skipped = False + for stmt in func_node.body: + # Skip docstring (only the FIRST expression statement that is a + # string constant — later bare string literals are not docstrings + # and should count as non-trivial logic). + if (not docstring_skipped + and isinstance(stmt, ast.Expr) + and isinstance(stmt.value, ast.Constant) + and isinstance(stmt.value.value, str)): + docstring_skipped = True + continue + if isinstance(stmt, ast.Pass): + continue + if isinstance(stmt, ast.Return): + returns.append(stmt) + continue + # Any other statement (if/for/assign/etc.) means control flow is + # non-trivial; bail out to be conservative. + other_logic = True + break + if other_logic or len(returns) != 1: + return None + val = eval_node(returns[0].value) + return val if isinstance(val, bool) else None + + def deep_merge(base, override): """Deep merge two dictionaries. Override values take precedence.""" if base is None: @@ -186,8 +227,55 @@ if not os.path.isdir(specs_dir): print(json.dumps({"error": f"Directory not found: {specs_dir}", "cwd": os.getcwd()})) sys.exit(1) -# First pass: collect all class info (name, bases, metadata) -class_info = {} # class_name -> {bases: [], metadata: {}, engine_name: str, filename: str} +# Capability flag attributes with their defaults from BaseEngineSpec +CAP_ATTR_DEFAULTS = { + 'supports_dynamic_schema': False, + 'supports_catalog': False, + 'supports_dynamic_catalog': False, + 'disable_ssh_tunneling': False, + 'supports_file_upload': True, + 'allows_joins': True, + 'allows_subqueries': True, +} + +# Maps source capability attribute -> output field name used in databases.json. +# When a cap attr is assigned an unevaluable expression (e.g. +# allows_joins = is_feature_enabled("DRUID_JOINS")), the JS layer uses this +# mapping to preserve the corresponding field from the previously-generated +# JSON rather than silently inheriting an incorrect parent default. +CAP_ATTR_TO_OUTPUT_FIELD = { + 'allows_joins': 'joins', + 'allows_subqueries': 'subqueries', + 'supports_dynamic_schema': 'supports_dynamic_schema', + 'supports_catalog': 'supports_catalog', + 'supports_dynamic_catalog': 'supports_dynamic_catalog', + 'disable_ssh_tunneling': 'ssh_tunneling', + 'supports_file_upload': 'supports_file_upload', +} + +# Methods that indicate a capability when overridden by a non-BaseEngineSpec class. +# Mirrors the has_custom_method checks in superset/db_engine_specs/lib.py. +# cancel_query / has_implicit_cancel -> query_cancelation +# (diagnose() checks cancel_query override OR has_implicit_cancel() == True; +# base has_implicit_cancel returns False, so overriding it is the static +# equivalent of that method returning True. get_cancel_query_id is NOT +# part of the diagnose() heuristic and is intentionally excluded.) +# estimate_statement_cost / estimate_query_cost -> query_cost_estimation +# impersonate_user / update_impersonation_config / get_url_for_impersonation -> user_impersonation +# validate_sql -> sql_validation (not used yet; validation is engine-based) +CAP_METHODS = { + 'cancel_query', 'has_implicit_cancel', + 'estimate_statement_cost', 'estimate_query_cost', + 'impersonate_user', 'update_impersonation_config', 'get_url_for_impersonation', + 'validate_sql', +} + +# Only the literal BaseEngineSpec is excluded from method-override tracking. +# Intermediate base classes (e.g. PrestoBaseEngineSpec) do count as overrides. +TRUE_BASE_CLASS = 'BaseEngineSpec' + +# First pass: collect all class info (name, bases, metadata, cap_attrs, direct_methods) +class_info = {} # class_name -> {bases: [], metadata: {}, engine_name: str, filename: str, ...} for filename in sorted(os.listdir(specs_dir)): if not filename.endswith('.py') or filename in ('__init__.py', 'lib.py', 'lint_metadata.py'): @@ -218,30 +306,54 @@ for filename in sorted(os.listdir(specs_dir)): # Extract class attributes engine_name = None + engine_attr = None metadata = None + cap_attrs = {} # capability flag attributes defined directly in this class + # Cap attrs assigned via expressions we can't statically resolve + # (e.g. is_feature_enabled("FLAG")). Tracked so the JS layer can + # fall back to the previously-generated databases.json value + # rather than inherit a parent default that would be wrong. + unresolved_cap_attrs = set() + direct_methods = set() # capability methods defined directly in this class for item in node.body: if isinstance(item, ast.Assign): for target in item.targets: - if isinstance(target, ast.Name): - if target.id == 'engine_name': - val = eval_node(item.value) - if isinstance(val, str): - engine_name = val - elif target.id == 'metadata': - metadata = eval_node(item.value) + if not isinstance(target, ast.Name): + continue + if target.id == 'engine_name': + val = eval_node(item.value) + if isinstance(val, str): + engine_name = val + elif target.id == 'engine': + val = eval_node(item.value) + if isinstance(val, str): + engine_attr = val + elif target.id == 'metadata': + metadata = eval_node(item.value) + elif target.id in CAP_ATTR_DEFAULTS: + val = eval_node(item.value) + if isinstance(val, bool): + cap_attrs[target.id] = val + else: + # Unevaluable expression — defer to JS fallback. + unresolved_cap_attrs.add(target.id) + elif isinstance(item, (ast.FunctionDef, ast.AsyncFunctionDef)): + if item.name in CAP_METHODS: + # has_implicit_cancel is special: diagnose() uses the + # method's RETURN VALUE, not just its presence. If the + # override statically returns False, treat it as if + # the method weren't overridden so query_cancelation + # matches diagnose(). Unresolvable / True / anything + # else falls through as an override (conservative). + if item.name == 'has_implicit_cancel': + if static_return_bool(item) is False: + continue + direct_methods.add(item.name) # Check for engine attribute with non-empty value to distinguish # true base classes from product classes like OceanBaseEngineSpec - has_non_empty_engine = False - for item in node.body: - if isinstance(item, ast.Assign): - for target in item.targets: - if isinstance(target, ast.Name) and target.id == 'engine': - # Check if engine value is non-empty string - if isinstance(item.value, ast.Constant): - has_non_empty_engine = bool(item.value.value) - break + has_non_empty_engine = engine_attr is not None and bool(engine_attr) # True base classes: end with BaseEngineSpec AND don't define engine # or have empty engine (like PostgresBaseEngineSpec with engine = "") @@ -254,13 +366,18 @@ for filename in sorted(os.listdir(specs_dir)): 'bases': base_names, 'metadata': metadata, 'engine_name': engine_name, + 'engine': engine_attr, 'filename': filename, 'is_base_or_mixin': is_true_base, + 'cap_attrs': cap_attrs, + 'unresolved_cap_attrs': unresolved_cap_attrs, + 'direct_methods': direct_methods, } except Exception as e: errors.append(f"{filename}: {str(e)}") -# Second pass: resolve inheritance and build final metadata +# Second pass: resolve inheritance and build final metadata + capability flags + def get_inherited_metadata(class_name, visited=None): """Recursively get metadata from parent classes.""" if visited is None: @@ -286,6 +403,64 @@ def get_inherited_metadata(class_name, visited=None): return inherited +def get_resolved_caps(class_name, visited=None): + """ + Resolve capability flags and method overrides with inheritance. + + Returns (attr_values, unresolved, methods): + - attr_values: {attr: bool} for attrs where the nearest MRO assignment + was a literal bool. Defaults are applied at the call site. + - unresolved: attrs where the nearest MRO assignment was an unevaluable + expression (e.g. is_feature_enabled("FLAG")). The JS layer falls + back to the previously-generated JSON value for these. + - methods: capability methods defined directly in some non-base ancestor, + matching the has_custom_method() logic in db_engine_specs/lib.py. + + attr_values and unresolved are disjoint — an attr is in at most one. + """ + if visited is None: + visited = set() + if class_name in visited: + return {}, set(), set() + visited.add(class_name) + + info = class_info.get(class_name) + if not info: + return {}, set(), set() + + attr_values = {} + unresolved = set() + resolved_methods = set() + + # Collect from parents, iterating right-to-left so leftmost bases win + # (matches Python MRO: for class C(A, B), A's attributes take precedence). + for base_name in reversed(info['bases']): + p_vals, p_unres, p_meth = get_resolved_caps(base_name, visited.copy()) + # A parent's literal assignments overwrite whatever we inherited so far. + for attr, val in p_vals.items(): + attr_values[attr] = val + unresolved.discard(attr) + # A parent's unresolved assignments likewise take precedence. + for attr in p_unres: + unresolved.add(attr) + attr_values.pop(attr, None) + resolved_methods.update(p_meth) + + # Apply this class's own assignments (override parents). + for attr, val in info['cap_attrs'].items(): + attr_values[attr] = val + unresolved.discard(attr) + for attr in info['unresolved_cap_attrs']: + unresolved.add(attr) + attr_values.pop(attr, None) + + # Accumulate method overrides, but skip the literal BaseEngineSpec + # (its implementations are stubs; only non-base overrides count). + if class_name != TRUE_BASE_CLASS: + resolved_methods.update(info['direct_methods']) + + return attr_values, unresolved, resolved_methods + for class_name, info in class_info.items(): # Skip base classes and mixins if info['is_base_or_mixin']: @@ -310,7 +485,14 @@ for class_name, info in class_info.items(): if final_metadata and isinstance(final_metadata, dict) and display_name: debug_info["classes_with_metadata"] += 1 - databases[display_name] = { + + # Resolve capability flags from Python source + attr_values, unresolved_caps, cap_methods = get_resolved_caps(class_name) + cap_attrs = dict(CAP_ATTR_DEFAULTS) + cap_attrs.update(attr_values) + engine_attr = info.get('engine') or '' + + entry = { 'engine': display_name.lower().replace(' ', '_'), 'engine_name': display_name, 'module': info['filename'][:-3], # Remove .py extension @@ -318,19 +500,40 @@ for class_name, info in class_info.items(): 'time_grains': {}, 'score': 0, 'max_score': 0, - 'joins': True, - 'subqueries': True, - 'supports_dynamic_schema': False, - 'supports_catalog': False, - 'supports_dynamic_catalog': False, - 'ssh_tunneling': False, - 'query_cancelation': False, - 'supports_file_upload': False, - 'user_impersonation': False, - 'query_cost_estimation': False, - 'sql_validation': False, + # Capability flags read from engine spec class attributes/methods + 'joins': cap_attrs['allows_joins'], + 'subqueries': cap_attrs['allows_subqueries'], + 'supports_dynamic_schema': cap_attrs['supports_dynamic_schema'], + 'supports_catalog': cap_attrs['supports_catalog'], + 'supports_dynamic_catalog': cap_attrs['supports_dynamic_catalog'], + 'ssh_tunneling': not cap_attrs['disable_ssh_tunneling'], + 'supports_file_upload': cap_attrs['supports_file_upload'], + # Method-based flags: True only when a non-base class overrides them. + # Matches diagnose() in lib.py: cancel_query override OR + # has_implicit_cancel() returning True (which, given the base + # returns False, is equivalent to overriding has_implicit_cancel). + 'query_cancelation': bool({'cancel_query', 'has_implicit_cancel'} & cap_methods), + 'query_cost_estimation': bool({'estimate_statement_cost', 'estimate_query_cost'} & cap_methods), + # SQL validation is implemented in external validator classes keyed by engine name + 'sql_validation': engine_attr in {'presto', 'postgresql'}, + 'user_impersonation': bool( + {'impersonate_user', 'update_impersonation_config', 'get_url_for_impersonation'} & cap_methods + ), } + # Tell the JS layer which output fields were populated from the + # BaseEngineSpec default because the source assignment was an + # unevaluable expression; those get overridden from existing JSON. + unresolved_fields = sorted( + CAP_ATTR_TO_OUTPUT_FIELD[attr] + for attr in unresolved_caps + if attr in CAP_ATTR_TO_OUTPUT_FIELD + ) + if unresolved_fields: + entry['_unresolved_cap_fields'] = unresolved_fields + + databases[display_name] = entry + if errors and not databases: print(json.dumps({"error": "Parse errors", "details": errors, "debug": debug_info}), file=sys.stderr) @@ -851,24 +1054,52 @@ function loadExistingData() { } } +/** + * Fall back to the previously-generated databases.json for capability flags + * whose source assignment couldn't be statically resolved (e.g. + * `allows_joins = is_feature_enabled("DRUID_JOINS")`). The Python extractor + * flags these via the internal `_unresolved_cap_fields` marker; without this + * fallback those fields would silently inherit the BaseEngineSpec default + * and disagree with runtime behavior. The marker is stripped before output. + */ +function fallbackUnresolvedCaps(newDatabases, existingData) { + for (const [name, db] of Object.entries(newDatabases)) { + const unresolved = db._unresolved_cap_fields; + if (!unresolved || unresolved.length === 0) { + delete db._unresolved_cap_fields; + continue; + } + const existingDb = existingData?.databases?.[name]; + if (existingDb) { + for (const field of unresolved) { + if (existingDb[field] !== undefined) { + db[field] = existingDb[field]; + } + } + } + delete db._unresolved_cap_fields; + } + return newDatabases; +} + /** * Merge new documentation with existing diagnostics - * Preserves score, time_grains, and feature flags from existing data + * Preserves score, max_score, and time_grains from existing data (these require + * Flask context to generate and cannot be derived from static source analysis). + * Capability flags (joins, supports_catalog, etc.) are NOT preserved here — they + * are read fresh from the Python engine spec source by extractEngineSpecMetadata(), + * with a separate fallback for expression-based assignments (see fallbackUnresolvedCaps). */ function mergeWithExistingDiagnostics(newDatabases, existingData) { if (!existingData?.databases) return newDatabases; - const diagnosticFields = [ - 'score', 'max_score', 'time_grains', 'joins', 'subqueries', - 'supports_dynamic_schema', 'supports_catalog', 'supports_dynamic_catalog', - 'ssh_tunneling', 'query_cancelation', 'supports_file_upload', - 'user_impersonation', 'query_cost_estimation', 'sql_validation' - ]; + // Only preserve fields that require Flask/runtime context to generate + const diagnosticFields = ['score', 'max_score', 'time_grains']; for (const [name, db] of Object.entries(newDatabases)) { const existingDb = existingData.databases[name]; if (existingDb && existingDb.score > 0) { - // Preserve diagnostics from existing data + // Preserve score/time_grain diagnostics from existing data for (const field of diagnosticFields) { if (existingDb[field] !== undefined) { db[field] = existingDb[field]; @@ -879,7 +1110,7 @@ function mergeWithExistingDiagnostics(newDatabases, existingData) { const preserved = Object.values(newDatabases).filter(d => d.score > 0).length; if (preserved > 0) { - console.log(`Preserved diagnostics for ${preserved} databases from existing data`); + console.log(`Preserved score/time_grains for ${preserved} databases from existing data`); } return newDatabases; @@ -927,6 +1158,12 @@ async function main() { databases = mergeWithExistingDiagnostics(databases, existingData); } + // For cap flags assigned via unevaluable expressions (e.g. + // `is_feature_enabled(...)`), prefer the value from a previously-generated + // JSON. Runs regardless of scores since it addresses static-analysis gaps, + // not missing Flask diagnostics. Always strips the internal marker. + databases = fallbackUnresolvedCaps(databases, existingData); + // Extract and merge custom_errors for troubleshooting documentation const customErrors = extractCustomErrors(); mergeCustomErrors(databases, customErrors); diff --git a/docs/scripts/generate-superset-components.mjs b/docs/scripts/generate-superset-components.mjs index b3de2ba1dad..2244631d7ca 100644 --- a/docs/scripts/generate-superset-components.mjs +++ b/docs/scripts/generate-superset-components.mjs @@ -185,6 +185,76 @@ const SKIP_STORIES = [ ]; +/** + * Collect the set of value names exported from a barrel file, following + * `export * from './X'` re-exports one level deep. Used to verify that a + * component the docs claim is importable is actually re-exported from the + * public package entry point. + */ +function collectBarrelExports(barrelPath, visited = new Set()) { + const exports = new Set(); + if (!fs.existsSync(barrelPath) || visited.has(barrelPath)) return exports; + visited.add(barrelPath); + + const content = fs.readFileSync(barrelPath, 'utf8'); + + for (const m of content.matchAll(/export\s+\{([\s\S]*?)\}(?:\s+from\s+['"][^'"]+['"])?/g)) { + for (const part of m[1].split(',')) { + const cleaned = part.trim().replace(/^type\s+/, ''); + if (!cleaned) continue; + const asMatch = cleaned.match(/(?:^|\s)as\s+([A-Za-z_]\w*)\s*$/); + if (asMatch) { + exports.add(asMatch[1]); + } else { + const plain = cleaned.match(/^([A-Za-z_]\w*)\s*$/); + if (plain) exports.add(plain[1]); + } + } + } + + for (const m of content.matchAll( + /export\s+(?:const|let|var|function|class)\s+([A-Za-z_]\w*)/g + )) { + exports.add(m[1]); + } + + for (const m of content.matchAll(/export\s+\*\s+from\s+['"]([^'"]+)['"]/g)) { + const target = m[1]; + if (!target.startsWith('.')) continue; + const baseDir = path.dirname(barrelPath); + const candidates = [ + path.resolve(baseDir, `${target}.ts`), + path.resolve(baseDir, `${target}.tsx`), + path.resolve(baseDir, target, 'index.ts'), + path.resolve(baseDir, target, 'index.tsx'), + ]; + const resolved = candidates.find(p => fs.existsSync(p)); + if (resolved) { + for (const name of collectBarrelExports(resolved, visited)) { + exports.add(name); + } + } + } + + return exports; +} + +const SOURCE_PUBLIC_EXPORTS = new Map(); +function getPublicExports(sourceConfig) { + if (SOURCE_PUBLIC_EXPORTS.has(sourceConfig)) { + return SOURCE_PUBLIC_EXPORTS.get(sourceConfig); + } + const sourceDir = path.join(FRONTEND_DIR, sourceConfig.path); + const candidates = [ + path.join(sourceDir, 'index.ts'), + path.join(sourceDir, 'index.tsx'), + ]; + const barrel = candidates.find(p => fs.existsSync(p)); + const result = barrel ? collectBarrelExports(barrel) : null; + SOURCE_PUBLIC_EXPORTS.set(sourceConfig, result); + return result; +} + /** * Recursively find all story files in a directory */ @@ -1048,6 +1118,28 @@ function generateMDX(component, storyContent) { // Use resolved import path if available, otherwise fall back to source config const componentImportPath = resolvedImportPath || sourceConfig.importPrefix; + // The displayed import in user docs should reflect the public package path, + // not the internal storybook alias. + const docImportPath = sourceConfig.importPrefix.startsWith('@superset/') + ? sourceConfig.docImportPrefix + : componentImportPath; + + // When the source uses the internal storybook alias, the public package + // re-exports components as named exports (e.g. `export { default as Foo }`), + // so users must use named imports even when the story uses a default import. + const useDefaultImport = + isDefaultExport && !sourceConfig.importPrefix.startsWith('@superset/'); + + // Only render the import snippet if the component is actually re-exported + // from the public package barrel; otherwise the snippet would mislead users + // copy-pasting it (e.g. TableCollection, which has a story but is not + // re-exported from `@superset-ui/core/components`). + const publicExports = sourceConfig.importPrefix.startsWith('@superset/') + ? getPublicExports(sourceConfig) + : null; + const isPubliclyExported = + !publicExports || publicExports.has(componentName); + // Determine component description based on source const defaultDesc = sourceConfig.category === 'ui' ? `The ${componentName} component from Superset's UI library.` @@ -1134,13 +1226,13 @@ ${Object.keys(args).length > 0 ? `## Props |------|------|---------|-------------| ${propsTable}` : ''} -## Import +${isPubliclyExported ? `## Import \`\`\`tsx -${isDefaultExport ? `import ${componentName} from '${componentImportPath}';` : `import { ${componentName} } from '${componentImportPath}';`} +${useDefaultImport ? `import ${componentName} from '${docImportPath}';` : `import { ${componentName} } from '${docImportPath}';`} \`\`\` ---- +---` : '---'} :::tip[Improve this page] This documentation is auto-generated from the component's Storybook story. diff --git a/docs/src/components/GetStartedSplitButton.tsx b/docs/src/components/GetStartedSplitButton.tsx new file mode 100644 index 00000000000..9f4a541884c --- /dev/null +++ b/docs/src/components/GetStartedSplitButton.tsx @@ -0,0 +1,155 @@ +/** + * 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 { DownOutlined } from '@ant-design/icons'; +import Link from '@docusaurus/Link'; +import { Dropdown } from 'antd'; +import type { MenuProps } from 'antd'; +import styled from '@emotion/styled'; +import { mq } from '../utils.js'; + +const getStartedMenuItems: MenuProps['items'] = [ + { key: 'users', label: Users }, + { key: 'admins', label: Admins }, + { key: 'developers', label: Developers }, +]; + +const Root = styled.div<{ $variant: 'hero' | 'navbar' }>` + display: flex; + align-items: stretch; + border-radius: 10px; + overflow: hidden; + position: relative; + z-index: 2; + font-weight: bold; + + ${({ $variant }) => + $variant === 'hero' + ? ` + width: 208px; + margin: 15px auto 0; + font-size: 20px; + ${mq[1]} { + font-size: 19px; + width: 214px; + } + ` + : ` + width: 176px; + margin-right: 20px; + font-size: 18px; + `} + + .split-main { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + color: #ffffff; + text-decoration: none; + min-width: 0; + ${({ $variant }) => + $variant === 'hero' + ? `padding: 10px 10px;` + : `padding: 7px 8px;`} + } + + .split-main:hover { + color: #ffffff; + } + + .split-divider { + width: 1px; + flex-shrink: 0; + align-self: stretch; + background: rgba(255, 255, 255, 0.38); + ${({ $variant }) => + $variant === 'hero' + ? `margin: 8px 0;` + : `margin: 6px 0;`} + } + + .split-dropdown-trigger { + flex-shrink: 0; + border: none; + padding: 0; + margin: 0; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + background: transparent; + color: #ffffff; + ${({ $variant }) => + $variant === 'hero' + ? ` + width: 44px; + font-size: 11px; + ${mq[1]} { + width: 46px; + } + ` + : ` + width: 38px; + font-size: 10px; + `} + } + + .split-dropdown-trigger:hover { + color: #ffffff; + } +`; + +export type GetStartedSplitButtonProps = { + variant: 'hero' | 'navbar'; + /** Classes for the outer control (include default-button-theme get-started-split) */ + rootClassName: string; +}; + +export default function GetStartedSplitButton({ + variant, + rootClassName, +}: GetStartedSplitButtonProps) { + const menuClassName = `get-started-split-dropdown-menu get-started-split-dropdown-menu--${variant}`; + + return ( + + + Get Started + + + + + + + ); +} diff --git a/docs/src/data/databases.json b/docs/src/data/databases.json index 38914dd7868..8a766c481c8 100644 --- a/docs/src/data/databases.json +++ b/docs/src/data/databases.json @@ -1,95 +1,18 @@ { - "generated": "2026-02-24T20:28:17.222Z", + "generated": "2026-04-17T17:08:35.132Z", "statistics": { - "totalDatabases": 72, - "withDocumentation": 72, - "withConnectionString": 72, - "withDrivers": 36, - "withAuthMethods": 4, - "supportsJoins": 68, - "supportsSubqueries": 69, - "supportsDynamicSchema": 15, - "supportsCatalog": 9, - "averageScore": 31, + "totalDatabases": 80, + "withDocumentation": 80, + "withConnectionString": 80, + "withDrivers": 28, + "withAuthMethods": 5, + "supportsJoins": 74, + "supportsSubqueries": 77, + "supportsDynamicSchema": 29, + "supportsCatalog": 20, + "averageScore": 54, "maxScore": 201, "byCategory": { - "Other Databases": [ - "Arc", - "Shillelagh", - "Superset meta database" - ], - "Proprietary": [ - "Arc", - "Amazon Athena", - "Google BigQuery", - "Databend", - "IBM Db2", - "Denodo", - "Dremio", - "Amazon DynamoDB", - "Exasol", - "Firebolt", - "SAP HANA", - "Hologres", - "IBM Db2 for i", - "Azure Data Explorer", - "MongoDB", - "Microsoft SQL Server", - "Azure Synapse", - "IBM Netezza Performance Server", - "Ocient", - "Oracle", - "Amazon Redshift", - "SingleStore", - "Snowflake", - "SAP Sybase", - "Teradata", - "Vertica" - ], - "Cloud Data Warehouses": [ - "Ascend", - "Cloudflare D1", - "Databend", - "Databricks", - "MotherDuck", - "Firebolt", - "Hologres", - "Azure Synapse", - "Snowflake", - "YugabyteDB" - ], - "Analytical Databases": [ - "Ascend", - "Google BigQuery", - "ClickHouse", - "Databend", - "Databricks", - "Apache Doris", - "DuckDB", - "MotherDuck", - "Exasol", - "Firebolt", - "Hologres", - "Azure Data Explorer", - "Apache Kylin", - "Azure Synapse", - "Ocient", - "Apache Phoenix", - "Amazon Redshift", - "RisingWave", - "SingleStore", - "Snowflake", - "StarRocks", - "TimescaleDB", - "Vertica" - ], - "Hosted Open Source": [ - "Ascend", - "Cloudflare D1", - "Databricks", - "MotherDuck", - "Google Sheets" - ], "Cloud - AWS": [ "Amazon Athena", "Amazon DynamoDB", @@ -97,77 +20,128 @@ ], "Query Engines": [ "Amazon Athena", - "Databricks Interactive Cluster", - "Denodo", - "Dremio", "Apache Drill", "Apache Hive", "Apache Impala", - "Presto", "Apache Spark SQL", + "Databricks Interactive Cluster", + "Denodo", + "Dremio", + "Presto", "Trino" ], - "Traditional RDBMS": [ - "Aurora MySQL (Data API)", - "Aurora PostgreSQL (Data API)", - "Aurora MySQL", - "Aurora PostgreSQL", - "CockroachDB", - "Cloudflare D1", + "Proprietary": [ + "Amazon Athena", + "Amazon DynamoDB", + "Amazon Redshift", + "Arc", + "Azure Data Explorer", + "Azure Synapse", + "Databend", + "Denodo", + "Dremio", + "Exasol", + "Firebolt", + "Google BigQuery", + "Google Datastore", + "Hologres", "IBM Db2", - "Firebird", - "Greenplum", - "SAP HANA", "IBM Db2 for i", - "MariaDB", - "MonetDB", - "Microsoft SQL Server", - "MySQL", "IBM Netezza Performance Server", - "OceanBase", + "Microsoft SQL Server", + "MongoDB", + "Ocient", "Oracle", - "PostgreSQL", - "SQLite", + "SAP HANA", "SAP Sybase", + "SingleStore", + "Snowflake", "Teradata", - "YDB", - "YugabyteDB" + "Vertica" + ], + "Search & NoSQL": [ + "Amazon DynamoDB", + "Apache Solr", + "Couchbase", + "Elasticsearch", + "Google Datastore", + "MongoDB", + "Parseable" + ], + "Analytical Databases": [ + "Amazon Redshift", + "Apache Doris", + "Apache Kylin", + "Apache Phoenix", + "Ascend", + "Azure Data Explorer", + "Azure Synapse", + "ClickHouse", + "Databend", + "Databricks", + "DuckDB", + "Exasol", + "Firebolt", + "Google BigQuery", + "Hologres", + "MotherDuck", + "Ocient", + "RisingWave", + "SingleStore", + "Snowflake", + "StarRocks", + "TimescaleDB", + "Vertica" + ], + "Apache Projects": [ + "Apache Doris", + "Apache Drill", + "Apache Druid", + "Apache Hive", + "Apache Impala", + "Apache IoTDB", + "Apache Kylin", + "Apache Phoenix", + "Apache Pinot", + "Apache Solr", + "Apache Spark SQL", + "Databricks Interactive Cluster" ], "Open Source": [ - "Aurora MySQL (Data API)", - "Aurora PostgreSQL (Data API)", + "Apache Doris", + "Apache Drill", + "Apache Druid", + "Apache Hive", + "Apache Impala", + "Apache IoTDB", + "Apache Kylin", + "Apache Phoenix", + "Apache Pinot", + "Apache Solr", + "Apache Spark SQL", "Aurora MySQL", + "Aurora MySQL (Data API)", "Aurora PostgreSQL", + "Aurora PostgreSQL (Data API)", "ClickHouse", "CockroachDB", "Couchbase", "CrateDB", "Databricks Interactive Cluster", - "Apache Doris", - "Apache Drill", - "Apache Druid", "DuckDB", "Elasticsearch", "Firebird", "Greenplum", - "Apache Hive", - "Apache Impala", - "Apache IoTDB", - "Apache Kylin", "MariaDB", "MonetDB", "MySQL", "OceanBase", "Parseable", - "Apache Phoenix", - "Apache Pinot", "PostgreSQL", "Presto", "RisingWave", - "Shillelagh", - "Apache Solr", - "Apache Spark SQL", "SQLite", + "Shillelagh", "StarRocks", "TDengine", "TimescaleDB", @@ -175,144 +149,148 @@ "YDB", "YugabyteDB" ], - "Cloud - Google": [ - "Google BigQuery", - "Google Sheets" - ], - "Search & NoSQL": [ - "Couchbase", - "Amazon DynamoDB", - "Elasticsearch", - "MongoDB", - "Parseable", - "Apache Solr" - ], "Time Series Databases": [ - "CrateDB", "Apache Druid", "Apache IoTDB", "Apache Pinot", + "CrateDB", "TDengine" ], - "Apache Projects": [ - "Databricks Interactive Cluster", - "Apache Doris", - "Apache Drill", - "Apache Druid", - "Apache Hive", - "Apache Impala", - "Apache IoTDB", - "Apache Kylin", - "Apache Phoenix", - "Apache Pinot", - "Apache Solr", - "Apache Spark SQL" + "Other Databases": [ + "Arc", + "Azure Data Explorer (KQL)", + "ClickHouse (sqlalchemy)", + "Databend (legacy)", + "Databricks (legacy)", + "Databricks SQL Endpoint", + "OpenSearch (OpenDistro)", + "Shillelagh", + "Superset meta database", + "base" + ], + "Cloud Data Warehouses": [ + "Ascend", + "Azure Synapse", + "Cloudflare D1", + "Databend", + "Databricks", + "Firebolt", + "Hologres", + "MotherDuck", + "Snowflake", + "YugabyteDB" + ], + "Hosted Open Source": [ + "Ascend", + "Cloudflare D1", + "Databricks", + "Google Sheets", + "MotherDuck" + ], + "Traditional RDBMS": [ + "Aurora MySQL", + "Aurora MySQL (Data API)", + "Aurora PostgreSQL", + "Aurora PostgreSQL (Data API)", + "Cloudflare D1", + "CockroachDB", + "Firebird", + "Greenplum", + "IBM Db2", + "IBM Db2 for i", + "IBM Netezza Performance Server", + "MariaDB", + "Microsoft SQL Server", + "MonetDB", + "MySQL", + "OceanBase", + "Oracle", + "PostgreSQL", + "SAP HANA", + "SAP Sybase", + "SQLite", + "Teradata", + "YDB", + "YugabyteDB" ], "Cloud - Azure": [ "Azure Data Explorer" + ], + "Cloud - Google": [ + "Google BigQuery", + "Google Datastore", + "Google Sheets" ] } }, "databases": { - "Arc": { - "engine": "arc", - "engine_name": "Arc", - "module": "arc", - "documentation": { - "description": "Arc is a data platform with multiple connection options.", - "categories": [ - "OTHER", - "PROPRIETARY" - ], - "pypi_packages": [ - "arc-superset-arrow" - ], - "connection_string": "arc+arrow://{api_key}@{hostname}:{port}/{database}", - "parameters": { - "api_key": "Arc API key", - "hostname": "Arc hostname", - "port": "Arc port", - "database": "Database name" - }, - "drivers": [ - { - "name": "Apache Arrow (Recommended)", - "pypi_package": "arc-superset-arrow", - "connection_string": "arc+arrow://{api_key}@{hostname}:{port}/{database}", - "is_recommended": true, - "notes": "Recommended for production. Provides 3-5x better performance using Apache Arrow IPC." - }, - { - "name": "JSON", - "pypi_package": "arc-superset-dialect", - "connection_string": "arc+json://{api_key}@{hostname}:{port}/{database}", - "is_recommended": false - } - ], - "notes": "Arc supports multiple databases (schemas) within a single instance. Each Arc database appears as a schema in SQL Lab." - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Ascend": { - "engine": "ascend", - "engine_name": "Ascend", - "module": "ascend", - "documentation": { - "description": "Ascend.io is a data automation platform for building data pipelines.", - "logo": "ascend.webp", - "homepage_url": "https://www.ascend.io/", - "pypi_packages": [ - "impyla", - "impyla" - ], - "connection_string": "ascend://{username}:{password}@{hostname}:{port}/{database}?auth_mechanism=PLAIN;use_ssl=true", - "default_port": 21050, - "categories": [ - "CLOUD_DATA_WAREHOUSES", - "ANALYTICAL_DATABASES", - "HOSTED_OPEN_SOURCE" - ] - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, "Amazon Athena": { - "engine": "amazon_athena", - "engine_name": "Amazon Athena", - "module": "athena", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.athena", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": false, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": false, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 30, + "max_score": 201, "documentation": { "description": "Amazon Athena is an interactive query service for analyzing data in S3 using SQL.", "logo": "amazon-athena.jpg", "homepage_url": "https://aws.amazon.com/athena/", "categories": [ - "CLOUD_AWS", - "QUERY_ENGINES", - "PROPRIETARY" + "Cloud - AWS", + "Query Engines", + "Proprietary" ], "pypi_packages": [ "pyathena[pandas]" @@ -346,6 +324,7 @@ } ], "notes": "URL-encode special characters in s3_staging_dir (e.g., s3:// becomes s3%3A//).", + "category": "Cloud - AWS", "custom_errors": [ { "regex_name": "SYNTAX_ERROR_REGEX", @@ -359,546 +338,106 @@ } ] }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, + "engine": "awsathena", + "engine_name": "Amazon Athena", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": true, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, - "Aurora MySQL (Data API)": { - "engine": "aurora_mysql_(data_api)", - "engine_name": "Aurora MySQL (Data API)", - "module": "aurora", - "documentation": { - "description": "MySQL is a popular open-source relational database.", - "logo": "mysql.png", - "homepage_url": "https://www.mysql.com/", - "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "mysqlclient" - ], - "connection_string": "mysql://{username}:{password}@{host}/{database}", - "default_port": 3306, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "localhost, 127.0.0.1, IP address, or hostname", - "database": "Database name" - }, - "host_examples": [ - { - "platform": "Localhost", - "host": "localhost or 127.0.0.1" - }, - { - "platform": "Docker on Linux", - "host": "172.18.0.1" - }, - { - "platform": "Docker on macOS", - "host": "docker.for.mac.host.internal" - }, - { - "platform": "On-premise", - "host": "IP address or hostname" - } - ], - "drivers": [ - { - "name": "mysqlclient", - "pypi_package": "mysqlclient", - "connection_string": "mysql://{username}:{password}@{host}/{database}", - "is_recommended": true, - "notes": "Recommended driver. May fail with caching_sha2_password auth." - }, - { - "name": "mysql-connector-python", - "pypi_package": "mysql-connector-python", - "connection_string": "mysql+mysqlconnector://{username}:{password}@{host}/{database}", - "is_recommended": false, - "notes": "Required for newer MySQL databases using caching_sha2_password authentication." - } - ] - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Aurora PostgreSQL (Data API)": { - "engine": "aurora_postgresql_(data_api)", - "engine_name": "Aurora PostgreSQL (Data API)", - "module": "aurora", - "documentation": { - "description": "PostgreSQL is an advanced open-source relational database.", - "logo": "postgresql.svg", - "homepage_url": "https://www.postgresql.org/", - "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "psycopg2" - ], - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", - "default_port": 5432, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "For localhost: localhost or 127.0.0.1. For AWS: endpoint URL", - "port": "Default 5432", - "database": "Database name" - }, - "notes": "The psycopg2 library comes bundled with Superset Docker images.", - "connection_examples": [ - { - "description": "Basic connection", - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}" - }, - { - "description": "With SSL required", - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}?sslmode=require" - } - ], - "docs_url": "https://www.postgresql.org/docs/", - "sqlalchemy_docs_url": "https://docs.sqlalchemy.org/en/13/dialects/postgresql.html" - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Aurora MySQL": { - "engine": "aurora_mysql", - "engine_name": "Aurora MySQL", - "module": "aurora", - "documentation": { - "description": "MySQL is a popular open-source relational database.", - "logo": "mysql.png", - "homepage_url": "https://www.mysql.com/", - "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "mysqlclient" - ], - "connection_string": "mysql://{username}:{password}@{host}/{database}", - "default_port": 3306, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "localhost, 127.0.0.1, IP address, or hostname", - "database": "Database name" - }, - "host_examples": [ - { - "platform": "Localhost", - "host": "localhost or 127.0.0.1" - }, - { - "platform": "Docker on Linux", - "host": "172.18.0.1" - }, - { - "platform": "Docker on macOS", - "host": "docker.for.mac.host.internal" - }, - { - "platform": "On-premise", - "host": "IP address or hostname" - } - ], - "drivers": [ - { - "name": "mysqlclient", - "pypi_package": "mysqlclient", - "connection_string": "mysql://{username}:{password}@{host}/{database}", - "is_recommended": true, - "notes": "Recommended driver. May fail with caching_sha2_password auth." - }, - { - "name": "mysql-connector-python", - "pypi_package": "mysql-connector-python", - "connection_string": "mysql+mysqlconnector://{username}:{password}@{host}/{database}", - "is_recommended": false, - "notes": "Required for newer MySQL databases using caching_sha2_password authentication." - } - ] - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Aurora PostgreSQL": { - "engine": "aurora_postgresql", - "engine_name": "Aurora PostgreSQL", - "module": "aurora", - "documentation": { - "description": "PostgreSQL is an advanced open-source relational database.", - "logo": "postgresql.svg", - "homepage_url": "https://www.postgresql.org/", - "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "psycopg2" - ], - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", - "default_port": 5432, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "For localhost: localhost or 127.0.0.1. For AWS: endpoint URL", - "port": "Default 5432", - "database": "Database name" - }, - "notes": "The psycopg2 library comes bundled with Superset Docker images.", - "connection_examples": [ - { - "description": "Basic connection", - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}" - }, - { - "description": "With SSL required", - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}?sslmode=require" - } - ], - "docs_url": "https://www.postgresql.org/docs/", - "sqlalchemy_docs_url": "https://docs.sqlalchemy.org/en/13/dialects/postgresql.html" - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Google BigQuery": { - "engine": "google_bigquery", - "engine_name": "Google BigQuery", - "module": "bigquery", - "documentation": { - "description": "Google BigQuery is a serverless, highly scalable data warehouse.", - "logo": "google-big-query.svg", - "homepage_url": "https://cloud.google.com/bigquery/", - "categories": [ - "CLOUD_GCP", - "ANALYTICAL_DATABASES", - "PROPRIETARY" - ], - "pypi_packages": [ - "sqlalchemy-bigquery" - ], - "connection_string": "bigquery://{project_id}", - "install_instructions": "echo \"sqlalchemy-bigquery\" >> ./docker/requirements-local.txt", - "authentication_methods": [ - { - "name": "Service Account JSON", - "description": "Upload service account credentials JSON or paste in Secure Extra", - "secure_extra": { - "credentials_info": { - "type": "service_account", - "project_id": "...", - "private_key_id": "...", - "private_key": "...", - "client_email": "...", - "client_id": "...", - "auth_uri": "...", - "token_uri": "..." - } - } - } - ], - "notes": "Create a Service Account via GCP console with access to BigQuery datasets. For CSV/Excel uploads, also install pandas_gbq.", - "warnings": [ - "Google BigQuery Python SDK is not compatible with gevent. Use a worker type other than gevent when deploying with gunicorn." - ], - "docs_url": "https://github.com/googleapis/python-bigquery-sqlalchemy", - "custom_errors": [ - { - "regex_name": "CONNECTION_DATABASE_PERMISSIONS_REGEX", - "message_template": "Unable to connect. Verify that the following roles are set on the service account: \"BigQuery Data Viewer\", \"BigQuery Metadata Viewer\", \"BigQuery Job User\" and the following permissions are set \"bigquery.readsessions.create\", \"bigquery.readsessions.getData\"", - "error_type": "CONNECTION_DATABASE_PERMISSIONS_ERROR", - "category": "Permissions", - "description": "Insufficient permissions", - "issue_codes": [ - 1017 - ] - }, - { - "regex_name": "TABLE_DOES_NOT_EXIST_REGEX", - "message_template": "The table \"%(table)s\" does not exist. A valid table must be used to run this query.", - "error_type": "TABLE_DOES_NOT_EXIST_ERROR", - "category": "Query", - "description": "Table not found", - "issue_codes": [ - 1003, - 1005 - ] - }, - { - "regex_name": "COLUMN_DOES_NOT_EXIST_REGEX", - "message_template": "We can't seem to resolve column \"%(column)s\" at line %(location)s.", - "error_type": "COLUMN_DOES_NOT_EXIST_ERROR", - "category": "Query", - "description": "Column not found", - "issue_codes": [ - 1003, - 1004 - ] - }, - { - "regex_name": "SCHEMA_DOES_NOT_EXIST_REGEX", - "message_template": "The schema \"%(schema)s\" does not exist. A valid schema must be used to run this query.", - "error_type": "SCHEMA_DOES_NOT_EXIST_ERROR", - "category": "Query", - "description": "Schema not found", - "issue_codes": [ - 1003, - 1016 - ] - }, - { - "regex_name": "SYNTAX_ERROR_REGEX", - "message_template": "Please check your query for syntax errors at or near \"%(syntax_error)s\". Then, try running your query again.", - "error_type": "SYNTAX_ERROR", - "category": "Query", - "description": "SQL syntax error", - "issue_codes": [ - 1030 - ] - } - ] - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "ClickHouse": { - "engine": "clickhouse", - "engine_name": "ClickHouse", - "module": "clickhouse", - "documentation": { - "description": "ClickHouse is an open-source column-oriented database for real-time analytics using SQL. It's known for extremely fast query performance on large datasets.", - "logo": "clickhouse.png", - "homepage_url": "https://clickhouse.com/", - "categories": [ - "ANALYTICAL_DATABASES", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "clickhouse-connect>=0.6.8" - ], - "connection_string": "clickhousedb://{username}:{password}@{host}:{port}/{database}", - "default_port": 8123, - "drivers": [ - { - "name": "clickhouse-connect (Recommended)", - "pypi_package": "clickhouse-connect>=0.6.8", - "connection_string": "clickhousedb://{username}:{password}@{host}:{port}/{database}", - "is_recommended": true, - "notes": "Official ClickHouse Python driver with native protocol support." - }, - { - "name": "clickhouse-sqlalchemy (Legacy)", - "pypi_package": "clickhouse-sqlalchemy", - "connection_string": "clickhouse://{username}:{password}@{host}:{port}/{database}", - "is_recommended": false, - "notes": "Older driver using HTTP interface. Use clickhouse-connect for new deployments." - } - ], - "connection_examples": [ - { - "description": "Altinity Cloud", - "connection_string": "clickhousedb://demo:demo@github.demo.trial.altinity.cloud/default?secure=true" - }, - { - "description": "Local (no auth, no SSL)", - "connection_string": "clickhousedb://localhost/default" - } - ], - "install_instructions": "echo \"clickhouse-connect>=0.6.8\" >> ./docker/requirements-local.txt", - "compatible_databases": [ - { - "name": "ClickHouse Cloud", - "description": "ClickHouse Cloud is the official fully-managed cloud service for ClickHouse. It provides automatic scaling, built-in backups, and enterprise security features.", - "logo": "clickhouse.png", - "homepage_url": "https://clickhouse.cloud/", - "categories": [ - "ANALYTICAL_DATABASES", - "CLOUD_DATA_WAREHOUSES", - "HOSTED_OPEN_SOURCE" - ], - "pypi_packages": [ - "clickhouse-connect>=0.6.8" - ], - "connection_string": "clickhousedb://{username}:{password}@{host}:8443/{database}?secure=true", - "parameters": { - "username": "ClickHouse Cloud username", - "password": "ClickHouse Cloud password", - "host": "Your ClickHouse Cloud hostname", - "database": "Database name (default)" - }, - "docs_url": "https://clickhouse.com/docs/en/cloud" - }, - { - "name": "Altinity.Cloud", - "description": "Altinity.Cloud is a managed ClickHouse service providing Kubernetes-native deployments with enterprise support.", - "logo": "altinity.png", - "homepage_url": "https://altinity.cloud/", - "categories": [ - "ANALYTICAL_DATABASES", - "CLOUD_DATA_WAREHOUSES", - "HOSTED_OPEN_SOURCE" - ], - "pypi_packages": [ - "clickhouse-connect>=0.6.8" - ], - "connection_string": "clickhousedb://{username}:{password}@{host}/{database}?secure=true", - "docs_url": "https://docs.altinity.com/" - } - ] - }, + "Amazon DynamoDB": { "time_grains": { - "SECOND": false, + "SECOND": true, "FIVE_SECONDS": false, "THIRTY_SECONDS": false, "MINUTE": true, - "FIVE_MINUTES": true, - "TEN_MINUTES": true, - "FIFTEEN_MINUTES": true, - "THIRTY_MINUTES": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, "HALF_HOUR": false, "HOUR": true, "SIX_HOURS": false, "DAY": true, "WEEK": true, - "WEEK_STARTING_SUNDAY": false, - "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": false, - "WEEK_ENDING_SUNDAY": false, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": true, "MONTH": true, "QUARTER": true, "QUARTER_YEAR": false, "YEAR": true }, - "score": 51, - "max_score": 201, + "module": "superset.db_engine_specs.dynamodb", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "CockroachDB": { - "engine": "cockroachdb", - "engine_name": "CockroachDB", - "module": "cockroachdb", + "sql_validation": false, + "score": 32, + "max_score": 201, "documentation": { - "description": "CockroachDB is a distributed SQL database built for cloud applications.", - "logo": "cockroachdb.png", - "homepage_url": "https://www.cockroachlabs.com/", - "pypi_packages": [ - "psycopg2", - "cockroachdb" - ], - "connection_string": "cockroachdb://root@{hostname}:{port}/{database}?sslmode=disable", - "default_port": 26257, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "For localhost: localhost or 127.0.0.1. For AWS: endpoint URL", - "port": "Default 5432", - "database": "Database name" - }, - "notes": "The psycopg2 library comes bundled with Superset Docker images.", - "connection_examples": [ - { - "description": "Basic connection", - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}" - }, - { - "description": "With SSL required", - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}?sslmode=require" - } - ], - "docs_url": "https://github.com/cockroachdb/sqlalchemy-cockroachdb", - "sqlalchemy_docs_url": "https://docs.sqlalchemy.org/en/13/dialects/postgresql.html", + "description": "Amazon DynamoDB is a serverless NoSQL database with SQL via PartiQL.", + "logo": "aws.png", + "homepage_url": "https://aws.amazon.com/dynamodb/", "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" - ] + "Cloud - AWS", + "Search & NoSQL", + "Proprietary" + ], + "pypi_packages": [ + "pydynamodb" + ], + "connection_string": "dynamodb://{aws_access_key_id}:{aws_secret_access_key}@dynamodb.{region}.amazonaws.com:443?connector=superset", + "parameters": { + "aws_access_key_id": "AWS access key ID", + "aws_secret_access_key": "AWS secret access key", + "region": "AWS region (e.g., us-east-1)" + }, + "notes": "Uses PartiQL for SQL queries. Requires connector=superset parameter.", + "docs_url": "https://github.com/passren/PyDynamoDB", + "category": "Cloud - AWS" }, + "engine": "dynamodb", + "engine_name": "Amazon DynamoDB", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Amazon Redshift": { "time_grains": { "SECOND": true, "FIVE_SECONDS": true, @@ -922,53 +461,3038 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 94, - "max_score": 201, + "module": "superset.db_engine_specs.redshift", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": true, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 127, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": false, - "query_cost_estimation": true, - "sql_validation": false - }, - "Couchbase": { - "engine": "couchbase", - "engine_name": "Couchbase", - "module": "couchbase", + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 44, + "max_score": 201, "documentation": { - "description": "Couchbase is a distributed NoSQL document database with SQL++ support.", - "logo": "couchbase.svg", - "homepage_url": "https://www.couchbase.com/", + "description": "Amazon Redshift is a fully managed data warehouse service.", + "logo": "redshift.png", + "homepage_url": "https://aws.amazon.com/redshift/", "categories": [ - "SEARCH_NOSQL", - "OPEN_SOURCE" + "Cloud - AWS", + "Analytical Databases", + "Proprietary" ], "pypi_packages": [ - "couchbase-sqlalchemy" + "sqlalchemy-redshift" ], - "connection_string": "couchbase://{username}:{password}@{host}:{port}?ssl=true", - "default_port": 8091, + "connection_string": "redshift+psycopg2://{username}:{password}@{host}:5439/{database}", + "default_port": 5439, "parameters": { - "username": "Couchbase username", - "password": "Couchbase password", - "host": "Couchbase host or connection string for cloud", - "port": "Couchbase port (default 8091)", - "database": "Couchbase database/bucket name" + "username": "Database username", + "password": "Database password", + "host": "AWS Endpoint", + "port": "Default 5439", + "database": "Database name" }, "drivers": [ { - "name": "couchbase-sqlalchemy", - "pypi_package": "couchbase-sqlalchemy", - "connection_string": "couchbase://{username}:{password}@{host}:{port}?ssl=true", + "name": "psycopg2", + "pypi_package": "psycopg2", + "connection_string": "redshift+psycopg2://{username}:{password}@{host}:5439/{database}", "is_recommended": true + }, + { + "name": "redshift_connector", + "pypi_package": "redshift_connector", + "connection_string": "redshift+redshift_connector://{username}:{password}@{host}:5439/{database}", + "is_recommended": false, + "notes": "Supports IAM-based credentials for clusters and serverless." + } + ], + "authentication_methods": [ + { + "name": "IAM Credentials (Cluster)", + "description": "Use IAM-based temporary database credentials for Redshift clusters", + "requirements": "IAM role must have redshift:GetClusterCredentials permission", + "connection_string": "redshift+redshift_connector://", + "engine_parameters": { + "connect_args": { + "iam": true, + "database": "", + "cluster_identifier": "", + "db_user": "" + } + } + }, + { + "name": "IAM Role (Serverless)", + "description": "Authenticate using the IAM role attached to the environment (EC2 instance profile, ECS task role, etc.). No credentials needed.", + "requirements": "The attached IAM role must have redshift-serverless:GetCredentials and redshift-serverless:GetWorkgroup permissions.", + "connection_string": "redshift+redshift_connector://", + "engine_parameters": { + "connect_args": { + "iam": true, + "is_serverless": true, + "serverless_acct_id": "", + "serverless_work_group": "", + "database": "", + "user": "IAMR:" + } + } + }, + { + "name": "IAM Access Key (Serverless)", + "description": "Authenticate using explicit AWS access key and secret. Suitable for local development or CI environments without an attached IAM role.", + "requirements": "The IAM user must have redshift-serverless:GetCredentials and redshift-serverless:GetWorkgroup permissions.", + "connection_string": "redshift+redshift_connector://", + "engine_parameters": { + "connect_args": { + "iam": true, + "is_serverless": true, + "serverless_acct_id": "", + "serverless_work_group": "", + "database": "", + "host": "", + "port": 5439, + "region": "", + "access_key_id": "", + "secret_access_key": "" + } + } + } + ], + "category": "Cloud - AWS", + "custom_errors": [ + { + "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", + "message_template": "Either the username \"%(username)s\" or the password is incorrect.", + "error_type": "CONNECTION_ACCESS_DENIED_ERROR", + "category": "Authentication", + "description": "Access denied", + "issue_codes": [ + 1014, + 1015 + ], + "invalid_fields": [ + "username", + "password" + ] + }, + { + "regex_name": "CONNECTION_INVALID_HOSTNAME_REGEX", + "message_template": "The hostname \"%(hostname)s\" cannot be resolved.", + "error_type": "CONNECTION_INVALID_HOSTNAME_ERROR", + "category": "Connection", + "description": "Invalid hostname", + "issue_codes": [ + 1007 + ], + "invalid_fields": [ + "host" + ] + }, + { + "regex_name": "CONNECTION_PORT_CLOSED_REGEX", + "message_template": "Port %(port)s on hostname \"%(hostname)s\" refused the connection.", + "error_type": "CONNECTION_PORT_CLOSED_ERROR", + "category": "Connection", + "description": "Port closed or refused", + "issue_codes": [ + 1008 + ], + "invalid_fields": [ + "host", + "port" + ] + }, + { + "regex_name": "CONNECTION_HOST_DOWN_REGEX", + "message_template": "The host \"%(hostname)s\" might be down, and can't be reached on port %(port)s.", + "error_type": "CONNECTION_HOST_DOWN_ERROR", + "category": "Connection", + "description": "Host unreachable", + "issue_codes": [ + 1009 + ], + "invalid_fields": [ + "host", + "port" + ] + }, + { + "regex_name": "CONNECTION_UNKNOWN_DATABASE_REGEX", + "message_template": "We were unable to connect to your database named \"%(database)s\". Please verify your database name and try again.", + "error_type": "CONNECTION_UNKNOWN_DATABASE_ERROR", + "category": "Connection", + "description": "Unknown database", + "issue_codes": [ + 1015 + ], + "invalid_fields": [ + "database" + ] } ] }, + "engine": "redshift", + "engine_name": "Amazon Redshift", + "engine_aliases": [], + "default_driver": "psycopg2", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Apache Doris": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.doris", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 64, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 79, + "max_score": 201, + "documentation": { + "description": "Apache Doris is a high-performance real-time analytical database.", + "logo": "doris.png", + "homepage_url": "https://doris.apache.org/", + "categories": [ + "Apache Projects", + "Analytical Databases", + "Open Source" + ], + "pypi_packages": [ + "pydoris" + ], + "connection_string": "doris://{username}:{password}@{host}:{port}/{catalog}.{database}", + "default_port": 9030, + "parameters": { + "username": "User name", + "password": "Password", + "host": "Doris FE Host", + "port": "Doris FE port", + "catalog": "Catalog name", + "database": "Database name" + }, + "category": "Apache Projects", + "custom_errors": [ + { + "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", + "message_template": "Either the username \"%(username)s\" or the password is incorrect.", + "error_type": "CONNECTION_ACCESS_DENIED_ERROR", + "category": "Authentication", + "description": "Access denied", + "issue_codes": [ + 1014, + 1015 + ], + "invalid_fields": [ + "username", + "password" + ] + }, + { + "regex_name": "CONNECTION_INVALID_HOSTNAME_REGEX", + "message_template": "Unknown Doris server host \"%(hostname)s\".", + "error_type": "CONNECTION_INVALID_HOSTNAME_ERROR", + "category": "Connection", + "description": "Invalid hostname", + "issue_codes": [ + 1007 + ], + "invalid_fields": [ + "host" + ] + }, + { + "regex_name": "CONNECTION_HOST_DOWN_REGEX", + "message_template": "The host \"%(hostname)s\" might be down and can't be reached.", + "error_type": "CONNECTION_HOST_DOWN_ERROR", + "category": "Connection", + "description": "Host unreachable", + "issue_codes": [ + 1009 + ], + "invalid_fields": [ + "host", + "port" + ] + }, + { + "regex_name": "CONNECTION_UNKNOWN_DATABASE_REGEX", + "message_template": "Unable to connect to database \"%(database)s\".", + "error_type": "CONNECTION_UNKNOWN_DATABASE_ERROR", + "category": "Connection", + "description": "Unknown database", + "issue_codes": [ + 1015 + ], + "invalid_fields": [ + "database" + ] + }, + { + "regex_name": "SYNTAX_ERROR_REGEX", + "message_template": "Please check your query for syntax errors near \"%(server_error)s\". Then, try running your query again.", + "error_type": "SYNTAX_ERROR", + "category": "Query", + "description": "SQL syntax error", + "issue_codes": [ + 1030 + ] + } + ] + }, + "engine": "pydoris", + "engine_name": "Apache Doris", + "engine_aliases": [ + "doris" + ], + "default_driver": "pydoris", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Apache Drill": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.drill", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": true, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 50, + "max_score": 201, + "documentation": { + "description": "Apache Drill is a schema-free SQL query engine for Hadoop and NoSQL.", + "logo": "apache-drill.png", + "homepage_url": "https://drill.apache.org/", + "categories": [ + "Apache Projects", + "Query Engines", + "Open Source" + ], + "pypi_packages": [ + "sqlalchemy-drill" + ], + "connection_string": "drill+sadrill://{username}:{password}@{host}:{port}/{storage_plugin}?use_ssl=True", + "default_port": 8047, + "drivers": [ + { + "name": "SQLAlchemy (REST)", + "pypi_package": "sqlalchemy-drill", + "connection_string": "drill+sadrill://{username}:{password}@{host}:{port}/{storage_plugin}?use_ssl=True", + "is_recommended": true + }, + { + "name": "JDBC", + "pypi_package": "sqlalchemy-drill", + "connection_string": "drill+jdbc://{username}:{password}@{host}:{port}", + "is_recommended": false, + "notes": "Requires Drill JDBC Driver installation.", + "docs_url": "https://drill.apache.org/docs/using-the-jdbc-driver/" + }, + { + "name": "ODBC", + "pypi_package": "sqlalchemy-drill", + "is_recommended": false, + "notes": "See Apache Drill documentation for ODBC setup.", + "docs_url": "https://drill.apache.org/docs/installing-the-driver-on-linux/" + } + ], + "connection_examples": [ + { + "description": "Local embedded mode", + "connection_string": "drill+sadrill://localhost:8047/dfs?use_ssl=False" + } + ], + "category": "Apache Projects" + }, + "engine": "drill", + "engine_name": "Apache Drill", + "engine_aliases": [], + "default_driver": "sadrill", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Apache Druid": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": true, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.druid", + "limit_method": 1, + "limit_clause": true, + "joins": false, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 47, + "max_score": 201, + "documentation": { + "description": "Apache Druid is a high performance real-time analytics database.", + "logo": "druid.png", + "homepage_url": "https://druid.apache.org/", + "categories": [ + "Apache Projects", + "Time Series Databases", + "Open Source" + ], + "pypi_packages": [ + "pydruid" + ], + "connection_string": "druid://{username}:{password}@{host}:{port}/druid/v2/sql", + "default_port": 9088, + "parameters": { + "username": "Database username", + "password": "Database password", + "host": "IP address or URL of the host", + "port": "Default 9088" + }, + "ssl_configuration": { + "custom_certificate": "Add certificate in Root Certificate field. pydruid will automatically use https.", + "disable_ssl_verification": { + "engine_params": { + "connect_args": { + "scheme": "https", + "ssl_verify_cert": false + } + } + } + }, + "advanced_features": { + "aggregations": "Define common aggregations in datasource edit view under List Druid Column tab.", + "post_aggregations": "Create metrics with postagg as Metric Type and provide valid JSON post-aggregation definition." + }, + "notes": "A native Druid connector ships with Superset (behind DRUID_IS_ACTIVE flag) but SQLAlchemy connector via pydruid is preferred.", + "compatible_databases": [ + { + "name": "Imply", + "description": "Imply is a fully-managed cloud platform and enterprise distribution built on Apache Druid. It provides real-time analytics with enterprise security and support.", + "logo": "imply.png", + "homepage_url": "https://imply.io/", + "categories": [ + "Time Series Databases", + "Cloud Data Warehouses", + "Hosted Open Source" + ], + "pypi_packages": [ + "pydruid" + ], + "connection_string": "druid://{username}:{password}@{host}/druid/v2/sql", + "docs_url": "https://docs.imply.io/" + } + ], + "category": "Apache Projects" + }, + "engine": "druid", + "engine_name": "Apache Druid", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Apache Hive": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.hive", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": false, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 767, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, + "user_impersonation": true, + "file_upload": true, + "get_extra_table_metadata": true, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": true, + "expand_data": true, + "query_cost_estimation": true, + "sql_validation": false, + "score": 140, + "max_score": 201, + "documentation": { + "description": "Apache Hive is a data warehouse infrastructure built on Hadoop.", + "logo": "apache-hive.svg", + "homepage_url": "https://hive.apache.org/", + "categories": [ + "Apache Projects", + "Query Engines", + "Open Source" + ], + "pypi_packages": [ + "pyhive" + ], + "connection_string": "hive://hive@{hostname}:{port}/{database}", + "default_port": 10000, + "category": "Apache Projects" + }, + "engine": "hive", + "engine_name": "Apache Hive", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Apache Impala": { + "time_grains": { + "SECOND": false, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.impala", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 37, + "max_score": 201, + "documentation": { + "description": "Apache Impala is an open-source massively parallel processing SQL query engine.", + "logo": "apache-impala.png", + "homepage_url": "https://impala.apache.org/", + "categories": [ + "Apache Projects", + "Query Engines", + "Open Source" + ], + "pypi_packages": [ + "impyla" + ], + "connection_string": "impala://{hostname}:{port}/{database}", + "default_port": 21050, + "category": "Apache Projects" + }, + "engine": "impala", + "engine_name": "Apache Impala", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Apache IoTDB": { + "time_grains": { + "SECOND": false, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": false, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": false, + "SIX_HOURS": false, + "DAY": false, + "WEEK": false, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": false, + "QUARTER": false, + "QUARTER_YEAR": false, + "YEAR": false + }, + "module": "superset.db_engine_specs.iotdb", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 20, + "max_score": 201, + "documentation": { + "description": "Apache IoTDB is a time series database designed for IoT data, with efficient storage and query capabilities for massive time series data.", + "logo": "apache-iotdb.svg", + "homepage_url": "https://iotdb.apache.org/", + "categories": [ + "Apache Projects", + "Time Series Databases", + "Open Source" + ], + "pypi_packages": [ + "apache-iotdb" + ], + "connection_string": "iotdb://{username}:{password}@{hostname}:{port}", + "default_port": 6667, + "parameters": { + "username": "Database username (default: root)", + "password": "Database password (default: root)", + "hostname": "IP address or hostname", + "port": "Default 6667" + }, + "notes": "The IoTDB SQLAlchemy dialect was written to integrate with Apache Superset. IoTDB uses a hierarchical data model, which is reorganized into a relational model for SQL queries.", + "category": "Apache Projects" + }, + "engine": "iotdb", + "engine_name": "Apache IoTDB", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Apache Kylin": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.kylin", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 28, + "max_score": 201, + "documentation": { + "description": "Apache Kylin is an open-source OLAP engine for big data.", + "logo": "apache-kylin.png", + "homepage_url": "https://kylin.apache.org/", + "categories": [ + "Apache Projects", + "Analytical Databases", + "Open Source" + ], + "pypi_packages": [ + "kylinpy" + ], + "connection_string": "kylin://{username}:{password}@{hostname}:{port}/{project}?{param1}={value1}&{param2}={value2}", + "default_port": 7070, + "category": "Apache Projects" + }, + "engine": "kylin", + "engine_name": "Apache Kylin", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Apache Phoenix": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.phoenix", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 28, + "max_score": 201, + "documentation": { + "description": "Apache Phoenix is a relational database layer over Apache HBase, providing low-latency SQL queries over HBase data.", + "logo": "apache-phoenix.png", + "homepage_url": "https://phoenix.apache.org/", + "categories": [ + "Apache Projects", + "Analytical Databases", + "Open Source" + ], + "pypi_packages": [ + "phoenixdb" + ], + "connection_string": "phoenix://{hostname}:{port}/", + "default_port": 8765, + "notes": "Phoenix provides a SQL interface to Apache HBase. The phoenixdb driver connects via the Phoenix Query Server and supports a subset of SQLAlchemy.", + "category": "Apache Projects" + }, + "engine": "phoenix", + "engine_name": "Apache Phoenix", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Apache Pinot": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.pinot", + "limit_method": 1, + "limit_clause": true, + "joins": false, + "subqueries": false, + "alias_in_select": false, + "alias_in_orderby": false, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 32, + "max_score": 201, + "documentation": { + "description": "Apache Pinot is a real-time distributed OLAP datastore.", + "logo": "apache-pinot.svg", + "homepage_url": "https://pinot.apache.org/", + "categories": [ + "Apache Projects", + "Time Series Databases", + "Open Source" + ], + "pypi_packages": [ + "pinotdb" + ], + "connection_string": "pinot+http://{broker_host}:{broker_port}/query?controller=http://{controller_host}:{controller_port}/", + "default_port": 8099, + "connection_examples": [ + { + "description": "With authentication", + "connection_string": "pinot://{username}:{password}@{broker_host}:{broker_port}/query/sql?controller=http://{controller_host}:{controller_port}/verify_ssl=true" + } + ], + "engine_parameters": [ + { + "name": "Multi-stage Query Engine", + "description": "Enable for Explore view, joins, window functions", + "json": { + "connect_args": { + "use_multistage_engine": "true" + } + }, + "docs_url": "https://docs.pinot.apache.org/reference/multi-stage-engine" + } + ], + "category": "Apache Projects" + }, + "engine": "pinot", + "engine_name": "Apache Pinot", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Apache Solr": { + "time_grains": { + "SECOND": false, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": false, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": false, + "SIX_HOURS": false, + "DAY": false, + "WEEK": false, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": false, + "QUARTER": false, + "QUARTER_YEAR": false, + "YEAR": false + }, + "module": "superset.db_engine_specs.solr", + "limit_method": 1, + "limit_clause": true, + "joins": false, + "subqueries": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 20, + "max_score": 201, + "documentation": { + "description": "Apache Solr is an open-source enterprise search platform.", + "logo": "apache-solr.png", + "homepage_url": "https://solr.apache.org/", + "categories": [ + "Apache Projects", + "Search & NoSQL", + "Open Source" + ], + "pypi_packages": [ + "sqlalchemy-solr" + ], + "connection_string": "solr://{username}:{password}@{host}:{port}/{server_path}/{collection}[/?use_ssl=true|false]", + "default_port": 8983, + "category": "Apache Projects" + }, + "engine": "solr", + "engine_name": "Apache Solr", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Apache Spark SQL": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.spark", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": false, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 767, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, + "user_impersonation": true, + "file_upload": true, + "get_extra_table_metadata": true, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": true, + "expand_data": true, + "query_cost_estimation": true, + "sql_validation": false, + "score": 140, + "max_score": 201, + "documentation": { + "description": "Apache Spark SQL is a module for structured data processing.", + "logo": "apache-spark.png", + "homepage_url": "https://spark.apache.org/sql/", + "categories": [ + "Apache Projects", + "Query Engines", + "Open Source" + ], + "pypi_packages": [ + "pyhive" + ], + "connection_string": "hive://hive@{hostname}:{port}/{database}", + "default_port": 10000, + "category": "Apache Projects" + }, + "engine": "hive", + "engine_name": "Apache Spark SQL", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Arc": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.arc", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 28, + "max_score": 201, + "documentation": { + "description": "Arc is a data platform with multiple connection options.", + "categories": [ + "Other Databases", + "Proprietary" + ], + "pypi_packages": [ + "arc-superset-arrow" + ], + "connection_string": "arc+arrow://{api_key}@{hostname}:{port}/{database}", + "parameters": { + "api_key": "Arc API key", + "hostname": "Arc hostname", + "port": "Arc port", + "database": "Database name" + }, + "drivers": [ + { + "name": "Apache Arrow (Recommended)", + "pypi_package": "arc-superset-arrow", + "connection_string": "arc+arrow://{api_key}@{hostname}:{port}/{database}", + "is_recommended": true, + "notes": "Recommended for production. Provides 3-5x better performance using Apache Arrow IPC." + }, + { + "name": "JSON", + "pypi_package": "arc-superset-dialect", + "connection_string": "arc+json://{api_key}@{hostname}:{port}/{database}", + "is_recommended": false + } + ], + "notes": "Arc supports multiple databases (schemas) within a single instance. Each Arc database appears as a schema in SQL Lab.", + "category": "Other Databases" + }, + "engine": "arc", + "engine_name": "Arc", + "engine_aliases": [], + "default_driver": "arrow", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Ascend": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.ascend", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 38, + "max_score": 201, + "documentation": { + "description": "Ascend.io is a data automation platform for building data pipelines.", + "logo": "ascend.webp", + "homepage_url": "https://www.ascend.io/", + "categories": [ + "Cloud Data Warehouses", + "Analytical Databases", + "Hosted Open Source" + ], + "pypi_packages": [ + "impyla" + ], + "connection_string": "ascend://{username}:{password}@{hostname}:{port}/{database}?auth_mechanism=PLAIN;use_ssl=true", + "category": "Other Databases" + }, + "engine": "ascend", + "engine_name": "Ascend", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Aurora MySQL": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.aurora", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 64, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 59, + "max_score": 201, + "documentation": { + "description": "MySQL is a popular open-source relational database.", + "logo": "mysql.png", + "homepage_url": "https://www.mysql.com/", + "categories": [ + "Traditional RDBMS", + "Open Source" + ], + "pypi_packages": [ + "mysqlclient" + ], + "connection_string": "mysql://{username}:{password}@{host}/{database}", + "default_port": 3306, + "parameters": { + "username": "Database username", + "password": "Database password", + "host": "localhost, 127.0.0.1, IP address, or hostname", + "database": "Database name" + }, + "host_examples": [ + { + "platform": "Localhost", + "host": "localhost or 127.0.0.1" + }, + { + "platform": "Docker on Linux", + "host": "172.18.0.1" + }, + { + "platform": "Docker on macOS", + "host": "docker.for.mac.host.internal" + }, + { + "platform": "On-premise", + "host": "IP address or hostname" + } + ], + "drivers": [ + { + "name": "mysqlclient", + "pypi_package": "mysqlclient", + "connection_string": "mysql://{username}:{password}@{host}/{database}", + "is_recommended": true, + "notes": "Recommended driver. May fail with caching_sha2_password auth." + }, + { + "name": "mysql-connector-python", + "pypi_package": "mysql-connector-python", + "connection_string": "mysql+mysqlconnector://{username}:{password}@{host}/{database}", + "is_recommended": false, + "notes": "Required for newer MySQL databases using caching_sha2_password authentication." + } + ], + "compatible_databases": [ + { + "name": "MariaDB", + "description": "MariaDB is a community-developed fork of MySQL, fully compatible with MySQL.", + "logo": "mariadb.png", + "homepage_url": "https://mariadb.org/", + "pypi_packages": [ + "mysqlclient" + ], + "connection_string": "mysql://{username}:{password}@{host}:{port}/{database}", + "categories": [ + "Open Source" + ] + }, + { + "name": "Amazon Aurora MySQL", + "description": "Amazon Aurora MySQL is a fully managed, MySQL-compatible relational database with up to 5x the throughput of standard MySQL.", + "logo": "aws-aurora.jpg", + "homepage_url": "https://aws.amazon.com/rds/aurora/", + "pypi_packages": [ + "sqlalchemy-aurora-data-api" + ], + "connection_string": "mysql+auroradataapi://{aws_access_id}:{aws_secret_access_key}@/{database_name}?aurora_cluster_arn={aurora_cluster_arn}&secret_arn={secret_arn}®ion_name={region_name}", + "parameters": { + "aws_access_id": "AWS Access Key ID", + "aws_secret_access_key": "AWS Secret Access Key", + "database_name": "Database name", + "aurora_cluster_arn": "Aurora cluster ARN", + "secret_arn": "Secrets Manager ARN for credentials", + "region_name": "AWS region (e.g., us-east-1)" + }, + "notes": "Uses the Data API for serverless access. Standard MySQL connections also work with mysqlclient.", + "categories": [ + "Cloud - AWS", + "Hosted Open Source" + ] + } + ], + "category": "Traditional RDBMS" + }, + "engine": "mysql", + "engine_name": "Aurora MySQL", + "engine_aliases": [], + "default_driver": "mysqldb", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Aurora MySQL (Data API)": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.aurora", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 64, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 59, + "max_score": 201, + "documentation": { + "description": "MySQL is a popular open-source relational database.", + "logo": "mysql.png", + "homepage_url": "https://www.mysql.com/", + "categories": [ + "Traditional RDBMS", + "Open Source" + ], + "pypi_packages": [ + "mysqlclient" + ], + "connection_string": "mysql://{username}:{password}@{host}/{database}", + "default_port": 3306, + "parameters": { + "username": "Database username", + "password": "Database password", + "host": "localhost, 127.0.0.1, IP address, or hostname", + "database": "Database name" + }, + "host_examples": [ + { + "platform": "Localhost", + "host": "localhost or 127.0.0.1" + }, + { + "platform": "Docker on Linux", + "host": "172.18.0.1" + }, + { + "platform": "Docker on macOS", + "host": "docker.for.mac.host.internal" + }, + { + "platform": "On-premise", + "host": "IP address or hostname" + } + ], + "drivers": [ + { + "name": "mysqlclient", + "pypi_package": "mysqlclient", + "connection_string": "mysql://{username}:{password}@{host}/{database}", + "is_recommended": true, + "notes": "Recommended driver. May fail with caching_sha2_password auth." + }, + { + "name": "mysql-connector-python", + "pypi_package": "mysql-connector-python", + "connection_string": "mysql+mysqlconnector://{username}:{password}@{host}/{database}", + "is_recommended": false, + "notes": "Required for newer MySQL databases using caching_sha2_password authentication." + } + ], + "compatible_databases": [ + { + "name": "MariaDB", + "description": "MariaDB is a community-developed fork of MySQL, fully compatible with MySQL.", + "logo": "mariadb.png", + "homepage_url": "https://mariadb.org/", + "pypi_packages": [ + "mysqlclient" + ], + "connection_string": "mysql://{username}:{password}@{host}:{port}/{database}", + "categories": [ + "Open Source" + ] + }, + { + "name": "Amazon Aurora MySQL", + "description": "Amazon Aurora MySQL is a fully managed, MySQL-compatible relational database with up to 5x the throughput of standard MySQL.", + "logo": "aws-aurora.jpg", + "homepage_url": "https://aws.amazon.com/rds/aurora/", + "pypi_packages": [ + "sqlalchemy-aurora-data-api" + ], + "connection_string": "mysql+auroradataapi://{aws_access_id}:{aws_secret_access_key}@/{database_name}?aurora_cluster_arn={aurora_cluster_arn}&secret_arn={secret_arn}®ion_name={region_name}", + "parameters": { + "aws_access_id": "AWS Access Key ID", + "aws_secret_access_key": "AWS Secret Access Key", + "database_name": "Database name", + "aurora_cluster_arn": "Aurora cluster ARN", + "secret_arn": "Secrets Manager ARN for credentials", + "region_name": "AWS region (e.g., us-east-1)" + }, + "notes": "Uses the Data API for serverless access. Standard MySQL connections also work with mysqlclient.", + "categories": [ + "Cloud - AWS", + "Hosted Open Source" + ] + } + ], + "category": "Traditional RDBMS" + }, + "engine": "mysql", + "engine_name": "Aurora MySQL (Data API)", + "engine_aliases": [], + "default_driver": "auroradataapi", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Aurora PostgreSQL": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.aurora", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 63, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": true, + "sql_validation": true, + "score": 104, + "max_score": 201, + "documentation": { + "description": "PostgreSQL is an advanced open-source relational database.", + "logo": "postgresql.svg", + "homepage_url": "https://www.postgresql.org/", + "categories": [ + "Traditional RDBMS", + "Open Source" + ], + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", + "default_port": 5432, + "parameters": { + "username": "Database username", + "password": "Database password", + "host": "For localhost: localhost or 127.0.0.1. For AWS: endpoint URL", + "port": "Default 5432", + "database": "Database name" + }, + "notes": "The psycopg2 library comes bundled with Superset Docker images.", + "connection_examples": [ + { + "description": "Basic connection", + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}" + }, + { + "description": "With SSL required", + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}?sslmode=require" + } + ], + "docs_url": "https://www.postgresql.org/docs/", + "sqlalchemy_docs_url": "https://docs.sqlalchemy.org/en/13/dialects/postgresql.html", + "compatible_databases": [ + { + "name": "Hologres", + "description": "Alibaba Cloud real-time interactive analytics service, fully compatible with PostgreSQL 11.", + "logo": "hologres.png", + "homepage_url": "https://www.alibabacloud.com/product/hologres", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql+psycopg2://{username}:{password}@{host}:{port}/{database}", + "parameters": { + "username": "AccessKey ID of your Alibaba Cloud account", + "password": "AccessKey secret of your Alibaba Cloud account", + "host": "Public endpoint of the Hologres instance", + "port": "Port number of the Hologres instance", + "database": "Name of the Hologres database" + }, + "categories": [ + "Proprietary" + ] + }, + { + "name": "TimescaleDB", + "description": "Open-source relational database for time-series and analytics, built on PostgreSQL.", + "logo": "timescale.png", + "homepage_url": "https://www.timescale.com/", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", + "connection_examples": [ + { + "description": "Timescale Cloud (SSL required)", + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}?sslmode=require" + } + ], + "notes": "psycopg2 comes bundled with Superset Docker images.", + "docs_url": "https://docs.timescale.com/", + "categories": [ + "Open Source" + ] + }, + { + "name": "YugabyteDB", + "description": "Distributed SQL database built on top of PostgreSQL.", + "logo": "yugabyte.png", + "homepage_url": "https://www.yugabyte.com/", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", + "notes": "psycopg2 comes bundled with Superset Docker images.", + "docs_url": "https://www.yugabyte.com/", + "categories": [ + "Open Source" + ] + }, + { + "name": "Supabase", + "description": "Open-source Firebase alternative built on top of PostgreSQL, providing a full backend-as-a-service with a hosted Postgres database.", + "logo": "supabase.svg", + "homepage_url": "https://supabase.com/", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", + "connection_examples": [ + { + "description": "Supabase project (connection pooler)", + "connection_string": "postgresql://{username}.{project_ref}:{password}@aws-0-{region}.pooler.supabase.com:6543/{database}" + } + ], + "parameters": { + "username": "Database user (default: postgres)", + "password": "Database password", + "host": "Supabase project host (from project settings)", + "port": "Default 5432 (direct) or 6543 (pooler)", + "database": "Database name (default: postgres)", + "project_ref": "Supabase project reference (from project settings)", + "region": "Supabase project region (e.g., us-east-1)" + }, + "notes": "Find connection details in your Supabase project dashboard under Settings > Database. Use the connection pooler (port 6543) for better connection management.", + "docs_url": "https://supabase.com/docs/guides/database/connecting-to-postgres", + "categories": [ + "Hosted Open Source" + ] + }, + { + "name": "Google AlloyDB", + "description": "Google Cloud's PostgreSQL-compatible database service for demanding transactional and analytical workloads.", + "logo": "alloydb.png", + "homepage_url": "https://cloud.google.com/alloydb", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", + "parameters": { + "username": "Database user (default: postgres)", + "password": "Database password", + "host": "AlloyDB instance IP or Auth Proxy address", + "port": "Default 5432", + "database": "Database name" + }, + "notes": "For public IP connections, use the AlloyDB Auth Proxy for secure access. Private IP connections can connect directly.", + "docs_url": "https://cloud.google.com/alloydb/docs", + "categories": [ + "Cloud - Google", + "Hosted Open Source" + ] + }, + { + "name": "Neon", + "description": "Serverless PostgreSQL with branching, scale-to-zero, and bottomless storage.", + "logo": "neon.png", + "homepage_url": "https://neon.tech/", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}/{database}?sslmode=require", + "parameters": { + "username": "Neon role name", + "password": "Neon role password", + "host": "Neon hostname (e.g., ep-cool-name-123456.us-east-2.aws.neon.tech)", + "database": "Database name (default: neondb)" + }, + "notes": "SSL is required for all connections. Find connection details in the Neon console under Connection Details.", + "docs_url": "https://neon.tech/docs/connect/connect-from-any-app", + "categories": [ + "Hosted Open Source" + ] + }, + { + "name": "Amazon Aurora PostgreSQL", + "description": "Amazon Aurora PostgreSQL is a fully managed, PostgreSQL-compatible relational database with up to 5x the throughput of standard PostgreSQL.", + "logo": "aws-aurora.jpg", + "homepage_url": "https://aws.amazon.com/rds/aurora/", + "pypi_packages": [ + "sqlalchemy-aurora-data-api" + ], + "connection_string": "postgresql+auroradataapi://{aws_access_id}:{aws_secret_access_key}@/{database_name}?aurora_cluster_arn={aurora_cluster_arn}&secret_arn={secret_arn}®ion_name={region_name}", + "parameters": { + "aws_access_id": "AWS Access Key ID", + "aws_secret_access_key": "AWS Secret Access Key", + "database_name": "Database name", + "aurora_cluster_arn": "Aurora cluster ARN", + "secret_arn": "Secrets Manager ARN for credentials", + "region_name": "AWS region (e.g., us-east-1)" + }, + "notes": "Uses the Data API for serverless access. Standard PostgreSQL connections also work with psycopg2.", + "categories": [ + "Cloud - AWS", + "Hosted Open Source" + ] + } + ], + "category": "Traditional RDBMS" + }, + "engine": "postgresql", + "engine_name": "Aurora PostgreSQL", + "engine_aliases": [ + "postgres" + ], + "default_driver": "psycopg2", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Aurora PostgreSQL (Data API)": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.aurora", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 63, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": true, + "sql_validation": true, + "score": 104, + "max_score": 201, + "documentation": { + "description": "PostgreSQL is an advanced open-source relational database.", + "logo": "postgresql.svg", + "homepage_url": "https://www.postgresql.org/", + "categories": [ + "Traditional RDBMS", + "Open Source" + ], + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", + "default_port": 5432, + "parameters": { + "username": "Database username", + "password": "Database password", + "host": "For localhost: localhost or 127.0.0.1. For AWS: endpoint URL", + "port": "Default 5432", + "database": "Database name" + }, + "notes": "The psycopg2 library comes bundled with Superset Docker images.", + "connection_examples": [ + { + "description": "Basic connection", + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}" + }, + { + "description": "With SSL required", + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}?sslmode=require" + } + ], + "docs_url": "https://www.postgresql.org/docs/", + "sqlalchemy_docs_url": "https://docs.sqlalchemy.org/en/13/dialects/postgresql.html", + "compatible_databases": [ + { + "name": "Hologres", + "description": "Alibaba Cloud real-time interactive analytics service, fully compatible with PostgreSQL 11.", + "logo": "hologres.png", + "homepage_url": "https://www.alibabacloud.com/product/hologres", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql+psycopg2://{username}:{password}@{host}:{port}/{database}", + "parameters": { + "username": "AccessKey ID of your Alibaba Cloud account", + "password": "AccessKey secret of your Alibaba Cloud account", + "host": "Public endpoint of the Hologres instance", + "port": "Port number of the Hologres instance", + "database": "Name of the Hologres database" + }, + "categories": [ + "Proprietary" + ] + }, + { + "name": "TimescaleDB", + "description": "Open-source relational database for time-series and analytics, built on PostgreSQL.", + "logo": "timescale.png", + "homepage_url": "https://www.timescale.com/", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", + "connection_examples": [ + { + "description": "Timescale Cloud (SSL required)", + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}?sslmode=require" + } + ], + "notes": "psycopg2 comes bundled with Superset Docker images.", + "docs_url": "https://docs.timescale.com/", + "categories": [ + "Open Source" + ] + }, + { + "name": "YugabyteDB", + "description": "Distributed SQL database built on top of PostgreSQL.", + "logo": "yugabyte.png", + "homepage_url": "https://www.yugabyte.com/", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", + "notes": "psycopg2 comes bundled with Superset Docker images.", + "docs_url": "https://www.yugabyte.com/", + "categories": [ + "Open Source" + ] + }, + { + "name": "Supabase", + "description": "Open-source Firebase alternative built on top of PostgreSQL, providing a full backend-as-a-service with a hosted Postgres database.", + "logo": "supabase.svg", + "homepage_url": "https://supabase.com/", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", + "connection_examples": [ + { + "description": "Supabase project (connection pooler)", + "connection_string": "postgresql://{username}.{project_ref}:{password}@aws-0-{region}.pooler.supabase.com:6543/{database}" + } + ], + "parameters": { + "username": "Database user (default: postgres)", + "password": "Database password", + "host": "Supabase project host (from project settings)", + "port": "Default 5432 (direct) or 6543 (pooler)", + "database": "Database name (default: postgres)", + "project_ref": "Supabase project reference (from project settings)", + "region": "Supabase project region (e.g., us-east-1)" + }, + "notes": "Find connection details in your Supabase project dashboard under Settings > Database. Use the connection pooler (port 6543) for better connection management.", + "docs_url": "https://supabase.com/docs/guides/database/connecting-to-postgres", + "categories": [ + "Hosted Open Source" + ] + }, + { + "name": "Google AlloyDB", + "description": "Google Cloud's PostgreSQL-compatible database service for demanding transactional and analytical workloads.", + "logo": "alloydb.png", + "homepage_url": "https://cloud.google.com/alloydb", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", + "parameters": { + "username": "Database user (default: postgres)", + "password": "Database password", + "host": "AlloyDB instance IP or Auth Proxy address", + "port": "Default 5432", + "database": "Database name" + }, + "notes": "For public IP connections, use the AlloyDB Auth Proxy for secure access. Private IP connections can connect directly.", + "docs_url": "https://cloud.google.com/alloydb/docs", + "categories": [ + "Cloud - Google", + "Hosted Open Source" + ] + }, + { + "name": "Neon", + "description": "Serverless PostgreSQL with branching, scale-to-zero, and bottomless storage.", + "logo": "neon.png", + "homepage_url": "https://neon.tech/", + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql://{username}:{password}@{host}/{database}?sslmode=require", + "parameters": { + "username": "Neon role name", + "password": "Neon role password", + "host": "Neon hostname (e.g., ep-cool-name-123456.us-east-2.aws.neon.tech)", + "database": "Database name (default: neondb)" + }, + "notes": "SSL is required for all connections. Find connection details in the Neon console under Connection Details.", + "docs_url": "https://neon.tech/docs/connect/connect-from-any-app", + "categories": [ + "Hosted Open Source" + ] + }, + { + "name": "Amazon Aurora PostgreSQL", + "description": "Amazon Aurora PostgreSQL is a fully managed, PostgreSQL-compatible relational database with up to 5x the throughput of standard PostgreSQL.", + "logo": "aws-aurora.jpg", + "homepage_url": "https://aws.amazon.com/rds/aurora/", + "pypi_packages": [ + "sqlalchemy-aurora-data-api" + ], + "connection_string": "postgresql+auroradataapi://{aws_access_id}:{aws_secret_access_key}@/{database_name}?aurora_cluster_arn={aurora_cluster_arn}&secret_arn={secret_arn}®ion_name={region_name}", + "parameters": { + "aws_access_id": "AWS Access Key ID", + "aws_secret_access_key": "AWS Secret Access Key", + "database_name": "Database name", + "aurora_cluster_arn": "Aurora cluster ARN", + "secret_arn": "Secrets Manager ARN for credentials", + "region_name": "AWS region (e.g., us-east-1)" + }, + "notes": "Uses the Data API for serverless access. Standard PostgreSQL connections also work with psycopg2.", + "categories": [ + "Cloud - AWS", + "Hosted Open Source" + ] + } + ], + "category": "Traditional RDBMS" + }, + "engine": "postgresql", + "engine_name": "Aurora PostgreSQL (Data API)", + "engine_aliases": [ + "postgres" + ], + "default_driver": "auroradataapi", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Azure Data Explorer": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": false, + "HALF_HOUR": true, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.kusto", + "limit_method": 2, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": true, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": false, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 54, + "max_score": 201, + "documentation": { + "description": "Azure Data Explorer (Kusto) is a fast, fully managed data analytics service from Microsoft Azure. Query data using SQL or native KQL syntax.", + "logo": "kusto.png", + "homepage_url": "https://azure.microsoft.com/en-us/products/data-explorer/", + "categories": [ + "Cloud - Azure", + "Analytical Databases", + "Proprietary" + ], + "pypi_packages": [ + "sqlalchemy-kusto" + ], + "connection_string": "kustosql+https://{cluster}.kusto.windows.net/{database}?msi=False&azure_ad_client_id={client_id}&azure_ad_client_secret={client_secret}&azure_ad_tenant_id={tenant_id}", + "parameters": { + "cluster": "Azure Data Explorer cluster name", + "database": "Database name", + "client_id": "Azure AD application (client) ID", + "client_secret": "Azure AD application secret", + "tenant_id": "Azure AD tenant ID" + }, + "drivers": [ + { + "name": "SQL Interface (Recommended)", + "pypi_package": "sqlalchemy-kusto", + "connection_string": "kustosql+https://{cluster}.kusto.windows.net/{database}?msi=False&azure_ad_client_id={client_id}&azure_ad_client_secret={client_secret}&azure_ad_tenant_id={tenant_id}", + "is_recommended": true, + "notes": "Use familiar SQL syntax to query Azure Data Explorer." + }, + { + "name": "KQL (Kusto Query Language)", + "pypi_package": "sqlalchemy-kusto", + "connection_string": "kustokql+https://{cluster}.kusto.windows.net/{database}?msi=False&azure_ad_client_id={client_id}&azure_ad_client_secret={client_secret}&azure_ad_tenant_id={tenant_id}", + "is_recommended": false, + "notes": "Use native Kusto Query Language for advanced analytics." + } + ], + "category": "Cloud - Azure" + }, + "engine": "kustosql", + "engine_name": "Azure Data Explorer", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Azure Data Explorer (KQL)": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": false, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.kusto", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": true, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": false, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 40, + "max_score": 201, + "documentation": { + "pypi_packages": [], + "connection_string": "engine+driver://user:password@host:port/dbname[?key=value&key=value...]", + "category": "Cloud - Azure" + }, + "engine": "kustokql", + "engine_name": "Azure Data Explorer (KQL)", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Azure Synapse": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.mssql", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": false, + "max_column_name": 128, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 44, + "max_score": 201, + "documentation": { + "description": "Azure Synapse Analytics is a cloud-based enterprise data warehouse from Microsoft that combines big data and data warehousing.", + "logo": "azure.svg", + "homepage_url": "https://azure.microsoft.com/en-us/products/synapse-analytics/", + "categories": [ + "Cloud Data Warehouses", + "Analytical Databases", + "Proprietary" + ], + "pypi_packages": [ + "pymssql" + ], + "connection_string": "mssql+pymssql://{username}@{server}:{password}@{server}.database.windows.net:1433/{database}", + "category": "Cloud - Azure", + "custom_errors": [ + { + "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", + "message_template": "Either the username \"%(username)s\", password, or database name \"%(database)s\" is incorrect.", + "error_type": "CONNECTION_ACCESS_DENIED_ERROR", + "category": "Authentication", + "description": "Access denied", + "issue_codes": [ + 1014, + 1015 + ] + }, + { + "regex_name": "CONNECTION_INVALID_HOSTNAME_REGEX", + "message_template": "The hostname \"%(hostname)s\" cannot be resolved.", + "error_type": "CONNECTION_INVALID_HOSTNAME_ERROR", + "category": "Connection", + "description": "Invalid hostname", + "issue_codes": [ + 1007 + ] + }, + { + "regex_name": "CONNECTION_PORT_CLOSED_REGEX", + "message_template": "Port %(port)s on hostname \"%(hostname)s\" refused the connection.", + "error_type": "CONNECTION_PORT_CLOSED_ERROR", + "category": "Connection", + "description": "Port closed or refused", + "issue_codes": [ + 1008 + ] + }, + { + "regex_name": "CONNECTION_HOST_DOWN_REGEX", + "message_template": "The host \"%(hostname)s\" might be down, and can't be reached on port %(port)s.", + "error_type": "CONNECTION_HOST_DOWN_ERROR", + "category": "Connection", + "description": "Host unreachable", + "issue_codes": [ + 1009 + ] + } + ] + }, + "engine": "mssql", + "engine_name": "Azure Synapse", + "engine_aliases": [], + "default_driver": "pyodbc", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "ClickHouse": { + "time_grains": { + "SECOND": false, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.clickhouse", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": true, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, + "user_impersonation": false, + "file_upload": false, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 61, + "max_score": 201, + "documentation": { + "description": "ClickHouse is an open-source column-oriented database for real-time analytics using SQL. It's known for extremely fast query performance on large datasets.", + "logo": "clickhouse.png", + "homepage_url": "https://clickhouse.com/", + "categories": [ + "Analytical Databases", + "Open Source" + ], + "pypi_packages": [ + "clickhouse-connect>=0.13.0" + ], + "connection_string": "clickhousedb://{username}:{password}@{host}:{port}/{database}", + "default_port": 8123, + "drivers": [ + { + "name": "clickhouse-connect (Recommended)", + "pypi_package": "clickhouse-connect>=0.13.0", + "connection_string": "clickhousedb://{username}:{password}@{host}:{port}/{database}", + "is_recommended": true, + "notes": "Official ClickHouse Python driver with native protocol support." + }, + { + "name": "clickhouse-sqlalchemy (Legacy)", + "pypi_package": "clickhouse-sqlalchemy", + "connection_string": "clickhouse://{username}:{password}@{host}:{port}/{database}", + "is_recommended": false, + "notes": "Older driver using HTTP interface. Use clickhouse-connect for new deployments." + } + ], + "connection_examples": [ + { + "description": "Altinity Cloud", + "connection_string": "clickhousedb://demo:demo@github.demo.trial.altinity.cloud/default?secure=true" + }, + { + "description": "Local (no auth, no SSL)", + "connection_string": "clickhousedb://localhost/default" + } + ], + "install_instructions": "echo \"clickhouse-connect>=0.13.0\" >> ./docker/requirements-local.txt", + "compatible_databases": [ + { + "name": "ClickHouse Cloud", + "description": "ClickHouse Cloud is the official fully-managed cloud service for ClickHouse. It provides automatic scaling, built-in backups, and enterprise security features.", + "logo": "clickhouse.png", + "homepage_url": "https://clickhouse.cloud/", + "categories": [ + "Analytical Databases", + "Cloud Data Warehouses", + "Hosted Open Source" + ], + "pypi_packages": [ + "clickhouse-connect>=0.13.0" + ], + "connection_string": "clickhousedb://{username}:{password}@{host}:8443/{database}?secure=true", + "parameters": { + "username": "ClickHouse Cloud username", + "password": "ClickHouse Cloud password", + "host": "Your ClickHouse Cloud hostname", + "database": "Database name (default)" + }, + "docs_url": "https://clickhouse.com/docs/en/cloud" + }, + { + "name": "Altinity.Cloud", + "description": "Altinity.Cloud is a managed ClickHouse service providing Kubernetes-native deployments with enterprise support.", + "logo": "altinity.png", + "homepage_url": "https://altinity.cloud/", + "categories": [ + "Analytical Databases", + "Cloud Data Warehouses", + "Hosted Open Source" + ], + "pypi_packages": [ + "clickhouse-connect>=0.13.0" + ], + "connection_string": "clickhousedb://{username}:{password}@{host}/{database}?secure=true", + "docs_url": "https://docs.altinity.com/" + } + ], + "category": "Analytical Databases" + }, + "engine": "clickhousedb", + "engine_name": "ClickHouse", + "engine_aliases": [], + "default_driver": "connect", + "supports_file_upload": false, + "supports_dynamic_schema": true, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "ClickHouse (sqlalchemy)": { + "time_grains": { + "SECOND": false, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.clickhouse", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": true, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, + "user_impersonation": false, + "file_upload": false, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 51, + "max_score": 201, + "documentation": { + "pypi_packages": [], + "connection_string": "engine+driver://user:password@host:port/dbname[?key=value&key=value...]", + "category": "Analytical Databases" + }, + "engine": "clickhouse", + "engine_name": "ClickHouse (sqlalchemy)", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": false, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Cloudflare D1": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": true, + "HOUR": true, + "SIX_HOURS": true, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": true, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": true, + "YEAR": true + }, + "module": "superset.db_engine_specs.d1", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": true, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": false, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 41, + "max_score": 201, + "documentation": { + "description": "Cloudflare D1 is a serverless SQLite database.", + "logo": "cloudflare.png", + "homepage_url": "https://developers.cloudflare.com/d1/", + "categories": [ + "Cloud Data Warehouses", + "Traditional RDBMS", + "Hosted Open Source" + ], + "pypi_packages": [ + "superset-engine-d1" + ], + "connection_string": "d1://{cloudflare_account_id}:{cloudflare_api_token}@{cloudflare_d1_database_id}", + "parameters": { + "cloudflare_account_id": "Cloudflare account ID", + "cloudflare_api_token": "Cloudflare API token", + "cloudflare_d1_database_id": "D1 database ID" + }, + "install_instructions": "pip install superset-engine-d1", + "category": "Other Databases" + }, + "engine": "d1", + "engine_name": "Cloudflare D1", + "engine_aliases": [], + "default_driver": "d1", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "CockroachDB": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.cockroachdb", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 63, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": true, + "sql_validation": false, + "score": 94, + "max_score": 201, + "documentation": { + "description": "CockroachDB is a distributed SQL database built for cloud applications.", + "logo": "cockroachdb.png", + "homepage_url": "https://www.cockroachlabs.com/", + "categories": [ + "Traditional RDBMS", + "Open Source" + ], + "pypi_packages": [ + "cockroachdb" + ], + "connection_string": "cockroachdb://root@{hostname}:{port}/{database}?sslmode=disable", + "default_port": 26257, + "docs_url": "https://github.com/cockroachdb/sqlalchemy-cockroachdb", + "category": "Other Databases" + }, + "engine": "cockroachdb", + "engine_name": "CockroachDB", + "engine_aliases": [ + "postgres" + ], + "default_driver": "psycopg2", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Couchbase": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -992,51 +3516,83 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 27, - "max_score": 201, + "module": "superset.db_engine_specs.couchbase", + "limit_method": 1, + "limit_clause": true, "joins": false, "subqueries": false, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "CrateDB": { - "engine": "cratedb", - "engine_name": "CrateDB", - "module": "crate", + "sql_validation": false, + "score": 27, + "max_score": 201, "documentation": { - "description": "CrateDB is a distributed SQL database for machine data and IoT workloads.", - "logo": "cratedb.svg", - "homepage_url": "https://crate.io/", + "description": "Couchbase is a distributed NoSQL document database with SQL++ support.", + "logo": "couchbase.svg", + "homepage_url": "https://www.couchbase.com/", "categories": [ - "TIME_SERIES", - "OPEN_SOURCE" + "Search & NoSQL", + "Open Source" ], "pypi_packages": [ - "crate", - "sqlalchemy-cratedb" + "couchbase-sqlalchemy" ], - "connection_string": "crate://{host}:{port}", - "default_port": 4200, + "connection_string": "couchbase://{username}:{password}@{host}:{port}?ssl=true", + "default_port": 8091, "parameters": { - "host": "CrateDB host", - "port": "CrateDB HTTP port (default 4200)" + "username": "Couchbase username", + "password": "Couchbase password", + "host": "Couchbase host or connection string for cloud", + "port": "Couchbase port (default 8091)", + "database": "Couchbase database/bucket name" }, "drivers": [ { - "name": "crate", - "pypi_package": "crate[sqlalchemy]", - "connection_string": "crate://{host}:{port}", + "name": "couchbase-sqlalchemy", + "pypi_package": "couchbase-sqlalchemy", + "connection_string": "couchbase://{username}:{password}@{host}:{port}?ssl=true", "is_recommended": true } - ] + ], + "category": "Search & NoSQL" }, + "engine": "couchbase", + "engine_name": "Couchbase", + "engine_aliases": [ + "couchbasedb" + ], + "default_driver": "couchbase", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "CrateDB": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -1060,86 +3616,79 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 28, - "max_score": 201, + "module": "superset.db_engine_specs.crate", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "Cloudflare D1": { - "engine": "cloudflare_d1", - "engine_name": "Cloudflare D1", - "module": "d1", + "sql_validation": false, + "score": 28, + "max_score": 201, "documentation": { - "description": "Cloudflare D1 is a serverless SQLite database.", - "logo": "cloudflare.png", - "homepage_url": "https://developers.cloudflare.com/d1/", - "pypi_packages": [ - "superset-engine-d1" - ], - "connection_string": "d1://{cloudflare_account_id}:{cloudflare_api_token}@{cloudflare_d1_database_id}", - "notes": "No additional library needed. SQLite is bundled with Python.", + "description": "CrateDB is a distributed SQL database for machine data and IoT workloads.", + "logo": "cratedb.svg", + "homepage_url": "https://cratedb.com", "categories": [ - "CLOUD_DATA_WAREHOUSES", - "TRADITIONAL_RDBMS", - "HOSTED_OPEN_SOURCE" + "Time Series Databases", + "Open Source" ], + "pypi_packages": [ + "crate", + "sqlalchemy-cratedb" + ], + "connection_string": "crate://{host}:{port}", + "default_port": 4200, "parameters": { - "cloudflare_account_id": "Cloudflare account ID", - "cloudflare_api_token": "Cloudflare API token", - "cloudflare_d1_database_id": "D1 database ID" + "host": "CrateDB host", + "port": "CrateDB HTTP port (default 4200)" }, - "install_instructions": "pip install superset-engine-d1" + "drivers": [ + { + "name": "crate", + "pypi_package": "crate[sqlalchemy]", + "connection_string": "crate://{host}:{port}", + "is_recommended": true + } + ], + "category": "Other Databases" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, + "engine": "crate", + "engine_name": "CrateDB", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, "Databend": { - "engine": "databend", - "engine_name": "Databend", - "module": "databend", - "documentation": { - "description": "Databend is a modern cloud-native data warehouse with instant elasticity and pay-as-you-go pricing. Built in Rust for high performance.", - "logo": "databend.png", - "homepage_url": "https://www.databend.com/", - "categories": [ - "CLOUD_DATA_WAREHOUSES", - "ANALYTICAL_DATABASES", - "PROPRIETARY" - ], - "pypi_packages": [ - "databend-sqlalchemy" - ], - "connection_string": "databend://{username}:{password}@{host}:{port}/{database}?secure=true", - "default_port": 443, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "Databend host", - "port": "Databend port (default 443 for HTTPS)", - "database": "Database name" - } - }, "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -1163,81 +3712,213 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 51, - "max_score": 201, + "module": "superset.db_engine_specs.databend", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": true, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, + "user_impersonation": false, + "file_upload": false, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "Databricks Interactive Cluster": { - "engine": "databricks_interactive_cluster", - "engine_name": "Databricks Interactive Cluster", - "module": "databricks", + "sql_validation": false, + "score": 51, + "max_score": 201, "documentation": { - "description": "Apache Hive is a data warehouse infrastructure built on Hadoop.", - "logo": "apache-hive.svg", - "homepage_url": "https://hive.apache.org/", - "pypi_packages": [ - "pyhive", - "pyhive" - ], - "install_instructions": "pip install \"apache-superset[presto]\"", - "connection_string": "hive://hive@{hostname}:{port}/{database}", - "default_port": 10000, - "parameters": { - "hostname": "Presto coordinator hostname", - "port": "Presto coordinator port (default 8080)", - "database": "Catalog name" - }, - "drivers": [ - { - "name": "PyHive", - "pypi_package": "pyhive", - "connection_string": "presto://{hostname}:{port}/{database}", - "is_recommended": true - } - ], + "description": "Databend is a modern cloud-native data warehouse with instant elasticity and pay-as-you-go pricing. Built in Rust for high performance.", + "logo": "databend.png", + "homepage_url": "https://www.databend.com/", "categories": [ - "APACHE_PROJECTS", - "QUERY_ENGINES", - "OPEN_SOURCE" - ] + "Cloud Data Warehouses", + "Analytical Databases", + "Proprietary" + ], + "pypi_packages": [ + "databend-sqlalchemy" + ], + "connection_string": "databend://{username}:{password}@{host}:{port}/{database}?secure=true", + "default_port": 443, + "parameters": { + "username": "Database username", + "password": "Database password", + "host": "Databend host", + "port": "Databend port (default 443 for HTTPS)", + "database": "Database name" + }, + "category": "Other Databases" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, + "engine": "databend", + "engine_name": "Databend", + "engine_aliases": [], + "default_driver": "databend", + "supports_file_upload": false, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, + "supports_dynamic_catalog": false + }, + "Databend (legacy)": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.databend", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": true, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, "user_impersonation": false, + "file_upload": false, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false + "sql_validation": false, + "score": 51, + "max_score": 201, + "documentation": { + "pypi_packages": [], + "connection_string": "engine+driver://user:password@host:port/dbname[?key=value&key=value...]", + "category": "Other Databases" + }, + "engine": "databend", + "engine_name": "Databend (legacy)", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": false, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false }, "Databricks": { - "engine": "databricks", - "engine_name": "Databricks", - "module": "databricks", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.databricks", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": true, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 70, + "max_score": 201, "documentation": { "description": "Databricks is a unified analytics platform built on Apache Spark, providing data engineering, data science, and machine learning capabilities in the cloud. Use the Python Connector for SQL warehouses and clusters.", "logo": "databricks.png", "homepage_url": "https://www.databricks.com/", "categories": [ - "CLOUD_DATA_WAREHOUSES", - "ANALYTICAL_DATABASES", - "HOSTED_OPEN_SOURCE" + "Cloud Data Warehouses", + "Analytical Databases", + "Hosted Open Source" ], "pypi_packages": [ "apache-superset[databricks]" @@ -1279,77 +3960,19 @@ "is_recommended": false, "notes": "Legacy connector. Use Python Connector for new deployments." } - ] + ], + "category": "Cloud Data Warehouses" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "engine": "databricks", + "engine_name": "Databricks", + "engine_aliases": [], + "default_driver": "databricks-sql-python", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true }, - "IBM Db2": { - "engine": "ibm_db2", - "engine_name": "IBM Db2", - "module": "db2", - "documentation": { - "description": "IBM Db2 is a family of data management products for enterprise workloads, available on-premises, in containers, and across cloud platforms.", - "logo": "ibm-db2.svg", - "homepage_url": "https://www.ibm.com/db2", - "categories": [ - "TRADITIONAL_RDBMS", - "PROPRIETARY" - ], - "pypi_packages": [ - "ibm_db_sa" - ], - "connection_string": "db2+ibm_db://{username}:{password}@{hostname}:{port}/{database}", - "default_port": 50000, - "drivers": [ - { - "name": "ibm_db_sa (with LIMIT)", - "connection_string": "db2+ibm_db://{username}:{password}@{hostname}:{port}/{database}", - "is_recommended": true - }, - { - "name": "ibm_db_sa (without LIMIT syntax)", - "connection_string": "ibm_db_sa://{username}:{password}@{hostname}:{port}/{database}", - "is_recommended": false, - "notes": "Use for older DB2 versions without LIMIT [n] syntax. Recommended for SQL Lab." - } - ], - "compatible_databases": [ - { - "name": "IBM Db2 for i (AS/400)", - "description": "Db2 for i is a fully integrated database engine on IBM i (AS/400) systems. Uses a different SQLAlchemy driver optimized for IBM i.", - "logo": "ibm-db2.svg", - "homepage_url": "https://www.ibm.com/products/db2-for-i", - "pypi_packages": [ - "sqlalchemy-ibmi" - ], - "connection_string": "ibmi://{username}:{password}@{host}/{database}", - "parameters": { - "username": "IBM i username", - "password": "IBM i password", - "host": "IBM i system host", - "database": "Library/schema name" - }, - "docs_url": "https://github.com/IBM/sqlalchemy-ibmi", - "categories": [ - "PROPRIETARY" - ] - } - ], - "docs_url": "https://github.com/ibmdb/python-ibmdbsa" - }, + "Databricks (legacy)": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -1364,6 +3987,236 @@ "SIX_HOURS": false, "DAY": true, "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.databricks", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": true, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 70, + "max_score": 201, + "documentation": { + "pypi_packages": [], + "connection_string": "databricks+connector://token:{access_token}@{host}:{port}/{database_name}", + "category": "Cloud Data Warehouses" + }, + "engine": "databricks", + "engine_name": "Databricks (legacy)", + "engine_aliases": [], + "default_driver": "connector", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Databricks Interactive Cluster": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.databricks", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": false, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 767, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, + "user_impersonation": true, + "file_upload": true, + "get_extra_table_metadata": true, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": true, + "expand_data": true, + "query_cost_estimation": true, + "sql_validation": false, + "score": 140, + "max_score": 201, + "documentation": { + "description": "Apache Hive is a data warehouse infrastructure built on Hadoop.", + "logo": "apache-hive.svg", + "homepage_url": "https://hive.apache.org/", + "categories": [ + "Apache Projects", + "Query Engines", + "Open Source" + ], + "pypi_packages": [ + "pyhive" + ], + "connection_string": "hive://hive@{hostname}:{port}/{database}", + "default_port": 10000, + "category": "Cloud Data Warehouses" + }, + "engine": "databricks", + "engine_name": "Databricks Interactive Cluster", + "engine_aliases": [], + "default_driver": "pyhive", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Databricks SQL Endpoint": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.databricks", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 30, + "max_score": 201, + "documentation": { + "pypi_packages": [], + "connection_string": "engine+driver://user:password@host:port/dbname[?key=value&key=value...]", + "category": "Cloud Data Warehouses" + }, + "engine": "databricks", + "engine_name": "Databricks SQL Endpoint", + "engine_aliases": [], + "default_driver": "pyodbc", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Denodo": { + "time_grains": { + "SECOND": false, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, "WEEK_STARTING_SUNDAY": false, "WEEK_STARTING_MONDAY": false, "WEEK_ENDING_SATURDAY": false, @@ -1373,31 +4226,48 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 38, - "max_score": 201, + "module": "superset.db_engine_specs.denodo", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "Denodo": { - "engine": "denodo", - "engine_name": "Denodo", - "module": "denodo", + "sql_validation": false, + "score": 27, + "max_score": 201, "documentation": { "description": "Denodo is a data virtualization platform for logical data management.", "logo": "denodo.png", "homepage_url": "https://www.denodo.com/", "categories": [ - "QUERY_ENGINES", - "PROPRIETARY" + "Query Engines", + "Proprietary" ], "pypi_packages": [ "psycopg2" @@ -1420,6 +4290,7 @@ "notes": "Uses PostgreSQL wire protocol." } ], + "category": "Other Databases", "custom_errors": [ { "message_template": "Incorrect username or password.", @@ -1535,8 +4406,18 @@ } ] }, + "engine": "denodo", + "engine_name": "Denodo", + "engine_aliases": [], + "default_driver": "psycopg2", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Dremio": { "time_grains": { - "SECOND": false, + "SECOND": true, "FIVE_SECONDS": false, "THIRTY_SECONDS": false, "MINUTE": true, @@ -1558,197 +4439,48 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 27, - "max_score": 201, + "module": "superset.db_engine_specs.dremio", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "Apache Doris": { - "engine": "apache_doris", - "engine_name": "Apache Doris", - "module": "doris", - "documentation": { - "description": "Apache Doris is a high-performance real-time analytical database.", - "logo": "doris.png", - "homepage_url": "https://doris.apache.org/", - "pypi_packages": [ - "mysqlclient", - "pydoris" - ], - "connection_string": "doris://{username}:{password}@{host}:{port}/{catalog}.{database}", - "default_port": 9030, - "parameters": { - "username": "User name", - "password": "Password", - "host": "Doris FE Host", - "database": "Database name", - "port": "Doris FE port", - "catalog": "Catalog name" - }, - "host_examples": [ - { - "platform": "Localhost", - "host": "localhost or 127.0.0.1" - }, - { - "platform": "Docker on Linux", - "host": "172.18.0.1" - }, - { - "platform": "Docker on macOS", - "host": "docker.for.mac.host.internal" - }, - { - "platform": "On-premise", - "host": "IP address or hostname" - } - ], - "drivers": [ - { - "name": "mysqlclient", - "pypi_package": "mysqlclient", - "connection_string": "mysql://{username}:{password}@{host}/{database}", - "is_recommended": true, - "notes": "Recommended driver. May fail with caching_sha2_password auth." - }, - { - "name": "mysql-connector-python", - "pypi_package": "mysql-connector-python", - "connection_string": "mysql+mysqlconnector://{username}:{password}@{host}/{database}", - "is_recommended": false, - "notes": "Required for newer MySQL databases using caching_sha2_password authentication." - } - ], - "categories": [ - "APACHE_PROJECTS", - "ANALYTICAL_DATABASES", - "OPEN_SOURCE" - ], - "custom_errors": [ - { - "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", - "message_template": "Either the username \"%(username)s\" or the password is incorrect.", - "error_type": "CONNECTION_ACCESS_DENIED_ERROR", - "category": "Authentication", - "description": "Access denied", - "issue_codes": [ - 1014, - 1015 - ], - "invalid_fields": [ - "username", - "password" - ] - }, - { - "regex_name": "CONNECTION_INVALID_HOSTNAME_REGEX", - "message_template": "Unknown Doris server host \"%(hostname)s\".", - "error_type": "CONNECTION_INVALID_HOSTNAME_ERROR", - "category": "Connection", - "description": "Invalid hostname", - "issue_codes": [ - 1007 - ], - "invalid_fields": [ - "host" - ] - }, - { - "regex_name": "CONNECTION_HOST_DOWN_REGEX", - "message_template": "The host \"%(hostname)s\" might be down and can't be reached.", - "error_type": "CONNECTION_HOST_DOWN_ERROR", - "category": "Connection", - "description": "Host unreachable", - "issue_codes": [ - 1009 - ], - "invalid_fields": [ - "host", - "port" - ] - }, - { - "regex_name": "CONNECTION_UNKNOWN_DATABASE_REGEX", - "message_template": "Unable to connect to database \"%(database)s\".", - "error_type": "CONNECTION_UNKNOWN_DATABASE_ERROR", - "category": "Connection", - "description": "Unknown database", - "issue_codes": [ - 1015 - ], - "invalid_fields": [ - "database" - ] - }, - { - "regex_name": "SYNTAX_ERROR_REGEX", - "message_template": "Please check your query for syntax errors near \"%(server_error)s\". Then, try running your query again.", - "error_type": "SYNTAX_ERROR", - "category": "Query", - "description": "SQL syntax error", - "issue_codes": [ - 1030 - ] - } - ] - }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, - "MINUTE": true, - "FIVE_MINUTES": false, - "TEN_MINUTES": false, - "FIFTEEN_MINUTES": false, - "THIRTY_MINUTES": false, - "HALF_HOUR": false, - "HOUR": true, - "SIX_HOURS": false, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": false, - "WEEK_STARTING_MONDAY": true, - "WEEK_ENDING_SATURDAY": false, - "WEEK_ENDING_SUNDAY": false, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 79, + "sql_validation": false, + "score": 28, "max_score": 201, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": true, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Dremio": { - "engine": "dremio", - "engine_name": "Dremio", - "module": "dremio", "documentation": { "description": "Dremio is a data lakehouse platform for fast, self-service analytics.", "logo": "dremio.png", "homepage_url": "https://www.dremio.com/", "categories": [ - "QUERY_ENGINES", - "PROPRIETARY" + "Query Engines", + "Proprietary" ], "pypi_packages": [ "sqlalchemy_dremio" @@ -1771,8 +4503,21 @@ "is_recommended": false, "notes": "Requires Dremio ODBC drivers installed." } - ] + ], + "category": "Other Databases" }, + "engine": "dremio", + "engine_name": "Dremio", + "engine_aliases": [ + "dremio+flight" + ], + "default_driver": "flight", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "DuckDB": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -1796,212 +4541,48 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 28, - "max_score": 201, + "module": "superset.db_engine_specs.duckdb", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": false, - "supports_file_upload": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Apache Drill": { - "engine": "apache_drill", - "engine_name": "Apache Drill", - "module": "drill", - "documentation": { - "description": "Apache Drill is a schema-free SQL query engine for Hadoop and NoSQL.", - "logo": "apache-drill.png", - "homepage_url": "https://drill.apache.org/", - "categories": [ - "APACHE_PROJECTS", - "QUERY_ENGINES", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "sqlalchemy-drill" - ], - "connection_string": "drill+sadrill://{username}:{password}@{host}:{port}/{storage_plugin}?use_ssl=True", - "default_port": 8047, - "drivers": [ - { - "name": "SQLAlchemy (REST)", - "pypi_package": "sqlalchemy-drill", - "connection_string": "drill+sadrill://{username}:{password}@{host}:{port}/{storage_plugin}?use_ssl=True", - "is_recommended": true - }, - { - "name": "JDBC", - "pypi_package": "sqlalchemy-drill", - "connection_string": "drill+jdbc://{username}:{password}@{host}:{port}", - "is_recommended": false, - "notes": "Requires Drill JDBC Driver installation.", - "docs_url": "https://drill.apache.org/docs/using-the-jdbc-driver/" - }, - { - "name": "ODBC", - "pypi_package": "sqlalchemy-drill", - "is_recommended": false, - "notes": "See Apache Drill documentation for ODBC setup.", - "docs_url": "https://drill.apache.org/docs/installing-the-driver-on-linux/" - } - ], - "connection_examples": [ - { - "description": "Local embedded mode", - "connection_string": "drill+sadrill://localhost:8047/dfs?use_ssl=False" - } - ] - }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, - "MINUTE": true, - "FIVE_MINUTES": false, - "TEN_MINUTES": false, - "FIFTEEN_MINUTES": true, - "THIRTY_MINUTES": true, - "HALF_HOUR": false, - "HOUR": true, - "SIX_HOURS": false, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": false, - "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": false, - "WEEK_ENDING_SUNDAY": false, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 50, - "max_score": 201, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "Apache Druid": { - "engine": "apache_druid", - "engine_name": "Apache Druid", - "module": "druid", - "documentation": { - "description": "Apache Druid is a high performance real-time analytics database.", - "logo": "druid.png", - "homepage_url": "https://druid.apache.org/", - "categories": [ - "APACHE_PROJECTS", - "TIME_SERIES", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "pydruid" - ], - "connection_string": "druid://{username}:{password}@{host}:{port}/druid/v2/sql", - "default_port": 9088, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "IP address or URL of the host", - "port": "Default 9088" - }, - "ssl_configuration": { - "custom_certificate": "Add certificate in Root Certificate field. pydruid will automatically use https.", - "disable_ssl_verification": { - "engine_params": { - "connect_args": { - "scheme": "https", - "ssl_verify_cert": false - } - } - } - }, - "advanced_features": { - "aggregations": "Define common aggregations in datasource edit view under List Druid Column tab.", - "post_aggregations": "Create metrics with postagg as Metric Type and provide valid JSON post-aggregation definition." - }, - "notes": "A native Druid connector ships with Superset (behind DRUID_IS_ACTIVE flag) but SQLAlchemy connector via pydruid is preferred.", - "compatible_databases": [ - { - "name": "Imply", - "description": "Imply is a fully-managed cloud platform and enterprise distribution built on Apache Druid. It provides real-time analytics with enterprise security and support.", - "logo": "imply.png", - "homepage_url": "https://imply.io/", - "categories": [ - "TIME_SERIES", - "CLOUD_DATA_WAREHOUSES", - "HOSTED_OPEN_SOURCE" - ], - "pypi_packages": [ - "pydruid" - ], - "connection_string": "druid://{username}:{password}@{host}/druid/v2/sql", - "docs_url": "https://docs.imply.io/" - } - ] - }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": true, - "THIRTY_SECONDS": true, - "MINUTE": true, - "FIVE_MINUTES": true, - "TEN_MINUTES": true, - "FIFTEEN_MINUTES": true, - "THIRTY_MINUTES": true, - "HALF_HOUR": false, - "HOUR": true, - "SIX_HOURS": true, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": true, - "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": true, - "WEEK_ENDING_SUNDAY": false, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 47, + "sql_validation": false, + "score": 38, "max_score": 201, - "joins": false, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "DuckDB": { - "engine": "duckdb", - "engine_name": "DuckDB", - "module": "duckdb", "documentation": { "description": "DuckDB is an in-process OLAP database designed for fast analytical queries on local data. Supports CSV, Parquet, JSON, and many other file formats.", "logo": "duckdb.png", "homepage_url": "https://duckdb.org/", "categories": [ - "ANALYTICAL_DATABASES", - "OPEN_SOURCE" + "Analytical Databases", + "Open Source" ], "pypi_packages": [ "duckdb-engine" @@ -2033,10 +4614,11 @@ }, "notes": "Cloud-hosted DuckDB with collaboration features.", "categories": [ - "HOSTED_OPEN_SOURCE" + "Hosted Open Source" ] } ], + "category": "Other Databases", "custom_errors": [ { "regex_name": "COLUMN_DOES_NOT_EXIST_REGEX", @@ -2051,6 +4633,16 @@ } ] }, + "engine": "duckdb", + "engine_name": "DuckDB", + "engine_aliases": [], + "default_driver": "duckdb_engine", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Elasticsearch": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -2070,143 +4662,52 @@ "WEEK_ENDING_SATURDAY": false, "WEEK_ENDING_SUNDAY": false, "MONTH": true, - "QUARTER": true, + "QUARTER": false, "QUARTER_YEAR": false, "YEAR": true }, - "score": 38, - "max_score": 201, - "joins": true, + "module": "superset.db_engine_specs.elasticsearch", + "limit_method": 1, + "limit_clause": true, + "joins": false, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": true, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": false, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "MotherDuck": { - "engine": "motherduck", - "engine_name": "MotherDuck", - "module": "duckdb", - "documentation": { - "description": "MotherDuck is a serverless cloud analytics platform built on DuckDB. It combines the simplicity of DuckDB with cloud-scale data sharing and collaboration.", - "logo": "motherduck.png", - "homepage_url": "https://motherduck.com/", - "pypi_packages": [ - "duckdb-engine", - "duckdb", - "duckdb-engine" - ], - "connection_string": "duckdb:///md:{database}?motherduck_token={token}", - "drivers": [ - { - "name": "duckdb-engine", - "pypi_package": "duckdb-engine", - "connection_string": "duckdb:////path/to/duck.db", - "is_recommended": true - }, - { - "name": "duckdb-engine", - "pypi_package": "duckdb-engine", - "connection_string": "duckdb:///md:{database}?motherduck_token={token}", - "is_recommended": true - } - ], - "notes": "DuckDB supports both local file and in-memory databases. Use `:memory:` for in-memory database.", - "categories": [ - "ANALYTICAL_DATABASES", - "CLOUD_DATA_WAREHOUSES", - "HOSTED_OPEN_SOURCE" - ], - "parameters": { - "database": "MotherDuck database name", - "token": "Service token from MotherDuck dashboard" - }, - "docs_url": "https://motherduck.com/docs/getting-started/", - "custom_errors": [ - { - "regex_name": "COLUMN_DOES_NOT_EXIST_REGEX", - "message_template": "We can't seem to resolve the column \"%(column_name)s\"", - "error_type": "COLUMN_DOES_NOT_EXIST_ERROR", - "category": "Query", - "description": "Column not found", - "issue_codes": [ - 1003, - 1004 - ] - } - ] - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Amazon DynamoDB": { - "engine": "amazon_dynamodb", - "engine_name": "Amazon DynamoDB", - "module": "dynamodb", - "documentation": { - "description": "Amazon DynamoDB is a serverless NoSQL database with SQL via PartiQL.", - "logo": "aws.png", - "homepage_url": "https://aws.amazon.com/dynamodb/", - "categories": [ - "CLOUD_AWS", - "SEARCH_NOSQL", - "PROPRIETARY" - ], - "pypi_packages": [ - "pydynamodb" - ], - "connection_string": "dynamodb://{aws_access_key_id}:{aws_secret_access_key}@dynamodb.{region}.amazonaws.com:443?connector=superset", - "parameters": { - "aws_access_key_id": "AWS access key ID", - "aws_secret_access_key": "AWS secret access key", - "region": "AWS region (e.g., us-east-1)" - }, - "notes": "Uses PartiQL for SQL queries. Requires connector=superset parameter.", - "docs_url": "https://github.com/passren/PyDynamoDB" - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Elasticsearch": { - "engine": "elasticsearch", - "engine_name": "Elasticsearch", - "module": "elasticsearch", + "sql_validation": false, + "score": 37, + "max_score": 201, "documentation": { "description": "Elasticsearch is a distributed search and analytics engine. Query data using Elasticsearch SQL or OpenSearch SQL syntax.", "logo": "elasticsearch.png", "homepage_url": "https://www.elastic.co/elasticsearch/", "categories": [ - "SEARCH_NOSQL", - "OPEN_SOURCE" + "Search & NoSQL", + "Open Source" ], "pypi_packages": [ "elasticsearch-dbapi" @@ -2241,8 +4742,8 @@ "logo": "elasticsearch.png", "homepage_url": "https://www.elastic.co/cloud/", "categories": [ - "SEARCH_NOSQL", - "HOSTED_OPEN_SOURCE" + "Search & NoSQL", + "Hosted Open Source" ], "pypi_packages": [ "elasticsearch-dbapi" @@ -2256,9 +4757,9 @@ "logo": "elasticsearch.png", "homepage_url": "https://aws.amazon.com/opensearch-service/", "categories": [ - "SEARCH_NOSQL", - "CLOUD_AWS", - "HOSTED_OPEN_SOURCE" + "Search & NoSQL", + "Cloud - AWS", + "Hosted Open Source" ], "pypi_packages": [ "elasticsearch-dbapi" @@ -2266,34 +4767,84 @@ "connection_string": "odelasticsearch+https://{user}:{password}@{host}:443/", "docs_url": "https://docs.aws.amazon.com/opensearch-service/latest/developerguide/" } - ] + ], + "category": "Search & NoSQL" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, + "engine": "elasticsearch", + "engine_name": "Elasticsearch", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, "Exasol": { - "engine": "exasol", - "engine_name": "Exasol", - "module": "exasol", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.exasol", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 128, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 28, + "max_score": 201, "documentation": { "description": "Exasol is a high-performance, in-memory, MPP analytical database.", "logo": "exasol.png", "homepage_url": "https://www.exasol.com/", "categories": [ - "ANALYTICAL_DATABASES", - "PROPRIETARY" + "Analytical Databases", + "Proprietary" ], "pypi_packages": [ "sqlalchemy-exasol" @@ -2327,70 +4878,19 @@ "is_recommended": false, "notes": "Pure Python, no ODBC required." } - ] + ], + "category": "Other Databases" }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, - "MINUTE": true, - "FIVE_MINUTES": false, - "TEN_MINUTES": false, - "FIFTEEN_MINUTES": false, - "THIRTY_MINUTES": false, - "HALF_HOUR": false, - "HOUR": true, - "SIX_HOURS": false, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": false, - "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": false, - "WEEK_ENDING_SUNDAY": false, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 28, - "max_score": 201, - "joins": true, - "subqueries": true, + "engine": "exa", + "engine_name": "Exasol", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, "Firebird": { - "engine": "firebird", - "engine_name": "Firebird", - "module": "firebird", - "documentation": { - "description": "Firebird is an open-source relational database.", - "logo": "firebird.png", - "homepage_url": "https://firebirdsql.org/", - "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "sqlalchemy-firebird" - ], - "version_requirements": "sqlalchemy-firebird>=0.7.0,<0.8", - "connection_string": "firebird+fdb://{username}:{password}@{host}:{port}//{path_to_db_file}", - "default_port": 3050, - "connection_examples": [ - { - "description": "Local database", - "connection_string": "firebird+fdb://SYSDBA:masterkey@192.168.86.38:3050//Library/Frameworks/Firebird.framework/Versions/A/Resources/examples/empbuild/employee.fdb" - } - ] - }, "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -2414,53 +4914,73 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 26, - "max_score": 201, + "module": "superset.db_engine_specs.firebird", + "limit_method": 3, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "Firebolt": { - "engine": "firebolt", - "engine_name": "Firebolt", - "module": "firebolt", + "sql_validation": false, + "score": 26, + "max_score": 201, "documentation": { - "description": "Firebolt is a cloud data warehouse designed for high-performance analytics.", - "logo": "firebolt.png", - "homepage_url": "https://www.firebolt.io/", + "description": "Firebird is an open-source relational database.", + "logo": "firebird.png", + "homepage_url": "https://firebirdsql.org/", "categories": [ - "CLOUD_DATA_WAREHOUSES", - "ANALYTICAL_DATABASES", - "PROPRIETARY" + "Traditional RDBMS", + "Open Source" ], "pypi_packages": [ - "firebolt-sqlalchemy" + "sqlalchemy-firebird" ], - "connection_string": "firebolt://{client_id}:{client_secret}@{database}/{engine_name}?account_name={account_name}", - "parameters": { - "client_id": "Service account client ID", - "client_secret": "Service account client secret", - "database": "Database name", - "engine_name": "Engine name", - "account_name": "Account name" - }, - "drivers": [ + "version_requirements": "sqlalchemy-firebird>=0.7.0,<0.8", + "connection_string": "firebird+fdb://{username}:{password}@{host}:{port}//{path_to_db_file}", + "default_port": 3050, + "connection_examples": [ { - "name": "firebolt-sqlalchemy", - "pypi_package": "firebolt-sqlalchemy", - "connection_string": "firebolt://{client_id}:{client_secret}@{database}/{engine_name}?account_name={account_name}", - "is_recommended": true + "description": "Local database", + "connection_string": "firebird+fdb://SYSDBA:masterkey@192.168.86.38:3050//Library/Frameworks/Firebird.framework/Versions/A/Resources/examples/empbuild/employee.fdb" } - ] + ], + "category": "Other Databases" }, + "engine": "firebird", + "engine_name": "Firebird", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Firebolt": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -2484,98 +5004,224 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 28, - "max_score": 201, + "module": "superset.db_engine_specs.firebolt", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "Greenplum": { - "engine": "greenplum", - "engine_name": "Greenplum", - "module": "greenplum", + "sql_validation": false, + "score": 28, + "max_score": 201, "documentation": { - "description": "VMware Greenplum is a massively parallel processing (MPP) database built on PostgreSQL.", - "logo": "greenplum.png", - "homepage_url": "https://greenplum.org/", - "pypi_packages": [ - "psycopg2", - "sqlalchemy-greenplum", - "psycopg2" + "description": "Firebolt is a cloud data warehouse designed for high-performance analytics.", + "logo": "firebolt.png", + "homepage_url": "https://www.firebolt.io/", + "categories": [ + "Cloud Data Warehouses", + "Analytical Databases", + "Proprietary" ], - "connection_string": "greenplum://{username}:{password}@{host}:{port}/{database}", - "default_port": 5432, + "pypi_packages": [ + "firebolt-sqlalchemy" + ], + "connection_string": "firebolt://{client_id}:{client_secret}@{database}/{engine_name}?account_name={account_name}", "parameters": { - "username": "Database username", - "password": "Database password", - "host": "Greenplum coordinator host", - "port": "Default 5432", - "database": "Database name" + "client_id": "Service account client ID", + "client_secret": "Service account client secret", + "database": "Database name", + "engine_name": "Engine name", + "account_name": "Account name" }, - "notes": "The psycopg2 library comes bundled with Superset Docker images.", - "connection_examples": [ + "drivers": [ { - "description": "Basic connection", - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}" - }, - { - "description": "With SSL required", - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}?sslmode=require" + "name": "firebolt-sqlalchemy", + "pypi_package": "firebolt-sqlalchemy", + "connection_string": "firebolt://{client_id}:{client_secret}@{database}/{engine_name}?account_name={account_name}", + "is_recommended": true } ], - "docs_url": "https://docs.vmware.com/en/VMware-Greenplum/", - "sqlalchemy_docs_url": "https://docs.sqlalchemy.org/en/13/dialects/postgresql.html", - "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" - ] + "category": "Other Databases" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, + "engine": "firebolt", + "engine_name": "Firebolt", + "engine_aliases": [], + "default_driver": "firebolt", + "supports_file_upload": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, + "supports_dynamic_catalog": false + }, + "Google BigQuery": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.bigquery", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": true, + "cte_in_subquery": true, + "max_column_name": 128, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": true, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": false, + "catalog": true, + "dynamic_catalog": true, "ssh_tunneling": false, "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Google Sheets": { - "engine": "google_sheets", - "engine_name": "Google Sheets", - "module": "gsheets", + "get_metrics": false, + "where_latest_partition": true, + "expand_data": false, + "query_cost_estimation": true, + "sql_validation": false, + "score": 83, + "max_score": 201, "documentation": { - "description": "Google Sheets allows querying spreadsheets as SQL tables via shillelagh.", - "logo": "google-sheets.svg", - "homepage_url": "https://www.google.com/sheets/about/", - "pypi_packages": [ - "shillelagh[gsheetsapi]", - "shillelagh[gsheetsapi]" - ], - "connection_string": "gsheets://", - "notes": "Requires Google service account credentials or OAuth2 authentication. See docs for setup instructions.", + "description": "Google BigQuery is a serverless, highly scalable data warehouse.", + "logo": "google-big-query.svg", + "homepage_url": "https://cloud.google.com/bigquery/", "categories": [ - "CLOUD_GCP", - "HOSTED_OPEN_SOURCE" + "Cloud - Google", + "Analytical Databases", + "Proprietary" ], - "install_instructions": "pip install \"apache-superset[gsheets]\"", + "pypi_packages": [ + "sqlalchemy-bigquery" + ], + "connection_string": "bigquery://{project_id}", + "install_instructions": "echo \"sqlalchemy-bigquery\" >> ./docker/requirements-local.txt", + "authentication_methods": [ + { + "name": "Service Account JSON", + "description": "Upload service account credentials JSON or paste in Secure Extra", + "secure_extra": { + "credentials_info": { + "type": "service_account", + "project_id": "...", + "private_key_id": "...", + "private_key": "...", + "client_email": "...", + "client_id": "...", + "auth_uri": "...", + "token_uri": "..." + } + } + } + ], + "notes": "Create a Service Account via GCP console with access to BigQuery datasets. For CSV/Excel uploads, also install pandas_gbq.", + "warnings": [ + "Google BigQuery Python SDK is not compatible with gevent. Use a worker type other than gevent when deploying with gunicorn." + ], + "docs_url": "https://github.com/googleapis/python-bigquery-sqlalchemy", + "category": "Cloud - Google", "custom_errors": [ + { + "regex_name": "CONNECTION_DATABASE_PERMISSIONS_REGEX", + "message_template": "Unable to connect. Verify that the following roles are set on the service account: \"BigQuery Data Viewer\", \"BigQuery Metadata Viewer\", \"BigQuery Job User\" and the following permissions are set \"bigquery.readsessions.create\", \"bigquery.readsessions.getData\"", + "error_type": "CONNECTION_DATABASE_PERMISSIONS_ERROR", + "category": "Permissions", + "description": "Insufficient permissions", + "issue_codes": [ + 1017 + ] + }, + { + "regex_name": "TABLE_DOES_NOT_EXIST_REGEX", + "message_template": "The table \"%(table)s\" does not exist. A valid table must be used to run this query.", + "error_type": "TABLE_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Table not found", + "issue_codes": [ + 1003, + 1005 + ] + }, + { + "regex_name": "COLUMN_DOES_NOT_EXIST_REGEX", + "message_template": "We can't seem to resolve column \"%(column)s\" at line %(location)s.", + "error_type": "COLUMN_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Column not found", + "issue_codes": [ + 1003, + 1004 + ] + }, + { + "regex_name": "SCHEMA_DOES_NOT_EXIST_REGEX", + "message_template": "The schema \"%(schema)s\" does not exist. A valid schema must be used to run this query.", + "error_type": "SCHEMA_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Schema not found", + "issue_codes": [ + 1003, + 1016 + ] + }, { "regex_name": "SYNTAX_ERROR_REGEX", - "message_template": "Please check your query for syntax errors near \"%(server_error)s\". Then, try running your query again.", + "message_template": "Please check your query for syntax errors at or near \"%(syntax_error)s\". Then, try running your query again.", "error_type": "SYNTAX_ERROR", "category": "Query", "description": "SQL syntax error", @@ -2585,6 +5231,174 @@ } ] }, + "engine": "bigquery", + "engine_name": "Google BigQuery", + "engine_aliases": [], + "default_driver": "bigquery", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Google Datastore": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.datastore", + "limit_method": 3, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": true, + "cte_in_subquery": true, + "max_column_name": 128, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": true, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": false, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 73, + "max_score": 201, + "documentation": { + "description": "Google Cloud Datastore is a highly scalable NoSQL database for your applications.", + "logo": "datastore.png", + "homepage_url": "https://cloud.google.com/datastore/", + "categories": [ + "Cloud - Google", + "Search & NoSQL", + "Proprietary" + ], + "pypi_packages": [ + "python-datastore-sqlalchemy" + ], + "connection_string": "datastore://{project_id}/?database={database_id}", + "authentication_methods": [ + { + "name": "Service Account JSON", + "description": "Upload service account credentials JSON or paste in Secure Extra", + "secure_extra": { + "credentials_info": { + "type": "service_account", + "project_id": "...", + "private_key_id": "...", + "private_key": "...", + "client_email": "...", + "client_id": "...", + "auth_uri": "...", + "token_uri": "..." + } + } + } + ], + "notes": "Create a Service Account via GCP console with access to datastore datasets.", + "docs_url": "https://github.com/splasky/Python-datastore-sqlalchemy", + "category": "Cloud - Google", + "custom_errors": [ + { + "regex_name": "CONNECTION_DATABASE_PERMISSIONS_REGEX", + "message_template": "Unable to connect. Verify that the following roles are set on the service account: \"Cloud Datastore Viewer\", \"Cloud Datastore User\", \"Cloud Datastore Creator\"", + "error_type": "CONNECTION_DATABASE_PERMISSIONS_ERROR", + "category": "Permissions", + "description": "Insufficient permissions", + "issue_codes": [ + 1017 + ] + }, + { + "regex_name": "TABLE_DOES_NOT_EXIST_REGEX", + "message_template": "The table \"%(table)s\" does not exist. A valid table must be used to run this query.", + "error_type": "TABLE_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Table not found", + "issue_codes": [ + 1003, + 1005 + ] + }, + { + "regex_name": "COLUMN_DOES_NOT_EXIST_REGEX", + "message_template": "We can't seem to resolve column \"%(column)s\" at line %(location)s.", + "error_type": "COLUMN_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Column not found", + "issue_codes": [ + 1003, + 1004 + ] + }, + { + "regex_name": "SCHEMA_DOES_NOT_EXIST_REGEX", + "message_template": "The schema \"%(schema)s\" does not exist. A valid schema must be used to run this query.", + "error_type": "SCHEMA_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Schema not found", + "issue_codes": [ + 1003, + 1016 + ] + }, + { + "regex_name": "SYNTAX_ERROR_REGEX", + "message_template": "Please check your query for syntax errors at or near \"%(syntax_error)s\". Then, try running your query again.", + "error_type": "SYNTAX_ERROR", + "category": "Query", + "description": "SQL syntax error", + "issue_codes": [ + 1030 + ] + } + ] + }, + "engine": "datastore", + "engine_name": "Google Datastore", + "engine_aliases": [], + "default_driver": "datastore", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Google Sheets": { "time_grains": { "SECOND": true, "FIVE_SECONDS": true, @@ -2608,55 +5422,93 @@ "QUARTER_YEAR": true, "YEAR": true }, - "score": 61, - "max_score": 201, + "module": "superset.db_engine_specs.gsheets", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": true, + "user_impersonation": true, + "file_upload": true, + "get_extra_table_metadata": true, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": false, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "SAP HANA": { - "engine": "sap_hana", - "engine_name": "SAP HANA", - "module": "hana", + "sql_validation": false, + "score": 61, + "max_score": 201, "documentation": { - "description": "SAP HANA is an in-memory relational database and application platform.", - "logo": "sap-hana.png", - "homepage_url": "https://www.sap.com/products/technology-platform/hana.html", + "description": "Google Sheets allows querying spreadsheets as SQL tables via shillelagh.", + "logo": "google-sheets.svg", + "homepage_url": "https://www.google.com/sheets/about/", "categories": [ - "TRADITIONAL_RDBMS", - "PROPRIETARY" + "Cloud - Google", + "Hosted Open Source" ], "pypi_packages": [ - "hdbcli", - "sqlalchemy-hana" + "shillelagh[gsheetsapi]" ], - "install_instructions": "pip install apache_superset[hana]", - "connection_string": "hana://{username}:{password}@{host}:{port}", - "default_port": 30015, - "docs_url": "https://github.com/SAP/sqlalchemy-hana" + "install_instructions": "pip install \"apache-superset[gsheets]\"", + "connection_string": "gsheets://", + "notes": "Requires Google service account credentials or OAuth2 authentication. See docs for setup instructions.", + "category": "Cloud - Google", + "custom_errors": [ + { + "regex_name": "SYNTAX_ERROR_REGEX", + "message_template": "Please check your query for syntax errors near \"%(server_error)s\". Then, try running your query again.", + "error_type": "SYNTAX_ERROR", + "category": "Query", + "description": "SQL syntax error", + "issue_codes": [ + 1030 + ] + } + ] }, + "engine": "gsheets", + "engine_name": "Google Sheets", + "engine_aliases": [], + "default_driver": "apsw", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Greenplum": { "time_grains": { "SECOND": true, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, "MINUTE": true, - "FIVE_MINUTES": false, - "TEN_MINUTES": false, - "FIFTEEN_MINUTES": false, - "THIRTY_MINUTES": false, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, "HALF_HOUR": false, "HOUR": true, "SIX_HOURS": false, "DAY": true, - "WEEK": false, + "WEEK": true, "WEEK_STARTING_SUNDAY": false, "WEEK_STARTING_MONDAY": false, "WEEK_ENDING_SATURDAY": false, @@ -2666,54 +5518,169 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 27, - "max_score": 201, + "module": "superset.db_engine_specs.greenplum", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 63, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": true, + "sql_validation": false, + "score": 94, + "max_score": 201, + "documentation": { + "description": "VMware Greenplum is a massively parallel processing (MPP) database built on PostgreSQL.", + "logo": "greenplum.png", + "homepage_url": "https://greenplum.org/", + "categories": [ + "Traditional RDBMS", + "Open Source" + ], + "pypi_packages": [ + "sqlalchemy-greenplum", + "psycopg2" + ], + "connection_string": "greenplum://{username}:{password}@{host}:{port}/{database}", + "default_port": 5432, + "parameters": { + "username": "Database username", + "password": "Database password", + "host": "Greenplum coordinator host", + "port": "Default 5432", + "database": "Database name" + }, + "docs_url": "https://docs.vmware.com/en/VMware-Greenplum/", + "category": "Other Databases" + }, + "engine": "greenplum", + "engine_name": "Greenplum", + "engine_aliases": [ + "postgres" + ], + "default_driver": "psycopg2", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Hologres": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.hologres", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "Apache Hive": { - "engine": "apache_hive", - "engine_name": "Apache Hive", - "module": "hive", + "sql_validation": false, + "score": 34, + "max_score": 201, "documentation": { - "description": "Apache Hive is a data warehouse infrastructure built on Hadoop.", - "logo": "apache-hive.svg", - "homepage_url": "https://hive.apache.org/", - "pypi_packages": [ - "pyhive", - "pyhive" - ], - "install_instructions": "pip install \"apache-superset[presto]\"", - "connection_string": "hive://hive@{hostname}:{port}/{database}", - "default_port": 10000, - "parameters": { - "hostname": "Presto coordinator hostname", - "port": "Presto coordinator port (default 8080)", - "database": "Catalog name" - }, - "drivers": [ - { - "name": "PyHive", - "pypi_package": "pyhive", - "connection_string": "presto://{hostname}:{port}/{database}", - "is_recommended": true - } - ], + "description": "Alibaba Cloud Hologres is a real-time interactive analytics service, fully compatible with PostgreSQL 11.", + "logo": "hologres.png", + "homepage_url": "https://www.alibabacloud.com/product/hologres", "categories": [ - "APACHE_PROJECTS", - "QUERY_ENGINES", - "OPEN_SOURCE" - ] + "Cloud Data Warehouses", + "Analytical Databases", + "Proprietary" + ], + "pypi_packages": [ + "psycopg2" + ], + "connection_string": "postgresql+psycopg2://{username}:{password}@{host}:{port}/{database}", + "parameters": { + "username": "AccessKey ID of your Alibaba Cloud account", + "password": "AccessKey secret of your Alibaba Cloud account", + "host": "Public endpoint of the Hologres instance", + "port": "Port number of the Hologres instance", + "database": "Name of the Hologres database" + }, + "default_port": 80, + "notes": "Uses the PostgreSQL driver. psycopg2 comes bundled with Superset.", + "category": "Other Databases" }, + "engine": "hologres", + "engine_name": "Hologres", + "engine_aliases": [], + "default_driver": "psycopg2", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "IBM Db2": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -2728,82 +5695,57 @@ "SIX_HOURS": false, "DAY": true, "WEEK": true, - "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_SUNDAY": false, "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SATURDAY": false, "WEEK_ENDING_SUNDAY": false, "MONTH": true, "QUARTER": true, "QUARTER_YEAR": false, "YEAR": true }, - "score": 140, - "max_score": 201, + "module": "superset.db_engine_specs.db2", + "limit_method": 2, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": true, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": true, - "query_cost_estimation": true, - "sql_validation": false - }, - "Hologres": { - "engine": "hologres", - "engine_name": "Hologres", - "module": "hologres", - "documentation": { - "description": "Alibaba Cloud Hologres is a real-time interactive analytics service, fully compatible with PostgreSQL 11.", - "logo": "hologres.png", - "homepage_url": "https://www.alibabacloud.com/product/hologres", - "categories": [ - "CLOUD_DATA_WAREHOUSES", - "ANALYTICAL_DATABASES", - "PROPRIETARY" - ], - "pypi_packages": [ - "psycopg2" - ], - "connection_string": "postgresql+psycopg2://{username}:{password}@{host}:{port}/{database}", - "parameters": { - "username": "AccessKey ID of your Alibaba Cloud account", - "password": "AccessKey secret of your Alibaba Cloud account", - "host": "Public endpoint of the Hologres instance", - "port": "Port number of the Hologres instance", - "database": "Name of the Hologres database" - }, - "default_port": 80, - "notes": "Uses the PostgreSQL driver. psycopg2 comes bundled with Superset." - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 30, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "IBM Db2 for i": { - "engine": "ibm_db2_for_i", - "engine_name": "IBM Db2 for i", - "module": "ibmi", + "sql_validation": false, + "score": 38, + "max_score": 201, "documentation": { "description": "IBM Db2 is a family of data management products for enterprise workloads, available on-premises, in containers, and across cloud platforms.", "logo": "ibm-db2.svg", "homepage_url": "https://www.ibm.com/db2", "categories": [ - "TRADITIONAL_RDBMS", - "PROPRIETARY" + "Traditional RDBMS", + "Proprietary" ], "pypi_packages": [ "ibm_db_sa" @@ -2823,195 +5765,43 @@ "notes": "Use for older DB2 versions without LIMIT [n] syntax. Recommended for SQL Lab." } ], - "docs_url": "https://github.com/ibmdb/python-ibmdbsa" - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Apache Impala": { - "engine": "apache_impala", - "engine_name": "Apache Impala", - "module": "impala", - "documentation": { - "description": "Apache Impala is an open-source massively parallel processing SQL query engine.", - "logo": "apache-impala.png", - "homepage_url": "https://impala.apache.org/", - "categories": [ - "APACHE_PROJECTS", - "QUERY_ENGINES", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "impyla" - ], - "connection_string": "impala://{hostname}:{port}/{database}", - "default_port": 21050 - }, - "time_grains": { - "SECOND": false, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, - "MINUTE": true, - "FIVE_MINUTES": false, - "TEN_MINUTES": false, - "FIFTEEN_MINUTES": false, - "THIRTY_MINUTES": false, - "HALF_HOUR": false, - "HOUR": true, - "SIX_HOURS": false, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": false, - "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": false, - "WEEK_ENDING_SUNDAY": false, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 37, - "max_score": 201, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Apache IoTDB": { - "engine": "apache_iotdb", - "engine_name": "Apache IoTDB", - "module": "iotdb", - "documentation": { - "description": "Apache IoTDB is a time series database designed for IoT data, with efficient storage and query capabilities for massive time series data.", - "logo": "apache-iotdb.svg", - "homepage_url": "https://iotdb.apache.org/", - "categories": [ - "APACHE_PROJECTS", - "TIME_SERIES", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "apache-iotdb" - ], - "connection_string": "iotdb://{username}:{password}@{hostname}:{port}", - "default_port": 6667, - "parameters": { - "username": "Database username (default: root)", - "password": "Database password (default: root)", - "hostname": "IP address or hostname", - "port": "Default 6667" - }, - "notes": "The IoTDB SQLAlchemy dialect was written to integrate with Apache Superset. IoTDB uses a hierarchical data model, which is reorganized into a relational model for SQL queries." - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Azure Data Explorer": { - "engine": "azure_data_explorer", - "engine_name": "Azure Data Explorer", - "module": "kusto", - "documentation": { - "description": "Azure Data Explorer (Kusto) is a fast, fully managed data analytics service from Microsoft Azure. Query data using SQL or native KQL syntax.", - "logo": "kusto.png", - "homepage_url": "https://azure.microsoft.com/en-us/products/data-explorer/", - "categories": [ - "CLOUD_AZURE", - "ANALYTICAL_DATABASES", - "PROPRIETARY" - ], - "pypi_packages": [ - "sqlalchemy-kusto" - ], - "connection_string": "kustosql+https://{cluster}.kusto.windows.net/{database}?msi=False&azure_ad_client_id={client_id}&azure_ad_client_secret={client_secret}&azure_ad_tenant_id={tenant_id}", - "parameters": { - "cluster": "Azure Data Explorer cluster name", - "database": "Database name", - "client_id": "Azure AD application (client) ID", - "client_secret": "Azure AD application secret", - "tenant_id": "Azure AD tenant ID" - }, - "drivers": [ + "compatible_databases": [ { - "name": "SQL Interface (Recommended)", - "pypi_package": "sqlalchemy-kusto", - "connection_string": "kustosql+https://{cluster}.kusto.windows.net/{database}?msi=False&azure_ad_client_id={client_id}&azure_ad_client_secret={client_secret}&azure_ad_tenant_id={tenant_id}", - "is_recommended": true, - "notes": "Use familiar SQL syntax to query Azure Data Explorer." - }, - { - "name": "KQL (Kusto Query Language)", - "pypi_package": "sqlalchemy-kusto", - "connection_string": "kustokql+https://{cluster}.kusto.windows.net/{database}?msi=False&azure_ad_client_id={client_id}&azure_ad_client_secret={client_secret}&azure_ad_tenant_id={tenant_id}", - "is_recommended": false, - "notes": "Use native Kusto Query Language for advanced analytics." + "name": "IBM Db2 for i (AS/400)", + "description": "Db2 for i is a fully integrated database engine on IBM i (AS/400) systems. Uses a different SQLAlchemy driver optimized for IBM i.", + "logo": "ibm-db2.svg", + "homepage_url": "https://www.ibm.com/products/db2-for-i", + "pypi_packages": [ + "sqlalchemy-ibmi" + ], + "connection_string": "ibmi://{username}:{password}@{host}/{database}", + "parameters": { + "username": "IBM i username", + "password": "IBM i password", + "host": "IBM i system host", + "database": "Library/schema name" + }, + "docs_url": "https://github.com/IBM/sqlalchemy-ibmi", + "categories": [ + "Proprietary" + ] } - ] + ], + "docs_url": "https://github.com/ibmdb/python-ibmdbsa", + "category": "Other Databases" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, + "engine": "db2", + "engine_name": "IBM Db2", + "engine_aliases": [ + "ibm_db_sa" + ], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": true, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, - "Apache Kylin": { - "engine": "apache_kylin", - "engine_name": "Apache Kylin", - "module": "kylin", - "documentation": { - "description": "Apache Kylin is an open-source OLAP engine for big data.", - "logo": "apache-kylin.png", - "homepage_url": "https://kylin.apache.org/", - "categories": [ - "APACHE_PROJECTS", - "ANALYTICAL_DATABASES", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "kylinpy" - ], - "connection_string": "kylin://{username}:{password}@{hostname}:{port}/{project}?{param1}={value1}&{param2}={value2}", - "default_port": 7070 - }, + "IBM Db2 for i": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -3035,80 +5825,187 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 28, - "max_score": 201, + "module": "superset.db_engine_specs.ibmi", + "limit_method": 2, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 128, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "MariaDB": { - "engine": "mariadb", - "engine_name": "MariaDB", - "module": "mariadb", + "sql_validation": false, + "score": 38, + "max_score": 201, "documentation": { - "description": "MariaDB is a community-developed fork of MySQL.", - "logo": "mariadb.png", - "homepage_url": "https://mariadb.org/", + "description": "IBM Db2 is a family of data management products for enterprise workloads, available on-premises, in containers, and across cloud platforms.", + "logo": "ibm-db2.svg", + "homepage_url": "https://www.ibm.com/db2", + "categories": [ + "Traditional RDBMS", + "Proprietary" + ], "pypi_packages": [ - "mysqlclient", - "mysqlclient" - ], - "connection_string": "mysql://{username}:{password}@{host}/{database}", - "default_port": 3306, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "localhost, 127.0.0.1, IP address, or hostname", - "database": "Database name" - }, - "host_examples": [ - { - "platform": "Localhost", - "host": "localhost or 127.0.0.1" - }, - { - "platform": "Docker on Linux", - "host": "172.18.0.1" - }, - { - "platform": "Docker on macOS", - "host": "docker.for.mac.host.internal" - }, - { - "platform": "On-premise", - "host": "IP address or hostname" - } + "ibm_db_sa" ], + "connection_string": "db2+ibm_db://{username}:{password}@{hostname}:{port}/{database}", + "default_port": 50000, "drivers": [ { - "name": "mysqlclient", - "pypi_package": "mysqlclient", - "connection_string": "mysql://{username}:{password}@{host}/{database}", - "is_recommended": true, - "notes": "Recommended driver. May fail with caching_sha2_password auth." + "name": "ibm_db_sa (with LIMIT)", + "connection_string": "db2+ibm_db://{username}:{password}@{hostname}:{port}/{database}", + "is_recommended": true }, { - "name": "mysql-connector-python", - "pypi_package": "mysql-connector-python", - "connection_string": "mysql+mysqlconnector://{username}:{password}@{host}/{database}", + "name": "ibm_db_sa (without LIMIT syntax)", + "connection_string": "ibm_db_sa://{username}:{password}@{hostname}:{port}/{database}", "is_recommended": false, - "notes": "Required for newer MySQL databases using caching_sha2_password authentication." + "notes": "Use for older DB2 versions without LIMIT [n] syntax. Recommended for SQL Lab." } ], - "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" + "compatible_databases": [ + { + "name": "IBM Db2 for i (AS/400)", + "description": "Db2 for i is a fully integrated database engine on IBM i (AS/400) systems. Uses a different SQLAlchemy driver optimized for IBM i.", + "logo": "ibm-db2.svg", + "homepage_url": "https://www.ibm.com/products/db2-for-i", + "pypi_packages": [ + "sqlalchemy-ibmi" + ], + "connection_string": "ibmi://{username}:{password}@{host}/{database}", + "parameters": { + "username": "IBM i username", + "password": "IBM i password", + "host": "IBM i system host", + "database": "Library/schema name" + }, + "docs_url": "https://github.com/IBM/sqlalchemy-ibmi", + "categories": [ + "Proprietary" + ] + } ], - "notes": "Uses the MySQL driver. Fully compatible with MySQL connector." + "docs_url": "https://github.com/ibmdb/python-ibmdbsa", + "category": "Other Databases" }, + "engine": "ibmi", + "engine_name": "IBM Db2 for i", + "engine_aliases": [ + "ibm_db_sa" + ], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "IBM Netezza Performance Server": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.netezza", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 28, + "max_score": 201, + "documentation": { + "description": "IBM Netezza Performance Server is a data warehouse appliance.", + "logo": "netezza.png", + "homepage_url": "https://www.ibm.com/products/netezza", + "categories": [ + "Traditional RDBMS", + "Proprietary" + ], + "pypi_packages": [ + "nzalchemy" + ], + "connection_string": "netezza+nzpy://{username}:{password}@{hostname}:{port}/{database}", + "default_port": 5480, + "category": "Other Databases" + }, + "engine": "netezza", + "engine_name": "IBM Netezza Performance Server", + "engine_aliases": [], + "default_driver": "nzpy", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "MariaDB": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -3132,31 +6029,274 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 59, - "max_score": 201, + "module": "superset.db_engine_specs.mariadb", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 64, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false + "sql_validation": false, + "score": 59, + "max_score": 201, + "documentation": { + "description": "MariaDB is a community-developed fork of MySQL.", + "logo": "mariadb.png", + "homepage_url": "https://mariadb.org/", + "categories": [ + "Traditional RDBMS", + "Open Source" + ], + "pypi_packages": [ + "mysqlclient" + ], + "connection_string": "mysql://{username}:{password}@{host}/{database}", + "default_port": 3306, + "notes": "Uses the MySQL driver. Fully compatible with MySQL connector.", + "category": "Traditional RDBMS" + }, + "engine": "mariadb", + "engine_name": "MariaDB", + "engine_aliases": [], + "default_driver": "mysqldb", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Microsoft SQL Server": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.mssql", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": false, + "max_column_name": 128, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 44, + "max_score": 201, + "documentation": { + "description": "Microsoft SQL Server is a relational database management system.", + "logo": "msql.png", + "homepage_url": "https://www.microsoft.com/en-us/sql-server", + "categories": [ + "Traditional RDBMS", + "Proprietary" + ], + "pypi_packages": [ + "pymssql" + ], + "connection_string": "mssql+pymssql://{username}:{password}@{host}:{port}/{database}", + "default_port": 1433, + "drivers": [ + { + "name": "pymssql", + "pypi_package": "pymssql", + "connection_string": "mssql+pymssql://{username}:{password}@{host}:{port}/{database}", + "is_recommended": true + }, + { + "name": "pyodbc", + "pypi_package": "pyodbc", + "connection_string": "mssql+pyodbc:///?odbc_connect=Driver%3D%7BODBC+Driver+17+for+SQL+Server%7D%3BServer%3Dtcp%3A%3C{host}%3E%2C1433%3BDatabase%3D{database}%3BUid%3D{username}%3BPwd%3D{password}%3BEncrypt%3Dyes%3BConnection+Timeout%3D30", + "is_recommended": false, + "notes": "Connection string must be URL-encoded. Special characters like @ need encoding." + } + ], + "docs_url": "https://docs.sqlalchemy.org/en/20/core/engines.html#escaping-special-characters-such-as-signs-in-passwords", + "category": "Cloud - Azure", + "custom_errors": [ + { + "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", + "message_template": "Either the username \"%(username)s\", password, or database name \"%(database)s\" is incorrect.", + "error_type": "CONNECTION_ACCESS_DENIED_ERROR", + "category": "Authentication", + "description": "Access denied", + "issue_codes": [ + 1014, + 1015 + ] + }, + { + "regex_name": "CONNECTION_INVALID_HOSTNAME_REGEX", + "message_template": "The hostname \"%(hostname)s\" cannot be resolved.", + "error_type": "CONNECTION_INVALID_HOSTNAME_ERROR", + "category": "Connection", + "description": "Invalid hostname", + "issue_codes": [ + 1007 + ] + }, + { + "regex_name": "CONNECTION_PORT_CLOSED_REGEX", + "message_template": "Port %(port)s on hostname \"%(hostname)s\" refused the connection.", + "error_type": "CONNECTION_PORT_CLOSED_ERROR", + "category": "Connection", + "description": "Port closed or refused", + "issue_codes": [ + 1008 + ] + }, + { + "regex_name": "CONNECTION_HOST_DOWN_REGEX", + "message_template": "The host \"%(hostname)s\" might be down, and can't be reached on port %(port)s.", + "error_type": "CONNECTION_HOST_DOWN_ERROR", + "category": "Connection", + "description": "Host unreachable", + "issue_codes": [ + 1009 + ] + } + ] + }, + "engine": "mssql", + "engine_name": "Microsoft SQL Server", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false }, "MonetDB": { - "engine": "monetdb", - "engine_name": "MonetDB", - "module": "monetdb", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": false, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": false, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.monetdb", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 26, + "max_score": 201, "documentation": { "description": "MonetDB is an open-source column-oriented relational database for high-performance analytics.", "logo": "monet-db.png", "homepage_url": "https://www.monetdb.org/", "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" + "Traditional RDBMS", + "Open Source" ], "pypi_packages": [ "sqlalchemy-monetdb", @@ -3171,34 +6311,84 @@ "port": "Default 50000", "database": "Database name" }, - "docs_url": "https://www.monetdb.org/documentation/" + "docs_url": "https://www.monetdb.org/documentation/", + "category": "Other Databases" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, + "engine": "monetdb", + "engine_name": "MonetDB", + "engine_aliases": [], + "default_driver": "pymonetdb", + "supports_file_upload": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, "MongoDB": { - "engine": "mongodb", - "engine_name": "MongoDB", - "module": "mongodb", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": true, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.mongodb", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 32, + "max_score": 201, "documentation": { "description": "MongoDB is a document-oriented, operational NoSQL database.", "logo": "mongodb.png", "homepage_url": "https://www.mongodb.com/", "categories": [ - "SEARCH_NOSQL", - "PROPRIETARY" + "Search & NoSQL", + "Proprietary" ], "pypi_packages": [ "pymongosql" @@ -3228,115 +6418,146 @@ } ], "notes": "Uses PartiQL for SQL queries. Requires mode=superset parameter.", - "docs_url": "https://github.com/passren/PyMongoSQL" + "docs_url": "https://github.com/passren/PyMongoSQL", + "category": "Other Databases" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, + "engine": "mongodb", + "engine_name": "MongoDB", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, - "Microsoft SQL Server": { - "engine": "microsoft_sql_server", - "engine_name": "Microsoft SQL Server", - "module": "mssql", - "documentation": { - "description": "Microsoft SQL Server is a relational database management system.", - "logo": "msql.png", - "homepage_url": "https://www.microsoft.com/en-us/sql-server", - "categories": [ - "TRADITIONAL_RDBMS", - "PROPRIETARY" - ], - "pypi_packages": [ - "pymssql" - ], - "connection_string": "mssql+pymssql://{username}:{password}@{host}:{port}/{database}", - "default_port": 1433, - "drivers": [ - { - "name": "pymssql", - "pypi_package": "pymssql", - "connection_string": "mssql+pymssql://{username}:{password}@{host}:{port}/{database}", - "is_recommended": true - }, - { - "name": "pyodbc", - "pypi_package": "pyodbc", - "connection_string": "mssql+pyodbc:///?odbc_connect=Driver%3D%7BODBC+Driver+17+for+SQL+Server%7D%3BServer%3Dtcp%3A%3C{host}%3E%2C1433%3BDatabase%3D{database}%3BUid%3D{username}%3BPwd%3D{password}%3BEncrypt%3Dyes%3BConnection+Timeout%3D30", - "is_recommended": false, - "notes": "Connection string must be URL-encoded. Special characters like @ need encoding." - } - ], - "docs_url": "https://docs.sqlalchemy.org/en/20/core/engines.html#escaping-special-characters-such-as-signs-in-passwords", - "custom_errors": [ - { - "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", - "message_template": "Either the username \"%(username)s\", password, or database name \"%(database)s\" is incorrect.", - "error_type": "CONNECTION_ACCESS_DENIED_ERROR", - "category": "Authentication", - "description": "Access denied", - "issue_codes": [ - 1014, - 1015 - ] - }, - { - "regex_name": "CONNECTION_INVALID_HOSTNAME_REGEX", - "message_template": "The hostname \"%(hostname)s\" cannot be resolved.", - "error_type": "CONNECTION_INVALID_HOSTNAME_ERROR", - "category": "Connection", - "description": "Invalid hostname", - "issue_codes": [ - 1007 - ] - }, - { - "regex_name": "CONNECTION_PORT_CLOSED_REGEX", - "message_template": "Port %(port)s on hostname \"%(hostname)s\" refused the connection.", - "error_type": "CONNECTION_PORT_CLOSED_ERROR", - "category": "Connection", - "description": "Port closed or refused", - "issue_codes": [ - 1008 - ] - }, - { - "regex_name": "CONNECTION_HOST_DOWN_REGEX", - "message_template": "The host \"%(hostname)s\" might be down, and can't be reached on port %(port)s.", - "error_type": "CONNECTION_HOST_DOWN_ERROR", - "category": "Connection", - "description": "Host unreachable", - "issue_codes": [ - 1009 - ] - } - ] - }, + "MotherDuck": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, "THIRTY_SECONDS": false, "MINUTE": true, - "FIVE_MINUTES": true, - "TEN_MINUTES": true, - "FIFTEEN_MINUTES": true, - "THIRTY_MINUTES": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, "HALF_HOUR": false, "HOUR": true, "SIX_HOURS": false, "DAY": true, "WEEK": true, - "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.duckdb", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 58, + "max_score": 201, + "documentation": { + "description": "MotherDuck is a serverless cloud analytics platform built on DuckDB. It combines the simplicity of DuckDB with cloud-scale data sharing and collaboration.", + "logo": "motherduck.png", + "homepage_url": "https://motherduck.com/", + "categories": [ + "Analytical Databases", + "Cloud Data Warehouses", + "Hosted Open Source" + ], + "pypi_packages": [ + "duckdb", + "duckdb-engine" + ], + "connection_string": "duckdb:///md:{database}?motherduck_token={token}", + "parameters": { + "database": "MotherDuck database name", + "token": "Service token from MotherDuck dashboard" + }, + "docs_url": "https://motherduck.com/docs/getting-started/", + "drivers": [ + { + "name": "duckdb-engine", + "pypi_package": "duckdb-engine", + "connection_string": "duckdb:///md:{database}?motherduck_token={token}", + "is_recommended": true + } + ], + "category": "Other Databases", + "custom_errors": [ + { + "regex_name": "COLUMN_DOES_NOT_EXIST_REGEX", + "message_template": "We can't seem to resolve the column \"%(column_name)s\"", + "error_type": "COLUMN_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Column not found", + "issue_codes": [ + 1003, + 1004 + ] + } + ] + }, + "engine": "motherduck", + "engine_name": "MotherDuck", + "engine_aliases": [ + "duckdb" + ], + "default_driver": "duckdb_engine", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "MySQL": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, "WEEK_STARTING_MONDAY": true, "WEEK_ENDING_SATURDAY": false, "WEEK_ENDING_SUNDAY": false, @@ -3345,125 +6566,48 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 44, - "max_score": 201, + "module": "superset.db_engine_specs.mysql", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 64, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, - "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "Azure Synapse": { - "engine": "azure_synapse", - "engine_name": "Azure Synapse", - "module": "mssql", - "documentation": { - "description": "Azure Synapse Analytics is a cloud-based enterprise data warehouse from Microsoft that combines big data and data warehousing.", - "logo": "azure.svg", - "homepage_url": "https://azure.microsoft.com/en-us/products/synapse-analytics/", - "pypi_packages": [ - "pymssql", - "pymssql" - ], - "connection_string": "mssql+pymssql://{username}@{server}:{password}@{server}.database.windows.net:1433/{database}", - "default_port": 1433, - "drivers": [ - { - "name": "pymssql", - "pypi_package": "pymssql", - "connection_string": "mssql+pymssql://{username}:{password}@{host}:{port}/{database}", - "is_recommended": true - }, - { - "name": "pyodbc", - "pypi_package": "pyodbc", - "connection_string": "mssql+pyodbc:///?odbc_connect=Driver%3D%7BODBC+Driver+17+for+SQL+Server%7D%3BServer%3Dtcp%3A%3C{host}%3E%2C1433%3BDatabase%3D{database}%3BUid%3D{username}%3BPwd%3D{password}%3BEncrypt%3Dyes%3BConnection+Timeout%3D30", - "is_recommended": false, - "notes": "Connection string must be URL-encoded. Special characters like @ need encoding." - } - ], - "docs_url": "https://docs.sqlalchemy.org/en/20/core/engines.html#escaping-special-characters-such-as-signs-in-passwords", - "categories": [ - "CLOUD_DATA_WAREHOUSES", - "ANALYTICAL_DATABASES", - "PROPRIETARY" - ], - "custom_errors": [ - { - "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", - "message_template": "Either the username \"%(username)s\", password, or database name \"%(database)s\" is incorrect.", - "error_type": "CONNECTION_ACCESS_DENIED_ERROR", - "category": "Authentication", - "description": "Access denied", - "issue_codes": [ - 1014, - 1015 - ] - }, - { - "regex_name": "CONNECTION_INVALID_HOSTNAME_REGEX", - "message_template": "The hostname \"%(hostname)s\" cannot be resolved.", - "error_type": "CONNECTION_INVALID_HOSTNAME_ERROR", - "category": "Connection", - "description": "Invalid hostname", - "issue_codes": [ - 1007 - ] - }, - { - "regex_name": "CONNECTION_PORT_CLOSED_REGEX", - "message_template": "Port %(port)s on hostname \"%(hostname)s\" refused the connection.", - "error_type": "CONNECTION_PORT_CLOSED_ERROR", - "category": "Connection", - "description": "Port closed or refused", - "issue_codes": [ - 1008 - ] - }, - { - "regex_name": "CONNECTION_HOST_DOWN_REGEX", - "message_template": "The host \"%(hostname)s\" might be down, and can't be reached on port %(port)s.", - "error_type": "CONNECTION_HOST_DOWN_ERROR", - "category": "Connection", - "description": "Host unreachable", - "issue_codes": [ - 1009 - ] - } - ] - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "MySQL": { - "engine": "mysql", - "engine_name": "MySQL", - "module": "mysql", + "sql_validation": false, + "score": 59, + "max_score": 201, "documentation": { "description": "MySQL is a popular open-source relational database.", "logo": "mysql.png", "homepage_url": "https://www.mysql.com/", "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" + "Traditional RDBMS", + "Open Source" ], "pypi_packages": [ "mysqlclient" @@ -3521,7 +6665,7 @@ ], "connection_string": "mysql://{username}:{password}@{host}:{port}/{database}", "categories": [ - "OPEN_SOURCE" + "Open Source" ] }, { @@ -3543,11 +6687,12 @@ }, "notes": "Uses the Data API for serverless access. Standard MySQL connections also work with mysqlclient.", "categories": [ - "CLOUD_AWS", - "HOSTED_OPEN_SOURCE" + "Cloud - AWS", + "Hosted Open Source" ] } ], + "category": "Traditional RDBMS", "custom_errors": [ { "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", @@ -3616,6 +6761,16 @@ } ] }, + "engine": "mysql", + "engine_name": "MySQL", + "engine_aliases": [], + "default_driver": "mysqldb", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "OceanBase": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -3639,111 +6794,54 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 59, - "max_score": 201, + "module": "superset.db_engine_specs.oceanbase", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 128, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "IBM Netezza Performance Server": { - "engine": "ibm_netezza_performance_server", - "engine_name": "IBM Netezza Performance Server", - "module": "netezza", - "documentation": { - "description": "IBM Netezza Performance Server is a data warehouse appliance.", - "logo": "netezza.png", - "homepage_url": "https://www.ibm.com/products/netezza", - "categories": [ - "TRADITIONAL_RDBMS", - "PROPRIETARY" - ], - "pypi_packages": [ - "nzalchemy" - ], - "connection_string": "netezza+nzpy://{username}:{password}@{hostname}:{port}/{database}", - "default_port": 5480 - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "OceanBase": { - "engine": "oceanbase", - "engine_name": "OceanBase", - "module": "oceanbase", + "sql_validation": false, + "score": 59, + "max_score": 201, "documentation": { "description": "OceanBase is a distributed relational database.", "logo": "oceanbase.svg", "homepage_url": "https://www.oceanbase.com/", + "categories": [ + "Traditional RDBMS", + "Open Source" + ], "pypi_packages": [ - "mysqlclient", "oceanbase_py" ], "connection_string": "oceanbase://{username}:{password}@{host}:{port}/{database}", - "default_port": 3306, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "localhost, 127.0.0.1, IP address, or hostname", - "database": "Database name" - }, - "host_examples": [ - { - "platform": "Localhost", - "host": "localhost or 127.0.0.1" - }, - { - "platform": "Docker on Linux", - "host": "172.18.0.1" - }, - { - "platform": "Docker on macOS", - "host": "docker.for.mac.host.internal" - }, - { - "platform": "On-premise", - "host": "IP address or hostname" - } - ], - "drivers": [ - { - "name": "mysqlclient", - "pypi_package": "mysqlclient", - "connection_string": "mysql://{username}:{password}@{host}/{database}", - "is_recommended": true, - "notes": "Recommended driver. May fail with caching_sha2_password auth." - }, - { - "name": "mysql-connector-python", - "pypi_package": "mysql-connector-python", - "connection_string": "mysql+mysqlconnector://{username}:{password}@{host}/{database}", - "is_recommended": false, - "notes": "Required for newer MySQL databases using caching_sha2_password authentication." - } - ], - "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" - ], + "category": "Other Databases", "custom_errors": [ { "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", @@ -3812,36 +6910,89 @@ } ] }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, + "engine": "oceanbase", + "engine_name": "OceanBase", + "engine_aliases": [ + "oceanbase", + "oceanbase_py" + ], + "default_driver": "oceanbase", + "supports_file_upload": true, + "supports_dynamic_schema": true, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, "Ocient": { - "engine": "ocient", - "engine_name": "Ocient", - "module": "ocient", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": false, + "QUARTER_YEAR": true, + "YEAR": true + }, + "module": "superset.db_engine_specs.ocient", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": false, + "max_column_name": 30, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 38, + "max_score": 201, "documentation": { "description": "Ocient is a hyperscale data analytics database.", "categories": [ - "ANALYTICAL_DATABASES", - "PROPRIETARY" + "Analytical Databases", + "Proprietary" ], "pypi_packages": [ "sqlalchemy-ocient" ], "connection_string": "ocient://{username}:{password}@{host}:{port}/{database}", "install_instructions": "pip install sqlalchemy-ocient", + "category": "Other Databases", "custom_errors": [ { "regex_name": "CONNECTION_INVALID_USERNAME_REGEX", @@ -3932,6 +7083,16 @@ } ] }, + "engine": "ocient", + "engine_name": "Ocient", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "OpenSearch (OpenDistro)": { "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -3945,50 +7106,66 @@ "HOUR": true, "SIX_HOURS": false, "DAY": true, - "WEEK": true, + "WEEK": false, "WEEK_STARTING_SUNDAY": false, "WEEK_STARTING_MONDAY": false, "WEEK_ENDING_SATURDAY": false, "WEEK_ENDING_SUNDAY": false, "MONTH": true, "QUARTER": false, - "QUARTER_YEAR": true, + "QUARTER_YEAR": false, "YEAR": true }, - "score": 38, - "max_score": 201, - "joins": true, + "module": "superset.db_engine_specs.elasticsearch", + "limit_method": 1, + "limit_clause": true, + "joins": false, "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": true, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": false, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 26, + "max_score": 201, + "documentation": { + "pypi_packages": [], + "connection_string": "engine+driver://user:password@host:port/dbname[?key=value&key=value...]", + "category": "Other Databases" + }, + "engine": "odelasticsearch", + "engine_name": "OpenSearch (OpenDistro)", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, "Oracle": { - "engine": "oracle", - "engine_name": "Oracle", - "module": "oracle", - "documentation": { - "description": "Oracle Database is a multi-model database management system.", - "logo": "oraclelogo.png", - "homepage_url": "https://www.oracle.com/database/", - "categories": [ - "TRADITIONAL_RDBMS", - "PROPRIETARY" - ], - "pypi_packages": [ - "oracledb" - ], - "connection_string": "oracle://{username}:{password}@{hostname}:{port}", - "default_port": 1521, - "notes": "Previously used cx_Oracle, now uses oracledb.", - "docs_url": "https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html" - }, "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -4012,29 +7189,131 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 28, - "max_score": 201, + "module": "superset.db_engine_specs.oracle", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 128, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false + "sql_validation": false, + "score": 28, + "max_score": 201, + "documentation": { + "description": "Oracle Database is a multi-model database management system.", + "logo": "oraclelogo.png", + "homepage_url": "https://www.oracle.com/database/", + "categories": [ + "Traditional RDBMS", + "Proprietary" + ], + "pypi_packages": [ + "oracledb" + ], + "connection_string": "oracle://{username}:{password}@{hostname}:{port}", + "default_port": 1521, + "notes": "Previously used cx_Oracle, now uses oracledb.", + "docs_url": "https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html", + "category": "Other Databases" + }, + "engine": "oracle", + "engine_name": "Oracle", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false }, "Parseable": { - "engine": "parseable", - "engine_name": "Parseable", - "module": "parseable", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.parseable", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 28, + "max_score": 201, "documentation": { "description": "Parseable is a distributed log analytics database with SQL-like query interface.", "categories": [ - "SEARCH_NOSQL", - "OPEN_SOURCE" + "Search & NoSQL", + "Open Source" ], "pypi_packages": [ "sqlalchemy-parseable" @@ -4047,121 +7326,23 @@ } ], "notes": "Stream name in URI represents the Parseable logstream to query. Supports HTTP (80) and HTTPS (443).", - "docs_url": "https://www.parseable.io" + "docs_url": "https://www.parseable.io", + "category": "Other Databases" }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, - "MINUTE": true, - "FIVE_MINUTES": false, - "TEN_MINUTES": false, - "FIFTEEN_MINUTES": false, - "THIRTY_MINUTES": false, - "HALF_HOUR": false, - "HOUR": true, - "SIX_HOURS": false, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": false, - "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": false, - "WEEK_ENDING_SUNDAY": false, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 28, - "max_score": 201, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": false, + "engine": "parseable", + "engine_name": "Parseable", + "engine_aliases": [], + "default_driver": null, "supports_file_upload": true, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Apache Phoenix": { - "engine": "apache_phoenix", - "engine_name": "Apache Phoenix", - "module": "phoenix", - "documentation": { - "description": "Apache Phoenix is a relational database layer over Apache HBase, providing low-latency SQL queries over HBase data.", - "logo": "apache-phoenix.png", - "homepage_url": "https://phoenix.apache.org/", - "categories": [ - "APACHE_PROJECTS", - "ANALYTICAL_DATABASES", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "phoenixdb" - ], - "connection_string": "phoenix://{hostname}:{port}/", - "default_port": 8765, - "notes": "Phoenix provides a SQL interface to Apache HBase. The phoenixdb driver connects via the Phoenix Query Server and supports a subset of SQLAlchemy." - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, - "Apache Pinot": { - "engine": "apache_pinot", - "engine_name": "Apache Pinot", - "module": "pinot", - "documentation": { - "description": "Apache Pinot is a real-time distributed OLAP datastore.", - "logo": "apache-pinot.svg", - "homepage_url": "https://pinot.apache.org/", - "categories": [ - "APACHE_PROJECTS", - "TIME_SERIES", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "pinotdb" - ], - "connection_string": "pinot+http://{broker_host}:{broker_port}/query?controller=http://{controller_host}:{controller_port}/", - "default_port": 8099, - "connection_examples": [ - { - "description": "With authentication", - "connection_string": "pinot://{username}:{password}@{broker_host}:{broker_port}/query/sql?controller=http://{controller_host}:{controller_port}/verify_ssl=true" - } - ], - "engine_parameters": [ - { - "name": "Multi-stage Query Engine", - "description": "Enable for Explore view, joins, window functions", - "json": { - "connect_args": { - "use_multistage_engine": "true" - } - }, - "docs_url": "https://docs.pinot.apache.org/reference/multi-stage-engine" - } - ] - }, + "PostgreSQL": { "time_grains": { "SECOND": true, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, "MINUTE": true, "FIVE_MINUTES": true, "TEN_MINUTES": true, @@ -4181,31 +7362,48 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 32, - "max_score": 201, - "joins": false, - "subqueries": false, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": false, - "supports_file_upload": true, + "module": "superset.db_engine_specs.postgres", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 63, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "PostgreSQL": { - "engine": "postgresql", - "engine_name": "PostgreSQL", - "module": "postgres", + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": true, + "sql_validation": true, + "score": 104, + "max_score": 201, "documentation": { "description": "PostgreSQL is an advanced open-source relational database.", "logo": "postgresql.svg", "homepage_url": "https://www.postgresql.org/", "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" + "Traditional RDBMS", + "Open Source" ], "pypi_packages": [ "psycopg2" @@ -4250,7 +7448,7 @@ "database": "Name of the Hologres database" }, "categories": [ - "PROPRIETARY" + "Proprietary" ] }, { @@ -4271,7 +7469,7 @@ "notes": "psycopg2 comes bundled with Superset Docker images.", "docs_url": "https://docs.timescale.com/", "categories": [ - "OPEN_SOURCE" + "Open Source" ] }, { @@ -4286,7 +7484,7 @@ "notes": "psycopg2 comes bundled with Superset Docker images.", "docs_url": "https://www.yugabyte.com/", "categories": [ - "OPEN_SOURCE" + "Open Source" ] }, { @@ -4316,7 +7514,7 @@ "notes": "Find connection details in your Supabase project dashboard under Settings > Database. Use the connection pooler (port 6543) for better connection management.", "docs_url": "https://supabase.com/docs/guides/database/connecting-to-postgres", "categories": [ - "HOSTED_OPEN_SOURCE" + "Hosted Open Source" ] }, { @@ -4338,8 +7536,8 @@ "notes": "For public IP connections, use the AlloyDB Auth Proxy for secure access. Private IP connections can connect directly.", "docs_url": "https://cloud.google.com/alloydb/docs", "categories": [ - "CLOUD_GCP", - "HOSTED_OPEN_SOURCE" + "Cloud - Google", + "Hosted Open Source" ] }, { @@ -4360,7 +7558,7 @@ "notes": "SSL is required for all connections. Find connection details in the Neon console under Connection Details.", "docs_url": "https://neon.tech/docs/connect/connect-from-any-app", "categories": [ - "HOSTED_OPEN_SOURCE" + "Hosted Open Source" ] }, { @@ -4382,11 +7580,12 @@ }, "notes": "Uses the Data API for serverless access. Standard PostgreSQL connections also work with psycopg2.", "categories": [ - "CLOUD_AWS", - "HOSTED_OPEN_SOURCE" + "Cloud - AWS", + "Hosted Open Source" ] } ], + "category": "Traditional RDBMS", "custom_errors": [ { "regex_name": "CONNECTION_INVALID_USERNAME_REGEX", @@ -4506,6 +7705,18 @@ } ] }, + "engine": "postgresql", + "engine_name": "PostgreSQL", + "engine_aliases": [ + "postgres" + ], + "default_driver": "psycopg2", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "Presto": { "time_grains": { "SECOND": true, "FIVE_SECONDS": true, @@ -4514,46 +7725,63 @@ "FIVE_MINUTES": true, "TEN_MINUTES": true, "FIFTEEN_MINUTES": true, - "THIRTY_MINUTES": true, - "HALF_HOUR": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": true, "HOUR": true, - "SIX_HOURS": false, + "SIX_HOURS": true, "DAY": true, "WEEK": true, - "WEEK_STARTING_SUNDAY": false, - "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": false, - "WEEK_ENDING_SUNDAY": false, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": true, "MONTH": true, "QUARTER": true, "QUARTER_YEAR": false, "YEAR": true }, - "score": 104, - "max_score": 201, + "module": "superset.db_engine_specs.presto", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": true, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": true, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, + "user_impersonation": true, + "file_upload": true, + "get_extra_table_metadata": true, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, "ssh_tunneling": true, "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": true, + "expand_data": true, "query_cost_estimation": true, - "sql_validation": true - }, - "Presto": { - "engine": "presto", - "engine_name": "Presto", - "module": "presto", + "sql_validation": true, + "score": 159, + "max_score": 201, "documentation": { "description": "Presto is a distributed SQL query engine for big data.", "logo": "presto-og.png", "homepage_url": "https://prestodb.io/", "categories": [ - "QUERY_ENGINES", - "OPEN_SOURCE" + "Query Engines", + "Open Source" ], "pypi_packages": [ "pyhive" @@ -4574,6 +7802,7 @@ "is_recommended": true } ], + "category": "Query Engines", "custom_errors": [ { "regex_name": "COLUMN_DOES_NOT_EXIST_REGEX", @@ -4661,241 +7890,16 @@ } ] }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": true, - "THIRTY_SECONDS": true, - "MINUTE": true, - "FIVE_MINUTES": true, - "TEN_MINUTES": true, - "FIFTEEN_MINUTES": true, - "THIRTY_MINUTES": false, - "HALF_HOUR": true, - "HOUR": true, - "SIX_HOURS": true, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": true, - "WEEK_STARTING_MONDAY": true, - "WEEK_ENDING_SATURDAY": true, - "WEEK_ENDING_SUNDAY": true, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 159, - "max_score": 201, - "joins": true, - "subqueries": true, + "engine": "presto", + "engine_name": "Presto", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, "supports_dynamic_schema": true, "supports_catalog": true, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": true, - "query_cost_estimation": true, - "sql_validation": true - }, - "Amazon Redshift": { - "engine": "amazon_redshift", - "engine_name": "Amazon Redshift", - "module": "redshift", - "documentation": { - "description": "Amazon Redshift is a fully managed data warehouse service.", - "logo": "redshift.png", - "homepage_url": "https://aws.amazon.com/redshift/", - "categories": [ - "CLOUD_AWS", - "ANALYTICAL_DATABASES", - "PROPRIETARY" - ], - "pypi_packages": [ - "sqlalchemy-redshift" - ], - "connection_string": "redshift+psycopg2://{username}:{password}@{host}:5439/{database}", - "default_port": 5439, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "AWS Endpoint", - "port": "Default 5439", - "database": "Database name" - }, - "drivers": [ - { - "name": "psycopg2", - "pypi_package": "psycopg2", - "connection_string": "redshift+psycopg2://{username}:{password}@{host}:5439/{database}", - "is_recommended": true - }, - { - "name": "redshift_connector", - "pypi_package": "redshift_connector", - "connection_string": "redshift+redshift_connector://{username}:{password}@{host}:5439/{database}", - "is_recommended": false, - "notes": "Supports IAM-based credentials for clusters and serverless." - } - ], - "authentication_methods": [ - { - "name": "IAM Credentials (Cluster)", - "description": "Use IAM-based temporary database credentials for Redshift clusters", - "requirements": "IAM role must have redshift:GetClusterCredentials permission", - "connection_string": "redshift+redshift_connector://", - "engine_parameters": { - "connect_args": { - "iam": true, - "database": "", - "cluster_identifier": "", - "db_user": "" - } - } - }, - { - "name": "IAM Credentials (Serverless)", - "description": "Use IAM-based credentials for Redshift Serverless", - "requirements": "IAM role must have redshift-serverless:GetCredentials and redshift-serverless:GetWorkgroup permissions", - "connection_string": "redshift+redshift_connector://", - "engine_parameters": { - "connect_args": { - "iam": true, - "is_serverless": true, - "serverless_acct_id": "", - "serverless_work_group": "", - "database": "", - "user": "IAMR:" - } - } - } - ], - "custom_errors": [ - { - "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", - "message_template": "Either the username \"%(username)s\" or the password is incorrect.", - "error_type": "CONNECTION_ACCESS_DENIED_ERROR", - "category": "Authentication", - "description": "Access denied", - "issue_codes": [ - 1014, - 1015 - ], - "invalid_fields": [ - "username", - "password" - ] - }, - { - "regex_name": "CONNECTION_INVALID_HOSTNAME_REGEX", - "message_template": "The hostname \"%(hostname)s\" cannot be resolved.", - "error_type": "CONNECTION_INVALID_HOSTNAME_ERROR", - "category": "Connection", - "description": "Invalid hostname", - "issue_codes": [ - 1007 - ], - "invalid_fields": [ - "host" - ] - }, - { - "regex_name": "CONNECTION_PORT_CLOSED_REGEX", - "message_template": "Port %(port)s on hostname \"%(hostname)s\" refused the connection.", - "error_type": "CONNECTION_PORT_CLOSED_ERROR", - "category": "Connection", - "description": "Port closed or refused", - "issue_codes": [ - 1008 - ], - "invalid_fields": [ - "host", - "port" - ] - }, - { - "regex_name": "CONNECTION_HOST_DOWN_REGEX", - "message_template": "The host \"%(hostname)s\" might be down, and can't be reached on port %(port)s.", - "error_type": "CONNECTION_HOST_DOWN_ERROR", - "category": "Connection", - "description": "Host unreachable", - "issue_codes": [ - 1009 - ], - "invalid_fields": [ - "host", - "port" - ] - }, - { - "regex_name": "CONNECTION_UNKNOWN_DATABASE_REGEX", - "message_template": "We were unable to connect to your database named \"%(database)s\". Please verify your database name and try again.", - "error_type": "CONNECTION_UNKNOWN_DATABASE_ERROR", - "category": "Connection", - "description": "Unknown database", - "issue_codes": [ - 1015 - ], - "invalid_fields": [ - "database" - ] - } - ] - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": true }, "RisingWave": { - "engine": "risingwave", - "engine_name": "RisingWave", - "module": "risingwave", - "documentation": { - "description": "RisingWave is a distributed streaming database.", - "logo": "risingwave.svg", - "homepage_url": "https://risingwave.com/", - "pypi_packages": [ - "psycopg2", - "sqlalchemy-risingwave" - ], - "connection_string": "risingwave://root@{hostname}:{port}/{database}?sslmode=disable", - "default_port": 4566, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "For localhost: localhost or 127.0.0.1. For AWS: endpoint URL", - "port": "Default 5432", - "database": "Database name" - }, - "notes": "The psycopg2 library comes bundled with Superset Docker images.", - "connection_examples": [ - { - "description": "Basic connection", - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}" - }, - { - "description": "With SSL required", - "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}?sslmode=require" - } - ], - "docs_url": "https://github.com/risingwavelabs/sqlalchemy-risingwave", - "sqlalchemy_docs_url": "https://docs.sqlalchemy.org/en/13/dialects/postgresql.html", - "categories": [ - "ANALYTICAL_DATABASES", - "OPEN_SOURCE" - ] - }, "time_grains": { "SECOND": true, "FIVE_SECONDS": true, @@ -4919,86 +7923,424 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 94, - "max_score": 201, + "module": "superset.db_engine_specs.risingwave", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": true, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 63, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, "ssh_tunneling": true, "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": true, - "sql_validation": false + "sql_validation": false, + "score": 94, + "max_score": 201, + "documentation": { + "description": "RisingWave is a distributed streaming database.", + "logo": "risingwave.svg", + "homepage_url": "https://risingwave.com/", + "categories": [ + "Analytical Databases", + "Open Source" + ], + "pypi_packages": [ + "sqlalchemy-risingwave" + ], + "connection_string": "risingwave://root@{hostname}:{port}/{database}?sslmode=disable", + "default_port": 4566, + "docs_url": "https://github.com/risingwavelabs/sqlalchemy-risingwave", + "category": "Other Databases" + }, + "engine": "risingwave", + "engine_name": "RisingWave", + "engine_aliases": [ + "postgres" + ], + "default_driver": "", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true + }, + "SAP HANA": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": false, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.hana", + "limit_method": 2, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 30, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 27, + "max_score": 201, + "documentation": { + "description": "SAP HANA is an in-memory relational database and application platform.", + "logo": "sap-hana.png", + "homepage_url": "https://www.sap.com/products/technology-platform/hana.html", + "categories": [ + "Traditional RDBMS", + "Proprietary" + ], + "pypi_packages": [ + "hdbcli", + "sqlalchemy-hana" + ], + "install_instructions": "pip install apache_superset[hana]", + "connection_string": "hana://{username}:{password}@{host}:{port}", + "default_port": 30015, + "docs_url": "https://github.com/SAP/sqlalchemy-hana", + "category": "Other Databases" + }, + "engine": "hana", + "engine_name": "SAP HANA", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "SAP Sybase": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.sybase", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": false, + "max_column_name": 128, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 44, + "max_score": 201, + "documentation": { + "description": "SAP ASE (formerly Sybase) is an enterprise relational database.", + "logo": "sybase.png", + "homepage_url": "https://www.sap.com/products/technology-platform/sybase-ase.html", + "categories": [ + "Traditional RDBMS", + "Proprietary" + ], + "pypi_packages": [ + "sqlalchemy-sybase", + "pyodbc" + ], + "connection_string": "sybase+pyodbc://{username}:{password}@{dsn}", + "parameters": { + "username": "Database username", + "password": "Database password", + "dsn": "ODBC Data Source Name configured for SAP ASE" + }, + "notes": "Requires SAP ASE ODBC driver installed and configured as a DSN.", + "docs_url": "https://help.sap.com/docs/SAP_ASE", + "category": "Other Databases" + }, + "engine": "sybase", + "engine_name": "SAP Sybase", + "engine_aliases": [ + "sybase_sqlany" + ], + "default_driver": "pyodbc", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "SQLite": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": true, + "HOUR": true, + "SIX_HOURS": true, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": true, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": true, + "YEAR": true + }, + "module": "superset.db_engine_specs.sqlite", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": true, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": false, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 41, + "max_score": 201, + "documentation": { + "description": "SQLite is a self-contained, serverless SQL database engine.", + "logo": "sqlite.png", + "homepage_url": "https://www.sqlite.org/", + "categories": [ + "Traditional RDBMS", + "Open Source" + ], + "pypi_packages": [], + "connection_string": "sqlite:///path/to/file.db?check_same_thread=false", + "notes": "No additional library needed. SQLite is bundled with Python.", + "category": "Traditional RDBMS", + "custom_errors": [ + { + "regex_name": "COLUMN_DOES_NOT_EXIST_REGEX", + "message_template": "We can't seem to resolve the column \"%(column_name)s\"", + "error_type": "COLUMN_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Column not found", + "issue_codes": [ + 1003, + 1004 + ] + } + ] + }, + "engine": "sqlite", + "engine_name": "SQLite", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false }, "Shillelagh": { - "engine": "shillelagh", - "engine_name": "Shillelagh", - "module": "shillelagh", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": true, + "HOUR": true, + "SIX_HOURS": true, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": true, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": true, + "YEAR": true + }, + "module": "superset.db_engine_specs.shillelagh", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": true, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": false, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 41, + "max_score": 201, "documentation": { "description": "Shillelagh is a Python library that allows querying many data sources using SQL, including Google Sheets, CSV files, and APIs.", "logo": "shillelagh.png", "homepage_url": "https://shillelagh.readthedocs.io/", + "categories": [ + "Other Databases", + "Open Source" + ], "pypi_packages": [ "shillelagh[gsheetsapi]" ], "connection_string": "shillelagh://", "notes": "Shillelagh uses virtual tables to query external data sources. Google Sheets requires OAuth credentials configured.", - "categories": [ - "OTHER", - "OPEN_SOURCE" - ] + "category": "Other Databases" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, + "engine": "shillelagh", + "engine_name": "Shillelagh", + "engine_aliases": [], + "default_driver": "apsw", + "supports_file_upload": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, "SingleStore": { - "engine": "singlestore", - "engine_name": "SingleStore", - "module": "singlestore", - "documentation": { - "description": "SingleStore is a distributed SQL database for real-time analytics and transactions.", - "logo": "singlestore.png", - "homepage_url": "https://www.singlestore.com/", - "categories": [ - "ANALYTICAL_DATABASES", - "PROPRIETARY" - ], - "pypi_packages": [ - "singlestoredb" - ], - "connection_string": "singlestoredb://{username}:{password}@{host}:{port}/{database}", - "default_port": 3306, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "SingleStore host", - "port": "SingleStore port (default 3306)", - "database": "Database name" - }, - "drivers": [ - { - "name": "singlestoredb", - "pypi_package": "singlestoredb", - "connection_string": "singlestoredb://{username}:{password}@{host}:{port}/{database}", - "is_recommended": true - } - ] - }, "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -5022,32 +8364,147 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 68, - "max_score": 201, + "module": "superset.db_engine_specs.singlestore", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 256, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false + "sql_validation": false, + "score": 68, + "max_score": 201, + "documentation": { + "description": "SingleStore is a distributed SQL database for real-time analytics and transactions.", + "logo": "singlestore.png", + "homepage_url": "https://www.singlestore.com/", + "categories": [ + "Analytical Databases", + "Proprietary" + ], + "pypi_packages": [ + "singlestoredb" + ], + "connection_string": "singlestoredb://{username}:{password}@{host}:{port}/{database}", + "default_port": 3306, + "parameters": { + "username": "Database username", + "password": "Database password", + "host": "SingleStore host", + "port": "SingleStore port (default 3306)", + "database": "Database name" + }, + "drivers": [ + { + "name": "singlestoredb", + "pypi_package": "singlestoredb", + "connection_string": "singlestoredb://{username}:{password}@{host}:{port}/{database}", + "is_recommended": true + } + ], + "category": "Other Databases" + }, + "engine": "singlestoredb", + "engine_name": "SingleStore", + "engine_aliases": [], + "default_driver": "singlestoredb", + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": false, + "supports_dynamic_catalog": false }, "Snowflake": { - "engine": "snowflake", - "engine_name": "Snowflake", - "module": "snowflake", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.snowflake", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 256, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 72, + "max_score": 201, "documentation": { "description": "Snowflake is a cloud-native data warehouse.", "logo": "snowflake.svg", "homepage_url": "https://www.snowflake.com/", "categories": [ - "CLOUD_DATA_WAREHOUSES", - "ANALYTICAL_DATABASES", - "PROPRIETARY" + "Cloud Data Warehouses", + "Analytical Databases", + "Proprietary" ], "pypi_packages": [ "snowflake-sqlalchemy" @@ -5074,6 +8531,7 @@ ], "notes": "Schema is not required in connection string. Ensure user has privileges for all databases/schemas/tables/views/warehouses.", "docs_url": "https://docs.snowflake.com/en/user-guide/key-pair-auth.html", + "category": "Cloud Data Warehouses", "custom_errors": [ { "regex_name": "OBJECT_DOES_NOT_EXIST_REGEX", @@ -5097,247 +8555,83 @@ } ] }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, - "MINUTE": true, - "FIVE_MINUTES": true, - "TEN_MINUTES": true, - "FIFTEEN_MINUTES": true, - "THIRTY_MINUTES": true, - "HALF_HOUR": false, - "HOUR": true, - "SIX_HOURS": false, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": false, - "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": false, - "WEEK_ENDING_SUNDAY": false, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 72, - "max_score": 201, - "joins": true, - "subqueries": true, + "engine": "snowflake", + "engine_name": "Snowflake", + "engine_aliases": [], + "default_driver": "snowflake", + "supports_file_upload": true, "supports_dynamic_schema": true, "supports_catalog": true, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Apache Solr": { - "engine": "apache_solr", - "engine_name": "Apache Solr", - "module": "solr", - "documentation": { - "description": "Apache Solr is an open-source enterprise search platform.", - "logo": "apache-solr.png", - "homepage_url": "https://solr.apache.org/", - "categories": [ - "APACHE_PROJECTS", - "SEARCH_NOSQL", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "sqlalchemy-solr" - ], - "connection_string": "solr://{username}:{password}@{host}:{port}/{server_path}/{collection}[/?use_ssl=true|false]", - "default_port": 8983 - }, - "time_grains": { - "SECOND": false, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, - "MINUTE": false, - "FIVE_MINUTES": false, - "TEN_MINUTES": false, - "FIFTEEN_MINUTES": false, - "THIRTY_MINUTES": false, - "HALF_HOUR": false, - "HOUR": false, - "SIX_HOURS": false, - "DAY": false, - "WEEK": false, - "WEEK_STARTING_SUNDAY": false, - "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": false, - "WEEK_ENDING_SUNDAY": false, - "MONTH": false, - "QUARTER": false, - "QUARTER_YEAR": false, - "YEAR": false - }, - "score": 20, - "max_score": 201, - "joins": false, - "subqueries": false, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "Apache Spark SQL": { - "engine": "apache_spark_sql", - "engine_name": "Apache Spark SQL", - "module": "spark", - "documentation": { - "description": "Apache Spark SQL is a module for structured data processing.", - "logo": "apache-spark.png", - "homepage_url": "https://spark.apache.org/sql/", - "pypi_packages": [ - "pyhive", - "pyhive", - "pyhive" - ], - "install_instructions": "pip install \"apache-superset[presto]\"", - "connection_string": "hive://hive@{hostname}:{port}/{database}", - "default_port": 10000, - "parameters": { - "hostname": "Presto coordinator hostname", - "port": "Presto coordinator port (default 8080)", - "database": "Catalog name" - }, - "drivers": [ - { - "name": "PyHive", - "pypi_package": "pyhive", - "connection_string": "presto://{hostname}:{port}/{database}", - "is_recommended": true - } - ], - "categories": [ - "APACHE_PROJECTS", - "QUERY_ENGINES", - "OPEN_SOURCE" - ] - }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, - "MINUTE": true, - "FIVE_MINUTES": false, - "TEN_MINUTES": false, - "FIFTEEN_MINUTES": false, - "THIRTY_MINUTES": false, - "HALF_HOUR": false, - "HOUR": true, - "SIX_HOURS": false, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": true, - "WEEK_STARTING_MONDAY": false, - "WEEK_ENDING_SATURDAY": true, - "WEEK_ENDING_SUNDAY": false, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 140, - "max_score": 201, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": true, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": true, - "query_cost_estimation": true, - "sql_validation": false - }, - "SQLite": { - "engine": "sqlite", - "engine_name": "SQLite", - "module": "sqlite", - "documentation": { - "description": "SQLite is a self-contained, serverless SQL database engine.", - "logo": "sqlite.png", - "homepage_url": "https://www.sqlite.org/", - "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" - ], - "pypi_packages": [], - "connection_string": "sqlite:///path/to/file.db?check_same_thread=false", - "notes": "No additional library needed. SQLite is bundled with Python.", - "custom_errors": [ - { - "regex_name": "COLUMN_DOES_NOT_EXIST_REGEX", - "message_template": "We can't seem to resolve the column \"%(column_name)s\"", - "error_type": "COLUMN_DOES_NOT_EXIST_ERROR", - "category": "Query", - "description": "Column not found", - "issue_codes": [ - 1003, - 1004 - ] - } - ] - }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": true, - "THIRTY_SECONDS": true, - "MINUTE": true, - "FIVE_MINUTES": true, - "TEN_MINUTES": true, - "FIFTEEN_MINUTES": true, - "THIRTY_MINUTES": true, - "HALF_HOUR": true, - "HOUR": true, - "SIX_HOURS": true, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": true, - "WEEK_STARTING_MONDAY": true, - "WEEK_ENDING_SATURDAY": true, - "WEEK_ENDING_SUNDAY": true, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": true, - "YEAR": true - }, - "score": 41, - "max_score": 201, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": true }, "StarRocks": { - "engine": "starrocks", - "engine_name": "StarRocks", - "module": "starrocks", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": false, + "MINUTE": true, + "FIVE_MINUTES": false, + "TEN_MINUTES": false, + "FIFTEEN_MINUTES": false, + "THIRTY_MINUTES": false, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.starrocks", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 64, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": false, + "user_impersonation": true, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 89, + "max_score": 201, "documentation": { "description": "StarRocks is a high-performance analytical database for real-time analytics.", "logo": "starrocks.png", "homepage_url": "https://www.starrocks.io/", + "categories": [ + "Analytical Databases", + "Open Source" + ], "pypi_packages": [ - "mysqlclient", "starrocks" ], "connection_string": "starrocks://{username}:{password}@{host}:{port}/{catalog}.{database}", @@ -5346,43 +8640,11 @@ "username": "Database username", "password": "Database password", "host": "StarRocks FE host", - "database": "Database name", "port": "Query port (default 9030)", - "catalog": "Catalog name" + "catalog": "Catalog name", + "database": "Database name" }, - "host_examples": [ - { - "platform": "Localhost", - "host": "localhost or 127.0.0.1" - }, - { - "platform": "Docker on Linux", - "host": "172.18.0.1" - }, - { - "platform": "Docker on macOS", - "host": "docker.for.mac.host.internal" - }, - { - "platform": "On-premise", - "host": "IP address or hostname" - } - ], "drivers": [ - { - "name": "mysqlclient", - "pypi_package": "mysqlclient", - "connection_string": "mysql://{username}:{password}@{host}/{database}", - "is_recommended": true, - "notes": "Recommended driver. May fail with caching_sha2_password auth." - }, - { - "name": "mysql-connector-python", - "pypi_package": "mysql-connector-python", - "connection_string": "mysql+mysqlconnector://{username}:{password}@{host}/{database}", - "is_recommended": false, - "notes": "Required for newer MySQL databases using caching_sha2_password authentication." - }, { "name": "starrocks", "pypi_package": "starrocks", @@ -5404,10 +8666,6 @@ "notes": "Pure Python MySQL driver, no compilation required." } ], - "categories": [ - "ANALYTICAL_DATABASES", - "OPEN_SOURCE" - ], "compatible_databases": [ { "name": "CelerData", @@ -5415,9 +8673,9 @@ "logo": "celerdata.png", "homepage_url": "https://celerdata.com/", "categories": [ - "ANALYTICAL_DATABASES", - "CLOUD_DATA_WAREHOUSES", - "HOSTED_OPEN_SOURCE" + "Analytical Databases", + "Cloud Data Warehouses", + "Hosted Open Source" ], "pypi_packages": [ "starrocks" @@ -5434,6 +8692,7 @@ "docs_url": "https://docs.celerdata.com/" } ], + "category": "Analytical Databases", "custom_errors": [ { "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", @@ -5465,158 +8724,96 @@ } ] }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": false, - "THIRTY_SECONDS": false, - "MINUTE": true, - "FIVE_MINUTES": false, - "TEN_MINUTES": false, - "FIFTEEN_MINUTES": false, - "THIRTY_MINUTES": false, - "HALF_HOUR": false, - "HOUR": true, - "SIX_HOURS": false, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": false, - "WEEK_STARTING_MONDAY": true, - "WEEK_ENDING_SATURDAY": false, - "WEEK_ENDING_SUNDAY": false, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 69, - "max_score": 201, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": true, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": true, + "engine": "starrocks", + "engine_name": "StarRocks", + "engine_aliases": [], + "default_driver": "starrocks", "supports_file_upload": true, - "user_impersonation": true, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true }, "Superset meta database": { - "engine": "superset_meta_database", - "engine_name": "Superset meta database", - "module": "superset", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": true, + "HOUR": true, + "SIX_HOURS": true, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": true, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": true, + "YEAR": true + }, + "module": "superset.db_engine_specs.superset", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": true, + "user_impersonation": false, + "file_upload": false, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": false, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 31, + "max_score": 201, "documentation": { "description": "Superset meta database is an experimental feature that enables querying across multiple configured databases using a single connection.", "logo": "superset.svg", "homepage_url": "https://superset.apache.org/", - "pypi_packages": [ - "shillelagh[gsheetsapi]" + "categories": [ + "Other Databases" ], + "pypi_packages": [], "connection_string": "superset://", "notes": "This is an internal Superset feature. Enable with ENABLE_SUPERSET_META_DB feature flag. Allows cross-database queries using virtual tables.", - "categories": [ - "OTHER" - ] + "category": "Other Databases" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, + "engine": "superset", + "engine_name": "Superset meta database", + "engine_aliases": [], + "default_driver": "", + "supports_file_upload": false, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false - }, - "SAP Sybase": { - "engine": "sap_sybase", - "engine_name": "SAP Sybase", - "module": "sybase", - "documentation": { - "description": "SAP ASE (formerly Sybase) is an enterprise relational database.", - "logo": "sybase.png", - "homepage_url": "https://www.sap.com/products/technology-platform/sybase-ase.html", - "pypi_packages": [ - "pymssql", - "sqlalchemy-sybase", - "pyodbc" - ], - "connection_string": "sybase+pyodbc://{username}:{password}@{dsn}", - "default_port": 1433, - "drivers": [ - { - "name": "pymssql", - "pypi_package": "pymssql", - "connection_string": "mssql+pymssql://{username}:{password}@{host}:{port}/{database}", - "is_recommended": true - }, - { - "name": "pyodbc", - "pypi_package": "pyodbc", - "connection_string": "mssql+pyodbc:///?odbc_connect=Driver%3D%7BODBC+Driver+17+for+SQL+Server%7D%3BServer%3Dtcp%3A%3C{host}%3E%2C1433%3BDatabase%3D{database}%3BUid%3D{username}%3BPwd%3D{password}%3BEncrypt%3Dyes%3BConnection+Timeout%3D30", - "is_recommended": false, - "notes": "Connection string must be URL-encoded. Special characters like @ need encoding." - } - ], - "docs_url": "https://help.sap.com/docs/SAP_ASE", - "categories": [ - "TRADITIONAL_RDBMS", - "PROPRIETARY" - ], - "parameters": { - "username": "Database username", - "password": "Database password", - "dsn": "ODBC Data Source Name configured for SAP ASE" - }, - "notes": "Requires SAP ASE ODBC driver installed and configured as a DSN." - }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, "TDengine": { - "engine": "tdengine", - "engine_name": "TDengine", - "module": "tdengine", - "documentation": { - "description": "TDengine is a high-performance time-series database for IoT.", - "logo": "tdengine.png", - "homepage_url": "https://tdengine.com/", - "categories": [ - "TIME_SERIES", - "OPEN_SOURCE" - ], - "pypi_packages": [ - "taospy", - "taos-ws-py" - ], - "connection_string": "taosws://{user}:{password}@{host}:{port}", - "default_port": 6041, - "connection_examples": [ - { - "description": "Local connection", - "connection_string": "taosws://root:taosdata@127.0.0.1:6041" - } - ], - "docs_url": "https://www.tdengine.com" - }, "time_grains": { "SECOND": true, "FIVE_SECONDS": false, @@ -5640,54 +8837,74 @@ "QUARTER_YEAR": false, "YEAR": false }, - "score": 25, - "max_score": 201, + "module": "superset.db_engine_specs.tdengine", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 64, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "Teradata": { - "engine": "teradata", - "engine_name": "Teradata", - "module": "teradata", + "sql_validation": false, + "score": 25, + "max_score": 201, "documentation": { - "description": "Teradata is an enterprise data warehouse platform.", - "logo": "teradata.png", - "homepage_url": "https://www.teradata.com/", + "description": "TDengine is a high-performance time-series database for IoT.", + "logo": "tdengine.png", + "homepage_url": "https://tdengine.com/", "categories": [ - "TRADITIONAL_RDBMS", - "PROPRIETARY" + "Time Series Databases", + "Open Source" ], "pypi_packages": [ - "teradatasqlalchemy" + "taospy", + "taos-ws-py" ], - "connection_string": "teradatasql://{user}:{password}@{host}", - "default_port": 1025, - "drivers": [ + "connection_string": "taosws://{user}:{password}@{host}:{port}", + "default_port": 6041, + "connection_examples": [ { - "name": "teradatasqlalchemy (Recommended)", - "pypi_package": "teradatasqlalchemy", - "connection_string": "teradatasql://{user}:{password}@{host}", - "is_recommended": true, - "notes": "No ODBC drivers required." - }, - { - "name": "sqlalchemy-teradata (ODBC)", - "pypi_package": "sqlalchemy-teradata", - "is_recommended": false, - "notes": "Requires ODBC driver installation.", - "docs_url": "https://downloads.teradata.com/download/connectivity/odbc-driver/linux" + "description": "Local connection", + "connection_string": "taosws://root:taosdata@127.0.0.1:6041" } - ] + ], + "docs_url": "https://www.tdengine.com", + "category": "Other Databases" }, + "engine": "taosws", + "engine_name": "TDengine", + "engine_aliases": [], + "default_driver": "taosws", + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "Teradata": { "time_grains": { "SECOND": false, "FIVE_SECONDS": false, @@ -5711,31 +8928,147 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 27, - "max_score": 201, + "module": "superset.db_engine_specs.teradata", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": 30, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false + "sql_validation": false, + "score": 27, + "max_score": 201, + "documentation": { + "description": "Teradata is an enterprise data warehouse platform.", + "logo": "teradata.png", + "homepage_url": "https://www.teradata.com/", + "categories": [ + "Traditional RDBMS", + "Proprietary" + ], + "pypi_packages": [ + "teradatasqlalchemy" + ], + "connection_string": "teradatasql://{user}:{password}@{host}", + "default_port": 1025, + "drivers": [ + { + "name": "teradatasqlalchemy (Recommended)", + "pypi_package": "teradatasqlalchemy", + "connection_string": "teradatasql://{user}:{password}@{host}", + "is_recommended": true, + "notes": "No ODBC drivers required." + }, + { + "name": "sqlalchemy-teradata (ODBC)", + "pypi_package": "sqlalchemy-teradata", + "is_recommended": false, + "notes": "Requires ODBC driver installation.", + "docs_url": "https://downloads.teradata.com/download/connectivity/odbc-driver/linux" + } + ], + "category": "Other Databases" + }, + "engine": "teradatasql", + "engine_name": "Teradata", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false }, "TimescaleDB": { - "engine": "timescaledb", - "engine_name": "TimescaleDB", - "module": "timescaledb", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.timescaledb", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 34, + "max_score": 201, "documentation": { "description": "TimescaleDB is an open-source relational database for time-series and analytics, built on PostgreSQL.", "logo": "timescale.png", "homepage_url": "https://www.timescale.com/", "categories": [ - "ANALYTICAL_DATABASES", - "OPEN_SOURCE" + "Analytical Databases", + "Open Source" ], "pypi_packages": [ "psycopg2" @@ -5749,34 +9082,84 @@ } ], "notes": "Uses the PostgreSQL driver. psycopg2 comes bundled with Superset.", - "docs_url": "https://docs.timescale.com/" + "docs_url": "https://docs.timescale.com/", + "category": "Other Databases" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, + "engine": "timescaledb", + "engine_name": "TimescaleDB", + "engine_aliases": [], + "default_driver": "psycopg2", + "supports_file_upload": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "supports_dynamic_catalog": false }, "Trino": { - "engine": "trino", - "engine_name": "Trino", - "module": "trino", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": false, + "HALF_HOUR": true, + "HOUR": true, + "SIX_HOURS": true, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": true, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.trino", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": true, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, + "user_impersonation": true, + "file_upload": true, + "get_extra_table_metadata": true, + "dbapi_exception_mapping": true, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": true, + "get_metrics": false, + "where_latest_partition": true, + "expand_data": false, + "query_cost_estimation": true, + "sql_validation": false, + "score": 149, + "max_score": 201, "documentation": { "description": "Trino is a distributed SQL query engine for big data analytics.", "logo": "trino.png", "homepage_url": "https://trino.io/", "categories": [ - "QUERY_ENGINES", - "OPEN_SOURCE" + "Query Engines", + "Open Source" ], "pypi_packages": [ "trino" @@ -5806,9 +9189,9 @@ "logo": "starburst.png", "homepage_url": "https://www.starburst.io/platform/starburst-galaxy/", "categories": [ - "QUERY_ENGINES", - "CLOUD_DATA_WAREHOUSES", - "HOSTED_OPEN_SOURCE" + "Query Engines", + "Cloud Data Warehouses", + "Hosted Open Source" ], "pypi_packages": [ "trino" @@ -5829,8 +9212,8 @@ "logo": "starburst.png", "homepage_url": "https://www.starburst.io/platform/starburst-enterprise/", "categories": [ - "QUERY_ENGINES", - "HOSTED_OPEN_SOURCE" + "Query Engines", + "Hosted Open Source" ], "pypi_packages": [ "trino" @@ -5838,72 +9221,19 @@ "connection_string": "trino://{username}:{password}@{hostname}:{port}/{catalog}", "docs_url": "https://docs.starburst.io/" } - ] + ], + "category": "Query Engines" }, - "time_grains": { - "SECOND": true, - "FIVE_SECONDS": true, - "THIRTY_SECONDS": true, - "MINUTE": true, - "FIVE_MINUTES": true, - "TEN_MINUTES": true, - "FIFTEEN_MINUTES": true, - "THIRTY_MINUTES": false, - "HALF_HOUR": true, - "HOUR": true, - "SIX_HOURS": true, - "DAY": true, - "WEEK": true, - "WEEK_STARTING_SUNDAY": true, - "WEEK_STARTING_MONDAY": true, - "WEEK_ENDING_SATURDAY": true, - "WEEK_ENDING_SUNDAY": true, - "MONTH": true, - "QUARTER": true, - "QUARTER_YEAR": false, - "YEAR": true - }, - "score": 149, - "max_score": 201, - "joins": true, - "subqueries": true, + "engine": "trino", + "engine_name": "Trino", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, "supports_dynamic_schema": true, "supports_catalog": true, - "supports_dynamic_catalog": false, - "ssh_tunneling": true, - "query_cancelation": true, - "supports_file_upload": true, - "user_impersonation": true, - "query_cost_estimation": true, - "sql_validation": false + "supports_dynamic_catalog": true }, "Vertica": { - "engine": "vertica", - "engine_name": "Vertica", - "module": "vertica", - "documentation": { - "description": "Vertica is a column-oriented analytics database.", - "logo": "vertica.png", - "homepage_url": "https://www.vertica.com/", - "categories": [ - "ANALYTICAL_DATABASES", - "PROPRIETARY" - ], - "pypi_packages": [ - "sqlalchemy-vertica-python" - ], - "connection_string": "vertica+vertica_python://{username}:{password}@{host}/{database}", - "default_port": 5433, - "parameters": { - "username": "Database username", - "password": "Database password", - "host": "localhost, IP address, or hostname (cloud or on-prem)", - "database": "Database name", - "port": "Default 5433" - }, - "notes": "Supports load balancer backup host configuration.", - "docs_url": "http://www.vertica.com/" - }, "time_grains": { "SECOND": true, "FIVE_SECONDS": true, @@ -5927,31 +9257,140 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 34, - "max_score": 201, + "module": "superset.db_engine_specs.vertica", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": true, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false + "sql_validation": false, + "score": 34, + "max_score": 201, + "documentation": { + "description": "Vertica is a column-oriented analytics database.", + "logo": "vertica.png", + "homepage_url": "https://www.vertica.com/", + "categories": [ + "Analytical Databases", + "Proprietary" + ], + "pypi_packages": [ + "sqlalchemy-vertica-python" + ], + "connection_string": "vertica+vertica_python://{username}:{password}@{host}/{database}", + "default_port": 5433, + "parameters": { + "username": "Database username", + "password": "Database password", + "host": "localhost, IP address, or hostname (cloud or on-prem)", + "database": "Database name", + "port": "Default 5433" + }, + "notes": "Supports load balancer backup host configuration.", + "docs_url": "http://www.vertica.com/", + "category": "Analytical Databases" + }, + "engine": "vertica", + "engine_name": "Vertica", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false }, "YDB": { - "engine": "ydb", - "engine_name": "YDB", - "module": "ydb", + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": false, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": true, + "HALF_HOUR": false, + "HOUR": true, + "SIX_HOURS": false, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": false, + "WEEK_STARTING_MONDAY": false, + "WEEK_ENDING_SATURDAY": false, + "WEEK_ENDING_SUNDAY": false, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.ydb", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": false, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, + "query_cost_estimation": false, + "sql_validation": false, + "score": 23, + "max_score": 201, "documentation": { "description": "YDB is a distributed SQL database by Yandex.", "logo": "ydb.svg", "homepage_url": "https://ydb.tech/", "categories": [ - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" + "Traditional RDBMS", + "Open Source" ], "pypi_packages": [ "ydb-sqlalchemy" @@ -6000,11 +9439,25 @@ } } } - ] + ], + "category": "Other Databases" }, + "engine": "yql", + "engine_name": "YDB", + "engine_aliases": [ + "yql+ydb", + "ydb" + ], + "default_driver": "ydb", + "supports_file_upload": false, + "supports_dynamic_schema": false, + "supports_catalog": false, + "supports_dynamic_catalog": false + }, + "YugabyteDB": { "time_grains": { "SECOND": true, - "FIVE_SECONDS": false, + "FIVE_SECONDS": true, "THIRTY_SECONDS": true, "MINUTE": true, "FIVE_MINUTES": true, @@ -6025,32 +9478,49 @@ "QUARTER_YEAR": false, "YEAR": true }, - "score": 23, - "max_score": 201, + "module": "superset.db_engine_specs.yugabytedb", + "limit_method": 1, + "limit_clause": true, "joins": true, "subqueries": true, - "supports_dynamic_schema": false, - "supports_catalog": false, - "supports_dynamic_catalog": false, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": false, + "function_names": false, + "user_impersonation": false, + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": false, + "catalog": false, + "dynamic_catalog": false, "ssh_tunneling": true, "query_cancelation": false, - "supports_file_upload": false, - "user_impersonation": false, + "get_metrics": false, + "where_latest_partition": false, + "expand_data": false, "query_cost_estimation": false, - "sql_validation": false - }, - "YugabyteDB": { - "engine": "yugabytedb", - "engine_name": "YugabyteDB", - "module": "yugabytedb", + "sql_validation": false, + "score": 34, + "max_score": 201, "documentation": { "description": "YugabyteDB is a distributed SQL database built on top of PostgreSQL.", "logo": "yugabyte.png", "homepage_url": "https://www.yugabyte.com/", "categories": [ - "CLOUD_DATA_WAREHOUSES", - "TRADITIONAL_RDBMS", - "OPEN_SOURCE" + "Cloud Data Warehouses", + "Traditional RDBMS", + "Open Source" ], "pypi_packages": [ "psycopg2" @@ -6058,22 +9528,176 @@ "connection_string": "postgresql://{username}:{password}@{host}:{port}/{database}", "default_port": 5433, "notes": "Uses the PostgreSQL driver. psycopg2 comes bundled with Superset.", - "docs_url": "https://docs.yugabyte.com/" + "docs_url": "https://docs.yugabyte.com/", + "category": "Other Databases" }, - "time_grains": {}, - "score": 0, - "max_score": 0, - "joins": true, - "subqueries": true, + "engine": "yugabytedb", + "engine_name": "YugabyteDB", + "engine_aliases": [], + "default_driver": "psycopg2", + "supports_file_upload": true, "supports_dynamic_schema": false, "supports_catalog": false, - "supports_dynamic_catalog": false, - "ssh_tunneling": false, - "query_cancelation": false, - "supports_file_upload": false, + "supports_dynamic_catalog": false + }, + "base": { + "time_grains": { + "SECOND": true, + "FIVE_SECONDS": true, + "THIRTY_SECONDS": true, + "MINUTE": true, + "FIVE_MINUTES": true, + "TEN_MINUTES": true, + "FIFTEEN_MINUTES": true, + "THIRTY_MINUTES": false, + "HALF_HOUR": true, + "HOUR": true, + "SIX_HOURS": true, + "DAY": true, + "WEEK": true, + "WEEK_STARTING_SUNDAY": true, + "WEEK_STARTING_MONDAY": true, + "WEEK_ENDING_SATURDAY": true, + "WEEK_ENDING_SUNDAY": true, + "MONTH": true, + "QUARTER": true, + "QUARTER_YEAR": false, + "YEAR": true + }, + "module": "superset.db_engine_specs.presto", + "limit_method": 1, + "limit_clause": true, + "joins": true, + "subqueries": true, + "alias_in_select": true, + "alias_in_orderby": true, + "time_groupby_inline": false, + "alias_to_source_column": false, + "order_by_not_in_select": true, + "expressions_in_orderby": false, + "cte_in_subquery": true, + "max_column_name": null, + "sql_comments": true, + "escaped_colons": true, + "masked_encrypted_extra": false, + "column_type_mapping": true, + "function_names": true, "user_impersonation": false, - "query_cost_estimation": false, - "sql_validation": false + "file_upload": true, + "get_extra_table_metadata": false, + "dbapi_exception_mapping": false, + "custom_errors": false, + "dynamic_schema": true, + "catalog": true, + "dynamic_catalog": true, + "ssh_tunneling": true, + "query_cancelation": false, + "get_metrics": false, + "where_latest_partition": true, + "expand_data": false, + "query_cost_estimation": true, + "sql_validation": false, + "score": 109, + "max_score": 201, + "documentation": { + "pypi_packages": [], + "connection_string": "engine+driver://user:password@host:port/dbname[?key=value&key=value...]", + "category": "Other Databases", + "custom_errors": [ + { + "regex_name": "COLUMN_DOES_NOT_EXIST_REGEX", + "message_template": "We can't seem to resolve the column \"%(column_name)s\" at line %(location)s.", + "error_type": "COLUMN_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Column not found", + "issue_codes": [ + 1003, + 1004 + ] + }, + { + "regex_name": "TABLE_DOES_NOT_EXIST_REGEX", + "message_template": "The table \"%(table_name)s\" does not exist. A valid table must be used to run this query.", + "error_type": "TABLE_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Table not found", + "issue_codes": [ + 1003, + 1005 + ] + }, + { + "regex_name": "SCHEMA_DOES_NOT_EXIST_REGEX", + "message_template": "The schema \"%(schema_name)s\" does not exist. A valid schema must be used to run this query.", + "error_type": "SCHEMA_DOES_NOT_EXIST_ERROR", + "category": "Query", + "description": "Schema not found", + "issue_codes": [ + 1003, + 1016 + ] + }, + { + "regex_name": "CONNECTION_ACCESS_DENIED_REGEX", + "message_template": "Either the username \"%(username)s\" or the password is incorrect.", + "error_type": "CONNECTION_ACCESS_DENIED_ERROR", + "category": "Authentication", + "description": "Access denied", + "issue_codes": [ + 1014, + 1015 + ] + }, + { + "regex_name": "CONNECTION_INVALID_HOSTNAME_REGEX", + "message_template": "The hostname \"%(hostname)s\" cannot be resolved.", + "error_type": "CONNECTION_INVALID_HOSTNAME_ERROR", + "category": "Connection", + "description": "Invalid hostname", + "issue_codes": [ + 1007 + ] + }, + { + "regex_name": "CONNECTION_HOST_DOWN_REGEX", + "message_template": "The host \"%(hostname)s\" might be down, and can't be reached on port %(port)s.", + "error_type": "CONNECTION_HOST_DOWN_ERROR", + "category": "Connection", + "description": "Host unreachable", + "issue_codes": [ + 1009 + ] + }, + { + "regex_name": "CONNECTION_PORT_CLOSED_REGEX", + "message_template": "Port %(port)s on hostname \"%(hostname)s\" refused the connection.", + "error_type": "CONNECTION_PORT_CLOSED_ERROR", + "category": "Connection", + "description": "Port closed or refused", + "issue_codes": [ + 1008 + ] + }, + { + "regex_name": "CONNECTION_UNKNOWN_DATABASE_ERROR", + "message_template": "Unable to connect to catalog named \"%(catalog_name)s\".", + "error_type": "CONNECTION_UNKNOWN_DATABASE_ERROR", + "category": "Connection", + "description": "Unknown database", + "issue_codes": [ + 1015 + ] + } + ] + }, + "engine": "base", + "engine_name": "base", + "engine_aliases": [], + "default_driver": null, + "supports_file_upload": true, + "supports_dynamic_schema": true, + "supports_catalog": true, + "supports_dynamic_catalog": true } } } diff --git a/docs/src/pages/index.tsx b/docs/src/pages/index.tsx index dba54bc6065..04f8c89789b 100644 --- a/docs/src/pages/index.tsx +++ b/docs/src/pages/index.tsx @@ -28,6 +28,7 @@ import databaseData from '../data/databases.json'; import BlurredSection from '../components/BlurredSection'; import DataSet from '../../../RESOURCES/INTHEWILD.yaml'; import type { DatabaseData } from '../components/databases/types'; +import GetStartedSplitButton from '../components/GetStartedSplitButton'; import '../styles/main.css'; // Build database list from databases.json (databases with logos) @@ -191,20 +192,6 @@ const StyledTitleContainer = styled('div')` } `; -const StyledButton = styled(Link)` - border-radius: 10px; - font-size: 20px; - font-weight: bold; - width: 170px; - padding: 10px 0; - margin: 15px auto 0; - ${mq[1]} { - font-size: 19px; - width: 175px; - padding: 10px 0; - } -`; - const StyledScreenshotContainer = styled('div')` position: relative; display: inline-block; @@ -717,9 +704,10 @@ export default function Home(): JSX.Element { line - - Get Started - + span > svg { opacity: 1; } +/* Homepage split "Get started": gradient button + chevron column */ +.default-button-theme.get-started-split { + display: flex; + padding: 0; +} + +.get-started-split-dropdown-menu.ant-dropdown-menu { + background: linear-gradient(180deg, #20a7c9 0%, #0c8fae 100%) !important; + border: 1px solid rgba(255, 255, 255, 0.22); + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2) !important; +} + +.get-started-split-dropdown-menu--hero.ant-dropdown-menu { + min-width: 208px; +} + +@media (max-width: 768px) { + .get-started-split-dropdown-menu--hero.ant-dropdown-menu { + min-width: 214px; + } +} + +.get-started-split-dropdown-menu--navbar.ant-dropdown-menu { + min-width: 176px; +} + +.get-started-split-dropdown-menu .ant-dropdown-menu-item { + color: #ffffff !important; +} + +.get-started-split-dropdown-menu .ant-dropdown-menu-item:hover, +.get-started-split-dropdown-menu .ant-dropdown-menu-item-active { + background: rgba(255, 255, 255, 0.15) !important; +} + +.get-started-split-dropdown-menu .ant-dropdown-menu-item a { + color: inherit !important; +} + /* Navbar */ .navbar { @@ -117,11 +156,14 @@ a > span > svg { border-radius: 10px; font-size: 18px; font-weight: bold; - width: 142px; - padding: 7px 0; margin-right: 20px; } +.navbar .get-started-button.get-started-split { + width: 176px; + padding: 0; +} + .navbar .github-button { background-image: url('/img/github.png'); background-size: contain; diff --git a/docs/src/theme/NavbarItem/ComponentTypes.tsx b/docs/src/theme/NavbarItem/ComponentTypes.tsx new file mode 100644 index 00000000000..4b7ebe63a13 --- /dev/null +++ b/docs/src/theme/NavbarItem/ComponentTypes.tsx @@ -0,0 +1,41 @@ +/** + * 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 DocNavbarItem from '@theme-original/NavbarItem/DocNavbarItem'; +import DocSidebarNavbarItem from '@theme-original/NavbarItem/DocSidebarNavbarItem'; +import DocsVersionDropdownNavbarItem from '@theme-original/NavbarItem/DocsVersionDropdownNavbarItem'; +import DocsVersionNavbarItem from '@theme-original/NavbarItem/DocsVersionNavbarItem'; +import DropdownNavbarItem from '@theme-original/NavbarItem/DropdownNavbarItem'; +import DefaultNavbarItem from '@theme-original/NavbarItem/DefaultNavbarItem'; +import HtmlNavbarItem from '@theme-original/NavbarItem/HtmlNavbarItem'; +import LocaleDropdownNavbarItem from '@theme-original/NavbarItem/LocaleDropdownNavbarItem'; +import SearchNavbarItem from '@theme-original/NavbarItem/SearchNavbarItem'; +import GetStartedSplitNavbarItem from './GetStartedSplitNavbarItem'; + +export default { + default: DefaultNavbarItem, + localeDropdown: LocaleDropdownNavbarItem, + search: SearchNavbarItem, + dropdown: DropdownNavbarItem, + html: HtmlNavbarItem, + doc: DocNavbarItem, + docSidebar: DocSidebarNavbarItem, + docsVersion: DocsVersionNavbarItem, + docsVersionDropdown: DocsVersionDropdownNavbarItem, + 'custom-getStartedSplit': GetStartedSplitNavbarItem, +}; diff --git a/docs/src/theme/NavbarItem/GetStartedSplitNavbarItem.tsx b/docs/src/theme/NavbarItem/GetStartedSplitNavbarItem.tsx new file mode 100644 index 00000000000..7c7b202b7e6 --- /dev/null +++ b/docs/src/theme/NavbarItem/GetStartedSplitNavbarItem.tsx @@ -0,0 +1,29 @@ +/** + * 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 GetStartedSplitButton from '../../components/GetStartedSplitButton'; +import '../../styles/main.css'; + +export default function GetStartedSplitNavbarItem() { + return ( + + ); +} diff --git a/docs/src/theme/Root.js b/docs/src/theme/Root.js index 10538df6970..677531ff905 100644 --- a/docs/src/theme/Root.js +++ b/docs/src/theme/Root.js @@ -147,7 +147,9 @@ export default function Root({ children }) { const button = event.target.closest('.get-started-button, .default-button-theme'); if (button) { const buttonText = button.textContent?.trim() || 'Unknown'; - const href = button.getAttribute('href') || ''; + const clickedLink = event.target.closest?.('a'); + const href = + clickedLink?.getAttribute('href') || button.getAttribute('href') || ''; trackEvent('CTA', 'Click', `${buttonText} - ${href}`); } }; diff --git a/docs/static/feature-flags.json b/docs/static/feature-flags.json index 516115ac0ae..0da6171b46f 100644 --- a/docs/static/feature-flags.json +++ b/docs/static/feature-flags.json @@ -81,6 +81,12 @@ "lifecycle": "development", "description": "Expand nested types in Presto into extra columns/arrays. Experimental, doesn't work with all nested types." }, + { + "name": "SEMANTIC_LAYERS", + "default": false, + "lifecycle": "development", + "description": "Enable semantic layers and show semantic views alongside datasets" + }, { "name": "TABLE_V2_TIME_COMPARISON_ENABLED", "default": false, diff --git a/docs/static/img/screenshots/dashboard.jpg b/docs/static/img/screenshots/dashboard.jpg index 9062d7a479d..2bea533aa7a 100644 Binary files a/docs/static/img/screenshots/dashboard.jpg and b/docs/static/img/screenshots/dashboard.jpg differ diff --git a/docs/static/img/screenshots/explore.jpg b/docs/static/img/screenshots/explore.jpg index 8ac41b65796..916f119bcd4 100644 Binary files a/docs/static/img/screenshots/explore.jpg and b/docs/static/img/screenshots/explore.jpg differ diff --git a/docs/static/img/screenshots/gallery.jpg b/docs/static/img/screenshots/gallery.jpg index 2312bd37982..e20749639dd 100644 Binary files a/docs/static/img/screenshots/gallery.jpg and b/docs/static/img/screenshots/gallery.jpg differ diff --git a/docs/static/img/screenshots/sql_lab.jpg b/docs/static/img/screenshots/sql_lab.jpg index d8f5a964adb..a3134bd8c98 100644 Binary files a/docs/static/img/screenshots/sql_lab.jpg and b/docs/static/img/screenshots/sql_lab.jpg differ diff --git a/docs/static/img/tutorial/create_pivot.png b/docs/static/img/tutorial/create_pivot.png index 2a24ee25153..52abb7fc048 100644 Binary files a/docs/static/img/tutorial/create_pivot.png and b/docs/static/img/tutorial/create_pivot.png differ diff --git a/docs/static/img/tutorial/publish_button_dashboard.png b/docs/static/img/tutorial/publish_button_dashboard.png index c20a097dfdc..9c4f29e4055 100644 Binary files a/docs/static/img/tutorial/publish_button_dashboard.png and b/docs/static/img/tutorial/publish_button_dashboard.png differ diff --git a/docs/static/img/tutorial/tutorial_08_sources_tables.png b/docs/static/img/tutorial/tutorial_08_sources_tables.png index 67252a706e9..dee2e47caa1 100644 Binary files a/docs/static/img/tutorial/tutorial_08_sources_tables.png and b/docs/static/img/tutorial/tutorial_08_sources_tables.png differ diff --git a/docs/static/img/tutorial/tutorial_chart_resize.png b/docs/static/img/tutorial/tutorial_chart_resize.png index 50983127aec..c40b90da3c2 100644 Binary files a/docs/static/img/tutorial/tutorial_chart_resize.png and b/docs/static/img/tutorial/tutorial_chart_resize.png differ diff --git a/docs/static/img/tutorial/tutorial_edit_button.png b/docs/static/img/tutorial/tutorial_edit_button.png index 9028fa5743f..6ae85634f8f 100644 Binary files a/docs/static/img/tutorial/tutorial_edit_button.png and b/docs/static/img/tutorial/tutorial_edit_button.png differ diff --git a/docs/static/img/tutorial/tutorial_first_dashboard.png b/docs/static/img/tutorial/tutorial_first_dashboard.png index f0382290766..ce925328f24 100644 Binary files a/docs/static/img/tutorial/tutorial_first_dashboard.png and b/docs/static/img/tutorial/tutorial_first_dashboard.png differ diff --git a/docs/static/img/tutorial/tutorial_save_slice.png b/docs/static/img/tutorial/tutorial_save_slice.png index 89e26773838..91ba6f9685d 100644 Binary files a/docs/static/img/tutorial/tutorial_save_slice.png and b/docs/static/img/tutorial/tutorial_save_slice.png differ diff --git a/docs/tsconfig.json b/docs/tsconfig.json index ff0f5ac238c..e505bfd86ae 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -3,6 +3,7 @@ "extends": "@docusaurus/tsconfig", "compilerOptions": { "baseUrl": ".", + "ignoreDeprecations": "6.0", "skipLibCheck": true, "noImplicitAny": false, "strict": false, diff --git a/docs/versioned_docs/version-6.0.0/configuration/configuring-superset.mdx b/docs/versioned_docs/version-6.0.0/configuration/configuring-superset.mdx index d9fb2ca41a0..a61d05ecfe4 100644 --- a/docs/versioned_docs/version-6.0.0/configuration/configuring-superset.mdx +++ b/docs/versioned_docs/version-6.0.0/configuration/configuring-superset.mdx @@ -109,6 +109,14 @@ SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY' You can generate a strong secure key with `openssl rand -base64 42`. +Alternatively, you can set the secret key using `SUPERSET_SECRET_KEY` environment variable: + +On a Unix-based system, such as Linux or macOS, you can do so by running the following command in your terminal: + +```bash +export SUPERSET_SECRET_KEY=$(openssl rand -base64 42) +``` + :::caution Use a strong secret key This key will be used for securely signing session cookies and encrypting sensitive information stored in Superset's application metadata database. Your deployment must use a complex, unique key. diff --git a/docs/yarn.lock b/docs/yarn.lock index 20d4beb91b9..cda4ffe89a4 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -173,7 +173,7 @@ dependencies: "@algolia/client-common" "5.40.0" -"@ant-design/colors@^8.0.0", "@ant-design/colors@^8.0.1": +"@ant-design/colors@^8.0.1": version "8.0.1" resolved "https://registry.npmjs.org/@ant-design/colors/-/colors-8.0.1.tgz" integrity sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ== @@ -207,19 +207,19 @@ resolved "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-3.0.1.tgz" integrity sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw== -"@ant-design/icons-svg@^4.4.0": +"@ant-design/icons-svg@^4.4.2": version "4.4.2" resolved "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz" integrity sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA== -"@ant-design/icons@^6.1.1": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-6.1.1.tgz#068963d3de44ff7034dce32c9cec3ff7d343fe6b" - integrity sha512-AMT4N2y++TZETNHiM77fs4a0uPVCJGuL5MTonk13Pvv7UN7sID1cNEZOc1qNqx6zLKAOilTEFAdAoAFKa0U//Q== +"@ant-design/icons@^6.1.1", "@ant-design/icons@^6.2.2": + version "6.2.2" + resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-6.2.2.tgz#ed33a140ff35d7bcb6e48f01a6970ea6939cef99" + integrity sha512-zlJtE7AMbG12TeYVPhtBXwNpFInNy8mjLzcIm+0BPw16/b8ODG87YJ1G37VIF5VFscdgfsf6EweAFPTobu/3iQ== dependencies: - "@ant-design/colors" "^8.0.0" - "@ant-design/icons-svg" "^4.4.0" - "@rc-component/util" "^1.3.0" + "@ant-design/colors" "^8.0.1" + "@ant-design/icons-svg" "^4.4.2" + "@rc-component/util" "^1.10.1" clsx "^2.1.1" "@ant-design/react-slick@~2.0.0": @@ -261,6 +261,15 @@ js-tokens "^4.0.0" picocolors "^1.1.1" +"@babel/code-frame@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c" + integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== + dependencies: + "@babel/helper-validator-identifier" "^7.28.5" + js-tokens "^4.0.0" + picocolors "^1.1.1" + "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.0": version "7.28.0" resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz" @@ -303,6 +312,17 @@ "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" +"@babel/generator@^7.29.0": + version "7.29.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50" + integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== + dependencies: + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + "@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3": version "7.27.3" resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz" @@ -404,6 +424,11 @@ resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz" integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== +"@babel/helper-plugin-utils@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8" + integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug== + "@babel/helper-remap-async-to-generator@^7.27.1": version "7.27.1" resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz" @@ -435,11 +460,6 @@ resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz" integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== -"@babel/helper-validator-identifier@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz" - integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== - "@babel/helper-validator-identifier@^7.28.5": version "7.28.5" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz" @@ -474,6 +494,13 @@ dependencies: "@babel/types" "^7.28.6" +"@babel/parser@^7.29.0": + version "7.29.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.3.tgz#116f70a77958307fceac27747573032f8a62f88e" + integrity sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA== + dependencies: + "@babel/types" "^7.29.0" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1": version "7.27.1" resolved "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz" @@ -758,14 +785,14 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-modules-systemjs@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz" - integrity sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA== + version "7.29.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz#f621105da99919c15cf4bde6fcc7346ef95e7b20" + integrity sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w== dependencies: - "@babel/helper-module-transforms" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.27.1" + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.29.0" "@babel/plugin-transform-modules-umd@^7.27.1": version "7.27.1" @@ -1163,6 +1190,19 @@ "@babel/types" "^7.28.6" debug "^4.3.1" +"@babel/traverse@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a" + integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/types" "^7.29.0" + debug "^4.3.1" + "@babel/types@^7.21.3", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.6", "@babel/types@^7.4.4": version "7.28.6" resolved "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz" @@ -1171,6 +1211,14 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.28.5" +"@babel/types@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" + integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@braintree/sanitize-url@^7.0.4": version "7.1.1" resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz" @@ -1570,10 +1618,10 @@ "@docsearch/core" "4.6.2" "@docsearch/css" "4.6.2" -"@docusaurus/babel@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/babel/-/babel-3.10.0.tgz#819819f107233dfcf50b59cd51158f23fb04878a" - integrity sha512-mqCJhCZNZUDg0zgDEaPTM4DnRsisa24HdqTy/qn/MQlbwhTb4WVaZg6ZyX6yIVKqTz8fS1hBMgM+98z+BeJJDg== +"@docusaurus/babel@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/babel/-/babel-3.10.1.tgz#2f714f682117658ba43d308e9b35b6a73a105227" + integrity sha512-DZzFO1K3v/GoEt1fx1DiYHF4en+PuhtQf1AkQJa5zu3CoeKSpr5cpQRUlz3jr0m44wyzmSXu9bVpfir+N4+8bg== dependencies: "@babel/core" "^7.25.9" "@babel/generator" "^7.25.9" @@ -1584,23 +1632,23 @@ "@babel/preset-typescript" "^7.25.9" "@babel/runtime" "^7.25.9" "@babel/traverse" "^7.25.9" - "@docusaurus/logger" "3.10.0" - "@docusaurus/utils" "3.10.0" + "@docusaurus/logger" "3.10.1" + "@docusaurus/utils" "3.10.1" babel-plugin-dynamic-import-node "^2.3.3" fs-extra "^11.1.1" tslib "^2.6.0" -"@docusaurus/bundler@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/bundler/-/bundler-3.10.0.tgz#878c4c46bfa3434671ea37a43da184238a6aae26" - integrity sha512-iONUGZGgp+lAkw/cJZH6irONcF4p8+278IsdRlq8lYhxGjkoNUs0w7F4gVXBYSNChq5KG5/JleTSsdJySShxow== +"@docusaurus/bundler@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/bundler/-/bundler-3.10.1.tgz#82fa5079f3787a67502e25f82d37d05ec5de0cc3" + integrity sha512-HIqQPvbqnnQRe4NsBd1774KRarjXqS6wHsWELtyuSs1gCfvixJO2jUGH/OEBtr1Gvzpw+ze5CjGMvSJ8UE1KUw== dependencies: "@babel/core" "^7.25.9" - "@docusaurus/babel" "3.10.0" - "@docusaurus/cssnano-preset" "3.10.0" - "@docusaurus/logger" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils" "3.10.0" + "@docusaurus/babel" "3.10.1" + "@docusaurus/cssnano-preset" "3.10.1" + "@docusaurus/logger" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils" "3.10.1" babel-loader "^9.2.1" clean-css "^5.3.3" copy-webpack-plugin "^11.0.0" @@ -1618,20 +1666,20 @@ tslib "^2.6.0" url-loader "^4.1.1" webpack "^5.95.0" - webpackbar "^6.0.1" + webpackbar "^7.0.0" -"@docusaurus/core@3.10.0", "@docusaurus/core@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-3.10.0.tgz#642e71a0209d62c3f5ef275ed9d74a881f40df39" - integrity sha512-mgLdQsO8xppnQZc3LPi+Mf+PkPeyxJeIx11AXAq/14fsaMefInQiMEZUUmrc7J+956G/f7MwE7tn8KZgi3iRcA== +"@docusaurus/core@3.10.1", "@docusaurus/core@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-3.10.1.tgz#3f8bdb97451b4df14f2a3b39ab0186366fbf8fbe" + integrity sha512-3pf2fXXw0eVk8WnC3T4LIigRDupcpvngpKo9Vy7mYyBhuddc0klDUuZAIfzMoK6z05pdlk6EFC/vBSX43+1O5w== dependencies: - "@docusaurus/babel" "3.10.0" - "@docusaurus/bundler" "3.10.0" - "@docusaurus/logger" "3.10.0" - "@docusaurus/mdx-loader" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-common" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/babel" "3.10.1" + "@docusaurus/bundler" "3.10.1" + "@docusaurus/logger" "3.10.1" + "@docusaurus/mdx-loader" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-common" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" boxen "^6.2.1" chalk "^4.1.2" chokidar "^3.5.3" @@ -1668,22 +1716,22 @@ webpack-dev-server "^5.2.2" webpack-merge "^6.0.1" -"@docusaurus/cssnano-preset@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.10.0.tgz#be1b435c33df09d743473d3fadda67b4568dfae3" - integrity sha512-qzSshTO1DB3TYW+dPUal5KHM7XPc5YQfzF3Kdb2NDACJUyGbNcFtw3tGkCJlYwhNCRKbZcmwraKUS1i5dcHdGg== +"@docusaurus/cssnano-preset@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.10.1.tgz#4b6bafeca8bb9423364d2fd6683c28e2f85a4665" + integrity sha512-eNfHGcTKCSq6xmcavAkX3RRclHaE2xRCMParlDXLdXVP01/a2e/jKXMj/0ULnLFQSNwwuI62L0Ge8J+nZsR7UQ== dependencies: cssnano-preset-advanced "^6.1.2" postcss "^8.5.4" postcss-sort-media-queries "^5.2.0" tslib "^2.6.0" -"@docusaurus/faster@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/faster/-/faster-3.10.0.tgz#0758a93196f685537aa7700bde62faf926e6c817" - integrity sha512-GNPtVH14ISjHfSwnHu3KiFGf86ICmJSQDeSv/QaanpBgiZGOtgZaslnC5q8WiguxM1EVkwcGxPuD8BXF4eggKw== +"@docusaurus/faster@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/faster/-/faster-3.10.1.tgz#a63d89ae980c98e1eeab3ff15ee083f7c20ed353" + integrity sha512-XTZhE5C1gZ/DaYYMlSk02dwP5vhpQON5QHVz1s3892mSESAywgWanURpXEDAvt4GvGuq7s+XP8rTWHZvfaJmdQ== dependencies: - "@docusaurus/types" "3.10.0" + "@docusaurus/types" "3.10.1" "@rspack/core" "^1.7.10" "@swc/core" "^1.7.39" "@swc/html" "^1.13.5" @@ -1694,22 +1742,22 @@ tslib "^2.6.0" webpack "^5.95.0" -"@docusaurus/logger@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.10.0.tgz#2bacbd004dd78e3da926dbe8f6fa9a930856575d" - integrity sha512-9jrZzFuBH1LDRlZ7cznAhCLmAZ3HSDqgwdrSSZdGHq9SPUOQgXXu8mnxe2ZRB9NS1PCpMTIOVUqDtZPIhMafZg== +"@docusaurus/logger@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.10.1.tgz#34c964e32e18f120e30f80171a38cfefe72cfb4b" + integrity sha512-oPjNFnfJsRCkePVjkGrxWGq4MvJKRQT0r9jOP0eRBTZ7Wr9FAbzdP/Gjs0I2Ss6YRkPoEgygKG112OkE6skvJw== dependencies: chalk "^4.1.2" tslib "^2.6.0" -"@docusaurus/mdx-loader@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.10.0.tgz#1d4b050d751389ecf38dee48bcb61e53df8ffb82" - integrity sha512-mQQV97080AH4PYNs087l202NMDqRopZA4mg5W76ZZyTFrmWhJ3mHg+8A+drJVENxw5/Q+wHMHLgsx+9z1nEs0A== +"@docusaurus/mdx-loader@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.10.1.tgz#050ae9bc614158a4ec07a628aa75fa9ae90d7e82" + integrity sha512-GRmeb/wQ+iXRrFwcHBfgQhrJxGElgCsoTWZYDhccjsZVne1p8MK/EpQVIloXttz76TCe78kKD5AEG9n1xc1oxQ== dependencies: - "@docusaurus/logger" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/logger" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" "@mdx-js/mdx" "^3.0.0" "@slorber/remark-comment" "^1.0.0" escape-html "^1.0.3" @@ -1732,12 +1780,12 @@ vfile "^6.0.1" webpack "^5.88.1" -"@docusaurus/module-type-aliases@3.10.0", "@docusaurus/module-type-aliases@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.10.0.tgz#749928f104d563f11f046bf0c9ab6489a470c7c8" - integrity sha512-/1O0Zg8w3DFrYX/I6Fbss7OJrtZw1QoyjDhegiFNHVi9A9Y0gQ3jUAytVxF6ywpAWpLyLxch8nN8H/V3XfzdJQ== +"@docusaurus/module-type-aliases@3.10.1", "@docusaurus/module-type-aliases@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.10.1.tgz#22d39177c296786eb6e0d940699cd590cc93ca77" + integrity sha512-YoOZKUdGlp8xSYhuAkGdSo5Ydkbq4V4eK3sD8v0a2hloxCWdQbNBhkc+Ko9QyjpESc0BYcIGM5iHVAy5hdFV6w== dependencies: - "@docusaurus/types" "3.10.0" + "@docusaurus/types" "3.10.1" "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" @@ -1745,34 +1793,34 @@ react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" react-loadable "npm:@docusaurus/react-loadable@6.0.0" -"@docusaurus/plugin-client-redirects@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.10.0.tgz#4dd4619817fd69462d1e6d986580343aeb911111" - integrity sha512-P+VLoLoZTc74so8+IbsaPZ33/mkf2BWL1CYXQpPRkl0v1QVCN2CgfsZY/8QtbYjQnx2upXUnv45abDhNcSggNw== +"@docusaurus/plugin-client-redirects@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.10.1.tgz#e22ed20e5837b7c3a28258e3d1816c4239c82b36" + integrity sha512-LHgd+YDvkhfOHMAE6XtUng3DQNzVM765RqVRrMJgHtzAvfopQhY6ieprqjxDVBdv21cLma6I0jHr+YCZH8fL9A== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/logger" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-common" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/logger" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-common" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" eta "^2.2.0" fs-extra "^11.1.1" lodash "^4.17.21" tslib "^2.6.0" -"@docusaurus/plugin-content-blog@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.10.0.tgz#10095291b637440847854ecb2c8afcd8746debd7" - integrity sha512-RuTz68DhB7CL96QO5UsFbciD7GPYq6QV+YMfF9V0+N4ZgLhJIBgpVAr8GobrKF6NRe5cyWWETU5z5T834piG9g== +"@docusaurus/plugin-content-blog@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.10.1.tgz#0bd8de700ccbd8e95d920df2613304ef59abe72b" + integrity sha512-mmkgE6Q2+K74tnkou7tXlpDLvoCU/qkSa2GSQ3XUiHWvcebCoDQzS670RR3tO8PmaWlIyWWISYWzZLuMfxunRA== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/logger" "3.10.0" - "@docusaurus/mdx-loader" "3.10.0" - "@docusaurus/theme-common" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-common" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/logger" "3.10.1" + "@docusaurus/mdx-loader" "3.10.1" + "@docusaurus/theme-common" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-common" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" cheerio "1.0.0-rc.12" combine-promises "^1.1.0" feed "^4.2.2" @@ -1785,20 +1833,20 @@ utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-docs@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.10.0.tgz#9c4ea1d5a405340f28c281d2e4586c695a7c65a5" - integrity sha512-9BjHhf15ct8Z7TThTC0xRndKDVvMKmVsAGAN7W9FpNRzfMdScOGcXtLmcCWtJGvAezjOJIm6CxOYCy3Io5+RnQ== +"@docusaurus/plugin-content-docs@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.10.1.tgz#261e0e982e4a937c05b462e3c5729374f433b752" + integrity sha512-2jRVrtzjf8LClGTHQlwlwuD3wQXRx3WEoF7XUarJ8Ou+0onV+SLtejsyfY9JLpfUh9hPhXM4pbBGkyAY4Bi3HQ== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/logger" "3.10.0" - "@docusaurus/mdx-loader" "3.10.0" - "@docusaurus/module-type-aliases" "3.10.0" - "@docusaurus/theme-common" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-common" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/logger" "3.10.1" + "@docusaurus/mdx-loader" "3.10.1" + "@docusaurus/module-type-aliases" "3.10.1" + "@docusaurus/theme-common" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-common" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" "@types/react-router-config" "^5.0.7" combine-promises "^1.1.0" fs-extra "^11.1.1" @@ -1809,142 +1857,142 @@ utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-pages@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.10.0.tgz#7670cbb3c849f434949f542bfdfded1580a13165" - integrity sha512-5amX8kEJI+nIGtuLVjYk59Y5utEJ3CHETFOPEE4cooIRLA4xM4iBsA6zFgu4ljcopeYwvBzFEWf5g2I6Yb9SkA== +"@docusaurus/plugin-content-pages@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.10.1.tgz#8c6ffc2079ed0262548ecc4df1dea6add6aa9673" + integrity sha512-huJpaRPMl42nsFwuCXvV8bVDj2MazuwRJIUylI/RSlmZeJssVoZXeCjVf1y+1Drtpa9SKcdGn8yoJ76IRJijtw== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/mdx-loader" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/mdx-loader" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" fs-extra "^11.1.1" tslib "^2.6.0" webpack "^5.88.1" -"@docusaurus/plugin-css-cascade-layers@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.10.0.tgz#71e318d842be95f92be6c3dca00ceea4971d0edb" - integrity sha512-6q1vtt5FJcg5osgkHeM1euErECNqEZ5Z1j69yiNx2luEBIso+nxCkS9nqj8w+MK5X7rvKEToGhFfOFWncs51pQ== +"@docusaurus/plugin-css-cascade-layers@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.10.1.tgz#440578d95cbe1a6120936fa83df868d2626cd1d8" + integrity sha512-r//fn+MNHkE1wCof8T29VAQezt1enGCpsFxoziBbvLgBM4JfXN2P3rxrBaavHmvLvm7lYkpJeitcDthwnmWCTw== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" tslib "^2.6.0" -"@docusaurus/plugin-debug@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-3.10.0.tgz#e77f924604e1e09d5d90fe0bdf23a3be8ea3307e" - integrity sha512-XcljKN+G+nmmK69uQA1d9BlYU3ZftG3T3zpK8/7Hf/wrOlV7TA4Ampdrdwkg0jElKdKAoSnPhCO0/U3bQGsVQQ== +"@docusaurus/plugin-debug@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-3.10.1.tgz#b8b7b24d9a7d185fd8a56a030f90145d3bfd8239" + integrity sha512-9KqOpKNfAyqGZykRb9LhIT/vyRF6sm/ykhjj/39JvaJahDS+jZJE0Z1Wfz9q3DUNDTMNN0Q7u/kk4rKKU+IJuA== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils" "3.10.1" fs-extra "^11.1.1" react-json-view-lite "^2.3.0" tslib "^2.6.0" -"@docusaurus/plugin-google-analytics@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.10.0.tgz#22c7e976fe4d970c7cd1c73c9723d9a5786c6e37" - integrity sha512-hTEoodatpBZnUat5nFExbuTGA1lhWGy7vZGuTew5Q3QDtGKFpSJLYmZJhdTjvCFwv1+qQ67hgAVlKdJOB8TXow== +"@docusaurus/plugin-google-analytics@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.10.1.tgz#ac15afc77386e0352edb8a1698d993aa5de36ffc" + integrity sha512-8o0P1KtmgdYQHH+oInitPpRWI0Of5XednAX4+DMhQNSmGSRNrsEEHg1ebv35m9AgRClfAytCJ5jA9KvcASTyuA== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" tslib "^2.6.0" -"@docusaurus/plugin-google-gtag@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.10.0.tgz#c38a2ba638257851cc845b934506b80c08d47f96" - integrity sha512-iB/Zzjv/eelJRbdULZqzWCbgMgJ7ht4ONVjXtN3+BI/muil6S87gQ1OJyPwlXD+ELdKkitC7bWv5eJdYOZLhrQ== +"@docusaurus/plugin-google-gtag@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.10.1.tgz#0482b83b9bc411aa99a432be2b39d2e53a00e2e0" + integrity sha512-pu3xIUo5o/zCMLfUY9BO5KOwSH0zIsAGyFRPvXHayFSA5XIhCU/SFuB0g0ZNjFn9niZLCaNvoeAuOGFJZq0fdw== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" "@types/gtag.js" "^0.0.20" tslib "^2.6.0" -"@docusaurus/plugin-google-tag-manager@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.10.0.tgz#5469c923cc1ad4608399d0b17e5fcacd8e030d56" - integrity sha512-FEjZxqKgLHa+Wez/EgKxRwvArNCWIScfyEQD95rot7jkxp6nonjI5XIbGfO/iYhM5Qinwe8aIEQHP2KZtpqVuA== +"@docusaurus/plugin-google-tag-manager@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.10.1.tgz#eaf5765d6f82b4fb661d92a793d1883f9d1ec106" + integrity sha512-f6fyGHiCm7kJHBtAisGQS5oNBnpnMTYQZxDXeVrnw/3zWU+LMA22pr6UHGYkBKDbN+qPC5QHG3NuOfzQLq3+Lw== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" tslib "^2.6.0" -"@docusaurus/plugin-sitemap@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.10.0.tgz#35d59d46803f279f22aa64fc1bd18c048f12662b" - integrity sha512-DVTSLjB97hIjmayGnGcBfognCeI7ZuUKgEnU7Oz81JYqXtVg94mVTthDjq3QHTylYNeCUbkaW8VF0FDLcc8pPw== +"@docusaurus/plugin-sitemap@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.10.1.tgz#66a6974bb2fd1b9d8f5cb0f3c5ecd2201c118565" + integrity sha512-C26MbmmqgdjkDq1htaZ3aD7LzEDKFWXfpyQpt0EOUThuq5nV77zDaedV20yHcVo9p+3ey9aZ4pbHA0D3QcZTzg== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/logger" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-common" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/logger" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-common" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" fs-extra "^11.1.1" sitemap "^7.1.1" tslib "^2.6.0" -"@docusaurus/plugin-svgr@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-svgr/-/plugin-svgr-3.10.0.tgz#8ada2e6dd8318d20206a9b044fc091a5794ba3f0" - integrity sha512-lNljBESaETZqVBMPqkrGchr+UPT1eZzEPLmJhz8I76BxbjqgsUnRvrq6lQJ9sYjgmgX52KB7kkgczqd2yzoswQ== +"@docusaurus/plugin-svgr@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-svgr/-/plugin-svgr-3.10.1.tgz#c217c24d6d23fd2bc6f54d44c040635b49d6b36e" + integrity sha512-6SFxsmjWFkVLDmBUvFK6i72QjUwqyQFe4Ovz+SUJophJjOyVG3ZZG5IQpBC/kX/Gfv1yWeU9nWauH6F6Q7QX/Q== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" "@svgr/core" "8.1.0" "@svgr/webpack" "^8.1.0" tslib "^2.6.0" webpack "^5.88.1" -"@docusaurus/preset-classic@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-3.10.0.tgz#74b6facdaf568bcd41ec90cae9aebb7ca0ac8619" - integrity sha512-kw/Ye02Hc6xP1OdTswy8yxQEHg0fdPpyWAQRxr5b2x3h7LlG2Zgbb5BDFROnXDDMpUxB7YejlocJIE5HIEfpNA== +"@docusaurus/preset-classic@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-3.10.1.tgz#faf330d96aedc9083a59bec09d966ae4dfc8b2fb" + integrity sha512-YO/FL8v1zmbxoTso6mjMz/RDjhaTJxb1UpFFTDdY5847LLDCeyYiYlrhyTbgN1RIN3xnkLKZ9Lj1x8hUzI4JOg== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/plugin-content-blog" "3.10.0" - "@docusaurus/plugin-content-docs" "3.10.0" - "@docusaurus/plugin-content-pages" "3.10.0" - "@docusaurus/plugin-css-cascade-layers" "3.10.0" - "@docusaurus/plugin-debug" "3.10.0" - "@docusaurus/plugin-google-analytics" "3.10.0" - "@docusaurus/plugin-google-gtag" "3.10.0" - "@docusaurus/plugin-google-tag-manager" "3.10.0" - "@docusaurus/plugin-sitemap" "3.10.0" - "@docusaurus/plugin-svgr" "3.10.0" - "@docusaurus/theme-classic" "3.10.0" - "@docusaurus/theme-common" "3.10.0" - "@docusaurus/theme-search-algolia" "3.10.0" - "@docusaurus/types" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/plugin-content-blog" "3.10.1" + "@docusaurus/plugin-content-docs" "3.10.1" + "@docusaurus/plugin-content-pages" "3.10.1" + "@docusaurus/plugin-css-cascade-layers" "3.10.1" + "@docusaurus/plugin-debug" "3.10.1" + "@docusaurus/plugin-google-analytics" "3.10.1" + "@docusaurus/plugin-google-gtag" "3.10.1" + "@docusaurus/plugin-google-tag-manager" "3.10.1" + "@docusaurus/plugin-sitemap" "3.10.1" + "@docusaurus/plugin-svgr" "3.10.1" + "@docusaurus/theme-classic" "3.10.1" + "@docusaurus/theme-common" "3.10.1" + "@docusaurus/theme-search-algolia" "3.10.1" + "@docusaurus/types" "3.10.1" -"@docusaurus/theme-classic@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.10.0.tgz#d937915c691189f27ced649c822994d839ea565b" - integrity sha512-9msCAsRdN+UG+RwPwCFb0uKy4tGoPh5YfBozXeGUtIeAgsMdn6f3G/oY861luZ3t8S2ET8S9Y/1GnpJAGWytww== +"@docusaurus/theme-classic@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.10.1.tgz#deed8cf73cc0f56113e53775cbb3b168c3c61566" + integrity sha512-VU1RK0qb2pab0si4r7HFK37cYco8VzqLj3u1PspVipSr/z/GPVKHO4/HXbnePqHoWDk8urjyGSeatH0NIMBM1A== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/logger" "3.10.0" - "@docusaurus/mdx-loader" "3.10.0" - "@docusaurus/module-type-aliases" "3.10.0" - "@docusaurus/plugin-content-blog" "3.10.0" - "@docusaurus/plugin-content-docs" "3.10.0" - "@docusaurus/plugin-content-pages" "3.10.0" - "@docusaurus/theme-common" "3.10.0" - "@docusaurus/theme-translations" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-common" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/logger" "3.10.1" + "@docusaurus/mdx-loader" "3.10.1" + "@docusaurus/module-type-aliases" "3.10.1" + "@docusaurus/plugin-content-blog" "3.10.1" + "@docusaurus/plugin-content-docs" "3.10.1" + "@docusaurus/plugin-content-pages" "3.10.1" + "@docusaurus/theme-common" "3.10.1" + "@docusaurus/theme-translations" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-common" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" "@mdx-js/react" "^3.0.0" clsx "^2.0.0" copy-text-to-clipboard "^3.2.0" @@ -1959,15 +2007,15 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-common@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.10.0.tgz#70b419ccfdf62f092299354a72d1692e81be597d" - integrity sha512-Dkp1YXKn16ByCJAdIjbDIOpVb4Z66MsVD694/ilX1vAAHaVEMrVsf/NPd9VgreyFx08rJ9GqV1MtzsbTcU73Kg== +"@docusaurus/theme-common@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.10.1.tgz#cbfec82b1b107be5c229811ed9caae14a501361c" + integrity sha512-0YtmIeoNo1fIw65LO8+/1dPgmDV86UmhMkow37gzjytuiCSQm9xob6PJy0L4kuQEMTLfUOGvkXvZr7GPrHquMA== dependencies: - "@docusaurus/mdx-loader" "3.10.0" - "@docusaurus/module-type-aliases" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-common" "3.10.0" + "@docusaurus/mdx-loader" "3.10.1" + "@docusaurus/module-type-aliases" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-common" "3.10.1" "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" @@ -1977,48 +2025,48 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-live-codeblock@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-live-codeblock/-/theme-live-codeblock-3.10.0.tgz#05a38c6bfac479fd698f18f27ca06ebb126633d9" - integrity sha512-1Ycxu0dBAhEXzXPQ1dQW01aY1MNi7TCTUOBtIF0GcNrQBFj74XxhDqv/T6GxYBsaN+6QnIDs1T+D43iV2/r2hQ== +"@docusaurus/theme-live-codeblock@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-live-codeblock/-/theme-live-codeblock-3.10.1.tgz#29e6ddee467d816205ad611fd7bf10f00db5bdef" + integrity sha512-MKG/0zreelS6YlupQAoKmS5nCw9RRKwDHihJg2FinsU1+rqbrOYNYVq//eQy+m649k9b8XCazEw9VUMTFhpCTg== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/theme-common" "3.10.0" - "@docusaurus/theme-translations" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/theme-common" "3.10.1" + "@docusaurus/theme-translations" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" "@philpl/buble" "^0.19.7" clsx "^2.0.0" fs-extra "^11.1.1" react-live "^4.1.6" tslib "^2.6.0" -"@docusaurus/theme-mermaid@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-mermaid/-/theme-mermaid-3.10.0.tgz#6581ccf16d27e4c02fe8c7cf15488862f27be9c8" - integrity sha512-Y2xrlwhIJ80oOZIO3PXL6A7J869splfcMI87E3NKpYsy3zJxOyV+BP1QMtGi59ajKgU868HPuyyn6J+6BZGOBg== +"@docusaurus/theme-mermaid@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-mermaid/-/theme-mermaid-3.10.1.tgz#dada9c50c780524d246906234ace8a35446f26fc" + integrity sha512-2gxpmln8Pc4EN1oWzshQEx2HTs67jk14v7MmgqGs8ZU7Nm8oihg+fTouof2u4vN8DtB3Fln4cDJu4UprSX1S3Q== dependencies: - "@docusaurus/core" "3.10.0" - "@docusaurus/module-type-aliases" "3.10.0" - "@docusaurus/theme-common" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/module-type-aliases" "3.10.1" + "@docusaurus/theme-common" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" mermaid ">=11.6.0" tslib "^2.6.0" -"@docusaurus/theme-search-algolia@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.10.0.tgz#0ff57fe58db6abde8f5ad2877e459cd2fa6e7464" - integrity sha512-f5FPKI08e3JRG63vR/o4qeuUVHUHzFzM0nnF+AkB67soAZgNsKJRf2qmUZvlQkGwlV+QFkKe4D0ANMh1jToU3g== +"@docusaurus/theme-search-algolia@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.10.1.tgz#6f422058711629ce8d7c2f17e1e54efa075c626e" + integrity sha512-OTaARARVZj2GvkJQjB+1jOIxntRaXea+G+fMsNqrZBAU1O1vJKDW22R7kECOHW27oJCLFN9HKaZeRrfAUyviug== dependencies: "@algolia/autocomplete-core" "^1.19.2" "@docsearch/react" "^3.9.0 || ^4.3.2" - "@docusaurus/core" "3.10.0" - "@docusaurus/logger" "3.10.0" - "@docusaurus/plugin-content-docs" "3.10.0" - "@docusaurus/theme-common" "3.10.0" - "@docusaurus/theme-translations" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-validation" "3.10.0" + "@docusaurus/core" "3.10.1" + "@docusaurus/logger" "3.10.1" + "@docusaurus/plugin-content-docs" "3.10.1" + "@docusaurus/theme-common" "3.10.1" + "@docusaurus/theme-translations" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-validation" "3.10.1" algoliasearch "^5.37.0" algoliasearch-helper "^3.26.0" clsx "^2.0.0" @@ -2028,23 +2076,23 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-translations@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.10.0.tgz#8fdc23d29bd7f907db49c36cf65e2123d96be300" - integrity sha512-L9IbFLwTc5+XdgH45iQYufLn0SVZd6BUNelDbKIFlH+E4hhjuj/XHWAFMX/w2K59rfy8wak9McOaei7BSUfRPA== +"@docusaurus/theme-translations@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.10.1.tgz#c3119a015652290eea560ca45ac775963d6eb75b" + integrity sha512-cLMyaKivjBVWKMJuWqyFVVgtqe8DPJNPkog0bn8W1MDVAKcPdxRFycBfC1We1RaNp7Rdk513bmtW78RR6OBxBw== dependencies: fs-extra "^11.1.1" tslib "^2.6.0" -"@docusaurus/tsconfig@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/tsconfig/-/tsconfig-3.10.0.tgz#f40a57248828f0503a5f355cf30aa59941c9baaa" - integrity sha512-TXdC3WXuPrdQAexLvjUJfnYf3YKEgEqAs5nK0Q88pRBCW7t7oN4ILvWYb3A5Z1wlSXyXGWW/mCUmLEhdWsjnDQ== +"@docusaurus/tsconfig@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/tsconfig/-/tsconfig-3.10.1.tgz#1db31b4a4a5c914bdffa80070a35b6365d34f2e8" + integrity sha512-rYvB7yqkdqWIpAbDzQljGfM4cDBkLTbhmagZBEcsyj6oPUsz47lmW2pYdN1j+7sGFgltbAmQH62xfbrij4Eh6Q== -"@docusaurus/types@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-3.10.0.tgz#a69232bba74b738fcf4671fd5f0f079366dd3d13" - integrity sha512-F0dOt3FOoO20rRaFK7whGFQZ3ggyrWEdQc/c8/UiRuzhtg4y1w9FspXH5zpCT07uMnJKBPGh+qNazbNlCQqvSw== +"@docusaurus/types@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-3.10.1.tgz#d42837938ae43ca2be0ca47e63e00476b5eb94be" + integrity sha512-XYMK8k1szDCFMw2V+Xyen0g7Kee1sP3dtFnl7vkGkZOkeAJ/oPDQPL8iz4HBKOo/cwU8QeV6onVjMqtP+tFzsw== dependencies: "@mdx-js/mdx" "^3.0.0" "@types/history" "^4.7.11" @@ -2057,36 +2105,36 @@ webpack "^5.95.0" webpack-merge "^5.9.0" -"@docusaurus/utils-common@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.10.0.tgz#2a6dc76b312664fca7234d33607c085318ff1ae3" - integrity sha512-JyL7sb9QVDgYvudIS81Dv0lsWm7le0vGZSDwsztxWam1SPBqrnkvBy9UYL/amh6pbybkyYTd3CMTkO24oMlCSw== +"@docusaurus/utils-common@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.10.1.tgz#6350b4898691e765de750f90eade0e0fa7902d99" + integrity sha512-5mFSgEADtnFxFH7RLw02QA5MpU5JVUCj0MPeIvi/aF4Fi45tQRIuTwXoXDqJ+1VfQJuYJGz3SI63wmGz4HvXzA== dependencies: - "@docusaurus/types" "3.10.0" + "@docusaurus/types" "3.10.1" tslib "^2.6.0" -"@docusaurus/utils-validation@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.10.0.tgz#a2418d7f31980d991fd3a1f39c8aad8820b36812" - integrity sha512-c+6n2+ZPOJtWWc8Bb/EYdpSDfjYEScdCu9fB/SNjOmSCf1IdVnGf2T53o0tsz0gDRtCL90tifTL0JE/oMuP1Mw== +"@docusaurus/utils-validation@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.10.1.tgz#ddbcce997a5506424cdd16abf6845cc51692acae" + integrity sha512-cRv1X69jwaWv47waglllgZVWzeBFLhl53XT/XED/83BerVBTC5FTP8WTcVl8Z6sZOegDSwitu/wpCSPCDOT6lg== dependencies: - "@docusaurus/logger" "3.10.0" - "@docusaurus/utils" "3.10.0" - "@docusaurus/utils-common" "3.10.0" + "@docusaurus/logger" "3.10.1" + "@docusaurus/utils" "3.10.1" + "@docusaurus/utils-common" "3.10.1" fs-extra "^11.2.0" joi "^17.9.2" js-yaml "^4.1.0" lodash "^4.17.21" tslib "^2.6.0" -"@docusaurus/utils@3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.10.0.tgz#ea7d7b0d325b60f728decc00bb3908d00ef86faf" - integrity sha512-T3B0WTigsIthe0D4LQa2k+7bJY+c3WS+Wq2JhcznOSpn1lSN64yNtHQXboCj3QnUs1EuAZszQG1SHKu5w5ZrlA== +"@docusaurus/utils@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.10.1.tgz#535968caa2c9bff69f997a081b98b95b3c5d3785" + integrity sha512-3ojeJry9xBYdJO6qoyyzqeJFSJBVx2mXhyDzSdjwL2+URFQMf+h25gG38iswGImicK0ELjTd1EL2xzk8hf3QPw== dependencies: - "@docusaurus/logger" "3.10.0" - "@docusaurus/types" "3.10.0" - "@docusaurus/utils-common" "3.10.0" + "@docusaurus/logger" "3.10.1" + "@docusaurus/types" "3.10.1" + "@docusaurus/utils-common" "3.10.1" escape-string-regexp "^4.0.0" execa "^5.1.1" file-loader "^6.2.0" @@ -2986,23 +3034,23 @@ "@rc-component/util" "^1.2.1" clsx "^2.1.1" -"@rc-component/form@~1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@rc-component/form/-/form-1.8.0.tgz#ed565337a69ebb6cfa20d1ad0dd58e443a71313a" - integrity sha512-eUD5KKYnIZWmJwRA0vnyO/ovYUfHGU1svydY1OrqU5fw8Oz9Tdqvxvrlh0wl6xI/EW69dT7II49xpgOWzK3T5A== +"@rc-component/form@~1.8.1": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@rc-component/form/-/form-1.8.1.tgz#d811fb52df41bf72297938ebfe5cf4a4774588d4" + integrity sha512-8O7TB55Fi2mWIGvSnwZjk8jFqVNYyKDAswglwGShcbndxqzKz4cHwNtNaLjZlAeRge9wcB0LL8IWsC/Bl18raQ== dependencies: "@rc-component/async-validator" "^5.1.0" "@rc-component/util" "^1.6.2" clsx "^2.1.1" -"@rc-component/image@~1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@rc-component/image/-/image-1.8.0.tgz#1bfbb13a72782df05c075be45aed94222aee7a88" - integrity sha512-Dr41bFevLB5NgVaJhEUmNvbEf+ynAhim6W98ZW2xvCsdFISc2TYP4ZvCVdie3eaZdum2kieVcvpNHu+UrzAAHA== +"@rc-component/image@~1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@rc-component/image/-/image-1.9.0.tgz#110785d735d20336afcdbac84e8fbfd059a7a44e" + integrity sha512-khF7w7xkBH5B1bsBcI1FSUZdkyd1aqpl2eYyILCqCzzQH3XdfehGUaZTnptyaJJfs09/R5hv9jXWyazOMFIClQ== dependencies: "@rc-component/motion" "^1.0.0" "@rc-component/portal" "^2.1.2" - "@rc-component/util" "^1.10.0" + "@rc-component/util" "^1.10.1" clsx "^2.1.1" "@rc-component/input-number@~1.6.2": @@ -3279,10 +3327,10 @@ "@rc-component/util" "^1.3.0" clsx "^2.1.1" -"@rc-component/util@^1.1.0", "@rc-component/util@^1.10.0", "@rc-component/util@^1.2.0", "@rc-component/util@^1.2.1", "@rc-component/util@^1.3.0", "@rc-component/util@^1.4.0", "@rc-component/util@^1.6.2", "@rc-component/util@^1.7.0", "@rc-component/util@^1.8.1", "@rc-component/util@^1.9.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@rc-component/util/-/util-1.10.0.tgz#faeebbe0510f998b6d5cee9da9176b6d613cac2c" - integrity sha512-aY9GLBuiUdpyfIUpAWSYer4Tu3mVaZCo5A0q9NtXcazT3MRiI3/WNHCR+DUn5VAtR6iRRf0ynCqQUcHli5UdYw== +"@rc-component/util@^1.1.0", "@rc-component/util@^1.10.1", "@rc-component/util@^1.2.0", "@rc-component/util@^1.2.1", "@rc-component/util@^1.3.0", "@rc-component/util@^1.4.0", "@rc-component/util@^1.6.2", "@rc-component/util@^1.7.0", "@rc-component/util@^1.8.1", "@rc-component/util@^1.9.0": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@rc-component/util/-/util-1.10.1.tgz#213c84c77e8b2001095530d3b0dc47c49c34ffe3" + integrity sha512-q++9S6rUa5Idb/xIBNz6jtvumw5+O5YV5V0g4iK9mn9jWs4oGJheE3ZN1kAnE723AXyaD8v95yeOASmdk8Jnng== dependencies: is-mobile "^5.0.0" react-is "^18.2.0" @@ -3718,26 +3766,26 @@ "@svgr/plugin-jsx" "8.1.0" "@svgr/plugin-svgo" "8.1.0" -"@swagger-api/apidom-ast@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ast/-/apidom-ast-1.10.2.tgz#fd7b49929bdd8ca07c247efeaae3c47c86d7da68" - integrity sha512-vTl8gWyeZaj887/NSWYs3as4K8wXHar5wY/606XRBjR2UgmJBokBgKjq7S23LW9tsYjsT4MjQKC8idjgw17xvg== +"@swagger-api/apidom-ast@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ast/-/apidom-ast-1.11.0.tgz#95632d4935a0737fc3f82d839eb42207873da915" + integrity sha512-poLd6eNipLCFCrxjZD+E9E0Z85CLfFzueNiVcYj86rwMp2OszYsTzZS2jz82yR/usNCjXCpkQ2xEXWSmDhefPg== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-error" "^1.10.2" + "@swagger-api/apidom-error" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" unraw "^3.0.0" -"@swagger-api/apidom-core@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-core/-/apidom-core-1.10.2.tgz#1ecf2808a1e3b1814e7f133e5c94cdd9fd5b9dcd" - integrity sha512-qryNBGHNWDvSRyK1w5rox0UOrHrVBjZOHgeXFpGHF+oBO7ntSc/H7BSiYMDR+KQESkzMcAxn4tZMLYItaBt06w== +"@swagger-api/apidom-core@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-core/-/apidom-core-1.11.0.tgz#7a1d60ad121bd32af46685c4888e64414dff5f80" + integrity sha512-7TvbbC3dG3yM8cjqyrFXoTOpwgOC68+Z17Ro36drJwZ0k/c7QQc0dI/KvTSPHn9UfimEMdZ0q+yIIzqrAiEmww== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" + "@swagger-api/apidom-ast" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" "@types/ramda" "~0.30.0" minim "~0.23.8" ramda "~0.30.0" @@ -3745,319 +3793,319 @@ short-unique-id "^5.3.2" ts-mixer "^6.0.3" -"@swagger-api/apidom-error@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-error/-/apidom-error-1.10.2.tgz#a017b9653d22414908d664468f12634841f37696" - integrity sha512-SWyPyL5xwTUsDzPi0A5zwTFwqPezvlwj4opEqruqjESNTYupUA7+vt4Mdj7IlDaRYRG1qyCWQgKhIBXznVUD4w== +"@swagger-api/apidom-error@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-error/-/apidom-error-1.11.0.tgz#7f2235e9068e8e1b3c87a43835623c623d0f7392" + integrity sha512-JPt37oOrf73CAZNQBPffnLzU5iEUs8cT9pFmc9vy2gHQp+vjSKxeJ9F6zagTp8VnLPUq0gVjIvCQvcX8NPW2jA== dependencies: "@babel/runtime-corejs3" "^7.20.7" -"@swagger-api/apidom-json-pointer@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.10.2.tgz#f454e11606759432ee87432216eb65703a76057f" - integrity sha512-zySHPqIXF4HZ3VWbHwTxO+H1e9dJw7mGHzoX+tZjx5wVyLQO3kZDCAAXzz3c3/TIY21Y2Zkpkez3q9hjFyuLvQ== +"@swagger-api/apidom-json-pointer@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.11.0.tgz#f129dec39b749a09d03ad84909033b998a886339" + integrity sha512-11JWHr55FciYGTbcicNZrBsFEwNuLLZybi00YHJ3OBcuXcFJPKmKluLnVL7GhZYEqvLYOcVsCfInYW5MXoj00w== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" "@swaggerexpert/json-pointer" "^2.10.1" -"@swagger-api/apidom-ns-api-design-systems@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.10.2.tgz#0bea51cbfbb86ec272890c58cd771876329368e2" - integrity sha512-MsZ4GWmWN7wkWv7G9Pwk8sHU1j0bwk7xoGeaZmNCylbTfYvGkg6jJGMHdAdQNCQXbbpfLeKt1O+3YCN//JUQ7w== +"@swagger-api/apidom-ns-api-design-systems@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.11.0.tgz#c9bee1def674b6b12559a97da243c9358e4f5d13" + integrity sha512-IskDsUkUtNas4guoChRKKkw0wOst64nRA24WuIjLf8ztfBdcl/oqx/cgy8pwWCUqNYvL9L3+sD5HeuokqMrySw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-1" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-1" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-arazzo-1@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-arazzo-1/-/apidom-ns-arazzo-1-1.10.2.tgz#419ac738a943f4990a770dcfd521f0fa6122b08f" - integrity sha512-fQSwDlIR85tbnLXAjtV/ypSGUBfrzFcZ4NbH6BL1DSTR4uEunVxAULdD4wlhCt9gGNDl/zxZD3vQtlYDkXDFmw== +"@swagger-api/apidom-ns-arazzo-1@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-arazzo-1/-/apidom-ns-arazzo-1-1.11.0.tgz#ceda21f89fe970d8c6e2504e0ea644f864eabae1" + integrity sha512-n+aGSlLHyrpmCaBa9DBZkIqnNVzYAYSa010MvAwhlwtW3EbFYNwYWinbTwLqCd3leN6XWTvQYCvk0/k7/9Cq4A== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-json-schema-2020-12" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-json-schema-2020-12" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-asyncapi-2@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.10.2.tgz#37c5e15a847a3dbefb5c002e3033a75476b3744f" - integrity sha512-obWHe3pyAj65Nf9ISwnbtJ4C5mZ15C6mtQXxzHVW5maVZqlqt3s/YbPY87EqK9ArdNOwOZHkQt2Uth02GMmjxA== +"@swagger-api/apidom-ns-asyncapi-2@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.11.0.tgz#9e7dcb40c6de940c6b4ad23c8413864aa3286127" + integrity sha512-SHh3naFZlXFI0gG36tNYvJ/VO8aZsjnXIQAqJHfOE6rrpl5msJrdDatmNczh+57WPZxEZA+KTXWCqNKdeu3G3Q== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-json-schema-draft-7" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-json-schema-draft-7" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-asyncapi-3@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-asyncapi-3/-/apidom-ns-asyncapi-3-1.10.2.tgz#787851874b278dabe5b9583120f13ed06aafc21a" - integrity sha512-yqNmXeObF2OLAusgGEapXz2CrGjXwkcfG3DYcQDtOvgRytvGZxC2EkCUR+wEXCVNYhoJ7QpVzzTJOHs3jOvptg== +"@swagger-api/apidom-ns-asyncapi-3@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-asyncapi-3/-/apidom-ns-asyncapi-3-1.11.0.tgz#92a3f5b78f795f651114a5d7e572dadd051e62b0" + integrity sha512-4vrgNYDj68hgmgZj1eGBaBr5xqIETWn4jAioiRHek4jV1FLvmxCs3nC2nYs8CzQqqJ1bqirdiirrUpqhaQvTEA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-asyncapi-2" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-asyncapi-2" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-json-schema-2019-09@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2019-09/-/apidom-ns-json-schema-2019-09-1.10.2.tgz#358652692fb3dc89dbfc5f775ec79a27791b9620" - integrity sha512-I1FaBoDFMjybF4QVsesIYl8OilkwycZ0mQ0jf1P++zfTRG27uIePB8M+Iuj6iqMsE3qpkjjJJ6ZLnrLPdKvmRw== +"@swagger-api/apidom-ns-json-schema-2019-09@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2019-09/-/apidom-ns-json-schema-2019-09-1.11.0.tgz#18531aa5a09192d2f296474f458b493e64f40d5c" + integrity sha512-5avPMY1YbQmJIqXlu7rm3yftf4xhT2REBxpEgw8Nc7Zlbn4Z5iGXBsHr60982MwqeE6W8wA+HHQMKHM5siuhdQ== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" - "@swagger-api/apidom-ns-json-schema-draft-7" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" + "@swagger-api/apidom-ns-json-schema-draft-7" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.4" -"@swagger-api/apidom-ns-json-schema-2020-12@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.10.2.tgz#f83dc1f6f403d1572acd2457557c37618379581d" - integrity sha512-lg9XfRlJRNoBa2EDGpEFc7HvFV39G6RG0/SbjQY0BE/WZer10wmfTCU7l3RUNJXRFGKH6/O/nsYgP7AFjTanXQ== +"@swagger-api/apidom-ns-json-schema-2020-12@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.11.0.tgz#deb31661039e6a0be281173ab959644ed75ebe69" + integrity sha512-zddyOxWKlQ9WPaZR0e8ykmy8AbGnDvqCqqy6BdYqKZ9Ts8ZK1XwOB2j9ruccZpoiy/rp2tow+CUf3XE5rricmQ== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" - "@swagger-api/apidom-ns-json-schema-2019-09" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" + "@swagger-api/apidom-ns-json-schema-2019-09" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.4" -"@swagger-api/apidom-ns-json-schema-draft-4@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.10.2.tgz#79e984a17ce86a5a768cab521ea0bd79987d705f" - integrity sha512-C50KnSKynrmHky/oOB6+hHyZVpwng78Fz5aZjay3h8X5C/PJHmm3sDJFvF3/9wkYHO3N9sPp7cpu4Xm9VJ4/wQ== +"@swagger-api/apidom-ns-json-schema-draft-4@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.11.0.tgz#45cd21eb80541c80cb503c332aeda8eac2f245fd" + integrity sha512-upc0xKb3nxsYPECRDf5UygnZHTSj78xHj5+SBIHNDXoaGDhvMCtWoDVGAKFtZ+jZlIkyJt7cGAeOX0w9IV3XkA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.10.2" - "@swagger-api/apidom-core" "^1.10.2" + "@swagger-api/apidom-ast" "^1.11.0" + "@swagger-api/apidom-core" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.4" -"@swagger-api/apidom-ns-json-schema-draft-6@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.10.2.tgz#e55d05c44bb580e6690b1d8bdbafc29c9480c822" - integrity sha512-/wiP8+2lF8UJRrkoQ9HvKnMbnqijk2uY/hAg+/Bo73T9NGKkEa29jYVUKYNYj7gJBw4hhkUHfHFWuZUpxPC4ZA== +"@swagger-api/apidom-ns-json-schema-draft-6@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.11.0.tgz#c251d9dfe26a39f9cfa7d316251112f3cb541ffd" + integrity sha512-sd/U6Y34uRqdgd3Phz1oEhO7UBCn60+OfIasFFpHZcKe7O0jTmayiaJqbpwirhwt7Fv5Ev5m58+y1nVomLnhQw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" - "@swagger-api/apidom-ns-json-schema-draft-4" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" + "@swagger-api/apidom-ns-json-schema-draft-4" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.4" -"@swagger-api/apidom-ns-json-schema-draft-7@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.10.2.tgz#357b62e4df4f07912c5283ac9a214e175aa27593" - integrity sha512-firN/uvnVxQgACqcyzV3NU9qjbMvNMJkpmm3wOat3URmaFMaFBT3qjbU1pFHBGbnXI3+I9pQJZHmJSwqNzfUbQ== +"@swagger-api/apidom-ns-json-schema-draft-7@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.11.0.tgz#3d8416635d60914e0699becb0681370b1b2aeb2c" + integrity sha512-7ptuxmuh2vN1hDr3cLkYm2rl+ak2J1byoGxswucKfSb+7IaFoA36/t7kcOsE/hIO4yI7T3ZPOuNSpeg1NBVjEw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" - "@swagger-api/apidom-ns-json-schema-draft-6" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" + "@swagger-api/apidom-ns-json-schema-draft-6" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.4" -"@swagger-api/apidom-ns-openapi-2@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.10.2.tgz#9b2bec035501d40393291a70f9260e333c8d3ee5" - integrity sha512-FK5kYvo/1uwAByumRVRsynBlnKxUUImfsjPEFgRCW6yhbCGRqN47NaZ7GYFHpbhjC3OmMN5/etYj6B0jnZx7Gg== +"@swagger-api/apidom-ns-openapi-2@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.11.0.tgz#89b97db3173589cab4b9c57650a6d75638f870bb" + integrity sha512-cAIPJhLxm/nj1kzneNySeaTahY+hH5gkGNsgbmifGnLPsC5YOOfEVMKLj18IREdXqdnxJgRbsI9Azl4g09TPkg== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" - "@swagger-api/apidom-ns-json-schema-draft-4" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" + "@swagger-api/apidom-ns-json-schema-draft-4" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-openapi-3-0@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.10.2.tgz#8f86fd918cd1909444bb7b7c6b0ecc06bdaa76f2" - integrity sha512-ziyv85QbJYHRdc9oTEFBy3pxwxg7BW/a9GrwH01/SmuXVQPjLjwzRb+SjCxLogJppm0yjxOkDFI2VWPp2RADFg== +"@swagger-api/apidom-ns-openapi-3-0@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.11.0.tgz#4b44fb8a292439f4966bedef7d0c484926ece0e5" + integrity sha512-IUEWVSuETE5DdgTJhIt6oZyRTYUV892/I9UdyTResR0Bypc7gy3YXwlzMlUZx73S2klaiFo1dL4iu/fqzA2fEg== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" - "@swagger-api/apidom-ns-json-schema-draft-4" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" + "@swagger-api/apidom-ns-json-schema-draft-4" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-openapi-3-1@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.10.2.tgz#968eaa27f98595a7bb0e820d5b805e770c886be0" - integrity sha512-ngcmO4dH77JT5hZB04OJdyTzgKnt2lNhAZQ+4wXjum/xhszjUmDhOeYfXdHw3Lm7MxsEsTesWzLYQ5LKADc41A== +"@swagger-api/apidom-ns-openapi-3-1@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.11.0.tgz#51ebf009a2e1afc4704a665dbed993516560375e" + integrity sha512-WpUvFgOs4YMUmyeJRQEADps+U5o71YTtzKMPNr1cF1ZHKKkcRMUJL9QlJ4Y9cxAdjo6oXzXZa5922XOpwMYhxA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.10.2" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-json-pointer" "^1.10.2" - "@swagger-api/apidom-ns-json-schema-2020-12" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-0" "^1.10.2" + "@swagger-api/apidom-ast" "^1.11.0" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-json-pointer" "^1.11.0" + "@swagger-api/apidom-ns-json-schema-2020-12" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-0" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-ns-openapi-3-2@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-2/-/apidom-ns-openapi-3-2-1.10.2.tgz#b2bb8f0d8ac71660255d6744aa71cb870c76fabf" - integrity sha512-3SWJ5ipWwn+w11HTUESWex/522jy2aGLzBqqMgH36sy+Wdwx+9Mw2bgSDqkxmNC5+jpzOGUOIWoQAMuCpS/Gzg== +"@swagger-api/apidom-ns-openapi-3-2@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-ns-openapi-3-2/-/apidom-ns-openapi-3-2-1.11.0.tgz#7486802e6168b00814425c01093b74d948a7f65c" + integrity sha512-mUErHIq8rHVoOrkHnRj3mhoNYVIl8th474/m0+E8OB2wBAe0KgiczaJX9KkBQoAo5XIxoRfmI5T3bp+fRabwCA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.10.2" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-json-pointer" "^1.10.2" - "@swagger-api/apidom-ns-json-schema-2020-12" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-0" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-1" "^1.10.2" + "@swagger-api/apidom-ast" "^1.11.0" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-json-pointer" "^1.11.0" + "@swagger-api/apidom-ns-json-schema-2020-12" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-0" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-1" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" ts-mixer "^6.0.3" -"@swagger-api/apidom-parser-adapter-api-design-systems-json@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.10.2.tgz#8249b5abdd430624a7c7f9d1a007ecfc9e2bc3cc" - integrity sha512-kzhJUGzsJ38Uohj5xRQDkQC08rqNhatbqgD30LZ0/UWryJ9nAsjqK2ovuP9t+5WKcDE4iwcYeGSt1NA2XgEZwg== +"@swagger-api/apidom-parser-adapter-api-design-systems-json@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.11.0.tgz#b7c757fadafe6bbcfb12f897b9f7432795de9460" + integrity sha512-0OdwcnV/QF+Vs3Vj0dTmlRHEp9WQg9aBvWWl8Fq25OviyDhGGRpqgkEAOjtVYCH3XyZ1Xz+jhIDOdd5pxBajsA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-api-design-systems" "^1.10.2" - "@swagger-api/apidom-parser-adapter-json" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-api-design-systems" "^1.11.0" + "@swagger-api/apidom-parser-adapter-json" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-api-design-systems-yaml@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.10.2.tgz#053cc675e02bce40b16e2773fc57a11689cceb26" - integrity sha512-i3CmSxJ/iG67ybRDAJ9xpuMrOMFvC/obX2lI36E0VZzBTb+llw4Zd5qFmBqNnImLpwdmk11Z1V7i+5HM+J7ijQ== +"@swagger-api/apidom-parser-adapter-api-design-systems-yaml@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.11.0.tgz#7dd524f0241fd9997e8959a071a3e8b2cf58f1f6" + integrity sha512-K714DT6nFW+ZM9LTo+c120zkUjsEcIFO2DU+0cnzReRyenb1x6RZe+uOqTt7iWohnnWp2FV/j0exd/mCsxW65Q== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-api-design-systems" "^1.10.2" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-api-design-systems" "^1.11.0" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-arazzo-json-1@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-arazzo-json-1/-/apidom-parser-adapter-arazzo-json-1-1.10.2.tgz#988b6999d34df1b85bfbc3f5dc54f419b3b448f0" - integrity sha512-HwiUkwvo5i2hV2SS6KWrdj62BdceZGfhuXhr1il8akWekpU4jXPtr5pv4gOnKKJN7VgjAmwt/DlcCSRo1+9jVA== +"@swagger-api/apidom-parser-adapter-arazzo-json-1@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-arazzo-json-1/-/apidom-parser-adapter-arazzo-json-1-1.11.0.tgz#8b8bafdab34b4a917a2cb68aeb0e9e94ad511fc2" + integrity sha512-z9K6XEr3AafV2EA+1pfW+8VoMCCSSpm2IU7oUTjSnhxRb5t/DZR4Qg8FEK8tRKdS2BO2kFFLb2xikrY3Qx8B+g== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-arazzo-1" "^1.10.2" - "@swagger-api/apidom-parser-adapter-json" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-arazzo-1" "^1.11.0" + "@swagger-api/apidom-parser-adapter-json" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-arazzo-yaml-1@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-arazzo-yaml-1/-/apidom-parser-adapter-arazzo-yaml-1-1.10.2.tgz#fe2371ff7a9cf84094b1ec1554c404c804958c28" - integrity sha512-w8VTVuE7GPbRqWxvMgRoTb726JRsMhFPMfTBf8+MJ4pQThjk78dSXPV2Zlse71b2DWBuQy2sr6zGyLUNs/3ePQ== +"@swagger-api/apidom-parser-adapter-arazzo-yaml-1@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-arazzo-yaml-1/-/apidom-parser-adapter-arazzo-yaml-1-1.11.0.tgz#2a21d25375dae5bfd76ef331a581ad84fd00ccdd" + integrity sha512-HPb7Wzr+cj0IJkRRlqsK1tNCQXivuGRP4iB2yek16sQZXo2eqSUZ3j3Lz/WwWgnN/FWGAODm4bj9+EhGQ11TnA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-arazzo-1" "^1.10.2" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-arazzo-1" "^1.11.0" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-asyncapi-json-2@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.10.2.tgz#aca77a0e3abb7643aab18fa7dcb370334de6d264" - integrity sha512-FDNjqmn2vV1jFoVVwQDO0XPPm8R5xzmcyY/6yBLFmKZADin3smSKVZ+njYHmfRjpspXwN0AwI0drdvuH0FZLJg== +"@swagger-api/apidom-parser-adapter-asyncapi-json-2@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.11.0.tgz#b9c6efff4ece06882a3aba91ed787b307618d6fe" + integrity sha512-sQenLXZRmTDQehe3JCSQpz6jpE3DhMQ0aoe2gpNqo23Gt/4oeW6nAP2h49q9Ne+CHPp0ApFUUyIXF7UTmbUWqA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-asyncapi-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-json" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-asyncapi-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-json" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-asyncapi-json-3@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-json-3/-/apidom-parser-adapter-asyncapi-json-3-1.10.2.tgz#01ff7e0b05336288776791c9d537d6abe98ddb57" - integrity sha512-x/0vM2nDDzYzFnXr69+so/KSH+2py2TiZd1K49pWcX8cHsPV1Y4Ppih7GVOMymd8m/IOCjLYlV7qt4eWDwdldg== +"@swagger-api/apidom-parser-adapter-asyncapi-json-3@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-json-3/-/apidom-parser-adapter-asyncapi-json-3-1.11.0.tgz#af21567e11a9e2eaf84748d5a5a93436c19bc71a" + integrity sha512-aGnG3AYp4Qsimn1FOP0B9leYCJAQVockzHqyJj30xiNAXquBMXr6lq3L2/AEsmpDGv/x/++YJ4p2ggSxy12QNw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-asyncapi-3" "^1.10.2" - "@swagger-api/apidom-parser-adapter-json" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-asyncapi-3" "^1.11.0" + "@swagger-api/apidom-parser-adapter-json" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.10.2.tgz#0912939a3d6f0845587bcd0ed6b67ae36c9989b0" - integrity sha512-2bVACmU9ZmAVVnqQWSc3Bs+xG0HHLU1tfZbYL8xNgSi8kw4HcnejF5mWtN+MLFzTaBmWCi2In7P7BYNR8+2Dyg== +"@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.11.0.tgz#c8d2670275331f075714bdf6afb99a00aa53d3e4" + integrity sha512-iIRlB8B46UPiu0EkKhq1TvwloBgObASJ5ROx8rhT5+Pj+BBegE+KIY02EUKwcz5FgXJrH3XcltLiI7ZA68347Q== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-asyncapi-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-asyncapi-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-asyncapi-yaml-3@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-yaml-3/-/apidom-parser-adapter-asyncapi-yaml-3-1.10.2.tgz#b8de51551d183f74e9c3eb3d0754200bc5751ff0" - integrity sha512-oHpbf+iqBcDS3qtsipMpgCwAeckKMxg0qFKYTCRZyJdctRgupJTxVeir6t/SGo0Ny0a1iknt2LN0u5frEen0kg== +"@swagger-api/apidom-parser-adapter-asyncapi-yaml-3@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-asyncapi-yaml-3/-/apidom-parser-adapter-asyncapi-yaml-3-1.11.0.tgz#aaaf47cd034228d453d6426b3afcf2b429a3a497" + integrity sha512-BF2ZyQYMUNrjP1nMneX6ZD2IWBLycWpxg3yllXDCJtfdQT/IMzldIPKCNI9qoBE57lM6j2hpy+Jd86QJk20t2w== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-asyncapi-3" "^1.10.2" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-asyncapi-3" "^1.11.0" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-json@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.10.2.tgz#fd52f62064a2456a30f020b208d80715d4bb9ae2" - integrity sha512-VnwEkarKfsJYRF0zCI9AGiSIyBUXqS2d32KQuhVCt/HeuF1XO9sjeLjGiosA/24YVOnO0ul5TpiNFQn0pw89mA== +"@swagger-api/apidom-parser-adapter-json@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.11.0.tgz#81e5919a2e4139492c0f910f8413557eb059de8a" + integrity sha512-DObW0LxYwif0erzGoXiEAZ6ecc/18LIEKxjEAc5Bw2M5I0C/iGW4y/UxAywihGvhMEo1gOvdO6w9Jh6UnuPVmA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.10.2" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" + "@swagger-api/apidom-ast" "^1.11.0" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" @@ -4065,119 +4113,119 @@ tree-sitter-json "=0.24.8" web-tree-sitter "=0.24.5" -"@swagger-api/apidom-parser-adapter-openapi-json-2@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.10.2.tgz#18a604e5197f095d7633ec47263ed31c856c2b87" - integrity sha512-+d/o/8TrNBjvFzgPb0RQhrCc8gOWnrHZF+xvCO5gwp+4MUr1XP1AJIox1e6t1SO+j7IQjiF2ocx2r7eFE5QC7w== +"@swagger-api/apidom-parser-adapter-openapi-json-2@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.11.0.tgz#c48a0a51b4381ebf5b7c3406b90d9a25dfa48a49" + integrity sha512-dREUHAEHVry9aSGjqDpYF9Wzm1lgUkV6EgoYDflyQ9HxgCwhucDPFmUgI7UaR0G6bplnJumMcZXh1I1TGn1v7Q== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-openapi-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-json" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-openapi-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-json" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-openapi-json-3-0@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.10.2.tgz#80c16b46d5ef355848d7cc5ab57aec589ada20e1" - integrity sha512-3ieUeX8/WywkUzdOO1U1QKQDNmpZFfOeTAeb4ISDd/PKOVwuEx/b0w5I8EuOu97tKAe3UUesEdii+pJlkcFlFw== +"@swagger-api/apidom-parser-adapter-openapi-json-3-0@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.11.0.tgz#e432f87615bdd5652aa7c299454ede2cbec46f4a" + integrity sha512-U/NZpvuj9IpUS48zF2tYbgW2AtTw6Yi6kXNiHUtgUEomxYdb6XQeKLDGvgeWjgAgfUROohakcH+wx713VCGxfQ== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-0" "^1.10.2" - "@swagger-api/apidom-parser-adapter-json" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-0" "^1.11.0" + "@swagger-api/apidom-parser-adapter-json" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-openapi-json-3-1@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.10.2.tgz#58e2342896bc7a270d5b6cd5951b7b2536b7502e" - integrity sha512-z0c7IgMPLSDhE+ldTb54Xlhq+yPF0w/8LHXyeHX4V6BS1VG3Utb+mM/qTVfy1Eo+p1KGNlwNDEPsBp6jIaVb5Q== +"@swagger-api/apidom-parser-adapter-openapi-json-3-1@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.11.0.tgz#1c5043a00620235c0b175d03a1da4a17d41294fd" + integrity sha512-fYarNeaz39oKZ6VwqwON+IeJszidZGPvUYDfggLaar81NGimrz07y1U+DhAf96IX3qgUa2J6Fu3Bv1r57hs6Ng== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-1" "^1.10.2" - "@swagger-api/apidom-parser-adapter-json" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-1" "^1.11.0" + "@swagger-api/apidom-parser-adapter-json" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-openapi-json-3-2@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-3-2/-/apidom-parser-adapter-openapi-json-3-2-1.10.2.tgz#ec4ed3b67067a1ba3f48432feb02316a25453dc5" - integrity sha512-bx/kEIXWtpHu+4LEiyNdt0v8ER5EVwPjhQdlpOaC5qghnRH9aUYOTawZtVHsNHAQWTIMNn9DdPKYQgttQKD0Pw== +"@swagger-api/apidom-parser-adapter-openapi-json-3-2@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-json-3-2/-/apidom-parser-adapter-openapi-json-3-2-1.11.0.tgz#29bcb3388b9a452a78a01d2491e5891009755c2d" + integrity sha512-jtMoAH3R73bQUc4D2cJTUUvO4iJz9CV1W4+zoU/gT2l6h8Ji5EhZH0/VyynUk4J6mW/GdwxUN/q5z2P/DtSmfA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-json" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-json" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-openapi-yaml-2@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.10.2.tgz#9156fd645e4c262fb7d40a5a1893c933b9c4e2ff" - integrity sha512-e86JUXHGGEVsO4/xpy/GRSvYXGN30hLt1lMUhjzCFuE95N6/K3hmQHE3rA/H7ot1ajCWUhzukW5rGQac79NIjA== +"@swagger-api/apidom-parser-adapter-openapi-yaml-2@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.11.0.tgz#08a94606d3b636075aacb9af80b5fd25b4b15782" + integrity sha512-e8L4kHahgkOIzCCSGs5jTahXLInERNr37teSLS4SuqYgSVWr9AVXuNvpHNYGeMECD8briGIGfAAtnZChCGYrEA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-openapi-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-openapi-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.10.2.tgz#311050d1aaeae227773c8487f3210acd02b6f209" - integrity sha512-ucfc13Ai31tJ0ruAm1YiHhqENgcBuiOXL00OhoICWA56ggAcnA5WfWmvtsXVMlZsTHVbhZP3XpsH5rui2N8u5w== +"@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.11.0.tgz#55c35ac58764b20890456707c9176ef48f20d741" + integrity sha512-s+AXnNzLeAk28jUAeXwTSR1AlX+TXIAt2GfFgWUAV+SFw2OhRpoKYLzItN3n2UsHselqHvfyUL9xNCJBZleQtQ== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-0" "^1.10.2" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-0" "^1.11.0" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.10.2.tgz#5d50ae20d9dbb4f23edfa2042deb3ec9ea3516e6" - integrity sha512-7o8j93qgf9yYAaaJ/GpH+5sB3fC9EmvmjTCqlw5YWXp+cRgCn9q7f80Sv4+NjbracUafB6qL4i9F/m+Xs0XZaQ== +"@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.11.0.tgz#a6dc3316738f3175d896a832701c349ec416c11a" + integrity sha512-xyUyehHhB+BSOAT7mYGqmcEozuLKxmx1Hug97O9SVgNU8QTClc95+VWrAHhJbn8juPR6y2vSwm/wrQDwb4yq7w== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-1" "^1.10.2" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-1" "^1.11.0" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-openapi-yaml-3-2@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-3-2/-/apidom-parser-adapter-openapi-yaml-3-2-1.10.2.tgz#0b8e12e981cfb2361fb7317342897c7484fc706a" - integrity sha512-blDIeVmo8bpXYV/C+b6PYi54yS+5jPEZTFsK5jQ2NzpCPrkBPacp/KTuHBUBzJsYj4bj/ivRL3+JXGw4YovUHw== +"@swagger-api/apidom-parser-adapter-openapi-yaml-3-2@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-openapi-yaml-3-2/-/apidom-parser-adapter-openapi-yaml-3-2-1.11.0.tgz#bc83e0d8ec0a54c67c8a77109be56c5eef5be169" + integrity sha512-u7Y98zdjEs+0Upa8TdxOsb7z8hYJmLz9lVleRiB7rqysVga6oSDI5NAFdLVqMB6uAUuFi/tyiuiFT4Qosfd6Vw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.11.0" "@types/ramda" "~0.30.0" ramda "~0.30.0" ramda-adjunct "^5.0.0" -"@swagger-api/apidom-parser-adapter-yaml-1-2@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.10.2.tgz#d723a5f2668e5eb4aa0428f4045c3bca157b90c6" - integrity sha512-I5eCls8XS3SVEwH/cuL6T3iar1TPaFYh3gXwS/2rzP1aZQNKSHDP3y3ney7nAomKG4dFvE8Q248FL36arG7T/w== +"@swagger-api/apidom-parser-adapter-yaml-1-2@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.11.0.tgz#6bca1a605127d904bde0419bfd2df880c6051757" + integrity sha512-FZK9KfwiTnNc+imxg7Wu2ktKhXCYPeFQZ1uZJzJL/hk1n+zyPfRY/4Aue4HzDcG8+wbItd3dRjKClFanVZAXoA== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-ast" "^1.10.2" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" + "@swagger-api/apidom-ast" "^1.11.0" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" "@tree-sitter-grammars/tree-sitter-yaml" "=0.7.1" "@types/ramda" "~0.30.0" ramda "~0.30.0" @@ -4185,45 +4233,45 @@ tree-sitter "=0.22.4" web-tree-sitter "=0.24.5" -"@swagger-api/apidom-reference@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@swagger-api/apidom-reference/-/apidom-reference-1.10.2.tgz#82069138540116c35ec782a5395c41ced7b20942" - integrity sha512-H5UqOmae9CXdiLJbbh1j+/hwvcECmr6ci2XtUKTQpFviemvsIDZmPV1DKUAxCfzGr2iOkDO6SZc+/OEWlETqiQ== +"@swagger-api/apidom-reference@^1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@swagger-api/apidom-reference/-/apidom-reference-1.11.0.tgz#9deaff0a93e46058c090946394dbb83975a86a51" + integrity sha512-ftqegYrxxl9UwQFbdVOtXIqNolVd25M5u53X8fP96Wx6lEVr5Ed7B6+dzch8ttCUmKeoLIeagvt76b6BoYtnLw== dependencies: "@babel/runtime-corejs3" "^7.26.10" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" "@types/ramda" "~0.30.0" axios "^1.15.0" minimatch "^10.2.1" ramda "~0.30.0" ramda-adjunct "^5.0.0" optionalDependencies: - "@swagger-api/apidom-json-pointer" "^1.10.2" - "@swagger-api/apidom-ns-arazzo-1" "^1.10.2" - "@swagger-api/apidom-ns-asyncapi-2" "^1.10.2" - "@swagger-api/apidom-ns-openapi-2" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-0" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-1" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-api-design-systems-json" "^1.10.2" - "@swagger-api/apidom-parser-adapter-api-design-systems-yaml" "^1.10.2" - "@swagger-api/apidom-parser-adapter-arazzo-json-1" "^1.10.2" - "@swagger-api/apidom-parser-adapter-arazzo-yaml-1" "^1.10.2" - "@swagger-api/apidom-parser-adapter-asyncapi-json-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-asyncapi-json-3" "^1.10.2" - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-3" "^1.10.2" - "@swagger-api/apidom-parser-adapter-json" "^1.10.2" - "@swagger-api/apidom-parser-adapter-openapi-json-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-openapi-json-3-0" "^1.10.2" - "@swagger-api/apidom-parser-adapter-openapi-json-3-1" "^1.10.2" - "@swagger-api/apidom-parser-adapter-openapi-json-3-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-openapi-yaml-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0" "^1.10.2" - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1" "^1.10.2" - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-2" "^1.10.2" - "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.10.2" + "@swagger-api/apidom-json-pointer" "^1.11.0" + "@swagger-api/apidom-ns-arazzo-1" "^1.11.0" + "@swagger-api/apidom-ns-asyncapi-2" "^1.11.0" + "@swagger-api/apidom-ns-openapi-2" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-0" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-1" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-api-design-systems-json" "^1.11.0" + "@swagger-api/apidom-parser-adapter-api-design-systems-yaml" "^1.11.0" + "@swagger-api/apidom-parser-adapter-arazzo-json-1" "^1.11.0" + "@swagger-api/apidom-parser-adapter-arazzo-yaml-1" "^1.11.0" + "@swagger-api/apidom-parser-adapter-asyncapi-json-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-asyncapi-json-3" "^1.11.0" + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-3" "^1.11.0" + "@swagger-api/apidom-parser-adapter-json" "^1.11.0" + "@swagger-api/apidom-parser-adapter-openapi-json-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-openapi-json-3-0" "^1.11.0" + "@swagger-api/apidom-parser-adapter-openapi-json-3-1" "^1.11.0" + "@swagger-api/apidom-parser-adapter-openapi-json-3-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-openapi-yaml-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0" "^1.11.0" + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1" "^1.11.0" + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-2" "^1.11.0" + "@swagger-api/apidom-parser-adapter-yaml-1-2" "^1.11.0" "@swaggerexpert/cookie@^2.0.2": version "2.0.2" @@ -4239,86 +4287,86 @@ dependencies: apg-lite "^1.0.4" -"@swc/core-darwin-arm64@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.26.tgz#b10c6ef2ddfdb0f9a9d75add77fbcb05a876310e" - integrity sha512-OmcP96CFsNOwa65tamQayRcfqhNlcQ3YCWOq+0Wb+CAM4uB7kOMrXY41Gj4atthxrGhLQ9pg7Vk26iApb88idA== +"@swc/core-darwin-arm64@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.33.tgz#d84134fb80417d41128739f0b9014542e3ed9dd3" + integrity sha512-N+L0uXhuO7FIfzqwgxmzv0zIpV0qEp8wPX3QQs2p4atjMoywup2JTeDlXPw+z9pWJGCae3JjM+tZ6myclI+2gA== -"@swc/core-darwin-x64@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.15.26.tgz#91f81b957a46565b21933554f019b50249514f54" - integrity sha512-liTTTpKSv89ivIxcZ+iU1cRige9Y7JkOjVnJ2Ystzl+DsWNHqt7wLTTgm/u7gEqmmAS2JKryODLQn3q1UtFNPQ== +"@swc/core-darwin-x64@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.15.33.tgz#0badb9834071f1c6005986571d4a96359c1d7cd0" + integrity sha512-/Il4QHSOhV4FekbsDtkrNmKbsX26oSysvgrRswa/RYOHXAkwXDbB4jaeKq6PsJLSPkzJ2KzQ061gtBnk0vNHfA== -"@swc/core-linux-arm-gnueabihf@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.26.tgz#81a05689a7a2464fce1a558999ca049f682ede87" - integrity sha512-Y/g+m3I8CeBof5A3kWWOS6QA2HOIUytF5EeTgfwcAK+GKT/tGe7Xqo5svBtaqflU5od2zzbMTWqkinPXgRWGgA== +"@swc/core-linux-arm-gnueabihf@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.33.tgz#b7577a825b59d98b6a9a5c991d842046efe1c34a" + integrity sha512-C64hBnBxq4viOPQ8hlx+2lJ23bzZBGnjw7ryALmS+0Q3zHmwO8lw1/DArLENw4Q18/0w5wdEO1k3m1wWNtKGqQ== -"@swc/core-linux-arm64-gnu@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.26.tgz#ce32870841e85a8d5fa8d4dd8ad0b501aa641348" - integrity sha512-19IvwyPfBN/rz9s7qXhOTQmW0922+pjpRUUvIebu+CMM75nX6YuDzHsGx8hSmn5dS89SNaMCh1lgUuXqm++6jg== +"@swc/core-linux-arm64-gnu@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.33.tgz#304c48321494a18c67b2913c273b08674ee70d8c" + integrity sha512-TRJfnJbX3jqpxRDRoieMzRiCBS5jOmXNb3iQXmcgjFEHKLnAgK1RZRU8Cq1MsPqO4jAJp/ld1G4O3fXuxv85uw== -"@swc/core-linux-arm64-musl@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.26.tgz#6c4e5c5cdbe18718fe998c80b9432367d9a08d10" - integrity sha512-iNlbvTIo425rkKzDLLWFJGnFXr3myETUdIDHcjuiPNZE8b0ogmcAuilC4yEJX7FSHGbnlsoJcCT2xf4b3VJmmQ== +"@swc/core-linux-arm64-musl@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.33.tgz#d116cbc04ccb4f4ee810da6bca79d4423605dbcd" + integrity sha512-il7tYM+CpUNzieQbwAjFT1P8zqAhmGWNAGhQZBnxurXZ0aNn+5nqYFTEUKNZl7QibtT0uQXzTZrNGHCIj6Y1Og== -"@swc/core-linux-ppc64-gnu@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.26.tgz#60db5a6a5b780dd7bfba8ae58f3f58af621858cb" - integrity sha512-AuuEOtG+YXKIjIUup4RsxYNklx6XVB3WKWfhxG6hnfPrn7vp89RNOLbbyyprgj6Sk7k9ulwGVTJElEvmBNPSCA== +"@swc/core-linux-ppc64-gnu@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.33.tgz#f5354dba36db9414305bab344c817d57b8b457c2" + integrity sha512-ZtNBwN0Z7CFj9Il0FcPaKdjgP7URyKu/3RfH46vq+0paOBqLj4NYldD6Qo//Duif/7IOtAraUfDOmp0PLAufog== -"@swc/core-linux-s390x-gnu@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.26.tgz#7e942cecb219b2aec132fd84b2e2d6cc337d9cb9" - integrity sha512-JcMDWQvW1BchUyRg8E0jHiTx7CQYpUr5uDEL1dnPDECrEjBEGG2ynmJ3XX70sWXql0JagqR1t3VpANYFWdUnqA== +"@swc/core-linux-s390x-gnu@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.33.tgz#016df9f4c9d7fd65b85ca9c558c5aec341f06da0" + integrity sha512-De1IyajoOmhOYYjw/lx66bKlyDpHZTueqwpDrWgf5O7T6d1ODeJJO9/OqMBmrBQc5C+dNnlmIufHsp4QVCWufA== -"@swc/core-linux-x64-gnu@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.26.tgz#cb8774fa36ecbea1988dc42757360db55e0d3374" - integrity sha512-FW7V7Mbpq4+PA7BiAq76LJs8MdNuUSylyuRVfQRkhIyeWadFroZ+KOPgjku8Z/fXzngxBRvsk+PGGB0t8mGcjA== +"@swc/core-linux-x64-gnu@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.33.tgz#49f36558ede072e71999aa37f123367daed2a662" + integrity sha512-mGTH0YxmUN+x6vRN/I6NOk5X0ogNktkwPnJ94IMvR7QjhRDwL0O8RXEDhyUM0YtwWrryBOqaJQBX4zruxEPRGw== -"@swc/core-linux-x64-musl@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.26.tgz#fad8549f4b89277d11dafe507493e5525c6e85b5" - integrity sha512-w8erqMHsVcdGwUfJxF6LaiTuPoKnyLOcUbhLcxiXrlLt5MLjtlgcIeUY/NWK/oPoyqkgH+/i8pOJnMTxvl83ZQ== +"@swc/core-linux-x64-musl@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.33.tgz#b096665f5cfeee2612325f301da5c1590b10d8f3" + integrity sha512-hj628ZkSEJf6zMf5VMbYrG2O6QqyTIp2qwY6VlCjvIa9lAEZ5c2lfPblCLVGYubTeLJDxadLB/CxqQYOQABeEQ== -"@swc/core-win32-arm64-msvc@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.26.tgz#b41d975fd3df8f82a38362cfa86b3de1d654d5a0" - integrity sha512-uDCWCNpUiqkbvPmsuPUTn/P7ag9SqNXD2JT/W3dUu7yZ2krzN+nmmoQ2xRX63/J6RYiHI7aT4jo7Z++lsljlPA== +"@swc/core-win32-arm64-msvc@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.33.tgz#f3101263a0dbaa173ec47638c9719d0b89838bd2" + integrity sha512-GV2oohtN2/5+KSccl86VULu3aT+LrISC8uzgSq0FRnikpD+Zwc+sBlXmoKQ+Db6jI57ITUOIB8jRkdGMABC29g== -"@swc/core-win32-ia32-msvc@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.26.tgz#dadf3200ebb79e32fce204f0922f0eec7ebc958d" - integrity sha512-2k1ax1QmmqLEnpC0uRCw7OXhBfyvdPqERBXupDasjYbChT6ZSO/uha28Bp38cw0viKIG79L27aTDkbkABsMW3w== +"@swc/core-win32-ia32-msvc@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.33.tgz#eb981ef5613d42c9220559bdb0c8bc58cf6c3eb9" + integrity sha512-gtyvzSNR8DHKfFEA2uqb8Ld1myqi6uEg2jyeUq3ikn5ytYs7H8RpZYC8mdy4NXr8hfcdJfCLXPlYaqqfBXpoEQ== -"@swc/core-win32-x64-msvc@1.15.26": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.26.tgz#5aa0fe6533226e2e2f103ea81a2b1cc6fa3f60f5" - integrity sha512-aUuYecSEGa4SUSdyCWaI/vk8jdseifYnsF1GZQx2+piL8GIuT/5QrVcFfmes4Iwy7FIVXxtzD063z/FfpZ7K7w== +"@swc/core-win32-x64-msvc@1.15.33": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.33.tgz#a2fed9956933027ceb368857bac4bb4ee203d47c" + integrity sha512-d6fRqQSkJI+kmMEBWaDQ7TMl8+YjLYbwRUPZQ9DY0ORBJeTzOrG0twvfvlZ2xgw6jA0ScQKgfBm4vHLSLl5Hqg== -"@swc/core@^1.15.26", "@swc/core@^1.7.39": - version "1.15.26" - resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.15.26.tgz#347cdd3c49ab2fd02468ea569e6975ccb990bd67" - integrity sha512-tglZGyx8N5PC+x1Nd/JrZxqpqlcZoSuG9gTDKO6AuFToFiVB3uS8HvbKFuO7g3lJzvFf9riAb94xs9HU2UhAHQ== +"@swc/core@^1.15.33", "@swc/core@^1.7.39": + version "1.15.33" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.15.33.tgz#2a6571c8aca961925f14beae52b3f43c18370fc6" + integrity sha512-jOlwnFV2xhuuZeAUILGFULeR6vDPfijEJ57evfocwznQldLU3w2cZ9bSDryY9ip+AsM3r1NJKzf47V2NXebkeQ== dependencies: "@swc/counter" "^0.1.3" "@swc/types" "^0.1.26" optionalDependencies: - "@swc/core-darwin-arm64" "1.15.26" - "@swc/core-darwin-x64" "1.15.26" - "@swc/core-linux-arm-gnueabihf" "1.15.26" - "@swc/core-linux-arm64-gnu" "1.15.26" - "@swc/core-linux-arm64-musl" "1.15.26" - "@swc/core-linux-ppc64-gnu" "1.15.26" - "@swc/core-linux-s390x-gnu" "1.15.26" - "@swc/core-linux-x64-gnu" "1.15.26" - "@swc/core-linux-x64-musl" "1.15.26" - "@swc/core-win32-arm64-msvc" "1.15.26" - "@swc/core-win32-ia32-msvc" "1.15.26" - "@swc/core-win32-x64-msvc" "1.15.26" + "@swc/core-darwin-arm64" "1.15.33" + "@swc/core-darwin-x64" "1.15.33" + "@swc/core-linux-arm-gnueabihf" "1.15.33" + "@swc/core-linux-arm64-gnu" "1.15.33" + "@swc/core-linux-arm64-musl" "1.15.33" + "@swc/core-linux-ppc64-gnu" "1.15.33" + "@swc/core-linux-s390x-gnu" "1.15.33" + "@swc/core-linux-x64-gnu" "1.15.33" + "@swc/core-linux-x64-musl" "1.15.33" + "@swc/core-win32-arm64-msvc" "1.15.33" + "@swc/core-win32-ia32-msvc" "1.15.33" + "@swc/core-win32-x64-msvc" "1.15.33" "@swc/counter@^0.1.3": version "0.1.3" @@ -5040,100 +5088,100 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@8.58.2", "@typescript-eslint/eslint-plugin@^8.52.0": - version "8.58.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.2.tgz#a6882a6a328e1259cff259fdb03184245ef06191" - integrity sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw== +"@typescript-eslint/eslint-plugin@8.59.2", "@typescript-eslint/eslint-plugin@^8.52.0": + version "8.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.2.tgz#f37b2c189a0177141fe3de3b08f2a83991bfdbfa" + integrity sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ== dependencies: "@eslint-community/regexpp" "^4.12.2" - "@typescript-eslint/scope-manager" "8.58.2" - "@typescript-eslint/type-utils" "8.58.2" - "@typescript-eslint/utils" "8.58.2" - "@typescript-eslint/visitor-keys" "8.58.2" + "@typescript-eslint/scope-manager" "8.59.2" + "@typescript-eslint/type-utils" "8.59.2" + "@typescript-eslint/utils" "8.59.2" + "@typescript-eslint/visitor-keys" "8.59.2" ignore "^7.0.5" natural-compare "^1.4.0" ts-api-utils "^2.5.0" -"@typescript-eslint/parser@8.58.2", "@typescript-eslint/parser@^8.56.1": - version "8.58.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.58.2.tgz#b267545e4bd515d896fe1f3a5b6f334fa6aa0026" - integrity sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg== +"@typescript-eslint/parser@8.59.2", "@typescript-eslint/parser@^8.59.0": + version "8.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.59.2.tgz#e2fd0084baa5dd0c24cd789af1c72cbc3a7a1c62" + integrity sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ== dependencies: - "@typescript-eslint/scope-manager" "8.58.2" - "@typescript-eslint/types" "8.58.2" - "@typescript-eslint/typescript-estree" "8.58.2" - "@typescript-eslint/visitor-keys" "8.58.2" + "@typescript-eslint/scope-manager" "8.59.2" + "@typescript-eslint/types" "8.59.2" + "@typescript-eslint/typescript-estree" "8.59.2" + "@typescript-eslint/visitor-keys" "8.59.2" debug "^4.4.3" -"@typescript-eslint/project-service@8.58.2": - version "8.58.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.58.2.tgz#8c980249100e21b87baba0ca10880fdf893e0a8e" - integrity sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg== +"@typescript-eslint/project-service@8.59.2": + version "8.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.59.2.tgz#f8b8cbf8692e3a51c2c394acf8cf6900f7e755af" + integrity sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw== dependencies: - "@typescript-eslint/tsconfig-utils" "^8.58.2" - "@typescript-eslint/types" "^8.58.2" + "@typescript-eslint/tsconfig-utils" "^8.59.2" + "@typescript-eslint/types" "^8.59.2" debug "^4.4.3" -"@typescript-eslint/scope-manager@8.58.2": - version "8.58.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.58.2.tgz#aa73784d78f117940e83f71705af07ba695cd60c" - integrity sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q== +"@typescript-eslint/scope-manager@8.59.2": + version "8.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.59.2.tgz#63cbd0af2e3180949d6be81122cc555bc71e736d" + integrity sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg== dependencies: - "@typescript-eslint/types" "8.58.2" - "@typescript-eslint/visitor-keys" "8.58.2" + "@typescript-eslint/types" "8.59.2" + "@typescript-eslint/visitor-keys" "8.59.2" -"@typescript-eslint/tsconfig-utils@8.58.2", "@typescript-eslint/tsconfig-utils@^8.58.2": - version "8.58.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.2.tgz#fa13f96432c9348bf87f6f44826def585fad7bca" - integrity sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A== +"@typescript-eslint/tsconfig-utils@8.59.2", "@typescript-eslint/tsconfig-utils@^8.59.2": + version "8.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.2.tgz#6e92bc412083753185a79c9f1431e78169d9232f" + integrity sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw== -"@typescript-eslint/type-utils@8.58.2": - version "8.58.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.58.2.tgz#024eb1dd597f8a34cb22d8d9ab32da857bc9a817" - integrity sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg== +"@typescript-eslint/type-utils@8.59.2": + version "8.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.59.2.tgz#a60a1192a804fa472a92c41656853ac6a9ba7176" + integrity sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ== dependencies: - "@typescript-eslint/types" "8.58.2" - "@typescript-eslint/typescript-estree" "8.58.2" - "@typescript-eslint/utils" "8.58.2" + "@typescript-eslint/types" "8.59.2" + "@typescript-eslint/typescript-estree" "8.59.2" + "@typescript-eslint/utils" "8.59.2" debug "^4.4.3" ts-api-utils "^2.5.0" -"@typescript-eslint/types@8.58.2", "@typescript-eslint/types@^8.58.2": - version "8.58.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.58.2.tgz#3ab8051de0f19a46ddefb0749d0f7d82974bd57c" - integrity sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ== +"@typescript-eslint/types@8.59.2", "@typescript-eslint/types@^8.59.2": + version "8.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.59.2.tgz#01caabcd7e4715c33ad5e11cab260829714d6b9c" + integrity sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q== -"@typescript-eslint/typescript-estree@8.58.2": - version "8.58.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.2.tgz#b1beb1f959385b341cc76f0aebbf028e23dfdb8b" - integrity sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw== +"@typescript-eslint/typescript-estree@8.59.2": + version "8.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz#6a217ef65b18dbd12c718fc86a675d1d7a1414cc" + integrity sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg== dependencies: - "@typescript-eslint/project-service" "8.58.2" - "@typescript-eslint/tsconfig-utils" "8.58.2" - "@typescript-eslint/types" "8.58.2" - "@typescript-eslint/visitor-keys" "8.58.2" + "@typescript-eslint/project-service" "8.59.2" + "@typescript-eslint/tsconfig-utils" "8.59.2" + "@typescript-eslint/types" "8.59.2" + "@typescript-eslint/visitor-keys" "8.59.2" debug "^4.4.3" minimatch "^10.2.2" semver "^7.7.3" tinyglobby "^0.2.15" ts-api-utils "^2.5.0" -"@typescript-eslint/utils@8.58.2": - version "8.58.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.58.2.tgz#27165554a02d1ff57d98262fa92060498dabc8b3" - integrity sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA== +"@typescript-eslint/utils@8.59.2": + version "8.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.59.2.tgz#ff619a6a3075f4017fa91b8610b752a8ca3366aa" + integrity sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q== dependencies: "@eslint-community/eslint-utils" "^4.9.1" - "@typescript-eslint/scope-manager" "8.58.2" - "@typescript-eslint/types" "8.58.2" - "@typescript-eslint/typescript-estree" "8.58.2" + "@typescript-eslint/scope-manager" "8.59.2" + "@typescript-eslint/types" "8.59.2" + "@typescript-eslint/typescript-estree" "8.59.2" -"@typescript-eslint/visitor-keys@8.58.2": - version "8.58.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.2.tgz#9ed699eaa9b5720b6b6b6f9c16e6c7d4cd32b276" - integrity sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA== +"@typescript-eslint/visitor-keys@8.59.2": + version "8.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.2.tgz#5ccc486913cd347883d69158836b1189a660bfe6" + integrity sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA== dependencies: - "@typescript-eslint/types" "8.58.2" + "@typescript-eslint/types" "8.59.2" eslint-visitor-keys "^5.0.0" "@ungap/structured-clone@^1.0.0": @@ -5482,10 +5530,10 @@ ansis@^3.2.0: resolved "https://registry.yarnpkg.com/ansis/-/ansis-3.17.0.tgz#fa8d9c2a93fe7d1177e0c17f9eeb562a58a832d7" integrity sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg== -antd@^6.3.5: - version "6.3.5" - resolved "https://registry.yarnpkg.com/antd/-/antd-6.3.5.tgz#3f231e25306c4213925d6476ef9c2ec21cf53b7e" - integrity sha512-8BPz9lpZWQm42PTx7yL4KxWAotVuqINiKcoYRcLtdd5BFmAcAZicVyFTnBJyRDlzGZFZeRW3foGu6jXYFnej6Q== +antd@^6.3.7: + version "6.3.7" + resolved "https://registry.yarnpkg.com/antd/-/antd-6.3.7.tgz#620354ec04135356cbc5ce0a666871ddc73e4117" + integrity sha512-WTHi4bHVNKpYXLHESzU0Tts7rRNQeL84Bph9dfI3Qw7mHbTulExDcYKNHny5CTXcrBBOpraXbU9miBAwUR5vaw== dependencies: "@ant-design/colors" "^8.0.1" "@ant-design/cssinjs" "^2.1.2" @@ -5501,8 +5549,8 @@ antd@^6.3.5: "@rc-component/dialog" "~1.8.4" "@rc-component/drawer" "~1.4.2" "@rc-component/dropdown" "~1.0.2" - "@rc-component/form" "~1.8.0" - "@rc-component/image" "~1.8.0" + "@rc-component/form" "~1.8.1" + "@rc-component/image" "~1.9.0" "@rc-component/input" "~1.1.2" "@rc-component/input-number" "~1.6.2" "@rc-component/mentions" "~1.6.0" @@ -5530,7 +5578,7 @@ antd@^6.3.5: "@rc-component/tree-select" "~1.8.0" "@rc-component/trigger" "^3.9.0" "@rc-component/upload" "~1.1.0" - "@rc-component/util" "^1.10.0" + "@rc-component/util" "^1.10.1" clsx "^2.1.1" dayjs "^1.11.11" scroll-into-view-if-needed "^3.1.0" @@ -5794,10 +5842,10 @@ base64-js@^1.3.1, base64-js@^1.5.1: resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -baseline-browser-mapping@^2.10.19, baseline-browser-mapping@^2.9.0, baseline-browser-mapping@^2.9.19: - version "2.10.19" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.19.tgz#7697721c22f94f66195d0c34299b1a91e3299493" - integrity sha512-qCkNLi2sfBOn8XhZQ0FXsT1Ki/Yo5P90hrkRamVFRS7/KV9hpfA4HkoWNU152+8w0zPjnxo5psx5NL3PSGgv5g== +baseline-browser-mapping@^2.10.29, baseline-browser-mapping@^2.9.0, baseline-browser-mapping@^2.9.19: + version "2.10.29" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz#47bdc13027af28d341f367a4f35a07ce872e27b4" + integrity sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ== batch@0.6.1: version "0.6.1" @@ -6035,10 +6083,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001759, caniuse-lite@^1.0.30001788: - version "1.0.30001788" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz#31e97d1bfec332b3f2d7eea7781460c97629b3bf" - integrity sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001759, caniuse-lite@^1.0.30001792: + version "1.0.30001792" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz#ca8bb9be244835a335e2018272ce7223691873c5" + integrity sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw== ccount@^2.0.0: version "2.0.1" @@ -6062,12 +6110,7 @@ chalk@^4.0.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^5.0.1, chalk@^5.2.0: - version "5.6.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz" - integrity sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ== - -chalk@^5.6.2: +chalk@^5.0.1, chalk@^5.2.0, chalk@^5.6.2: version "5.6.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== @@ -7305,10 +7348,10 @@ doctrine@^2.1.0: dependencies: esutils "^2.0.2" -docusaurus-plugin-openapi-docs@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/docusaurus-plugin-openapi-docs/-/docusaurus-plugin-openapi-docs-5.0.1.tgz#2fe62b58fc1af11e3d947edc2f0d60e04f1aa149" - integrity sha512-OVfoDovRdiS78DQYWmr2BjuOF2A6kVmJ43mgkQaAEZxASyHbUft4zUIhvfa7gqema6KNL9pVKejDievZdZ3wGQ== +docusaurus-plugin-openapi-docs@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/docusaurus-plugin-openapi-docs/-/docusaurus-plugin-openapi-docs-5.0.2.tgz#f00028621deb9179065fe7d6a541256692ef941b" + integrity sha512-WCC2m6PpylXZfNga+ScelTG0a7jUGtbB9+AmbR9lUj93FPryTs8VHTMJ3fKtO0senJTWgOU3MDvZw0v+mE3ztA== dependencies: "@apidevtools/json-schema-ref-parser" "^15.3.3" "@redocly/openapi-core" "^2.25.2" @@ -7326,10 +7369,10 @@ docusaurus-plugin-openapi-docs@^5.0.1: swagger2openapi "^7.0.8" xml-formatter "^3.6.6" -docusaurus-theme-openapi-docs@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/docusaurus-theme-openapi-docs/-/docusaurus-theme-openapi-docs-5.0.1.tgz#a2c2c91346b6238f6d7862752cdb02611fb5396f" - integrity sha512-bVeb7hOqog9LKVrJzYXdNJ7/0N22lk0VE22QK+naAn5GuAvYo41JmpXW9hqLIPkEp2UbexTHoPW9SYVdUsyvvw== +docusaurus-theme-openapi-docs@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/docusaurus-theme-openapi-docs/-/docusaurus-theme-openapi-docs-5.0.2.tgz#2ab6f6b04fc2e494e24971d31432a9187c84a2fe" + integrity sha512-BD6WhbunR6kXqtoUUDlhxO4HlCNM2nYENGr/TbiTEknkgXYKQz+FEIhY4Hyz5GSLpuhPih0CDuNl7Xkfpcz0Yw== dependencies: "@hookform/error-message" "^2.0.1" "@reduxjs/toolkit" "^2.8.2" @@ -7404,10 +7447,10 @@ domhandler@^5.0.2, domhandler@^5.0.3: dependencies: domelementtype "^2.3.0" -dompurify@^3.2.5, dompurify@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.0.tgz#b1fc33ebdadb373241621e0a30e4ad81573dfd0b" - integrity sha512-nolgK9JcaUXMSmW+j1yaSvaEaoXYHwWyGJlkoCTghc97KgGDDSnpoU/PlEnw63Ah+TGKFOyY+X5LnxaWbCSfXg== +dompurify@^3.2.5, dompurify@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.1.tgz#521d04483ac12631b2aedf434a5f5390933b8789" + integrity sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw== optionalDependencies: "@types/trusted-types" "^2.0.7" @@ -8123,9 +8166,9 @@ fast-safe-stringify@^2.0.7: integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== fast-uri@^3.0.1: - version "3.0.6" - resolved "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz" - integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.2.tgz#8af3d4fc9d3e71b11572cc2673b514a7d1a8c8ec" + integrity sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ== fastq@^1.6.0: version "1.19.1" @@ -8474,10 +8517,10 @@ globals@^15.14.0: resolved "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz" integrity sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg== -globals@^17.4.0: - version "17.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-17.4.0.tgz#33d7d297ed1536b388a0e2f4bcd0ff19c8ff91b5" - integrity sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw== +globals@^17.6.0: + version "17.6.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-17.6.0.tgz#0f0be018d5cca8690e6375ead1f65c4bb96191fc" + integrity sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA== globalthis@^1.0.4: version "1.0.4" @@ -12428,9 +12471,9 @@ postcss-zindex@^6.0.2: integrity sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg== postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.33, postcss@^8.5.4: - version "8.5.6" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz" - integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== + version "8.5.10" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.10.tgz#8992d8c30acf3f12169e7c09514a12fed7e48356" + integrity sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ== dependencies: nanoid "^3.3.11" picocolors "^1.1.1" @@ -13328,7 +13371,7 @@ renderkid@^3.0.0: repeat-string@^1.5.2: version "1.6.1" - resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== require-directory@^2.1.1: @@ -14333,19 +14376,19 @@ svgo@^3.0.2, svgo@^3.2.0: picocolors "^1.0.0" sax "^1.5.0" -swagger-client@^3.37.2: - version "3.37.2" - resolved "https://registry.yarnpkg.com/swagger-client/-/swagger-client-3.37.2.tgz#19d15564b2c77c9200a3ee2b8a913e2bd2e4a596" - integrity sha512-KcB8psL1On4GWwv9Ribp1oteh50ygNnAyvQbd5MwiXMGkcB4f53rkZEdvZKPDdJO764mQjgErxQEGDVw6QBUMQ== +swagger-client@^3.37.3: + version "3.37.3" + resolved "https://registry.yarnpkg.com/swagger-client/-/swagger-client-3.37.3.tgz#dbe3f0d22c367d4bc04cc7ddaf5224e116d46074" + integrity sha512-PZv5smQPnPwfP6mnkq96fOp/RNDKBqd8vfwE4UuwA229wsesj20yd7RadXx+9uLBC3c0H6cu/H+bnbMTWG6oUQ== dependencies: "@babel/runtime-corejs3" "^7.22.15" "@scarf/scarf" "=1.4.0" - "@swagger-api/apidom-core" "^1.10.2" - "@swagger-api/apidom-error" "^1.10.2" - "@swagger-api/apidom-json-pointer" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-1" "^1.10.2" - "@swagger-api/apidom-ns-openapi-3-2" "^1.10.2" - "@swagger-api/apidom-reference" "^1.10.2" + "@swagger-api/apidom-core" "^1.11.0" + "@swagger-api/apidom-error" "^1.11.0" + "@swagger-api/apidom-json-pointer" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-1" "^1.11.0" + "@swagger-api/apidom-ns-openapi-3-2" "^1.11.0" + "@swagger-api/apidom-reference" "^1.11.0" "@swaggerexpert/cookie" "^2.0.2" deepmerge "~4.3.0" fast-json-patch "^3.0.0-1" @@ -14358,10 +14401,10 @@ swagger-client@^3.37.2: ramda "^0.30.1" ramda-adjunct "^5.1.0" -swagger-ui-react@^5.32.4: - version "5.32.4" - resolved "https://registry.yarnpkg.com/swagger-ui-react/-/swagger-ui-react-5.32.4.tgz#783b22213c4e826618b1470fd8ae9e68a2587c7d" - integrity sha512-OsTqKCiDT/o8/oqZbt+p1djPkrOk3unKK/7+wGvP1+WY6pOzFoDLM4D39cNFtpIArtlg9uoK6MKIz3W00WX8qw== +swagger-ui-react@^5.32.5: + version "5.32.5" + resolved "https://registry.yarnpkg.com/swagger-ui-react/-/swagger-ui-react-5.32.5.tgz#c4650972c71aaf4107a5f742e9c45615eba6857f" + integrity sha512-u86Qx36C5FvmJFVGMF3s62dxR3l0EfUmlylJVqCJ4vL0tvfd38kNdCQan9app6Y+C25uqVAjGLYu2w87UMD35Q== dependencies: "@babel/runtime-corejs3" "^7.27.1" "@scarf/scarf" "=1.4.0" @@ -14370,7 +14413,7 @@ swagger-ui-react@^5.32.4: classnames "^2.5.1" css.escape "1.5.1" deep-extend "0.6.0" - dompurify "^3.3.2" + dompurify "^3.4.0" ieee754 "^1.2.1" immutable "^3.x.x" js-file-download "^0.4.12" @@ -14392,7 +14435,7 @@ swagger-ui-react@^5.32.4: reselect "^5.1.1" serialize-error "^8.1.0" sha.js "^2.4.12" - swagger-client "^3.37.2" + swagger-client "^3.37.3" url-parse "^1.5.10" xml "=1.0.1" xml-but-prettier "^1.0.1" @@ -14720,20 +14763,20 @@ types-ramda@^0.30.1: dependencies: ts-toolbelt "^9.6.0" -typescript-eslint@^8.58.2: - version "8.58.2" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.58.2.tgz#55f425fc668c2d5148f45587f2cd04532d715c6a" - integrity sha512-V8iSng9mRbdZjl54VJ9NKr6ZB+dW0J3TzRXRGcSbLIej9jV86ZRtlYeTKDR/QLxXykocJ5icNzbsl2+5TzIvcQ== +typescript-eslint@^8.59.2: + version "8.59.2" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.59.2.tgz#e24b4f7232e20112e40572dba162a829a738ce98" + integrity sha512-pJw051uomb3ZeCzGTpRb8RbEqB5Y4WWet8gl/GcTlU35BSx0PVdZ86/bqkQCyKKuraVQEK7r6kBHQXF+fBhkoQ== dependencies: - "@typescript-eslint/eslint-plugin" "8.58.2" - "@typescript-eslint/parser" "8.58.2" - "@typescript-eslint/typescript-estree" "8.58.2" - "@typescript-eslint/utils" "8.58.2" + "@typescript-eslint/eslint-plugin" "8.59.2" + "@typescript-eslint/parser" "8.59.2" + "@typescript-eslint/typescript-estree" "8.59.2" + "@typescript-eslint/utils" "8.59.2" -typescript@~5.9.3: - version "5.9.3" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz" - integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== +typescript@~6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-6.0.3.tgz#90251dc007916e972786cb94d74d15b185577d21" + integrity sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw== ufo@^1.5.4: version "1.6.1" @@ -15368,7 +15411,7 @@ webpack@^5.106.2, webpack@^5.88.1, webpack@^5.95.0: watchpack "^2.5.1" webpack-sources "^3.3.4" -webpackbar@^6.0.1, webpackbar@^7.0.0: +webpackbar@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-7.0.0.tgz#7228d32881af2392381b6514499ddea73cdf218a" integrity sha512-aS9soqSO2iCHgqHoCrj4LbfGQUboDCYJPSFOAchEK+9psIjNrfSWW4Y0YEz67MKURNvMmfo0ycOg9d/+OOf9/Q== diff --git a/helm/superset/Chart.yaml b/helm/superset/Chart.yaml index 5ef4fb2e00f..8ed79ee8bb1 100644 --- a/helm/superset/Chart.yaml +++ b/helm/superset/Chart.yaml @@ -29,7 +29,7 @@ maintainers: - name: craig-rueda email: craig@craigrueda.com url: https://github.com/craig-rueda -version: 0.15.4 # See [README](https://github.com/apache/superset/blob/master/helm/superset/README.md#versioning) for version details. +version: 0.15.5 # See [README](https://github.com/apache/superset/blob/master/helm/superset/README.md#versioning) for version details. dependencies: - name: postgresql version: 16.7.27 diff --git a/helm/superset/README.md b/helm/superset/README.md index 29dbdeea8a6..53077bd338f 100644 --- a/helm/superset/README.md +++ b/helm/superset/README.md @@ -23,7 +23,7 @@ NOTE: This file is generated by helm-docs: https://github.com/norwoodj/helm-docs # superset -![Version: 0.15.4](https://img.shields.io/badge/Version-0.15.4-informational?style=flat-square) +![Version: 0.15.5](https://img.shields.io/badge/Version-0.15.5-informational?style=flat-square) Apache Superset is a modern, enterprise-ready business intelligence web application diff --git a/helm/superset/values.yaml b/helm/superset/values.yaml index fdcc7abccd8..fc5124004f7 100644 --- a/helm/superset/values.yaml +++ b/helm/superset/values.yaml @@ -844,6 +844,8 @@ postgresql: database: superset image: + registry: docker.io + repository: bitnamilegacy/postgresql tag: "14.17.0-debian-12-r3" ## PostgreSQL Primary parameters @@ -918,6 +920,11 @@ redis: accessModes: - ReadWriteOnce + image: + registry: docker.io + repository: bitnamilegacy/redis + tag: 7.0.10-debian-11-r4 + nodeSelector: {} tolerations: [] diff --git a/pyproject.toml b/pyproject.toml index 03e197e3b48..6a388f9afbf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,13 +70,13 @@ dependencies = [ # marshmallow>=4 has issues: https://github.com/apache/superset/issues/33162 "marshmallow>=3.0, <4", "marshmallow-union>=0.1", - "msgpack>=1.0.0, <1.1", - "nh3>=0.2.11, <0.3", + "msgpack>=1.0.0, <1.2", + "nh3>=0.2.11, <0.4", "numpy>1.23.5, <2.3", "packaging", # -------------------------- # pandas and related (wanting pandas[performance] without numba as it's 100+MB and not needed) - "pandas[excel]>=2.1.4, <2.2", + "pandas[excel]>=2.1.4, <2.4", "bottleneck", # recommended performance dependency for pandas, see https://pandas.pydata.org/docs/getting_started/install.html#performance-dependencies-recommended # -------------------------- "parsedatetime", @@ -89,12 +89,13 @@ dependencies = [ "python-dateutil", "python-dotenv", # optional dependencies for Flask but required for Superset, see https://flask.palletsprojects.com/en/stable/installation/#optional-dependencies "pygeohash", - "pyarrow>=16.1.0, <19", # before upgrading pyarrow, check that all db dependencies support this, see e.g. https://github.com/apache/superset/pull/34693 + "pyarrow>=16.1.0, <21", # before upgrading pyarrow, check that all db dependencies support this, see e.g. https://github.com/apache/superset/pull/34693 "pyyaml>=6.0.0, <7.0.0", "PyJWT>=2.4.0, <3.0", "redis>=5.0.0, <6.0", + "rison>=2.0.0, <3.0", "selenium>=4.14.0, <5.0", - "shillelagh[gsheetsapi]>=1.4.3, <2.0", + "shillelagh[gsheetsapi]>=1.4.4, <2.0", "sshtunnel>=0.4.0, <0.5", "simplejson>=3.15.0", "slack_sdk>=3.19.0, <4", @@ -108,12 +109,12 @@ dependencies = [ "watchdog>=6.0.0", "wtforms>=2.3.3, <4", "wtforms-json", - "xlsxwriter>=3.0.7, <3.1", + "xlsxwriter>=3.0.7, <3.3", ] [project.optional-dependencies] -athena = ["pyathena[pandas]>=2, <3"] +athena = ["pyathena[pandas]>=2, <4"] aurora-data-api = ["preset-sqlalchemy-aurora-data-api>=0.2.8,<0.3"] bigquery = [ "pandas-gbq>=0.19.1", @@ -130,25 +131,31 @@ d1 = [ ] databend = ["databend-sqlalchemy>=0.3.2, <1.0"] databricks = [ - "databricks-sql-connector==4.1.2", + "databricks-sql-connector==4.2.6", "databricks-sqlalchemy==1.0.5", ] -db2 = ["ibm-db-sa>0.3.8, <=0.4.0"] -denodo = ["denodo-sqlalchemy~=1.0.6"] +db2 = ["ibm-db-sa>0.3.8, <=0.4.4"] +denodo = ["denodo-sqlalchemy>=1.0.6,<2.1.0"] dremio = ["sqlalchemy-dremio>=1.2.1, <4"] drill = ["sqlalchemy-drill>=1.1.4, <2"] druid = ["pydruid>=0.6.5,<0.7"] duckdb = ["duckdb>=1.4.2,<2", "duckdb-engine>=0.17.0"] dynamodb = ["pydynamodb>=0.4.2"] solr = ["sqlalchemy-solr >= 0.2.0"] -elasticsearch = ["elasticsearch-dbapi>=0.2.12, <0.3.0"] +elasticsearch = ["elasticsearch-dbapi>=0.2.13, <0.3.0"] exasol = ["sqlalchemy-exasol >= 2.4.0, <3.0"] excel = ["xlrd>=1.2.0, <1.3"] -fastmcp = ["fastmcp>=3.1.0,<4.0"] -firebird = ["sqlalchemy-firebird>=0.7.0, <0.8"] +fastmcp = [ + "fastmcp>=3.2.4,<4.0", + # tiktoken backs the response-size-guard token estimator. Without + # it, the middleware falls back to a coarser character-based + # heuristic that under-counts JSON-heavy MCP responses. + "tiktoken>=0.7.0,<1.0", +] +firebird = ["sqlalchemy-firebird>=0.7.0, <2.2"] firebolt = ["firebolt-sqlalchemy>=1.0.0, <2"] gevent = ["gevent>=23.9.1"] -gsheets = ["shillelagh[gsheetsapi]>=1.4.3, <2"] +gsheets = ["shillelagh[gsheetsapi]>=1.4.4, <2"] hana = ["hdbcli==2.4.162", "sqlalchemy_hana==0.4.0"] hive = [ "pyhive[hive]>=0.6.5;python_version<'3.11'", @@ -157,7 +164,7 @@ hive = [ "thrift>=0.14.1, <1.0.0", "thrift_sasl>=0.4.3, < 1.0.0", ] -impala = ["impyla>0.16.2, <0.17"] +impala = ["impyla>0.16.2, <0.23"] kusto = ["sqlalchemy-kusto>=3.0.0, <4"] kylin = ["kylinpy>=2.8.1, <2.9"] mssql = ["pymssql>=2.2.8, <3"] @@ -170,19 +177,20 @@ ocient = [ "shapely", "geojson", ] -oracle = ["cx-Oracle>8.0.0, <8.1"] +oracle = ["cx-Oracle>8.0.0, <8.4"] parseable = ["sqlalchemy-parseable>=0.1.3,<0.2.0"] -pinot = ["pinotdb>=5.0.0, <6.0.0"] +pinot = ["pinotdb>=5.0.0, <10.0.0"] playwright = ["playwright>=1.37.0, <2"] -postgres = ["psycopg2-binary==2.9.9"] +postgres = ["psycopg2-binary==2.9.12"] presto = ["pyhive[presto]>=0.6.5"] trino = ["trino>=0.328.0"] prophet = ["prophet>=1.1.6, <2"] redshift = ["sqlalchemy-redshift>=0.8.1, <0.9"] risingwave = ["sqlalchemy-risingwave"] -shillelagh = ["shillelagh[all]>=1.4.3, <2"] +shillelagh = ["shillelagh[all]>=1.4.4, <2"] singlestore = ["sqlalchemy-singlestoredb>=1.1.1, <2"] snowflake = ["snowflake-sqlalchemy>=1.2.4, <2"] +sqlite = ["syntaqlite>=0.1.0"] spark = [ "pyhive[hive]>=0.6.5;python_version<'3.11'", "pyhive[hive_pure_sasl]>=0.7", @@ -195,7 +203,7 @@ tdengine = [ ] teradata = ["teradatasql>=16.20.0.23"] thumbnails = [] # deprecated, will be removed in 7.0 -vertica = ["sqlalchemy-vertica-python>=0.5.9, < 0.6"] +vertica = ["sqlalchemy-vertica-python>= 0.5.9, < 0.7"] netezza = ["nzalchemy>=11.0.2"] starrocks = ["starrocks>=1.0.0"] doris = ["pydoris>=1.0.0, <2.0.0"] @@ -216,7 +224,7 @@ development = [ "progress>=1.5,<2", "psutil", "pyfakefs", - "pyinstrument>=4.0.2,<5", + "pyinstrument>=4.0.2,<6", "pylint", "pytest<8.0.0", # hairy issue with pytest >=8 where current_app proxies are not set in time "pytest-asyncio", @@ -226,6 +234,7 @@ development = [ "ruff", "sqloxide", "statsd", + "syntaqlite>=0.1.0", ] [project.urls] @@ -238,7 +247,7 @@ combine_as_imports = true include_trailing_comma = true line_length = 88 known_first_party = "superset, apache-superset-core, apache-superset-extensions-cli" -known_third_party = "alembic, apispec, backoff, celery, click, colorama, cron_descriptor, croniter, cryptography, dateutil, deprecation, flask, flask_appbuilder, flask_babel, flask_caching, flask_compress, flask_jwt_extended, flask_login, flask_migrate, flask_sqlalchemy, flask_talisman, flask_testing, flask_wtf, freezegun, geohash, geopy, holidays, humanize, isodate, jinja2, jwt, markdown, markupsafe, marshmallow, marshmallow-union, msgpack, nh3, numpy, pandas, parameterized, parsedatetime, pgsanity, polyline, prison, progress, pyarrow, sqlalchemy_bigquery, pyhive, pyparsing, pytest, pytest_mock, pytz, redis, requests, selenium, setuptools, shillelagh, simplejson, slack, sqlalchemy, sqlalchemy_utils, typing_extensions, urllib3, werkzeug, wtforms, wtforms_json, yaml" +known_third_party = "alembic, apispec, backoff, celery, click, colorama, cron_descriptor, croniter, cryptography, dateutil, deprecation, flask, flask_appbuilder, flask_babel, flask_caching, flask_compress, flask_jwt_extended, flask_login, flask_migrate, flask_sqlalchemy, flask_talisman, flask_testing, flask_wtf, freezegun, geohash, geopy, holidays, humanize, isodate, jinja2, jwt, markdown, markupsafe, marshmallow, marshmallow-union, msgpack, nh3, numpy, pandas, parameterized, parsedatetime, pgsanity, polyline, rison, progress, pyarrow, sqlalchemy_bigquery, pyhive, pyparsing, pytest, pytest_mock, pytz, redis, requests, selenium, setuptools, shillelagh, simplejson, slack, sqlalchemy, sqlalchemy_utils, syntaqlite, typing_extensions, urllib3, werkzeug, wtforms, wtforms_json, yaml" multi_line_output = 3 order_by_type = false @@ -285,6 +294,7 @@ module = [ "superset.tags.filters", "superset.commands.security.update", "superset.commands.security.create", + "superset.semantic_layers.api", ] warn_unused_ignores = false @@ -373,6 +383,7 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" [tool.ruff.lint.per-file-ignores] "superset/mcp_service/app.py" = ["S608", "E501"] # LLM instruction text: SQL examples (S608) and long lines in multiline string (E501) +"superset/mcp_service/*/tool/list_*.py" = ["E501"] # LLM docstring examples show full request shapes which exceed line length "scripts/*" = ["TID251"] "setup.py" = ["TID251"] "superset/config.py" = ["TID251"] diff --git a/requirements/base.in b/requirements/base.in index 2d6100beab3..cad39dc543c 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -25,6 +25,16 @@ filelock>=3.20.3,<4.0.0 # Security: decompression bomb fix (required by aiohttp 3.13.3) brotli>=1.2.0,<2.0.0 numexpr>=2.9.0 +# Security: CVE-2026-34073 (MEDIUM) - Improper Certificate Validation +cryptography>=46.0.7,<47.0.0 +# Security: Snyk - XSS vulnerability in Mako templates +mako>=1.3.11,<2.0.0 +# Security: CVE-2024-52338 (CRITICAL) - Deserialization of untrusted data in IPC/Parquet readers +pyarrow>=20.0.0,<21.0.0 +# Security: CVE-2026-27459 - pyopenssl certificate validation +pyopenssl>=26.0.0,<27.0.0 +# Security: CVE-2026-25645 (MEDIUM) - Insecure Temporary File +requests>=2.33.0,<3.0.0 # 5.0.0 has a sensitive deprecation used in other libs # -> https://github.com/aio-libs/async-timeout/blob/master/CHANGES.rst#500-2024-10-31 diff --git a/requirements/base.txt b/requirements/base.txt index 983098bddce..9c99184f920 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -86,8 +86,9 @@ cron-descriptor==1.4.5 # via apache-superset (pyproject.toml) croniter==6.0.0 # via apache-superset (pyproject.toml) -cryptography==46.0.6 +cryptography==46.0.7 # via + # -r requirements/base.in # apache-superset (pyproject.toml) # paramiko # pyopenssl @@ -182,7 +183,9 @@ idna==3.10 # trio # url-normalize isodate==0.7.2 - # via apache-superset (pyproject.toml) + # via + # apache-superset (pyproject.toml) + # apache-superset-core itsdangerous==2.2.0 # via # flask @@ -205,8 +208,9 @@ kombu==5.5.3 # via celery limits==5.1.0 # via flask-limiter -mako==1.3.10 +mako==1.3.11 # via + # -r requirements/base.in # apache-superset (pyproject.toml) # alembic markdown==3.8.1 @@ -247,7 +251,6 @@ numpy==1.26.4 # bottleneck # numexpr # pandas - # pyarrow odfpy==1.4.1 # via pandas openapi-schema-validator==0.6.3 @@ -279,7 +282,7 @@ parsedatetime==2.6 # via apache-superset (pyproject.toml) pgsanity==0.2.9 # via apache-superset (pyproject.toml) -pillow==12.1.1 +pillow==12.2.0 # via apache-superset (pyproject.toml) platformdirs==4.3.8 # via requests-cache @@ -291,8 +294,11 @@ prison==0.2.1 # via flask-appbuilder prompt-toolkit==3.0.51 # via click-repl -pyarrow==16.1.0 - # via apache-superset (pyproject.toml) +pyarrow==20.0.0 + # via + # -r requirements/base.in + # apache-superset (pyproject.toml) + # apache-superset-core pyasn1==0.6.3 # via # pyasn1-modules @@ -319,8 +325,10 @@ pyjwt==2.12.0 # redis pynacl==1.6.2 # via paramiko -pyopenssl==25.3.0 - # via shillelagh +pyopenssl==26.0.0 + # via + # -r requirements/base.in + # shillelagh pyparsing==3.2.3 # via apache-superset (pyproject.toml) pysocks==1.7.1 @@ -334,7 +342,7 @@ python-dateutil==2.9.0.post0 # holidays # pandas # shillelagh -python-dotenv==1.1.0 +python-dotenv==1.2.2 # via apache-superset (pyproject.toml) pytz==2025.2 # via @@ -353,8 +361,9 @@ referencing==0.36.2 # via # jsonschema # jsonschema-specifications -requests==2.32.4 +requests==2.33.0 # via + # -r requirements/base.in # requests-cache # shillelagh requests-cache==1.2.1 @@ -363,6 +372,8 @@ rfc3339-validator==0.1.4 # via openapi-schema-validator rich==13.9.4 # via flask-limiter +rison==2.0.0 + # via apache-superset (pyproject.toml) rpds-py==0.25.0 # via # jsonschema @@ -373,7 +384,7 @@ selenium==4.32.0 # via apache-superset (pyproject.toml) setuptools==80.9.0 # via -r requirements/base.in -shillelagh==1.4.3 +shillelagh==1.4.4 # via apache-superset (pyproject.toml) simplejson==3.20.1 # via apache-superset (pyproject.toml) diff --git a/requirements/development.txt b/requirements/development.txt index 7fecd31e208..b7664ddae6b 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -52,7 +52,7 @@ attrs==25.3.0 # referencing # requests-cache # trio -authlib==1.6.7 +authlib==1.6.9 # via fastmcp babel==2.17.0 # via @@ -178,7 +178,7 @@ croniter==6.0.0 # via # -c requirements/base-constraint.txt # apache-superset -cryptography==46.0.6 +cryptography==46.0.7 # via # -c requirements/base-constraint.txt # apache-superset @@ -236,7 +236,7 @@ et-xmlfile==2.0.0 # openpyxl exceptiongroup==1.3.0 # via fastmcp -fastmcp==3.1.0 +fastmcp==3.2.4 # via apache-superset filelock==3.20.3 # via @@ -379,6 +379,8 @@ greenlet==3.1.1 # gevent # shillelagh # sqlalchemy +griffelib==2.0.2 + # via fastmcp grpcio==1.71.0 # via # apache-superset @@ -440,6 +442,7 @@ isodate==0.7.2 # via # -c requirements/base-constraint.txt # apache-superset + # apache-superset-core isort==6.0.1 # via pylint itsdangerous==2.2.0 @@ -503,7 +506,7 @@ limits==5.1.0 # via # -c requirements/base-constraint.txt # flask-limiter -mako==1.3.10 +mako==1.3.11 # via # -c requirements/base-constraint.txt # alembic @@ -580,7 +583,6 @@ numpy==1.26.4 # pandas # pandas-gbq # prophet - # pyarrow oauthlib==3.2.2 # via requests-oauthlib odfpy==1.4.1 @@ -655,7 +657,7 @@ pgsanity==0.2.9 # via # -c requirements/base-constraint.txt # apache-superset -pillow==12.1.1 +pillow==12.2.0 # via # -c requirements/base-constraint.txt # apache-superset @@ -706,14 +708,15 @@ protobuf==4.25.8 # proto-plus psutil==6.1.0 # via apache-superset -psycopg2-binary==2.9.9 +psycopg2-binary==2.9.12 # via apache-superset py-key-value-aio==0.4.4 # via fastmcp -pyarrow==16.1.0 +pyarrow==20.0.0 # via # -c requirements/base-constraint.txt # apache-superset + # apache-superset-core # db-dtypes # pandas-gbq pyasn1==0.6.3 @@ -778,7 +781,7 @@ pynacl==1.6.2 # via # -c requirements/base-constraint.txt # paramiko -pyopenssl==25.3.0 +pyopenssl==26.0.0 # via # -c requirements/base-constraint.txt # shillelagh @@ -826,7 +829,7 @@ python-dateutil==2.9.0.post0 # pyhive # shillelagh # trino -python-dotenv==1.1.0 +python-dotenv==1.2.2 # via # -c requirements/base-constraint.txt # apache-superset @@ -865,7 +868,9 @@ referencing==0.36.2 # jsonschema # jsonschema-path # jsonschema-specifications -requests==2.32.4 +regex==2026.4.4 + # via tiktoken +requests==2.33.0 # via # -c requirements/base-constraint.txt # docker @@ -877,6 +882,7 @@ requests==2.32.4 # requests-cache # requests-oauthlib # shillelagh + # tiktoken # trino requests-cache==1.2.1 # via @@ -897,6 +903,10 @@ rich==13.9.4 # rich-rst rich-rst==1.3.1 # via cyclopts +rison==2.0.0 + # via + # -c requirements/base-constraint.txt + # apache-superset rpds-py==0.25.0 # via # -c requirements/base-constraint.txt @@ -926,7 +936,7 @@ setuptools==80.9.0 # pydata-google-auth # zope-event # zope-interface -shillelagh==1.4.3 +shillelagh==1.4.4 # via # -c requirements/base-constraint.txt # apache-superset @@ -992,10 +1002,14 @@ starlette==0.49.1 # via mcp statsd==4.0.1 # via apache-superset +syntaqlite==0.1.0 + # via apache-superset tabulate==0.9.0 # via # -c requirements/base-constraint.txt # apache-superset +tiktoken==0.12.0 + # via apache-superset tomli-w==1.2.0 # via apache-superset-extensions-cli tomlkit==0.13.3 diff --git a/scripts/oxlint.sh b/scripts/oxlint.sh index 5eb984f0b3a..95f48afabb6 100755 --- a/scripts/oxlint.sh +++ b/scripts/oxlint.sh @@ -45,7 +45,17 @@ if [ ${#js_ts_files[@]} -gt 0 ]; then # Skip custom OXC build in pre-commit for speed export SKIP_CUSTOM_OXC=true # Use quiet mode in pre-commit to reduce noise (only show errors) - npx oxlint --config oxlint.json --fix --quiet "${js_ts_files[@]}" + # Capture output so we can treat "No files found" (all files ignored by + # ignorePatterns) as success rather than a false-positive failure. + output=$(npx oxlint --config oxlint.json --fix --quiet "${js_ts_files[@]}" 2>&1) || { + if echo "$output" | grep -q "No files found"; then + echo "No files to lint after applying ignore patterns" + exit 0 + fi + echo "$output" >&2 + exit 1 + } + [ -n "$output" ] && echo "$output" else echo "No JavaScript/TypeScript files to lint" fi diff --git a/superset-core/pyproject.toml b/superset-core/pyproject.toml index 1796b694153..a3ee4bcf45e 100644 --- a/superset-core/pyproject.toml +++ b/superset-core/pyproject.toml @@ -18,7 +18,7 @@ [project] name = "apache-superset-core" -version = "0.1.0rc2" +version = "0.1.0rc3" description = "Core Python package for building Apache Superset backend extensions and integrations" readme = "README.md" authors = [ @@ -43,6 +43,8 @@ classifiers = [ ] dependencies = [ "flask-appbuilder>=5.0.2,<6", + "isodate>=0.7.0", + "pyarrow>=16.0.0", "pydantic>=2.8.0", "sqlalchemy>=1.4.0,<2.0", "sqlalchemy-utils>=0.38.0, <0.43", # expanding lowerbound to work with pydoris diff --git a/superset-core/src/superset_core/semantic_layers/config.py b/superset-core/src/superset_core/semantic_layers/config.py new file mode 100644 index 00000000000..7c9aa520b11 --- /dev/null +++ b/superset-core/src/superset_core/semantic_layers/config.py @@ -0,0 +1,73 @@ +# 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. + +from __future__ import annotations + +from typing import Any + +from pydantic import BaseModel + + +def build_configuration_schema( + config_class: type[BaseModel], + configuration: BaseModel | None = None, +) -> dict[str, Any]: + """ + Build a JSON schema from a Pydantic configuration class. + + Handles generic boilerplate that any semantic layer with dynamic fields needs: + + - Reorders properties to match model field order (Pydantic sorts alphabetically) + - When ``configuration`` is None, sets ``enum: []`` on all ``x-dynamic`` properties + so the frontend renders them as empty dropdowns + + Semantic layer implementations call this instead of + ``model_json_schema()`` directly, + then only need to add their own dynamic population logic. + """ + schema = config_class.model_json_schema() + + # Pydantic sorts properties alphabetically; restore model field order + field_order = [ + field.alias or name for name, field in config_class.model_fields.items() + ] + schema["properties"] = { + key: schema["properties"][key] + for key in field_order + if key in schema["properties"] + } + + if configuration is None: + for prop_schema in schema["properties"].values(): + if prop_schema.get("x-dynamic"): + prop_schema["enum"] = [] + + return schema + + +def check_dependencies( + prop_schema: dict[str, Any], + configuration: BaseModel, +) -> bool: + """ + Check whether a dynamic property's dependencies are satisfied. + + Reads the ``x-dependsOn`` list from the property schema and returns ``True`` + when every referenced attribute on ``configuration`` is truthy. + """ + dependencies = prop_schema.get("x-dependsOn", []) + return all(getattr(configuration, dep, None) for dep in dependencies) diff --git a/superset-core/src/superset_core/semantic_layers/daos.py b/superset-core/src/superset_core/semantic_layers/daos.py new file mode 100644 index 00000000000..4b55231d0b2 --- /dev/null +++ b/superset-core/src/superset_core/semantic_layers/daos.py @@ -0,0 +1,169 @@ +# 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. + +""" +Semantic layer DAO interfaces for superset-core. + +Provides abstract DAO classes for semantic layers and views that define the +interface contract. Host implementations replace these with concrete classes +backed by SQLAlchemy during initialization. + +Usage: + from superset_core.semantic_layers.daos import ( + AbstractSemanticLayerDAO, + AbstractSemanticViewDAO, + ) +""" + +from __future__ import annotations + +from abc import abstractmethod +from typing import Any, ClassVar + +from superset_core.common.daos import BaseDAO +from superset_core.semantic_layers.models import SemanticLayerModel, SemanticViewModel + + +class AbstractSemanticLayerDAO(BaseDAO[SemanticLayerModel]): + """ + Abstract DAO interface for SemanticLayer. + + Host implementations will replace this class during initialization + with a concrete DAO providing actual database access. + """ + + model_cls: ClassVar[type[Any] | None] = None + base_filter = None + id_column_name = "uuid" + uuid_column_name = "uuid" + + @classmethod + @abstractmethod + def validate_uniqueness(cls, name: str) -> bool: + """ + Validate that a semantic layer name is unique. + + :param name: Semantic layer name to validate + :return: True if the name is unique, False otherwise + """ + ... + + @classmethod + @abstractmethod + def validate_update_uniqueness(cls, layer_uuid: str, name: str) -> bool: + """ + Validate that a semantic layer name is unique for an update operation, + excluding the layer being updated. + + :param layer_uuid: UUID of the semantic layer being updated + :param name: New name to validate + :return: True if the name is unique, False otherwise + """ + ... + + @classmethod + @abstractmethod + def find_by_name(cls, name: str) -> SemanticLayerModel | None: + """ + Find a semantic layer by name. + + :param name: Semantic layer name + :return: SemanticLayerModel instance or None + """ + ... + + @classmethod + @abstractmethod + def get_semantic_views(cls, layer_uuid: str) -> list[SemanticViewModel]: + """ + Get all semantic views associated with a semantic layer. + + :param layer_uuid: UUID of the semantic layer + :return: List of SemanticViewModel instances + """ + ... + + +class AbstractSemanticViewDAO(BaseDAO[SemanticViewModel]): + """ + Abstract DAO interface for SemanticView. + + Host implementations will replace this class during initialization + with a concrete DAO providing actual database access. + """ + + model_cls: ClassVar[type[Any] | None] = None + base_filter = None + id_column_name = "id" + uuid_column_name = "uuid" + + @classmethod + @abstractmethod + def validate_uniqueness( + cls, + name: str, + layer_uuid: str, + configuration: dict[str, Any], + ) -> bool: + """ + Validate that a semantic view is unique within a semantic layer. + + Uniqueness is determined by the combination of name, layer UUID, and + configuration. + + :param name: View name + :param layer_uuid: UUID of the parent semantic layer + :param configuration: Configuration dict to compare + :return: True if unique, False otherwise + """ + ... + + @classmethod + @abstractmethod + def validate_update_uniqueness( + cls, + view_uuid: str, + name: str, + layer_uuid: str, + configuration: dict[str, Any], + ) -> bool: + """ + Validate that a semantic view is unique within a semantic layer for an + update operation, excluding the view being updated. + + :param view_uuid: UUID of the view being updated + :param name: New name to validate + :param layer_uuid: UUID of the parent semantic layer + :param configuration: Configuration dict to compare + :return: True if unique, False otherwise + """ + ... + + @classmethod + @abstractmethod + def find_by_name(cls, name: str, layer_uuid: str) -> SemanticViewModel | None: + """ + Find a semantic view by name within a semantic layer. + + :param name: View name + :param layer_uuid: UUID of the parent semantic layer + :return: SemanticViewModel instance or None + """ + ... + + +__all__ = ["AbstractSemanticLayerDAO", "AbstractSemanticViewDAO"] diff --git a/superset-core/src/superset_core/semantic_layers/decorators.py b/superset-core/src/superset_core/semantic_layers/decorators.py new file mode 100644 index 00000000000..50dd975702c --- /dev/null +++ b/superset-core/src/superset_core/semantic_layers/decorators.py @@ -0,0 +1,102 @@ +# 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. + +""" +Semantic layer registration decorator for Superset. + +This module provides a decorator interface to register semantic layer +implementations with the host application, enabling automatic discovery +by the extensions framework. + +Usage: + from superset_core.semantic_layers.decorators import semantic_layer + + @semantic_layer( + id="snowflake", + name="Snowflake Cortex", + description="Snowflake semantic layer via Cortex Analyst", + ) + class SnowflakeSemanticLayer(SemanticLayer[SnowflakeConfig, SnowflakeView]): + ... + + # Or with minimal arguments: + @semantic_layer(id="dbt", name="dbt Semantic Layer") + class DbtSemanticLayer(SemanticLayer[DbtConfig, DbtView]): + ... +""" + +from __future__ import annotations + +from typing import Callable, TypeVar + +# Type variable for decorated semantic layer classes +T = TypeVar("T") + + +def semantic_layer( + id: str, + name: str, + description: str | None = None, +) -> Callable[[T], T]: + """ + Decorator to register a semantic layer implementation. + + Automatically detects extension context and applies appropriate + namespacing to prevent ID conflicts between host and extension + semantic layers. + + Host implementations will replace this function during initialization + with a concrete implementation providing actual functionality. + + Args: + id: Unique semantic layer type identifier (e.g., "snowflake", + "dbt"). Used as the key in the semantic layers registry and + stored in the ``type`` column of the ``SemanticLayer`` model. + name: Human-readable display name (e.g., "Snowflake Cortex"). + Shown in the UI when listing available semantic layer types. + description: Optional description for documentation and UI + tooltips. + + Returns: + Decorated semantic layer class registered with the host + application. + + Raises: + NotImplementedError: If called before host implementation is + initialized. + + Example: + from superset_core.semantic_layers.decorators import semantic_layer + from superset_core.semantic_layers.layer import SemanticLayer + + @semantic_layer( + id="snowflake", + name="Snowflake Cortex", + description="Connect to Snowflake Cortex Analyst", + ) + class SnowflakeSemanticLayer( + SemanticLayer[SnowflakeConfig, SnowflakeView] + ): + ... + """ + raise NotImplementedError( + "Semantic layer decorator not initialized. " + "This decorator should be replaced during Superset startup." + ) + + +__all__ = ["semantic_layer"] diff --git a/superset-core/src/superset_core/semantic_layers/layer.py b/superset-core/src/superset_core/semantic_layers/layer.py new file mode 100644 index 00000000000..2dbffdec003 --- /dev/null +++ b/superset-core/src/superset_core/semantic_layers/layer.py @@ -0,0 +1,129 @@ +# 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. + +from __future__ import annotations + +from abc import ABC, abstractmethod +from typing import Any, Generic, TypeVar + +from pydantic import BaseModel +from superset_core.semantic_layers.view import SemanticView + +ConfigT = TypeVar("ConfigT", bound=BaseModel) +SemanticViewT = TypeVar("SemanticViewT", bound="SemanticView") + + +class SemanticLayer(ABC, Generic[ConfigT, SemanticViewT]): + """ + Abstract base class for semantic layers. + """ + + configuration_class: type[BaseModel] + + @classmethod + @abstractmethod + def from_configuration( + cls, + configuration: dict[str, Any], + ) -> SemanticLayer[ConfigT, SemanticViewT]: + """ + Create a semantic layer from its configuration. + """ + raise NotImplementedError( + "Semantic layers must implement the from_configuration method" + ) + + @classmethod + @abstractmethod + def get_configuration_schema( + cls, + configuration: ConfigT | None = None, + ) -> dict[str, Any]: + """ + Get the JSON schema for the configuration needed to add the semantic layer. + + A partial configuration `configuration` can be sent to improve the schema, + allowing for progressive validation and better UX. For example, a semantic + layer might require: + + - auth information + - a database + + If the user provides the auth information, a client can send the partial + configuration to this method, and the resulting JSON schema would include + the list of databases the user has access to, allowing a dropdown to be + populated. + + The Snowflake semantic layer has an example implementation of this method, where + database and schema names are populated based on the provided connection info. + """ + raise NotImplementedError( + "Semantic layers must implement the get_configuration_schema method" + ) + + @classmethod + @abstractmethod + def get_runtime_schema( + cls, + configuration: ConfigT, + runtime_data: dict[str, Any] | None = None, + ) -> dict[str, Any]: + """ + Get the JSON schema for the runtime parameters needed to load semantic views. + + This returns the schema needed to connect to a semantic view given the + configuration for the semantic layer. For example, a semantic layer might + be configured by: + + - auth information + - an optional database + + If the user does not provide a database when creating the semantic layer, the + runtime schema would require the database name to be provided before loading any + semantic views. This allows users to create semantic layers that connect to a + specific database (or project, account, etc.), or that allow users to select it + at query time. + + The Snowflake semantic layer has an example implementation of this method, where + database and schema names are required if they were not provided in the initial + configuration. + """ + raise NotImplementedError( + "Semantic layers must implement the get_runtime_schema method" + ) + + @abstractmethod + def get_semantic_views( + self, + runtime_configuration: dict[str, Any], + ) -> set[SemanticViewT]: + """ + Get the semantic views available in the semantic layer. + + The runtime configuration can provide information like a given project or + schema, used to restrict the semantic views returned. + """ + + @abstractmethod + def get_semantic_view( + self, + name: str, + additional_configuration: dict[str, Any], + ) -> SemanticViewT: + """ + Get a specific semantic view by its name and additional configuration. + """ diff --git a/superset-core/src/superset_core/semantic_layers/models.py b/superset-core/src/superset_core/semantic_layers/models.py new file mode 100644 index 00000000000..e132a108499 --- /dev/null +++ b/superset-core/src/superset_core/semantic_layers/models.py @@ -0,0 +1,85 @@ +# 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. + +""" +Semantic layer model interfaces for superset-core. + +Provides abstract model classes for semantic layers and views that will be +replaced by the host implementation's concrete SQLAlchemy models during +initialization. + +Usage: + from superset_core.semantic_layers.models import ( + SemanticLayerModel, + SemanticViewModel, + ) +""" + +from __future__ import annotations + +from datetime import datetime +from uuid import UUID + +from superset_core.common.models import CoreModel + + +class SemanticLayerModel(CoreModel): + """ + Abstract interface for the SemanticLayer database model. + + Host implementations will replace this class during initialization + with a concrete SQLAlchemy model providing actual persistence. + """ + + __abstract__ = True + + # Type hints for expected column attributes + uuid: UUID + name: str + description: str | None + type: str + configuration: str + configuration_version: int + cache_timeout: int | None + created_on: datetime | None + changed_on: datetime | None + + +class SemanticViewModel(CoreModel): + """ + Abstract interface for the SemanticView database model. + + Host implementations will replace this class during initialization + with a concrete SQLAlchemy model providing actual persistence. + """ + + __abstract__ = True + + # Type hints for expected column attributes + id: int + uuid: UUID + name: str + description: str | None + configuration: str + configuration_version: int + cache_timeout: int | None + semantic_layer_uuid: UUID + created_on: datetime | None + changed_on: datetime | None + + +__all__ = ["SemanticLayerModel", "SemanticViewModel"] diff --git a/superset-core/src/superset_core/semantic_layers/types.py b/superset-core/src/superset_core/semantic_layers/types.py new file mode 100644 index 00000000000..1239c1303be --- /dev/null +++ b/superset-core/src/superset_core/semantic_layers/types.py @@ -0,0 +1,209 @@ +# 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. + +from __future__ import annotations + +import enum +from dataclasses import dataclass +from datetime import date, datetime, time, timedelta + +import isodate +import pyarrow as pa + + +@dataclass(frozen=True) +class Grain: + """ + Represents a time grain (e.g., day, month, year). + + Attributes: + name: Human-readable name of the grain (e.g., "Second") + representation: ISO 8601 duration (e.g., "PT1S", "P1D", "P1M") + """ + + name: str + representation: str + + def __post_init__(self) -> None: + isodate.parse_duration(self.representation) + + def __eq__(self, other: object) -> bool: + if isinstance(other, Grain): + return self.representation == other.representation + return NotImplemented + + def __hash__(self) -> int: + return hash(self.representation) + + +class Grains: + """Pre-defined common grains and factory for custom ones.""" + + SECOND = Grain("Second", "PT1S") + MINUTE = Grain("Minute", "PT1M") + HOUR = Grain("Hour", "PT1H") + DAY = Grain("Day", "P1D") + WEEK = Grain("Week", "P1W") + MONTH = Grain("Month", "P1M") + QUARTER = Grain("Quarter", "P3M") + YEAR = Grain("Year", "P1Y") + + _REGISTRY: dict[str, Grain] = { + "PT1S": SECOND, + "PT1M": MINUTE, + "PT1H": HOUR, + "P1D": DAY, + "P1W": WEEK, + "P1M": MONTH, + "P3M": QUARTER, + "P1Y": YEAR, + } + + @classmethod + def get(cls, representation: str, name: str | None = None) -> Grain: + """Return a pre-defined grain or create a custom one.""" + if grain := cls._REGISTRY.get(representation): + return grain + return Grain(name or representation, representation) + + +@dataclass(frozen=True) +class Dimension: + id: str + name: str + type: pa.DataType + + definition: str | None = None + description: str | None = None + grain: Grain | None = None + + +@dataclass(frozen=True) +class Metric: + id: str + name: str + type: pa.DataType + + definition: str + description: str | None = None + + +@dataclass(frozen=True) +class AdhocExpression: + id: str + definition: str + + +class Operator(str, enum.Enum): + EQUALS = "=" + NOT_EQUALS = "!=" + GREATER_THAN = ">" + LESS_THAN = "<" + GREATER_THAN_OR_EQUAL = ">=" + LESS_THAN_OR_EQUAL = "<=" + IN = "IN" + NOT_IN = "NOT IN" + LIKE = "LIKE" + NOT_LIKE = "NOT LIKE" + IS_NULL = "IS NULL" + IS_NOT_NULL = "IS NOT NULL" + ADHOC = "ADHOC" + + +FilterValues = str | int | float | bool | datetime | date | time | timedelta | None + + +class PredicateType(enum.Enum): + WHERE = "WHERE" + HAVING = "HAVING" + + +@dataclass(frozen=True, order=True) +class Filter: + type: PredicateType + column: Dimension | Metric | None + operator: Operator + value: FilterValues | frozenset[FilterValues] + + +class OrderDirection(enum.Enum): + ASC = "ASC" + DESC = "DESC" + + +OrderTuple = tuple[Metric | Dimension | AdhocExpression, OrderDirection] + + +@dataclass(frozen=True) +class GroupLimit: + """ + Limit query to top/bottom N combinations of specified dimensions. + + The `filters` parameter allows specifying separate filter constraints for the + group limit subquery. This is useful when you want to determine the top N groups + using different criteria (e.g., a different time range) than the main query. + + For example, you might want to find the top 10 products by sales over the last + 30 days, but then show daily sales for those products over the last 7 days. + """ + + dimensions: list[Dimension] + top: int + metric: Metric | None + direction: OrderDirection = OrderDirection.DESC + group_others: bool = False + filters: set[Filter] | None = None + + +@dataclass(frozen=True) +class SemanticRequest: + """ + Represents a request made to obtain semantic results. + + This could be a SQL query, an HTTP request, etc. + """ + + type: str + definition: str + + +@dataclass(frozen=True) +class SemanticResult: + """ + Represents the results of a semantic query. + + This includes any requests (SQL queries, HTTP requests) that were performed in order + to obtain the results, in order to help troubleshooting. + """ + + requests: list[SemanticRequest] + results: pa.Table + + +@dataclass(frozen=True) +class SemanticQuery: + """ + Represents a semantic query. + """ + + metrics: list[Metric] + dimensions: list[Dimension] + filters: set[Filter] | None = None + order: list[OrderTuple] | None = None + limit: int | None = None + offset: int | None = None + group_limit: GroupLimit | None = None diff --git a/superset-core/src/superset_core/semantic_layers/view.py b/superset-core/src/superset_core/semantic_layers/view.py new file mode 100644 index 00000000000..73ee35aee85 --- /dev/null +++ b/superset-core/src/superset_core/semantic_layers/view.py @@ -0,0 +1,113 @@ +# 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. + +from __future__ import annotations + +import enum +from abc import ABC, abstractmethod + +from superset_core.semantic_layers.types import ( + Dimension, + Filter, + Metric, + SemanticQuery, + SemanticResult, +) + + +# TODO (betodealmeida): move to the extension JSON +class SemanticViewFeature(enum.Enum): + """ + Custom features supported by semantic layers. + """ + + ADHOC_EXPRESSIONS_IN_ORDERBY = "ADHOC_EXPRESSIONS_IN_ORDERBY" + GROUP_LIMIT = "GROUP_LIMIT" + GROUP_OTHERS = "GROUP_OTHERS" + + +class SemanticView(ABC): + """ + Abstract base class for semantic views. + """ + + features: frozenset[SemanticViewFeature] + + # Implementations must expose a display name for the view. + # Declared here as a type annotation (not abstract) so that existing + # implementations are not required to add a formal @abstractmethod. + name: str + + @abstractmethod + def uid(self) -> str: + """ + Returns a unique identifier for the semantic view. + """ + + @abstractmethod + def get_dimensions(self) -> set[Dimension]: + """ + Get the dimensions defined in the semantic view. + """ + + @abstractmethod + def get_metrics(self) -> set[Metric]: + """ + Get the metrics defined in the semantic view. + """ + + @abstractmethod + def get_values( + self, + dimension: Dimension, + filters: set[Filter] | None = None, + ) -> SemanticResult: + """ + Return distinct values for a dimension. + """ + + @abstractmethod + def get_table(self, query: SemanticQuery) -> SemanticResult: + """ + Execute a semantic query and return the results. + """ + + @abstractmethod + def get_row_count(self, query: SemanticQuery) -> SemanticResult: + """ + Execute a query and return the number of rows the result would have. + """ + + @abstractmethod + def get_compatible_metrics( + self, + selected_metrics: set[Metric], + selected_dimensions: set[Dimension], + ) -> set[Metric]: + """ + Return metrics compatible with the selected dimensions. + """ + + @abstractmethod + def get_compatible_dimensions( + self, + selected_metrics: set[Metric], + selected_dimensions: set[Dimension], + ) -> set[Dimension]: + """ + Return dimensions compatible with the selected metrics. + """ diff --git a/superset-embedded-sdk/src/index.ts b/superset-embedded-sdk/src/index.ts index e732a36c22f..2eb9f37181a 100644 --- a/superset-embedded-sdk/src/index.ts +++ b/superset-embedded-sdk/src/index.ts @@ -66,7 +66,7 @@ export type EmbedDashboardParams = { iframeTitle?: string; /** additional iframe sandbox attributes ex (allow-top-navigation, allow-popups-to-escape-sandbox) **/ iframeSandboxExtras?: string[]; - /** iframe allow attribute for Permissions Policy (e.g., ['clipboard-write', 'fullscreen']) **/ + /** Additional Permissions Policy features for the iframe's `allow` attribute (e.g., ['camera', 'microphone']). `fullscreen` and `clipboard-write` are granted by default. **/ iframeAllowExtras?: string[]; /** force a specific refererPolicy to be used in the iframe request **/ referrerPolicy?: ReferrerPolicy; @@ -233,9 +233,14 @@ export async function embedDashboard({ iframe.src = `${supersetDomain}/embedded/${id}${urlParamsString}`; iframe.title = iframeTitle; iframe.style.background = 'transparent'; - if (iframeAllowExtras.length > 0) { - iframe.setAttribute('allow', iframeAllowExtras.join('; ')); - } + // Permissions Policy features the embedded dashboard relies on. Modern + // browsers gate these APIs on the iframe's `allow` attribute regardless + // of sandbox flags, so we include them by default. Host apps can extend + // the list via `iframeAllowExtras`. + const allowFeatures = Array.from( + new Set(['fullscreen', 'clipboard-write', ...iframeAllowExtras]), + ); + iframe.setAttribute('allow', allowFeatures.join('; ')); //@ts-ignore mountPoint.replaceChildren(iframe); log('placed the iframe'); diff --git a/superset-extensions-cli/pyproject.toml b/superset-extensions-cli/pyproject.toml index 55261c841ab..6c5cdf7288c 100644 --- a/superset-extensions-cli/pyproject.toml +++ b/superset-extensions-cli/pyproject.toml @@ -17,7 +17,7 @@ [project] name = "apache-superset-extensions-cli" -version = "0.1.0rc2" +version = "0.1.0rc3" description = "Official command-line interface for building, bundling, and managing Apache Superset extensions" readme = "README.md" authors = [ diff --git a/superset-frontend/oxlint.json b/superset-frontend/oxlint.json index fb4401c4bab..d2fe2bfb5ac 100644 --- a/superset-frontend/oxlint.json +++ b/superset-frontend/oxlint.json @@ -33,6 +33,33 @@ // - No FontAwesome icons (use Icons component) // - No template variables in i18n (use parameterized messages) + // === Rules carried over from ESLint that oxlint does NOT implement === + // oxlint 1.58+ errors on unknown builtin rules, so these can no longer + // be listed in this config. They were silently dropped in earlier + // oxlint versions (not actually enforced). Documented here for future + // maintainers — if/when oxlint adds them, re-enable in the relevant + // plugin section above. + // import: newline-after-import, no-extraneous-dependencies, + // no-import-module-exports, no-relative-packages, + // no-unresolved, no-useless-path-segments + // react: default-props-match-prop-types, destructuring-assignment, + // forbid-component-props, forbid-foreign-prop-types, + // forbid-prop-types, function-component-definition, + // jsx-no-bind, jsx-uses-vars, no-access-state-in-setstate, + // no-deprecated, no-did-update-set-state, no-typos, + // no-unstable-nested-components, + // no-unused-class-component-methods, no-unused-prop-types, + // no-unused-state, prefer-stateless-function, prop-types, + // require-default-props, sort-comp, static-property-placement + // (prefer-stateless-function / function-component-definition + // are represented by react/prefer-function-component below) + // jsx-a11y: interactive-supports-focus, + // no-interactive-element-to-noninteractive-role, + // no-noninteractive-element-interactions, + // no-noninteractive-element-to-interactive-role + // typescript: naming-convention + // unicorn: prevent-abbreviations + // === Core ESLint rules === // Error prevention "no-console": "warn", @@ -89,7 +116,6 @@ "no-object-constructor": "error", // === Import plugin rules === - "import/no-unresolved": "error", // TODO: Fix incorrect named imports in Storybook and other files "import/named": "warn", // TODO: Fix duplicate exports in shared-controls and other modules @@ -105,56 +131,24 @@ "import/first": "error", // TODO: Consolidate duplicate imports in DatasetList and other files "import/no-duplicates": "warn", - "import/newline-after-import": "error", "import/no-absolute-path": "error", "import/no-dynamic-require": "error", "import/no-webpack-loader-syntax": "error", "import/no-self-import": "error", "import/no-cycle": "off", - "import/no-useless-path-segments": ["error", { "commonjs": true }], "import/prefer-default-export": "off", - "import/no-relative-packages": "off", - "import/no-import-module-exports": "off", - "import/no-extraneous-dependencies": [ - "error", - { - "devDependencies": [ - "test/**", - "tests/**", - "spec/**", - "**/__tests__/**", - "**/__mocks__/**", - "*.test.{js,jsx,ts,tsx}", - "*.spec.{js,jsx,ts,tsx}", - "**/*.test.{js,jsx,ts,tsx}", - "**/*.spec.{js,jsx,ts,tsx}", - "**/jest.config.js", - "**/jest.setup.js", - "**/webpack.config.js", - "**/webpack.config.*.js", - "**/.eslintrc.js" - ], - "optionalDependencies": false - } - ], // === React plugin rules === - "react/prop-types": "off", - "react/require-default-props": "off", - "react/forbid-prop-types": "off", - "react/forbid-component-props": "warn", "react/jsx-filename-extension": [ "warn", { "extensions": [".jsx", ".tsx"] } ], "react/jsx-fragments": "error", - "react/jsx-no-bind": "off", "react/jsx-props-no-spreading": "off", "react/jsx-boolean-value": ["error", "never", { "always": [] }], "react/jsx-no-duplicate-props": "error", "react/jsx-no-undef": "error", "react/jsx-pascal-case": ["error", { "allowAllCaps": true, "ignore": [] }], - "react/jsx-uses-vars": "error", "react/jsx-no-target-blank": ["error", { "enforceDynamicLinks": "always" }], "react/jsx-no-comment-textnodes": "error", "react/jsx-no-useless-fragment": "off", @@ -165,40 +159,27 @@ "react/no-array-index-key": "off", "react/no-children-prop": "error", "react/no-danger": "error", - "react/forbid-foreign-prop-types": "error", "react/no-danger-with-children": "error", - "react/no-deprecated": "error", - "react/no-did-update-set-state": "error", "react/no-find-dom-node": "error", "react/no-is-mounted": "error", "react/no-render-return-value": "error", "react/no-string-refs": "off", "react/no-unescaped-entities": "off", "react/no-unknown-property": "off", - "react/no-unused-prop-types": "off", - "react/no-unused-state": "error", "react/no-will-update-set-state": "error", "react/prefer-es6-class": ["error", "always"], - "react/prefer-stateless-function": [ - "error", - { "ignorePureComponents": true } - ], "react/require-render-return": "error", "react/self-closing-comp": "error", "react/void-dom-elements-no-children": "error", - "react/no-access-state-in-setstate": "error", "react/no-redundant-should-component-update": "error", "react/no-this-in-sfc": "error", - "react/no-typos": "error", - "react/no-unstable-nested-components": "off", - "react/no-unused-class-component-methods": "off", - "react/destructuring-assignment": "off", - "react/sort-comp": "off", "react/state-in-constructor": "off", - "react/static-property-placement": "off", "react/react-in-jsx-scope": "off", - "react/function-component-definition": "off", - "react/default-props-match-prop-types": "off", + // Successor to the ESLint-era `react/prefer-stateless-function` and + // `react/function-component-definition` rules. Disabled because the + // codebase still contains legacy class components; flip to "error" + // once the class-to-function migration completes. + "react/prefer-function-component": "off", "react/button-has-type": [ "error", { "button": true, "submit": true, "reset": false } @@ -223,7 +204,6 @@ "jsx-a11y/html-has-lang": "error", "jsx-a11y/iframe-has-title": "error", "jsx-a11y/img-redundant-alt": "error", - "jsx-a11y/interactive-supports-focus": "error", "jsx-a11y/label-has-associated-control": "error", "jsx-a11y/lang": "error", "jsx-a11y/media-has-caption": "error", @@ -231,9 +211,6 @@ "jsx-a11y/no-access-key": "error", "jsx-a11y/no-autofocus": ["error", { "ignoreNonDOM": true }], "jsx-a11y/no-distracting-elements": "error", - "jsx-a11y/no-interactive-element-to-noninteractive-role": "error", - "jsx-a11y/no-noninteractive-element-interactions": "error", - "jsx-a11y/no-noninteractive-element-to-interactive-role": "error", "jsx-a11y/no-noninteractive-tabindex": "error", "jsx-a11y/no-redundant-roles": "error", "jsx-a11y/no-static-element-interactions": "off", @@ -253,17 +230,6 @@ "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/no-unused-vars": "warn", "@typescript-eslint/prefer-optional-chain": "error", - "@typescript-eslint/naming-convention": [ - "error", - { - "selector": "enum", - "format": ["PascalCase"] - }, - { - "selector": "enumMember", - "format": ["PascalCase"] - } - ], // === Unicorn rules (bonus coverage) === "unicorn/no-new-array": "error", @@ -279,7 +245,6 @@ "unicorn/prefer-negative-index": "error", "unicorn/prefer-math-trunc": "error", "unicorn/filename-case": "off", - "unicorn/prevent-abbreviations": "off", "unicorn/no-null": "off", "unicorn/no-array-reduce": "off", "unicorn/no-array-for-each": "off", diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 7d2eb0458ab..2be3f5cded7 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -28,8 +28,14 @@ "@emotion/cache": "^11.4.0", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", + "@fontsource/fira-code": "^5.2.7", "@fontsource/ibm-plex-mono": "^5.2.7", + "@fontsource/inter": "^5.2.8", "@googleapis/sheets": "^13.0.1", + "@great-expectations/jsonforms-antd-renderers": "^2.2.10", + "@jsonforms/core": "^3.7.0", + "@jsonforms/react": "^3.7.0", + "@jsonforms/vanilla-renderers": "^3.7.0", "@luma.gl/constants": "~9.2.5", "@luma.gl/core": "~9.2.5", "@luma.gl/engine": "~9.2.5", @@ -37,6 +43,7 @@ "@luma.gl/shadertools": "~9.2.5", "@luma.gl/webgl": "~9.2.5", "@reduxjs/toolkit": "^1.9.3", + "@rjsf/antd": "^5.24.13", "@rjsf/core": "^5.24.13", "@rjsf/utils": "^5.24.3", "@rjsf/validator-ajv8": "^5.24.13", @@ -73,12 +80,12 @@ "@visx/scale": "^3.5.0", "@visx/tooltip": "^3.0.0", "@visx/xychart": "^3.5.1", - "ag-grid-community": "35.0.1", - "ag-grid-react": "35.0.1", + "ag-grid-community": "35.2.1", + "ag-grid-react": "35.2.1", "antd": "^5.26.0", "chrono-node": "^2.9.0", "classnames": "^2.2.5", - "content-disposition": "^1.0.1", + "content-disposition": "^1.1.0", "d3-color": "^3.1.0", "d3-scale": "^4.0.2", "dayjs": "^1.11.20", @@ -89,9 +96,9 @@ "fs-extra": "^11.3.4", "fuse.js": "^7.3.0", "geolib": "^3.3.14", - "geostyler": "^18.3.1", + "geostyler": "^18.5.1", "geostyler-data": "^1.1.0", - "geostyler-openlayers-parser": "^5.4.1", + "geostyler-openlayers-parser": "^5.7.0", "geostyler-style": "11.0.2", "geostyler-wfs-parser": "^3.0.1", "google-auth-library": "^10.6.2", @@ -102,24 +109,24 @@ "json-bigint": "^1.0.0", "json-stringify-pretty-compact": "^2.0.0", "lodash": "^4.18.1", - "mapbox-gl": "^3.20.0", - "markdown-to-jsx": "^9.7.15", - "match-sorter": "^8.2.0", + "mapbox-gl": "^3.23.0", + "markdown-to-jsx": "^9.7.16", + "match-sorter": "^8.3.0", "memoize-one": "^5.2.1", "mousetrap": "^1.6.5", "mustache": "^4.2.0", - "nanoid": "^5.1.7", - "ol": "^10.8.0", + "nanoid": "^5.1.11", + "ol": "^10.9.0", "pretty-ms": "^9.3.0", "query-string": "9.3.1", "re-resizable": "^6.11.2", - "react": "^17.0.2", - "react-arborist": "^3.4.3", + "react": "^18.2.0", + "react-arborist": "^3.5.0", "react-checkbox-tree": "^1.8.0", - "react-diff-viewer-continued": "^4.2.0", + "react-diff-viewer-continued": "^4.2.2", "react-dnd": "^11.1.3", "react-dnd-html5-backend": "^11.1.3", - "react-dom": "^17.0.2", + "react-dom": "^18.2.0", "react-google-recaptcha": "^3.1.0", "react-intersection-observer": "^10.0.3", "react-json-tree": "^0.20.0", @@ -130,7 +137,6 @@ "react-reverse-portal": "^2.3.0", "react-router-dom": "^5.3.4", "react-search-input": "^0.11.3", - "react-sortable-hoc": "^2.0.0", "react-split": "^2.0.9", "react-table": "^7.8.0", "react-transition-group": "^4.4.5", @@ -149,9 +155,9 @@ "use-event-callback": "^0.1.0", "use-immer": "^0.11.0", "use-query-params": "^2.2.2", - "uuid": "^13.0.0", + "uuid": "^14.0.0", "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz", - "yargs": "^17.7.2" + "yargs": "^18.0.0" }, "devDependencies": { "@babel/cli": "^7.28.6", @@ -163,49 +169,48 @@ "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.28.6", "@babel/plugin-transform-runtime": "^7.29.0", - "@babel/preset-env": "^7.29.2", + "@babel/preset-env": "^7.29.3", "@babel/preset-react": "^7.28.5", "@babel/preset-typescript": "^7.28.5", "@babel/register": "^7.23.7", "@babel/runtime": "^7.29.2", "@babel/runtime-corejs3": "^7.29.2", "@babel/types": "^7.28.6", - "@cypress/react": "^8.0.2", "@emotion/babel-plugin": "^11.13.5", "@emotion/jest": "^11.14.2", "@istanbuljs/nyc-config-typescript": "^1.0.1", "@mihkeleidast/storybook-addon-source": "^1.0.1", "@playwright/test": "^1.59.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.6.2", - "@storybook/addon-actions": "^8.6.17", - "@storybook/addon-controls": "^8.6.17", - "@storybook/addon-essentials": "^8.6.17", - "@storybook/addon-links": "^8.6.17", - "@storybook/addon-mdx-gfm": "^8.6.17", - "@storybook/components": "^8.6.17", - "@storybook/preview-api": "^8.6.17", - "@storybook/react": "^8.6.17", - "@storybook/react-webpack5": "^8.6.17", - "@storybook/test": "^8.6.15", + "@storybook/addon-actions": "^8.6.18", + "@storybook/addon-controls": "^8.6.18", + "@storybook/addon-essentials": "^8.6.18", + "@storybook/addon-links": "^8.6.18", + "@storybook/addon-mdx-gfm": "^8.6.18", + "@storybook/components": "^8.6.18", + "@storybook/preview-api": "^8.6.18", + "@storybook/react": "^8.6.18", + "@storybook/react-webpack5": "^8.6.18", + "@storybook/test": "^8.6.18", "@storybook/test-runner": "^0.17.0", "@svgr/webpack": "^8.1.0", - "@swc/core": "^1.15.24", - "@swc/plugin-emotion": "^14.8.0", + "@swc/core": "^1.15.32", + "@swc/plugin-emotion": "^14.9.0", "@swc/plugin-transform-imports": "^12.5.0", - "@testing-library/dom": "^8.20.1", + "@testing-library/dom": "^9.3.4", "@testing-library/jest-dom": "^6.9.1", - "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "^8.0.1", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^12.8.3", "@types/content-disposition": "^0.5.9", "@types/dom-to-image": "^2.6.7", "@types/jest": "^30.0.0", + "@types/jquery": "^4.0.0", "@types/js-levenshtein": "^1.1.3", "@types/json-bigint": "^1.0.4", "@types/mousetrap": "^1.6.15", "@types/node": "^25.6.0", - "@types/react": "^17.0.83", - "@types/react-dom": "^17.0.26", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", "@types/react-loadable": "^5.5.11", "@types/react-redux": "^7.1.10", "@types/react-resizable": "^3.0.8", @@ -217,14 +222,14 @@ "@types/rison": "0.1.0", "@types/tinycolor2": "^1.4.3", "@types/unzipper": "^0.10.11", - "@typescript-eslint/eslint-plugin": "^7.18.0", - "@typescript-eslint/parser": "^7.18.0", + "@typescript-eslint/eslint-plugin": "^8.59.2", + "@typescript-eslint/parser": "^8.58.2", "babel-jest": "^30.0.2", "babel-loader": "^10.1.1", "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-jsx-remove-data-test-id": "^3.0.0", "babel-plugin-lodash": "^3.3.4", - "baseline-browser-mapping": "^2.10.16", + "baseline-browser-mapping": "^2.10.24", "cheerio": "1.2.0", "concurrently": "^9.2.1", "copy-webpack-plugin": "^14.0.0", @@ -241,17 +246,17 @@ "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest-dom": "^5.5.0", "eslint-plugin-lodash": "^7.4.0", - "eslint-plugin-no-only-tests": "^3.3.0", + "eslint-plugin-no-only-tests": "^3.4.0", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-react-prefer-function-component": "^5.0.0", - "eslint-plugin-react-you-might-not-need-an-effect": "^0.9.2", + "eslint-plugin-react-you-might-not-need-an-effect": "^0.10.0", "eslint-plugin-storybook": "^0.8.0", "eslint-plugin-testing-library": "^7.16.2", "eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors", "fetch-mock": "^12.6.0", "fork-ts-checker-webpack-plugin": "^9.1.0", "history": "^5.3.0", - "html-webpack-plugin": "^5.6.6", + "html-webpack-plugin": "^5.6.7", "http-server": "^14.1.1", "imports-loader": "^5.0.0", "jest": "^30.3.0", @@ -259,12 +264,12 @@ "jest-html-reporter": "^4.4.0", "jest-websocket-mock": "^2.5.0", "js-yaml-loader": "^1.2.2", - "jsdom": "^29.0.2", + "jsdom": "^29.1.1", "lerna": "^9.0.4", "lightningcss": "^1.32.0", "mini-css-extract-plugin": "^2.10.2", "open-cli": "^9.0.0", - "oxlint": "^1.56.0", + "oxlint": "^1.62.0", "po2json": "^0.4.5", "prettier": "3.8.3", "prettier-plugin-packagejson": "^3.0.2", @@ -275,24 +280,23 @@ "source-map": "^0.7.6", "source-map-support": "^0.5.21", "speed-measure-webpack-plugin": "^1.6.0", - "storybook": "8.6.17", + "storybook": "8.6.18", "style-loader": "^4.0.0", "swc-loader": "^0.2.7", - "terser-webpack-plugin": "^5.4.0", - "thread-loader": "^4.0.4", + "terser-webpack-plugin": "^5.5.0", "ts-jest": "^29.4.9", "tscw-config": "^1.1.2", "tsx": "^4.21.0", "typescript": "5.4.5", "unzipper": "^0.12.3", "vm-browserify": "^1.1.2", - "wait-on": "^9.0.5", - "webpack": "^5.106.0", + "wait-on": "^9.0.6", + "webpack": "^5.106.2", "webpack-bundle-analyzer": "^5.3.0", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.3", "webpack-manifest-plugin": "^5.0.1", - "webpack-sources": "^3.3.4", + "webpack-sources": "^3.4.1", "webpack-visualizer-plugin2": "^2.0.0" }, "engines": { @@ -398,9 +402,9 @@ "license": "MIT" }, "node_modules/@ant-design/cssinjs/node_modules/stylis": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.5.tgz", - "integrity": "sha512-K7npNOKGRYuhAFFzkzMGfxFDpN6gDwf8hcMiE+uveTVbBgm93HrNP3ZDUpKqzZ4pG7TP6fmb+EMAQPjq9FqqvA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.4.0.tgz", + "integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==", "license": "MIT" }, "node_modules/@ant-design/fast-color": { @@ -462,14 +466,15 @@ "link": true }, "node_modules/@asamuzakjp/css-color": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.6.tgz", - "integrity": "sha512-BXWCh8dHs9GOfpo/fWGDJtDmleta2VePN9rn6WQt3GjEbxzutVF4t0x2pmH+7dbMCLtuv3MlwqRsAuxlzFXqFg==", + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz", + "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-calc": "^3.1.1", - "@csstools/css-color-parser": "^4.0.2", + "@asamuzakjp/generational-cache": "^1.0.1", + "@csstools/css-calc": "^3.2.0", + "@csstools/css-color-parser": "^4.1.0", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, @@ -478,12 +483,13 @@ } }, "node_modules/@asamuzakjp/dom-selector": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.0.7.tgz", - "integrity": "sha512-d2BgqDUOS1Hfp4IzKUZqCNz+Kg3Y88AkaBvJK/ZVSQPU1f7OpPNi7nQTH6/oI47Dkdg+Z3e8Yp6ynOu4UMINAQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz", + "integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==", "dev": true, "license": "MIT", "dependencies": { + "@asamuzakjp/generational-cache": "^1.0.1", "@asamuzakjp/nwsapi": "^2.3.9", "bidi-js": "^1.0.3", "css-tree": "^3.2.1", @@ -514,6 +520,16 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/@asamuzakjp/generational-cache": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz", + "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, "node_modules/@asamuzakjp/nwsapi": { "version": "2.3.9", "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", @@ -566,9 +582,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", "dev": true, "license": "MIT", "engines": { @@ -762,9 +778,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz", - "integrity": "sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", "dev": true, "license": "MIT", "dependencies": { @@ -1050,6 +1066,23 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.3.tgz", + "integrity": "sha512-SRS46DFR4HqzUzCVgi90/xMoL+zeBDBvWdKYXSEzh79kXswNFEglUpMKxR04//dPqwYXWUBJ3mpUd933ru9Kmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", @@ -2376,19 +2409,20 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.2.tgz", - "integrity": "sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.3.tgz", + "integrity": "sha512-ySZypNLAIH1ClygLDQzVMoGQRViATnkHkYYV6TcNDz+8+jwZCdsguGvsb3EY5d9wyWyhmF1iSuFM0Yh5XPnqSA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.29.0", + "@babel/compat-data": "^7.29.3", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", @@ -2461,13 +2495,13 @@ } }, "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.0.tgz", - "integrity": "sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", + "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", "core-js-compat": "^3.48.0" }, "peerDependencies": { @@ -2659,30 +2693,25 @@ } }, "node_modules/@bramus/specificity/node_modules/css-tree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", "dev": true, "license": "MIT", "dependencies": { - "mdn-data": "2.12.2", - "source-map-js": "^1.0.1" + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "node_modules/@bramus/specificity/node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=0.1.90" - } + "license": "CC0-1.0" }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", @@ -2727,9 +2756,9 @@ } }, "node_modules/@csstools/css-calc": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", - "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.0.tgz", + "integrity": "sha512-bR9e6o2BDB12jzN/gIbjHa5wLJ4UjD1CB9pM7ehlc0ddk6EBz+yYS1EV2MF55/HUxrHcB/hehAyt5vhsA3hx7w==", "dev": true, "funding": [ { @@ -2751,9 +2780,9 @@ } }, "node_modules/@csstools/css-color-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz", - "integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.0.tgz", + "integrity": "sha512-U0KhLYmy2GVj6q4T3WaAe6NPuFYCPQoE3b0dRGxejWDgcPp8TP7S5rVdM5ZrFaqu4N67X8YaPBw14dQSYx3IyQ==", "dev": true, "funding": [ { @@ -2768,7 +2797,7 @@ "license": "MIT", "dependencies": { "@csstools/color-helpers": "^6.0.2", - "@csstools/css-calc": "^3.1.1" + "@csstools/css-calc": "^3.2.0" }, "engines": { "node": ">=20.19.0" @@ -2821,97 +2850,14 @@ "node": ">=20.19.0" } }, - "node_modules/@cypress/react": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@cypress/react/-/react-8.0.2.tgz", - "integrity": "sha512-7TgXXEeJ/GnGiIQhO8mAfkyychyMv5hNyISV3ti/vceriTI0uGtbjwRqLQhuVgOSHLtboUZUIoRlR6BkgIdVVg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^16.9.16 || ^17.0.0", - "cypress": "*", - "react": "^=16.x || ^=17.x", - "react-dom": "^=16.x || ^=17.x" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@cypress/request": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.10.tgz", - "integrity": "sha512-hauBrOdvu08vOsagkZ/Aju5XuiZx6ldsLfByg1htFeldhex+PeMrYauANzFsMJeAA0+dyPLbDoX2OYuvVoLDkQ==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~4.0.4", - "http-signature": "~1.4.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "performance-now": "^2.1.0", - "qs": "~6.14.1", - "safe-buffer": "^5.1.2", - "tough-cookie": "^5.0.0", - "tunnel-agent": "^0.6.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@cypress/request/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@cypress/xvfb": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", - "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "debug": "^3.1.0", - "lodash.once": "^4.1.1" - } - }, - "node_modules/@cypress/xvfb/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/@deck.gl/aggregation-layers": { - "version": "9.2.6", - "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-9.2.6.tgz", - "integrity": "sha512-T42ZwB63KI4+0pe2HBwMQS7qnqyv3LlqAQfRSHBlFZMzBq72SxIgk9BzhrT16uBHxFFjjMh6K5g28/UfDOXQEg==", + "version": "9.2.11", + "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-9.2.11.tgz", + "integrity": "sha512-MRFbBHtMcDkOthxXnMPm6nF08DjFDACaIQsJSyHkdWtLUTSLHsWnOTn/8QbB4ka86WyNyfJy3dibLu/m3ei2ow==", "license": "MIT", "dependencies": { - "@luma.gl/constants": "^9.2.6", - "@luma.gl/shadertools": "^9.2.6", + "@luma.gl/constants": "~9.2.6", + "@luma.gl/shadertools": "~9.2.6", "@math.gl/core": "^4.1.0", "@math.gl/web-mercator": "^4.1.0", "d3-hexbin": "^0.2.1" @@ -2949,13 +2895,13 @@ } }, "node_modules/@deck.gl/extensions": { - "version": "9.2.6", - "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-9.2.6.tgz", - "integrity": "sha512-HNuzo76mD6Ykc/xMEyCMH+to6/Xi+7ehG3VYToSm+R3196Ki5p58pyRHzvq9CrBDvFd3SLMe9QqRm2GTg3wn/w==", + "version": "9.2.11", + "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-9.2.11.tgz", + "integrity": "sha512-zlpM4Bg1ifBziW1Juiii9NY5gyW2rEhyVTWnhagH/bpTCZ2E73OhnToYt1ouqmoxL6lMtIjhRXz6LPb7tJbHHQ==", "license": "MIT", "dependencies": { - "@luma.gl/constants": "^9.2.6", - "@luma.gl/shadertools": "^9.2.6", + "@luma.gl/constants": "~9.2.6", + "@luma.gl/shadertools": "~9.2.6", "@math.gl/core": "^4.1.0" }, "peerDependencies": { @@ -3020,22 +2966,6 @@ "@luma.gl/engine": "~9.2.4" } }, - "node_modules/@deck.gl/mapbox": { - "version": "9.2.11", - "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-9.2.11.tgz", - "integrity": "sha512-5OaFZgjyA4Vq6WjHUdcEdl0Phi8dwj8hSCErej0NetW90mctdbxwMt0gSbqcvWBowwhyj2QAhH0P2FcITjKG/A==", - "license": "MIT", - "dependencies": { - "@luma.gl/constants": "~9.2.6", - "@math.gl/web-mercator": "^4.1.0" - }, - "peerDependencies": { - "@deck.gl/core": "~9.2.0", - "@luma.gl/constants": "~9.2.6", - "@luma.gl/core": "~9.2.6", - "@math.gl/web-mercator": "^4.1.0" - } - }, "node_modules/@deck.gl/mesh-layers": { "version": "9.2.6", "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-9.2.6.tgz", @@ -3068,9 +2998,9 @@ } }, "node_modules/@deck.gl/widgets": { - "version": "9.2.6", - "resolved": "https://registry.npmjs.org/@deck.gl/widgets/-/widgets-9.2.6.tgz", - "integrity": "sha512-WkKP+HB90x1qwOxs5l6Dg0d1iAvf999jJGDdGUbDVsRF7+hJDv03GZY6XKpoiEW7VfcZ1y1iU2vRwV/GHuQ57g==", + "version": "9.2.11", + "resolved": "https://registry.npmjs.org/@deck.gl/widgets/-/widgets-9.2.11.tgz", + "integrity": "sha512-90HWlQPsiRyTPWR4aYfLwnYDrJdHG2mqCzRcyMUKewWBNQLu4upB//l4ewIkUeXXCzAprjjVeRnNb7wdYj2CXQ==", "license": "MIT", "peer": true, "dependencies": { @@ -3700,9 +3630,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz", - "integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", "cpu": [ "arm64" ], @@ -3734,9 +3664,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz", - "integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", "cpu": [ "arm64" ], @@ -3768,9 +3698,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz", - "integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", "cpu": [ "arm64" ], @@ -3885,9 +3815,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { @@ -3919,9 +3849,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -3942,22 +3872,6 @@ "dev": true, "license": "Python-2.0" }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", @@ -3978,19 +3892,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@eslint/js": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", @@ -4019,6 +3920,15 @@ } } }, + "node_modules/@fontsource/fira-code": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@fontsource/fira-code/-/fira-code-5.2.7.tgz", + "integrity": "sha512-tnB9NNund9TwIym8/7DMJe573nlPEQb+fKUV5GL8TBYXjIhDvL0D7mgmNVNQUPhXp+R7RylQeiBdkA4EbOHPGQ==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@fontsource/ibm-plex-mono": { "version": "5.2.7", "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.2.7.tgz", @@ -4029,11 +3939,10 @@ } }, "node_modules/@fontsource/inter": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.2.6.tgz", - "integrity": "sha512-CZs9S1CrjD0jPwsNy9W6j0BhsmRSQrgwlTNkgQXTsAeDRM42LBRLo3eo9gCzfH4GvV7zpyf78Ozfl773826csw==", + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.2.8.tgz", + "integrity": "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg==", "license": "OFL-1.1", - "peer": true, "funding": { "url": "https://github.com/sponsors/ayuhito" } @@ -4060,6 +3969,26 @@ "node": ">=12.0.0" } }, + "node_modules/@great-expectations/jsonforms-antd-renderers": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@great-expectations/jsonforms-antd-renderers/-/jsonforms-antd-renderers-2.3.5.tgz", + "integrity": "sha512-nWJQCX6zg2mQNk+QT5SFZUkaq2SNDRO5H7zoJmNvlndd0Byoq6AaB+UTdGt/SpO1knJFe80mmiWwh99fY/go3A==", + "license": "MIT", + "dependencies": { + "lodash.isempty": "^4.4.0", + "lodash.merge": "^4.6.2", + "lodash.range": "^3.2.0", + "lodash.startcase": "^4.4.0" + }, + "peerDependencies": { + "@ant-design/icons": "^5.3.0", + "@jsonforms/core": "^3.3.0", + "@jsonforms/react": "^3.3.0", + "antd": "^5.14.0", + "dayjs": "^1", + "react": "^17 || ^18" + } + }, "node_modules/@hapi/address": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-5.1.1.tgz", @@ -4247,16 +4176,6 @@ } } }, - "node_modules/@inquirer/core/node_modules/mute-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", - "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, "node_modules/@inquirer/core/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -4320,6 +4239,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, "license": "MIT", "dependencies": { "chardet": "^2.1.1", @@ -4338,9 +4258,10 @@ } }, "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -4357,6 +4278,7 @@ "version": "1.0.15", "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -4568,9 +4490,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -4581,9 +4503,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -4612,13 +4534,13 @@ } }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -4825,9 +4747,9 @@ } }, "node_modules/@jest/console/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -5018,9 +4940,9 @@ } }, "node_modules/@jest/core/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -5177,9 +5099,9 @@ } }, "node_modules/@jest/create-cache-key-function/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -5201,9 +5123,9 @@ } }, "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", + "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", "dev": true, "license": "MIT", "engines": { @@ -5253,16 +5175,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/expect/node_modules/@jest/diff-sequences": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", - "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/expect/node_modules/@jest/expect-utils": { "version": "30.3.0", "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", @@ -5309,9 +5221,9 @@ } }, "node_modules/@jest/expect/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -5598,16 +5510,16 @@ } }, "node_modules/@jest/globals/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, "node_modules/@jest/globals/node_modules/@sinonjs/fake-timers": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz", + "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -5826,33 +5738,20 @@ } }, "node_modules/@jest/reporters/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, - "node_modules/@jest/reporters/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" + "balanced-match": "^1.0.0" } }, "node_modules/@jest/reporters/node_modules/chalk": { @@ -5981,13 +5880,13 @@ } }, "node_modules/@jest/reporters/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -6109,9 +6008,9 @@ } }, "node_modules/@jest/snapshot-utils/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -6196,9 +6095,9 @@ } }, "node_modules/@jest/test-result/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -6304,9 +6203,9 @@ } }, "node_modules/@jest/transform/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -6451,15 +6350,54 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.30", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", - "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsonforms/core": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@jsonforms/core/-/core-3.7.0.tgz", + "integrity": "sha512-CE9viWtwi9QWLqlWLeOul1/R1GRAyOA9y6OoUpsCc0FhyR+g5p29F3k0fUExHWxL0Sf4KHcXYkfhtqfRBPS8ww==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.3", + "ajv": "^8.6.1", + "ajv-formats": "^2.1.0", + "lodash": "^4.17.21" + } + }, + "node_modules/@jsonforms/react": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@jsonforms/react/-/react-3.7.0.tgz", + "integrity": "sha512-HkY7qAx8vW97wPEgZ7GxCB3iiXG1c95GuObxtcDHGPBJWMwnxWBnVYJmv5h7nthrInKsQKHZL5OusnC/sj/1GQ==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + }, + "peerDependencies": { + "@jsonforms/core": "3.7.0", + "react": "^16.12.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@jsonforms/vanilla-renderers": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@jsonforms/vanilla-renderers/-/vanilla-renderers-3.7.0.tgz", + "integrity": "sha512-RdXQGsheARUJVbaTe6SqGw9W4/yrm0BgUok6OKUj8krp1NF4fqXc5UbYGHFksMR/p7LCuoYHCtQzKLXEfxJbDw==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + }, + "peerDependencies": { + "@jsonforms/core": "3.7.0", + "@jsonforms/react": "3.7.0", + "react": "^16.12.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@jsonjoy.com/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", @@ -6477,17 +6415,369 @@ "tslib": "2" } }, - "node_modules/@jsonjoy.com/json-pack": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.2.0.tgz", - "integrity": "sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==", + "node_modules/@jsonjoy.com/buffers": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", + "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.2.tgz", + "integrity": "sha512-SVjwklkpIV5wrynpYtuYnfYH1QF4/nDuLBX7VXdb+3miglcAgBVZb/5y0cOsehRV/9Vb+3UqhkMq3/NR3ztdkQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/base64": "^1.1.1", - "@jsonjoy.com/util": "^1.1.2", + "@jsonjoy.com/fs-node-builtins": "4.57.2", + "@jsonjoy.com/fs-node-utils": "4.57.2", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.2.tgz", + "integrity": "sha512-fhO8+iR2I+OCw668ISDJdn1aArc9zx033sWejIyzQ8RBeXa9bDSaUeA3ix0poYOfrj1KdOzytmYNv2/uLDfV6g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.2", + "@jsonjoy.com/fs-node-builtins": "4.57.2", + "@jsonjoy.com/fs-node-utils": "4.57.2", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.2.tgz", + "integrity": "sha512-nX2AdL6cOFwLdju9G4/nbRnYevmCJbh7N7hvR3gGm97Cs60uEjyd0rpR+YBS7cTg175zzl22pGKXR5USaQMvKg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.2", + "@jsonjoy.com/fs-node-builtins": "4.57.2", + "@jsonjoy.com/fs-node-utils": "4.57.2", + "@jsonjoy.com/fs-print": "4.57.2", + "@jsonjoy.com/fs-snapshot": "4.57.2", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.2.tgz", + "integrity": "sha512-xhiegylRmhw43Ki2HO1ZBL7DQ5ja/qpRsL29VtQ2xuUHiuDGbgf2uD4p9Qd8hJI5P6RCtGYD50IXHXVq/Ocjcg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.2.tgz", + "integrity": "sha512-18LmWTSONhoAPW+IWRuf8w/+zRolPFGPeGwMxlAhhfY11EKzX+5XHDBPAw67dBF5dxDErHJbl40U+3IXSDRXSQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.57.2", + "@jsonjoy.com/fs-node-builtins": "4.57.2", + "@jsonjoy.com/fs-node-utils": "4.57.2" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.2.tgz", + "integrity": "sha512-rsPSJgekz43IlNbLyAM/Ab+ouYLWGp5DDBfYBNNEqDaSpsbXfthBn29Q4muFA9L0F+Z3mKo+CWlgSCXrf+mOyQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.2" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.2.tgz", + "integrity": "sha512-wK9NSow48i4DbDl9F1CQE5TqnyZOJ04elU3WFG5aJ76p+YxO/ulyBBQvKsessPxdo381Bc2pcEoyPujMOhcRqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.57.2", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.2.tgz", + "integrity": "sha512-GdduDZuoP5V/QCgJkx9+BZ6SC0EZ/smXAdTS7PfMqgMTGXLlt/bH/FqMYaqB9JmLf05sJPtO0XRbAwwkEEPbVw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.57.2", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", + "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", + "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", + "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "17.67.0", + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0", + "@jsonjoy.com/json-pointer": "17.67.0", + "@jsonjoy.com/util": "17.67.0", "hyperdyperid": "^1.2.0", - "thingies": "^1.20.0" + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", + "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/util": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", + "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.2.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.2", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" }, "engines": { "node": ">=10.0" @@ -6501,9 +6791,30 @@ } }, "node_modules/@jsonjoy.com/util": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.6.0.tgz", - "integrity": "sha512-sw/RMbehRhN68WRtcKCpQOPfnH6lLP4GJfqzi3iYej8tnzpZUDr6UkZYJjcjjC0FWEJOJbyM3PTIwxucUmDG2A==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -7037,13 +7348,10 @@ } }, "node_modules/@maplibre/geojson-vt": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-6.0.4.tgz", - "integrity": "sha512-HYv3POhMRCdhP3UPPATM/hfcy6/WuVIf5FKboH8u/ZuFMTnAIcSVlq5nfOqroLokd925w2QtE7YwquFOIacwVQ==", - "license": "ISC", - "dependencies": { - "kdbush": "^4.0.2" - } + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-5.0.4.tgz", + "integrity": "sha512-KGg9sma45S+stfH9vPCJk1J0lSDLWZgCT9Y8u8qWZJyjFlP8MNP1WGTxIMYJZjDvVT3PDn05kN1C95Sut1HpgQ==", + "license": "ISC" }, "node_modules/@maplibre/maplibre-gl-style-spec": { "version": "24.8.1", @@ -7071,12 +7379,6 @@ "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", "license": "MIT" }, - "node_modules/@maplibre/maplibre-gl-style-spec/node_modules/quickselect": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", - "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", - "license": "ISC" - }, "node_modules/@maplibre/maplibre-gl-style-spec/node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", @@ -7130,12 +7432,6 @@ "pbf": "^4.0.1" } }, - "node_modules/@maplibre/vt-pbf/node_modules/@maplibre/geojson-vt": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-5.0.4.tgz", - "integrity": "sha512-KGg9sma45S+stfH9vPCJk1J0lSDLWZgCT9Y8u8qWZJyjFlP8MNP1WGTxIMYJZjDvVT3PDn05kN1C95Sut1HpgQ==", - "license": "ISC" - }, "node_modules/@maplibre/vt-pbf/node_modules/pbf": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz", @@ -7298,6 +7594,18 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7389,9 +7697,9 @@ } }, "node_modules/@npmcli/agent/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -7469,23 +7777,10 @@ "node": "18 || 20 || >=22" } }, - "node_modules/@npmcli/arborist/node_modules/hosted-git-info": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^11.1.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/@npmcli/arborist/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -7493,13 +7788,13 @@ } }, "node_modules/@npmcli/arborist/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -7647,9 +7942,9 @@ } }, "node_modules/@npmcli/git/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -7767,9 +8062,9 @@ } }, "node_modules/@npmcli/map-workspaces/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -7777,13 +8072,13 @@ } }, "node_modules/@npmcli/map-workspaces/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -7933,19 +8228,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@npmcli/package-json/node_modules/hosted-git-info": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^11.1.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/@npmcli/package-json/node_modules/jackspeak": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", @@ -7963,9 +8245,9 @@ } }, "node_modules/@npmcli/package-json/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -7973,13 +8255,13 @@ } }, "node_modules/@npmcli/package-json/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -8197,19 +8479,6 @@ "node": "18 || 20 || >=22" } }, - "node_modules/@nx/devkit/node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/@nx/devkit/node_modules/minimatch": { "version": "10.2.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", @@ -8374,9 +8643,9 @@ "license": "MIT" }, "node_modules/@oxlint/binding-android-arm-eabi": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.56.0.tgz", - "integrity": "sha512-IyfYPthZyiSKwAv/dLjeO18SaK8MxLI9Yss2JrRDyweQAkuL3LhEy7pwIwI7uA3KQc1Vdn20kdmj3q0oUIQL6A==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.62.0.tgz", + "integrity": "sha512-pKsthNECyvJh8lPTICz6VcwVy2jOqdhhsp1rlxCkhgZR47aKvXPmaRWQDv+zlXpRae4qm1MaaTnutkaOk5aofg==", "cpu": [ "arm" ], @@ -8391,9 +8660,9 @@ } }, "node_modules/@oxlint/binding-android-arm64": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.56.0.tgz", - "integrity": "sha512-Ga5zYrzH6vc/VFxhn6MmyUnYEfy9vRpwTIks99mY3j6Nz30yYpIkWryI0QKPCgvGUtDSXVLEaMum5nA+WrNOSg==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.62.0.tgz", + "integrity": "sha512-b1AUNViByvgmR2xJDubvLIr+dSuu3uraG7bsAoKo+xrpspPvu6RIn6Fhr2JUhobfep3jwUTy18Huco6GkwdvGQ==", "cpu": [ "arm64" ], @@ -8408,9 +8677,9 @@ } }, "node_modules/@oxlint/binding-darwin-arm64": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.56.0.tgz", - "integrity": "sha512-ogmbdJysnw/D4bDcpf1sPLpFThZ48lYp4aKYm10Z/6Nh1SON6NtnNhTNOlhEY296tDFItsZUz+2tgcSYqh8Eyw==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.62.0.tgz", + "integrity": "sha512-iG+Tvf70UJ6otfwFYIHk36Sjq9cpPP5YLxkoggANNRtzgi3Tj3g8q6Ybqi6AtkU3+yg9QwF7bDCkCS6bbL4PCg==", "cpu": [ "arm64" ], @@ -8425,9 +8694,9 @@ } }, "node_modules/@oxlint/binding-darwin-x64": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.56.0.tgz", - "integrity": "sha512-x8QE1h+RAtQ2g+3KPsP6Fk/tdz6zJQUv5c7fTrJxXV3GHOo+Ry5p/PsogU4U+iUZg0rj6hS+E4xi+mnwwlDCWQ==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.62.0.tgz", + "integrity": "sha512-oOWI6YPPr5AJUx+yIDlxmuUbQjS5gZX3OH3QisawYvsZgLiQVvZtR0rPBcJTxLWqt2ClrWg0DlSrlUiG5SQNHg==", "cpu": [ "x64" ], @@ -8442,9 +8711,9 @@ } }, "node_modules/@oxlint/binding-freebsd-x64": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.56.0.tgz", - "integrity": "sha512-6G+WMZvwJpMvY7my+/SHEjb7BTk/PFbePqLpmVmUJRIsJMy/UlyYqjpuh0RCgYYkPLcnXm1rUM04kbTk8yS1Yg==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.62.0.tgz", + "integrity": "sha512-dLP33T7VLCmLVv4cvjkVX+rmkcwNk2UfxmsZPNur/7BQHoQR60zJ7XLiRvNUawlzn0u8ngCa3itjEG73MAMa/w==", "cpu": [ "x64" ], @@ -8459,9 +8728,9 @@ } }, "node_modules/@oxlint/binding-linux-arm-gnueabihf": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.56.0.tgz", - "integrity": "sha512-YYHBsk/sl7fYwQOok+6W5lBPeUEvisznV/HZD2IfZmF3Bns6cPC3Z0vCtSEOaAWTjYWN3jVsdu55jMxKlsdlhg==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.62.0.tgz", + "integrity": "sha512-fl//LWNks6qo9chNY60UDYyIwtp7a5cEx4Y/rHPjaarhuwqx6jtbzEpD5V5AqmdL4a6Y5D8zeXg5HF2Cr0QmSQ==", "cpu": [ "arm" ], @@ -8476,9 +8745,9 @@ } }, "node_modules/@oxlint/binding-linux-arm-musleabihf": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.56.0.tgz", - "integrity": "sha512-+AZK8rOUr78y8WT6XkDb04IbMRqauNV+vgT6f8ZLOH8wnpQ9i7Nol0XLxAu+Cq7Sb+J9wC0j6Km5hG8rj47/yQ==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.62.0.tgz", + "integrity": "sha512-i5vkAuxvueTODV3J2dL61/TXewDHhMFKvtD156cIsk7GsdfiAu7zW7kY0NJXhKeFHeiMZIh7eFNjkPYH6J47HQ==", "cpu": [ "arm" ], @@ -8493,9 +8762,9 @@ } }, "node_modules/@oxlint/binding-linux-arm64-gnu": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.56.0.tgz", - "integrity": "sha512-urse2SnugwJRojUkGSSeH2LPMaje5Q50yQtvtL9HFckiyeqXzoFwOAZqD5TR29R2lq7UHidfFDM9EGcchcbb8A==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.62.0.tgz", + "integrity": "sha512-QwN19LLuIGuOjEflSeJkZmOTfBdBMlTmW8xbMf8TZhjd//cxVNYQPq75q7oKZBJc6hRx3gY7sX0Egc8cEIFZYg==", "cpu": [ "arm64" ], @@ -8510,9 +8779,9 @@ } }, "node_modules/@oxlint/binding-linux-arm64-musl": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.56.0.tgz", - "integrity": "sha512-rkTZkBfJ4TYLjansjSzL6mgZOdN5IvUnSq3oNJSLwBcNvy3dlgQtpHPrRxrCEbbcp7oQ6If0tkNaqfOsphYZ9g==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.62.0.tgz", + "integrity": "sha512-8eCy3FCDuWUM5hWujAv6heMvfZPbcCOU3SdQUAkixZLu5bSzOkNfirJiLGoQFO943xceOKkiQRMQNzH++jM3WA==", "cpu": [ "arm64" ], @@ -8527,9 +8796,9 @@ } }, "node_modules/@oxlint/binding-linux-ppc64-gnu": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.56.0.tgz", - "integrity": "sha512-uqL1kMH3u69/e1CH2EJhP3CP28jw2ExLsku4o8RVAZ7fySo9zOyI2fy9pVlTAp4voBLVgzndXi3SgtdyCTa2aA==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.62.0.tgz", + "integrity": "sha512-NjQ7K7tpTPDe9J+yq8p/s/J0E7lRCkK2uDBDqvT4XIT6f4Z0tlnr59OBg/WcrmVHER1AbrcfyxhGTXgcG8ytWg==", "cpu": [ "ppc64" ], @@ -8544,9 +8813,9 @@ } }, "node_modules/@oxlint/binding-linux-riscv64-gnu": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.56.0.tgz", - "integrity": "sha512-j0CcMBOgV6KsRaBdsebIeiy7hCjEvq2KdEsiULf2LZqAq0v1M1lWjelhCV57LxsqaIGChXFuFJ0RiFrSRHPhSg==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.62.0.tgz", + "integrity": "sha512-oKZed9gmSwze29dEt3/Wnsv6l/Ygw/FUst+8Kfpv2SGeS/glEoTGZAMQw37SVyzFV76UTHJN2snGgxK2t2+8ow==", "cpu": [ "riscv64" ], @@ -8561,9 +8830,9 @@ } }, "node_modules/@oxlint/binding-linux-riscv64-musl": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.56.0.tgz", - "integrity": "sha512-7VDOiL8cDG3DQ/CY3yKjbV1c4YPvc4vH8qW09Vv+5ukq3l/Kcyr6XGCd5NvxUmxqDb2vjMpM+eW/4JrEEsUetA==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.62.0.tgz", + "integrity": "sha512-gBjBxQ+9lGpAYq+ELqw0w8QXsBnkZclFc7GRX2r0LnEVn3ZTEqeIKpKcGjucmp76Q53bvJD0i4qBWBhcfhSfGA==", "cpu": [ "riscv64" ], @@ -8578,9 +8847,9 @@ } }, "node_modules/@oxlint/binding-linux-s390x-gnu": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.56.0.tgz", - "integrity": "sha512-JGRpX0M+ikD3WpwJ7vKcHKV6Kg0dT52BW2Eu2BupXotYeqGXBrbY+QPkAyKO6MNgKozyTNaRh3r7g+VWgyAQYQ==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.62.0.tgz", + "integrity": "sha512-Ew2Kxs9EQ9/mbAIJ2hvocMC0wsOu6YKzStI2eFBDt+Td5O8seVC/oxgRIHqCcl5sf5ratA1nozQBAuv7tphkHg==", "cpu": [ "s390x" ], @@ -8595,9 +8864,9 @@ } }, "node_modules/@oxlint/binding-linux-x64-gnu": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.56.0.tgz", - "integrity": "sha512-dNaICPvtmuxFP/VbqdofrLqdS3bM/AKJN3LMJD52si44ea7Be1cBk6NpfIahaysG9Uo+L98QKddU9CD5L8UHnQ==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.62.0.tgz", + "integrity": "sha512-5z25jcAA0gfKyVwz71A0VXgaPlocPoTAxhlv/hgoK6tlCrfoNuw7haWbDHvGMfjXhdic4EqVXGRv5XsTqFnbRQ==", "cpu": [ "x64" ], @@ -8612,9 +8881,9 @@ } }, "node_modules/@oxlint/binding-linux-x64-musl": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.56.0.tgz", - "integrity": "sha512-pF1vOtM+GuXmbklM1hV8WMsn6tCNPvkUzklj/Ej98JhlanbmA2RB1BILgOpwSuCTRTIYx2MXssmEyQQ90QF5aA==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.62.0.tgz", + "integrity": "sha512-IWpHmMB6ZDllPvqWDkG6AmXrN7JF5e/c4g/0PuURsmlK+vHoYZPB70rr4u1bn3I4LsKCSpqqfveyx6UCOC8wdg==", "cpu": [ "x64" ], @@ -8629,9 +8898,9 @@ } }, "node_modules/@oxlint/binding-openharmony-arm64": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.56.0.tgz", - "integrity": "sha512-bp8NQ4RE6fDIFLa4bdBiOA+TAvkNkg+rslR+AvvjlLTYXLy9/uKAYLQudaQouWihLD/hgkrXIKKzXi5IXOewwg==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.62.0.tgz", + "integrity": "sha512-fjlSxxrD5pA594vkyikCS9MnPRjQawW6/BLgyTYkO+73wwPlYjkcZ7LSd974l0Q2zkHQmu4DPvJFLYA7o8xrxQ==", "cpu": [ "arm64" ], @@ -8646,9 +8915,9 @@ } }, "node_modules/@oxlint/binding-win32-arm64-msvc": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.56.0.tgz", - "integrity": "sha512-PxT4OJDfMOQBzo3OlzFb9gkoSD+n8qSBxyVq2wQSZIHFQYGEqIRTo9M0ZStvZm5fdhMqaVYpOnJvH2hUMEDk/g==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.62.0.tgz", + "integrity": "sha512-EiFXr8loNS0Ul3Gu80+9nr1T8jRmnKocqmHHg16tj5ZqTgUXyb97l2rrspVHdDluyFn9JfR4PoJFdNzw4paHww==", "cpu": [ "arm64" ], @@ -8663,9 +8932,9 @@ } }, "node_modules/@oxlint/binding-win32-ia32-msvc": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.56.0.tgz", - "integrity": "sha512-PTRy6sIEPqy2x8PTP1baBNReN/BNEFmde0L+mYeHmjXE1Vlcc9+I5nsqENsB2yAm5wLkzPoTNCMY/7AnabT4/A==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.62.0.tgz", + "integrity": "sha512-IgOFvL73li1bFgab+hThXYA0N2Xms2kV2MvZN95cebV+fmrZ9AVui1JSxfeeqRLo3CpPxKZlzhyq4G0cnaAvIw==", "cpu": [ "ia32" ], @@ -8680,9 +8949,9 @@ } }, "node_modules/@oxlint/binding-win32-x64-msvc": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.56.0.tgz", - "integrity": "sha512-ZHa0clocjLmIDr+1LwoWtxRcoYniAvERotvwKUYKhH41NVfl0Y4LNbyQkwMZzwDvKklKGvGZ5+DAG58/Ik47tQ==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.62.0.tgz", + "integrity": "sha512-6hMpyDWQ2zGA1OXFKBrdYMUveUCO8UJhkO6JdwZPd78xIdHZNhjx+pib+4fC2Cljuhjyl0QwA2F3df/bs4Bp6A==", "cpu": [ "x64" ], @@ -9299,6 +9568,89 @@ "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==", "license": "MIT" }, + "node_modules/@rjsf/antd": { + "version": "5.24.13", + "resolved": "https://registry.npmjs.org/@rjsf/antd/-/antd-5.24.13.tgz", + "integrity": "sha512-UiWE8xoBxxCoe/SEkdQEmL5E6z3I1pw0+y0dTyGt8SHfAxxFc4/OWn7tKOAiNsKCXgf83t0JKn6CHWLD01sAdQ==", + "license": "Apache-2.0", + "dependencies": { + "classnames": "^2.5.1", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "rc-picker": "2.7.6" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@ant-design/icons": "^4.0.0 || ^5.0.0", + "@rjsf/core": "^5.24.x", + "@rjsf/utils": "^5.24.x", + "antd": "^4.24.0 || ^5.8.5", + "dayjs": "^1.8.0", + "react": "^16.14.0 || >=17" + } + }, + "node_modules/@rjsf/antd/node_modules/rc-picker": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-2.7.6.tgz", + "integrity": "sha512-H9if/BUJUZBOhPfWcPeT15JUI3/ntrG9muzERrXDkSoWmDj4yzmBvumozpxYrHwjcKnjyDGAke68d+whWwvhHA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "date-fns": "2.x", + "dayjs": "1.x", + "moment": "^2.24.0", + "rc-trigger": "^5.0.4", + "rc-util": "^5.37.0", + "shallowequal": "^1.1.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rjsf/antd/node_modules/rc-picker/node_modules/rc-trigger": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.3.4.tgz", + "integrity": "sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "classnames": "^2.2.6", + "rc-align": "^4.0.0", + "rc-motion": "^2.0.0", + "rc-util": "^5.19.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rjsf/antd/node_modules/rc-picker/node_modules/rc-trigger/node_modules/rc-align": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.15.tgz", + "integrity": "sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "dom-align": "^1.7.0", + "rc-util": "^5.26.0", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, "node_modules/@rjsf/core": { "version": "5.24.13", "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.24.13.tgz", @@ -9619,20 +9971,33 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/@simple-git/args-pathspec": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@simple-git/args-pathspec/-/args-pathspec-1.0.3.tgz", + "integrity": "sha512-ngJMaHlsWDTfjyq9F3VIQ8b7NXbBLq5j9i5bJ6XLYtD6qlDXT7fdKY2KscWWUF8t18xx052Y/PUO1K1TRc9yKA==", + "license": "MIT" + }, + "node_modules/@simple-git/argv-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@simple-git/argv-parser/-/argv-parser-1.1.1.tgz", + "integrity": "sha512-Q9lBcfQ+VQCpQqGJFHe5yooOS5hGdLFFbJ5R+R5aDsnkPCahtn1hSkMcORX65J2Z5lxSkD0lQorMsncuBQxYUw==", + "license": "MIT", + "dependencies": { + "@simple-git/args-pathspec": "^1.0.3" + } + }, "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", + "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", "dev": true, "license": "MIT" }, "node_modules/@sindresorhus/merge-streams": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", - "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=18" }, @@ -9668,9 +10033,9 @@ "license": "MIT" }, "node_modules/@storybook/addon-actions": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.17.tgz", - "integrity": "sha512-/G3Y7WIzGHMtKT6r3KCqgY/pAzfMhNHvBoRWoPfxMa27GiwmUaJlbfRPSReK/jGz6ye0Uwqix+NFbRXKiTqOJQ==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.18.tgz", + "integrity": "sha512-GcYhtE91GjIQTuZlwpTJ8jfMp6NC79nkpe1DGe0eetTpyQqLq1WUt+ACkk0Z5lqq2u8HBc09zCCGw+D8iCLpYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9685,7 +10050,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-actions/node_modules/uuid": { @@ -9703,9 +10068,9 @@ } }, "node_modules/@storybook/addon-controls": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.17.tgz", - "integrity": "sha512-kquUfiJyJMh8IHviTIz1A4UKqqNfvqrYFku9D3UukqkTriM1ngDOb9nryaJcUNTkco5JmIuGjYEJisva+u13lw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.18.tgz", + "integrity": "sha512-K09dHDCfGW3cudsfuyfu0Yi49aZ2h7VYK4IXDGo1sfmtzVh4xd3HrZQQMVUeKLcfDP/NnJowT+fLVwg04CLrxQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9718,25 +10083,25 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-essentials": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.17.tgz", - "integrity": "sha512-nyp2RUxWGpD+xhGWOo221kHOY6cZlgXsV1F11sn7WxkH+yA7YHhLLYlIPHmNKKH+hdxN0rnlcpwjbr21u0Katg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.18.tgz", + "integrity": "sha512-MmH7gFb8pyfRoAth0w2RW8j7mBaEJbEWGP3juIoH03ZqTGmbMUbJXElCuRgxQhve7pyz39zLsgtE78D7G+76ew==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/addon-actions": "8.6.17", - "@storybook/addon-backgrounds": "8.6.17", - "@storybook/addon-controls": "8.6.17", - "@storybook/addon-docs": "8.6.17", - "@storybook/addon-highlight": "8.6.17", - "@storybook/addon-measure": "8.6.17", - "@storybook/addon-outline": "8.6.17", - "@storybook/addon-toolbars": "8.6.17", - "@storybook/addon-viewport": "8.6.17", + "@storybook/addon-actions": "8.6.18", + "@storybook/addon-backgrounds": "8.6.18", + "@storybook/addon-controls": "8.6.18", + "@storybook/addon-docs": "8.6.18", + "@storybook/addon-highlight": "8.6.18", + "@storybook/addon-measure": "8.6.18", + "@storybook/addon-outline": "8.6.18", + "@storybook/addon-toolbars": "8.6.18", + "@storybook/addon-viewport": "8.6.18", "ts-dedent": "^2.0.0" }, "funding": { @@ -9744,13 +10109,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-backgrounds": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.17.tgz", - "integrity": "sha512-oh7jEQUt8WhH7cBm0jsJ1dujyaujM5rVS5IXJmDgdFJ8l0pqGzOUDmgkBVX147Uo5W1U47Sx+hA69lg6TKPOMQ==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.18.tgz", + "integrity": "sha512-froND3WwvSCYzjEBO8QODStaWNL+aGXqxBEbrMnGYejDFST4qEFkvM2IYWMnLBkRgrgJ0yIqTeDQoyH9b9/8uQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9763,20 +10128,20 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-docs": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.17.tgz", - "integrity": "sha512-zvcSzoYvaZO4l9NxsviDr5vmuq8GVnH4Ap0v+5sSTq192yevm/iQcRnkWYBD9E/Lg5GBeyE+Ml2vjEOK+EPBEg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.18.tgz", + "integrity": "sha512-55ADer0yNmmeR928Y3UAv3r4i7bJSd9LwywsQ+lRol/FNe0ZcwLEz31xL+jVsqQFNnDh/imsDIp8aYapGMtfEQ==", "dev": true, "license": "MIT", "dependencies": { "@mdx-js/react": "^3.0.0", - "@storybook/blocks": "8.6.17", - "@storybook/csf-plugin": "8.6.17", - "@storybook/react-dom-shim": "8.6.17", + "@storybook/blocks": "8.6.18", + "@storybook/csf-plugin": "8.6.18", + "@storybook/react-dom-shim": "8.6.18", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" @@ -9786,13 +10151,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-docs/node_modules/@storybook/blocks": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.17.tgz", - "integrity": "sha512-zuYHH+0egovMrjWRKwOtgVGbz6KALGowPSWBzQ8deTBu6IXfkz6Ce1hRLJPn5S6/jDqqr9xx8vuAiypnRQ98tA==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.18.tgz", + "integrity": "sha512-esZv4msPQ9LxgTb8YUIZhhxVMuI6BPi5bkXtk8c7w7sWuAsqsCe/RnVInn7ooUry2gjnD4hd9+8Eqj0b8oTVoA==", "dev": true, "license": "MIT", "dependencies": { @@ -9806,7 +10171,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "8.6.17" + "storybook": "8.6.18" }, "peerDependenciesMeta": { "react": { @@ -9818,9 +10183,9 @@ } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-docs/node_modules/@storybook/csf-plugin": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.17.tgz", - "integrity": "sha512-ouvF/izbKclZxpfnRUkyC5ZVDU7QA0cHhjQnXTDT4F8b0uciQUDw1LosDZy5MXf03BeIDdyBAtzd/ym3wzd+kw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.18.tgz", + "integrity": "sha512-x1ioz/L0CwaelCkHci3P31YtvwayN3FBftvwQOPbvRh9qeb4Cpz5IdVDmyvSxxYwXN66uAORNoqgjTi7B4/y5Q==", "dev": true, "license": "MIT", "dependencies": { @@ -9831,29 +10196,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" - } - }, - "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-docs/node_modules/@storybook/react-dom-shim": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.17.tgz", - "integrity": "sha512-bHLsR9b/tiwm9lXbN8kp9XlOgkRXeg84UFwXaWBPu3pOO7vRXukk23SQUpLW+HhjKtCJ3xClSi5uMpse5MpkVQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-highlight": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.17.tgz", - "integrity": "sha512-Tf7DxksSg+DqH0a0rLIpB5g9bJBUHcqmEGeYGX7EPQrXBpQAtFXz/XdzuD8eYDlPC1r42iQQw4w+CQnXJCOHFw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.18.tgz", + "integrity": "sha512-wTFJ1DPM0C8gK6nGTJxH75byayQj7BPAz02fME4AOmT6clrBpVl1zSTFTkXaSr+k4xOfeMR/xNUfVskaXz6T9w==", "dev": true, "license": "MIT", "dependencies": { @@ -9864,13 +10213,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-measure": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.17.tgz", - "integrity": "sha512-OFGmCrz9MTWfxa0t2GP+633VXZS7W3ahIM5bRmCTeG+jF/gdiVw3S2Adq7YiIZw+nROW9VtHBjuWGvy2miZxcQ==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.18.tgz", + "integrity": "sha512-fMEOJXgPrTm6qHlWoRM+WTLE7Mr1QBIf2ei+pujBQFcWkD6Gjc2pV8zKzvh93d+EA13wD8AmwOq1DEw9J+XH+g==", "dev": true, "license": "MIT", "dependencies": { @@ -9882,13 +10231,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-outline": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.17.tgz", - "integrity": "sha512-UfFThgImS8cuv9Mts5JozGO2/SgjU61uKZxn7w+YpJQu0r2UAF56ZBBMZF/Ur5IC4HaoqDWF5DksMlFqMHPBsw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.18.tgz", + "integrity": "sha512-TErFqfCtlV2xt9B6/kskROt69TPjr6AXdHpMselaRrN1X4WEjcMk9GT9PcNP7FXqL88/VYqUb3uNMiAmpDmS/g==", "dev": true, "license": "MIT", "dependencies": { @@ -9900,13 +10249,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-toolbars": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.17.tgz", - "integrity": "sha512-LoWtnMVQJWivAu+SZdgYIsaiEqIq0mZ8Ses2xSwLnQZxndCakyqPYv/7YcdLDJaX5f8DpjPvSzJ77oa75oKgFw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.18.tgz", + "integrity": "sha512-x037KXCEcNfPISGX485DtiP+8Bw/cOT45plcQa8eiAQVrVcUwYaDoLubE9YV5b5CsSAjX8sDviGTme6ALfq7+w==", "dev": true, "license": "MIT", "funding": { @@ -9914,13 +10263,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-viewport": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.17.tgz", - "integrity": "sha512-gVUtbFQq/mpD5CFOqXGAu5hUpGm/t5G/psg3YsTjnaRBd18dJZ/+//HzZVbX9aEW8t5qTJeJcEYaF5463BVfNA==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.18.tgz", + "integrity": "sha512-z9sDJSkuWQb4BP+Z1+H+y/Q0rFbPSDcw+OBBEhMfRcJPPXavdC2pNQ0GdQNVw+tDwhAXj+U7jehKnMDKaP7TyA==", "dev": true, "license": "MIT", "dependencies": { @@ -9931,13 +10280,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/addon-links": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.6.17.tgz", - "integrity": "sha512-ch1GgXILEmekf81nUvmre3xyhlg5zDibRxm8+psPqj7GqzWBI5l4kAiha0XOBWGz6vQEL5xCvN/rr8rfA9kWdQ==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.6.18.tgz", + "integrity": "sha512-FFlQcPRTgXoFZr2uawtf7lNc/ceIVRhU13BkJbJZKlil3+C8ORFDO1vnREzHje9JzeOWm/rzI0ay0RVetCcXzg==", "dev": true, "license": "MIT", "dependencies": { @@ -9950,7 +10299,7 @@ }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "8.6.17" + "storybook": "8.6.18" }, "peerDependenciesMeta": { "react": { @@ -9959,9 +10308,9 @@ } }, "node_modules/@storybook/addon-mdx-gfm": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/addon-mdx-gfm/-/addon-mdx-gfm-8.6.17.tgz", - "integrity": "sha512-6gfRnNmUVYJNHrnOjix2v2QmsiJQW1+yCWDneO0fc6FDxZKzASb/sENgOEe04AItrdzEjPeKEIdsa35vmPtqlA==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-mdx-gfm/-/addon-mdx-gfm-8.6.18.tgz", + "integrity": "sha512-u4+6N7wAjtEfXKQrve9vUyhVsRwSTBJPQdsEScfwoVjg+amCQQDhjbwB78gsCjrxXcbHtpqNM6DXHy8yvhocOg==", "dev": true, "license": "MIT", "dependencies": { @@ -9973,879 +10322,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-find-and-replace": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz", - "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-gfm": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz", - "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-gfm-autolink-literal": "^1.0.0", - "mdast-util-gfm-footnote": "^1.0.0", - "mdast-util-gfm-strikethrough": "^1.0.0", - "mdast-util-gfm-table": "^1.0.0", - "mdast-util-gfm-task-list-item": "^1.0.0", - "mdast-util-to-markdown": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-gfm-autolink-literal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz", - "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "ccount": "^2.0.0", - "mdast-util-find-and-replace": "^2.0.0", - "micromark-util-character": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-gfm-footnote": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz", - "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0", - "micromark-util-normalize-identifier": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-gfm-strikethrough": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz", - "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-gfm-table": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz", - "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-to-markdown": "^1.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-gfm-task-list-item": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz", - "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-phrasing": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", - "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-to-markdown": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", - "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^3.0.0", - "mdast-util-to-string": "^3.0.0", - "micromark-util-decode-string": "^1.0.0", - "unist-util-visit": "^4.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-extension-gfm": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz", - "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^1.0.0", - "micromark-extension-gfm-footnote": "^1.0.0", - "micromark-extension-gfm-strikethrough": "^1.0.0", - "micromark-extension-gfm-table": "^1.0.0", - "micromark-extension-gfm-tagfilter": "^1.0.0", - "micromark-extension-gfm-task-list-item": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-extension-gfm-autolink-literal": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz", - "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-extension-gfm-footnote": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz", - "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark-core-commonmark": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-extension-gfm-strikethrough": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz", - "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-extension-gfm-table": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz", - "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-extension-gfm-tagfilter": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz", - "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-extension-gfm-task-list-item": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz", - "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/remark-gfm": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", - "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-gfm": "^2.0.0", - "micromark-extension-gfm": "^2.0.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@storybook/addon-mdx-gfm/node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "storybook": "8.6.18" } }, "node_modules/@storybook/components": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.17.tgz", - "integrity": "sha512-0b8xkkuPCNbM8LTOzyfxuo2KdJCHIfu3+QxWBFllXap0eYNHwVeSxE5KERQ/bk2GDCiRzaUbwH9PeLorxOzJJQ==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.18.tgz", + "integrity": "sha512-55yViiZzPS/cPBuOeW4QGxGqrusjXVyxuknmbYCIwDtFyyvI/CgbjXRHdxNBaIjz+IlftxvBmmSaOqFG5+/dkA==", "dev": true, "license": "MIT", "funding": { @@ -10857,13 +10340,13 @@ } }, "node_modules/@storybook/core": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.17.tgz", - "integrity": "sha512-lndZDYIvUddWk54HmgYwE4h2B0JtWt8ztIRAzHRt6ReZZ9QQbmM5b85Qpa+ng4dyQEKc2JAtYD3Du7RRFcpHlw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.18.tgz", + "integrity": "sha512-dRBP2TnX6fGdS0T2mXBHjkS/3Nlu1ra1huovZVFuM67CYMzrhM/3hX/zru1vWSC5rqY93ZaAhjMciPW4pK5mMQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/theming": "8.6.17", + "@storybook/theming": "8.6.18", "better-opn": "^3.0.2", "browser-assert": "^1.2.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", @@ -10902,6 +10385,23 @@ "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" } }, + "node_modules/@storybook/core-webpack": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.6.18.tgz", + "integrity": "sha512-M+y/DFbiT3CJYQ90wJdXT4WxYImphof1f11StZSxJGo0u5PnCCdCze1qchXubApXRDO2T8HGxurXfhTEMqaGsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.18" + } + }, "node_modules/@storybook/csf": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.13.tgz", @@ -10948,9 +10448,9 @@ } }, "node_modules/@storybook/manager-api": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.17.tgz", - "integrity": "sha512-sPJytvClNrw5GgKcPletMTxDOAYcTRA8VRt9E+ncKvPSYHtPDqLfGTgWajXmt0hRsiBUN5bOgLS9bmNjNQWhrw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.18.tgz", + "integrity": "sha512-BjIp12gEMgzFkEsgKpDIbZdnSWTZpm2dlws8WiPJCpgJtG+HWSxZ0/Ms30Au9yfwzQEKRSbV/5zpsKMGc2SIJw==", "dev": true, "license": "MIT", "funding": { @@ -10962,9 +10462,9 @@ } }, "node_modules/@storybook/preview-api": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.17.tgz", - "integrity": "sha512-vpTCTkw11wXerYnlG5Q0y4SbFqG9O6GhR0hlYgCn3Z9kcHlNjK/xuwd3h4CvwNXxRNWZGT8qYYCLn5gSSrX6fA==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.18.tgz", + "integrity": "sha512-joXRXh3GdVvzhbfIgmix1xs90p8Q/nja7AhEAC2egn5Pl7SKsIYZUCYI6UdrQANb2myg9P552LKXfPect8llKg==", "dev": true, "license": "MIT", "funding": { @@ -10976,18 +10476,18 @@ } }, "node_modules/@storybook/react": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.17.tgz", - "integrity": "sha512-yoOzgyZ2VXPJBmvcKS4EVoAf7SJxXbMBcLjWGvmWdDnS+hd7S9cHG/SbgQ+9/vgiLUc+uEuvQjiKrwY3iOA5rg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.18.tgz", + "integrity": "sha512-BuLpzMkKtF+UCQCbi+lYVX9cdcAMG86Lu2dDn7UFkPi5HRNFq/zHPSvlz1XDgL0OYMtcqB1aoVzFzcyzUBhhjw==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/components": "8.6.17", + "@storybook/components": "8.6.18", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "8.6.17", - "@storybook/preview-api": "8.6.17", - "@storybook/react-dom-shim": "8.6.17", - "@storybook/theming": "8.6.17" + "@storybook/manager-api": "8.6.18", + "@storybook/preview-api": "8.6.18", + "@storybook/react-dom-shim": "8.6.18", + "@storybook/theming": "8.6.18" }, "engines": { "node": ">=18.0.0" @@ -10997,10 +10497,10 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "@storybook/test": "8.6.17", + "@storybook/test": "8.6.18", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "8.6.17", + "storybook": "8.6.18", "typescript": ">= 4.2.x" }, "peerDependenciesMeta": { @@ -11076,16 +10576,32 @@ "semver": "bin/semver.js" } }, + "node_modules/@storybook/react-dom-shim": { + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.18.tgz", + "integrity": "sha512-N4xULcAWZQTUv4jy1/d346Tyb4gufuC3UaLCuU/iVSZ1brYF4OW3ANr+096btbMxY8pR/65lmtoqr5CTGwnBvA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.6.18" + } + }, "node_modules/@storybook/react-webpack5": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/react-webpack5/-/react-webpack5-8.6.17.tgz", - "integrity": "sha512-61rMF7O+Un+XgfSODkkvpQv6QToMkYB1OJBqHMidW4/VROuA+G51a2+xTWD1JrwIU11uJQU2DeqHn6w2nc9blQ==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/react-webpack5/-/react-webpack5-8.6.18.tgz", + "integrity": "sha512-oh7V2//Nm6O+7J5b7v4l+BTxksMq7thCmy607diwSBZHYz6G2CxcW3GhxWwZzpHoUVX6vOR5Uc94u9+wBuPi7A==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/builder-webpack5": "8.6.17", - "@storybook/preset-react-webpack": "8.6.17", - "@storybook/react": "8.6.17" + "@storybook/builder-webpack5": "8.6.18", + "@storybook/preset-react-webpack": "8.6.18", + "@storybook/react": "8.6.18" }, "engines": { "node": ">=18.0.0" @@ -11097,7 +10613,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "8.6.17", + "storybook": "8.6.18", "typescript": ">= 4.2.x" }, "peerDependenciesMeta": { @@ -11107,13 +10623,13 @@ } }, "node_modules/@storybook/react-webpack5/node_modules/@storybook/builder-webpack5": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.6.17.tgz", - "integrity": "sha512-QK0HuTLn/doWQNu/tBC8tP0DrQLqyZk/IeYaxYh43G3igsYHI+yTIG//lHLSRFqkJM6tFT2SIJO8xExE/MCMGQ==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.6.18.tgz", + "integrity": "sha512-rg73TpqIUzXc66c/AaQ4kuc8yiZ+tStvy5fb1OnFYZ9rAeYQejDD0OIIaI2rqtX5XYuxC+yQEGitMntlIMV0og==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/core-webpack": "8.6.17", + "@storybook/core-webpack": "8.6.18", "@types/semver": "^7.3.4", "browser-assert": "^1.2.1", "case-sensitive-paths-webpack-plugin": "^2.4.0", @@ -11143,7 +10659,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" }, "peerDependenciesMeta": { "typescript": { @@ -11151,32 +10667,15 @@ } } }, - "node_modules/@storybook/react-webpack5/node_modules/@storybook/builder-webpack5/node_modules/@storybook/core-webpack": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.6.17.tgz", - "integrity": "sha512-q8acHGExmDdqUyzYoPrxp52bUQ3pEskXlcZIETReb3++pATv7zlSghPVA283O9jgj9jYfz9VYyRjW3vqzIzi0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "8.6.17" - } - }, "node_modules/@storybook/react-webpack5/node_modules/@storybook/preset-react-webpack": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.6.17.tgz", - "integrity": "sha512-gMEc6BL8hQIXwOK6yeDc9PMgHKJO6wNM2c8Cttmk9oZeq1YzwIdrQjcLVdKYINGVaQRqLFBvLTmCzz/qPtI5qg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.6.18.tgz", + "integrity": "sha512-UkioZsLIyKGQTAdVB3EMx4NyqwIPDRyuDTIQyCwlMcLYCJCs9Ks2ILbM1x1554/iqRIxy8Yv2IBMapK+euCwgg==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/core-webpack": "8.6.17", - "@storybook/react": "8.6.17", + "@storybook/core-webpack": "8.6.18", + "@storybook/react": "8.6.18", "@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0", "@types/semver": "^7.3.4", "find-up": "^5.0.0", @@ -11197,7 +10696,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "8.6.17" + "storybook": "8.6.18" }, "peerDependenciesMeta": { "typescript": { @@ -11205,27 +10704,10 @@ } } }, - "node_modules/@storybook/react-webpack5/node_modules/@storybook/preset-react-webpack/node_modules/@storybook/core-webpack": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.6.17.tgz", - "integrity": "sha512-q8acHGExmDdqUyzYoPrxp52bUQ3pEskXlcZIETReb3++pATv7zlSghPVA283O9jgj9jYfz9VYyRjW3vqzIzi0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "8.6.17" - } - }, "node_modules/@storybook/react-webpack5/node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -11416,31 +10898,15 @@ "node": ">= 6" } }, - "node_modules/@storybook/react/node_modules/@storybook/react-dom-shim": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.17.tgz", - "integrity": "sha512-bHLsR9b/tiwm9lXbN8kp9XlOgkRXeg84UFwXaWBPu3pOO7vRXukk23SQUpLW+HhjKtCJ3xClSi5uMpse5MpkVQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "8.6.17" - } - }, "node_modules/@storybook/test": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.17.tgz", - "integrity": "sha512-VTuCylXGQrFDZXqZ29+yvJ+A4TZ69jG72rLjiic8hI0SOt87AC/8X1NaYvd2NS4TY0G0PwqtxmKeig8qRDrhNg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.18.tgz", + "integrity": "sha512-u/RwfWMyHcH0N2hqfMTw2CoZ58IXdeED3b8NmcHc8bmERB3byI5vVAkwYbcD7+WeRHIiym38ZHi0SRn+IpkO3Q==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.6.17", + "@storybook/instrumenter": "8.6.18", "@testing-library/dom": "10.4.0", "@testing-library/jest-dom": "6.5.0", "@testing-library/user-event": "14.5.2", @@ -11452,7 +10918,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/test-runner": { @@ -11860,22 +11326,10 @@ "node": ">=8" } }, - "node_modules/@storybook/test-runner/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, "node_modules/@storybook/test-runner/node_modules/dedent": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", - "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "dev": true, "license": "MIT", "peerDependencies": { @@ -11887,52 +11341,6 @@ } } }, - "node_modules/@storybook/test-runner/node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/@storybook/test-runner/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/test-runner/node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/@storybook/test-runner/node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -12438,13 +11846,13 @@ } }, "node_modules/@storybook/test-runner/node_modules/jest-watch-typeahead/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -12473,185 +11881,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@storybook/test-runner/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/test-runner/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@storybook/test-runner/node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@storybook/test-runner/node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/@storybook/test-runner/node_modules/nyc/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@storybook/test-runner/node_modules/nyc/node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/test-runner/node_modules/nyc/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@storybook/test-runner/node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/test-runner/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/test-runner/node_modules/p-locate/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@storybook/test-runner/node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@storybook/test-runner/node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -12697,23 +11926,6 @@ ], "license": "MIT" }, - "node_modules/@storybook/test-runner/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@storybook/test-runner/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -12769,41 +11981,29 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/@storybook/test-runner/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@storybook/test-runner/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@storybook/test-runner/node_modules/yargs-parser/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/@storybook/test-runner/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, "engines": { - "node": ">=6" + "node": ">=12" } }, "node_modules/@storybook/test/node_modules/@storybook/instrumenter": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.17.tgz", - "integrity": "sha512-uPqC0sPY2tYGkEVi1x+L4hvhkTwxT16B/LB8xIXh68co3gR8vY6wVskoBp2tM7LSUGl08U2ksZWxyTo1DaQY5Q==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.18.tgz", + "integrity": "sha512-viEC1BGlYyjAzi1Tv3LZjByh7Y3Oh04u6QKsujxdeUbr5rUOH4pa/wCKmxXmY6yWrD4WjcNtojmUvQZN/66FXQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12815,7 +12015,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "8.6.17" + "storybook": "8.6.18" } }, "node_modules/@storybook/test/node_modules/@testing-library/dom": { @@ -12908,9 +12108,9 @@ } }, "node_modules/@storybook/theming": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.17.tgz", - "integrity": "sha512-IttFvRqozpuzN5MlQEWGOzUA2rZg86688Dyv1d+bjpYcFHtY1X4XyTCGwv1BPTaTsB959oM8R2yoNYWQkABbBA==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.18.tgz", + "integrity": "sha512-n6OEjEtHupa2PdTwWzRepr7cO8NkDd4rgF6BKLitRbujOspLxzMBEqdphs+QLcuiCIgf33SqmEA64QWnbSMhPw==", "dev": true, "license": "MIT", "funding": { @@ -13285,9 +12485,9 @@ } }, "node_modules/@swc/core": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.24.tgz", - "integrity": "sha512-5Hj8aNasue7yusUt8LGCUe/AjM7RMAce8ZoyDyiFwx7Al+GbYKL+yE7g4sJk8vEr1dKIkTRARkNIJENc4CjkBQ==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.32.tgz", + "integrity": "sha512-/eWL0n43D64QWEUHLtTE+jDqjkJhyidjkDhv6f0uJohOUAhywxQ9wXYp845DNNds0JpCdI4Uo0a9bl+vbXf+ew==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -13303,18 +12503,18 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.15.24", - "@swc/core-darwin-x64": "1.15.24", - "@swc/core-linux-arm-gnueabihf": "1.15.24", - "@swc/core-linux-arm64-gnu": "1.15.24", - "@swc/core-linux-arm64-musl": "1.15.24", - "@swc/core-linux-ppc64-gnu": "1.15.24", - "@swc/core-linux-s390x-gnu": "1.15.24", - "@swc/core-linux-x64-gnu": "1.15.24", - "@swc/core-linux-x64-musl": "1.15.24", - "@swc/core-win32-arm64-msvc": "1.15.24", - "@swc/core-win32-ia32-msvc": "1.15.24", - "@swc/core-win32-x64-msvc": "1.15.24" + "@swc/core-darwin-arm64": "1.15.32", + "@swc/core-darwin-x64": "1.15.32", + "@swc/core-linux-arm-gnueabihf": "1.15.32", + "@swc/core-linux-arm64-gnu": "1.15.32", + "@swc/core-linux-arm64-musl": "1.15.32", + "@swc/core-linux-ppc64-gnu": "1.15.32", + "@swc/core-linux-s390x-gnu": "1.15.32", + "@swc/core-linux-x64-gnu": "1.15.32", + "@swc/core-linux-x64-musl": "1.15.32", + "@swc/core-win32-arm64-msvc": "1.15.32", + "@swc/core-win32-ia32-msvc": "1.15.32", + "@swc/core-win32-x64-msvc": "1.15.32" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" @@ -13326,9 +12526,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.24.tgz", - "integrity": "sha512-uM5ZGfFXjtvtJ+fe448PVBEbn/CSxS3UAyLj3O9xOqKIWy3S6hPTXSPbszxkSsGDYKi+YFhzAsR4r/eXLxEQ0g==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.32.tgz", + "integrity": "sha512-/YWMvJDPu+AAwuUsM2G+DNQ/7zhodURGzdQyewEqcvgklAdDHs3LwQmLLnyn6SJl8DT8UOxkbzK+D1PmPeelRg==", "cpu": [ "arm64" ], @@ -13342,9 +12542,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.24.tgz", - "integrity": "sha512-fMIb/Zfn929pw25VMBhV7Ji2Dl+lCWtUPNdYJQYOke+00E5fcQ9ynxtP8+qhUo/HZc+mYQb1gJxwHM9vty+lXg==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.32.tgz", + "integrity": "sha512-KOTXJXdAhWL+hZ77MYP3z+4pcMFaQhQ74yqyN1uz093q0YnbxpqMtYpPISbYvMHzVRNNx5kN+9RZAXEaadhWVA==", "cpu": [ "x64" ], @@ -13358,9 +12558,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.24.tgz", - "integrity": "sha512-vOkjsyjjxnoYx3hMEWcGxQrMgnNrRm6WAegBXrN8foHtDAR+zpdhpGF5a4lj1bNPgXAvmysjui8cM1ov/Clkaw==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.32.tgz", + "integrity": "sha512-oOoxLweljlc0A4X8ybsgxV7cVaYTwBOg2iMDJcFR3Sr48C+lsv9VzSmqdK/IVIXF4W4GjLc3VqTAdSMXlfVLuQ==", "cpu": [ "arm" ], @@ -13374,9 +12574,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.24.tgz", - "integrity": "sha512-h/oNu+upkXJ6Cicnq7YGVj9PkdfarLCdQa8l/FlHYvfv8CEiMaeeTnpLU7gSBH/rGxosM6Qkfa/J9mThGF9CLA==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.32.tgz", + "integrity": "sha512-oDzEkdl6D6BAWdMtU5KGO7y3HR5fJcvByNLyEk9+ugj8nP5Ovb7P4kBcStBXc4MPExFGQryehiINMlmY8HlclA==", "cpu": [ "arm64" ], @@ -13390,9 +12590,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.24.tgz", - "integrity": "sha512-ZpF/pRe1guk6sKzQI9D1jAORtjTdNlyeXn9GDz8ophof/w2WhojRblvSDJaGe7rJjcPN8AaOkhwdRUh7q8oYIg==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.32.tgz", + "integrity": "sha512-omcqjoZP/b8D8PuczVoRwJieC6ibj7qIxTftNYokz4/aSmKFHvsd7nIFfPk5ZvtzncbH4AY7+Dkr/Lp2gWxYeA==", "cpu": [ "arm64" ], @@ -13406,9 +12606,9 @@ } }, "node_modules/@swc/core-linux-ppc64-gnu": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.24.tgz", - "integrity": "sha512-QZEsZfisHTSJlmyChgDFNmKPb3W6Lhbfo/O76HhIngfEdnQNmukS38/VSe1feho+xkV5A5hETyCbx3sALBZKAQ==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.32.tgz", + "integrity": "sha512-KGkTMyz/Tbn3PBNu0AVZ4GTDFKnICrYcTiNPZq8DrvK42pnFsf3GNDrIG9E5AtQlTmC0YigkWKmu0eMcfTrmgA==", "cpu": [ "ppc64" ], @@ -13422,9 +12622,9 @@ } }, "node_modules/@swc/core-linux-s390x-gnu": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.24.tgz", - "integrity": "sha512-DLdJKVsJgglqQrJBuoUYNmzm3leI7kUZhLbZGHv42onfKsGf6JDS3+bzCUQfte/XOqDjh/tmmn1DR/CF/tCJFw==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.32.tgz", + "integrity": "sha512-G3Aa4tVS/3OGZBkoNIwUF9F6RAy+Osb4GOlo62SinLmDiErz/ykmM7KH0wkz6l9kM8jJq1HyAM6atJTUEbBk7g==", "cpu": [ "s390x" ], @@ -13438,9 +12638,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.24.tgz", - "integrity": "sha512-IpLYfposPA/XLxYOKpRfeccl1p5dDa3+okZDHHTchBkXEaVCnq5MADPmIWwIYj1tudt7hORsEHccG5no6IUQRw==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.32.tgz", + "integrity": "sha512-ERsjfGcj6CBmj3vJnGDO8m8rTvw6RqMcWo1dogOtNx3/+/0+NNpJiXDobJrr1GwInI/BHAEkvSFIH6d2LqPcUQ==", "cpu": [ "x64" ], @@ -13454,9 +12654,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.24.tgz", - "integrity": "sha512-JHy3fMSc0t/EPWgo74+OK5TGr51aElnzqfUPaiRf2qJ/BfX5CUCfMiWVBuhI7qmVMBnk1jTRnL/xZnOSHDPLYg==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.32.tgz", + "integrity": "sha512-N4Ggahe/8SUbTX50P6EdhbW9YWcgbZVb52R4cq6MK+zsoMjRq7rGvV5ztA05QnbaCYqMYx8rTY7KAIA3Crdo4Q==", "cpu": [ "x64" ], @@ -13470,9 +12670,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.24.tgz", - "integrity": "sha512-Txj+qUH1z2bUd1P3JvwByfjKFti3cptlAxhWgmunBUUxy/IW3CXLZ6l6Gk4liANadKkU71nIU1X30Z5vpMT3BA==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.32.tgz", + "integrity": "sha512-01yN0o9jvo8xBTP12aPK2wW8b41jmOlGbDDlAnoynotc4pO6xA0zby9f1z6j++qXDpGBttLySq1omgVrlQKYcw==", "cpu": [ "arm64" ], @@ -13486,9 +12686,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.24.tgz", - "integrity": "sha512-15D/nl3XwrhFpMv+MADFOiVwv3FvH9j8c6Rf8EXBT3Q5LoMh8YnDnSgPYqw1JzPnksvsBX6QPXLiPqmcR/Z4qQ==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.32.tgz", + "integrity": "sha512-fLagI9XZYNpTcmlqAcp3KBtmj7E19WCmYD80Jxj1Kn5tGNa7yxNLd3NNdWxuZGUPl5iC0/KqZru7g08gF6Fsrw==", "cpu": [ "ia32" ], @@ -13502,9 +12702,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.15.24", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.24.tgz", - "integrity": "sha512-PR0PlTlPra2JbaDphrOAzm6s0v9rA0F17YzB+XbWD95B4g2cWcZY9LAeTa4xll70VLw9Jr7xBrlohqlQmelMFQ==", + "version": "1.15.32", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.32.tgz", + "integrity": "sha512-gbc2bQ/T2CiR+w0OvcVKwLOFAcPZBvmWmolbwpg1E8UrpeC03DGtyMUApOHNXNYWA3SHFrYXCQtosrcMza1YFg==", "cpu": [ "x64" ], @@ -13543,9 +12743,9 @@ } }, "node_modules/@swc/plugin-emotion": { - "version": "14.8.0", - "resolved": "https://registry.npmjs.org/@swc/plugin-emotion/-/plugin-emotion-14.8.0.tgz", - "integrity": "sha512-otFM4JfEE9uyH6HxhD5Dmw6WUY773d2Ln44kEobc89HoVbdGkO3DZv9r2h5znFy7wORyl894V3nYd/mhqc4dIQ==", + "version": "14.9.0", + "resolved": "https://registry.npmjs.org/@swc/plugin-emotion/-/plugin-emotion-14.9.0.tgz", + "integrity": "sha512-h57mL/TsOrhimvHs6KQQLZO1T+D7FQyx+7WS17p9vV228qxmZatF0IgEXMyERWthm1QL7fAB6cEMBCtujSVbyw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -13573,9 +12773,9 @@ } }, "node_modules/@testing-library/dom": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", - "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.10.4", @@ -13588,7 +12788,7 @@ "pretty-format": "^27.0.2" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/@testing-library/dom/node_modules/chalk": { @@ -13633,67 +12833,21 @@ "license": "MIT" }, "node_modules/@testing-library/react": { - "version": "12.1.5", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", - "integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==", + "version": "14.3.1", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.3.1.tgz", + "integrity": "sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.0.0", - "@types/react-dom": "<18.0.0" + "@testing-library/dom": "^9.0.0", + "@types/react-dom": "^18.0.0" }, "engines": { - "node": ">=12" + "node": ">=14" }, "peerDependencies": { - "react": "<18.0.0", - "react-dom": "<18.0.0" - } - }, - "node_modules/@testing-library/react-hooks": { - "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", - "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 - } - } - }, - "node_modules/@testing-library/react-hooks/node_modules/react-error-boundary": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", - "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "react": ">=16.13.1" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@testing-library/user-event": { @@ -13819,13 +12973,13 @@ } }, "node_modules/@tufjs/models/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -13844,21 +12998,6 @@ "@turf/invariant": "^5.1.5" } }, - "node_modules/@turf/boolean-clockwise/node_modules/@turf/helpers": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-5.1.5.tgz", - "integrity": "sha512-/lF+JR+qNDHZ8bF9d+Cp58nxtZWJ3sqFe6n3u3Vpj+/0cqkjk4nXKYBSY0azm+GIYB5mWKxUXvuP/m0ZnKj1bw==", - "license": "MIT" - }, - "node_modules/@turf/boolean-clockwise/node_modules/@turf/invariant": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-5.2.0.tgz", - "integrity": "sha512-28RCBGvCYsajVkw2EydpzLdcYyhSA77LovuOvgCJplJWaNVyJYH6BOR3HR9w50MEkPqb/Vc/jdo6I6ermlRtQA==", - "license": "MIT", - "dependencies": { - "@turf/helpers": "^5.1.5" - } - }, "node_modules/@turf/clone": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/@turf/clone/-/clone-5.1.5.tgz", @@ -13868,12 +13007,21 @@ "@turf/helpers": "^5.1.5" } }, - "node_modules/@turf/clone/node_modules/@turf/helpers": { + "node_modules/@turf/helpers": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-5.1.5.tgz", "integrity": "sha512-/lF+JR+qNDHZ8bF9d+Cp58nxtZWJ3sqFe6n3u3Vpj+/0cqkjk4nXKYBSY0azm+GIYB5mWKxUXvuP/m0ZnKj1bw==", "license": "MIT" }, + "node_modules/@turf/invariant": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-5.2.0.tgz", + "integrity": "sha512-28RCBGvCYsajVkw2EydpzLdcYyhSA77LovuOvgCJplJWaNVyJYH6BOR3HR9w50MEkPqb/Vc/jdo6I6ermlRtQA==", + "license": "MIT", + "dependencies": { + "@turf/helpers": "^5.1.5" + } + }, "node_modules/@turf/rewind": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/@turf/rewind/-/rewind-5.1.5.tgz", @@ -13887,21 +13035,6 @@ "@turf/meta": "^5.1.5" } }, - "node_modules/@turf/rewind/node_modules/@turf/helpers": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-5.1.5.tgz", - "integrity": "sha512-/lF+JR+qNDHZ8bF9d+Cp58nxtZWJ3sqFe6n3u3Vpj+/0cqkjk4nXKYBSY0azm+GIYB5mWKxUXvuP/m0ZnKj1bw==", - "license": "MIT" - }, - "node_modules/@turf/rewind/node_modules/@turf/invariant": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-5.2.0.tgz", - "integrity": "sha512-28RCBGvCYsajVkw2EydpzLdcYyhSA77LovuOvgCJplJWaNVyJYH6BOR3HR9w50MEkPqb/Vc/jdo6I6ermlRtQA==", - "license": "MIT", - "dependencies": { - "@turf/helpers": "^5.1.5" - } - }, "node_modules/@turf/rewind/node_modules/@turf/meta": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-5.2.0.tgz", @@ -14067,10 +13200,9 @@ "license": "MIT" }, "node_modules/@types/d3": { - "version": "3.5.53", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.53.tgz", - "integrity": "sha512-8yKQA9cAS6+wGsJpBysmnhlaaxlN42Qizqkw+h2nILSlS+MAG2z4JdO6p+PJrJ+ACvimkmLJL281h157e52psQ==", - "dev": true, + "version": "3.5.38", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.38.tgz", + "integrity": "sha512-O/gRkjWULp3xVX8K85V0H3tsSGole0WYt77KVpGZO2xTGLuVFuvE6JIsIli3fvFHCYBhGFn/8OHEEyMYF+QehA==", "license": "MIT" }, "node_modules/@types/d3-array": { @@ -14090,10 +13222,9 @@ } }, "node_modules/@types/d3-color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", - "dev": true, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==", "license": "MIT" }, "node_modules/@types/d3-delaunay": { @@ -14184,9 +13315,9 @@ "license": "MIT" }, "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", "license": "MIT", "dependencies": { "@types/ms": "*" @@ -14235,9 +13366,9 @@ } }, "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -14362,17 +13493,6 @@ "@types/node": "*" } }, - "node_modules/@types/inquirer": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.7.tgz", - "integrity": "sha512-Q0zyBupO6NxGRZut/JdmqYKOnN95Eg5V8Csg3PGKkP+FnvsUZx1jAyK7fztIszxxMuoBA6E3KXWvdZVXIpx60g==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/through": "*", - "rxjs": "^7.2.0" - } - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -14412,9 +13532,9 @@ } }, "node_modules/@types/jest/node_modules/@jest/expect-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", - "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", + "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", "dev": true, "license": "MIT", "dependencies": { @@ -14438,9 +13558,9 @@ } }, "node_modules/@types/jest/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", + "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", "dependencies": { @@ -14457,9 +13577,9 @@ } }, "node_modules/@types/jest/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -14481,69 +13601,69 @@ } }, "node_modules/@types/jest/node_modules/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", "dev": true, "license": "MIT", "dependencies": { - "@jest/expect-utils": "30.2.0", + "@jest/expect-utils": "30.3.0", "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@types/jest/node_modules/jest-diff": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", - "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/diff-sequences": "30.0.1", + "@jest/diff-sequences": "30.3.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@types/jest/node_modules/jest-matcher-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", - "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", + "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", "dev": true, "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "jest-diff": "30.2.0", - "pretty-format": "30.2.0" + "jest-diff": "30.3.0", + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@types/jest/node_modules/jest-message-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", - "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", + "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", + "picomatch": "^4.0.3", + "pretty-format": "30.3.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -14552,33 +13672,33 @@ } }, "node_modules/@types/jest/node_modules/jest-mock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", - "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", + "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-util": "30.2.0" + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@types/jest/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", + "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -14598,9 +13718,9 @@ } }, "node_modules/@types/jest/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", "dependencies": { @@ -14636,14 +13756,11 @@ } }, "node_modules/@types/jquery": { - "version": "3.5.33", - "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.33.tgz", - "integrity": "sha512-SeyVJXlCZpEki5F0ghuYe+L+PprQta6nRZqhONt9F13dWBtR/ftoaIbdRQ7cis7womE+X2LKhsDdDtkkDhJS6g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-4.0.0.tgz", + "integrity": "sha512-Z+to+A2VkaHq1DfI2oSwsoCdhCHMpTSgjWzNcbNlRGYzksDBpPUgEcAL+RQjOBJRaLoEAOHXxqDGBVP+BblBwg==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/sizzle": "*" - } + "license": "MIT" }, "node_modules/@types/js-levenshtein": { "version": "1.1.3", @@ -14810,9 +13927,9 @@ "license": "MIT" }, "node_modules/@types/prop-types": { - "version": "15.7.14", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", - "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", "license": "MIT" }, "node_modules/@types/qs": { @@ -14843,23 +13960,22 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "17.0.83", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.83.tgz", - "integrity": "sha512-l0m4ArKJvmFtR4e8UmKrj1pB4tUgOhJITf+mADyF/p69Ts1YAR/E+G9XEM0mHXKVRa1dQNHseyyDNzeuAXfXQw==", + "version": "18.3.28", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz", + "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==", "license": "MIT", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "^0.16", - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { - "version": "17.0.26", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.26.tgz", - "integrity": "sha512-Z+2VcYXJwOqQ79HreLU/1fyQ88eXSSFh6I3JdrEHQIfYSI0kCQpTGvOrbE6jFGGYXKsHuwY9tBa/w5Uo6KzrEg==", + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "license": "MIT", "peerDependencies": { - "@types/react": "^17.0.0" + "@types/react": "^18.0.0" } }, "node_modules/@types/react-google-recaptcha": { @@ -15032,12 +14148,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "license": "MIT" - }, "node_modules/@types/seedrandom": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-3.0.8.tgz", @@ -15085,13 +14195,6 @@ "@types/send": "*" } }, - "node_modules/@types/sizzle": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz", - "integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/sockjs": { "version": "0.3.36", "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", @@ -15130,16 +14233,6 @@ "integrity": "sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==", "license": "MIT" }, - "node_modules/@types/through": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.33.tgz", - "integrity": "sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/tinycolor2": { "version": "1.4.6", "resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.6.tgz", @@ -15264,78 +14357,100 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", - "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.2.tgz", + "integrity": "sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/type-utils": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/type-utils": "8.59.2", + "@typescript-eslint/utils": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.5.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.59.2", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/project-service": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.2.tgz", + "integrity": "sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" + "@typescript-eslint/tsconfig-utils": "^8.59.2", + "@typescript-eslint/types": "^8.59.2", + "debug": "^4.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.2.tgz", + "integrity": "sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.2.tgz", + "integrity": "sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.2.tgz", + "integrity": "sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -15343,69 +14458,69 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", - "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz", + "integrity": "sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0" + "@typescript-eslint/project-service": "8.59.2", + "@typescript-eslint/tsconfig-utils": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.2.tgz", + "integrity": "sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "eslint-visitor-keys": "^3.4.3" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.2.tgz", + "integrity": "sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -15423,9 +14538,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -15436,89 +14551,134 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, - "license": "ISC", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/parser": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", - "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.2.tgz", + "integrity": "sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "debug": "^4.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.2.tgz", + "integrity": "sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" + "@typescript-eslint/tsconfig-utils": "^8.59.2", + "@typescript-eslint/types": "^8.59.2", + "debug": "^4.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.2.tgz", + "integrity": "sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.2.tgz", + "integrity": "sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.2.tgz", + "integrity": "sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -15526,46 +14686,45 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz", + "integrity": "sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "@typescript-eslint/project-service": "8.59.2", + "@typescript-eslint/tsconfig-utils": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.2.tgz", + "integrity": "sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.59.2", + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -15583,9 +14742,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -15596,43 +14755,43 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", - "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.1.tgz", + "integrity": "sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.0", - "@typescript-eslint/types": "^8.56.0", + "@typescript-eslint/tsconfig-utils": "^8.59.1", + "@typescript-eslint/types": "^8.59.1", "debug": "^4.4.3" }, "engines": { @@ -15643,13 +14802,13 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", - "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz", + "integrity": "sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==", "dev": true, "license": "MIT", "engines": { @@ -15679,9 +14838,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", - "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz", + "integrity": "sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==", "dev": true, "license": "MIT", "engines": { @@ -15692,63 +14851,99 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", - "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.2.tgz", + "integrity": "sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/utils": "8.59.2", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/project-service": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.2.tgz", + "integrity": "sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" + "@typescript-eslint/tsconfig-utils": "^8.59.2", + "@typescript-eslint/types": "^8.59.2", + "debug": "^4.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.2.tgz", + "integrity": "sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.2.tgz", + "integrity": "sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.2.tgz", + "integrity": "sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -15756,69 +14951,69 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", - "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz", + "integrity": "sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0" + "@typescript-eslint/project-service": "8.59.2", + "@typescript-eslint/tsconfig-utils": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.2.tgz", + "integrity": "sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "eslint-visitor-keys": "^3.4.3" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.2.tgz", + "integrity": "sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -15836,9 +15031,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -15849,29 +15044,29 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -16217,16 +15412,27 @@ } }, "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz", - "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.9.0" + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" } }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { @@ -16613,12 +15819,6 @@ "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", "license": "MIT" }, - "node_modules/@visx/vendor/node_modules/@types/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==", - "license": "MIT" - }, "node_modules/@visx/vendor/node_modules/@types/d3-format": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", @@ -16655,27 +15855,6 @@ "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", "license": "MIT" }, - "node_modules/@visx/vendor/node_modules/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-gUY/qeHq/yNqqoCKNq4vtpFLdoCdvyNpWoC/KNjhGbhDuQpAM9sIQQKkXSNpXa9h5KySs/gzm7R88WkUutgwWQ==", - "license": "ISC", - "dependencies": { - "internmap": "1 - 2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@visx/vendor/node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/@visx/voronoi": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/@visx/voronoi/-/voronoi-3.12.0.tgz", @@ -17063,234 +16242,6 @@ "node": ">=18.12.0" } }, - "node_modules/@yeoman/adapter": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@yeoman/adapter/-/adapter-1.6.0.tgz", - "integrity": "sha512-oJw/i6zUDdfsT5VOPuANDDEWs5NhlMq5+rmyZIVdgBTXalbCw6nUfJQOblO2Fnq+Ov6CxlyzDBTWQvL5cEjA+g==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/inquirer": "^9.0.3", - "chalk": "^5.2.0", - "inquirer": "^9.2.2", - "log-symbols": "^7.0.0", - "ora": "^8.1.0", - "p-queue": "^8.0.1", - "text-table": "^0.2.0" - }, - "engines": { - "node": ">=18.12.0" - } - }, - "node_modules/@yeoman/adapter/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@yeoman/adapter/node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", - "license": "MIT", - "peer": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@yeoman/adapter/node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "license": "MIT", - "peer": true, - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@yeoman/adapter/node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@yeoman/adapter/node_modules/emoji-regex": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", - "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", - "license": "MIT", - "peer": true - }, - "node_modules/@yeoman/adapter/node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@yeoman/adapter/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@yeoman/adapter/node_modules/ora": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-8.1.1.tgz", - "integrity": "sha512-YWielGi1XzG1UTvOaCFaNgEnuhZVMSHYkW/FQ7UX8O26PtlpdM84c0f7wLPlkvx2RfiQmnzd61d/MGxmpQeJPw==", - "license": "MIT", - "peer": true, - "dependencies": { - "chalk": "^5.3.0", - "cli-cursor": "^5.0.0", - "cli-spinners": "^2.9.2", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.0.0", - "log-symbols": "^6.0.0", - "stdin-discarder": "^0.2.2", - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@yeoman/adapter/node_modules/ora/node_modules/log-symbols": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", - "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", - "license": "MIT", - "peer": true, - "dependencies": { - "chalk": "^5.3.0", - "is-unicode-supported": "^1.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@yeoman/adapter/node_modules/ora/node_modules/log-symbols/node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@yeoman/adapter/node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "license": "MIT", - "peer": true, - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@yeoman/adapter/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "peer": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@yeoman/adapter/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@yeoman/adapter/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/@yeoman/namespace": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@yeoman/namespace/-/namespace-1.0.1.tgz", @@ -17301,45 +16252,36 @@ } }, "node_modules/@yeoman/types": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@yeoman/types/-/types-1.5.0.tgz", - "integrity": "sha512-uyeQdpKw3ftj3zN5gG28vOgMuqOGEfKiqWH1R04bm5RK8LRsnXO9SqPao1kC6dwowVQE0Wl/D9+6XmA6y/4qzQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@yeoman/types/-/types-1.11.1.tgz", + "integrity": "sha512-27CI5hHQAHfq8ohYILmLNzClbdzBJzu+ny9AzUVV6naJO0l4/+t+67QDKlwQvt+TW3oE5j74I/Mh4Kn14rsVXA==", "license": "MIT", "peer": true, - "dependencies": { - "@yeoman/adapter": "^1.6.0" - }, - "acceptDependencies": { - "@yeoman/adapter": "^2.0.0-beta.0", - "mem-fs": "^4.0.0-beta.1", - "mem-fs-editor": ">=10.0.2" - }, "engines": { "node": "^16.13.0 || >=18.12.0" }, "peerDependencies": { "@types/node": ">=16.18.26", - "@yeoman/adapter": "^1.6.0", - "mem-fs": "^3.0.0", - "mem-fs-editor": "^10.0.2" + "@yeoman/adapter": "^1.6.0 || ^2.0.0-beta.0 || ^3.0.0 || ^4.0.0", + "mem-fs": "^3.0.0 || ^4.0.0-beta.1" }, "peerDependenciesMeta": { - "mem-fs": { + "@yeoman/adapter": { "optional": true }, - "mem-fs-editor": { + "mem-fs": { "optional": true } } }, "node_modules/@zarrita/storage": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@zarrita/storage/-/storage-0.1.4.tgz", - "integrity": "sha512-qURfJAQcQGRfDQ4J9HaCjGaj3jlJKc66bnRk6G/IeLUsM7WKyG7Bzsuf1EZurSXyc0I4LVcu6HaeQQ4d3kZ16g==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@zarrita/storage/-/storage-0.2.0.tgz", + "integrity": "sha512-855ZXqtnds7spnT8vNvD+MXa3QExP1m2GqShe8yt7uZXHnQLgJHgkpVwFjE1B0KDDRO0ki09hmk6OboTaIfPsQ==", "license": "MIT", "dependencies": { "reference-spec-reader": "^0.2.0", - "unzipit": "1.4.3" + "unzipit": "2.0.0" } }, "node_modules/@zkochan/js-yaml": { @@ -17431,6 +16373,30 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk/node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", @@ -17439,27 +16405,27 @@ "license": "MIT" }, "node_modules/ag-charts-types": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/ag-charts-types/-/ag-charts-types-13.0.1.tgz", - "integrity": "sha512-qg9adyiAaeUaDtWZEEPF45dv55kdJTe6Ghi0EQXCS79h/7KvOd6dxhqGZjPL1zeFl/L9qEXuYgb+LkGStq4mgQ==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/ag-charts-types/-/ag-charts-types-13.2.1.tgz", + "integrity": "sha512-r7veb3QqJtIKlXmeUsLR4/oDPwmHxFI2tmbZra/203mdaz3uwQUrrgYNg628nrK+7L2YxXnwGc6L05tWjLLjNQ==", "license": "MIT" }, "node_modules/ag-grid-community": { - "version": "35.0.1", - "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-35.0.1.tgz", - "integrity": "sha512-fYYZdymWKsN9/tZv+R6uZRnuiWYEQr+GHl85ZrB0ixbFcE8opYK4NJI29NnMc9ShYiCBnAO9hj54IFa+FI4aDA==", + "version": "35.2.1", + "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-35.2.1.tgz", + "integrity": "sha512-ycmGI+1EbUT7i3eg/Kgi1owwnkdHXRufo10Xm6cfSsVPM3TMpvlbLgi28KIPt9DGHZWHq9fOBn7nxMNdv1Yaow==", "license": "MIT", "dependencies": { - "ag-charts-types": "13.0.1" + "ag-charts-types": "13.2.1" } }, "node_modules/ag-grid-react": { - "version": "35.0.1", - "resolved": "https://registry.npmjs.org/ag-grid-react/-/ag-grid-react-35.0.1.tgz", - "integrity": "sha512-NvrrgWUm+DsnsZVFho16srlyBNKSl9nqeSadk63HpHYerq4S4vN/2JCxdNtfqns7SpbYx7GbasbMFCXKYj7Qaw==", + "version": "35.2.1", + "resolved": "https://registry.npmjs.org/ag-grid-react/-/ag-grid-react-35.2.1.tgz", + "integrity": "sha512-UzdU15R6fyGJB+lBKEC458xacGoZged3Ra6Plqa7LvrJ/Mg0tWn1NH01UnuKyGEKPWMEAGvdXruOtOUywsPElA==", "license": "MIT", "dependencies": { - "ag-grid-community": "35.0.1", + "ag-grid-community": "35.2.1", "prop-types": "^15.8.1" }, "peerDependencies": { @@ -17495,9 +16461,9 @@ } }, "node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -17561,6 +16527,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -17576,6 +16543,7 @@ "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -17685,21 +16653,6 @@ "react-dom": ">=16.9.0" } }, - "node_modules/antd/node_modules/rc-input": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.8.0.tgz", - "integrity": "sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.11.1", - "classnames": "^2.2.1", - "rc-util": "^5.18.1" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -17733,28 +16686,6 @@ "dev": true, "license": "ISC" }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "peer": true - }, "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -17811,6 +16742,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-differ": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-4.0.0.tgz", + "integrity": "sha512-Q6VPTLMsmXZ47ENG3V+wQyZS1ZxXMxFyYzA+Z/GMrJ6yIutAIEf9wTyroTzmGjNfox9/h3GdGBCVh43GVFx4Uw==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -17971,17 +16914,6 @@ "node": ">=0.10.0" } }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, "node_modules/asn1js": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.7.tgz", @@ -17997,17 +16929,6 @@ "node": ">=12.0.0" } }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.8" - } - }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -18040,17 +16961,6 @@ "node": ">=4" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", @@ -18073,17 +16983,6 @@ "dev": true, "license": "MIT" }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "license": "ISC", - "peer": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -18099,33 +16998,14 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", - "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/axios": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", - "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", "dev": true, "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.11", + "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } @@ -18478,9 +17358,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.16", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.16.tgz", - "integrity": "sha512-Lyf3aK28zpsD1yQMiiHD4RvVb6UdMoo8xzG2XzFIfR9luPzOpcBlAsT/qfB1XWS1bxWT+UtE4WmQgsp297FYOA==", + "version": "2.10.24", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.24.tgz", + "integrity": "sha512-I2NkZOOrj2XuguvWCK6OVh9GavsNjZjK908Rq3mIBK25+GD8vPX5w2WdxVqnQ7xx3SrZJiCiZFu+/Oz50oSYSA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -18517,17 +17397,6 @@ "dev": true, "license": "MIT" }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/better-opn": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", @@ -18666,6 +17535,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -18673,14 +17543,6 @@ "readable-stream": "^3.4.0" } }, - "node_modules/blob-util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", - "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "dev": true, - "license": "Apache-2.0", - "peer": true - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -18805,9 +17667,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -18927,6 +17789,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "funding": [ { "type": "github", @@ -18947,17 +17810,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "*" - } - }, "node_modules/buffer-equal": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", @@ -19121,9 +17973,9 @@ } }, "node_modules/cacache/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -19131,13 +17983,13 @@ } }, "node_modules/cacache/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -19189,17 +18041,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/cachedir": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", - "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", @@ -19434,14 +18275,6 @@ "node": ">=4" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, - "license": "Apache-2.0", - "peer": true - }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -19523,6 +18356,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "dev": true, "license": "MIT" }, "node_modules/charenc": { @@ -19550,17 +18384,6 @@ "node": ">= 16" } }, - "node_modules/check-more-types": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", - "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/cheerio": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", @@ -19729,9 +18552,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", - "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", "dev": true, "license": "MIT" }, @@ -19778,6 +18601,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" @@ -19790,6 +18614,7 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -19798,45 +18623,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cli-width": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, "license": "ISC", "engines": { "node": ">= 12" @@ -19897,13 +18688,6 @@ "node": ">=6" } }, - "node_modules/clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "license": "MIT", - "peer": true - }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -20060,17 +18844,6 @@ "dev": true, "license": "ISC" }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -20267,6 +19040,25 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/concurrently/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -20308,9 +19100,9 @@ "license": "MIT" }, "node_modules/content-disposition": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", "license": "MIT", "engines": { "node": ">=18" @@ -20606,9 +19398,9 @@ } }, "node_modules/core-js": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", - "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", + "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -20955,9 +19747,9 @@ } }, "node_modules/create-jest/node_modules/dedent": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", - "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "dev": true, "license": "MIT", "peerDependencies": { @@ -21283,9 +20075,9 @@ } }, "node_modules/create-jest/node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -21633,9 +20425,9 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", + "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", "dependencies": { @@ -21652,9 +20444,9 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -21689,33 +20481,33 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", + "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/css-minimizer-webpack-plugin/node_modules/jest-worker": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", - "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", + "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.2.0", + "jest-util": "30.3.0", "merge-stream": "^2.0.0", "supports-color": "^8.1.1" }, @@ -21753,9 +20545,9 @@ } }, "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -21783,13 +20575,6 @@ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "node_modules/css-tree/node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true, - "license": "CC0-1.0" - }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -21949,6 +20734,13 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true, + "license": "MIT" + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -21975,225 +20767,6 @@ "node": ">=0.8" } }, - "node_modules/cypress": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-14.0.0.tgz", - "integrity": "sha512-kEGqQr23so5IpKeg/dp6GVi7RlHx1NmW66o2a2Q4wk9gRaAblLZQSiZJuDI8UMC4LlG5OJ7Q6joAiqTrfRNbTw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@cypress/request": "^3.0.6", - "@cypress/xvfb": "^1.2.4", - "@types/sinonjs__fake-timers": "8.1.1", - "@types/sizzle": "^2.3.2", - "arch": "^2.2.0", - "blob-util": "^2.0.2", - "bluebird": "^3.7.2", - "buffer": "^5.7.1", - "cachedir": "^2.3.0", - "chalk": "^4.1.0", - "check-more-types": "^2.24.0", - "ci-info": "^4.0.0", - "cli-cursor": "^3.1.0", - "cli-table3": "~0.6.1", - "commander": "^6.2.1", - "common-tags": "^1.8.0", - "dayjs": "^1.10.4", - "debug": "^4.3.4", - "enquirer": "^2.3.6", - "eventemitter2": "6.4.7", - "execa": "4.1.0", - "executable": "^4.1.1", - "extract-zip": "2.0.1", - "figures": "^3.2.0", - "fs-extra": "^9.1.0", - "getos": "^3.2.1", - "is-installed-globally": "~0.4.0", - "lazy-ass": "^1.6.0", - "listr2": "^3.8.3", - "lodash": "^4.17.21", - "log-symbols": "^4.0.0", - "minimist": "^1.2.8", - "ospath": "^1.2.2", - "pretty-bytes": "^5.6.0", - "process": "^0.11.10", - "proxy-from-env": "1.0.0", - "request-progress": "^3.0.0", - "semver": "^7.5.3", - "supports-color": "^8.1.1", - "tmp": "~0.2.3", - "tree-kill": "1.2.2", - "untildify": "^4.0.0", - "yauzl": "^2.10.0" - }, - "bin": { - "cypress": "bin/cypress" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - } - }, - "node_modules/cypress/node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", - "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/cypress/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/cypress/node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cypress/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/cypress/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cypress/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", - "peer": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cypress/node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/cypress/node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cypress/node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cypress/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/d3": { "version": "3.5.17", "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz", @@ -22201,20 +20774,17 @@ "license": "BSD-3-Clause" }, "node_modules/d3-array": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", - "license": "BSD-3-Clause", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-gUY/qeHq/yNqqoCKNq4vtpFLdoCdvyNpWoC/KNjhGbhDuQpAM9sIQQKkXSNpXa9h5KySs/gzm7R88WkUutgwWQ==", + "license": "ISC", "dependencies": { - "internmap": "^1.0.0" + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" } }, - "node_modules/d3-array/node_modules/internmap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", - "license": "ISC" - }, "node_modules/d3-collection": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", @@ -22249,10 +20819,13 @@ "license": "BSD-3-Clause" }, "node_modules/d3-format": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", - "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==", - "license": "BSD-3-Clause" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "engines": { + "node": ">=12" + } }, "node_modules/d3-geo": { "version": "3.1.0", @@ -22410,20 +20983,6 @@ "node": ">=8" } }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-urls": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", @@ -22510,11 +21069,21 @@ "topojson": "^1.6.19" } }, - "node_modules/datamaps/node_modules/@types/d3": { - "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.38.tgz", - "integrity": "sha512-O/gRkjWULp3xVX8K85V0H3tsSGole0WYt77KVpGZO2xTGLuVFuvE6JIsIli3fvFHCYBhGFn/8OHEEyMYF+QehA==", - "license": "MIT" + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } }, "node_modules/dateformat": { "version": "3.0.2", @@ -22767,6 +21336,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, "license": "MIT", "dependencies": { "clone": "^1.0.2" @@ -22779,6 +21349,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.8" @@ -23121,6 +21692,12 @@ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "license": "MIT" }, + "node_modules/dom-align": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz", + "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==", + "license": "MIT" + }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -23206,9 +21783,9 @@ } }, "node_modules/dompurify": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.0.tgz", - "integrity": "sha512-nolgK9JcaUXMSmW+j1yaSvaEaoXYHwWyGJlkoCTghc97KgGDDSnpoU/PlEnw63Ah+TGKFOyY+X5LnxaWbCSfXg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.1.tgz", + "integrity": "sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -23413,26 +21990,6 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ecc-jsbn/node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -23484,7 +22041,7 @@ "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" @@ -23603,15 +22160,13 @@ } }, "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" + "ansi-colors": "^4.1.1" }, "engines": { "node": ">=8.6" @@ -24233,35 +22788,6 @@ "eslint": ">=7" } }, - "node_modules/eslint-plugin-cypress/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-plugin-cypress/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint-plugin-i18n-strings": { "resolved": "eslint-rules/eslint-plugin-i18n-strings", "link": true @@ -24415,9 +22941,9 @@ } }, "node_modules/eslint-plugin-no-only-tests": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.3.0.tgz", - "integrity": "sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.4.0.tgz", + "integrity": "sha512-4S3/9Nb7A2tiMcpzEQE9bQSlpeOz6WJkgryBuou/SA8W2x2c8Zf4j0NvTKBjv6qNhF9T79tmkecm/0CHqV0UGg==", "dev": true, "license": "MIT", "engines": { @@ -24463,9 +22989,9 @@ "license": "MIT" }, "node_modules/eslint-plugin-react-you-might-not-need-an-effect": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-you-might-not-need-an-effect/-/eslint-plugin-react-you-might-not-need-an-effect-0.9.2.tgz", - "integrity": "sha512-VplJMf2kAYI4bF1KSCOygQ9BHzOqM/0P3cqpnBTylnSVv9aNxVrz2RDMs8bKJtITcp2CV9kuAUkzjUP0zgxbSw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-you-might-not-need-an-effect/-/eslint-plugin-react-you-might-not-need-an-effect-0.10.0.tgz", + "integrity": "sha512-a4pugbQc2zLiE2NZGuXdTjtMNvlP2984QFPDv71eskUYDzigLFYfBL4QjK+RnRtcboHoXRKOcQqEZKxiK6KegA==", "dev": true, "license": "MIT", "dependencies": { @@ -24479,9 +23005,9 @@ } }, "node_modules/eslint-plugin-react-you-might-not-need-an-effect/node_modules/globals": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", - "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", "dev": true, "license": "MIT", "engines": { @@ -24538,14 +23064,14 @@ } }, "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", - "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz", + "integrity": "sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0" + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -24556,9 +23082,9 @@ } }, "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/types": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", - "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz", + "integrity": "sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==", "dev": true, "license": "MIT", "engines": { @@ -24570,21 +23096,21 @@ } }, "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", - "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz", + "integrity": "sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.56.0", - "@typescript-eslint/tsconfig-utils": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/project-service": "8.59.1", + "@typescript-eslint/tsconfig-utils": "8.59.1", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -24594,20 +23120,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", - "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.1.tgz", + "integrity": "sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0" + "@typescript-eslint/scope-manager": "8.59.1", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/typescript-estree": "8.59.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -24618,17 +23144,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", - "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz", + "integrity": "sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/types": "8.59.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -24663,9 +23189,9 @@ } }, "node_modules/eslint-plugin-testing-library/node_modules/eslint-visitor-keys": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", - "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -24676,34 +23202,21 @@ } }, "node_modules/eslint-plugin-testing-library/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/eslint-plugin-testing-library/node_modules/ts-api-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, "node_modules/eslint-plugin-theme-colors": { "resolved": "eslint-rules/eslint-plugin-theme-colors", "link": true @@ -24743,9 +23256,9 @@ } }, "node_modules/eslint/node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -24826,22 +23339,6 @@ "node": ">=10.13.0" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/js-yaml": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", @@ -24862,19 +23359,6 @@ "dev": true, "license": "MIT" }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -24894,9 +23378,9 @@ } }, "node_modules/espree/node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -24977,13 +23461,6 @@ "@types/estree": "^1.0.0" } }, - "node_modules/estree-walker/node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -25003,20 +23480,12 @@ "node": ">= 0.6" } }, - "node_modules/eventemitter2": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", - "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT", - "peer": true + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" }, "node_modules/events": { "version": "3.3.0", @@ -25052,20 +23521,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "pify": "^2.2.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -25225,56 +23680,6 @@ "node": ">=0.10.0" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extract-zip/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", - "peer": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "peer": true - }, "node_modules/falafel": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.2.5.tgz", @@ -25389,9 +23794,9 @@ "license": "BSD-3-Clause" }, "node_modules/fast-xml-builder": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", - "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz", + "integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==", "funding": [ { "type": "github", @@ -25404,9 +23809,9 @@ } }, "node_modules/fast-xml-parser": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.5.tgz", - "integrity": "sha512-cK9c5I/DwIOI7/Q7AlGN3DuTdwN61gwSfL8rvuVPK+0mcCNHHGxRrpiFtaZZRfRMJL3Gl8B2AFlBG6qXf03w9A==", + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.6.tgz", + "integrity": "sha512-Yd4vkROfJf8AuJrDIVMVmYfULKmIJszVsMv7Vo71aocsKgFxpdlpSHXSaInvyYfgw2PRuObQSW2GFpVMUjxu9A==", "funding": [ { "type": "github", @@ -25476,17 +23881,6 @@ "bser": "2.1.1" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -25612,18 +24006,18 @@ } }, "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz", - "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -25878,6 +24272,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/first-chunk-stream": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-5.0.0.tgz", @@ -25916,23 +24322,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/flatted": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", @@ -26006,17 +24395,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "*" - } - }, "node_modules/fork-ts-checker-webpack-plugin": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.1.0.tgz", @@ -26046,9 +24424,9 @@ } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -26499,9 +24877,9 @@ "license": "MIT" }, "node_modules/geostyler": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/geostyler/-/geostyler-18.3.1.tgz", - "integrity": "sha512-ZEZDwdAtP6Z4ANtlMfYtMwymdFMrr6n0kD4q8dMANA54taXgbeJKU2quC93MQlXlSo8Ka8Y1xI3qAliRasvWcw==", + "version": "18.5.1", + "resolved": "https://registry.npmjs.org/geostyler/-/geostyler-18.5.1.tgz", + "integrity": "sha512-5+vLuDo1oR4QQTnrfkccIQSe3qEn0ytV9dLiFFhnxhPdziv/Wp3vKNhJZ37MUF5yIj2ISWZ+q/VmSNH6ifvWpg==", "license": "BSD-2-Clause", "dependencies": { "@ant-design/icons": "^5.5.1", @@ -26524,15 +24902,15 @@ "geostyler-data": "^1.1.0", "geostyler-geojson-parser": "^2.0.0", "geostyler-mapbox-parser": "^6.1.1", - "geostyler-openlayers-parser": "^5.4.0", + "geostyler-openlayers-parser": "^5.7.0", "geostyler-qgis-parser": "^4.0.2", - "geostyler-sld-parser": "^8.3.0", - "geostyler-style": "^11.0.2", + "geostyler-sld-parser": "^8.4.2", + "geostyler-style": "^11.1.0", "geostyler-wfs-parser": "^3.0.1", "lodash-es": "^4.17.21", "monaco-editor": "^0.52.0", "proj4": "^2.11.0", - "typescript-json-schema": "^0.65.0" + "typescript-json-schema": "^0.67.0" }, "engines": { "node": ">=20.6.0" @@ -26645,13 +25023,13 @@ } }, "node_modules/geostyler-openlayers-parser": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/geostyler-openlayers-parser/-/geostyler-openlayers-parser-5.4.1.tgz", - "integrity": "sha512-nNTywqeKO8itHbbSEV3vaO7H+gNGXz5+Fg7HMbUuELMNZwWM6NTLm0l5iemDeHPhi6WvifXwauXvxj6U8lIMsQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/geostyler-openlayers-parser/-/geostyler-openlayers-parser-5.7.0.tgz", + "integrity": "sha512-FRNTNPLoKJzKYnWas+E4hb4h38SGaK3KeNPZmLUqO5EcTootJjAJyTbCy/Cuv9afk56HYIBpM2gHh6q/fLwqsg==", "license": "BSD-2-Clause", "dependencies": { "css-font-parser": "^2.0.0", - "geostyler-style": "^11.0.1" + "geostyler-style": "^11.1.0" }, "engines": { "node": ">=20.6.0" @@ -26663,6 +25041,19 @@ "ol": ">=7.4" } }, + "node_modules/geostyler-openlayers-parser/node_modules/geostyler-style": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/geostyler-style/-/geostyler-style-11.1.0.tgz", + "integrity": "sha512-PixhZL0yR6XVSxCGdm3/ti4DjclXTGOSm4xc2TpuymfAxOhQZ3t8u392o9Ne4l4fM4nIzRRKACj7Kr0nO9H1Vg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.6.0", + "npm": ">=10.0.0" + }, + "funding": { + "url": "https://opencollective.com/geostyler" + } + }, "node_modules/geostyler-qgis-parser": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/geostyler-qgis-parser/-/geostyler-qgis-parser-4.1.0.tgz", @@ -26720,14 +25111,13 @@ } }, "node_modules/geostyler-sld-parser": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/geostyler-sld-parser/-/geostyler-sld-parser-8.4.0.tgz", - "integrity": "sha512-XR7o5L1n/+xBk/W1WVobX7ftoeoRy486o7qfI1D24PYcRFK3EBr5Dh1TZgGI2U7VXDWx2/S4ipl0hztqbjYnxw==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/geostyler-sld-parser/-/geostyler-sld-parser-8.4.2.tgz", + "integrity": "sha512-NPlTC1VoxgsApUgs/KhEAkGuMhWrUr2slJj8gSyXhd+oJUaYaPOfeGEFiaV+MGk1va+g3XJ1e5gkRD6aHjx8Eg==", "license": "BSD-2-Clause", "dependencies": { "fast-xml-parser": "^5.2.3", - "geostyler-style": "^11.0.2", - "lodash": "^4.17.21" + "geostyler-style": "^11.0.2" }, "engines": { "node": ">=20.6.0" @@ -26737,9 +25127,9 @@ } }, "node_modules/geostyler-sld-parser/node_modules/fast-xml-parser": { - "version": "5.5.9", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.9.tgz", - "integrity": "sha512-jldvxr1MC6rtiZKgrFnDSvT8xuH+eJqxqOBThUVjYrxssYTo1avZLGql5l0a0BAERR01CadYzZ83kVEkbyDg+g==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.2.tgz", + "integrity": "sha512-P7oW7tLbYnhOLQk/Gv7cZgzgMPP/XN03K02/Jy6Y/NHzyIAIpxuZIM/YqAkfiXFPxA2CTm7NtCijK9EDu09u2w==", "funding": [ { "type": "github", @@ -26748,18 +25138,19 @@ ], "license": "MIT", "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.2.0", - "strnum": "^2.2.2" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.5", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "node_modules/geostyler-sld-parser/node_modules/strnum": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.2.tgz", - "integrity": "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz", + "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==", "funding": [ { "type": "github", @@ -26808,13 +25199,26 @@ "react": ">=16.8.0" } }, + "node_modules/geostyler/node_modules/geostyler-style": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/geostyler-style/-/geostyler-style-11.1.0.tgz", + "integrity": "sha512-PixhZL0yR6XVSxCGdm3/ti4DjclXTGOSm4xc2TpuymfAxOhQZ3t8u392o9Ne4l4fM4nIzRRKACj7Kr0nO9H1Vg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.6.0", + "npm": ">=10.0.0" + }, + "funding": { + "url": "https://opencollective.com/geostyler" + } + }, "node_modules/geotiff": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-3.0.3.tgz", - "integrity": "sha512-yRoDQDYxWYiB421p0cbxJvdy79OlQW+rxDI9GDbIUeWCAh6YAZ0vlTKF448EAiEuuUpBsNaegd2flavF0p+kvw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-3.0.5.tgz", + "integrity": "sha512-OWcL9S9+yDZ6iAlXMt32T1iwUApJM8UiD47xbm6ZP1h33d10fqkPs14EG/ttT5EnefpZSx3G15iDFC5FxUNUwA==", "license": "MIT", "dependencies": { - "@petamoriken/float16": "^3.4.7", + "@petamoriken/float16": "^3.9.3", "lerc": "^3.0.0", "pako": "^2.0.4", "parse-headers": "^2.0.2", @@ -26859,7 +25263,6 @@ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -27026,9 +25429,9 @@ } }, "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", "dev": true, "license": "MIT", "engines": { @@ -27077,28 +25480,6 @@ "node": ">=0.10.0" } }, - "node_modules/getos": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", - "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "async": "^3.2.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/gettext-parser": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.1.0.tgz", @@ -27247,6 +25628,23 @@ "node": ">= 6" } }, + "node_modules/glob-to-regex.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", + "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", @@ -27254,34 +25652,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/global-dirs/node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "license": "ISC", - "peer": true, - "engines": { - "node": ">=10" - } - }, "node_modules/global-modules": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", @@ -27352,6 +25722,35 @@ "which": "bin/which" } }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globalthis": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", @@ -27729,9 +26128,9 @@ } }, "node_modules/hast-util-from-parse5/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -27805,9 +26204,9 @@ "license": "MIT" }, "node_modules/hast-util-raw/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -27834,9 +26233,9 @@ } }, "node_modules/hast-util-raw/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -28008,6 +26407,27 @@ "node": ">=0.10.0" } }, + "node_modules/hosted-git-info": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", + "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -28141,9 +26561,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.6.6", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.6.tgz", - "integrity": "sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw==", + "version": "5.6.7", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.7.tgz", + "integrity": "sha512-md+vXtdCAe60s1k6AU3dUyMJnDxUyQAwfwPKoLisvgUF1IXjtlLsk2se54+qfL9Mdm26bbwvjJybpNx48NKRLw==", "dev": true, "license": "MIT", "dependencies": { @@ -28369,13 +26789,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/http-proxy/node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true, - "license": "MIT" - }, "node_modules/http-server": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", @@ -28454,22 +26867,6 @@ "node": ">=12" } }, - "node_modules/http-signature": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", - "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2", - "sshpk": "^1.18.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -28554,7 +26951,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">= 4" @@ -28597,13 +26994,13 @@ } }, "node_modules/ignore-walk/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -28725,6 +27122,18 @@ "node": ">=8" } }, + "node_modules/index-to-position": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", + "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -28777,101 +27186,6 @@ "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", "license": "MIT" }, - "node_modules/inquirer": { - "version": "9.3.8", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.3.8.tgz", - "integrity": "sha512-pFGGdaHrmRKMh4WoDDSowddgjT1Vkl90atobmTeSmcPGdYiwikch/m/Ef5wRaiamHejtw0cUUMMerzDUXCci2w==", - "license": "MIT", - "peer": true, - "dependencies": { - "@inquirer/external-editor": "^1.0.2", - "@inquirer/figures": "^1.0.3", - "ansi-escapes": "^4.3.2", - "cli-width": "^4.1.0", - "mute-stream": "1.0.0", - "ora": "^5.4.1", - "run-async": "^3.0.0", - "rxjs": "^7.8.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^6.2.0", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inquirer/node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "license": "MIT", - "peer": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inquirer/node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -28921,15 +27235,6 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, "node_modules/iobuffer": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-5.4.0.tgz", @@ -29376,28 +27681,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29754,12 +28042,10 @@ "license": "MIT" }, "node_modules/isbinaryfile": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.3.tgz", - "integrity": "sha512-VR4gNjFaDP8csJQvzInG20JvBj8MaHYLxNOMXysxRbGM7tcsHZwCjhch3FubFtZBkuDbN55i4dUukGeIrzF+6g==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.7.tgz", + "integrity": "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==", "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 18.0.0" }, @@ -29782,14 +28068,6 @@ "node": ">=0.10.0" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -29861,23 +28139,6 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-processinfo/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/istanbul-lib-processinfo/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -30089,9 +28350,9 @@ } }, "node_modules/jest-changed-files/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -30175,16 +28436,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/diff-sequences": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", - "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-circus/node_modules/@jest/environment": { "version": "30.3.0", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", @@ -30252,16 +28503,16 @@ } }, "node_modules/jest-circus/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, "node_modules/jest-circus/node_modules/@sinonjs/fake-timers": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz", + "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -30503,9 +28754,9 @@ } }, "node_modules/jest-cli/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -30557,6 +28808,25 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/jest-cli/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/jest-config": { "version": "30.3.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", @@ -30641,16 +28911,16 @@ } }, "node_modules/jest-config/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, "node_modules/jest-config/node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, "license": "MIT", "dependencies": { @@ -30905,9 +29175,9 @@ } }, "node_modules/jest-each/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -31016,9 +29286,9 @@ } }, "node_modules/jest-environment-jsdom/node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -31039,26 +29309,6 @@ "acorn-walk": "^8.0.2" } }, - "node_modules/jest-environment-jsdom/node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jest-environment-jsdom/node_modules/cssom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", - "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", - "dev": true, - "license": "MIT" - }, "node_modules/jest-environment-jsdom/node_modules/cssstyle": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", @@ -31362,16 +29612,16 @@ } }, "node_modules/jest-environment-node/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, "node_modules/jest-environment-node/node_modules/@sinonjs/fake-timers": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz", + "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -31568,9 +29818,9 @@ } }, "node_modules/jest-haste-map/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -31678,9 +29928,9 @@ } }, "node_modules/jest-html-reporter/node_modules/@jest/schemas": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.1.tgz", - "integrity": "sha512-+g/1TKjFuGrf1Hh0QPCv0gISwBxJ+MQSNXmG9zjHy7BmFhtoJ9fdNhWJp3qUKRi93AOZHXtdxZgJ1vAtz6z65w==", + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", "dependencies": { @@ -31691,14 +29941,14 @@ } }, "node_modules/jest-html-reporter/node_modules/@jest/types": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.1.tgz", - "integrity": "sha512-HGwoYRVF0QSKJu1ZQX0o5ZrUrrhj0aOOFA8hXrumD7SIzjouevhawbTjmXdwOmURdGluU9DM/XvGm3NyFoiQjw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", + "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", "dependencies": { "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.1", + "@jest/schemas": "30.0.5", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -31710,9 +29960,9 @@ } }, "node_modules/jest-html-reporter/node_modules/@sinclair/typebox": { - "version": "0.34.37", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.37.tgz", - "integrity": "sha512-2TRuQVgQYfy+EzHRTIvkhv2ADEouJ2xNS/Vq+W5EuuewBdOrvATvljZTxHWZSTYr2sTjTHpGvucaGAt67S2akw==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -31787,9 +30037,9 @@ } }, "node_modules/jest-leak-detector/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -32166,9 +30416,9 @@ } }, "node_modules/jest-resolve/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -32331,16 +30581,16 @@ } }, "node_modules/jest-runner/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, "node_modules/jest-runner/node_modules/@sinonjs/fake-timers": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz", + "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -32624,16 +30874,16 @@ } }, "node_modules/jest-runtime/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, "node_modules/jest-runtime/node_modules/@sinonjs/fake-timers": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", - "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz", + "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -32641,9 +30891,9 @@ } }, "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, "license": "MIT", "dependencies": { @@ -32860,16 +31110,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-snapshot/node_modules/@jest/diff-sequences": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", - "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/jest-snapshot/node_modules/@jest/expect-utils": { "version": "30.3.0", "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", @@ -32916,9 +31156,9 @@ } }, "node_modules/jest-snapshot/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -33196,9 +31436,9 @@ } }, "node_modules/jest-validate/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -33300,9 +31540,9 @@ } }, "node_modules/jest-watcher/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -33430,9 +31670,9 @@ } }, "node_modules/jest/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -33454,9 +31694,9 @@ } }, "node_modules/joi": { - "version": "18.1.2", - "resolved": "https://registry.npmjs.org/joi/-/joi-18.1.2.tgz", - "integrity": "sha512-rF5MAmps5esSlhCA+N1b6IYHDw9j/btzGaqfgie522jS02Ju/HXBxamlXVlKEHAxoMKQL77HWI8jlqWsFuekZA==", + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/joi/-/joi-18.2.1.tgz", + "integrity": "sha512-2/OKlogiESf2Nh3TFCrRjrr9z1DRHeW0I+KReF67+4J0Ns+8hBtHRmoWAZ2OFU6I5+TWLEe6sVlSdXPjHm5UbQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -33558,28 +31798,28 @@ } }, "node_modules/jsdom": { - "version": "29.0.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.0.2.tgz", - "integrity": "sha512-9VnGEBosc/ZpwyOsJBCQ/3I5p7Q5ngOY14a9bf5btenAORmZfDse1ZEheMiWcJ3h81+Fv7HmJFdS0szo/waF2w==", + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.1.1.tgz", + "integrity": "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^5.1.5", - "@asamuzakjp/dom-selector": "^7.0.6", + "@asamuzakjp/css-color": "^5.1.11", + "@asamuzakjp/dom-selector": "^7.1.1", "@bramus/specificity": "^2.4.2", - "@csstools/css-syntax-patches-for-csstree": "^1.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.1.3", "@exodus/bytes": "^1.15.0", "css-tree": "^3.2.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.2.7", - "parse5": "^8.0.0", + "lru-cache": "^11.3.5", + "parse5": "^8.0.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.1", - "undici": "^7.24.5", + "undici": "^7.25.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", @@ -33599,9 +31839,9 @@ } }, "node_modules/jsdom/node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.2.tgz", - "integrity": "sha512-5GkLzz4prTIpoyeUiIu3iV6CSG3Plo7xRVOFPKI7FVEJ3mZ0A8SwK0XU3Gl7xAkiQ+mDyam+NNp875/C5y+jSA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.3.tgz", + "integrity": "sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==", "dev": true, "funding": [ { @@ -33642,9 +31882,9 @@ } }, "node_modules/jsdom/node_modules/@noble/hashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz", - "integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", + "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", "dev": true, "license": "MIT", "optional": true, @@ -33671,22 +31911,22 @@ } }, "node_modules/jsdom/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", "dev": true, "license": "BSD-2-Clause", "engines": { - "node": ">=0.12" + "node": ">=20.19.0" }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/jsdom/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -33701,51 +31941,18 @@ "license": "CC0-1.0" }, "node_modules/jsdom/node_modules/parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", - "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", "dev": true, "license": "MIT", "dependencies": { - "entities": "^6.0.0" + "entities": "^8.0.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/jsdom/node_modules/tldts": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.27.tgz", - "integrity": "sha512-I4FZcVFcqCRuT0ph6dCDpPuO4Xgzvh+spkcTr1gK7peIvxWauoloVO0vuy1FQnijT63ss6AsHB6+OIM4aXHbPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "tldts-core": "^7.0.27" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/jsdom/node_modules/tldts-core": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.27.tgz", - "integrity": "sha512-YQ7uPjgWUibIK6DW5lrKujGwUKhLevU4hcGbP5O6TcIUb+oTjJYJVWPS4nZsIHrEEEG6myk/oqAJUEQmpZrHsg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsdom/node_modules/tough-cookie": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", - "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tldts": "^7.0.5" - }, - "engines": { - "node": ">=16" - } - }, "node_modules/jsdom/node_modules/webidl-conversions": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", @@ -33811,14 +32018,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "license": "(AFL-2.1 OR BSD-3-Clause)", - "peer": true - }, "node_modules/json-schema-compare": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", @@ -33972,23 +32171,6 @@ "html2canvas": "^1.0.0-rc.5" } }, - "node_modules/jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "peer": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, "node_modules/jszip": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", @@ -34140,17 +32322,6 @@ "shell-quote": "^1.8.1" } }, - "node_modules/lazy-ass": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", - "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "> 0.8" - } - }, "node_modules/lerc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lerc/-/lerc-3.0.0.tgz", @@ -34238,16 +32409,6 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, - "node_modules/lerna/node_modules/@jest/diff-sequences": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", - "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/lerna/node_modules/@jest/schemas": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", @@ -34429,9 +32590,9 @@ } }, "node_modules/lerna/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -34508,13 +32669,6 @@ } } }, - "node_modules/lerna/node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true, - "license": "MIT" - }, "node_modules/lerna/node_modules/execa": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", @@ -34557,19 +32711,6 @@ } } }, - "node_modules/lerna/node_modules/get-stream": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", - "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/lerna/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -34683,16 +32824,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/lerna/node_modules/mute-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", - "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, "node_modules/lerna/node_modules/p-queue": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", @@ -34821,6 +32952,25 @@ "dev": true, "license": "ISC" }, + "node_modules/lerna/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -35172,54 +33322,6 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "node_modules/listr2/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/load-json-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", @@ -35308,6 +33410,12 @@ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "license": "MIT" }, + "node_modules/lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==", + "license": "MIT" + }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -35339,16 +33447,19 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, "license": "MIT" }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "dev": true, - "license": "MIT", - "peer": true + "node_modules/lodash.range": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.range/-/lodash.range-3.2.0.tgz", + "integrity": "sha512-Fgkb7SinmuzqgIhNhAElo0BL/R1rHCnhwSZf78omqSwvWqD0kD2ssOAutQonDKH/ldS8BxA72ORYI09qAY9CYg==", + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "license": "MIT" }, "node_modules/lodash.uniq": { "version": "4.5.0", @@ -35357,62 +33468,6 @@ "dev": true, "license": "MIT" }, - "node_modules/log-symbols": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.0.tgz", - "integrity": "sha512-zrc91EDk2M+2AXo/9BTvK91pqb7qrPg2nX/Hy+u8a5qQlbaOflCKO+6SqgZ+M+xUFxGdKTgwnGiL96b1W3ikRA==", - "license": "MIT", - "peer": true, - "dependencies": { - "is-unicode-supported": "^2.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, "node_modules/loglevel": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", @@ -35635,18 +33690,18 @@ "license": "MIT" }, "node_modules/mapbox-gl": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.20.0.tgz", - "integrity": "sha512-+rVQkf6ymUlAEJiQBZy0OiamJvQN4Uk15mRHI98PRUSmRS40GOoLJyEZEG39LEUtvmzc7qGh+4ygZfJ//O5VnQ==", + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.23.0.tgz", + "integrity": "sha512-zzjNAaMNvXnAVEUrYpOWmRVEBCIWgDAMLRPvSOoKY3smKvrINFVrRK/1jEpUDbEa7Ppf5Q/nwC6E07tz/i7IKw==", "license": "SEE LICENSE IN LICENSE.txt", "workspaces": [ "src/style-spec", + "packages/pmtiles-provider", "test/build/vite", "test/build/webpack", "test/build/typings" ], "dependencies": { - "@mapbox/jsonlint-lines-primitives": "^2.0.2", "@mapbox/mapbox-gl-supported": "^3.0.0", "@mapbox/point-geometry": "^1.1.0", "@mapbox/tiny-sdf": "^2.0.6", @@ -35690,9 +33745,9 @@ } }, "node_modules/mapbox-gl/node_modules/earcut": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.1.tgz", - "integrity": "sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", + "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==", "license": "ISC" }, "node_modules/mapbox-gl/node_modules/pbf": { @@ -35707,25 +33762,19 @@ "pbf": "bin/pbf" } }, - "node_modules/mapbox-gl/node_modules/quickselect": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", - "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", - "license": "ISC" - }, "node_modules/maplibre-gl": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.22.0.tgz", - "integrity": "sha512-nc8YA+YSEioMZg5W0cb6Cf3wQ8aJge66dsttyBgpOArOnlmFJO1Kc5G32kYVPeUYhLpBja83T99uanmJvYAIyQ==", + "version": "5.24.0", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.24.0.tgz", + "integrity": "sha512-ALyFxgtd5R+65UqZ/++lOqwWcC0SNho9c27fYSyLmG7AfnAul2o46F05aDJGPbFU57wos9dgcIySHs0Xe6ia3A==", "license": "BSD-3-Clause", "dependencies": { "@mapbox/jsonlint-lines-primitives": "^2.0.2", "@mapbox/point-geometry": "^1.1.0", - "@mapbox/tiny-sdf": "^2.0.7", + "@mapbox/tiny-sdf": "^2.1.0", "@mapbox/unitbezier": "^0.0.1", "@mapbox/vector-tile": "^2.0.4", "@mapbox/whoots-js": "^3.1.0", - "@maplibre/geojson-vt": "^6.0.4", + "@maplibre/geojson-vt": "^6.1.0", "@maplibre/maplibre-gl-style-spec": "^24.8.1", "@maplibre/mlt": "^1.1.8", "@maplibre/vt-pbf": "^4.3.0", @@ -35764,6 +33813,15 @@ "pbf": "^4.0.1" } }, + "node_modules/maplibre-gl/node_modules/@maplibre/geojson-vt": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-6.1.0.tgz", + "integrity": "sha512-2eIY4gZxeKIVOZVNkAMb+5NgXhgsMQpOveTQAvnp53LYqHGJZDidk7Ew0Tged9PThidpbS+NFTh0g4zivhPDzQ==", + "license": "ISC", + "dependencies": { + "kdbush": "^4.0.2" + } + }, "node_modules/maplibre-gl/node_modules/earcut": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", @@ -35782,12 +33840,6 @@ "pbf": "bin/pbf" } }, - "node_modules/maplibre-gl/node_modules/quickselect": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", - "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", - "license": "ISC" - }, "node_modules/markdown-table": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", @@ -35799,9 +33851,9 @@ } }, "node_modules/markdown-to-jsx": { - "version": "9.7.15", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-9.7.15.tgz", - "integrity": "sha512-e+zu57JYDDEiCYNSC8ohEeihBcAs73QdS++qd9Ffmeo6EU+yBFsfbgntkaT7lU2pRU6W4Yqh8a0cvpbmad7wHA==", + "version": "9.7.16", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-9.7.16.tgz", + "integrity": "sha512-+LEgOlYfUEB9i2Oaxasec9H2HytB1+SQcgwFmQiNTKwe8cQ2E9bDNgePGq6ChIycMxtpcEY0g44aQ3uJoMw8eg==", "license": "MIT", "engines": { "node": ">= 18" @@ -35844,9 +33896,9 @@ "license": "Unlicense" }, "node_modules/match-sorter": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-8.2.0.tgz", - "integrity": "sha512-qRVB7wYMJXizAWR4TKo5UYwgW7oAVzA8V9jve0wGzRvV91ou9dcqL+/2gJtD0PZ/Pm2Fq6cVT4VHXHmDFVMGRA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-8.3.0.tgz", + "integrity": "sha512-8Py1GbZi5zsclYSFcPAH4H5xfTbeD0bOREA7qP/t8bW4MbOSlPl8sbqHOedEV7O+Bxyvxm6xs/v6BXJGe+JDNA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.8", @@ -35909,6 +33961,375 @@ "@types/unist": "^2" } }, + "node_modules/mdast-util-find-and-replace": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz", + "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-from-markdown/node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz", + "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-gfm-autolink-literal": "^1.0.0", + "mdast-util-gfm-footnote": "^1.0.0", + "mdast-util-gfm-strikethrough": "^1.0.0", + "mdast-util-gfm-table": "^1.0.0", + "mdast-util-gfm-task-list-item": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz", + "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "ccount": "^2.0.0", + "mdast-util-find-and-replace": "^2.0.0", + "micromark-util-character": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz", + "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0", + "micromark-util-normalize-identifier": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz", + "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz", + "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-to-markdown": "^1.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz", + "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-phrasing/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-to-hast": { "version": "13.2.1", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", @@ -35946,9 +34367,9 @@ "license": "MIT" }, "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -35975,9 +34396,9 @@ } }, "node_modules/mdast-util-to-hast/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -35988,10 +34409,61 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-to-markdown": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", + "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "micromark-util-decode-string": "^1.0.0", + "unist-util-visit": "^4.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, "node_modules/mdn-data": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true, "license": "CC0-1.0" }, @@ -36006,192 +34478,21 @@ } }, "node_modules/mem-fs": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/mem-fs/-/mem-fs-4.1.2.tgz", - "integrity": "sha512-CMwusHK+Kz0tu1qjgbd0rwcJxzgg76jlkPpqK+pDTv8Hth8JyM7JlgxNWaAFRKe969HATPTz/sp8T63QflyI+w==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/mem-fs/-/mem-fs-4.1.4.tgz", + "integrity": "sha512-NlRHmUiEcxDHI7FeDlrrTZP5YFvnoS74wEf5OrQ7NAg83B2Rv3oF+FWr961I0rVdxkKbZMjq2BcV7VFWGFPkog==", "license": "MIT", "peer": true, "dependencies": { "@types/node": ">=18", - "@types/vinyl": "^2.0.8", - "vinyl": "^3.0.0", + "@types/vinyl": "^2.0.12", + "vinyl": "^3.0.1", "vinyl-file": "^5.0.0" }, "engines": { "node": ">=18.0.0" } }, - "node_modules/mem-fs-editor": { - "version": "11.1.4", - "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-11.1.4.tgz", - "integrity": "sha512-Z4QX14Ev6eOVTuVSayS5rdiOua6C3gHcFw+n9Qc7WiaVTbC+H8b99c32MYGmbQN9UFHJeI/p3lf3LAxiIzwEmA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@types/ejs": "^3.1.4", - "@types/node": ">=18", - "binaryextensions": "^6.11.0", - "commondir": "^1.0.1", - "deep-extend": "^0.6.0", - "ejs": "^3.1.10", - "globby": "^14.0.2", - "isbinaryfile": "5.0.3", - "minimatch": "^9.0.3", - "multimatch": "^7.0.0", - "normalize-path": "^3.0.0", - "textextensions": "^6.11.0", - "vinyl": "^3.0.0" - }, - "acceptDependencies": { - "isbinaryfile": "^5.0.3" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "mem-fs": "^4.0.0" - } - }, - "node_modules/mem-fs-editor/node_modules/array-differ": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-4.0.0.tgz", - "integrity": "sha512-Q6VPTLMsmXZ47ENG3V+wQyZS1ZxXMxFyYzA+Z/GMrJ6yIutAIEf9wTyroTzmGjNfox9/h3GdGBCVh43GVFx4Uw==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mem-fs-editor/node_modules/array-union": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", - "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mem-fs-editor/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/mem-fs-editor/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/mem-fs-editor/node_modules/globby": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", - "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mem-fs-editor/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mem-fs-editor/node_modules/multimatch": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-7.0.0.tgz", - "integrity": "sha512-SYU3HBAdF4psHEL/+jXDKHO95/m5P2RvboHT2Y0WtTttvJLP4H/2WS9WlQPFvF6C8d6SpLw8vjCnQOnVIVOSJQ==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "array-differ": "^4.0.0", - "array-union": "^3.0.1", - "minimatch": "^9.0.3" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mem-fs-editor/node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mem-fs-editor/node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/memfs": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", @@ -36262,17 +34563,11 @@ } }, "node_modules/meow/node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } + "license": "ISC" }, "node_modules/meow/node_modules/locate-path": { "version": "5.0.0", @@ -36316,6 +34611,32 @@ "node": ">=10" } }, + "node_modules/meow/node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/normalize-package-data/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/meow/node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -36389,13 +34710,6 @@ "node": ">=8" } }, - "node_modules/meow/node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -36409,16 +34723,6 @@ "validate-npm-package-license": "^3.0.1" } }, - "node_modules/meow/node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", @@ -36429,6 +34733,16 @@ "node": ">=8" } }, + "node_modules/meow/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/meow/node_modules/type-fest": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", @@ -36519,6 +34833,961 @@ "integrity": "sha512-awNbTOqCxK1DBGjalK3xqWIstBZgN6fxsMSiXLs9/spqWkF2pAhb2rrYCFSsr1/tT7PhcDGjZndG8SWYn0byYA==", "license": "MIT" }, + "node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz", + "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^1.0.0", + "micromark-extension-gfm-footnote": "^1.0.0", + "micromark-extension-gfm-strikethrough": "^1.0.0", + "micromark-extension-gfm-table": "^1.0.0", + "micromark-extension-gfm-tagfilter": "^1.0.0", + "micromark-extension-gfm-task-list-item": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz", + "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz", + "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==", + "license": "MIT", + "dependencies": { + "micromark-core-commonmark": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz", + "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==", + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-table": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz", + "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==", + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz", + "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz", + "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==", + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromark-util-character": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", @@ -36539,6 +35808,259 @@ "micromark-util-types": "^2.0.0" } }, + "node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-combine-extensions/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromark-util-encode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", @@ -36555,6 +36077,92 @@ ], "license": "MIT" }, + "node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-resolve-all/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromark-util-sanitize-uri": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", @@ -36576,6 +36184,60 @@ "micromark-util-symbol": "^2.0.0" } }, + "node_modules/micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromark-util-symbol": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", @@ -36593,9 +36255,98 @@ "license": "MIT" }, "node_modules/micromark-util-types": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz", - "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark/node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", "funding": [ { "type": "GitHub Sponsors", @@ -36661,24 +36412,12 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -36935,7 +36674,6 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "license": "MIT", - "peer": true, "engines": { "node": "*" } @@ -36991,6 +36729,71 @@ "multicast-dns": "cli.js" } }, + "node_modules/multimatch": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-8.0.0.tgz", + "integrity": "sha512-0D10M2/MnEyvoog7tmozlpSqL3HEU1evxUFa3v1dsKYmBDFSP1dLSX4CH2rNjpQ+4Fps8GKmUkCwiKryaKqd9A==", + "license": "MIT", + "dependencies": { + "array-differ": "^4.0.0", + "array-union": "^3.0.1", + "minimatch": "^10.2.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/multimatch/node_modules/array-union": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", + "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/multimatch/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/multimatch/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/multimatch/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/murmurhash-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", @@ -37007,19 +36810,19 @@ } }, "node_modules/mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, "license": "ISC", - "peer": true, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/nanoid": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.7.tgz", - "integrity": "sha512-ua3NDgISf6jdwezAheMOk4mbE1LXjm1DfMUDMuJf4AqxLFK3ccGpgWizwa5YV7Yz9EpXwEaWoRXSb/BnV0t5dQ==", + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.11.tgz", + "integrity": "sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg==", "funding": [ { "type": "github", @@ -37320,6 +37123,20 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/normalize-package-data": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", + "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^9.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -37381,29 +37198,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/npm-package-arg/node_modules/hosted-git-info": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^11.1.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm-package-arg/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/npm-packlist": { "version": "10.0.3", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.3.tgz", @@ -37612,16 +37406,6 @@ } } }, - "node_modules/nx/node_modules/@jest/diff-sequences": { - "version": "30.3.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", - "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/nx/node_modules/@jest/schemas": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", @@ -37636,9 +37420,9 @@ } }, "node_modules/nx/node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "version": "0.34.49", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", + "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "dev": true, "license": "MIT" }, @@ -37682,19 +37466,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/nx/node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/nx/node_modules/ignore": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", @@ -37765,13 +37536,31 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/nx/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/nyc": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", - "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", @@ -37780,12 +37569,12 @@ "decamelize": "^1.2.0", "find-cache-dir": "^3.2.0", "find-up": "^4.1.0", - "foreground-child": "^3.3.0", + "foreground-child": "^2.0.0", "get-package-type": "^0.1.0", "glob": "^7.1.6", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^6.0.2", + "istanbul-lib-instrument": "^4.0.0", "istanbul-lib-processinfo": "^2.0.2", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", @@ -37805,7 +37594,7 @@ "nyc": "bin/nyc.js" }, "engines": { - "node": ">=18" + "node": ">=8.9" } }, "node_modules/nyc/node_modules/camelcase": { @@ -37814,7 +37603,6 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -37825,7 +37613,6 @@ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -37837,8 +37624,7 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/nyc/node_modules/find-cache-dir": { "version": "3.3.2", @@ -37846,7 +37632,6 @@ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -37865,7 +37650,6 @@ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -37874,13 +37658,42 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/nyc/node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/nyc/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-locate": "^4.1.0" }, @@ -37894,7 +37707,6 @@ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "semver": "^6.0.0" }, @@ -37905,24 +37717,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/nyc/node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/nyc/node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-try": "^2.0.0" }, @@ -37939,7 +37739,6 @@ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-limit": "^2.2.0" }, @@ -37953,7 +37752,6 @@ "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -37961,22 +37759,14 @@ "node": ">=8" } }, - "node_modules/nyc/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "node_modules/nyc/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "semver": "bin/semver.js" } }, "node_modules/nyc/node_modules/y18n": { @@ -37984,8 +37774,7 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/nyc/node_modules/yargs": { "version": "15.4.1", @@ -37993,7 +37782,6 @@ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -38017,7 +37805,6 @@ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -38182,17 +37969,17 @@ "license": "MIT" }, "node_modules/ol": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/ol/-/ol-10.8.0.tgz", - "integrity": "sha512-kLk7jIlJvKyhVMAjORTXKjzlM6YIByZ1H/d0DBx3oq8nSPCG6/gbLr5RxukzPgwbhnAqh+xHNCmrvmFKhVMvoQ==", + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/ol/-/ol-10.9.0.tgz", + "integrity": "sha512-svbbgVQUmEHaKpLQ8kRySojs59Brvgl2zYIrqG9eQNXGfsbi55rQasZIDpwpQzDL6OlzrUb0H4hQaiX9wDoGmA==", "license": "BSD-2-Clause", "dependencies": { "@types/rbush": "4.0.0", "earcut": "^3.0.0", - "geotiff": "^3.0.2", + "geotiff": "^3.0.5 || ^3.1.0-beta.0", "pbf": "4.0.1", "rbush": "^4.0.0", - "zarrita": "^0.6.0" + "zarrita": "^0.7.1" }, "funding": { "type": "opencollective", @@ -38253,6 +38040,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -38477,14 +38265,6 @@ "node": ">=0.10.0" } }, - "node_modules/ospath": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", - "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -38503,9 +38283,9 @@ } }, "node_modules/oxlint": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.56.0.tgz", - "integrity": "sha512-Q+5Mj5PVaH/R6/fhMMFzw4dT+KPB+kQW4kaL8FOIq7tfhlnEVp6+3lcWqFruuTNlUo9srZUW3qH7Id4pskeR6g==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.62.0.tgz", + "integrity": "sha512-1uFkg6HakjsGIpW9wNdeW4/2LOHW9MEkoWjZUTUfQtIHyLIZPYt00w3Sg+H3lH+206FgBPHBbW5dVE5l2ExECQ==", "dev": true, "license": "MIT", "bin": { @@ -38518,28 +38298,28 @@ "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { - "@oxlint/binding-android-arm-eabi": "1.56.0", - "@oxlint/binding-android-arm64": "1.56.0", - "@oxlint/binding-darwin-arm64": "1.56.0", - "@oxlint/binding-darwin-x64": "1.56.0", - "@oxlint/binding-freebsd-x64": "1.56.0", - "@oxlint/binding-linux-arm-gnueabihf": "1.56.0", - "@oxlint/binding-linux-arm-musleabihf": "1.56.0", - "@oxlint/binding-linux-arm64-gnu": "1.56.0", - "@oxlint/binding-linux-arm64-musl": "1.56.0", - "@oxlint/binding-linux-ppc64-gnu": "1.56.0", - "@oxlint/binding-linux-riscv64-gnu": "1.56.0", - "@oxlint/binding-linux-riscv64-musl": "1.56.0", - "@oxlint/binding-linux-s390x-gnu": "1.56.0", - "@oxlint/binding-linux-x64-gnu": "1.56.0", - "@oxlint/binding-linux-x64-musl": "1.56.0", - "@oxlint/binding-openharmony-arm64": "1.56.0", - "@oxlint/binding-win32-arm64-msvc": "1.56.0", - "@oxlint/binding-win32-ia32-msvc": "1.56.0", - "@oxlint/binding-win32-x64-msvc": "1.56.0" + "@oxlint/binding-android-arm-eabi": "1.62.0", + "@oxlint/binding-android-arm64": "1.62.0", + "@oxlint/binding-darwin-arm64": "1.62.0", + "@oxlint/binding-darwin-x64": "1.62.0", + "@oxlint/binding-freebsd-x64": "1.62.0", + "@oxlint/binding-linux-arm-gnueabihf": "1.62.0", + "@oxlint/binding-linux-arm-musleabihf": "1.62.0", + "@oxlint/binding-linux-arm64-gnu": "1.62.0", + "@oxlint/binding-linux-arm64-musl": "1.62.0", + "@oxlint/binding-linux-ppc64-gnu": "1.62.0", + "@oxlint/binding-linux-riscv64-gnu": "1.62.0", + "@oxlint/binding-linux-riscv64-musl": "1.62.0", + "@oxlint/binding-linux-s390x-gnu": "1.62.0", + "@oxlint/binding-linux-x64-gnu": "1.62.0", + "@oxlint/binding-linux-x64-musl": "1.62.0", + "@oxlint/binding-openharmony-arm64": "1.62.0", + "@oxlint/binding-win32-arm64-msvc": "1.62.0", + "@oxlint/binding-win32-ia32-msvc": "1.62.0", + "@oxlint/binding-win32-x64-msvc": "1.62.0" }, "peerDependencies": { - "oxlint-tsgolint": ">=0.15.0" + "oxlint-tsgolint": ">=0.18.0" }, "peerDependenciesMeta": { "oxlint-tsgolint": { @@ -38628,23 +38408,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-queue": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.0.tgz", - "integrity": "sha512-mxLDbbGIBEXTJL0zEx8JIylaj3xQ7Z/7eEVjcF9fJX4DBiH9oqe+oahYnlKKxm0Ci9TlWTyhSHgygxMxjIB2jw==", - "license": "MIT", - "peer": true, - "dependencies": { - "eventemitter3": "^5.0.1", - "p-timeout": "^6.1.2" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-reduce": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", @@ -38655,19 +38418,6 @@ "node": ">=8" } }, - "node_modules/p-timeout": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", - "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -39138,9 +38888,9 @@ } }, "node_modules/path-expression-matcher": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.2.0.tgz", - "integrity": "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", "funding": [ { "type": "github", @@ -39250,20 +39000,12 @@ "through2": "^2.0.3" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "devOptional": true, - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/picocolors": { "version": "1.1.1", @@ -39535,9 +39277,9 @@ } }, "node_modules/postcss-calc/node_modules/postcss-selector-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", - "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, "license": "MIT", "dependencies": { @@ -39776,9 +39518,9 @@ } }, "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", - "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, "license": "MIT", "dependencies": { @@ -39806,9 +39548,9 @@ } }, "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", - "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, "license": "MIT", "dependencies": { @@ -40082,9 +39824,9 @@ "license": "MIT" }, "node_modules/postcss/node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -40120,9 +39862,9 @@ } }, "node_modules/preact": { - "version": "10.28.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.3.tgz", - "integrity": "sha512-tCmoRkPQLpBeWzpmbhryairGnhW9tKV6c6gr/w+RhoRoKEJwsjzipwp//1oCpGPOchvSLaAPlpcJi9MwMmoPyA==", + "version": "10.29.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.1.tgz", + "integrity": "sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg==", "license": "MIT", "peer": true, "funding": { @@ -40187,20 +39929,6 @@ } } }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", @@ -40472,14 +40200,6 @@ "node": ">= 0.10" } }, - "node_modules/proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/psl": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", @@ -40503,18 +40223,6 @@ "node": ">=6" } }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -40634,6 +40342,12 @@ "node": ">=8" } }, + "node_modules/quickselect": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", + "license": "ISC" + }, "node_modules/quote-stream": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz", @@ -40737,12 +40451,6 @@ "quickselect": "^3.0.0" } }, - "node_modules/rbush/node_modules/quickselect": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", - "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", - "license": "ISC" - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -40891,6 +40599,21 @@ "react-dom": ">=16.9.0" } }, + "node_modules/rc-input": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.8.0.tgz", + "integrity": "sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.18.1" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, "node_modules/rc-input-number": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.5.0.tgz", @@ -40908,21 +40631,6 @@ "react-dom": ">=16.9.0" } }, - "node_modules/rc-input-number/node_modules/rc-input": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.8.0.tgz", - "integrity": "sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.11.1", - "classnames": "^2.2.1", - "rc-util": "^5.18.1" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, "node_modules/rc-mentions": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.20.0.tgz", @@ -40942,21 +40650,6 @@ "react-dom": ">=16.9.0" } }, - "node_modules/rc-mentions/node_modules/rc-input": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.8.0.tgz", - "integrity": "sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.11.1", - "classnames": "^2.2.1", - "rc-util": "^5.18.1" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, "node_modules/rc-menu": { "version": "9.16.1", "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.16.1.tgz", @@ -41273,21 +40966,6 @@ "react-dom": ">=16.9.0" } }, - "node_modules/rc-textarea/node_modules/rc-input": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.8.0.tgz", - "integrity": "sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.11.1", - "classnames": "^2.2.1", - "rc-util": "^5.18.1" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, "node_modules/rc-tooltip": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.4.0.tgz", @@ -41415,13 +41093,12 @@ } }, "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" @@ -41446,9 +41123,9 @@ } }, "node_modules/react-arborist": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/react-arborist/-/react-arborist-3.4.3.tgz", - "integrity": "sha512-yFnq1nIQhT2uJY4TZVz2tgAiBb9lxSyvF4vC3S8POCK8xLzjGIxVv3/4dmYquQJ7AHxaZZArRGHiHKsEewKdTQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/react-arborist/-/react-arborist-3.5.0.tgz", + "integrity": "sha512-FdXOICSt7P2h+Pxin1ULN02b4qrXJznNcshgwwWVtuYMLWSJcD245PQ4HOSj/Lr2T1uEegmnEm5Lbns2hUUsqg==", "license": "MIT", "dependencies": { "react-dnd": "^14.0.3", @@ -41568,9 +41245,9 @@ } }, "node_modules/react-checkbox-tree/node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", @@ -41586,15 +41263,15 @@ } }, "node_modules/react-diff-viewer-continued": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/react-diff-viewer-continued/-/react-diff-viewer-continued-4.2.0.tgz", - "integrity": "sha512-KXeevuPpMRNDAtF878G04Yih/01DBBoC+RjDzWiA5S6TPtUzSfqF5XOlEWyXVWvJuz5n+EQ9QdUQd0ffK2By6w==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/react-diff-viewer-continued/-/react-diff-viewer-continued-4.2.2.tgz", + "integrity": "sha512-8wT0/smXGox70oXJ7SZkTYF1p1Uh7jNGXhN7ykqrqPven0sZ+wM2c62SG3ZqORx5aW75te+WhmUWo0E4NyoSvg==", "license": "MIT", "dependencies": { "@emotion/css": "^11.13.5", "@emotion/react": "^11.14.0", "classnames": "^2.5.1", - "diff": "^8.0.3", + "diff": "^9.0.0", "js-yaml": "^4.1.1", "memoize-one": "^6.0.0" }, @@ -41613,9 +41290,9 @@ "license": "Python-2.0" }, "node_modules/react-diff-viewer-continued/node_modules/diff": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", - "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz", + "integrity": "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==", "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -41697,17 +41374,16 @@ } }, "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.3.1" } }, "node_modules/react-draggable": { @@ -41794,6 +41470,96 @@ "react": "*" } }, + "node_modules/react-map-gl": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/react-map-gl/-/react-map-gl-8.1.1.tgz", + "integrity": "sha512-aSqFAFoxvY7wxbGI93Dz0E41171mkAb3GcNbnkFIotmu88OFw495os6mIDZSi7irYNT/PZEIOEHUxhun4ToGuQ==", + "license": "MIT", + "dependencies": { + "@vis.gl/react-mapbox": "8.1.1", + "@vis.gl/react-maplibre": "8.1.1" + }, + "peerDependencies": { + "mapbox-gl": ">=1.13.0", + "maplibre-gl": ">=1.13.0", + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + }, + "peerDependenciesMeta": { + "mapbox-gl": { + "optional": true + }, + "maplibre-gl": { + "optional": true + } + } + }, + "node_modules/react-map-gl/node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "19.3.3", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.3.tgz", + "integrity": "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==", + "license": "ISC", + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^3.0.0", + "minimist": "^1.2.8", + "rw": "^1.3.3", + "sort-object": "^3.0.3" + }, + "bin": { + "gl-style-format": "dist/gl-style-format.mjs", + "gl-style-migrate": "dist/gl-style-migrate.mjs", + "gl-style-validate": "dist/gl-style-validate.mjs" + } + }, + "node_modules/react-map-gl/node_modules/@vis.gl/react-mapbox": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@vis.gl/react-mapbox/-/react-mapbox-8.1.1.tgz", + "integrity": "sha512-KMDTjtWESXxHS4uqWxjsvgQUHvuL3Z6SdKe68o7Nxma2qUfuyH3x4TCkIqGn3FQTrFvZLWvTnSAbGvtm+Kd13A==", + "license": "MIT", + "peerDependencies": { + "mapbox-gl": ">=3.5.0", + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + }, + "peerDependenciesMeta": { + "mapbox-gl": { + "optional": true + } + } + }, + "node_modules/react-map-gl/node_modules/@vis.gl/react-maplibre": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@vis.gl/react-maplibre/-/react-maplibre-8.1.1.tgz", + "integrity": "sha512-iUOfzJAhFAJwEZp1644tQb7LOTFgi5/GzdaztkhzNgFVuoF2Ez7guvwZjQAKB9CN2TlHTgNuYH8UW85kO7cVhw==", + "license": "MIT", + "dependencies": { + "@maplibre/maplibre-gl-style-spec": "^19.2.1" + }, + "peerDependencies": { + "maplibre-gl": ">=4.0.0", + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + }, + "peerDependenciesMeta": { + "maplibre-gl": { + "optional": true + } + } + }, + "node_modules/react-map-gl/node_modules/json-stringify-pretty-compact": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz", + "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==", + "license": "MIT" + }, + "node_modules/react-map-gl/node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, "node_modules/react-markdown": { "version": "8.0.7", "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.7.tgz", @@ -42010,22 +41776,6 @@ "node": ">=6" } }, - "node_modules/react-sortable-hoc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/react-sortable-hoc/-/react-sortable-hoc-2.0.0.tgz", - "integrity": "sha512-JZUw7hBsAHXK7PTyErJyI7SopSBFRcFHDjWW5SWjcugY0i6iH7f+eJkY8cJmGMlZ1C9xz1J3Vjz0plFpavVeRg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.2.0", - "invariant": "^2.2.4", - "prop-types": "^15.5.7" - }, - "peerDependencies": { - "prop-types": "^15.5.7", - "react": "^16.3.0 || ^17.0.0", - "react-dom": "^16.3.0 || ^17.0.0" - } - }, "node_modules/react-split": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/react-split/-/react-split-2.0.14.tgz", @@ -42153,6 +41903,86 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/read-package-up": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-12.0.0.tgz", + "integrity": "sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw==", + "license": "MIT", + "dependencies": { + "find-up-simple": "^1.0.1", + "read-pkg": "^10.0.0", + "type-fest": "^5.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-package-up/node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-package-up/node_modules/parse-json/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-package-up/node_modules/read-pkg": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", + "integrity": "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==", + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.4", + "normalize-package-data": "^8.0.0", + "parse-json": "^8.3.0", + "type-fest": "^5.4.4", + "unicorn-magic": "^0.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-package-up/node_modules/type-fest": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", + "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -42348,16 +42178,6 @@ "node": ">=4" } }, - "node_modules/read/node_modules/mute-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", - "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -42751,9 +42571,9 @@ } }, "node_modules/rehype-raw/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -42810,6 +42630,31 @@ "node": ">=4" } }, + "node_modules/remark-gfm": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", + "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-gfm": "^2.0.0", + "micromark-extension-gfm": "^2.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, "node_modules/remark-parse": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", @@ -42834,498 +42679,6 @@ "@types/unist": "^2" } }, - "node_modules/remark-parse/node_modules/mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse/node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse/node_modules/micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/remark-parse/node_modules/micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/remark-parse/node_modules/micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/remark-parse/node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/remark-parse/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/remark-parse/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/remark-rehype": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", @@ -43581,17 +42934,6 @@ "node": ">= 10" } }, - "node_modules/request-progress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", - "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "throttleit": "^1.0.0" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -43749,6 +43091,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, "license": "MIT", "dependencies": { "onetime": "^5.1.0", @@ -43778,14 +43121,6 @@ "node": ">=0.10.0" } }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/rgbcolor": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", @@ -43796,6 +43131,23 @@ "node": ">= 0.8.15" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rison": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/rison/-/rison-0.1.1.tgz", @@ -43803,9 +43155,9 @@ "license": "Apache-2.0" }, "node_modules/robust-predicates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", + "integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==", "license": "Unlicense" }, "node_modules/run-applescript": { @@ -43821,16 +43173,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/run-async": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -43863,6 +43205,7 @@ "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -43965,6 +43308,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, "license": "MIT" }, "node_modules/sax": { @@ -43990,13 +43334,12 @@ } }, "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "license": "MIT", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { @@ -44344,6 +43687,12 @@ "integrity": "sha512-b6i4ZpVuUxB9h5gfCxPiusKYkqTMOjEbBs4wMaFbkfia4yFv92UKZ6Df8WXcKbn08JNL/abvg3FnMAOfakDvUw==", "license": "MIT" }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, "node_modules/shapefile": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/shapefile/-/shapefile-0.3.1.tgz", @@ -44485,6 +43834,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, "license": "ISC" }, "node_modules/sigstore": { @@ -44506,13 +43856,15 @@ } }, "node_modules/simple-git": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.33.0.tgz", - "integrity": "sha512-D4V/tGC2sjsoNhoMybKyGoE+v8A60hRawKQ1iFRA1zwuDgGZCBJ4ByOzZ5J8joBbi4Oam0qiPH+GhzmSBwbJng==", + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.36.0.tgz", + "integrity": "sha512-cGQjLjK8bxJw4QuYT7gxHw3/IouVESbhahSsHrX97MzCL1gu2u7oy38W6L2ZIGECEfIBG4BabsWDPjBxJENv9Q==", "license": "MIT", "dependencies": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", + "@simple-git/args-pathspec": "^1.0.3", + "@simple-git/argv-parser": "^1.1.0", "debug": "^4.4.0" }, "funding": { @@ -44530,9 +43882,9 @@ } }, "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", "license": "MIT" }, "node_modules/simple-zstd": { @@ -44588,22 +43940,6 @@ "node": ">=6" } }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -44916,23 +44252,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/spawn-wrap/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/spawn-wrap/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -45153,41 +44472,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "license": "BSD-3-Clause" }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/ssri": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", @@ -45474,19 +44758,6 @@ "node": ">= 0.8" } }, - "node_modules/stdin-discarder": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", - "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", @@ -45501,13 +44772,13 @@ } }, "node_modules/storybook": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.17.tgz", - "integrity": "sha512-krR/l680A6qVnkGiK9p8jY0ucX3+kFCs2f4zw+S3w2Cdq8EiM/tFebPcX2V4S3z2UsO0v0dwAJOJNpzbFPdmVg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.18.tgz", + "integrity": "sha512-p8seiSI6FiVY6P3V0pG+5v7c8pDMehMAFRWEhG5XqIBSQszzOjDnW2rNvm3odoLKfo3V3P6Cs6Hv9ILzymULyQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/core": "8.6.17" + "@storybook/core": "8.6.18" }, "bin": { "getstorybook": "bin/index.cjs", @@ -46152,9 +45423,9 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz", - "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.5.0.tgz", + "integrity": "sha512-UYhptBwhWvfIjKd/UuFo6D8uq9xpGLDK+z8EDsj/zWhrTaH34cKEbrkMKfV5YWqGBvAYA3tlzZbs2R+qYrbQJA==", "dev": true, "license": "MIT", "dependencies": { @@ -46217,9 +45488,9 @@ } }, "node_modules/terser/node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -46315,41 +45586,22 @@ } }, "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==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz", + "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==", "dev": true, - "license": "Unlicense", + "license": "MIT", "engines": { "node": ">=10.18" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, "peerDependencies": { "tslib": "^2" } }, - "node_modules/thread-loader": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-4.0.4.tgz", - "integrity": "sha512-tXagu6Hivd03wB2tiS1bqvw345sc7mKei32EgpYpq31ZLes9FN0mEK2nKzXLRFgwt3PsBB0E/MZDp159rDoqwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.1.0", - "neo-async": "^2.6.2", - "schema-utils": "^4.2.0" - }, - "engines": { - "node": ">= 16.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, "node_modules/throttle-debounce": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", @@ -46359,17 +45611,6 @@ "node": ">=12.22" } }, - "node_modules/throttleit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", - "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -46455,13 +45696,13 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -46526,26 +45767,24 @@ } }, "node_modules/tldts": { - "version": "6.1.74", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.74.tgz", - "integrity": "sha512-O5vTZ1UmmEmrLl/59U9igitnSMlprALLaLgbv//dEvjobPT9vyURhHXKMCDLEhn3qxZFIkb9PwAfNYV0Ol7RPQ==", + "version": "7.0.29", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.29.tgz", + "integrity": "sha512-JIXCerhudr/N6OWLwLF1HVsTTUo7ry6qHa5eWZEkiMuxsIiAACL55tGLfqfHfoH7QaMQUW8fngD7u7TxWexYQg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "tldts-core": "^6.1.74" + "tldts-core": "^7.0.29" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "6.1.74", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.74.tgz", - "integrity": "sha512-gTwtY6L2GfuxiL4CWpLknv9JDYYqBvKCk/BT5uAaAvCA0s6pzX7lr2IrkQZSUlnSjRHIjTl8ZwKCVXJ7XNRWYw==", + "version": "7.0.29", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.29.tgz", + "integrity": "sha512-W99NuU7b1DcG3uJ3v9k9VztCH3WialNbBkBft5wCs8V8mexu0XQqaZEYb9l9RNNzK8+3EJ9PKWB0/RUtTQ/o+Q==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/tmp": { "version": "0.2.5", @@ -46650,14 +45889,13 @@ } }, "node_modules/tough-cookie": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.0.tgz", - "integrity": "sha512-rvZUv+7MoBYTiDmFPBrhL7Ujx9Sk+q9wwm22x8c8T5IJaR+Wsyc7TNxbVxo84kZoRJZZMazowFLqpankBEQrGg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", + "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { - "tldts": "^6.1.32" + "tldts": "^7.0.5" }, "engines": { "node": ">=16" @@ -46704,9 +45942,9 @@ } }, "node_modules/tree-dump": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.3.tgz", - "integrity": "sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -46771,16 +46009,16 @@ } }, "node_modules/ts-api-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", - "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/ts-dedent": { @@ -46903,9 +46141,9 @@ } }, "node_modules/ts-node/node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -46914,18 +46152,6 @@ "node": ">=0.4.0" } }, - "node_modules/ts-node/node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ts-node/node_modules/diff": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", @@ -46977,9 +46203,9 @@ } }, "node_modules/tscw-config/node_modules/strip-json-comments": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", - "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", + "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==", "dev": true, "license": "MIT", "engines": { @@ -47039,9 +46265,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz", - "integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", "cpu": [ "ppc64" ], @@ -47056,9 +46282,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-arm": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz", - "integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", "cpu": [ "arm" ], @@ -47073,9 +46299,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz", - "integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", "cpu": [ "arm64" ], @@ -47090,9 +46316,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz", - "integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", "cpu": [ "x64" ], @@ -47107,9 +46333,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz", - "integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", "cpu": [ "arm64" ], @@ -47124,9 +46350,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/darwin-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz", - "integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", "cpu": [ "x64" ], @@ -47141,9 +46367,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz", - "integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", "cpu": [ "arm64" ], @@ -47158,9 +46384,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz", - "integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", "cpu": [ "x64" ], @@ -47175,9 +46401,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-arm": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz", - "integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", "cpu": [ "arm" ], @@ -47192,9 +46418,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz", - "integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", "cpu": [ "arm64" ], @@ -47209,9 +46435,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-ia32": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz", - "integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", "cpu": [ "ia32" ], @@ -47226,9 +46452,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-loong64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz", - "integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", "cpu": [ "loong64" ], @@ -47243,9 +46469,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz", - "integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", "cpu": [ "mips64el" ], @@ -47260,9 +46486,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz", - "integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", "cpu": [ "ppc64" ], @@ -47277,9 +46503,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz", - "integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", "cpu": [ "riscv64" ], @@ -47294,9 +46520,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-s390x": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz", - "integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", "cpu": [ "s390x" ], @@ -47311,9 +46537,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz", - "integrity": "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", "cpu": [ "x64" ], @@ -47328,9 +46554,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz", - "integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", "cpu": [ "x64" ], @@ -47345,9 +46571,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz", - "integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", "cpu": [ "x64" ], @@ -47362,9 +46588,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/sunos-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz", - "integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", "cpu": [ "x64" ], @@ -47379,9 +46605,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz", - "integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", "cpu": [ "arm64" ], @@ -47396,9 +46622,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-ia32": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz", - "integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", "cpu": [ "ia32" ], @@ -47413,9 +46639,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz", - "integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", "cpu": [ "x64" ], @@ -47430,9 +46656,9 @@ } }, "node_modules/tsx/node_modules/esbuild": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz", - "integrity": "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -47443,32 +46669,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.1", - "@esbuild/android-arm": "0.27.1", - "@esbuild/android-arm64": "0.27.1", - "@esbuild/android-x64": "0.27.1", - "@esbuild/darwin-arm64": "0.27.1", - "@esbuild/darwin-x64": "0.27.1", - "@esbuild/freebsd-arm64": "0.27.1", - "@esbuild/freebsd-x64": "0.27.1", - "@esbuild/linux-arm": "0.27.1", - "@esbuild/linux-arm64": "0.27.1", - "@esbuild/linux-ia32": "0.27.1", - "@esbuild/linux-loong64": "0.27.1", - "@esbuild/linux-mips64el": "0.27.1", - "@esbuild/linux-ppc64": "0.27.1", - "@esbuild/linux-riscv64": "0.27.1", - "@esbuild/linux-s390x": "0.27.1", - "@esbuild/linux-x64": "0.27.1", - "@esbuild/netbsd-arm64": "0.27.1", - "@esbuild/netbsd-x64": "0.27.1", - "@esbuild/openbsd-arm64": "0.27.1", - "@esbuild/openbsd-x64": "0.27.1", - "@esbuild/openharmony-arm64": "0.27.1", - "@esbuild/sunos-x64": "0.27.1", - "@esbuild/win32-arm64": "0.27.1", - "@esbuild/win32-ia32": "0.27.1", - "@esbuild/win32-x64": "0.27.1" + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" } }, "node_modules/tsyringe": { @@ -47506,28 +46732,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "license": "Unlicense", - "peer": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -47704,9 +46908,9 @@ } }, "node_modules/typescript-json-schema": { - "version": "0.65.1", - "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.65.1.tgz", - "integrity": "sha512-tuGH7ff2jPaUYi6as3lHyHcKpSmXIqN7/mu50x3HlYn0EHzLpmt3nplZ7EuhUkO0eqDRc9GqWNkfjgBPIS9kxg==", + "version": "0.67.1", + "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.67.1.tgz", + "integrity": "sha512-vKTZB/RoYTIBdVP7E7vrgHMCssBuhja91wQy498QIVhvfRimaOgjc98uwAXmZ7mbLUytJmOSbF11wPz+ByQeXg==", "license": "BSD-3-Clause", "dependencies": { "@types/json-schema": "^7.0.9", @@ -47716,6 +46920,7 @@ "safe-stable-stringify": "^2.2.0", "ts-node": "^10.9.1", "typescript": "~5.5.0", + "vm2": "^3.10.0", "yargs": "^17.1.1" }, "bin": { @@ -47750,6 +46955,24 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "license": "MIT" }, + "node_modules/typescript-json-schema/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/typewise": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", @@ -47829,9 +47052,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.6.tgz", - "integrity": "sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", "dev": true, "license": "MIT", "engines": { @@ -47889,14 +47112,12 @@ } }, "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "license": "MIT", - "optional": true, - "peer": true, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -47987,9 +47208,9 @@ } }, "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -48139,9 +47360,9 @@ } }, "node_modules/unplugin/node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -48186,27 +47407,13 @@ "@unrs/resolver-binding-win32-x64-msvc": "1.9.2" } }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/unzipit": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unzipit/-/unzipit-1.4.3.tgz", - "integrity": "sha512-gsq2PdJIWWGhx5kcdWStvNWit9FVdTewm4SEG7gFskWs+XCVaULt9+BwuoBtJiRE8eo3L1IPAOrbByNLtLtIlg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unzipit/-/unzipit-2.0.0.tgz", + "integrity": "sha512-DVeVIWUZCAQPNzm5sB0hpsG1GygTTdBnzNtYYEpInkttx5evkyqRgZi6rTczoySqp8hO5jHVKzrH0f23X8FZLg==", "license": "MIT", - "dependencies": { - "uzip-module": "^1.0.2" - }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/unzipper": { @@ -48421,9 +47628,9 @@ } }, "node_modules/uuid": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", - "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", + "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -48460,12 +47667,6 @@ "node": ">=6" } }, - "node_modules/uzip-module": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/uzip-module/-/uzip-module-1.0.3.tgz", - "integrity": "sha512-AMqwWZaknLM77G+VPYNZLEruMGWGzyigPK3/Whg99B3S6vGHuqsyl5ZrOv1UUF3paGK1U6PM0cnayioaryg/fA==", - "license": "MIT" - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -48569,22 +47770,6 @@ "node": ">= 0.8" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "peer": true, - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "node_modules/version-range": { "version": "4.14.0", "resolved": "https://registry.npmjs.org/version-range/-/version-range-4.14.0.tgz", @@ -48648,9 +47833,9 @@ } }, "node_modules/vfile-location/node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -48702,14 +47887,12 @@ } }, "node_modules/vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", + "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", "license": "MIT", - "peer": true, "dependencies": { "clone": "^2.1.2", - "clone-stats": "^1.0.0", "remove-trailing-separator": "^1.1.0", "replace-ext": "^2.0.0", "teex": "^1.0.1" @@ -48750,6 +47933,34 @@ "dev": true, "license": "MIT" }, + "node_modules/vm2": { + "version": "3.10.5", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.10.5.tgz", + "integrity": "sha512-3P/2QDccVFBcujfCOeP8vVNuGfuBJHEuvGR8eMmI10p/iwLL2UwF5PDaNaoOS2pRGQEDmJRyeEcc8kmm2Z59RA==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "acorn-walk": "^8.3.4" + }, + "bin": { + "vm2": "bin/vm2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/vm2/node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", @@ -48764,14 +47975,14 @@ } }, "node_modules/wait-on": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-9.0.5.tgz", - "integrity": "sha512-qgnbHDfDTRIp73ANEJNRW/7kn8CrDUcvZz18xotJQku/P4saTGkbIzvnMZebPmVvVNUiRq1qWAPyqCH+W4H8KA==", + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-9.0.6.tgz", + "integrity": "sha512-KR+Te+NBg6DmPVil4anyIO72mpt/QDHjRo3nVFkwRgb26oweUp3DDW2szO3EeUY4cqafWy4rQuOOeEk4n+7Oeg==", "dev": true, "license": "MIT", "dependencies": { - "axios": "^1.15.0", - "joi": "^18.1.2", + "axios": "^1.16.0", + "joi": "^18.2.1", "lodash": "^4.18.1", "minimist": "^1.2.8", "rxjs": "^7.8.2" @@ -48934,6 +48145,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, "license": "MIT", "dependencies": { "defaults": "^1.0.3" @@ -48975,9 +48187,9 @@ } }, "node_modules/webpack": { - "version": "5.106.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.106.0.tgz", - "integrity": "sha512-Pkx5joZ9RrdgO5LBkyX1L2ZAJeK/Taz3vqZ9CbcP0wS5LEMx5QkKsEwLl29QJfihZ+DKRBFldzy1O30pJ1MDpA==", + "version": "5.106.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.106.2.tgz", + "integrity": "sha512-wGN3qcrBQIFmQ/c0AiOAQBvrZ5lmY8vbbMv4Mxfgzqd/B6+9pXtLo73WuS1dSGXM5QYY3hZnIbvx+K1xxe6FyA==", "dev": true, "license": "MIT", "dependencies": { @@ -48997,9 +48209,8 @@ "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.3.1", - "mime-types": "^2.1.27", + "mime-db": "^1.54.0", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", @@ -49049,9 +48260,9 @@ } }, "node_modules/webpack-bundle-analyzer/node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -49061,19 +48272,6 @@ "node": ">=0.4.0" } }, - "node_modules/webpack-bundle-analyzer/node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/webpack-bundle-analyzer/node_modules/commander": { "version": "14.0.3", "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", @@ -49104,28 +48302,6 @@ "dev": true, "license": "MIT" }, - "node_modules/webpack-bundle-analyzer/node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/webpack-cli": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", @@ -49180,9 +48356,9 @@ } }, "node_modules/webpack-cli/node_modules/envinfo": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", - "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", "dev": true, "license": "MIT", "bin": { @@ -49310,9 +48486,9 @@ } }, "node_modules/webpack-dev-server/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.3.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", + "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", "dev": true, "license": "MIT", "engines": { @@ -49320,9 +48496,9 @@ } }, "node_modules/webpack-dev-server/node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", "dev": true, "license": "MIT", "dependencies": { @@ -49336,36 +48512,73 @@ } }, "node_modules/webpack-dev-server/node_modules/memfs": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz", - "integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==", + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.57.2.tgz", + "integrity": "sha512-2nWzSsJzrukurSDna4Z0WywuScK4Id3tSKejgu74u8KCdW4uNrseKRSIDg75C6Yw5ZRqBe0F0EtMNlTbUq8bAQ==", "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", + "@jsonjoy.com/fs-core": "4.57.2", + "@jsonjoy.com/fs-fsa": "4.57.2", + "@jsonjoy.com/fs-node": "4.57.2", + "@jsonjoy.com/fs-node-builtins": "4.57.2", + "@jsonjoy.com/fs-node-to-fsa": "4.57.2", + "@jsonjoy.com/fs-node-utils": "4.57.2", + "@jsonjoy.com/fs-print": "4.57.2", + "@jsonjoy.com/fs-snapshot": "4.57.2", + "@jsonjoy.com/json-pack": "^1.11.0", + "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", + "thingies": "^2.5.0", + "tree-dump": "^1.0.3", "tslib": "^2.0.0" }, - "engines": { - "node": ">= 4.0.0" - }, "funding": { "type": "github", "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/webpack-dev-server/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/webpack-dev-server/node_modules/open": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", - "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", "dev": true, "license": "MIT", "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", - "is-wsl": "^3.1.0" + "wsl-utils": "^0.1.0" }, "engines": { "node": ">=18" @@ -49393,15 +48606,15 @@ } }, "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": "7.4.5", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz", + "integrity": "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==", "dev": true, "license": "MIT", "dependencies": { "colorette": "^2.0.10", - "memfs": "^4.6.0", - "mime-types": "^2.1.31", + "memfs": "^4.43.1", + "mime-types": "^3.0.1", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" @@ -49422,26 +48635,20 @@ } } }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "node_modules/webpack-dev-server/node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", "dev": true, "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, "engines": { - "node": ">=10.0.0" + "node": ">=18" }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/webpack-hot-middleware": { @@ -49513,9 +48720,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", - "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.4.1.tgz", + "integrity": "sha512-eACpxRN02yaawnt+uUNIF7Qje6A9zArxBbcAJjK1PK3S9Ycg5jIuJ8pW4q8EMnwNZCEGltcjkRx1QzOxOkKD8A==", "dev": true, "license": "MIT", "engines": { @@ -49559,50 +48766,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/webpack-visualizer-plugin2/node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-visualizer-plugin2/node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/webpack-visualizer-plugin2/node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/webpack/node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, "node_modules/webpack/node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", @@ -49630,18 +48793,21 @@ } }, "node_modules/webpack/node_modules/es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", "dev": true, "license": "MIT" }, - "node_modules/webpack/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "node_modules/webpack/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">= 0.6" + } }, "node_modules/websocket-driver": { "version": "0.7.4", @@ -49713,9 +48879,9 @@ } }, "node_modules/whatwg-url/node_modules/@exodus/bytes": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.11.0.tgz", - "integrity": "sha512-wO3vd8nsEHdumsXrjGO/v4p6irbg7hy9kvIeR6i2AwylZSk4HJdWgL0FNaVquW1+AweJcdvU1IEpuIWk/WaPnA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz", + "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==", "dev": true, "license": "MIT", "engines": { @@ -49731,15 +48897,15 @@ } }, "node_modules/whatwg-url/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", + "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", "dev": true, "license": "MIT", "optional": true, "peer": true, "engines": { - "node": "^14.21.3 || >=16" + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -49904,6 +49070,7 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -49967,9 +49134,9 @@ } }, "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "dev": true, "license": "MIT", "engines": { @@ -50159,21 +49326,20 @@ } }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", "license": "MIT", "dependencies": { - "cliui": "^8.0.1", + "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^7.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^22.0.0" }, "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs-parser": { @@ -50185,16 +49351,106 @@ "node": ">=12" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", - "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/yargs/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yargs/node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "license": "ISC", "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/yargs/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yn": { @@ -50235,6 +49491,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -50267,9 +49524,9 @@ } }, "node_modules/yosay/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" @@ -50279,9 +49536,9 @@ } }, "node_modules/yosay/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", "engines": { "node": ">=12" @@ -50291,9 +49548,9 @@ } }, "node_modules/yosay/node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -50315,9 +49572,9 @@ } }, "node_modules/yosay/node_modules/emoji-regex": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", - "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "license": "MIT" }, "node_modules/yosay/node_modules/meow": { @@ -50350,12 +49607,12 @@ } }, "node_modules/yosay/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -50405,24 +49662,15 @@ } }, "node_modules/zarrita": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/zarrita/-/zarrita-0.6.1.tgz", - "integrity": "sha512-YOMTW8FT55Rz+vadTIZeOFZ/F2h4svKizyldvPtMYSxPgSNcRkOzkxCsWpIWlWzB1I/LmISmi0bEekOhLlI+Zw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/zarrita/-/zarrita-0.7.2.tgz", + "integrity": "sha512-BHP+Z+yemkl9pOogkO1XMOrJ5qI4RNqrmheqJeYtIhpiaW4uvqplYx/jGkMD6edQjIZRQhniFigJZE2oTh7dwQ==", "license": "MIT", "dependencies": { - "@zarrita/storage": "^0.1.4", + "@zarrita/storage": "^0.2.0", "numcodecs": "^0.3.2" } }, - "node_modules/zod": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/zrender": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.1.tgz", @@ -50475,49 +49723,13 @@ "cross-env": "^10.1.0", "fs-extra": "^11.3.4", "jest": "^30.3.0", - "yeoman-test": "^11.3.1" + "yeoman-test": "^11.4.2" }, "engines": { "node": ">= 18.0.0", "npm": ">= 4.0.0" } }, - "packages/generator-superset/node_modules/@sindresorhus/merge-streams": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", - "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/generator-superset/node_modules/array-differ": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-4.0.0.tgz", - "integrity": "sha512-Q6VPTLMsmXZ47ENG3V+wQyZS1ZxXMxFyYzA+Z/GMrJ6yIutAIEf9wTyroTzmGjNfox9/h3GdGBCVh43GVFx4Uw==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/generator-superset/node_modules/array-union": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", - "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/generator-superset/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -50607,18 +49819,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/generator-superset/node_modules/find-up-simple": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", - "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/generator-superset/node_modules/fs-extra": { "version": "11.3.2", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", @@ -50650,18 +49850,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/generator-superset/node_modules/hosted-git-info": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", - "license": "ISC", - "dependencies": { - "lru-cache": "^11.1.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "packages/generator-superset/node_modules/human-signals": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", @@ -50671,18 +49859,6 @@ "node": ">=18.18.0" } }, - "packages/generator-superset/node_modules/index-to-position": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", - "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/generator-superset/node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -50707,27 +49883,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/generator-superset/node_modules/isbinaryfile": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.7.tgz", - "integrity": "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==", - "license": "MIT", - "engines": { - "node": ">= 18.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "packages/generator-superset/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "packages/generator-superset/node_modules/mem-fs-editor": { "version": "12.0.2", "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-12.0.2.tgz", @@ -50766,12 +49921,12 @@ } }, "packages/generator-superset/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -50780,37 +49935,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "packages/generator-superset/node_modules/multimatch": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-8.0.0.tgz", - "integrity": "sha512-0D10M2/MnEyvoog7tmozlpSqL3HEU1evxUFa3v1dsKYmBDFSP1dLSX4CH2rNjpQ+4Fps8GKmUkCwiKryaKqd9A==", - "license": "MIT", - "dependencies": { - "array-differ": "^4.0.0", - "array-union": "^3.0.1", - "minimatch": "^10.2.2" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/generator-superset/node_modules/normalize-package-data": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", - "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^9.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "packages/generator-superset/node_modules/npm-run-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", @@ -50827,35 +49951,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/generator-superset/node_modules/parse-json": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", - "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.26.2", - "index-to-position": "^1.1.0", - "type-fest": "^4.39.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/generator-superset/node_modules/parse-json/node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/generator-superset/node_modules/path-key": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", @@ -50868,54 +49963,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/generator-superset/node_modules/read-package-up": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-12.0.0.tgz", - "integrity": "sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw==", - "license": "MIT", - "dependencies": { - "find-up-simple": "^1.0.1", - "read-pkg": "^10.0.0", - "type-fest": "^5.2.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/generator-superset/node_modules/read-pkg": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", - "integrity": "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==", - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.4", - "normalize-package-data": "^8.0.0", - "parse-json": "^8.3.0", - "type-fest": "^5.4.4", - "unicorn-magic": "^0.4.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/generator-superset/node_modules/read-pkg/node_modules/unicorn-magic": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", - "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/generator-superset/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -50941,9 +49988,9 @@ } }, "packages/generator-superset/node_modules/type-fest": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.4.4.tgz", - "integrity": "sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", + "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", "license": "(MIT OR CC0-1.0)", "dependencies": { "tagged-tag": "^1.0.0" @@ -50967,21 +50014,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/generator-superset/node_modules/vinyl": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", - "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", - "license": "MIT", - "dependencies": { - "clone": "^2.1.2", - "remove-trailing-separator": "^1.1.0", - "replace-ext": "^2.0.0", - "teex": "^1.0.1" - }, - "engines": { - "node": ">=10.13.0" - } - }, "packages/generator-superset/node_modules/yeoman-generator": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-8.1.2.tgz", @@ -51058,19 +50090,18 @@ }, "packages/superset-core": { "name": "@apache-superset/core", - "version": "0.1.0-rc2", + "version": "0.1.0-rc3", "license": "Apache-2.0", "devDependencies": { "@babel/cli": "^7.28.6", "@babel/core": "^7.29.0", - "@babel/preset-env": "^7.29.2", + "@babel/preset-env": "^7.29.3", "@babel/preset-react": "^7.28.5", "@babel/preset-typescript": "^7.28.5", "@emotion/styled": "^11.14.1", - "@testing-library/dom": "^8.20.1", + "@testing-library/dom": "^9.3.4", "@testing-library/jest-dom": "*", - "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "*", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "*", "@types/lodash": "^4.17.24", "@types/react": "*", @@ -51089,8 +50120,8 @@ "jed": "^1.1.1", "lodash": "^4.18.1", "nanoid": "^5.0.9", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-loadable": "^5.5.0", "tinycolor2": "*" } @@ -51109,17 +50140,16 @@ "@ant-design/icons": "^5.6.1", "@emotion/react": "^11.4.1", "@superset-ui/core": "*", - "@testing-library/dom": "^8.20.1", + "@testing-library/dom": "^9.3.4", "@testing-library/jest-dom": "*", - "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "*", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "*", "ace-builds": "^1.4.14", "brace": "^0.11.1", "memoize-one": "^5.1.1", - "react": "^17.0.2", + "react": "^18.2.0", "react-ace": "^10.1.0", - "react-dom": "^17.0.2" + "react-dom": "^18.2.0" } }, "packages/superset-ui-core": { @@ -51127,14 +50157,14 @@ "version": "0.20.4", "license": "Apache-2.0", "dependencies": { - "@ant-design/icons": "^6.1.1", + "@ant-design/icons": "^6.2.2", "@apache-superset/core": "*", "@babel/runtime": "^7.29.2", "@types/json-bigint": "^1.0.4", "@visx/responsive": "^3.12.0", "ace-builds": "^1.43.6", - "ag-grid-community": "35.0.1", - "ag-grid-react": "35.0.1", + "ag-grid-community": "35.2.1", + "ag-grid-react": "35.2.1", "brace": "^0.11.1", "classnames": "^2.5.1", "core-js": "^3.49.0", @@ -51145,7 +50175,7 @@ "d3-time": "^3.1.0", "d3-time-format": "^4.1.0", "dayjs": "^1.11.20", - "dompurify": "^3.4.0", + "dompurify": "^3.4.1", "fetch-retry": "^6.0.0", "handlebars": "^4.7.9", "jed": "^1.1.1", @@ -51177,7 +50207,7 @@ "@types/d3-scale": "^2.1.1", "@types/d3-time": "^3.0.4", "@types/d3-time-format": "^4.0.3", - "@types/jquery": "^3.5.33", + "@types/jquery": "^4.0.0", "@types/lodash": "^4.17.24", "@types/node": "^25.6.0", "@types/prop-types": "^15.7.15", @@ -51194,10 +50224,9 @@ "@emotion/cache": "^11.4.0", "@emotion/react": "^11.4.1", "@emotion/styled": "^11.14.1", - "@testing-library/dom": "^8.20.1", + "@testing-library/dom": "^9.3.4", "@testing-library/jest-dom": "*", - "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "*", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "*", "@types/react": "*", "@types/react-loadable": "*", @@ -51205,8 +50234,8 @@ "@types/tinycolor2": "*", "antd": "^5.26.0", "nanoid": "^5.0.9", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-loadable": "^5.5.0", "tinycolor2": "*" } @@ -51230,14 +50259,14 @@ } }, "packages/superset-ui-core/node_modules/@ant-design/icons": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-6.1.1.tgz", - "integrity": "sha512-AMT4N2y++TZETNHiM77fs4a0uPVCJGuL5MTonk13Pvv7UN7sID1cNEZOc1qNqx6zLKAOilTEFAdAoAFKa0U//Q==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-6.2.2.tgz", + "integrity": "sha512-zlJtE7AMbG12TeYVPhtBXwNpFInNy8mjLzcIm+0BPw16/b8ODG87YJ1G37VIF5VFscdgfsf6EweAFPTobu/3iQ==", "license": "MIT", "dependencies": { - "@ant-design/colors": "^8.0.0", - "@ant-design/icons-svg": "^4.4.0", - "@rc-component/util": "^1.3.0", + "@ant-design/colors": "^8.0.1", + "@ant-design/icons-svg": "^4.4.2", + "@rc-component/util": "^1.10.1", "clsx": "^2.1.1" }, "engines": { @@ -51249,9 +50278,9 @@ } }, "packages/superset-ui-core/node_modules/@ant-design/icons/node_modules/@rc-component/util": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@rc-component/util/-/util-1.10.0.tgz", - "integrity": "sha512-aY9GLBuiUdpyfIUpAWSYer4Tu3mVaZCo5A0q9NtXcazT3MRiI3/WNHCR+DUn5VAtR6iRRf0ynCqQUcHli5UdYw==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@rc-component/util/-/util-1.10.1.tgz", + "integrity": "sha512-q++9S6rUa5Idb/xIBNz6jtvumw5+O5YV5V0g4iK9mn9jWs4oGJheE3ZN1kAnE723AXyaD8v95yeOASmdk8Jnng==", "license": "MIT", "dependencies": { "is-mobile": "^5.0.0", @@ -51262,33 +50291,6 @@ "react-dom": ">=18.0.0" } }, - "packages/superset-ui-core/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2" - } - }, - "packages/superset-ui-core/node_modules/@types/prop-types": { - "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", - "dev": true, - "license": "MIT" - }, - "packages/superset-ui-core/node_modules/core-js": { - "version": "3.49.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", - "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "packages/superset-ui-core/node_modules/d3-format": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", @@ -51298,762 +50300,6 @@ "node": ">=12" } }, - "packages/superset-ui-core/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-find-and-replace": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz", - "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-gfm": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz", - "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-gfm-autolink-literal": "^1.0.0", - "mdast-util-gfm-footnote": "^1.0.0", - "mdast-util-gfm-strikethrough": "^1.0.0", - "mdast-util-gfm-table": "^1.0.0", - "mdast-util-gfm-task-list-item": "^1.0.0", - "mdast-util-to-markdown": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-gfm-autolink-literal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz", - "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "ccount": "^2.0.0", - "mdast-util-find-and-replace": "^2.0.0", - "micromark-util-character": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-gfm-footnote": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz", - "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0", - "micromark-util-normalize-identifier": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-gfm-strikethrough": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz", - "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-gfm-table": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz", - "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-to-markdown": "^1.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-gfm-task-list-item": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz", - "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-phrasing": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", - "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-to-markdown": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", - "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^3.0.0", - "mdast-util-to-string": "^3.0.0", - "micromark-util-decode-string": "^1.0.0", - "unist-util-visit": "^4.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-extension-gfm": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz", - "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^1.0.0", - "micromark-extension-gfm-footnote": "^1.0.0", - "micromark-extension-gfm-strikethrough": "^1.0.0", - "micromark-extension-gfm-table": "^1.0.0", - "micromark-extension-gfm-tagfilter": "^1.0.0", - "micromark-extension-gfm-task-list-item": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/micromark-extension-gfm-autolink-literal": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz", - "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/micromark-extension-gfm-footnote": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz", - "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==", - "license": "MIT", - "dependencies": { - "micromark-core-commonmark": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/micromark-extension-gfm-strikethrough": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz", - "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==", - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/micromark-extension-gfm-table": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz", - "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==", - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/micromark-extension-gfm-tagfilter": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz", - "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/micromark-extension-gfm-task-list-item": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz", - "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==", - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "packages/superset-ui-core/node_modules/micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "packages/superset-ui-core/node_modules/micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "packages/superset-ui-core/node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "packages/superset-ui-core/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, "packages/superset-ui-core/node_modules/react-ace": { "version": "14.0.1", "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-14.0.1.tgz", @@ -52127,22 +50373,6 @@ "react": ">= 0.14.0" } }, - "packages/superset-ui-core/node_modules/remark-gfm": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", - "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-gfm": "^2.0.0", - "micromark-extension-gfm": "^2.0.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "packages/superset-ui-core/node_modules/timezone-mock": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/timezone-mock/-/timezone-mock-1.4.2.tgz", @@ -52150,46 +50380,6 @@ "dev": true, "license": "MIT" }, - "packages/superset-ui-core/node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "packages/superset-ui-core/node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "packages/superset-ui-switchboard": { "name": "@superset-ui/switchboard", "version": "0.20.3", @@ -52210,7 +50400,7 @@ "@emotion/react": "^11.4.1", "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "react": "^17.0.2" + "react": "^18.2.0" } }, "plugins/legacy-plugin-chart-calendar/node_modules/d3-array": { @@ -52241,7 +50431,7 @@ "dependencies": { "d3": "^3.5.17", "prop-types": "^15.8.1", - "react": "^19.2.1" + "react": "^19.2.5" }, "peerDependencies": { "@apache-superset/core": "*", @@ -52250,9 +50440,9 @@ } }, "plugins/legacy-plugin-chart-chord/node_modules/react": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", - "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", + "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -52271,7 +50461,7 @@ "@apache-superset/core": "*", "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "react": "^17.0.2" + "react": "^18.2.0" } }, "plugins/legacy-plugin-chart-country-map/node_modules/d3-array": { @@ -52299,7 +50489,7 @@ "@apache-superset/core": "*", "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "react": "^17.0.2" + "react": "^18.2.0" } }, "plugins/legacy-plugin-chart-horizon/node_modules/d3-array": { @@ -52320,25 +50510,6 @@ "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", "license": "ISC" }, - "plugins/legacy-plugin-chart-map-box": { - "name": "@superset-ui/legacy-plugin-chart-map-box", - "version": "0.20.3", - "extraneous": true, - "license": "Apache-2.0", - "dependencies": { - "@math.gl/web-mercator": "^4.1.0", - "prop-types": "^15.8.1", - "react-map-gl": "^6.1.19", - "supercluster": "^8.0.1" - }, - "peerDependencies": { - "@apache-superset/core": "*", - "@superset-ui/chart-controls": "*", - "@superset-ui/core": "*", - "mapbox-gl": "*", - "react": "^17.0.2" - } - }, "plugins/legacy-plugin-chart-paired-t-test": { "name": "@superset-ui/legacy-plugin-chart-paired-t-test", "version": "0.20.3", @@ -52352,7 +50523,7 @@ "@apache-superset/core": "*", "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "react": "^17.0.2" + "react": "^18.2.0" } }, "plugins/legacy-plugin-chart-parallel-coordinates": { @@ -52367,7 +50538,7 @@ "@apache-superset/core": "*", "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "react": "^17.0.2" + "react": "^18.2.0" } }, "plugins/legacy-plugin-chart-partition": { @@ -52384,9 +50555,9 @@ "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", "@testing-library/jest-dom": "*", - "@testing-library/react": "^12.1.5", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "@testing-library/react": "^14.0.0", + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, "plugins/legacy-plugin-chart-rose": { @@ -52403,7 +50574,7 @@ "@emotion/react": "^11.4.1", "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "react": "^17.0.2" + "react": "^18.2.0" } }, "plugins/legacy-plugin-chart-world-map": { @@ -52421,7 +50592,7 @@ "@apache-superset/core": "*", "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "react": "^17.0.2" + "react": "^18.2.0" } }, "plugins/legacy-plugin-chart-world-map/node_modules/d3-array": { @@ -52496,7 +50667,7 @@ "dependencies": { "d3": "^3.5.17", "d3-tip": "^0.9.1", - "dompurify": "^3.4.0", + "dompurify": "^3.4.1", "fast-safe-stringify": "^2.1.1", "lodash": "^4.18.1", "nvd3-fork": "^2.0.5", @@ -52508,7 +50679,7 @@ "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", "dayjs": "^1.11.19", - "react": "^17.0.2" + "react": "^18.2.0" } }, "plugins/plugin-chart-ag-grid-table": { @@ -52521,7 +50692,7 @@ "classnames": "^2.5.1", "d3-array": "^3.2.4", "lodash": "^4.18.1", - "memoize-one": "^5.2.1", + "memoize-one": "^6.0.0", "react-table": "^7.8.0", "regenerator-runtime": "^0.14.1", "xss": "^1.0.15" @@ -52531,14 +50702,13 @@ "@apache-superset/core": "*", "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "@testing-library/dom": "^8.20.1", + "@testing-library/dom": "^9.3.4", "@testing-library/jest-dom": "*", - "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "*", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "*", "@types/react": "*", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, "plugins/plugin-chart-ag-grid-table/node_modules/d3-array": { @@ -52553,6 +50723,12 @@ "node": ">=12" } }, + "plugins/plugin-chart-ag-grid-table/node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, "plugins/plugin-chart-cartodiagram": { "name": "@superset-ui/plugin-chart-cartodiagram", "version": "0.0.1", @@ -52576,8 +50752,8 @@ "geostyler-wfs-parser": "^3.0.1", "ol": "^10.8.0", "polished": "*", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, "plugins/plugin-chart-echarts": { @@ -52590,7 +50766,7 @@ "acorn": "^8.16.0", "d3-array": "^3.2.4", "lodash": "^4.18.1", - "zod": "^4.3.6" + "zod": "^4.4.3" }, "peerDependencies": { "@apache-superset/core": "*", @@ -52599,7 +50775,7 @@ "dayjs": "^1.11.19", "echarts": "*", "memoize-one": "*", - "react": "^17.0.2" + "react": "^18.2.0" } }, "plugins/plugin-chart-echarts/node_modules/acorn": { @@ -52626,6 +50802,15 @@ "node": ">=12" } }, + "plugins/plugin-chart-echarts/node_modules/zod": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.1.tgz", + "integrity": "sha512-a6ENMBBGZBsnlSebQ/eKCguSBeGKSf4O7BPnqVPmYGtpBYI7VSqoVqw+QcB7kPRjbqPwhYTpFbVj/RqNz/CT0Q==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "plugins/plugin-chart-handlebars": { "name": "@superset-ui/plugin-chart-handlebars", "version": "0.20.3", @@ -52648,9 +50833,9 @@ "dayjs": "^1.11.19", "handlebars": "^4.7.8", "lodash": "^4.18.1", - "react": "^17.0.2", + "react": "^18.2.0", "react-ace": "^10.1.0", - "react-dom": "^17.0.2" + "react-dom": "^18.2.0" } }, "plugins/plugin-chart-handlebars/node_modules/just-handlebars-helpers": { @@ -52665,13 +50850,6 @@ "sprintf-js": ">= 1.1.1 < 2" } }, - "plugins/plugin-chart-handlebars/node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "license": "BSD-3-Clause", - "peer": true - }, "plugins/plugin-chart-pivot-table": { "name": "@superset-ui/plugin-chart-pivot-table", "version": "0.20.3", @@ -52688,8 +50866,8 @@ "@superset-ui/core": "*", "lodash": "^4.18.1", "prop-types": "*", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, "plugins/plugin-chart-point-cluster-map": { @@ -52698,17 +50876,17 @@ "license": "Apache-2.0", "dependencies": { "@math.gl/web-mercator": "^4.1.0", - "mapbox-gl": "^3.0.0", - "maplibre-gl": "^5.0.0", - "react-map-gl": "^8.0.0", + "mapbox-gl": "^3.23.0", + "maplibre-gl": "^5.24.0", + "react-map-gl": "^8.1.0", "supercluster": "^8.0.1" }, "peerDependencies": { "@apache-superset/core": "*", "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "react": "^17.0.2 || ^19.0.0", - "react-dom": "^17.0.2 || ^19.0.0" + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, "plugins/plugin-chart-point-cluster-map/node_modules/react-map-gl": { @@ -52745,7 +50923,7 @@ "classnames": "^2.5.1", "d3-array": "^3.2.4", "lodash": "^4.18.1", - "memoize-one": "^5.2.1", + "memoize-one": "^6.0.0", "react-table": "^7.8.0", "regenerator-runtime": "^0.14.1", "xss": "^1.0.15" @@ -52755,15 +50933,14 @@ "@apache-superset/core": "*", "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "@testing-library/dom": "^8.20.1", + "@testing-library/dom": "^9.3.4", "@testing-library/jest-dom": "*", - "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "*", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "*", "@types/react": "*", "match-sorter": "^8.2.0", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, "plugins/plugin-chart-table/node_modules/d3-array": { @@ -52778,13 +50955,19 @@ "node": ">=12" } }, + "plugins/plugin-chart-table/node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, "plugins/plugin-chart-word-cloud": { "name": "@superset-ui/plugin-chart-word-cloud", "version": "0.20.4", "license": "Apache-2.0", "dependencies": { "@types/d3-scale": "^4.0.9", - "d3-cloud": "^1.2.9", + "d3-cloud": "^1.2.8", "d3-scale": "^4.0.2" }, "devDependencies": { @@ -52796,7 +50979,7 @@ "@superset-ui/core": "*", "@types/lodash": "*", "@types/react": "*", - "react": "^17.0.2" + "react": "^18.2.0" } }, "plugins/plugin-chart-word-cloud/node_modules/@types/d3-scale": { @@ -52827,7 +51010,7 @@ "@deck.gl/extensions": "~9.2.9", "@deck.gl/geo-layers": "~9.2.5", "@deck.gl/layers": "~9.2.5", - "@deck.gl/mapbox": "~9.2.5", + "@deck.gl/mapbox": "~9.3.2", "@deck.gl/mesh-layers": "~9.2.5", "@luma.gl/constants": "~9.2.5", "@luma.gl/core": "~9.2.5", @@ -52844,11 +51027,11 @@ "d3-scale": "^4.0.2", "handlebars": "^4.7.9", "lodash": "^4.18.1", - "maplibre-gl": "^5.0.0", + "maplibre-gl": "^5.24.0", "mousetrap": "^1.6.5", "ngeohash": "^0.6.3", "prop-types": "^15.8.1", - "react-map-gl": "^8.0.0", + "react-map-gl": "^8.1.1", "underscore": "^1.13.7", "urijs": "^1.19.11", "xss": "^1.0.15" @@ -52865,8 +51048,8 @@ "@superset-ui/core": "*", "dayjs": "^1.11.19", "mapbox-gl": ">=1.0.0", - "react": "^17.0.2 || ^19.0.0", - "react-dom": "^17.0.2 || ^19.0.0" + "react": "^18.2.0", + "react-dom": "^18.2.0" }, "peerDependenciesMeta": { "mapbox-gl": { @@ -52874,39 +51057,18 @@ } } }, - "plugins/preset-chart-deckgl/node_modules/@deck.gl/aggregation-layers": { - "version": "9.2.11", - "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-9.2.11.tgz", - "integrity": "sha512-MRFbBHtMcDkOthxXnMPm6nF08DjFDACaIQsJSyHkdWtLUTSLHsWnOTn/8QbB4ka86WyNyfJy3dibLu/m3ei2ow==", + "plugins/preset-chart-deckgl/node_modules/@deck.gl/mapbox": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-9.3.2.tgz", + "integrity": "sha512-+T9pJwsOXwjUxyGN6oiBMfIs28VtDIG1V1Rqz4qqn4TjjNEFFw+xO0olJIg8FO5IAqw2OtePdsrMj0tX8tHdGQ==", "license": "MIT", "dependencies": { - "@luma.gl/constants": "~9.2.6", - "@luma.gl/shadertools": "~9.2.6", - "@math.gl/core": "^4.1.0", - "@math.gl/web-mercator": "^4.1.0", - "d3-hexbin": "^0.2.1" + "@math.gl/web-mercator": "^4.1.0" }, "peerDependencies": { - "@deck.gl/core": "~9.2.0", - "@deck.gl/layers": "~9.2.0", - "@luma.gl/core": "~9.2.6", - "@luma.gl/engine": "~9.2.6" - } - }, - "plugins/preset-chart-deckgl/node_modules/@deck.gl/extensions": { - "version": "9.2.11", - "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-9.2.11.tgz", - "integrity": "sha512-zlpM4Bg1ifBziW1Juiii9NY5gyW2rEhyVTWnhagH/bpTCZ2E73OhnToYt1ouqmoxL6lMtIjhRXz6LPb7tJbHHQ==", - "license": "MIT", - "dependencies": { - "@luma.gl/constants": "~9.2.6", - "@luma.gl/shadertools": "~9.2.6", - "@math.gl/core": "^4.1.0" - }, - "peerDependencies": { - "@deck.gl/core": "~9.2.0", - "@luma.gl/core": "~9.2.6", - "@luma.gl/engine": "~9.2.6" + "@deck.gl/core": "~9.3.0", + "@luma.gl/core": "~9.3.3", + "@math.gl/web-mercator": "^4.1.0" } }, "plugins/preset-chart-deckgl/node_modules/d3-array": { @@ -52921,30 +51083,6 @@ "node": ">=12" } }, - "plugins/preset-chart-deckgl/node_modules/react-map-gl": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/react-map-gl/-/react-map-gl-8.1.0.tgz", - "integrity": "sha512-vDx/QXR3Tb+8/ap/z6gdMjJQ8ZEyaZf6+uMSPz7jhWF5VZeIsKsGfPvwHVPPwGF43Ryn+YR4bd09uEFNR5OPdg==", - "license": "MIT", - "dependencies": { - "@vis.gl/react-mapbox": "8.1.0", - "@vis.gl/react-maplibre": "8.1.0" - }, - "peerDependencies": { - "mapbox-gl": ">=1.13.0", - "maplibre-gl": ">=1.13.0", - "react": ">=16.3.0", - "react-dom": ">=16.3.0" - }, - "peerDependenciesMeta": { - "mapbox-gl": { - "optional": true - }, - "maplibre-gl": { - "optional": true - } - } - }, "tools/eslint-i18n-strings": { "version": "1.0.0", "extraneous": true, diff --git a/superset-frontend/package.json b/superset-frontend/package.json index fc9526ed633..77d04a5e9f7 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -119,7 +119,14 @@ "@luma.gl/gltf": "~9.2.5", "@luma.gl/shadertools": "~9.2.5", "@luma.gl/webgl": "~9.2.5", + "@fontsource/fira-code": "^5.2.7", + "@fontsource/inter": "^5.2.8", + "@great-expectations/jsonforms-antd-renderers": "^2.2.10", + "@jsonforms/core": "^3.7.0", + "@jsonforms/react": "^3.7.0", + "@jsonforms/vanilla-renderers": "^3.7.0", "@reduxjs/toolkit": "^1.9.3", + "@rjsf/antd": "^5.24.13", "@rjsf/core": "^5.24.13", "@rjsf/utils": "^5.24.3", "@rjsf/validator-ajv8": "^5.24.13", @@ -156,12 +163,12 @@ "@visx/scale": "^3.5.0", "@visx/tooltip": "^3.0.0", "@visx/xychart": "^3.5.1", - "ag-grid-community": "35.0.1", - "ag-grid-react": "35.0.1", + "ag-grid-community": "35.2.1", + "ag-grid-react": "35.2.1", "antd": "^5.26.0", "chrono-node": "^2.9.0", "classnames": "^2.2.5", - "content-disposition": "^1.0.1", + "content-disposition": "^1.1.0", "d3-color": "^3.1.0", "d3-scale": "^4.0.2", "dayjs": "^1.11.20", @@ -172,9 +179,9 @@ "fs-extra": "^11.3.4", "fuse.js": "^7.3.0", "geolib": "^3.3.14", - "geostyler": "^18.3.1", + "geostyler": "^18.5.1", "geostyler-data": "^1.1.0", - "geostyler-openlayers-parser": "^5.4.1", + "geostyler-openlayers-parser": "^5.7.0", "geostyler-style": "11.0.2", "geostyler-wfs-parser": "^3.0.1", "google-auth-library": "^10.6.2", @@ -185,24 +192,24 @@ "json-bigint": "^1.0.0", "json-stringify-pretty-compact": "^2.0.0", "lodash": "^4.18.1", - "mapbox-gl": "^3.20.0", - "markdown-to-jsx": "^9.7.15", - "match-sorter": "^8.2.0", + "mapbox-gl": "^3.23.0", + "markdown-to-jsx": "^9.7.16", + "match-sorter": "^8.3.0", "memoize-one": "^5.2.1", "mousetrap": "^1.6.5", "mustache": "^4.2.0", - "nanoid": "^5.1.7", - "ol": "^10.8.0", + "nanoid": "^5.1.11", + "ol": "^10.9.0", "pretty-ms": "^9.3.0", "query-string": "9.3.1", "re-resizable": "^6.11.2", - "react": "^17.0.2", - "react-arborist": "^3.4.3", + "react": "^18.2.0", + "react-arborist": "^3.5.0", "react-checkbox-tree": "^1.8.0", - "react-diff-viewer-continued": "^4.2.0", + "react-diff-viewer-continued": "^4.2.2", "react-dnd": "^11.1.3", "react-dnd-html5-backend": "^11.1.3", - "react-dom": "^17.0.2", + "react-dom": "^18.2.0", "react-google-recaptcha": "^3.1.0", "react-intersection-observer": "^10.0.3", "react-json-tree": "^0.20.0", @@ -213,7 +220,6 @@ "react-reverse-portal": "^2.3.0", "react-router-dom": "^5.3.4", "react-search-input": "^0.11.3", - "react-sortable-hoc": "^2.0.0", "react-split": "^2.0.9", "react-table": "^7.8.0", "react-transition-group": "^4.4.5", @@ -232,9 +238,9 @@ "use-event-callback": "^0.1.0", "use-immer": "^0.11.0", "use-query-params": "^2.2.2", - "uuid": "^13.0.0", + "uuid": "^14.0.0", "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz", - "yargs": "^17.7.2" + "yargs": "^18.0.0" }, "devDependencies": { "@babel/cli": "^7.28.6", @@ -246,49 +252,48 @@ "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.28.6", "@babel/plugin-transform-runtime": "^7.29.0", - "@babel/preset-env": "^7.29.2", + "@babel/preset-env": "^7.29.3", "@babel/preset-react": "^7.28.5", "@babel/preset-typescript": "^7.28.5", "@babel/register": "^7.23.7", "@babel/runtime": "^7.29.2", "@babel/runtime-corejs3": "^7.29.2", "@babel/types": "^7.28.6", - "@cypress/react": "^8.0.2", "@emotion/babel-plugin": "^11.13.5", "@emotion/jest": "^11.14.2", "@istanbuljs/nyc-config-typescript": "^1.0.1", "@mihkeleidast/storybook-addon-source": "^1.0.1", "@playwright/test": "^1.59.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.6.2", - "@storybook/addon-actions": "^8.6.17", - "@storybook/addon-controls": "^8.6.17", - "@storybook/addon-essentials": "^8.6.17", - "@storybook/addon-links": "^8.6.17", - "@storybook/addon-mdx-gfm": "^8.6.17", - "@storybook/components": "^8.6.17", - "@storybook/preview-api": "^8.6.17", - "@storybook/react": "^8.6.17", - "@storybook/react-webpack5": "^8.6.17", - "@storybook/test": "^8.6.15", + "@storybook/addon-actions": "^8.6.18", + "@storybook/addon-controls": "^8.6.18", + "@storybook/addon-essentials": "^8.6.18", + "@storybook/addon-links": "^8.6.18", + "@storybook/addon-mdx-gfm": "^8.6.18", + "@storybook/components": "^8.6.18", + "@storybook/preview-api": "^8.6.18", + "@storybook/react": "^8.6.18", + "@storybook/react-webpack5": "^8.6.18", + "@storybook/test": "^8.6.18", "@storybook/test-runner": "^0.17.0", "@svgr/webpack": "^8.1.0", - "@swc/core": "^1.15.24", - "@swc/plugin-emotion": "^14.8.0", + "@swc/core": "^1.15.32", + "@swc/plugin-emotion": "^14.9.0", "@swc/plugin-transform-imports": "^12.5.0", - "@testing-library/dom": "^8.20.1", + "@testing-library/dom": "^9.3.4", "@testing-library/jest-dom": "^6.9.1", - "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "^8.0.1", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^12.8.3", "@types/content-disposition": "^0.5.9", "@types/dom-to-image": "^2.6.7", "@types/jest": "^30.0.0", + "@types/jquery": "^4.0.0", "@types/js-levenshtein": "^1.1.3", "@types/json-bigint": "^1.0.4", "@types/mousetrap": "^1.6.15", "@types/node": "^25.6.0", - "@types/react": "^17.0.83", - "@types/react-dom": "^17.0.26", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", "@types/react-loadable": "^5.5.11", "@types/react-redux": "^7.1.10", "@types/react-resizable": "^3.0.8", @@ -300,14 +305,14 @@ "@types/rison": "0.1.0", "@types/tinycolor2": "^1.4.3", "@types/unzipper": "^0.10.11", - "@typescript-eslint/eslint-plugin": "^7.18.0", - "@typescript-eslint/parser": "^7.18.0", + "@typescript-eslint/eslint-plugin": "^8.59.2", + "@typescript-eslint/parser": "^8.58.2", "babel-jest": "^30.0.2", "babel-loader": "^10.1.1", "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-jsx-remove-data-test-id": "^3.0.0", "babel-plugin-lodash": "^3.3.4", - "baseline-browser-mapping": "^2.10.16", + "baseline-browser-mapping": "^2.10.24", "cheerio": "1.2.0", "concurrently": "^9.2.1", "copy-webpack-plugin": "^14.0.0", @@ -324,17 +329,17 @@ "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest-dom": "^5.5.0", "eslint-plugin-lodash": "^7.4.0", - "eslint-plugin-no-only-tests": "^3.3.0", + "eslint-plugin-no-only-tests": "^3.4.0", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-react-prefer-function-component": "^5.0.0", - "eslint-plugin-react-you-might-not-need-an-effect": "^0.9.2", + "eslint-plugin-react-you-might-not-need-an-effect": "^0.10.0", "eslint-plugin-storybook": "^0.8.0", "eslint-plugin-testing-library": "^7.16.2", "eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors", "fetch-mock": "^12.6.0", "fork-ts-checker-webpack-plugin": "^9.1.0", "history": "^5.3.0", - "html-webpack-plugin": "^5.6.6", + "html-webpack-plugin": "^5.6.7", "http-server": "^14.1.1", "imports-loader": "^5.0.0", "jest": "^30.3.0", @@ -342,12 +347,12 @@ "jest-html-reporter": "^4.4.0", "jest-websocket-mock": "^2.5.0", "js-yaml-loader": "^1.2.2", - "jsdom": "^29.0.2", + "jsdom": "^29.1.1", "lerna": "^9.0.4", "lightningcss": "^1.32.0", "mini-css-extract-plugin": "^2.10.2", "open-cli": "^9.0.0", - "oxlint": "^1.56.0", + "oxlint": "^1.62.0", "po2json": "^0.4.5", "prettier": "3.8.3", "prettier-plugin-packagejson": "^3.0.2", @@ -358,24 +363,23 @@ "source-map": "^0.7.6", "source-map-support": "^0.5.21", "speed-measure-webpack-plugin": "^1.6.0", - "storybook": "8.6.17", + "storybook": "8.6.18", "style-loader": "^4.0.0", "swc-loader": "^0.2.7", - "terser-webpack-plugin": "^5.4.0", - "thread-loader": "^4.0.4", + "terser-webpack-plugin": "^5.5.0", "ts-jest": "^29.4.9", "tscw-config": "^1.1.2", "tsx": "^4.21.0", "typescript": "5.4.5", "unzipper": "^0.12.3", "vm-browserify": "^1.1.2", - "wait-on": "^9.0.5", - "webpack": "^5.106.0", + "wait-on": "^9.0.6", + "webpack": "^5.106.2", "webpack-bundle-analyzer": "^5.3.0", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.3", "webpack-manifest-plugin": "^5.0.1", - "webpack-sources": "^3.3.4", + "webpack-sources": "^3.4.1", "webpack-visualizer-plugin2": "^2.0.0" }, "peerDependencies": { diff --git a/superset-frontend/packages/generator-superset/package.json b/superset-frontend/packages/generator-superset/package.json index 662e437107f..a2d7ce8450d 100644 --- a/superset-frontend/packages/generator-superset/package.json +++ b/superset-frontend/packages/generator-superset/package.json @@ -37,7 +37,7 @@ "cross-env": "^10.1.0", "fs-extra": "^11.3.4", "jest": "^30.3.0", - "yeoman-test": "^11.3.1" + "yeoman-test": "^11.4.2" }, "engines": { "npm": ">= 4.0.0", diff --git a/superset-frontend/packages/superset-core/package.json b/superset-frontend/packages/superset-core/package.json index 1ccf3616b81..d45064c14f2 100644 --- a/superset-frontend/packages/superset-core/package.json +++ b/superset-frontend/packages/superset-core/package.json @@ -1,6 +1,6 @@ { "name": "@apache-superset/core", - "version": "0.1.0-rc2", + "version": "0.1.0-rc3", "description": "This package contains UI elements, APIs, and utility functions used by Superset.", "sideEffects": false, "main": "lib/index.js", @@ -75,16 +75,15 @@ "devDependencies": { "@babel/cli": "^7.28.6", "@babel/core": "^7.29.0", - "@babel/preset-env": "^7.29.2", + "@babel/preset-env": "^7.29.3", "@babel/preset-react": "^7.28.5", "@babel/preset-typescript": "^7.28.5", "typescript": "^5.0.0", "@emotion/styled": "^11.14.1", "@types/lodash": "^4.17.24", - "@testing-library/dom": "^8.20.1", + "@testing-library/dom": "^9.3.4", "@testing-library/jest-dom": "*", - "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "*", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "*", "@types/react": "*", "@types/react-loadable": "*", @@ -98,8 +97,8 @@ "@fontsource/ibm-plex-mono": "^5.2.7", "@fontsource/inter": "^5.2.6", "nanoid": "^5.0.9", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-loadable": "^5.5.0", "tinycolor2": "*", "lodash": "^4.18.1", diff --git a/superset-frontend/packages/superset-core/src/testing.tsx b/superset-frontend/packages/superset-core/src/testing.tsx index e68186343c9..fba2f353967 100644 --- a/superset-frontend/packages/superset-core/src/testing.tsx +++ b/superset-frontend/packages/superset-core/src/testing.tsx @@ -18,7 +18,7 @@ */ import userEvent from '@testing-library/user-event'; import { ReactElement } from 'react'; -import { render, RenderOptions } from '@testing-library/react'; +import { render, RenderOptions, RenderResult } from '@testing-library/react'; import '@testing-library/jest-dom'; import { themeObject } from './theme'; @@ -33,7 +33,7 @@ const Providers = ({ children }: { children: React.ReactNode }) => ( const customRender = ( ui: ReactElement, options?: Omit, -) => render(ui, { wrapper: Providers, ...options }); +): RenderResult => render(ui, { wrapper: Providers, ...options }); export { createEvent, diff --git a/superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx b/superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx index 33a30a9fa61..7c750d2087f 100644 --- a/superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx +++ b/superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx @@ -29,14 +29,20 @@ import '@fontsource/ibm-plex-mono/600.css'; /* eslint-enable import/extensions */ import { css, useTheme, Global } from '@emotion/react'; +import { useThemeMode } from './utils/themeUtils'; export const GlobalStyles = () => { const theme = useTheme(); + const isDark = useThemeMode(); return ( = {}, -): Record { +): ControlStateMapping { const defaults: Record = { matrixify_enable: false, matrixify_mode_rows: 'disabled', @@ -36,7 +37,7 @@ function makeControls( const merged = { ...defaults, ...overrides }; return Object.fromEntries( Object.entries(merged).map(([k, v]) => [k, { value: v }]), - ); + ) as ControlStateMapping; } // ── matrixify_enable guard ────────────────────────────────────────── diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/matrixifyControls.tsx b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/matrixifyControls.tsx index 3e1b331d167..1ec8a340297 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/matrixifyControls.tsx +++ b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/matrixifyControls.tsx @@ -20,7 +20,7 @@ import { t } from '@apache-superset/core/translation'; import { validateNonEmpty } from '@superset-ui/core'; -import { SharedControlConfig } from '../types'; +import { ControlStateMapping, SharedControlConfig } from '../types'; import { dndAdhocMetricControl } from './dndControls'; import { defineSavedMetrics } from '../utils'; @@ -29,9 +29,12 @@ import { defineSavedMetrics } from '../utils'; * Controls for transforming charts into matrix/grid layouts */ -// Utility function to check if matrixify controls should be visible +// Utility function to check if matrixify controls should be visible. +// Controls both visibility callbacks and validator injection via mapStateToProps. +// The matrixify_enable guard prevents hidden validators from firing on +// pre-revamp charts with stale matrixify_mode defaults (fix for #38519). const isMatrixifyVisible = ( - controls: any, + controls: ControlStateMapping | undefined, axis: 'rows' | 'columns', mode?: 'metrics' | 'dimensions', selectionMode?: 'members' | 'topn' | 'all', 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 6344222d594..e1d656dc144 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -588,6 +588,7 @@ export type ControlFormItemSpec = { creatable?: boolean; minWidth?: number | string; validators?: ControlFormValueValidator[]; + tokenSeparators?: string[]; } : T extends 'RadioButtonControl' ? { diff --git a/superset-frontend/packages/superset-ui-chart-controls/test/shared-controls/matrixifyControls.test.tsx b/superset-frontend/packages/superset-ui-chart-controls/test/shared-controls/matrixifyControls.test.tsx new file mode 100644 index 00000000000..f78e6162f47 --- /dev/null +++ b/superset-frontend/packages/superset-ui-chart-controls/test/shared-controls/matrixifyControls.test.tsx @@ -0,0 +1,238 @@ +/** + * 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. + */ + +/** + * Tests for the matrixify_enable guard in isMatrixifyVisible() and + * validator injection via mapStateToProps on real matrixify control definitions. + * + * These are TDD tests for the fix to apache/superset#38519 regression: + * isMatrixifyVisible() must check matrixify_enable before evaluating mode, + * otherwise pre-revamp charts with stale matrixify_mode defaults trigger + * hidden validators that block save. + */ + +import { + matrixifyControls, + isMatrixifyVisible, +} from '../../src/shared-controls/matrixifyControls'; +import type { ControlPanelState, ControlStateMapping } from '../../src/types'; + +// Helper: build a minimal controls object for ControlPanelState +const buildControls = ( + overrides: Record = {}, +): ControlStateMapping => { + const controls: Record = {}; + Object.entries(overrides).forEach(([key, value]) => { + controls[key] = { value }; + }); + return controls as ControlStateMapping; +}; + +// Helper: build a minimal ControlPanelState for mapStateToProps. +// Only provides fields that isMatrixifyVisible and mapStateToProps actually read. +const buildState = ( + controlValues: Record = {}, + formData: Record = {}, +) => + ({ + controls: buildControls(controlValues), + datasource: { columns: [], type: 'table' }, + form_data: formData, + common: {}, + metadata: {}, + slice: { slice_id: 0 }, + }) as unknown as ControlPanelState; + +// ============================================================ +// Validator injection tests via real mapStateToProps (rows) +// ============================================================ + +// --- matrixify_dimension_rows --- + +test('matrixify_dimension_rows: validators empty when matrixify_enable is falsy', () => { + const control = matrixifyControls.matrixify_dimension_rows; + const state = buildState( + { + matrixify_enable: undefined, + matrixify_mode_rows: 'dimensions', + matrixify_dimension_selection_mode_rows: 'members', + }, + { matrixify_mode_rows: 'dimensions' }, + ); + + const result = control.mapStateToProps!(state, {} as any); + expect(result.validators).toEqual([]); +}); + +test('matrixify_dimension_rows: validators present when matrixify_enable is true', () => { + const control = matrixifyControls.matrixify_dimension_rows; + const state = buildState( + { + matrixify_enable: true, + matrixify_mode_rows: 'dimensions', + matrixify_dimension_selection_mode_rows: 'members', + }, + { matrixify_mode_rows: 'dimensions' }, + ); + + const result = control.mapStateToProps!(state, {} as any); + expect(result.validators.length).toBeGreaterThan(0); +}); + +// --- matrixify_topn_value_rows --- + +test('matrixify_topn_value_rows: validators empty when matrixify_enable is falsy', () => { + const control = matrixifyControls.matrixify_topn_value_rows; + const state = buildState( + { + matrixify_enable: undefined, + matrixify_mode_rows: 'dimensions', + matrixify_dimension_selection_mode_rows: 'topn', + }, + { matrixify_mode_rows: 'dimensions' }, + ); + + const result = control.mapStateToProps!(state, {} as any); + expect(result.validators).toEqual([]); +}); + +test('matrixify_topn_value_rows: validators present when matrixify_enable is true', () => { + const control = matrixifyControls.matrixify_topn_value_rows; + const state = buildState( + { + matrixify_enable: true, + matrixify_mode_rows: 'dimensions', + matrixify_dimension_selection_mode_rows: 'topn', + }, + { matrixify_mode_rows: 'dimensions' }, + ); + + const result = control.mapStateToProps!(state, {} as any); + expect(result.validators.length).toBeGreaterThan(0); +}); + +// --- matrixify_topn_metric_rows --- + +test('matrixify_topn_metric_rows: validators empty when matrixify_enable is falsy', () => { + const control = matrixifyControls.matrixify_topn_metric_rows; + const state = buildState( + { + matrixify_enable: undefined, + matrixify_mode_rows: 'dimensions', + matrixify_dimension_selection_mode_rows: 'topn', + }, + { matrixify_mode_rows: 'dimensions' }, + ); + + const result = control.mapStateToProps!(state, {} as any); + expect(result.validators).toEqual([]); +}); + +test('matrixify_topn_metric_rows: validators present when matrixify_enable is true', () => { + const control = matrixifyControls.matrixify_topn_metric_rows; + const state = buildState( + { + matrixify_enable: true, + matrixify_mode_rows: 'dimensions', + matrixify_dimension_selection_mode_rows: 'topn', + }, + { matrixify_mode_rows: 'dimensions' }, + ); + + const result = control.mapStateToProps!(state, {} as any); + expect(result.validators.length).toBeGreaterThan(0); +}); + +// ============================================================ +// Validator injection tests via real mapStateToProps (columns) +// ============================================================ + +test('matrixify_dimension_columns: validators empty when matrixify_enable is falsy', () => { + const control = matrixifyControls.matrixify_dimension_columns; + const state = buildState( + { + matrixify_enable: undefined, + matrixify_mode_columns: 'dimensions', + matrixify_dimension_selection_mode_columns: 'members', + }, + { matrixify_mode_columns: 'dimensions' }, + ); + + const result = control.mapStateToProps!(state, {} as any); + expect(result.validators).toEqual([]); +}); + +test('matrixify_dimension_columns: validators present when matrixify_enable is true', () => { + const control = matrixifyControls.matrixify_dimension_columns; + const state = buildState( + { + matrixify_enable: true, + matrixify_mode_columns: 'dimensions', + matrixify_dimension_selection_mode_columns: 'members', + }, + { matrixify_mode_columns: 'dimensions' }, + ); + + const result = control.mapStateToProps!(state, {} as any); + expect(result.validators.length).toBeGreaterThan(0); +}); + +// ============================================================ +// Direct isMatrixifyVisible guard tests +// ============================================================ + +test.each([ + ['undefined', undefined], + ['null', null], + ['false', false], + ['0', 0], +])( + 'isMatrixifyVisible returns false when matrixify_enable is %s', + (_, value) => { + const controls = buildControls({ + matrixify_enable: value, + matrixify_mode_rows: 'dimensions', + }); + expect(isMatrixifyVisible(controls, 'rows')).toBe(false); + }, +); + +test('isMatrixifyVisible returns true when matrixify_enable is true and mode matches', () => { + const controls = buildControls({ + matrixify_enable: true, + matrixify_mode_rows: 'dimensions', + }); + expect(isMatrixifyVisible(controls, 'rows', 'dimensions')).toBe(true); +}); + +test('isMatrixifyVisible returns false when matrixify_enable is true but mode is disabled', () => { + const controls = buildControls({ + matrixify_enable: true, + matrixify_mode_rows: 'disabled', + }); + expect(isMatrixifyVisible(controls, 'rows')).toBe(false); +}); + +test('isMatrixifyVisible returns true when matrixify_enable is true and any non-disabled mode (no mode filter)', () => { + const controls = buildControls({ + matrixify_enable: true, + matrixify_mode_columns: 'metrics', + }); + expect(isMatrixifyVisible(controls, 'columns')).toBe(true); +}); diff --git a/superset-frontend/packages/superset-ui-core/package.json b/superset-frontend/packages/superset-ui-core/package.json index 4ce486cc3d4..06a43ccae5b 100644 --- a/superset-frontend/packages/superset-ui-core/package.json +++ b/superset-frontend/packages/superset-ui-core/package.json @@ -24,14 +24,14 @@ "lib" ], "dependencies": { - "@ant-design/icons": "^6.1.1", + "@ant-design/icons": "^6.2.2", "@apache-superset/core": "*", "@babel/runtime": "^7.29.2", "@types/json-bigint": "^1.0.4", "@visx/responsive": "^3.12.0", "ace-builds": "^1.43.6", - "ag-grid-community": "35.0.1", - "ag-grid-react": "35.0.1", + "ag-grid-community": "35.2.1", + "ag-grid-react": "35.2.1", "brace": "^0.11.1", "classnames": "^2.5.1", "core-js": "^3.49.0", @@ -42,7 +42,7 @@ "d3-time": "^3.1.0", "d3-time-format": "^4.1.0", "dayjs": "^1.11.20", - "dompurify": "^3.4.0", + "dompurify": "^3.4.1", "fetch-retry": "^6.0.0", "handlebars": "^4.7.9", "jed": "^1.1.1", @@ -74,7 +74,7 @@ "@types/d3-scale": "^2.1.1", "@types/d3-time": "^3.0.4", "@types/d3-time-format": "^4.0.3", - "@types/jquery": "^3.5.33", + "@types/jquery": "^4.0.0", "@types/lodash": "^4.17.24", "@types/node": "^25.6.0", "@types/prop-types": "^15.7.15", @@ -91,10 +91,9 @@ "@emotion/cache": "^11.4.0", "@emotion/react": "^11.4.1", "@emotion/styled": "^11.14.1", - "@testing-library/dom": "^8.20.1", + "@testing-library/dom": "^9.3.4", "@testing-library/jest-dom": "*", - "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "*", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "*", "@types/react": "*", "@types/react-loadable": "*", @@ -102,8 +101,8 @@ "@types/tinycolor2": "*", "antd": "^5.26.0", "nanoid": "^5.0.9", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-loadable": "^5.5.0", "tinycolor2": "*" }, diff --git a/superset-frontend/packages/superset-ui-core/src/chart-composition/ChartFrame.tsx b/superset-frontend/packages/superset-ui-core/src/chart-composition/ChartFrame.tsx index 88cf52ec72f..91836814e9f 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart-composition/ChartFrame.tsx +++ b/superset-frontend/packages/superset-ui-core/src/chart-composition/ChartFrame.tsx @@ -17,7 +17,7 @@ * under the License. */ -import { PureComponent, ReactNode } from 'react'; +import { memo, ReactNode } from 'react'; import { isDefined } from '../utils'; @@ -29,7 +29,7 @@ type Props = { contentWidth?: number; contentHeight?: number; height: number; - renderContent: ({ + renderContent?: ({ height, width, }: { @@ -39,36 +39,35 @@ type Props = { width: number; }; -export default class ChartFrame extends PureComponent { - static defaultProps = { - renderContent() {}, - }; +function ChartFrame({ + contentWidth, + contentHeight, + width, + height, + renderContent = () => null, +}: Props) { + const overflowX = checkNumber(contentWidth) && contentWidth > width; + const overflowY = checkNumber(contentHeight) && contentHeight > height; - render() { - const { contentWidth, contentHeight, width, height, renderContent } = - this.props; - - const overflowX = checkNumber(contentWidth) && contentWidth > width; - const overflowY = checkNumber(contentHeight) && contentHeight > height; - - if (overflowX || overflowY) { - return ( -
- {renderContent({ - height: Math.max(contentHeight ?? 0, height), - width: Math.max(contentWidth ?? 0, width), - })} -
- ); - } - - return renderContent({ height, width }); + if (overflowX || overflowY) { + return ( +
+ {renderContent({ + height: Math.max(contentHeight ?? 0, height), + width: Math.max(contentWidth ?? 0, width), + })} +
+ ); } + + return <>{renderContent({ height, width })}; } + +export default memo(ChartFrame); diff --git a/superset-frontend/packages/superset-ui-core/src/chart-composition/legend/WithLegend.tsx b/superset-frontend/packages/superset-ui-core/src/chart-composition/legend/WithLegend.tsx index a2cac92ee33..48e7309cdab 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart-composition/legend/WithLegend.tsx +++ b/superset-frontend/packages/superset-ui-core/src/chart-composition/legend/WithLegend.tsx @@ -17,26 +17,19 @@ * under the License. */ -import { CSSProperties, ReactNode, PureComponent } from 'react'; +import { CSSProperties, ReactNode, memo, useMemo } from 'react'; import { ParentSize } from '@visx/responsive'; -const defaultProps = { - className: '', - height: 'auto' as number | string, - position: 'top', - width: 'auto' as number | string, -}; - type Props = { - className: string; + className?: string; debounceTime?: number; - width: number | string; - height: number | string; + width?: number | string; + height?: number | string; legendJustifyContent?: 'center' | 'flex-start' | 'flex-end'; - position: 'top' | 'left' | 'bottom' | 'right'; + position?: 'top' | 'left' | 'bottom' | 'right'; renderChart: (dim: { width: number; height: number }) => ReactNode; renderLegend?: (params: { direction: string }) => ReactNode; -} & Readonly; +}; const LEGEND_STYLE_BASE: CSSProperties = { display: 'flex', @@ -52,95 +45,101 @@ const CHART_STYLE_BASE: CSSProperties = { position: 'relative', }; -class WithLegend extends PureComponent { - static defaultProps = defaultProps; - - getContainerDirection(): CSSProperties['flexDirection'] { - const { position } = this.props; - - if (position === 'left') { - return 'row'; - } - if (position === 'right') { - return 'row-reverse'; - } - if (position === 'bottom') { - return 'column-reverse'; - } - - return 'column'; +function getContainerDirection( + position: Props['position'], +): CSSProperties['flexDirection'] { + if (position === 'left') { + return 'row'; + } + if (position === 'right') { + return 'row-reverse'; + } + if (position === 'bottom') { + return 'column-reverse'; } - getLegendJustifyContent() { - const { legendJustifyContent, position } = this.props; - if (legendJustifyContent) { - return legendJustifyContent; - } - - if (position === 'left' || position === 'right') { - return 'flex-start'; - } - - return 'flex-end'; - } - - render() { - const { - className, - debounceTime, - width, - height, - position, - renderChart, - renderLegend, - } = this.props; - - const isHorizontal = position === 'left' || position === 'right'; - - const style: CSSProperties = { - display: 'flex', - flexDirection: this.getContainerDirection(), - height, - width, - }; - - const chartStyle: CSSProperties = { ...CHART_STYLE_BASE }; - if (isHorizontal) { - chartStyle.width = 0; - } else { - chartStyle.height = 0; - } - - const legendDirection = isHorizontal ? 'column' : 'row'; - const legendStyle: CSSProperties = { - ...LEGEND_STYLE_BASE, - flexDirection: legendDirection, - justifyContent: this.getLegendJustifyContent(), - }; - - return ( -
- {renderLegend && ( -
- {renderLegend({ - // Pass flexDirection for @vx/legend to arrange legend items - direction: legendDirection, - })} -
- )} -
- - {(parent: { width: number; height: number }) => - parent.width > 0 && parent.height > 0 - ? // Only render when necessary - renderChart(parent) - : null - } - -
-
- ); - } + return 'column'; } -export default WithLegend; +function getLegendJustifyContent( + legendJustifyContent: Props['legendJustifyContent'], + position: Props['position'], +) { + if (legendJustifyContent) { + return legendJustifyContent; + } + + if (position === 'left' || position === 'right') { + return 'flex-start'; + } + + return 'flex-end'; +} + +function WithLegend({ + className = '', + debounceTime, + width = 'auto', + height = 'auto', + legendJustifyContent, + position = 'top', + renderChart, + renderLegend, +}: Props) { + const isHorizontal = position === 'left' || position === 'right'; + + const style: CSSProperties = useMemo( + () => ({ + display: 'flex', + flexDirection: getContainerDirection(position), + height, + width, + }), + [position, height, width], + ); + + const chartStyle: CSSProperties = useMemo(() => { + const baseStyle = { ...CHART_STYLE_BASE }; + if (isHorizontal) { + baseStyle.width = 0; + } else { + baseStyle.height = 0; + } + return baseStyle; + }, [isHorizontal]); + + const legendDirection = isHorizontal ? 'column' : 'row'; + const legendStyle: CSSProperties = useMemo( + () => ({ + ...LEGEND_STYLE_BASE, + flexDirection: legendDirection, + justifyContent: getLegendJustifyContent(legendJustifyContent, position), + }), + [legendDirection, legendJustifyContent, position], + ); + + return ( +
+ {renderLegend && ( +
+ {renderLegend({ + // Pass flexDirection for @vx/legend to arrange legend items + direction: legendDirection, + })} +
+ )} +
+ + {(parent: { width: number; height: number }) => + parent.width > 0 && parent.height > 0 + ? // Only render when necessary + renderChart(parent) + : null + } + +
+
+ ); +} + +export default memo(WithLegend); diff --git a/superset-frontend/packages/superset-ui-core/src/chart-composition/tooltip/TooltipFrame.tsx b/superset-frontend/packages/superset-ui-core/src/chart-composition/tooltip/TooltipFrame.tsx index d470a229403..19008654316 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart-composition/tooltip/TooltipFrame.tsx +++ b/superset-frontend/packages/superset-ui-core/src/chart-composition/tooltip/TooltipFrame.tsx @@ -17,31 +17,21 @@ * under the License. */ -import { PureComponent, ReactNode } from 'react'; - -const defaultProps = { - className: '', -}; +import { memo, ReactNode } from 'react'; type Props = { className?: string; children: ReactNode; -} & Readonly; +}; const CONTAINER_STYLE = { padding: 8 }; -class TooltipFrame extends PureComponent { - static defaultProps = defaultProps; - - render() { - const { className, children } = this.props; - - return ( -
- {children} -
- ); - } +function TooltipFrame({ className = '', children }: Props) { + return ( +
+ {children} +
+ ); } -export default TooltipFrame; +export default memo(TooltipFrame); diff --git a/superset-frontend/packages/superset-ui-core/src/chart/components/ChartDataProvider.tsx b/superset-frontend/packages/superset-ui-core/src/chart/components/ChartDataProvider.tsx index 457bdd9fefb..541bf19b9e4 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart/components/ChartDataProvider.tsx +++ b/superset-frontend/packages/superset-ui-core/src/chart/components/ChartDataProvider.tsx @@ -17,8 +17,7 @@ * under the License. */ -/* eslint react/sort-comp: 'off' */ -import { PureComponent, ReactNode } from 'react'; +import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'; import { SupersetClientInterface, RequestConfig, @@ -67,103 +66,112 @@ export type ChartDataProviderState = { error?: ProvidedProps['error']; }; -class ChartDataProvider extends PureComponent< - ChartDataProviderProps, - ChartDataProviderState -> { - readonly chartClient: ChartClient; +function ChartDataProvider({ + children, + client, + formData, + sliceId, + loadDatasource, + onError, + onLoaded, + formDataRequestOptions, + datasourceRequestOptions, + queryRequestOptions, +}: ChartDataProviderProps): JSX.Element | null { + const [state, setState] = useState({ + status: 'uninitialized', + }); - constructor(props: ChartDataProviderProps) { - super(props); - this.state = { status: 'uninitialized' }; - this.chartClient = new ChartClient({ client: props.client }); - } + const chartClient = useMemo(() => new ChartClient({ client }), [client]); - componentDidMount() { - this.handleFetchData(); - } + const extractSliceIdAndFormData = useCallback( + (): SliceIdAndOrFormData => + formData ? { formData } : { sliceId: sliceId as number }, + [formData, sliceId], + ); - componentDidUpdate(prevProps: ChartDataProviderProps) { - const { formData, sliceId } = this.props; - if (formData !== prevProps.formData || sliceId !== prevProps.sliceId) { - this.handleFetchData(); + const handleReceiveData = useCallback( + (payload?: Payload) => { + if (onLoaded) onLoaded(payload); + setState({ payload, status: 'loaded' }); + }, + [onLoaded], + ); + + const handleError = useCallback( + (error: ProvidedProps['error']) => { + if (onError) onError(error); + setState({ error, status: 'error' }); + }, + [onError], + ); + + const handleFetchData = useCallback(() => { + setState({ status: 'loading' }); + try { + chartClient + .loadFormData(extractSliceIdAndFormData(), formDataRequestOptions) + .then(loadedFormData => + Promise.all([ + loadDatasource + ? chartClient.loadDatasource( + loadedFormData.datasource, + datasourceRequestOptions, + ) + : Promise.resolve(undefined), + chartClient.loadQueryData(loadedFormData, queryRequestOptions), + ]).then( + ([datasource, queriesData]) => + ({ + datasource, + formData: loadedFormData, + queriesData, + }) as Payload, + ), + ) + .then(handleReceiveData) + .catch(handleError); + } catch (error) { + handleError(error as Error); } - } + }, [ + chartClient, + extractSliceIdAndFormData, + formDataRequestOptions, + loadDatasource, + datasourceRequestOptions, + queryRequestOptions, + handleReceiveData, + handleError, + ]); - private extractSliceIdAndFormData() { - const { formData, sliceId } = this.props; - return formData ? { formData } : { sliceId: sliceId as number }; - } + // Fetch on mount and only refetch when formData or sliceId changes. + // This preserves the original class component's componentDidUpdate + // semantics (which compared only formData and sliceId). Other + // fetch-related inputs referenced by handleFetchData (callbacks and + // request option props) are intentionally excluded from the dependency + // array, so the exhaustive-deps rule is suppressed here. + useEffect(() => { + handleFetchData(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [formData, sliceId]); - private handleFetchData = () => { - const { - loadDatasource, - formDataRequestOptions, - datasourceRequestOptions, - queryRequestOptions, - } = this.props; + const { status, payload, error } = state; - this.setState({ status: 'loading' }, () => { - try { - this.chartClient - .loadFormData( - this.extractSliceIdAndFormData(), - formDataRequestOptions, - ) - .then(formData => - Promise.all([ - loadDatasource - ? this.chartClient.loadDatasource( - formData.datasource, - datasourceRequestOptions, - ) - : Promise.resolve(undefined), - this.chartClient.loadQueryData(formData, queryRequestOptions), - ]).then( - ([datasource, queriesData]) => - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - ({ - datasource, - formData, - queriesData, - }) as Payload, - ), - ) - .then(this.handleReceiveData) - .catch(this.handleError); - } catch (error) { - this.handleError(error as Error); - } - }); - }; - - private handleReceiveData = (payload?: Payload) => { - const { onLoaded } = this.props; - if (onLoaded) onLoaded(payload); - this.setState({ payload, status: 'loaded' }); - }; - - private handleError = (error: ProvidedProps['error']) => { - const { onError } = this.props; - if (onError) onError(error); - this.setState({ error, status: 'error' }); - }; - - render() { - const { children } = this.props; - const { status, payload, error } = this.state; - - switch (status) { - case 'loading': - return children({ loading: true }); - case 'loaded': - return children({ payload }); - case 'error': - return children({ error }); - case 'uninitialized': - default: - return null; - } + // Wrap the children result in a Fragment so the component's return type + // stays `JSX.Element | null` (which TypeScript requires for JSX components) + // while still letting consumers return any ReactNode (strings, fragments, + // arrays, null, etc.) from the render prop. + switch (status) { + case 'loading': + return <>{children({ loading: true })}; + case 'loaded': + return <>{children({ payload })}; + case 'error': + return <>{children({ error })}; + case 'uninitialized': + default: + return null; } } diff --git a/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChart.tsx b/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChart.tsx index 553a98f568a..52a0ed6e1b7 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChart.tsx +++ b/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChart.tsx @@ -21,8 +21,11 @@ import { ReactNode, RefObject, ComponentType, - PureComponent, Fragment, + memo, + useCallback, + useMemo, + useRef, } from 'react'; import { @@ -32,23 +35,19 @@ import { } from 'react-error-boundary'; import { ParentSize } from '@visx/responsive'; import { createSelector } from 'reselect'; -import { withTheme } from '@emotion/react'; +import { useTheme } from '@emotion/react'; import { parseLength, Dimension } from '../../dimension'; import getChartMetadataRegistry from '../registries/ChartMetadataRegistrySingleton'; -import SuperChartCore, { Props as SuperChartCoreProps } from './SuperChartCore'; +import SuperChartCore, { + Props as SuperChartCoreProps, + SuperChartCoreRef, +} from './SuperChartCore'; import DefaultFallbackComponent from './FallbackComponent'; import ChartProps, { ChartPropsConfig } from '../models/ChartProps'; import NoResultsComponent from './NoResultsComponent'; import { isMatrixifyEnabled } from '../types/matrixify'; import MatrixifyGridRenderer from './Matrixify/MatrixifyGridRenderer'; - -const defaultProps = { - FallbackComponent: DefaultFallbackComponent, - height: 400 as string | number, - width: '100%' as string | number, - enableNoResults: true, -}; - +import { supersetTheme, SupersetTheme } from '@apache-superset/core/theme'; export type FallbackPropsWithDimension = FallbackProps & Partial; export type WrapperProps = Dimension & { @@ -56,7 +55,9 @@ export type WrapperProps = Dimension & { }; export type Props = Omit & - Omit & { + Omit & { + /** Theme object (optional, falls back to ThemeProvider context) */ + theme?: SupersetTheme; /** * Set this to true to disable error boundary built-in in SuperChart * and let the error propagate to upper level @@ -102,215 +103,269 @@ export type Props = Omit & inContextMenu?: boolean; }; -type PropsWithDefault = Props & Readonly; - -class SuperChart extends PureComponent { +function SuperChart({ + id, + className, + chartType, + preTransformProps, + overrideTransformProps, + postTransformProps, + onRenderSuccess, + onRenderFailure, + disableErrorBoundary, + FallbackComponent = DefaultFallbackComponent, + onErrorBoundary, + Wrapper, + queriesData, + enableNoResults = true, + noResults, + theme: themeProp, + debounceTime, + height = 400, + width = '100%', + ...rest +}: Props): JSX.Element { /** - * SuperChart's core + * SuperChart's core ref */ - core?: SuperChartCore | null; + const coreRef = useRef(null); - private createChartProps = ChartProps.createSelector(); + // Use theme from prop if provided, otherwise from context. + // When no ThemeProvider is present, useTheme() returns an empty object, + // so we fall back to the default supersetTheme to avoid passing an invalid theme downstream. + const themeFromContext = useTheme() as Partial; + const theme = + themeProp ?? + (Object.keys(themeFromContext).length > 0 + ? (themeFromContext as SupersetTheme) + : supersetTheme); - private parseDimension = createSelector( - [ - ({ width }: { width: string | number; height: string | number }) => width, - ({ height }) => height, - ], - (width, height) => { - // Parse them in case they are % or 'auto' - const widthInfo = parseLength(width); - const heightInfo = parseLength(height); - const boxHeight = heightInfo.isDynamic - ? `${heightInfo.multiplier * 100}%` - : heightInfo.value; - const boxWidth = widthInfo.isDynamic - ? `${widthInfo.multiplier * 100}%` - : widthInfo.value; - const style = { - height: boxHeight, - width: boxWidth, - }; + const createChartProps = useMemo(() => ChartProps.createSelector(), []); - // bounding box will ensure that when one dimension is not dynamic - // e.g. height = 300 - // the auto size will be bound to that value instead of being 100% by default - // e.g. height: 300 instead of height: '100%' - const BoundingBox = - widthInfo.isDynamic && - heightInfo.isDynamic && - widthInfo.multiplier === 1 && - heightInfo.multiplier === 1 - ? Fragment - : ({ children }: { children: ReactNode }) => ( -
{children}
- ); + const parseDimension = useMemo( + () => + createSelector( + [ + ({ width: w }: { width: string | number; height: string | number }) => + w, + ({ + height: h, + }: { + width: string | number; + height: string | number; + }) => h, + ], + (w, h) => { + // Parse them in case they are % or 'auto' + const widthInfo = parseLength(w); + const heightInfo = parseLength(h); + const boxHeight = heightInfo.isDynamic + ? `${heightInfo.multiplier * 100}%` + : heightInfo.value; + const boxWidth = widthInfo.isDynamic + ? `${widthInfo.multiplier * 100}%` + : widthInfo.value; + const style = { + height: boxHeight, + width: boxWidth, + }; - return { BoundingBox, heightInfo, widthInfo }; - }, + // bounding box will ensure that when one dimension is not dynamic + // e.g. height = 300 + // the auto size will be bound to that value instead of being 100% by default + // e.g. height: 300 instead of height: '100%' + const BoundingBox = + widthInfo.isDynamic && + heightInfo.isDynamic && + widthInfo.multiplier === 1 && + heightInfo.multiplier === 1 + ? Fragment + : ({ children }: { children: ReactNode }) => ( +
{children}
+ ); + + return { BoundingBox, heightInfo, widthInfo }; + }, + ), + [], ); - static defaultProps = defaultProps; + const setRef = useCallback((core: SuperChartCoreRef | null) => { + coreRef.current = core; + }, []); - private setRef = (core: SuperChartCore | null) => { - this.core = core; - }; + const getQueryCount = useCallback( + () => getChartMetadataRegistry().get(chartType)?.queryObjectCount ?? 1, + [chartType], + ); - private getQueryCount = () => - getChartMetadataRegistry().get(this.props.chartType)?.queryObjectCount ?? 1; + const renderChart = useCallback( + (chartWidth: number, chartHeight: number) => { + const chartProps = createChartProps({ + ...rest, + queriesData, + height: chartHeight, + width: chartWidth, + theme, + }); - renderChart(width: number, height: number) { - const { + // Check if Matrixify is enabled - use rawFormData (snake_case) + const matrixifyEnabled = isMatrixifyEnabled(chartProps.rawFormData); + + if (matrixifyEnabled) { + // When matrixify is enabled, queriesData is expected to be empty + // since each cell fetches its own data via StatefulChart + const matrixifyChart = ( + + ); + + // Apply wrapper if provided + const wrappedChart = Wrapper ? ( + + {matrixifyChart} + + ) : ( + matrixifyChart + ); + + // Include error boundary unless disabled + return disableErrorBoundary === true ? ( + wrappedChart + ) : ( + ( + + )} + onError={onErrorBoundary} + > + {wrappedChart} + + ); + } + + // Check for no results only for non-matrixified charts + const noResultQueries = + enableNoResults && + (!queriesData || + queriesData + .slice(0, getQueryCount()) + .every( + ({ data }) => !data || (Array.isArray(data) && data.length === 0), + )); + + let chart: JSX.Element; + if (noResultQueries) { + chart = noResults ? ( + <>{noResults} + ) : ( + + ); + } else { + const chartWithoutWrapper = ( + + ); + chart = Wrapper ? ( + + {chartWithoutWrapper} + + ) : ( + chartWithoutWrapper + ); + } + // Include the error boundary by default unless it is specifically disabled. + return disableErrorBoundary === true ? ( + chart + ) : ( + ( + + )} + onError={onErrorBoundary} + > + {chart} + + ); + }, + [ + createChartProps, + rest, + queriesData, + theme, + Wrapper, + disableErrorBoundary, + FallbackComponent, + onErrorBoundary, + enableNoResults, + getQueryCount, + noResults, id, className, + setRef, chartType, preTransformProps, overrideTransformProps, postTransformProps, onRenderSuccess, onRenderFailure, - disableErrorBoundary, - FallbackComponent, - onErrorBoundary, - Wrapper, - queriesData, - enableNoResults, - noResults, - theme, - ...rest - } = this.props as PropsWithDefault; + ], + ); - const chartProps = this.createChartProps({ - ...rest, - queriesData, - height, - width, - theme, - }); + const { heightInfo, widthInfo, BoundingBox } = parseDimension({ + width, + height, + }); - // Check if Matrixify is enabled - use rawFormData (snake_case) - const matrixifyEnabled = isMatrixifyEnabled(chartProps.rawFormData); - - if (matrixifyEnabled) { - // When matrixify is enabled, queriesData is expected to be empty - // since each cell fetches its own data via StatefulChart - const matrixifyChart = ( - - ); - - // Apply wrapper if provided - const wrappedChart = Wrapper ? ( - - {matrixifyChart} - - ) : ( - matrixifyChart - ); - - // Include error boundary unless disabled - return disableErrorBoundary === true ? ( - wrappedChart - ) : ( - ( - - )} - onError={onErrorBoundary} - > - {wrappedChart} - - ); - } - - // Check for no results only for non-matrixified charts - const noResultQueries = - enableNoResults && - (!queriesData || - queriesData - .slice(0, this.getQueryCount()) - .every( - ({ data }) => !data || (Array.isArray(data) && data.length === 0), - )); - - let chart; - if (noResultQueries) { - chart = noResults || ( - - ); - } else { - const chartWithoutWrapper = ( - - ); - chart = Wrapper ? ( - - {chartWithoutWrapper} - - ) : ( - chartWithoutWrapper - ); - } - // Include the error boundary by default unless it is specifically disabled. - return disableErrorBoundary === true ? ( - chart - ) : ( - ( - - )} - onError={onErrorBoundary} - > - {chart} - + // If any of the dimension is dynamic, get parent's dimension + if (widthInfo.isDynamic || heightInfo.isDynamic) { + return ( + + + {({ width: parentWidth, height: parentHeight }) => + renderChart( + widthInfo.isDynamic ? Math.floor(parentWidth) : widthInfo.value, + heightInfo.isDynamic + ? Math.floor(parentHeight) + : heightInfo.value, + ) + } + + ); } - render() { - const { heightInfo, widthInfo, BoundingBox } = this.parseDimension( - this.props as PropsWithDefault, - ); - - // If any of the dimension is dynamic, get parent's dimension - if (widthInfo.isDynamic || heightInfo.isDynamic) { - const { debounceTime } = this.props; - - return ( - - - {({ width, height }) => - this.renderChart( - widthInfo.isDynamic ? Math.floor(width) : widthInfo.value, - heightInfo.isDynamic ? Math.floor(height) : heightInfo.value, - ) - } - - - ); - } - - return this.renderChart(widthInfo.value, heightInfo.value); - } + return renderChart(widthInfo.value, heightInfo.value); } -export default withTheme(SuperChart); +// Wrap in memo to preserve the shallow-prop-comparison behavior +// of the original PureComponent implementation. +export default memo(SuperChart); diff --git a/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChartCore.tsx b/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChartCore.tsx index 844dbae7c6a..30ba894a37f 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChartCore.tsx +++ b/superset-frontend/packages/superset-ui-core/src/chart/components/SuperChartCore.tsx @@ -17,8 +17,13 @@ * under the License. */ -/* eslint-disable react/jsx-sort-default-props */ -import { PureComponent } from 'react'; +import { + forwardRef, + useCallback, + useImperativeHandle, + useMemo, + useRef, +} from 'react'; import { t } from '@apache-superset/core/translation'; import { createSelector } from 'reselect'; import getChartComponentRegistry from '../registries/ChartComponentRegistrySingleton'; @@ -39,16 +44,6 @@ function IDENTITY(x: T) { const EMPTY = () => null; -const defaultProps = { - id: '', - className: '', - preTransformProps: IDENTITY, - overrideTransformProps: undefined, - postTransformProps: IDENTITY, - onRenderSuccess() {}, - onRenderFailure() {}, -}; - interface LoadingProps { error: { toString(): string }; } @@ -78,174 +73,231 @@ export type Props = { onRenderFailure?: HandlerFunction; }; -export default class SuperChartCore extends PureComponent { - /** - * The HTML element that wraps all chart content - */ - container?: HTMLElement | null; +export interface SuperChartCoreRef { + container: HTMLElement | null; +} - /** - * memoized function so it will not recompute and return previous value - * unless one of - * - preTransformProps - * - chartProps - * is changed. - */ - preSelector = createSelector( - [ - (input: { +const SuperChartCore = forwardRef( + function SuperChartCore( + { + id = '', + className = '', + chartProps = BLANK_CHART_PROPS, + chartType, + preTransformProps = IDENTITY, + overrideTransformProps, + postTransformProps = IDENTITY, + onRenderSuccess = () => {}, + onRenderFailure = () => {}, + }, + ref, + ) { + const containerRef = useRef(null); + + // Expose container via ref + useImperativeHandle( + ref, + () => ({ + get container() { + return containerRef.current; + }, + }), + [], + ); + + /** + * memoized function so it will not recompute and return previous value + * unless one of + * - preTransformProps + * - chartProps + * is changed. + */ + const preSelector = useMemo( + () => + createSelector( + [ + (input: { + chartProps: ChartProps; + preTransformProps?: PreTransformProps; + }) => input.chartProps, + input => input.preTransformProps, + ], + (inputChartProps, pre = IDENTITY) => pre(inputChartProps), + ), + [], + ); + + /** + * memoized function so it will not recompute and return previous value + * unless one of the input arguments have changed. + */ + const transformSelector = useMemo( + () => + createSelector( + [ + (input: { + chartProps: ChartProps; + transformProps?: TransformProps; + }) => input.chartProps, + input => input.transformProps, + ], + (preprocessedChartProps, transform = IDENTITY) => + transform(preprocessedChartProps), + ), + [], + ); + + /** + * memoized function so it will not recompute and return previous value + * unless one of the input arguments have changed. + */ + const postSelector = useMemo( + () => + createSelector( + [ + (input: { + chartProps: ChartProps; + postTransformProps?: PostTransformProps; + }) => input.chartProps, + input => input.postTransformProps, + ], + (transformedChartProps, post = IDENTITY) => + post(transformedChartProps), + ), + [], + ); + + /** + * Using each memoized function to retrieve the computed chartProps + */ + const processChartProps = useCallback( + ({ + chartProps: inputChartProps, + preTransformProps: pre, + transformProps, + postTransformProps: post, + }: { chartProps: ChartProps; preTransformProps?: PreTransformProps; - }) => input.chartProps, - input => input.preTransformProps, - ], - (chartProps, pre = IDENTITY) => pre(chartProps), - ); - - /** - * memoized function so it will not recompute and return previous value - * unless one of the input arguments have changed. - */ - transformSelector = createSelector( - [ - (input: { chartProps: ChartProps; transformProps?: TransformProps }) => - input.chartProps, - input => input.transformProps, - ], - (preprocessedChartProps, transform = IDENTITY) => - transform(preprocessedChartProps), - ); - - /** - * memoized function so it will not recompute and return previous value - * unless one of the input arguments have changed. - */ - postSelector = createSelector( - [ - (input: { - chartProps: ChartProps; + transformProps?: TransformProps; postTransformProps?: PostTransformProps; - }) => input.chartProps, - input => input.postTransformProps, - ], - (transformedChartProps, post = IDENTITY) => post(transformedChartProps), - ); - - /** - * Using each memoized function to retrieve the computed chartProps - */ - processChartProps = ({ - chartProps, - preTransformProps, - transformProps, - postTransformProps, - }: { - chartProps: ChartProps; - preTransformProps?: PreTransformProps; - transformProps?: TransformProps; - postTransformProps?: PostTransformProps; - }) => - this.postSelector({ - chartProps: this.transformSelector({ - chartProps: this.preSelector({ chartProps, preTransformProps }), - transformProps, - }), - postTransformProps, - }); - - /** - * memoized function so it will not recompute - * and return previous value - * unless one of - * - chartType - * - overrideTransformProps - * is changed. - */ - private createLoadableRenderer = createSelector( - [ - (input: { chartType: string; overrideTransformProps?: TransformProps }) => - input.chartType, - input => input.overrideTransformProps, - ], - (chartType, overrideTransformProps) => { - if (chartType) { - const Renderer = createLoadableRenderer({ - loader: { - Chart: () => getChartComponentRegistry().getAsPromise(chartType), - transformProps: overrideTransformProps - ? () => Promise.resolve(overrideTransformProps) - : () => getChartTransformPropsRegistry().getAsPromise(chartType), - }, - loading: (loadingProps: LoadingProps) => - this.renderLoading(loadingProps, chartType), - render: this.renderChart, - }); - - // Trigger preloading. - Renderer.preload(); - - return Renderer; - } - - return EMPTY; - }, - ); - - static defaultProps = defaultProps; - - private renderChart = (loaded: LoadedModules, props: RenderProps) => { - const { Chart, transformProps } = loaded; - const { chartProps, preTransformProps, postTransformProps } = props; - - return ( - + }) => + postSelector({ + chartProps: transformSelector({ + chartProps: preSelector({ + chartProps: inputChartProps, + preTransformProps: pre, + }), + transformProps, + }), + postTransformProps: post, + }), + [preSelector, transformSelector, postSelector], ); - }; - private renderLoading = (loadingProps: LoadingProps, chartType: string) => { - const { error } = loadingProps; + const renderLoading = useCallback( + (loadingProps: LoadingProps, loadingChartType: string) => { + const { error } = loadingProps; - if (error) { - return ( -
- {t('ERROR')}  - chartType="{chartType}" — - {error.toString()} -
- ); - } + if (error) { + return ( +
+ {t('ERROR')}  + chartType="{loadingChartType}" — + {error.toString()} +
+ ); + } - return null; - }; + return null; + }, + [], + ); - private setRef = (container: HTMLElement | null) => { - this.container = container; - }; + const renderChart = useCallback( + (loaded: LoadedModules, props: RenderProps) => { + const { Chart, transformProps } = loaded; + const { + chartProps: renderChartProps, + preTransformProps: pre, + postTransformProps: post, + } = props; - render() { - const { - id, - className, - preTransformProps, - postTransformProps, - chartProps = BLANK_CHART_PROPS, - onRenderSuccess, - onRenderFailure, - } = this.props; + return ( + + ); + }, + [processChartProps], + ); + + /** + * memoized function so it will not recompute + * and return previous value + * unless one of + * - chartType + * - overrideTransformProps + * is changed. + */ + const createLoadableRendererSelector = useMemo( + () => + createSelector( + [ + (input: { + chartType: string; + overrideTransformProps?: TransformProps; + }) => input.chartType, + input => input.overrideTransformProps, + ], + (selectorChartType, selectorOverrideTransformProps) => { + if (selectorChartType) { + const Renderer = createLoadableRenderer({ + loader: { + Chart: () => + getChartComponentRegistry().getAsPromise(selectorChartType), + transformProps: selectorOverrideTransformProps + ? () => Promise.resolve(selectorOverrideTransformProps) + : () => + getChartTransformPropsRegistry().getAsPromise( + selectorChartType, + ), + }, + loading: (loadingProps: LoadingProps) => + renderLoading(loadingProps, selectorChartType), + render: renderChart, + }); + + // Trigger preloading. + Renderer.preload(); + + return Renderer; + } + + return EMPTY; + }, + ), + [renderLoading, renderChart], + ); + + const setRef = useCallback((container: HTMLElement | null) => { + containerRef.current = container; + }, []); // Create LoadableRenderer and start preloading // the lazy-loaded Chart components - const Renderer = this.createLoadableRenderer(this.props); + const Renderer = createLoadableRendererSelector({ + chartType, + overrideTransformProps, + }); // Do not render if chartProps is set to null. - // but the pre-loading has been started in this.createLoadableRenderer + // but the pre-loading has been started in createLoadableRendererSelector // to prepare for rendering once chartProps becomes available. if (chartProps === null) { return null; @@ -263,7 +315,7 @@ export default class SuperChartCore extends PureComponent { } return ( -
+
{ />
); - } -} + }, +); + +export default SuperChartCore; diff --git a/superset-frontend/packages/superset-ui-core/src/color/CategoricalColorScale.ts b/superset-frontend/packages/superset-ui-core/src/color/CategoricalColorScale.ts index d5128f03986..b3f28f54d41 100644 --- a/superset-frontend/packages/superset-ui-core/src/color/CategoricalColorScale.ts +++ b/superset-frontend/packages/superset-ui-core/src/color/CategoricalColorScale.ts @@ -94,11 +94,20 @@ class CategoricalColorScale extends ExtensibleFunction { /** * Increment the color range with analogous colors + * + * @param forceMinimumExpansion When true, expand at least once even if the + * ordinal domain is still shorter than the palette. Shared dashboard labels + * can resolve from the global map without entering the scale domain, so + * domain-based sizing alone would skip expansion while collision resolution + * still needs analogous colors. */ - incrementColorRange() { - const multiple = Math.floor( + incrementColorRange(forceMinimumExpansion = false) { + const domainBasedMultiple = Math.floor( this.domain().length / this.originColors.length, ); + const multiple = forceMinimumExpansion + ? Math.max(domainBasedMultiple, 1) + : domainBasedMultiple; // the domain has grown larger than the original range // increments the range with analogous colors if (multiple > this.multiple) { @@ -144,6 +153,7 @@ class CategoricalColorScale extends ExtensibleFunction { if (isFeatureEnabled(FeatureFlag.UseAnalogousColors)) { this.incrementColorRange(); } + if ( // feature flag to be deprecated (will become standard behaviour) isFeatureEnabled(FeatureFlag.AvoidColorsCollision) && @@ -154,6 +164,39 @@ class CategoricalColorScale extends ExtensibleFunction { } } + if ( + isFeatureEnabled(FeatureFlag.AvoidColorsCollision) && + source === LabelsColorMapSource.Dashboard && + (forcedColor || isExistingLabel) + ) { + const colliding = [...this.chartLabelsColorMap.entries()].filter( + ([labelKey, c]) => c === color && labelKey !== cleanedValue, + ); + if ( + colliding.length > 0 && + isFeatureEnabled(FeatureFlag.UseAnalogousColors) + ) { + this.incrementColorRange(true); + } + for (const [otherLabel] of colliding) { + if ( + Object.prototype.hasOwnProperty.call(this.forcedColors, otherLabel) + ) { + continue; + } + const newColor = this.getNextAvailableColor(otherLabel, color); + this.chartLabelsColorMap.set(otherLabel, newColor); + if (sliceId) { + this.labelsColorMapInstance.addSlice( + otherLabel, + newColor, + sliceId, + appliedColorScheme, + ); + } + } + } + // keep track of values in this slice this.chartLabelsColorMap.set(cleanedValue, color); diff --git a/superset-frontend/packages/superset-ui-core/src/components/ActionButton/index.tsx b/superset-frontend/packages/superset-ui-core/src/components/ActionButton/index.tsx index ccc2cbd2b71..d0473812915 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/ActionButton/index.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/ActionButton/index.tsx @@ -17,19 +17,15 @@ * under the License. */ -import type { ReactElement } from 'react'; -import { - Tooltip, - type TooltipPlacement, - type IconType, -} from '@superset-ui/core/components'; +import type { ReactElement, ReactNode } from 'react'; +import { Tooltip, type TooltipPlacement } from '@superset-ui/core/components'; import { css, useTheme } from '@apache-superset/core/theme'; export interface ActionProps { label: string; tooltip?: string | ReactElement; placement?: TooltipPlacement; - icon: IconType; + icon: ReactNode; onClick: () => void; } diff --git a/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/useJsonValidation.test.ts b/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/useJsonValidation.test.ts index e9179b4ce70..99712600fa4 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/useJsonValidation.test.ts +++ b/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/useJsonValidation.test.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { renderHook } from '@testing-library/react-hooks'; +import { renderHook } from '@testing-library/react'; import { useJsonValidation } from './useJsonValidation'; describe('useJsonValidation', () => { @@ -60,7 +60,7 @@ describe('useJsonValidation', () => { expect(result.current[0]).toMatchObject({ type: 'error', row: 0, - column: 0, + column: 1, text: expect.stringContaining('Invalid JSON'), }); }); diff --git a/superset-frontend/packages/superset-ui-core/src/components/AsyncEsmComponent/index.tsx b/superset-frontend/packages/superset-ui-core/src/components/AsyncEsmComponent/index.tsx index aeb8f8b7220..20e06b32028 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/AsyncEsmComponent/index.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/AsyncEsmComponent/index.tsx @@ -16,16 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { - useEffect, - useState, - RefObject, - forwardRef, - ComponentType, - ForwardRefExoticComponent, - PropsWithoutRef, - RefAttributes, -} from 'react'; +import React, { useEffect, useState, forwardRef, ComponentType } from 'react'; import { Loading } from '../Loading'; import type { PlaceholderProps } from './types'; @@ -93,15 +84,16 @@ export function AsyncEsmComponent< return promise; } - type AsyncComponent = ForwardRefExoticComponent< - PropsWithoutRef & RefAttributes> + type AsyncComponent = React.ForwardRefExoticComponent< + React.PropsWithoutRef & React.RefAttributes > & { preload?: typeof waitForPromise; }; + // @ts-expect-error -- generic forwardRef has PropsWithoutRef incompatibility with FullProps const AsyncComponent: AsyncComponent = forwardRef(function AsyncComponent( props: FullProps, - ref: RefObject>, + ref, ) { const [loaded, setLoaded] = useState(component !== undefined); useEffect(() => { diff --git a/superset-frontend/packages/superset-ui-core/src/components/Button/types.ts b/superset-frontend/packages/superset-ui-core/src/components/Button/types.ts index 92e29eaeed3..d53e90e64e0 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Button/types.ts +++ b/superset-frontend/packages/superset-ui-core/src/components/Button/types.ts @@ -24,7 +24,6 @@ import type { ButtonVariantType, ButtonColorType, } from 'antd/es/button'; -import { IconType } from '@superset-ui/core/components/Icons/types'; import type { TooltipPlacement } from '../Tooltip/types'; export type { AntdButtonProps, ButtonType, ButtonVariantType, ButtonColorType }; @@ -49,5 +48,5 @@ export type ButtonProps = Omit & { buttonStyle?: ButtonStyle; cta?: boolean; showMarginRight?: boolean; - icon?: IconType; + icon?: ReactNode; }; diff --git a/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.stories.tsx b/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.stories.tsx index 8790a2a6f53..f70cbc094a6 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.stories.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.stories.tsx @@ -73,7 +73,7 @@ export const Component = (props: DropdownContainerProps) => { const [overflowingState, setOverflowingState] = useState(); const containerRef = useRef(null); const onOverflowingStateChange = useCallback( - value => { + (value: OverflowingState) => { if (!isEqual(overflowingState, value)) { setItems(generateItems(value)); setOverflowingState(value); diff --git a/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/types.ts b/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/types.ts index a7150ffabf9..5cfe20ced72 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/types.ts +++ b/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/types.ts @@ -17,7 +17,6 @@ * under the License. */ import type { CSSProperties, ReactElement, RefObject, ReactNode } from 'react'; -import { IconType } from '../Icons'; /** * Container item. @@ -70,7 +69,7 @@ export interface DropdownContainerProps { /** * Icon of the dropdown trigger. */ - dropdownTriggerIcon?: IconType; + dropdownTriggerIcon?: ReactNode; /** * Text of the dropdown trigger. */ diff --git a/superset-frontend/packages/superset-ui-core/src/components/DynamicEditableTitle/DynamicEditableTitle.regression.test.tsx b/superset-frontend/packages/superset-ui-core/src/components/DynamicEditableTitle/DynamicEditableTitle.regression.test.tsx new file mode 100644 index 00000000000..3cea4bdcfd4 --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/src/components/DynamicEditableTitle/DynamicEditableTitle.regression.test.tsx @@ -0,0 +1,80 @@ +/** + * 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 { fireEvent, render, screen, userEvent } from '@superset-ui/core/spec'; +import { useState } from 'react'; +import { DynamicEditableTitle } from '.'; + +const Harness = ({ initialTitle = 'Original' }: { initialTitle?: string }) => { + const [title, setTitle] = useState(initialTitle); + return ( + + ); +}; + +test('rapid typing then backspacing keeps every keystroke', async () => { + render(); + const input = screen.getByRole('textbox') as HTMLInputElement; + userEvent.click(input); + await userEvent.type(input, 'abc', { delay: 1 }); + expect(input.value).toBe('Originalabc'); + await userEvent.type(input, '{backspace}{backspace}{backspace}', { + delay: 1, + }); + expect(input.value).toBe('Original'); +}); + +test('a change event that arrives before isEditing flips is not dropped', () => { + // Reproduces the regression: the input is focused but `isEditing` is still + // false because no click has been registered yet (e.g. focus arrived via + // tab, autofocus, or programmatic focus). The pre-fix `handleChange` + // bailed out with `!isEditing`, dropping the keystroke. Because the + // input is controlled, antd's internal `useMergedState` then resyncs the + // DOM value back to the (stale) `props.value`, so the user sees their + // typed character disappear. This test fires a raw change event so it + // doesn't go through userEvent's implicit click. + const onSave = jest.fn(); + render( + , + ); + const input = screen.getByRole('textbox') as HTMLInputElement; + fireEvent.change(input, { target: { value: 'FooX' } }); + expect(input.value).toBe('FooX'); +}); + +test('prop changes mid-edit do not clobber unsaved typing', async () => { + const { rerender } = render(); + const input = screen.getByRole('textbox') as HTMLInputElement; + userEvent.click(input); + await userEvent.type(input, 'X', { delay: 1 }); + expect(input.value).toBe('FooX'); + rerender(); + expect(input.value).toBe('FooX'); +}); diff --git a/superset-frontend/packages/superset-ui-core/src/components/DynamicEditableTitle/index.tsx b/superset-frontend/packages/superset-ui-core/src/components/DynamicEditableTitle/index.tsx index 0604b976de0..ec9cf88d85e 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/DynamicEditableTitle/index.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/DynamicEditableTitle/index.tsx @@ -23,6 +23,7 @@ import { useCallback, useEffect, useLayoutEffect, + useRef, useState, } from 'react'; import { t } from '@apache-superset/core/translation'; @@ -30,6 +31,7 @@ import { css, SupersetTheme, useTheme } from '@apache-superset/core/theme'; import { useResizeDetector } from 'react-resize-detector'; import { Tooltip } from '../Tooltip'; import { Input } from '../Input'; +import type { InputRef } from '../Input'; import type { DynamicEditableTitleProps } from './types'; const titleStyles = (theme: SupersetTheme) => css` @@ -75,8 +77,10 @@ export const DynamicEditableTitle = memo( const [isEditing, setIsEditing] = useState(false); const [showTooltip, setShowTooltip] = useState(false); const [currentTitle, setCurrentTitle] = useState(title || ''); + const [inputWidth, setInputWidth] = useState(0); - const { width: inputWidth, ref: sizerRef } = useResizeDetector(); + const sizerRef = useRef(null); + const inputRef = useRef(null); const { width: containerWidth, ref: containerRef } = useResizeDetector({ refreshMode: 'debounce', }); @@ -85,27 +89,33 @@ export const DynamicEditableTitle = memo( setCurrentTitle(title); }, [title]); useEffect(() => { - if (isEditing && sizerRef?.current) { + if (isEditing) { // move cursor and scroll to the end - if (sizerRef.current.setSelectionRange) { - const { length } = sizerRef.current.value; - sizerRef.current.setSelectionRange(length, length); - sizerRef.current.scrollLeft = sizerRef.current.scrollWidth; + const inputElement = inputRef.current?.input; + if (inputElement) { + const { length } = inputElement.value; + inputElement.setSelectionRange(length, length); + inputElement.scrollLeft = inputElement.scrollWidth; } } }, [isEditing]); // a trick to make the input grow when user types text - // we make additional span component, place it somewhere out of view and copy input - // then we can measure the width of that span to resize the input element + // we make an additional span component, place it somewhere out of view and + // mirror the input value, then measure the span synchronously (pre-paint) + // to resize the input element. Reading offsetWidth in a useLayoutEffect + // forces a sync layout, so the input width updates in the same commit as + // the value change — preventing a flicker frame where the input is shown + // with new value but stale width. useLayoutEffect(() => { - if (sizerRef?.current) { + if (sizerRef.current) { sizerRef.current.textContent = currentTitle || placeholder; + setInputWidth(sizerRef.current.offsetWidth); } - }, [currentTitle, placeholder, sizerRef]); + }, [currentTitle, placeholder]); useEffect(() => { - const inputElement = sizerRef.current?.input; + const inputElement = inputRef.current?.input; if (inputElement) { if (inputElement.scrollWidth > inputElement.clientWidth) { @@ -137,9 +147,17 @@ export const DynamicEditableTitle = memo( const handleChange = useCallback( (ev: ChangeEvent) => { - if (!canEdit || !isEditing) { + if (!canEdit) { return; } + // Any change implies the user is editing. Ensure isEditing is true + // even if the change event arrives before the click handler has + // committed (e.g. focus via tab, autofocus, or batched click+type + // events). Otherwise the keystroke would be dropped and the + // controlled input would revert to the previous value. + if (!isEditing) { + setIsEditing(true); + } setCurrentTitle(ev.target.value); }, [canEdit, isEditing], @@ -168,6 +186,7 @@ export const DynamicEditableTitle = memo( } > void; /** Controls image size. Defaults to 'medium'. */ size?: EmptyStateSize; diff --git a/superset-frontend/packages/superset-ui-core/src/components/Form/Form.tsx b/superset-frontend/packages/superset-ui-core/src/components/Form/Form.tsx index 2c2be866fe0..a15a1ab6895 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Form/Form.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Form/Form.tsx @@ -20,7 +20,7 @@ import { Form as AntdForm } from 'antd'; import { FormProps } from './types'; function CustomForm(props: FormProps) { - return ; + return ; } export const Form = Object.assign(CustomForm, { diff --git a/superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx b/superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx index 947a5ff3926..818a4ed5e23 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx @@ -90,6 +90,7 @@ import { InfoCircleFilled, InsertRowAboveOutlined, InsertRowBelowOutlined, + LeftOutlined, LineChartOutlined, LineOutlined, LinkOutlined, @@ -246,6 +247,7 @@ const AntdIcons = { InfoCircleFilled, InsertRowAboveOutlined, InsertRowBelowOutlined, + LeftOutlined, LineChartOutlined, LineOutlined, LinkOutlined, diff --git a/superset-frontend/packages/superset-ui-core/src/components/Label/Label.test.tsx b/superset-frontend/packages/superset-ui-core/src/components/Label/Label.test.tsx index 216db7daa57..d57d1cffaaa 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Label/Label.test.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Label/Label.test.tsx @@ -41,7 +41,6 @@ test('renders with monospace prop', () => { // test stories from the storybook! test('renders all the storybook gallery variants', () => { - // @ts-expect-error: Suppress TypeScript error for LabelGallery usage const { container } = render(); const nonInteractiveLabelCount = 4; const renderedLabelCount = options.length * 2 + nonInteractiveLabelCount; diff --git a/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx b/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx index cab54c35e8a..3eb02f57139 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx @@ -23,7 +23,7 @@ import { Label } from '..'; // Define the prop types for DatasetTypeLabel interface DatasetTypeLabelProps { - datasetType: 'physical' | 'virtual'; // Accepts only 'physical' or 'virtual' + datasetType: 'physical' | 'virtual' | 'semantic_view'; } const SIZE = 's'; // Define the size as a constant @@ -32,6 +32,22 @@ export const DatasetTypeLabel: React.FC = ({ datasetType, }) => { const theme = useTheme(); + if (datasetType === 'semantic_view') { + return ( + + ); + } const isPhysical = datasetType === 'physical'; const label: string = isPhysical ? t('Physical') : t('Virtual'); const labelType = isPhysical ? 'primary' : 'default'; diff --git a/superset-frontend/packages/superset-ui-core/src/components/ListViewCard/index.tsx b/superset-frontend/packages/superset-ui-core/src/components/ListViewCard/index.tsx index c5994181323..e9271d0de6a 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/ListViewCard/index.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/ListViewCard/index.tsx @@ -95,10 +95,13 @@ const TitleLink = styled.span` const TitleRight = styled.span` ${({ theme }) => css` position: absolute; - right: -1px; font-weight: 400; bottom: ${theme.sizeUnit * 3}px; right: ${theme.sizeUnit * 2}px; + max-width: 120px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; `} `; const CoverFooter = styled.div` @@ -244,7 +247,11 @@ function ListViewCard({ {title} - {titleRight && {titleRight}} + {titleRight && ( + + {titleRight} + + )}
{actions}
diff --git a/superset-frontend/packages/superset-ui-core/src/components/ListViewCard/types.ts b/superset-frontend/packages/superset-ui-core/src/components/ListViewCard/types.ts index db0c2f6faf0..175a74d6126 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/ListViewCard/types.ts +++ b/superset-frontend/packages/superset-ui-core/src/components/ListViewCard/types.ts @@ -21,6 +21,7 @@ import type { BackgroundPosition } from './ImageLoader'; export interface LinkProps { to: string; + children?: ReactNode; } export interface ListViewCardProps { diff --git a/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/MetadataBar.tsx b/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/MetadataBar.tsx index 32e71f6b1aa..50b2f3cac00 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/MetadataBar.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/MetadataBar.tsx @@ -194,7 +194,7 @@ const MetadataBar = ({ items, tooltipPlacement = 'top' }: MetadataBarProps) => { } const onResize = useCallback( - width => { + (width: number | undefined) => { // Calculates the breakpoint width to collapse the bar. // The last item does not have a space, so we subtract SPACE_BETWEEN_ITEMS from the total. const breakpoint = diff --git a/superset-frontend/packages/superset-ui-core/src/components/Modal/FormModal.tsx b/superset-frontend/packages/superset-ui-core/src/components/Modal/FormModal.tsx index a7fe66fd898..8fa56ae7458 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Modal/FormModal.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Modal/FormModal.tsx @@ -54,7 +54,7 @@ export function FormModal({ }, [onSave, resetForm]); const handleFormSubmit = useCallback( - async values => { + async (values: object) => { try { setIsSaving(true); await formSubmitHandler(values); diff --git a/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx b/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx index 890084be4c6..5c3cca7122a 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx @@ -55,132 +55,141 @@ export const StyledModal = styled(BaseModal)` height, draggable, hideFooter, - }) => css` - ${responsive && - css` - max-width: ${maxWidth ?? '900px'}; - padding-left: ${theme.sizeUnit * 3}px; - padding-right: ${theme.sizeUnit * 3}px; - padding-bottom: 0; - top: 0; - `} + }) => { + const closeButtonWidth = theme.sizeUnit * 14; - .ant-modal-content { - background-color: ${theme.colorBgContainer}; - display: flex; - flex-direction: column; - max-height: calc(100vh - ${theme.sizeUnit * 8}px); - margin-bottom: ${theme.sizeUnit * 4}px; - margin-top: ${theme.sizeUnit * 4}px; - padding: 0; - } + return css` + ${responsive && + css` + max-width: ${maxWidth ?? '900px'}; + padding-left: ${theme.sizeUnit * 3}px; + padding-right: ${theme.sizeUnit * 3}px; + padding-bottom: 0; + top: 0; + `} - .ant-modal-header { - flex: 0 0 auto; - border-radius: ${theme.borderRadius}px ${theme.borderRadius}px 0 0; - padding: ${theme.sizeUnit * 4}px ${theme.sizeUnit * 4}px; - - .ant-modal-title { - font-weight: ${theme.fontWeightStrong}; - } - - .ant-modal-title h4 { + .ant-modal-content { + background-color: ${theme.colorBgContainer}; display: flex; - margin: 0; - align-items: center; - } - } - - .ant-modal-close { - width: ${theme.sizeUnit * 14}px; - height: ${theme.sizeUnit * 14}px; - padding: ${theme.sizeUnit * 6}px ${theme.sizeUnit * 4}px - ${theme.sizeUnit * 4}px; - top: 0; - right: 0; - display: flex; - justify-content: center; - } - - .ant-modal-close:hover { - background: transparent; - } - - .ant-modal-close-x { - display: flex; - align-items: center; - [data-test='close-modal-btn'] { - justify-content: center; - } - .close { - flex: 1 1 auto; - margin-bottom: ${theme.sizeUnit}px; - color: ${theme.colorPrimaryText}; - font-weight: ${theme.fontWeightLight}; - } - } - - .ant-modal-body { - flex: 0 1 auto; - padding: ${theme.sizeUnit * 4}px ${theme.sizeUnit * 6}px; - - overflow: auto; - ${!resizable && height && `height: ${height};`} - } - - .ant-modal-footer { - flex: 0 0 1; - border-top: ${theme.sizeUnit / 4}px solid ${theme.colorSplit}; - padding: ${theme.sizeUnit * 4}px; - margin-top: 0; - - .btn { - font-size: 12px; - } - - .btn + .btn { - margin-left: ${theme.sizeUnit * 2}px; - } - } - - &.no-content-padding .ant-modal-body { - padding: 0; - } - - ${draggable && - css` - .ant-modal-header { + flex-direction: column; + max-height: calc(100vh - ${theme.sizeUnit * 8}px); + margin-bottom: ${theme.sizeUnit * 4}px; + margin-top: ${theme.sizeUnit * 4}px; padding: 0; + } - .draggable-trigger { - cursor: move; - padding: ${theme.sizeUnit * 4}px; - width: 100%; + .ant-modal-header { + flex: 0 0 auto; + border-radius: ${theme.borderRadius}px ${theme.borderRadius}px 0 0; + padding: ${theme.sizeUnit * 4}px ${closeButtonWidth}px + ${theme.sizeUnit * 4}px ${theme.sizeUnit * 4}px; + + .ant-modal-title { + font-weight: ${theme.fontWeightStrong}; + } + + .ant-modal-title h4 { + display: flex; + margin: 0; + align-items: center; } } - `} - ${resizable && - css` - .resizable { - pointer-events: all; + .ant-modal-close { + width: ${closeButtonWidth}px; + height: ${theme.sizeUnit * 14}px; + padding: ${theme.sizeUnit * 6}px ${theme.sizeUnit * 4}px + ${theme.sizeUnit * 4}px; + top: 0; + right: 0; + display: flex; + justify-content: center; + // Keep the close button clickable when modal body content uses + // position: sticky with elevated z-index (e.g. DatabaseModal header). + z-index: ${theme.zIndexPopupBase + 1}; + } - .resizable-wrapper { - height: 100%; + .ant-modal-close:hover { + background: transparent; + } + + .ant-modal-close-x { + display: flex; + align-items: center; + [data-test='close-modal-btn'] { + justify-content: center; + } + .close { + flex: 1 1 auto; + margin-bottom: ${theme.sizeUnit}px; + color: ${theme.colorPrimaryText}; + font-weight: ${theme.fontWeightLight}; + } + } + + .ant-modal-body { + flex: 0 1 auto; + padding: ${theme.sizeUnit * 4}px ${theme.sizeUnit * 6}px; + + overflow: auto; + ${!resizable && height && `height: ${height};`} + } + + .ant-modal-footer { + flex: 0 0 1; + border-top: ${theme.sizeUnit / 4}px solid ${theme.colorSplit}; + padding: ${theme.sizeUnit * 4}px; + margin-top: 0; + + .btn { + font-size: 12px; } - .ant-modal-content { - height: 100%; + .btn + .btn { + margin-left: ${theme.sizeUnit * 2}px; + } + } - .ant-modal-body { - height: ${hideFooter - ? `calc(100% - ${MODAL_HEADER_HEIGHT}px)` - : `calc(100% - ${MODAL_HEADER_HEIGHT}px - ${MODAL_FOOTER_HEIGHT}px)`}; + &.no-content-padding .ant-modal-body { + padding: 0; + } + + ${draggable && + css` + .ant-modal-header { + padding: 0; + + .draggable-trigger { + cursor: move; + padding: ${theme.sizeUnit * 4}px ${closeButtonWidth}px + ${theme.sizeUnit * 4}px ${theme.sizeUnit * 4}px; + width: 100%; } } - } - `} - `} + `} + + ${resizable && + css` + .resizable { + pointer-events: all; + + .resizable-wrapper { + height: 100%; + } + + .ant-modal-content { + height: 100%; + + .ant-modal-body { + height: ${hideFooter + ? `calc(100% - ${MODAL_HEADER_HEIGHT}px)` + : `calc(100% - ${MODAL_HEADER_HEIGHT}px - ${MODAL_FOOTER_HEIGHT}px)`}; + } + } + } + `} + `; + }} `; const defaultResizableConfig = (hideFooter: boolean | undefined) => ({ @@ -227,8 +236,15 @@ const CustomModal = ({ draggableConfig, destroyOnHidden, openerRef, + bodyStyle, + styles: stylesProp, ...rest }: ModalProps) => { + // Convert deprecated bodyStyle to styles.body + const styles = useMemo( + () => (bodyStyle ? { ...stylesProp, body: bodyStyle } : stylesProp), + [bodyStyle, stylesProp], + ); const draggableRef = useRef(null); const [bounds, setBounds] = useState(); const [dragDisabled, setDragDisabled] = useState(true); @@ -361,6 +377,7 @@ const CustomModal = ({ draggable={draggable} resizable={resizable} destroyOnHidden={destroyOnHidden} + styles={styles} {...rest} > {children} diff --git a/superset-frontend/packages/superset-ui-core/src/components/Modal/types.ts b/superset-frontend/packages/superset-ui-core/src/components/Modal/types.ts index 7876a1bc46c..4159a8c949f 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Modal/types.ts +++ b/superset-frontend/packages/superset-ui-core/src/components/Modal/types.ts @@ -17,7 +17,7 @@ * under the License. */ import type { CSSProperties, ReactNode } from 'react'; -import type { ModalFuncProps } from 'antd'; +import type { FormInstance, ModalFuncProps } from 'antd'; import type { ResizableProps } from 're-resizable'; import type { DraggableProps } from 'react-draggable'; import { ButtonStyle } from '../Button/types'; @@ -51,7 +51,9 @@ export interface ModalProps { destroyOnHidden?: boolean; maskClosable?: boolean; zIndex?: number; + /** @deprecated Use styles.body instead */ bodyStyle?: CSSProperties; + styles?: { body?: CSSProperties; [key: string]: CSSProperties | undefined }; openerRef?: React.RefObject; } @@ -66,7 +68,8 @@ export interface StyledModalProps { export type { ModalFuncProps }; -export interface FormModalProps extends ModalProps { +export interface FormModalProps extends Omit { + children: ReactNode | ((form: FormInstance) => ReactNode); initialValues?: object; formSubmitHandler: (values: object) => Promise; onSave: () => void; diff --git a/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/index.tsx b/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/index.tsx index ae11b6ceff8..a8dd727064d 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/index.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/index.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { ReactNode, ReactElement } from 'react'; +import { ReactNode, ReactElement, memo } from 'react'; import { t } from '@apache-superset/core/translation'; import { css, SupersetTheme, useTheme } from '@apache-superset/core/theme'; import { Icons } from '@superset-ui/core/components/Icons'; @@ -118,60 +118,64 @@ export type PageHeaderWithActionsProps = { }; }; -export const PageHeaderWithActions = ({ - editableTitleProps, - showTitlePanelItems, - certificatiedBadgeProps, - showFaveStar, - faveStarProps, - titlePanelAdditionalItems, - rightPanelAdditionalItems, - additionalActionsMenu, - menuDropdownProps, - showMenuDropdown = true, - tooltipProps, -}: PageHeaderWithActionsProps) => { - const theme = useTheme(); - return ( -
-
- - {showTitlePanelItems && ( -
- {certificatiedBadgeProps?.certifiedBy && ( - - )} - {showFaveStar && } - {titlePanelAdditionalItems} -
- )} -
-
- {rightPanelAdditionalItems} -
- {showMenuDropdown && ( - additionalActionsMenu} - {...menuDropdownProps} - > - - +export const PageHeaderWithActions = memo( + ({ + editableTitleProps, + showTitlePanelItems, + certificatiedBadgeProps, + showFaveStar, + faveStarProps, + titlePanelAdditionalItems, + rightPanelAdditionalItems, + additionalActionsMenu, + menuDropdownProps, + showMenuDropdown = true, + tooltipProps, + }: PageHeaderWithActionsProps) => { + const theme = useTheme(); + return ( +
+
+ + {showTitlePanelItems && ( +
+ {certificatiedBadgeProps?.certifiedBy && ( + + )} + {showFaveStar && } + {titlePanelAdditionalItems} +
)}
+
+ {rightPanelAdditionalItems} +
+ {showMenuDropdown && ( + additionalActionsMenu} + {...menuDropdownProps} + > + + + + + )} +
+
-
- ); -}; + ); + }, +); diff --git a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx index 2f8cb6860a2..2b558b072cb 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx @@ -1160,7 +1160,7 @@ test('does not fire onChange if the same value is selected in single mode', asyn // Reference for the bug this tests: https://github.com/apache/superset/pull/33043#issuecomment-2809419640 test('typing and deleting the last character for a new option displays correctly', async () => { - jest.useFakeTimers(); + jest.useFakeTimers({ advanceTimers: true }); render( - - )} +
+ 0} + onChange={(values: string[]) => { + setNativeFilterFieldValues( + form, + filterId, + { + time_grains: + values.length > 0 && + values.length < + datasetDetails + .time_grain_sqla.length + ? values + : undefined, + }, + ); + forceUpdate(); + formChanged(); + }} + css={{ width: INPUT_WIDTH }} + /> + + + + )} {itemTypeField !== 'filter_range' ? ( { - if (value !== undefined) { - const previous = - form.getFieldValue( - 'filters', - )?.[filterId].controlValues || - {}; - setNativeFilterFieldValues( - form, - filterId, - { - controlValues: { - ...previous, - sortMetric: value, - }, + const previous = + form.getFieldValue('filters')?.[ + filterId + ].controlValues || {}; + setNativeFilterFieldValues( + form, + filterId, + { + controlValues: { + ...previous, + sortMetric: value, }, - ); - forceUpdate(); - } + }, + ); + forceUpdate(); formChanged(); }} /> diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/TimeGrainPreFilter.test.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/TimeGrainPreFilter.test.tsx new file mode 100644 index 00000000000..0520d9e486d --- /dev/null +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/TimeGrainPreFilter.test.tsx @@ -0,0 +1,203 @@ +/** + * 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 { + cleanup, + render, + screen, + userEvent, + waitFor, +} from 'spec/helpers/testing-library'; +import { Form, Select } from '@superset-ui/core/components'; +import { CollapsibleControl } from './CollapsibleControl'; +import { getTimeGrainOptions } from './utils'; + +/** + * Tests for the Time Grain Pre-filter feature (CollapsibleControl + Select). + * + * These tests verify: + * - Options are rendered in database order (no client-side sorting) + * - A saved subset of time_grains is loaded and shown as selected values + * - The CollapsibleControl checkbox shows/hides the Select + * - Toggling the checkbox off clears the underlying selection + */ + +const TIME_GRAIN_TUPLES: [string, string][] = [ + ['PT1S', 'Second'], + ['PT1M', 'Minute'], + ['PT1H', 'Hour'], + ['P1D', 'Day'], + ['P1W', 'Week'], +]; + +// NOTE: This file uses the real AntD Select. In jsdom, rc-overflow schedules +// deferred updates (raf/timers) that can fire after unmount and cause +// "state update on unmounted component" warnings. Scoped fake timers let us +// clear pending work deterministically during teardown for this test only. +beforeEach(() => { + jest.useFakeTimers({ advanceTimers: true }); +}); + +afterEach(() => { + cleanup(); + jest.clearAllTimers(); + jest.useRealTimers(); +}); + +const renderPreFilter = (props: { + savedGrains?: string[]; + initialChecked?: boolean; + onChangeMock?: jest.Mock; +}) => { + const { + savedGrains, + initialChecked = false, + onChangeMock = jest.fn(), + } = props; + const options = getTimeGrainOptions(TIME_GRAIN_TUPLES); + + const PreFilterHarness = () => { + const [form] = Form.useForm(); + + const handleToggle = (checked: boolean) => { + // Mirrors the real form behavior: clear persisted values when disabled. + if (!checked) { + form.setFieldValue('time_grains', undefined); + } + onChangeMock(checked); + }; + + return ( +
+ + + )} + {canDownload && onDownloadCSV && onDownloadXLSX && ( + + )} {copyEnabled ? ( ) : ( @@ -122,6 +133,17 @@ export const TableControls = ({ )} + {onReload && ( + + + + )}
); diff --git a/superset-frontend/src/explore/components/DataTablesPane/components/SamplesPane.tsx b/superset-frontend/src/explore/components/DataTablesPane/components/SamplesPane.tsx index b7c4b4ae48b..ae901bc23ac 100644 --- a/superset-frontend/src/explore/components/DataTablesPane/components/SamplesPane.tsx +++ b/superset-frontend/src/explore/components/DataTablesPane/components/SamplesPane.tsx @@ -19,6 +19,7 @@ import { useState, useEffect, useMemo, useCallback } from 'react'; import { t } from '@apache-superset/core/translation'; import { ensureIsArray } from '@superset-ui/core'; +import { datasetLabelLower } from 'src/features/semanticLayers/label'; import { styled } from '@apache-superset/core/theme'; import { EmptyState, Loading } from '@superset-ui/core/components'; import { GenericDataType } from '@apache-superset/core/common'; @@ -160,7 +161,10 @@ export const SamplesPane = ({ } if (data.length === 0) { - const title = t('No samples were returned for this dataset'); + const title = t( + 'No samples were returned for this %s', + datasetLabelLower(), + ); return ; } diff --git a/superset-frontend/src/explore/components/DataTablesPane/components/SingleQueryResultPane.tsx b/superset-frontend/src/explore/components/DataTablesPane/components/SingleQueryResultPane.tsx index 2b27f515a2c..8cd279f4164 100644 --- a/superset-frontend/src/explore/components/DataTablesPane/components/SingleQueryResultPane.tsx +++ b/superset-frontend/src/explore/components/DataTablesPane/components/SingleQueryResultPane.tsx @@ -57,6 +57,9 @@ export const SingleQueryResultPane = ({ rowLimit, rowLimitOptions, onRowLimitChange, + onDownloadCSV, + onDownloadXLSX, + onReload, }: SingleQueryResultPaneProp) => { const [filterText, setFilterText] = useState(''); const { gridHeight, measuredRef } = useGridHeight(); @@ -83,6 +86,9 @@ export const SingleQueryResultPane = ({ rowLimit={rowLimit} rowLimitOptions={rowLimitOptions} onRowLimitChange={onRowLimitChange} + onDownloadCSV={onDownloadCSV} + onDownloadXLSX={onDownloadXLSX} + onReload={onReload} /> diff --git a/superset-frontend/src/explore/components/DataTablesPane/types.ts b/superset-frontend/src/explore/components/DataTablesPane/types.ts index b01523f4d62..6135bb6fe38 100644 --- a/superset-frontend/src/explore/components/DataTablesPane/types.ts +++ b/superset-frontend/src/explore/components/DataTablesPane/types.ts @@ -63,7 +63,13 @@ export interface SamplesPaneProps { canDownload: boolean; } -export interface TableControlsProps { +export interface DrillControlsProps { + onDownloadCSV?: () => void; + onDownloadXLSX?: () => void; + onReload?: () => void; +} + +export interface TableControlsProps extends DrillControlsProps { data: Record[]; // {datasource.id}__{datasource.type}, eg: 1__table datasourceId?: string; @@ -85,7 +91,8 @@ export interface QueryResultInterface { data: Record[][]; } -export interface SingleQueryResultPaneProp extends QueryResultInterface { +export interface SingleQueryResultPaneProp + extends QueryResultInterface, DrillControlsProps { // {datasource.id}__{datasource.type}, eg: 1__table datasourceId?: string; isVisible: boolean; diff --git a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/DatasourcePanelDragOption.test.tsx b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/DatasourcePanelDragOption.test.tsx index 12fd816b6db..050671c7b4e 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/DatasourcePanelDragOption.test.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/DatasourcePanelDragOption.test.tsx @@ -26,7 +26,7 @@ test('should render', async () => { value={{ metric_name: 'test', uuid: '1' }} type={DndItemType.Metric} />, - { useDnd: true }, + { useDnd: true, useRedux: true, initialState: { explore: {} } }, ); expect( @@ -41,7 +41,7 @@ test('should have attribute draggable:true', async () => { value={{ metric_name: 'test', uuid: '1' }} type={DndItemType.Metric} />, - { useDnd: true }, + { useDnd: true, useRedux: true, initialState: { explore: {} } }, ); expect( diff --git a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx index dad76da609d..d7968dcb3eb 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx @@ -16,8 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -import { RefObject } from 'react'; +import { RefObject, useMemo } from 'react'; import { useDrag } from 'react-dnd'; +import { useSelector } from 'react-redux'; import { Metric } from '@superset-ui/core'; import { css, styled, useTheme } from '@apache-superset/core/theme'; import { ColumnMeta } from '@superset-ui/chart-controls'; @@ -27,6 +28,7 @@ import { StyledMetricOption, } from 'src/explore/components/optionRenderers'; import { Icons } from '@superset-ui/core/components/Icons'; +import { ExplorePageState } from 'src/explore/types'; import { DatasourcePanelDndItem } from '../types'; @@ -70,11 +72,38 @@ export default function DatasourcePanelDragOption( ) { const { labelRef, showTooltip, type, value } = props; const theme = useTheme(); + + // Read compatibility lists from Redux. + // `null` means no filtering is active (SQL datasets, or no selection yet). + const compatibleMetrics = useSelector< + ExplorePageState, + string[] | null | undefined + >(state => state.explore.compatibleMetrics); + const compatibleDimensions = useSelector< + ExplorePageState, + string[] | null | undefined + >(state => state.explore.compatibleDimensions); + + // An item is compatible when the list is null (no filter) or when its + // name explicitly appears in the list returned by the backend. + const isCompatible = useMemo(() => { + if (type === DndItemType.Metric) { + if (!compatibleMetrics) return true; + return compatibleMetrics.includes((value as Metric).metric_name); + } + if (type === DndItemType.Column) { + if (!compatibleDimensions) return true; + return compatibleDimensions.includes((value as ColumnMeta).column_name); + } + return true; + }, [type, value, compatibleMetrics, compatibleDimensions]); + const [{ isDragging }, drag] = useDrag({ item: { value: props.value, type: props.type, }, + canDrag: isCompatible, collect: monitor => ({ isDragging: monitor.isDragging(), }), @@ -87,7 +116,14 @@ export default function DatasourcePanelDragOption( }; return ( - + {type === DndItemType.Column ? ( ) : ( diff --git a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelItem.test.tsx b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelItem.test.tsx index 621b33a323f..37449902b5e 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelItem.test.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelItem.test.tsx @@ -89,7 +89,7 @@ const setup = (data: DatasourcePanelItemProps['data'] = mockData) => ))} , - { useDnd: true }, + { useDnd: true, useRedux: true, initialState: { explore: {} } }, ); test('renders each item accordingly', () => { diff --git a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx index 74718ae3751..7e9d5244130 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { useContext, useMemo, useState } from 'react'; +import { useContext, useDeferredValue, useMemo, useState } from 'react'; import { t } from '@apache-superset/core/translation'; import { DatasourceType, Metric, QueryFormData } from '@superset-ui/core'; import { Alert } from '@apache-superset/core/components'; @@ -26,12 +26,11 @@ import { ControlConfig } from '@superset-ui/chart-controls'; import AutoSizer from 'react-virtualized-auto-sizer'; import { matchSorter, rankings } from 'match-sorter'; -import { Constants, Input } from '@superset-ui/core/components'; +import { Input } from '@superset-ui/core/components'; import { SaveDatasetModal } from 'src/SqlLab/components/SaveDatasetModal'; import { getDatasourceAsSaveableDataset } from 'src/utils/datasourceUtils'; import { ExploreActions } from 'src/explore/actions/exploreActions'; import Control from 'src/explore/components/Control'; -import { useDebounceValue } from 'src/hooks/useDebounceValue'; import { DndItemType } from '../DndItemType'; import { DatasourceFolder, DatasourcePanelColumn, DndItemValue } from './types'; import { DropzoneContext } from '../ExploreContainer'; @@ -122,7 +121,7 @@ const sortColumns = (slice: DatasourcePanelColumn[]) => if (col2?.is_dttm && !col1?.is_dttm) { return 1; } - return 0; + return (col1?.column_name ?? '').localeCompare(col2?.column_name ?? ''); }) .sort((a, b) => (b?.is_certified ?? 0) - (a?.is_certified ?? 0)); @@ -160,7 +159,7 @@ export default function DataSourcePanel({ const [showSaveDatasetModal, setShowSaveDatasetModal] = useState(false); const [inputValue, setInputValue] = useState(''); - const searchKeyword = useDebounceValue(inputValue, Constants.FAST_DEBOUNCE); + const searchKeyword = useDeferredValue(inputValue); const filteredColumns = useMemo(() => { if (!searchKeyword) { @@ -191,7 +190,9 @@ export default function DataSourcePanel({ const filteredMetrics = useMemo(() => { if (!searchKeyword) { - return allowedMetrics ?? []; + return [...(allowedMetrics ?? [])].sort((a, b) => + (a?.metric_name ?? '').localeCompare(b?.metric_name ?? ''), + ); } return matchSorter(allowedMetrics, searchKeyword, { keys: [ diff --git a/superset-frontend/src/explore/components/ExploreChartHeader/index.tsx b/superset-frontend/src/explore/components/ExploreChartHeader/index.tsx index a839fbfaab5..78e4d01af22 100644 --- a/superset-frontend/src/explore/components/ExploreChartHeader/index.tsx +++ b/superset-frontend/src/explore/components/ExploreChartHeader/index.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import { FC, memo, useCallback, useEffect, useMemo, useState } from 'react'; import { useHistory } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import { QueryFormData, JsonObject } from '@superset-ui/core'; @@ -100,7 +100,7 @@ const additionalItemsStyles = (theme: SupersetTheme) => css` } `; -export const ExploreChartHeader: FC = ({ +const ExploreChartHeader: FC = ({ dashboardId, colorScheme: dashboardColorScheme, slice, @@ -270,77 +270,112 @@ export const ExploreChartHeader: FC = ({ } }, [showUnsavedChangesModal, shouldForceCloseModal]); + const editableTitleProps = useMemo( + () => ({ + title: sliceName ?? '', + canEdit: + !slice || + canOverwrite || + (user?.userId !== undefined && + (slice?.owners || []).includes(user.userId)), + onSave: actions.updateChartTitle, + placeholder: t('Add the name of the chart'), + label: t('Chart title'), + }), + [actions.updateChartTitle, canOverwrite, slice, sliceName, user?.userId], + ); + + const certificatiedBadgeProps = useMemo( + () => ({ + certifiedBy: slice?.certified_by, + details: slice?.certification_details, + }), + [slice?.certified_by, slice?.certification_details], + ); + + const faveStarProps = useMemo( + () => ({ + itemId: slice?.slice_id ?? 0, + fetchFaveStar: actions.fetchFaveStar, + saveFaveStar: actions.saveFaveStar, + isStarred, + showTooltip: true, + }), + [actions.fetchFaveStar, actions.saveFaveStar, isStarred, slice?.slice_id], + ); + + const titlePanelAdditionalItems = useMemo( + () => ( +
+ {sliceFormData ? ( + + ) : null} + {formData && isMatrixifyEnabled(formData as MatrixifyFormData) && ( + + )} + {metadataBar} +
+ ), + [ + currentFormData, + formData, + formDiffs, + metadataBar, + originalFormData, + sliceFormData, + ], + ); + + const rightPanelAdditionalItems = useMemo( + () => ( + + {/* needed to wrap button in a div - antd tooltip doesn't work with disabled button */} +
+ +
+
+ ), + [saveDisabled, showModal], + ); + + const menuDropdownProps = useMemo( + () => ({ + open: isDropdownVisible, + onOpenChange: setIsDropdownVisible, + }), + [isDropdownVisible, setIsDropdownVisible], + ); + return ( <> - {sliceFormData ? ( - - ) : null} - {formData && isMatrixifyEnabled(formData as MatrixifyFormData) && ( - - )} - {metadataBar} -
- } - rightPanelAdditionalItems={ - - {/* needed to wrap button in a div - antd tooltip doesn't work with disabled button */} -
- -
-
- } + faveStarProps={faveStarProps} + titlePanelAdditionalItems={titlePanelAdditionalItems} + rightPanelAdditionalItems={rightPanelAdditionalItems} additionalActionsMenu={menu} - menuDropdownProps={{ - open: isDropdownVisible, - onOpenChange: setIsDropdownVisible, - }} + menuDropdownProps={menuDropdownProps} /> {isPropertiesModalOpen && ( = ({ ); }; -export default ExploreChartHeader; +export default memo(ExploreChartHeader); diff --git a/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx b/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx index d7393a0f99e..697e5ef419d 100644 --- a/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx +++ b/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx @@ -58,7 +58,9 @@ import { ExploreAlert } from '../ExploreAlert'; import useResizeDetectorByObserver from './useResizeDetectorByObserver'; const extensionsRegistry = getExtensionsRegistry(); -const DefaultHeader: React.FC = ({ children }) => <>{children}; +const DefaultHeader: React.FC<{ children?: React.ReactNode }> = ({ + children, +}) => <>{children}; export interface ExploreChartPanelProps { actions: { diff --git a/superset-frontend/src/explore/components/ExploreContainer/index.tsx b/superset-frontend/src/explore/components/ExploreContainer/index.tsx index fbac64cf1f6..14150a7d60c 100644 --- a/superset-frontend/src/explore/components/ExploreContainer/index.tsx +++ b/superset-frontend/src/explore/components/ExploreContainer/index.tsx @@ -22,6 +22,7 @@ import { useState, Dispatch, FC, + ReactNode, useReducer, } from 'react'; @@ -60,7 +61,7 @@ const reducer = (state: DropzoneSet = {}, action: Action) => { return state; }; -const ExploreContainer: FC<{}> = ({ children }) => { +const ExploreContainer: FC<{ children?: ReactNode }> = ({ children }) => { const dragDropManager = useDragDropManager(); const [dragging, setDragging] = useState( dragDropManager.getMonitor().isDragging(), diff --git a/superset-frontend/src/explore/components/ExploreViewContainer/index.tsx b/superset-frontend/src/explore/components/ExploreViewContainer/index.tsx index 73d732d0cce..baa5b947314 100644 --- a/superset-frontend/src/explore/components/ExploreViewContainer/index.tsx +++ b/superset-frontend/src/explore/components/ExploreViewContainer/index.tsx @@ -36,6 +36,7 @@ import { JsonObject, MatrixifyFormData, DatasourceType, + ensureIsArray, } from '@superset-ui/core'; import { ControlStateMapping, @@ -412,8 +413,53 @@ function ExploreViewContainer(props: ExploreViewContainerProps) { [originalTitle, theme?.brandAppName, theme?.brandLogoAlt], ); + // M3 + M4: fire compatibility check on mount and whenever the metric / + // dimension selection changes. Only semantic views use the endpoint; + // SQL datasets short-circuit to null inside fetchCompatibility. + const selectedMetrics = useMemo( + () => + ensureIsArray(props.form_data.metrics).filter( + (m): m is string => typeof m === 'string', + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [JSON.stringify(props.form_data.metrics)], + ); + const selectedDimensions = useMemo( + () => + [ + ...ensureIsArray(props.form_data.groupby), + ...ensureIsArray(props.form_data.columns), + ...(typeof props.form_data.x_axis === 'string' + ? [props.form_data.x_axis] + : []), + ].filter((d): d is string => typeof d === 'string'), + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + JSON.stringify(props.form_data.groupby), + JSON.stringify(props.form_data.columns), + props.form_data.x_axis, + ], + ); + useEffect(() => { + props.actions.fetchCompatibility( + props.datasource.type, + props.datasource.id as number, + selectedMetrics, + selectedDimensions, + ); + // props.datasource.id covers the saved-chart-loading case (M4) + }, [ + props.datasource.id, + props.datasource.type, + selectedMetrics, + selectedDimensions, + ]); + const addHistory = useCallback( - async ({ isReplace = false, title } = {}) => { + async ({ + isReplace = false, + title, + }: { isReplace?: boolean; title?: string } = {}) => { const formData = props.dashboardId ? { ...props.form_data, diff --git a/superset-frontend/src/explore/components/SaveModal.test.tsx b/superset-frontend/src/explore/components/SaveModal.test.tsx index 1c79be556f5..e4fdf217ceb 100644 --- a/superset-frontend/src/explore/components/SaveModal.test.tsx +++ b/superset-frontend/src/explore/components/SaveModal.test.tsx @@ -179,6 +179,33 @@ test('renders the right footer buttons', () => { ).toBeInTheDocument(); }); +test('initializes chart name from current Explore slice name', () => { + const previewSliceName = 'RENAMED - Bug Evidence'; + const savedSliceName = 'Most Populated Countries'; + const { getByTestId } = setup( + { + ...defaultProps, + form_data: { + ...defaultProps.form_data, + slice_name: previewSliceName, + }, + sliceName: previewSliceName, + }, + mockStore({ + ...initialState, + explore: { + ...initialState.explore, + slice: { + ...initialState.explore.slice, + slice_name: savedSliceName, + }, + }, + }), + ); + + expect(getByTestId('new-chart-name')).toHaveValue(previewSliceName); +}); + test('does not render a message when overriding', () => { const { getByRole, queryByRole } = setup(); diff --git a/superset-frontend/src/explore/components/StashFormDataContainer/index.tsx b/superset-frontend/src/explore/components/StashFormDataContainer/index.tsx index 5761bef0a6e..a35d77f83c8 100644 --- a/superset-frontend/src/explore/components/StashFormDataContainer/index.tsx +++ b/superset-frontend/src/explore/components/StashFormDataContainer/index.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { useEffect, FC } from 'react'; +import { useEffect, FC, ReactNode } from 'react'; import { useDispatch } from 'react-redux'; import { setStashFormData } from 'src/explore/actions/exploreActions'; @@ -25,6 +25,7 @@ import useEffectEvent from 'src/hooks/useEffectEvent'; type Props = { shouldStash: boolean; fieldNames: ReadonlyArray; + children?: ReactNode; }; const StashFormDataContainer: FC = ({ diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx index c9f2904abc8..76de0d526d2 100644 --- a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx +++ b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/AnnotationLayer.tsx @@ -130,7 +130,7 @@ interface AnnotationLayerState { const AUTOMATIC_COLOR = ''; const NotFoundContentWrapper = styled.div` - && > div:first-child { + && > div:first-of-type { padding-left: 0; padding-right: 0; } diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/index.tsx b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/index.tsx index 9538264b22a..556e08089bf 100644 --- a/superset-frontend/src/explore/components/controls/AnnotationLayerControl/index.tsx +++ b/superset-frontend/src/explore/components/controls/AnnotationLayerControl/index.tsx @@ -257,7 +257,7 @@ class AnnotationLayerControl extends PureComponent { )} title={t('Add annotation layer')} open={this.state.popoverVisible[addLayerPopoverKey]} - destroyTooltipOnHide + destroyOnHidden onOpenChange={visible => this.handleVisibleChange(visible, addLayerPopoverKey) } diff --git a/superset-frontend/src/explore/components/controls/CollectionControl/index.tsx b/superset-frontend/src/explore/components/controls/CollectionControl/index.tsx index d21ffeecc69..2b0e01b0129 100644 --- a/superset-frontend/src/explore/components/controls/CollectionControl/index.tsx +++ b/superset-frontend/src/explore/components/controls/CollectionControl/index.tsx @@ -16,17 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -import React, { Component } from 'react'; +import React, { useCallback, useMemo, useRef } from 'react'; import { IconTooltip, List } from '@superset-ui/core/components'; import { nanoid } from 'nanoid'; import { t } from '@apache-superset/core/translation'; -import { withTheme, type SupersetTheme } from '@apache-superset/core/theme'; +import { useTheme, type SupersetTheme } from '@apache-superset/core/theme'; import { - SortableContainer, - SortableHandle, - SortableElement, + DndContext, + closestCenter, + useSensor, + useSensors, + PointerSensor, + type DragEndEvent, +} from '@dnd-kit/core'; +import { + SortableContext, + verticalListSortingStrategy, + useSortable, arrayMove, -} from 'react-sortable-hoc'; +} from '@dnd-kit/sortable'; +import { CSS } from '@dnd-kit/utilities'; import { Icons } from '@superset-ui/core/components/Icons'; import { HeaderContainer, @@ -41,7 +50,7 @@ interface CollectionItem { [key: string]: unknown; } -interface CollectionControlProps { +export interface CollectionControlProps { name: string; label?: string | null; description?: string | null; @@ -54,161 +63,265 @@ interface CollectionControlProps { isFloat?: boolean; isInt?: boolean; controlName: string; - theme: SupersetTheme; } -const defaultProps: Partial = { - label: null, - description: null, - onChange: () => {}, - placeholder: t('Empty collection'), - itemGenerator: () => ({ key: nanoid(11) }), - keyAccessor: (o: CollectionItem) => o.key ?? '', - value: [], - addTooltip: t('Add an item'), -}; -const SortableListItem = SortableElement(CustomListItem); -const SortableList = SortableContainer(List); -const SortableDragger = SortableHandle(() => ( - -)); +function DragHandle() { + return ( + + ); +} -class CollectionControl extends Component { - static defaultProps = defaultProps; +interface SortableItemProps { + id: string; + index: number; + item: CollectionItem; + controlProps: Omit; + onChangeItem: (index: number, value: CollectionItem) => void; + onRemoveItem: (index: number) => void; +} - constructor(props: CollectionControlProps) { - super(props); - this.onAdd = this.onAdd.bind(this); - } +function SortableItem({ + id, + index, + item, + controlProps, + onChangeItem, + onRemoveItem, +}: SortableItemProps) { + const { attributes, listeners, setNodeRef, transform, transition } = + useSortable({ id }); + const style = { + transform: CSS.Transform.toString(transform), + transition: transition ?? undefined, + }; + const Control = (controlMap as Record>)[ + controlProps.controlName + ]; - onChange(i: number, value: CollectionItem) { - const currentValue = this.props.value ?? []; - const newValue = [...currentValue]; - newValue[i] = { ...currentValue[i], ...value }; - this.props.onChange?.(newValue); - } - - onAdd() { - const currentValue = this.props.value ?? []; - const newItem = this.props.itemGenerator?.(); - // Cast needed: original JS allowed undefined items from itemGenerator - this.props.onChange?.( - currentValue.concat([newItem] as unknown as CollectionItem[]), - ); - } - - onSortEnd({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }) { - const currentValue = this.props.value ?? []; - this.props.onChange?.(arrayMove(currentValue, oldIndex, newIndex)); - } - - removeItem(i: number) { - const currentValue = this.props.value ?? []; - this.props.onChange?.(currentValue.filter((o, ix) => i !== ix)); - } - - renderList() { - const currentValue = this.props.value ?? []; - if (currentValue.length === 0) { - return
{this.props.placeholder}
; - } - const Control = (controlMap as Record>)[ - this.props.controlName - ]; - const keyAccessor = - this.props.keyAccessor ?? ((o: CollectionItem) => o.key ?? ''); - return ( - ({ + alignItems: 'center', + justifyContent: 'flex-start', + display: 'flex', + paddingInline: theme.sizeUnit * 6, + })} + > + + + +
({ - borderRadius: theme.borderRadius, + flex: 1, + marginLeft: theme.sizeUnit * 2, + marginRight: theme.sizeUnit * 2, })} > - {currentValue.map((o: CollectionItem, i: number) => { - // label relevant only for header, not here - const { label, theme, ...commonProps } = this.props; - return ( - ({ - alignItems: 'center', - justifyContent: 'flex-start', - display: 'flex', - paddingInline: theme.sizeUnit * 6, - })} - key={keyAccessor(o)} - index={i} - > - -
({ - flex: 1, - marginLeft: theme.sizeUnit * 2, - marginRight: theme.sizeUnit * 2, - })} - > - -
- ({ - padding: 0, - minWidth: 'auto', - height: 'auto', - lineHeight: 1, - cursor: 'pointer', - '& svg path': { - fill: theme.colorIcon, - transition: `fill ${theme.motionDurationMid} ease-out`, - }, - '&:hover svg path': { - fill: theme.colorError, - }, - })} - > - - -
- ); - })} - - ); - } - - render() { - return ( -
- - - - - - - {this.renderList()} + onChangeItem(index, value)} + />
- ); - } + onRemoveItem(index)} + tooltip={t('Remove item')} + mouseEnterDelay={0} + mouseLeaveDelay={0} + css={(theme: SupersetTheme) => ({ + padding: 0, + minWidth: 'auto', + height: 'auto', + lineHeight: 1, + cursor: 'pointer', + '& svg path': { + fill: theme.colorIcon, + transition: `fill ${theme.motionDurationMid} ease-out`, + }, + '&:hover svg path': { + fill: theme.colorError, + }, + })} + > + + + + ); } -export default withTheme(CollectionControl); +const defaultKeyAccessor = (o: CollectionItem) => o.key ?? ''; +const defaultItemGenerator = () => ({ key: nanoid(11) }); + +function CollectionControl({ + name, + label = null, + description = null, + placeholder = t('Empty collection'), + addTooltip = t('Add an item'), + itemGenerator = defaultItemGenerator, + keyAccessor = defaultKeyAccessor, + onChange, + value = [], + isFloat, + isInt, + controlName, +}: CollectionControlProps) { + const theme = useTheme(); + + const sensors = useSensors( + useSensor(PointerSensor, { + activationConstraint: { distance: 5 }, + }), + ); + + // Two items can collide when keyAccessor returns falsy and the index + // fallback is used — breaking dnd-kit reordering and React reconciliation. + // Assign a stable nanoid per item ref when no key is available. + const generatedIdsRef = useRef>(new WeakMap()); + const itemIds = useMemo( + () => + value.map(item => { + const accessed = keyAccessor(item); + if (accessed) return accessed; + let id = generatedIdsRef.current.get(item); + if (!id) { + id = nanoid(11); + generatedIdsRef.current.set(item, id); + } + return id; + }), + [value, keyAccessor], + ); + + const onAdd = useCallback(() => { + const newItem = itemGenerator(); + onChange?.(value.concat([newItem] as unknown as CollectionItem[])); + }, [value, itemGenerator, onChange]); + + const onChangeItem = useCallback( + (i: number, itemValue: CollectionItem) => { + const oldItem = value[i]; + const newItem = { ...oldItem, ...itemValue }; + // Replacing the object would orphan the WeakMap-stored id and remount + // the row. Carry the generated id over to the new ref. + const generatedId = generatedIdsRef.current.get(oldItem); + if (generatedId) { + generatedIdsRef.current.set(newItem, generatedId); + } + const newValue = [...value]; + newValue[i] = newItem; + onChange?.(newValue); + }, + [value, onChange], + ); + + const onRemoveItem = useCallback( + (i: number) => { + onChange?.(value.filter((_, ix) => i !== ix)); + }, + [value, onChange], + ); + + const handleDragEnd = useCallback( + (event: DragEndEvent) => { + const { active, over } = event; + if (over && active.id !== over.id) { + const oldIndex = itemIds.indexOf(String(active.id)); + const newIndex = itemIds.indexOf(String(over.id)); + onChange?.(arrayMove(value, oldIndex, newIndex)); + } + }, + [value, itemIds, onChange], + ); + + const controlProps = useMemo( + () => ({ + name, + description, + placeholder, + addTooltip, + itemGenerator, + keyAccessor, + onChange, + value, + isFloat, + isInt, + controlName, + }), + [ + name, + description, + placeholder, + addTooltip, + itemGenerator, + keyAccessor, + onChange, + value, + isFloat, + isInt, + controlName, + ], + ); + + const renderList = () => { + if (value.length === 0) { + return
{placeholder}
; + } + return ( + + + ({ + borderRadius: theme.borderRadius, + })} + > + {value.map((item, i) => ( + + ))} + + + + ); + }; + + return ( +
+ + + + + + + {renderList()} +
+ ); +} + +export default CollectionControl; diff --git a/superset-frontend/src/explore/components/controls/ColumnConfigControl/ColumnConfigConstants.test.tsx b/superset-frontend/src/explore/components/controls/ColumnConfigControl/ColumnConfigConstants.test.tsx new file mode 100644 index 00000000000..3f8e40367bf --- /dev/null +++ b/superset-frontend/src/explore/components/controls/ColumnConfigControl/ColumnConfigConstants.test.tsx @@ -0,0 +1,37 @@ +/** + * 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 { SHARED_COLUMN_CONFIG_PROPS } from './constants'; + +test('should allow commas in D3 format inputs', () => { + const { options } = SHARED_COLUMN_CONFIG_PROPS.d3NumberFormat; + const labels = (options ?? []).map((option: { label: unknown }) => + String(option.label), + ); + expect(labels.some((label: string) => label.includes(','))).toBe(true); +}); + +test('should use defaults from Select token separators', () => { + expect( + Object.prototype.hasOwnProperty.call( + SHARED_COLUMN_CONFIG_PROPS.d3NumberFormat, + 'tokenSeparators', + ), + ).toBe(false); +}); diff --git a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.test.tsx b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.test.tsx index 11716aa43a1..b40806bbe71 100644 --- a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.test.tsx +++ b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.test.tsx @@ -38,7 +38,11 @@ const defaultProps = { test('renders "is false" operator label without trailing undefined', () => { const value: ConditionalFormattingConfig[] = [ - { column: 'my_col', operator: Comparator.IsFalse, colorScheme: 'colorSuccess' }, + { + column: 'my_col', + operator: Comparator.IsFalse, + colorScheme: 'colorSuccess', + }, ]; render(); expect(screen.getByText('my_col is false')).toBeInTheDocument(); @@ -46,7 +50,11 @@ test('renders "is false" operator label without trailing undefined', () => { test('renders "is true" operator label without trailing undefined', () => { const value: ConditionalFormattingConfig[] = [ - { column: 'my_col', operator: Comparator.IsTrue, colorScheme: 'colorSuccess' }, + { + column: 'my_col', + operator: Comparator.IsTrue, + colorScheme: 'colorSuccess', + }, ]; render(); expect(screen.getByText('my_col is true')).toBeInTheDocument(); @@ -54,7 +62,11 @@ test('renders "is true" operator label without trailing undefined', () => { test('renders "is null" operator label without trailing undefined', () => { const value: ConditionalFormattingConfig[] = [ - { column: 'my_col', operator: Comparator.IsNull, colorScheme: 'colorSuccess' }, + { + column: 'my_col', + operator: Comparator.IsNull, + colorScheme: 'colorSuccess', + }, ]; render(); expect(screen.getByText('my_col is null')).toBeInTheDocument(); @@ -62,7 +74,11 @@ test('renders "is null" operator label without trailing undefined', () => { test('renders "is not null" operator label without trailing undefined', () => { const value: ConditionalFormattingConfig[] = [ - { column: 'my_col', operator: Comparator.IsNotNull, colorScheme: 'colorSuccess' }, + { + column: 'my_col', + operator: Comparator.IsNotNull, + colorScheme: 'colorSuccess', + }, ]; render(); expect(screen.getByText('my_col is not null')).toBeInTheDocument(); @@ -70,7 +86,11 @@ test('renders "is not null" operator label without trailing undefined', () => { test('renders verbose column name when available', () => { const value: ConditionalFormattingConfig[] = [ - { column: 'my_col', operator: Comparator.IsFalse, colorScheme: 'colorSuccess' }, + { + column: 'my_col', + operator: Comparator.IsFalse, + colorScheme: 'colorSuccess', + }, ]; render( onEdit(newConfig, index) } - destroyTooltipOnHide + destroyOnHidden extraColorChoices={extraColorChoices} allColumns={allColumns} > @@ -179,7 +179,7 @@ const ConditionalFormattingControl = ({ title={t('Add new formatter')} columns={columnOptions} onChange={onSave} - destroyTooltipOnHide + destroyOnHidden extraColorChoices={extraColorChoices} allColumns={allColumns} > diff --git a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx index f7926929e2d..5bda7ba898a 100644 --- a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx +++ b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx @@ -170,7 +170,7 @@ const renderOperatorFields = (
)} - {showEditDatasourceModal && ( - - )} + {showEditDatasourceModal && + (String(datasource.type) === 'semantic_view' ? ( + this.onDatasourceSave(datasource)} + semanticView={{ + id: datasource.id, + table_name: datasource.name, + description: datasource.description, + cache_timeout: datasource.cache_timeout, + }} + /> + ) : ( + + ))} {showChangeDatasourceModal && ( isOverflowingFilterBar ? (nodeTrigger.parentNode as HTMLElement) diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/tests/CustomFrame.test.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/tests/CustomFrame.test.tsx index 3ea0fb106f2..0f196928efa 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/tests/CustomFrame.test.tsx +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/tests/CustomFrame.test.tsx @@ -28,7 +28,7 @@ import { import { CustomFrame } from '../components'; const TODAY = '2024-06-03'; -jest.useFakeTimers(); +jest.useFakeTimers({ advanceTimers: true }); jest.setSystemTime(new Date(TODAY).getTime()); const emptyValue = ''; diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx index f61fafe8bcb..1e69be2c45e 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.tsx @@ -142,6 +142,10 @@ const ColumnSelectPopover = ({ const datasourceType = useSelector( state => state.explore.datasource.type, ); + const compatibleDimensions = useSelector< + ExplorePageState, + string[] | null | undefined + >(state => state.explore.compatibleDimensions); const [initialLabel] = useState(label); const [initialAdhocColumn, initialCalculatedColumn, initialSimpleColumn] = getInitialColumnValues(editedColumn); @@ -167,21 +171,22 @@ const ColumnSelectPopover = ({ const sqlEditorRef = useRef(null); - const [calculatedColumns, simpleColumns] = useMemo( - () => - columns?.reduce( - (acc: [ColumnMeta[], ColumnMeta[]], column: ColumnMeta) => { - if (column.expression) { - acc[0].push(column); - } else { - acc[1].push(column); - } - return acc; - }, - [[], []], - ), - [columns], - ); + const [calculatedColumns, simpleColumns] = useMemo(() => { + const [calc, simple] = (columns ?? []).reduce( + (acc: [ColumnMeta[], ColumnMeta[]], column: ColumnMeta) => { + if (column.expression) { + acc[0].push(column); + } else { + acc[1].push(column); + } + return acc; + }, + [[], []], + ); + const alpha = (a: ColumnMeta, b: ColumnMeta) => + (a.column_name ?? '').localeCompare(b.column_name ?? ''); + return [calc.sort(alpha), simple.sort(alpha)]; + }, [columns]); // Filter metrics that are already selected in the chart const availableMetrics = useMemo(() => { @@ -203,7 +208,7 @@ const ColumnSelectPopover = ({ ); const onSqlExpressionChange = useCallback( - sqlExpression => { + (sqlExpression: string) => { setAdhocColumn({ label, sqlExpression, expressionType: 'SQL' }); setSelectedSimpleColumn(undefined); setSelectedCalculatedColumn(undefined); @@ -213,7 +218,7 @@ const ColumnSelectPopover = ({ ); const onCalculatedColumnChange = useCallback( - selectedColumnName => { + (selectedColumnName: string) => { const selectedColumn = calculatedColumns.find( col => col.column_name === selectedColumnName, ); @@ -229,7 +234,7 @@ const ColumnSelectPopover = ({ ); const onSimpleColumnChange = useCallback( - selectedColumnName => { + (selectedColumnName: string) => { const selectedColumn = simpleColumns.find( col => col.column_name === selectedColumnName, ); @@ -245,7 +250,7 @@ const ColumnSelectPopover = ({ ); const onSimpleMetricChange = useCallback( - selectedMetricName => { + (selectedMetricName: string) => { const selectedMetric = availableMetrics.find( metric => metric.metric_name === selectedMetricName, ); @@ -261,7 +266,7 @@ const ColumnSelectPopover = ({ ); const onSimpleItemChange = useCallback( - selectedValue => { + (selectedValue: string) => { const selectedColumn = columnMap[selectedValue]; if (selectedColumn) { onSimpleColumnChange(selectedValue); @@ -349,7 +354,7 @@ const ColumnSelectPopover = ({ ]); const onTabChange = useCallback( - tab => { + (tab: string) => { getCurrentTab(tab); setSelectedTab(tab); sqlEditorRef.current?.focus(); @@ -551,6 +556,11 @@ const ColumnSelectPopover = ({ key: `column-${simpleColumn.column_name}`, column_name: simpleColumn.column_name, verbose_name: simpleColumn.verbose_name ?? '', + disabled: + compatibleDimensions != null && + !compatibleDimensions.includes( + simpleColumn.column_name, + ), })), ...availableMetrics.map(metric => ({ value: metric.metric_name, @@ -565,6 +575,9 @@ const ColumnSelectPopover = ({ key: `metric-${metric.metric_name}`, metric_name: metric.metric_name, verbose_name: metric.verbose_name ?? '', + disabled: + compatibleDimensions != null && + !compatibleDimensions.includes(metric.metric_name), })), ]} optionFilterProps={[ diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx index cde8a498ec8..cf8692b7503 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopoverTrigger.tsx @@ -199,7 +199,7 @@ const ColumnSelectPopoverTriggerInner = ({ open={visible} onOpenChange={handleTogglePopover} title={popoverTitle} - destroyTooltipOnHide + destroyOnHidden > {children} diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndAdhocFilterOption.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndAdhocFilterOption.tsx index 857b098003b..525b2350496 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndAdhocFilterOption.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndAdhocFilterOption.tsx @@ -23,6 +23,7 @@ import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilt import { OptionSortType } from 'src/explore/types'; import { useGetTimeRangeLabel } from 'src/explore/components/controls/FilterControl/utils'; import OptionWrapper from './OptionWrapper'; +import { datasetLabelLower } from 'src/features/semanticLayers/label'; export interface DndAdhocFilterOptionProps { adhocFilter: AdhocFilter; @@ -68,7 +69,10 @@ export default function DndAdhocFilterOption({ isExtra={adhocFilter.isExtra} datasourceWarningMessage={ adhocFilter.datasourceWarning - ? t('This filter might be incompatible with current dataset') + ? t( + 'This filter might be incompatible with current %s', + datasetLabelLower(), + ) : undefined } /> diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnMetricSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnMetricSelect.tsx index 126d699ddff..0c4fbe40d76 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnMetricSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnMetricSelect.tsx @@ -38,6 +38,7 @@ import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetr import MetricDefinitionValue from 'src/explore/components/controls/MetricControl/MetricDefinitionValue'; import ColumnSelectPopoverTrigger from './ColumnSelectPopoverTrigger'; import { DndControlProps } from './types'; +import { datasetLabelLower } from 'src/features/semanticLayers/label'; const AGGREGATED_DECK_GL_CHART_TYPES = [ 'deck_screengrid', @@ -129,6 +130,16 @@ function DndColumnMetricSelect(props: DndColumnMetricSelectProps) { formData, } = props; + // Semantic views do not support arbitrary SQL expressions as dimensions. + // Merge 'sqlExpression' into disabledTabs so the Custom SQL tab is hidden. + const effectiveDisabledTabs = useMemo( + () => + String(datasource?.type) === 'semantic_view' + ? new Set([...(disabledTabs ?? []), 'sqlExpression']) + : disabledTabs, + [datasource?.type, disabledTabs], + ); + const [newColumnPopoverVisible, setNewColumnPopoverVisible] = useState(false); const combinedOptionsMap = useMemo(() => { @@ -303,7 +314,7 @@ function DndColumnMetricSelect(props: DndColumnMetricSelectProps) { }} editedColumn={column} isTemporal={isTemporal} - disabledTabs={disabledTabs} + disabledTabs={effectiveDisabledTabs} > diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx index 6e474e552cf..1d46fd0020c 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx @@ -17,6 +17,7 @@ * under the License. */ import { useCallback, useMemo, useState } from 'react'; +import { useSelector } from 'react-redux'; import { t } from '@apache-superset/core/translation'; import { AdhocColumn, QueryFormColumn, isAdhocColumn } from '@superset-ui/core'; import { tn } from '@apache-superset/core/translation'; @@ -27,8 +28,10 @@ import OptionWrapper from 'src/explore/components/controls/DndColumnSelectContro import { OptionSelector } from 'src/explore/components/controls/DndColumnSelectControl/utils'; import { DatasourcePanelDndItem } from 'src/explore/components/DatasourcePanel/types'; import { DndItemType } from 'src/explore/components/DndItemType'; +import { ExplorePageState } from 'src/explore/types'; import ColumnSelectPopoverTrigger from './ColumnSelectPopoverTrigger'; import { DndControlProps } from './types'; +import { datasetLabelLower } from 'src/features/semanticLayers/label'; export type DndColumnSelectProps = DndControlProps & { options: ColumnMeta[]; @@ -49,6 +52,19 @@ function DndColumnSelect(props: DndColumnSelectProps) { isTemporal, disabledTabs, } = props; + + // Semantic views do not support arbitrary SQL expressions as dimensions. + const datasourceType = useSelector( + state => state.explore.datasource?.type, + ); + const effectiveDisabledTabs = useMemo( + () => + datasourceType === 'semantic_view' + ? new Set([...(disabledTabs ?? []), 'sqlExpression']) + : disabledTabs, + [datasourceType, disabledTabs], + ); + const [newColumnPopoverVisible, setNewColumnPopoverVisible] = useState(false); const optionSelector = useMemo(() => { @@ -103,7 +119,10 @@ function DndColumnSelect(props: DndColumnSelectProps) { optionSelector.values.map((column, idx) => { const datasourceWarningMessage = isAdhocColumn(column) && column.datasourceWarning - ? t('This column might be incompatible with current dataset') + ? t( + 'This column might be incompatible with current %s', + datasetLabelLower(), + ) : undefined; const withCaret = isAdhocColumn(column) || !column.error_text; @@ -121,7 +140,7 @@ function DndColumnSelect(props: DndColumnSelectProps) { }} editedColumn={column} isTemporal={isTemporal} - disabledTabs={disabledTabs} + disabledTabs={effectiveDisabledTabs} >
diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelectPopoverTitle.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelectPopoverTitle.tsx index e836e202e10..dcc01245432 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelectPopoverTitle.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelectPopoverTitle.tsx @@ -63,7 +63,7 @@ export const DndColumnSelectPopoverTitle = ({ }, []); const onInputBlur = useCallback( - e => { + (e: React.FocusEvent) => { if (e.target.value === '') { onChange(e); } diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx index db1c341ab23..59610ce4dc0 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx @@ -69,7 +69,7 @@ const baseFormData = { }; const mockStore = configureStore([thunk]); -const store = mockStore({}); +const store = mockStore({ explore: {} }); function setup({ value = undefined, diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx index 3f9c525e920..37fbe7210f8 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx @@ -357,6 +357,7 @@ const DndFilterSelect = (props: DndFilterSelectProps) => { () => values.map((adhocFilter: AdhocFilter, index: number) => ( { - render(, { useDnd: true }); + render(, { + useDnd: true, + useRedux: true, + }); expect( screen.getByText('Drop a column/metric here or click'), ).toBeInTheDocument(); }); test('renders with default props and multi = true', () => { - render(, { useDnd: true }); + render(, { + useDnd: true, + useRedux: true, + }); expect( screen.getByText('Drop columns/metrics here or click'), ).toBeInTheDocument(); @@ -86,6 +92,7 @@ test('render selected metrics correctly', () => { const metricValues = ['metric_a', 'metric_b', adhocMetricB]; render(, { useDnd: true, + useRedux: true, }); expect(screen.getByText('metric_a')).toBeVisible(); expect(screen.getByText('Metric B')).toBeVisible(); @@ -107,6 +114,7 @@ test('warn selected custom metric when metric gets removed from dataset', async />, { useDnd: true, + useRedux: true, }, ); @@ -159,6 +167,7 @@ test('warn selected custom metric when metric gets removed from dataset for sing />, { useDnd: true, + useRedux: true, }, ); @@ -217,6 +226,7 @@ test('remove selected adhoc metric when column gets removed from dataset', async />, { useDnd: true, + useRedux: true, }, ); @@ -259,6 +269,7 @@ test('update adhoc metric name when column label in dataset changes', () => { />, { useDnd: true, + useRedux: true, }, ); @@ -304,6 +315,7 @@ test('can drag metrics', async () => { const metricValues = ['metric_a', 'metric_b', adhocMetricB]; render(, { useDnd: true, + useRedux: true, }); expect(screen.getByText('metric_a')).toBeVisible(); @@ -341,6 +353,7 @@ test('cannot drop a duplicated item', () => { , { useDnd: true, + useRedux: true, }, ); @@ -374,6 +387,7 @@ test('can drop a saved metric when disallow_adhoc_metrics', () => { , { useDnd: true, + useRedux: true, }, ); @@ -415,6 +429,7 @@ test('cannot drop non-saved metrics when disallow_adhoc_metrics', () => { , { useDnd: true, + useRedux: true, }, ); @@ -463,6 +478,7 @@ test('title changes on custom SQL text change', async () => { />, { useDnd: true, + useRedux: true, }, ); diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx index 0dd1074acec..988eb302da5 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx @@ -41,6 +41,7 @@ import { DndItemType } from 'src/explore/components/DndItemType'; import DndSelectLabel from 'src/explore/components/controls/DndColumnSelectControl/DndSelectLabel'; import { savedMetricType } from 'src/explore/components/controls/MetricControl/types'; import { AGGREGATES } from 'src/explore/constants'; +import { datasetLabelLower } from 'src/features/semanticLayers/label'; const EMPTY_OBJECT = {}; const DND_ACCEPTED_TYPES = [DndItemType.Column, DndItemType.Metric]; @@ -77,7 +78,10 @@ const coerceMetrics = ( ) { return { metric_name: metric, - error_text: t('This metric might be incompatible with current dataset'), + error_text: t( + 'This metric might be incompatible with current %s', + datasetLabelLower(), + ), uuid: nanoid(), }; } @@ -128,6 +132,26 @@ const DndMetricSelect = (props: any) => { return extra; }, [datasource?.extra]); + // Semantic views do not support arbitrary SQL expressions as metrics. + const disallowAdhocMetrics = + extra.disallow_adhoc_metrics || datasource?.type === 'semantic_view'; + + // AdhocMetricEditPopover reads `datasource.extra.disallow_adhoc_metrics` + // directly, so we need to inject the flag there too — not just in canDrop. + const datasourceForPopover = useMemo(() => { + if (!disallowAdhocMetrics || !datasource) return datasource; + let parsedExtra: Record = {}; + if (datasource.extra) { + try { + parsedExtra = JSON.parse(datasource.extra as string); + } catch {} // eslint-disable-line no-empty + } + return { + ...datasource, + extra: JSON.stringify({ ...parsedExtra, disallow_adhoc_metrics: true }), + }; + }, [disallowAdhocMetrics, datasource]); + const savedMetricSet = useMemo( () => new Set( @@ -139,7 +163,7 @@ const DndMetricSelect = (props: any) => { ); const handleChange = useCallback( - opts => { + (opts: ValueType | ValueType[] | null) => { // if clear out options if (opts === null) { onChange(null); @@ -150,7 +174,11 @@ const DndMetricSelect = (props: any) => { const optionValues = transformedOpts .map(option => { // pre-defined metric - if (option.metric_name) { + if ( + typeof option === 'object' && + 'metric_name' in option && + option.metric_name + ) { return option.metric_name; } return option; @@ -180,7 +208,7 @@ const DndMetricSelect = (props: any) => { const canDrop = useCallback( (item: DatasourcePanelDndItem) => { if ( - extra.disallow_adhoc_metrics && + disallowAdhocMetrics && (item.type !== DndItemType.Metric || !savedMetricSet.has(item.value.metric_name)) ) { @@ -263,7 +291,7 @@ const DndMetricSelect = (props: any) => { ); const getSavedMetricOptionsForMetric = useCallback( - index => + (index: number) => getOptionsForSavedMetrics( props.savedMetrics, props.value, @@ -289,14 +317,17 @@ const DndMetricSelect = (props: any) => { columns={props.columns} savedMetrics={props.savedMetrics} savedMetricsOptions={getSavedMetricOptionsForMetric(index)} - datasource={props.datasource} + datasource={datasourceForPopover} onMoveLabel={moveLabel} onDropLabel={handleDropLabel} type={`${DndItemType.AdhocMetricOption}_${props.name}_${props.label}`} multi={multi} datasourceWarningMessage={ option instanceof AdhocMetric && option.datasourceWarning - ? t('This metric might be incompatible with current dataset') + ? t( + 'This metric might be incompatible with current %s', + datasetLabelLower(), + ) : undefined } /> @@ -395,7 +426,7 @@ const DndMetricSelect = (props: any) => { columns={props.columns} savedMetricsOptions={newSavedMetricOptions} savedMetric={EMPTY_OBJECT as savedMetricType} - datasource={props.datasource} + datasource={datasourceForPopover} isControlledComponent visible={newMetricPopoverVisible} togglePopover={togglePopover} diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/Option.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/Option.tsx index 9e5a715464f..6ab8ef322d4 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/Option.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/Option.tsx @@ -44,7 +44,7 @@ export default function Option({ }: OptionProps) { const theme = useTheme(); const onClickClose = useCallback( - e => { + (e: React.MouseEvent) => { e.stopPropagation(); clickClose(index); }, diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl/index.tsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl/index.tsx index f51da2fdc13..943d9100846 100644 --- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl/index.tsx +++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl/index.tsx @@ -69,7 +69,7 @@ interface Datasource { [key: string]: unknown; } -interface AdhocFilterControlProps { +export interface AdhocFilterControlProps { label?: ReactNode; name?: string; sections?: string[]; diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover/index.tsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover/index.tsx index 97cb4bfb2f1..e8158462ea5 100644 --- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover/index.tsx +++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover/index.tsx @@ -415,21 +415,25 @@ export default class AdhocFilterEditPopover extends Component< ), }, - { - key: ExpressionTypes.Sql, - label: t('Custom SQL'), - children: ( - - - - ), - }, + ...(datasource?.type === 'semantic_view' + ? [] + : [ + { + key: ExpressionTypes.Sql, + label: t('Custom SQL'), + children: ( + + + + ), + }, + ]), ]} /> {hasDeckSlices && ( diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger/index.tsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger/index.tsx index 115fb9449a7..ead19ecd5e9 100644 --- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger/index.tsx +++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger/index.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { PureComponent } from 'react'; +import { PureComponent, ReactNode } from 'react'; import { OptionSortType } from 'src/explore/types'; import AdhocFilterEditPopover from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopover'; import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter'; @@ -37,6 +37,7 @@ interface AdhocFilterPopoverTriggerProps { togglePopover?: (visible: boolean) => void; closePopover?: () => void; requireSave?: boolean; + children?: ReactNode; } interface AdhocFilterPopoverTriggerState { @@ -109,7 +110,7 @@ class AdhocFilterPopoverTrigger extends PureComponent< defaultOpen={visible} open={visible} onOpenChange={togglePopover} - destroyTooltipOnHide + destroyOnHidden > {this.props.children} diff --git a/superset-frontend/src/explore/components/controls/FilterControl/utils/useDatePickerInAdhocfilter.test.ts b/superset-frontend/src/explore/components/controls/FilterControl/utils/useDatePickerInAdhocfilter.test.ts index 27dffc2daff..41372f267be 100644 --- a/superset-frontend/src/explore/components/controls/FilterControl/utils/useDatePickerInAdhocfilter.test.ts +++ b/superset-frontend/src/explore/components/controls/FilterControl/utils/useDatePickerInAdhocfilter.test.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { renderHook, cleanup } from '@testing-library/react-hooks'; +import { renderHook, cleanup } from '@testing-library/react'; import { TestDataset } from '@superset-ui/chart-controls'; import { useDatePickerInAdhocFilter } from './useDatePickerInAdhocFilter'; diff --git a/superset-frontend/src/explore/components/controls/FilterControl/utils/useGetTimeRangeLabel.test.ts b/superset-frontend/src/explore/components/controls/FilterControl/utils/useGetTimeRangeLabel.test.ts index 6aab9287b66..d3f6899bfad 100644 --- a/superset-frontend/src/explore/components/controls/FilterControl/utils/useGetTimeRangeLabel.test.ts +++ b/superset-frontend/src/explore/components/controls/FilterControl/utils/useGetTimeRangeLabel.test.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { renderHook } from '@testing-library/react-hooks'; +import { renderHook, waitFor } from '@testing-library/react'; import { NO_TIME_RANGE, fetchTimeRange } from '@superset-ui/core'; import { Operators } from 'src/explore/constants'; import { useGetTimeRangeLabel } from './useGetTimeRangeLabel'; @@ -80,10 +80,12 @@ test('should get actualTimeRange and title', async () => { clause: Clauses.Where, }); - const { result } = await renderHook(() => useGetTimeRangeLabel(adhocFilter)); - expect(result.current).toEqual({ - actualTimeRange: 'MOCK TIME', - title: 'Last week', + const { result } = renderHook(() => useGetTimeRangeLabel(adhocFilter)); + await waitFor(() => { + expect(result.current).toEqual({ + actualTimeRange: 'MOCK TIME', + title: 'Last week', + }); }); }); @@ -98,9 +100,11 @@ test('should get actualTimeRange and title when gets an error', async () => { clause: Clauses.Where, }); - const { result } = await renderHook(() => useGetTimeRangeLabel(adhocFilter)); - expect(result.current).toEqual({ - actualTimeRange: 'temporal column (Last week)', - title: 'MOCK ERROR', + const { result } = renderHook(() => useGetTimeRangeLabel(adhocFilter)); + await waitFor(() => { + expect(result.current).toEqual({ + actualTimeRange: 'temporal column (Last week)', + title: 'MOCK ERROR', + }); }); }); diff --git a/superset-frontend/src/explore/components/controls/JSEditorControl.test.tsx b/superset-frontend/src/explore/components/controls/JSEditorControl.test.tsx index 5a083702b94..34d121f291e 100644 --- a/superset-frontend/src/explore/components/controls/JSEditorControl.test.tsx +++ b/superset-frontend/src/explore/components/controls/JSEditorControl.test.tsx @@ -45,10 +45,6 @@ jest.mock('src/core/editors', () => ({ ), })); -jest.mock('src/hooks/useDebounceValue', () => ({ - useDebounceValue: (value: string) => value, -})); - const defaultProps = { name: 'echartOptions', label: 'EChart Options', diff --git a/superset-frontend/src/explore/components/controls/JSEditorControl.tsx b/superset-frontend/src/explore/components/controls/JSEditorControl.tsx index 7cf4c252ac5..d0130b1ad96 100644 --- a/superset-frontend/src/explore/components/controls/JSEditorControl.tsx +++ b/superset-frontend/src/explore/components/controls/JSEditorControl.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { useMemo } from 'react'; +import { useDeferredValue, useMemo } from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; import ControlHeader, { ControlHeaderProps, @@ -28,7 +28,6 @@ import { EChartOptionsParseError, } from '@superset-ui/plugin-chart-echarts'; import { EditorHost } from 'src/core/editors'; -import { useDebounceValue } from 'src/hooks/useDebounceValue'; const Container = styled.div` border: 1px solid ${({ theme }) => theme.colorBorder}; @@ -50,10 +49,10 @@ export default function JSEditorControl({ onChange, value, }: ControlHeaderProps & ControlComponentProps) { - const debouncedValue = useDebounceValue(value); + const deferredValue = useDeferredValue(value); const error = useMemo(() => { try { - safeParseEChartOptions(debouncedValue ?? ''); + safeParseEChartOptions(deferredValue ?? ''); return null; } catch (err) { if (err instanceof EChartOptionsParseError) { @@ -61,7 +60,7 @@ export default function JSEditorControl({ } throw err; } - }, [debouncedValue]); + }, [deferredValue]); const headerProps = { name, label: label ?? name, diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/AdhocMetricEditPopover.test.tsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/AdhocMetricEditPopover.test.tsx index a18346ffa0f..cf28e55e619 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/AdhocMetricEditPopover.test.tsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/AdhocMetricEditPopover.test.tsx @@ -67,13 +67,19 @@ const createProps = () => ({ test('Should render', () => { const props = createProps(); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(screen.getByTestId('metrics-edit-popover')).toBeVisible(); }); test('Should render correct elements', () => { const props = createProps(); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(screen.getByRole('tablist')).toBeVisible(); expect(screen.getByRole('button', { name: 'Resize' })).toBeVisible(); expect(screen.getByRole('button', { name: 'Save' })).toBeVisible(); @@ -82,7 +88,10 @@ test('Should render correct elements', () => { test('Should render correct elements for SQL', () => { const props = createProps(); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(screen.getByRole('tab', { name: 'Custom SQL' })).toBeVisible(); expect(screen.getByRole('tab', { name: 'Simple' })).toBeVisible(); expect(screen.getByRole('tab', { name: 'Saved' })).toBeVisible(); @@ -94,7 +103,10 @@ test('Should render correct elements for allow ad-hoc metrics', () => { ...createProps(), datasource: { extra: '{"disallow_adhoc_metrics": false}' }, }; - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(screen.getByRole('tab', { name: 'Custom SQL' })).toBeEnabled(); expect(screen.getByRole('tab', { name: 'Simple' })).toBeEnabled(); expect(screen.getByRole('tab', { name: 'Saved' })).toBeEnabled(); @@ -106,7 +118,10 @@ test('Should render correct elements for disallow ad-hoc metrics', () => { ...createProps(), datasource: { extra: '{"disallow_adhoc_metrics": true}' }, }; - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(screen.getByRole('tab', { name: 'Custom SQL' })).toHaveAttribute( 'aria-disabled', 'true', @@ -121,7 +136,10 @@ test('Should render correct elements for disallow ad-hoc metrics', () => { test('Clicking on "Close" should call onClose', () => { const props = createProps(); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(props.onClose).toHaveBeenCalledTimes(0); userEvent.click(screen.getByRole('button', { name: 'Close' })); expect(props.onClose).toHaveBeenCalledTimes(1); @@ -129,7 +147,10 @@ test('Clicking on "Close" should call onClose', () => { test('Clicking on "Save" should call onChange and onClose', async () => { const props = createProps(); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(props.onChange).toHaveBeenCalledTimes(0); expect(props.onClose).toHaveBeenCalledTimes(0); userEvent.click( @@ -145,7 +166,10 @@ test('Clicking on "Save" should call onChange and onClose', async () => { test('Clicking on "Save" should not call onChange and onClose', () => { const props = createProps(); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(props.onChange).toHaveBeenCalledTimes(0); expect(props.onClose).toHaveBeenCalledTimes(0); userEvent.click(screen.getByRole('button', { name: 'Save' })); @@ -155,7 +179,10 @@ test('Clicking on "Save" should not call onChange and onClose', () => { test('Clicking on "Save" should call onChange and onClose for new metric', () => { const props = createProps(); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(props.onChange).toHaveBeenCalledTimes(0); expect(props.onClose).toHaveBeenCalledTimes(0); userEvent.click(screen.getByRole('button', { name: 'Save' })); @@ -165,7 +192,10 @@ test('Clicking on "Save" should call onChange and onClose for new metric', () => test('Clicking on "Save" should call onChange and onClose for new title', () => { const props = createProps(); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(props.onChange).toHaveBeenCalledTimes(0); expect(props.onClose).toHaveBeenCalledTimes(0); userEvent.click(screen.getByRole('button', { name: 'Save' })); @@ -178,7 +208,10 @@ test('Should switch to tab:Simple', () => { props.getCurrentTab.mockImplementation(tab => { props.adhocMetric.expressionType = tab; }); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(screen.getByRole('tabpanel', { name: 'Saved' })).toBeVisible(); expect( @@ -202,7 +235,10 @@ test('Should render "Simple" tab correctly', () => { props.getCurrentTab.mockImplementation(tab => { props.adhocMetric.expressionType = tab; }); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); const tab = screen.getByRole('tab', { name: 'Simple' }).parentElement!; userEvent.click(tab); @@ -216,7 +252,10 @@ test('Should switch to tab:Custom SQL', () => { props.getCurrentTab.mockImplementation(tab => { props.adhocMetric.expressionType = tab; }); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); expect(screen.getByRole('tabpanel', { name: 'Saved' })).toBeVisible(); expect( @@ -242,7 +281,10 @@ test('Should render "Custom SQL" tab correctly', async () => { props.getCurrentTab.mockImplementation(tab => { props.adhocMetric.expressionType = tab; }); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); const tab = screen.getByRole('tab', { name: 'Custom SQL' }).parentElement!; userEvent.click(tab); @@ -286,7 +328,10 @@ test('Should filter saved metrics by metric_name and verbose_name', async () => }, ], }; - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); const combobox = screen.getByRole('combobox', { name: 'Select saved metrics', @@ -362,7 +407,10 @@ test('Should filter columns by column_name and verbose_name in Simple tab', asyn props.getCurrentTab.mockImplementation(tab => { props.adhocMetric.expressionType = tab; }); - render(); + render(, { + useRedux: true, + initialState: { explore: {} }, + }); const tab = screen.getByRole('tab', { name: 'Simple' }).parentElement!; userEvent.click(tab); diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.tsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.tsx index 031248df0a0..22fdeaa93ee 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.tsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.tsx @@ -18,6 +18,7 @@ */ /* eslint-disable camelcase */ import { PureComponent, createRef } from 'react'; +import { useSelector } from 'react-redux'; import { isDefined, ensureIsArray, DatasourceType } from '@superset-ui/core'; import { t } from '@apache-superset/core/translation'; import type { editors } from '@apache-superset/core'; @@ -94,6 +95,8 @@ interface AdhocMetricEditPopoverProps { datasource?: DatasourceInfo; isNewMetric?: boolean; isLabelModified?: boolean; + /** Names of metrics the user may select; null means no filtering. */ + compatibleMetrics?: string[] | null; } interface AdhocMetricEditPopoverState { @@ -123,7 +126,7 @@ const StyledSelect = styled(Select)` export const SAVED_TAB_KEY = 'SAVED'; -export default class AdhocMetricEditPopover extends PureComponent< +class AdhocMetricEditPopover extends PureComponent< AdhocMetricEditPopoverProps, AdhocMetricEditPopoverState > { @@ -438,15 +441,24 @@ export default class AdhocMetricEditPopover extends PureComponent< ensureIsArray(savedMetricsOptions).length > 0 ? ( ({ + options={[...ensureIsArray(savedMetricsOptions)] + .sort((a, b) => + (a.metric_name ?? '').localeCompare( + b.metric_name ?? '', + ), + ) + .map(savedMetric => ({ value: savedMetric.metric_name, label: this.renderMetricOption(savedMetric), key: savedMetric.id, metric_name: savedMetric.metric_name, verbose_name: savedMetric.verbose_name ?? '', - }), - )} + disabled: + this.props.compatibleMetrics != null && + !this.props.compatibleMetrics.includes( + savedMetric.metric_name, + ), + }))} optionFilterProps={['metric_name', 'verbose_name']} {...savedSelectProps} /> @@ -596,3 +608,20 @@ export default class AdhocMetricEditPopover extends PureComponent< } // @ts-expect-error - defaultProps for backward compatibility AdhocMetricEditPopover.defaultProps = defaultProps; + +// --------------------------------------------------------------------------- +// Thin functional wrapper that injects compatibility data from Redux. +// AdhocMetricEditPopover is a class component and cannot use hooks directly. +// --------------------------------------------------------------------------- +function AdhocMetricEditPopoverWithRedux(props: AdhocMetricEditPopoverProps) { + const compatibleMetrics = useSelector( + (state: any) => + state.explore?.compatibleMetrics as string[] | null | undefined, + ); + return ( + + ); +} + +export { AdhocMetricEditPopover }; +export default AdhocMetricEditPopoverWithRedux; diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.test.tsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.test.tsx index 72a7c975b93..e947bee3953 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.test.tsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.test.tsx @@ -61,7 +61,11 @@ function setup(overrides: Record = {}) { ...overrides, }; // eslint-disable-next-line @typescript-eslint/no-explicit-any - return render(, { useDnd: true }); + return render(, { + useDnd: true, + useRedux: true, + initialState: { explore: {} }, + }); } test('renders an overlay trigger wrapper for the label', () => { diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx index b26346933b8..77ae48b51a6 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx @@ -272,7 +272,7 @@ class AdhocMetricPopoverTrigger extends PureComponent< open={visible} onOpenChange={togglePopover} title={popoverTitle} - destroyTooltipOnHide + destroyOnHidden > {this.props.children} diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.test.tsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.test.tsx index 234b5068c3c..78db85a6cb4 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.test.tsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.test.tsx @@ -62,7 +62,10 @@ function setup(overrides: Record = {}) { ...defaultProps, ...overrides, }; - const result = render(, { useDnd: true }); + const result = render(, { + useDnd: true, + useRedux: true, + }); return { onChange, ...result }; } @@ -107,7 +110,7 @@ test('accepts an edited metric from an AdhocMetricEditPopover', async () => { userEvent.click(metricLabel); await screen.findByText('aggregate'); - selectOption('AVG', 'Select aggregate options'); + await selectOption('AVG', 'Select aggregate options'); await screen.findByText('AVG(value)'); @@ -166,7 +169,7 @@ test('does not remove custom SQL metric if savedMetrics changes', async () => { ]} datasource={undefined} />, - { useDnd: true }, + { useDnd: true, useRedux: true }, ); expect(screen.getByText('old label')).toBeInTheDocument(); diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.tsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.tsx index a3cd9bad883..656d01bb310 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.tsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.tsx @@ -108,7 +108,7 @@ const getMetricsMatchingCurrentDataset = ( ); }); -interface MetricsControlProps { +export interface MetricsControlProps { name: string; onChange: (value: unknown) => void; multi?: boolean; diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx index e35619772c2..a0cad6f63a6 100644 --- a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx +++ b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx @@ -45,7 +45,7 @@ import VizTypeControl, { VIZ_TYPE_CONTROL_TEST_ID } from './index'; // Mock scrollIntoView to avoid errors in test environment jest.mock('scroll-into-view-if-needed', () => jest.fn()); -jest.useFakeTimers(); +jest.useFakeTimers({ advanceTimers: true }); class MainPreset extends Preset { constructor() { diff --git a/superset-frontend/src/explore/components/useExploreAdditionalActionsMenu/index.tsx b/superset-frontend/src/explore/components/useExploreAdditionalActionsMenu/index.tsx index f4dc6b57af8..6b9e7b048de 100644 --- a/superset-frontend/src/explore/components/useExploreAdditionalActionsMenu/index.tsx +++ b/superset-frontend/src/explore/components/useExploreAdditionalActionsMenu/index.tsx @@ -19,13 +19,13 @@ import React, { ReactElement, useCallback, + useDeferredValue, useMemo, useState, Dispatch, SetStateAction, } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useDebounceValue } from 'src/hooks/useDebounceValue'; import { isFeatureEnabled, FeatureFlag, @@ -213,10 +213,7 @@ export const useExploreAdditionalActionsMenu = ( const dispatch = useDispatch(); const [isDropdownVisible, setIsDropdownVisible] = useState(false); const [dashboardSearchTerm, setDashboardSearchTerm] = useState(''); - const debouncedDashboardSearchTerm = useDebounceValue( - dashboardSearchTerm, - 300, - ); + const deferredDashboardSearchTerm = useDeferredValue(dashboardSearchTerm); const chart = useSelector(state => state.explore ? state.charts?.[getChartKey(state.explore)] : undefined, ); @@ -304,7 +301,7 @@ export const useExploreAdditionalActionsMenu = ( const dashboardMenuItems = useDashboardsMenuItems({ chartId: slice?.slice_id, dashboards, - searchTerm: debouncedDashboardSearchTerm, + searchTerm: deferredDashboardSearchTerm, }); const showDashboardSearch = (dashboards?.length ?? 0) > SEARCH_THRESHOLD; @@ -1054,7 +1051,7 @@ export const useExploreAdditionalActionsMenu = ( dashboards, dashboardMenuItems, dashboardSearchTerm, - debouncedDashboardSearchTerm, + deferredDashboardSearchTerm, datasource, dispatch, exportCSV, diff --git a/superset-frontend/src/explore/controls.tsx b/superset-frontend/src/explore/controls.tsx index 91e91de6867..74caebe52f1 100644 --- a/superset-frontend/src/explore/controls.tsx +++ b/superset-frontend/src/explore/controls.tsx @@ -64,6 +64,7 @@ import { validateNonEmpty, } from '@superset-ui/core'; import { t } from '@apache-superset/core/translation'; +import { datasetLabel } from 'src/features/semanticLayers/label'; import { formatSelectOptions } from 'src/explore/exploreUtils'; import { TIME_FILTER_LABELS } from './constants'; import { StyledColumnOption } from './components/optionRenderers'; @@ -214,7 +215,7 @@ export const controls = { datasource: { type: 'DatasourceControl', - label: t('Dataset'), + label: datasetLabel(), default: null, description: null, mapStateToProps: ({ datasource }: ControlState) => ({ diff --git a/superset-frontend/src/explore/reducers/exploreReducer.ts b/superset-frontend/src/explore/reducers/exploreReducer.ts index faffbfac5fa..c7eaf4d699d 100644 --- a/superset-frontend/src/explore/reducers/exploreReducer.ts +++ b/superset-frontend/src/explore/reducers/exploreReducer.ts @@ -70,6 +70,9 @@ export interface ExploreState { metadata?: { owners?: string[] | null; }; + compatibleMetrics?: string[] | null; + compatibleDimensions?: string[] | null; + compatibilityLoading?: boolean; saveAction?: SaveActionType | null; chartStates?: Record; } @@ -178,6 +181,13 @@ interface UpdateExploreChartStateAction { lastModified: number; } +interface SetCompatibilityAction { + type: typeof actions.SET_COMPATIBILITY; + compatibleMetrics: string[] | null; + compatibleDimensions: string[] | null; + compatibilityLoading: boolean; +} + type ExploreAction = | DynamicPluginControlsReadyAction | ToggleFaveStarAction @@ -197,6 +207,7 @@ type ExploreAction = | SliceUpdatedAction | SetForceQueryAction | UpdateExploreChartStateAction + | SetCompatibilityAction | HydrateExplore; // Extended control state for dynamic form controls - uses Record for flexibility @@ -635,6 +646,15 @@ export default function exploreReducer( force: typedAction.force, }; }, + [actions.SET_COMPATIBILITY]() { + const typedAction = action as SetCompatibilityAction; + return { + ...state, + compatibleMetrics: typedAction.compatibleMetrics, + compatibleDimensions: typedAction.compatibleDimensions, + compatibilityLoading: typedAction.compatibilityLoading, + }; + }, [actions.UPDATE_EXPLORE_CHART_STATE]() { const typedAction = action as UpdateExploreChartStateAction; return { diff --git a/superset-frontend/src/explore/store.test.tsx b/superset-frontend/src/explore/store.test.tsx index 602390a4d4f..d74b5bf0c18 100644 --- a/superset-frontend/src/explore/store.test.tsx +++ b/superset-frontend/src/explore/store.test.tsx @@ -17,55 +17,359 @@ * under the License. */ import { getChartControlPanelRegistry } from '@superset-ui/core'; -import { applyDefaultFormData } from 'src/explore/store'; +import { + applyDefaultFormData, + getControlsState, + handleDeprecatedControls, +} from 'src/explore/store'; -// eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks -describe('store', () => { - beforeAll(() => { - getChartControlPanelRegistry().registerValue('test-chart', { - controlPanelSections: [ - { - label: 'Test section', - expanded: true, - controlSetRows: [['row_limit']], - }, - ], - }); - }); +// eslint-disable-next-line @typescript-eslint/no-explicit-any +(window as any).featureFlags = {}; - afterAll(() => { - getChartControlPanelRegistry().remove('test-chart'); - }); - - // eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks - describe('applyDefaultFormData', () => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (window as any).featureFlags = {}; - - test('applies default to formData if the key is missing', () => { - const inputFormData = { - datasource: '11_table', - viz_type: 'test-chart', - }; - let outputFormData = applyDefaultFormData(inputFormData); - expect(outputFormData.row_limit).toEqual(10000); - - const inputWithRowLimit = { - ...inputFormData, - row_limit: 888, - }; - outputFormData = applyDefaultFormData(inputWithRowLimit); - expect(outputFormData.row_limit).toEqual(888); - }); - - test('keeps null if key is defined with null', () => { - const inputFormData = { - datasource: '11_table', - viz_type: 'test-chart', - row_limit: null, - }; - const outputFormData = applyDefaultFormData(inputFormData); - expect(outputFormData.row_limit).toBe(null); - }); +beforeAll(() => { + getChartControlPanelRegistry().registerValue('test-chart', { + controlPanelSections: [ + { + label: 'Test section', + expanded: true, + controlSetRows: [['row_limit']], + }, + ], }); }); + +afterAll(() => { + getChartControlPanelRegistry().remove('test-chart'); +}); + +// Helper: build ExploreState for getControlsState +const buildExploreState = (controlOverrides: Record = {}) => ({ + datasource: { type: 'table' }, + controls: Object.fromEntries( + Object.entries(controlOverrides).map(([k, v]) => [k, { value: v }]), + ), +}); + +// ============================================================ +// Existing applyDefaultFormData tests +// ============================================================ + +test('applyDefaultFormData applies default to formData if the key is missing', () => { + const inputFormData = { + datasource: '11_table', + viz_type: 'test-chart', + }; + let outputFormData = applyDefaultFormData(inputFormData); + expect(outputFormData.row_limit).toEqual(10000); + + const inputWithRowLimit = { + ...inputFormData, + row_limit: 888, + }; + outputFormData = applyDefaultFormData(inputWithRowLimit); + expect(outputFormData.row_limit).toEqual(888); +}); + +test('applyDefaultFormData keeps null if key is defined with null', () => { + const inputFormData = { + datasource: '11_table', + viz_type: 'test-chart', + row_limit: null, + }; + const outputFormData = applyDefaultFormData(inputFormData); + expect(outputFormData.row_limit).toBe(null); +}); + +// ============================================================ +// Migration tests: handleDeprecatedControls normalizes stale matrixify modes +// (fix for apache/superset#38519 regression — guards validators AND +// downstream UI consumers that infer matrixify state from mode values) +// ============================================================ + +test('getControlsState resets stale matrixify_mode_rows to disabled when matrixify_enable key absent', () => { + const state = buildExploreState(); + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_mode_rows: 'dimensions', // stale pre-revamp default + }; + + const result = getControlsState(state as any, formData as any); + const modeControl = result.matrixify_mode_rows as any; + expect(modeControl?.value).toBe('disabled'); +}); + +test('getControlsState resets stale matrixify_mode_columns to disabled when matrixify_enable key absent', () => { + const state = buildExploreState(); + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_mode_columns: 'metrics', // stale pre-revamp default + }; + + const result = getControlsState(state as any, formData as any); + const modeControl = result.matrixify_mode_columns as any; + expect(modeControl?.value).toBe('disabled'); +}); + +test('getControlsState preserves matrixify mode values when matrixify_enable is true', () => { + const state = buildExploreState(); + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_enable: true, + matrixify_mode_rows: 'dimensions', + }; + + const result = getControlsState(state as any, formData as any); + const modeControl = result.matrixify_mode_rows as any; + expect(modeControl?.value).toBe('dimensions'); +}); + +test('getControlsState preserves matrixify mode values when matrixify_enable is explicitly false', () => { + const state = buildExploreState(); + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_enable: false, + matrixify_mode_rows: 'dimensions', + }; + + const result = getControlsState(state as any, formData as any); + const modeControl = result.matrixify_mode_rows as any; + // matrixify_enable key IS present (just false) — migration does NOT fire + expect(modeControl?.value).toBe('dimensions'); +}); + +test('getControlsState is idempotent when matrixify modes already disabled', () => { + const state = buildExploreState(); + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_mode_rows: 'disabled', + matrixify_mode_columns: 'disabled', + }; + + const result = getControlsState(state as any, formData as any); + expect((result.matrixify_mode_rows as any)?.value).toBe('disabled'); + expect((result.matrixify_mode_columns as any)?.value).toBe('disabled'); +}); + +test('getControlsState handles form_data with no matrixify keys', () => { + const state = buildExploreState(); + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + }; + + const result = getControlsState(state as any, formData as any); + // Controls should get their defaults — matrixify_mode defaults to 'disabled' + expect((result.matrixify_mode_rows as any)?.value).toBe('disabled'); + expect((result.matrixify_mode_columns as any)?.value).toBe('disabled'); +}); + +test('getControlsState round-trip: pre-revamp form_data produces no matrixify validation errors', () => { + // Simulate a chart saved before #38519 with stale matrixify defaults + // Empty controls: on real first-load hydration, no pre-existing controls exist + const state = buildExploreState(); + const preRevampFormData = { + datasource: '1__table', + viz_type: 'test-chart', + // Stale old defaults — no matrixify_enable key (legacy chart) + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + }; + + const result = getControlsState(state as any, preRevampFormData as any); + + // Every matrixify control should have zero validation errors + const matrixifyControlEntries = Object.entries(result).filter(([name]) => + name.startsWith('matrixify_'), + ); + const controlsWithErrors = matrixifyControlEntries.filter( + ([, control]) => (control as any)?.validationErrors?.length > 0, + ); + + expect(controlsWithErrors).toEqual([]); +}); + +// ============================================================ +// Dashboard hydration: applyDefaultFormData with stale form_data +// ============================================================ + +test('applyDefaultFormData normalizes stale matrixify modes for legacy charts', () => { + // Dashboard hydration now runs handleDeprecatedControls too, so stale + // matrixify modes from pre-revamp charts are normalized to 'disabled'. + // This protects downstream consumers (ChartContextMenu, DrillBySubmenu, + // ChartRenderer) that infer "matrixify is active" from mode values alone. + const preRevampFormData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + // No matrixify_enable key — legacy chart that never used matrixify + }; + + const outputFormData = applyDefaultFormData(preRevampFormData as any); + + // Stale values are now normalized to 'disabled' + expect(outputFormData.matrixify_mode_rows).toBe('disabled'); + expect(outputFormData.matrixify_mode_columns).toBe('disabled'); + expect(outputFormData.matrixify_enable).toBe(false); +}); + +// ============================================================ +// P1: Pre-revamp charts that actually used matrixify via old per-axis flags +// (matrixify_enable_vertical_layout / matrixify_enable_horizontal_layout) +// ============================================================ + +test('getControlsState preserves modes and sets matrixify_enable when old vertical flag is true', () => { + const state = buildExploreState(); + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_enable_vertical_layout: true, + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + }; + + const result = getControlsState(state as any, formData as any); + // Vertical layout was enabled — rows mode preserved, matrixify_enable migrated + expect((result.matrixify_mode_rows as any)?.value).toBe('dimensions'); + expect((result.matrixify_enable as any)?.value).toBe(true); + // Horizontal layout was NOT enabled — columns mode reset + expect((result.matrixify_mode_columns as any)?.value).toBe('disabled'); +}); + +test('getControlsState preserves modes and sets matrixify_enable when old horizontal flag is true', () => { + const state = buildExploreState(); + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_enable_horizontal_layout: true, + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + }; + + const result = getControlsState(state as any, formData as any); + // Horizontal layout was enabled — columns mode preserved, matrixify_enable migrated + expect((result.matrixify_mode_columns as any)?.value).toBe('metrics'); + expect((result.matrixify_enable as any)?.value).toBe(true); + // Vertical layout was NOT enabled — rows mode reset + expect((result.matrixify_mode_rows as any)?.value).toBe('disabled'); +}); + +test('getControlsState preserves both modes when both old per-axis flags are true', () => { + const state = buildExploreState(); + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_enable_vertical_layout: true, + matrixify_enable_horizontal_layout: true, + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + }; + + const result = getControlsState(state as any, formData as any); + expect((result.matrixify_mode_rows as any)?.value).toBe('dimensions'); + expect((result.matrixify_mode_columns as any)?.value).toBe('metrics'); + expect((result.matrixify_enable as any)?.value).toBe(true); +}); + +test('getControlsState resets modes when old per-axis flags are explicitly false', () => { + const state = buildExploreState(); + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_enable_vertical_layout: false, + matrixify_enable_horizontal_layout: false, + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + }; + + const result = getControlsState(state as any, formData as any); + // Old flags present but false — chart never used matrixify, reset stale modes + expect((result.matrixify_mode_rows as any)?.value).toBe('disabled'); + expect((result.matrixify_mode_columns as any)?.value).toBe('disabled'); +}); + +// ============================================================ +// P2: Dashboard hydration (applyDefaultFormData) with old per-axis flags +// ============================================================ + +test('applyDefaultFormData preserves modes when old vertical flag is true', () => { + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_enable_vertical_layout: true, + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + }; + + const outputFormData = applyDefaultFormData(formData as any); + expect(outputFormData.matrixify_mode_rows).toBe('dimensions'); + expect(outputFormData.matrixify_enable).toBe(true); + // Horizontal not enabled — columns reset + expect(outputFormData.matrixify_mode_columns).toBe('disabled'); +}); + +test('applyDefaultFormData preserves modes when both old flags are true', () => { + const formData = { + datasource: '1__table', + viz_type: 'test-chart', + matrixify_enable_vertical_layout: true, + matrixify_enable_horizontal_layout: true, + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + }; + + const outputFormData = applyDefaultFormData(formData as any); + expect(outputFormData.matrixify_mode_rows).toBe('dimensions'); + expect(outputFormData.matrixify_mode_columns).toBe('metrics'); + expect(outputFormData.matrixify_enable).toBe(true); +}); + +// ============================================================ +// Direct handleDeprecatedControls tests: verify form_data mutation +// so callers (hydrateExplore) can propagate migrated fields into state +// ============================================================ + +test('handleDeprecatedControls sets matrixify_enable on form_data when old vertical flag is true', () => { + const formData: any = { + matrixify_enable_vertical_layout: true, + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + }; + handleDeprecatedControls(formData); + + expect(formData.matrixify_enable).toBe(true); + expect(formData.matrixify_mode_rows).toBe('dimensions'); + // Horizontal not enabled — columns reset + expect(formData.matrixify_mode_columns).toBe('disabled'); +}); + +test('handleDeprecatedControls resets modes when no matrixify_enable and no old flags', () => { + const formData: any = { + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + }; + handleDeprecatedControls(formData); + + expect(formData.matrixify_enable).toBeUndefined(); + expect(formData.matrixify_mode_rows).toBe('disabled'); + expect(formData.matrixify_mode_columns).toBe('disabled'); +}); + +test('handleDeprecatedControls is idempotent — no-op when matrixify_enable already present', () => { + const formData: any = { + matrixify_enable: true, + matrixify_mode_rows: 'dimensions', + matrixify_mode_columns: 'metrics', + }; + handleDeprecatedControls(formData); + + // No mutation — matrixify_enable key is present + expect(formData.matrixify_enable).toBe(true); + expect(formData.matrixify_mode_rows).toBe('dimensions'); + expect(formData.matrixify_mode_columns).toBe('metrics'); +}); diff --git a/superset-frontend/src/explore/store.ts b/superset-frontend/src/explore/store.ts index b1189efff44..79b5826df03 100644 --- a/superset-frontend/src/explore/store.ts +++ b/superset-frontend/src/explore/store.ts @@ -41,9 +41,16 @@ type FormData = QueryFormData & { y_axis_zero?: boolean; y_axis_bounds?: [number | null, number | null]; datasource?: string; + matrixify_enable?: boolean; + matrixify_mode_rows?: string; + matrixify_mode_columns?: string; + // Pre-revamp per-axis enable flags (removed in #38519, may still exist in + // persisted form_data for charts that actually used matrixify) + matrixify_enable_vertical_layout?: boolean; + matrixify_enable_horizontal_layout?: boolean; }; -function handleDeprecatedControls(formData: FormData): void { +export function handleDeprecatedControls(formData: FormData): void { // Reaffectation / handling of deprecated controls /* eslint-disable no-param-reassign */ @@ -51,6 +58,37 @@ function handleDeprecatedControls(formData: FormData): void { if (formData.y_axis_zero) { formData.y_axis_bounds = [0, null]; } + + // #38519: migrate pre-revamp matrixify controls to the new single-toggle + // system. Before the revamp, per-axis enable flags + // (matrixify_enable_vertical_layout / matrixify_enable_horizontal_layout) + // gated visibility, and matrixify_mode_rows/columns defaulted to + // non-disabled values ('dimensions'/'metrics'). The revamp replaced those + // with a single matrixify_enable toggle and mode default 'disabled'. + // + // Charts that actually used matrixify pre-revamp have the old per-axis + // flags set to true — we must preserve their modes and set + // matrixify_enable: true. Charts that never used matrixify (or predate it) + // need stale mode defaults reset to 'disabled' because 4 downstream UI + // consumers (ExploreChartPanel, ChartContextMenu, DrillBySubmenu, + // ChartRenderer) infer "matrixify is active" from mode values alone. + if (!('matrixify_enable' in formData)) { + const hadVerticalLayout = + formData.matrixify_enable_vertical_layout === true; + const hadHorizontalLayout = + formData.matrixify_enable_horizontal_layout === true; + + if (hadVerticalLayout || hadHorizontalLayout) { + // Pre-revamp chart that genuinely used matrixify — migrate to new flag + formData.matrixify_enable = true; + if (!hadVerticalLayout) formData.matrixify_mode_rows = 'disabled'; + if (!hadHorizontalLayout) formData.matrixify_mode_columns = 'disabled'; + } else { + // Never used matrixify — reset stale defaults + formData.matrixify_mode_rows = 'disabled'; + formData.matrixify_mode_columns = 'disabled'; + } + } } export function getControlsState( @@ -89,25 +127,31 @@ export function getControlsState( export function applyDefaultFormData( inputFormData: FormData, ): Record { - const datasourceType = inputFormData.datasource?.split('__')[1] ?? ''; - const vizType = inputFormData.viz_type; + // Normalize deprecated controls before building control state — ensures + // stale matrixify modes are cleaned on the dashboard hydration path too, + // not just the explore path (getControlsState). + const cleanedFormData = { ...inputFormData }; + handleDeprecatedControls(cleanedFormData); + + const datasourceType = cleanedFormData.datasource?.split('__')[1] ?? ''; + const vizType = cleanedFormData.viz_type; const controlsState = getAllControlsState( vizType, datasourceType as DatasourceType, null, - inputFormData, + cleanedFormData, ); // eslint-disable-next-line @typescript-eslint/no-explicit-any const controlFormData = getFormDataFromControls(controlsState as any); const formData: Record = {}; Object.keys(controlsState) - .concat(Object.keys(inputFormData)) + .concat(Object.keys(cleanedFormData)) .forEach(controlName => { - if (inputFormData[controlName as keyof FormData] === undefined) { + if (cleanedFormData[controlName as keyof FormData] === undefined) { formData[controlName] = controlFormData[controlName]; } else { - formData[controlName] = inputFormData[controlName as keyof FormData]; + formData[controlName] = cleanedFormData[controlName as keyof FormData]; } }); diff --git a/superset-frontend/src/explore/types.ts b/superset-frontend/src/explore/types.ts index d1420fbb3fd..72b5e239809 100644 --- a/superset-frontend/src/explore/types.ts +++ b/superset-frontend/src/explore/types.ts @@ -71,6 +71,8 @@ export type OptionSortType = Partial< export type Datasource = Dataset & { database?: DatabaseObject; + /** The parent resource that owns this datasource (database or semantic layer). */ + parent?: { name: string }; datasource?: string; catalog?: string | null; schema?: string; @@ -131,6 +133,9 @@ export interface ExplorePageState { standalone: boolean; force: boolean; common: JsonObject; + compatibleMetrics?: string[] | null; + compatibleDimensions?: string[] | null; + compatibilityLoading?: boolean; }; sliceEntities?: JsonObject; // propagated from Dashboard view } diff --git a/superset-frontend/src/features/alerts/AlertReportModal.tsx b/superset-frontend/src/features/alerts/AlertReportModal.tsx index fc3f3ce5fc0..ee300a5380b 100644 --- a/superset-frontend/src/features/alerts/AlertReportModal.tsx +++ b/superset-frontend/src/features/alerts/AlertReportModal.tsx @@ -1156,7 +1156,13 @@ const AlertReportModal: FunctionComponent = ({ addDangerToast(t('There was an error retrieving dashboard tabs.')); }); } - }, [dashboard, tabsEnabled, filtersEnabled, currentAlert?.extra, addDangerToast]); + }, [ + dashboard, + tabsEnabled, + filtersEnabled, + currentAlert?.extra, + addDangerToast, + ]); const databaseLabel = currentAlert?.database && !currentAlert.database.label; useEffect(() => { diff --git a/superset-frontend/src/features/alerts/components/NotificationMethod.tsx b/superset-frontend/src/features/alerts/components/NotificationMethod.tsx index e7f69a5c7c8..72b19c2cbc2 100644 --- a/superset-frontend/src/features/alerts/components/NotificationMethod.tsx +++ b/superset-frontend/src/features/alerts/components/NotificationMethod.tsx @@ -100,7 +100,7 @@ const StyledNotificationMethod = styled.div` margin-left: ${theme.sizeUnit * 4}px; } - .ghost-button:first-child[style*='none'] + .ghost-button { + .ghost-button:first-of-type[style*='none'] + .ghost-button { margin-left: 0px; /* Remove margin when the first button is hidden */ } `} diff --git a/superset-frontend/src/features/charts/ChartCard.tsx b/superset-frontend/src/features/charts/ChartCard.tsx index 3d48207aa2d..47562c84450 100644 --- a/superset-frontend/src/features/charts/ChartCard.tsx +++ b/superset-frontend/src/features/charts/ChartCard.tsx @@ -34,6 +34,8 @@ import Chart from 'src/types/Chart'; import { FacePile } from 'src/components'; import { handleChartDelete, CardStyles } from 'src/views/CRUD/utils'; import { assetUrl } from 'src/utils/assetUrl'; +import type { ListViewFetchDataConfig as FetchDataConfig } from 'src/components'; +import { TableTab } from 'src/views/CRUD/types'; interface ChartCardProps { chart: Chart; @@ -42,7 +44,7 @@ interface ChartCardProps { bulkSelectEnabled: boolean; addDangerToast: (msg: string) => void; addSuccessToast: (msg: string) => void; - refreshData: () => void; + refreshData: (config?: FetchDataConfig | null) => void; loading?: boolean; saveFavoriteStatus: (id: number, isStarred: boolean) => void; favoriteStatus: boolean; @@ -50,6 +52,7 @@ interface ChartCardProps { userId?: string | number; showThumbnails?: boolean; handleBulkChartExport: (chartsToExport: Chart[]) => void; + getData?: (tab: TableTab) => void; } export default function ChartCard({ @@ -67,6 +70,7 @@ export default function ChartCard({ chartFilter, userId, handleBulkChartExport, + getData, }: ChartCardProps) { const history = useHistory(); const canEdit = hasPerm('can_write'); @@ -136,6 +140,7 @@ export default function ChartCard({ refreshData, chartFilter, userId, + getData, ) } > diff --git a/superset-frontend/src/features/cssTemplates/CssTemplateModal.test.tsx b/superset-frontend/src/features/cssTemplates/CssTemplateModal.test.tsx new file mode 100644 index 00000000000..96b812c59b6 --- /dev/null +++ b/superset-frontend/src/features/cssTemplates/CssTemplateModal.test.tsx @@ -0,0 +1,104 @@ +/** + * 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 { useState } from 'react'; +import { render, screen, waitFor } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import fetchMock from 'fetch-mock'; +import CssTemplateModal from './CssTemplateModal'; +import { TemplateObject } from './types'; + +const mockTemplate: TemplateObject = { + id: 1, + template_name: 'Existing Template', + css: '.existing { color: red; }', +}; + +beforeEach(() => { + fetchMock.clearHistory().removeRoutes(); + fetchMock.get('glob:*/api/v1/css_template/1', { result: mockTemplate }); +}); + +afterEach(() => { + fetchMock.removeRoutes(); +}); + +// The Ace editor renders with the DOM id supplied via the editor's `id` prop +// (forwarded to react-ace as `name`). The CSS template modal uses +// id="css-template-editor". +const aceEditorSelector = '#css-template-editor.ace_editor'; + +test('renders the CSS editor field in Edit mode (guard for #38563)', async () => { + render( + {}} cssTemplate={mockTemplate} />, + { useRedux: true, useTheme: true }, + ); + + expect(screen.getByText('css')).toBeInTheDocument(); + await waitFor(() => { + expect(document.querySelector(aceEditorSelector)).toBeInTheDocument(); + }); +}); + +test('renders the CSS editor field in Add mode', async () => { + render( {}} />, { + useRedux: true, + useTheme: true, + }); + + expect(await screen.findByText('Add CSS template')).toBeInTheDocument(); + expect(screen.getByText('css')).toBeInTheDocument(); + await waitFor(() => { + expect(document.querySelector(aceEditorSelector)).toBeInTheDocument(); + }); +}); + +test('renders the editor after closed (Add) -> open (Edit) transition', async () => { + // Mirrors src/pages/CssTemplateList/index.tsx, where the modal is mounted + // up-front with show=false and cssTemplate=null, then both flip together + // when the user clicks the Edit row action. + function Harness() { + const [show, setShow] = useState(false); + const [tpl, setTpl] = useState(null); + return ( + <> + + setShow(false)} + /> + + ); + } + + render(, { useRedux: true, useTheme: true }); + await userEvent.click(screen.getByText('open')); + await waitFor(() => { + expect(document.querySelector(aceEditorSelector)).toBeInTheDocument(); + }); +}); diff --git a/superset-frontend/src/features/databases/DatabaseModal/index.test.tsx b/superset-frontend/src/features/databases/DatabaseModal/index.test.tsx index 2cc9fbe1a87..455c4740a26 100644 --- a/superset-frontend/src/features/databases/DatabaseModal/index.test.tsx +++ b/superset-frontend/src/features/databases/DatabaseModal/index.test.tsx @@ -643,15 +643,15 @@ describe('DatabaseModal', () => { name: /sqlite/i, }), ); + expect(await screen.findByText(/step 2 of 2/i)).toBeInTheDocument(); // Click the "Advanced" tab - userEvent.click(await screen.findByRole('tab', { name: /advanced/i })); + userEvent.click(screen.getByRole('tab', { name: /advanced/i })); // Click the "SQL Lab" tab userEvent.click(screen.getByTestId('sql-lab-label-test')); - expect(await screen.findByText(/step 2 of 2/i)).toBeInTheDocument(); // ----- BEGIN STEP 2 (ADVANCED - SQL LAB) // - AntD header - const closeButton = await screen.findByRole('button', { name: /close/i }); + const closeButton = screen.getByRole('button', { name: /close/i }); const advancedHeader = screen.getByRole('heading', { name: /connect a database/i, }); @@ -666,10 +666,8 @@ describe('DatabaseModal', () => { }); // - Basic/Advanced tabs const basicTab = screen.getByRole('tab', { name: /basic/i }); - const advancedTab = await screen.findByRole('tab', { name: /advanced/i }); - const advancedTabPanel = await screen.findByRole('tabpanel', { - name: /advanced/i, - }); + const advancedTab = screen.getByRole('tab', { name: /advanced/i }); + const advancedTabPanel = screen.getAllByRole('tabpanel')[0]; // - Advanced tabs const sqlLabTab = screen.getByTestId('sql-lab-label-test'); // These are the checkbox SVGs that cover the actual checkboxes diff --git a/superset-frontend/src/features/databases/DatabaseModal/index.tsx b/superset-frontend/src/features/databases/DatabaseModal/index.tsx index 0919941938a..1fa38c5e152 100644 --- a/superset-frontend/src/features/databases/DatabaseModal/index.tsx +++ b/superset-frontend/src/features/databases/DatabaseModal/index.tsx @@ -35,7 +35,6 @@ import { CheckboxChangeEvent } from '@superset-ui/core/components/Checkbox/types import { useHistory } from 'react-router-dom'; import { setItem, LocalStorageKeys } from 'src/utils/localStorageHelpers'; -import { makeUrl } from 'src/utils/pathUtils'; import Tabs from '@superset-ui/core/components/Tabs'; import { Button, @@ -1824,7 +1823,9 @@ const DatabaseModal: FunctionComponent = ({ onClick={() => { setLoading(true); fetchAndSetDB(); - redirectURL(makeUrl(`/sqllab?db=true`)); + // redirectURL() delegates to history.push; React Router's basename + // already prefixes the application root, so pass a relative path. + redirectURL('/sqllab?db=true'); }} > {t('Query data in SQL Lab')} diff --git a/superset-frontend/src/features/databases/DatabaseModal/styles.ts b/superset-frontend/src/features/databases/DatabaseModal/styles.ts index c8e37d93412..8aa9aa16ec2 100644 --- a/superset-frontend/src/features/databases/DatabaseModal/styles.ts +++ b/superset-frontend/src/features/databases/DatabaseModal/styles.ts @@ -293,10 +293,17 @@ export const StyledInputContainer = styled.div` `} `; +// Named-reference type annotation: TypeScript 6.0 declaration emit (TS2883) +// won't let us leak react-ace's IAceOptions/ICommand/IEditorProps/IMarker +// through the inferred type because they live in @superset-ui/core's nested +// node_modules and aren't portable. Aliasing to `typeof JsonEditor` emits a +// named reference in the .d.ts instead of the expanded structural type. +// The styled-components and ForwardRefExoticComponent shapes don't overlap +// structurally, so we bounce through `unknown` to widen the cast. export const StyledJsonEditor = styled(JsonEditor)` flex: 1 1 auto; /* Border is already applied by AceEditor itself */ -`; +` as unknown as typeof JsonEditor; export const StyledExpandableForm = styled.div` padding-top: ${({ theme }) => theme.sizeUnit}px; diff --git a/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/DatasetPanelWrapper.test.tsx b/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/DatasetPanelWrapper.test.tsx new file mode 100644 index 00000000000..66d02d22874 --- /dev/null +++ b/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/DatasetPanelWrapper.test.tsx @@ -0,0 +1,59 @@ +/** + * 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 { render, waitFor } from 'spec/helpers/testing-library'; +import { SupersetClient } from '@superset-ui/core'; +import DatasetPanelWrapper from 'src/features/datasets/AddDataset/DatasetPanel'; + +jest.mock( + '@superset-ui/core/components/Icons/AsyncIcon', + () => + ({ fileName }: { fileName: string }) => ( + + ), +); + +afterEach(() => { + jest.restoreAllMocks(); +}); + +test('fetches table metadata for schema-less database without schema', async () => { + const getSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({ + json: { + name: 'my_table', + columns: [{ name: 'id', type: 'INTEGER', longType: 'INTEGER' }], + }, + } as any); + + render( + , + { useRouter: true }, + ); + + await waitFor(() => { + expect(getSpy).toHaveBeenCalledWith( + expect.objectContaining({ + endpoint: expect.stringContaining('/api/v1/database/1/table_metadata/'), + }), + ); + }); +}); diff --git a/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/index.tsx b/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/index.tsx index 661650b720c..f41ee9020fc 100644 --- a/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/index.tsx +++ b/superset-frontend/src/features/datasets/AddDataset/DatasetPanel/index.tsx @@ -22,6 +22,7 @@ import { SupersetClient } from '@superset-ui/core'; import { logging } from '@apache-superset/core/utils'; import { DatasetObject } from 'src/features/datasets/AddDataset/types'; import { addDangerToast } from 'src/components/MessageToasts/actions'; +import { type DatabaseObject } from 'src/components'; import { toQueryString } from 'src/utils/urlUtils'; import DatasetPanel from './DatasetPanel'; import { ITableColumn, IDatabaseTable, isIDatabaseTable } from './types'; @@ -39,9 +40,9 @@ interface IColumnProps { */ tableName: string; /** - * Name of the schema + * Name of the schema (optional for databases that don't support schemas) */ - schema: string; + schema?: string | null; } export interface IDatasetPanelWrapperProps { @@ -58,6 +59,10 @@ export interface IDatasetPanelWrapperProps { */ catalog?: string | null; schema?: string | null; + /** + * The selected database object (used to check engine capabilities) + */ + database?: Partial | null; setHasColumns?: Function; datasets?: DatasetObject[] | undefined; } @@ -67,6 +72,7 @@ const DatasetPanelWrapper = ({ dbId, catalog, schema, + database, setHasColumns, datasets, }: IDatasetPanelWrapperProps) => { @@ -128,12 +134,13 @@ const DatasetPanelWrapper = ({ useEffect(() => { tableNameRef.current = tableName; - if (tableName && schema && dbId) { - getTableMetadata({ tableName, dbId, schema }); + const schemaRequired = database?.supports_schemas !== false; + if (tableName && dbId && (schema || !schemaRequired)) { + getTableMetadata({ tableName, dbId, schema: schema || undefined }); } // getTableMetadata is a const and should not be in dependency array // eslint-disable-next-line react-hooks/exhaustive-deps - }, [tableName, dbId, schema]); + }, [tableName, dbId, schema, database]); return ( { expect(result.current.datasetNames).toEqual([]); }); +test('useDatasetsList fetches datasets for schema-less databases without schema filter', async () => { + const schemalessDb = { + id: 2, + database_name: 'ydb', + owners: [1] as [number], + supports_schemas: false, + }; + + const getSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({ + json: { + count: 1, + result: [{ id: 10, table_name: 'my_table', schema: null }], + }, + } as unknown as JsonResponse); + + const { result } = renderHook(() => useDatasetsList(schemalessDb, null)); + + await waitFor(() => { + expect(result.current.datasets).toHaveLength(1); + }); + + expect(result.current.datasetNames).toEqual(['my_table']); + expect(getSpy).toHaveBeenCalledTimes(1); + + // Verify the API was called without a schema filter + const callArg = getSpy.mock.calls[0]?.[0]?.endpoint; + expect(callArg).toBeDefined(); + + const risonParam = new URL(callArg!, 'http://localhost').searchParams.get( + 'q', + ); + expect(risonParam).toBeTruthy(); + const decoded = rison.decode(risonParam!) as { + filters: Array<{ col: string; opr: string; value: unknown }>; + }; + + // Only database filter and sql filter — no schema filter + const schemaFilter = decoded.filters.find(f => f.col === 'schema'); + expect(schemaFilter).toBeUndefined(); + + const dbFilter = decoded.filters.find(f => f.col === 'database'); + expect(dbFilter).toEqual({ col: 'database', opr: 'rel_o_m', value: 2 }); +}); + +test('useDatasetsList skips fetching when schema-less database id is undefined', () => { + const getSpy = jest.spyOn(SupersetClient, 'get'); + + const schemalessDb = { + database_name: 'ydb', + owners: [1] as [number], + supports_schemas: false, + } as typeof mockDb & { supports_schemas: boolean }; + + const { result } = renderHook(() => useDatasetsList(schemalessDb, null)); + + // No db.id — should NOT call API even for schema-less DB + expect(getSpy).not.toHaveBeenCalled(); + expect(result.current.datasets).toEqual([]); +}); + test('useDatasetsList encodes schemas with spaces and special characters in endpoint URL', async () => { const getSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({ json: { count: 0, result: [] }, diff --git a/superset-frontend/src/features/datasets/hooks/useDatasetLists.ts b/superset-frontend/src/features/datasets/hooks/useDatasetLists.ts index 96241fe5b61..b2f925b1759 100644 --- a/superset-frontend/src/features/datasets/hooks/useDatasetLists.ts +++ b/superset-frontend/src/features/datasets/hooks/useDatasetLists.ts @@ -37,7 +37,8 @@ const useDatasetsList = ( schema: string | null | undefined, ) => { const [datasets, setDatasets] = useState([]); - const encodedSchema = schema ? encodeURIComponent(schema) : undefined; + const supportsSchemas = db?.supports_schemas !== false; + const encodedSchema = schema ? encodeURIComponent(schema) : null; const getDatasetsList = useCallback(async (filters: object[]) => { let results: DatasetObject[] = []; @@ -77,14 +78,16 @@ const useDatasetsList = ( useEffect(() => { const filters = [ { col: 'database', opr: 'rel_o_m', value: db?.id }, - { col: 'schema', opr: 'eq', value: encodedSchema }, + ...(supportsSchemas + ? [{ col: 'schema', opr: 'eq', value: encodedSchema }] + : []), { col: 'sql', opr: 'dataset_is_null_or_empty', value: true }, ]; - if (schema && db?.id !== undefined) { + if (db?.id !== undefined && (schema || !supportsSchemas)) { getDatasetsList(filters); } - }, [db?.id, schema, encodedSchema, getDatasetsList]); + }, [db?.id, schema, encodedSchema, supportsSchemas, getDatasetsList]); const datasetNames = useMemo( () => datasets?.map(dataset => dataset.table_name), diff --git a/superset-frontend/src/features/datasets/metadataBar/useDatasetMetadataBar.test.tsx b/superset-frontend/src/features/datasets/metadataBar/useDatasetMetadataBar.test.tsx index 6be5603cea2..a5999c545b8 100644 --- a/superset-frontend/src/features/datasets/metadataBar/useDatasetMetadataBar.test.tsx +++ b/superset-frontend/src/features/datasets/metadataBar/useDatasetMetadataBar.test.tsx @@ -18,7 +18,7 @@ */ import fetchMock from 'fetch-mock'; -import { renderHook } from '@testing-library/react-hooks'; +import { renderHook } from '@testing-library/react'; import { createWrapper, render } from 'spec/helpers/testing-library'; import { supersetGetCache } from 'src/utils/cachedSupersetGet'; import { useDatasetMetadataBar } from './useDatasetMetadataBar'; diff --git a/superset-frontend/src/features/home/ActivityTable.tsx b/superset-frontend/src/features/home/ActivityTable.tsx index 52a3714b6bf..e71006a3adb 100644 --- a/superset-frontend/src/features/home/ActivityTable.tsx +++ b/superset-frontend/src/features/home/ActivityTable.tsx @@ -126,19 +126,28 @@ export default function ActivityTable({ const [editedCards, setEditedCards] = useState(); const [isFetchingEditedCards, setIsFetchingEditedCards] = useState(false); - const getEditedCards = () => { - setIsFetchingEditedCards(true); - getEditedObjects(user.userId).then(r => { - setEditedCards([...r.editedChart, ...r.editedDash]); - setIsFetchingEditedCards(false); - }); - }; - useEffect(() => { + let isMounted = true; + if (activeChild === TableTab.Edited) { - getEditedCards(); + setIsFetchingEditedCards(true); + getEditedObjects(user.userId).then(r => { + if (!isMounted) return; + // `getEditedObjects` swallows errors via `.catch(err => err)` and + // returns the raw error object, which has no `editedChart` / + // `editedDash` arrays. Guard against that so spreading can't throw. + const editedChart = Array.isArray(r?.editedChart) ? r.editedChart : []; + const editedDash = Array.isArray(r?.editedDash) ? r.editedDash : []; + setEditedCards([...editedChart, ...editedDash]); + setIsFetchingEditedCards(false); + }); } - }, [activeChild]); + + return () => { + isMounted = false; + setIsFetchingEditedCards(false); + }; + }, [activeChild, user.userId]); const tabs = [ { diff --git a/superset-frontend/src/features/home/ChartTable.test.tsx b/superset-frontend/src/features/home/ChartTable.test.tsx index 4425fe696a7..22e4cf9517b 100644 --- a/superset-frontend/src/features/home/ChartTable.test.tsx +++ b/superset-frontend/src/features/home/ChartTable.test.tsx @@ -26,6 +26,7 @@ import { VizType } from '@superset-ui/core'; import fetchMock from 'fetch-mock'; import { act } from 'react-dom/test-utils'; import handleResourceExport from 'src/utils/export'; +import { LocalStorageKeys } from 'src/utils/localStorageHelpers'; import ChartTable from './ChartTable'; // Mock the export module @@ -53,12 +54,16 @@ const mockCharts = Array.from({ length: 3 }).map((_, i) => ({ thumbnail_url: '', })); -fetchMock.get(chartsEndpoint, { - result: mockCharts, -}); +fetchMock.get( + chartsEndpoint, + { + result: mockCharts, + }, + { name: chartsEndpoint }, +); fetchMock.get(chartsInfoEndpoint, { - permissions: ['can_add', 'can_edit', 'can_delete', 'can_export'], + permissions: ['can_add', 'can_write', 'can_delete', 'can_export'], }); fetchMock.get(chartFavoriteStatusEndpoint, { @@ -99,6 +104,10 @@ const renderChartTable = (props: any) => render(, renderOptions); }); +beforeEach(() => { + window.localStorage.removeItem(LocalStorageKeys.HomepageChartFilter); +}); + test('renders with EmptyState if no data present', async () => { await renderChartTable(mockedProps); expect(screen.getAllByRole('tab')).toHaveLength(3); @@ -178,3 +187,58 @@ test('handles chart export with correct ID and shows spinner', async () => { { timeout: 3000 }, ); }); + +test('refreshes other tab data after deleting a chart', async () => { + fetchMock.removeRoute(chartsEndpoint); + fetchMock.get( + chartsEndpoint, + { + result: mockCharts.slice(1), + count: mockCharts.length - 1, + }, + { name: chartsEndpoint }, + ); + fetchMock.delete('glob:*/api/v1/chart/0', { + message: 'Chart deleted', + }); + + await renderChartTable({ + ...otherTabProps, + otherTabTitle: 'All', + }); + + expect(screen.getByText('cool chart 0')).toBeInTheDocument(); + + const refreshCallsBeforeDelete = + fetchMock.callHistory.calls(chartsEndpoint).length; + + const moreButtons = screen.getAllByRole('img', { name: /more/i }); + await userEvent.click(moreButtons[0]); + + await userEvent.click(await screen.findByText('Delete')); + + const deleteInput = screen.getByTestId('delete-modal-input'); + await userEvent.type(deleteInput, 'DELETE'); + await userEvent.click(screen.getByTestId('modal-confirm-button')); + + await waitFor(() => { + expect( + fetchMock.callHistory.calls(/api\/v1\/chart\/0/, { + method: 'DELETE', + }), + ).toHaveLength(1); + }); + + await waitFor(() => { + expect(fetchMock.callHistory.calls(chartsEndpoint).length).toBe( + refreshCallsBeforeDelete + 1, + ); + }); + + await waitFor(() => { + expect(screen.queryByText('cool chart 0')).not.toBeInTheDocument(); + }); + + expect(screen.getByText('cool chart 1')).toBeInTheDocument(); + expect(screen.getByText('cool chart 2')).toBeInTheDocument(); +}); diff --git a/superset-frontend/src/features/home/ChartTable.tsx b/superset-frontend/src/features/home/ChartTable.tsx index 013128f71c8..37d594c7c50 100644 --- a/superset-frontend/src/features/home/ChartTable.tsx +++ b/superset-frontend/src/features/home/ChartTable.tsx @@ -112,18 +112,19 @@ function ChartTable({ const [preparingExport, setPreparingExport] = useState(false); const [loaded, setLoaded] = useState(false); - const getData = (tab: TableTab) => - fetchData({ - pageIndex: 0, - pageSize: PAGE_SIZE, - sortBy: [ - { - id: 'changed_on_delta_humanized', - desc: true, - }, - ], - filters: getFilterValues(tab, WelcomeTable.Charts, user, otherTabFilters), - }); + const getChartFetchDataConfig = (tab: TableTab) => ({ + pageIndex: 0, + pageSize: PAGE_SIZE, + sortBy: [ + { + id: 'changed_on_delta_humanized', + desc: true, + }, + ], + filters: getFilterValues(tab, WelcomeTable.Charts, user, otherTabFilters), + }); + + const getData = (tab: TableTab) => fetchData(getChartFetchDataConfig(tab)); useEffect(() => { if (loaded || activeTab === TableTab.Favorite) { @@ -234,6 +235,7 @@ function ChartTable({ refreshData={refreshData} addDangerToast={addDangerToast} addSuccessToast={addSuccessToast} + getData={getData} favoriteStatus={favoriteStatus[e.id]} saveFavoriteStatus={saveFavoriteStatus} handleBulkChartExport={handleBulkChartExport} diff --git a/superset-frontend/src/features/home/EmptyState.tsx b/superset-frontend/src/features/home/EmptyState.tsx index 119fd6596ce..436f8181f5b 100644 --- a/superset-frontend/src/features/home/EmptyState.tsx +++ b/superset-frontend/src/features/home/EmptyState.tsx @@ -24,7 +24,6 @@ import { TableTab } from 'src/views/CRUD/types'; import { t } from '@apache-superset/core/translation'; import { styled } from '@apache-superset/core/theme'; import { navigateTo } from 'src/utils/navigationUtils'; -import { makeUrl } from 'src/utils/pathUtils'; import { WelcomeTable } from './types'; const EmptyContainer = styled.div` @@ -59,7 +58,9 @@ const REDIRECTS = { create: { [WelcomeTable.Charts]: '/chart/add', [WelcomeTable.Dashboards]: '/dashboard/new', - [WelcomeTable.SavedQueries]: makeUrl('/sqllab?new=true'), + // navigateTo() applies the application root internally; keep this + // relative so the prefix isn't added twice. + [WelcomeTable.SavedQueries]: '/sqllab?new=true', }, viewAll: { [WelcomeTable.Charts]: '/chart/list', diff --git a/superset-frontend/src/features/home/Menu.tsx b/superset-frontend/src/features/home/Menu.tsx index 1849e8a2e2d..06d606cc6a4 100644 --- a/superset-frontend/src/features/home/Menu.tsx +++ b/superset-frontend/src/features/home/Menu.tsx @@ -18,6 +18,7 @@ */ import { useState, useEffect } from 'react'; import { styled, css, useTheme } from '@apache-superset/core/theme'; +import { t } from '@apache-superset/core/translation'; import { ensureStaticPrefix } from 'src/utils/assetUrl'; import { ensureAppRoot } from 'src/utils/pathUtils'; import { getUrlParam } from 'src/utils/urlUtils'; @@ -34,6 +35,7 @@ import { MenuObjectProps, MenuData, } from 'src/types/bootstrapTypes'; +import { datasetsLabel } from 'src/features/semanticLayers/label'; import RightMenu from './RightMenu'; import { NAVBAR_MENU_POPUP_OFFSET } from './commonMenuData'; @@ -222,7 +224,7 @@ export function Menu({ setActiveTabs(['Charts']); break; case path.startsWith(Paths.Datasets): - setActiveTabs(['Datasets']); + setActiveTabs([datasetsLabel()]); break; case path.startsWith(Paths.SqlLab) || path.startsWith(Paths.SavedQueries): setActiveTabs(['SQL']); @@ -334,7 +336,12 @@ export function Menu({ return <>{link}; }; return ( - + string> = { + Datasets: datasetsLabel, + }; + // Cycle through menu.menu to build out cleanedMenu and settings const cleanedMenu: MenuObjectProps[] = []; const settings: MenuObjectProps[] = []; @@ -413,6 +426,10 @@ export default function MenuWrapper({ data, ...rest }: MenuProps) { const children: (MenuObjectProps | string)[] = []; const newItem = { ...item, + // Apply any label override for this item (keyed by FAB internal name). + ...(item.name && labelOverrides[item.name] + ? { label: labelOverrides[item.name]() } + : {}), }; // Filter childs diff --git a/superset-frontend/src/features/home/RightMenu.test.tsx b/superset-frontend/src/features/home/RightMenu.test.tsx index 4c15c585ad6..b62ce4439d7 100644 --- a/superset-frontend/src/features/home/RightMenu.test.tsx +++ b/superset-frontend/src/features/home/RightMenu.test.tsx @@ -377,11 +377,12 @@ test('If there is NOT a DB with allow_file_upload set as True the option should await userEvent.hover(dropdown); const dataMenu = await screen.findByText(dropdownItems[0].label); await userEvent.hover(dataMenu); - const csvMenu = await screen.findByRole('menuitem', { - name: 'Upload CSV to database', - }); + const csvMenu = await screen.findByText('Upload CSV to database'); expect(csvMenu).toBeInTheDocument(); - expect(csvMenu).toHaveAttribute('aria-disabled', 'true'); + expect(csvMenu.closest('li[role="menuitem"]')).toHaveAttribute( + 'aria-disabled', + 'true', + ); }); test('Logs out and clears local storage item redux', async () => { diff --git a/superset-frontend/src/features/home/RightMenu.tsx b/superset-frontend/src/features/home/RightMenu.tsx index 28c25498642..6462c1c588b 100644 --- a/superset-frontend/src/features/home/RightMenu.tsx +++ b/superset-frontend/src/features/home/RightMenu.tsx @@ -44,7 +44,7 @@ import { TelemetryPixel, } from '@superset-ui/core/components'; import type { ItemType, MenuItem } from '@superset-ui/core/components/Menu'; -import { ensureAppRoot, makeUrl } from 'src/utils/pathUtils'; +import { ensureAppRoot } from 'src/utils/pathUtils'; import { isEmbedded } from 'src/dashboard/util/isEmbedded'; import { findPermission } from 'src/utils/findPermission'; import { isUserAdmin } from 'src/dashboard/util/permissionUtils'; @@ -213,7 +213,10 @@ const RightMenu = ({ }, { label: t('SQL query'), - url: makeUrl('/sqllab?new=true'), + // Keep the URL relative so isFrontendRoute() matches and Link navigates + // via React Router; the fallback applies ensureAppRoot + // exactly once for non-frontend routes. + url: '/sqllab?new=true', icon: , perm: 'can_sqllab', view: 'Superset', diff --git a/superset-frontend/src/features/home/SubMenu.tsx b/superset-frontend/src/features/home/SubMenu.tsx index f71892fb501..9c2e2c451eb 100644 --- a/superset-frontend/src/features/home/SubMenu.tsx +++ b/superset-frontend/src/features/home/SubMenu.tsx @@ -28,7 +28,7 @@ import { } from '@apache-superset/core/theme'; import cx from 'classnames'; import { debounce } from 'lodash'; -import { Menu, MenuMode, MainNav } from '@superset-ui/core/components/Menu'; +import { Menu, MenuMode } from '@superset-ui/core/components/Menu'; import { Button, Tooltip, @@ -36,7 +36,6 @@ import { type OnClickHandler, } from '@superset-ui/core/components'; import { Icons } from '@superset-ui/core/components/Icons'; -import { IconType } from '@superset-ui/core/components/Icons/types'; import { MenuObjectProps } from 'src/types/bootstrapTypes'; import { Typography } from '@superset-ui/core/components/Typography'; @@ -149,7 +148,8 @@ export interface ButtonProps { 'data-test'?: string; buttonStyle: 'primary' | 'secondary' | 'dashed' | 'link' | 'tertiary'; loading?: boolean; - icon?: IconType; + icon?: ReactNode; + component?: ReactNode; } export interface SubMenuProps { @@ -164,10 +164,9 @@ export interface SubMenuProps { color?: string; dropDownLinks?: Array; backgroundColor?: string; + children?: ReactNode; } -const { SubMenu } = MainNav; - const SubMenuComponent: FunctionComponent = props => { const [showMenu, setMenu] = useState('horizontal'); const [navRightStyle, setNavRightStyle] = useState('nav-right'); @@ -183,7 +182,10 @@ const SubMenuComponent: FunctionComponent = props => { } useEffect(() => { + let isMounted = true; + function handleResize() { + if (!isMounted) return; if (window.innerWidth <= 767) setMenu('inline'); else setMenu('horizontal'); @@ -192,7 +194,6 @@ const SubMenuComponent: FunctionComponent = props => { props.buttons.length >= 3 && window.innerWidth >= 795 ) { - // eslint-disable-next-line no-unused-expressions setNavRightStyle('nav-right'); } else if ( props.buttons && @@ -205,12 +206,16 @@ const SubMenuComponent: FunctionComponent = props => { handleResize(); const resize = debounce(handleResize, 10); window.addEventListener('resize', resize); - return () => window.removeEventListener('resize', resize); + return () => { + isMounted = false; + resize.cancel(); + window.removeEventListener('resize', resize); + }; }, [props.buttons]); return ( - + {props.name &&
{props.name}
} = props => { })} />
- - {props.dropDownLinks?.map((link, i) => ( - ({ + key: `dropdown-${i}`, + label: link.label, + icon: , + popupOffset: [10, 20], + className: 'dropdown-menu-links', + children: link.childs + ?.filter( + (item): item is Exclude => + typeof item === 'object', + ) + .map(item => + item.disable + ? { + key: item.label, + disabled: true, + label: ( + + + {item.label} + + + ), + } + : { + key: item.label, + label: ( + + {item.label} + + ), + }, + ), + }))} + /> + {props.buttons?.map((btn, i) => + btn.component ? ( + {btn.component} + ) : ( + - {props.buttons?.map((btn, i) => ( - - ))} + {btn.name} + + ), + )}
{props.children} diff --git a/superset-frontend/src/features/home/types.ts b/superset-frontend/src/features/home/types.ts index a59e9fcd858..633f0bffcfa 100644 --- a/superset-frontend/src/features/home/types.ts +++ b/superset-frontend/src/features/home/types.ts @@ -17,6 +17,7 @@ * under the License. */ +import { ReactNode } from 'react'; import { Filter } from 'src/views/CRUD/types'; import { NavBarProps, MenuObjectProps } from 'src/types/bootstrapTypes'; @@ -45,6 +46,7 @@ export interface RightMenuProps { text: string; color: string; }; + children?: ReactNode; } export enum GlobalMenuDataOptions { diff --git a/superset-frontend/src/features/reports/ReportModal/HeaderReportDropdown/index.tsx b/superset-frontend/src/features/reports/ReportModal/HeaderReportDropdown/index.tsx index be5c90fcdfd..2481b323bf8 100644 --- a/superset-frontend/src/features/reports/ReportModal/HeaderReportDropdown/index.tsx +++ b/superset-frontend/src/features/reports/ReportModal/HeaderReportDropdown/index.tsx @@ -50,7 +50,7 @@ const StyledDropdownItemWithIcon = styled.div` flex-direction: row; justify-content: space-between; align-items: center; - > *:first-child { + > *:first-of-type { margin-right: ${({ theme }) => theme.sizeUnit}px; } `; diff --git a/superset-frontend/src/features/reports/ReportModal/index.tsx b/superset-frontend/src/features/reports/ReportModal/index.tsx index 425867ced55..061615cf2ff 100644 --- a/superset-frontend/src/features/reports/ReportModal/index.tsx +++ b/superset-frontend/src/features/reports/ReportModal/index.tsx @@ -366,7 +366,7 @@ function ReportModal({ }} onError={setCronError} /> - {cronError} + {cronError?.description}
TimezoneHeaderStyle(theme)} diff --git a/superset-frontend/src/features/reports/ReportModal/styles.tsx b/superset-frontend/src/features/reports/ReportModal/styles.tsx index 14acc3e0012..0b487bd6803 100644 --- a/superset-frontend/src/features/reports/ReportModal/styles.tsx +++ b/superset-frontend/src/features/reports/ReportModal/styles.tsx @@ -67,10 +67,13 @@ export const StyledScheduleTitle = styled.div` } `; +// Named-reference type annotation: TypeScript 6.0 declaration emit (TS2883) +// can't name CronProps from react-js-cron via its nested node_modules path. +// Aliasing to `typeof CronPicker` emits a named reference in the .d.ts. export const StyledCronPicker = styled(CronPicker)` margin-bottom: ${({ theme }) => theme.sizeUnit * 3}px; width: ${({ theme }) => theme.sizeUnit * 120}px; -`; +` as typeof CronPicker; export const StyledCronError = styled.p` color: ${({ theme }) => theme.colorError}; diff --git a/superset-frontend/src/features/roles/RoleListEditModal.test.tsx b/superset-frontend/src/features/roles/RoleListEditModal.test.tsx index 5129b6318ef..b05f946d808 100644 --- a/superset-frontend/src/features/roles/RoleListEditModal.test.tsx +++ b/superset-frontend/src/features/roles/RoleListEditModal.test.tsx @@ -145,6 +145,11 @@ describe('RoleListEditModal', () => { render(); + // Wait for user hydration to complete so setFieldsValue has populated + // the form with the fetched users before submitting. + await screen.findByText('johndoe'); + await screen.findByText('janesmith'); + fireEvent.change(screen.getByTestId('role-name-input'), { target: { value: 'Updated Role' }, }); diff --git a/superset-frontend/src/features/roles/RoleListEditModal.tsx b/superset-frontend/src/features/roles/RoleListEditModal.tsx index 42581ecfe2b..d14f8b9755a 100644 --- a/superset-frontend/src/features/roles/RoleListEditModal.tsx +++ b/superset-frontend/src/features/roles/RoleListEditModal.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { useEffect, useMemo, useRef, useState } from 'react'; +import { ReactNode, useEffect, useMemo, useRef, useState } from 'react'; import { t } from '@apache-superset/core/translation'; import Tabs from '@superset-ui/core/components/Tabs'; import { RoleObject } from 'src/pages/RolesList'; @@ -330,45 +330,47 @@ function RoleListEditModal({ initialValues={initialValues} requiredFields={['roleName']} > - {(form: FormInstance) => { - formRef.current = form; + { + ((form: FormInstance) => { + formRef.current = form; - return ( - setActiveTabKey(activeKey)} - > - setActiveTabKey(activeKey)} > - <> - - + <> + + + + + + + + - - - - - - - - - ); - }} + + + ); + }) as unknown as ReactNode + } ); } diff --git a/superset-frontend/src/features/semanticLayers/SemanticLayerModal.test.tsx b/superset-frontend/src/features/semanticLayers/SemanticLayerModal.test.tsx new file mode 100644 index 00000000000..a3aed93fde7 --- /dev/null +++ b/superset-frontend/src/features/semanticLayers/SemanticLayerModal.test.tsx @@ -0,0 +1,130 @@ +/** + * 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 { SupersetClient } from '@superset-ui/core'; +import { render, waitFor } from 'spec/helpers/testing-library'; + +import SemanticLayerModal from './SemanticLayerModal'; + +let mockJsonFormsChangeTriggered = false; + +jest.mock('@jsonforms/react', () => ({ + ...jest.requireActual('@jsonforms/react'), + JsonForms: ({ onChange }: { onChange: (value: unknown) => void }) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + if (!mockJsonFormsChangeTriggered) { + mockJsonFormsChangeTriggered = true; + onChange({ + data: { warehouse: 'wh1' }, + errors: [], + }); + } + return null; + }, +})); + +jest.mock('@superset-ui/core', () => ({ + ...jest.requireActual('@superset-ui/core'), + SupersetClient: { + ...jest.requireActual('@superset-ui/core').SupersetClient, + get: jest.fn(), + post: jest.fn(), + put: jest.fn(), + }, + getClientErrorObject: jest.fn(() => Promise.resolve({ error: '' })), +})); + +const mockedGet = SupersetClient.get as jest.Mock; +const mockedPost = SupersetClient.post as jest.Mock; + +const props = { + show: true, + onHide: jest.fn(), + addDangerToast: jest.fn(), + addSuccessToast: jest.fn(), + semanticLayerUuid: '11111111-1111-1111-1111-111111111111', +}; + +beforeEach(() => { + mockJsonFormsChangeTriggered = false; + jest.useFakeTimers({ advanceTimers: true }); + mockedGet.mockReset(); + mockedPost.mockReset(); + + mockedGet + .mockResolvedValueOnce({ + json: { + result: [{ id: 'snowflake', name: 'Snowflake', description: '' }], + }, + }) + .mockResolvedValueOnce({ + json: { + result: { + name: 'Layer 1', + type: 'snowflake', + configuration: { warehouse: 'wh0' }, + }, + }, + }); + + mockedPost.mockResolvedValue({ + json: { + result: { + type: 'object', + properties: { + warehouse: { + type: 'string', + 'x-dynamic': true, + 'x-dependsOn': ['warehouse'], + }, + }, + }, + }, + }); +}); + +afterEach(() => { + jest.runOnlyPendingTimers(); + jest.useRealTimers(); +}); + +test('posts configuration schema refresh after debounce', async () => { + render(); + + await waitFor(() => { + expect(mockedPost).toHaveBeenNthCalledWith(1, { + endpoint: '/api/v1/semantic_layer/schema/configuration', + jsonPayload: { + type: 'snowflake', + configuration: { warehouse: 'wh0' }, + }, + }); + }); + + jest.advanceTimersByTime(501); + + await waitFor(() => { + expect(mockedPost).toHaveBeenNthCalledWith(2, { + endpoint: '/api/v1/semantic_layer/schema/configuration', + jsonPayload: { + type: 'snowflake', + configuration: { warehouse: 'wh1' }, + }, + }); + }); +}); diff --git a/superset-frontend/src/features/semanticLayers/SemanticLayerModal.tsx b/superset-frontend/src/features/semanticLayers/SemanticLayerModal.tsx new file mode 100644 index 00000000000..0193f296488 --- /dev/null +++ b/superset-frontend/src/features/semanticLayers/SemanticLayerModal.tsx @@ -0,0 +1,408 @@ +/** + * 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 { useState, useEffect, useCallback, useRef } from 'react'; +import { t } from '@apache-superset/core/translation'; +import { SupersetClient, getClientErrorObject } from '@superset-ui/core'; +import { Input, Select, Button } from '@superset-ui/core/components'; +import { Icons } from '@superset-ui/core/components/Icons'; +import { JsonForms } from '@jsonforms/react'; +import type { JsonSchema, UISchemaElement } from '@jsonforms/core'; +import { cellRegistryEntries } from '@great-expectations/jsonforms-antd-renderers'; +import type { ErrorObject } from 'ajv'; +import { + StandardModal, + ModalFormField, + MODAL_STANDARD_WIDTH, + MODAL_MEDIUM_WIDTH, +} from 'src/components/Modal'; +import { styled } from '@apache-superset/core/theme'; +import { + renderers, + sanitizeSchema, + buildUiSchema, + getDynamicDependencies, + areDependenciesSatisfied, + serializeDependencyValues, + SCHEMA_REFRESH_DEBOUNCE_MS, +} from './jsonFormsHelpers'; + +const ModalContent = styled.div` + padding: ${({ theme }) => theme.sizeUnit * 4}px; +`; + +type Step = 'type' | 'config'; +type ValidationMode = 'ValidateAndHide' | 'ValidateAndShow'; + +interface SemanticLayerType { + id: string; + name: string; + description: string; +} + +interface SemanticLayerModalProps { + show: boolean; + onHide: () => void; + addDangerToast: (msg: string) => void; + addSuccessToast: (msg: string) => void; + semanticLayerUuid?: string; +} + +export default function SemanticLayerModal({ + show, + onHide, + addDangerToast, + addSuccessToast, + semanticLayerUuid, +}: SemanticLayerModalProps) { + const isEditMode = !!semanticLayerUuid; + const [step, setStep] = useState('type'); + const [name, setName] = useState(''); + const [selectedType, setSelectedType] = useState(null); + const [types, setTypes] = useState([]); + const [loading, setLoading] = useState(false); + const [configSchema, setConfigSchema] = useState(null); + const [uiSchema, setUiSchema] = useState( + undefined, + ); + const [formData, setFormData] = useState>({}); + const [saving, setSaving] = useState(false); + const [hasErrors, setHasErrors] = useState(true); + const [refreshingSchema, setRefreshingSchema] = useState(false); + const [validationMode, setValidationMode] = + useState('ValidateAndHide'); + const errorsRef = useRef([]); + const debounceTimerRef = useRef | null>(null); + const lastDepSnapshotRef = useRef(''); + const dynamicDepsRef = useRef>({}); + + const fetchTypes = useCallback(async () => { + setLoading(true); + try { + const { json } = await SupersetClient.get({ + endpoint: '/api/v1/semantic_layer/types', + }); + setTypes(json.result ?? []); + } catch (error) { + const clientError = await getClientErrorObject(error); + addDangerToast( + clientError.error || + t('An error occurred while fetching semantic layer types'), + ); + } finally { + setLoading(false); + } + }, [addDangerToast]); + + const applySchema = useCallback((rawSchema: JsonSchema) => { + const schema = sanitizeSchema(rawSchema); + setConfigSchema(schema); + setUiSchema(buildUiSchema(schema)); + dynamicDepsRef.current = getDynamicDependencies(rawSchema); + }, []); + + const fetchConfigSchema = useCallback( + async (type: string, configuration?: Record) => { + const isInitialFetch = !configuration; + if (isInitialFetch) setLoading(true); + else setRefreshingSchema(true); + try { + const { json } = await SupersetClient.post({ + endpoint: '/api/v1/semantic_layer/schema/configuration', + jsonPayload: { type, configuration }, + }); + applySchema(json.result); + if (json.warning) { + addDangerToast(String(json.warning)); + } + if (isInitialFetch) setStep('config'); + } catch (error) { + const clientError = await getClientErrorObject(error); + if (isInitialFetch) { + addDangerToast( + clientError.error || + t('An error occurred while fetching the configuration schema'), + ); + } else { + addDangerToast( + clientError.error || + t('An error occurred while refreshing the configuration schema'), + ); + } + } finally { + if (isInitialFetch) setLoading(false); + else setRefreshingSchema(false); + } + }, + [addDangerToast, applySchema], + ); + + const fetchExistingLayer = useCallback( + async (uuid: string) => { + setLoading(true); + try { + const { json } = await SupersetClient.get({ + endpoint: `/api/v1/semantic_layer/${uuid}`, + }); + const layer = json.result; + setName(layer.name ?? ''); + setSelectedType(layer.type); + setFormData(layer.configuration ?? {}); + setHasErrors(false); + // In edit mode, fetch the enriched schema using the full saved + // configuration so that dynamic dropdowns (account, project, + // environment) show their human-readable labels immediately rather + // than flashing raw IDs while the background refresh completes. + const { json: schemaJson } = await SupersetClient.post({ + endpoint: '/api/v1/semantic_layer/schema/configuration', + jsonPayload: { type: layer.type, configuration: layer.configuration }, + }); + applySchema(schemaJson.result); + setStep('config'); + } catch (error) { + const clientError = await getClientErrorObject(error); + addDangerToast( + clientError.error || + t('An error occurred while fetching the semantic layer'), + ); + } finally { + setLoading(false); + } + }, + [addDangerToast, applySchema], + ); + + useEffect(() => { + if (show) { + if (isEditMode && semanticLayerUuid) { + fetchTypes(); + fetchExistingLayer(semanticLayerUuid); + } else { + fetchTypes(); + } + } else { + setStep('type'); + setName(''); + setSelectedType(null); + setTypes([]); + setConfigSchema(null); + setUiSchema(undefined); + setFormData({}); + setHasErrors(true); + setRefreshingSchema(false); + setValidationMode('ValidateAndHide'); + errorsRef.current = []; + lastDepSnapshotRef.current = ''; + dynamicDepsRef.current = {}; + if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current); + } + }, [show, fetchTypes, isEditMode, semanticLayerUuid, fetchExistingLayer]); + + const handleStepAdvance = () => { + if (selectedType) { + fetchConfigSchema(selectedType); + } + }; + + const handleBack = () => { + setStep('type'); + setConfigSchema(null); + setUiSchema(undefined); + setFormData({}); + setValidationMode('ValidateAndHide'); + errorsRef.current = []; + lastDepSnapshotRef.current = ''; + dynamicDepsRef.current = {}; + if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current); + }; + + const handleCreate = async () => { + setSaving(true); + try { + if (isEditMode && semanticLayerUuid) { + await SupersetClient.put({ + endpoint: `/api/v1/semantic_layer/${semanticLayerUuid}`, + jsonPayload: { name, configuration: formData }, + }); + addSuccessToast(t('Semantic layer updated')); + } else { + await SupersetClient.post({ + endpoint: '/api/v1/semantic_layer/', + jsonPayload: { name, type: selectedType, configuration: formData }, + }); + addSuccessToast(t('Semantic layer created')); + } + onHide(); + } catch (error) { + const clientError = await getClientErrorObject(error); + addDangerToast( + clientError.error || + (isEditMode + ? t('An error occurred while updating the semantic layer') + : t('An error occurred while creating the semantic layer')), + ); + } finally { + setSaving(false); + } + }; + + const handleSave = () => { + if (step === 'type') { + handleStepAdvance(); + } else { + // Trigger validation UI and submit only from explicit save action. + setValidationMode('ValidateAndShow'); + if (errorsRef.current.length === 0) { + handleCreate(); + } + } + }; + + const maybeRefreshSchema = useCallback( + (data: Record) => { + if (!selectedType) return; + + const dynamicDeps = dynamicDepsRef.current; + if (Object.keys(dynamicDeps).length === 0) return; + + // Check if any dynamic field has all dependencies satisfied + const hasSatisfiedDeps = Object.values(dynamicDeps).some(deps => + areDependenciesSatisfied(deps, data, configSchema ?? undefined), + ); + if (!hasSatisfiedDeps) return; + + // Only re-fetch if dependency values actually changed + const snapshot = serializeDependencyValues(dynamicDeps, data); + if (snapshot === lastDepSnapshotRef.current) return; + lastDepSnapshotRef.current = snapshot; + + if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current); + debounceTimerRef.current = setTimeout(() => { + fetchConfigSchema(selectedType, data); + }, SCHEMA_REFRESH_DEBOUNCE_MS); + }, + [selectedType, fetchConfigSchema, configSchema], + ); + + const handleFormChange = useCallback( + ({ + data, + errors, + }: { + data: Record; + errors?: ErrorObject[]; + }) => { + setFormData(data); + errorsRef.current = errors ?? []; + setHasErrors(errorsRef.current.length > 0); + maybeRefreshSchema(data); + }, + [maybeRefreshSchema], + ); + + const selectedTypeName = + types.find(type => type.id === selectedType)?.name ?? ''; + + const title = isEditMode + ? t('Edit %s', selectedTypeName || t('Semantic Layer')) + : step === 'type' + ? t('New Semantic Layer') + : t('Configure %s', selectedTypeName); + + return ( + : } + width={step === 'type' ? MODAL_STANDARD_WIDTH : MODAL_MEDIUM_WIDTH} + saveDisabled={ + step === 'type' ? !selectedType : saving || !name.trim() || hasErrors + } + saveText={ + step === 'type' ? undefined : isEditMode ? t('Save') : t('Create') + } + saveLoading={saving} + contentLoading={loading} + > + + {step === 'type' ? ( + + setName(e.target.value)} + placeholder={t('Name of the semantic layer')} + /> + + {configSchema && ( + // Wrap in a form with autocomplete="off" so browsers do not + // autofill credential fields (service token, account, etc.). + // eslint-disable-next-line jsx-a11y/no-redundant-roles + e.preventDefault()} + > + + + )} + + )} + + + ); +} diff --git a/superset-frontend/src/features/semanticLayers/jsonFormsHelpers.test.ts b/superset-frontend/src/features/semanticLayers/jsonFormsHelpers.test.ts new file mode 100644 index 00000000000..9f81bea4772 --- /dev/null +++ b/superset-frontend/src/features/semanticLayers/jsonFormsHelpers.test.ts @@ -0,0 +1,150 @@ +/** + * 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 type { JsonSchema } from '@jsonforms/core'; + +import { + areDependenciesSatisfied, + sanitizeSchema, + buildUiSchema, + getDynamicDependencies, + serializeDependencyValues, +} from './jsonFormsHelpers'; + +test('areDependenciesSatisfied returns true for present dependency values', () => { + expect( + areDependenciesSatisfied(['database', 'schema'], { + database: 'examples', + schema: 'public', + }), + ).toBe(true); +}); + +test('areDependenciesSatisfied treats empty object dependencies as unsatisfied', () => { + expect( + areDependenciesSatisfied(['auth'], { + auth: {}, + }), + ).toBe(false); +}); + +test('areDependenciesSatisfied uses schema defaults for untouched fields', () => { + const schema: JsonSchema = { + type: 'object', + properties: { + database: { + type: 'string', + default: 'analytics', + }, + }, + }; + + expect(areDependenciesSatisfied(['database'], {}, schema)).toBe(true); +}); + +test('sanitizeSchema removes empty enums and preserves other properties', () => { + const schema: JsonSchema = { + type: 'object', + properties: { + environment: { + type: 'string', + enum: [], + }, + warehouse: { + type: 'string', + enum: ['xsmall', 'small'], + }, + }, + }; + + const sanitized = sanitizeSchema(schema); + const sanitizedProperties = + (sanitized.properties as Record) ?? {}; + + expect(sanitizedProperties.environment?.enum).toBeUndefined(); + expect(sanitizedProperties.warehouse?.enum).toEqual(['xsmall', 'small']); +}); + +test('buildUiSchema respects x-propertyOrder and includes placeholders/tooltips', () => { + const schema = { + type: 'object', + properties: { + database: { + type: 'string', + description: 'Target database', + examples: ['examples'], + }, + schema: { + type: 'string', + }, + }, + 'x-propertyOrder': ['schema', 'database'], + } as JsonSchema; + + const uiSchema = buildUiSchema(schema) as { + type: string; + elements: Array>; + }; + + expect(uiSchema.type).toBe('VerticalLayout'); + expect(uiSchema.elements[0].scope).toBe('#/properties/schema'); + expect(uiSchema.elements[1].scope).toBe('#/properties/database'); + expect(uiSchema.elements[1].options).toEqual({ + placeholderText: 'examples', + tooltip: 'Target database', + }); +}); + +test('getDynamicDependencies extracts x-dynamic dependency mapping', () => { + const schema = { + type: 'object', + properties: { + schema: { + type: 'string', + 'x-dynamic': true, + 'x-dependsOn': ['database'], + }, + database: { + type: 'string', + }, + warehouse: { + type: 'string', + 'x-dynamic': true, + }, + }, + } as JsonSchema; + + expect(getDynamicDependencies(schema)).toEqual({ schema: ['database'] }); +}); + +test('serializeDependencyValues is stable and sorted by key', () => { + const dynamicDeps = { + schema: ['database'], + role: ['warehouse', 'database'], + }; + + const data = { + warehouse: 'compute_wh', + database: 'analytics', + ignored: 'x', + }; + + expect(serializeDependencyValues(dynamicDeps, data)).toBe( + JSON.stringify({ database: 'analytics', warehouse: 'compute_wh' }), + ); +}); diff --git a/superset-frontend/src/features/semanticLayers/jsonFormsHelpers.tsx b/superset-frontend/src/features/semanticLayers/jsonFormsHelpers.tsx new file mode 100644 index 00000000000..85c7b891dbc --- /dev/null +++ b/superset-frontend/src/features/semanticLayers/jsonFormsHelpers.tsx @@ -0,0 +1,386 @@ +/** + * 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 { useEffect } from 'react'; +import { t } from '@apache-superset/core/translation'; +import { Spin, Select, Form } from 'antd'; +import { withJsonFormsControlProps } from '@jsonforms/react'; +import type { + JsonSchema, + UISchemaElement, + ControlProps, +} from '@jsonforms/core'; +import { + rankWith, + and, + isStringControl, + formatIs, + schemaMatches, +} from '@jsonforms/core'; +import { + rendererRegistryEntries, + TextControl, +} from '@great-expectations/jsonforms-antd-renderers'; + +export const SCHEMA_REFRESH_DEBOUNCE_MS = 500; + +/** + * Custom renderer that renders `Input.Password` for fields with + * `format: "password"` in the JSON Schema (e.g. Pydantic `SecretStr`). + */ +function PasswordControl(props: ControlProps) { + const uischema = { + ...props.uischema, + options: { + ...props.uischema.options, + type: 'password', + inputProps: { + ...((props.uischema.options?.inputProps as Record) ?? + {}), + // Prevent browsers from autofilling stored login passwords into + // service-token fields. 'new-password' is respected even when + // 'off' is ignored (Chrome ≥ 34). + autoComplete: 'new-password', + }, + }, + }; + return TextControl({ ...props, uischema }); +} +const PasswordRenderer = withJsonFormsControlProps(PasswordControl); +const passwordEntry = { + tester: rankWith(3, and(isStringControl, formatIs('password'))), + renderer: PasswordRenderer, +}; + +/** + * Renderer for `const` properties (e.g. Pydantic discriminator fields). + * Renders nothing visually but ensures the const value is set in form data, + * so discriminated unions resolve correctly on the backend. + */ +function ConstControl({ data, handleChange, path, schema }: ControlProps) { + const constValue = (schema as Record).const; + useEffect(() => { + if (constValue !== undefined && data !== constValue) { + handleChange(path, constValue); + } + }, [constValue, data, handleChange, path]); + return null; +} +const ConstRenderer = withJsonFormsControlProps(ConstControl); +const constEntry = { + tester: rankWith( + 10, + schemaMatches( + s => + s !== undefined && + 'const' in s && + !(s as Record).readOnly, + ), + ), + renderer: ConstRenderer, +}; + +/** + * Renderer for read-only fields (e.g. a fixed database that the admin locked). + * Renders a disabled input showing the current value. Also ensures the default + * value is injected into form data (like ConstControl does for hidden fields). + */ +function ReadOnlyControl({ + data, + handleChange, + path, + schema, + ...rest +}: ControlProps) { + const defaultValue = + (schema as Record).const ?? + (schema as Record).default; + useEffect(() => { + if (defaultValue !== undefined && data !== defaultValue) { + handleChange(path, defaultValue); + } + }, [defaultValue, data, handleChange, path]); + + return TextControl({ + ...rest, + data, + handleChange, + path, + schema, + enabled: false, + }); +} +const ReadOnlyRenderer = withJsonFormsControlProps(ReadOnlyControl); +const readOnlyEntry = { + tester: rankWith( + 11, + schemaMatches( + s => s !== undefined && (s as Record).readOnly === true, + ), + ), + renderer: ReadOnlyRenderer, +}; + +/** + * Checks whether all dependency values are filled (non-empty). + * Handles nested objects (like auth) by checking they have at least one key. + * + * Fields that have a `default` in the schema are considered satisfied even + * when the user has not explicitly touched them yet — JsonForms does not + * write default values into `data` until a field is interacted with, so + * without this fallback a field like `admin_host` (which ships with a + * sensible default) would permanently block the refresh. + */ +export function areDependenciesSatisfied( + dependencies: string[], + data: Record, + schema?: JsonSchema, +): boolean { + return dependencies.every(dep => { + const value = data[dep]; + if (value !== null && value !== undefined && value !== '') { + if (typeof value === 'object' && Object.keys(value).length === 0) + return false; + return true; + } + // Fall back to the schema default when the field hasn't been touched yet. + const defaultValue = schema?.properties?.[dep]?.default; + return ( + defaultValue !== null && defaultValue !== undefined && defaultValue !== '' + ); + }); +} + +/** + * Renderer for fields marked `x-dynamic` in the JSON Schema. + * Shows a loading spinner inside the input while the schema is being + * refreshed with dynamic values from the backend. + */ +function DynamicFieldControl(props: ControlProps) { + const { refreshingSchema, formData: cfgData } = props.config ?? {}; + const deps = (props.schema as Record)?.['x-dependsOn']; + const refreshing = + refreshingSchema && + Array.isArray(deps) && + areDependenciesSatisfied( + deps as string[], + (cfgData as Record) ?? {}, + props.rootSchema, + ); + + if (!refreshing) { + return TextControl(props); + } + + const uischema = { + ...props.uischema, + options: { + ...props.uischema.options, + placeholderText: t('Loading...'), + inputProps: { suffix: }, + }, + }; + return TextControl({ ...props, uischema, enabled: false }); +} +const DynamicFieldRenderer = withJsonFormsControlProps(DynamicFieldControl); +const dynamicFieldEntry = { + tester: rankWith( + 3, + and( + isStringControl, + schemaMatches( + s => (s as Record)?.['x-dynamic'] === true, + ), + ), + ), + renderer: DynamicFieldRenderer, +}; + +/** + * Renderer for fields that carry an ``x-enumNames`` array alongside their + * ``enum`` values. Renders as an Antd Select showing human-readable labels + * (from ``x-enumNames``) while storing the underlying enum values in form + * data. Used for MetricFlow's integer-ID fields (account, project, + * environment) where the backend provides both IDs and display names. + */ +function EnumNamesControl(props: ControlProps) { + const { refreshingSchema } = props.config ?? {}; + const schema = props.schema as Record; + const enumValues = (schema.enum as unknown[]) ?? []; + const enumNames = + (schema['x-enumNames'] as string[]) ?? enumValues.map(String); + + const options = enumValues.map((value, index) => ({ + value, + label: enumNames[index] ?? String(value), + })); + + const tooltip = (props.uischema?.options as Record) + ?.tooltip as string | undefined; + + return ( + + handleLayerChange(value as string)} + options={layers.map(l => ({ + value: l.uuid, + label: l.name, + }))} + getPopupContainer={() => document.body} + /> + + + {/* Loading runtime schema */} + {loadingRuntime && ( + + + + )} + + {/* Source location (runtime config fields) */} + {hasRuntimeFields && !loadingRuntime && ( + <> + {t('Source location')} + + + + + )} + + {/* Semantic Views — always visible once a layer is selected */} + {selectedLayerUuid && !loadingRuntime && ( + + ( + <> + - - - + + + - - - + + + - - - { - form.setFieldsValue({ isActive: checked }); - }} - /> - - - - - - + + + + + + + + ({ - value: role.id, - label: role.name, - }))} - getPopupContainer={trigger => - trigger.closest('.ant-modal-content') - } - /> - - - ({ + value: role.id, + label: role.name, + }))} + getPopupContainer={trigger => + trigger.closest('.ant-modal-content') + } + /> + + ({ - value: group.id, - label: group.name, - }))} - getPopupContainer={trigger => - trigger.closest('.ant-modal-content') - } - /> - - {!isEditMode && ( - <> - - + :1:1\n" + " |\n" + "1 | SELEC * FROM foo\n" + " | ^~~~~\n" + ) + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=1, stderr=stderr), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="SELEC * FROM foo", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 1 + annotation = annotations[0] + assert annotation.line_number == 1 + assert annotation.start_column == 1 + # "SELEC" is 5 chars → caret + 4 tildes → end_column = 1 + 1 + 4 = 6 + assert annotation.end_column == 6 + assert "SELEC" in annotation.message + + +def test_invalid_syntax_multiple_errors() -> None: + mock_database = MagicMock() + stderr = ( + 'error: near "SELEC": syntax error\n' + " --> :1:1\n" + " |\n" + "1 | SELEC * FROM foo; SELEC * FROM bar\n" + " | ^~~~~\n\n" + 'error: near "SELEC": syntax error\n' + " --> :1:20\n" + " |\n" + "1 | SELEC * FROM foo; SELEC * FROM bar\n" + " | ^~~~~\n" + ) + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=1, stderr=stderr), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="SELEC * FROM foo; SELEC * FROM bar", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 2 + assert "SELEC" in annotations[0].message + # "SELEC" is 5 chars → caret + 4 tildes → end_column = start_column + 1 + 4 + assert isinstance(annotations[0].start_column, int) + assert isinstance(annotations[0].start_column, int) + assert annotations[0].end_column == annotations[0].start_column + 5 + assert annotations[1].end_column == annotations[1].start_column + 5 + + +def test_multiline_error_reports_correct_line() -> None: + mock_database = MagicMock() + stderr = ( + 'error: near "SELEC": syntax error\n' + " --> :2:1\n" + " |\n" + "2 | SELEC * FROM foo\n" + " | ^~~~~\n" + ) + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=1, stderr=stderr), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="SELECT 1;\nSELEC * FROM foo", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 1 + assert annotations[0].line_number == 2 + + +def test_empty_sql() -> None: + mock_database = MagicMock() + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=0), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="", + catalog=None, + schema="", + database=mock_database, + ) + + assert annotations == [] + + +def test_valid_complex_query() -> None: + mock_database = MagicMock() + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=0), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql=( + "SELECT a, COUNT(*) AS cnt " + "FROM my_table " + "WHERE b > 10 " + "GROUP BY a " + "HAVING cnt > 1 " + "ORDER BY cnt DESC " + "LIMIT 100" + ), + catalog=None, + schema="", + database=mock_database, + ) + + assert annotations == [] + + +def test_annotation_to_dict() -> None: + mock_database = MagicMock() + stderr = ( + 'error: near "SELEC": syntax error\n' + " --> :1:1\n" + " |\n" + "1 | SELEC * FROM foo\n" + " | ^~~~~\n" + ) + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=1, stderr=stderr), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="SELEC * FROM foo", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 1 + result = annotations[0].to_dict() + assert "line_number" in result + assert "start_column" in result + assert "end_column" in result + assert "message" in result + + +def test_missing_syntaqlite_returns_annotation() -> None: + mock_database = MagicMock() + with patch("superset.sql_validators.sqlite.get_binary_path", None): + annotations = SQLiteSQLValidator.validate( + sql="SELECT 1", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 1 + assert "syntaqlite is not installed" in annotations[0].message + assert annotations[0].line_number is None + + +def test_timeout_returns_annotation() -> None: + mock_database = MagicMock() + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + side_effect=subprocess.TimeoutExpired(cmd="syntaqlite", timeout=10), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="SELECT 1", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 1 + assert "timed out" in annotations[0].message + assert annotations[0].line_number is None + + +def test_get_validator_by_name() -> None: + from superset.sql_validators import get_validator_by_name + + validator = get_validator_by_name("SQLiteSQLValidator") + assert validator is SQLiteSQLValidator diff --git a/tests/unit_tests/sql_validators/sqlite_test.py b/tests/unit_tests/sql_validators/sqlite_test.py new file mode 100644 index 00000000000..a950580eafc --- /dev/null +++ b/tests/unit_tests/sql_validators/sqlite_test.py @@ -0,0 +1,303 @@ +# 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. + +from __future__ import annotations + +import subprocess +from subprocess import CompletedProcess +from unittest.mock import MagicMock, patch + +from superset.sql_validators.sqlite import SQLiteSQLValidator + + +def _mock_result( + returncode: int, + stderr: str = "", + stdout: str = "", +) -> CompletedProcess[str]: + return CompletedProcess( + args=[], + returncode=returncode, + stdout=stdout, + stderr=stderr, + ) + + +def test_valid_syntax() -> None: + mock_database = MagicMock() + sql = "SELECT 1, col FROM my_table" + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", + return_value="syntaqlite", + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=0), + ) as run, + ): + annotations = SQLiteSQLValidator.validate( + sql=sql, + catalog=None, + schema="", + database=mock_database, + ) + + assert annotations == [] + run.assert_called_once() + command = run.call_args.args[0] + assert "--input" not in command + assert "-e" not in command + assert run.call_args.kwargs["input"] == sql + + +def test_invalid_syntax_single_error() -> None: + mock_database = MagicMock() + stderr = ( + 'error: near "SELEC": syntax error\n' + " --> :1:1\n" + " |\n" + "1 | SELEC * FROM foo\n" + " | ^~~~~\n" + ) + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=1, stderr=stderr), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="SELEC * FROM foo", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 1 + annotation = annotations[0] + assert annotation.line_number == 1 + assert annotation.start_column == 1 + # "SELEC" is 5 chars → caret + 4 tildes → end_column = 1 + 1 + 4 = 6 + assert annotation.end_column == 6 + assert "SELEC" in annotation.message + + +def test_invalid_syntax_multiple_errors() -> None: + mock_database = MagicMock() + stderr = ( + 'error: near "SELEC": syntax error\n' + " --> :1:1\n" + " |\n" + "1 | SELEC * FROM foo; SELEC * FROM bar\n" + " | ^~~~~\n\n" + 'error: near "SELEC": syntax error\n' + " --> :1:20\n" + " |\n" + "1 | SELEC * FROM foo; SELEC * FROM bar\n" + " | ^~~~~\n" + ) + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=1, stderr=stderr), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="SELEC * FROM foo; SELEC * FROM bar", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 2 + assert "SELEC" in annotations[0].message + # "SELEC" is 5 chars → caret + 4 tildes → end_column = start_column + 1 + 4 + assert isinstance(annotations[0].start_column, int) + assert annotations[0].end_column == annotations[0].start_column + 5 + assert isinstance(annotations[1].start_column, int) + assert annotations[1].end_column == annotations[1].start_column + 5 + + +def test_multiline_error_reports_correct_line() -> None: + mock_database = MagicMock() + stderr = ( + 'error: near "SELEC": syntax error\n' + " --> :2:1\n" + " |\n" + "2 | SELEC * FROM foo\n" + " | ^~~~~\n" + ) + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=1, stderr=stderr), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="SELECT 1;\nSELEC * FROM foo", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 1 + assert annotations[0].line_number == 2 + + +def test_empty_sql() -> None: + mock_database = MagicMock() + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=0), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="", + catalog=None, + schema="", + database=mock_database, + ) + + assert annotations == [] + + +def test_valid_complex_query() -> None: + mock_database = MagicMock() + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=0), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql=( + "SELECT a, COUNT(*) AS cnt " + "FROM my_table " + "WHERE b > 10 " + "GROUP BY a " + "HAVING cnt > 1 " + "ORDER BY cnt DESC " + "LIMIT 100" + ), + catalog=None, + schema="", + database=mock_database, + ) + + assert annotations == [] + + +def test_annotation_to_dict() -> None: + mock_database = MagicMock() + stderr = ( + 'error: near "SELEC": syntax error\n' + " --> :1:1\n" + " |\n" + "1 | SELEC * FROM foo\n" + " | ^~~~~\n" + ) + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + return_value=_mock_result(returncode=1, stderr=stderr), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="SELEC * FROM foo", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 1 + result = annotations[0].to_dict() + assert "line_number" in result + assert "start_column" in result + assert "end_column" in result + assert "message" in result + + +def test_missing_syntaqlite_returns_annotation() -> None: + mock_database = MagicMock() + with patch("superset.sql_validators.sqlite.get_binary_path", None): + annotations = SQLiteSQLValidator.validate( + sql="SELECT 1", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 1 + assert "syntaqlite is not installed" in annotations[0].message + assert annotations[0].line_number is None + + +def test_timeout_returns_annotation() -> None: + mock_database = MagicMock() + + with ( + patch( + "superset.sql_validators.sqlite.get_binary_path", return_value="syntaqlite" + ), + patch( + "superset.sql_validators.sqlite.subprocess.run", + side_effect=subprocess.TimeoutExpired(cmd="syntaqlite", timeout=10), + ), + ): + annotations = SQLiteSQLValidator.validate( + sql="SELECT 1", + catalog=None, + schema="", + database=mock_database, + ) + + assert len(annotations) == 1 + assert "timed out" in annotations[0].message + assert annotations[0].line_number is None + + +def test_get_validator_by_name() -> None: + from superset.sql_validators import get_validator_by_name + + validator = get_validator_by_name("SQLiteSQLValidator") + assert validator is SQLiteSQLValidator diff --git a/tests/unit_tests/tasks/test_async_queries.py b/tests/unit_tests/tasks/test_async_queries.py index a7dafb3b51a..d2e73466e07 100644 --- a/tests/unit_tests/tasks/test_async_queries.py +++ b/tests/unit_tests/tasks/test_async_queries.py @@ -21,7 +21,12 @@ from flask_babel import lazy_gettext as _ from superset.commands.chart.exceptions import ChartDataQueryFailedError from superset.errors import ErrorLevel, SupersetError, SupersetErrorType -from superset.exceptions import SupersetErrorException, SupersetErrorsException +from superset.exceptions import ( + OAuth2RedirectError, + SupersetErrorException, + SupersetErrorsException, + SupersetVizException, +) @mock.patch("superset.tasks.async_queries.security_manager") @@ -149,3 +154,170 @@ def test_load_chart_data_into_cache_with_superset_errors_exception( assert errors[1]["message"] == "Table not found" assert errors[1]["error_type"] == SupersetErrorType.TABLE_DOES_NOT_EXIST_ERROR assert errors[1]["level"] == ErrorLevel.WARNING + + +@mock.patch("superset.tasks.async_queries.security_manager") +@mock.patch("superset.tasks.async_queries.async_query_manager") +@mock.patch("superset.tasks.async_queries.get_viz") +@mock.patch("superset.tasks.async_queries.get_datasource_info") +def test_load_explore_json_into_cache_preserves_oauth2_redirect_error( + mock_get_datasource_info, + mock_get_viz, + mock_async_query_manager, + mock_security_manager, +): + """ + OAuth2RedirectError raised by ``viz_obj.get_payload`` must reach the async + job's errors list as a structured SIP-40 envelope so the frontend can + render the OAuth2 banner identically to the sync legacy path. + """ + from superset.tasks.async_queries import load_explore_json_into_cache + + job_metadata = {"user_id": 1} + form_data: dict = {} + + mock_get_datasource_info.return_value = (1, "table") + mock_security_manager.get_user_by_id.return_value = mock.MagicMock() + mock_async_query_manager.STATUS_ERROR = "error" + + viz_obj = mock.MagicMock() + viz_obj.get_payload.side_effect = OAuth2RedirectError( + url="https://accounts.example.com/o/oauth2/v2/auth?...", + tab_id="tab-123", + redirect_uri="https://superset.example.com/oauth2/redirect", + ) + mock_get_viz.return_value = viz_obj + + with pytest.raises(OAuth2RedirectError): + load_explore_json_into_cache(job_metadata, form_data) + + call_args = mock_async_query_manager.update_job.call_args + assert call_args[0] == (job_metadata, "error") + errors = call_args[1]["errors"] + assert len(errors) == 1 + assert errors[0]["error_type"] == SupersetErrorType.OAUTH2_REDIRECT + assert errors[0]["extra"] == { + "url": "https://accounts.example.com/o/oauth2/v2/auth?...", + "tab_id": "tab-123", + "redirect_uri": "https://superset.example.com/oauth2/redirect", + } + + +@mock.patch("superset.tasks.async_queries.security_manager") +@mock.patch("superset.tasks.async_queries.async_query_manager") +@mock.patch("superset.tasks.async_queries.get_viz") +@mock.patch("superset.tasks.async_queries.get_datasource_info") +def test_load_explore_json_into_cache_preserves_superset_errors_exception( + mock_get_datasource_info, + mock_get_viz, + mock_async_query_manager, + mock_security_manager, +): + """SupersetErrorsException must be preserved as a list of SIP-40 dicts.""" + from superset.tasks.async_queries import load_explore_json_into_cache + + job_metadata = {"user_id": 1} + form_data: dict = {} + + mock_get_datasource_info.return_value = (1, "table") + mock_security_manager.get_user_by_id.return_value = mock.MagicMock() + mock_async_query_manager.STATUS_ERROR = "error" + + viz_obj = mock.MagicMock() + viz_obj.get_payload.side_effect = SupersetErrorsException( + [ + SupersetError( + message="Column not found", + error_type=SupersetErrorType.COLUMN_DOES_NOT_EXIST_ERROR, + level=ErrorLevel.ERROR, + ), + SupersetError( + message="Table not found", + error_type=SupersetErrorType.TABLE_DOES_NOT_EXIST_ERROR, + level=ErrorLevel.WARNING, + ), + ] + ) + mock_get_viz.return_value = viz_obj + + with pytest.raises(SupersetErrorsException): + load_explore_json_into_cache(job_metadata, form_data) + + errors = mock_async_query_manager.update_job.call_args[1]["errors"] + assert len(errors) == 2 + assert errors[0]["error_type"] == SupersetErrorType.COLUMN_DOES_NOT_EXIST_ERROR + assert errors[1]["error_type"] == SupersetErrorType.TABLE_DOES_NOT_EXIST_ERROR + + +@mock.patch("superset.tasks.async_queries.security_manager") +@mock.patch("superset.tasks.async_queries.async_query_manager") +@mock.patch("superset.tasks.async_queries.get_viz") +@mock.patch("superset.tasks.async_queries.get_datasource_info") +def test_load_explore_json_into_cache_preserves_superset_viz_exception( + mock_get_datasource_info, + mock_get_viz, + mock_async_query_manager, + mock_security_manager, +): + """ + Test that SupersetVizException passes ``ex.errors`` straight through. + """ + from superset.tasks.async_queries import load_explore_json_into_cache + + job_metadata = {"user_id": 1} + form_data: dict = {} + + mock_get_datasource_info.return_value = (1, "table") + mock_security_manager.get_user_by_id.return_value = mock.MagicMock() + mock_async_query_manager.STATUS_ERROR = "error" + + payload_errors = [ + { + "message": "Bad column", + "error_type": SupersetErrorType.VIZ_GET_DF_ERROR, + "level": ErrorLevel.ERROR, + } + ] + viz_obj = mock.MagicMock() + viz_obj.get_payload.return_value = {"errors": payload_errors} + viz_obj.has_error.return_value = True + mock_get_viz.return_value = viz_obj + + with pytest.raises(SupersetVizException): + load_explore_json_into_cache(job_metadata, form_data) + + errors = mock_async_query_manager.update_job.call_args[1]["errors"] + assert errors == payload_errors + + +@mock.patch("superset.tasks.async_queries.security_manager") +@mock.patch("superset.tasks.async_queries.async_query_manager") +@mock.patch("superset.tasks.async_queries.get_viz") +@mock.patch("superset.tasks.async_queries.get_datasource_info") +def test_load_explore_json_into_cache_falls_back_to_string_for_generic_exception( + mock_get_datasource_info, + mock_get_viz, + mock_async_query_manager, + mock_security_manager, +): + """ + Test that Non-Superset exception are passed as plain-string error. + """ + from superset.tasks.async_queries import load_explore_json_into_cache + + job_metadata = {"user_id": 1} + form_data: dict = {} + + mock_get_datasource_info.return_value = (1, "table") + mock_security_manager.get_user_by_id.return_value = mock.MagicMock() + mock_async_query_manager.STATUS_ERROR = "error" + + viz_obj = mock.MagicMock() + viz_obj.get_payload.side_effect = RuntimeError("boom") + mock_get_viz.return_value = viz_obj + + with pytest.raises(RuntimeError): + load_explore_json_into_cache(job_metadata, form_data) + + errors = mock_async_query_manager.update_job.call_args[1]["errors"] + assert errors == ["boom"] diff --git a/tests/unit_tests/test_viz_cache_key.py b/tests/unit_tests/test_viz_cache_key.py new file mode 100644 index 00000000000..d6eb614265c --- /dev/null +++ b/tests/unit_tests/test_viz_cache_key.py @@ -0,0 +1,111 @@ +# 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. +""" +Behavioral tests for ``viz.BaseViz.cache_key`` covering per-user cache-key +inclusion. +""" + +from typing import Any +from unittest.mock import patch + +from flask_appbuilder.security.sqla.models import User + +from superset import viz +from superset.connectors.sqla.models import SqlaTable +from superset.models.core import Database +from superset.utils.core import override_user + +QUERY_OBJ: dict[str, Any] = {"row_limit": 100, "from_dttm": None, "to_dttm": None} + + +def _viz_for(database: Database) -> viz.BaseViz: + datasource = SqlaTable( + table_name="t", + columns=[], + metrics=[], + main_dttm_col=None, + database=database, + ) + return viz.BaseViz(datasource=datasource, form_data={"viz_type": "table"}) + + +def test_no_per_user_opt_in_keys_match_across_users(): + """ + Without any per-user caching opt-in, two different users on the same + database/query must produce the *same* cache key (regression guard — we + must not accidentally make every cache key per-user). + """ + database = Database(database_name="d", sqlalchemy_uri="sqlite://") + obj = _viz_for(database) + + with override_user(User(username="alice")): + key_a = obj.cache_key(QUERY_OBJ) + with override_user(User(username="bob")): + key_b = obj.cache_key(QUERY_OBJ) + + assert key_a == key_b + + +def test_per_user_caching_in_extra_yields_distinct_keys_per_user(): + """ + With ``per_user_caching: true`` set on the database, two different users + must produce *different* cache keys for the same query. + """ + database = Database( + database_name="d", + sqlalchemy_uri="sqlite://", + extra='{"per_user_caching": true}', + ) + obj = _viz_for(database) + + with override_user(User(username="alice")): + key_a = obj.cache_key(QUERY_OBJ) + with override_user(User(username="bob")): + key_b = obj.cache_key(QUERY_OBJ) + + assert key_a != key_b + + +def test_same_user_same_query_idempotent(): + database = Database( + database_name="d", + sqlalchemy_uri="sqlite://", + extra='{"per_user_caching": true}', + ) + obj = _viz_for(database) + + with override_user(User(username="alice")): + assert obj.cache_key(QUERY_OBJ) == obj.cache_key(QUERY_OBJ) + + +@patch("superset.utils.cache_keys.feature_flag_manager") +def test_cache_query_by_user_flag_yields_distinct_keys(feature_flag_mock): + """ + Global ``CACHE_QUERY_BY_USER`` flag also reaches the legacy viz path. + """ + feature_flag_mock.is_feature_enabled.side_effect = ( + lambda feature=None: feature == "CACHE_QUERY_BY_USER" + ) + database = Database(database_name="d", sqlalchemy_uri="sqlite://") + obj = _viz_for(database) + + with override_user(User(username="alice")): + key_a = obj.cache_key(QUERY_OBJ) + with override_user(User(username="bob")): + key_b = obj.cache_key(QUERY_OBJ) + + assert key_a != key_b diff --git a/tests/unit_tests/test_viz_get_df_payload.py b/tests/unit_tests/test_viz_get_df_payload.py new file mode 100644 index 00000000000..8c8549d6495 --- /dev/null +++ b/tests/unit_tests/test_viz_get_df_payload.py @@ -0,0 +1,111 @@ +# 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. +from typing import Any +from unittest.mock import patch + +import pytest + +from superset import viz +from superset.common.db_query_status import QueryStatus +from superset.connectors.sqla.models import SqlaTable +from superset.errors import SupersetErrorType +from superset.exceptions import ( + OAuth2RedirectError, + QueryObjectValidationError, +) +from superset.models.core import Database + +QUERY_OBJ: dict[str, Any] = {"row_limit": 100, "from_dttm": None, "to_dttm": None} + + +def _viz() -> viz.BaseViz: + database = Database(database_name="d", sqlalchemy_uri="sqlite://") + datasource = SqlaTable( + table_name="t", + columns=[], + metrics=[], + main_dttm_col=None, + database=database, + ) + # ``force=True`` skips the data cache lookup branch so ``get_df`` is always + # invoked, which is what we want to assert error-handling against. + return viz.BaseViz( + datasource=datasource, + form_data={"viz_type": "table"}, + force=True, + ) + + +def test_get_df_payload_propagates_oauth2_redirect_error() -> None: + """ + OAuth2RedirectError (a SupersetErrorException) must propagate out of + ``get_df_payload`` so the global Flask error handler can serialize it. + """ + obj = _viz() + oauth_exc = OAuth2RedirectError( + url="https://accounts.example.com/o/oauth2/v2/auth?...", + tab_id="tab-123", + redirect_uri="https://superset.example.com/oauth2/redirect", + ) + + with patch.object(viz.BaseViz, "get_df", side_effect=oauth_exc): + with pytest.raises(OAuth2RedirectError) as exc_info: + obj.get_df_payload(QUERY_OBJ) + + assert exc_info.value.error.error_type == SupersetErrorType.OAUTH2_REDIRECT + assert exc_info.value.error.extra == { + "url": "https://accounts.example.com/o/oauth2/v2/auth?...", + "tab_id": "tab-123", + "redirect_uri": "https://superset.example.com/oauth2/redirect", + } + + +def test_get_df_payload_captures_generic_exception_as_viz_get_df_error() -> None: + """ + Non-Superset exception raised by ``get_df`` are downgraded to a + ``VIZ_GET_DF_ERROR`` entry on ``self.errors``. + """ + obj = _viz() + + with patch.object(viz.BaseViz, "get_df", side_effect=RuntimeError("boom")): + payload = obj.get_df_payload(QUERY_OBJ) + + assert obj.status == QueryStatus.FAILED + assert payload["status"] == QueryStatus.FAILED + assert len(obj.errors) == 1 + assert obj.errors[0]["error_type"] == SupersetErrorType.VIZ_GET_DF_ERROR + assert obj.errors[0]["message"] == "boom" + + +def test_get_df_payload_captures_query_object_validation_error() -> None: + """ + ``QueryObjectValidationError`` is reported as ``VIZ_GET_DF_ERROR``. + """ + obj = _viz() + + with patch.object( + viz.BaseViz, + "get_df", + side_effect=QueryObjectValidationError("bad query"), + ): + payload = obj.get_df_payload(QUERY_OBJ) + + assert obj.status == QueryStatus.FAILED + assert payload["status"] == QueryStatus.FAILED + assert len(obj.errors) == 1 + assert obj.errors[0]["error_type"] == SupersetErrorType.VIZ_GET_DF_ERROR + assert obj.errors[0]["message"] == "bad query" diff --git a/tests/unit_tests/utils/oauth2_tests.py b/tests/unit_tests/utils/oauth2_tests.py index a320a8a23e8..c74b2f9570b 100644 --- a/tests/unit_tests/utils/oauth2_tests.py +++ b/tests/unit_tests/utils/oauth2_tests.py @@ -137,6 +137,7 @@ def test_refresh_oauth2_token_deletes_token_on_oauth2_exception( refresh_oauth2_token(DUMMY_OAUTH2_CONFIG, 1, 1, db_engine_spec, token) db.session.delete.assert_called_with(token) + db.session.flush.assert_called_once() def test_refresh_oauth2_token_keeps_token_on_other_exception( @@ -338,6 +339,45 @@ def test_encode_decode_oauth2_state( assert decoded["user_id"] == 2 +def test_get_oauth2_access_token_lock_not_acquired_no_error_log( + mocker: MockerFixture, + caplog: pytest.LogCaptureFixture, +) -> None: + """ + Test that when a distributed lock can't be acquired, no error is logged and + the function returns None instead of raising. + + This scenario occurs when a dashboard with multiple charts from the same + OAuth2-enabled DB has an expired token: simultaneous requests compete for + the lock, and only the first one wins. The rest should silently return None. + """ + import logging + + from superset.exceptions import AcquireDistributedLockFailedException + + mocker.patch("time.sleep") # avoid backoff delays in tests + + db = mocker.patch("superset.utils.oauth2.db") + db_engine_spec = mocker.MagicMock() + token = mocker.MagicMock() + token.access_token = "access-token" # noqa: S105 + token.access_token_expiration = datetime(2024, 1, 1) + token.refresh_token = "refresh-token" # noqa: S105 + db.session.query().filter_by().one_or_none.return_value = token + + mocker.patch( + "superset.utils.oauth2.refresh_oauth2_token", + side_effect=AcquireDistributedLockFailedException("Lock not available"), + ) + + with freeze_time("2024-01-02"): + with caplog.at_level(logging.DEBUG): + result = get_oauth2_access_token({}, 1, 1, db_engine_spec) + + assert result is None + assert not any(record.levelno >= logging.ERROR for record in caplog.records) + + def test_get_oauth2_redirect_uri_from_config(mocker: MockerFixture) -> None: """ Test that get_oauth2_redirect_uri returns the configured value when set. diff --git a/tests/unit_tests/utils/test_core.py b/tests/unit_tests/utils/test_core.py index 463ee32180a..5e663dd095a 100644 --- a/tests/unit_tests/utils/test_core.py +++ b/tests/unit_tests/utils/test_core.py @@ -39,6 +39,7 @@ from superset.utils.core import ( get_stacktrace, get_user_agent, is_test, + markdown, merge_extra_filters, merge_extra_form_data, merge_request_params, @@ -1688,3 +1689,44 @@ def test_sanitize_url_blocks_dangerous(): """Test that dangerous URL schemes are blocked.""" assert sanitize_url("javascript:alert('xss')") == "" assert sanitize_url("data:text/html,") == "" + + +def test_markdown_basic() -> None: + result = markdown("**bold**") + + assert "bold" in result + + +def test_markdown_allows_target_blank_on_links() -> None: + raw = 'Click here' + result = markdown(raw) + + assert 'href="https://example.com"' in result + assert 'target="_blank"' in result + assert 'rel="noopener noreferrer"' in result + + +def test_markdown_replaces_custom_rel_with_safe_rel() -> None: + raw = 'Click' + result = markdown(raw) + + assert 'href="https://example.com"' in result + assert ">Click" in result + assert 'rel="noopener noreferrer"' in result + assert 'rel="external"' not in result + + +def test_markdown_sanitizes_dangerous_content() -> None: + raw = '
Content
' + result = markdown(raw) + + assert "