mirror of
https://github.com/apache/superset.git
synced 2026-06-11 10:39:15 +00:00
Compare commits
2 Commits
dependabot
...
fix/extens
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b25ebcf2e3 | ||
|
|
965ede7b04 |
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -41,8 +41,8 @@ body:
|
||||
label: Superset version
|
||||
options:
|
||||
- master / latest-dev
|
||||
- "6.1.0"
|
||||
- "6.0.0"
|
||||
- "5.0.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
|
||||
28
.github/dependabot.yml
vendored
28
.github/dependabot.yml
vendored
@@ -14,6 +14,12 @@ updates:
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
ignore:
|
||||
# TODO: remove below entries until React >= 18.0.0
|
||||
- dependency-name: "storybook"
|
||||
update-types: ["version-update:semver-major", "version-update:semver-minor"]
|
||||
- dependency-name: "@storybook*"
|
||||
update-types: ["version-update:semver-major", "version-update:semver-minor"]
|
||||
- dependency-name: "eslint-plugin-storybook"
|
||||
- dependency-name: "react-error-boundary"
|
||||
- dependency-name: "@rjsf/*"
|
||||
# remark-gfm v4+ requires react-markdown v9+, which needs React 18
|
||||
@@ -36,6 +42,14 @@ updates:
|
||||
# and confirm the issue https://github.com/apache/superset/issues/39600 is fixed
|
||||
- dependency-name: "react-checkbox-tree"
|
||||
update-types: ["version-update:semver-major"]
|
||||
groups:
|
||||
storybook:
|
||||
applies-to: version-updates
|
||||
patterns:
|
||||
- "@storybook*"
|
||||
- "storybook"
|
||||
update-types:
|
||||
- "patch"
|
||||
directory: "/superset-frontend/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
@@ -76,7 +90,21 @@ updates:
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/docs/"
|
||||
ignore:
|
||||
# TODO: remove below entries until React >= 18.0.0 in superset-frontend
|
||||
- dependency-name: "storybook"
|
||||
update-types: ["version-update:semver-major", "version-update:semver-minor"]
|
||||
- dependency-name: "@storybook*"
|
||||
update-types: ["version-update:semver-major", "version-update:semver-minor"]
|
||||
- dependency-name: "eslint-plugin-storybook"
|
||||
- dependency-name: "react-error-boundary"
|
||||
groups:
|
||||
storybook:
|
||||
applies-to: version-updates
|
||||
patterns:
|
||||
- "@storybook*"
|
||||
- "storybook"
|
||||
update-types:
|
||||
- "patch"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
3
.github/workflows/bump-python-package.yml
vendored
3
.github/workflows/bump-python-package.yml
vendored
@@ -30,8 +30,9 @@ jobs:
|
||||
pull-requests: write
|
||||
checks: write
|
||||
steps:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: true
|
||||
ref: master
|
||||
|
||||
2
.github/workflows/check-python-deps.yml
vendored
2
.github/workflows/check-python-deps.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Check and notify
|
||||
|
||||
20
.github/workflows/claude.yml
vendored
20
.github/workflows/claude.yml
vendored
@@ -75,14 +75,14 @@ jobs:
|
||||
issues: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 1
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Run Claude PR Action
|
||||
uses: anthropics/claude-code-action@5fb899572b81d2bb648d4d187173a2f423a9677c # beta
|
||||
with:
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
timeout_minutes: "60"
|
||||
- name: Run Claude PR Action
|
||||
uses: anthropics/claude-code-action@5fb899572b81d2bb648d4d187173a2f423a9677c # beta
|
||||
with:
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
timeout_minutes: "60"
|
||||
|
||||
8
.github/workflows/codeql-analysis.yml
vendored
8
.github/workflows/codeql-analysis.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
frontend: ${{ steps.check.outputs.frontend }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
@@ -57,13 +57,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4
|
||||
uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -74,6 +74,6 @@ jobs:
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4
|
||||
uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
4
.github/workflows/dependency-review.yml
vendored
4
.github/workflows/dependency-review.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout Repository"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: "Dependency Review"
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: "Checkout Repository"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
8
.github/workflows/docker.yml
vendored
8
.github/workflows/docker.yml
vendored
@@ -18,6 +18,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
changes:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
@@ -30,7 +31,7 @@ jobs:
|
||||
docker: ${{ steps.check.outputs.docker }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
@@ -70,8 +71,9 @@ jobs:
|
||||
IMAGE_TAG: apache/superset:GHA-${{ matrix.build_preset }}-${{ github.run_id }}
|
||||
|
||||
steps:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -145,7 +147,7 @@ jobs:
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Setup Docker Environment
|
||||
|
||||
6
.github/workflows/embedded-sdk-release.yml
vendored
6
.github/workflows/embedded-sdk-release.yml
vendored
@@ -33,13 +33,13 @@ jobs:
|
||||
run:
|
||||
working-directory: superset-embedded-sdk
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./superset-embedded-sdk/.nvmrc"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
node-version-file: './superset-embedded-sdk/.nvmrc'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- run: npm ci
|
||||
- run: npm run ci:release
|
||||
env:
|
||||
|
||||
6
.github/workflows/embedded-sdk-test.yml
vendored
6
.github/workflows/embedded-sdk-test.yml
vendored
@@ -21,13 +21,13 @@ jobs:
|
||||
run:
|
||||
working-directory: superset-embedded-sdk
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./superset-embedded-sdk/.nvmrc"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
node-version-file: './superset-embedded-sdk/.nvmrc'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
- run: npm run build
|
||||
|
||||
2
.github/workflows/generate-FOSSA-report.yml
vendored
2
.github/workflows/generate-FOSSA-report.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
@@ -18,6 +18,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
validate-all-ghas:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
@@ -27,14 +28,14 @@ jobs:
|
||||
security-events: write
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: "20"
|
||||
node-version: '20'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm install -g @action-validator/core @action-validator/cli --save-dev
|
||||
|
||||
3
.github/workflows/issue_creation.yml
vendored
3
.github/workflows/issue_creation.yml
vendored
@@ -15,8 +15,9 @@ jobs:
|
||||
pull-requests: write
|
||||
issues: write
|
||||
steps:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
46
.github/workflows/latest-release-tag.yml
vendored
46
.github/workflows/latest-release-tag.yml
vendored
@@ -11,29 +11,29 @@ jobs:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
- name: Check for latest tag
|
||||
id: latest-tag
|
||||
env:
|
||||
RELEASE_TAG_NAME: ${{ github.event.release.tag_name }}
|
||||
run: |
|
||||
source ./scripts/tag_latest_release.sh "$RELEASE_TAG_NAME" --dry-run
|
||||
- name: Check for latest tag
|
||||
id: latest-tag
|
||||
env:
|
||||
RELEASE_TAG_NAME: ${{ github.event.release.tag_name }}
|
||||
run: |
|
||||
source ./scripts/tag_latest_release.sh "$RELEASE_TAG_NAME" --dry-run
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config user.name "$GITHUB_ACTOR"
|
||||
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config user.name "$GITHUB_ACTOR"
|
||||
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||
|
||||
- name: Run latest-tag
|
||||
uses: ./.github/actions/latest-tag
|
||||
if: steps.latest-tag.outputs.SKIP_TAG != 'true'
|
||||
with:
|
||||
description: Superset latest release
|
||||
tag-name: latest
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Run latest-tag
|
||||
uses: ./.github/actions/latest-tag
|
||||
if: steps.latest-tag.outputs.SKIP_TAG != 'true'
|
||||
with:
|
||||
description: Superset latest release
|
||||
tag-name: latest
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
6
.github/workflows/license-check.yml
vendored
6
.github/workflows/license-check.yml
vendored
@@ -18,14 +18,14 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: "11"
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
- name: Run license check
|
||||
run: ./scripts/check_license.sh
|
||||
|
||||
5
.github/workflows/pr-lint.yml
vendored
5
.github/workflows/pr-lint.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -31,5 +31,6 @@ jobs:
|
||||
on-failed-regex-fail-action: true
|
||||
on-failed-regex-request-changes: false
|
||||
on-failed-regex-create-review: false
|
||||
on-failed-regex-comment: "Please format your PR title to match: `%regex%`!"
|
||||
on-failed-regex-comment:
|
||||
"Please format your PR title to match: `%regex%`!"
|
||||
repo-token: "${{ github.token }}"
|
||||
|
||||
10
.github/workflows/pre-commit.yml
vendored
10
.github/workflows/pre-commit.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
python-version: ${{ github.event_name == 'pull_request' && fromJSON('["current"]') || fromJSON('["current", "previous", "next"]') }}
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -48,9 +48,9 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "superset-frontend/package-lock.json"
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'superset-frontend/package-lock.json'
|
||||
|
||||
- name: Install Frontend Dependencies
|
||||
run: |
|
||||
@@ -74,7 +74,7 @@ jobs:
|
||||
id: changed_files
|
||||
uses: ./.github/actions/file-changes-action
|
||||
with:
|
||||
output: " "
|
||||
output: ' '
|
||||
|
||||
- name: pre-commit
|
||||
env:
|
||||
|
||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
# pulls all commits (needed for lerna / semantic release to correctly version)
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
if: env.HAS_TAGS
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./superset-frontend/.nvmrc"
|
||||
node-version-file: './superset-frontend/.nvmrc'
|
||||
|
||||
- name: Cache npm
|
||||
if: env.HAS_TAGS
|
||||
|
||||
6
.github/workflows/showtime-trigger.yml
vendored
6
.github/workflows/showtime-trigger.yml
vendored
@@ -10,11 +10,11 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr_number:
|
||||
description: "PR number to sync"
|
||||
description: 'PR number to sync'
|
||||
required: true
|
||||
type: number
|
||||
sha:
|
||||
description: "Specific SHA to deploy (optional, defaults to latest)"
|
||||
description: 'Specific SHA to deploy (optional, defaults to latest)'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
|
||||
- name: Checkout PR code (only if build needed)
|
||||
if: steps.auth.outputs.authorized == 'true' && steps.check.outputs.build_needed == 'true'
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
ref: ${{ steps.check.outputs.target_sha }}
|
||||
persist-credentials: false
|
||||
|
||||
2
.github/workflows/superset-app-cli.yml
vendored
2
.github/workflows/superset-app-cli.yml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
8
.github/workflows/superset-docs-deploy.yml
vendored
8
.github/workflows/superset-docs-deploy.yml
vendored
@@ -60,7 +60,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.event.workflow_run.head_sha || github.sha }}"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
persist-credentials: false
|
||||
@@ -68,13 +68,13 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./docs/.nvmrc"
|
||||
node-version-file: './docs/.nvmrc'
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-backend/
|
||||
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
|
||||
with:
|
||||
distribution: "zulu"
|
||||
java-version: "21"
|
||||
distribution: 'zulu'
|
||||
java-version: '21'
|
||||
- name: Install Graphviz
|
||||
run: sudo apt-get install -y graphviz
|
||||
- name: Compute Entity Relationship diagram (ERD)
|
||||
|
||||
14
.github/workflows/superset-docs-verify.yml
vendored
14
.github/workflows/superset-docs-verify.yml
vendored
@@ -28,12 +28,12 @@ jobs:
|
||||
name: Link Checking
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
# Do not bump this linkinator-action version without opening
|
||||
# an ASF Infra ticket to allow the new version first!
|
||||
- uses: JustinBeckwith/linkinator-action@af984b9f30f63e796ae2ea5be5e07cb587f1bbd9 # v2.3
|
||||
- uses: JustinBeckwith/linkinator-action@af984b9f30f63e796ae2ea5be5e07cb587f1bbd9 # v2.3
|
||||
continue-on-error: true # This will make the job advisory (non-blocking, no red X)
|
||||
with:
|
||||
paths: "**/*.md, **/*.mdx"
|
||||
@@ -73,14 +73,14 @@ jobs:
|
||||
working-directory: docs
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./docs/.nvmrc"
|
||||
node-version-file: './docs/.nvmrc'
|
||||
- name: yarn install
|
||||
run: |
|
||||
yarn install --check-cache
|
||||
@@ -112,7 +112,7 @@ jobs:
|
||||
working-directory: docs
|
||||
steps:
|
||||
- name: "Checkout PR head: ${{ github.event.workflow_run.head_sha }}"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_sha }}
|
||||
persist-credentials: false
|
||||
@@ -120,7 +120,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./docs/.nvmrc"
|
||||
node-version-file: './docs/.nvmrc'
|
||||
- name: yarn install
|
||||
run: |
|
||||
yarn install --check-cache
|
||||
@@ -131,7 +131,7 @@ jobs:
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: database-diagnostics
|
||||
path: docs/src/data/
|
||||
if_no_artifact_found: "warning"
|
||||
if_no_artifact_found: 'warning'
|
||||
- name: Use fresh diagnostics
|
||||
run: |
|
||||
if [ -f "src/data/databases-diagnostics.json" ]; then
|
||||
|
||||
38
.github/workflows/superset-e2e.yml
vendored
38
.github/workflows/superset-e2e.yml
vendored
@@ -10,17 +10,17 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
use_dashboard:
|
||||
description: "Use Cypress Dashboard (true/false) [paid service - trigger manually when needed]. You MUST provide a branch and/or PR number below for this to work."
|
||||
description: 'Use Cypress Dashboard (true/false) [paid service - trigger manually when needed]. You MUST provide a branch and/or PR number below for this to work.'
|
||||
required: false
|
||||
default: "false"
|
||||
default: 'false'
|
||||
ref:
|
||||
description: "The branch or tag to checkout"
|
||||
description: 'The branch or tag to checkout'
|
||||
required: false
|
||||
default: ""
|
||||
default: ''
|
||||
pr_id:
|
||||
description: "The pull request ID to checkout"
|
||||
description: 'The pull request ID to checkout'
|
||||
required: false
|
||||
default: ""
|
||||
default: ''
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
frontend: ${{ steps.check.outputs.frontend }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
@@ -97,21 +97,21 @@ jobs:
|
||||
# Conditional checkout based on context
|
||||
- name: Checkout for push or pull_request event
|
||||
if: github.event_name == 'push' || github.event_name == 'pull_request'
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
- name: Checkout using ref (workflow_dispatch)
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != ''
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: ${{ github.event.inputs.ref }}
|
||||
submodules: recursive
|
||||
- name: Checkout using PR ID (workflow_dispatch)
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != ''
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: refs/pull/${{ github.event.inputs.pr_id }}/merge
|
||||
@@ -130,9 +130,9 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./superset-frontend/.nvmrc"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "superset-frontend/package-lock.json"
|
||||
node-version-file: './superset-frontend/.nvmrc'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'superset-frontend/package-lock.json'
|
||||
- name: Install npm dependencies
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
with:
|
||||
@@ -207,21 +207,21 @@ jobs:
|
||||
# Conditional checkout based on context (same as Cypress workflow)
|
||||
- name: Checkout for push or pull_request event
|
||||
if: github.event_name == 'push' || github.event_name == 'pull_request'
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
- name: Checkout using ref (workflow_dispatch)
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != ''
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: ${{ github.event.inputs.ref }}
|
||||
submodules: recursive
|
||||
- name: Checkout using PR ID (workflow_dispatch)
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != ''
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: refs/pull/${{ github.event.inputs.pr_id }}/merge
|
||||
@@ -240,9 +240,9 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./superset-frontend/.nvmrc"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "superset-frontend/package-lock.json"
|
||||
node-version-file: './superset-frontend/.nvmrc'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'superset-frontend/package-lock.json'
|
||||
- name: Install npm dependencies
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
with:
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
working-directory: superset-extensions-cli
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
4
.github/workflows/superset-frontend.yml
vendored
4
.github/workflows/superset-frontend.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
should-run: ${{ steps.check.outputs.frontend }}
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
@@ -110,7 +110,7 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
|
||||
4
.github/workflows/superset-helm-lint.yml
vendored
4
.github/workflows/superset-helm-lint.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-backend/
|
||||
with:
|
||||
install-superset: "false"
|
||||
install-superset: 'false'
|
||||
|
||||
- name: Set up chart-testing
|
||||
uses: ./.github/actions/chart-testing-action
|
||||
|
||||
2
.github/workflows/superset-helm-release.yml
vendored
2
.github/workflows/superset-helm-release.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
ref: ${{ inputs.ref || github.ref_name }}
|
||||
persist-credentials: true
|
||||
|
||||
22
.github/workflows/superset-playwright.yml
vendored
22
.github/workflows/superset-playwright.yml
vendored
@@ -10,13 +10,13 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
description: "The branch or tag to checkout"
|
||||
description: 'The branch or tag to checkout'
|
||||
required: false
|
||||
default: ""
|
||||
default: ''
|
||||
pr_id:
|
||||
description: "The pull request ID to checkout"
|
||||
description: 'The pull request ID to checkout'
|
||||
required: false
|
||||
default: ""
|
||||
default: ''
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
frontend: ${{ steps.check.outputs.frontend }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
@@ -83,21 +83,21 @@ jobs:
|
||||
# Conditional checkout based on context (same as Cypress workflow)
|
||||
- name: Checkout for push or pull_request event
|
||||
if: github.event_name == 'push' || github.event_name == 'pull_request'
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
- name: Checkout using ref (workflow_dispatch)
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.ref != ''
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: ${{ github.event.inputs.ref }}
|
||||
submodules: recursive
|
||||
- name: Checkout using PR ID (workflow_dispatch)
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.pr_id != ''
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: refs/pull/${{ github.event.inputs.pr_id }}/merge
|
||||
@@ -116,9 +116,9 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./superset-frontend/.nvmrc"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "superset-frontend/package-lock.json"
|
||||
node-version-file: './superset-frontend/.nvmrc'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'superset-frontend/package-lock.json'
|
||||
- name: Install npm dependencies
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
with:
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
python: ${{ steps.check.outputs.python }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -202,7 +202,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
python: ${{ steps.check.outputs.python }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
@@ -72,7 +72,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -127,7 +127,7 @@ jobs:
|
||||
- 16379:6379
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
python: ${{ steps.check.outputs.python }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Check for file changes
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
PYTHONPATH: ${{ github.workspace }}
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
10
.github/workflows/superset-translations.yml
vendored
10
.github/workflows/superset-translations.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
pull-requests: read
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
@@ -40,9 +40,9 @@ jobs:
|
||||
if: steps.check.outputs.frontend
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./superset-frontend/.nvmrc"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "superset-frontend/package-lock.json"
|
||||
node-version-file: './superset-frontend/.nvmrc'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'superset-frontend/package-lock.json'
|
||||
- name: Install dependencies
|
||||
if: steps.check.outputs.frontend
|
||||
uses: ./.github/actions/cached-dependencies
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
pull-requests: read
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
2
.github/workflows/superset-websocket.yml
vendored
2
.github/workflows/superset-websocket.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install dependencies
|
||||
|
||||
4
.github/workflows/supersetbot.yml
vendored
4
.github/workflows/supersetbot.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
comment_body:
|
||||
description: "Comment Body"
|
||||
description: 'Comment Body'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
});
|
||||
|
||||
- name: "Checkout ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
15
.github/workflows/tag-release.yml
vendored
15
.github/workflows/tag-release.yml
vendored
@@ -16,11 +16,11 @@ on:
|
||||
force-latest:
|
||||
required: true
|
||||
type: choice
|
||||
default: "false"
|
||||
default: 'false'
|
||||
description: Whether to force a latest tag on the release
|
||||
options:
|
||||
- "true"
|
||||
- "false"
|
||||
- 'true'
|
||||
- 'false'
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -49,12 +49,12 @@ jobs:
|
||||
contents: write
|
||||
strategy:
|
||||
matrix:
|
||||
build_preset:
|
||||
["dev", "lean", "py310", "websocket", "dockerize", "py311", "py312"]
|
||||
build_preset: ["dev", "lean", "py310", "websocket", "dockerize", "py311", "py312"]
|
||||
fail-fast: false
|
||||
steps:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
@@ -119,8 +119,9 @@ jobs:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
|
||||
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
|
||||
4
.github/workflows/tech-debt.yml
vendored
4
.github/workflows/tech-debt.yml
vendored
@@ -32,14 +32,14 @@ jobs:
|
||||
name: Generate Reports
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: "./superset-frontend/.nvmrc"
|
||||
node-version-file: './superset-frontend/.nvmrc'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
|
||||
@@ -55,13 +55,6 @@ WORKDIR /app/superset-frontend
|
||||
RUN mkdir -p /app/superset/static/assets \
|
||||
/app/superset/translations
|
||||
|
||||
# Harden `npm ci` against transient npm-registry network blips (e.g. ECONNRESET),
|
||||
# which otherwise fail the entire multi-platform image build with no retry.
|
||||
ENV npm_config_fetch_retries=5 \
|
||||
npm_config_fetch_retry_mintimeout=20000 \
|
||||
npm_config_fetch_retry_maxtimeout=120000 \
|
||||
npm_config_fetch_timeout=600000
|
||||
|
||||
# Mount package files and install dependencies if not in dev mode
|
||||
# NOTE: we mount packages and plugins as they are referenced in package.json as workspaces
|
||||
# ideally we'd COPY only their package.json. Here npm ci will be cached as long
|
||||
|
||||
47
UPDATING.md
47
UPDATING.md
@@ -24,27 +24,6 @@ assists people when migrating to a new version.
|
||||
|
||||
## Next
|
||||
|
||||
### Map chart renderer and OpenStreetMap migration behavior
|
||||
|
||||
The MapLibre migration for deck.gl charts preserves saved non-Mapbox styles on
|
||||
the MapLibre-compatible path. Saved styles such as OpenStreetMap, `tile://`
|
||||
tile templates, generic HTTPS style URLs, and charts without a saved style are
|
||||
not reclassified as Mapbox during migration and do not require
|
||||
`MAPBOX_API_KEY` only because of the migration.
|
||||
|
||||
Saved true Mapbox styles whose value starts with `mapbox://` remain
|
||||
Mapbox-backed. If a Superset deployment does not configure `MAPBOX_API_KEY`,
|
||||
those saved Mapbox charts keep the existing missing-key message instead of
|
||||
silently falling back to MapLibre or another provider. In Explore, deck.gl and
|
||||
point-cluster renderer controls preserve saved Mapbox state, but the Mapbox
|
||||
choice is not available as a new working renderer without a configured key.
|
||||
|
||||
The MapLibre style choices include `Streets (OSM)`, backed by
|
||||
`https://tile.openstreetmap.org/{z}/{x}/{y}.png`. This OpenStreetMap tile
|
||||
service requires visible `© OpenStreetMap contributors` attribution and should
|
||||
be used through normal browser map tile requests and caching; it is not intended
|
||||
for bulk prefetch or offline tile downloads.
|
||||
|
||||
### Duration formatter precision
|
||||
|
||||
The `DURATION` number formatter now uses `Intl.DurationFormat` for locale-aware output. By default, sub-second fields are omitted, so values that previously displayed fractional seconds with `pretty-ms`, such as `10500` milliseconds rendering as `10.5s`, now render as `10s`.
|
||||
@@ -65,32 +44,6 @@ The embedded dashboard page now validates the origin of incoming `postMessage` e
|
||||
|
||||
Enforcement only applies when the Allowed Domains list is non-empty. If the list is empty (the default), any origin is accepted, so there is no behavior change for embeds that did not configure Allowed Domains.
|
||||
|
||||
### Default guest/async JWT secrets are rejected at startup
|
||||
|
||||
Superset already refuses to start in production (non-debug, non-testing) when `SECRET_KEY` is left at its built-in default, and when `GUEST_TOKEN_JWT_SECRET` is left at its default while `EMBEDDED_SUPERSET` is enabled. This behavior is extended to `GLOBAL_ASYNC_QUERIES_JWT_SECRET`: if the `GLOBAL_ASYNC_QUERIES` feature flag is enabled and the secret is still the publicly known default (`test-secret-change-me`), Superset logs a clear error and refuses to start.
|
||||
|
||||
As with the existing `SECRET_KEY` check, this only fails in production. In debug mode, testing mode, or under the test runner, a warning is logged instead of exiting, so local development is unaffected.
|
||||
|
||||
To resolve the error, set a strong random value in `superset_config.py`:
|
||||
|
||||
```python
|
||||
GLOBAL_ASYNC_QUERIES_JWT_SECRET = "<output of: openssl rand -base64 42>"
|
||||
```
|
||||
|
||||
The check is only active when the relevant feature is enabled, so deployments that do not use global async queries (or embedding) are not affected.
|
||||
|
||||
### Guest token revocation (opt-in)
|
||||
|
||||
Embedded guest tokens can be coarsely revoked at runtime via a new opt-in mechanism. A new config flag `GUEST_TOKEN_REVOCATION_ENABLED` (default `False`) gates the feature. When enabled, every minted guest token carries a revocation version, and tokens whose version is below the current expected version (stored in the metadata database) are rejected at validation time.
|
||||
|
||||
Bump the expected version with the new CLI command to invalidate all outstanding guest tokens:
|
||||
|
||||
```bash
|
||||
superset revoke-guest-tokens
|
||||
```
|
||||
|
||||
This change is backward compatible. The feature is off by default, and even when enabled nothing is revoked until an admin explicitly bumps the version: the expected version starts at `0`, and tokens minted before this change (which carry no version claim) are treated as version `0`. No database migration is required.
|
||||
|
||||
### Dataset import validates catalog against the target connection
|
||||
|
||||
Importing a dataset now validates the `catalog` field against the target database connection. When the connection has multi-catalog disabled (`allow_multi_catalog` off) and the dataset's catalog is not the connection's default catalog, the import fails instead of silently persisting the non-default catalog. This matches the validation already enforced on the dataset update path and prevents imported datasets from querying an unintended database.
|
||||
|
||||
@@ -34,6 +34,7 @@ x-superset-volumes: &superset-volumes
|
||||
- superset_home:/app/superset_home
|
||||
- ./tests:/app/tests
|
||||
- superset_data:/app/data
|
||||
- ./local_extensions:/app/local_extensions
|
||||
x-common-build: &common-build
|
||||
context: .
|
||||
target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean`
|
||||
|
||||
@@ -96,7 +96,9 @@ case "${1}" in
|
||||
echo " 🔒 Werkzeug debugger disabled (set SUPERSET_DEBUG_ENABLED=true to enable)"
|
||||
fi
|
||||
|
||||
flask run -p $PORT --reload $DEBUGGER_FLAG --host=0.0.0.0 --exclude-patterns "*/node_modules/*:*/.venv/*:*/build/*:*/__pycache__/*:*/superset-frontend/*"
|
||||
flask run -p $PORT --reload $DEBUGGER_FLAG --host=0.0.0.0 \
|
||||
--extra-files "/app/superset/extensions/.reload_trigger" \
|
||||
--exclude-patterns "*/node_modules/*:*/.venv/*:*/build/*:*/__pycache__/*:*/superset-frontend/*:*/superset/__init__.py"
|
||||
;;
|
||||
app-gunicorn)
|
||||
echo "Starting web app..."
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/react": "^19.1.8",
|
||||
"@typescript-eslint/eslint-plugin": "^8.59.3",
|
||||
"@typescript-eslint/parser": "^8.60.1",
|
||||
"@typescript-eslint/parser": "^8.60.0",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-prettier": "^5.5.6",
|
||||
@@ -109,7 +109,7 @@
|
||||
"globals": "^17.6.0",
|
||||
"prettier": "^3.8.3",
|
||||
"typescript": "~6.0.3",
|
||||
"typescript-eslint": "^8.60.1",
|
||||
"typescript-eslint": "^8.60.0",
|
||||
"webpack": "^5.107.2"
|
||||
},
|
||||
"browserslist": {
|
||||
|
||||
156
docs/yarn.lock
156
docs/yarn.lock
@@ -4812,110 +4812,110 @@
|
||||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@8.60.1", "@typescript-eslint/eslint-plugin@^8.59.3":
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz#c1060bb8fa4be80624d3f3dec8dd9caca373af76"
|
||||
integrity sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==
|
||||
"@typescript-eslint/eslint-plugin@8.60.0", "@typescript-eslint/eslint-plugin@^8.59.3":
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.0.tgz#8fc1e0a950c43270eaf0212dc060f7edaa42f9cf"
|
||||
integrity sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==
|
||||
dependencies:
|
||||
"@eslint-community/regexpp" "^4.12.2"
|
||||
"@typescript-eslint/scope-manager" "8.60.1"
|
||||
"@typescript-eslint/type-utils" "8.60.1"
|
||||
"@typescript-eslint/utils" "8.60.1"
|
||||
"@typescript-eslint/visitor-keys" "8.60.1"
|
||||
"@typescript-eslint/scope-manager" "8.60.0"
|
||||
"@typescript-eslint/type-utils" "8.60.0"
|
||||
"@typescript-eslint/utils" "8.60.0"
|
||||
"@typescript-eslint/visitor-keys" "8.60.0"
|
||||
ignore "^7.0.5"
|
||||
natural-compare "^1.4.0"
|
||||
ts-api-utils "^2.5.0"
|
||||
|
||||
"@typescript-eslint/parser@8.60.1", "@typescript-eslint/parser@^8.60.1":
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.60.1.tgz#a9d7f30850384d34b41f4687dd8944823c09e289"
|
||||
integrity sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==
|
||||
"@typescript-eslint/parser@8.60.0", "@typescript-eslint/parser@^8.60.0":
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.60.0.tgz#38d611b8e658cb10850d4975e8a175a222fbcd6a"
|
||||
integrity sha512-fcqpj/MyK4sxDPcbe7STNPbpQL4RLZOPWuaTmwZYuc+hJKzRf58yRxfhqGpc6PIq9ZyfSBpfHgmUHmHs0KwHwg==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "8.60.1"
|
||||
"@typescript-eslint/types" "8.60.1"
|
||||
"@typescript-eslint/typescript-estree" "8.60.1"
|
||||
"@typescript-eslint/visitor-keys" "8.60.1"
|
||||
"@typescript-eslint/scope-manager" "8.60.0"
|
||||
"@typescript-eslint/types" "8.60.0"
|
||||
"@typescript-eslint/typescript-estree" "8.60.0"
|
||||
"@typescript-eslint/visitor-keys" "8.60.0"
|
||||
debug "^4.4.3"
|
||||
|
||||
"@typescript-eslint/project-service@8.60.1":
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.60.1.tgz#eb29712f58d72c222fc727162e92f2ab4670971b"
|
||||
integrity sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==
|
||||
"@typescript-eslint/project-service@8.60.0":
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.60.0.tgz#b82ab12e64d005d0c7163d1240c432381f1bde0f"
|
||||
integrity sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg==
|
||||
dependencies:
|
||||
"@typescript-eslint/tsconfig-utils" "^8.60.1"
|
||||
"@typescript-eslint/types" "^8.60.1"
|
||||
"@typescript-eslint/tsconfig-utils" "^8.60.0"
|
||||
"@typescript-eslint/types" "^8.60.0"
|
||||
debug "^4.4.3"
|
||||
|
||||
"@typescript-eslint/scope-manager@8.60.1":
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.60.1.tgz#2f875962eaad0a0789cc3c36aea9b4ddeb2dd9c8"
|
||||
integrity sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==
|
||||
"@typescript-eslint/scope-manager@8.60.0":
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.60.0.tgz#7617a4617c043fe235dcf066f9a40f106cfd2fd5"
|
||||
integrity sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.60.1"
|
||||
"@typescript-eslint/visitor-keys" "8.60.1"
|
||||
"@typescript-eslint/types" "8.60.0"
|
||||
"@typescript-eslint/visitor-keys" "8.60.0"
|
||||
|
||||
"@typescript-eslint/tsconfig-utils@8.60.1":
|
||||
"@typescript-eslint/tsconfig-utils@8.60.0":
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.0.tgz#3af78c48956227a407dea9626b8db8ca53f130d2"
|
||||
integrity sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ==
|
||||
|
||||
"@typescript-eslint/tsconfig-utils@^8.60.0":
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.1.tgz#bee8b942a13679a878101c9c74577d732062ed93"
|
||||
integrity sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==
|
||||
|
||||
"@typescript-eslint/tsconfig-utils@^8.60.1":
|
||||
version "8.61.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.0.tgz#05d6e3ff20001674ebcd22d03dac29ee448043ba"
|
||||
integrity sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==
|
||||
|
||||
"@typescript-eslint/type-utils@8.60.1":
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.60.1.tgz#1ae45f0f2a701354beea4a58c2161e40a5e3c379"
|
||||
integrity sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==
|
||||
"@typescript-eslint/type-utils@8.60.0":
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.60.0.tgz#6971a61bc4f3a1b2df45dcc14e26a43a88a4cb6a"
|
||||
integrity sha512-SX46wEUtitCpq7AN38HkUU/+zvUpdKf7ephtWAFgckH8O7PQIyL5gvrhQgBLuEYgLfuKWOVvWVskMbuFHAz5xg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.60.1"
|
||||
"@typescript-eslint/typescript-estree" "8.60.1"
|
||||
"@typescript-eslint/utils" "8.60.1"
|
||||
"@typescript-eslint/types" "8.60.0"
|
||||
"@typescript-eslint/typescript-estree" "8.60.0"
|
||||
"@typescript-eslint/utils" "8.60.0"
|
||||
debug "^4.4.3"
|
||||
ts-api-utils "^2.5.0"
|
||||
|
||||
"@typescript-eslint/types@8.60.1":
|
||||
"@typescript-eslint/types@8.60.0":
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.60.0.tgz#e77ad768e933263b1960b2fe79de75fe1cc6e7db"
|
||||
integrity sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==
|
||||
|
||||
"@typescript-eslint/types@^8.60.0":
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.60.1.tgz#ccdc482ba9e17f9723a10ce240b5e67dad3046c4"
|
||||
integrity sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==
|
||||
|
||||
"@typescript-eslint/types@^8.60.1":
|
||||
version "8.61.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.61.0.tgz#0ddb46e012a4288292950bdd253db42f278ce64d"
|
||||
integrity sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==
|
||||
|
||||
"@typescript-eslint/typescript-estree@8.60.1":
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.1.tgz#016630b119228bf483ddc652703a6a038f3fdd74"
|
||||
integrity sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==
|
||||
"@typescript-eslint/typescript-estree@8.60.0":
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.0.tgz#c102196a44414481190041c99eea1d854e66001b"
|
||||
integrity sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g==
|
||||
dependencies:
|
||||
"@typescript-eslint/project-service" "8.60.1"
|
||||
"@typescript-eslint/tsconfig-utils" "8.60.1"
|
||||
"@typescript-eslint/types" "8.60.1"
|
||||
"@typescript-eslint/visitor-keys" "8.60.1"
|
||||
"@typescript-eslint/project-service" "8.60.0"
|
||||
"@typescript-eslint/tsconfig-utils" "8.60.0"
|
||||
"@typescript-eslint/types" "8.60.0"
|
||||
"@typescript-eslint/visitor-keys" "8.60.0"
|
||||
debug "^4.4.3"
|
||||
minimatch "^10.2.2"
|
||||
semver "^7.7.3"
|
||||
tinyglobby "^0.2.15"
|
||||
ts-api-utils "^2.5.0"
|
||||
|
||||
"@typescript-eslint/utils@8.60.1":
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.60.1.tgz#31cf566095602d9fe8ad91837d2eb520b8de762b"
|
||||
integrity sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==
|
||||
"@typescript-eslint/utils@8.60.0":
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.60.0.tgz#6110cddaef87606ae4ca6f8bf81bb5949fc8e098"
|
||||
integrity sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.9.1"
|
||||
"@typescript-eslint/scope-manager" "8.60.1"
|
||||
"@typescript-eslint/types" "8.60.1"
|
||||
"@typescript-eslint/typescript-estree" "8.60.1"
|
||||
"@typescript-eslint/scope-manager" "8.60.0"
|
||||
"@typescript-eslint/types" "8.60.0"
|
||||
"@typescript-eslint/typescript-estree" "8.60.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@8.60.1":
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.1.tgz#165d1d8901137b944efaf18f00ab5ecb57f06995"
|
||||
integrity sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==
|
||||
"@typescript-eslint/visitor-keys@8.60.0":
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.0.tgz#f2c41eedd3d7b03b808369fb2e3fb40a93783ec2"
|
||||
integrity sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.60.1"
|
||||
"@typescript-eslint/types" "8.60.0"
|
||||
eslint-visitor-keys "^5.0.0"
|
||||
|
||||
"@ungap/structured-clone@^1.0.0":
|
||||
@@ -13490,9 +13490,9 @@ shebang-regex@^3.0.0:
|
||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
shell-quote@^1.8.3:
|
||||
version "1.8.4"
|
||||
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.4.tgz#2edd9a4dcefc96649e2e2cb12f637b1f1d92a190"
|
||||
integrity sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==
|
||||
version "1.8.3"
|
||||
resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz"
|
||||
integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==
|
||||
|
||||
shelljs@0.8.5:
|
||||
version "0.8.5"
|
||||
@@ -14389,15 +14389,15 @@ types-ramda@^0.30.1:
|
||||
dependencies:
|
||||
ts-toolbelt "^9.6.0"
|
||||
|
||||
typescript-eslint@^8.60.1:
|
||||
version "8.60.1"
|
||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.60.1.tgz#13db05c6eabb89669deec44545b788a0e9aee640"
|
||||
integrity sha512-6m5hkkRAp8lKvhVpcprAIn5KkehQEh+47oHH2VGnExEh7dhNxXlg6GPAOIu6TxbVQxhebrJDvjl3020ooiWCMA==
|
||||
typescript-eslint@^8.60.0:
|
||||
version "8.60.0"
|
||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.60.0.tgz#6686fecb1f4f367c0bf0075828e93b7ecacbc62b"
|
||||
integrity sha512-9f65qWLZdAW9m1JaxBDUHcqRUfL8bkxxXL7XxEfI+F09q56PkBvIfCjLF3yInsDM/BBmwkqmCQdCZe/RYlIWEw==
|
||||
dependencies:
|
||||
"@typescript-eslint/eslint-plugin" "8.60.1"
|
||||
"@typescript-eslint/parser" "8.60.1"
|
||||
"@typescript-eslint/typescript-estree" "8.60.1"
|
||||
"@typescript-eslint/utils" "8.60.1"
|
||||
"@typescript-eslint/eslint-plugin" "8.60.0"
|
||||
"@typescript-eslint/parser" "8.60.0"
|
||||
"@typescript-eslint/typescript-estree" "8.60.0"
|
||||
"@typescript-eslint/utils" "8.60.0"
|
||||
|
||||
typescript@~6.0.3:
|
||||
version "6.0.3"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
apiVersion: v2
|
||||
appVersion: "6.1.0"
|
||||
appVersion: "5.0.0"
|
||||
description: Apache Superset is a modern, enterprise-ready business intelligence web application
|
||||
name: superset
|
||||
icon: https://artifacthub.io/image/68c1d717-0e97-491f-b046-754e46f46922@2x
|
||||
@@ -29,7 +29,7 @@ maintainers:
|
||||
- name: craig-rueda
|
||||
email: craig@craigrueda.com
|
||||
url: https://github.com/craig-rueda
|
||||
version: 0.16.0 # See [README](https://github.com/apache/superset/blob/master/helm/superset/README.md#versioning) for version details.
|
||||
version: 0.15.5 # See [README](https://github.com/apache/superset/blob/master/helm/superset/README.md#versioning) for version details.
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
version: 16.7.27
|
||||
|
||||
@@ -23,7 +23,7 @@ NOTE: This file is generated by helm-docs: https://github.com/norwoodj/helm-docs
|
||||
|
||||
# superset
|
||||
|
||||

|
||||

|
||||
|
||||
Apache Superset is a modern, enterprise-ready business intelligence web application
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ dependencies = [
|
||||
"holidays>=0.45, <1",
|
||||
"humanize",
|
||||
"isodate",
|
||||
"jsonpath-ng>=1.8.0, <2",
|
||||
"jsonpath-ng>=1.6.1, <2",
|
||||
"Mako>=1.2.2",
|
||||
"markdown>=3.10.2",
|
||||
# marshmallow>=4 has issues: https://github.com/apache/superset/issues/33162
|
||||
@@ -89,12 +89,12 @@ dependencies = [
|
||||
"python-dateutil",
|
||||
"python-dotenv", # optional dependencies for Flask but required for Superset, see https://flask.palletsprojects.com/en/stable/installation/#optional-dependencies
|
||||
"pygeohash",
|
||||
"pyarrow>=24.0.0, <25", # before upgrading pyarrow, check that all db dependencies support this, see e.g. https://github.com/apache/superset/pull/34693
|
||||
"pyarrow>=16.1.0, <21", # before upgrading pyarrow, check that all db dependencies support this, see e.g. https://github.com/apache/superset/pull/34693
|
||||
"pyyaml>=6.0.0, <7.0.0",
|
||||
"PyJWT>=2.4.0, <3.0",
|
||||
"redis>=5.0.0, <6.0",
|
||||
"rison>=2.0.0, <3.0",
|
||||
"selenium>=4.44.0, <5.0",
|
||||
"selenium>=4.14.0, <5.0",
|
||||
"shillelagh[gsheetsapi]>=1.4.4, <2.0",
|
||||
"sshtunnel>=0.4.0, <0.5",
|
||||
"simplejson>=3.15.0",
|
||||
@@ -107,7 +107,7 @@ dependencies = [
|
||||
"typing-extensions>=4, <5",
|
||||
"waitress; sys_platform == 'win32'",
|
||||
"watchdog>=6.0.0",
|
||||
"wtforms>=3.2.2, <4",
|
||||
"wtforms>=2.3.3, <4",
|
||||
"wtforms-json",
|
||||
"xlsxwriter>=3.2.9, <3.3",
|
||||
]
|
||||
@@ -121,7 +121,7 @@ bigquery = [
|
||||
"sqlalchemy-bigquery>=1.15.0",
|
||||
"google-cloud-bigquery>=3.10.0",
|
||||
]
|
||||
clickhouse = ["clickhouse-connect>=1.1.1, <2.0"]
|
||||
clickhouse = ["clickhouse-connect>=0.13.0, <2.0"]
|
||||
cockroachdb = ["cockroachdb>=0.3.5, <0.4"]
|
||||
crate = ["sqlalchemy-cratedb>=0.41.0, <1"]
|
||||
d1 = [
|
||||
@@ -161,7 +161,7 @@ hive = [
|
||||
"pyhive[hive]>=0.6.5;python_version<'3.11'",
|
||||
"pyhive[hive_pure_sasl]>=0.7.0",
|
||||
"tableschema",
|
||||
"thrift>=0.23.0, <1.0.0",
|
||||
"thrift>=0.14.1, <1.0.0",
|
||||
"thrift_sasl>=0.4.3, < 1.0.0",
|
||||
]
|
||||
impala = ["impyla>0.16.2, <0.23"]
|
||||
@@ -195,7 +195,7 @@ spark = [
|
||||
"pyhive[hive]>=0.6.5;python_version<'3.11'",
|
||||
"pyhive[hive_pure_sasl]>=0.7",
|
||||
"tableschema",
|
||||
"thrift>=0.23.0, <1",
|
||||
"thrift>=0.14.1, <1",
|
||||
]
|
||||
tdengine = [
|
||||
"taospy>=2.7.21",
|
||||
@@ -447,7 +447,6 @@ requirement_txt_file = "requirements/base.txt"
|
||||
authorized_licenses = [
|
||||
"academic free license (afl)",
|
||||
"any-osi",
|
||||
"apache-2.0",
|
||||
"apache license 2.0",
|
||||
"apache software",
|
||||
"apache software, bsd",
|
||||
|
||||
@@ -30,7 +30,7 @@ cryptography>=46.0.7,<47.0.0
|
||||
# Security: Snyk - XSS vulnerability in Mako templates
|
||||
mako>=1.3.11,<2.0.0
|
||||
# Security: CVE-2024-52338 (CRITICAL) - Deserialization of untrusted data in IPC/Parquet readers
|
||||
pyarrow>=24.0.0,<25.0.0
|
||||
pyarrow>=20.0.0,<21.0.0
|
||||
# Security: CVE-2026-27459 - pyopenssl certificate validation
|
||||
pyopenssl>=26.0.0,<27.0.0
|
||||
# Security: CVE-2026-25645 (MEDIUM) - Insecure Temporary File
|
||||
|
||||
@@ -50,7 +50,7 @@ cattrs==25.1.1
|
||||
# via requests-cache
|
||||
celery==5.5.2
|
||||
# via apache-superset (pyproject.toml)
|
||||
certifi==2026.5.20
|
||||
certifi==2025.6.15
|
||||
# via
|
||||
# requests
|
||||
# selenium
|
||||
@@ -194,7 +194,7 @@ jinja2==3.1.6
|
||||
# via
|
||||
# flask
|
||||
# flask-babel
|
||||
jsonpath-ng==1.8.0
|
||||
jsonpath-ng==1.7.0
|
||||
# via apache-superset (pyproject.toml)
|
||||
jsonschema==4.23.0
|
||||
# via
|
||||
@@ -286,13 +286,15 @@ pillow==12.2.0
|
||||
# via apache-superset (pyproject.toml)
|
||||
platformdirs==4.3.8
|
||||
# via requests-cache
|
||||
ply==3.11
|
||||
# via jsonpath-ng
|
||||
polyline==2.0.2
|
||||
# via apache-superset (pyproject.toml)
|
||||
prison==0.2.1
|
||||
# via flask-appbuilder
|
||||
prompt-toolkit==3.0.51
|
||||
# via click-repl
|
||||
pyarrow==24.0.0
|
||||
pyarrow==20.0.0
|
||||
# via
|
||||
# -r requirements/base.in
|
||||
# apache-superset (pyproject.toml)
|
||||
@@ -378,7 +380,7 @@ rpds-py==0.25.0
|
||||
# referencing
|
||||
rsa==4.9.1
|
||||
# via google-auth
|
||||
selenium==4.44.0
|
||||
selenium==4.32.0
|
||||
# via apache-superset (pyproject.toml)
|
||||
setuptools==80.9.0
|
||||
# via -r requirements/base.in
|
||||
@@ -421,7 +423,7 @@ sshtunnel==0.4.0
|
||||
# via apache-superset (pyproject.toml)
|
||||
tabulate==0.10.0
|
||||
# via apache-superset (pyproject.toml)
|
||||
trio==0.33.0
|
||||
trio==0.30.0
|
||||
# via
|
||||
# selenium
|
||||
# trio-websocket
|
||||
@@ -478,7 +480,7 @@ wrapt==1.17.2
|
||||
# via deprecated
|
||||
wsproto==1.2.0
|
||||
# via trio-websocket
|
||||
wtforms==3.2.2
|
||||
wtforms==3.2.1
|
||||
# via
|
||||
# apache-superset (pyproject.toml)
|
||||
# flask-appbuilder
|
||||
|
||||
@@ -112,7 +112,7 @@ celery==5.5.2
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
certifi==2026.5.20
|
||||
certifi==2025.6.15
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# httpcore
|
||||
@@ -471,7 +471,7 @@ jmespath==1.1.0
|
||||
# via
|
||||
# boto3
|
||||
# botocore
|
||||
jsonpath-ng==1.8.0
|
||||
jsonpath-ng==1.7.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
@@ -674,6 +674,10 @@ platformdirs==4.3.8
|
||||
# virtualenv
|
||||
pluggy==1.5.0
|
||||
# via pytest
|
||||
ply==3.11
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# jsonpath-ng
|
||||
polib==1.2.0
|
||||
# via apache-superset
|
||||
polyline==2.0.2
|
||||
@@ -711,7 +715,7 @@ psycopg2-binary==2.9.12
|
||||
# via apache-superset
|
||||
py-key-value-aio==0.4.4
|
||||
# via fastmcp
|
||||
pyarrow==24.0.0
|
||||
pyarrow==20.0.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
@@ -921,7 +925,7 @@ s3transfer==0.16.0
|
||||
# via boto3
|
||||
secretstorage==3.5.0
|
||||
# via keyring
|
||||
selenium==4.44.0
|
||||
selenium==4.32.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
@@ -1019,7 +1023,7 @@ tqdm==4.67.1
|
||||
# prophet
|
||||
trino==0.330.0
|
||||
# via apache-superset
|
||||
trio==0.33.0
|
||||
trio==0.30.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# selenium
|
||||
@@ -1121,7 +1125,7 @@ wsproto==1.2.0
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# trio-websocket
|
||||
wtforms==3.2.2
|
||||
wtforms==3.2.1
|
||||
# via
|
||||
# -c requirements/base-constraint.txt
|
||||
# apache-superset
|
||||
|
||||
@@ -55,21 +55,10 @@ msgcat --sort-by-msgid --no-wrap --no-location superset/translations/messages.po
|
||||
cat $LICENSE_TMP superset/translations/messages.pot > messages.pot.tmp \
|
||||
&& mv messages.pot.tmp superset/translations/messages.pot
|
||||
|
||||
# --no-fuzzy-matching: when a *new* source string is added, Babel's fuzzy
|
||||
# matcher otherwise guesses a "close" existing translation and marks it
|
||||
# `#, fuzzy` in every language catalog. Those guesses are (a) usually wrong
|
||||
# (e.g. a new "valuename" string mapped onto an unrelated "table name"
|
||||
# translation) and (b) counted by check_translation_regression.py as a
|
||||
# regression, so every PR that merely adds a translatable string failed the
|
||||
# babel-extract check. Disabling fuzzy matching means new strings land as
|
||||
# cleanly untranslated (empty msgstr) instead — accurate, and no spurious
|
||||
# regression. Renames likewise drop the stale translation rather than
|
||||
# stranding a wrong guess; the string is re-translated by the community.
|
||||
pybabel update \
|
||||
-i superset/translations/messages.pot \
|
||||
-d superset/translations \
|
||||
--ignore-obsolete \
|
||||
--no-fuzzy-matching
|
||||
--ignore-obsolete
|
||||
|
||||
# Chop off last blankline from po/pot files, see https://github.com/python-babel/babel/issues/799
|
||||
for file in $( find superset/translations/** );
|
||||
|
||||
@@ -20,21 +20,20 @@ Check that source-code changes don't cause translation regressions.
|
||||
|
||||
What counts as a regression
|
||||
---------------------------
|
||||
A regression is an *existing translation that a source change invalidated*.
|
||||
The check keys on the **increase in fuzzy entries** rather than a drop in the
|
||||
translated count, because a count drop happens identically for a benign
|
||||
*deletion* and a real *rename*, so it cannot distinguish the two — whereas a
|
||||
``#, fuzzy`` marker unambiguously flags a stranded translation.
|
||||
A regression is an *existing translation that a source change invalidated* —
|
||||
i.e. a string was renamed/reworded so its committed translation no longer
|
||||
applies. ``babel_update.sh`` (``pybabel update --ignore-obsolete``) surfaces
|
||||
exactly these as **newly fuzzy** entries: the old translation is fuzzy-matched
|
||||
onto the new ``msgid`` and flagged ``#, fuzzy``.
|
||||
|
||||
Note ``babel_update.sh`` runs ``pybabel update`` with ``--no-fuzzy-matching``,
|
||||
so *adding* (or renaming) a source string does **not** auto-generate a fuzzy
|
||||
guess against an unrelated existing translation — new strings land as cleanly
|
||||
untranslated (empty ``msgstr``). This deliberately avoids the prior behaviour
|
||||
where *every* PR that merely added a translatable string tripped this check on
|
||||
spurious fuzzies. As a result the check now guards against ``#, fuzzy`` entries
|
||||
that arrive another way — e.g. a committed ``.po`` edit — rather than ones the
|
||||
update step synthesises. *Deleting* a string is still not a regression: with
|
||||
``--ignore-obsolete`` it is simply dropped and no fuzzy is created.
|
||||
Crucially, *deleting* a translatable string is **not** a regression. With
|
||||
``--ignore-obsolete`` a removed string is dropped from the catalogs entirely;
|
||||
no fuzzy entry is created. So a PR that intentionally removes a string (e.g. a
|
||||
security fix that stops rendering a value) legitimately lowers the translated
|
||||
count without introducing any fuzzies, and must not be flagged. We therefore
|
||||
key the check on the **increase in fuzzy entries**, not on a drop in the
|
||||
translated count (a drop happens identically for a benign deletion and a real
|
||||
rename, so it cannot distinguish the two).
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
getGuestTokenRefreshTiming,
|
||||
MIN_REFRESH_WAIT_MS,
|
||||
DEFAULT_TOKEN_EXP_MS,
|
||||
DEFAULT_TOKEN_REFRESH_RETRY_MS,
|
||||
} from "./guestTokenRefresh";
|
||||
|
||||
describe("guest token refresh", () => {
|
||||
@@ -94,11 +93,4 @@ describe("guest token refresh", () => {
|
||||
expect(timing).toBeGreaterThan(MIN_REFRESH_WAIT_MS);
|
||||
expect(timing).toBe(DEFAULT_TOKEN_EXP_MS - REFRESH_TIMING_BUFFER_MS);
|
||||
});
|
||||
|
||||
it("exposes a positive retry delay for failed token refreshes", () => {
|
||||
// The refresh loop reschedules itself after this delay when a fetch
|
||||
// fails or times out, so it must be a sane positive value.
|
||||
expect(DEFAULT_TOKEN_REFRESH_RETRY_MS).toBe(10000);
|
||||
expect(DEFAULT_TOKEN_REFRESH_RETRY_MS).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,7 +21,6 @@ import { jwtDecode } from "jwt-decode";
|
||||
export const REFRESH_TIMING_BUFFER_MS = 5000 // refresh guest token early to avoid failed superset requests
|
||||
export const MIN_REFRESH_WAIT_MS = 10000 // avoid blasting requests as fast as the cpu can handle
|
||||
export const DEFAULT_TOKEN_EXP_MS = 300000 // (5 min) used only when parsing guest token exp fails
|
||||
export const DEFAULT_TOKEN_REFRESH_RETRY_MS = 10000 // wait before retrying a failed/timed-out token refresh
|
||||
|
||||
// when do we refresh the guest token?
|
||||
export function getGuestTokenRefreshTiming(currentGuestToken: string) {
|
||||
|
||||
@@ -24,11 +24,7 @@ import {
|
||||
|
||||
// We can swap this out for the actual switchboard package once it gets published
|
||||
import { Switchboard } from '@superset-ui/switchboard';
|
||||
import {
|
||||
getGuestTokenRefreshTiming,
|
||||
DEFAULT_TOKEN_REFRESH_RETRY_MS,
|
||||
} from './guestTokenRefresh';
|
||||
import { withTimeout } from './withTimeout';
|
||||
import { getGuestTokenRefreshTiming } from './guestTokenRefresh';
|
||||
|
||||
/**
|
||||
* The function to fetch a guest token from your Host App's backend server.
|
||||
@@ -53,9 +49,6 @@ export type UiConfigType = {
|
||||
showRowLimitWarning?: boolean;
|
||||
};
|
||||
|
||||
/** Default per-call timeout (ms) applied to the host `fetchGuestToken` callback. */
|
||||
const DEFAULT_GUEST_TOKEN_FETCH_TIMEOUT_MS = 30_000;
|
||||
|
||||
export type EmbedDashboardParams = {
|
||||
/** The id provided by the embed configuration UI in Superset */
|
||||
id: string;
|
||||
@@ -80,10 +73,6 @@ export type EmbedDashboardParams = {
|
||||
/** Callback to resolve permalink URLs. If provided, this will be called when generating permalinks
|
||||
* to allow the host app to customize the URL. If not provided, Superset's default URL is used. */
|
||||
resolvePermalinkUrl?: ResolvePermalinkUrlFn;
|
||||
/** Timeout, in milliseconds, applied to each `fetchGuestToken` call so a host
|
||||
* callback that never resolves cannot hang the embed/refresh cycle. Defaults
|
||||
* to 30000ms. Set to 0 to disable the timeout. */
|
||||
guestTokenFetchTimeoutMs?: number;
|
||||
};
|
||||
|
||||
export type Size = {
|
||||
@@ -138,7 +127,6 @@ export async function embedDashboard({
|
||||
iframeAllowExtras = [],
|
||||
referrerPolicy,
|
||||
resolvePermalinkUrl,
|
||||
guestTokenFetchTimeoutMs = DEFAULT_GUEST_TOKEN_FETCH_TIMEOUT_MS,
|
||||
}: EmbedDashboardParams): Promise<EmbeddedDashboard> {
|
||||
function log(...info: unknown[]) {
|
||||
if (debug) {
|
||||
@@ -146,16 +134,6 @@ export async function embedDashboard({
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap the host-provided fetchGuestToken so a callback that never settles
|
||||
// cannot hang the initial embed or a later refresh cycle.
|
||||
function fetchGuestTokenWithTimeout(): Promise<string> {
|
||||
return withTimeout(
|
||||
fetchGuestToken(),
|
||||
guestTokenFetchTimeoutMs,
|
||||
'fetchGuestToken',
|
||||
);
|
||||
}
|
||||
|
||||
log('embedding');
|
||||
|
||||
if (supersetDomain.endsWith('/')) {
|
||||
@@ -269,57 +247,21 @@ export async function embedDashboard({
|
||||
});
|
||||
}
|
||||
|
||||
let guestToken: string;
|
||||
let ourPort: Switchboard;
|
||||
try {
|
||||
[guestToken, ourPort] = await Promise.all([
|
||||
fetchGuestTokenWithTimeout(),
|
||||
mountIframe(),
|
||||
]);
|
||||
} catch (err) {
|
||||
// If the initial token fetch (or timeout) rejects after the iframe has
|
||||
// already been mounted, tear down the partially initialized iframe so the
|
||||
// host isn't left with an orphaned embedded dashboard before rethrowing.
|
||||
//@ts-ignore
|
||||
mountPoint.replaceChildren();
|
||||
throw err;
|
||||
}
|
||||
const [guestToken, ourPort]: [string, Switchboard] = await Promise.all([
|
||||
fetchGuestToken(),
|
||||
mountIframe(),
|
||||
]);
|
||||
|
||||
ourPort.emit('guestToken', { guestToken });
|
||||
log('sent guest token');
|
||||
|
||||
// Track the pending refresh timer so it can be cancelled on unmount, and
|
||||
// stop the cycle once unmounted so it cannot leak across mount/unmount cycles.
|
||||
let refreshTimer: ReturnType<typeof setTimeout> | undefined;
|
||||
let unmounted = false;
|
||||
|
||||
async function refreshGuestToken() {
|
||||
if (unmounted) return;
|
||||
try {
|
||||
const newGuestToken = await fetchGuestTokenWithTimeout();
|
||||
if (unmounted) return;
|
||||
ourPort.emit('guestToken', { guestToken: newGuestToken });
|
||||
refreshTimer = setTimeout(
|
||||
refreshGuestToken,
|
||||
getGuestTokenRefreshTiming(newGuestToken),
|
||||
);
|
||||
} catch (err) {
|
||||
// A transient fetch failure or timeout must not permanently stop the
|
||||
// refresh cycle. Log it and retry so the session can recover once the
|
||||
// host callback succeeds again.
|
||||
log('failed to refresh guest token, will retry:', err);
|
||||
if (unmounted) return;
|
||||
refreshTimer = setTimeout(
|
||||
refreshGuestToken,
|
||||
DEFAULT_TOKEN_REFRESH_RETRY_MS,
|
||||
);
|
||||
}
|
||||
const newGuestToken = await fetchGuestToken();
|
||||
ourPort.emit('guestToken', { guestToken: newGuestToken });
|
||||
setTimeout(refreshGuestToken, getGuestTokenRefreshTiming(newGuestToken));
|
||||
}
|
||||
|
||||
refreshTimer = setTimeout(
|
||||
refreshGuestToken,
|
||||
getGuestTokenRefreshTiming(guestToken),
|
||||
);
|
||||
setTimeout(refreshGuestToken, getGuestTokenRefreshTiming(guestToken));
|
||||
|
||||
// Register the resolvePermalinkUrl method for the iframe to call
|
||||
// Returns null if no callback provided or on error, allowing iframe to use default URL
|
||||
@@ -341,11 +283,6 @@ export async function embedDashboard({
|
||||
|
||||
function unmount() {
|
||||
log('unmounting');
|
||||
unmounted = true;
|
||||
if (refreshTimer !== undefined) {
|
||||
clearTimeout(refreshTimer);
|
||||
refreshTimer = undefined;
|
||||
}
|
||||
//@ts-ignore
|
||||
mountPoint.replaceChildren();
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* 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 { withTimeout } from "./withTimeout";
|
||||
|
||||
test("resolves with the value when the promise settles in time", async () => {
|
||||
await expect(withTimeout(Promise.resolve("ok"), 1000, "fetch")).resolves.toBe(
|
||||
"ok"
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects when the promise does not settle within the timeout", async () => {
|
||||
const never = new Promise<string>(() => {});
|
||||
await expect(withTimeout(never, 10, "fetch")).rejects.toThrow(
|
||||
/fetch did not resolve within 10ms/
|
||||
);
|
||||
});
|
||||
|
||||
test("passes the promise through unchanged when the timeout is disabled", async () => {
|
||||
await expect(withTimeout(Promise.resolve("ok"), 0, "fetch")).resolves.toBe(
|
||||
"ok"
|
||||
);
|
||||
});
|
||||
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Rejects if `promise` does not settle within `ms` milliseconds. A non-positive
|
||||
* `ms` disables the timeout and returns the promise unchanged. The timer is
|
||||
* always cleared so it cannot keep the event loop alive.
|
||||
*/
|
||||
export function withTimeout<T>(
|
||||
promise: Promise<T>,
|
||||
ms: number,
|
||||
label: string,
|
||||
): Promise<T> {
|
||||
if (!ms || ms <= 0) {
|
||||
return promise;
|
||||
}
|
||||
let timer: ReturnType<typeof setTimeout>;
|
||||
const timeout = new Promise<never>((_resolve, reject) => {
|
||||
timer = setTimeout(
|
||||
() => reject(new Error(`${label} did not resolve within ${ms}ms`)),
|
||||
ms,
|
||||
);
|
||||
});
|
||||
return Promise.race([promise, timeout]).finally(() =>
|
||||
clearTimeout(timer),
|
||||
) as Promise<T>;
|
||||
}
|
||||
@@ -226,7 +226,7 @@ def copy_frontend_dist(cwd: Path) -> str:
|
||||
def copy_backend_files(cwd: Path) -> None:
|
||||
"""Copy backend files based on pyproject.toml build configuration (validation already passed)."""
|
||||
dist_dir = cwd / "dist"
|
||||
backend_dir = (cwd / "backend").resolve()
|
||||
backend_dir = cwd / "backend"
|
||||
|
||||
# Read build config from pyproject.toml
|
||||
pyproject = read_toml(backend_dir / "pyproject.toml")
|
||||
@@ -239,31 +239,11 @@ def copy_backend_files(cwd: Path) -> None:
|
||||
|
||||
# Process include patterns
|
||||
for pattern in include_patterns:
|
||||
# Include patterns are only meant to select files within the backend
|
||||
# directory. Reject absolute patterns or ones that walk outside it via
|
||||
# parent ("..") components before handing them to glob().
|
||||
pattern_parts = Path(pattern).parts
|
||||
if Path(pattern).is_absolute() or ".." in pattern_parts:
|
||||
raise click.ClickException(
|
||||
f"Invalid include pattern {pattern!r}: patterns must be "
|
||||
"relative to the backend directory and may not contain '..'."
|
||||
)
|
||||
for f in backend_dir.glob(pattern):
|
||||
if not f.is_file():
|
||||
continue
|
||||
|
||||
# Defense in depth: confirm the matched file resolves to a location
|
||||
# inside the backend directory before copying it into the bundle.
|
||||
resolved = f.resolve()
|
||||
if not resolved.is_relative_to(backend_dir):
|
||||
raise click.ClickException(
|
||||
f"Refusing to copy {f}: resolved path is outside the "
|
||||
f"backend directory {backend_dir}."
|
||||
)
|
||||
|
||||
# Use the matched path (not the resolved target) for the bundle
|
||||
# layout and exclude evaluation so symlinked files are staged at
|
||||
# their configured path rather than their symlink target.
|
||||
# Check exclude patterns
|
||||
relative_path = f.relative_to(backend_dir)
|
||||
should_exclude = any(
|
||||
relative_path.match(excl_pattern) for excl_pattern in exclude_patterns
|
||||
|
||||
@@ -20,7 +20,6 @@ from __future__ import annotations
|
||||
import json
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import click
|
||||
import pytest
|
||||
from superset_extensions_cli.cli import (
|
||||
app,
|
||||
@@ -626,155 +625,6 @@ exclude = []
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_copy_backend_files_supports_legitimate_nested_patterns(isolated_filesystem):
|
||||
"""Test copy_backend_files copies deeply nested files via recursive globs."""
|
||||
backend_dir = isolated_filesystem / "backend"
|
||||
nested = backend_dir / "src" / "test_org" / "test_ext" / "deep" / "deeper"
|
||||
nested.mkdir(parents=True)
|
||||
(nested / "module.py").write_text("# nested module")
|
||||
|
||||
pyproject_content = """[project]
|
||||
name = "test_org-test_ext"
|
||||
version = "1.0.0"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[tool.apache_superset_extensions.build]
|
||||
include = [
|
||||
"src/test_org/test_ext/**/*.py",
|
||||
]
|
||||
exclude = []
|
||||
"""
|
||||
(backend_dir / "pyproject.toml").write_text(pyproject_content)
|
||||
|
||||
extension_data = {
|
||||
"publisher": "test-org",
|
||||
"name": "test-ext",
|
||||
"displayName": "Test Extension",
|
||||
"version": "1.0.0",
|
||||
"permissions": [],
|
||||
}
|
||||
(isolated_filesystem / "extension.json").write_text(json.dumps(extension_data))
|
||||
|
||||
clean_dist(isolated_filesystem)
|
||||
copy_backend_files(isolated_filesystem)
|
||||
|
||||
dist_dir = isolated_filesystem / "dist"
|
||||
assert_file_exists(
|
||||
dist_dir
|
||||
/ "backend"
|
||||
/ "src"
|
||||
/ "test_org"
|
||||
/ "test_ext"
|
||||
/ "deep"
|
||||
/ "deeper"
|
||||
/ "module.py"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.parametrize(
|
||||
"bad_pattern",
|
||||
[
|
||||
"../../.ssh/*",
|
||||
"../config",
|
||||
"src/../../secret.txt",
|
||||
"/etc/passwd",
|
||||
],
|
||||
)
|
||||
def test_copy_backend_files_rejects_patterns_escaping_backend_dir(
|
||||
isolated_filesystem, bad_pattern
|
||||
):
|
||||
"""Test copy_backend_files refuses include patterns that escape backend_dir."""
|
||||
# Create a sensitive file outside the backend directory.
|
||||
(isolated_filesystem / "secret.txt").write_text("SECRET")
|
||||
(isolated_filesystem / "config").write_text("SECRET")
|
||||
|
||||
backend_dir = isolated_filesystem / "backend"
|
||||
backend_src = backend_dir / "src" / "test_org" / "test_ext"
|
||||
backend_src.mkdir(parents=True)
|
||||
(backend_src / "__init__.py").write_text("# init")
|
||||
|
||||
pyproject_content = f"""[project]
|
||||
name = "test_org-test_ext"
|
||||
version = "1.0.0"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[tool.apache_superset_extensions.build]
|
||||
include = [
|
||||
"{bad_pattern}",
|
||||
]
|
||||
exclude = []
|
||||
"""
|
||||
(backend_dir / "pyproject.toml").write_text(pyproject_content)
|
||||
|
||||
extension_data = {
|
||||
"publisher": "test-org",
|
||||
"name": "test-ext",
|
||||
"displayName": "Test Extension",
|
||||
"version": "1.0.0",
|
||||
"permissions": [],
|
||||
}
|
||||
(isolated_filesystem / "extension.json").write_text(json.dumps(extension_data))
|
||||
|
||||
clean_dist(isolated_filesystem)
|
||||
|
||||
with pytest.raises(click.ClickException):
|
||||
copy_backend_files(isolated_filesystem)
|
||||
|
||||
# Nothing outside the backend directory should have been staged into dist,
|
||||
# including paths reachable via ".." from inside dist/backend.
|
||||
dist_dir = isolated_filesystem / "dist"
|
||||
assert not (dist_dir / "secret.txt").exists()
|
||||
assert not (dist_dir / "config").exists()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_copy_backend_files_stages_symlink_at_matched_path(isolated_filesystem):
|
||||
"""Symlinked files inside backend are staged at the matched path, not the target."""
|
||||
backend_dir = isolated_filesystem / "backend"
|
||||
target_dir = backend_dir / "src" / "common"
|
||||
target_dir.mkdir(parents=True)
|
||||
(target_dir / "module.py").write_text("# shared module")
|
||||
|
||||
link_dir = backend_dir / "src" / "test_org" / "test_ext" / "common"
|
||||
link_dir.mkdir(parents=True)
|
||||
link = link_dir / "module.py"
|
||||
link.symlink_to(target_dir / "module.py")
|
||||
|
||||
pyproject_content = """[project]
|
||||
name = "test_org-test_ext"
|
||||
version = "1.0.0"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[tool.apache_superset_extensions.build]
|
||||
include = [
|
||||
"src/test_org/test_ext/**/*.py",
|
||||
]
|
||||
exclude = []
|
||||
"""
|
||||
(backend_dir / "pyproject.toml").write_text(pyproject_content)
|
||||
|
||||
extension_data = {
|
||||
"publisher": "test-org",
|
||||
"name": "test-ext",
|
||||
"displayName": "Test Extension",
|
||||
"version": "1.0.0",
|
||||
"permissions": [],
|
||||
}
|
||||
(isolated_filesystem / "extension.json").write_text(json.dumps(extension_data))
|
||||
|
||||
clean_dist(isolated_filesystem)
|
||||
copy_backend_files(isolated_filesystem)
|
||||
|
||||
dist_dir = isolated_filesystem / "dist"
|
||||
# Staged at the configured (symlink) path, not the resolved target path.
|
||||
assert_file_exists(
|
||||
dist_dir / "backend" / "src" / "test_org" / "test_ext" / "common" / "module.py"
|
||||
)
|
||||
assert not (dist_dir / "backend" / "src" / "common" / "module.py").exists()
|
||||
|
||||
|
||||
# Removed obsolete tests:
|
||||
# - test_copy_backend_files_handles_no_backend_config: This scenario can't happen since copy_backend_files is only called when backend exists
|
||||
# - test_copy_backend_files_exits_when_extension_json_missing: Validation catches this before copy_backend_files is called
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { dirname, join } from 'path';
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
@@ -16,16 +17,8 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
// This file has been automatically migrated to valid ESM format by Storybook.
|
||||
import path from 'node:path';
|
||||
import { createRequire } from 'node:module';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
// Superset's webpack.config.js
|
||||
import customConfig from '../webpack.config.js';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const customConfig = require('../webpack.config.js');
|
||||
|
||||
// Filter out plugins that shouldn't be included in Storybook's static build
|
||||
// ReactRefreshWebpackPlugin adds Fast Refresh code that requires a dev server runtime,
|
||||
@@ -83,7 +76,7 @@ const disableDevModeInRules = rules =>
|
||||
};
|
||||
});
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
stories: [
|
||||
'../src/**/*.stories.tsx',
|
||||
'../packages/superset-ui-core/src/**/*.stories.tsx',
|
||||
@@ -91,8 +84,11 @@ export default {
|
||||
],
|
||||
|
||||
addons: [
|
||||
"@storybook/addon-links",
|
||||
"@storybook/addon-docs"
|
||||
getAbsolutePath('@storybook/addon-essentials'),
|
||||
getAbsolutePath('@storybook/addon-links'),
|
||||
'@mihkeleidast/storybook-addon-source',
|
||||
getAbsolutePath('@storybook/addon-controls'),
|
||||
getAbsolutePath('@storybook/addon-mdx-gfm'),
|
||||
],
|
||||
|
||||
staticDirs: ['../src/assets/images'],
|
||||
@@ -109,13 +105,11 @@ export default {
|
||||
alias: {
|
||||
...config.resolve?.alias,
|
||||
...customConfig.resolve?.alias,
|
||||
// Fix for Storybook 8.6.x with React 17 - resolve ESM module paths
|
||||
'react-dom/test-utils': require.resolve('react-dom/test-utils'),
|
||||
// Shared storybook utilities
|
||||
'@storybook-shared': path.join(__dirname, 'shared'),
|
||||
'@storybook-shared': join(__dirname, 'shared'),
|
||||
},
|
||||
fallback: {
|
||||
tty: false,
|
||||
vm: require.resolve('vm-browserify')
|
||||
}
|
||||
},
|
||||
plugins: [...config.plugins, ...filteredPlugins],
|
||||
}),
|
||||
@@ -125,11 +119,15 @@ export default {
|
||||
},
|
||||
|
||||
framework: {
|
||||
name: getAbsolutePath("@storybook/react-webpack5"),
|
||||
name: getAbsolutePath('@storybook/react-webpack5'),
|
||||
options: {},
|
||||
}
|
||||
},
|
||||
|
||||
docs: {
|
||||
autodocs: false,
|
||||
},
|
||||
};
|
||||
|
||||
function getAbsolutePath(value) {
|
||||
return path.dirname(require.resolve(path.join(value, 'package.json')));
|
||||
return dirname(require.resolve(join(value, 'package.json')));
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { withJsx } from '@mihkeleidast/storybook-addon-source';
|
||||
import { themeObject, css, exampleThemes } from '@apache-superset/core/theme';
|
||||
import { combineReducers, createStore, applyMiddleware, compose } from 'redux';
|
||||
import thunk from 'redux-thunk';
|
||||
@@ -113,12 +114,9 @@ const providerDecorator = Story => (
|
||||
</Provider>
|
||||
);
|
||||
|
||||
export const decorators = [themeDecorator, providerDecorator];
|
||||
export const decorators = [withJsx, themeDecorator, providerDecorator];
|
||||
|
||||
export const parameters = {
|
||||
docs: {
|
||||
codePanel: true,
|
||||
},
|
||||
paddings: {
|
||||
values: [
|
||||
{ name: 'None', value: '0px' },
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
import { useState, ReactNode, SyntheticEvent } from 'react';
|
||||
import { styled } from '@apache-superset/core/theme';
|
||||
import type { Decorator } from '@storybook/react-webpack5';
|
||||
import type { Decorator } from '@storybook/react';
|
||||
import { ResizeCallbackData } from 'react-resizable';
|
||||
import ResizablePanel, { Size } from './ResizablePanel';
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ module.exports = {
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
'@babel/plugin-transform-export-namespace-from',
|
||||
['@babel/plugin-transform-class-properties', { loose: true }],
|
||||
'@babel/plugin-transform-class-static-block',
|
||||
['@babel/plugin-transform-optional-chaining', { loose: true }],
|
||||
['@babel/plugin-transform-private-methods', { loose: true }],
|
||||
['@babel/plugin-transform-nullish-coalescing-operator', { loose: true }],
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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 { SAMPLE_DASHBOARD_1 } from 'cypress/utils/urls';
|
||||
import { interceptFav, interceptUnfav } from './utils';
|
||||
|
||||
describe('Dashboard actions', () => {
|
||||
beforeEach(() => {
|
||||
cy.createSampleDashboards([0]);
|
||||
cy.visit(SAMPLE_DASHBOARD_1);
|
||||
});
|
||||
it('should allow to favorite/unfavorite dashboard', () => {
|
||||
interceptFav();
|
||||
interceptUnfav();
|
||||
|
||||
// Find and click StarOutlined (adds to favorites)
|
||||
cy.getBySel('dashboard-header-container')
|
||||
.find("[aria-label='unstarred']")
|
||||
.as('starIconOutlined')
|
||||
.should('exist')
|
||||
.click();
|
||||
|
||||
cy.wait('@select');
|
||||
|
||||
// After clicking, StarFilled should appear
|
||||
cy.getBySel('dashboard-header-container')
|
||||
.find("[aria-label='starred']")
|
||||
.as('starIconFilled')
|
||||
.should('exist');
|
||||
|
||||
// Verify the color of the filled star (gold)
|
||||
cy.get('@starIconFilled')
|
||||
.should('have.css', 'color')
|
||||
.and('eq', 'rgb(252, 199, 0)');
|
||||
|
||||
// Click on StarFilled (removes from favorites)
|
||||
cy.get('@starIconFilled').click();
|
||||
|
||||
cy.wait('@unselect');
|
||||
|
||||
// After clicking, StarOutlined should reappear
|
||||
cy.getBySel('dashboard-header-container')
|
||||
.find("[aria-label='unstarred']")
|
||||
.as('starIconOutlinedAfter')
|
||||
.should('exist');
|
||||
|
||||
// Verify the color of the outlined star (gray)
|
||||
cy.get('@starIconOutlinedAfter')
|
||||
.should('have.css', 'color')
|
||||
.and('eq', 'rgba(0, 0, 0, 0.45)');
|
||||
});
|
||||
});
|
||||
@@ -160,6 +160,18 @@ export function interceptLog() {
|
||||
cy.intercept('**/superset/log/?explode=events&dashboard_id=*').as('logs');
|
||||
}
|
||||
|
||||
export function interceptFav() {
|
||||
cy.intercept({ url: `**/api/v1/dashboard/*/favorites/`, method: 'POST' }).as(
|
||||
'select',
|
||||
);
|
||||
}
|
||||
|
||||
export function interceptUnfav() {
|
||||
cy.intercept({ url: `**/api/v1/dashboard/*/favorites/`, method: 'POST' }).as(
|
||||
'unselect',
|
||||
);
|
||||
}
|
||||
|
||||
export function interceptDataset() {
|
||||
cy.intercept('GET', `**/api/v1/dataset/*`).as('getDataset');
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ module.exports = {
|
||||
],
|
||||
coverageReporters: ['lcov', 'json-summary', 'html', 'text'],
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!@formatjs/.*|d3-(array|interpolate|color|time|scale|time-format|format)|internmap|@mapbox/tiny-sdf|remark-gfm|(?!@ngrx|(?!deck.gl)|d3-scale)|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|uuid|@rjsf/*.|echarts|zrender|fetch-mock|pretty-ms|parse-ms|ol|@babel/runtime|@emotion|cheerio|cheerio/lib|parse5|dom-serializer|entities|htmlparser2|rehype-sanitize|hast-util-sanitize|unified|unist-.*|hast-.*|rehype-.*|remark-.*|mdast-.*|micromark-.*|parse-entities|property-information|space-separated-tokens|comma-separated-tokens|bail|devlop|zwitch|longest-streak|geostyler|geostyler-.*|(?!geostyler)lodash|react-error-boundary|react-json-tree|react-base16-styling|lodash-es|rbush|quickselect|react-diff-viewer-continued|storybook/*.)',
|
||||
'node_modules/(?!@formatjs/.*|d3-(array|interpolate|color|time|scale|time-format|format)|internmap|@mapbox/tiny-sdf|remark-gfm|(?!@ngrx|(?!deck.gl)|d3-scale)|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|uuid|@rjsf/*.|echarts|zrender|fetch-mock|pretty-ms|parse-ms|ol|@babel/runtime|@emotion|cheerio|cheerio/lib|parse5|dom-serializer|entities|htmlparser2|rehype-sanitize|hast-util-sanitize|unified|unist-.*|hast-.*|rehype-.*|remark-.*|mdast-.*|micromark-.*|parse-entities|property-information|space-separated-tokens|comma-separated-tokens|bail|devlop|zwitch|longest-streak|geostyler|geostyler-.*|(?!geostyler)lodash|react-error-boundary|react-json-tree|react-base16-styling|lodash-es|rbush|quickselect|react-diff-viewer-continued)',
|
||||
],
|
||||
preset: 'ts-jest',
|
||||
transform: {
|
||||
|
||||
9151
superset-frontend/package-lock.json
generated
9151
superset-frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -164,8 +164,8 @@
|
||||
"@visx/scale": "^3.5.0",
|
||||
"@visx/tooltip": "^3.0.0",
|
||||
"@visx/xychart": "^3.5.1",
|
||||
"ag-grid-community": "35.3.1",
|
||||
"ag-grid-react": "35.3.1",
|
||||
"ag-grid-community": "35.3.0",
|
||||
"ag-grid-react": "35.3.0",
|
||||
"antd": "^5.26.0",
|
||||
"chrono-node": "^2.9.1",
|
||||
"classnames": "^2.2.5",
|
||||
@@ -178,7 +178,7 @@
|
||||
"echarts": "^5.6.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"fs-extra": "^11.3.5",
|
||||
"fuse.js": "^7.4.1",
|
||||
"fuse.js": "^7.3.0",
|
||||
"geolib": "^3.3.14",
|
||||
"geostyler": "^18.6.0",
|
||||
"geostyler-data": "^1.1.0",
|
||||
@@ -261,14 +261,22 @@
|
||||
"@babel/types": "^7.29.7",
|
||||
"@emotion/babel-plugin": "^11.13.5",
|
||||
"@emotion/jest": "^11.14.2",
|
||||
"@formatjs/intl-durationformat": "^0.10.13",
|
||||
"@formatjs/intl-durationformat": "^0.10.3",
|
||||
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
||||
"@mihkeleidast/storybook-addon-source": "^1.0.1",
|
||||
"@playwright/test": "^1.60.0",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.2",
|
||||
"@storybook/addon-docs": "10.4.2",
|
||||
"@storybook/addon-links": "10.4.2",
|
||||
"@storybook/react-webpack5": "10.4.2",
|
||||
"@storybook/test-runner": "0.24.4",
|
||||
"@storybook/addon-actions": "^8.6.18",
|
||||
"@storybook/addon-controls": "^8.6.18",
|
||||
"@storybook/addon-essentials": "^8.6.18",
|
||||
"@storybook/addon-links": "^8.6.18",
|
||||
"@storybook/addon-mdx-gfm": "^8.6.18",
|
||||
"@storybook/components": "^8.6.18",
|
||||
"@storybook/preview-api": "^8.6.18",
|
||||
"@storybook/react": "^8.6.18",
|
||||
"@storybook/react-webpack5": "^8.6.18",
|
||||
"@storybook/test": "^8.6.18",
|
||||
"@storybook/test-runner": "^0.17.0",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@swc/core": "^1.15.40",
|
||||
"@swc/plugin-emotion": "^14.12.0",
|
||||
@@ -289,6 +297,7 @@
|
||||
"@types/react-dom": "^18.2.0",
|
||||
"@types/react-loadable": "^5.5.11",
|
||||
"@types/react-redux": "^7.1.10",
|
||||
"@types/react-resizable": "^4.0.0",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/react-transition-group": "^4.4.12",
|
||||
"@types/react-window": "^1.8.8",
|
||||
@@ -297,7 +306,7 @@
|
||||
"@types/rison": "0.1.0",
|
||||
"@types/tinycolor2": "^1.4.3",
|
||||
"@types/unzipper": "^0.10.11",
|
||||
"@typescript-eslint/eslint-plugin": "^8.60.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.60.0",
|
||||
"@typescript-eslint/parser": "^8.59.4",
|
||||
"babel-jest": "^30.4.1",
|
||||
"babel-loader": "^10.1.1",
|
||||
@@ -306,7 +315,7 @@
|
||||
"babel-plugin-lodash": "^3.3.4",
|
||||
"baseline-browser-mapping": "^2.10.33",
|
||||
"cheerio": "1.2.0",
|
||||
"concurrently": "^10.0.3",
|
||||
"concurrently": "^10.0.0",
|
||||
"copy-webpack-plugin": "^14.0.0",
|
||||
"cross-env": "^10.1.0",
|
||||
"css-loader": "^7.1.4",
|
||||
@@ -314,7 +323,7 @@
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^7.2.0",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-import-resolver-typescript": "^4.4.5",
|
||||
"eslint-import-resolver-typescript": "^4.4.4",
|
||||
"eslint-plugin-cypress": "^3.6.0",
|
||||
"eslint-plugin-i18n-strings": "file:eslint-rules/eslint-plugin-i18n-strings",
|
||||
"eslint-plugin-icons": "file:eslint-rules/eslint-plugin-icons",
|
||||
@@ -325,7 +334,7 @@
|
||||
"eslint-plugin-prettier": "^5.5.6",
|
||||
"eslint-plugin-react-prefer-function-component": "^5.0.0",
|
||||
"eslint-plugin-react-you-might-not-need-an-effect": "^0.10.4",
|
||||
"eslint-plugin-storybook": "10.4.2",
|
||||
"eslint-plugin-storybook": "^0.8.0",
|
||||
"eslint-plugin-testing-library": "^7.16.2",
|
||||
"eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors",
|
||||
"fetch-mock": "^12.6.0",
|
||||
@@ -344,7 +353,7 @@
|
||||
"lightningcss": "^1.32.0",
|
||||
"mini-css-extract-plugin": "^2.10.2",
|
||||
"open-cli": "^9.0.0",
|
||||
"oxlint": "^1.68.0",
|
||||
"oxlint": "^1.67.0",
|
||||
"po2json": "^0.4.5",
|
||||
"prettier": "3.8.3",
|
||||
"prettier-plugin-packagejson": "^3.0.2",
|
||||
@@ -355,7 +364,7 @@
|
||||
"source-map": "^0.7.6",
|
||||
"source-map-support": "^0.5.21",
|
||||
"speed-measure-webpack-plugin": "^1.6.0",
|
||||
"storybook": "10.4.2",
|
||||
"storybook": "8.6.18",
|
||||
"style-loader": "^4.0.0",
|
||||
"swc-loader": "^0.2.7",
|
||||
"terser-webpack-plugin": "^5.6.1",
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
* ```
|
||||
*/
|
||||
|
||||
import { Disposable, Event } from '../common';
|
||||
import { Disposable } from '../common';
|
||||
|
||||
/**
|
||||
* Represents a menu item that links a view to a command.
|
||||
@@ -102,37 +102,3 @@ export declare function registerMenuItem(
|
||||
* ```
|
||||
*/
|
||||
export declare function getMenu(location: string): Menu | undefined;
|
||||
|
||||
/**
|
||||
* Event fired when a menu item is registered.
|
||||
*/
|
||||
export interface MenuItemRegisteredEvent {
|
||||
/** The menu item that was registered. */
|
||||
item: MenuItem;
|
||||
/** The location where the item was registered. */
|
||||
location: string;
|
||||
/** The group the item was placed in. */
|
||||
group: 'primary' | 'secondary' | 'context';
|
||||
}
|
||||
|
||||
/**
|
||||
* Event fired when a menu item is unregistered.
|
||||
*/
|
||||
export interface MenuItemUnregisteredEvent {
|
||||
/** The menu item that was unregistered. */
|
||||
item: MenuItem;
|
||||
/** The location where the item was registered. */
|
||||
location: string;
|
||||
/** The group the item was placed in. */
|
||||
group: 'primary' | 'secondary' | 'context';
|
||||
}
|
||||
|
||||
/**
|
||||
* Event fired when a menu item is registered.
|
||||
*/
|
||||
export declare const onDidRegisterMenuItem: Event<MenuItemRegisteredEvent>;
|
||||
|
||||
/**
|
||||
* Event fired when a menu item is unregistered.
|
||||
*/
|
||||
export declare const onDidUnregisterMenuItem: Event<MenuItemUnregisteredEvent>;
|
||||
|
||||
@@ -508,12 +508,6 @@ export interface ThemeContextType {
|
||||
clearLocalOverrides: () => void;
|
||||
getCurrentCrudThemeId: () => string | null;
|
||||
hasDevOverride: () => boolean;
|
||||
/**
|
||||
* True when an explicit theme config override is active (e.g. supplied via
|
||||
* the Embedded SDK). Such an override takes precedence over a
|
||||
* dashboard-level theme.
|
||||
*/
|
||||
hasThemeConfigOverride: boolean;
|
||||
canSetMode: () => boolean;
|
||||
canSetTheme: () => boolean;
|
||||
canDetectOSPreference: () => boolean;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
import { ReactElement } from 'react';
|
||||
import { Disposable, Event } from '../common';
|
||||
import { Disposable } from '../common';
|
||||
|
||||
/**
|
||||
* Represents a contributed view in the application.
|
||||
@@ -88,33 +88,3 @@ export declare function registerView(
|
||||
* ```
|
||||
*/
|
||||
export declare function getViews(location: string): View[] | undefined;
|
||||
|
||||
/**
|
||||
* Event fired when a view is registered.
|
||||
*/
|
||||
export interface ViewRegisteredEvent {
|
||||
/** The descriptor of the view that was registered. */
|
||||
view: View;
|
||||
/** The location where the view was registered. */
|
||||
location: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event fired when a view is unregistered.
|
||||
*/
|
||||
export interface ViewUnregisteredEvent {
|
||||
/** The descriptor of the view that was unregistered. */
|
||||
view: View;
|
||||
/** The location where the view was registered. */
|
||||
location: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event fired when a view is registered.
|
||||
*/
|
||||
export declare const onDidRegisterView: Event<ViewRegisteredEvent>;
|
||||
|
||||
/**
|
||||
* Event fired when a view is unregistered.
|
||||
*/
|
||||
export declare const onDidUnregisterView: Event<ViewUnregisteredEvent>;
|
||||
|
||||
@@ -118,6 +118,7 @@ const matrixifyControls: Record<string, SharedControlConfig<any>> = {};
|
||||
description: t(`Select dimension and values`),
|
||||
default: { dimension: '', values: [] },
|
||||
validators: [], // No validation - rely on visibility
|
||||
renderTrigger: true,
|
||||
tabOverride: 'matrixify',
|
||||
shouldMapStateToProps: (prevState, state) => {
|
||||
// Recalculate when any relevant form_data field changes
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
"@types/json-bigint": "^1.0.4",
|
||||
"@visx/responsive": "^3.12.0",
|
||||
"ace-builds": "^1.44.0",
|
||||
"ag-grid-community": "35.3.1",
|
||||
"ag-grid-react": "35.3.1",
|
||||
"ag-grid-community": "35.3.0",
|
||||
"ag-grid-react": "35.3.0",
|
||||
"brace": "^0.11.1",
|
||||
"classnames": "^2.5.1",
|
||||
"core-js": "^3.49.0",
|
||||
@@ -43,7 +43,7 @@
|
||||
"d3-time": "^3.1.0",
|
||||
"d3-time-format": "^4.1.0",
|
||||
"dayjs": "^1.11.21",
|
||||
"dompurify": "^3.4.8",
|
||||
"dompurify": "^3.4.7",
|
||||
"fetch-retry": "^6.0.0",
|
||||
"handlebars": "^4.7.9",
|
||||
"jed": "^1.1.1",
|
||||
|
||||
@@ -17,20 +17,8 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
forwardRef,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
} from 'react';
|
||||
import type {
|
||||
ComponentType,
|
||||
WeakValidationMap,
|
||||
ForwardRefExoticComponent,
|
||||
PropsWithoutRef,
|
||||
RefAttributes,
|
||||
} from 'react';
|
||||
// eslint-disable-next-line no-restricted-syntax -- whole React import is required for `reactify.test.tsx` Jest test passing.
|
||||
import { Component, ComponentClass, WeakValidationMap } from 'react';
|
||||
|
||||
// TODO: Note that id and className can collide between Props and ReactifyProps
|
||||
// leading to (likely) unexpected behaviors. We should either require Props to not
|
||||
@@ -61,103 +49,66 @@ export interface RenderFuncType<Props> {
|
||||
propTypes?: WeakValidationMap<Props & ReactifyProps>;
|
||||
}
|
||||
|
||||
export interface ReactifiedComponentRef {
|
||||
container?: HTMLDivElement;
|
||||
}
|
||||
|
||||
export type ReactifiedComponent<Props> = ForwardRefExoticComponent<
|
||||
PropsWithoutRef<Props & ReactifyProps> & RefAttributes<ReactifiedComponentRef>
|
||||
>;
|
||||
|
||||
// Return the widest public type that covers "use it as a React component" so
|
||||
// TypeScript JSX callers and `ComponentType<...>`-typed variables still compile;
|
||||
// callers with explicit `ComponentClass<...>` annotations must widen to
|
||||
// `ComponentType`. Those wanting the forwardRef surface can narrow to
|
||||
// `ReactifiedComponent<Props>` explicitly.
|
||||
export default function reactify<Props extends object>(
|
||||
renderFn: RenderFuncType<Props>,
|
||||
callbacks?: LifeCycleCallbacks,
|
||||
): ComponentType<Props & ReactifyProps> {
|
||||
const ReactifiedComponent = forwardRef<
|
||||
ReactifiedComponentRef,
|
||||
Props & ReactifyProps
|
||||
>(function ReactifiedComponent(props, ref) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
// Keep the latest props available to the unmount callback — legacy
|
||||
// consumers read values off `this.props` (e.g. ReactNVD3 uses id).
|
||||
// Update the ref in a layout effect rather than during render so the
|
||||
// assignment only happens for committed renders (safe under Concurrent
|
||||
// Mode) and is in place before the passive unmount effect reads it.
|
||||
const propsRef = useRef(props);
|
||||
useLayoutEffect(() => {
|
||||
propsRef.current = props;
|
||||
});
|
||||
): ComponentClass<Props & ReactifyProps> {
|
||||
class ReactifiedComponent extends Component<Props & ReactifyProps> {
|
||||
container?: HTMLDivElement;
|
||||
|
||||
// Expose container via ref for external access
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => ({
|
||||
get container() {
|
||||
return containerRef.current ?? undefined;
|
||||
},
|
||||
}),
|
||||
[],
|
||||
);
|
||||
constructor(props: Props & ReactifyProps) {
|
||||
super(props);
|
||||
this.setContainerRef = this.setContainerRef.bind(this);
|
||||
}
|
||||
|
||||
// Execute renderFn on mount and every update (mimics componentDidMount + componentDidUpdate)
|
||||
useEffect(() => {
|
||||
if (containerRef.current) {
|
||||
// `forwardRef` widens the props parameter to `PropsWithoutRef<...>`,
|
||||
// which TypeScript can't narrow back to `Props & ReactifyProps` when
|
||||
// `Props` is a generic `object`. The values are identical at runtime,
|
||||
// so assert the original prop shape for `renderFn`.
|
||||
renderFn(
|
||||
containerRef.current,
|
||||
props as Readonly<Props & ReactifyProps>,
|
||||
);
|
||||
componentDidMount() {
|
||||
this.execute();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.execute();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.container = undefined;
|
||||
if (callbacks?.componentWillUnmount) {
|
||||
callbacks.componentWillUnmount.bind(this)();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Cleanup on unmount
|
||||
useEffect(
|
||||
() => () => {
|
||||
if (callbacks?.componentWillUnmount) {
|
||||
// Preserve legacy behavior where `this` was a component instance
|
||||
// exposing `props`. The class version cleared `this.container`
|
||||
// before invoking componentWillUnmount, so mirror that here to
|
||||
// prevent callbacks from touching a DOM node that's being torn
|
||||
// down.
|
||||
callbacks.componentWillUnmount.call({
|
||||
container: undefined,
|
||||
props: propsRef.current,
|
||||
});
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
setContainerRef(ref: HTMLDivElement) {
|
||||
this.container = ref;
|
||||
}
|
||||
|
||||
const { id, className } = props;
|
||||
execute() {
|
||||
if (this.container) {
|
||||
renderFn(this.container, this.props);
|
||||
}
|
||||
}
|
||||
|
||||
return <div ref={containerRef} id={id} className={className} />;
|
||||
});
|
||||
render() {
|
||||
const { id, className } = this.props;
|
||||
|
||||
if (renderFn.displayName) {
|
||||
ReactifiedComponent.displayName = renderFn.displayName;
|
||||
return <div ref={this.setContainerRef} id={id} className={className} />;
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- forwardRef static field types don't line up with renderFn's validator types
|
||||
const result = ReactifiedComponent as any;
|
||||
const ReactifiedClass: ComponentClass<Props & ReactifyProps> =
|
||||
ReactifiedComponent;
|
||||
|
||||
if (renderFn.displayName) {
|
||||
ReactifiedClass.displayName = renderFn.displayName;
|
||||
}
|
||||
// eslint-disable-next-line react/forbid-foreign-prop-types
|
||||
if (renderFn.propTypes) {
|
||||
result.propTypes = {
|
||||
...result.propTypes,
|
||||
ReactifiedClass.propTypes = {
|
||||
...ReactifiedClass.propTypes,
|
||||
...renderFn.propTypes,
|
||||
};
|
||||
}
|
||||
|
||||
if (renderFn.defaultProps) {
|
||||
result.defaultProps = renderFn.defaultProps;
|
||||
ReactifiedClass.defaultProps = renderFn.defaultProps;
|
||||
}
|
||||
|
||||
return result as unknown as ComponentType<Props & ReactifyProps>;
|
||||
return ReactifiedComponent;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
import { useState } from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { AutoComplete } from '.';
|
||||
import type { AutoCompleteProps } from './types';
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Breadcrumb } from '.';
|
||||
import type { BreadcrumbProps } from './types';
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { action } from 'storybook/actions';
|
||||
import { Meta, StoryFn } from '@storybook/react-webpack5';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { Meta, StoryFn } from '@storybook/react';
|
||||
import { CachedLabel } from '.';
|
||||
import type { CacheLabelProps } from './types';
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { useArgs } from 'storybook/preview-api';
|
||||
import { useArgs } from '@storybook/preview-api';
|
||||
import { useState } from 'react';
|
||||
import { Checkbox } from '.';
|
||||
import type { CheckboxProps, CheckboxChangeEvent } from './types';
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { Meta, StoryFn } from '@storybook/react-webpack5';
|
||||
import { Meta, StoryFn } from '@storybook/react';
|
||||
import { Row, Col } from '@superset-ui/core/components';
|
||||
import { EmptyState, imageMap } from '.';
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { FaveStar } from '.';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import Slider from '@superset-ui/core/components/Slider/index';
|
||||
import { useState } from 'react';
|
||||
import { Row, Col } from '.';
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { IconButton } from '.';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { StoryObj } from '@storybook/react-webpack5';
|
||||
import type { StoryObj } from '@storybook/react';
|
||||
import { Input, InputNumber } from '.';
|
||||
import type { InputProps, InputNumberProps, TextAreaProps } from './types';
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { action } from 'storybook/actions';
|
||||
import { Meta, StoryFn } from '@storybook/react-webpack5';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { Meta, StoryFn } from '@storybook/react';
|
||||
import type { LabelType } from './types';
|
||||
import { Label, DatasetTypeLabel, PublishedLabel } from '.';
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { Icons } from '@superset-ui/core/components/Icons';
|
||||
import { Menu } from '../Menu';
|
||||
import type { LayoutProps, SiderProps } from './types';
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { ListViewCard } from '.';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -369,7 +369,7 @@ const CustomModal = ({
|
||||
resizable || draggable ? (
|
||||
<Draggable
|
||||
disabled={!draggable || dragDisabled}
|
||||
bounds={bounds ?? false}
|
||||
bounds={bounds}
|
||||
onStart={(event, uiData) => onDragStart(event, uiData)}
|
||||
{...draggableConfig}
|
||||
>
|
||||
|
||||
@@ -47,7 +47,7 @@ export interface ModalProps {
|
||||
resizable?: boolean;
|
||||
resizableConfig?: ResizableProps;
|
||||
draggable?: boolean;
|
||||
draggableConfig?: Partial<DraggableProps>;
|
||||
draggableConfig?: DraggableProps;
|
||||
destroyOnHidden?: boolean;
|
||||
maskClosable?: boolean;
|
||||
zIndex?: number;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { StoryObj } from '@storybook/react-webpack5';
|
||||
import type { StoryObj } from '@storybook/react';
|
||||
import { css } from '@apache-superset/core/theme';
|
||||
import { Icons } from '@superset-ui/core/components/Icons';
|
||||
import { Space } from '../Space';
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { Meta, StoryFn } from '@storybook/react-webpack5';
|
||||
import { Meta, StoryFn } from '@storybook/react';
|
||||
import { SafeMarkdown } from './SafeMarkdown';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Space } from '../Space';
|
||||
import { Skeleton, type SkeletonProps } from '.';
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { useArgs } from 'storybook/preview-api';
|
||||
import { useArgs } from '@storybook/preview-api';
|
||||
import { Switch, type SwitchProps } from '.';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
*/
|
||||
import { useState, DragEvent } from 'react';
|
||||
|
||||
import type { Meta, StoryFn } from '@storybook/react-webpack5';
|
||||
import { action } from 'storybook/actions';
|
||||
import type { Meta, StoryFn } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import {
|
||||
ColumnsType,
|
||||
ETableAction,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { StoryFn, Meta } from '@storybook/react-webpack5';
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
import ActionCell from './index';
|
||||
import { exampleMenuOptions, exampleRow } from './fixtures';
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { action } from 'storybook/actions';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ActionMenuItem } from './index';
|
||||
|
||||
export const exampleMenuOptions: ActionMenuItem[] = [
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { StoryFn, Meta } from '@storybook/react-webpack5';
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
import BooleanCell from '.';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { StoryFn, Meta } from '@storybook/react-webpack5';
|
||||
import { action } from 'storybook/actions';
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { ButtonCell } from './index';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { StoryFn, Meta } from '@storybook/react-webpack5';
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
import NullCell from '.';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { StoryFn, Meta } from '@storybook/react-webpack5';
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
import { CurrencyCode, NumericCell, LocaleCode, Style } from './index';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { StoryFn, Meta } from '@storybook/react-webpack5';
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
import { TimeFormats } from '@superset-ui/core';
|
||||
import TimeCell from '.';
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
import { useMemo, useState, useCallback } from 'react';
|
||||
import { Meta, StoryFn } from '@storybook/react-webpack5';
|
||||
import { Meta, StoryFn } from '@storybook/react';
|
||||
import {
|
||||
useTable,
|
||||
useSortBy,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user