mirror of
https://github.com/apache/superset.git
synced 2026-09-10 01:04:25 +00:00
Compare commits
125
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9dd0c3be2a | ||
|
|
70b52908b9 | ||
|
|
44869b6c96 | ||
|
|
a78591be60 | ||
|
|
4dcc800b58 | ||
|
|
9267d8b666 | ||
|
|
b1c6401e82 | ||
|
|
196fe87c54 | ||
|
|
09522cc4b8 | ||
|
|
4aca0d7da4 | ||
|
|
ce700f389c | ||
|
|
072a29ddb5 | ||
|
|
f73ccee782 | ||
|
|
0fe58044cb | ||
|
|
4686d13379 | ||
|
|
68528e3308 | ||
|
|
c442180328 | ||
|
|
80ebfad094 | ||
|
|
d1ad6aeda6 | ||
|
|
d137fd1c06 | ||
|
|
7f06e4eb60 | ||
|
|
07a8f8b984 | ||
|
|
ccb5fb279f | ||
|
|
08e686b535 | ||
|
|
97329bb1cf | ||
|
|
3108f41167 | ||
|
|
4d8dfdd152 | ||
|
|
57a92170bd | ||
|
|
954dbc9ff6 | ||
|
|
7b83ed8374 | ||
|
|
49b9347974 | ||
|
|
df95ab23ec | ||
|
|
e43f44e91e | ||
|
|
d38f20e5ad | ||
|
|
0a412b07cb | ||
|
|
5e99f14ac9 | ||
|
|
ea287c1ab0 | ||
|
|
e170822a28 | ||
|
|
677e9189f1 | ||
|
|
638f87de5f | ||
|
|
cb2188aec3 | ||
|
|
176a50d254 | ||
|
|
010c7a12ed | ||
|
|
de08dc207c | ||
|
|
f64b45f2c4 | ||
|
|
9079f002ee | ||
|
|
1ab6077e06 | ||
|
|
c76e4d98f2 | ||
|
|
fc110d8428 | ||
|
|
4f26627a6a | ||
|
|
613871ed36 | ||
|
|
c503f92642 | ||
|
|
50c1504cac | ||
|
|
5d771e9f46 | ||
|
|
c9965c7bf4 | ||
|
|
9669e41471 | ||
|
|
daf41bdf04 | ||
|
|
986b648f1c | ||
|
|
acb29937ae | ||
|
|
2875c76d55 | ||
|
|
d0f139c210 | ||
|
|
9de50b85e5 | ||
|
|
c510946df5 | ||
|
|
91f4d01ca2 | ||
|
|
3828dcb922 | ||
|
|
362d3509cb | ||
|
|
fa31e9c1c3 | ||
|
|
335a2a78ea | ||
|
|
3564baabf6 | ||
|
|
380675662d | ||
|
|
0e6170aaa3 | ||
|
|
9d89dbddc7 | ||
|
|
02ea5775c1 | ||
|
|
83d5d1ccda | ||
|
|
7b65d22205 | ||
|
|
1339bdc6ce | ||
|
|
10866337c5 | ||
|
|
e6d088d6b1 | ||
|
|
5986fe92c2 | ||
|
|
04ab089962 | ||
|
|
bc35151350 | ||
|
|
7029c468c4 | ||
|
|
60553b4326 | ||
|
|
85ea6e900a | ||
|
|
a114b4cc46 | ||
|
|
3ccab2ea7a | ||
|
|
067a356b6f | ||
|
|
57eafd75e0 | ||
|
|
c45fc6a31a | ||
|
|
33c6df77c9 | ||
|
|
204ccc7ce7 | ||
|
|
08694d64cb | ||
|
|
056fd218d4 | ||
|
|
ad319bd8a3 | ||
|
|
7382ee0bfe | ||
|
|
7d0cf1acfc | ||
|
|
c4e145b071 | ||
|
|
cdb6c8e0c9 | ||
|
|
89786160f9 | ||
|
|
bd3ab30907 | ||
|
|
1b3758d2a4 | ||
|
|
1fb6b98941 | ||
|
|
8d6044a147 | ||
|
|
574d121cd8 | ||
|
|
d22069a7af | ||
|
|
233f6379ae | ||
|
|
4440887dc2 | ||
|
|
53070fa4c0 | ||
|
|
92bd2ba057 | ||
|
|
4eff13b81e | ||
|
|
06913244de | ||
|
|
a5377541c9 | ||
|
|
e5e6d74819 | ||
|
|
b8fb5a268c | ||
|
|
07052752b6 | ||
|
|
7c9c32651c | ||
|
|
0db9ca7401 | ||
|
|
7d09490bb8 | ||
|
|
df3abe474c | ||
|
|
87f138cc80 | ||
|
|
c03f3441bd | ||
|
|
f3896ccf20 | ||
|
|
18d277c096 | ||
|
|
fe1b368bcd | ||
|
|
1358543827 |
@@ -1,23 +0,0 @@
|
||||
name: Label Draft PRs
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- converted_to_draft
|
||||
jobs:
|
||||
label-draft:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check if the PR is a draft
|
||||
id: check-draft
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const isDraft = context.payload.pull_request.draft;
|
||||
core.setOutput('isDraft', isDraft);
|
||||
- name: Add `review:draft` Label
|
||||
if: steps.check-draft.outputs.isDraft == 'true'
|
||||
uses: actions-ecosystem/action-add-labels@v1
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: "review:draft"
|
||||
@@ -26,7 +26,7 @@ runs:
|
||||
|
||||
- name: Set up QEMU
|
||||
if: ${{ inputs.build == 'true' }}
|
||||
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
|
||||
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
|
||||
with:
|
||||
# Pin the binfmt image to a specific QEMU release. The default
|
||||
# (`tonistiigi/binfmt:latest`) is a moving target, and drift across
|
||||
@@ -39,12 +39,12 @@ runs:
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
if: ${{ inputs.build == 'true' }}
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
|
||||
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
|
||||
|
||||
- name: Try to login to DockerHub
|
||||
if: ${{ inputs.login-to-dockerhub == 'true' }}
|
||||
continue-on-error: true
|
||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
||||
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
||||
with:
|
||||
username: ${{ inputs.dockerhub-user }}
|
||||
password: ${{ inputs.dockerhub-token }}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# Verifies that every `uses:` ref under .github/ is on the ASF Infrastructure
|
||||
# GitHub Actions allowlist (apache/infrastructure-actions). An action that is
|
||||
# not allowlisted fails at "Set up job" with no logs and no notification, so
|
||||
# this check surfaces the problem at PR time instead. It also warns (without
|
||||
# failing) when a pinned SHA's allowlist entry is about to expire.
|
||||
name: ASF Allowlist Check
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
paths:
|
||||
- ".github/**"
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
- "[0-9].[0-9]*"
|
||||
paths:
|
||||
- ".github/**"
|
||||
schedule:
|
||||
# Weekly, so allowlist expirations are surfaced even when nothing under
|
||||
# .github/ has changed.
|
||||
- cron: "0 6 * * 1"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# cancel previous workflow jobs for PRs
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
asf-allowlist-check:
|
||||
runs-on: ubuntu-26.04
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check action refs against the ASF allowlist
|
||||
uses: apache/infrastructure-actions/allowlist-check@df54e48ff76152790f317934c691cfa7fd7a1a46 # allowlist-check/v1.0.1
|
||||
with:
|
||||
# Default scan-glob is .github/**/*.yml, which misses .yaml files.
|
||||
scan-glob: ".github/**/*.y*ml"
|
||||
@@ -49,4 +49,4 @@ jobs:
|
||||
run: bash .github/workflows/scripts/check-docs-deploy-freshness.test.sh
|
||||
|
||||
- name: Check for security issues on GHA workflows
|
||||
uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2
|
||||
uses: zizmorcore/zizmor-action@70fb788f84895a7701f5643d103d587e460b5c99 # v0.6.3
|
||||
|
||||
@@ -168,7 +168,10 @@ jobs:
|
||||
needs: changes
|
||||
if: needs.changes.outputs.python == 'true' || needs.changes.outputs.frontend == 'true'
|
||||
runs-on: ubuntu-26.04
|
||||
timeout-minutes: 30
|
||||
# Embedded Tests below adds its own gunicorn boot + spec run on top of
|
||||
# Required and Soft-delete; 30m was tight even for the two-step shadow
|
||||
# job this replaced.
|
||||
timeout-minutes: 40
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
@@ -176,7 +179,10 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
browser: ["chromium"]
|
||||
app_root: ${{ github.event_name == 'push' && fromJSON('["", "/app/prefix"]') || fromJSON('[""]') }}
|
||||
# Subdirectory deployment (APPLICATION_ROOT) is a required-to-pass
|
||||
# dimension, not an optional one, so it runs on every event —
|
||||
# unlike cypress-matrix above, which only widens on push.
|
||||
app_root: ["", "/app/prefix"]
|
||||
env:
|
||||
SUPERSET_ENV: development
|
||||
SUPERSET_CONFIG: tests.integration_tests.superset_test_config
|
||||
@@ -266,14 +272,25 @@ jobs:
|
||||
# Scoped to this step: each playwright-run boots its own gunicorn
|
||||
# with the step's env, so the Required Tests server above keeps
|
||||
# master's Flask configuration while this one runs with SOFT_DELETE
|
||||
# on — the same isolation pattern as the Embedded step in
|
||||
# superset-playwright.yml. Without a flag-on server the
|
||||
# recently-archived specs skip themselves everywhere and ship zero
|
||||
# executed E2E coverage; in the Required run above they are
|
||||
# collected and skipped, which is expected.
|
||||
# on — the same isolation pattern as the Embedded Tests step below.
|
||||
# Without a flag-on server the recently-archived specs skip
|
||||
# themselves everywhere and ship zero executed E2E coverage; in the
|
||||
# Required run above they are collected and skipped, which is
|
||||
# expected.
|
||||
SUPERSET_FEATURE_SOFT_DELETE: "true"
|
||||
with:
|
||||
run: playwright-run "${{ matrix.app_root }}" recently-archived/
|
||||
- name: Run Playwright (Embedded Tests)
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
env:
|
||||
NODE_OPTIONS: "--max-old-space-size=4096"
|
||||
# Scoped to this step for the same reason as Soft-delete above:
|
||||
# embedding is a real, required feature, so its Playwright coverage
|
||||
# now gates merges instead of running only in shadow mode.
|
||||
SUPERSET_FEATURE_EMBEDDED_SUPERSET: "true"
|
||||
INCLUDE_EMBEDDED: "true"
|
||||
with:
|
||||
run: playwright-run "${{ matrix.app_root }}" embedded
|
||||
- name: Set safe app root
|
||||
if: failure()
|
||||
id: set-safe-app-root
|
||||
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
# allowlist (only v8.1.0+ are, at apache/infrastructure-actions'
|
||||
# actions.yml). Needs an INFRA request before this can de-vendor too.
|
||||
- name: Set up chart-testing
|
||||
uses: ./.github/actions/chart-testing-action
|
||||
uses: $/.github/actions/chart-testing-action
|
||||
|
||||
- name: Run chart-testing (list-changed)
|
||||
id: list-changed
|
||||
|
||||
@@ -42,12 +42,14 @@ jobs:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
id: check
|
||||
uses: ./.github/actions/change-detector/
|
||||
uses: $/.github/actions/change-detector/
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# NOTE: Required Playwright tests are in superset-e2e.yml (E2E / playwright-tests)
|
||||
# This workflow contains only experimental tests that run in shadow mode
|
||||
# NOTE: Required Playwright tests are in superset-e2e.yml (E2E / playwright-tests),
|
||||
# including Embedded — it moved out of this workflow because embedding is a
|
||||
# required feature, not an experimental one. This workflow now contains
|
||||
# only experimental and mobile tests, which run in shadow mode.
|
||||
playwright-tests-experimental:
|
||||
needs: changes
|
||||
if: needs.changes.outputs.python == 'true' || needs.changes.outputs.frontend == 'true'
|
||||
@@ -107,13 +109,25 @@ jobs:
|
||||
submodules: recursive
|
||||
# -------------------------------------------------------
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-backend/
|
||||
uses: $/.github/actions/setup-backend/
|
||||
- name: Setup postgres
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# cached-dependencies is a submodule (not a plain directory), and
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's link. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
with:
|
||||
run: setup-postgres
|
||||
- name: Import test data
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# cached-dependencies is a submodule (not a plain directory), and
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's link. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
with:
|
||||
run: playwright_testdata
|
||||
- name: Setup Node.js
|
||||
@@ -123,48 +137,53 @@ jobs:
|
||||
cache: "npm"
|
||||
cache-dependency-path: "superset-frontend/package-lock.json"
|
||||
- name: Install npm dependencies
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# cached-dependencies is a submodule (not a plain directory), and
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's link. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
with:
|
||||
run: npm-install
|
||||
- name: Build javascript packages
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# cached-dependencies is a submodule (not a plain directory), and
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's link. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
with:
|
||||
run: build-instrumented-assets
|
||||
- name: Build embedded SDK
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
with:
|
||||
run: build-embedded-sdk
|
||||
- name: Install Playwright
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's gitlink. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
with:
|
||||
run: playwright-install
|
||||
- name: Run Playwright (Experimental Tests)
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# cached-dependencies is a submodule (not a plain directory), and
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's link. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
env:
|
||||
NODE_OPTIONS: "--max-old-space-size=4096"
|
||||
with:
|
||||
run: playwright-run "${{ matrix.app_root }}" experimental/
|
||||
- name: Run Playwright (Embedded Tests)
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
env:
|
||||
NODE_OPTIONS: "--max-old-space-size=4096"
|
||||
# Scope embedded-only env vars to this step. Setting them at the job
|
||||
# level enabled the EMBEDDED_SUPERSET feature flag inside Flask for
|
||||
# the preceding "Required Tests" and "Experimental Tests" steps too,
|
||||
# which loads extra handlers and destabilizes the werkzeug dev
|
||||
# server under the 2-worker Playwright load. Required Tests should
|
||||
# match master's Flask configuration.
|
||||
SUPERSET_FEATURE_EMBEDDED_SUPERSET: "true"
|
||||
INCLUDE_EMBEDDED: "true"
|
||||
with:
|
||||
run: playwright-run "${{ matrix.app_root }}" embedded
|
||||
- name: Run Playwright (Mobile Tests)
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
env:
|
||||
NODE_OPTIONS: "--max-old-space-size=4096"
|
||||
# Scoped to this step for the same reason as the embedded flags
|
||||
# above: the mobile consumption mode should not alter Flask's
|
||||
# configuration for the required desktop test steps.
|
||||
# Scoped to this step: setting feature flags at the job level would
|
||||
# alter Flask's configuration for the preceding Experimental step
|
||||
# too — the mobile consumption mode should not do that.
|
||||
SUPERSET_FEATURE_MOBILE_CONSUMPTION_MODE: "true"
|
||||
INCLUDE_MOBILE: "true"
|
||||
with:
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
id: check
|
||||
uses: ./.github/actions/change-detector/
|
||||
uses: $/.github/actions/change-detector/
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -75,9 +75,15 @@ jobs:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-backend/
|
||||
uses: $/.github/actions/setup-backend/
|
||||
- name: Setup MySQL
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# cached-dependencies is a git submodule (not a plain directory), and
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's gitlink. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
with:
|
||||
run: setup-mysql
|
||||
- name: Start Celery worker
|
||||
@@ -210,9 +216,15 @@ jobs:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-backend/
|
||||
uses: $/.github/actions/setup-backend/
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# cached-dependencies is a git submodule (not a plain directory), and
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's gitlink. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
with:
|
||||
run: |
|
||||
# sqlite needs this working directory
|
||||
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
id: check
|
||||
uses: ./.github/actions/change-detector/
|
||||
uses: $/.github/actions/change-detector/
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -80,9 +80,15 @@ jobs:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-backend/
|
||||
uses: $/.github/actions/setup-backend/
|
||||
- name: Setup Postgres
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# cached-dependencies is a submodule (not a plain directory), and
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's link. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
with:
|
||||
run: setup-postgres
|
||||
- name: Start Celery worker
|
||||
@@ -141,13 +147,19 @@ jobs:
|
||||
- name: Start hadoop and hive
|
||||
run: docker compose -f scripts/databases/hive/docker-compose.yml up -d
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-backend/
|
||||
uses: $/.github/actions/setup-backend/
|
||||
- name: Setup Postgres
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
with:
|
||||
run: setup-postgres
|
||||
- name: Start Celery worker
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# cached-dependencies is a submodule (not a plain directory), and
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's link. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
with:
|
||||
run: celery-worker
|
||||
- name: Python unit tests (PostgreSQL)
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
id: check
|
||||
uses: ./.github/actions/change-detector/
|
||||
uses: $/.github/actions/change-detector/
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-backend/
|
||||
uses: $/.github/actions/setup-backend/
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Python unit tests
|
||||
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
|
||||
- name: Check for file changes
|
||||
id: check
|
||||
uses: ./.github/actions/change-detector/
|
||||
uses: $/.github/actions/change-detector/
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -45,7 +45,13 @@ jobs:
|
||||
cache-dependency-path: "superset-frontend/package-lock.json"
|
||||
- name: Install dependencies
|
||||
if: steps.check.outputs.frontend
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
# cached-dependencies is a git submodule (not a plain directory), and
|
||||
# the $/ self-repository syntax resolves action files directly from
|
||||
# the repository without performing a real (submodule-aware)
|
||||
# checkout, so it can't see into a submodule's gitlink. Keep this one
|
||||
# on the workspace-relative ./ form, consistent with every other
|
||||
# workflow in the repo that references this action.
|
||||
uses: ./.github/actions/cached-dependencies # zizmor: ignore[self-repository] - $/ cannot resolve an action that lives in a submodule; ./ is required here
|
||||
with:
|
||||
run: npm-install
|
||||
- name: lint
|
||||
@@ -68,13 +74,13 @@ jobs:
|
||||
|
||||
- name: Check for file changes
|
||||
id: check
|
||||
uses: ./.github/actions/change-detector/
|
||||
uses: $/.github/actions/change-detector/
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Setup Python
|
||||
if: steps.check.outputs.python == 'true' || steps.check.outputs.frontend == 'true'
|
||||
uses: ./.github/actions/setup-backend/
|
||||
uses: $/.github/actions/setup-backend/
|
||||
|
||||
- name: Install gettext tools
|
||||
if: steps.check.outputs.python == 'true' || steps.check.outputs.frontend == 'true'
|
||||
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup supersetbot
|
||||
uses: ./.github/actions/setup-supersetbot/
|
||||
uses: $/.github/actions/setup-supersetbot/
|
||||
|
||||
- name: Execute custom Node.js script
|
||||
env:
|
||||
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Docker Environment
|
||||
uses: ./.github/actions/setup-docker
|
||||
uses: $/.github/actions/setup-docker
|
||||
with:
|
||||
dockerhub-user: ${{ secrets.DOCKERHUB_USER }}
|
||||
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@@ -81,7 +81,7 @@ jobs:
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Setup supersetbot
|
||||
uses: ./.github/actions/setup-supersetbot/
|
||||
uses: $/.github/actions/setup-supersetbot
|
||||
|
||||
- name: Execute custom Node.js script
|
||||
env:
|
||||
@@ -139,7 +139,7 @@ jobs:
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Setup supersetbot
|
||||
uses: ./.github/actions/setup-supersetbot/
|
||||
uses: $/.github/actions/setup-supersetbot/
|
||||
|
||||
- name: Label the PRs with the right release-related labels
|
||||
env:
|
||||
|
||||
@@ -178,7 +178,7 @@ repos:
|
||||
name: zizmor (GHA security audit)
|
||||
entry: zizmor
|
||||
language: python
|
||||
additional_dependencies: [zizmor==1.25.2]
|
||||
additional_dependencies: [zizmor==1.30.0]
|
||||
files: ^\.github/
|
||||
types: [yaml]
|
||||
pass_filenames: false
|
||||
|
||||
+56
-25
@@ -231,20 +231,6 @@ RUN /app/docker/apt-install.sh \
|
||||
# The database file will be created at runtime when examples are loaded from Parquet files
|
||||
RUN mkdir -p /app/data && chown -R superset:superset /app/data
|
||||
|
||||
# Copy compiled things from previous stages
|
||||
COPY --from=superset-node /app/superset/static/assets superset/static/assets
|
||||
# Copy service.worker.js optionall as it doesn't exist when DEV_MODE=true
|
||||
COPY --from=superset-node /app/superset/static/service-worker.j[s] superset/static/service-worker.js
|
||||
|
||||
# TODO, when the next version comes out, use --exclude superset/translations
|
||||
COPY superset superset
|
||||
# TODO in the meantime, remove the .po files
|
||||
RUN rm superset/translations/*/*/*.po
|
||||
|
||||
# Merging translations from backend and frontend stages
|
||||
COPY --from=superset-node /app/superset/translations superset/translations
|
||||
COPY --from=python-translation-compiler /app/translations_mo superset/translations
|
||||
|
||||
# --- Realtime WebSocket server (part of the official image) ---------------
|
||||
# The realtime transport (superset-websocket) is a Node service, bundled by
|
||||
# esbuild into a single self-contained file. Copy the Node runtime plus that
|
||||
@@ -267,7 +253,10 @@ EXPOSE ${SUPERSET_PORT}
|
||||
######################################################################
|
||||
FROM python-common AS lean
|
||||
|
||||
# Install Python dependencies using docker/pip-install.sh
|
||||
# Install Python dependencies using docker/pip-install.sh.
|
||||
# Requirements are installed *before* the application source is copied
|
||||
# below so that source-only changes don't bust this (slow, network-bound)
|
||||
# cache layer or defeat --cache-from.
|
||||
COPY requirements/base.txt requirements/
|
||||
|
||||
# Copy superset-core package needed for editable install in base.txt
|
||||
@@ -275,9 +264,27 @@ COPY superset-core superset-core
|
||||
|
||||
RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \
|
||||
/app/docker/pip-install.sh --requires-build-essential -r requirements/base.txt
|
||||
# Install the superset package
|
||||
|
||||
# Copy compiled frontend assets and application source now that
|
||||
# dependencies have been resolved and cached above.
|
||||
COPY --from=superset-node /app/superset/static/assets superset/static/assets
|
||||
# Copy service.worker.js optionally as it doesn't exist when DEV_MODE=true
|
||||
COPY --from=superset-node /app/superset/static/service-worker.j[s] superset/static/service-worker.js
|
||||
|
||||
# TODO, when the next version comes out, use --exclude superset/translations
|
||||
COPY superset superset
|
||||
# TODO in the meantime, remove the .po files
|
||||
RUN rm superset/translations/*/*/*.po
|
||||
|
||||
# Merging translations from backend and frontend stages
|
||||
COPY --from=superset-node /app/superset/translations superset/translations
|
||||
COPY --from=python-translation-compiler /app/translations_mo superset/translations
|
||||
|
||||
# Install the superset package itself. --no-deps because its dependencies
|
||||
# were already installed from requirements/base.txt above, so this layer
|
||||
# stays fast even though the source copy above changes on every edit.
|
||||
RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \
|
||||
uv pip install -e .
|
||||
uv pip install -e . --no-deps
|
||||
RUN python -m compileall /app/superset
|
||||
|
||||
USER superset
|
||||
@@ -293,22 +300,46 @@ RUN /app/docker/apt-install.sh \
|
||||
pkg-config \
|
||||
default-libmysqlclient-dev
|
||||
|
||||
# Copy development requirements and install them
|
||||
# Copy development requirements and install them *before* the application
|
||||
# source is copied below, so source-only edits don't bust this cache layer.
|
||||
COPY requirements/*.txt requirements/
|
||||
|
||||
# Copy local packages needed for editable installs in development.txt
|
||||
COPY superset-core superset-core
|
||||
COPY superset-extensions-cli superset-extensions-cli
|
||||
|
||||
# Install Python dependencies using docker/pip-install.sh
|
||||
# requirements/development.txt is generated by `uv pip compile` and embeds
|
||||
# `-e .` (an editable install of this same package) as its first line. That
|
||||
# self-reference needs the full superset/ source tree, which hasn't been
|
||||
# copied in yet at this point, so it's stripped here; the real editable
|
||||
# install of `.` runs below, once the source is present.
|
||||
RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \
|
||||
/app/docker/pip-install.sh --requires-build-essential -r requirements/development.txt
|
||||
# Install the superset package
|
||||
RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \
|
||||
uv pip install -e .
|
||||
grep -vxF -- "-e ." requirements/development.txt > requirements/development-deps.txt && \
|
||||
/app/docker/pip-install.sh --requires-build-essential -r requirements/development-deps.txt
|
||||
|
||||
RUN uv pip install .[postgres]
|
||||
RUN python -m compileall /app/superset
|
||||
# Copy compiled frontend assets and application source now that
|
||||
# dependencies have been resolved and cached above.
|
||||
COPY --from=superset-node /app/superset/static/assets superset/static/assets
|
||||
# Copy service.worker.js optionally as it doesn't exist when DEV_MODE=true
|
||||
COPY --from=superset-node /app/superset/static/service-worker.j[s] superset/static/service-worker.js
|
||||
|
||||
# TODO, when the next version comes out, use --exclude superset/translations
|
||||
COPY superset superset
|
||||
# TODO in the meantime, remove the .po files
|
||||
RUN rm superset/translations/*/*/*.po
|
||||
|
||||
# Merging translations from backend and frontend stages
|
||||
COPY --from=superset-node /app/superset/translations superset/translations
|
||||
COPY --from=python-translation-compiler /app/translations_mo superset/translations
|
||||
|
||||
# Install the superset package together with its postgres extra, using the
|
||||
# same uv cache mount as the requirements install above. --no-deps because
|
||||
# all dependencies (including the postgres extra's psycopg2-binary) are
|
||||
# already installed from requirements/development.txt above.
|
||||
# NOTE: source is bind-mounted over /app/superset in DEV_MODE, so a
|
||||
# compileall pass here would be wasted work; unlike `lean`, `dev` skips it.
|
||||
RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \
|
||||
uv pip install -e .[postgres] --no-deps
|
||||
|
||||
USER superset
|
||||
|
||||
|
||||
@@ -125,6 +125,7 @@ Here are some of the major database solutions that are supported:
|
||||
<a href="https://superset.apache.org/docs/databases/supported/apache-pinot" title="Apache Pinot"><img src="docs/static/img/databases/apache-pinot.svg" alt="Apache Pinot" width="76" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/apache-solr" title="Apache Solr"><img src="docs/static/img/databases/apache-solr.png" alt="Apache Solr" width="79" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/apache-spark-sql" title="Apache Spark SQL"><img src="docs/static/img/databases/apache-spark.png" alt="Apache Spark SQL" width="75" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/ascend" title="Ascend"><img src="docs/static/img/databases/ascend.webp" alt="Ascend" width="117" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/aurora-mysql-data-api" title="Aurora MySQL (Data API)"><img src="docs/static/img/databases/mysql.png" alt="Aurora MySQL (Data API)" width="77" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/aurora-postgresql-data-api" title="Aurora PostgreSQL (Data API)"><img src="docs/static/img/databases/postgresql.svg" alt="Aurora PostgreSQL (Data API)" width="76" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/azure-data-explorer" title="Azure Data Explorer"><img src="docs/static/img/databases/kusto.png" alt="Azure Data Explorer" width="40" height="40" /></a>
|
||||
|
||||
+57
-22
@@ -24,6 +24,34 @@ assists people when migrating to a new version.
|
||||
|
||||
## Next
|
||||
|
||||
### Tagging is on by default
|
||||
|
||||
`TAGGING_SYSTEM` now ships **on**. The Tags menu entry, the tag columns and
|
||||
filters on the chart, dashboard and saved-query lists, and the Tags field in the
|
||||
chart and dashboard property modals are all visible without configuration, and
|
||||
tags are included in asset export and import.
|
||||
|
||||
**What operators should expect:**
|
||||
|
||||
- **Implicit tags accrue.** Saving a chart, dashboard, dataset or saved query,
|
||||
and favoriting an asset, write rows to `tag` and `tagged_object` (`type:chart`,
|
||||
`editor:<user id>`, `favorited_by:<user id>`). These have always been created
|
||||
when the flag was on; they are simply no longer opt-in.
|
||||
- **Exports gain a `tags` key and a `tags.yaml` file.** Chart and dashboard
|
||||
export bundles carry custom tags. Importers on 6.0 and later understand both;
|
||||
older importers skip the unrecognized `tags.yaml` file but reject chart and
|
||||
dashboard YAML that contains a `tags` key, so strip that key before importing
|
||||
a bundle into Superset 5.x or earlier.
|
||||
- **The flag is honored at write time.** The tagging SQLA event listeners are
|
||||
always attached at startup; the ones that create tags check `TAGGING_SYSTEM`
|
||||
when they fire, so the flag, including a runtime override through
|
||||
`GET_FEATURE_FLAGS_FUNC` or `IS_FEATURE_ENABLED_FUNC`, takes effect without a
|
||||
restart. The cleanup listeners run regardless of the flag, so deleting an
|
||||
asset never leaves orphaned `tagged_object` rows behind.
|
||||
|
||||
Set `FEATURE_FLAGS = {"TAGGING_SYSTEM": False}` to restore the previous
|
||||
behavior. Existing tag rows are left untouched.
|
||||
|
||||
### Global Async Queries re-platformed onto the Global Task Framework (breaking)
|
||||
|
||||
Global Async Queries (GAQ) no longer runs on its own bespoke async-events
|
||||
@@ -202,8 +230,7 @@ before retrying. Preview or recheck failures fail closed rather than treating
|
||||
unknown impact as zero. Chart and dashboard purge endpoints are unchanged.
|
||||
|
||||
- The dashboard datasource-based visibility fallback now fails closed: a dashboard whose member charts’ datasources cannot be resolved (deleted datasource rows, missing `datasource_id`, or unsupported datasource types) is no longer accessible to users without explicit editor/viewer rights, and a dashboard composed of semantic-view charts now requires `datasource_access` on (at least one of) its semantic views or their parent semantic layer — previously any authenticated user could open such a dashboard’s shell. Because the fallback now considers every member chart rather than only table-backed ones, a user holding `datasource_access` on any single member datasource — including a semantic view or its parent layer — can open a mixed dashboard that previously denied them. Dashboards with no charts remain accessible, and dashboards with explicit viewers are unaffected. Conversely, holders of `all_datasource_access` now see every published no-viewer dashboard in the dashboard list — including chart-less ones previously hidden by the inner joins — matching what the object-level gate already allowed them to open.
|
||||
- As the `ascend.io` platform shut down, its DB integration has been removed. Any existing users
|
||||
using `ascend://` DB protocol should switch to compatible `impala://` or preferentially remove the connection.
|
||||
- Version restore (`POST /api/v1/{chart,dashboard,dataset}/<uuid>/versions/<version_uuid>/restore`) now refuses an **externally managed** entity (`is_managed_externally = True`) with HTTP 403, enforcing server-side what the docs already promised. Previously the refusal existed only in the browser, so an otherwise-authorized editor could restore such an entity by calling the endpoint directly and have the restore overwritten on the next external sync. Soft-delete recovery is deliberately unaffected — it changes visibility, not content.
|
||||
- `SAMPLES_ROW_LIMIT` is now the default for `/datasource/samples` requests without a valid explicit `per_page`, rather than a hard per-request ceiling; explicit limits are honored up to the existing global row-limit ceiling, matching `/chart/data` SAMPLES requests.
|
||||
- The `cockroachdb` extra (`pip install apache-superset[cockroachdb]`) now installs `sqlalchemy-cockroachdb` instead of the abandoned `cockroachdb` package, whose SQLAlchemy dialect could not be imported under SQLAlchemy 2.0. Existing environments with the old package installed should `pip uninstall cockroachdb && pip install sqlalchemy-cockroachdb` (or simply reinstall the extra) to restore CockroachDB connectivity.
|
||||
|
||||
@@ -511,31 +538,37 @@ Note that a retried query returns partial data with no truncation indicator
|
||||
(e.g. a filter dropdown may list only a subset of values on tables above the
|
||||
row cap).
|
||||
|
||||
### Dashboard "Export Data to Excel" requires a Celery worker and S3 bucket
|
||||
### Dashboard Excel exports support direct downloads
|
||||
|
||||
A new dashboard action exports every chart's data to a single multi-sheet
|
||||
`.xlsx` asynchronously. It is disabled by default and turns on only when
|
||||
`EXCEL_EXPORT_S3_BUCKET` is set (the endpoint returns `501` otherwise). It also
|
||||
requires a running Celery worker and a configured SMTP transport, since the task
|
||||
emails the requesting user a pre-signed download link. New config keys:
|
||||
`EXCEL_EXPORT_S3_BUCKET`, `EXCEL_EXPORT_S3_KEY_PREFIX`,
|
||||
`.xlsx`. Without an export bucket, Superset builds the workbook during the
|
||||
request and returns it to the browser. When `EXCEL_EXPORT_S3_BUCKET` is set, a
|
||||
Celery worker builds and uploads the workbook, then emails the user a pre-signed
|
||||
download link. This queued path also needs a worker and SMTP transport.
|
||||
|
||||
Direct downloads are limited by `EXCEL_EXPORT_SYNC_MAX_ROWS` (default
|
||||
`100_000`), based on the combined `row_limit` of the planned queries. Superset
|
||||
uses `ROW_LIMIT` when a query omits its limit and returns `400` before querying
|
||||
if the total exceeds the limit. Image exports also return `400` without an export
|
||||
bucket because they require background webdriver rendering.
|
||||
|
||||
`POST /api/v1/dashboard/<id>/export_xlsx/` returns either `202` with a queued job
|
||||
id or `200` with the workbook. It no longer returns `501` when no bucket is set.
|
||||
|
||||
New config keys: `EXCEL_EXPORT_S3_BUCKET`, `EXCEL_EXPORT_S3_KEY_PREFIX`,
|
||||
`EXCEL_EXPORT_LINK_TTL_SECONDS`, `EXCEL_EXPORT_S3_CLIENT_KWARGS`,
|
||||
`EXCEL_EXPORT_TABLE_VIZ_TYPES`, and `EXCEL_EXPORT_QUERY_CONTEXT_BUILDER`.
|
||||
`EXCEL_EXPORT_SYNC_MAX_ROWS`, `EXCEL_EXPORT_TABLE_VIZ_TYPES`, and
|
||||
`EXCEL_EXPORT_QUERY_CONTEXT_BUILDER`.
|
||||
|
||||
The feature depends on `boto3`, which is **not** installed by default; install it
|
||||
with `pip install apache-superset[excel-export]`.
|
||||
The queued path depends on `boto3`, which is **not** installed by default; install
|
||||
it with `pip install apache-superset[excel-export]`. The direct-download path
|
||||
does not use it.
|
||||
|
||||
Charts store their `query_context` only once they have been (re-)saved in
|
||||
Explore, so older charts may have none. For a fixed, conservative set of viz
|
||||
types (`table`, `big_number_total`, `big_number`, `pie`) the export rebuilds a
|
||||
query context from the chart's saved form data so those charts still export.
|
||||
The rebuild is a single-query mapping and does **not** reproduce plugin
|
||||
post-processing (pivot, rolling, forecast) or multi-query charts, so any chart of
|
||||
another type without a saved query context is skipped and listed in the email for
|
||||
the user to re-save. To cover those types, set `EXCEL_EXPORT_QUERY_CONTEXT_BUILDER`
|
||||
to a callable that receives the chart's form data and returns a query-context
|
||||
payload (or `None` to fall back to the built-in rebuild) — for example one backed
|
||||
by a service that runs the chart's real frontend `buildQuery`.
|
||||
For `table`, `big_number_total`, `big_number`, and `pie` charts without a saved
|
||||
`query_context`, Superset rebuilds a single query from saved form data. Charts
|
||||
that need post-processing or multiple queries are skipped and listed on the
|
||||
workbook's "Export Summary" sheet. Use `EXCEL_EXPORT_QUERY_CONTEXT_BUILDER` to
|
||||
support more chart types.
|
||||
|
||||
A second mode, **Export Images to Excel**, embeds non-table charts as rendered
|
||||
images (which viz types stay tabular is controlled by
|
||||
@@ -1206,6 +1239,8 @@ Custom time ranges that use the "Now" or "Today" anchor (for the Start, End, or
|
||||
|
||||
Charts and dashboards using these anchors will compute a different (correct) timestamp after upgrading; if a chart's filters or drill-downs were tuned to compensate for the old offset, review them after upgrading.
|
||||
|
||||
- [43916](https://github.com/apache/superset/pull/43916): The `docker-compose` dev loop now skips re-running `superset load_examples` on every `docker compose up` once the example data and dashboards are present in the databases (set `SUPERSET_FORCE_LOAD_EXAMPLES=yes` to reload them anyway), and the `superset-node` service now defaults `DISABLE_TS_CHECKER=true` like `docker-compose-light.yml` already did, skipping webpack's TypeScript type-checking pass in dev by default.
|
||||
|
||||
## 6.1.0
|
||||
|
||||
### ClickHouse minimum driver version bump
|
||||
|
||||
@@ -138,6 +138,7 @@ services:
|
||||
condition: service_started
|
||||
volumes: *superset-volumes
|
||||
environment:
|
||||
SUPERSET_FORCE_LOAD_EXAMPLES: "${SUPERSET_FORCE_LOAD_EXAMPLES:-}"
|
||||
DATABASE_HOST: db-light
|
||||
DATABASE_DB: superset_light
|
||||
POSTGRES_DB: superset_light
|
||||
|
||||
@@ -183,6 +183,8 @@ services:
|
||||
condition: service_started
|
||||
user: *superset-user
|
||||
volumes: *superset-volumes
|
||||
environment:
|
||||
SUPERSET_FORCE_LOAD_EXAMPLES: "${SUPERSET_FORCE_LOAD_EXAMPLES:-}"
|
||||
healthcheck:
|
||||
disable: true
|
||||
|
||||
@@ -202,6 +204,7 @@ services:
|
||||
BUILD_SUPERSET_FRONTEND_IN_DOCKER: true
|
||||
NPM_RUN_PRUNE: false
|
||||
SCARF_ANALYTICS: "${SCARF_ANALYTICS:-}"
|
||||
DISABLE_TS_CHECKER: "${DISABLE_TS_CHECKER:-true}"
|
||||
# configuring the dev-server to use the host.docker.internal to connect to the backend
|
||||
superset: "http://superset:8088"
|
||||
# Webpack dev server must bind to 0.0.0.0 to be accessible from outside the container
|
||||
|
||||
@@ -73,6 +73,12 @@ SUPERSET_ENV=development
|
||||
# Swagger UI is opt-in (off by default); enable it for local development.
|
||||
SUPERSET_ENABLE_SWAGGER_UI=true
|
||||
SUPERSET_LOAD_EXAMPLES=yes
|
||||
# Once the example data and dashboards are present in the databases,
|
||||
# `docker-init.sh` skips `superset load_examples` on later runs. Set to "yes"
|
||||
# (or run `SUPERSET_FORCE_LOAD_EXAMPLES=yes docker compose up`) to reload the
|
||||
# examples anyway, e.g. after changing the example datasets or after a partial
|
||||
# load.
|
||||
#SUPERSET_FORCE_LOAD_EXAMPLES=no
|
||||
CYPRESS_CONFIG=false
|
||||
SUPERSET_PORT=8088
|
||||
MAPBOX_API_KEY=''
|
||||
|
||||
+33
-3
@@ -66,14 +66,44 @@ echo_step "3" "Starting" "Setting up roles and perms"
|
||||
superset init
|
||||
echo_step "3" "Complete" "Setting up roles and perms"
|
||||
|
||||
# Loading examples parses and inserts every example dataset, chart and
|
||||
# dashboard and is one of the slowest steps of `docker compose up`. Rather
|
||||
# than trusting a marker file (which goes stale as soon as the database volume
|
||||
# is recreated), ask the databases themselves: when both the example data and
|
||||
# the dashboards imported from it are present, the previous load completed and
|
||||
# there is nothing left to redo. Any failure here (missing tables, unreachable
|
||||
# database, import error) simply reports "not loaded" so the full load runs.
|
||||
examples_already_loaded() {
|
||||
python - <<'PY' 2>/dev/null
|
||||
import sys
|
||||
|
||||
from superset.app import create_app
|
||||
from superset.sql.parse import Table
|
||||
|
||||
app = create_app()
|
||||
with app.app_context():
|
||||
from superset import db
|
||||
from superset.models.dashboard import Dashboard
|
||||
from superset.utils.database import get_example_database
|
||||
|
||||
has_dashboard = (
|
||||
db.session.query(Dashboard).filter_by(slug="world_health").first() is not None
|
||||
)
|
||||
has_data = get_example_database().has_table(Table("wb_health_population"))
|
||||
sys.exit(0 if has_dashboard and has_data else 1)
|
||||
PY
|
||||
}
|
||||
|
||||
if [ "$SUPERSET_LOAD_EXAMPLES" = "yes" ]; then
|
||||
# Load some data to play with
|
||||
echo_step "4" "Starting" "Loading examples"
|
||||
|
||||
|
||||
# If Cypress run which consumes superset_test_config – load required data for tests
|
||||
# Cypress runs always load, since they need a distinct set of test data
|
||||
# (`--load-test-data`) in a separate database. Set
|
||||
# SUPERSET_FORCE_LOAD_EXAMPLES=yes to reload the examples regardless.
|
||||
if [ "$CYPRESS_CONFIG" == "true" ]; then
|
||||
superset load_examples --load-test-data
|
||||
elif [ "$SUPERSET_FORCE_LOAD_EXAMPLES" != "yes" ] && examples_already_loaded; then
|
||||
echo "Examples already loaded, skipping (set SUPERSET_FORCE_LOAD_EXAMPLES=yes to reload them)"
|
||||
else
|
||||
superset load_examples
|
||||
fi
|
||||
|
||||
@@ -476,6 +476,16 @@ to determine which hosts are internal.
|
||||
|
||||
There are many reasons that reports might not be working. Try these steps to check for specific issues.
|
||||
|
||||
### Blank PDF or PNG captures
|
||||
|
||||
Playwright report captures are checked for blank image content as well as chart
|
||||
readiness. Captures detected as blank where chart content is expected are retried
|
||||
up to three total attempts, within the execution deadline. If they remain blank,
|
||||
the report fails instead of delivering the blank or partial attachment. This also
|
||||
applies to alerts that attach reports. Check worker logs for
|
||||
`ScreenshotBlankCaptureError` and `report_capture_validation` when investigating
|
||||
these failures.
|
||||
|
||||
### Confirm feature flag is enabled and you have sufficient permissions
|
||||
|
||||
If you don't see "Alerts & Reports" under the _Manage_ section of the Settings dropdown in the Superset UI, you need to enable the `ALERT_REPORTS` feature flag (see above). Enable another feature flag and check to see that it took effect, to verify that your config file is getting loaded.
|
||||
@@ -486,6 +496,39 @@ Log in as an admin user to ensure you have adequate permissions.
|
||||
|
||||
This is the best source of information about the problem. In a docker compose deployment, you can do this with a command like `docker logs superset_worker --since 1h`.
|
||||
|
||||
### CSV and Excel chart-data request failures
|
||||
|
||||
The worker uses the saved query context to POST to the chart-data export endpoint,
|
||||
falling back to the legacy GET export when a query context cannot be generated.
|
||||
`ALERT_REPORTS_CSV_REQUEST_TIMEOUT` (60 seconds by default) limits socket operations;
|
||||
the report execution budget and its delivery/cleanup reserves also cap the request.
|
||||
Connection and read timeouts are reported as CSV/Excel generation timeouts.
|
||||
These attachment timeouts are logged at error level and explicitly mark the report
|
||||
task as failed, while the report execution retains its ERROR state and separate
|
||||
error-notification history. Other HTTP 408 exception handling is unchanged.
|
||||
|
||||
To tolerate short-lived transport failures, operators can opt in with
|
||||
`ALERT_REPORTS_CSV_REQUEST_RETRY = True` (default: `False`). This permits **one** retry
|
||||
for transient connection/read failures and HTTP 429, 500, 502, 503, or 504. Other
|
||||
HTTP statuses are not retried. Backoff is 0.5 seconds, extended to at most 2 seconds
|
||||
for a numeric `Retry-After`; longer, invalid, or date-based delays are not retried
|
||||
inline. Both attempts and backoff share the initial request timeout allowance and
|
||||
respect the remaining execution budget. Unbounded requests are not retried.
|
||||
A request that consumes its entire timeout does **not** get another full timeout.
|
||||
Socket timeouts are not wall-clock cancellation: existing report task limits still
|
||||
interrupt in-flight work. A timed-out server query can continue running, so enabling
|
||||
retries can increase database load. Leave retries disabled unless appropriate for
|
||||
your deployment; disable the setting to roll back retry behavior.
|
||||
|
||||
Worker diagnostics include schedule/chart identifiers, a fixed endpoint path (no
|
||||
query string), error category, HTTP status, timeout, elapsed duration, and attempt.
|
||||
For HTTP errors, at most 4097 response bytes are read to enforce a 4096-byte limit.
|
||||
Only recognized Superset error types from up to four JSON errors are retained;
|
||||
free-form messages, extra fields, and non-JSON or oversized bodies are redacted or
|
||||
omitted. Cookies, authentication headers, URLs, SQL, and query payloads are not
|
||||
included in these transport diagnostics. HTTP 400 therefore remains a failure to
|
||||
investigate, not a reason to repeat the same request.
|
||||
|
||||
### Check web browser and webdriver installation
|
||||
|
||||
To take a screenshot, the worker visits the dashboard or chart using a headless browser, then takes a screenshot. If you are able to send a chart as CSV, XLSX, or text but can't send as PNG, your problem may lie with the browser.
|
||||
|
||||
@@ -540,6 +540,8 @@ MCP_STORE_CONFIG = {
|
||||
|
||||
When `CACHE_REDIS_URL` is set, the MCP server uses a Redis-backed EventStore for session management, allowing replicas to share state. Without Redis, each pod manages its own in-memory sessions and stateful MCP interactions may fail when requests hit different replicas.
|
||||
|
||||
`MCP_STATELESS_HTTP` (default `True`) controls whether requests get a fresh, ephemeral transport per HTTP round trip or a transport that stays alive for the session's lifetime. The default suits multi-pod deployments because it doesn't require session affinity -- any pod can handle any request. Its tradeoff: a client disconnecting mid-tool-call can crash not just its own session but other concurrent sessions on the same worker. Setting it to `False` avoids that, but it requires session-affinity (sticky session) routing on `Mcp-Session-Id` at the mesh/ingress layer, since a session's follow-up requests must land on the same pod that created it. See [`MCP_STATELESS_HTTP`](#core) below.
|
||||
|
||||
---
|
||||
|
||||
## Configuration Reference
|
||||
@@ -555,6 +557,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_STATELESS_HTTP` | `True` | Streamable-HTTP session mode. `True` gives each request a fresh, ephemeral transport, torn down as soon as that request completes; a client disconnecting mid-tool-call can crash not just its own session but other concurrent sessions on the same worker. `False` keeps the transport alive for the session's lifetime, avoiding that crash, but requires session-affinity routing on `Mcp-Session-Id` for multi-pod deployments (see [Multi-Pod (Kubernetes)](#multi-pod-kubernetes)). |
|
||||
| `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. |
|
||||
| `MCP_DISABLED_TOOLS` | `set()` | Set of tool names to remove from the MCP server at startup. Disabled tools are never advertised to AI clients during tool discovery. Useful when a custom extension tool should replace a built-in Superset tool. See [Disabling built-in tools](#disabling-built-in-tools). |
|
||||
| `MCP_DISABLED_CHART_PLUGINS` | `frozenset()` | Set of chart type plugin names (e.g. `"handlebars"`) to hide from `generate_chart`. Does not affect `get_chart_type_schema`. See [Disabling chart type plugins](#disabling-chart-type-plugins). |
|
||||
@@ -951,7 +954,11 @@ Specifying a tool name that does not exist logs a warning at startup and is othe
|
||||
|
||||
## Disabling chart type plugins
|
||||
|
||||
The `generate_chart` tool dispatches per chart type (`xy`, `table`, `pie`, `pivot_table`, `mixed_timeseries`, `handlebars`, `big_number`, `histogram`, `box_plot`, `waterfall`) to a registered chart type plugin. Two settings let operators enable or disable individual chart type plugins at runtime, without a code deploy.
|
||||
The `generate_chart` tool dispatches per chart type (`xy`, `table`, `pie`, `gauge`, `pivot_table`, `interactive_pivot`, `mixed_timeseries`, `handlebars`, `big_number`, `histogram`, `box_plot`, `waterfall`) to a registered chart type plugin. Gauge requests use the public MCP discriminator `chart_type: "gauge"`; Superset stores the corresponding native Explore visualization as `viz_type: "gauge_chart"`. Two settings let operators enable or disable individual chart type plugins at runtime, without a code deploy.
|
||||
|
||||
Gauge data inspection and JSON/CSV/XLSX exports preserve source groups, including NULL and non-finite metric values, using the same row-count and completeness semantics as other chart types. The default XLSX exporter writes non-finite floats as `nan`, `inf`, or `-inf` text, matching CSV and distinguishing them from blank NULL cells. Only previews and compile checks skip NULL, NaN, non-finite, and other nonnumeric dial values while preserving finite groups. In preview/compile paths, a nonempty result containing no finite dial returns an error; genuinely empty results retain the no-data behavior. Compile checks inspect the configured dial limit (at most 10), rather than only two groups. Grouped Vega previews center each needle within its own facet and extend it to the midpoint of the dial band. Automatic all-zero ranges span 0–1. Empty or whitespace-only temporal ranges, like `No filter`, are neutral sentinels; missing or non-string native temporal comparators are invalid.
|
||||
|
||||
Gauge previews retain data-derived automatic bounds even when configured interval thresholds extend beyond the visible range; Vega previews clip those thresholds into adjacent, non-overlapping bands. Explicit min/max bounds still constrain intervals. All-zero data with both bounds omitted uses a nondegenerate preview range of 0–1. On same-dataset Gauge updates, clearing or changing the dashboard temporal binding preserves user-authored temporal ranges; dataset rebinds discard old query roles and filters. The native `"No filter"` sentinel is a neutral dashboard temporal binding, not a conflicting restriction. Duplicate generated neutral bindings self-heal on updates without removing user-authored ranges. Restating the existing dataset ID without a config is allowed; changing the Gauge dataset still requires a complete config. Native restrictive temporal filters that conflict with the top-level range or another restrictive temporal filter are rejected rather than silently dropped. Unsupported native filter operators are rejected with an indexed error. Native `TEMPORAL_RANGE` adhoc filters require an explicit string comparator; `"No filter"`, empty strings, and whitespace represent an unrestricted range.
|
||||
|
||||
### Static deny-list
|
||||
|
||||
|
||||
@@ -138,6 +138,18 @@ The existing `APP_NAME` Python config key continues to work for backward compati
|
||||
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.
|
||||
|
||||
To hide the entire brand area in the navbar (both the logo image and the
|
||||
brand text), set `HIDE_NAVBAR_LOGO` in `superset_config.py`:
|
||||
|
||||
```python
|
||||
# Hide the entire brand area in the navbar, including the logo image and the
|
||||
# brand text (brandAppName / APP_NAME). Defaults to False.
|
||||
HIDE_NAVBAR_LOGO = True
|
||||
```
|
||||
|
||||
`HIDE_NAVBAR_LOGO` is a Python config flag rather than a theme token, so it
|
||||
cannot be set through the theme CRUD UI or `THEME_DEFAULT`/`THEME_DARK`.
|
||||
|
||||
### Migration from Configuration to UI
|
||||
|
||||
When `ENABLE_UI_THEME_ADMINISTRATION = True`:
|
||||
@@ -487,6 +499,118 @@ THEME_DEFAULT = {
|
||||
|
||||
This feature provides powerful theming capabilities while maintaining the flexibility of ECharts' extensive configuration options.
|
||||
|
||||
## Component Sizing & Style Tokens
|
||||
|
||||
:::note
|
||||
These tokens landed after the Superset 6.1 release and are only available on
|
||||
`master`; they are not present in any tagged release yet.
|
||||
:::
|
||||
|
||||
Beyond colors and fonts, a handful of Superset-specific tokens let you tune the
|
||||
sizing, radius, and outline behavior of individual UI components. All of these
|
||||
tokens are optional — omit them and components fall back to their existing
|
||||
defaults, so applying them is a zero-visual-change operation until you opt in.
|
||||
|
||||
### Button & DropdownButton Sizing
|
||||
|
||||
```python
|
||||
THEME_DEFAULT = {
|
||||
"token": {
|
||||
# ... other tokens
|
||||
"buttonControlHeight": 32, # default button height, in px
|
||||
"buttonControlHeightSM": 30, # small/dropdown button height, in px
|
||||
"buttonControlHeightXS": 22, # xsmall button height, in px
|
||||
"buttonPaddingInline": 18, # horizontal padding, in px
|
||||
"buttonPaddingInlineSM": 10, # horizontal padding for small buttons, in px
|
||||
"buttonFontSize": 14,
|
||||
"buttonBorderRadius": 4,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`buttonControlHeight` and `buttonBorderRadius` also drive the sizing of the
|
||||
menu-trigger button used by `PageHeaderWithActions`, so a single pair of tokens
|
||||
keeps page-header icon buttons visually consistent with regular buttons.
|
||||
|
||||
For one-off overrides that shouldn't apply to every button in the app, pass a
|
||||
`styleConfig` prop directly to `Button` or `DropdownButton` instead of setting
|
||||
a theme token:
|
||||
|
||||
```tsx
|
||||
<Button
|
||||
styleConfig={{
|
||||
controlHeight: 40,
|
||||
paddingInline: 20,
|
||||
fontSize: 16,
|
||||
fontWeight: 700,
|
||||
borderRadius: 8,
|
||||
ctaMinWidth: 120,
|
||||
ctaMinHeight: 40,
|
||||
iconGap: 8,
|
||||
}}
|
||||
>
|
||||
Click me
|
||||
</Button>
|
||||
|
||||
<DropdownButton
|
||||
styleConfig={{
|
||||
controlHeight: 32,
|
||||
fontSize: 14,
|
||||
fontWeight: 500,
|
||||
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
||||
}}
|
||||
menu={menuProps}
|
||||
>
|
||||
Options
|
||||
</DropdownButton>
|
||||
```
|
||||
|
||||
`styleConfig` values take precedence over the equivalent theme tokens, which in
|
||||
turn take precedence over the built-in defaults.
|
||||
|
||||
### Label Border Radius
|
||||
|
||||
```python
|
||||
THEME_DEFAULT = {
|
||||
"token": {
|
||||
"labelBorderRadius": 4, # defaults to 8px
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Select Option Outline
|
||||
|
||||
By default, hovering or navigating to an option in a `Select` dropdown draws a
|
||||
2px outline in `colorPrimary`. Set `selectOptionActiveOutline` to `False` for a
|
||||
more subtle hover style with no outline:
|
||||
|
||||
```python
|
||||
THEME_DEFAULT = {
|
||||
"token": {
|
||||
"selectOptionActiveOutline": False,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Dashboard Tile Appearance
|
||||
|
||||
Chart tiles on a dashboard (not text/markdown tiles) can be restyled via
|
||||
`dashboardTile*` tokens. All fall back to the existing look — a
|
||||
`colorBgContainer` background, a `1px solid colorBorder` border, and a
|
||||
hairline `box-shadow` while the tile is fading out (e.g. when a filter
|
||||
makes it irrelevant):
|
||||
|
||||
```python
|
||||
THEME_DEFAULT = {
|
||||
"token": {
|
||||
"dashboardTileBg": "#ffffff",
|
||||
"dashboardTileBorder": "1px solid #e0e0e0",
|
||||
"dashboardTileBorderRadius": 8,
|
||||
"dashboardTileBoxShadow": "0 1px 2px rgba(0, 0, 0, 0.08)",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced Features
|
||||
|
||||
- **System Themes**: Manage system-wide default and dark themes via UI or configuration
|
||||
|
||||
@@ -196,7 +196,9 @@ One important variable is `SUPERSET_LOAD_EXAMPLES` which determines whether the
|
||||
container will populate example data and visualizations into the metadata database. These examples
|
||||
are helpful for learning and testing out Superset but unnecessary for experienced users and
|
||||
production deployments. The loading process can sometimes take a few minutes and a good amount of
|
||||
CPU, so you may want to disable it on a resource-constrained device.
|
||||
CPU, so you may want to disable it on a resource-constrained device. Once the example data and
|
||||
dashboards are present in the databases, later `superset_init` runs skip loading them; run
|
||||
`SUPERSET_FORCE_LOAD_EXAMPLES=yes docker compose up` to reload the examples anyway.
|
||||
|
||||
For more advanced or dynamic configurations that are typically managed in a `superset_config.py` file
|
||||
located in your `PYTHONPATH`, note that it can be done by providing a
|
||||
@@ -215,7 +217,7 @@ If you have a good solution for this, let us know!
|
||||
:::
|
||||
|
||||
:::note
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/scarf-gateway) to collect telemetry
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/) to collect telemetry
|
||||
data. Knowing the installation counts for different Superset versions informs the project's
|
||||
decisions about patching and long-term support. Scarf purges personally identifiable information
|
||||
(PII) and provides only aggregated statistics.
|
||||
|
||||
@@ -87,6 +87,7 @@ The chart will publish appropriate services to expose the Superset UI internally
|
||||
|
||||
- Configure the Service as a `LoadBalancer` or `NodePort`
|
||||
- Set up an `Ingress` for it - the chart includes a definition, but will need to be tuned to your needs (hostname, tls, annotations etc...)
|
||||
- Set up a Gateway API `HTTPRoute` for it - see [Exposing Superset via Gateway API (HTTPRoute)](#exposing-superset-via-gateway-api-httproute) below
|
||||
- Run `kubectl port-forward superset-xxxx-yyyy :8088` to directly tunnel one pod's port into your localhost
|
||||
|
||||
Depending how you configured external access, the URL will vary. Once you've identified the appropriate URL you can log in with:
|
||||
@@ -135,7 +136,7 @@ init:
|
||||
```
|
||||
|
||||
:::note
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/scarf-gateway) to collect telemetry data. Knowing the installation counts for different Superset versions informs the project's decisions about patching and long-term support. Scarf purges personally identifiable information (PII) and provides only aggregated statistics.
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/) to collect telemetry data. Knowing the installation counts for different Superset versions informs the project's decisions about patching and long-term support. Scarf purges personally identifiable information (PII) and provides only aggregated statistics.
|
||||
|
||||
There are two independent telemetry channels:
|
||||
|
||||
@@ -319,6 +320,53 @@ configOverrides:
|
||||
AUTH_USER_REGISTRATION_ROLE = "Admin"
|
||||
```
|
||||
|
||||
### Exposing Superset via Gateway API (HTTPRoute)
|
||||
|
||||
As an alternative to `Ingress`, the chart can create a [Gateway API](https://gateway-api.sigs.k8s.io/)
|
||||
`HTTPRoute` that attaches to a Gateway already running in your cluster. This requires the Gateway
|
||||
API CRDs serving the configured `httproute.apiVersion` (`gateway.networking.k8s.io/v1` by default)
|
||||
to be installed, along with a Gateway resource for the route to attach to. If the Gateway lives in
|
||||
a different namespace than the `HTTPRoute` (as in the
|
||||
example below), its listener's `allowedRoutes` must explicitly permit routes from this release's
|
||||
namespace, or the `HTTPRoute` will install successfully but never attach.
|
||||
|
||||
```yaml
|
||||
httproute:
|
||||
enabled: true
|
||||
parentRefs:
|
||||
- name: my-gateway
|
||||
namespace: gateway-system
|
||||
hostnames:
|
||||
- superset.example.com
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
```
|
||||
|
||||
- `httproute.parentRefs` lists the Gateway(s) the route attaches to.
|
||||
- `httproute.hostnames` matches against the HTTP `Host` header; it's templated, so values like
|
||||
`{{ .Release.Name }}` can be used.
|
||||
- `httproute.rules` are routing rules backed by the Superset service; each rule accepts standard
|
||||
`matches`, `filters`, and `timeouts` fields, and an optional `weight` (defaults to `1`) applied to
|
||||
its single backend reference. Since each rule maps to one backend, `weight` has no traffic-splitting
|
||||
effect here; it only matters if you fork the template to add multiple `backendRefs` to a rule.
|
||||
`timeouts` only joined the Gateway API Standard channel in v1.2, so it requires both v1.2+ CRDs
|
||||
and a supporting controller; drop it if either predates that.
|
||||
- If `supersetWebsockets.enabled` is set, an extra rule routing `supersetWebsockets.ingress.path`
|
||||
(default `/ws`) to the `-ws` service is appended automatically, mirroring the `Ingress` behavior.
|
||||
WebSocket upgrade support is controller-dependent under Gateway API; check your Gateway
|
||||
implementation's docs in case it needs an explicit protocol opt-in for global async queries to
|
||||
keep working behind a Gateway.
|
||||
- If `supersetMcp.enabled` and `supersetMcp.httproute.enabled` are both set, an extra rule routing
|
||||
`supersetMcp.httproute.path` to the `-mcp` service is appended as well. Don't expose this route
|
||||
without first enabling MCP authentication — see the
|
||||
[MCP Server Deployment & Authentication](/admin-docs/configuration/mcp-server#authentication) doc;
|
||||
by default the MCP server runs in dev mode with auth disabled.
|
||||
- Set `httproute.apiVersion` to `gateway.networking.k8s.io/v1beta1` if your cluster's Gateway API
|
||||
installation hasn't promoted `HTTPRoute` to `v1` yet.
|
||||
|
||||
### Enable Alerts and Reports
|
||||
|
||||
For this, as per the [Alerts and Reports doc](/admin-docs/configuration/alerts-reports), you will need to:
|
||||
|
||||
@@ -215,7 +215,7 @@ If you have a good solution for this, let us know!
|
||||
:::
|
||||
|
||||
:::note
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/scarf-gateway) to collect telemetry
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/) to collect telemetry
|
||||
data. Knowing the installation counts for different Superset versions informs the project's
|
||||
decisions about patching and long-term support. Scarf purges personally identifiable information
|
||||
(PII) and provides only aggregated statistics.
|
||||
|
||||
@@ -135,7 +135,7 @@ init:
|
||||
```
|
||||
|
||||
:::note
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/scarf-gateway) to collect telemetry data. Knowing the installation counts for different Superset versions informs the project's decisions about patching and long-term support. Scarf purges personally identifiable information (PII) and provides only aggregated statistics.
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/) to collect telemetry data. Knowing the installation counts for different Superset versions informs the project's decisions about patching and long-term support. Scarf purges personally identifiable information (PII) and provides only aggregated statistics.
|
||||
|
||||
To opt-out of this data collection in your Helm-based installation, edit the `repository:` line in your `helm/superset/values.yaml` file, replacing `apachesuperset.docker.scarf.sh/apache/superset` with `apache/superset` to pull the image directly from Docker Hub.
|
||||
:::
|
||||
|
||||
@@ -99,11 +99,16 @@ Affecting the Docker build process:
|
||||
- **INCLUDE_CHROMIUM (default=false):** whether to include the Chromium headless browser in the build
|
||||
- **BUILD_TRANSLATIONS(default=false):** whether to compile the translations from the .po files available
|
||||
- **SUPERSET_LOAD_EXAMPLES (default=yes):** whether to load the examples into the database upon startup,
|
||||
save some precious time on startup by `SUPERSET_LOAD_EXAMPLES=no docker compose up`
|
||||
save some precious time on startup by `SUPERSET_LOAD_EXAMPLES=no docker compose up`. Once the example
|
||||
data and dashboards are present in the databases, later `docker compose up` runs skip loading
|
||||
them; run `SUPERSET_FORCE_LOAD_EXAMPLES=yes docker compose up` to reload the examples anyway.
|
||||
- **SUPERSET_LOG_LEVEL (default=info)**: Can be set to debug, info, warning, error, critical
|
||||
for more verbose logging
|
||||
- **SUPERSET_DEBUG_ENABLED (default=false)**: Enable Werkzeug debugger with interactive console.
|
||||
Set to `true` for debugging: `SUPERSET_DEBUG_ENABLED=true docker compose up`
|
||||
- **DISABLE_TS_CHECKER (default=true)**: whether the `superset-node` webpack dev server skips
|
||||
TypeScript type-checking, which speeds up rebuilds and saves several GB of memory. Set to
|
||||
`false` to have webpack surface type errors during development.
|
||||
|
||||
For more env vars that affect your configuration, see this
|
||||
[superset_config.py](https://github.com/apache/superset/blob/master/docker/pythonpath_dev/superset_config.py)
|
||||
|
||||
@@ -159,6 +159,7 @@ single source of truth. The README.md retains its own static copy
|
||||
<a href="/user-docs/databases/supported/apache-pinot" title="Apache Pinot"><img src="/img/databases/apache-pinot.svg" alt="Apache Pinot" width="76" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/apache-solr" title="Apache Solr"><img src="/img/databases/apache-solr.png" alt="Apache Solr" width="79" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/apache-spark-sql" title="Apache Spark SQL"><img src="/img/databases/apache-spark.png" alt="Apache Spark SQL" width="75" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/ascend" title="Ascend"><img src="/img/databases/ascend.webp" alt="Ascend" width="117" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/aurora-mysql-data-api" title="Aurora MySQL (Data API)"><img src="/img/databases/mysql.png" alt="Aurora MySQL (Data API)" width="77" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/aurora-postgresql-data-api" title="Aurora PostgreSQL (Data API)"><img src="/img/databases/postgresql.svg" alt="Aurora PostgreSQL (Data API)" width="76" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/azure-data-explorer" title="Azure Data Explorer"><img src="/img/databases/kusto.png" alt="Azure Data Explorer" width="40" height="40" /></a>
|
||||
|
||||
@@ -379,6 +379,15 @@ AG Grid supports server-side column filters that query the full dataset — not
|
||||
|
||||
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.
|
||||
|
||||
#### Show Summary
|
||||
|
||||
The **Show summary** checkbox lives at the top of the **Visual formatting** section in the **Customize** tab, for both **Aggregate** and **Raw Records** query modes. Enabling it pins a summary row to the bottom of the grid whenever there is something to summarize: at least one metric in **Aggregate** mode, or at least one eligible numeric column in **Raw Records** mode. Otherwise no summary row is added.
|
||||
|
||||
- In **Aggregate** mode, the summary row applies each metric's own aggregation (or the **Summary aggregation** override, where available) across the full filtered dataset.
|
||||
- In **Raw Records** mode, the summary row defaults to a server-side `SUM` for each numeric column that's backed by a physical or calculated dataset column; the **Summary aggregation** control can override this to `AVG` as well. Non-numeric cells and columns built from free-form SQL expressions stay blank.
|
||||
|
||||
In both modes, the summary is computed across the full result set, independent of the chart's row limit and pagination, and it reflects dashboard and chart-level filters. It does not reflect AG Grid's own server-side column filters (the per-column filter UI in the grid header), which are excluded from the summary query.
|
||||
|
||||
### Dynamic Currency Formatting
|
||||
|
||||
Chart metric values can display currencies dynamically rather than using a fixed currency code. To enable:
|
||||
|
||||
@@ -145,3 +145,51 @@ The following URL parameters can be passed through the `urlParams` option in `da
|
||||
- **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.
|
||||
- **Redacted errors** — API responses to a guest token report a generic `An error occurred while fetching the data.` instead of the underlying error, since engine errors quote catalog, schema, table and column names. Errors Superset raises itself — access denials, timeouts, payload validation — keep their message, and the full error is always available in the server logs.
|
||||
|
||||
|
||||
## Guest-token request-header size diagnostics
|
||||
|
||||
A successful guest-token mint does not guarantee the token can pass through your
|
||||
deployment's proxies. Limits apply to the **encoded JWT bytes plus header
|
||||
overhead**, not the number of RLS rules or identifiers. A proxy can reject the
|
||||
subsequent authentication request before it reaches Superset, including an HTTP
|
||||
400 HTML response instead of JSON. A 400 alone does not establish a size problem.
|
||||
|
||||
Operators can set a deployment-specific diagnostic budget in `superset_config.py`:
|
||||
|
||||
```python
|
||||
# Example only: choose a budget for your complete proxy path.
|
||||
GUEST_TOKEN_HEADER_MAX_BYTES = 16 * 1024
|
||||
```
|
||||
|
||||
The default is `None` (no budget warnings). Positive integer budgets count UTF-8
|
||||
bytes of `GUEST_TOKEN_HEADER_NAME`, `: `, the encoded token, and `\r\n`
|
||||
(four framing bytes). Only sizes **strictly greater** than the budget warn;
|
||||
equality does not. This is consistent diagnostic accounting, not a prediction of
|
||||
every proxy's wire-level accounting, HTTP/2 compression, or total-header limits.
|
||||
Leave a safety margin and validate your actual deployment, including custom
|
||||
header names. Zero, negative, non-integral, or non-numeric values (including strings and
|
||||
booleans) disable budget warnings, as do values above JavaScript's maximum safe
|
||||
integer (2^53 − 1). Whole-number floats are accepted. Convert environment-variable
|
||||
strings to integers in deployment configuration to enable the budget.
|
||||
|
||||
Issuance audit metadata includes `token_bytes`, `header_bytes`,
|
||||
`header_budget_bytes`, and `header_budget_exceeded`. Issuance remains HTTP 200
|
||||
with the same token and response shape. The embedded bootstrap exposes the budget
|
||||
and configured header name; reload the iframe after changing deployment config.
|
||||
The embedded client measures initial and refreshed tokens and warns in the
|
||||
developer console with sizes only. Initial authentication failures get a targeted
|
||||
suggestion only when the request's token exceeds the budget and the failure has
|
||||
no status or HTTP 400/431/494; other statuses and ambiguous in-flight
|
||||
refreshes use the generic error. Refresh warnings do not restart authentication.
|
||||
These diagnostics do not record JWTs, decoded claims, RLS SQL, or request headers.
|
||||
|
||||
[AWS Application Load Balancer quotas](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-limits.html)
|
||||
list a non-adjustable 16 K single-header limit. Increasing a Superset diagnostic
|
||||
budget does not increase that limit or add large-token support.
|
||||
|
||||
To reduce payload size, replace large inline RLS ID lists with a compact
|
||||
entitlements-table subquery where supported by your database. Keep the same
|
||||
tenant/user restrictions, derive identity from your trusted token-issuing
|
||||
backend, and verify equivalent row access and query performance before rollout.
|
||||
Do not remove RLS or broaden entitlements to make a token smaller.
|
||||
|
||||
@@ -9,22 +9,31 @@ version: 1
|
||||
|
||||
Superset can export every chart on a dashboard to a single Excel workbook, with
|
||||
each chart's underlying data rendered as its own worksheet. The export reflects
|
||||
the dashboard's currently applied filters and runs asynchronously: when it
|
||||
finishes, the requesting user receives an email with a time-limited download
|
||||
link.
|
||||
the dashboard's currently applied filters.
|
||||
|
||||
How the finished workbook reaches you depends on whether the deployment has
|
||||
export storage configured:
|
||||
|
||||
- **With an export bucket**, a background worker builds the workbook and emails
|
||||
the user a time-limited download link.
|
||||
- **Without an export bucket**, Superset builds the workbook during the request
|
||||
and returns it to the browser. This path only supports data exports within
|
||||
`EXCEL_EXPORT_SYNC_MAX_ROWS` (see [Prerequisites](#prerequisites)).
|
||||
|
||||
## Using the export
|
||||
|
||||
From a dashboard, open the **... (actions) → Download** submenu and choose
|
||||
**Export Data to Excel**. The action appears for users who have the dashboard
|
||||
`can_export` permission. You'll see a confirmation that the export is being
|
||||
prepared; the workbook arrives by email when it's ready.
|
||||
`can_export` permission. Where the export is queued you'll see a confirmation
|
||||
that it is being prepared, then receive the workbook by email. Direct exports
|
||||
download when ready.
|
||||
|
||||
A second option, **Export Images to Excel**, embeds each non-table chart as a
|
||||
rendered image (tables stay tabular) instead of exporting raw data. Because it
|
||||
renders charts through the headless webdriver, this option only appears when the
|
||||
webdriver screenshot feature flags are enabled (see the prerequisites below);
|
||||
which viz types stay tabular is controlled by `EXCEL_EXPORT_TABLE_VIZ_TYPES`.
|
||||
Image exports always run in the background and require an export bucket.
|
||||
|
||||
Notes on the generated workbook:
|
||||
|
||||
@@ -36,31 +45,37 @@ Notes on the generated workbook:
|
||||
re-saved in Explore) still exports when it is a `table`, `big_number`,
|
||||
`big_number_total` or `pie`, by rebuilding the query from the chart's saved
|
||||
form data. Charts of other types — and charts relying on post-processing the
|
||||
rebuild can't reproduce — are skipped and listed in the email; open the chart
|
||||
in Explore and re-save it to include it next time, or configure
|
||||
`EXCEL_EXPORT_QUERY_CONTEXT_BUILDER`.
|
||||
rebuild can't reproduce — are skipped; open the chart in Explore and re-save it
|
||||
to include it next time, or configure `EXCEL_EXPORT_QUERY_CONTEXT_BUILDER`.
|
||||
The workbook's **Export Summary** sheet lists skipped charts. Queued exports
|
||||
also list them in the email.
|
||||
- Row counts per sheet are capped the same way as the chart-level CSV/Excel
|
||||
export (`ROW_LIMIT`, bounded by `SQL_MAX_ROW`), and never exceed Excel's
|
||||
per-sheet maximum.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This feature is **disabled by default**. It requires:
|
||||
Dashboard data exports need no configuration. By default, Superset builds the
|
||||
workbook during the request and returns it to the browser. The combined
|
||||
`row_limit` of its queries must not exceed `EXCEL_EXPORT_SYNC_MAX_ROWS` (100,000
|
||||
by default). Queries without a `row_limit` use `ROW_LIMIT`. Keep this setting
|
||||
within your web server's request timeout.
|
||||
|
||||
For larger data exports and all image exports, configure the background path:
|
||||
|
||||
1. **The `boto3` dependency.** It is not installed by default; install it with
|
||||
`pip install apache-superset[excel-export]`. Without it, exports fail and the
|
||||
user receives a failure email.
|
||||
2. **An S3 bucket.** Set `EXCEL_EXPORT_S3_BUCKET`. Until it is set, the export
|
||||
endpoint returns `501` and the menu action surfaces a "not configured"
|
||||
message.
|
||||
3. **A running Celery worker.** The export runs as a Celery task. If no worker
|
||||
is running, the request is accepted but nothing is produced.
|
||||
2. **An S3 bucket.** Set `EXCEL_EXPORT_S3_BUCKET` to queue exports and deliver
|
||||
them by email.
|
||||
3. **A running Celery worker.** The queued export runs as a Celery task. If no
|
||||
worker is running, the request is accepted but nothing is produced.
|
||||
4. **A configured SMTP transport.** The download link is delivered by email
|
||||
using the same settings as alerts & reports (`SMTP_*`,
|
||||
`EMAIL_REPORTS_SUBJECT_PREFIX`).
|
||||
|
||||
**Export Images to Excel** additionally requires a working headless webdriver —
|
||||
the same infrastructure scheduled reports and thumbnails use (`WEBDRIVER_*`,
|
||||
**Export Images to Excel** also requires the headless webdriver used by scheduled
|
||||
reports and thumbnails (`WEBDRIVER_*`,
|
||||
plus the `ENABLE_DASHBOARD_SCREENSHOT_ENDPOINTS` and
|
||||
`ENABLE_DASHBOARD_DOWNLOAD_WEBDRIVER_SCREENSHOT` feature flags). The menu option
|
||||
is hidden when those flags are off; if the webdriver is unreachable, image
|
||||
@@ -72,14 +87,15 @@ will not register.
|
||||
|
||||
## Configuration keys
|
||||
|
||||
| Key | Default | Description |
|
||||
| ------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `EXCEL_EXPORT_S3_BUCKET` | `None` | Destination bucket. Required; `501` if unset. |
|
||||
| `EXCEL_EXPORT_S3_KEY_PREFIX` | `"dashboard-exports/"` | Key prefix: `{prefix}{dashboard_id}/{job_id}.xlsx`. |
|
||||
| `EXCEL_EXPORT_LINK_TTL_SECONDS` | `86400` | Lifetime of the pre-signed download URL (24h). |
|
||||
| `EXCEL_EXPORT_S3_CLIENT_KWARGS` | `{}` | Extra kwargs for `boto3.client("s3", ...)` — e.g. `region_name`, or `endpoint_url` for MinIO/LocalStack. |
|
||||
| `EXCEL_EXPORT_TABLE_VIZ_TYPES` | `None` | Viz types kept tabular in **Export Images to Excel** mode; every other type is embedded as an image. `None` uses the built-in default (`table`, `pivot_table`, `pivot_table_v2`). |
|
||||
| `EXCEL_EXPORT_QUERY_CONTEXT_BUILDER` | `None` | Optional `Callable[[form_data_dict], dict \| None]` to build a query context for a chart missing a saved one, tried before the built-in form-data rebuild. Point it at a service that runs the chart's real frontend `buildQuery` to faithfully export viz types the built-in rebuild can't handle. Must return `None` when it can't build faithfully, so the export falls back. |
|
||||
| Key | Default | Description |
|
||||
| ------------------------------------ | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `EXCEL_EXPORT_S3_BUCKET` | `None` | Destination bucket. When unset, eligible data exports download directly. |
|
||||
| `EXCEL_EXPORT_SYNC_MAX_ROWS` | `100000` | Maximum combined query `row_limit` for a direct download. Ignored when a bucket is configured. |
|
||||
| `EXCEL_EXPORT_S3_KEY_PREFIX` | `"dashboard-exports/"` | Key prefix: `{prefix}{dashboard_id}/{job_id}.xlsx`. |
|
||||
| `EXCEL_EXPORT_LINK_TTL_SECONDS` | `86400` | Lifetime of the pre-signed download URL (24h). |
|
||||
| `EXCEL_EXPORT_S3_CLIENT_KWARGS` | `{}` | Extra arguments for `boto3.client("s3", ...)`, such as `region_name` or an `endpoint_url` for MinIO or LocalStack. |
|
||||
| `EXCEL_EXPORT_TABLE_VIZ_TYPES` | `None` | Viz types kept tabular in image mode. `None` uses `table`, `pivot_table`, and `pivot_table_v2`. |
|
||||
| `EXCEL_EXPORT_QUERY_CONTEXT_BUILDER` | `None` | Optional callable that builds a query context from `Slice.form_data`. Return `None` to use the built-in rebuild. |
|
||||
|
||||
Credentials and region resolve through the standard boto3 chain (environment
|
||||
variables, shared config, or instance role) unless overridden via
|
||||
@@ -88,8 +104,9 @@ variables, shared config, or instance role) unless overridden via
|
||||
## Security considerations
|
||||
|
||||
- The emailed link is a **pre-signed S3 URL**: anyone who holds it can download
|
||||
the workbook until it expires. Keep the bucket **private**, enable
|
||||
encryption, and consider a lifecycle rule to delete objects after a few days.
|
||||
the workbook until it expires. Direct downloads are not stored or linked.
|
||||
Keep the bucket **private**, enable encryption, and consider a lifecycle rule
|
||||
to delete objects after a few days.
|
||||
Lower `EXCEL_EXPORT_LINK_TTL_SECONDS` if 24 hours is too long for your data.
|
||||
- The export runs with the requesting user's permissions; each chart's query is
|
||||
access-checked, so users only ever receive data they are entitled to.
|
||||
@@ -97,9 +114,9 @@ variables, shared config, or instance role) unless overridden via
|
||||
## Limitations
|
||||
|
||||
- **Embedded dashboards / guest tokens are not supported** in this version,
|
||||
because guest users have no email address to deliver the link to. Logged-in
|
||||
users viewing an embedded dashboard can still use the export.
|
||||
including direct downloads. Logged-in users viewing an embedded dashboard can
|
||||
still use the export.
|
||||
- The default **Export Data to Excel** mode exports data only (no visual
|
||||
styling). Use **Export Images to Excel** to embed rendered chart images, which
|
||||
requires the webdriver infrastructure described in the prerequisites.
|
||||
requires an export bucket and the webdriver setup described above.
|
||||
- Scheduled/automated exports are not part of this feature.
|
||||
|
||||
@@ -71,17 +71,17 @@ Parses a JSON string into an object that can be used in your template.
|
||||
|
||||
---
|
||||
|
||||
#### `groupBy`
|
||||
#### `group`
|
||||
|
||||
Groups an array of objects by a key, powered by [handlebars-group-by](https://github.com/nicktindall/handlebars-group-by).
|
||||
Groups an array of objects by a key, powered by [handlebars-group-by](https://github.com/nicktindall/handlebars-group-by). The key is passed as a `by` hash argument.
|
||||
|
||||
```handlebars
|
||||
{{#groupBy data 'department'}}
|
||||
{{#group data by="department"}}
|
||||
<h3>{{value}}</h3>
|
||||
{{#each items}}
|
||||
<p>{{this.name}}</p>
|
||||
{{/each}}
|
||||
{{/groupBy}}
|
||||
{{/group}}
|
||||
```
|
||||
|
||||
---
|
||||
@@ -90,6 +90,14 @@ Groups an array of objects by a key, powered by [handlebars-group-by](https://gi
|
||||
|
||||
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:
|
||||
|
||||
:::note
|
||||
These names are specific to `just-handlebars-helpers` and differ from other
|
||||
Handlebars helper libraries — notably `handlebars-helpers`, which spells the
|
||||
math helpers `add`, `subtract`, `multiply` and `divide`. Calling a helper that
|
||||
is not registered raises `Missing helper: "..."`, which renders the chart blank,
|
||||
so it is worth checking a name against the tables below before using it.
|
||||
:::
|
||||
|
||||
#### Comparison
|
||||
|
||||
| Helper | Description | Example |
|
||||
@@ -97,6 +105,7 @@ Superset also registers all helpers from the [just-handlebars-helpers](https://g
|
||||
| `eq` | Strict equality | `{{#if (eq status "active")}}` |
|
||||
| `eqw` | Weak equality | `{{#if (eqw count "5")}}` |
|
||||
| `neq` | Strict inequality | `{{#if (neq role "admin")}}` |
|
||||
| `neqw` | Weak inequality | `{{#if (neqw count "5")}}` |
|
||||
| `lt` | Less than | `{{#if (lt score 50)}}` |
|
||||
| `lte` | Less than or equal | `{{#if (lte score 100)}}` |
|
||||
| `gt` | Greater than | `{{#if (gt price 0)}}` |
|
||||
@@ -114,25 +123,52 @@ Superset also registers all helpers from the [just-handlebars-helpers](https://g
|
||||
|
||||
#### 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")}}` |
|
||||
| Helper | Description | Example |
|
||||
| ----------------- | ----------------------------------------------- | ------------------------------ |
|
||||
| `capitalizeFirst` | Capitalizes the first letter | `{{capitalizeFirst name}}` |
|
||||
| `capitalizeEach` | Capitalizes the first letter of each word | `{{capitalizeEach title}}` |
|
||||
| `uppercase` | Converts to uppercase | `{{uppercase status}}` |
|
||||
| `lowercase` | Converts to lowercase | `{{lowercase email}}` |
|
||||
| `excerpt` | Truncates to a length and appends an ellipsis | `{{excerpt description 100}}` |
|
||||
| `sprintf` | printf-style formatting | `{{sprintf "%.1f" score}}` |
|
||||
| `concat` | Concatenates values | `{{concat first " " last}}` |
|
||||
| `join` | Joins an array with a separator | `{{join tags ", "}}` |
|
||||
| `first` / `last` | First or last element of an array | `{{first items}}` |
|
||||
| `newLineToBr` | Converts newlines to `<br>` (needs `{{{ }}}`) | `{{{newLineToBr notes}}}` |
|
||||
|
||||
#### 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}}` |
|
||||
| Helper | Description | Example |
|
||||
| ---------------- | ----------------------- | ------------------------------------ |
|
||||
| `sum` | Addition | `{{sum a b}}` |
|
||||
| `difference` | Subtraction | `{{difference total discount}}` |
|
||||
| `multiplication` | Multiplication | `{{multiplication price quantity}}` |
|
||||
| `division` | Division | `{{division total count}}` |
|
||||
| `remainder` | Modulo | `{{remainder index 2}}` |
|
||||
| `abs` | Absolute value | `{{abs delta}}` |
|
||||
| `ceil` | Ceiling | `{{ceil value}}` |
|
||||
| `floor` | Floor | `{{floor value}}` |
|
||||
|
||||
`sum` takes exactly two arguments — it adds a pair of numbers and does not total
|
||||
an array. There is no `round` helper; use `{{sprintf "%.0f" value}}` to round to
|
||||
a given number of decimal places.
|
||||
|
||||
#### Arrays
|
||||
|
||||
| Helper | Description | Example |
|
||||
| ---------- | ---------------------------------- | --------------------------------- |
|
||||
| `includes` | Whether an array contains a value | `{{#if (includes tags "urgent")}}` |
|
||||
| `empty` | Whether an array is empty | `{{#if (empty rows)}}` |
|
||||
| `count` | Number of items in an array | `{{count rows}}` |
|
||||
|
||||
`includes` tests array membership. It returns `false` for a string, so it cannot
|
||||
be used to check for a substring.
|
||||
|
||||
#### Formatting
|
||||
|
||||
| Helper | Description | Example |
|
||||
| ---------------- | ---------------------------- | -------------------------------- |
|
||||
| `formatCurrency` | Formats a number as currency | `{{formatCurrency revenue "$"}}` |
|
||||
|
||||
For the full list of available helpers, see the [just-handlebars-helpers documentation](https://github.com/leapfrogtechnology/just-handlebars-helpers).
|
||||
|
||||
|
||||
@@ -305,6 +305,14 @@ Ask your admin for the MCP server URL and any authentication tokens you need.
|
||||
| `list_databases` | List configured database connections |
|
||||
| `get_database_info` | Get details about a specific database connection |
|
||||
|
||||
### Themes
|
||||
|
||||
| Tool | Description |
|
||||
| ---------------- | ------------------------------------------------------------------------- |
|
||||
| `list_themes` | Discover themes (antd design-token configurations) with filters |
|
||||
| `get_theme_info` | Get a theme's tokens (`json_data`) by ID or UUID |
|
||||
| `create_theme` | Create a reusable theme from antd design tokens (requires write access) |
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
+5
-2
@@ -43,8 +43,11 @@ publish = "build"
|
||||
ignore = 'if [ -n "$CACHED_COMMIT_REF" ]; then git diff --quiet "$CACHED_COMMIT_REF" HEAD -- . ../README.md; else git fetch --no-tags origin master >/dev/null 2>&1 || true; i=0; while [ "$i" -lt 10 ] && ! git merge-base origin/master HEAD >/dev/null 2>&1; do git fetch --deepen=200 origin master >/dev/null 2>&1 || break; i=$((i+1)); done; BASE="$(git merge-base origin/master HEAD 2>/dev/null || true)"; if [ -z "$BASE" ]; then exit 1; fi; git diff --quiet "$BASE" HEAD -- . ../README.md; fi'
|
||||
|
||||
[build.environment]
|
||||
# Node version matching docs/.nvmrc
|
||||
NODE_VERSION = "20"
|
||||
# Node version is intentionally not pinned here: Netlify auto-detects it
|
||||
# from docs/.nvmrc, which is a symlink to the repo's single source of truth
|
||||
# at superset-frontend/.nvmrc. Duplicating the version here previously let
|
||||
# it drift out of sync (stuck on Node 20 after the repo moved to Node 24),
|
||||
# breaking installs once a dependency required a newer Node engine.
|
||||
# Yarn version
|
||||
YARN_VERSION = "1.22.22"
|
||||
# Increase heap size for webpack bundling of Superset UI components
|
||||
|
||||
+4
-4
@@ -43,7 +43,7 @@
|
||||
"version:remove:components": "node scripts/manage-versions.mjs remove components"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^6.2.5",
|
||||
"@ant-design/icons": "^6.3.4",
|
||||
"@docusaurus/core": "^3.10.2",
|
||||
"@docusaurus/faster": "^3.10.2",
|
||||
"@docusaurus/plugin-client-redirects": "^3.10.2",
|
||||
@@ -87,11 +87,11 @@
|
||||
"@docusaurus/module-type-aliases": "^3.10.2",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/react": "^19.1.8",
|
||||
"oxfmt": "^0.65.0",
|
||||
"oxlint": "^1.80.0",
|
||||
"oxfmt": "^0.66.0",
|
||||
"oxlint": "^1.81.0",
|
||||
"oxlint-tsgolint": "^7.0.2001",
|
||||
"typescript": "7.0.2",
|
||||
"webpack": "^5.110.1"
|
||||
"webpack": "^5.110.3"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
"Apache Doris",
|
||||
"Apache Kylin",
|
||||
"Apache Phoenix",
|
||||
"Ascend",
|
||||
"Azure Data Explorer",
|
||||
"Azure Synapse",
|
||||
"ClickHouse",
|
||||
@@ -167,6 +168,7 @@
|
||||
"base"
|
||||
],
|
||||
"Cloud Data Warehouses": [
|
||||
"Ascend",
|
||||
"Azure Synapse",
|
||||
"Cloudflare D1",
|
||||
"Databend",
|
||||
@@ -178,6 +180,7 @@
|
||||
"YugabyteDB"
|
||||
],
|
||||
"Hosted Open Source": [
|
||||
"Ascend",
|
||||
"Cloudflare D1",
|
||||
"Databricks",
|
||||
"Google Sheets",
|
||||
@@ -1738,6 +1741,87 @@
|
||||
"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,
|
||||
|
||||
Vendored
+6
-6
@@ -98,12 +98,6 @@
|
||||
"default": false,
|
||||
"lifecycle": "development",
|
||||
"description": "Enable Table V2 time comparison feature"
|
||||
},
|
||||
{
|
||||
"name": "TAGGING_SYSTEM",
|
||||
"default": false,
|
||||
"lifecycle": "development",
|
||||
"description": "Enables the tagging system for organizing assets"
|
||||
}
|
||||
],
|
||||
"testing": [
|
||||
@@ -240,6 +234,12 @@
|
||||
"description": "Allow users to enable SSH tunneling when creating a DB connection. DB engine must support SSH Tunnels.",
|
||||
"docs": "https://superset.apache.org/docs/configuration/setup-ssh-tunneling"
|
||||
},
|
||||
{
|
||||
"name": "TAGGING_SYSTEM",
|
||||
"default": true,
|
||||
"lifecycle": "testing",
|
||||
"description": "Enables the tagging system for organizing assets"
|
||||
},
|
||||
{
|
||||
"name": "USE_ANALOGOUS_COLORS",
|
||||
"default": false,
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Vendored
+14
-26
@@ -1203,28 +1203,6 @@
|
||||
},
|
||||
"time_grain_sqla": {
|
||||
"description": "To what level of granularity should the temporal column be aggregated. Supports [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Durations) durations.",
|
||||
"enum": [
|
||||
"PT1S",
|
||||
"PT5S",
|
||||
"PT30S",
|
||||
"PT1M",
|
||||
"PT5M",
|
||||
"PT10M",
|
||||
"PT15M",
|
||||
"PT30M",
|
||||
"PT1H",
|
||||
"PT6H",
|
||||
"P1D",
|
||||
"P1W",
|
||||
"P1M",
|
||||
"P3M",
|
||||
"P1Y",
|
||||
"1969-12-28T00:00:00Z/P1W",
|
||||
"1969-12-29T00:00:00Z/P1W",
|
||||
"P1W/1970-01-03T00:00:00Z",
|
||||
"P1W/1970-01-04T00:00:00Z",
|
||||
null
|
||||
],
|
||||
"example": "P1D",
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
@@ -1485,12 +1463,14 @@
|
||||
"PT10M",
|
||||
"PT15M",
|
||||
"PT30M",
|
||||
"PT0.5H",
|
||||
"PT1H",
|
||||
"PT6H",
|
||||
"P1D",
|
||||
"P1W",
|
||||
"P1M",
|
||||
"P3M",
|
||||
"P0.25Y",
|
||||
"P1Y",
|
||||
"1969-12-28T00:00:00Z/P1W",
|
||||
"1969-12-29T00:00:00Z/P1W",
|
||||
@@ -19541,7 +19521,7 @@
|
||||
},
|
||||
"/api/v1/dashboard/{pk}/export_xlsx/": {
|
||||
"post": {
|
||||
"description": "Enqueues an async task that writes each chart's data to its own worksheet, uploads the .xlsx to S3, and emails the requesting user a pre-signed download link. Returns immediately with a job id.",
|
||||
"description": "Writes each chart to a worksheet. With export storage, the work is queued and the user receives a download link by email. Without it, eligible workbooks are returned in the response.",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "The dashboard id",
|
||||
@@ -19563,6 +19543,17 @@
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
|
||||
"schema": {
|
||||
"format": "binary",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "The exported workbook, built during this request"
|
||||
},
|
||||
"202": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
@@ -19587,9 +19578,6 @@
|
||||
},
|
||||
"500": {
|
||||
"$ref": "#/components/responses/500"
|
||||
},
|
||||
"501": {
|
||||
"description": "Excel export is not configured on this server"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
|
||||
@@ -50,6 +50,7 @@ are compatible with Superset.
|
||||
| [Apache Pinot](/user-docs/6.0.0/configuration/databases#apache-pinot) | `pip install pinotdb` | `pinot://BROKER:5436/query?server=http://CONTROLLER:5983/` |
|
||||
| [Apache Solr](/user-docs/6.0.0/configuration/databases#apache-solr) | `pip install sqlalchemy-solr` | `solr://{username}:{password}@{hostname}:{port}/{server_path}/{collection}` |
|
||||
| [Apache Spark SQL](/user-docs/6.0.0/configuration/databases#apache-spark-sql) | `pip install pyhive` | `hive://hive@{hostname}:{port}/{database}` |
|
||||
| [Ascend.io](/user-docs/6.0.0/configuration/databases#ascendio) | `pip install impyla` | `ascend://{username}:{password}@{hostname}:{port}/{database}?auth_mechanism=PLAIN;use_ssl=true` |
|
||||
| [Azure MS SQL](/user-docs/6.0.0/configuration/databases#sql-server) | `pip install pymssql` | `mssql+pymssql://UserName@presetSQL:TestPassword@presetSQL.database.windows.net:1433/TestSchema` |
|
||||
| [ClickHouse](/user-docs/6.0.0/configuration/databases#clickhouse) | `pip install clickhouse-connect` | `clickhousedb://{username}:{password}@{hostname}:{port}/{database}` |
|
||||
| [CockroachDB](/user-docs/6.0.0/configuration/databases#cockroachdb) | `pip install cockroachdb` | `cockroachdb://root@{hostname}:{port}/{database}?sslmode=disable` |
|
||||
@@ -187,6 +188,16 @@ Repeat this process for each type of database you want Superset to connect to.
|
||||
|
||||
### Database-specific Instructions
|
||||
|
||||
#### Ascend.io
|
||||
|
||||
The recommended connector library to Ascend.io is [impyla](https://github.com/cloudera/impyla).
|
||||
|
||||
The expected connection string is formatted as follows:
|
||||
|
||||
```
|
||||
ascend://{username}:{password}@{hostname}:{port}/{database}?auth_mechanism=PLAIN;use_ssl=true
|
||||
```
|
||||
|
||||
#### Apache Doris
|
||||
|
||||
The [sqlalchemy-doris](https://pypi.org/project/pydoris/) library is the recommended way to connect to Apache Doris through SQLAlchemy.
|
||||
|
||||
@@ -215,7 +215,7 @@ If you have a good solution for this, let us know!
|
||||
:::
|
||||
|
||||
:::note
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/scarf-gateway) to collect telemetry
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/) to collect telemetry
|
||||
data. Knowing the installation counts for different Superset versions informs the project's
|
||||
decisions about patching and long-term support. Scarf purges personally identifiable information
|
||||
(PII) and provides only aggregated statistics.
|
||||
|
||||
@@ -135,7 +135,7 @@ init:
|
||||
```
|
||||
|
||||
:::note
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/scarf-gateway) to collect telemetry data. Knowing the installation counts for different Superset versions informs the project's decisions about patching and long-term support. Scarf purges personally identifiable information (PII) and provides only aggregated statistics.
|
||||
Superset uses [Scarf Gateway](https://about.scarf.sh/) to collect telemetry data. Knowing the installation counts for different Superset versions informs the project's decisions about patching and long-term support. Scarf purges personally identifiable information (PII) and provides only aggregated statistics.
|
||||
|
||||
To opt-out of this data collection in your Helm-based installation, edit the `repository:` line in your `helm/superset/values.yaml` file, replacing `apachesuperset.docker.scarf.sh/apache/superset` with `apache/superset` to pull the image directly from Docker Hub.
|
||||
:::
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
"Apache Doris",
|
||||
"Apache Kylin",
|
||||
"Apache Phoenix",
|
||||
"Ascend",
|
||||
"Azure Data Explorer",
|
||||
"Azure Synapse",
|
||||
"ClickHouse",
|
||||
@@ -164,6 +165,7 @@
|
||||
"base"
|
||||
],
|
||||
"Cloud Data Warehouses": [
|
||||
"Ascend",
|
||||
"Azure Synapse",
|
||||
"Cloudflare D1",
|
||||
"Databend",
|
||||
@@ -175,6 +177,7 @@
|
||||
"YugabyteDB"
|
||||
],
|
||||
"Hosted Open Source": [
|
||||
"Ascend",
|
||||
"Cloudflare D1",
|
||||
"Databricks",
|
||||
"Google Sheets",
|
||||
@@ -1735,6 +1738,87 @@
|
||||
"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,
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
title: Ascend
|
||||
sidebar_label: Ascend
|
||||
description: 'Ascend.io is a data automation platform for building data pipelines.'
|
||||
hide_title: true
|
||||
---
|
||||
|
||||
{/*
|
||||
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 { DatabasePage } from '@site/src/components/databases';
|
||||
|
||||
export const databaseInfo = {
|
||||
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: {
|
||||
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: 38,
|
||||
max_score: 201,
|
||||
joins: true,
|
||||
subqueries: true,
|
||||
supports_dynamic_schema: false,
|
||||
supports_catalog: false,
|
||||
supports_dynamic_catalog: false,
|
||||
ssh_tunneling: true,
|
||||
supports_file_upload: true,
|
||||
query_cancelation: true,
|
||||
query_cost_estimation: false,
|
||||
sql_validation: false,
|
||||
user_impersonation: false,
|
||||
};
|
||||
|
||||
<DatabasePage name="Ascend" database={databaseInfo} />
|
||||
@@ -159,6 +159,7 @@ single source of truth. The README.md retains its own static copy
|
||||
<a href="/user-docs/databases/supported/apache-pinot" title="Apache Pinot"><img src="/img/databases/apache-pinot.svg" alt="Apache Pinot" width="76" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/apache-solr" title="Apache Solr"><img src="/img/databases/apache-solr.png" alt="Apache Solr" width="79" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/apache-spark-sql" title="Apache Spark SQL"><img src="/img/databases/apache-spark.png" alt="Apache Spark SQL" width="75" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/ascend" title="Ascend"><img src="/img/databases/ascend.webp" alt="Ascend" width="117" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/aurora-mysql-data-api" title="Aurora MySQL (Data API)"><img src="/img/databases/mysql.png" alt="Aurora MySQL (Data API)" width="77" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/aurora-postgresql-data-api" title="Aurora PostgreSQL (Data API)"><img src="/img/databases/postgresql.svg" alt="Aurora PostgreSQL (Data API)" width="76" height="40" /></a>
|
||||
<a href="/user-docs/databases/supported/azure-data-explorer" title="Azure Data Explorer"><img src="/img/databases/kusto.png" alt="Azure Data Explorer" width="40" height="40" /></a>
|
||||
|
||||
@@ -128,6 +128,7 @@ Here are some of the major database solutions that are supported:
|
||||
<a href="https://superset.apache.org/docs/databases/supported/apache-pinot" title="Apache Pinot"><img src="docs/static/img/databases/apache-pinot.svg" alt="Apache Pinot" width="76" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/apache-solr" title="Apache Solr"><img src="docs/static/img/databases/apache-solr.png" alt="Apache Solr" width="79" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/apache-spark-sql" title="Apache Spark SQL"><img src="docs/static/img/databases/apache-spark.png" alt="Apache Spark SQL" width="75" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/ascend" title="Ascend"><img src="docs/static/img/databases/ascend.webp" alt="Ascend" width="117" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/aurora-mysql-data-api" title="Aurora MySQL (Data API)"><img src="docs/static/img/databases/mysql.png" alt="Aurora MySQL (Data API)" width="77" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/aurora-postgresql-data-api" title="Aurora PostgreSQL (Data API)"><img src="docs/static/img/databases/postgresql.svg" alt="Aurora PostgreSQL (Data API)" width="76" height="40" /></a>
|
||||
<a href="https://superset.apache.org/docs/databases/supported/azure-data-explorer" title="Azure Data Explorer"><img src="docs/static/img/databases/kusto.png" alt="Azure Data Explorer" width="40" height="40" /></a>
|
||||
|
||||
@@ -71,17 +71,17 @@ Parses a JSON string into an object that can be used in your template.
|
||||
|
||||
---
|
||||
|
||||
#### `groupBy`
|
||||
#### `group`
|
||||
|
||||
Groups an array of objects by a key, powered by [handlebars-group-by](https://github.com/nicktindall/handlebars-group-by).
|
||||
Groups an array of objects by a key, powered by [handlebars-group-by](https://github.com/nicktindall/handlebars-group-by). The key is passed as a `by` hash argument.
|
||||
|
||||
```handlebars
|
||||
{{#groupBy data 'department'}}
|
||||
{{#group data by="department"}}
|
||||
<h3>{{value}}</h3>
|
||||
{{#each items}}
|
||||
<p>{{this.name}}</p>
|
||||
{{/each}}
|
||||
{{/groupBy}}
|
||||
{{/group}}
|
||||
```
|
||||
|
||||
---
|
||||
@@ -90,6 +90,14 @@ Groups an array of objects by a key, powered by [handlebars-group-by](https://gi
|
||||
|
||||
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:
|
||||
|
||||
:::note
|
||||
These names are specific to `just-handlebars-helpers` and differ from other
|
||||
Handlebars helper libraries — notably `handlebars-helpers`, which spells the
|
||||
math helpers `add`, `subtract`, `multiply` and `divide`. Calling a helper that
|
||||
is not registered raises `Missing helper: "..."`, which renders the chart blank,
|
||||
so it is worth checking a name against the tables below before using it.
|
||||
:::
|
||||
|
||||
#### Comparison
|
||||
|
||||
| Helper | Description | Example |
|
||||
@@ -97,6 +105,7 @@ Superset also registers all helpers from the [just-handlebars-helpers](https://g
|
||||
| `eq` | Strict equality | `{{#if (eq status "active")}}` |
|
||||
| `eqw` | Weak equality | `{{#if (eqw count "5")}}` |
|
||||
| `neq` | Strict inequality | `{{#if (neq role "admin")}}` |
|
||||
| `neqw` | Weak inequality | `{{#if (neqw count "5")}}` |
|
||||
| `lt` | Less than | `{{#if (lt score 50)}}` |
|
||||
| `lte` | Less than or equal | `{{#if (lte score 100)}}` |
|
||||
| `gt` | Greater than | `{{#if (gt price 0)}}` |
|
||||
@@ -114,25 +123,52 @@ Superset also registers all helpers from the [just-handlebars-helpers](https://g
|
||||
|
||||
#### 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")}}` |
|
||||
| Helper | Description | Example |
|
||||
| ----------------- | ----------------------------------------------- | ------------------------------ |
|
||||
| `capitalizeFirst` | Capitalizes the first letter | `{{capitalizeFirst name}}` |
|
||||
| `capitalizeEach` | Capitalizes the first letter of each word | `{{capitalizeEach title}}` |
|
||||
| `uppercase` | Converts to uppercase | `{{uppercase status}}` |
|
||||
| `lowercase` | Converts to lowercase | `{{lowercase email}}` |
|
||||
| `excerpt` | Truncates to a length and appends an ellipsis | `{{excerpt description 100}}` |
|
||||
| `sprintf` | printf-style formatting | `{{sprintf "%.1f" score}}` |
|
||||
| `concat` | Concatenates values | `{{concat first " " last}}` |
|
||||
| `join` | Joins an array with a separator | `{{join tags ", "}}` |
|
||||
| `first` / `last` | First or last element of an array | `{{first items}}` |
|
||||
| `newLineToBr` | Converts newlines to `<br>` (needs `{{{ }}}`) | `{{{newLineToBr notes}}}` |
|
||||
|
||||
#### 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}}` |
|
||||
| Helper | Description | Example |
|
||||
| ---------------- | ----------------------- | ------------------------------------ |
|
||||
| `sum` | Addition | `{{sum a b}}` |
|
||||
| `difference` | Subtraction | `{{difference total discount}}` |
|
||||
| `multiplication` | Multiplication | `{{multiplication price quantity}}` |
|
||||
| `division` | Division | `{{division total count}}` |
|
||||
| `remainder` | Modulo | `{{remainder index 2}}` |
|
||||
| `abs` | Absolute value | `{{abs delta}}` |
|
||||
| `ceil` | Ceiling | `{{ceil value}}` |
|
||||
| `floor` | Floor | `{{floor value}}` |
|
||||
|
||||
`sum` takes exactly two arguments — it adds a pair of numbers and does not total
|
||||
an array. There is no `round` helper; use `{{sprintf "%.0f" value}}` to round to
|
||||
a given number of decimal places.
|
||||
|
||||
#### Arrays
|
||||
|
||||
| Helper | Description | Example |
|
||||
| ---------- | ---------------------------------- | --------------------------------- |
|
||||
| `includes` | Whether an array contains a value | `{{#if (includes tags "urgent")}}` |
|
||||
| `empty` | Whether an array is empty | `{{#if (empty rows)}}` |
|
||||
| `count` | Number of items in an array | `{{count rows}}` |
|
||||
|
||||
`includes` tests array membership. It returns `false` for a string, so it cannot
|
||||
be used to check for a substring.
|
||||
|
||||
#### Formatting
|
||||
|
||||
| Helper | Description | Example |
|
||||
| ---------------- | ---------------------------- | -------------------------------- |
|
||||
| `formatCurrency` | Formats a number as currency | `{{formatCurrency revenue "$"}}` |
|
||||
|
||||
For the full list of available helpers, see the [just-handlebars-helpers documentation](https://github.com/leapfrogtechnology/just-handlebars-helpers).
|
||||
|
||||
|
||||
+283
-344
@@ -222,18 +222,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/fast-color/-/fast-color-3.0.1.tgz#fee56b95427c0b55b216c93d9a7f3473f31615b5"
|
||||
integrity sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw==
|
||||
|
||||
"@ant-design/icons-svg@^4.5.0":
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/icons-svg/-/icons-svg-4.5.0.tgz#7b1c567e489840d747f211d3688949bcba363ad2"
|
||||
integrity sha512-1BTUFyKPTBZ53MuTP8s0k5SFEXL7o3VHEOwLgzaoWKwnBeqIcqUtVshc4SKzhI6uACfqhJqBwBUE9FsWR3uULA==
|
||||
"@ant-design/icons-svg@^4.6.0":
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/icons-svg/-/icons-svg-4.6.0.tgz#5f7ebfe2a6b7c871920f73db095bd4ab50d7764d"
|
||||
integrity sha512-PRomU725ABMf/lnQp5HiB7my1kjEbFY0D10N4lXYxK6TIB1gKjIVD5MRThpDaezLgw1D774J8eOeeDB0M6wHrQ==
|
||||
|
||||
"@ant-design/icons@^6.2.5", "@ant-design/icons@^6.3.2":
|
||||
version "6.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-6.3.2.tgz#8291dffc53003db9a5df59f80ed758473cd5c8df"
|
||||
integrity sha512-B6O5a5XJ4wjtNOfZejXYwHW5zvKV5gYkjGf11dHGLEbKn0ABDGndo41+gfIiXyTFhvESj4XTotuud33mUFid0g==
|
||||
"@ant-design/icons@^6.3.2", "@ant-design/icons@^6.3.4":
|
||||
version "6.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-6.3.4.tgz#9a76f7b6b4554a65f25e3e5c439405b96c4ebd71"
|
||||
integrity sha512-kDoUlppczVyCUTFthF6cHmPzMBYqNZQhu9j6EyIX/YIdM9j9CZNZoJUjzVw7/1v1VO8WwVMmPp15r/uwIAS0AQ==
|
||||
dependencies:
|
||||
"@ant-design/colors" "^8.0.1"
|
||||
"@ant-design/icons-svg" "^4.5.0"
|
||||
"@ant-design/icons-svg" "^4.6.0"
|
||||
"@rc-component/util" "^1.11.0"
|
||||
clsx "^2.1.1"
|
||||
|
||||
@@ -3078,100 +3078,100 @@
|
||||
resolved "https://registry.yarnpkg.com/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-11.21.2.tgz#dbdf12721396ef4c31899d0963b002df32f57050"
|
||||
integrity sha512-VPoCAhKvCQTlG7vxqaBXcmuvbh77BfnGXj8g0pbvVXpm1F/R8rDVwqIWcEbMzrI1JvJlm8v7T9uMVQb6UctMRg==
|
||||
|
||||
"@oxfmt/binding-android-arm-eabi@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.65.0.tgz#1d9be45cec55c86b17e1feffbffaeadd45fd2c9a"
|
||||
integrity sha512-M10Gs1SSpTNI6ahGx3M/OlIdUF4hkaP6OgUb+MS79t/Pgflk3r1nW5gPFqsZGUAXg0H1AfANT9AvLdBSTIhZKg==
|
||||
"@oxfmt/binding-android-arm-eabi@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.66.0.tgz#81935e074d88a7da5afc731d4cc74bb1763aa3f1"
|
||||
integrity sha512-2Me9eoptv6ERdEuI2P8AOlYdHHraXebJaM6SC0kc2Dfb+mLrep2db+fedBPKaYn673h/vBgvP4tkOdAbaudX6w==
|
||||
|
||||
"@oxfmt/binding-android-arm64@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.65.0.tgz#7a6dbd301c1198d2a16439e005ca33fb3ebd2f62"
|
||||
integrity sha512-6DXH5sftNlaHpWJG50hFMF+Qxtq5D2TmahvcDPxWNcGIf8qrC9Y0YgHYcYZ2hlWzaccKXh/f3GcssH8vtkl4JA==
|
||||
"@oxfmt/binding-android-arm64@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.66.0.tgz#ea52efcaff8f7d708a61119124b36e656b0d74ca"
|
||||
integrity sha512-u7O+bSSF0HGsDKkQQxBqvLGVepu93RA+JKu+ONqvfh4sCnCEbj31wZj4iG5gk3XfRwrmYj0/8catkO2LcblQKQ==
|
||||
|
||||
"@oxfmt/binding-darwin-arm64@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.65.0.tgz#7fa69acf25aefb7ff832aaa207ece9f55c48398e"
|
||||
integrity sha512-K9m7lr53pcOLETNsC88sWes/GWHUGjZyHx95UhYcSXy0r30haLdeXlSufSenEAtoLaW753WN8/l4M7GYcRt6cg==
|
||||
"@oxfmt/binding-darwin-arm64@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.66.0.tgz#620dfd8993f71e557b169eeda792203d15698061"
|
||||
integrity sha512-/ikyMIVjX/sdo7KtjxoEsSUosfPzveVhT9RWMx9yGqFDKFJ89JAEKuEeLBmurDjrkb4w8tOnAdSO3SBaplY3bw==
|
||||
|
||||
"@oxfmt/binding-darwin-x64@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.65.0.tgz#c315ca1fb9fb606477dc76fc4154d92c32a244a9"
|
||||
integrity sha512-sTNwIx1gre3MyiHOPLu7IGW4UyMScYL4DTmJT01p4vzB0En+OJUQz6KuH8t0PpsClRSaMuY3b0QmtoPItfO8Lg==
|
||||
"@oxfmt/binding-darwin-x64@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.66.0.tgz#9f45ff27d347283fdc2a79b87cd67cc40204a46e"
|
||||
integrity sha512-q5xUsKeFqawa9NXa6ZGXWimFV19m8MogKPdTaSVDAAk2EQKBmBZRDeluwcl1p8ty/OFc9s9888OKEh3xfPVH0g==
|
||||
|
||||
"@oxfmt/binding-freebsd-x64@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.65.0.tgz#4815e6ac50a9f38cd93dda3d649c6988bded481d"
|
||||
integrity sha512-lYZMVIiIpnjGu5hJb2jxA8NYQ/e0OTGuaiAf4dqlGPNnPmUTu23FZRMltmjro/KkQm1uE4NT4n5yJ2zWmKcpfA==
|
||||
"@oxfmt/binding-freebsd-x64@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.66.0.tgz#5c04bc6fea57c0829d06698c480331019acf57f3"
|
||||
integrity sha512-CR+x4VzMY0pRXLK/xFQ/RzsSFkP5t2Z2mef0QY6OP/rTRcMUoMLCOM62/3Fp/t0K+UDoBKxvMyeb6D0zPMjleA==
|
||||
|
||||
"@oxfmt/binding-linux-arm-gnueabihf@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.65.0.tgz#36c1c82b18186293c62c48fbcf1e3e4bdc9cd72d"
|
||||
integrity sha512-gIdXFAt/bURnjxuoedDEWdZ0PEWEmdDcm8qdpoFYYvW3QMk/5D4vUaH4mlMeRpeTdST4izUgHVO6RawQ4QulJw==
|
||||
"@oxfmt/binding-linux-arm-gnueabihf@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.66.0.tgz#c343c923fb1acab9b22bf411ad7feb12ee9c415a"
|
||||
integrity sha512-ZEYmO/LbH9tTQCADILHGZE4GeOXOAj2VzedHkASNwjmwlwtutJCLpCJbIs37wRGTFgWRoEcD72jpMX+IBJUGjQ==
|
||||
|
||||
"@oxfmt/binding-linux-arm-musleabihf@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.65.0.tgz#623880e16cd16fb36abf02aa050e5e33d1acbf67"
|
||||
integrity sha512-jJVyADto7gA2AaX5qAjAexrxx9PJQaKWOe8PICE7yKMbjBRyOHcmj9TtVJ+MZYDUQ3hodU0AcoTj0jFQ1W4C6Q==
|
||||
"@oxfmt/binding-linux-arm-musleabihf@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.66.0.tgz#ec038e354a0b4fa903eaaf29b7e70b3ea0ce4956"
|
||||
integrity sha512-hNtR9/oU0CeTkq7JnRkmBQwqe17v2ZaAMLC4VcN7IIOWeRyWDk0knSPWS9iiLmtbZ2RRBBtsG01jQgkZmKCJeQ==
|
||||
|
||||
"@oxfmt/binding-linux-arm64-gnu@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.65.0.tgz#1570f61b877385b9c1b56800663f68e8f988c533"
|
||||
integrity sha512-p3RFkB+u7u+8up99b/NEcI1hdpLDiGgJYNwDorB60n7eH+eKposAKuMBxx+NqB3b+sJP4CZmYDh9G7X62tUsKg==
|
||||
"@oxfmt/binding-linux-arm64-gnu@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.66.0.tgz#11b3a1d966acbb65cb76238594fa62b68d226109"
|
||||
integrity sha512-uwOVQ8i6I1LT/+eDzfsgrrcZp8Fn6NPVUPn8fF5gdFGekFf0PddF+LEuwsD0/pbNUcKZhDj2rQ5UpITh9gF4iQ==
|
||||
|
||||
"@oxfmt/binding-linux-arm64-musl@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.65.0.tgz#e7494ed26c0cd52a1ac4b38fe5f0a2a88231cd2e"
|
||||
integrity sha512-5Prb0uFzJHr+OUD/qS/TmU526wD+PaHDsm3KoRiUXbMIDpTSErjeQYkK3OQeshAvD/PuLa9WGEi9WPajjdOZJg==
|
||||
"@oxfmt/binding-linux-arm64-musl@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.66.0.tgz#b441c3255ff3cecf393a15e4393e2bc506c59dba"
|
||||
integrity sha512-tTkF2Dmx4nGAjmBlZb+UtTGqR/EK4ZrW9qBfzte07a9XWqzoGGKzpFFlyNDhQe+Uwql94+ReCTeNbhOXscw1Dg==
|
||||
|
||||
"@oxfmt/binding-linux-ppc64-gnu@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.65.0.tgz#e87bc27e8d9fba5eaba59b11a1f00ad1e116f803"
|
||||
integrity sha512-S8svxTp81obnF3admN9yd+u2rOYXtyzThLGBTg1PY6TPtGcC09BaaXLQD+TBSMa7yvqhCDZ8DFri+S/yG60qCg==
|
||||
"@oxfmt/binding-linux-ppc64-gnu@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.66.0.tgz#8300b1420ffab047d07527ae78776f331f5aeef6"
|
||||
integrity sha512-F3cKHUav4yXOHn6GFnwpBhSYsJOYKKf9eqO/9jlEuqPxNw9zb98E9ZFct79gcg8pibUGkbveEu9WDlmXJpDzKw==
|
||||
|
||||
"@oxfmt/binding-linux-riscv64-gnu@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.65.0.tgz#dd27e2b20b27817938815a2b47f87fcf41ca1aa0"
|
||||
integrity sha512-WtXBr75G/h2qOHy8SiGtC1R6aS3jt4mE52v1D8AtwMXIgoOmSNP9lKvbSaTRoL0e5wsMPoi6T72QWDYPu+S+nA==
|
||||
"@oxfmt/binding-linux-riscv64-gnu@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.66.0.tgz#58718cadbd2e876414802ffd2445b61063f496fc"
|
||||
integrity sha512-K5fDaNZfDyQMYA/3qL21bqyN0X9T15LLwwbFPt2aHc94+ZG7bh0vZEsy2y7NlRnjjHFSwN+Hzg6ldJtbOriH4Q==
|
||||
|
||||
"@oxfmt/binding-linux-riscv64-musl@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.65.0.tgz#dc37b95c1f07579eeedcf869d7cf3b47ca695ac9"
|
||||
integrity sha512-YwSLVvpaz4o/nv/miiPEBJz+eJ+VmbgNIrao6RccK9ce+L5EA8wP+ZD0uFeq6wKOza6zoWv/dR0sj6lip6R3EA==
|
||||
"@oxfmt/binding-linux-riscv64-musl@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.66.0.tgz#f397a34335356dacaefc5e3e9fb4a58de7d9c0c8"
|
||||
integrity sha512-44Yc+I+qOmTElRcEhm5hUKIUJEQIOugymz4ua4tB0Wox7tGAfIbjzmXz/HDAtw1Ij6gmBwZlzh4hc9679RhWeA==
|
||||
|
||||
"@oxfmt/binding-linux-s390x-gnu@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.65.0.tgz#c898674718ce8da7a7c625f3b3bcda0b0ff55bc1"
|
||||
integrity sha512-XQTPqgvyrgkKcFq+Tp2eK6JS7sqqJ+nRmy2Fav4j3I+i4dJoPJm7YwEdoeSDX9xkqj9jZ/lWfF3bXUWztIrn6A==
|
||||
"@oxfmt/binding-linux-s390x-gnu@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.66.0.tgz#4d0d9f6c18136836d9e366f366d1cd5afff0f1c0"
|
||||
integrity sha512-1e29Eg9hEj2kRBB19M0seIehPbbXHCk35GvImjDvb79rjjYjXCRmtbUNHJcgoktZAMIzXrTbxDBKmTc1V4bg3A==
|
||||
|
||||
"@oxfmt/binding-linux-x64-gnu@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.65.0.tgz#720a641158804551480d79cdc85cfed21b0882c8"
|
||||
integrity sha512-cjZlx6S/VkeCNWCbwZriTnLnZeTcV3DEyeRGSw/2wwLP9viq+C0bJ4bC1k/ZLkFxDcB1lUgSasPkYGP1bdraOg==
|
||||
"@oxfmt/binding-linux-x64-gnu@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.66.0.tgz#cd02a84ea2ac21d5267592d947a0df7234ad5a7a"
|
||||
integrity sha512-vODY1UQo10gngn0+D4xHKU84F1Twm1LqrzV4SqPXvmQKSd87paehvZ6jqA5wKs6XQrlWul9clYMDVHcoW9CPMA==
|
||||
|
||||
"@oxfmt/binding-linux-x64-musl@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.65.0.tgz#6cb3e1f25c85c619ce634b2f7e3238c33caafe86"
|
||||
integrity sha512-2azCjxdLtK4zCcIOU1dlXlU0xxfbPi6EjwWx7Ac7teWPidIIDOcIhudup83xNCKYhtqeVd/gaVDOxbUq4syXWA==
|
||||
"@oxfmt/binding-linux-x64-musl@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.66.0.tgz#9b3066ef25ee4c011dbda21cd96479b645997c58"
|
||||
integrity sha512-YDzXx2JsT4+HL4MdkVrYjO55NS5lUKNm8rLC4ZPou8+seu0v0jhecSh+ufoO6+xEa8gccEezMlI2WHJi4ApUgw==
|
||||
|
||||
"@oxfmt/binding-openharmony-arm64@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.65.0.tgz#c620f9f383c544428f363bf4418b94b81b5b9346"
|
||||
integrity sha512-KXQ7xi1e/voP0IQaw6fG6XY4Z5+Llf1XmRSZS1t7pVFCecFJ0iXaboKmVwjFtp5MLlT5iWQrJ2U1C3GJdZ2u+Q==
|
||||
"@oxfmt/binding-openharmony-arm64@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.66.0.tgz#7d0e493670a2e6b8a15d03698be7eabb40234976"
|
||||
integrity sha512-mJjUYd8lj0+j4JkYyEM+5qKBf1Rnrpgjn/SVYKJhicVDqLz566ooa7Fs8zflPqt+dnZDV7X054rVIQX6ZcQNlQ==
|
||||
|
||||
"@oxfmt/binding-win32-arm64-msvc@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.65.0.tgz#79c59706cc5450854d57d582116b13d6611e875c"
|
||||
integrity sha512-2FbbjG5jEqLSLKVJwBap84uJfpn5Y5A53KEO0aUNr+zeiRB9nyPUIFMcSbZVMFLitfBytFWRNngozXYjb6Rsbw==
|
||||
"@oxfmt/binding-win32-arm64-msvc@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.66.0.tgz#3d20c363517caea2ddc6621641216d1f099ce5d8"
|
||||
integrity sha512-soV+0vESv7e5ntCHWC61x4gg8OSak6IHHnWsZmHrJFlvMj2AK+kmldErCNkVkrvc1Ts2/++rJXn+IuAb2WMXhw==
|
||||
|
||||
"@oxfmt/binding-win32-ia32-msvc@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.65.0.tgz#6a52067c7fc666ee46a1b95366c08a9a1c9b26a1"
|
||||
integrity sha512-LJ+ZacAPSjegDOnSLyA1TMWAhdDrsK4el3REdr1oL2UtVBCMhO2II/Sb3cEW6mF2MfLhl8hDNCSvc7KSbgk3LQ==
|
||||
"@oxfmt/binding-win32-ia32-msvc@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.66.0.tgz#19f58a4532b4499ea14bf1a740d5fe1be7640e36"
|
||||
integrity sha512-YCPi23uRIEYuIKTZohAkKbPFpujQ5QBuUM5iDv+UqbCmTPAkaFsxjsSuB8xlBpRT0G7eP/4HMF+cPDSqHtOD9A==
|
||||
|
||||
"@oxfmt/binding-win32-x64-msvc@0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.65.0.tgz#f63624f39bbfddcd679d471c15879176581bb32b"
|
||||
integrity sha512-higu9cWEO6XXFzATD1jf0mCK34rNfN2H9JrJie7QB1IhleVpTh0QlLH9Ip2C1H/Nd5n0v5pvRtC+5R0uE4HpVg==
|
||||
"@oxfmt/binding-win32-x64-msvc@0.66.0":
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.66.0.tgz#6a427d9080a54713e59dcef338b13a870df888ea"
|
||||
integrity sha512-bwTQcv/JVRPkOqQtMF0X7vpvpncDQiBcXHxZ9S2hR12Hlo8bvBdUR5x5XnxzDZ3kM0qoZw1rv7KaD66Ly+pFWA==
|
||||
|
||||
"@oxlint-tsgolint/darwin-arm64@7.0.2001":
|
||||
version "7.0.2001"
|
||||
@@ -3203,100 +3203,100 @@
|
||||
resolved "https://registry.yarnpkg.com/@oxlint-tsgolint/win32-x64/-/win32-x64-7.0.2001.tgz#814bcdd2707fa8ab1ae0f0b51a7243b034d2833a"
|
||||
integrity sha512-FkDRm8hx9OwzGQqyWG1tO5QrTLRApff9DzSgpz9QZau37BR8d1VYKOxMLGf6shPZntJFoTwIIJYT68VndYDCog==
|
||||
|
||||
"@oxlint/binding-android-arm-eabi@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.80.0.tgz#924b041cbcea4e934fd9ef66a2d2b7d7463c0180"
|
||||
integrity sha512-RM3Plj+biQpxa5d1GOOX6ciDlcUROmm4OZ/pLTpitkQt2mJv4jhtY4cbgaetOm5UKWZe05/TGQ6o1Vl8EOHkrA==
|
||||
"@oxlint/binding-android-arm-eabi@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.81.0.tgz#86a0305480e680431429c8259c5701ac5592e4a7"
|
||||
integrity sha512-IcCRsXiedJoJopY6mpZUBEeVFsUrutmrG7dZ87zMuKJlhg70Ora9bBl1WcCxZQtyI10YpnVdEso5oCg7YcfSHw==
|
||||
|
||||
"@oxlint/binding-android-arm64@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-android-arm64/-/binding-android-arm64-1.80.0.tgz#d1716d2be903de06b4fdb2fdaa121a2943695c35"
|
||||
integrity sha512-YlO5JEf0Yr2bUUlu8O8daVcUxtcGGbcSmyV7E7nSbJbfAdxTE0PFPwgnIlw7wXJaTYjb+qs5hI5q3jxUkI7cAw==
|
||||
"@oxlint/binding-android-arm64@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-android-arm64/-/binding-android-arm64-1.81.0.tgz#dba51cb2a1258f37eaca15a4e74d5d6ee19f238c"
|
||||
integrity sha512-GRrIPyTGVhx3L3h+0T5xT2A0jFAcdPv4+IfuXpGDLIdl6XeYhgg/zw72A5ILZoUgRqZuM8F1y+V/gfDriXSxzQ==
|
||||
|
||||
"@oxlint/binding-darwin-arm64@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.80.0.tgz#475eb4061db4d4fe9349e92f15962c0203e8ebec"
|
||||
integrity sha512-BULDOyO3AhsmdWfQeIUCykDt3dd7XZBGLhp1eIh56skRv01O+cNjNPwXMIbeW1x4+pxcln5if72wcRgViVo7PA==
|
||||
"@oxlint/binding-darwin-arm64@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.81.0.tgz#f384ae1eddd399429281f88a0073729e287ec0b1"
|
||||
integrity sha512-qNQ9tXRgLuKbqSV1S2h9h4KPHjbovO7RRR2/enUOtHzTkFZ7B9X5zqqHJua8dRyc7dBy7Aoyq5pqTSLFVcAzGQ==
|
||||
|
||||
"@oxlint/binding-darwin-x64@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.80.0.tgz#602fa5681dd746c0fb5ca7a0e4a81d0dd07b7f90"
|
||||
integrity sha512-YJ4JzLw7N5TDSQFlA0hAQGHvnDZgyypm1yunObVWcWiF9KM7eGCJKYKLgTC2Fi/57OdnBhbj4OkzPGdFQJ6HyA==
|
||||
"@oxlint/binding-darwin-x64@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.81.0.tgz#7167e3b4c18852fcd1ddade536d232d73d55d30c"
|
||||
integrity sha512-q0QTm32jWga2Gv4j7IaVZN0jYMi9UV73sWVgFtDA4iIfqwMCLLZ3ve+9KwfYtsaKZSgQhmPaogeZWqDZpcY1Pw==
|
||||
|
||||
"@oxlint/binding-freebsd-x64@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.80.0.tgz#4e0490c344726fd0b1a027afc129fb9c78f069ec"
|
||||
integrity sha512-AYUIk5QnL0s8oWAYsREZwkRYy1SupJTXALo93J1TgzHywxQtdM99FecRMQ87MXEdPQ0j1TmEpeeq3fGNkpvMqg==
|
||||
"@oxlint/binding-freebsd-x64@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.81.0.tgz#64f230765343bfe7e2280b071bb191bb666303ac"
|
||||
integrity sha512-/+8wVWDXEC7wHVAhOc59Fw/SkMc1arLkFD8iQCaSsmzenK1X4doFqquL9H1wrtGUzaiycVqkf/sSpcILK6W1UA==
|
||||
|
||||
"@oxlint/binding-linux-arm-gnueabihf@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.80.0.tgz#82d215fc05e046a0ec085821c1da8ab99d35fbdc"
|
||||
integrity sha512-9hBZVANupQ89W9dXyE0n8doCyaW5pDyGn3y6XlIMPZ+rIKuyqkr3SNUXmVJIhuvUq0NBU3RBiSXXE69l4XI6KA==
|
||||
"@oxlint/binding-linux-arm-gnueabihf@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.81.0.tgz#5095f021a28009146f7536a7ccd518cdfcbfc3bf"
|
||||
integrity sha512-4xt422FEgioRq9hAL4Tq7fujGUWnc8z1BJ+Oi8RN8vB8axaP+sdK6a2xdlcQCCYnJg9QMuMFS0AucuIFx/EacA==
|
||||
|
||||
"@oxlint/binding-linux-arm-musleabihf@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.80.0.tgz#92068e3b51cd50fc5a83a3ebfba7925313d6cd11"
|
||||
integrity sha512-SvS2uKqzY+pbfuvAHzH4338R6Zwo805GAwrIMVvK1KxoOWCIjZUdfzTCvilD7z6JK91v011+zYMryabhDo2AsQ==
|
||||
"@oxlint/binding-linux-arm-musleabihf@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.81.0.tgz#d894dcfb6fb1b8b224b79e6ce07b17403f413749"
|
||||
integrity sha512-u3vna8KdGplH4DRCW9K54D68fcMo7IxVrkCJWwXnIhwtBdnDnYrmzOUA/XjmBlPpcLsgw9Z5BNdY4za9+Dj+MQ==
|
||||
|
||||
"@oxlint/binding-linux-arm64-gnu@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.80.0.tgz#6c81ddc85dd5b79070f87401d61813172068666d"
|
||||
integrity sha512-tCLadyqRVL3pQTRPNg7cjXKvcvS4fbyXeQHhKk5BTJ1oftQln5/yIIWbu/Xom/DX41zv2P9QGt6+D/TtQVtY3A==
|
||||
"@oxlint/binding-linux-arm64-gnu@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.81.0.tgz#bf8e362c87e7828ba28c2ec36bae73ad82989ef1"
|
||||
integrity sha512-3j9k+gsYsE7nv71GWotXsqsa2l9/aJenD7dVHNt/CBvsb0SgRjSMnHFeP59IXUAl1wvVFhqGl2wJNMwWU3UBlA==
|
||||
|
||||
"@oxlint/binding-linux-arm64-musl@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.80.0.tgz#11216704b606d67e946a868850243dc2739ec92e"
|
||||
integrity sha512-XfpCNRlOPcLlJl4Bn/FUhjqlR6BVavEykERBf/MV7YA9VZDa5g5znVqYhyviMafcxS9Pe/i/kPvHNO0U6svEHQ==
|
||||
"@oxlint/binding-linux-arm64-musl@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.81.0.tgz#2aa5214eb5b032e8f77d94a27c9bd3f6dbc446f3"
|
||||
integrity sha512-k5iAp3dNxW0/uDCBY+WSm8jKB2szu7SkEQZdgRRpDXvuDd69vvDcqhB3A/pWCfCwXyenjNjFn9Td1fVoyAc+Yg==
|
||||
|
||||
"@oxlint/binding-linux-ppc64-gnu@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.80.0.tgz#125302a0e6732e32e4a7d53f0212d58f1b13af01"
|
||||
integrity sha512-3I4yMwcFG9NeO8ioY6JBBuKsIm5GL/x7MATt1S4tVWaxPu5HcJ+XnLUbcVBTxG8q2Wu56HSj+NmXQiVYb1lp6A==
|
||||
"@oxlint/binding-linux-ppc64-gnu@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.81.0.tgz#a0af1af6fd309214555f33b4fa0432f3ec45f242"
|
||||
integrity sha512-TFqLja3uYmVSte6nof9GWrex9Z8WgdZrNiLC6Te5rXGDqXB2y4j/26iFhwosXiAFqDhE9JJVuuCkDKLwptTn1g==
|
||||
|
||||
"@oxlint/binding-linux-riscv64-gnu@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.80.0.tgz#03846614f184ed3dcbab4bffad7417fd54cd0967"
|
||||
integrity sha512-E1wAKymkpe1/E8helzBKdm81OBOF+ezxRyXRMEuik3ZpWDER5CPOKZwF66RsdwW98uwZv8UTFremUQtC1CzdJA==
|
||||
"@oxlint/binding-linux-riscv64-gnu@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.81.0.tgz#60413a335a63e0911a625d047690e41c03f2a833"
|
||||
integrity sha512-UEcySvGS0NOVo7h7n7CYyJL9+6gFAh7Zc/ToDXVScFvzHSTIxtzkMVU30rmQ6+nQ1LF+UdiRDdJajpDu+OylLg==
|
||||
|
||||
"@oxlint/binding-linux-riscv64-musl@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.80.0.tgz#49e0fb90e1c8358429b9989a407f4020c56d8ea9"
|
||||
integrity sha512-+gLRGD4sIo3+VA++iham5UxD9tKSoJ/VOrROCEXIcknrYtQg6iIQgvjN0cpiRF7N6UYC7pJbvHJlDnMge5LRpQ==
|
||||
"@oxlint/binding-linux-riscv64-musl@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.81.0.tgz#5f1dd7bc2bdbe92fa5454df081ee91fa2c499948"
|
||||
integrity sha512-H+diDbhD00+wI1IRP8Kz88x/lat+DgtoBJzoTthS16xkTJGNaEkfb8gzmd1rzc/2uDQQMl7GNl+JFUacVeWxIA==
|
||||
|
||||
"@oxlint/binding-linux-s390x-gnu@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.80.0.tgz#7aee2ae2426f7bdcae77969073a015a6b3f8373e"
|
||||
integrity sha512-aR0PrzHj9leW3NmzBAAP4EzdoBNoJcs9sjnIQPIwyRnBGYrRbXUIpEB5Q39AqK3PLY5JK5uEhDQDiUa1QSAstw==
|
||||
"@oxlint/binding-linux-s390x-gnu@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.81.0.tgz#830c5bdd145ad39c9b5371e3214d0a9f9c1f46b1"
|
||||
integrity sha512-8znJ/5TekjOKg1j1Acho4PJMdiAHLtlcXuWEiipOhAMV6rQcXdmDdXCbheyDczN6TjBwiNfjcP81k4AthrKRzw==
|
||||
|
||||
"@oxlint/binding-linux-x64-gnu@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.80.0.tgz#0c850b00faed2f884cf8665fe9c391f9f653d6ca"
|
||||
integrity sha512-vSVh5cSo3Xxs6ghBCcFJlpbkbENzDog1qXtoXLa/HC3aCrR4XO76GZbXmQoCPHnu99nQpdCeC3H9tdNICfDh7A==
|
||||
"@oxlint/binding-linux-x64-gnu@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.81.0.tgz#7f72ea3c9ae70a76c1a92e56a5755869f335e756"
|
||||
integrity sha512-Q2Wj70yFsvn5QjlmifFzbj4H+kJy53bwqc41o1fzoM7MpLV1NIbhg/LpWXRfC6KOkSAdUx1Wd8VJsdPmhp/HRA==
|
||||
|
||||
"@oxlint/binding-linux-x64-musl@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.80.0.tgz#91f54f1b0cc93a7e75ce4118aa85f9fd112f25c0"
|
||||
integrity sha512-FfzBXpNQ8u7/ZI/p8bl73MeZ508Ax3hxWp3SiJpEFiC+BB9XcXy5FAZHTLKDPSzrUpxQZSZJAVdDmuJp/+HDBQ==
|
||||
"@oxlint/binding-linux-x64-musl@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.81.0.tgz#758fd6ea69123c6f4c1ba160bfc28f6b84548c11"
|
||||
integrity sha512-cPInHp/ddEe5qkyK2IiyQ8Q3Mp2oLLEhhsGgTK2oZx4L6+llGam1H1yBvJZ7qHfOXj8N3hxBS8sj4tO+gtFlIg==
|
||||
|
||||
"@oxlint/binding-openharmony-arm64@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.80.0.tgz#7ab37c21e547812177bffdbd97c8a34493eedd7b"
|
||||
integrity sha512-zMzbkumtmprCgRwoYNzcB3iC39fXdJIMLMU33KdCjEGLlJGOEt1+LwQ4LF8ndLzAEKVz4BR0y3V6Xrkk3Nm3yA==
|
||||
"@oxlint/binding-openharmony-arm64@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.81.0.tgz#e492b7a1875b70ea55ffe13f685d4302e6b1900e"
|
||||
integrity sha512-0CQxSX4ajqm07AHBf5U33qQzXKdd7wtq/oTL/7vpY6RNNuxrRi8W4bqUV1Jyu/vj+9KmxQyDhxfeVX1nQL6kfg==
|
||||
|
||||
"@oxlint/binding-win32-arm64-msvc@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.80.0.tgz#5a470fa82339044ad9cceef2bb8c62d88695e394"
|
||||
integrity sha512-ib6iRcrXsk4t1fm3iKcwksyWh1ZkZXC/2mEzakl0ai2+6HZunf1WWMZ/xP9EJAvw9g9K4UVTC3NF/+G2qLrbTQ==
|
||||
"@oxlint/binding-win32-arm64-msvc@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.81.0.tgz#9247fdc1b4c86ecc718747c5f8c68902969677d1"
|
||||
integrity sha512-l0hbeISm9673hVrrQU8j/p2M7YH9Ouoj7p7E/QM55NTrKVLP+P3PF8hLu+OY+x0VtGRW+ggiQKZqmdYps9H+TA==
|
||||
|
||||
"@oxlint/binding-win32-ia32-msvc@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.80.0.tgz#06f6559998f1a53a8f5ace78d91f217a54f6a963"
|
||||
integrity sha512-xhRWBMpLxZvgKAH6+DJZmpP+W8Y8UdQOSU1JfxSWNXsaBaRGW77j+1hCuNHlzj7OH4SPN8fYd1q0o2qrDtoVyw==
|
||||
"@oxlint/binding-win32-ia32-msvc@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.81.0.tgz#dfa4eed78612c5f4df788eb056fd5d1b05a75bb1"
|
||||
integrity sha512-ksqPP5jbFXcYreEQ7zdJh06rJQBymCTyGRCdaXjfcf2aG4f8KxUWY5wcgYHmaTK+FJ4bPG5sUAdOX+6trnH1JA==
|
||||
|
||||
"@oxlint/binding-win32-x64-msvc@1.80.0":
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.80.0.tgz#d3abbf1a7a09b9039ca5ca570c9689908850efc4"
|
||||
integrity sha512-yAnO7lwBYQnz2pcfBPIGQQZWIX5zd5R/1aAKIF3oE+TVj7IhoHcROjOkz3sRDngzqhfPKfFaXqug5j5rE5dn6Q==
|
||||
"@oxlint/binding-win32-x64-msvc@1.81.0":
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.81.0.tgz#27a474cc288e47a0e5c2d9c922bee64de0cfd614"
|
||||
integrity sha512-IZuUCwGw9emG5JtCp+fYGB+Z4OWEoeEcM8R5BA1pYw63/ieYFVdcU2ylxTpHbVHSenZnsYE+ZZ20uHAJszQ4cA==
|
||||
|
||||
"@parcel/watcher-android-arm64@2.5.6":
|
||||
version "2.5.6"
|
||||
@@ -4969,85 +4969,85 @@
|
||||
resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9"
|
||||
integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==
|
||||
|
||||
"@swc/html-darwin-arm64@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-darwin-arm64/-/html-darwin-arm64-1.15.43.tgz#c88069f140ead901724018f96ad709779526a368"
|
||||
integrity sha512-+PFbHbeeN+zB0zfvR1V1NmvPriuWPI+sijQXpI+wq/nLIujxvtENWjOKVHgouC9TIN/uKmL2zu9HAq6L6YxnPA==
|
||||
"@swc/html-darwin-arm64@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-darwin-arm64/-/html-darwin-arm64-1.16.2.tgz#dfe45d70266262a59aaaa0d93740b6161803f192"
|
||||
integrity sha512-SNBUxkxLBXD0ATwnOG1rF8mpSrRtFDfqWnEUmbm/g4KwmCt7NuHHv9YYqA3lqfq90Ucc+Xlk7afx8KAW/utz4A==
|
||||
|
||||
"@swc/html-darwin-x64@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-darwin-x64/-/html-darwin-x64-1.15.43.tgz#9bc8171494d3b98eac017b5b73f0f63054558626"
|
||||
integrity sha512-LQJ2U8Oxcx4T1rRF25y4h+/p05nn58FugTe/uGxC5OT3K83c2MftcSZLYaahOu4GVHRZeS1NI94CkSvQV++TVw==
|
||||
"@swc/html-darwin-x64@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-darwin-x64/-/html-darwin-x64-1.16.2.tgz#72066bda0d843c024dd5230aa013445d10037cde"
|
||||
integrity sha512-WVBgn6yrBPMZu+DL95/XGAXYcgd1nhd67Ml1UjMtFoFMVKY+VRpCq8JpTZTMXhWbVoRENUHk+3PHu0nNjlE/Fg==
|
||||
|
||||
"@swc/html-linux-arm-gnueabihf@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-arm-gnueabihf/-/html-linux-arm-gnueabihf-1.15.43.tgz#271a5d345719fa2c381df45355f70870faaaf35c"
|
||||
integrity sha512-DKIen6DuIRO7Xc5gAbgBT5QyRHJGEGXreIdM1VBosYWTGnnrQ//Hwd7bLD6UbT8X8eU1vqvpXwQ1E24QRqRaBQ==
|
||||
"@swc/html-linux-arm-gnueabihf@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-arm-gnueabihf/-/html-linux-arm-gnueabihf-1.16.2.tgz#efa7dd85b03b941ac173ae2870355f9721993905"
|
||||
integrity sha512-V9F/Akd2TXrf5nUhdLgdy3FoVFxQbw8pA2AOyqnEOa2Mbm1R7DZJJ0GdShEMcoyMyMDB9r/4pWuWfxNtP4mFHA==
|
||||
|
||||
"@swc/html-linux-arm64-gnu@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-arm64-gnu/-/html-linux-arm64-gnu-1.15.43.tgz#93cd3202f204351e7279efd07abc280fe0b2d193"
|
||||
integrity sha512-0AuHiyfcE86CZ/CajFIszLzZVzbM2wn5p01oet8Q9RikflCGwyH79Nv9TrAKD1Cx7juUrONzDk+f2b/x73wLTg==
|
||||
"@swc/html-linux-arm64-gnu@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-arm64-gnu/-/html-linux-arm64-gnu-1.16.2.tgz#4b6a02b42a40463e9ed9a96e0c42b7095b244f48"
|
||||
integrity sha512-jonZVtHc6BesMjC/muUEJGzE1L2kVdgiPVuHc7CL79MrUm0Hjf8LS4Wmtjqe2bLTfRcaMfaYl/60ZcRXHCaYSQ==
|
||||
|
||||
"@swc/html-linux-arm64-musl@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-arm64-musl/-/html-linux-arm64-musl-1.15.43.tgz#a6c0c2a1646755b1ee53a6bddbee68674f8edaea"
|
||||
integrity sha512-TweIdl/g9ugkoiYvcL/qbu+gbglDY3TqNxfXH84WXc4rSqEP20owVlxLya2NjVct8LIP2wDrtutpOwAXWC+Eew==
|
||||
"@swc/html-linux-arm64-musl@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-arm64-musl/-/html-linux-arm64-musl-1.16.2.tgz#0334e071cb8a01e0423fe7da27204b71f1afed66"
|
||||
integrity sha512-dvki9/sgacHk9ouORmnIok5FbpeE9zUE8yqGGhL1kitNJi6/TKzfnMOpRxSxeDk1/ccvJTAdjRGDIGkT45+b3Q==
|
||||
|
||||
"@swc/html-linux-ppc64-gnu@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-ppc64-gnu/-/html-linux-ppc64-gnu-1.15.43.tgz#51319cc1a4184b788613e0e556fc33ff77af0c52"
|
||||
integrity sha512-4oue1pB38/W6mbudp+w0q1jbwxuwdbdbaOj85ay0pisCs213WkgP+MPN8Zqa5VVPjQnVk2CTY9kmEc74XQI/sA==
|
||||
"@swc/html-linux-ppc64-gnu@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-ppc64-gnu/-/html-linux-ppc64-gnu-1.16.2.tgz#6c0d7293a1f7f7631e975c767755eb5236769193"
|
||||
integrity sha512-6m0vVWHl9MW7cmWKVgKlFW6yhRv0uahMEaDxNIvXrPC3LdbbiiYZui+ryhyQGIYeVps3OMujzUjc0GihNz/afQ==
|
||||
|
||||
"@swc/html-linux-s390x-gnu@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-s390x-gnu/-/html-linux-s390x-gnu-1.15.43.tgz#a612115a5f2f6c9df438a52ab2cf8bc4fd3865b1"
|
||||
integrity sha512-/tceMNvAxK70SKUZtcn3X+K0vcElMGk3i8Sz0CmPdtooso8MZ7WfAvVP1qi3TWgh1rpQ3cC+Al3433AHlET6+w==
|
||||
"@swc/html-linux-s390x-gnu@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-s390x-gnu/-/html-linux-s390x-gnu-1.16.2.tgz#853018d7b57377e2f3b23d369a1571862c34d2b9"
|
||||
integrity sha512-TOlz6wgKyZjg4THJsNZfDz/rAMO+rBa0s2eewTeHEfuJhI+jGu7H6Co6bdbMpN3oyDvTMG7N1f1ktSbkE0erAg==
|
||||
|
||||
"@swc/html-linux-x64-gnu@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-x64-gnu/-/html-linux-x64-gnu-1.15.43.tgz#028980da812e1797316f0a06a758a49aca699318"
|
||||
integrity sha512-YE7ltlTt5ZFl59GsoHTDrIHnCBY8EDBio66CVj4bqkElFXbE/28xmpVE5ksdGoI5c5aQ/8byUCfHxqzCzQQSVg==
|
||||
"@swc/html-linux-x64-gnu@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-x64-gnu/-/html-linux-x64-gnu-1.16.2.tgz#a347921e256f6ecb8847956bbacd4a23e1476adb"
|
||||
integrity sha512-5EduoVpsnuAAkG9BW8COxcIKAe5swgNAEo+BVkAJCOy1ZMZm0krQYBdvlaDCsGGE9yLDKVPm7rpYIi7vTTZTbA==
|
||||
|
||||
"@swc/html-linux-x64-musl@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-x64-musl/-/html-linux-x64-musl-1.15.43.tgz#363ac7ce3866b664db0c35d78a6a90636f280139"
|
||||
integrity sha512-nS20HmbOk+dEEzdosJqqxAeyjMIiS5yrCAti8LUf0+dgr4eRmjkH4MlkjfPjf49aayR8o+eMJ1jsDZ7whx4zog==
|
||||
"@swc/html-linux-x64-musl@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-linux-x64-musl/-/html-linux-x64-musl-1.16.2.tgz#ebfbbdb05f2f991a34bc500dce0ca10bfbcdfc3b"
|
||||
integrity sha512-c0Z84dvBd0oh1ZcBHnM18itmvJFLbCZBKFF2lEDHsGBSLQ/1sPbggEKsVO4KgWkkhwQV2l9AB4jnsw1HrwZJCg==
|
||||
|
||||
"@swc/html-win32-arm64-msvc@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-win32-arm64-msvc/-/html-win32-arm64-msvc-1.15.43.tgz#d0aa3f99c091577aaaa1aaf51a3695c98278564d"
|
||||
integrity sha512-Yz7aQQhXT/Yc6QcuMDQDZP9jqf2phkVyU+qSu8ZRWEcJgIorrPL6q7YLqMk+MB5PpZyu5XJEODvc1/UVDE1Kyg==
|
||||
"@swc/html-win32-arm64-msvc@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-win32-arm64-msvc/-/html-win32-arm64-msvc-1.16.2.tgz#69207d99cd80e55fe1ea722c8c8d5174b3d3cd2a"
|
||||
integrity sha512-Aq7V2B5gS23X59DzV2z892c4NBHYtJbwhvsCjJN1MBMx723htjgNE9KVIJp9dQaJBr2PrNfb/u3QFwnWV2tAoQ==
|
||||
|
||||
"@swc/html-win32-ia32-msvc@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-win32-ia32-msvc/-/html-win32-ia32-msvc-1.15.43.tgz#e2cfe4dd26ce8b8c5787ca1fdd69ef6b5dc94822"
|
||||
integrity sha512-muUgfsSQRZk6YBRuhaGKSLvXy0bV9BW6/mHLI0N/06btWuf0hekoHhIzR7dUmS98NXKCA7Hv+buBPE/0vXUwyA==
|
||||
"@swc/html-win32-ia32-msvc@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-win32-ia32-msvc/-/html-win32-ia32-msvc-1.16.2.tgz#9473a17f22c65ec20059533bd8cc78b32c82a711"
|
||||
integrity sha512-9gslPcsfXxKvAZtOvDkxGuEbM7lqBrONzLAyRsyUtw8KxFcSYkGIO48RDTstGWOkgTgKjjAq/WWqt9qr/NcE3A==
|
||||
|
||||
"@swc/html-win32-x64-msvc@1.15.43":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-win32-x64-msvc/-/html-win32-x64-msvc-1.15.43.tgz#ee1a8a7fe4d928595268c214cf17c72867ee8f0f"
|
||||
integrity sha512-tuLDy4MxPXsLi6jW+ozCdFWO61AoMMnlhePWJxMafefC2Ojm+iILxP2zI2Hgfu6F16y1q7ITdXdpEuqptu5fHw==
|
||||
"@swc/html-win32-x64-msvc@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html-win32-x64-msvc/-/html-win32-x64-msvc-1.16.2.tgz#7c7aeaa21b8848a765be2d4f7ee2ee3fecfd0f52"
|
||||
integrity sha512-Kdb4VdC8FyF5s1MQaFUNeASLckHECrb/oYy/6OCtU+hbgxQ/o/JCgE4uCe8YAg0LCWSOjhx73PCZDGwPf1TpKw==
|
||||
|
||||
"@swc/html@^1.15.40":
|
||||
version "1.15.43"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html/-/html-1.15.43.tgz#421da1ffc3226d149fd57c73f73755c6e6148427"
|
||||
integrity sha512-SKbkbdGi9SDO9cTdV+6H0/AYifnb2nDOlz5BlWxlWMXACV3kmX6WwZDo0bBdyGlO/G4jCVWdR5r84qfotU2now==
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@swc/html/-/html-1.16.2.tgz#91ee34374e4c926c6c8a8f43561688192b8a1725"
|
||||
integrity sha512-RmWH8m5dePWDFpHpmFKquZCRe5SyD/Sb0FBPxWcWv/tsjtlJl6oHeaxBsTL2edvaHuW385Fy5nPuTjDD/a+GEA==
|
||||
dependencies:
|
||||
"@swc/counter" "^0.1.3"
|
||||
optionalDependencies:
|
||||
"@swc/html-darwin-arm64" "1.15.43"
|
||||
"@swc/html-darwin-x64" "1.15.43"
|
||||
"@swc/html-linux-arm-gnueabihf" "1.15.43"
|
||||
"@swc/html-linux-arm64-gnu" "1.15.43"
|
||||
"@swc/html-linux-arm64-musl" "1.15.43"
|
||||
"@swc/html-linux-ppc64-gnu" "1.15.43"
|
||||
"@swc/html-linux-s390x-gnu" "1.15.43"
|
||||
"@swc/html-linux-x64-gnu" "1.15.43"
|
||||
"@swc/html-linux-x64-musl" "1.15.43"
|
||||
"@swc/html-win32-arm64-msvc" "1.15.43"
|
||||
"@swc/html-win32-ia32-msvc" "1.15.43"
|
||||
"@swc/html-win32-x64-msvc" "1.15.43"
|
||||
"@swc/html-darwin-arm64" "1.16.2"
|
||||
"@swc/html-darwin-x64" "1.16.2"
|
||||
"@swc/html-linux-arm-gnueabihf" "1.16.2"
|
||||
"@swc/html-linux-arm64-gnu" "1.16.2"
|
||||
"@swc/html-linux-arm64-musl" "1.16.2"
|
||||
"@swc/html-linux-ppc64-gnu" "1.16.2"
|
||||
"@swc/html-linux-s390x-gnu" "1.16.2"
|
||||
"@swc/html-linux-x64-gnu" "1.16.2"
|
||||
"@swc/html-linux-x64-musl" "1.16.2"
|
||||
"@swc/html-win32-arm64-msvc" "1.16.2"
|
||||
"@swc/html-win32-ia32-msvc" "1.16.2"
|
||||
"@swc/html-win32-x64-msvc" "1.16.2"
|
||||
|
||||
"@swc/types@^0.1.28":
|
||||
version "0.1.28"
|
||||
@@ -6924,9 +6924,9 @@ color-name@~1.1.4:
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
colord@^2.9.3:
|
||||
version "2.9.3"
|
||||
resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43"
|
||||
integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==
|
||||
version "2.10.0"
|
||||
resolved "https://registry.yarnpkg.com/colord/-/colord-2.10.0.tgz#56c9050e6b06b4b6c62ddec366a48d65ef57e860"
|
||||
integrity sha512-AidJptpBJmjTclAp9BkLwJi0T93fo5epJnbaZslpg6QVzpHjAiveF55mE9AcUJiGMqRHgMDY8soMsQtuNYMHfw==
|
||||
|
||||
colorette@^1.2.0:
|
||||
version "1.4.0"
|
||||
@@ -8284,36 +8284,11 @@ escape-string-regexp@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8"
|
||||
integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
|
||||
|
||||
eslint-scope@5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
|
||||
dependencies:
|
||||
esrecurse "^4.3.0"
|
||||
estraverse "^4.1.1"
|
||||
|
||||
esprima@~4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||
|
||||
esrecurse@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
|
||||
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
|
||||
dependencies:
|
||||
estraverse "^5.2.0"
|
||||
|
||||
estraverse@^4.1.1:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
|
||||
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
|
||||
|
||||
estraverse@^5.2.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
||||
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
|
||||
|
||||
estree-util-attach-comments@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz#344bde6a64c8a31d15231e5ee9e297566a691c2d"
|
||||
@@ -9671,9 +9646,9 @@ jiti@^1.20.0:
|
||||
integrity sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==
|
||||
|
||||
joi@^17.9.2:
|
||||
version "17.13.4"
|
||||
resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.4.tgz#ad6153d97ce558eb3a3b593e0d43eab51df1c474"
|
||||
integrity sha512-1RuuER6kmt8K8I3nIWvPZKi5RQCb568ZPyY4Pwjlua+yo+63ZTmIwxLZH0heBmiKN4uxjvCiarDrjaeH84xicQ==
|
||||
version "17.13.7"
|
||||
resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.7.tgz#92e212c50dbbbcb1a1592424f84083eb265cc778"
|
||||
integrity sha512-MF80Dm5Y2veNy8QWVx9Bj3ui4mo7+VPSPsR1M+oaHXV0Gx6zGX9a2F+OZG3Blby9tOlzU9Rs5FUimlEhbKtfnQ==
|
||||
dependencies:
|
||||
"@hapi/hoek" "^9.3.0"
|
||||
"@hapi/topo" "^5.1.0"
|
||||
@@ -11137,16 +11112,6 @@ minimist@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
|
||||
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||
|
||||
minimizer-webpack-plugin@^5.6.1:
|
||||
version "5.6.1"
|
||||
resolved "https://registry.yarnpkg.com/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.6.1.tgz#289922a4c96c4ed1ddb76b8a00bd8074e89a2f7f"
|
||||
integrity sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==
|
||||
dependencies:
|
||||
"@jridgewell/trace-mapping" "^0.3.25"
|
||||
jest-worker "^27.4.5"
|
||||
schema-utils "^4.3.0"
|
||||
terser "^5.31.1"
|
||||
|
||||
minimizer-webpack-plugin@^5.7.0:
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.8.0.tgz#744f0e28da888aa1708e2be32b4ddcf2eeb09e58"
|
||||
@@ -11576,32 +11541,32 @@ oxc-resolver@11.21.2:
|
||||
"@oxc-resolver/binding-win32-arm64-msvc" "11.21.2"
|
||||
"@oxc-resolver/binding-win32-x64-msvc" "11.21.2"
|
||||
|
||||
oxfmt@^0.65.0:
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/oxfmt/-/oxfmt-0.65.0.tgz#43f38114a6d9ad0952741c13c49f70ff1a4208d6"
|
||||
integrity sha512-SgS5VgnP42T0zl3zWD+xoH8FCqg1SAFnSRoOT/qeoa6gxcYIqrDMOmcXIg/EWSN92Du4ogB4riuKhKd6Y4CGhw==
|
||||
oxfmt@^0.66.0:
|
||||
version "0.66.0"
|
||||
resolved "https://registry.yarnpkg.com/oxfmt/-/oxfmt-0.66.0.tgz#4b1e831d31676a2a8fc9e85551115ffa778515a7"
|
||||
integrity sha512-FfvqR8RFtV6JJpRrpkfqyVCQ7HDvZ/VriWFx7veftCgL1B5ZO9qNr+1rvPieycMQnNfVG0PWyJQiy7p0hq1I5w==
|
||||
dependencies:
|
||||
tinypool "2.1.0"
|
||||
optionalDependencies:
|
||||
"@oxfmt/binding-android-arm-eabi" "0.65.0"
|
||||
"@oxfmt/binding-android-arm64" "0.65.0"
|
||||
"@oxfmt/binding-darwin-arm64" "0.65.0"
|
||||
"@oxfmt/binding-darwin-x64" "0.65.0"
|
||||
"@oxfmt/binding-freebsd-x64" "0.65.0"
|
||||
"@oxfmt/binding-linux-arm-gnueabihf" "0.65.0"
|
||||
"@oxfmt/binding-linux-arm-musleabihf" "0.65.0"
|
||||
"@oxfmt/binding-linux-arm64-gnu" "0.65.0"
|
||||
"@oxfmt/binding-linux-arm64-musl" "0.65.0"
|
||||
"@oxfmt/binding-linux-ppc64-gnu" "0.65.0"
|
||||
"@oxfmt/binding-linux-riscv64-gnu" "0.65.0"
|
||||
"@oxfmt/binding-linux-riscv64-musl" "0.65.0"
|
||||
"@oxfmt/binding-linux-s390x-gnu" "0.65.0"
|
||||
"@oxfmt/binding-linux-x64-gnu" "0.65.0"
|
||||
"@oxfmt/binding-linux-x64-musl" "0.65.0"
|
||||
"@oxfmt/binding-openharmony-arm64" "0.65.0"
|
||||
"@oxfmt/binding-win32-arm64-msvc" "0.65.0"
|
||||
"@oxfmt/binding-win32-ia32-msvc" "0.65.0"
|
||||
"@oxfmt/binding-win32-x64-msvc" "0.65.0"
|
||||
"@oxfmt/binding-android-arm-eabi" "0.66.0"
|
||||
"@oxfmt/binding-android-arm64" "0.66.0"
|
||||
"@oxfmt/binding-darwin-arm64" "0.66.0"
|
||||
"@oxfmt/binding-darwin-x64" "0.66.0"
|
||||
"@oxfmt/binding-freebsd-x64" "0.66.0"
|
||||
"@oxfmt/binding-linux-arm-gnueabihf" "0.66.0"
|
||||
"@oxfmt/binding-linux-arm-musleabihf" "0.66.0"
|
||||
"@oxfmt/binding-linux-arm64-gnu" "0.66.0"
|
||||
"@oxfmt/binding-linux-arm64-musl" "0.66.0"
|
||||
"@oxfmt/binding-linux-ppc64-gnu" "0.66.0"
|
||||
"@oxfmt/binding-linux-riscv64-gnu" "0.66.0"
|
||||
"@oxfmt/binding-linux-riscv64-musl" "0.66.0"
|
||||
"@oxfmt/binding-linux-s390x-gnu" "0.66.0"
|
||||
"@oxfmt/binding-linux-x64-gnu" "0.66.0"
|
||||
"@oxfmt/binding-linux-x64-musl" "0.66.0"
|
||||
"@oxfmt/binding-openharmony-arm64" "0.66.0"
|
||||
"@oxfmt/binding-win32-arm64-msvc" "0.66.0"
|
||||
"@oxfmt/binding-win32-ia32-msvc" "0.66.0"
|
||||
"@oxfmt/binding-win32-x64-msvc" "0.66.0"
|
||||
|
||||
oxlint-tsgolint@^7.0.2001:
|
||||
version "7.0.2001"
|
||||
@@ -11615,30 +11580,30 @@ oxlint-tsgolint@^7.0.2001:
|
||||
"@oxlint-tsgolint/win32-arm64" "7.0.2001"
|
||||
"@oxlint-tsgolint/win32-x64" "7.0.2001"
|
||||
|
||||
oxlint@^1.80.0:
|
||||
version "1.80.0"
|
||||
resolved "https://registry.yarnpkg.com/oxlint/-/oxlint-1.80.0.tgz#228271087d3f04e391e383ccdc0e840458d8b653"
|
||||
integrity sha512-5nTiSps4qdbCWLbxzuO00alHkEO2exR9YMN/ig6QXWrLsYSG0KaObOAM+l6oU2LcKPWoSAGYbkZIGEu1ViiWKA==
|
||||
oxlint@^1.81.0:
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/oxlint/-/oxlint-1.81.0.tgz#7b20ada29a171883de4517d041ea5b057fb48ab5"
|
||||
integrity sha512-HyrJYqeoOCL0iqaLEzGewGT48ZX99P3hxYh8udAF9RGGIghSamkXE4ClUyBpEDNqasamThgmlPbuMOe7SAZmHg==
|
||||
optionalDependencies:
|
||||
"@oxlint/binding-android-arm-eabi" "1.80.0"
|
||||
"@oxlint/binding-android-arm64" "1.80.0"
|
||||
"@oxlint/binding-darwin-arm64" "1.80.0"
|
||||
"@oxlint/binding-darwin-x64" "1.80.0"
|
||||
"@oxlint/binding-freebsd-x64" "1.80.0"
|
||||
"@oxlint/binding-linux-arm-gnueabihf" "1.80.0"
|
||||
"@oxlint/binding-linux-arm-musleabihf" "1.80.0"
|
||||
"@oxlint/binding-linux-arm64-gnu" "1.80.0"
|
||||
"@oxlint/binding-linux-arm64-musl" "1.80.0"
|
||||
"@oxlint/binding-linux-ppc64-gnu" "1.80.0"
|
||||
"@oxlint/binding-linux-riscv64-gnu" "1.80.0"
|
||||
"@oxlint/binding-linux-riscv64-musl" "1.80.0"
|
||||
"@oxlint/binding-linux-s390x-gnu" "1.80.0"
|
||||
"@oxlint/binding-linux-x64-gnu" "1.80.0"
|
||||
"@oxlint/binding-linux-x64-musl" "1.80.0"
|
||||
"@oxlint/binding-openharmony-arm64" "1.80.0"
|
||||
"@oxlint/binding-win32-arm64-msvc" "1.80.0"
|
||||
"@oxlint/binding-win32-ia32-msvc" "1.80.0"
|
||||
"@oxlint/binding-win32-x64-msvc" "1.80.0"
|
||||
"@oxlint/binding-android-arm-eabi" "1.81.0"
|
||||
"@oxlint/binding-android-arm64" "1.81.0"
|
||||
"@oxlint/binding-darwin-arm64" "1.81.0"
|
||||
"@oxlint/binding-darwin-x64" "1.81.0"
|
||||
"@oxlint/binding-freebsd-x64" "1.81.0"
|
||||
"@oxlint/binding-linux-arm-gnueabihf" "1.81.0"
|
||||
"@oxlint/binding-linux-arm-musleabihf" "1.81.0"
|
||||
"@oxlint/binding-linux-arm64-gnu" "1.81.0"
|
||||
"@oxlint/binding-linux-arm64-musl" "1.81.0"
|
||||
"@oxlint/binding-linux-ppc64-gnu" "1.81.0"
|
||||
"@oxlint/binding-linux-riscv64-gnu" "1.81.0"
|
||||
"@oxlint/binding-linux-riscv64-musl" "1.81.0"
|
||||
"@oxlint/binding-linux-s390x-gnu" "1.81.0"
|
||||
"@oxlint/binding-linux-x64-gnu" "1.81.0"
|
||||
"@oxlint/binding-linux-x64-musl" "1.81.0"
|
||||
"@oxlint/binding-openharmony-arm64" "1.81.0"
|
||||
"@oxlint/binding-win32-arm64-msvc" "1.81.0"
|
||||
"@oxlint/binding-win32-ia32-msvc" "1.81.0"
|
||||
"@oxlint/binding-win32-x64-msvc" "1.81.0"
|
||||
|
||||
p-cancelable@^3.0.0:
|
||||
version "3.0.0"
|
||||
@@ -14219,9 +14184,9 @@ svg-parser@^2.0.4:
|
||||
integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==
|
||||
|
||||
svgo@^3.0.2, svgo@^3.2.0:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.3.4.tgz#fd2aa10ff585b3bd2b83ce3602f5582bc0718bb5"
|
||||
integrity sha512-GsNRis4e8jxn2Y9ENz/8lbJ93CstG8svtMnuRaHbiF2LTJ5tK0/q3t/URPq9Zc7zVWBJnNnJMIp6bevK7bSmNg==
|
||||
version "3.3.5"
|
||||
resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.3.5.tgz#8a3d9557ab2f386eca7e24760385849554985a1c"
|
||||
integrity sha512-8SQMzdrvWaD8deUmrnYB+ASyxBVgWUOilg+A75nE/76WdLpj6LopCwiAVvkzkcqy/9b7t2Mg7faFLjg0ZRcZ3w==
|
||||
dependencies:
|
||||
commander "^7.2.0"
|
||||
css-select "^5.1.0"
|
||||
@@ -15163,10 +15128,10 @@ webpack-virtual-modules@^0.6.2:
|
||||
resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8"
|
||||
integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==
|
||||
|
||||
webpack@^5.110.1:
|
||||
version "5.110.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.110.1.tgz#d662d8ff1866fcb58a6b8af09c86bc6f1b9c5c1d"
|
||||
integrity sha512-gInQB+jxXxgnZyvPwuzT5NGQmECDqeu85oxcrjinrYHqPoBex0hCAN2SFTJVyPVrK0Pq9E44VFP+e89fAc10/w==
|
||||
webpack@^5.110.3, webpack@^5.88.1, webpack@^5.95.0:
|
||||
version "5.110.3"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.110.3.tgz#e122b66f6226b7af8f209b6102cd13238c4813a8"
|
||||
integrity sha512-GuizBzRvo9YPpyoNMf3ag7AzxbaW85qrRSqTha345KyJbAFPt3/cMzBM0h+RWg7SK/7DdzRLINP3LvQ0hvr4hg==
|
||||
dependencies:
|
||||
"@types/estree" "^1.0.8"
|
||||
"@types/json-schema" "^7.0.15"
|
||||
@@ -15188,32 +15153,6 @@ webpack@^5.110.1:
|
||||
watchpack "^2.5.2"
|
||||
webpack-sources "^3.5.1"
|
||||
|
||||
webpack@^5.88.1, webpack@^5.95.0:
|
||||
version "5.109.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.109.2.tgz#b58dc289561c3282db35c210a99379a836a4c28d"
|
||||
integrity sha512-U9/cvLzxObKNEZ9+TtdqrHM5/9z3lgl2c+c4BzbqGxFQvQvBAq87yql5A8pQ+rrMbS496MZJeF5enVBndIy2hw==
|
||||
dependencies:
|
||||
"@types/estree" "^1.0.8"
|
||||
"@types/json-schema" "^7.0.15"
|
||||
"@webassemblyjs/ast" "^1.14.1"
|
||||
"@webassemblyjs/wasm-edit" "^1.14.1"
|
||||
"@webassemblyjs/wasm-parser" "^1.14.1"
|
||||
acorn "^8.16.0"
|
||||
browserslist "^4.28.1"
|
||||
chrome-trace-event "^1.0.2"
|
||||
enhanced-resolve "^5.24.4"
|
||||
es-module-lexer "^2.1.0"
|
||||
eslint-scope "5.1.1"
|
||||
events "^3.2.0"
|
||||
graceful-fs "^4.2.11"
|
||||
mime-db "^1.54.0"
|
||||
minimizer-webpack-plugin "^5.6.1"
|
||||
neo-async "^2.6.2"
|
||||
schema-utils "^4.3.3"
|
||||
tapable "^2.3.0"
|
||||
watchpack "^2.5.2"
|
||||
webpack-sources "^3.5.1"
|
||||
|
||||
webpackbar@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-7.0.0.tgz#7228d32881af2392381b6514499ddea73cdf218a"
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ dependencies = [
|
||||
"deprecation>=2.1.0, <2.2.0",
|
||||
"flask>=2.2.5, <4.0.0",
|
||||
"flask-appbuilder>=5.2.2, <6.0.0",
|
||||
"flask-caching>=2.4.1, <3",
|
||||
"flask-caching>=2.5.0, <3",
|
||||
"flask-compress>=1.13, <2.0",
|
||||
"flask-talisman>=1.0.0, <2.0",
|
||||
"flask-login>=0.6.0, < 1.0",
|
||||
|
||||
@@ -40,7 +40,7 @@ brotli==1.2.0
|
||||
# via
|
||||
# -r requirements/base.in
|
||||
# flask-compress
|
||||
cachelib==0.13.0
|
||||
cachelib==0.17.0
|
||||
# via
|
||||
# flask-caching
|
||||
# flask-session
|
||||
@@ -105,7 +105,7 @@ et-xmlfile==2.0.0
|
||||
# via openpyxl
|
||||
filelock==3.20.3
|
||||
# via -r requirements/base.in
|
||||
flask==2.3.3
|
||||
flask==3.1.3
|
||||
# via
|
||||
# apache-superset (pyproject.toml)
|
||||
# flask-appbuilder
|
||||
@@ -124,9 +124,9 @@ flask-appbuilder==5.2.2
|
||||
# via
|
||||
# apache-superset (pyproject.toml)
|
||||
# apache-superset-core
|
||||
flask-babel==3.1.0
|
||||
flask-babel==4.0.0
|
||||
# via flask-appbuilder
|
||||
flask-caching==2.4.1
|
||||
flask-caching==2.5.0
|
||||
# via apache-superset (pyproject.toml)
|
||||
flask-compress==1.24
|
||||
# via apache-superset (pyproject.toml)
|
||||
@@ -218,6 +218,7 @@ markdown-it-py==3.0.0
|
||||
# via rich
|
||||
markupsafe==3.0.2
|
||||
# via
|
||||
# flask
|
||||
# jinja2
|
||||
# mako
|
||||
# werkzeug
|
||||
|
||||
@@ -94,7 +94,7 @@ brotli==1.2.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# flask-compress
|
||||
cachelib==0.13.0
|
||||
cachelib==0.17.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# flask-caching
|
||||
@@ -247,7 +247,7 @@ filelock==3.20.3
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# virtualenv
|
||||
flask==2.3.3
|
||||
flask==3.1.3
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
@@ -269,11 +269,11 @@ flask-appbuilder==5.2.2
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
# apache-superset-core
|
||||
flask-babel==3.1.0
|
||||
flask-babel==4.0.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# flask-appbuilder
|
||||
flask-caching==2.4.1
|
||||
flask-caching==2.5.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
@@ -524,6 +524,7 @@ markdown-it-py==3.0.0
|
||||
markupsafe==3.0.2
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# flask
|
||||
# jinja2
|
||||
# mako
|
||||
# werkzeug
|
||||
|
||||
Generated
+8
-8
@@ -17,13 +17,13 @@
|
||||
"@babel/core": "^8.0.1",
|
||||
"@babel/preset-env": "^8.0.1",
|
||||
"@babel/preset-typescript": "^8.0.1",
|
||||
"@types/node": "^26.4.0",
|
||||
"@types/node": "^26.4.1",
|
||||
"babel-loader": "^10.1.1",
|
||||
"jsdom": "^30.0.1",
|
||||
"tscw-config": "^1.1.2",
|
||||
"typescript": "^7.0.2",
|
||||
"vitest": "^4.0.18",
|
||||
"webpack": "^5.110.0",
|
||||
"webpack": "^5.110.3",
|
||||
"webpack-cli": "^7.2.3"
|
||||
}
|
||||
},
|
||||
@@ -2184,9 +2184,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "26.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz",
|
||||
"integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==",
|
||||
"version": "26.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.1.tgz",
|
||||
"integrity": "sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -5260,9 +5260,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack": {
|
||||
"version": "5.110.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.110.1.tgz",
|
||||
"integrity": "sha512-gInQB+jxXxgnZyvPwuzT5NGQmECDqeu85oxcrjinrYHqPoBex0hCAN2SFTJVyPVrK0Pq9E44VFP+e89fAc10/w==",
|
||||
"version": "5.110.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.110.3.tgz",
|
||||
"integrity": "sha512-GuizBzRvo9YPpyoNMf3ag7AzxbaW85qrRSqTha345KyJbAFPt3/cMzBM0h+RWg7SK/7DdzRLINP3LvQ0hvr4hg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
"@babel/core": "^8.0.1",
|
||||
"@babel/preset-env": "^8.0.1",
|
||||
"@babel/preset-typescript": "^8.0.1",
|
||||
"@types/node": "^26.4.0",
|
||||
"@types/node": "^26.4.1",
|
||||
"babel-loader": "^10.1.1",
|
||||
"jsdom": "^30.0.1",
|
||||
"tscw-config": "^1.1.2",
|
||||
"typescript": "^7.0.2",
|
||||
"vitest": "^4.0.18",
|
||||
"webpack": "^5.110.0",
|
||||
"webpack": "^5.110.3",
|
||||
"webpack-cli": "^7.2.3"
|
||||
},
|
||||
"repository": {
|
||||
|
||||
Generated
+785
-817
File diff suppressed because it is too large
Load Diff
@@ -193,7 +193,7 @@
|
||||
"nanoid": "^6.0.1",
|
||||
"ol": "^10.10.0",
|
||||
"postcss": "^8.5.26",
|
||||
"query-string": "9.5.0",
|
||||
"query-string": "9.5.1",
|
||||
"re-resizable": "^6.11.2",
|
||||
"react": "^18.3.0",
|
||||
"react-arborist": "^3.16.0",
|
||||
@@ -280,7 +280,7 @@
|
||||
"@types/json-bigint": "^1.0.4",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/mousetrap": "^1.6.15",
|
||||
"@types/node": "^26.4.0",
|
||||
"@types/node": "^26.4.1",
|
||||
"@types/react": "^18.3.0",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-loadable": "^5.5.11",
|
||||
@@ -292,9 +292,9 @@
|
||||
"@types/rison": "0.1.0",
|
||||
"@types/tinycolor2": "^1.4.3",
|
||||
"@types/unzipper": "^0.10.11",
|
||||
"@typescript-eslint/eslint-plugin": "^8.68.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.69.0",
|
||||
"@typescript-eslint/parser": "^8.63.0",
|
||||
"babel-jest": "^30.5.0",
|
||||
"babel-jest": "^30.5.1",
|
||||
"babel-loader": "^10.1.1",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||
"babel-plugin-jsx-remove-data-test-id": "^3.0.0",
|
||||
@@ -320,8 +320,8 @@
|
||||
"history": "^5.3.0",
|
||||
"html-webpack-plugin": "^5.6.8",
|
||||
"imports-loader": "^5.0.0",
|
||||
"jest": "^30.5.0",
|
||||
"jest-environment-jsdom": "^30.5.0",
|
||||
"jest": "^30.5.1",
|
||||
"jest-environment-jsdom": "^30.5.1",
|
||||
"jest-html-reporter": "^4.4.0",
|
||||
"jest-websocket-mock": "^2.5.0",
|
||||
"js-yaml-loader": "^1.2.2",
|
||||
@@ -331,7 +331,7 @@
|
||||
"mini-css-extract-plugin": "^2.10.2",
|
||||
"minimizer-webpack-plugin": "^5.8.0",
|
||||
"open-cli": "^9.0.0",
|
||||
"oxfmt": "^0.65.0",
|
||||
"oxfmt": "^0.66.0",
|
||||
"oxlint": "^1.80.0",
|
||||
"po2json": "^0.4.5",
|
||||
"postcss-styled-syntax": "^0.7.2",
|
||||
@@ -349,11 +349,11 @@
|
||||
"swc-loader": "^0.2.7",
|
||||
"ts-jest": "^29.4.12",
|
||||
"tscw-config": "^1.1.2",
|
||||
"tsx": "^4.23.12",
|
||||
"tsx": "^4.23.13",
|
||||
"typescript": "5.4.5",
|
||||
"unzipper": "^0.12.5",
|
||||
"wait-on": "^9.1.0",
|
||||
"webpack": "^5.110.1",
|
||||
"webpack": "^5.110.3",
|
||||
"webpack-bundle-analyzer": "^5.3.2",
|
||||
"webpack-cli": "^7.2.3",
|
||||
"webpack-dev-server": "^6.0.0",
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"devDependencies": {
|
||||
"cross-env": "^10.1.0",
|
||||
"fs-extra": "^11.4.0",
|
||||
"jest": "^30.5.0",
|
||||
"jest": "^30.5.1",
|
||||
"yeoman-test": "^11.6.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -20,7 +20,3 @@
|
||||
export * from './TranslatorSingleton';
|
||||
export * from './types';
|
||||
export { default as Translator } from './Translator';
|
||||
|
||||
export default {};
|
||||
|
||||
export { default as __hack_reexport_translation } from './types';
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
import { Jed as BaseJed, JedOptions, DomainData, Translations } from './jed';
|
||||
|
||||
export { Translations, DomainConfig, DomainData, JedOptions } from './jed';
|
||||
export type { Translations, DomainConfig, DomainData, JedOptions } from './jed';
|
||||
|
||||
/**
|
||||
* Superset supported languages.
|
||||
@@ -86,5 +86,3 @@ export interface TranslatorConfig {
|
||||
* Key-value mapping of translation key and the translations.
|
||||
*/
|
||||
export type LocaleData = Partial<Record<Locale, Translations>>;
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -52,5 +52,3 @@ export interface Jed {
|
||||
|
||||
options: JedOptions;
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"tinycolor2": "*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ant-design/icons": "^5.6.1 || ^6.0.0",
|
||||
"@ant-design/icons": "^5.6.1",
|
||||
"@emotion/react": "^11.4.1",
|
||||
"@superset-ui/core": "*",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
|
||||
@@ -537,8 +537,6 @@ export type ResolvedColorFormatterResult = {
|
||||
color?: string;
|
||||
};
|
||||
|
||||
export default {};
|
||||
|
||||
export function isColumnMeta(column: AnyDict): column is ColumnMeta {
|
||||
return !!column && 'column_name' in column;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^6.3.2",
|
||||
"@ant-design/icons": "^6.3.4",
|
||||
"@apache-superset/core": "*",
|
||||
"@babel/runtime": "^7.29.7",
|
||||
"@braintree/sanitize-url": "^7.1.2",
|
||||
@@ -78,9 +78,9 @@
|
||||
"math-expression-evaluator": "^2.0.7",
|
||||
"parse-ms": "^4.0.0",
|
||||
"re-resizable": "^6.11.2",
|
||||
"react-ace": "^14.0.1",
|
||||
"react-ace": "^15.0.0",
|
||||
"react-draggable": "^4.7.1",
|
||||
"react-error-boundary": "^6.1.3",
|
||||
"react-error-boundary": "^6.1.4",
|
||||
"react-js-cron": "^6.0.2",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-resize-detector": "^7.1.2",
|
||||
@@ -103,7 +103,7 @@
|
||||
"@types/d3-time-format": "^4.0.3",
|
||||
"@types/jquery": "^4.0.1",
|
||||
"@types/lodash": "^4.17.25",
|
||||
"@types/node": "^26.4.0",
|
||||
"@types/node": "^26.4.1",
|
||||
"@types/prop-types": "^15.7.15",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/react-table": "^7.7.20",
|
||||
|
||||
+98
@@ -566,6 +566,104 @@ test('should NOT refetch data when other string-based renderTrigger controls cha
|
||||
});
|
||||
});
|
||||
|
||||
test('should NOT refetch data when echart_options (string-based renderTrigger control) changes', async () => {
|
||||
// Matches how the Timeseries/MixedTimeseries control panels reference this
|
||||
// shared control: a bare string, e.g. ['echart_options'].
|
||||
const controlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
{
|
||||
controlSetRows: [['echart_options']],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
jest.mocked(getChartControlPanelRegistry).mockReturnValue({
|
||||
get: jest.fn().mockReturnValue(controlPanelConfig),
|
||||
} as unknown as ReturnType<typeof getChartControlPanelRegistry>);
|
||||
|
||||
const formDataWithEchartOptions = {
|
||||
...mockFormData,
|
||||
echart_options: '{}',
|
||||
};
|
||||
|
||||
const { rerender, getByTestId } = render(
|
||||
<StatefulChart
|
||||
formData={formDataWithEchartOptions}
|
||||
chartType="test_chart"
|
||||
/>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockChartClient.client.post).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
// Edit the ECharts Options field (e.g. from the Customize tab while the
|
||||
// chart is part of a Matrixify grid cell).
|
||||
const updatedFormData = {
|
||||
...formDataWithEchartOptions,
|
||||
echart_options: '{"title": {"text": "My Chart"}}',
|
||||
};
|
||||
|
||||
rerender(<StatefulChart formData={updatedFormData} chartType="test_chart" />);
|
||||
|
||||
await waitFor(() => {
|
||||
// Should NOT refetch data - echart_options is a renderTrigger control
|
||||
expect(mockChartClient.client.post).toHaveBeenCalledTimes(1);
|
||||
// But should re-render with the new formData
|
||||
expect(getByTestId('super-chart')).toHaveTextContent(
|
||||
JSON.stringify(updatedFormData),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('should refetch when a chart overrides a shared renderTrigger control to renderTrigger: false', async () => {
|
||||
// Matches Country Map's controlPanel.controlOverrides, which sets
|
||||
// linear_color_scheme to renderTrigger: false because it drives the
|
||||
// choropleth data query rather than just styling.
|
||||
const controlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
{
|
||||
controlSetRows: [['linear_color_scheme']],
|
||||
},
|
||||
],
|
||||
controlOverrides: {
|
||||
linear_color_scheme: {
|
||||
renderTrigger: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
jest.mocked(getChartControlPanelRegistry).mockReturnValue({
|
||||
get: jest.fn().mockReturnValue(controlPanelConfig),
|
||||
} as unknown as ReturnType<typeof getChartControlPanelRegistry>);
|
||||
|
||||
const formDataWithColorScheme = {
|
||||
...mockFormData,
|
||||
linear_color_scheme: 'schemeA',
|
||||
};
|
||||
|
||||
const { rerender } = render(
|
||||
<StatefulChart formData={formDataWithColorScheme} chartType="test_chart" />,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockChartClient.client.post).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
const updatedFormData = {
|
||||
...formDataWithColorScheme,
|
||||
linear_color_scheme: 'schemeB',
|
||||
};
|
||||
|
||||
rerender(<StatefulChart formData={updatedFormData} chartType="test_chart" />);
|
||||
|
||||
await waitFor(() => {
|
||||
// Should refetch because this chart's controlOverrides mark the control
|
||||
// as data-affecting, overriding the shared-control fallback.
|
||||
expect(mockChartClient.client.post).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
test('should refetch when string control is NOT in RENDER_TRIGGER_SHARED_CONTROLS', async () => {
|
||||
// Control panel with a string control that is NOT in the renderTrigger set
|
||||
const controlPanelConfig = {
|
||||
|
||||
@@ -50,6 +50,9 @@ type LoadingState = 'uninitialized' | 'loading' | 'loaded' | 'error';
|
||||
* This list is needed because string-based control references (e.g., ['zoomable'])
|
||||
* cannot be introspected for their renderTrigger property without importing
|
||||
* sharedControls, which would create a circular dependency.
|
||||
*
|
||||
* Keep this list in sync with the `renderTrigger: true` entries in
|
||||
* @superset-ui/chart-controls's sharedControls.tsx.
|
||||
*/
|
||||
const RENDER_TRIGGER_SHARED_CONTROLS = new Set([
|
||||
'zoomable',
|
||||
@@ -57,6 +60,11 @@ const RENDER_TRIGGER_SHARED_CONTROLS = new Set([
|
||||
'time_shift_color',
|
||||
'y_axis_format',
|
||||
'currency_format',
|
||||
'color_picker',
|
||||
'linear_color_scheme',
|
||||
'x_axis_time_format',
|
||||
'x_axis_number_format',
|
||||
'echart_options',
|
||||
]);
|
||||
|
||||
/**
|
||||
@@ -111,6 +119,28 @@ function shouldRefetchData(
|
||||
}
|
||||
});
|
||||
|
||||
// Individual chart types can override a shared control's renderTrigger
|
||||
// behavior (e.g., Country Map sets `linear_color_scheme` to
|
||||
// renderTrigger: false because it drives the choropleth query, not just
|
||||
// styling). Apply those overrides on top of the shared-control fallback
|
||||
// so such controls still trigger a refetch for that chart type.
|
||||
const { controlOverrides } = controlPanel;
|
||||
if (controlOverrides) {
|
||||
Object.entries(controlOverrides).forEach(([controlName, override]) => {
|
||||
if (
|
||||
override &&
|
||||
typeof override === 'object' &&
|
||||
'renderTrigger' in override
|
||||
) {
|
||||
if ((override as { renderTrigger?: boolean }).renderTrigger) {
|
||||
renderTriggerControls.add(controlName);
|
||||
} else {
|
||||
renderTriggerControls.delete(controlName);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check which fields changed
|
||||
const changedFields = Object.keys(nextFormData).filter(
|
||||
key =>
|
||||
|
||||
@@ -44,7 +44,3 @@ export * from './types/TransformFunction';
|
||||
export * from './types/QueryResponse';
|
||||
export * from './types/VizType';
|
||||
export * from './types/matrixify';
|
||||
|
||||
export { default as __hack_reexport_chart_Base } from './types/Base';
|
||||
export { default as __hack_reexport_chart_TransformFunction } from './types/TransformFunction';
|
||||
export { default as __hack_reexport_chart_QueryResponse } from './types/QueryResponse';
|
||||
|
||||
@@ -113,8 +113,19 @@ export interface BackendOwnState {
|
||||
* Each chart plugin can implement this to convert its internal state representation
|
||||
* to the standardized backend format.
|
||||
*/
|
||||
export interface ChartStateConverterOptions {
|
||||
// Set when converting for a download/export query rather than the chart's
|
||||
// live (re-)query. Some chart-specific state (e.g. AG Grid's client-side
|
||||
// sort/filter) is normally excluded from the live query's ownState to
|
||||
// avoid triggering an unnecessary requery, but a downloaded file has no
|
||||
// client-side pass to apply that state, so it still needs to be converted
|
||||
// for exports to reproduce the displayed view.
|
||||
forExport?: boolean;
|
||||
}
|
||||
|
||||
export type ChartStateConverter<TChartState = JsonObject> = (
|
||||
chartState: TChartState,
|
||||
options?: ChartStateConverterOptions,
|
||||
) => Partial<BackendOwnState>;
|
||||
|
||||
export interface PlainObject {
|
||||
@@ -153,5 +164,3 @@ export enum AxisType {
|
||||
export interface LegendState {
|
||||
[key: string]: boolean;
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -48,5 +48,3 @@ export type LegacyQueryData = PlainObject;
|
||||
* Don't use this for a specific chart (since you know which API it uses already).
|
||||
*/
|
||||
export type QueryData = LegacyQueryData | ChartDataResponseResult;
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -50,5 +50,3 @@ export type BuildQueryFunction<T extends QueryFormData> = (
|
||||
};
|
||||
},
|
||||
) => QueryContext;
|
||||
|
||||
export default {};
|
||||
|
||||
+55
@@ -604,6 +604,61 @@ test('cleans up event listeners on unmount', async () => {
|
||||
offSpy.mockRestore();
|
||||
});
|
||||
|
||||
test('re-applies annotations only when their content actually changes across renders (react-ace 15 fast-equals regression guard)', async () => {
|
||||
// react-ace's componentDidUpdate decides whether to call
|
||||
// session.setAnnotations() by deep-comparing the new/old `annotations`
|
||||
// prop (lib/ace.js, using an internal deep-equality helper -- lodash's
|
||||
// isEqual through react-ace 14.x, fast-equals's deepEqual from 15.0.0
|
||||
// onward). Superset's own AceEditorProvider/EditorWrapper always pass a
|
||||
// freshly `.map()`-derived annotations array on every render, so this
|
||||
// guards the actual behavior Superset relies on: a same-content-but-
|
||||
// different-reference array must NOT re-trigger setAnnotations (or the
|
||||
// editor would thrash on every keystroke-driven re-render), while a
|
||||
// genuinely different array must still update the editor.
|
||||
const ref = createRef<AceEditor>();
|
||||
const annotationsV1 = [{ row: 0, column: 0, type: 'error', text: 'oops' }];
|
||||
|
||||
const { rerender, container } = render(
|
||||
<SQLEditor ref={ref as React.Ref<never>} annotations={annotationsV1} />,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(container.querySelector(selector)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const session = ref.current?.editor?.getSession();
|
||||
expect(session).toBeDefined();
|
||||
if (!session) return;
|
||||
|
||||
// The initial mount already applies annotations via componentDidMount,
|
||||
// not componentDidUpdate, so start observing only from the first update.
|
||||
const setAnnotationsSpy = jest.spyOn(session, 'setAnnotations');
|
||||
|
||||
// Same content, new array/object references -- must be a no-op.
|
||||
const annotationsV1SameContent = [
|
||||
{ row: 0, column: 0, type: 'error', text: 'oops' },
|
||||
];
|
||||
rerender(
|
||||
<SQLEditor
|
||||
ref={ref as React.Ref<never>}
|
||||
annotations={annotationsV1SameContent}
|
||||
/>,
|
||||
);
|
||||
expect(setAnnotationsSpy).not.toHaveBeenCalled();
|
||||
|
||||
// Genuinely different content -- must update, with the new value.
|
||||
const annotationsV2 = [
|
||||
{ row: 1, column: 2, type: 'warning', text: 'different' },
|
||||
];
|
||||
rerender(
|
||||
<SQLEditor ref={ref as React.Ref<never>} annotations={annotationsV2} />,
|
||||
);
|
||||
expect(setAnnotationsSpy).toHaveBeenCalledTimes(1);
|
||||
expect(setAnnotationsSpy).toHaveBeenCalledWith(annotationsV2);
|
||||
|
||||
setAnnotationsSpy.mockRestore();
|
||||
});
|
||||
|
||||
test('does not move autocomplete popup if target container is document.body', async () => {
|
||||
const ref = createRef<AceEditor>();
|
||||
const { container } = render(<SQLEditor ref={ref as React.Ref<never>} />);
|
||||
|
||||
+71
@@ -16,6 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { CSSProperties } from 'react';
|
||||
import { screen, render } from '@superset-ui/core/spec';
|
||||
import { Button, DropdownContainer, Icons } from '..';
|
||||
|
||||
@@ -178,3 +179,73 @@ test('component renders and functions without throwing errors', () => {
|
||||
// Basic functionality test
|
||||
expect(screen.getByText('Element 1')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const ITEM_WIDTH = 100;
|
||||
/* Width the flex layout leaves the row once the trigger button is laid out. */
|
||||
const ROW_WIDTH = 250;
|
||||
/* Item count of the transient row that holds every item while remeasuring. */
|
||||
const ALL_ITEMS = 4;
|
||||
|
||||
/**
|
||||
* Lays items out at ITEM_WIDTH each. In the steady state the row is reported at
|
||||
* the flex-bounded ROW_WIDTH, so a three-item row overflows and the trigger
|
||||
* shows. In the all-items frame the row is reported at its own content width
|
||||
* instead, which is the frame Edge can paint before the flex layout bounds the
|
||||
* row and its children spill out. `onRowMeasure` receives the row during that
|
||||
* frame so a test can assert how it is styled.
|
||||
*/
|
||||
const mockBoundingRects = (onRowMeasure: (row: HTMLElement) => void) => {
|
||||
const getBoundingClientRect: (this: HTMLElement) => DOMRect = function () {
|
||||
let right: number;
|
||||
if (this.dataset.test === 'container') {
|
||||
const allItemsFrame = this.children.length === ALL_ITEMS;
|
||||
right = allItemsFrame ? this.children.length * ITEM_WIDTH : ROW_WIDTH;
|
||||
if (allItemsFrame) {
|
||||
onRowMeasure(this);
|
||||
}
|
||||
} else {
|
||||
const itemNumber = Number(this.textContent?.match(/Element (\d+)/)?.[1]);
|
||||
right = itemNumber ? itemNumber * ITEM_WIDTH : ROW_WIDTH;
|
||||
}
|
||||
return {
|
||||
bottom: 0,
|
||||
height: 0,
|
||||
left: right - ITEM_WIDTH,
|
||||
right,
|
||||
top: 0,
|
||||
width: ITEM_WIDTH,
|
||||
x: right - ITEM_WIDTH,
|
||||
y: 0,
|
||||
toJSON: () => ({}),
|
||||
};
|
||||
};
|
||||
jest
|
||||
.spyOn(HTMLElement.prototype, 'getBoundingClientRect')
|
||||
.mockImplementation(getBoundingClientRect);
|
||||
};
|
||||
|
||||
/* Grows an overflowing row by one item, which mounts every item for a frame
|
||||
* while the new overflow index is calculated. */
|
||||
const remeasureWithExtraItem = (style?: CSSProperties) => {
|
||||
const { rerender } = render(<DropdownContainer items={generateItems(3)} />);
|
||||
rerender(<DropdownContainer items={generateItems(3)} />);
|
||||
expect(screen.getByTestId('dropdown-container-btn')).toBeInTheDocument();
|
||||
rerender(
|
||||
<DropdownContainer items={generateItems(ALL_ITEMS)} style={style} />,
|
||||
);
|
||||
};
|
||||
|
||||
test('clips the item row while remeasuring, then restores it', () => {
|
||||
const measured: string[] = [];
|
||||
mockBoundingRects(row => {
|
||||
measured.push(row.style.overflow);
|
||||
});
|
||||
|
||||
remeasureWithExtraItem({ overflow: 'visible' });
|
||||
|
||||
/* While the row holds every item its children can spill past its own box, so
|
||||
* clipping wins over the consumer's `overflow: visible` for that frame. Once
|
||||
* the new overflow index is applied the consumer's value comes back. */
|
||||
expect(measured[0]).toBe('hidden');
|
||||
expect(measured.at(-1)).toBe('visible');
|
||||
});
|
||||
|
||||
+12
-1
@@ -330,7 +330,18 @@ export const DropdownContainer = forwardRef(
|
||||
min-width: 0px;
|
||||
`}
|
||||
data-test="container"
|
||||
style={style}
|
||||
style={
|
||||
recalculating
|
||||
? {
|
||||
...style,
|
||||
/* The flex layout already bounds the row's own box, but its
|
||||
* children can spill past that box in the frame Edge paints
|
||||
* before the new overflow index is applied. Clipping keeps
|
||||
* them inside the filter bar. */
|
||||
overflow: 'hidden',
|
||||
}
|
||||
: style
|
||||
}
|
||||
>
|
||||
{notOverflowedItems.map(item => item.element)}
|
||||
</div>
|
||||
|
||||
+102
@@ -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.
|
||||
*/
|
||||
import { Icons } from '../Icons';
|
||||
import { Button } from '../Button';
|
||||
import MetadataBar, { MetadataType } from '../MetadataBar';
|
||||
import { Menu } from '../Menu';
|
||||
import { PageHeaderWithActions, PageHeaderWithActionsProps } from '.';
|
||||
|
||||
export default {
|
||||
title: 'Design System/Components/PageHeaderWithActions',
|
||||
component: PageHeaderWithActions,
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
'Header used on entity pages (e.g. the dashboard page) combining an editable title with badges, a metadata bar, and page-level actions.',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Mirrors src/dashboard/components/Header's real composition: an editable
|
||||
// title, the certified badge, and a titlePanelAdditionalItems cluster of a
|
||||
// refresh button, an auto-refresh indicator, a published-status toggle, and
|
||||
// a MetadataBar (Last Modified + Editor) -- the same items the real
|
||||
// dashboard header packs into that space -- so this story reproduces the
|
||||
// header's real narrow-viewport layout behavior, not just the isolated
|
||||
// MetadataBar. The real RefreshButton/AutoRefreshIndicator/PublishedStatus
|
||||
// components live in src/dashboard and depend on this package, so they
|
||||
// can't be imported here without inverting that dependency; these are
|
||||
// same-sized stand-ins built from core components instead.
|
||||
export const DashboardHeader = (args: PageHeaderWithActionsProps) => (
|
||||
<PageHeaderWithActions {...args} />
|
||||
);
|
||||
|
||||
DashboardHeader.args = {
|
||||
editableTitleProps: {
|
||||
title: 'Q3 Executive Revenue and Growth Overview Dashboard',
|
||||
placeholder: 'Add the name of the dashboard',
|
||||
onSave: () => {},
|
||||
canEdit: true,
|
||||
label: 'Dashboard title',
|
||||
},
|
||||
showTitlePanelItems: true,
|
||||
certificatiedBadgeProps: {
|
||||
certifiedBy: 'Jane Doe',
|
||||
details: 'Certified by the BI team',
|
||||
},
|
||||
showFaveStar: true,
|
||||
faveStarProps: { itemId: 1, saveFaveStar: () => {}, isStarred: false },
|
||||
titlePanelAdditionalItems: [
|
||||
<Button key="refresh-button" buttonStyle="link" tooltip="Refresh dashboard">
|
||||
<Icons.ReloadOutlined iconSize="l" />
|
||||
</Button>,
|
||||
<Icons.SyncOutlined key="auto-refresh-indicator" iconSize="l" />,
|
||||
<Button key="published-status" buttonStyle="link">
|
||||
Published
|
||||
</Button>,
|
||||
<MetadataBar
|
||||
key="metadata-bar"
|
||||
tooltipPlacement="bottom"
|
||||
items={[
|
||||
{
|
||||
type: MetadataType.LastModified,
|
||||
value: '2 hours ago',
|
||||
modifiedBy: 'Jane Doe',
|
||||
},
|
||||
{
|
||||
type: MetadataType.Editor,
|
||||
createdBy: 'Jane Doe',
|
||||
editors: ['Jane Doe', 'John Smith'],
|
||||
createdOn: 'a week ago',
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
],
|
||||
rightPanelAdditionalItems: <button type="button">Edit dashboard</button>,
|
||||
additionalActionsMenu: (
|
||||
<Menu
|
||||
items={[{ label: 'Edit properties', key: '1' }]}
|
||||
data-test="additional-actions-menu"
|
||||
/>
|
||||
),
|
||||
menuDropdownProps: {},
|
||||
};
|
||||
+18
-1
@@ -18,7 +18,12 @@
|
||||
*/
|
||||
|
||||
import { render, screen, userEvent } from '@superset-ui/core/spec';
|
||||
import { PageHeaderWithActions, PageHeaderWithActionsProps } from './index';
|
||||
import { supersetTheme } from '@apache-superset/core/theme';
|
||||
import {
|
||||
buttonsStyles,
|
||||
PageHeaderWithActions,
|
||||
PageHeaderWithActionsProps,
|
||||
} from './index';
|
||||
import { Menu } from '../Menu';
|
||||
|
||||
const defaultProps: PageHeaderWithActionsProps = {
|
||||
@@ -54,3 +59,15 @@ test('Renders', async () => {
|
||||
await userEvent.click(screen.getByLabelText('Menu actions trigger'));
|
||||
expect(defaultProps.menuDropdownProps.onOpenChange).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('clips the title panel buttons/metadata cluster instead of letting it overflow into the actions menu', () => {
|
||||
// jsdom doesn't compute real flexbox layout, so it can't verify the
|
||||
// overlap itself is fixed; this guards the underlying CSS from
|
||||
// regressing instead. Without `overflow: hidden`, this wrapper's
|
||||
// automatic flex minimum size is based on its content rather than 0, so
|
||||
// it refuses to shrink -- forcing the title to absorb all the space
|
||||
// pressure until the cluster's content renders outside its box and
|
||||
// overlaps the actions menu once the title has fully collapsed.
|
||||
const { styles } = buttonsStyles(supersetTheme);
|
||||
expect(styles).toMatch(/overflow:\s*hidden/);
|
||||
});
|
||||
|
||||
+5
-1
@@ -99,9 +99,13 @@ const headerStyles = (theme: SupersetTheme) => css`
|
||||
}
|
||||
`;
|
||||
|
||||
const buttonsStyles = (theme: SupersetTheme) => css`
|
||||
// Exported only so PageHeaderWithActions.test.tsx can assert on the
|
||||
// `overflow: hidden` declaration directly; not part of the component's
|
||||
// public API.
|
||||
export const buttonsStyles = (theme: SupersetTheme) => css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
padding-left: ${theme.sizeUnit * 2}px;
|
||||
|
||||
& .anticon-star {
|
||||
|
||||
@@ -222,6 +222,7 @@ export type {
|
||||
GridState,
|
||||
GridReadyEvent,
|
||||
CellClickedEvent,
|
||||
CellContextMenuEvent,
|
||||
CellKeyDownEvent,
|
||||
CellClassParams,
|
||||
IMenuActionParams,
|
||||
|
||||
@@ -26,4 +26,3 @@ export type { NormalizeOptions } from './normalizeBackendUrls';
|
||||
|
||||
export * from './types';
|
||||
export * from './constants';
|
||||
export { default as __hack_reexport_connection } from './types';
|
||||
|
||||
@@ -176,5 +176,3 @@ export interface SupersetClientInterface extends Pick<
|
||||
}
|
||||
|
||||
export type SupersetClientResponse = Response | JsonResponse | TextResponse;
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -24,4 +24,3 @@ export { default as mergeMargin } from './mergeMargin';
|
||||
export { default as parseLength } from './parseLength';
|
||||
|
||||
export * from './types';
|
||||
export { default as __hack_reexport_dimension } from './types';
|
||||
|
||||
@@ -37,5 +37,3 @@ export interface Dimension {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -21,4 +21,3 @@ export { default as getFormData } from './getFormData';
|
||||
export { default as getDatasourceMetadata } from './getDatasourceMetadata';
|
||||
|
||||
export * from './types';
|
||||
export { default as __hack_reexport_query_api_legacy } from './types';
|
||||
|
||||
@@ -24,5 +24,3 @@ export interface LegacyChartDataResponse extends Omit<
|
||||
> {
|
||||
data: Record<string, unknown>[] | Record<string, unknown>;
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -39,5 +39,3 @@ export interface TimeCompare {
|
||||
time_compare?: string;
|
||||
comparison_type?: ComparisonType;
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -82,5 +82,3 @@ export function isAdhocColumnReference(column?: any): column is AdhocColumn {
|
||||
export function isQueryFormColumn(column: any): column is QueryFormColumn {
|
||||
return isPhysicalColumn(column) || isAdhocColumn(column);
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -271,5 +271,3 @@ export interface LegacyChartCustomizationItem {
|
||||
chartId?: number;
|
||||
customization: LegacyChartCustomizationConfig;
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -71,5 +71,3 @@ export const DEFAULT_METRICS: Metric[] = [
|
||||
uuid: nanoid(),
|
||||
},
|
||||
];
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -97,5 +97,3 @@ export function isQueryFormMetric(metric: any): metric is QueryFormMetric {
|
||||
isAdhocMetricSQL(metric)
|
||||
);
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -494,5 +494,3 @@ export enum ContributionType {
|
||||
export type DatasourceSamplesQuery = {
|
||||
filters?: QueryObjectFilterClause[];
|
||||
};
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -214,5 +214,3 @@ export type LatestQueryFormData = Partial<QueryFormData>;
|
||||
//---------------------------------------------------
|
||||
// Type guards
|
||||
//---------------------------------------------------
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -114,5 +114,3 @@ export interface TimeseriesChartDataResponseResult extends ChartDataResponseResu
|
||||
export interface ChartDataResponse {
|
||||
queries: ChartDataResponseResult[];
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -36,5 +36,3 @@ export type TimeColumnConfigKey =
|
||||
export type AppliedTimeExtras = Partial<
|
||||
Record<TimeColumnConfigKey, keyof QueryObject>
|
||||
>;
|
||||
|
||||
export default {};
|
||||
|
||||
@@ -28,15 +28,3 @@ export * from './Time';
|
||||
export * from './AdvancedAnalytics';
|
||||
export * from './PostProcessing';
|
||||
export * from './Dashboard';
|
||||
|
||||
export { default as __hack_reexport_Datasource } from './Datasource';
|
||||
export { default as __hack_reexport_Column } from './Column';
|
||||
export { default as __hack_reexport_Metric } from './Metric';
|
||||
export { default as __hack_reexport_Query } from './Query';
|
||||
export { default as __hack_reexport_QueryResponse } from './QueryResponse';
|
||||
export { default as __hack_reexport_QueryFormData } from './QueryFormData';
|
||||
export { default as __hack_reexport_Time } from './Time';
|
||||
export { default as __hack_reexport_AdvancedAnalytics } from './AdvancedAnalytics';
|
||||
export { default as __hack_reexport_Dashboard } from './Dashboard';
|
||||
|
||||
export default {};
|
||||
|
||||
+17
-5
@@ -16,15 +16,27 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
DataRecordValue,
|
||||
normalizeTimestamp,
|
||||
TimeFormatFunction,
|
||||
} from '@superset-ui/core';
|
||||
import type { DataRecordValue } from '../query/types/QueryResponse';
|
||||
import type { TimeFormatFunction } from './types';
|
||||
import normalizeTimestamp from './utils/normalizeTimestamp';
|
||||
|
||||
/**
|
||||
* A missing date can arrive as either `null`/`undefined` or an empty string
|
||||
* (e.g. a blank cell in an otherwise-numeric epoch column, which also has the
|
||||
* side effect of degrading the whole column's formatter to `String` - see
|
||||
* `isNumeric` in transformProps.ts). Both should be treated as "no value".
|
||||
*/
|
||||
export const isEmptyDateInput = (input: DataRecordValue): boolean =>
|
||||
input === null || input === undefined || input === '';
|
||||
|
||||
/**
|
||||
* Extended Date object with a custom formatter, and retains the original input
|
||||
* when the formatter is simple `String(..)`.
|
||||
*
|
||||
* `toString()` never formats an Invalid Date: it returns the original input
|
||||
* instead. `stringifyTimeInput` relies on that when it falls back to
|
||||
* `${value}` for an unparseable input, otherwise the two would call each other
|
||||
* forever.
|
||||
*/
|
||||
export default class DateWithFormatter extends Date {
|
||||
formatter: TimeFormatFunction;
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
export { default as TimeFormats, LOCAL_PREFIX } from './TimeFormats';
|
||||
export { default as TimeFormatter, PREVIEW_TIME } from './TimeFormatter';
|
||||
export {
|
||||
default as DateWithFormatter,
|
||||
isEmptyDateInput,
|
||||
} from './DateWithFormatter';
|
||||
export { DEFAULT_D3_TIME_FORMAT } from './D3FormatConfig';
|
||||
|
||||
export {
|
||||
|
||||
+13
-2
@@ -28,8 +28,17 @@ export default function stringifyTimeInput(
|
||||
let time: Date;
|
||||
if (typeof value === 'string') {
|
||||
const trimmed = value.trim();
|
||||
// A bare four-digit string is the ISO 8601 year-only form ("2017"), which
|
||||
// every engine parses as January 1st of that year. Any other integer
|
||||
// string is an epoch timestamp in milliseconds that was stringified on
|
||||
// its way here, e.g. by the pivot table, and is not a valid Date input.
|
||||
const isYear = /^\d{4}$/.test(trimmed);
|
||||
const isIntegerString = /^-?\d+$/.test(trimmed);
|
||||
time = new Date(isIntegerString ? Number(trimmed) : value);
|
||||
if (isYear) {
|
||||
time = new Date(trimmed);
|
||||
} else {
|
||||
time = new Date(isIntegerString ? Number(trimmed) : value);
|
||||
}
|
||||
} else {
|
||||
time = value instanceof Date ? value : new Date(value);
|
||||
}
|
||||
@@ -37,7 +46,9 @@ export default function stringifyTimeInput(
|
||||
// An input that does not resolve to a valid date - a duration such as
|
||||
// "00:01:54", for instance - would otherwise be formatted from an Invalid
|
||||
// Date and render as "NaN:NaN:NaN". Fall back to its own representation,
|
||||
// as is already done for null and undefined above.
|
||||
// as is already done for null and undefined above. For a `DateWithFormatter`
|
||||
// this calls its `toString()`, which returns the original input rather than
|
||||
// re-entering the formatter; that guard is what keeps the fallback finite.
|
||||
if (Number.isNaN(time.getTime())) {
|
||||
return `${value}`;
|
||||
}
|
||||
|
||||
@@ -79,4 +79,5 @@ export interface AgGridChartState {
|
||||
columnOrder?: string[];
|
||||
pageSize?: number;
|
||||
currentPage?: number;
|
||||
serverPagination?: boolean;
|
||||
}
|
||||
|
||||
+2
-21
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/**
|
||||
* 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
|
||||
@@ -16,11 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { getTimeFormatter } from '@superset-ui/core';
|
||||
import { GenericDataType } from '@apache-superset/core/common';
|
||||
import DateWithFormatter from '../../src/utils/DateWithFormatter';
|
||||
import { formatColumnValue } from '../../src/utils/formatValue';
|
||||
import { DataColumnMeta } from '../../src/types';
|
||||
import { DateWithFormatter, getTimeFormatter } from '@superset-ui/core';
|
||||
|
||||
const formatter = getTimeFormatter('%H:%M:%S');
|
||||
|
||||
@@ -43,18 +39,3 @@ test('retains the original input when the formatter is String', () => {
|
||||
const value = new DateWithFormatter('00:01:54');
|
||||
expect(String(value)).toBe('00:01:54');
|
||||
});
|
||||
|
||||
test('renders a duration cell through the column formatter without producing NaN', () => {
|
||||
// The cell text is produced by formatColumnValue, which hands the wrapped
|
||||
// value straight to the formatter rather than going through toString().
|
||||
const column: DataColumnMeta = {
|
||||
key: 'call_period',
|
||||
label: 'call_period',
|
||||
dataType: GenericDataType.Temporal,
|
||||
formatter,
|
||||
isNumeric: false,
|
||||
};
|
||||
const value = new DateWithFormatter('00:01:54', { formatter });
|
||||
|
||||
expect(formatColumnValue(column, value)).toEqual([false, '00:01:54']);
|
||||
});
|
||||
+23
@@ -16,6 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { DateWithFormatter, getTimeFormatter } from '@superset-ui/core';
|
||||
import stringifyTimeInput from '../../../src/time-format/utils/stringifyTimeInput';
|
||||
|
||||
const format = (time: Date) => time.toISOString();
|
||||
@@ -56,3 +57,25 @@ test('returns unparseable strings unchanged instead of formatting an Invalid Dat
|
||||
test('returns the representation of a Date that could not be resolved', () => {
|
||||
expect(stringifyTimeInput(new Date('00:01:54'), format)).toBe('Invalid Date');
|
||||
});
|
||||
|
||||
test('treats a four-digit integer string as a year, not as milliseconds', () => {
|
||||
// "2017" is the ISO 8601 year-only form. Reading it as an epoch offset
|
||||
// would silently turn it into two seconds past 1970.
|
||||
expect(stringifyTimeInput('2017', format)).toBe('2017-01-01T00:00:00.000Z');
|
||||
expect(stringifyTimeInput(' 1987 ', format)).toBe('1987-01-01T00:00:00.000Z');
|
||||
// Longer digit strings stay epoch milliseconds.
|
||||
expect(stringifyTimeInput('1704067200000', format)).toBe(
|
||||
'2024-01-01T00:00:00.000Z',
|
||||
);
|
||||
});
|
||||
|
||||
test('returns the original input of an unparseable DateWithFormatter without re-entering the formatter', () => {
|
||||
// The `${value}` fallback calls `DateWithFormatter.toString()`, which must
|
||||
// return the input rather than call the formatter again, or the two would
|
||||
// recurse until the stack overflows.
|
||||
const formatter = getTimeFormatter('%H:%M:%S');
|
||||
const value = new DateWithFormatter('00:01:54', { formatter });
|
||||
|
||||
expect(stringifyTimeInput(value, time => formatter(time))).toBe('00:01:54');
|
||||
expect(formatter(value)).toBe('00:01:54');
|
||||
});
|
||||
|
||||
@@ -573,6 +573,12 @@ images:
|
||||
alt: Apache Spark SQL
|
||||
source_file: docs/intro.md
|
||||
selector: null
|
||||
- type: database-logo
|
||||
page_url: "https://superset.apache.org/user-docs"
|
||||
image_url: docs/static/img/databases/ascend.webp
|
||||
alt: Ascend
|
||||
source_file: docs/intro.md
|
||||
selector: null
|
||||
- type: database-logo
|
||||
page_url: "https://superset.apache.org/user-docs"
|
||||
image_url: docs/static/img/databases/aws.png
|
||||
@@ -941,6 +947,13 @@ images:
|
||||
alt: Apache Spark SQL
|
||||
source_file: docs/index.mdx
|
||||
selector: null
|
||||
- type: database-logo
|
||||
page_url: "https://superset.apache.org/user-docs"
|
||||
image_url: "https://superset.apache.org/img/databases/ascend.webp"
|
||||
output_path: docs/static/img/databases/ascend.webp
|
||||
alt: Ascend
|
||||
source_file: docs/index.mdx
|
||||
selector: null
|
||||
- type: database-logo
|
||||
page_url: "https://superset.apache.org/user-docs"
|
||||
image_url: "https://superset.apache.org/img/databases/aws.png"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user