From afbbe44de2fb86bf9744cd221e51c477f01c760d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 01:37:30 -0700 Subject: [PATCH 01/37] chore(deps): bump dom-to-image-more from 3.9.0 to 3.10.0 in /superset-frontend (#41237) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 8 ++++---- superset-frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 9979d870021..ca79cca7a06 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -90,7 +90,7 @@ "d3-color": "^3.1.0", "d3-scale": "^4.0.2", "dayjs": "^1.11.21", - "dom-to-image-more": "^3.9.0", + "dom-to-image-more": "^3.10.0", "dom-to-pdf": "^0.3.2", "echarts": "^5.6.0", "fast-glob": "^3.3.2", @@ -18079,9 +18079,9 @@ "license": "MIT" }, "node_modules/dom-to-image-more": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-3.9.0.tgz", - "integrity": "sha512-9h1dEJ5+pAnWp2QH5YsBdR4couy2778LaJl6t0w0/AUoe1CQFkLgHL86rIICOK0WWJ5pN5o0x5IIgv0oK14epQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/dom-to-image-more/-/dom-to-image-more-3.10.0.tgz", + "integrity": "sha512-APrFEimSmH4phJKs8DlURuSr3BFwDqNi62l14bx73Wrhx0OhE4dd0qzZR+4E3sH8PnHxvax1LOrosC9oXRFA5A==", "license": "MIT" }, "node_modules/dom-to-pdf": { diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 5d5949f059f..92c425f4657 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -173,7 +173,7 @@ "d3-color": "^3.1.0", "d3-scale": "^4.0.2", "dayjs": "^1.11.21", - "dom-to-image-more": "^3.9.0", + "dom-to-image-more": "^3.10.0", "dom-to-pdf": "^0.3.2", "echarts": "^5.6.0", "fast-glob": "^3.3.2", From 25ad827ff350067abb81bf7a297ff751a41072b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 01:37:34 -0700 Subject: [PATCH 02/37] chore(deps-dev): bump storybook from 10.4.3 to 10.4.4 in /superset-frontend (#41236) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 8 ++++---- superset-frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index ca79cca7a06..fa4207e76e1 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -273,7 +273,7 @@ "source-map": "^0.7.6", "source-map-support": "^0.5.21", "speed-measure-webpack-plugin": "^1.6.0", - "storybook": "10.4.3", + "storybook": "10.4.4", "style-loader": "^4.0.0", "swc-loader": "^0.2.7", "terser-webpack-plugin": "^5.6.1", @@ -39086,9 +39086,9 @@ } }, "node_modules/storybook": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.4.3.tgz", - "integrity": "sha512-oTfNXtS/K4PmASbcD+RyW7kxWGt3tknJL3RZodCMh+nnp3X4ng8vYg8yvIhTG/q0dqBxw7Ba8dHsfsEy4631vg==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.4.4.tgz", + "integrity": "sha512-Nn0qFRxU5fyABa6dGRftfL3lz0Y+HkKOaAkfytF8S4Q2K6Szwwq7TwPAEs3Wsj8hBQbYhsobrKADcPsyXQpJaA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 92c425f4657..d71d33632aa 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -356,7 +356,7 @@ "source-map": "^0.7.6", "source-map-support": "^0.5.21", "speed-measure-webpack-plugin": "^1.6.0", - "storybook": "10.4.3", + "storybook": "10.4.4", "style-loader": "^4.0.0", "swc-loader": "^0.2.7", "terser-webpack-plugin": "^5.6.1", From 28f9b3786cc29e91ceae0080776698a212884e15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 01:37:37 -0700 Subject: [PATCH 03/37] chore(deps-dev): bump baseline-browser-mapping from 2.10.35 to 2.10.36 in /superset-frontend (#41235) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 8 ++++---- superset-frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index fa4207e76e1..adc3cadb972 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -221,7 +221,7 @@ "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-jsx-remove-data-test-id": "^3.0.0", "babel-plugin-lodash": "^3.3.4", - "baseline-browser-mapping": "^2.10.35", + "baseline-browser-mapping": "^2.10.36", "cheerio": "1.2.0", "concurrently": "^10.0.3", "copy-webpack-plugin": "^14.0.0", @@ -14474,9 +14474,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.35", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.35.tgz", - "integrity": "sha512-honAfLBde0HAFLdNyBEfuuENkF6zR+ozxqxa/2zJKHBe1qzLqyTSeRKpdPEHAP03rlDGyQOPnCSxnVpVqQo9Mg==", + "version": "2.10.36", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.36.tgz", + "integrity": "sha512-lVq/Df7LXlO79MVaaUHztSwWiG9oXoWHlgvNS51v8Dpd4+G4/VIy6qYePTw31nAVls33nUtnfezYeLkYAak9dg==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/superset-frontend/package.json b/superset-frontend/package.json index d71d33632aa..e4ba4757427 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -304,7 +304,7 @@ "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-jsx-remove-data-test-id": "^3.0.0", "babel-plugin-lodash": "^3.3.4", - "baseline-browser-mapping": "^2.10.35", + "baseline-browser-mapping": "^2.10.36", "cheerio": "1.2.0", "concurrently": "^10.0.3", "copy-webpack-plugin": "^14.0.0", From 655395cb4ed77ffb91c7b8c4c6e808eec234d4f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 01:37:40 -0700 Subject: [PATCH 04/37] chore(deps): bump acorn from 8.16.0 to 8.17.0 in /superset-frontend (#41234) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 8 ++++---- .../plugins/plugin-chart-echarts/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index adc3cadb972..5574bb18999 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -45070,7 +45070,7 @@ "dependencies": { "@types/d3-array": "^3.2.2", "@types/react-redux": "^7.1.34", - "acorn": "^8.16.0", + "acorn": "^8.17.0", "d3-array": "^3.2.4", "lodash": "^4.18.1", "zod": "^4.4.3" @@ -45086,9 +45086,9 @@ } }, "plugins/plugin-chart-echarts/node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "license": "MIT", "bin": { "acorn": "bin/acorn" diff --git a/superset-frontend/plugins/plugin-chart-echarts/package.json b/superset-frontend/plugins/plugin-chart-echarts/package.json index bf85d94450f..a1467781349 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/package.json +++ b/superset-frontend/plugins/plugin-chart-echarts/package.json @@ -26,7 +26,7 @@ "dependencies": { "@types/d3-array": "^3.2.2", "@types/react-redux": "^7.1.34", - "acorn": "^8.16.0", + "acorn": "^8.17.0", "d3-array": "^3.2.4", "lodash": "^4.18.1", "zod": "^4.4.3" From a85796418a74c0f200ad3e11081b2966fe6366c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 01:37:43 -0700 Subject: [PATCH 05/37] chore(deps): bump @deck.gl/mapbox from 9.3.3 to 9.3.4 in /superset-frontend (#41233) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 8 ++++---- .../plugins/preset-chart-deckgl/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 5574bb18999..34cdd54937f 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -45275,7 +45275,7 @@ "@deck.gl/extensions": "~9.2.9", "@deck.gl/geo-layers": "~9.2.5", "@deck.gl/layers": "~9.2.5", - "@deck.gl/mapbox": "~9.3.3", + "@deck.gl/mapbox": "^9.3.4", "@deck.gl/mesh-layers": "~9.2.5", "@luma.gl/constants": "~9.2.5", "@luma.gl/core": "~9.2.5", @@ -45323,9 +45323,9 @@ } }, "plugins/preset-chart-deckgl/node_modules/@deck.gl/mapbox": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-9.3.3.tgz", - "integrity": "sha512-aUPqrwF6wkx+EtvKA3SaiK+UROMnZSmgEJWZ1qSKFSiH//kPuo5imbtXyan8sGhOet7NjnfEwJqFA3EBk7zDLA==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-9.3.4.tgz", + "integrity": "sha512-chAEyVc8qD5I/tvy+VO2b/W01LP19LJTQLamR0gVCMkCm58hnKh83nQtj/XGqrHk61LOpnN/ASfksXa7XNc0hA==", "license": "MIT", "dependencies": { "@math.gl/web-mercator": "^4.1.0" diff --git a/superset-frontend/plugins/preset-chart-deckgl/package.json b/superset-frontend/plugins/preset-chart-deckgl/package.json index 1e7f8e207bd..1d7bcf14c43 100644 --- a/superset-frontend/plugins/preset-chart-deckgl/package.json +++ b/superset-frontend/plugins/preset-chart-deckgl/package.json @@ -29,7 +29,7 @@ "@deck.gl/extensions": "~9.2.9", "@deck.gl/geo-layers": "~9.2.5", "@deck.gl/layers": "~9.2.5", - "@deck.gl/mapbox": "~9.3.3", + "@deck.gl/mapbox": "~9.3.4", "@deck.gl/mesh-layers": "~9.2.5", "@luma.gl/constants": "~9.2.5", "@luma.gl/core": "~9.2.5", From 4d5c171e9e7e39267afa53baf15a7941c24dd0b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 01:37:46 -0700 Subject: [PATCH 06/37] chore(deps): bump antd from 6.4.3 to 6.4.4 in /docs (#41228) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/package.json | 2 +- docs/yarn.lock | 214 ++++++++++++++++++++++++---------------------- 2 files changed, 113 insertions(+), 103 deletions(-) diff --git a/docs/package.json b/docs/package.json index 7ec93ca72ed..6684462842a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -71,7 +71,7 @@ "@storybook/theming": "^8.6.15", "@superset-ui/core": "^0.20.4", "@swc/core": "^1.15.41", - "antd": "^6.4.3", + "antd": "^6.4.4", "baseline-browser-mapping": "^2.10.35", "caniuse-lite": "^1.0.30001797", "docusaurus-plugin-openapi-docs": "^5.0.2", diff --git a/docs/yarn.lock b/docs/yarn.lock index a97a1d41596..b480bc10143 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -212,7 +212,7 @@ resolved "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz" integrity sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA== -"@ant-design/icons@^6.2.3", "@ant-design/icons@^6.2.5": +"@ant-design/icons@^6.2.5": version "6.2.5" resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-6.2.5.tgz#31c142aa6ce5eaf99598aaead222f4c459693512" integrity sha512-0hKtoKqTjGFOndUyJLJmC9Cg6k4rEO7rLo6xmgbNJH+/ZX1C57RVals2v1j1knHl9n7Q+sBOveTvn931wLOCKw== @@ -3162,21 +3162,21 @@ resolved "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz" integrity sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww== -"@rc-component/async-validator@^5.1.0": - version "5.1.0" - resolved "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.1.0.tgz" - integrity sha512-n4HcR5siNUXRX23nDizbZBQPO0ZM/5oTtmKZ6/eqL0L2bo747cklFdZGRN2f+c9qWGICwDzrhW0H7tE9PptdcA== +"@rc-component/async-validator@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@rc-component/async-validator/-/async-validator-6.0.0.tgz#1c20b8864f69bac63b7876b1321697c2ea71c68d" + integrity sha512-D3AGQwdyE58gmvx6waVSXJ80JGO+IY5L2O8HDnSOex7JNlzB3GuN/4hyHNTdhy2qtOhkpbIjmeAN3tL993wKbA== dependencies: "@babel/runtime" "^7.24.4" -"@rc-component/cascader@~1.15.0": - version "1.15.0" - resolved "https://registry.yarnpkg.com/@rc-component/cascader/-/cascader-1.15.0.tgz#554cba8e01e94a1288547cec96422b2cfc73ff40" - integrity sha512-ZzpMtwFCRo3fbXHuDnncARJMZQjdqA2w7aDuPofNQt+aDx39st1hgfIpEwTBLhe2Hqsvs/zOr8RTtgxTkCPySw== +"@rc-component/cascader@~1.16.1": + version "1.16.1" + resolved "https://registry.yarnpkg.com/@rc-component/cascader/-/cascader-1.16.1.tgz#94193ee55009219999a46e005a0f8589c8c021a2" + integrity sha512-wxLopwM+EBed0zNNGdnGE4coYoqcO+XD42fHgn+pDvO+XzhNFbdgSlSNXdKocIYqccvqgWvoxDPNb0OVRdi59A== dependencies: - "@rc-component/select" "~1.6.0" - "@rc-component/tree" "~1.3.0" - "@rc-component/util" "^1.4.0" + "@rc-component/select" "~1.7.1" + "@rc-component/tree" "~1.3.2" + "@rc-component/util" "^1.11.1" clsx "^2.1.1" "@rc-component/checkbox@~2.0.0": @@ -3242,13 +3242,13 @@ "@rc-component/util" "^1.2.1" clsx "^2.1.1" -"@rc-component/form@~1.8.1": - version "1.8.1" - resolved "https://registry.yarnpkg.com/@rc-component/form/-/form-1.8.1.tgz#d811fb52df41bf72297938ebfe5cf4a4774588d4" - integrity sha512-8O7TB55Fi2mWIGvSnwZjk8jFqVNYyKDAswglwGShcbndxqzKz4cHwNtNaLjZlAeRge9wcB0LL8IWsC/Bl18raQ== +"@rc-component/form@~1.8.3": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@rc-component/form/-/form-1.8.5.tgz#20571cfd401dc38c74c38cdf4722ddc6c23a9806" + integrity sha512-d24EYtvUOBhxEtSd/EqIu9DaMuqrWF2IRIvAFCTM6NQ/GJIYNr8DvEpUSUlv2uPxEJ0ZPwYQ+wwlGIAaiHvdrw== dependencies: - "@rc-component/async-validator" "^5.1.0" - "@rc-component/util" "^1.6.2" + "@rc-component/async-validator" "^6.0.0" + "@rc-component/util" "^1.11.1" clsx "^2.1.1" "@rc-component/image@~1.9.0": @@ -3270,13 +3270,13 @@ "@rc-component/util" "^1.4.0" clsx "^2.1.1" -"@rc-component/input@~1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@rc-component/input/-/input-1.3.0.tgz#a8c113000bbc39089cf75337bec68120115b9e05" - integrity sha512-IUUNOdAuWuEvDEFFgfmwQl818tiDbvXwLgon4HL1q2hJeYkqrRrYwYhJN0zfPHGTDxs3gvyVC/C02D4hWFoIcA== +"@rc-component/input@~1.3.0", "@rc-component/input@~1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@rc-component/input/-/input-1.3.1.tgz#230b8b59cdde8521d50f0eede63ddacb61cc0cd3" + integrity sha512-iFvTUT9W+JC/MSin2aGAk8NqsVlTzcExNC9DZariON1IWirju9NoNeEk47an4Q8iHazkoVI/y1LnDi88+CPcig== dependencies: "@rc-component/resize-observer" "^1.1.1" - "@rc-component/util" "^1.4.0" + "@rc-component/util" "^1.11.1" clsx "^2.1.1" "@rc-component/mentions@~1.9.0": @@ -3290,15 +3290,15 @@ "@rc-component/util" "^1.3.0" clsx "^2.1.1" -"@rc-component/menu@~1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@rc-component/menu/-/menu-1.3.0.tgz#fc70d81ca76ae6013b0d7955f20a2393adef04b3" - integrity sha512-u3NfiwpiEgT177qa5Yxm5QsI8i/93EBGpWj8HYZQDnh2pCZ2xtQCe/+w3pSR2NlwKOZDTCKzEhEyD09mGphssA== +"@rc-component/menu@~1.3.0", "@rc-component/menu@~1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@rc-component/menu/-/menu-1.3.1.tgz#16cae71a01080914e8bac08359fccdda7bfce540" + integrity sha512-pSZl9nBPgKgxN0aaW7NilIBEwWsc+43S+ulGdWAg9afak96dNOGWsGx0DLLBB1VQsAJvo6bQMTDzXoPlEHsBEw== dependencies: "@rc-component/motion" "^1.1.4" "@rc-component/overflow" "^1.0.0" "@rc-component/trigger" "^3.0.0" - "@rc-component/util" "^1.3.0" + "@rc-component/util" "^1.11.1" clsx "^2.1.1" "@rc-component/mini-decimal@^1.0.1": @@ -3308,12 +3308,12 @@ dependencies: "@babel/runtime" "^7.18.0" -"@rc-component/motion@^1.0.0", "@rc-component/motion@^1.1.3", "@rc-component/motion@^1.1.4", "@rc-component/motion@^1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@rc-component/motion/-/motion-1.3.2.tgz#bd96e0fd16ee9d98c1d9be14198f003e367d8feb" - integrity sha512-itfd+GztzJYAb04Z4RkEub1TbJAfZc2Iuy8p44U44xD1F5+fNYFKI3897ijlbIyfvXkTmMm+KGcjkQQGMHywEQ== +"@rc-component/motion@^1.0.0", "@rc-component/motion@^1.1.3", "@rc-component/motion@^1.1.4", "@rc-component/motion@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@rc-component/motion/-/motion-1.3.3.tgz#6a7bbe0a9f070bd11642168f741d40e78bb28565" + integrity sha512-Xh3IszxvlSv3/PLYFyC2UZi9LNB83yOnkB/LNmRzaypZLvkhqUIPS7MQpGZcCMWrNsXV2p6YTSWbSGvFpEle9A== dependencies: - "@rc-component/util" "^1.2.0" + "@rc-component/util" "^1.11.0" clsx "^2.1.1" "@rc-component/mutate-observer@^2.0.1": @@ -3342,12 +3342,12 @@ "@rc-component/util" "^1.4.0" clsx "^2.1.1" -"@rc-component/pagination@~1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@rc-component/pagination/-/pagination-1.2.0.tgz" - integrity sha512-YcpUFE8dMLfSo6OARJlK6DbHHvrxz7pMGPGmC/caZSJJz6HRKHC1RPP001PRHCvG9Z/veD039uOQmazVuLJzlw== +"@rc-component/pagination@~1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@rc-component/pagination/-/pagination-1.3.0.tgz#ee66301e37a03974826fb3028a91a1aeacdcd0ac" + integrity sha512-12ahTY+HPITg1L2bjWKXUqBJe/oOnpA2QsChdCjthqLVf/e19StiCsv8OLKpWoHbc+8PFEkNjRqRqrLoRBHjFw== dependencies: - "@rc-component/util" "^1.3.0" + "@rc-component/util" "^1.11.1" clsx "^2.1.1" "@rc-component/picker@~1.10.0": @@ -3377,10 +3377,10 @@ "@rc-component/util" "^1.2.1" clsx "^2.1.1" -"@rc-component/qrcode@~1.1.1": - version "1.1.1" - resolved "https://registry.npmjs.org/@rc-component/qrcode/-/qrcode-1.1.1.tgz" - integrity sha512-LfLGNymzKdUPjXUbRP+xOhIWY4jQ+YMj5MmWAcgcAq1Ij8XP7tRmAXqyuv96XvLUBE/5cA8hLFl9eO1JQMujrA== +"@rc-component/qrcode@~2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@rc-component/qrcode/-/qrcode-2.0.0.tgz#ef4134c213002e7a43edbe609b24248914de4974" + integrity sha512-aAv3QhPP1xyafuTZOxub6a54pCeBnN3IwQkpETrBtthq4BL5IgxnCbuoBWPDpdLw1y1j6BgBUCAKV92+yX06Dw== dependencies: "@babel/runtime" "^7.24.7" @@ -3409,15 +3409,15 @@ "@rc-component/util" "^1.3.0" clsx "^2.1.1" -"@rc-component/select@~1.6.0", "@rc-component/select@~1.6.15": - version "1.6.15" - resolved "https://registry.yarnpkg.com/@rc-component/select/-/select-1.6.15.tgz#de2a3c8b020834cabd600b52de573a328c061eef" - integrity sha512-SyVCWnqxCQZZcQvQJ/CxSjx2bGma6ds/HtnpkIfZVnt6RoEgbqUmHgD6vrzNarNXwbLXerwVzWwq8F3d1sst7g== +"@rc-component/select@~1.7.0", "@rc-component/select@~1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@rc-component/select/-/select-1.7.1.tgz#cdda0ac185f00ebed1c85e7809ae1f7855a9f7ab" + integrity sha512-GZ1cMJk2xQh0VHyOQjjG8drYL4iu24NcbkXioUcReQOCUr+ub/3fmRonZe6cRPEZhWMbJdeHsqnEltogDaZ5Tg== dependencies: "@rc-component/overflow" "^1.0.0" "@rc-component/trigger" "^3.0.0" - "@rc-component/util" "^1.3.0" - "@rc-component/virtual-list" "^1.0.1" + "@rc-component/util" "^1.11.1" + "@rc-component/virtual-list" "^1.2.0" clsx "^2.1.1" "@rc-component/slider@~1.0.1": @@ -3444,27 +3444,27 @@ "@rc-component/util" "^1.3.0" clsx "^2.1.1" -"@rc-component/table@~1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@rc-component/table/-/table-1.10.0.tgz#7a98d68176f23f50a762df464f4c9142e7db3942" - integrity sha512-SjtpcCf+rL7dDc62GKT3rXTdERjVuJvRiqjpU7g0Jc/ewCifXynHc7Nm3Em1XsD+WhGrgQtxNDScI/0+Lpfr0w== +"@rc-component/table@~1.10.2": + version "1.10.2" + resolved "https://registry.yarnpkg.com/@rc-component/table/-/table-1.10.2.tgz#7b052fd5eb2ccf6996a93eebeb7af7036a262c8b" + integrity sha512-b3PjqB9Gp25p5t/zq+9QrbXbodkptT8/zvLmwgd2FNPUUtaYyDnQqfxeD5a7ao8E8lpinLHsi2u2vdfPhyNvAw== dependencies: "@rc-component/context" "^2.0.1" "@rc-component/resize-observer" "^1.0.0" - "@rc-component/util" "^1.1.0" + "@rc-component/util" "^1.11.1" "@rc-component/virtual-list" "^1.0.1" clsx "^2.1.1" -"@rc-component/tabs@~1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@rc-component/tabs/-/tabs-1.9.0.tgz#8f3e3755450e5a90d240d1ed3dc140d520b1fbef" - integrity sha512-tn1slmbbaTyt8mgwyWJcT8jo/qNiYUs6u1H7OgGQt9faYO06BJIkU5cTmMqORzIrNmSEeeUY6pD5i+JlqSHYhg== +"@rc-component/tabs@~1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@rc-component/tabs/-/tabs-1.9.1.tgz#52b9cb0392c718fba43e7d558f46f6c910d19acb" + integrity sha512-6mY08Fce6aNOHuGsxbzT+f2ekgL9mg1cGGHkittMlVGymjGg+kGupu5v90sRxcUd/paRU9jclLLXtF/PkK1FUA== dependencies: "@rc-component/dropdown" "~1.0.0" "@rc-component/menu" "~1.3.0" "@rc-component/motion" "^1.1.3" "@rc-component/resize-observer" "^1.0.0" - "@rc-component/util" "^1.3.0" + "@rc-component/util" "^1.11.1" clsx "^2.1.1" "@rc-component/tooltip@~1.4.0": @@ -3486,30 +3486,30 @@ "@rc-component/util" "^1.7.0" clsx "^2.1.1" -"@rc-component/tree-select@~1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@rc-component/tree-select/-/tree-select-1.9.0.tgz#13ea516478b6cb558e04181abb0a01ae6fbdd31f" - integrity sha512-GXcFe15a+trUl1/J3OHWQhsVWFpwFpGFK2cqYWZ1sK22Zs3KZTvMwDpzr75PIo1s6QVioVxpE/pRwRopkeDQ6w== +"@rc-component/tree-select@~1.10.0": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@rc-component/tree-select/-/tree-select-1.10.0.tgz#72e337fd58591f677404189cb3e9d3f718cd3332" + integrity sha512-E1U4pn2LAbXEhLJdzIzid7WYbIuFbkTIctuFoeC6weppf8UbPR3+YYB6/ay0c0ksand4gXMRQpa1Z60Auo7VJA== dependencies: - "@rc-component/select" "~1.6.0" + "@rc-component/select" "~1.7.0" "@rc-component/tree" "~1.3.0" "@rc-component/util" "^1.4.0" clsx "^2.1.1" -"@rc-component/tree@~1.3.0", "@rc-component/tree@~1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@rc-component/tree/-/tree-1.3.1.tgz#6983ca6bd9d5f6d04dd7258d00cb0fe71cdfe661" - integrity sha512-zlL0PW0bTFlveTtLcA01VD/yMWKK73EywItFMgIZUY5sb6tMOAw7zV6qGzqldufqrV93ZWQB4H3NBNoTMCueJA== +"@rc-component/tree@~1.3.0", "@rc-component/tree@~1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@rc-component/tree/-/tree-1.3.2.tgz#4b0c13564314eff61ca948c18ef923b87c9d7e44" + integrity sha512-bJFj46wEkpBPnWyTm18XmgAgNQ/4YvprxMOPPY2a6rmhGJYxLuNKEFiL5Qej4Qctu9wHJm8WW+v2SYskafE0kA== dependencies: "@rc-component/motion" "^1.0.0" - "@rc-component/util" "^1.8.1" - "@rc-component/virtual-list" "^1.0.1" + "@rc-component/util" "^1.11.1" + "@rc-component/virtual-list" "^1.2.0" clsx "^2.1.1" -"@rc-component/trigger@^3.0.0", "@rc-component/trigger@^3.6.15", "@rc-component/trigger@^3.7.1", "@rc-component/trigger@^3.9.0": - version "3.9.0" - resolved "https://registry.npmjs.org/@rc-component/trigger/-/trigger-3.9.0.tgz" - integrity sha512-X8btpwfrT27AgrZVOz4swclhEHTZcqaHeQMXXBgveagOiakTa36uObXbdwerXffgV8G9dH1fAAE0DHtVQs8EHg== +"@rc-component/trigger@^3.0.0", "@rc-component/trigger@^3.6.15", "@rc-component/trigger@^3.7.1", "@rc-component/trigger@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@rc-component/trigger/-/trigger-3.9.1.tgz#3f730315c558bc392921a563ac9109a1d094ef23" + integrity sha512-LNsYvz60mrLJ/kRvKcHE7boUvcQfVMCfRqZ71x3Fo9AOiZ1KKIEqkzMA8DNvz2V3Bcvir/vwQNn7JF1NPODQ7Q== dependencies: "@rc-component/motion" "^1.1.4" "@rc-component/portal" "^2.2.0" @@ -3517,18 +3517,18 @@ "@rc-component/util" "^1.2.1" clsx "^2.1.1" -"@rc-component/upload@~1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@rc-component/upload/-/upload-1.1.0.tgz" - integrity sha512-LIBV90mAnUE6VK5N4QvForoxZc4XqEYZimcp7fk+lkE4XwHHyJWxpIXQQwMU8hJM+YwBbsoZkGksL1sISWHQxw== +"@rc-component/upload@~1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@rc-component/upload/-/upload-1.1.1.tgz#90d16edcdaeb104ffa9111fd0b428061de7c21ac" + integrity sha512-GvYWSKeaJTOxxC5p6+nOSadzfvXA1h8C/iHFPFZX+szH3JUXrvs+DLiW8YUTBgvMh8m63mJeHrlYlJzAlg+pDA== dependencies: - "@rc-component/util" "^1.3.0" + "@rc-component/util" "^1.11.1" clsx "^2.1.1" -"@rc-component/util@^1.1.0", "@rc-component/util@^1.10.1", "@rc-component/util@^1.11.0", "@rc-component/util@^1.2.0", "@rc-component/util@^1.2.1", "@rc-component/util@^1.3.0", "@rc-component/util@^1.4.0", "@rc-component/util@^1.6.2", "@rc-component/util@^1.7.0", "@rc-component/util@^1.8.1", "@rc-component/util@^1.9.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@rc-component/util/-/util-1.11.0.tgz#965c8b44a3f57fc96dc14e5072afbe32e422fd4d" - integrity sha512-jHG3/BYgUWiP5c7RZHiaUNToyw1L3nlPSKG2RPu+YoiD9b3ajiJwBWhsjO+ZELmCsKFAjNR5DelbKdlF0e2BDA== +"@rc-component/util@^1.10.1", "@rc-component/util@^1.11.0", "@rc-component/util@^1.11.1", "@rc-component/util@^1.2.0", "@rc-component/util@^1.2.1", "@rc-component/util@^1.3.0", "@rc-component/util@^1.4.0", "@rc-component/util@^1.7.0", "@rc-component/util@^1.9.0": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@rc-component/util/-/util-1.11.1.tgz#07d698908339c55648e4f974afa739345e65b483" + integrity sha512-awVlI3ub2vqfqkYxOBc/uQ0efm3jw0wcrhtO/YWLyZfxiKXczKwNbVuhlnyxytDt7H9pbbVQiqr+O6MLATtRYg== dependencies: is-mobile "^5.0.0" react-is "^18.2.0" @@ -3543,6 +3543,16 @@ "@rc-component/util" "^1.4.0" clsx "^2.1.1" +"@rc-component/virtual-list@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@rc-component/virtual-list/-/virtual-list-1.2.0.tgz#3c9ee8cd7d10da334a2a06ad86ca234e2792a381" + integrity sha512-iavRm1Jo4GDbASQwdGa7jFyk93RvSOo9xHyBT4QL1pgFJj/Fdf1G+3RErH7/7BmAMvx2AkF62mjGYxDbXsK9TQ== + dependencies: + "@babel/runtime" "^7.20.0" + "@rc-component/resize-observer" "^1.0.1" + "@rc-component/util" "^1.4.0" + clsx "^2.1.1" + "@redocly/ajv@^8.18.0": version "8.18.3" resolved "https://registry.yarnpkg.com/@redocly/ajv/-/ajv-8.18.3.tgz#a925753d9a33375219f1b2ba91aef320f9929577" @@ -5382,54 +5392,54 @@ ansis@^3.2.0: resolved "https://registry.yarnpkg.com/ansis/-/ansis-3.17.0.tgz#fa8d9c2a93fe7d1177e0c17f9eeb562a58a832d7" integrity sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg== -antd@^6.4.3: - version "6.4.3" - resolved "https://registry.yarnpkg.com/antd/-/antd-6.4.3.tgz#80a7aab9c13c35daa0e0e7eea80585ba57cb7203" - integrity sha512-6H2avkxCGfxcF67r3J2mwm9Ck50el1pks/73vfM1wDsPL/tPtj5vHuauMgJFnrqmq7CH3g8aoZ0VBQbt+jpAsw== +antd@^6.4.4: + version "6.4.4" + resolved "https://registry.yarnpkg.com/antd/-/antd-6.4.4.tgz#a422610959b37ac4d4b766dbaac67ea2d8fd0785" + integrity sha512-lgPz4KhfhiYddV/qPYo0ieqWimCVgV2OQF72mbeGNixE753JWNnmEc7UNGy08wBS/zZ7hxrmX0pc5aX7EUaIIg== dependencies: "@ant-design/colors" "^8.0.1" "@ant-design/cssinjs" "^2.1.2" "@ant-design/cssinjs-utils" "^2.1.2" "@ant-design/fast-color" "^3.0.1" - "@ant-design/icons" "^6.2.3" + "@ant-design/icons" "^6.2.5" "@ant-design/react-slick" "~2.0.0" "@babel/runtime" "^7.29.2" - "@rc-component/cascader" "~1.15.0" + "@rc-component/cascader" "~1.16.1" "@rc-component/checkbox" "~2.0.0" "@rc-component/collapse" "~1.2.0" "@rc-component/color-picker" "~3.1.1" "@rc-component/dialog" "~1.9.0" "@rc-component/drawer" "~1.4.2" "@rc-component/dropdown" "~1.0.2" - "@rc-component/form" "~1.8.1" + "@rc-component/form" "~1.8.3" "@rc-component/image" "~1.9.0" - "@rc-component/input" "~1.3.0" + "@rc-component/input" "~1.3.1" "@rc-component/input-number" "~1.6.2" "@rc-component/mentions" "~1.9.0" - "@rc-component/menu" "~1.3.0" - "@rc-component/motion" "^1.3.2" + "@rc-component/menu" "~1.3.1" + "@rc-component/motion" "^1.3.3" "@rc-component/mutate-observer" "^2.0.1" "@rc-component/notification" "~2.0.7" - "@rc-component/pagination" "~1.2.0" + "@rc-component/pagination" "~1.3.0" "@rc-component/picker" "~1.10.0" "@rc-component/progress" "~1.0.2" - "@rc-component/qrcode" "~1.1.1" + "@rc-component/qrcode" "~2.0.0" "@rc-component/rate" "~1.0.1" "@rc-component/resize-observer" "^1.1.2" "@rc-component/segmented" "~1.3.0" - "@rc-component/select" "~1.6.15" + "@rc-component/select" "~1.7.1" "@rc-component/slider" "~1.0.1" "@rc-component/steps" "~1.2.2" "@rc-component/switch" "~1.0.3" - "@rc-component/table" "~1.10.0" - "@rc-component/tabs" "~1.9.0" + "@rc-component/table" "~1.10.2" + "@rc-component/tabs" "~1.9.1" "@rc-component/tooltip" "~1.4.0" "@rc-component/tour" "~2.4.0" - "@rc-component/tree" "~1.3.1" - "@rc-component/tree-select" "~1.9.0" - "@rc-component/trigger" "^3.9.0" - "@rc-component/upload" "~1.1.0" - "@rc-component/util" "^1.11.0" + "@rc-component/tree" "~1.3.2" + "@rc-component/tree-select" "~1.10.0" + "@rc-component/trigger" "^3.9.1" + "@rc-component/upload" "~1.1.1" + "@rc-component/util" "^1.11.1" clsx "^2.1.1" dayjs "^1.11.11" scroll-into-view-if-needed "^3.1.0" From 55eb5699d532ba4c712ef93b7b25ead971869b6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 01:37:52 -0700 Subject: [PATCH 07/37] chore(deps): bump caniuse-lite from 1.0.30001797 to 1.0.30001799 in /docs (#41225) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/package.json | 2 +- docs/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/package.json b/docs/package.json index 6684462842a..a453627c5d1 100644 --- a/docs/package.json +++ b/docs/package.json @@ -73,7 +73,7 @@ "@swc/core": "^1.15.41", "antd": "^6.4.4", "baseline-browser-mapping": "^2.10.35", - "caniuse-lite": "^1.0.30001797", + "caniuse-lite": "^1.0.30001799", "docusaurus-plugin-openapi-docs": "^5.0.2", "docusaurus-theme-openapi-docs": "^5.0.2", "js-yaml": "^4.2.0", diff --git a/docs/yarn.lock b/docs/yarn.lock index b480bc10143..74f3588dd54 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -5944,10 +5944,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001759, caniuse-lite@^1.0.30001797: - version "1.0.30001797" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001797.tgz#1332709e1439f01ff92085dd17001e0a45897ec0" - integrity sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001759, caniuse-lite@^1.0.30001799: + version "1.0.30001799" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz#5c909138c27f1a61219d3e092071c1cc7d32dc55" + integrity sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw== ccount@^2.0.0: version "2.0.1" From e1be76e5faa8d150e8016df4066babb8a735f3f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 02:28:26 -0700 Subject: [PATCH 08/37] chore(deps): bump baseline-browser-mapping from 2.10.35 to 2.10.36 in /docs (#41227) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/package.json | 2 +- docs/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/package.json b/docs/package.json index a453627c5d1..65b1baabef1 100644 --- a/docs/package.json +++ b/docs/package.json @@ -72,7 +72,7 @@ "@superset-ui/core": "^0.20.4", "@swc/core": "^1.15.41", "antd": "^6.4.4", - "baseline-browser-mapping": "^2.10.35", + "baseline-browser-mapping": "^2.10.36", "caniuse-lite": "^1.0.30001799", "docusaurus-plugin-openapi-docs": "^5.0.2", "docusaurus-theme-openapi-docs": "^5.0.2", diff --git a/docs/yarn.lock b/docs/yarn.lock index 74f3588dd54..edbe58840e9 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -5698,10 +5698,10 @@ base64-js@^1.3.1, base64-js@^1.5.1: resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -baseline-browser-mapping@^2.10.35, baseline-browser-mapping@^2.9.0, baseline-browser-mapping@^2.9.19: - version "2.10.35" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.35.tgz#f0f2232e0de2d2f82cc491bcf830b05ed05937c6" - integrity sha512-honAfLBde0HAFLdNyBEfuuENkF6zR+ozxqxa/2zJKHBe1qzLqyTSeRKpdPEHAP03rlDGyQOPnCSxnVpVqQo9Mg== +baseline-browser-mapping@^2.10.36, baseline-browser-mapping@^2.9.0, baseline-browser-mapping@^2.9.19: + version "2.10.36" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.36.tgz#ff3c7c87095c70075b1ac787160fd4fc98750a74" + integrity sha512-lVq/Df7LXlO79MVaaUHztSwWiG9oXoWHlgvNS51v8Dpd4+G4/VIy6qYePTw31nAVls33nUtnfezYeLkYAak9dg== batch@0.6.1: version "0.6.1" From f545d706479c39c1503e5c5bd0b133fcd4175143 Mon Sep 17 00:00:00 2001 From: Alexandru Soare <37236580+alexandrusoare@users.noreply.github.com> Date: Fri, 19 Jun 2026 16:34:47 +0300 Subject: [PATCH 09/37] feat(listview): Add headerContent prop and HomeOutlined icon (#41244) --- .../src/components/Icons/AntdEnhanced.tsx | 2 + .../src/components/ListView/ListView.tsx | 38 ++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx b/superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx index 2597cdbea64..c5ffd9edf88 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx @@ -86,6 +86,7 @@ import { FundProjectionScreenOutlined, FunctionOutlined, HighlightOutlined, + HomeOutlined, InfoCircleOutlined, InfoCircleFilled, InsertRowAboveOutlined, @@ -243,6 +244,7 @@ const AntdIcons = { GoogleOutlined, GroupOutlined, HighlightOutlined, + HomeOutlined, InfoCircleOutlined, InfoCircleFilled, InsertRowAboveOutlined, diff --git a/superset-frontend/src/components/ListView/ListView.tsx b/superset-frontend/src/components/ListView/ListView.tsx index 75b6e441504..3ba1242b324 100644 --- a/superset-frontend/src/components/ListView/ListView.tsx +++ b/superset-frontend/src/components/ListView/ListView.tsx @@ -316,6 +316,8 @@ export interface ListViewProps { }>; /** Optional expandable row configuration, passed through to antd Table. */ expandable?: Record; + /** Content rendered between the filter bar and the table/card body. */ + headerContent?: ReactNode; } export function ListView({ @@ -344,6 +346,7 @@ export function ListView({ bulkTagResourceName, filtersRef, expandable, + headerContent, addSuccessToast, addDangerToast, }: ListViewProps) { @@ -484,6 +487,7 @@ export function ListView({ )} + {headerContent}
{bulkSelectEnabled && ( ({ .filter( action => !action.hidden?.( - selectedFlatRows.map( - (r: any) => r.original, - ), + selectedFlatRows.map((r: any) => r.original), ), ) .map(action => ( - - ))} + + ))} {enableBulkTag && ( Date: Fri, 19 Jun 2026 17:49:14 +0200 Subject: [PATCH 10/37] feat(dashboard): Edit dashboard description from ui (and api) and show tooltip on dashboard list view (#36071) --- .../src/dashboard/actions/dashboardState.ts | 3 ++ .../src/dashboard/components/Header/index.tsx | 5 ++ .../PropertiesModal/PropertiesModal.test.tsx | 6 +-- .../components/PropertiesModal/index.tsx | 13 ++++- .../sections/BasicInfoSection.test.tsx | 3 +- .../sections/BasicInfoSection.tsx | 12 +++++ superset-frontend/src/dashboard/types.ts | 1 + .../src/pages/ChartList/index.tsx | 1 + .../DashboardList/DashboardList.test.tsx | 2 +- .../src/pages/DashboardList/index.tsx | 48 ++++++++++++++----- superset/dashboards/api.py | 3 ++ superset/dashboards/schemas.py | 10 ++++ tests/integration_tests/base_tests.py | 2 + .../integration_tests/dashboards/api_tests.py | 4 +- 14 files changed, 94 insertions(+), 19 deletions(-) diff --git a/superset-frontend/src/dashboard/actions/dashboardState.ts b/superset-frontend/src/dashboard/actions/dashboardState.ts index dc5a1747ead..7b682a2a1a0 100644 --- a/superset-frontend/src/dashboard/actions/dashboardState.ts +++ b/superset-frontend/src/dashboard/actions/dashboardState.ts @@ -489,6 +489,7 @@ export function saveDashboardRequest( owners, roles, slug, + description, tags, } = data; @@ -521,6 +522,7 @@ export function saveDashboardRequest( hasId(r) ? r.id : r, ), slug: slug || null, + description: description || null, tags: !isFeatureEnabled(FeatureFlag.TaggingSystem) ? undefined : ensureIsArray((tags || []) as JsonObject[]).map((r: JsonObject) => @@ -672,6 +674,7 @@ export function saveDashboardRequest( css: cleanedData.css, dashboard_title: cleanedData.dashboard_title, slug: cleanedData.slug, + description: cleanedData.description, owners: cleanedData.owners, roles: cleanedData.roles, tags: cleanedData.tags || [], diff --git a/superset-frontend/src/dashboard/components/Header/index.tsx b/superset-frontend/src/dashboard/components/Header/index.tsx index 5eced8188e6..6131b5b31ab 100644 --- a/superset-frontend/src/dashboard/components/Header/index.tsx +++ b/superset-frontend/src/dashboard/components/Header/index.tsx @@ -101,6 +101,7 @@ import { RefreshButton } from '../RefreshButton'; type DashboardPropertiesUpdate = { slug?: string; + description?: string; jsonMetadata?: string; certifiedBy?: string; certificationDetails?: string; @@ -122,6 +123,7 @@ type DashboardInfoState = RootState['dashboardInfo'] & { dash_share_perm?: boolean; is_managed_externally?: boolean; slug?: string; + description?: string; last_modified_time?: number; certified_by?: string; certification_details?: string; @@ -442,6 +444,7 @@ const Header = (): JSX.Element => { owners: dashboardInfo.owners, roles: dashboardInfo.roles, slug, + description: dashboardInfo.description, tags: (dashboardInfo.tags || []).filter( item => item.type === TagTypeEnum.Custom || !item.type, ), @@ -497,6 +500,7 @@ const Header = (): JSX.Element => { shouldPersistRefreshFrequency, slug, themeId, + dashboardInfo.description, ]); const { @@ -555,6 +559,7 @@ const Header = (): JSX.Element => { (updates: DashboardPropertiesUpdate) => { boundActionCreators.dashboardInfoChanged({ slug: updates.slug, + description: updates.description, metadata: JSON.parse(updates.jsonMetadata || '{}'), certified_by: updates.certifiedBy, certification_details: updates.certificationDetails, diff --git a/superset-frontend/src/dashboard/components/PropertiesModal/PropertiesModal.test.tsx b/superset-frontend/src/dashboard/components/PropertiesModal/PropertiesModal.test.tsx index fbfd5da51c4..3b313c94535 100644 --- a/superset-frontend/src/dashboard/components/PropertiesModal/PropertiesModal.test.tsx +++ b/superset-frontend/src/dashboard/components/PropertiesModal/PropertiesModal.test.tsx @@ -212,7 +212,7 @@ describe('PropertiesModal', () => { expect(screen.getByRole('button', { name: 'Save' })).toBeInTheDocument(); // Only General information section is expanded by default - expect(screen.getAllByRole('textbox')).toHaveLength(2); // Name and Slug + expect(screen.getAllByRole('textbox')).toHaveLength(3); // Name, Slug and Description // Expand Styling section to see the ColorSchemeControlWrapper const stylingHeaderText = screen.getByText('Styling'); @@ -257,7 +257,7 @@ describe('PropertiesModal', () => { expect(screen.getByText('Certification')).toBeInTheDocument(); // General information section is expanded by default - expect(screen.getAllByRole('textbox')).toHaveLength(2); // Name and Slug are visible + expect(screen.getAllByRole('textbox')).toHaveLength(3); // Name, Slug and Description are visible // Expand Access & ownership to see Tags const accessPanel = screen @@ -302,7 +302,7 @@ describe('PropertiesModal', () => { await screen.findByTestId('dashboard-edit-properties-form'), ).toBeInTheDocument(); - expect(screen.getAllByRole('textbox')).toHaveLength(2); // Only Name and Slug visible initially + expect(screen.getAllByRole('textbox')).toHaveLength(3); // Only Name, Slug and Description visible initially // Click on the Advanced settings collapse panel to expand it const advancedHeaderText = screen.getByText('Advanced settings'); diff --git a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx index fe1fee734df..de7ce91f28e 100644 --- a/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx +++ b/superset-frontend/src/dashboard/components/PropertiesModal/index.tsx @@ -178,10 +178,12 @@ const PropertiesModal = ({ is_managed_externally, theme, css, + description, } = dashboardData; const dashboardInfo = { id, title: dashboard_title, + description: description || '', slug: slug || '', certifiedBy: certified_by || '', certificationDetails: certification_details || '', @@ -309,8 +311,13 @@ const PropertiesModal = ({ }; const onFinish = () => { - const { title, slug, certifiedBy, certificationDetails } = - form.getFieldsValue(); + const { + title, + description = '', + slug, + certifiedBy, + certificationDetails, + } = form.getFieldsValue(); let currentJsonMetadata = jsonMetadata; // validate currentJsonMetadata @@ -389,6 +396,7 @@ const PropertiesModal = ({ const onSubmitProps = { id: dashboardId, title, + description, slug, jsonMetadata: currentJsonMetadata, owners, @@ -416,6 +424,7 @@ const PropertiesModal = ({ } else { const saveData = { dashboard_title: title, + description: description || null, slug: slug || null, json_metadata: currentJsonMetadata || null, owners: (owners || []).map(o => o.id), diff --git a/superset-frontend/src/dashboard/components/PropertiesModal/sections/BasicInfoSection.test.tsx b/superset-frontend/src/dashboard/components/PropertiesModal/sections/BasicInfoSection.test.tsx index df3c8f322dd..78f3ce5d827 100644 --- a/superset-frontend/src/dashboard/components/PropertiesModal/sections/BasicInfoSection.test.tsx +++ b/superset-frontend/src/dashboard/components/PropertiesModal/sections/BasicInfoSection.test.tsx @@ -29,7 +29,7 @@ const defaultProps = { }, }; -test('renders name and slug fields', () => { +test('renders name, description and slug fields', () => { render(
@@ -38,6 +38,7 @@ test('renders name and slug fields', () => { expect(screen.getByTestId('dashboard-name-field')).toBeInTheDocument(); expect(screen.getByTestId('dashboard-slug-field')).toBeInTheDocument(); + expect(screen.getByTestId('dashboard-description-field')).toBeInTheDocument(); expect(screen.getByTestId('dashboard-title-input')).toBeInTheDocument(); }); diff --git a/superset-frontend/src/dashboard/components/PropertiesModal/sections/BasicInfoSection.tsx b/superset-frontend/src/dashboard/components/PropertiesModal/sections/BasicInfoSection.tsx index 1aafc74fb8d..1080f9e0be5 100644 --- a/superset-frontend/src/dashboard/components/PropertiesModal/sections/BasicInfoSection.tsx +++ b/superset-frontend/src/dashboard/components/PropertiesModal/sections/BasicInfoSection.tsx @@ -74,6 +74,18 @@ const BasicInfoSection = ({ /> + + + + + ); }; diff --git a/superset-frontend/src/dashboard/types.ts b/superset-frontend/src/dashboard/types.ts index 2a7056bebab..da2eee81525 100644 --- a/superset-frontend/src/dashboard/types.ts +++ b/superset-frontend/src/dashboard/types.ts @@ -212,6 +212,7 @@ export type DashboardInfo = { } | null; css?: string; slug?: string; + description?: string; last_modified_time: number; certified_by?: string; certification_details?: string; diff --git a/superset-frontend/src/pages/ChartList/index.tsx b/superset-frontend/src/pages/ChartList/index.tsx index 3c5ae28caf1..7b08bfc73e4 100644 --- a/superset-frontend/src/pages/ChartList/index.tsx +++ b/superset-frontend/src/pages/ChartList/index.tsx @@ -95,6 +95,7 @@ const FlexRowContainer = styled.div` text-overflow: ellipsis; white-space: nowrap; line-height: 1.2; + min-width: 0; } svg { diff --git a/superset-frontend/src/pages/DashboardList/DashboardList.test.tsx b/superset-frontend/src/pages/DashboardList/DashboardList.test.tsx index 87c974df801..ebd8fd3e4a7 100644 --- a/superset-frontend/src/pages/DashboardList/DashboardList.test.tsx +++ b/superset-frontend/src/pages/DashboardList/DashboardList.test.tsx @@ -88,7 +88,7 @@ test('fetches data', async () => { const calls = fetchMock.callHistory.calls(/dashboard\/\?q/); expect(calls[0].url).toMatchInlineSnapshot( - `"http://localhost/api/v1/dashboard/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:25,select_columns:!(id,dashboard_title,published,url,slug,changed_by,changed_by.id,changed_by.first_name,changed_by.last_name,changed_on_delta_humanized,owners,owners.id,owners.first_name,owners.last_name,tags.id,tags.name,tags.type,status,certified_by,certification_details,changed_on))"`, + `"http://localhost/api/v1/dashboard/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:25,select_columns:!(id,dashboard_title,published,url,slug,description,changed_by,changed_by.id,changed_by.first_name,changed_by.last_name,changed_on_delta_humanized,owners,owners.id,owners.first_name,owners.last_name,tags.id,tags.name,tags.type,status,certified_by,certification_details,changed_on))"`, ); }); diff --git a/superset-frontend/src/pages/DashboardList/index.tsx b/superset-frontend/src/pages/DashboardList/index.tsx index 13a3e44dd00..b68eaad249c 100644 --- a/superset-frontend/src/pages/DashboardList/index.tsx +++ b/superset-frontend/src/pages/DashboardList/index.tsx @@ -40,6 +40,7 @@ import { ConfirmStatusChange, DeleteModal, FaveStar, + InfoTooltip, Loading, PublishedLabel, Tooltip, @@ -120,12 +121,31 @@ const Actions = styled.div` color: ${({ theme }) => theme.colorIcon}; `; +const FlexRowContainer = styled.div` + align-items: center; + display: flex; + gap: ${({ theme }) => theme.sizeUnit}px; + + a { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + line-height: 1.2; + min-width: 0; + } + + svg { + margin-right: ${({ theme }) => theme.sizeUnit}px; + } +`; + const DASHBOARD_COLUMNS_TO_FETCH = [ 'id', 'dashboard_title', 'published', 'url', 'slug', + 'description', 'changed_by', 'changed_by.id', 'changed_by.first_name', @@ -241,6 +261,7 @@ function DashboardList(props: DashboardListProps) { changed_by: changedBy, dashboard_title: dashboardTitle = '', slug = '', + description = '', json_metadata: jsonMetadata = '', changed_on_delta_humanized: changedOnDeltaHumanized, url = '', @@ -255,6 +276,7 @@ function DashboardList(props: DashboardListProps) { changed_by: changedBy, dashboard_title: dashboardTitle, slug, + description, json_metadata: jsonMetadata, changed_on_delta_humanized: changedOnDeltaHumanized, url, @@ -341,20 +363,24 @@ function DashboardList(props: DashboardListProps) { dashboard_title: dashboardTitle, certified_by: certifiedBy, certification_details: certificationDetails, + description, }, }, }: any) => ( - - {certifiedBy && ( - <> - {' '} - - )} - {dashboardTitle} - + + + {certifiedBy && ( + <> + {' '} + + )} + {dashboardTitle} + + {description && } + ), Header: t('Name'), accessor: 'dashboard_title', diff --git a/superset/dashboards/api.py b/superset/dashboards/api.py index fe3d81820df..b8c437b7416 100644 --- a/superset/dashboards/api.py +++ b/superset/dashboards/api.py @@ -186,6 +186,7 @@ BASE_LIST_COLUMNS = [ "published", "status", "slug", + "description", "url", "certified_by", "certification_details", @@ -351,6 +352,7 @@ class DashboardRestApi(CustomTagsOptimizationMixin, BaseSupersetModelRestApi): "certification_details", "dashboard_title", "slug", + "description", "owners", "roles", "position_json", @@ -371,6 +373,7 @@ class DashboardRestApi(CustomTagsOptimizationMixin, BaseSupersetModelRestApi): "published", "roles", "slug", + "description", "tags", "uuid", ) diff --git a/superset/dashboards/schemas.py b/superset/dashboards/schemas.py index b11fa4cdc58..6f821e7f944 100644 --- a/superset/dashboards/schemas.py +++ b/superset/dashboards/schemas.py @@ -46,6 +46,7 @@ screenshot_query_schema = { }, } dashboard_title_description = "A title for the dashboard." +description_description = "A description for the dashboard." slug_description = "Unique identifying part for the web address of the dashboard." owners_description = ( "Owner are users ids allowed to delete or change this dashboard. " @@ -289,6 +290,7 @@ class DashboardGetResponseSchema(Schema): created_on_humanized = fields.String(data_key="created_on_delta_humanized") is_managed_externally = fields.Boolean(allow_none=True, dump_default=False) uuid = fields.UUID(allow_none=True) + description = fields.String(allow_none=True) # pylint: disable=unused-argument @post_dump() @@ -412,6 +414,10 @@ class DashboardPostSchema(BaseDashboardSchema): allow_none=True, validate=[Length(1, 255)], ) + description = fields.String( + metadata={"description": description_description}, + allow_none=True, + ) owners = fields.List(fields.Integer(metadata={"description": owners_description})) roles = fields.List(fields.Integer(metadata={"description": roles_description})) position_json = fields.String( @@ -466,6 +472,10 @@ class DashboardPutSchema(BaseDashboardSchema): allow_none=True, validate=Length(0, 500), ) + description = fields.String( + metadata={"description": description_description}, + allow_none=True, + ) slug = fields.String( metadata={"description": slug_description}, allow_none=True, diff --git a/tests/integration_tests/base_tests.py b/tests/integration_tests/base_tests.py index 9808dc2d3d2..93827cb8576 100644 --- a/tests/integration_tests/base_tests.py +++ b/tests/integration_tests/base_tests.py @@ -583,6 +583,7 @@ class SupersetTestCase(TestCase): published: bool = False, certified_by: Optional[str] = None, certification_details: Optional[str] = None, + desc: Optional[str] = None, ) -> Dashboard: obj_owners = list() # noqa: C408 obj_roles = list() # noqa: C408 @@ -606,6 +607,7 @@ class SupersetTestCase(TestCase): dashboard = Dashboard( dashboard_title=dashboard_title, slug=slug, + description=desc, owners=obj_owners, roles=obj_roles, position_json=position_json, diff --git a/tests/integration_tests/dashboards/api_tests.py b/tests/integration_tests/dashboards/api_tests.py index 70ef455e6de..83cd2224f33 100644 --- a/tests/integration_tests/dashboards/api_tests.py +++ b/tests/integration_tests/dashboards/api_tests.py @@ -81,6 +81,7 @@ class TestDashboardApi(ApiOwnersTestCaseMixin, InsertChartMixin, SupersetTestCas dashboard_data = { "dashboard_title": "title1_changed", "slug": "slug1_changed", + "description": "desc_changed", "position_json": '{"b": "B"}', "css": "css_changed", "json_metadata": '{"refresh_frequency": 30, "timed_refresh_immune_slices": [], "expanded_slices": {}, "color_scheme": "", "label_colors": {}, "shared_label_colors": [], "map_label_colors": {}, "color_scheme_domain": [], "cross_filters_enabled": false}', # noqa: E501 @@ -538,7 +539,7 @@ class TestDashboardApi(ApiOwnersTestCaseMixin, InsertChartMixin, SupersetTestCas """ admin = self.get_user("admin") dashboard = self.insert_dashboard( - "title", "slug1", [admin.id], created_by=admin + "title", "slug1", [admin.id], created_by=admin, desc="description" ) self.login(ADMIN_USERNAME) uri = f"api/v1/dashboard/{dashboard.id}" @@ -578,6 +579,7 @@ class TestDashboardApi(ApiOwnersTestCaseMixin, InsertChartMixin, SupersetTestCas "thumbnail_url": dashboard.thumbnail_url, "is_managed_externally": False, "theme": None, + "description": "description", } data = json.loads(rv.data.decode("utf-8")) assert "changed_on" in data["result"] From 9d3efb0aabfbffeae7e71709669bdaf3667e30ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Furkan=20Emre=20G=C3=BCng=C3=B6r?= <71993947+Bungic@users.noreply.github.com> Date: Fri, 19 Jun 2026 18:49:27 +0300 Subject: [PATCH 11/37] fix(csv): apply CSV_EXPORT encoding explicitly, Werkzeug 3 removed Response.charset (#40801) --- superset/views/base.py | 13 ++++++++++-- tests/unit_tests/views/test_base.py | 32 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/superset/views/base.py b/superset/views/base.py index 3220344013d..bb8cdf6ac84 100644 --- a/superset/views/base.py +++ b/superset/views/base.py @@ -730,12 +730,21 @@ class DatasourceFilter(BaseFilter): # pylint: disable=too-few-public-methods class CsvResponse(Response): """ - Override Response to take into account csv encoding from config.py + Response that encodes its body with the configured CSV_EXPORT encoding. + + Werkzeug 3.0 removed ``Response.charset``, which this class relied on, + so the configured encoding (e.g. the default "utf-8-sig") was silently + ignored and bodies were always plain utf-8. """ - charset = app.config["CSV_EXPORT"].get("encoding", "utf-8") default_mimetype = "text/csv" + def __init__(self, response: Any = None, *args: Any, **kwargs: Any) -> None: + if isinstance(response, str): + encoding = app.config["CSV_EXPORT"].get("encoding", "utf-8") + response = response.encode(encoding) + super().__init__(response, *args, **kwargs) + class XlsxResponse(Response): """ diff --git a/tests/unit_tests/views/test_base.py b/tests/unit_tests/views/test_base.py index ed47188db73..87b45eed90e 100644 --- a/tests/unit_tests/views/test_base.py +++ b/tests/unit_tests/views/test_base.py @@ -177,3 +177,35 @@ def test_api_query_returns_json_content_type() -> None: assert response.mimetype == "application/json" assert response.content_type.startswith("application/json") + + +@pytest.mark.parametrize( + "encoding, payload, expected", + [ + ("utf-8-sig", "Ürün,Şehir\n", "Ürün,Şehir\n".encode("utf-8-sig")), + ("utf-8", "Ürün,Şehir\n", "Ürün,Şehir\n".encode()), + ], +) +def test_csv_response_applies_csv_export_encoding( + encoding: str, payload: str, expected: bytes +) -> None: + """str bodies are encoded with CSV_EXPORT["encoding"].""" + from flask import current_app + + from superset.views.base import CsvResponse + + original = current_app.config["CSV_EXPORT"] + try: + current_app.config["CSV_EXPORT"] = {"encoding": encoding} + response = CsvResponse(payload) + assert response.get_data() == expected + assert response.mimetype == "text/csv" + finally: + current_app.config["CSV_EXPORT"] = original + + +def test_csv_response_leaves_bytes_untouched() -> None: + from superset.views.base import CsvResponse + + payload = "Ürün\n".encode("utf-8-sig") + assert CsvResponse(payload).get_data() == payload From e18cd1f50c03af441783b157e917d20df89d3629 Mon Sep 17 00:00:00 2001 From: Artem Lytkin <146867384+4RH1T3CT0R7@users.noreply.github.com> Date: Fri, 19 Jun 2026 18:49:40 +0300 Subject: [PATCH 12/37] fix(table): preserve percentage format for small numbers when d3SmallNumberFormat is unset (#37980) Co-authored-by: Superset Dev Co-authored-by: Claude Fable 5 --- .../superset-ui-chart-controls/src/types.ts | 4 +- .../src/currency-format/CurrencyFormatter.ts | 6 +- .../number-format/getSmallNumberFormatter.ts | 54 +++++++++++ .../src/number-format/index.ts | 1 + .../getSmallNumberFormatter.test.ts | 82 +++++++++++++++++ .../src/utils/formatValue.ts | 17 ++-- .../src/utils/formatValue.ts | 16 ++-- .../test/utils/formatValue.test.ts | 90 +++++++++++++++++++ 8 files changed, 247 insertions(+), 23 deletions(-) create mode 100644 superset-frontend/packages/superset-ui-core/src/number-format/getSmallNumberFormatter.ts create mode 100644 superset-frontend/packages/superset-ui-core/test/number-format/getSmallNumberFormatter.test.ts diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index 4e24d9debb5..aed80f3d357 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -677,7 +677,9 @@ export interface ServerPaginationData { export type TableColumnConfig = { d3NumberFormat?: string; - d3SmallNumberFormat?: string; + // Allow null to match JSON round-trips, where an unset value deserializes + // from the metadata DB as `null` rather than `undefined`. + d3SmallNumberFormat?: string | null; d3TimeFormat?: string; columnWidth?: number; horizontalAlign?: 'left' | 'right' | 'center'; diff --git a/superset-frontend/packages/superset-ui-core/src/currency-format/CurrencyFormatter.ts b/superset-frontend/packages/superset-ui-core/src/currency-format/CurrencyFormatter.ts index a7997879c59..28acc5a950e 100644 --- a/superset-frontend/packages/superset-ui-core/src/currency-format/CurrencyFormatter.ts +++ b/superset-frontend/packages/superset-ui-core/src/currency-format/CurrencyFormatter.ts @@ -18,7 +18,11 @@ */ import { ExtensibleFunction } from '../models'; -import { getNumberFormatter, NumberFormats } from '../number-format'; +// Import from the concrete modules rather than the `number-format` barrel to +// avoid a circular dependency (the barrel pulls in getSmallNumberFormatter, +// which imports CurrencyFormatter). +import { getNumberFormatter } from '../number-format/NumberFormatterRegistrySingleton'; +import NumberFormats from '../number-format/NumberFormats'; import { Currency } from '../query'; import { RowData, RowDataValue } from './types'; import { AUTO_CURRENCY_SYMBOL, ISO_4217_REGEX } from './CurrencyFormats'; diff --git a/superset-frontend/packages/superset-ui-core/src/number-format/getSmallNumberFormatter.ts b/superset-frontend/packages/superset-ui-core/src/number-format/getSmallNumberFormatter.ts new file mode 100644 index 00000000000..9eb100f769e --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/src/number-format/getSmallNumberFormatter.ts @@ -0,0 +1,54 @@ +/* + * 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 { CurrencyFormatter } from '../currency-format'; +import { Currency } from '../query'; +import NumberFormatter from './NumberFormatter'; +import { getNumberFormatter } from './NumberFormatterRegistrySingleton'; + +/** + * Returns the appropriate formatter for small numbers (|value| < 1). + * + * When `d3SmallNumberFormat` is nullish or blank the caller's default + * formatter is returned unchanged, which preserves percentage formats + * that would otherwise be lost. + * + * Handles the cases where `d3SmallNumberFormat` is `null` (from JSON + * serialization of `undefined`) or `""` (from a cleared Select control). + * + * The generic parameter `F` allows callers to pass any formatter type + * (e.g. TimeFormatter, CustomFormatter) without a circular dependency + * on @superset-ui/chart-controls. + */ +export default function getSmallNumberFormatter( + defaultFormatter: F, + d3SmallNumberFormat: string | null | undefined, + currencyFormat?: Currency, +): F | NumberFormatter | CurrencyFormatter { + if (d3SmallNumberFormat == null || d3SmallNumberFormat.trim() === '') { + return defaultFormatter; + } + if (currencyFormat) { + return new CurrencyFormatter({ + d3Format: d3SmallNumberFormat, + currency: currencyFormat, + }); + } + return getNumberFormatter(d3SmallNumberFormat); +} diff --git a/superset-frontend/packages/superset-ui-core/src/number-format/index.ts b/superset-frontend/packages/superset-ui-core/src/number-format/index.ts index b9835d332d0..95ac8cd8789 100644 --- a/superset-frontend/packages/superset-ui-core/src/number-format/index.ts +++ b/superset-frontend/packages/superset-ui-core/src/number-format/index.ts @@ -34,3 +34,4 @@ export { default as createDurationFormatter } from './factories/createDurationFo export { default as createMemoryFormatter } from './factories/createMemoryFormatter'; export { default as createSiAtMostNDigitFormatter } from './factories/createSiAtMostNDigitFormatter'; export { default as createSmartNumberFormatter } from './factories/createSmartNumberFormatter'; +export { default as getSmallNumberFormatter } from './getSmallNumberFormatter'; diff --git a/superset-frontend/packages/superset-ui-core/test/number-format/getSmallNumberFormatter.test.ts b/superset-frontend/packages/superset-ui-core/test/number-format/getSmallNumberFormatter.test.ts new file mode 100644 index 00000000000..71ab12e8913 --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/test/number-format/getSmallNumberFormatter.test.ts @@ -0,0 +1,82 @@ +/* + * 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 { + CurrencyFormatter, + getNumberFormatter, + getSmallNumberFormatter, + NumberFormatter, +} from '@superset-ui/core'; + +const defaultFormatter = getNumberFormatter('.8%'); + +describe('getSmallNumberFormatter', () => { + test('returns defaultFormatter when d3SmallNumberFormat is undefined', () => { + expect(getSmallNumberFormatter(defaultFormatter, undefined)).toBe( + defaultFormatter, + ); + }); + + test('returns defaultFormatter when d3SmallNumberFormat is null (JSON round-trip)', () => { + expect(getSmallNumberFormatter(defaultFormatter, null)).toBe( + defaultFormatter, + ); + }); + + test('returns defaultFormatter when d3SmallNumberFormat is empty string (cleared Select)', () => { + expect(getSmallNumberFormatter(defaultFormatter, '')).toBe( + defaultFormatter, + ); + }); + + test('returns defaultFormatter when d3SmallNumberFormat is whitespace', () => { + expect(getSmallNumberFormatter(defaultFormatter, ' ')).toBe( + defaultFormatter, + ); + }); + + test('returns a NumberFormatter when d3SmallNumberFormat is a valid format', () => { + const result = getSmallNumberFormatter(defaultFormatter, ',.4f'); + expect(result).toBeInstanceOf(NumberFormatter); + expect(result).not.toBe(defaultFormatter); + expect(result!(0.12345)).toBe('0.1235'); + }); + + test('returns a CurrencyFormatter when currencyFormat is provided', () => { + const result = getSmallNumberFormatter(defaultFormatter, ',.4f', { + symbol: 'USD', + symbolPosition: 'prefix', + }); + expect(result).toBeInstanceOf(CurrencyFormatter); + expect(result!(0.12345)).toContain('0.1235'); + expect(result!(0.12345)).toContain('$'); + }); + + test('preserves percentage formatter output for small numbers when d3SmallNumberFormat is null', () => { + const pctFormatter = getNumberFormatter('.8%'); + const result = getSmallNumberFormatter(pctFormatter, null); + expect(result!(-0.00001229)).toBe('-0.00122900%'); + }); + + test('returns undefined when defaultFormatter is undefined and d3SmallNumberFormat is nullish', () => { + expect(getSmallNumberFormatter(undefined, null)).toBeUndefined(); + expect(getSmallNumberFormatter(undefined, undefined)).toBeUndefined(); + expect(getSmallNumberFormatter(undefined, '')).toBeUndefined(); + }); +}); diff --git a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/formatValue.ts b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/formatValue.ts index 2e2b76853c5..38585550c45 100644 --- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/formatValue.ts +++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/formatValue.ts @@ -17,9 +17,8 @@ * under the License. */ import { - CurrencyFormatter, DataRecordValue, - getNumberFormatter, + getSmallNumberFormatter, isDefined, isProbablyHTML, sanitizeHtml, @@ -67,15 +66,11 @@ export function formatColumnValue( ) { const { dataType, formatter, config = {} } = column; const isNumber = dataType === GenericDataType.Numeric; - const smallNumberFormatter = - config.d3SmallNumberFormat === undefined - ? formatter - : config.currencyFormat - ? new CurrencyFormatter({ - d3Format: config.d3SmallNumberFormat, - currency: config.currencyFormat, - }) - : getNumberFormatter(config.d3SmallNumberFormat); + const smallNumberFormatter = getSmallNumberFormatter( + formatter, + config.d3SmallNumberFormat, + config.currencyFormat, + ); return formatValue( isNumber && typeof value === 'number' && Math.abs(value) < 1 ? smallNumberFormatter diff --git a/superset-frontend/plugins/plugin-chart-table/src/utils/formatValue.ts b/superset-frontend/plugins/plugin-chart-table/src/utils/formatValue.ts index f15347f1f0d..e5799f621ab 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/utils/formatValue.ts +++ b/superset-frontend/plugins/plugin-chart-table/src/utils/formatValue.ts @@ -19,7 +19,7 @@ import { CurrencyFormatter, DataRecordValue, - getNumberFormatter, + getSmallNumberFormatter, isProbablyHTML, sanitizeHtml, } from '@superset-ui/core'; @@ -69,15 +69,11 @@ export function formatColumnValue( ) { const { dataType, formatter, config = {}, currencyCodeColumn } = column; const isNumber = dataType === GenericDataType.Numeric; - const smallNumberFormatter = - config.d3SmallNumberFormat === undefined - ? formatter - : config.currencyFormat - ? new CurrencyFormatter({ - d3Format: config.d3SmallNumberFormat, - currency: config.currencyFormat, - }) - : getNumberFormatter(config.d3SmallNumberFormat); + const smallNumberFormatter = getSmallNumberFormatter( + formatter, + config.d3SmallNumberFormat, + config.currencyFormat, + ); return formatValue( isNumber && typeof value === 'number' && Math.abs(value) < 1 ? smallNumberFormatter diff --git a/superset-frontend/plugins/plugin-chart-table/test/utils/formatValue.test.ts b/superset-frontend/plugins/plugin-chart-table/test/utils/formatValue.test.ts index d8a2b8d2a4a..1aaa4278e55 100644 --- a/superset-frontend/plugins/plugin-chart-table/test/utils/formatValue.test.ts +++ b/superset-frontend/plugins/plugin-chart-table/test/utils/formatValue.test.ts @@ -130,6 +130,96 @@ test('formatColumnValue handles null values', () => { expect(nullResult).toBe('N/A'); }); +test('formatColumnValue preserves percentage format for small numbers when d3SmallNumberFormat is null', () => { + const formatter = getNumberFormatter('.8%'); + const column: DataColumnMeta = { + key: 'pct', + label: 'Percentage', + dataType: GenericDataType.Numeric, + formatter, + isNumeric: true, + config: { d3SmallNumberFormat: null }, + }; + + const [, result] = formatColumnValue(column, -0.00001229); + expect(result).toBe('-0.00122900%'); +}); + +test('formatColumnValue preserves percentage format for small numbers when d3SmallNumberFormat is empty string', () => { + const formatter = getNumberFormatter('.8%'); + const column: DataColumnMeta = { + key: 'pct', + label: 'Percentage', + dataType: GenericDataType.Numeric, + formatter, + isNumeric: true, + config: { d3SmallNumberFormat: '' }, + }; + + const [, result] = formatColumnValue(column, -0.00001229); + expect(result).toBe('-0.00122900%'); +}); + +test('formatColumnValue preserves percentage format for small numbers when config has no d3SmallNumberFormat', () => { + const formatter = getNumberFormatter('.8%'); + const column: DataColumnMeta = { + key: 'pct', + label: 'Percentage', + dataType: GenericDataType.Numeric, + formatter, + isNumeric: true, + config: {}, + }; + + const [, result] = formatColumnValue(column, -0.00001229); + expect(result).toBe('-0.00122900%'); +}); + +test('formatColumnValue uses default formatter for value exactly 1 (boundary)', () => { + const formatter = getNumberFormatter(',.2f'); + const column: DataColumnMeta = { + key: 'val', + label: 'Value', + dataType: GenericDataType.Numeric, + formatter, + isNumeric: true, + config: { d3SmallNumberFormat: null }, + }; + + const [, result] = formatColumnValue(column, 1); + expect(result).toBe('1.00'); +}); + +test('formatColumnValue uses default formatter for value exactly -1 (boundary)', () => { + const formatter = getNumberFormatter(',.2f'); + const column: DataColumnMeta = { + key: 'val', + label: 'Value', + dataType: GenericDataType.Numeric, + formatter, + isNumeric: true, + config: { d3SmallNumberFormat: null }, + }; + + const [, result] = formatColumnValue(column, -1); + expect(result).toBe('-1.00'); +}); + +test('formatColumnValue uses small number formatter for value 0', () => { + const formatter = getNumberFormatter('.8%'); + const column: DataColumnMeta = { + key: 'pct', + label: 'Percentage', + dataType: GenericDataType.Numeric, + formatter, + isNumeric: true, + config: { d3SmallNumberFormat: null }, + }; + + const [, result] = formatColumnValue(column, 0); + expect(result).toBe('0.00000000%'); +}); + test('formatColumnValue with small number format and currency', () => { const formatter = new CurrencyFormatter({ d3Format: ',.2f', From 146700642754e65fbc96cabd7b6277c4819d1ec3 Mon Sep 17 00:00:00 2001 From: Amin Ghadersohi Date: Fri, 19 Jun 2026 09:50:11 -0600 Subject: [PATCH 13/37] fix(mcp): generate durable explore permalink URL instead of ephemeral form_data_key (#40773) --- superset/mcp_service/chart/chart_utils.py | 56 +++- .../mcp_service/chart/tool/generate_chart.py | 4 +- .../chart/tool/update_chart_preview.py | 7 +- .../explore/tool/generate_explore_link.py | 26 +- superset/mcp_service/utils/url_utils.py | 16 + .../mcp_service/chart/test_chart_utils.py | 48 ++- .../tool/test_generate_explore_link.py | 306 +++++++++--------- .../unit_tests/mcp_service/test_url_utils.py | 46 +++ 8 files changed, 338 insertions(+), 171 deletions(-) create mode 100644 tests/unit_tests/mcp_service/test_url_utils.py diff --git a/superset/mcp_service/chart/chart_utils.py b/superset/mcp_service/chart/chart_utils.py index 0d531cd2cec..7f67c642b55 100644 --- a/superset/mcp_service/chart/chart_utils.py +++ b/superset/mcp_service/chart/chart_utils.py @@ -157,14 +157,31 @@ def validate_chart_dataset( ) -def generate_explore_link(dataset_id: int | str, form_data: Dict[str, Any]) -> str: - """Generate an explore link for the given dataset and form data.""" +def generate_explore_link( + dataset_id: int | str, + form_data: Dict[str, Any], + prefer_permalink: bool = True, +) -> str: + """Generate an explore link for the given dataset and form data. + + Prefers a durable explore permalink (DB-backed key-value store, does not + expire) over an ephemeral form_data_key (Redis cache, expires in ~24h). + Falls back to the form_data_key approach if permalink creation fails, then + to a plain dataset URL as a last resort. + + Set ``prefer_permalink=False`` for callers that depend on a ``form_data_key`` + in the returned URL (e.g. preview flows that extract and re-cache the key); + this skips the permalink path and returns an ``/explore/?form_data_key=...`` + URL directly. + """ from sqlalchemy.exc import SQLAlchemyError from superset.commands.exceptions import CommandException from superset.commands.explore.form_data.parameters import CommandParameters + from superset.commands.explore.permalink.create import CreateExplorePermalinkCommand from superset.daos.dataset import DatasetDAO from superset.exceptions import SupersetException + from superset.explore.permalink.exceptions import ExplorePermalinkCreateFailedError from superset.mcp_service.commands.create_form_data import ( MCPCreateFormDataCommand, ) @@ -200,7 +217,27 @@ def generate_explore_link(dataset_id: int | str, form_data: Dict[str, Any]) -> s "datasource": f"{numeric_dataset_id}__table", } - # Try to create form_data in cache using MCP-specific CreateFormDataCommand + # Try durable permalink first (DB-backed key-value store, does not expire). + # CreateExplorePermalinkCommand wraps its internal failures (encode/create/ + # SQLAlchemy errors) into ExplorePermalinkCreateFailedError, so catch only + # those expected modes here — letting programming errors (TypeError, etc.) + # surface instead of being silently masked by the form_data_key fallback. + # Callers that need a form_data_key URL opt out via prefer_permalink=False. + if prefer_permalink: + try: + state = {"formData": form_data_with_datasource} + permalink_key = CreateExplorePermalinkCommand(state=state).run() + return f"{base_url}/explore/p/{permalink_key}/" + except ( + ExplorePermalinkCreateFailedError, + SQLAlchemyError, + ) as permalink_e: + logger.debug( + "Permalink generation failed, falling back to form_data_key: %s", + permalink_e, + ) + + # Fall back to ephemeral form_data_key (Redis-backed cache) cmd_params = CommandParameters( datasource_type=DatasourceType.TABLE, datasource_id=numeric_dataset_id, @@ -208,23 +245,18 @@ def generate_explore_link(dataset_id: int | str, form_data: Dict[str, Any]) -> s tab_id=None, form_data=json.dumps(form_data_with_datasource), ) - - # Create the form_data cache entry and get the key form_data_key = MCPCreateFormDataCommand(cmd_params).run() - - # Return URL with just the form_data_key return f"{base_url}/explore/?form_data_key={form_data_key}" except ( CommandException, SupersetException, SQLAlchemyError, - KeyError, - ValueError, - AttributeError, - TypeError, ) as e: - # Fallback to basic explore URL with numeric ID if available + # Fallback to basic explore URL with numeric ID if available. Only the + # expected failure modes of dataset lookup / form_data creation are caught + # here; programming errors propagate to the tool handler so they aren't + # silently masked behind a fallback URL. logger.debug("Explore link generation fallback due to: %s", e) if numeric_dataset_id is not None: return ( diff --git a/superset/mcp_service/chart/tool/generate_chart.py b/superset/mcp_service/chart/tool/generate_chart.py index e830329e7ec..b237dc24ad5 100644 --- a/superset/mcp_service/chart/tool/generate_chart.py +++ b/superset/mcp_service/chart/tool/generate_chart.py @@ -527,7 +527,9 @@ async def generate_chart( # noqa: C901 # Generate explore link with cached form_data for preview-only mode from superset.mcp_service.chart.chart_utils import generate_explore_link - explore_url = generate_explore_link(request.dataset_id, form_data) + explore_url = generate_explore_link( + request.dataset_id, form_data, prefer_permalink=False + ) await ctx.debug("Generated explore link: explore_url=%s" % (explore_url,)) # Extract form_data_key from the explore URL diff --git a/superset/mcp_service/chart/tool/update_chart_preview.py b/superset/mcp_service/chart/tool/update_chart_preview.py index 4fc9a26c955..7425bfb86aa 100644 --- a/superset/mcp_service/chart/tool/update_chart_preview.py +++ b/superset/mcp_service/chart/tool/update_chart_preview.py @@ -240,8 +240,11 @@ def update_chart_preview( # noqa: C901 "api_version": "v1", } - # Generate new explore link with updated form_data - explore_url = generate_explore_link(request.dataset_id, new_form_data) + # Generate new explore link with updated form_data. This preview flow + # extracts and re-caches the form_data_key, so force that URL shape. + explore_url = generate_explore_link( + request.dataset_id, new_form_data, prefer_permalink=False + ) # Extract new form_data_key from the explore URL new_form_data_key = extract_form_data_key_from_url(explore_url) diff --git a/superset/mcp_service/explore/tool/generate_explore_link.py b/superset/mcp_service/explore/tool/generate_explore_link.py index 68ed36c037a..0e26c408dd0 100644 --- a/superset/mcp_service/explore/tool/generate_explore_link.py +++ b/superset/mcp_service/explore/tool/generate_explore_link.py @@ -30,7 +30,9 @@ from superset_core.mcp.decorators import tool, ToolAnnotations from superset.extensions import event_logger from superset.mcp_service.auth import has_dataset_access -from superset.mcp_service.chart.chart_helpers import extract_form_data_key_from_url +from superset.mcp_service.chart.chart_helpers import ( + extract_form_data_key_from_url, +) from superset.mcp_service.chart.chart_utils import ( generate_explore_link as generate_url, get_table_chart_type_label, @@ -40,6 +42,9 @@ from superset.mcp_service.chart.compile import validate_and_compile from superset.mcp_service.chart.schemas import ( GenerateExploreLinkRequest, ) +from superset.mcp_service.utils.url_utils import ( + extract_permalink_key_from_url, +) logger = logging.getLogger(__name__) @@ -135,6 +140,7 @@ async def generate_explore_link( return { "url": "", "form_data": {}, + "permalink_key": None, "form_data_key": None, "chart_type_label": None, "error": ( @@ -154,6 +160,7 @@ async def generate_explore_link( return { "url": "", "form_data": {}, + "permalink_key": None, "form_data_key": None, "chart_type_label": None, "error": ( @@ -178,6 +185,7 @@ async def generate_explore_link( return { "url": default_url, "form_data": {}, + "permalink_key": None, "form_data_key": None, "chart_type_label": None, "error": None, @@ -209,7 +217,7 @@ async def generate_explore_link( # Add datasource to form_data for consistency with generate_chart # Only set if not already present to avoid overwriting if "datasource" not in form_data: - form_data["datasource"] = f"{request.dataset_id}__table" + form_data["datasource"] = f"{dataset.id}__table" await ctx.debug( "Form data generated with keys: %s, has_viz_type=%s, has_datasource=%s" @@ -248,6 +256,7 @@ async def generate_explore_link( return { "url": "", "form_data": form_data, + "permalink_key": None, "form_data_key": None, "chart_type_label": None, "error": error_payload, @@ -262,19 +271,23 @@ async def generate_explore_link( dataset_id=request.dataset_id, form_data=form_data ) - # Extract form_data_key from the explore URL - form_data_key = extract_form_data_key_from_url(explore_url) + # Extract permalink_key (durable) or fall back to form_data_key (ephemeral) + permalink_key = extract_permalink_key_from_url(explore_url) + form_data_key = ( + extract_form_data_key_from_url(explore_url) if not permalink_key else None + ) await ctx.report_progress(4, 4, "URL generation complete") await ctx.info( "Explore link generated successfully: url_length=%s, dataset_id=%s, " - "form_data_key=%s" - % (len(explore_url or ""), request.dataset_id, form_data_key) + "permalink_key=%s, form_data_key=%s" + % (len(explore_url or ""), request.dataset_id, permalink_key, form_data_key) ) return { "url": explore_url, "form_data": form_data, + "permalink_key": permalink_key, "form_data_key": form_data_key, "chart_type_label": get_table_chart_type_label(form_data.get("viz_type")), "error": None, @@ -293,6 +306,7 @@ async def generate_explore_link( return { "url": "", "form_data": {}, + "permalink_key": None, "form_data_key": None, "chart_type_label": None, "error": f"Failed to generate explore link: {str(e)}", diff --git a/superset/mcp_service/utils/url_utils.py b/superset/mcp_service/utils/url_utils.py index 55108c7387c..5ee00aa528e 100644 --- a/superset/mcp_service/utils/url_utils.py +++ b/superset/mcp_service/utils/url_utils.py @@ -57,6 +57,22 @@ def get_superset_base_url() -> str: return default_url +def extract_permalink_key_from_url(url: str | None) -> str | None: + """Extract the permalink key from an explore permalink URL. + + Matches the /explore/p// pattern produced by + CreateExplorePermalinkCommand. Returns the key, or None if the URL + does not follow that pattern. + """ + if not url: + return None + path = urlparse(url).path + parts = [p for p in path.split("/") if p] + if len(parts) >= 3 and parts[-3] == "explore" and parts[-2] == "p": + return parts[-1] + return None + + def get_mcp_service_url() -> str: """ Get the MCP service base URL where screenshot endpoints are served. diff --git a/tests/unit_tests/mcp_service/chart/test_chart_utils.py b/tests/unit_tests/mcp_service/chart/test_chart_utils.py index 4e7e3feb0f7..c38d7050f73 100644 --- a/tests/unit_tests/mcp_service/chart/test_chart_utils.py +++ b/tests/unit_tests/mcp_service/chart/test_chart_utils.py @@ -1176,13 +1176,25 @@ class TestGenerateExploreLink: self, mock_command, mock_get_base_url ) -> None: """Test generate_explore_link creates form_data_key when dataset exists""" + from superset.explore.permalink.exceptions import ( + ExplorePermalinkCreateFailedError, + ) + mock_get_base_url.return_value = "http://localhost:9001" mock_command.return_value.run.return_value = "test_form_data_key" - # Mock dataset exists + # Mock dataset exists; force the durable-permalink path to fail so the + # function falls back to the ephemeral form_data_key. mock_dataset = type("Dataset", (), {"id": 123})() - with patch( - "superset.daos.dataset.DatasetDAO.find_by_id", return_value=mock_dataset + with ( + patch( + "superset.daos.dataset.DatasetDAO.find_by_id", return_value=mock_dataset + ), + patch( + "superset.commands.explore.permalink.create." + "CreateExplorePermalinkCommand.run", + side_effect=ExplorePermalinkCreateFailedError("permalink unavailable"), + ), ): result = generate_explore_link(123, {"viz_type": "table"}) @@ -1191,6 +1203,36 @@ class TestGenerateExploreLink: ) mock_command.assert_called_once() + @patch("superset.mcp_service.chart.chart_utils.get_superset_base_url") + @patch("superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand") + def test_generate_explore_link_prefer_permalink_false( + self, mock_command, mock_get_base_url + ) -> None: + """prefer_permalink=False skips the permalink path and returns a + form_data_key URL, so preview callers that re-parse the key keep working.""" + mock_get_base_url.return_value = "http://localhost:9001" + mock_command.return_value.run.return_value = "test_form_data_key" + + mock_dataset = type("Dataset", (), {"id": 123})() + with ( + patch( + "superset.daos.dataset.DatasetDAO.find_by_id", return_value=mock_dataset + ), + patch( + "superset.commands.explore.permalink.create." + "CreateExplorePermalinkCommand.run" + ) as mock_permalink, + ): + result = generate_explore_link( + 123, {"viz_type": "table"}, prefer_permalink=False + ) + + assert ( + result == "http://localhost:9001/explore/?form_data_key=test_form_data_key" + ) + mock_command.assert_called_once() + mock_permalink.assert_not_called() + @patch("superset.mcp_service.chart.chart_utils.get_superset_base_url") def test_generate_explore_link_exception_handling(self, mock_get_base_url) -> None: """Test generate_explore_link handles SQLAlchemy exceptions gracefully""" diff --git a/tests/unit_tests/mcp_service/explore/tool/test_generate_explore_link.py b/tests/unit_tests/mcp_service/explore/tool/test_generate_explore_link.py index a4dc86f86a3..6329a969e10 100644 --- a/tests/unit_tests/mcp_service/explore/tool/test_generate_explore_link.py +++ b/tests/unit_tests/mcp_service/explore/tool/test_generate_explore_link.py @@ -49,6 +49,13 @@ generate_explore_link_module = importlib.import_module( logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) +_PERMALINK_PATCH = ( + "superset.commands.explore.permalink.create.CreateExplorePermalinkCommand.run" +) +_FORM_DATA_PATCH = ( + "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" +) + @pytest.fixture def mcp_server(): @@ -100,6 +107,17 @@ def mock_webdriver_baseurl(app_context): current_app.config["WEBDRIVER_BASEURL_USER_FRIENDLY"] = original_value +@pytest.fixture(autouse=True) +def mock_permalink_creation(): + """Create durable permalink by default. + + Override in individual tests that need fallback-to-form_data_key or + fallback-to-basic-URL behaviour by patching _PERMALINK_PATCH to raise. + """ + with patch(_PERMALINK_PATCH, return_value="test_permalink_key"): + yield + + def _mock_dataset(id: int = 1) -> Mock: """Create a mock dataset object with columns and db_engine_spec.""" from superset.utils.core import ColumnSpec, GenericDataType @@ -132,15 +150,11 @@ class TestGenerateExploreLink: """Comprehensive tests for generate_explore_link MCP tool.""" @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_table_explore_link_minimal( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): """Test generating explore link for minimal table chart.""" - mock_create_form_data.return_value = "test_form_data_key_123" mock_find_dataset.return_value = _mock_dataset(id=1) config = TableChartConfig( @@ -156,21 +170,18 @@ class TestGenerateExploreLink: assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=test_form_data_key_123" + == "http://localhost:9001/explore/p/test_permalink_key/" ) + assert result.data["permalink_key"] == "test_permalink_key" + assert result.data["form_data_key"] is None assert result.data["chart_type_label"] == "table chart" - mock_create_form_data.assert_called_once() @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_table_explore_link_with_features( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): """Test generating explore link for table chart with features.""" - mock_create_form_data.return_value = "comprehensive_key_456" mock_find_dataset.return_value = _mock_dataset(id=5) config = TableChartConfig( @@ -196,21 +207,18 @@ class TestGenerateExploreLink: assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=comprehensive_key_456" + == "http://localhost:9001/explore/p/test_permalink_key/" ) + assert result.data["permalink_key"] == "test_permalink_key" + assert result.data["form_data_key"] is None assert result.data["chart_type_label"] == "table chart" - mock_create_form_data.assert_called_once() @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_ag_grid_table_explore_link_label( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ) -> None: """Test generating explore link reports AG Grid table label.""" - mock_create_form_data.return_value = "ag_grid_key_123" mock_find_dataset.return_value = _mock_dataset(id=1) config = TableChartConfig( @@ -229,15 +237,11 @@ class TestGenerateExploreLink: assert result.data["chart_type_label"] == "interactive table chart" @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_line_chart_explore_link( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): """Test generating explore link for line chart.""" - mock_create_form_data.return_value = "line_chart_key_789" mock_find_dataset.return_value = _mock_dataset(id=3) config = XYChartConfig( @@ -263,21 +267,14 @@ class TestGenerateExploreLink: assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=line_chart_key_789" + == "http://localhost:9001/explore/p/test_permalink_key/" ) assert result.data["chart_type_label"] is None - mock_create_form_data.assert_called_once() @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio - async def test_generate_bar_chart_explore_link( - self, mock_create_form_data, mock_find_dataset, mcp_server - ): + async def test_generate_bar_chart_explore_link(self, mock_find_dataset, mcp_server): """Test generating explore link for bar chart.""" - mock_create_form_data.return_value = "bar_chart_key_abc" mock_find_dataset.return_value = _mock_dataset(id=7) config = XYChartConfig( @@ -298,20 +295,15 @@ class TestGenerateExploreLink: assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=bar_chart_key_abc" + == "http://localhost:9001/explore/p/test_permalink_key/" ) - mock_create_form_data.assert_called_once() @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_area_chart_explore_link( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): """Test generating explore link for area chart.""" - mock_create_form_data.return_value = "area_chart_key_def" mock_find_dataset.return_value = _mock_dataset(id=2) config = XYChartConfig( @@ -335,20 +327,15 @@ class TestGenerateExploreLink: assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=area_chart_key_def" + == "http://localhost:9001/explore/p/test_permalink_key/" ) - mock_create_form_data.assert_called_once() @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_scatter_chart_explore_link( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): """Test generating explore link for scatter chart.""" - mock_create_form_data.return_value = "scatter_chart_key_ghi" mock_find_dataset.return_value = _mock_dataset(id=4) config = XYChartConfig( @@ -370,22 +357,71 @@ class TestGenerateExploreLink: assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=scatter_chart_key_ghi" + == "http://localhost:9001/explore/p/test_permalink_key/" ) + + @patch(_PERMALINK_PATCH) + @patch("superset.daos.dataset.DatasetDAO.find_by_id") + @patch(_FORM_DATA_PATCH) + @pytest.mark.asyncio + async def test_generate_explore_link_permalink_fails_fallback_to_form_data_key( + self, + mock_create_form_data, + mock_find_dataset, + mock_create_permalink, + mcp_server, + ): + """When permalink creation fails, fall back to ephemeral form_data_key URL.""" + from superset.explore.permalink.exceptions import ( + ExplorePermalinkCreateFailedError, + ) + + mock_find_dataset.return_value = _mock_dataset(id=1) + mock_create_permalink.side_effect = ExplorePermalinkCreateFailedError( + "DB unavailable" + ) + mock_create_form_data.return_value = "fallback_form_data_key" + + config = TableChartConfig( + chart_type="table", columns=[ColumnRef(name="test_col")] + ) + request = GenerateExploreLinkRequest(dataset_id="1", config=config) + + async with Client(mcp_server) as client: + result = await client.call_tool( + "generate_explore_link", {"request": request.model_dump()} + ) + + assert result.data["error"] is None + assert ( + result.data["url"] + == "http://localhost:9001/explore/?form_data_key=fallback_form_data_key" + ) + assert result.data["form_data_key"] == "fallback_form_data_key" + assert result.data["permalink_key"] is None mock_create_form_data.assert_called_once() + @patch(_PERMALINK_PATCH) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) + @patch(_FORM_DATA_PATCH) @pytest.mark.asyncio - async def test_generate_explore_link_cache_failure_fallback( - self, mock_create_form_data, mock_find_dataset, mcp_server + async def test_generate_explore_link_both_fail_fallback_to_basic_url( + self, + mock_create_form_data, + mock_find_dataset, + mock_create_permalink, + mcp_server, ): - """Test fallback when form_data cache creation fails.""" - mock_find_dataset.return_value = _mock_dataset(id=1) + """When both permalink and form_data_key fail, fall back to basic URL.""" from superset.commands.exceptions import CommandException + from superset.explore.permalink.exceptions import ( + ExplorePermalinkCreateFailedError, + ) + mock_find_dataset.return_value = _mock_dataset(id=1) + mock_create_permalink.side_effect = ExplorePermalinkCreateFailedError( + "DB unavailable" + ) mock_create_form_data.side_effect = CommandException("Cache storage failed") config = TableChartConfig( @@ -398,28 +434,31 @@ class TestGenerateExploreLink: "generate_explore_link", {"request": request.model_dump()} ) - # Should fallback to basic URL format assert result.data["error"] is None assert ( result.data["url"] == "http://localhost:9001/explore/?datasource_type=table&datasource_id=1" ) + @patch(_PERMALINK_PATCH) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) + @patch(_FORM_DATA_PATCH) @pytest.mark.asyncio async def test_generate_explore_link_database_lock_fallback( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, + mock_create_form_data, + mock_find_dataset, + mock_create_permalink, + mcp_server, ): - """Test fallback when database is locked.""" + """When permalink fails with SQLAlchemy error, fall back to form_data_key.""" from sqlalchemy.exc import OperationalError mock_find_dataset.return_value = _mock_dataset(id=5) - mock_create_form_data.side_effect = OperationalError( + mock_create_permalink.side_effect = OperationalError( "database is locked", None, None ) + mock_create_form_data.return_value = "lock_fallback_key" config = XYChartConfig( chart_type="xy", @@ -434,23 +473,18 @@ class TestGenerateExploreLink: "generate_explore_link", {"request": request.model_dump()} ) - # Should fallback to basic dataset URL assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?datasource_type=table&datasource_id=5" + == "http://localhost:9001/explore/?form_data_key=lock_fallback_key" ) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_explore_link_with_many_columns( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): """Test generating explore link with many columns.""" - mock_create_form_data.return_value = "many_columns_key" mock_find_dataset.return_value = _mock_dataset(id=1) # Create 15 columns @@ -474,20 +508,15 @@ class TestGenerateExploreLink: assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=many_columns_key" + == "http://localhost:9001/explore/p/test_permalink_key/" ) - mock_create_form_data.assert_called_once() @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_explore_link_with_many_filters( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): """Test generating explore link with many filters.""" - mock_create_form_data.return_value = "many_filters_key" mock_find_dataset.return_value = _mock_dataset(id=1) # Create 12 filters @@ -517,20 +546,15 @@ class TestGenerateExploreLink: assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=many_filters_key" + == "http://localhost:9001/explore/p/test_permalink_key/" ) - mock_create_form_data.assert_called_once() @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_explore_link_url_format_consistency( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): - """Test that all generated URLs follow consistent format.""" - mock_create_form_data.return_value = "consistency_test_key" + """Test that all generated URLs follow consistent permalink format.""" mock_find_dataset.return_value = _mock_dataset(id=1) configs = [ @@ -569,23 +593,19 @@ class TestGenerateExploreLink: "generate_explore_link", {"request": request.model_dump()} ) - # All URLs should follow the same format + # All URLs should follow the same permalink format assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=consistency_test_key" + == "http://localhost:9001/explore/p/test_permalink_key/" ) assert result.data["error"] is None @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_explore_link_dataset_id_types( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): """Test explore link generation with different dataset_id formats.""" - mock_create_form_data.return_value = "dataset_test_key" mock_find_dataset.return_value = _mock_dataset(id=1) config = TableChartConfig( @@ -604,19 +624,15 @@ class TestGenerateExploreLink: assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=dataset_test_key" + == "http://localhost:9001/explore/p/test_permalink_key/" ) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_explore_link_complex_configuration( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): """Test explore link generation with complex chart configuration.""" - mock_create_form_data.return_value = "complex_config_key" mock_find_dataset.return_value = _mock_dataset(id=10) config = XYChartConfig( @@ -648,22 +664,30 @@ class TestGenerateExploreLink: assert result.data["error"] is None assert ( result.data["url"] - == "http://localhost:9001/explore/?form_data_key=complex_config_key" + == "http://localhost:9001/explore/p/test_permalink_key/" ) - mock_create_form_data.assert_called_once() + @patch(_PERMALINK_PATCH) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) + @patch(_FORM_DATA_PATCH) @pytest.mark.asyncio async def test_fallback_url_different_datasets( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, + mock_create_form_data, + mock_find_dataset, + mock_create_permalink, + mcp_server, ): - """Test fallback URLs are correct for different dataset IDs.""" - mock_find_dataset.return_value = _mock_dataset(id=1) + """When both fallbacks fail, basic URL uses the correct dataset_id.""" from superset.commands.exceptions import CommandException + from superset.explore.permalink.exceptions import ( + ExplorePermalinkCreateFailedError, + ) + mock_find_dataset.return_value = _mock_dataset(id=1) + mock_create_permalink.side_effect = ExplorePermalinkCreateFailedError( + "Always fail for fallback testing" + ) mock_create_form_data.side_effect = CommandException( "Always fail for fallback testing" ) @@ -680,7 +704,10 @@ class TestGenerateExploreLink: ) # Should fallback to basic URL with correct dataset_id - expected_url = f"http://localhost:9001/explore/?datasource_type=table&datasource_id={dataset_id}" + expected_url = ( + f"http://localhost:9001/explore/?datasource_type=table" + f"&datasource_id={dataset_id}" + ) assert result.data["error"] is None assert result.data["url"] == expected_url @@ -720,22 +747,21 @@ class TestGenerateExploreLink: assert result.data["url"] == "" assert result.data["form_data"] == {} assert result.data["form_data_key"] is None + assert result.data["permalink_key"] is None assert result.data["chart_type_label"] is None assert "Invalid config structure" in result.data["error"] finally: # Restore original function explore_module.map_config_to_form_data = original_func + @patch(_PERMALINK_PATCH) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio - async def test_generate_explore_link_returns_form_data_key( - self, mock_create_form_data, mock_find_dataset, mcp_server + async def test_generate_explore_link_returns_permalink_key( + self, mock_find_dataset, mock_create_permalink, mcp_server ): - """Test that form_data_key is properly extracted from URL.""" - mock_create_form_data.return_value = "extracted_form_key_xyz" + """Test that permalink_key is properly extracted from the durable URL.""" + mock_create_permalink.return_value = "extracted_permalink_xyz" mock_find_dataset.return_value = _mock_dataset(id=1) config = TableChartConfig( @@ -749,19 +775,19 @@ class TestGenerateExploreLink: ) assert result.data["error"] is None - assert result.data["form_data_key"] == "extracted_form_key_xyz" - assert "form_data_key=extracted_form_key_xyz" in result.data["url"] + assert result.data["permalink_key"] == "extracted_permalink_xyz" + assert result.data["form_data_key"] is None + assert "extracted_permalink_xyz" in result.data["url"] + assert result.data["url"] == ( + "http://localhost:9001/explore/p/extracted_permalink_xyz/" + ) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_generate_explore_link_returns_form_data( - self, mock_create_form_data, mock_find_dataset, mcp_server + self, mock_find_dataset, mcp_server ): """Test that form_data dict is returned for external rendering.""" - mock_create_form_data.return_value = "form_data_test_key" mock_find_dataset.return_value = _mock_dataset(id=1) config = XYChartConfig( @@ -806,6 +832,7 @@ class TestGenerateExploreLink: assert result.data["url"] == "" assert result.data["form_data"] == {} assert result.data["form_data_key"] is None + assert result.data["permalink_key"] is None assert result.data["chart_type_label"] is None assert "Dataset not found: 99999" in result.data["error"] assert "list_datasets" in result.data["error"] @@ -833,6 +860,7 @@ class TestGenerateExploreLink: ) assert result.data["form_data"] == {} assert result.data["form_data_key"] is None + assert result.data["permalink_key"] is None assert result.data["chart_type_label"] is None @patch("superset.daos.dataset.DatasetDAO.find_by_id") @@ -853,6 +881,7 @@ class TestGenerateExploreLink: assert result.data["url"] == "" assert result.data["form_data"] == {} assert result.data["form_data_key"] is None + assert result.data["permalink_key"] is None assert result.data["chart_type_label"] is None assert "Dataset not found: 99999" in result.data["error"] @@ -879,6 +908,7 @@ class TestGenerateExploreLink: assert result.data["url"] == "" assert result.data["form_data"] == {} assert result.data["form_data_key"] is None + assert result.data["permalink_key"] is None assert result.data["chart_type_label"] is None assert "Dataset not found" in result.data["error"] @@ -895,19 +925,14 @@ class TestGenerateExploreLinkColumnNormalization: "superset.mcp_service.chart.validation.dataset_validator.DatasetValidator._get_dataset_context" ) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_xy_chart_x_axis_normalized_in_form_data( self, - mock_create_form_data, mock_find_dataset, mock_get_context, mcp_server, ): """x-axis column name in wrong case is normalized in form_data.""" - mock_create_form_data.return_value = "norm_test_key_1" mock_find_dataset.return_value = _mock_dataset(id=18) mock_get_context.return_value = DatasetContext( id=18, @@ -942,19 +967,14 @@ class TestGenerateExploreLinkColumnNormalization: "superset.mcp_service.chart.validation.dataset_validator.DatasetValidator._get_dataset_context" ) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_filter_column_normalized_in_form_data( self, - mock_create_form_data, mock_find_dataset, mock_get_context, mcp_server, ): """Filter column name in wrong case is normalized in adhoc_filters.""" - mock_create_form_data.return_value = "norm_test_key_2" mock_find_dataset.return_value = _mock_dataset(id=18) mock_get_context.return_value = DatasetContext( id=18, @@ -1001,19 +1021,14 @@ class TestGenerateExploreLinkColumnNormalization: "superset.mcp_service.chart.validation.dataset_validator.DatasetValidator._get_dataset_context" ) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_normalization_fallback_when_dataset_not_found( self, - mock_create_form_data, mock_find_dataset, mock_get_context, mcp_server, ): """When dataset context is unavailable, original names pass through.""" - mock_create_form_data.return_value = "norm_test_key_3" mock_find_dataset.return_value = _mock_dataset(id=99) mock_get_context.return_value = None @@ -1046,21 +1061,19 @@ class TestGenerateExploreLinkValidation: """ return + @patch(_PERMALINK_PATCH) @patch.object(generate_explore_link_module, "validate_and_compile") @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_validation_failure_returns_structured_error( self, - mock_create_form_data, mock_find_dataset, mock_validate, + mock_create_permalink, mcp_server, ): """Non-existent column → structured ChartGenerationError with suggestions, - and MCPCreateFormDataCommand must NOT be called (no cache write).""" + and CreateExplorePermalinkCommand must NOT be called (no cache write).""" from superset.mcp_service.chart.compile import CompileResult from superset.mcp_service.common.error_schemas import ChartGenerationError @@ -1094,29 +1107,28 @@ class TestGenerateExploreLinkValidation: assert result.data["url"] == "" assert result.data["form_data_key"] is None + assert result.data["permalink_key"] is None assert result.data["chart_type_label"] is None error = result.data["error"] assert isinstance(error, dict) assert error["error_code"] == "CHART_VALIDATION_FAILED" assert "sum_boys" in error["suggestions"] - mock_create_form_data.assert_not_called() + mock_create_permalink.assert_not_called() + @patch(_PERMALINK_PATCH) @patch.object( generate_explore_link_module, "has_dataset_access", return_value=False ) @patch("superset.daos.dataset.DatasetDAO.find_by_id") - @patch( - "superset.mcp_service.commands.create_form_data.MCPCreateFormDataCommand.run" - ) @pytest.mark.asyncio async def test_dataset_access_denied_short_circuits( self, - mock_create_form_data, mock_find_dataset, unused_access_mock, + mock_create_permalink, mcp_server, ): - """has_dataset_access=False blocks the tool before any cache write.""" + """has_dataset_access=False blocks the tool before any permalink write.""" mock_find_dataset.return_value = _mock_dataset(id=3) config = TableChartConfig( @@ -1133,4 +1145,4 @@ class TestGenerateExploreLinkValidation: assert result.data["chart_type_label"] is None # Surface as "not found" rather than leaking that the dataset exists. assert "Dataset not found" in result.data["error"] - mock_create_form_data.assert_not_called() + mock_create_permalink.assert_not_called() diff --git a/tests/unit_tests/mcp_service/test_url_utils.py b/tests/unit_tests/mcp_service/test_url_utils.py new file mode 100644 index 00000000000..14b6735cb8d --- /dev/null +++ b/tests/unit_tests/mcp_service/test_url_utils.py @@ -0,0 +1,46 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from superset.mcp_service.utils.url_utils import extract_permalink_key_from_url + + +def test_extract_permalink_key_from_url_with_trailing_slash(): + url = "http://localhost:8088/explore/p/abc123/" + assert extract_permalink_key_from_url(url) == "abc123" + + +def test_extract_permalink_key_from_url_without_trailing_slash(): + url = "http://localhost:8088/explore/p/abc123" + assert extract_permalink_key_from_url(url) == "abc123" + + +def test_extract_permalink_key_from_url_no_match(): + url = "http://localhost:8088/explore/?form_data_key=abc123" + assert extract_permalink_key_from_url(url) is None + + +def test_extract_permalink_key_from_url_none(): + assert extract_permalink_key_from_url(None) is None + + +def test_extract_permalink_key_from_url_empty(): + assert extract_permalink_key_from_url("") is None + + +def test_extract_permalink_key_from_url_with_path_prefix(): + url = "https://example.com/superset/explore/p/xyz789/" + assert extract_permalink_key_from_url(url) == "xyz789" From d32170b020f09df57101c21a64f7b25b804d73ea Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Fri, 19 Jun 2026 08:59:21 -0700 Subject: [PATCH 14/37] chore(embedded-sdk): remove temporary OIDC diagnostic step (#41216) --- .github/workflows/embedded-sdk-release.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/embedded-sdk-release.yml b/.github/workflows/embedded-sdk-release.yml index 67fc7e4b8a4..12f001555cb 100644 --- a/.github/workflows/embedded-sdk-release.yml +++ b/.github/workflows/embedded-sdk-release.yml @@ -34,15 +34,5 @@ jobs: - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: "./superset-embedded-sdk/.nvmrc" - # Diagnostic: confirm GitHub OIDC is granted to this job. npm trusted - # publishing needs the id-token request env vars; "no" here means OIDC was - # not issued and publishing cannot authenticate. - - name: Check OIDC availability - run: | - if [ -n "${ACTIONS_ID_TOKEN_REQUEST_URL}" ]; then - echo "GitHub OIDC available to job: yes" - else - echo "GitHub OIDC available to job: no" - fi - run: npm ci - run: npm run ci:release From bdf494d8b5af102e6094402b54974c6430d99f42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:10:21 -0700 Subject: [PATCH 15/37] chore(deps): bump @visx/axis from 3.12.0 to 4.0.0 in /superset-frontend (#41242) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 260 ++++++++++++++++++++++++++-- superset-frontend/package.json | 2 +- 2 files changed, 248 insertions(+), 14 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 34cdd54937f..256d549ae39 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -75,7 +75,7 @@ "@types/d3-selection": "^3.0.11", "@types/d3-time-format": "^4.0.3", "@types/react-google-recaptcha": "^2.1.9", - "@visx/axis": "^3.8.0", + "@visx/axis": "^4.0.0", "@visx/grid": "^3.5.0", "@visx/responsive": "^3.0.0", "@visx/scale": "^3.5.0", @@ -12772,22 +12772,218 @@ } }, "node_modules/@visx/axis": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-3.12.0.tgz", - "integrity": "sha512-8MoWpfuaJkhm2Yg+HwyytK8nk+zDugCqTT/tRmQX7gW4LYrHYLXFUXOzbDyyBakCVaUbUaAhVFxpMASJiQKf7A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-4.0.0.tgz", + "integrity": "sha512-cSPNO9Aic2UX49AmIeJJ9TQrrAkvUHpHOGqimUAXhbg07VI3HoHDKcXZdrjvQz+g0LhubrUkjj8Gwju2WZ3dtg==", "license": "MIT", "dependencies": { - "@types/react": "*", - "@visx/group": "3.12.0", - "@visx/point": "3.12.0", - "@visx/scale": "3.12.0", - "@visx/shape": "3.12.0", - "@visx/text": "3.12.0", - "classnames": "^2.3.1", - "prop-types": "^15.6.0" + "@visx/group": "4.0.0", + "@visx/point": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/shape": "4.0.0", + "@visx/text": "4.0.0", + "classnames": "^2.3.1" }, "peerDependencies": { - "react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/axis/node_modules/@types/d3-array": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", + "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", + "license": "MIT" + }, + "node_modules/@visx/axis/node_modules/@types/d3-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", + "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", + "license": "MIT" + }, + "node_modules/@visx/axis/node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@visx/axis/node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@visx/axis/node_modules/@types/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@visx/axis/node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@visx/axis/node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", + "license": "MIT" + }, + "node_modules/@visx/axis/node_modules/@types/d3-time-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", + "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", + "license": "MIT" + }, + "node_modules/@visx/axis/node_modules/@visx/curve": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-4.0.0.tgz", + "integrity": "sha512-bXrOSd2BzVCxR7kBE7gPTSU4plxzYN75w7erdHYabwn3vzP+xFk1o0gg3NOHEPJzt5tXqf0Ecm5YqHACOnipTA==", + "license": "MIT", + "dependencies": { + "@visx/vendor": "4.0.0" + } + }, + "node_modules/@visx/axis/node_modules/@visx/group": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", + "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", + "license": "MIT", + "dependencies": { + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/axis/node_modules/@visx/point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", + "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", + "license": "MIT" + }, + "node_modules/@visx/axis/node_modules/@visx/scale": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", + "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", + "license": "MIT", + "dependencies": { + "@visx/vendor": "4.0.0" + } + }, + "node_modules/@visx/axis/node_modules/@visx/shape": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-4.0.0.tgz", + "integrity": "sha512-X0FP3OFjQhc5/6Vj2aY7cK2JwKYI0H0hQM7cdNRWy/ZMMlrh5KpEdqx0HVo0KoTeTlkUvO+kydMLnAuuCRFIFw==", + "license": "MIT", + "dependencies": { + "@visx/curve": "4.0.0", + "@visx/group": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/vendor": "4.0.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/axis/node_modules/@visx/text": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", + "integrity": "sha512-39f2goSaKy5Mqn89lRDGSJ1IMr49wplkbIFHsFI8cPnAPbguiJxYZ+ulizd7Vcsq2z/hytuGv3Lmk165zUiUYQ==", + "license": "MIT", + "dependencies": { + "classnames": "^2.3.1", + "reduce-css-calc": "^1.3.0" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/axis/node_modules/@visx/vendor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", + "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", + "license": "MIT and ISC", + "dependencies": { + "@types/d3-array": "3.0.3", + "@types/d3-color": "3.1.0", + "@types/d3-delaunay": "6.0.1", + "@types/d3-format": "3.0.1", + "@types/d3-geo": "3.1.0", + "@types/d3-interpolate": "3.0.1", + "@types/d3-path": "3.1.1", + "@types/d3-scale": "4.0.2", + "@types/d3-shape": "3.1.7", + "@types/d3-time": "3.0.0", + "@types/d3-time-format": "2.1.0", + "d3-array": "3.2.1", + "d3-color": "3.1.0", + "d3-delaunay": "6.0.2", + "d3-format": "3.1.0", + "d3-geo": "3.1.0", + "d3-interpolate": "3.0.1", + "d3-path": "3.1.0", + "d3-scale": "4.0.2", + "d3-shape": "3.2.0", + "d3-time": "3.1.0", + "d3-time-format": "4.1.0", + "internmap": "2.0.3" + } + }, + "node_modules/@visx/axis/node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@visx/axis/node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/@visx/bounds": { @@ -12915,6 +13111,25 @@ "react": "^16.3.0-0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@visx/react-spring/node_modules/@visx/axis": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-3.12.0.tgz", + "integrity": "sha512-8MoWpfuaJkhm2Yg+HwyytK8nk+zDugCqTT/tRmQX7gW4LYrHYLXFUXOzbDyyBakCVaUbUaAhVFxpMASJiQKf7A==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "@visx/group": "3.12.0", + "@visx/point": "3.12.0", + "@visx/scale": "3.12.0", + "@visx/shape": "3.12.0", + "@visx/text": "3.12.0", + "classnames": "^2.3.1", + "prop-types": "^15.6.0" + }, + "peerDependencies": { + "react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" + } + }, "node_modules/@visx/responsive": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-3.12.0.tgz", @@ -13114,6 +13329,25 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@visx/xychart/node_modules/@visx/axis": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-3.12.0.tgz", + "integrity": "sha512-8MoWpfuaJkhm2Yg+HwyytK8nk+zDugCqTT/tRmQX7gW4LYrHYLXFUXOzbDyyBakCVaUbUaAhVFxpMASJiQKf7A==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "@visx/group": "3.12.0", + "@visx/point": "3.12.0", + "@visx/scale": "3.12.0", + "@visx/shape": "3.12.0", + "@visx/text": "3.12.0", + "classnames": "^2.3.1", + "prop-types": "^15.6.0" + }, + "peerDependencies": { + "react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" + } + }, "node_modules/@visx/xychart/node_modules/d3-shape": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index e4ba4757427..2f76c4f80e3 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -158,7 +158,7 @@ "@types/d3-selection": "^3.0.11", "@types/d3-time-format": "^4.0.3", "@types/react-google-recaptcha": "^2.1.9", - "@visx/axis": "^3.8.0", + "@visx/axis": "^4.0.0", "@visx/grid": "^3.5.0", "@visx/responsive": "^3.0.0", "@visx/scale": "^3.5.0", From ffa98d03df5facb87b274afb0d13a2aa1f3690b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:11:18 -0700 Subject: [PATCH 16/37] chore(deps): bump @visx/xychart from 3.12.0 to 4.0.0 in /superset-frontend (#41230) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 977 ++++++++++++++++++++++++---- superset-frontend/package.json | 2 +- 2 files changed, 858 insertions(+), 121 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 256d549ae39..331389a7c06 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -80,7 +80,7 @@ "@visx/responsive": "^3.0.0", "@visx/scale": "^3.5.0", "@visx/tooltip": "^3.0.0", - "@visx/xychart": "^3.5.1", + "@visx/xychart": "^4.0.0", "ag-grid-community": "35.3.1", "ag-grid-react": "35.3.1", "antd": "^5.26.0", @@ -9147,81 +9147,82 @@ "license": "MIT" }, "node_modules/@react-spring/animated": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.5.tgz", - "integrity": "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-10.1.1.tgz", + "integrity": "sha512-kqdtIzr1GfBmbojnYhNdEhgu23f1rQ9H98K6KGmWHpNBP0gGZWN8KEIzGYwCAon7Q8ktGmsR1dCyy6QTI4egug==", "license": "MIT", "peer": true, "dependencies": { - "@react-spring/shared": "~9.7.5", - "@react-spring/types": "~9.7.5" + "@react-spring/shared": "~10.1.1", + "@react-spring/types": "~10.1.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spring/core": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.5.tgz", - "integrity": "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-10.1.1.tgz", + "integrity": "sha512-eCxEJuJzNxbfFXEr+BuMqp+LYv0fdvIO/lk6B+A/aUDxD4M4EBKizPqhCkMz/B+U12d99KTAUSmWaGul/Lly+w==", "license": "MIT", "peer": true, "dependencies": { - "@react-spring/animated": "~9.7.5", - "@react-spring/shared": "~9.7.5", - "@react-spring/types": "~9.7.5" + "@react-spring/animated": "~10.1.1", + "@react-spring/shared": "~10.1.1", + "@react-spring/types": "~10.1.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/react-spring/donate" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spring/rafz": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.5.tgz", - "integrity": "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-10.1.1.tgz", + "integrity": "sha512-F7n2fU8EO8OokBkUHivU/tJ9HnL/QTIgd8V/2BhHFSrszt+OaLUoqEinomNeedLPIs24skiXQtki4APJHxghDQ==", "license": "MIT", "peer": true }, "node_modules/@react-spring/shared": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.5.tgz", - "integrity": "sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-10.1.1.tgz", + "integrity": "sha512-pOoQPoOa+EPWrRndqIYlIms71fNB1p0IQVJcCi5xHtErqL8N0+jS1V9pExHfryqn9aUhHv0+7kMiVrcb6U+IBQ==", "license": "MIT", "peer": true, "dependencies": { - "@react-spring/rafz": "~9.7.5", - "@react-spring/types": "~9.7.5" + "@react-spring/rafz": "~10.1.1", + "@react-spring/types": "~10.1.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/@react-spring/types": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.5.tgz", - "integrity": "sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-10.1.1.tgz", + "integrity": "sha512-C35b9XigBnwv1fZsUGR/lWzAKBskGhdAmf0LIBvqhwwHTYMtat4DXHZEnFyJQvfCAmpVc/d9Yug7j2Lbv2GDEA==", "license": "MIT", "peer": true }, "node_modules/@react-spring/web": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.5.tgz", - "integrity": "sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-10.1.1.tgz", + "integrity": "sha512-G8jVDH8YPAo9ALWio0YcpwvZjXIt6LFwSKZtS4XeTNWIMNUH+sTm2Uy8dxEobTqyzQ5kvKwnMfS3LsOpKrVOag==", "license": "MIT", "peer": true, "dependencies": { - "@react-spring/animated": "~9.7.5", - "@react-spring/core": "~9.7.5", - "@react-spring/shared": "~9.7.5", - "@react-spring/types": "~9.7.5" + "@react-spring/animated": "~10.1.1", + "@react-spring/core": "~10.1.1", + "@react-spring/shared": "~10.1.1", + "@react-spring/types": "~10.1.1", + "csstype": "^3.2.3" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/@reduxjs/toolkit": { @@ -12754,21 +12755,62 @@ ] }, "node_modules/@visx/annotation": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/annotation/-/annotation-3.12.0.tgz", - "integrity": "sha512-ZH6Y4jfrb47iEUV9O2itU9TATE5IPzhs5qvP6J7vmv26qkqwDcuE7xN3S3l9R70WjyEKGbpO8js4EijA3FJWkA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/annotation/-/annotation-4.0.0.tgz", + "integrity": "sha512-+ZZVyEqtUuMxKb3C2yN30/lPybao9+B733nnG+raW9ztFE9/Z3M+vAT0X/lxZiTc3uL6ZJlP7xzZN2+LcydWsQ==", "license": "MIT", "dependencies": { - "@types/react": "*", - "@visx/drag": "3.12.0", - "@visx/group": "3.12.0", - "@visx/text": "3.12.0", + "@visx/drag": "4.0.0", + "@visx/group": "4.0.0", + "@visx/text": "4.0.0", "classnames": "^2.3.1", - "prop-types": "^15.5.10", "react-use-measure": "^2.0.4" }, "peerDependencies": { - "react": "^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/annotation/node_modules/@visx/group": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", + "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", + "license": "MIT", + "dependencies": { + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/annotation/node_modules/@visx/text": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", + "integrity": "sha512-39f2goSaKy5Mqn89lRDGSJ1IMr49wplkbIFHsFI8cPnAPbguiJxYZ+ulizd7Vcsq2z/hytuGv3Lmk165zUiUYQ==", + "license": "MIT", + "dependencies": { + "classnames": "^2.3.1", + "reduce-css-calc": "^1.3.0" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@visx/axis": { @@ -13012,45 +13054,199 @@ } }, "node_modules/@visx/drag": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/drag/-/drag-3.12.0.tgz", - "integrity": "sha512-LXOoPVw//YPjpYhDJYBsCYDuv1QimsXjDV98duH0aCy4V94ediXMQpe2wHq4pnlDobLEB71FjOZMFrbFmqtERg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/drag/-/drag-4.0.0.tgz", + "integrity": "sha512-hWfe8a1sqkxTkcQP6EKNAsSZ9d/0owBOjyoC+cgULorfXkmBJpDK2xV7YGsicUqSbM1tuNIrPJME2HQACBc9Ng==", "license": "MIT", "dependencies": { - "@types/react": "*", - "@visx/event": "3.12.0", - "@visx/point": "3.12.0", - "prop-types": "^15.5.10" + "@visx/event": "4.0.0", + "@visx/point": "4.0.0" }, "peerDependencies": { - "react": "^16.8.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, + "node_modules/@visx/drag/node_modules/@visx/point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", + "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", + "license": "MIT" + }, "node_modules/@visx/event": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/event/-/event-3.12.0.tgz", - "integrity": "sha512-9Lvw6qJ0Fi+y1vsC1WspfdIKCxHTb7oy59Uql1uBdPGT8zChP0vuxW0jQNQRDbKgoefj4pCXAFi8+MF1mEtVTw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/event/-/event-4.0.0.tgz", + "integrity": "sha512-sOcVVzOUxOefF8mQenRFtutoEO7P9icpTcSJM36Sv13sepQbPBuYLknX7RV+EzqyNLOze5cO5GmLIUNH82FOoA==", "license": "MIT", "dependencies": { - "@types/react": "*", - "@visx/point": "3.12.0" - } - }, - "node_modules/@visx/glyph": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/glyph/-/glyph-3.12.0.tgz", - "integrity": "sha512-E9ST9MoPNyXQzjZxYYAGXT4CbBpnB90Qhx8UvUUM2/n/SZUNeH+m6UiB/CzT0jGK2b0lPHF91mlOiQ8JXBRhYg==", - "license": "MIT", - "dependencies": { - "@types/d3-shape": "^1.3.1", - "@types/react": "*", - "@visx/group": "3.12.0", - "classnames": "^2.3.1", - "d3-shape": "^1.2.0", - "prop-types": "^15.6.2" + "@visx/point": "4.0.0" }, "peerDependencies": { - "react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/event/node_modules/@visx/point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", + "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", + "license": "MIT" + }, + "node_modules/@visx/glyph": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/glyph/-/glyph-4.0.0.tgz", + "integrity": "sha512-MAj+nKCVQKoWGVo5p/8dDCPrjwZNL2bTEpPLnSwGVowAjmgF83J5xIEP5ARslNH/GrWJRpVT9uyl7ATEd8nzMQ==", + "license": "MIT", + "dependencies": { + "@visx/group": "4.0.0", + "@visx/vendor": "4.0.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/glyph/node_modules/@types/d3-array": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", + "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", + "license": "MIT" + }, + "node_modules/@visx/glyph/node_modules/@types/d3-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", + "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", + "license": "MIT" + }, + "node_modules/@visx/glyph/node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@visx/glyph/node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@visx/glyph/node_modules/@types/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@visx/glyph/node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@visx/glyph/node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", + "license": "MIT" + }, + "node_modules/@visx/glyph/node_modules/@types/d3-time-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", + "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", + "license": "MIT" + }, + "node_modules/@visx/glyph/node_modules/@visx/group": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", + "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", + "license": "MIT", + "dependencies": { + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/glyph/node_modules/@visx/vendor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", + "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", + "license": "MIT and ISC", + "dependencies": { + "@types/d3-array": "3.0.3", + "@types/d3-color": "3.1.0", + "@types/d3-delaunay": "6.0.1", + "@types/d3-format": "3.0.1", + "@types/d3-geo": "3.1.0", + "@types/d3-interpolate": "3.0.1", + "@types/d3-path": "3.1.1", + "@types/d3-scale": "4.0.2", + "@types/d3-shape": "3.1.7", + "@types/d3-time": "3.0.0", + "@types/d3-time-format": "2.1.0", + "d3-array": "3.2.1", + "d3-color": "3.1.0", + "d3-delaunay": "6.0.2", + "d3-format": "3.1.0", + "d3-geo": "3.1.0", + "d3-interpolate": "3.0.1", + "d3-path": "3.1.0", + "d3-scale": "4.0.2", + "d3-shape": "3.2.0", + "d3-time": "3.1.0", + "d3-time-format": "4.1.0", + "internmap": "2.0.3" + } + }, + "node_modules/@visx/glyph/node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@visx/glyph/node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/@visx/grid": { @@ -13093,22 +13289,264 @@ "license": "MIT" }, "node_modules/@visx/react-spring": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/react-spring/-/react-spring-3.12.0.tgz", - "integrity": "sha512-ehtmjFrUQx3g0mZ684M4LgI9UfQ84ZWD/m9tKfvXhEm1Vl8D4AjaZ4af1tTOg9S7vk2VlpxvVOVN7+t5pu0nSA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/react-spring/-/react-spring-4.0.0.tgz", + "integrity": "sha512-8eMQwDjppXzOZxxrendsmJiVnnwQGR3Ebx0oXUG0AXjfJY52tqHdHaufybxhxSzyNERB9QuS90xmvc/YQYd87Q==", "license": "MIT", "dependencies": { - "@types/react": "*", - "@visx/axis": "3.12.0", - "@visx/grid": "3.12.0", - "@visx/scale": "3.12.0", - "@visx/text": "3.12.0", - "classnames": "^2.3.1", - "prop-types": "^15.6.2" + "@visx/axis": "4.0.0", + "@visx/grid": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/text": "4.0.0", + "classnames": "^2.3.1" }, "peerDependencies": { - "@react-spring/web": "^9.4.5", - "react": "^16.3.0-0 || ^17.0.0 || ^18.0.0" + "@react-spring/web": "^9.7.5 || ^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/react-spring/node_modules/@types/d3-array": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", + "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", + "license": "MIT" + }, + "node_modules/@visx/react-spring/node_modules/@types/d3-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", + "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", + "license": "MIT" + }, + "node_modules/@visx/react-spring/node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@visx/react-spring/node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@visx/react-spring/node_modules/@types/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@visx/react-spring/node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@visx/react-spring/node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", + "license": "MIT" + }, + "node_modules/@visx/react-spring/node_modules/@types/d3-time-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", + "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", + "license": "MIT" + }, + "node_modules/@visx/react-spring/node_modules/@visx/axis": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-4.0.0.tgz", + "integrity": "sha512-cSPNO9Aic2UX49AmIeJJ9TQrrAkvUHpHOGqimUAXhbg07VI3HoHDKcXZdrjvQz+g0LhubrUkjj8Gwju2WZ3dtg==", + "license": "MIT", + "dependencies": { + "@visx/group": "4.0.0", + "@visx/point": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/shape": "4.0.0", + "@visx/text": "4.0.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/react-spring/node_modules/@visx/curve": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-4.0.0.tgz", + "integrity": "sha512-bXrOSd2BzVCxR7kBE7gPTSU4plxzYN75w7erdHYabwn3vzP+xFk1o0gg3NOHEPJzt5tXqf0Ecm5YqHACOnipTA==", + "license": "MIT", + "dependencies": { + "@visx/vendor": "4.0.0" + } + }, + "node_modules/@visx/react-spring/node_modules/@visx/grid": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/grid/-/grid-4.0.0.tgz", + "integrity": "sha512-BUnznqYo8jyn3zXRWZiF0zwg1VQl6w5kYqZ+XMY+cPXtAHZZbwGXBChMpPefH5Lj1+P1b4Pf3QihKG8zjL9PCw==", + "license": "MIT", + "dependencies": { + "@visx/curve": "4.0.0", + "@visx/group": "4.0.0", + "@visx/point": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/shape": "4.0.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/react-spring/node_modules/@visx/group": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", + "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", + "license": "MIT", + "dependencies": { + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/react-spring/node_modules/@visx/point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", + "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", + "license": "MIT" + }, + "node_modules/@visx/react-spring/node_modules/@visx/scale": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", + "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", + "license": "MIT", + "dependencies": { + "@visx/vendor": "4.0.0" + } + }, + "node_modules/@visx/react-spring/node_modules/@visx/shape": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-4.0.0.tgz", + "integrity": "sha512-X0FP3OFjQhc5/6Vj2aY7cK2JwKYI0H0hQM7cdNRWy/ZMMlrh5KpEdqx0HVo0KoTeTlkUvO+kydMLnAuuCRFIFw==", + "license": "MIT", + "dependencies": { + "@visx/curve": "4.0.0", + "@visx/group": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/vendor": "4.0.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/react-spring/node_modules/@visx/text": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", + "integrity": "sha512-39f2goSaKy5Mqn89lRDGSJ1IMr49wplkbIFHsFI8cPnAPbguiJxYZ+ulizd7Vcsq2z/hytuGv3Lmk165zUiUYQ==", + "license": "MIT", + "dependencies": { + "classnames": "^2.3.1", + "reduce-css-calc": "^1.3.0" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/react-spring/node_modules/@visx/vendor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", + "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", + "license": "MIT and ISC", + "dependencies": { + "@types/d3-array": "3.0.3", + "@types/d3-color": "3.1.0", + "@types/d3-delaunay": "6.0.1", + "@types/d3-format": "3.0.1", + "@types/d3-geo": "3.1.0", + "@types/d3-interpolate": "3.0.1", + "@types/d3-path": "3.1.1", + "@types/d3-scale": "4.0.2", + "@types/d3-shape": "3.1.7", + "@types/d3-time": "3.0.0", + "@types/d3-time-format": "2.1.0", + "d3-array": "3.2.1", + "d3-color": "3.1.0", + "d3-delaunay": "6.0.2", + "d3-format": "3.1.0", + "d3-geo": "3.1.0", + "d3-interpolate": "3.0.1", + "d3-path": "3.1.0", + "d3-scale": "4.0.2", + "d3-shape": "3.2.0", + "d3-time": "3.1.0", + "d3-time-format": "4.1.0", + "internmap": "2.0.3" + } + }, + "node_modules/@visx/react-spring/node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@visx/react-spring/node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/@visx/react-spring/node_modules/@visx/axis": { @@ -13281,52 +13719,348 @@ "license": "MIT" }, "node_modules/@visx/voronoi": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/voronoi/-/voronoi-3.12.0.tgz", - "integrity": "sha512-U3HWu6g5UjQchFDq8k/A4U9WrlN+80rAFPdGOUvIGOueQw9RmlZlNaeg8IJcQr2yk1s4O/VSpt3nR82zdINWMw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/voronoi/-/voronoi-4.0.0.tgz", + "integrity": "sha512-T8W7NAFgL9vTSCOpPaPgeqI2YDyt6gOMlEu3FIyAI/U8PC0/4gYHY/+WOoNjDFd5sEH0m6+0LUbaLEwKruHQzA==", "license": "MIT", "dependencies": { "@types/d3-voronoi": "^1.1.9", - "@types/react": "*", "classnames": "^2.3.1", - "d3-voronoi": "^1.1.2", - "prop-types": "^15.6.1" + "d3-voronoi": "^1.1.2" }, "peerDependencies": { - "react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@visx/xychart": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/xychart/-/xychart-3.12.0.tgz", - "integrity": "sha512-itJ7qvj/STpVmHesVyo2vPOataBM1mgSaf9R6/s4Bpe340wZldfCJ+IqRcNgdtbBagz1Hlr/sRnla4tWE2yw9A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/xychart/-/xychart-4.0.0.tgz", + "integrity": "sha512-cMeERMjjrnCQlmlNLOCMyo1rJp1hKFfAn5I0hR2U9sHL5hk+95Nx+Ruvx3gkHimVaAbJw8xVPyy80KC9GSTNAQ==", "license": "MIT", "dependencies": { - "@types/lodash": "^4.14.172", - "@types/react": "*", - "@visx/annotation": "3.12.0", - "@visx/axis": "3.12.0", - "@visx/event": "3.12.0", - "@visx/glyph": "3.12.0", - "@visx/grid": "3.12.0", - "@visx/react-spring": "3.12.0", - "@visx/responsive": "3.12.0", - "@visx/scale": "3.12.0", - "@visx/shape": "3.12.0", - "@visx/text": "3.12.0", - "@visx/tooltip": "3.12.0", - "@visx/vendor": "3.12.0", - "@visx/voronoi": "3.12.0", + "@visx/annotation": "4.0.0", + "@visx/axis": "4.0.0", + "@visx/event": "4.0.0", + "@visx/glyph": "4.0.0", + "@visx/grid": "4.0.0", + "@visx/react-spring": "4.0.0", + "@visx/responsive": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/shape": "4.0.0", + "@visx/text": "4.0.0", + "@visx/tooltip": "4.0.0", + "@visx/vendor": "4.0.0", + "@visx/voronoi": "4.0.0", "classnames": "^2.3.1", "d3-interpolate-path": "2.2.1", - "d3-shape": "^2.0.0", - "lodash": "^4.17.21", - "mitt": "^2.1.0", - "prop-types": "^15.6.2" + "mitt": "^2.1.0" }, "peerDependencies": { - "@react-spring/web": "^9.4.5", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@react-spring/web": "^9.7.5 || ^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@visx/xychart/node_modules/@types/d3-array": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", + "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", + "license": "MIT" + }, + "node_modules/@visx/xychart/node_modules/@types/d3-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", + "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", + "license": "MIT" + }, + "node_modules/@visx/xychart/node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@visx/xychart/node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@visx/xychart/node_modules/@types/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@visx/xychart/node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@visx/xychart/node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", + "license": "MIT" + }, + "node_modules/@visx/xychart/node_modules/@types/d3-time-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", + "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", + "license": "MIT" + }, + "node_modules/@visx/xychart/node_modules/@visx/axis": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-4.0.0.tgz", + "integrity": "sha512-cSPNO9Aic2UX49AmIeJJ9TQrrAkvUHpHOGqimUAXhbg07VI3HoHDKcXZdrjvQz+g0LhubrUkjj8Gwju2WZ3dtg==", + "license": "MIT", + "dependencies": { + "@visx/group": "4.0.0", + "@visx/point": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/shape": "4.0.0", + "@visx/text": "4.0.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/xychart/node_modules/@visx/bounds": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/bounds/-/bounds-4.0.0.tgz", + "integrity": "sha512-3wAfN5fg2bxg/5f3MlKWzGDTKU2hdKkxq8bVWXpPZQV0UiVc0myuU1qa34c7tN3hg5SDe6MJi/bae2eTQDgEiQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@visx/xychart/node_modules/@visx/curve": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-4.0.0.tgz", + "integrity": "sha512-bXrOSd2BzVCxR7kBE7gPTSU4plxzYN75w7erdHYabwn3vzP+xFk1o0gg3NOHEPJzt5tXqf0Ecm5YqHACOnipTA==", + "license": "MIT", + "dependencies": { + "@visx/vendor": "4.0.0" + } + }, + "node_modules/@visx/xychart/node_modules/@visx/grid": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/grid/-/grid-4.0.0.tgz", + "integrity": "sha512-BUnznqYo8jyn3zXRWZiF0zwg1VQl6w5kYqZ+XMY+cPXtAHZZbwGXBChMpPefH5Lj1+P1b4Pf3QihKG8zjL9PCw==", + "license": "MIT", + "dependencies": { + "@visx/curve": "4.0.0", + "@visx/group": "4.0.0", + "@visx/point": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/shape": "4.0.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/xychart/node_modules/@visx/group": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", + "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", + "license": "MIT", + "dependencies": { + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/xychart/node_modules/@visx/point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", + "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", + "license": "MIT" + }, + "node_modules/@visx/xychart/node_modules/@visx/responsive": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-4.0.0.tgz", + "integrity": "sha512-MGPK8AeiBIhzz34o9TNJIyUDQIdWEj5mt+U/Je4qVRRXpXSMhor1IE7v71czAS5b90OrFxC9L3w27AV+szG25w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/xychart/node_modules/@visx/scale": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", + "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", + "license": "MIT", + "dependencies": { + "@visx/vendor": "4.0.0" + } + }, + "node_modules/@visx/xychart/node_modules/@visx/shape": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-4.0.0.tgz", + "integrity": "sha512-X0FP3OFjQhc5/6Vj2aY7cK2JwKYI0H0hQM7cdNRWy/ZMMlrh5KpEdqx0HVo0KoTeTlkUvO+kydMLnAuuCRFIFw==", + "license": "MIT", + "dependencies": { + "@visx/curve": "4.0.0", + "@visx/group": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/vendor": "4.0.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/xychart/node_modules/@visx/text": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", + "integrity": "sha512-39f2goSaKy5Mqn89lRDGSJ1IMr49wplkbIFHsFI8cPnAPbguiJxYZ+ulizd7Vcsq2z/hytuGv3Lmk165zUiUYQ==", + "license": "MIT", + "dependencies": { + "classnames": "^2.3.1", + "reduce-css-calc": "^1.3.0" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/xychart/node_modules/@visx/tooltip": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/tooltip/-/tooltip-4.0.0.tgz", + "integrity": "sha512-+6J2h5qPvniT0pQtxQrLYGErPRVHr3pRfcMkNqTxD/HgofDGsL6vEBkjMR535MF1hkWYQ9XzOiWP6ERN4TF+mg==", + "license": "MIT", + "dependencies": { + "@visx/bounds": "4.0.0", + "classnames": "^2.3.1", + "react-use-measure": "^2.0.4" + }, + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@visx/xychart/node_modules/@visx/vendor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", + "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", + "license": "MIT and ISC", + "dependencies": { + "@types/d3-array": "3.0.3", + "@types/d3-color": "3.1.0", + "@types/d3-delaunay": "6.0.1", + "@types/d3-format": "3.0.1", + "@types/d3-geo": "3.1.0", + "@types/d3-interpolate": "3.0.1", + "@types/d3-path": "3.1.1", + "@types/d3-scale": "4.0.2", + "@types/d3-shape": "3.1.7", + "@types/d3-time": "3.0.0", + "@types/d3-time-format": "2.1.0", + "d3-array": "3.2.1", + "d3-color": "3.1.0", + "d3-delaunay": "6.0.2", + "d3-format": "3.1.0", + "d3-geo": "3.1.0", + "d3-interpolate": "3.0.1", + "d3-path": "3.1.0", + "d3-scale": "4.0.2", + "d3-shape": "3.2.0", + "d3-time": "3.1.0", + "d3-time-format": "4.1.0", + "internmap": "2.0.3" + } + }, + "node_modules/@visx/xychart/node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" } }, "node_modules/@visx/xychart/node_modules/@visx/axis": { @@ -13349,12 +14083,15 @@ } }, "node_modules/@visx/xychart/node_modules/d3-shape": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz", - "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==", - "license": "BSD-3-Clause", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", "dependencies": { - "d3-path": "1 - 2" + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/@vitest/expect": { diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 2f76c4f80e3..bcab5121bbe 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -163,7 +163,7 @@ "@visx/responsive": "^3.0.0", "@visx/scale": "^3.5.0", "@visx/tooltip": "^3.0.0", - "@visx/xychart": "^3.5.1", + "@visx/xychart": "^4.0.0", "ag-grid-community": "35.3.1", "ag-grid-react": "35.3.1", "antd": "^5.26.0", From 061f61977f4d0270fd33db2c274cc1f19a828e87 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:11:44 -0700 Subject: [PATCH 17/37] chore(deps-dev): bump react-dnd-test-backend from 11.1.3 to 16.0.1 in /superset-frontend (#41187) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 36 +++++++++++++++++++++++++---- superset-frontend/package.json | 2 +- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 331389a7c06..a19a29dc741 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -266,7 +266,7 @@ "prettier": "3.8.4", "prettier-plugin-packagejson": "^3.0.2", "process": "^0.11.10", - "react-dnd-test-backend": "^11.1.3", + "react-dnd-test-backend": "^16.0.1", "react-refresh": "^0.18.0", "react-resizable": "^4.0.1", "redux-mock-store": "^1.5.4", @@ -36617,13 +36617,39 @@ } }, "node_modules/react-dnd-test-backend": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/react-dnd-test-backend/-/react-dnd-test-backend-11.1.3.tgz", - "integrity": "sha512-5qFm+NI2GdWIUfiYun0A8Gv0xjbq0NGOPS+f6z3x/3nTuliApjmqcM1lfTgePoz1FDG47ZofF58N8y96If62+Q==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd-test-backend/-/react-dnd-test-backend-16.0.1.tgz", + "integrity": "sha512-sUsQKMmoachP3AGaHLZD4JZWq2dHPoiLRG3YVuC0gXJtGENk3PVR+uRIrml7BEnnTyv+RVeoNK2ziL38Ggh8cw==", "dev": true, "license": "MIT", "dependencies": { - "dnd-core": "^11.1.3" + "dnd-core": "^16.0.1" + } + }, + "node_modules/react-dnd-test-backend/node_modules/@react-dnd/asap": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz", + "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-dnd-test-backend/node_modules/@react-dnd/invariant": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz", + "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-dnd-test-backend/node_modules/dnd-core": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz", + "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@react-dnd/asap": "^5.0.1", + "@react-dnd/invariant": "^4.0.1", + "redux": "^4.2.0" } }, "node_modules/react-docgen": { diff --git a/superset-frontend/package.json b/superset-frontend/package.json index bcab5121bbe..9282be77d28 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -349,7 +349,7 @@ "prettier": "3.8.4", "prettier-plugin-packagejson": "^3.0.2", "process": "^0.11.10", - "react-dnd-test-backend": "^11.1.3", + "react-dnd-test-backend": "^16.0.1", "react-refresh": "^0.18.0", "react-resizable": "^4.0.1", "redux-mock-store": "^1.5.4", From 045674ab3cdddf2f8bb5627482bdce249daf627c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:48:07 -0700 Subject: [PATCH 18/37] chore(deps): bump @visx/tooltip from 3.12.0 to 4.0.0 in /superset-frontend (#41226) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 199 +++++----------------------- superset-frontend/package.json | 2 +- 2 files changed, 34 insertions(+), 167 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index a19a29dc741..3a51a4ece80 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -79,7 +79,7 @@ "@visx/grid": "^3.5.0", "@visx/responsive": "^3.0.0", "@visx/scale": "^3.5.0", - "@visx/tooltip": "^3.0.0", + "@visx/tooltip": "^4.0.0", "@visx/xychart": "^4.0.0", "ag-grid-community": "35.3.1", "ag-grid-react": "35.3.1", @@ -13029,18 +13029,23 @@ } }, "node_modules/@visx/bounds": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/bounds/-/bounds-3.12.0.tgz", - "integrity": "sha512-peAlNCUbYaaZ0IO6c1lDdEAnZv2iGPDiLIM8a6gu7CaMhtXZJkqrTh+AjidNcIqITktrICpGxJE/Qo9D099dvQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/bounds/-/bounds-4.0.0.tgz", + "integrity": "sha512-3wAfN5fg2bxg/5f3MlKWzGDTKU2hdKkxq8bVWXpPZQV0UiVc0myuU1qa34c7tN3hg5SDe6MJi/bae2eTQDgEiQ==", "license": "MIT", - "dependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "prop-types": "^15.5.10" - }, "peerDependencies": { - "react": "^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0", - "react-dom": "^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, "node_modules/@visx/curve": { @@ -13368,29 +13373,6 @@ "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", "license": "MIT" }, - "node_modules/@visx/react-spring/node_modules/@visx/axis": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-4.0.0.tgz", - "integrity": "sha512-cSPNO9Aic2UX49AmIeJJ9TQrrAkvUHpHOGqimUAXhbg07VI3HoHDKcXZdrjvQz+g0LhubrUkjj8Gwju2WZ3dtg==", - "license": "MIT", - "dependencies": { - "@visx/group": "4.0.0", - "@visx/point": "4.0.0", - "@visx/scale": "4.0.0", - "@visx/shape": "4.0.0", - "@visx/text": "4.0.0", - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@visx/react-spring/node_modules/@visx/curve": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-4.0.0.tgz", @@ -13549,25 +13531,6 @@ "node": ">=12" } }, - "node_modules/@visx/react-spring/node_modules/@visx/axis": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-3.12.0.tgz", - "integrity": "sha512-8MoWpfuaJkhm2Yg+HwyytK8nk+zDugCqTT/tRmQX7gW4LYrHYLXFUXOzbDyyBakCVaUbUaAhVFxpMASJiQKf7A==", - "license": "MIT", - "dependencies": { - "@types/react": "*", - "@visx/group": "3.12.0", - "@visx/point": "3.12.0", - "@visx/scale": "3.12.0", - "@visx/shape": "3.12.0", - "@visx/text": "3.12.0", - "classnames": "^2.3.1", - "prop-types": "^15.6.0" - }, - "peerDependencies": { - "react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" - } - }, "node_modules/@visx/responsive": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-3.12.0.tgz", @@ -13615,38 +13578,29 @@ "react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" } }, - "node_modules/@visx/text": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/text/-/text-3.12.0.tgz", - "integrity": "sha512-0rbDYQlbuKPhBqXkkGYKFec1gQo05YxV45DORzr6hCyaizdJk1G+n9VkuKSHKBy1vVQhBA0W3u/WXd7tiODQPA==", - "license": "MIT", - "dependencies": { - "@types/lodash": "^4.14.172", - "@types/react": "*", - "classnames": "^2.3.1", - "lodash": "^4.17.21", - "prop-types": "^15.7.2", - "reduce-css-calc": "^1.3.0" - }, - "peerDependencies": { - "react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" - } - }, "node_modules/@visx/tooltip": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/tooltip/-/tooltip-3.12.0.tgz", - "integrity": "sha512-pWhsYhgl0Shbeqf80qy4QCB6zpq6tQtMQQxKlh3UiKxzkkfl+Metaf9p0/S0HexNi4vewOPOo89xWx93hBeh3A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/tooltip/-/tooltip-4.0.0.tgz", + "integrity": "sha512-+6J2h5qPvniT0pQtxQrLYGErPRVHr3pRfcMkNqTxD/HgofDGsL6vEBkjMR535MF1hkWYQ9XzOiWP6ERN4TF+mg==", "license": "MIT", "dependencies": { - "@types/react": "*", - "@visx/bounds": "3.12.0", + "@visx/bounds": "4.0.0", "classnames": "^2.3.1", - "prop-types": "^15.5.10", "react-use-measure": "^2.0.4" }, "peerDependencies": { - "react": "^16.8.0-0 || ^17.0.0-0 || ^18.0.0-0", - "react-dom": "^16.8.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, "node_modules/@visx/vendor": { @@ -13834,49 +13788,6 @@ "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", "license": "MIT" }, - "node_modules/@visx/xychart/node_modules/@visx/axis": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-4.0.0.tgz", - "integrity": "sha512-cSPNO9Aic2UX49AmIeJJ9TQrrAkvUHpHOGqimUAXhbg07VI3HoHDKcXZdrjvQz+g0LhubrUkjj8Gwju2WZ3dtg==", - "license": "MIT", - "dependencies": { - "@visx/group": "4.0.0", - "@visx/point": "4.0.0", - "@visx/scale": "4.0.0", - "@visx/shape": "4.0.0", - "@visx/text": "4.0.0", - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@visx/xychart/node_modules/@visx/bounds": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/bounds/-/bounds-4.0.0.tgz", - "integrity": "sha512-3wAfN5fg2bxg/5f3MlKWzGDTKU2hdKkxq8bVWXpPZQV0UiVc0myuU1qa34c7tN3hg5SDe6MJi/bae2eTQDgEiQ==", - "license": "MIT", - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "@types/react-dom": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, "node_modules/@visx/xychart/node_modules/@visx/curve": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-4.0.0.tgz", @@ -13998,31 +13909,6 @@ } } }, - "node_modules/@visx/xychart/node_modules/@visx/tooltip": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/tooltip/-/tooltip-4.0.0.tgz", - "integrity": "sha512-+6J2h5qPvniT0pQtxQrLYGErPRVHr3pRfcMkNqTxD/HgofDGsL6vEBkjMR535MF1hkWYQ9XzOiWP6ERN4TF+mg==", - "license": "MIT", - "dependencies": { - "@visx/bounds": "4.0.0", - "classnames": "^2.3.1", - "react-use-measure": "^2.0.4" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "@types/react-dom": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, "node_modules/@visx/xychart/node_modules/@visx/vendor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", @@ -14063,25 +13949,6 @@ "node": ">=12" } }, - "node_modules/@visx/xychart/node_modules/@visx/axis": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/axis/-/axis-3.12.0.tgz", - "integrity": "sha512-8MoWpfuaJkhm2Yg+HwyytK8nk+zDugCqTT/tRmQX7gW4LYrHYLXFUXOzbDyyBakCVaUbUaAhVFxpMASJiQKf7A==", - "license": "MIT", - "dependencies": { - "@types/react": "*", - "@visx/group": "3.12.0", - "@visx/point": "3.12.0", - "@visx/scale": "3.12.0", - "@visx/shape": "3.12.0", - "@visx/text": "3.12.0", - "classnames": "^2.3.1", - "prop-types": "^15.6.0" - }, - "peerDependencies": { - "react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" - } - }, "node_modules/@visx/xychart/node_modules/d3-shape": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", @@ -46272,7 +46139,7 @@ "@deck.gl/extensions": "~9.2.9", "@deck.gl/geo-layers": "~9.2.5", "@deck.gl/layers": "~9.2.5", - "@deck.gl/mapbox": "^9.3.4", + "@deck.gl/mapbox": "~9.3.4", "@deck.gl/mesh-layers": "~9.2.5", "@luma.gl/constants": "~9.2.5", "@luma.gl/core": "~9.2.5", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 9282be77d28..0c7244dc3f3 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -162,7 +162,7 @@ "@visx/grid": "^3.5.0", "@visx/responsive": "^3.0.0", "@visx/scale": "^3.5.0", - "@visx/tooltip": "^3.0.0", + "@visx/tooltip": "^4.0.0", "@visx/xychart": "^4.0.0", "ag-grid-community": "35.3.1", "ag-grid-react": "35.3.1", From 81b7f31096a876676565f47db4ced2a56b534d58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:52:42 -0700 Subject: [PATCH 19/37] chore(deps-dev): bump Storybook 10.x packages from 10.4.3 to 10.4.4 in /superset-frontend (#41229) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evan Rusackas Co-authored-by: Claude Opus 4.8 --- superset-frontend/package-lock.json | 433 ++++++++++++++++------------ superset-frontend/package.json | 6 +- 2 files changed, 247 insertions(+), 192 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 3a51a4ece80..56c9d5c7fc1 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -182,9 +182,9 @@ "@istanbuljs/nyc-config-typescript": "^1.0.1", "@playwright/test": "^1.60.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.6.2", - "@storybook/addon-docs": "10.4.3", - "@storybook/addon-links": "10.4.3", - "@storybook/react-webpack5": "10.4.3", + "@storybook/addon-docs": "10.4.4", + "@storybook/addon-links": "10.4.4", + "@storybook/react-webpack5": "10.4.4", "@storybook/test-runner": "0.24.4", "@svgr/webpack": "^8.1.0", "@swc/core": "^1.15.41", @@ -9730,16 +9730,16 @@ "license": "MIT" }, "node_modules/@storybook/addon-docs": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.4.3.tgz", - "integrity": "sha512-CJGEXSo0zpIy7gvEeeUi09ZbjQUSNDi4YipAeb+lZGGEn8ShZUr2Pk330yd2ZO+ngNWJXD4ZxOb0e3/aIlxb3Q==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.4.4.tgz", + "integrity": "sha512-yPshCvtmQTq52T2sXuXgjy7B/QbhA/WIZxLYggptNjBL8BJMvbOfp9bAfCKh7+KpRWGqDZ6Y6tWL1Q48Wj3vtw==", "dev": true, "license": "MIT", "dependencies": { "@mdx-js/react": "^3.0.0", - "@storybook/csf-plugin": "10.4.3", + "@storybook/csf-plugin": "10.4.4", "@storybook/icons": "^2.0.2", - "@storybook/react-dom-shim": "10.4.3", + "@storybook/react-dom-shim": "10.4.4", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" @@ -9750,7 +9750,7 @@ }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.3" + "storybook": "^10.4.4" }, "peerDependenciesMeta": { "@types/react": { @@ -9758,10 +9758,36 @@ } } }, + "node_modules/@storybook/addon-docs/node_modules/@storybook/react-dom-shim": { + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.4.4.tgz", + "integrity": "sha512-y6SObmoW78AydE6VfKQSUmCkuqiaMPy9LgMpMdMEyWfJ/pSxBDMIKycr9dlRMJP1cvNgByaJgrusWtA46ndSQw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.4.4" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@storybook/addon-links": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-10.4.3.tgz", - "integrity": "sha512-GBJz1cwnhtwltu9KGUudceAWGFl0SRBv6r/MVc1FuD6ygpi/a8+tCc8TiEzFLFBJaU+4AgJ8IGtXSPzPihH2Iw==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-10.4.4.tgz", + "integrity": "sha512-sWydPWLgduT24p/NJ/hXHcHsPlAyzQP+cOtCGliSI989K9yBP/TOL3A8sz7LIDfukI9DVAsylPhJ1jDSiAEI1w==", "dev": true, "license": "MIT", "dependencies": { @@ -9774,7 +9800,7 @@ "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.3" + "storybook": "^10.4.4" }, "peerDependenciesMeta": { "@types/react": { @@ -9785,63 +9811,10 @@ } } }, - "node_modules/@storybook/builder-webpack5": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-10.4.3.tgz", - "integrity": "sha512-IfBz50mA47fUP+GrcchnE5ReOWHiUtpNi0dEJ+eCU7wbSYwxwsvmBuk9xNwfsSDZ0LG1qGFQ6Pyt6bHn15wWXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/core-webpack": "10.4.3", - "case-sensitive-paths-webpack-plugin": "^2.4.0", - "cjs-module-lexer": "^1.2.3", - "css-loader": "^7.1.2", - "es-module-lexer": "^1.5.0", - "fork-ts-checker-webpack-plugin": "^9.1.0", - "html-webpack-plugin": "^5.5.0", - "magic-string": "^0.30.5", - "style-loader": "^4.0.0", - "terser-webpack-plugin": "^5.3.17", - "ts-dedent": "^2.0.0", - "webpack": "5", - "webpack-dev-middleware": "^6.1.2", - "webpack-hot-middleware": "^2.25.1", - "webpack-virtual-modules": "^0.6.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^10.4.3" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@storybook/core-webpack": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-10.4.3.tgz", - "integrity": "sha512-8bLxUnajwfLXSvaX3LoGy4g/M/SZkU3tzc2lFB+FZukxmlEcyWBEjfM910muu2kuaQULP4NUNR+4LGJpuZoYoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^10.4.3" - } - }, "node_modules/@storybook/csf-plugin": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.4.3.tgz", - "integrity": "sha512-D+XF5CVhZmIOI0uhfTKxlQr+gR1z8X9djPy9phiA1USLPAOHagBAucp/PhLwlFVUxrKzEIf8yImrvkCv50IcDg==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.4.4.tgz", + "integrity": "sha512-1mzZyAwVUmAcw4WEUsJDVdSupkJf+Kf/f5uNAs4RzlBXA75P8YRkDKAb2EoMwsB5URiXFi9XoeAN/vWke0G6+w==", "dev": true, "license": "MIT", "dependencies": { @@ -9854,7 +9827,7 @@ "peerDependencies": { "esbuild": "*", "rollup": "*", - "storybook": "^10.4.3", + "storybook": "^10.4.4", "vite": "*", "webpack": "*" }, @@ -9891,74 +9864,6 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/@storybook/preset-react-webpack": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-10.4.3.tgz", - "integrity": "sha512-814EDY4yMTVECLoIFeCdbpoRuaFxtvN/U5TcB6czb6SDabaagEHsXWWVIDhx1xZlBGK6KUrxD9CMACPcB2fcKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/core-webpack": "10.4.3", - "@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0", - "@types/semver": "^7.7.1", - "magic-string": "^0.30.5", - "react-docgen": "^7.1.1", - "resolve": "^1.22.8", - "semver": "^7.7.3", - "tsconfig-paths": "^4.2.0", - "webpack": "5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.3" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@storybook/react": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.4.3.tgz", - "integrity": "sha512-Td+Zoi8ylJTPC1jg5vHw8OK7U2kJgqc5kuAn92UvD4IbAkcpMTBRPHDziK1piv6q7r8yNLVah+ku6IKHpTLeXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/global": "^5.0.0", - "@storybook/react-dom-shim": "10.4.3", - "react-docgen": "^8.0.2", - "react-docgen-typescript": "^2.2.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.3", - "typescript": ">= 4.9.x" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, "node_modules/@storybook/react-docgen-typescript-plugin": { "version": "1.0.6--canary.9.0c3f3b7.0", "resolved": "https://registry.npmjs.org/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.6--canary.9.0c3f3b7.0.tgz", @@ -10023,10 +9928,175 @@ "semver": "bin/semver.js" } }, - "node_modules/@storybook/react-dom-shim": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.4.3.tgz", - "integrity": "sha512-aPZ+Afd+zdoSygISOVCJIYdiqWJM6uRZFw0zhsONwNcn3kU1TNce6iAoBCY8cpEhDAu61M1QjeIHM3LPy/ieog==", + "node_modules/@storybook/react-webpack5": { + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/react-webpack5/-/react-webpack5-10.4.4.tgz", + "integrity": "sha512-LAYz4BlyOKNHhD/DR7f7eRFevJdl9lvoT1QsKEiT3ngFNxn9wMI2o8IMx7fOQYz0v1UTExZFYtwV2Ur/psJMEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/builder-webpack5": "10.4.4", + "@storybook/preset-react-webpack": "10.4.4", + "@storybook/react": "10.4.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.4.4", + "typescript": ">= 4.9.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/react-webpack5/node_modules/@storybook/builder-webpack5": { + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-10.4.4.tgz", + "integrity": "sha512-R/hUX+uPFXjh3CqRtwMTG4PXywpSn0Qb08GIHOrNihb2bmszbC3nZ89vReZsBYL1lm4IpgBQbz+XzmY8LOHaVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/core-webpack": "10.4.4", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "cjs-module-lexer": "^1.2.3", + "css-loader": "^7.1.2", + "es-module-lexer": "^1.5.0", + "fork-ts-checker-webpack-plugin": "^9.1.0", + "html-webpack-plugin": "^5.5.0", + "magic-string": "^0.30.5", + "style-loader": "^4.0.0", + "terser-webpack-plugin": "^5.3.17", + "ts-dedent": "^2.0.0", + "webpack": "5", + "webpack-dev-middleware": "^6.1.2", + "webpack-hot-middleware": "^2.25.1", + "webpack-virtual-modules": "^0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.4.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/react-webpack5/node_modules/@storybook/builder-webpack5/node_modules/@storybook/core-webpack": { + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-10.4.4.tgz", + "integrity": "sha512-tZ3cMhMunC/84KStq1vGhWanhNiFL99M0KFyKToEeULYx2WOyd/dC3oFIaWSNns3jRvykwR4Z11CwZzW6khjrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.4.4" + } + }, + "node_modules/@storybook/react-webpack5/node_modules/@storybook/preset-react-webpack": { + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-10.4.4.tgz", + "integrity": "sha512-n7JDUfY2mYW/5VqkfkHePWUWmUATCG1lF278pX+gaahvbMACJyM/bbZFcL56mlc1dEQIg6czC8VkA9y2Xm5nTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/core-webpack": "10.4.4", + "@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0", + "@types/semver": "^7.7.1", + "magic-string": "^0.30.5", + "react-docgen": "^7.1.1", + "resolve": "^1.22.8", + "semver": "^7.7.3", + "tsconfig-paths": "^4.2.0", + "webpack": "5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.4.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/react-webpack5/node_modules/@storybook/preset-react-webpack/node_modules/@storybook/core-webpack": { + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-10.4.4.tgz", + "integrity": "sha512-tZ3cMhMunC/84KStq1vGhWanhNiFL99M0KFyKToEeULYx2WOyd/dC3oFIaWSNns3jRvykwR4Z11CwZzW6khjrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.4.4" + } + }, + "node_modules/@storybook/react-webpack5/node_modules/@storybook/react": { + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.4.4.tgz", + "integrity": "sha512-6K5/uHrvjswrueyVpUt6IWGuSgYCMtMOYyVs86XJZYqKBV3Pv7nGsGNH7YSMLAVQBZW4CQqm2etd5Op0GHY9Kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/react-dom-shim": "10.4.4", + "react-docgen": "^8.0.2", + "react-docgen-typescript": "^2.2.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.4.4", + "typescript": ">= 4.9.x" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/react-webpack5/node_modules/@storybook/react/node_modules/@storybook/react-dom-shim": { + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.4.4.tgz", + "integrity": "sha512-y6SObmoW78AydE6VfKQSUmCkuqiaMPy9LgMpMdMEyWfJ/pSxBDMIKycr9dlRMJP1cvNgByaJgrusWtA46ndSQw==", "dev": true, "license": "MIT", "funding": { @@ -10038,7 +10108,7 @@ "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.3" + "storybook": "^10.4.4" }, "peerDependenciesMeta": { "@types/react": { @@ -10049,34 +10119,7 @@ } } }, - "node_modules/@storybook/react-webpack5": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/@storybook/react-webpack5/-/react-webpack5-10.4.3.tgz", - "integrity": "sha512-eWcXmRPixExctjT0Z6e5+efYemGfD953L0XkYcHaEXzlQYudZgIpbemknzFmyhkHG32F5DDgL4L5iBuL5A75Jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/builder-webpack5": "10.4.3", - "@storybook/preset-react-webpack": "10.4.3", - "@storybook/react": "10.4.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.3", - "typescript": ">= 4.9.x" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@storybook/react/node_modules/react-docgen": { + "node_modules/@storybook/react-webpack5/node_modules/@storybook/react/node_modules/react-docgen": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.3.tgz", "integrity": "sha512-aEZ9qP+/M+58x2qgfSFEWH1BxLyHe5+qkLNJOZQb5iGS017jpbRnoKhNRrXPeA6RfBrZO5wZrT9DMC1UqE1f1w==", @@ -10596,9 +10639,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -10615,9 +10655,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -10634,9 +10671,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -10653,9 +10687,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -10672,9 +10703,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -10691,9 +10719,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -26965,6 +26990,21 @@ } } }, + "node_modules/jsdom/node_modules/@noble/hashes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", + "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/jsdom/node_modules/css-tree": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", @@ -44113,6 +44153,21 @@ } } }, + "node_modules/whatwg-url/node_modules/@noble/hashes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", + "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/whatwg-url/node_modules/webidl-conversions": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 0c7244dc3f3..89d69d07370 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -265,9 +265,9 @@ "@istanbuljs/nyc-config-typescript": "^1.0.1", "@playwright/test": "^1.60.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.6.2", - "@storybook/addon-docs": "10.4.3", - "@storybook/addon-links": "10.4.3", - "@storybook/react-webpack5": "10.4.3", + "@storybook/addon-docs": "10.4.4", + "@storybook/addon-links": "10.4.4", + "@storybook/react-webpack5": "10.4.4", "@storybook/test-runner": "0.24.4", "@svgr/webpack": "^8.1.0", "@swc/core": "^1.15.41", From be225e5c20165edbc8f9ff579aa1d1fac51c082a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:54:28 -0700 Subject: [PATCH 20/37] chore(deps): bump @visx/responsive from 3.12.0 to 4.0.0 in /superset-frontend/packages/superset-ui-core (#41224) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evan Rusackas Co-authored-by: Claude Opus 4.8 --- superset-frontend/package-lock.json | 17 ++++++++++++++++- .../packages/superset-ui-core/package.json | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 56c9d5c7fc1..5846cbcd437 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -45396,7 +45396,7 @@ "@babel/runtime": "^7.29.7", "@braintree/sanitize-url": "^7.1.2", "@types/json-bigint": "^1.0.4", - "@visx/responsive": "^3.12.0", + "@visx/responsive": "^4.0.0", "ace-builds": "^1.44.0", "ag-grid-community": "35.3.1", "ag-grid-react": "35.3.1", @@ -45511,6 +45511,21 @@ "react-dom": ">=16.0.0" } }, + "packages/superset-ui-core/node_modules/@visx/responsive": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-4.0.0.tgz", + "integrity": "sha512-MGPK8AeiBIhzz34o9TNJIyUDQIdWEj5mt+U/Je4qVRRXpXSMhor1IE7v71czAS5b90OrFxC9L3w27AV+szG25w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "packages/superset-ui-core/node_modules/d3-format": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", diff --git a/superset-frontend/packages/superset-ui-core/package.json b/superset-frontend/packages/superset-ui-core/package.json index d247a587c88..a148bd6bd6f 100644 --- a/superset-frontend/packages/superset-ui-core/package.json +++ b/superset-frontend/packages/superset-ui-core/package.json @@ -29,7 +29,7 @@ "@babel/runtime": "^7.29.7", "@braintree/sanitize-url": "^7.1.2", "@types/json-bigint": "^1.0.4", - "@visx/responsive": "^3.12.0", + "@visx/responsive": "^4.0.0", "ace-builds": "^1.44.0", "ag-grid-community": "35.3.1", "ag-grid-react": "35.3.1", From 919bd35028887803c1722c8ee5267b17d5180853 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 10:02:35 -0700 Subject: [PATCH 21/37] chore(deps): bump marshmallow from 3.26.2 to 4.3.0 (#39751) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evan Co-authored-by: Claude Sonnet 4.6 Co-authored-by: Amin Ghadersohi --- pyproject.toml | 6 +- requirements/base.in | 9 +- requirements/base.txt | 4 +- requirements/development.txt | 4 +- superset/app.py | 3 + superset/charts/schemas.py | 4 +- superset/databases/schemas.py | 2 +- superset/marshmallow_compatibility.py | 88 ++++++++++ superset/reports/schemas.py | 6 +- superset/themes/schemas.py | 10 +- tests/unit_tests/dashboards/api_test.py | 5 + tests/unit_tests/test_marshmallow4_compat.py | 164 +++++++++++++++++++ 12 files changed, 285 insertions(+), 20 deletions(-) create mode 100644 superset/marshmallow_compatibility.py create mode 100644 tests/unit_tests/test_marshmallow4_compat.py diff --git a/pyproject.toml b/pyproject.toml index 3facbd4555c..b5f540c0433 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,8 +67,10 @@ dependencies = [ "jsonpath-ng>=1.8.0, <2", "Mako>=1.2.2", "markdown>=3.10.2", - # marshmallow>=4 has issues: https://github.com/apache/superset/issues/33162 - "marshmallow>=3.0, <4", + # marshmallow 4 compatibility: see superset/marshmallow_compatibility.py for a + # Flask-AppBuilder workaround. Tracking issue: + # https://github.com/apache/superset/issues/33162 + "marshmallow>=3.0, <5", "marshmallow-union>=0.1", "msgpack>=1.0.0, <1.2", "nh3>=0.3.5, <0.4", diff --git a/requirements/base.in b/requirements/base.in index b34d4afc04a..374c8d19469 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -44,11 +44,10 @@ async_timeout>=4.0.0,<5.0.0 # a bit of attention to bump. apispec>=6.0.0,<6.7.0 -# 1.4.1 appears to use much more memory, where the python test suite runs out of memory -# causing CI to fail. 1.4.0 is the last version that works. -# https://marshmallow-sqlalchemy.readthedocs.io/en/latest/changelog.html#id3 -# Opened this issue https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues/665 -marshmallow-sqlalchemy>=1.3.0,<1.4.1 +# 1.4.1 introduced a memory regression that exhausts memory in the test suite +# (https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues/665). 1.4.2 +# claimed a fix but did not address the root cause; only 1.5.0 actually fixes it. +marshmallow-sqlalchemy>=1.5.0 # needed for python 3.12 support openapi-schema-validator>=0.6.3 diff --git a/requirements/base.txt b/requirements/base.txt index a60bddc7378..e8ec36d67a8 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -223,13 +223,13 @@ markupsafe==3.0.2 # mako # werkzeug # wtforms -marshmallow==3.26.2 +marshmallow==4.3.0 # via # apache-superset (pyproject.toml) # flask-appbuilder # marshmallow-sqlalchemy # marshmallow-union -marshmallow-sqlalchemy==1.4.0 +marshmallow-sqlalchemy==1.5.0 # via # -r requirements/base.in # flask-appbuilder diff --git a/requirements/development.txt b/requirements/development.txt index c948d7e80bc..cabef0499f4 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -527,14 +527,14 @@ markupsafe==3.0.2 # mako # werkzeug # wtforms -marshmallow==3.26.2 +marshmallow==4.3.0 # via # -c requirements/base-constraint.txt # apache-superset # flask-appbuilder # marshmallow-sqlalchemy # marshmallow-union -marshmallow-sqlalchemy==1.4.0 +marshmallow-sqlalchemy==1.5.0 # via # -c requirements/base-constraint.txt # flask-appbuilder diff --git a/superset/app.py b/superset/app.py index e8671c4f88e..391d633488d 100644 --- a/superset/app.py +++ b/superset/app.py @@ -41,6 +41,9 @@ from superset.extensions.local_extensions_watcher import ( start_local_extensions_watcher_thread, ) from superset.initialization import SupersetAppInitializer +from superset.marshmallow_compatibility import patch_marshmallow_for_flask_appbuilder + +patch_marshmallow_for_flask_appbuilder() logger = logging.getLogger(__name__) diff --git a/superset/charts/schemas.py b/superset/charts/schemas.py index 26e2470fbff..1e514a20950 100644 --- a/superset/charts/schemas.py +++ b/superset/charts/schemas.py @@ -855,7 +855,9 @@ class ChartDataPivotOptionsSchema(ChartDataPostProcessingOperationOptionsSchema) fields.String(allow_none=False), metadata={"description": "Columns to group by on the table columns"}, ) - metric_fill_value = fields.Number( + # `fields.Number` became abstract in marshmallow 4; use `Float`, which + # preserves the previous "any numeric value" semantics for this field. + metric_fill_value = fields.Float( metadata={ "description": "Value to replace missing values with in " "aggregate calculations." diff --git a/superset/databases/schemas.py b/superset/databases/schemas.py index ce4cbda151f..32a949eec0d 100644 --- a/superset/databases/schemas.py +++ b/superset/databases/schemas.py @@ -1208,7 +1208,7 @@ class DelimitedListField(fields.List): class BaseUploadFilePostSchemaMixin(Schema): @validates("file") - def validate_file_extension(self, file: FileStorage) -> None: + def validate_file_extension(self, file: FileStorage, **kwargs: Any) -> None: allowed_extensions = current_app.config["ALLOWED_EXTENSIONS"] file_suffix = Path(file.filename).suffix if not file_suffix: diff --git a/superset/marshmallow_compatibility.py b/superset/marshmallow_compatibility.py new file mode 100644 index 00000000000..852627b4085 --- /dev/null +++ b/superset/marshmallow_compatibility.py @@ -0,0 +1,88 @@ +# 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. + +""" +Marshmallow 4.x compatibility patch for Flask-AppBuilder. + +Flask-AppBuilder auto-generates schema classes (via +``Model2SchemaConverter._meta_schema_factory``) whose ``Meta.fields`` reference +SQLAlchemy relationship names that are never declared as marshmallow fields. + +Marshmallow 3 tolerated this: ``_init_fields`` resolved each name with +``declared_fields.get(name, Inferred())``. Marshmallow 4 made the lookup strict +(``declared_fields[name]``) and raises ``KeyError`` for those names. This patch +restores the lenient behaviour by stubbing the missing FAB names with ``Raw`` +fields before ``_init_fields`` runs. +""" + +import logging +from typing import Any + +logger = logging.getLogger(__name__) + + +def patch_marshmallow_for_flask_appbuilder() -> None: + """Apply a compatibility patch to marshmallow for Flask-AppBuilder. + + Wraps ``marshmallow.Schema._init_fields`` so that any name referenced by a + schema's ``Meta.fields``/``Meta.additional`` that is not backed by a declared + field is stubbed with a ``Raw`` field. This mirrors marshmallow 3 semantics + and keeps Flask-AppBuilder's auto-generated schemas working under + marshmallow 4, where the field lookup became strict. + + The stubbing happens in a single pass per instantiation (no retry loop), so + it stays cheap even though FAB mints a fresh schema class on every call and + marshmallow rebuilds ``declared_fields`` for every instance. + + The patch is idempotent and will not apply twice. + """ + import marshmallow + + if getattr(marshmallow.Schema._init_fields, "_fab_patched", False): + return # already patched + + original_init_fields = marshmallow.Schema._init_fields + + def patched_init_fields(self: "marshmallow.Schema") -> Any: + opts = self.opts + # ``_init_fields`` iterates Meta.fields (falling back to declared field + # names) plus Meta.additional, then strictly looks each up in + # ``declared_fields``. Pre-stub the FAB relationship names it would + # otherwise choke on; unknown non-FAB names are left to raise so genuine + # schema bugs still surface. + candidates = set(opts.fields or ()) | set(getattr(opts, "additional", ()) or ()) + for name in candidates: + if name not in self.declared_fields and _looks_like_fab_field(name): + logger.debug( + "marshmallow FAB compat: stubbing Raw field for %r on %s", + name, + type(self).__name__, + ) + self.declared_fields[name] = marshmallow.fields.Raw() + return original_init_fields(self) + + patched_init_fields._fab_patched = True # type: ignore[attr-defined] + marshmallow.Schema._init_fields = patched_init_fields + + +def _looks_like_fab_field(name: str) -> bool: + """Return True if the field name looks like a FAB auto-generated relationship field. + + FAB generates fields like 'related_model', 'parent_id', etc. + These are typically snake_case and don't start with underscore. + """ + return bool(name) and not name.startswith("_") and name.replace("_", "").isalnum() diff --git a/superset/reports/schemas.py b/superset/reports/schemas.py index 8f7314d2aa1..5bc1516bae6 100644 --- a/superset/reports/schemas.py +++ b/superset/reports/schemas.py @@ -270,13 +270,14 @@ class ReportSchedulePostSchema(Schema): }, allow_none=True, required=False, - default=None, + dump_default=None, ) @validates("custom_width") def validate_custom_width( self, value: Optional[int], + **kwargs: Any, ) -> None: if value is None: return @@ -432,13 +433,14 @@ class ReportSchedulePutSchema(Schema): }, allow_none=True, required=False, - default=None, + dump_default=None, ) @validates("custom_width") def validate_custom_width( self, value: Optional[int], + **kwargs: Any, ) -> None: if value is None: return diff --git a/superset/themes/schemas.py b/superset/themes/schemas.py index 4c7d7c5bf86..eaa40fdd8bf 100644 --- a/superset/themes/schemas.py +++ b/superset/themes/schemas.py @@ -54,7 +54,7 @@ class ImportV1ThemeSchema(Schema): version = fields.String(required=True) @validates("json_data") - def validate_json_data(self, value: dict[str, Any]) -> None: + def validate_json_data(self, value: dict[str, Any], **kwargs: Any) -> None: # Convert dict to JSON string for validation if isinstance(value, dict): json_str = json.dumps(value) @@ -85,12 +85,12 @@ class ThemePostSchema(Schema): json_data = fields.String(required=True, allow_none=False) @validates("theme_name") - def validate_theme_name(self, value: str) -> None: + def validate_theme_name(self, value: str, **kwargs: Any) -> None: if not value or not value.strip(): raise ValidationError("Theme name cannot be empty.") @validates("json_data") - def validate_and_sanitize_json_data(self, value: str) -> None: + def validate_and_sanitize_json_data(self, value: str, **kwargs: Any) -> None: # Parse JSON try: theme_config = json.loads(value) if isinstance(value, str) else value @@ -112,12 +112,12 @@ class ThemePutSchema(Schema): json_data = fields.String(required=True, allow_none=False) @validates("theme_name") - def validate_theme_name(self, value: str) -> None: + def validate_theme_name(self, value: str, **kwargs: Any) -> None: if not value or not value.strip(): raise ValidationError("Theme name cannot be empty.") @validates("json_data") - def validate_and_sanitize_json_data(self, value: str) -> None: + def validate_and_sanitize_json_data(self, value: str, **kwargs: Any) -> None: # Parse JSON try: theme_config = json.loads(value) if isinstance(value, str) else value diff --git a/tests/unit_tests/dashboards/api_test.py b/tests/unit_tests/dashboards/api_test.py index 5f4c5e680d9..deaa07c456d 100644 --- a/tests/unit_tests/dashboards/api_test.py +++ b/tests/unit_tests/dashboards/api_test.py @@ -25,6 +25,11 @@ from superset.dashboards.schemas import DashboardGetResponseSchema @pytest.fixture def mock_dashboard() -> MagicMock: dash = MagicMock() + # Real Dashboard objects are not subscriptable. Without this, marshmallow's + # get_value reads ``dash["changed_on"]`` (which a MagicMock happily returns + # as another mock) instead of the attribute, and marshmallow 4's DateTime + # field then fails serializing the mock via datetime.isoformat(). + dash.__getitem__.side_effect = TypeError dash.id = 1 dash.slug = "test-slug" dash.url = "/superset/dashboard/test-slug/" diff --git a/tests/unit_tests/test_marshmallow4_compat.py b/tests/unit_tests/test_marshmallow4_compat.py new file mode 100644 index 00000000000..e78611505ac --- /dev/null +++ b/tests/unit_tests/test_marshmallow4_compat.py @@ -0,0 +1,164 @@ +# 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. +"""Regression tests for marshmallow 4.x compatibility. + +Marshmallow 4.x requires **kwargs on @validates-decorated methods and +ships with marshmallow-sqlalchemy >= 1.5.0. These tests confirm that +the codebase handles those requirements correctly. +""" +# pylint: disable=import-outside-toplevel + +from importlib.metadata import version +from unittest.mock import MagicMock + +import marshmallow +import pytest +from marshmallow import ValidationError + + +def test_validates_kwargs_database_schema() -> None: + """Regression: marshmallow 4.x requires **kwargs on @validates methods. + + Without **kwargs on validate_file_extension, marshmallow 4.x passes extra + keyword arguments to the validator and raises TypeError instead of + ValidationError when validating an uploaded file with a bad extension. + """ + from flask import Flask + + from superset.databases.schemas import BaseUploadFilePostSchemaMixin + + app = Flask(__name__) + app.config["ALLOWED_EXTENSIONS"] = {"csv", "json", "parquet", "zip"} + + # Build a minimal schema that inherits the mixin so @validates fires + class TestUploadSchema(BaseUploadFilePostSchemaMixin): + file = marshmallow.fields.Raw() + + schema = TestUploadSchema() + + # Construct a mock FileStorage with a disallowed extension + mock_file = MagicMock() + mock_file.filename = "malware.exe" + + with app.app_context(): + with pytest.raises(ValidationError): + # Must raise ValidationError, not TypeError + schema.load({"file": mock_file}) + + +def test_patch_marshmallow_for_flask_appbuilder_idempotent() -> None: + """Regression: patch_marshmallow_for_flask_appbuilder must be idempotent. + + Calling the patch function more than once must not create nested wrappers. + The _fab_patched sentinel on the patched method guards against re-patching. + """ + import marshmallow as mm + + from superset.marshmallow_compatibility import ( + patch_marshmallow_for_flask_appbuilder, + ) + + # Capture the state of _init_fields before the first call + original_init_fields = mm.Schema._init_fields + + patch_marshmallow_for_flask_appbuilder() + after_first = mm.Schema._init_fields + assert getattr(after_first, "_fab_patched", False), ( + "Expected _init_fields to be marked _fab_patched after first call" + ) + + patch_marshmallow_for_flask_appbuilder() + after_second = mm.Schema._init_fields + assert after_second is after_first, ( + "Expected _init_fields to be unchanged after second call (idempotent)" + ) + + # Restore original to avoid side-effects on other tests + mm.Schema._init_fields = original_init_fields + + +@pytest.mark.skipif( + tuple(int(p) for p in version("marshmallow").split(".")[:1]) < (4,), + reason="FAB _init_fields KeyError only occurs on marshmallow >= 4", +) +def test_fab_field_stubbing_is_single_pass() -> None: + """Regression: FAB compat must stub missing fields in one pass per instance. + + Flask-AppBuilder mints a fresh schema class on every call and marshmallow + rebuilds ``declared_fields`` for every instance, so any approach that re-runs + ``_init_fields`` on KeyError (a retry loop) re-pays its cost on every single + instantiation. Under coverage tracing that blew the unit-test job past its + timeout. The patch must instead stub the undeclared FAB names before the + original runs, so ``_init_fields`` executes exactly once per instance. + """ + import marshmallow as mm + + from superset.marshmallow_compatibility import ( + patch_marshmallow_for_flask_appbuilder, + ) + + # Count invocations of the underlying (pre-patch) _init_fields, then patch. + base_init_fields = mm.Schema._init_fields + calls = {"n": 0} + + def counting(self: mm.Schema) -> object: + calls["n"] += 1 + return base_init_fields(self) + + mm.Schema._init_fields = counting + try: + patch_marshmallow_for_flask_appbuilder() + + # FAB-style schema: Meta.fields references undeclared relationship names, + # which marshmallow 4.x rejects with KeyError. + class FabStyleSchema(mm.Schema): + a = mm.fields.String() + + class Meta: + fields = ("a", "related_model", "owner", "parent_id") + + calls["n"] = 0 + for _ in range(50): + FabStyleSchema() + # Exactly one underlying _init_fields per instance — no retry blowup. + assert calls["n"] == 50, ( + f"expected 50 _init_fields calls for 50 instances, got {calls['n']} " + "— single-pass stubbing regressed into a retry loop" + ) + + # The undeclared FAB names resolve to Raw stubs in the built field set. + instance = FabStyleSchema() + assert isinstance(instance.fields["related_model"], mm.fields.Raw) + finally: + mm.Schema._init_fields = base_init_fields + + +def test_marshmallow_sqlalchemy_version() -> None: + """Regression: marshmallow-sqlalchemy >= 1.5.0 is required. + + marshmallow 4.x needs marshmallow-sqlalchemy >= 1.4.x, but 1.4.1/1.4.2 carry + a memory regression (issue #665) that exhausts memory in the test suite; only + 1.5.0 fixes it. This test ensures the installed version is recent enough. + """ + import marshmallow_sqlalchemy # noqa: F401 # import to confirm it's installed + + installed = version("marshmallow-sqlalchemy") + parts = [int(x) for x in installed.split(".")[:3]] + minimum = [1, 5, 0] + assert parts >= minimum, ( + f"marshmallow-sqlalchemy {installed} is too old; need >= 1.5.0" + ) From 141f04510403f00ed06edd1778e759978bfe4efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Meyer?= <144404621+AndreMeyerr@users.noreply.github.com> Date: Fri, 19 Jun 2026 14:09:53 -0300 Subject: [PATCH 22/37] test: add unit tests for get_current_user (superset/tasks/utils.py) (#40878) Co-authored-by: Evan Rusackas --- tests/unit_tests/tasks/test_utils.py | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/unit_tests/tasks/test_utils.py b/tests/unit_tests/tasks/test_utils.py index e0ca86b107c..3fd99057e07 100644 --- a/tests/unit_tests/tasks/test_utils.py +++ b/tests/unit_tests/tasks/test_utils.py @@ -19,6 +19,7 @@ from contextlib import nullcontext from dataclasses import dataclass from enum import Enum from typing import Any, Optional, Union +from unittest.mock import MagicMock, patch import pytest from flask_appbuilder.security.sqla.models import User @@ -29,6 +30,7 @@ from superset.tasks.types import Executor, ExecutorType, FixedExecutor from superset.tasks.utils import ( error_update, get_active_dedup_key, + get_current_user, get_finished_dedup_key, parse_properties, progress_update, @@ -579,3 +581,37 @@ def test_properties_roundtrip(): serialized = serialize_properties(original) parsed = parse_properties(serialized) assert parsed == original + + +class TestGetCurrentUser: + """Tests for get_current_user.""" + + def test_returns_none_when_g_has_no_user_attribute(self) -> None: + """Return None when g has no 'user' attribute.""" + with patch("superset.tasks.utils.g", MagicMock(spec=[])): + assert get_current_user() is None + + @patch("superset.tasks.utils.g") + def test_returns_none_when_g_user_is_none(self, mock_g: MagicMock) -> None: + """Return None when g.user is None.""" + mock_g.user = None + assert get_current_user() is None + + @patch("superset.tasks.utils.g") + def test_returns_none_when_user_is_anonymous(self, mock_g: MagicMock) -> None: + """Return None when g.user is anonymous.""" + mock_user = MagicMock() + mock_user.is_anonymous = True + mock_g.user = mock_user + assert get_current_user() is None + + @patch("superset.tasks.utils.g") + def test_returns_username_when_user_is_authenticated( + self, mock_g: MagicMock + ) -> None: + """Return the username when g.user is authenticated.""" + mock_user = MagicMock() + mock_user.is_anonymous = False + mock_user.username = "admin" + mock_g.user = mock_user + assert get_current_user() == "admin" From 97659678f9bcc00f7d3e5875f7ea8206b78c4cc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 10:10:36 -0700 Subject: [PATCH 23/37] chore(deps): bump simple-zstd from 1.4.2 to 2.1.0 in /superset-frontend (#39369) Co-authored-by: Claude Code --- superset-frontend/package-lock.json | 120 ++++------------------ superset-frontend/package.json | 2 +- superset-frontend/webpack.proxy-config.js | 18 +++- 3 files changed, 33 insertions(+), 107 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 5846cbcd437..f495879010d 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -148,7 +148,7 @@ "redux-undo": "^1.0.0-beta9-9-7", "rison": "^0.1.1", "scroll-into-view-if-needed": "^3.1.0", - "simple-zstd": "^1.4.2", + "simple-zstd": "^2.1.0", "stream-browserify": "^3.0.0", "tinycolor2": "^1.4.2", "urijs": "^1.19.8", @@ -19084,12 +19084,6 @@ "node": ">= 0.4" } }, - "node_modules/duplex-maker": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/duplex-maker/-/duplex-maker-1.0.0.tgz", - "integrity": "sha512-KoHuzggxg7f+vvjqOHfXxaQYI1POzBm+ah0eec7YDssZmbt6QFBI8d1nl5GQwAgR2f+VQCPvyvZtmWWqWuFtlA==", - "license": "MIT" - }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -19135,54 +19129,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/duplexify/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, - "node_modules/duplexify/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/duplexify/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, - "node_modules/duplexify/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/earcut": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", @@ -19334,6 +19280,7 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, "license": "MIT", "dependencies": { "once": "^1.4.0" @@ -34187,17 +34134,6 @@ "pbf": "bin/pbf" } }, - "node_modules/peek-stream": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz", - "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "duplexify": "^3.5.0", - "through2": "^2.0.3" - } - }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -35234,19 +35170,6 @@ "node": ">=8" } }, - "node_modules/process-streams": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/process-streams/-/process-streams-1.0.3.tgz", - "integrity": "sha512-xkIaM5vYnyekB88WyET78YEqXiaJRy0xcvIdE22n+myhvBT7LlLmX6iAtq7jDvVH8CUx2rqQsd32JdRyJMV3NA==", - "funding": [ - "https://www.paypal.com/donate/?hosted_button_id=GB656ZSAEQEXN", - "https://de.liberapay.com/nils.knappmeier/" - ], - "license": "MIT", - "dependencies": { - "duplex-maker": "^1.0.0" - } - }, "node_modules/proggy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/proggy/-/proggy-3.0.0.tgz", @@ -39150,24 +39073,17 @@ "license": "MIT" }, "node_modules/simple-zstd": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/simple-zstd/-/simple-zstd-1.4.2.tgz", - "integrity": "sha512-kGYEvT33M5XfyQvvW4wxl3eKcWbdbCc1V7OZzuElnaXft0qbVzoIIXHXiCm3JCUki+MZKKmvjl8p2VGLJc5Y/A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/simple-zstd/-/simple-zstd-2.1.0.tgz", + "integrity": "sha512-pYzmKWl167db0EHoczlsSpmyjvZ7OinXciHicDEtlHjSKZlo1hPz6tXSyOfS84QIrbWPYT0XW9tx24YtGdQ6cA==", "license": "MIT", "dependencies": { + "debug": "^4.3.4", "is-zst": "^1.0.0", - "peek-stream": "^1.1.3", - "process-streams": "^1.0.1", - "through2": "^4.0.2" - } - }, - "node_modules/simple-zstd/node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "license": "MIT", - "dependencies": { - "readable-stream": "3" + "tmp-promise": "^3.0.3" + }, + "engines": { + "node": ">=22.0.0" } }, "node_modules/sirv": { @@ -40124,12 +40040,6 @@ "readable-stream": "^3.5.0" } }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "license": "MIT" - }, "node_modules/streamx": { "version": "2.21.1", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.1.tgz", @@ -41133,12 +41043,20 @@ "version": "0.2.7", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", - "dev": true, "license": "MIT", "engines": { "node": ">=14.14" } }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "license": "MIT", + "dependencies": { + "tmp": "^0.2.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 89d69d07370..32f0078ce40 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -231,7 +231,7 @@ "redux-undo": "^1.0.0-beta9-9-7", "rison": "^0.1.1", "scroll-into-view-if-needed": "^3.1.0", - "simple-zstd": "^1.4.2", + "simple-zstd": "^2.1.0", "stream-browserify": "^3.0.0", "tinycolor2": "^1.4.2", "urijs": "^1.19.8", diff --git a/superset-frontend/webpack.proxy-config.js b/superset-frontend/webpack.proxy-config.js index a5bc6bc091b..8fb51bca3e3 100644 --- a/superset-frontend/webpack.proxy-config.js +++ b/superset-frontend/webpack.proxy-config.js @@ -17,7 +17,7 @@ * under the License. */ const zlib = require('zlib'); -const { ZSTDDecompress } = require('simple-zstd'); +const { decompress: zstdDecompress } = require('simple-zstd'); const yargs = require('yargs'); const { hideBin } = require('yargs/helpers'); @@ -117,13 +117,13 @@ function copyHeaders(originalResponse, response) { * Manipulate HTML server response to replace asset files with * local webpack-dev-server build. */ -function processHTML(proxyResponse, response) { +async function processHTML(proxyResponse, response) { let body = Buffer.from([]); let originalResponse = proxyResponse; - let uncompress; const responseEncoding = originalResponse.headers['content-encoding']; // decode GZIP response + let uncompress; if (responseEncoding === 'gzip') { uncompress = zlib.createGunzip(); } else if (responseEncoding === 'br') { @@ -131,7 +131,7 @@ function processHTML(proxyResponse, response) { } else if (responseEncoding === 'deflate') { uncompress = zlib.createInflate(); } else if (responseEncoding === 'zstd') { - uncompress = ZSTDDecompress(); + uncompress = await zstdDecompress(); } if (uncompress) { originalResponse.pipe(uncompress); @@ -178,7 +178,15 @@ module.exports = newManifest => { // For HTML responses, flush headers before processing starts // processHTML sets up async handlers that will call response.end() response.flushHeaders(); - processHTML(proxyResponse, response); + processHTML(proxyResponse, response).catch(e => { + // eslint-disable-next-line no-console + console.error(`Error requesting ${request.path} from proxy:`, e); + if (!response.writableEnded) { + response.end( + `Error requesting ${request.path} from proxy: ${e.message}`, + ); + } + }); } else { const isCSV = (proxyResponse.headers['content-type'] || '').includes( 'text/csv', From fe017d0b2039a1bb4b6570ff2839a7b87f652200 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 11:04:20 -0700 Subject: [PATCH 24/37] chore(deps): bump @visx/responsive from 3.12.0 to 4.0.0 in /superset-frontend (#41239) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 82 ++++------------------------- superset-frontend/package.json | 2 +- 2 files changed, 12 insertions(+), 72 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index f495879010d..ddd5456a6e8 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -77,7 +77,7 @@ "@types/react-google-recaptcha": "^2.1.9", "@visx/axis": "^4.0.0", "@visx/grid": "^3.5.0", - "@visx/responsive": "^3.0.0", + "@visx/responsive": "^4.0.0", "@visx/scale": "^3.5.0", "@visx/tooltip": "^4.0.0", "@visx/xychart": "^4.0.0", @@ -13557,18 +13557,18 @@ } }, "node_modules/@visx/responsive": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-3.12.0.tgz", - "integrity": "sha512-GV1BTYwAGlk/K5c9vH8lS2syPnTuIqEacI7L6LRPbsuaLscXMNi+i9fZyzo0BWvAdtRV8v6Urzglo++lvAXT1Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-4.0.0.tgz", + "integrity": "sha512-MGPK8AeiBIhzz34o9TNJIyUDQIdWEj5mt+U/Je4qVRRXpXSMhor1IE7v71czAS5b90OrFxC9L3w27AV+szG25w==", "license": "MIT", - "dependencies": { - "@types/lodash": "^4.14.172", - "@types/react": "*", - "lodash": "^4.17.21", - "prop-types": "^15.6.1" - }, "peerDependencies": { - "react": "^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@visx/scale": { @@ -13869,21 +13869,6 @@ "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", "license": "MIT" }, - "node_modules/@visx/xychart/node_modules/@visx/responsive": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-4.0.0.tgz", - "integrity": "sha512-MGPK8AeiBIhzz34o9TNJIyUDQIdWEj5mt+U/Je4qVRRXpXSMhor1IE7v71czAS5b90OrFxC9L3w27AV+szG25w==", - "license": "MIT", - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@visx/xychart/node_modules/@visx/scale": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", @@ -26937,21 +26922,6 @@ } } }, - "node_modules/jsdom/node_modules/@noble/hashes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", - "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/jsdom/node_modules/css-tree": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", @@ -44071,21 +44041,6 @@ } } }, - "node_modules/whatwg-url/node_modules/@noble/hashes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", - "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/whatwg-url/node_modules/webidl-conversions": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", @@ -45429,21 +45384,6 @@ "react-dom": ">=16.0.0" } }, - "packages/superset-ui-core/node_modules/@visx/responsive": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-4.0.0.tgz", - "integrity": "sha512-MGPK8AeiBIhzz34o9TNJIyUDQIdWEj5mt+U/Je4qVRRXpXSMhor1IE7v71czAS5b90OrFxC9L3w27AV+szG25w==", - "license": "MIT", - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "packages/superset-ui-core/node_modules/d3-format": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 32f0078ce40..ed1e3e0a00d 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -160,7 +160,7 @@ "@types/react-google-recaptcha": "^2.1.9", "@visx/axis": "^4.0.0", "@visx/grid": "^3.5.0", - "@visx/responsive": "^3.0.0", + "@visx/responsive": "^4.0.0", "@visx/scale": "^3.5.0", "@visx/tooltip": "^4.0.0", "@visx/xychart": "^4.0.0", From 9e130e5927ecff6e8f97da617a695af9d17ce164 Mon Sep 17 00:00:00 2001 From: Vitor Avila <96086495+Vitor-Avila@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:07:24 -0300 Subject: [PATCH 25/37] fix(chart): preserve SQL_QUERY_MUTATOR line comments structure (#41215) --- superset/models/core.py | 5 ++++- tests/unit_tests/models/core_test.py | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/superset/models/core.py b/superset/models/core.py index b0d662e3cf0..c98df7ef01a 100755 --- a/superset/models/core.py +++ b/superset/models/core.py @@ -780,8 +780,11 @@ class Database(CoreDatabase, AuditMixinNullable, ImportExportMixin): # pylint: description = None for i, statement in enumerate(script.statements): + # For a single statement, execute the original SQL as-is. Re-rendering + # via statement.format() would round-trip through sqlglot + rendered = sql if len(script.statements) == 1 else statement.format() sql_ = self.mutate_sql_based_on_config( - statement.format(), + rendered, is_split=True, ) _log_query(sql_) diff --git a/tests/unit_tests/models/core_test.py b/tests/unit_tests/models/core_test.py index 0da5055624b..4a22b1564dd 100644 --- a/tests/unit_tests/models/core_test.py +++ b/tests/unit_tests/models/core_test.py @@ -1597,3 +1597,29 @@ def test_clear_bootstrap_cache_logs_warning_on_failure( mock_logger.warning.assert_called_once() call_args = mock_logger.warning.call_args assert call_args[0][0] == "Failed to clear theme bootstrap cache: %s" + + +def test_execute_sql_preserves_line_comments_single_statement( + mocker: MockerFixture, +) -> None: + """ + A single statement is executed verbatim, so the ``--`` line comments added by + ``SQL_QUERY_MUTATOR`` are not round-tripped through sqlglot (which would rewrite + them into ``/* */`` blocks). Regression test for the comment-mangling bug. + """ + database = Database(database_name="db", sqlalchemy_uri="sqlite://") + mocker.patch.object(database, "get_sqla_engine") + mocker.patch.object(database, "get_raw_connection") + mocker.patch.object(database.db_engine_spec, "fetch_data", return_value=[]) + # Identity mutator so the test isolates whether the SQL got reformatted. + mocker.patch.object( + database, "mutate_sql_based_on_config", side_effect=lambda sql, **kwargs: sql + ) + execute = mocker.patch.object(database.db_engine_spec, "execute") + + sql = "SELECT 1 AS one\n-- user: alice\n-- company: dunder mifflin" + database._execute_sql_with_mutation_and_logging(sql, fetch_last_result=True) + + executed_sql = execute.call_args.args[1] + assert executed_sql == sql + assert "/*" not in executed_sql From 334b13c3d94c12681f3f66b11d2c56a415e662ce Mon Sep 17 00:00:00 2001 From: Vitor Avila <96086495+Vitor-Avila@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:22:54 -0300 Subject: [PATCH 26/37] fix(chart API): apply dashboard filters by live scope, not stale chartsInScope (#41214) --- .../charts/data/dashboard_filter_context.py | 20 +++++------------- .../charts/test_dashboard_filter_context.py | 21 +++++++++++++------ .../chart/tool/test_get_chart_info.py | 5 ++++- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/superset/charts/data/dashboard_filter_context.py b/superset/charts/data/dashboard_filter_context.py index fa4227a9c04..b7d745b49bc 100644 --- a/superset/charts/data/dashboard_filter_context.py +++ b/superset/charts/data/dashboard_filter_context.py @@ -80,20 +80,11 @@ def _is_filter_in_scope_for_chart( """ Determines whether a native filter applies to a given chart. - When chartsInScope is present on the filter config, uses that directly. - Otherwise falls back to scope.rootPath and scope.excluded with the - dashboard layout. Also considers charts that were added to the dashboard - but were not instantiated in the layout. + A chart is in scope when one of its layout ancestors is in ``rootPath`` and + it's not excluded. The persisted ``chartsInScope`` is intentionally NOT used + here (it's a denormalized cache that the frontend recomputes from ``scope`` + on every load, so it can be stale). """ - if (charts_in_scope := filter_config.get("chartsInScope")) is not None: - if chart_id in charts_in_scope: - return True - - # If the chart is found in position_json and not in chartsInScope, - # it was explicitly excluded by the filter scope config. - if _find_chart_layout_item(chart_id, position_json) is not None: - return False - scope = filter_config.get("scope", {}) root_path: list[str] = scope.get("rootPath", []) excluded: list[int] = scope.get("excluded", []) @@ -107,8 +98,7 @@ def _is_filter_in_scope_for_chart( # If the chart doesn't exist in the dashboard layout, treat it as a # root-level chart. - else: - return "ROOT_ID" in root_path + return "ROOT_ID" in root_path def _find_chart_layout_item( diff --git a/tests/unit_tests/charts/test_dashboard_filter_context.py b/tests/unit_tests/charts/test_dashboard_filter_context.py index bfc2097f725..3bc062330bf 100644 --- a/tests/unit_tests/charts/test_dashboard_filter_context.py +++ b/tests/unit_tests/charts/test_dashboard_filter_context.py @@ -140,15 +140,24 @@ def test_filter_in_scope_via_charts_in_scope() -> None: assert _is_filter_in_scope_for_chart(flt, 10, SAMPLE_POSITION_JSON) is True -def test_filter_not_in_scope_via_charts_in_scope() -> None: - flt = _make_filter(charts_in_scope=[20, 30]) - assert _is_filter_in_scope_for_chart(flt, 10, SAMPLE_POSITION_JSON) is False +def test_filter_in_scope_ignores_stale_charts_in_scope() -> None: + """ + Regression: a chart present in the layout and within scope.rootPath is in + scope even when the (stale) chartsInScope cache omits it. chartsInScope is a + denormalized cache the frontend recomputes from scope on load (persisted + only on save). + """ + flt = _make_filter(charts_in_scope=[20, 30], scope_root=["ROOT_ID"]) + assert _is_filter_in_scope_for_chart(flt, 10, SAMPLE_POSITION_JSON) is True -def test_filter_empty_charts_in_scope_not_in_scope() -> None: - """Empty chartsInScope means in scope for no charts; do not fall back to rootPath""" +def test_filter_in_scope_ignores_empty_charts_in_scope() -> None: + """ + An empty (stale) chartsInScope must not exclude a chart that scope.rootPath + includes; scope is the source of truth. + """ flt = _make_filter(charts_in_scope=[], scope_root=["ROOT_ID"]) - assert _is_filter_in_scope_for_chart(flt, 10, SAMPLE_POSITION_JSON) is False + assert _is_filter_in_scope_for_chart(flt, 10, SAMPLE_POSITION_JSON) is True def test_filter_in_scope_via_root_path() -> None: diff --git a/tests/unit_tests/mcp_service/chart/tool/test_get_chart_info.py b/tests/unit_tests/mcp_service/chart/tool/test_get_chart_info.py index dc245342c8a..5bcf1ff7ebe 100644 --- a/tests/unit_tests/mcp_service/chart/tool/test_get_chart_info.py +++ b/tests/unit_tests/mcp_service/chart/tool/test_get_chart_info.py @@ -183,6 +183,7 @@ class TestBuildAppliedDashboardFilters: "type": "NATIVE_FILTER", "filterType": "filter_select", "chartsInScope": [1], + "scope": {"rootPath": ["ROOT_ID"], "excluded": []}, "targets": [{"column": {"name": "country"}, "datasetId": 7}], "defaultDataMask": { "filterState": {"value": ["US"]}, @@ -226,7 +227,8 @@ class TestBuildAppliedDashboardFilters: "name": "Region", "type": "NATIVE_FILTER", "filterType": "filter_select", - "chartsInScope": [2, 3], # chart 1 excluded + "chartsInScope": [2, 3], + "scope": {"rootPath": ["ROOT_ID"], "excluded": [1]}, # chart 1 excluded "targets": [{"column": {"name": "region"}, "datasetId": 7}], "defaultDataMask": { "filterState": {"value": ["NA"]}, @@ -257,6 +259,7 @@ class TestBuildAppliedDashboardFilters: "type": "NATIVE_FILTER", "filterType": "filter_select", "chartsInScope": [1], + "scope": {"rootPath": ["ROOT_ID"], "excluded": []}, "targets": [{"column": {"name": "region"}, "datasetId": 7}], "controlValues": {"defaultToFirstItem": True}, "defaultDataMask": {}, From 382a094795ae419a515b08c15de88b7e843662f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 11:39:05 -0700 Subject: [PATCH 27/37] chore(deps): bump @visx/grid from 3.12.0 to 4.0.0 in /superset-frontend (#41240) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 772 +++++++++++----------------- superset-frontend/package.json | 2 +- 2 files changed, 310 insertions(+), 464 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index ddd5456a6e8..263817f5d98 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -76,7 +76,7 @@ "@types/d3-time-format": "^4.0.3", "@types/react-google-recaptcha": "^2.1.9", "@visx/axis": "^4.0.0", - "@visx/grid": "^3.5.0", + "@visx/grid": "^4.0.0", "@visx/responsive": "^4.0.0", "@visx/scale": "^3.5.0", "@visx/tooltip": "^4.0.0", @@ -11303,9 +11303,9 @@ } }, "node_modules/@types/d3-path": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.11.tgz", - "integrity": "sha512-4pQMp8ldf7UaB/gR8Fvvy69psNHkTpD/pVw3vmEi8iZAB9EPMBruB1JvHO4BIq9QkUUd2lV1F5YXpMNj7JPBpw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", "license": "MIT" }, "node_modules/@types/d3-scale": { @@ -11332,12 +11332,12 @@ "license": "MIT" }, "node_modules/@types/d3-shape": { - "version": "1.3.12", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.3.12.tgz", - "integrity": "sha512-8oMzcd4+poSLGgV0R1Q1rOlx/xdmozS4Xab7np0eamFFUYq71AU9pOCJEFnkXW2aI/oXdVYJzw6pssbSut7Z9Q==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", "license": "MIT", "dependencies": { - "@types/d3-path": "^1" + "@types/d3-path": "*" } }, "node_modules/@types/d3-time": { @@ -12801,24 +12801,6 @@ } } }, - "node_modules/@visx/annotation/node_modules/@visx/group": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", - "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", - "license": "MIT", - "dependencies": { - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@visx/annotation/node_modules/@visx/text": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", @@ -12882,12 +12864,6 @@ "@types/d3-color": "*" } }, - "node_modules/@visx/axis/node_modules/@types/d3-path": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", - "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", - "license": "MIT" - }, "node_modules/@visx/axis/node_modules/@types/d3-scale": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", @@ -12897,15 +12873,6 @@ "@types/d3-time": "*" } }, - "node_modules/@visx/axis/node_modules/@types/d3-shape": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", - "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", - "license": "MIT", - "dependencies": { - "@types/d3-path": "*" - } - }, "node_modules/@visx/axis/node_modules/@types/d3-time": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", @@ -12918,39 +12885,6 @@ "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", "license": "MIT" }, - "node_modules/@visx/axis/node_modules/@visx/curve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-4.0.0.tgz", - "integrity": "sha512-bXrOSd2BzVCxR7kBE7gPTSU4plxzYN75w7erdHYabwn3vzP+xFk1o0gg3NOHEPJzt5tXqf0Ecm5YqHACOnipTA==", - "license": "MIT", - "dependencies": { - "@visx/vendor": "4.0.0" - } - }, - "node_modules/@visx/axis/node_modules/@visx/group": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", - "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", - "license": "MIT", - "dependencies": { - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@visx/axis/node_modules/@visx/point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", - "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", - "license": "MIT" - }, "node_modules/@visx/axis/node_modules/@visx/scale": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", @@ -12960,28 +12894,6 @@ "@visx/vendor": "4.0.0" } }, - "node_modules/@visx/axis/node_modules/@visx/shape": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-4.0.0.tgz", - "integrity": "sha512-X0FP3OFjQhc5/6Vj2aY7cK2JwKYI0H0hQM7cdNRWy/ZMMlrh5KpEdqx0HVo0KoTeTlkUvO+kydMLnAuuCRFIFw==", - "license": "MIT", - "dependencies": { - "@visx/curve": "4.0.0", - "@visx/group": "4.0.0", - "@visx/scale": "4.0.0", - "@visx/vendor": "4.0.0", - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@visx/axis/node_modules/@visx/text": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", @@ -13032,27 +12944,6 @@ "internmap": "2.0.3" } }, - "node_modules/@visx/axis/node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/@visx/axis/node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "license": "ISC", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@visx/bounds": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/bounds/-/bounds-4.0.0.tgz", @@ -13074,13 +12965,85 @@ } }, "node_modules/@visx/curve": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-3.12.0.tgz", - "integrity": "sha512-Ng1mefXIzoIoAivw7dJ+ZZYYUbfuwXgZCgQynShr6ZIVw7P4q4HeQfJP3W24ON+1uCSrzoycHSXRelhR9SBPcw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-4.0.0.tgz", + "integrity": "sha512-bXrOSd2BzVCxR7kBE7gPTSU4plxzYN75w7erdHYabwn3vzP+xFk1o0gg3NOHEPJzt5tXqf0Ecm5YqHACOnipTA==", "license": "MIT", "dependencies": { - "@types/d3-shape": "^1.3.1", - "d3-shape": "^1.0.6" + "@visx/vendor": "4.0.0" + } + }, + "node_modules/@visx/curve/node_modules/@types/d3-array": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", + "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", + "license": "MIT" + }, + "node_modules/@visx/curve/node_modules/@types/d3-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", + "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", + "license": "MIT" + }, + "node_modules/@visx/curve/node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@visx/curve/node_modules/@types/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@visx/curve/node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", + "license": "MIT" + }, + "node_modules/@visx/curve/node_modules/@types/d3-time-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", + "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", + "license": "MIT" + }, + "node_modules/@visx/curve/node_modules/@visx/vendor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", + "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", + "license": "MIT and ISC", + "dependencies": { + "@types/d3-array": "3.0.3", + "@types/d3-color": "3.1.0", + "@types/d3-delaunay": "6.0.1", + "@types/d3-format": "3.0.1", + "@types/d3-geo": "3.1.0", + "@types/d3-interpolate": "3.0.1", + "@types/d3-path": "3.1.1", + "@types/d3-scale": "4.0.2", + "@types/d3-shape": "3.1.7", + "@types/d3-time": "3.0.0", + "@types/d3-time-format": "2.1.0", + "d3-array": "3.2.1", + "d3-color": "3.1.0", + "d3-delaunay": "6.0.2", + "d3-format": "3.1.0", + "d3-geo": "3.1.0", + "d3-interpolate": "3.0.1", + "d3-path": "3.1.0", + "d3-scale": "4.0.2", + "d3-shape": "3.2.0", + "d3-time": "3.1.0", + "d3-time-format": "4.1.0", + "internmap": "2.0.3" } }, "node_modules/@visx/drag": { @@ -13102,12 +13065,6 @@ } } }, - "node_modules/@visx/drag/node_modules/@visx/point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", - "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", - "license": "MIT" - }, "node_modules/@visx/event": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/event/-/event-4.0.0.tgz", @@ -13126,12 +13083,6 @@ } } }, - "node_modules/@visx/event/node_modules/@visx/point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", - "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", - "license": "MIT" - }, "node_modules/@visx/glyph": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/glyph/-/glyph-4.0.0.tgz", @@ -13173,12 +13124,6 @@ "@types/d3-color": "*" } }, - "node_modules/@visx/glyph/node_modules/@types/d3-path": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", - "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", - "license": "MIT" - }, "node_modules/@visx/glyph/node_modules/@types/d3-scale": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", @@ -13188,15 +13133,6 @@ "@types/d3-time": "*" } }, - "node_modules/@visx/glyph/node_modules/@types/d3-shape": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", - "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", - "license": "MIT", - "dependencies": { - "@types/d3-path": "*" - } - }, "node_modules/@visx/glyph/node_modules/@types/d3-time": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", @@ -13209,24 +13145,6 @@ "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", "license": "MIT" }, - "node_modules/@visx/glyph/node_modules/@visx/group": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", - "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", - "license": "MIT", - "dependencies": { - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@visx/glyph/node_modules/@visx/vendor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", @@ -13258,64 +13176,133 @@ "internmap": "2.0.3" } }, - "node_modules/@visx/glyph/node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/@visx/glyph/node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "license": "ISC", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@visx/grid": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/grid/-/grid-3.12.0.tgz", - "integrity": "sha512-L4ex2ooSYhwNIxJ3XFIKRhoSvEGjPc2Y3YCrtNB4TV5Ofdj4q0UMOsxfrH23Pr8HSHuQhb6VGMgYoK0LuWqDmQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/grid/-/grid-4.0.0.tgz", + "integrity": "sha512-BUnznqYo8jyn3zXRWZiF0zwg1VQl6w5kYqZ+XMY+cPXtAHZZbwGXBChMpPefH5Lj1+P1b4Pf3QihKG8zjL9PCw==", "license": "MIT", "dependencies": { - "@types/react": "*", - "@visx/curve": "3.12.0", - "@visx/group": "3.12.0", - "@visx/point": "3.12.0", - "@visx/scale": "3.12.0", - "@visx/shape": "3.12.0", - "classnames": "^2.3.1", - "prop-types": "^15.6.2" + "@visx/curve": "4.0.0", + "@visx/group": "4.0.0", + "@visx/point": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/shape": "4.0.0", + "classnames": "^2.3.1" }, "peerDependencies": { - "react": "^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/grid/node_modules/@types/d3-array": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", + "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", + "license": "MIT" + }, + "node_modules/@visx/grid/node_modules/@types/d3-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", + "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", + "license": "MIT" + }, + "node_modules/@visx/grid/node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@visx/grid/node_modules/@types/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@visx/grid/node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", + "license": "MIT" + }, + "node_modules/@visx/grid/node_modules/@types/d3-time-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", + "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", + "license": "MIT" + }, + "node_modules/@visx/grid/node_modules/@visx/scale": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", + "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", + "license": "MIT", + "dependencies": { + "@visx/vendor": "4.0.0" + } + }, + "node_modules/@visx/grid/node_modules/@visx/vendor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", + "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", + "license": "MIT and ISC", + "dependencies": { + "@types/d3-array": "3.0.3", + "@types/d3-color": "3.1.0", + "@types/d3-delaunay": "6.0.1", + "@types/d3-format": "3.0.1", + "@types/d3-geo": "3.1.0", + "@types/d3-interpolate": "3.0.1", + "@types/d3-path": "3.1.1", + "@types/d3-scale": "4.0.2", + "@types/d3-shape": "3.1.7", + "@types/d3-time": "3.0.0", + "@types/d3-time-format": "2.1.0", + "d3-array": "3.2.1", + "d3-color": "3.1.0", + "d3-delaunay": "6.0.2", + "d3-format": "3.1.0", + "d3-geo": "3.1.0", + "d3-interpolate": "3.0.1", + "d3-path": "3.1.0", + "d3-scale": "4.0.2", + "d3-shape": "3.2.0", + "d3-time": "3.1.0", + "d3-time-format": "4.1.0", + "internmap": "2.0.3" } }, "node_modules/@visx/group": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/group/-/group-3.12.0.tgz", - "integrity": "sha512-Dye8iS1alVXPv7nj/7M37gJe6sSKqJLH7x6sEWAsRQ9clI0kFvjbKcKgF+U3aAVQr0NCohheFV+DtR8trfK/Ag==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", + "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", "license": "MIT", "dependencies": { - "@types/react": "*", - "classnames": "^2.3.1", - "prop-types": "^15.6.2" + "classnames": "^2.3.1" }, "peerDependencies": { - "react": "^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@visx/point": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/point/-/point-3.12.0.tgz", - "integrity": "sha512-I6UrHoJAEVbx3RORQNupgTiX5EzjuZpiwLPxn8L2mI5nfERotPKi1Yus12Cq2WtXqEBR/WgqTnoImlqOXBykcA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", + "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", "license": "MIT" }, "node_modules/@visx/react-spring": { @@ -13362,12 +13349,6 @@ "@types/d3-color": "*" } }, - "node_modules/@visx/react-spring/node_modules/@types/d3-path": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", - "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", - "license": "MIT" - }, "node_modules/@visx/react-spring/node_modules/@types/d3-scale": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", @@ -13377,15 +13358,6 @@ "@types/d3-time": "*" } }, - "node_modules/@visx/react-spring/node_modules/@types/d3-shape": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", - "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", - "license": "MIT", - "dependencies": { - "@types/d3-path": "*" - } - }, "node_modules/@visx/react-spring/node_modules/@types/d3-time": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", @@ -13398,62 +13370,6 @@ "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", "license": "MIT" }, - "node_modules/@visx/react-spring/node_modules/@visx/curve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-4.0.0.tgz", - "integrity": "sha512-bXrOSd2BzVCxR7kBE7gPTSU4plxzYN75w7erdHYabwn3vzP+xFk1o0gg3NOHEPJzt5tXqf0Ecm5YqHACOnipTA==", - "license": "MIT", - "dependencies": { - "@visx/vendor": "4.0.0" - } - }, - "node_modules/@visx/react-spring/node_modules/@visx/grid": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/grid/-/grid-4.0.0.tgz", - "integrity": "sha512-BUnznqYo8jyn3zXRWZiF0zwg1VQl6w5kYqZ+XMY+cPXtAHZZbwGXBChMpPefH5Lj1+P1b4Pf3QihKG8zjL9PCw==", - "license": "MIT", - "dependencies": { - "@visx/curve": "4.0.0", - "@visx/group": "4.0.0", - "@visx/point": "4.0.0", - "@visx/scale": "4.0.0", - "@visx/shape": "4.0.0", - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@visx/react-spring/node_modules/@visx/group": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", - "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", - "license": "MIT", - "dependencies": { - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@visx/react-spring/node_modules/@visx/point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", - "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", - "license": "MIT" - }, "node_modules/@visx/react-spring/node_modules/@visx/scale": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", @@ -13463,28 +13379,6 @@ "@visx/vendor": "4.0.0" } }, - "node_modules/@visx/react-spring/node_modules/@visx/shape": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-4.0.0.tgz", - "integrity": "sha512-X0FP3OFjQhc5/6Vj2aY7cK2JwKYI0H0hQM7cdNRWy/ZMMlrh5KpEdqx0HVo0KoTeTlkUvO+kydMLnAuuCRFIFw==", - "license": "MIT", - "dependencies": { - "@visx/curve": "4.0.0", - "@visx/group": "4.0.0", - "@visx/scale": "4.0.0", - "@visx/vendor": "4.0.0", - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@visx/react-spring/node_modules/@visx/text": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", @@ -13535,27 +13429,6 @@ "internmap": "2.0.3" } }, - "node_modules/@visx/react-spring/node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/@visx/react-spring/node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "license": "ISC", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@visx/responsive": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-4.0.0.tgz", @@ -13581,26 +13454,107 @@ } }, "node_modules/@visx/shape": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-3.12.0.tgz", - "integrity": "sha512-/1l0lrpX9tPic6SJEalryBKWjP/ilDRnQA+BGJTI1tj7i23mJ/J0t4nJHyA1GrL4QA/bM/qTJ35eyz5dEhJc4g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-4.0.0.tgz", + "integrity": "sha512-X0FP3OFjQhc5/6Vj2aY7cK2JwKYI0H0hQM7cdNRWy/ZMMlrh5KpEdqx0HVo0KoTeTlkUvO+kydMLnAuuCRFIFw==", "license": "MIT", "dependencies": { - "@types/d3-path": "^1.0.8", - "@types/d3-shape": "^1.3.1", - "@types/lodash": "^4.14.172", - "@types/react": "*", - "@visx/curve": "3.12.0", - "@visx/group": "3.12.0", - "@visx/scale": "3.12.0", - "classnames": "^2.3.1", - "d3-path": "^1.0.5", - "d3-shape": "^1.2.0", - "lodash": "^4.17.21", - "prop-types": "^15.5.10" + "@visx/curve": "4.0.0", + "@visx/group": "4.0.0", + "@visx/scale": "4.0.0", + "@visx/vendor": "4.0.0", + "classnames": "^2.3.1" }, "peerDependencies": { - "react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" + "@types/react": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@visx/shape/node_modules/@types/d3-array": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", + "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", + "license": "MIT" + }, + "node_modules/@visx/shape/node_modules/@types/d3-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", + "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", + "license": "MIT" + }, + "node_modules/@visx/shape/node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@visx/shape/node_modules/@types/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@visx/shape/node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", + "license": "MIT" + }, + "node_modules/@visx/shape/node_modules/@types/d3-time-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", + "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", + "license": "MIT" + }, + "node_modules/@visx/shape/node_modules/@visx/scale": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", + "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", + "license": "MIT", + "dependencies": { + "@visx/vendor": "4.0.0" + } + }, + "node_modules/@visx/shape/node_modules/@visx/vendor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", + "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", + "license": "MIT and ISC", + "dependencies": { + "@types/d3-array": "3.0.3", + "@types/d3-color": "3.1.0", + "@types/d3-delaunay": "6.0.1", + "@types/d3-format": "3.0.1", + "@types/d3-geo": "3.1.0", + "@types/d3-interpolate": "3.0.1", + "@types/d3-path": "3.1.1", + "@types/d3-scale": "4.0.2", + "@types/d3-shape": "3.1.7", + "@types/d3-time": "3.0.0", + "@types/d3-time-format": "2.1.0", + "d3-array": "3.2.1", + "d3-color": "3.1.0", + "d3-delaunay": "6.0.2", + "d3-format": "3.1.0", + "d3-geo": "3.1.0", + "d3-interpolate": "3.0.1", + "d3-path": "3.1.0", + "d3-scale": "4.0.2", + "d3-shape": "3.2.0", + "d3-time": "3.1.0", + "d3-time-format": "4.1.0", + "internmap": "2.0.3" } }, "node_modules/@visx/tooltip": { @@ -13777,12 +13731,6 @@ "@types/d3-color": "*" } }, - "node_modules/@visx/xychart/node_modules/@types/d3-path": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", - "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", - "license": "MIT" - }, "node_modules/@visx/xychart/node_modules/@types/d3-scale": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", @@ -13792,15 +13740,6 @@ "@types/d3-time": "*" } }, - "node_modules/@visx/xychart/node_modules/@types/d3-shape": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", - "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", - "license": "MIT", - "dependencies": { - "@types/d3-path": "*" - } - }, "node_modules/@visx/xychart/node_modules/@types/d3-time": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", @@ -13813,62 +13752,6 @@ "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", "license": "MIT" }, - "node_modules/@visx/xychart/node_modules/@visx/curve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/curve/-/curve-4.0.0.tgz", - "integrity": "sha512-bXrOSd2BzVCxR7kBE7gPTSU4plxzYN75w7erdHYabwn3vzP+xFk1o0gg3NOHEPJzt5tXqf0Ecm5YqHACOnipTA==", - "license": "MIT", - "dependencies": { - "@visx/vendor": "4.0.0" - } - }, - "node_modules/@visx/xychart/node_modules/@visx/grid": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/grid/-/grid-4.0.0.tgz", - "integrity": "sha512-BUnznqYo8jyn3zXRWZiF0zwg1VQl6w5kYqZ+XMY+cPXtAHZZbwGXBChMpPefH5Lj1+P1b4Pf3QihKG8zjL9PCw==", - "license": "MIT", - "dependencies": { - "@visx/curve": "4.0.0", - "@visx/group": "4.0.0", - "@visx/point": "4.0.0", - "@visx/scale": "4.0.0", - "@visx/shape": "4.0.0", - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@visx/xychart/node_modules/@visx/group": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", - "integrity": "sha512-HGAq8BCqn5x0t94CJOLJeKtWss9LFpF3HY69HbuO1PlR+B9c4aVT9xbjfudmU8wGQZLT6JNt+PJvxbO2aJ+1aA==", - "license": "MIT", - "dependencies": { - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@visx/xychart/node_modules/@visx/point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/point/-/point-4.0.0.tgz", - "integrity": "sha512-hwJ9UlIjg3iV4iiJ3RN5SNTXama+zGaNe57sXSrSvPiqhkDXypsYBdDSlAnHmKbMzHP0zFmgB1UJciB/QUyigw==", - "license": "MIT" - }, "node_modules/@visx/xychart/node_modules/@visx/scale": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", @@ -13878,28 +13761,6 @@ "@visx/vendor": "4.0.0" } }, - "node_modules/@visx/xychart/node_modules/@visx/shape": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/shape/-/shape-4.0.0.tgz", - "integrity": "sha512-X0FP3OFjQhc5/6Vj2aY7cK2JwKYI0H0hQM7cdNRWy/ZMMlrh5KpEdqx0HVo0KoTeTlkUvO+kydMLnAuuCRFIFw==", - "license": "MIT", - "dependencies": { - "@visx/curve": "4.0.0", - "@visx/group": "4.0.0", - "@visx/scale": "4.0.0", - "@visx/vendor": "4.0.0", - "classnames": "^2.3.1" - }, - "peerDependencies": { - "@types/react": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@visx/xychart/node_modules/@visx/text": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", @@ -13950,27 +13811,6 @@ "internmap": "2.0.3" } }, - "node_modules/@visx/xychart/node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/@visx/xychart/node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "license": "ISC", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@vitest/expect": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", @@ -18083,10 +17923,13 @@ "license": "BSD-3-Clause" }, "node_modules/d3-path": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", - "license": "BSD-3-Clause" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } }, "node_modules/d3-queue": { "version": "2.0.3", @@ -18117,12 +17960,15 @@ "license": "BSD-3-Clause" }, "node_modules/d3-shape": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", - "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", - "license": "BSD-3-Clause", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", "dependencies": { - "d3-path": "1" + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/d3-time": { diff --git a/superset-frontend/package.json b/superset-frontend/package.json index ed1e3e0a00d..8b462477d79 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -159,7 +159,7 @@ "@types/d3-time-format": "^4.0.3", "@types/react-google-recaptcha": "^2.1.9", "@visx/axis": "^4.0.0", - "@visx/grid": "^3.5.0", + "@visx/grid": "^4.0.0", "@visx/responsive": "^4.0.0", "@visx/scale": "^3.5.0", "@visx/tooltip": "^4.0.0", From f1504611fde33d642f0d0b73fc83de3b3d1d3382 Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Fri, 19 Jun 2026 13:01:47 -0700 Subject: [PATCH 28/37] docs(config): document customizing the landing page via FAB_INDEX_VIEW (#41222) Co-authored-by: Claude Opus 4.8 --- .../configuration/configuring-superset.mdx | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/docs/admin_docs/configuration/configuring-superset.mdx b/docs/admin_docs/configuration/configuring-superset.mdx index daf92b1c943..9ef6f075022 100644 --- a/docs/admin_docs/configuration/configuring-superset.mdx +++ b/docs/admin_docs/configuration/configuring-superset.mdx @@ -455,6 +455,51 @@ def FLASK_APP_MUTATOR(app: Flask) -> None: app.before_request_funcs.setdefault(None, []).append(make_session_permanent) ``` +## Customizing the landing page (index view) + +The page served at `/` is rendered by an index view. By default Superset registers +`SupersetIndexView`, which redirects to `/superset/welcome/` and also adds the +`/lang/` locale handler. You can replace it with your own view, for example +to send users straight to a specific dashboard or to a chart list. + +Set `FAB_INDEX_VIEW` to the **importable dotted path** of your view class. Flask-AppBuilder +resolves this during app initialization and uses it in place of the default: + +```python +# my_overrides.py — must be importable on the PYTHONPATH +from flask import redirect +from superset.initialization import SupersetIndexView +from superset.superset_typing import FlaskResponse +from flask_appbuilder import expose + + +class MyIndexView(SupersetIndexView): + @expose("/") + def index(self) -> FlaskResponse: + return redirect("/chart/list/") +``` + +```python +# superset_config.py +FAB_INDEX_VIEW = "my_overrides.MyIndexView" +``` + +A few things that commonly trip people up: + +- **Subclass `SupersetIndexView`, not Flask-AppBuilder's bare `IndexView`.** Subclassing + keeps Superset's `/lang/` locale handling; replacing it with a bare `IndexView` + silently drops that behavior. +- **The class must be importable as a real module.** `FAB_INDEX_VIEW` is resolved by + importing the dotted path, which is independent of how `superset_config.py` itself is + loaded. Superset only copies **uppercase** names out of `superset_config.py` into its + runtime config, so a `FAB_INDEX_VIEW = "superset_config.MyIndexView"` reference only works + if `superset_config` is itself importable by that name on the `PYTHONPATH`. If you load + config via `SUPERSET_CONFIG_PATH` (an arbitrary file path), put the view in a separate + importable module instead and reference that module. +- **Don't set `appbuilder.indexview` from `FLASK_APP_MUTATOR`.** The mutator runs after + routes are already registered, so the assignment has no effect on the `/` route. Use + `FAB_INDEX_VIEW` instead. + ## Feature Flags To support a diverse set of users, Superset has some features that are not enabled by default. For From b2e5f80db2785e2cd19bfd7792abb1bc5e26c1e5 Mon Sep 17 00:00:00 2001 From: Jean Dupuis <8055061+sitelight@users.noreply.github.com> Date: Fri, 19 Jun 2026 21:02:50 +0100 Subject: [PATCH 29/37] fix(sql): preserve multi-arg DISTINCT in sanitize_clause and format (#39340) --- superset/sql/parse.py | 48 ++++++++++++++++----- tests/unit_tests/sql/parse_tests.py | 66 +++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 11 deletions(-) diff --git a/superset/sql/parse.py b/superset/sql/parse.py index ec46b5850dc..f5f93d34d06 100644 --- a/superset/sql/parse.py +++ b/superset/sql/parse.py @@ -32,9 +32,11 @@ from sqlglot import exp from sqlglot.dialects.dialect import ( Dialect, Dialects, + DialectType, ) from sqlglot.dialects.singlestore import SingleStore from sqlglot.errors import ParseError +from sqlglot.generator import Generator from sqlglot.optimizer.pushdown_predicates import ( pushdown_predicates, ) @@ -137,6 +139,32 @@ class CTASMethod(enum.Enum): VIEW = enum.auto() +def _normalized_generator( + dialect_name: DialectType, + *, + pretty: bool, + comments: bool, +) -> Generator: + """ + Generator that preserves multi-argument DISTINCT expressions. + + Build a sqlglot generator that preserves user-written multi-argument + DISTINCT expressions verbatim. Postgres, Presto, Trino, and DuckDB + set ``MULTI_ARG_DISTINCT = False`` to emulate the unsupported + ``COUNT(DISTINCT a, b)`` idiom via a ``CASE WHEN`` row-expression, which + silently corrupts user-defined aggregates that natively accept multiple + arguments. Superset's sanitize / format paths normalize user SQL — they + do not transpile — so the emulation is undesirable here. + """ + dialect = Dialect.get_or_raise(dialect_name) + normalized_cls = type( + f"Normalized{dialect.generator_class.__name__}", + (dialect.generator_class,), + {"MULTI_ARG_DISTINCT": True}, + ) + return normalized_cls(dialect=dialect, pretty=pretty, comments=comments) + + class RLSMethod(enum.Enum): """ Methods for enforcing RLS. @@ -911,12 +939,11 @@ class SQLStatement(BaseSQLStatement[exp.Expression]): """ Pretty-format the SQL statement. """ - return Dialect.get_or_raise(self._dialect).generate( - self._parsed, - copy=True, - comments=comments, + return _normalized_generator( + self._dialect, pretty=True, - ) + comments=comments, + ).generate(self._parsed, copy=True) def get_settings(self) -> dict[str, str | bool]: """ @@ -1817,14 +1844,13 @@ def sanitize_clause(clause: str, engine: str) -> str: """ try: statement = SQLStatement(clause, engine) - dialect = SQLGLOT_DIALECTS.get(engine) - from sqlglot.dialects.dialect import Dialect - - return Dialect.get_or_raise(dialect).generate( + return _normalized_generator( + SQLGLOT_DIALECTS.get(engine), + pretty=False, + comments=True, + ).generate( statement._parsed, # pylint: disable=protected-access copy=True, - comments=True, - pretty=False, ) except SupersetParseError as ex: raise QueryClauseValidationException(f"Invalid SQL clause: {clause}") from ex diff --git a/tests/unit_tests/sql/parse_tests.py b/tests/unit_tests/sql/parse_tests.py index 6d58550f028..2f3b72c5b38 100644 --- a/tests/unit_tests/sql/parse_tests.py +++ b/tests/unit_tests/sql/parse_tests.py @@ -3153,6 +3153,48 @@ def test_is_valid_cvas(sql: str, engine: str, expected: bool) -> None: ("col1 = 1) AND (col2 = 2", QueryClauseValidationException, "base"), ("(col1 = 1)) AND ((col2 = 2)", QueryClauseValidationException, "base"), ("TRUE; SELECT 1", QueryClauseValidationException, "base"), + # Regression test for https://github.com/apache/superset/issues/39223: + # dialects with `MULTI_ARG_DISTINCT=False` (Postgres, Presto, Trino, + # DuckDB) must not rewrite user-defined multi-argument DISTINCT + # aggregates into row-expression null guards. Dremio is included + # below as a defensive regression guard even though its generator + # does not currently set `MULTI_ARG_DISTINCT=False`. + ( + "DISTINCT_AVG(DISTINCT report_id, time_to_accept / 86400)", + "DISTINCT_AVG(DISTINCT report_id, time_to_accept / 86400)", + "postgresql", + ), + ( + "DISTINCT_SUM(DISTINCT report_id, total_bounty_reward_amount)", + "DISTINCT_SUM(DISTINCT report_id, total_bounty_reward_amount)", + "postgresql", + ), + ( + "DISTINCT_AVG(DISTINCT k, v)", + "DISTINCT_AVG(DISTINCT k, v)", + "presto", + ), + ( + "DISTINCT_AVG(DISTINCT k, v)", + "DISTINCT_AVG(DISTINCT k, v)", + "trino", + ), + ( + "DISTINCT_AVG(DISTINCT k, v)", + "DISTINCT_AVG(DISTINCT k, v)", + "duckdb", + ), + ( + "DISTINCT_AVG(DISTINCT k, v)", + "DISTINCT_AVG(DISTINCT k, v)", + "dremio", + ), + # Single-argument DISTINCT must still round-trip cleanly. + ( + "COUNT(DISTINCT x)", + "COUNT(DISTINCT x)", + "postgresql", + ), ], ) def test_sanitize_clause(sql: str, expected: str | Exception, engine: str) -> None: @@ -3166,6 +3208,30 @@ def test_sanitize_clause(sql: str, expected: str | Exception, engine: str) -> No sanitize_clause(sql, engine) +@pytest.mark.parametrize( + "engine", + [ + "postgresql", + "presto", + "trino", + "duckdb", + "dremio", + ], +) +def test_sqlstatement_format_preserves_multi_arg_distinct(engine: str) -> None: + """ + Regression guard for https://github.com/apache/superset/issues/39223: + ``SQLStatement.format()`` must not rewrite user-defined multi-argument + DISTINCT aggregates into row-expression null guards. This is the SQL Lab / + executor path; the metric-expression path is covered by + ``test_sanitize_clause``. + """ + sql = "SELECT DISTINCT_AVG(DISTINCT a, b) FROM t" + formatted = SQLScript(sql, engine).format() + assert "DISTINCT_AVG(DISTINCT a, b)" in formatted + assert "CASE WHEN" not in formatted + + @pytest.mark.parametrize( "engine", [ From d0a34d9372d192ce5a3104f3d558942a31b313d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 15:07:06 -0700 Subject: [PATCH 30/37] chore(deps): bump @visx/scale from 3.12.0 to 4.0.0 in /superset-frontend (#41231) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 576 +--------------------------- superset-frontend/package.json | 2 +- 2 files changed, 13 insertions(+), 565 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 263817f5d98..31da8ad759e 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -78,7 +78,7 @@ "@visx/axis": "^4.0.0", "@visx/grid": "^4.0.0", "@visx/responsive": "^4.0.0", - "@visx/scale": "^3.5.0", + "@visx/scale": "^4.0.0", "@visx/tooltip": "^4.0.0", "@visx/xychart": "^4.0.0", "ag-grid-community": "35.3.1", @@ -12843,57 +12843,6 @@ } } }, - "node_modules/@visx/axis/node_modules/@types/d3-array": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", - "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", - "license": "MIT" - }, - "node_modules/@visx/axis/node_modules/@types/d3-format": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", - "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", - "license": "MIT" - }, - "node_modules/@visx/axis/node_modules/@types/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", - "license": "MIT", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@visx/axis/node_modules/@types/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", - "license": "MIT", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@visx/axis/node_modules/@types/d3-time": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", - "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", - "license": "MIT" - }, - "node_modules/@visx/axis/node_modules/@types/d3-time-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", - "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", - "license": "MIT" - }, - "node_modules/@visx/axis/node_modules/@visx/scale": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", - "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", - "license": "MIT", - "dependencies": { - "@visx/vendor": "4.0.0" - } - }, "node_modules/@visx/axis/node_modules/@visx/text": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", @@ -12913,37 +12862,6 @@ } } }, - "node_modules/@visx/axis/node_modules/@visx/vendor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", - "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", - "license": "MIT and ISC", - "dependencies": { - "@types/d3-array": "3.0.3", - "@types/d3-color": "3.1.0", - "@types/d3-delaunay": "6.0.1", - "@types/d3-format": "3.0.1", - "@types/d3-geo": "3.1.0", - "@types/d3-interpolate": "3.0.1", - "@types/d3-path": "3.1.1", - "@types/d3-scale": "4.0.2", - "@types/d3-shape": "3.1.7", - "@types/d3-time": "3.0.0", - "@types/d3-time-format": "2.1.0", - "d3-array": "3.2.1", - "d3-color": "3.1.0", - "d3-delaunay": "6.0.2", - "d3-format": "3.1.0", - "d3-geo": "3.1.0", - "d3-interpolate": "3.0.1", - "d3-path": "3.1.0", - "d3-scale": "4.0.2", - "d3-shape": "3.2.0", - "d3-time": "3.1.0", - "d3-time-format": "4.1.0", - "internmap": "2.0.3" - } - }, "node_modules/@visx/bounds": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/bounds/-/bounds-4.0.0.tgz", @@ -12973,79 +12891,6 @@ "@visx/vendor": "4.0.0" } }, - "node_modules/@visx/curve/node_modules/@types/d3-array": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", - "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", - "license": "MIT" - }, - "node_modules/@visx/curve/node_modules/@types/d3-format": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", - "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", - "license": "MIT" - }, - "node_modules/@visx/curve/node_modules/@types/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", - "license": "MIT", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@visx/curve/node_modules/@types/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", - "license": "MIT", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@visx/curve/node_modules/@types/d3-time": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", - "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", - "license": "MIT" - }, - "node_modules/@visx/curve/node_modules/@types/d3-time-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", - "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", - "license": "MIT" - }, - "node_modules/@visx/curve/node_modules/@visx/vendor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", - "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", - "license": "MIT and ISC", - "dependencies": { - "@types/d3-array": "3.0.3", - "@types/d3-color": "3.1.0", - "@types/d3-delaunay": "6.0.1", - "@types/d3-format": "3.0.1", - "@types/d3-geo": "3.1.0", - "@types/d3-interpolate": "3.0.1", - "@types/d3-path": "3.1.1", - "@types/d3-scale": "4.0.2", - "@types/d3-shape": "3.1.7", - "@types/d3-time": "3.0.0", - "@types/d3-time-format": "2.1.0", - "d3-array": "3.2.1", - "d3-color": "3.1.0", - "d3-delaunay": "6.0.2", - "d3-format": "3.1.0", - "d3-geo": "3.1.0", - "d3-interpolate": "3.0.1", - "d3-path": "3.1.0", - "d3-scale": "4.0.2", - "d3-shape": "3.2.0", - "d3-time": "3.1.0", - "d3-time-format": "4.1.0", - "internmap": "2.0.3" - } - }, "node_modules/@visx/drag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/drag/-/drag-4.0.0.tgz", @@ -13103,79 +12948,6 @@ } } }, - "node_modules/@visx/glyph/node_modules/@types/d3-array": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", - "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", - "license": "MIT" - }, - "node_modules/@visx/glyph/node_modules/@types/d3-format": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", - "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", - "license": "MIT" - }, - "node_modules/@visx/glyph/node_modules/@types/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", - "license": "MIT", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@visx/glyph/node_modules/@types/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", - "license": "MIT", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@visx/glyph/node_modules/@types/d3-time": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", - "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", - "license": "MIT" - }, - "node_modules/@visx/glyph/node_modules/@types/d3-time-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", - "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", - "license": "MIT" - }, - "node_modules/@visx/glyph/node_modules/@visx/vendor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", - "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", - "license": "MIT and ISC", - "dependencies": { - "@types/d3-array": "3.0.3", - "@types/d3-color": "3.1.0", - "@types/d3-delaunay": "6.0.1", - "@types/d3-format": "3.0.1", - "@types/d3-geo": "3.1.0", - "@types/d3-interpolate": "3.0.1", - "@types/d3-path": "3.1.1", - "@types/d3-scale": "4.0.2", - "@types/d3-shape": "3.1.7", - "@types/d3-time": "3.0.0", - "@types/d3-time-format": "2.1.0", - "d3-array": "3.2.1", - "d3-color": "3.1.0", - "d3-delaunay": "6.0.2", - "d3-format": "3.1.0", - "d3-geo": "3.1.0", - "d3-interpolate": "3.0.1", - "d3-path": "3.1.0", - "d3-scale": "4.0.2", - "d3-shape": "3.2.0", - "d3-time": "3.1.0", - "d3-time-format": "4.1.0", - "internmap": "2.0.3" - } - }, "node_modules/@visx/grid": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/grid/-/grid-4.0.0.tgz", @@ -13199,88 +12971,6 @@ } } }, - "node_modules/@visx/grid/node_modules/@types/d3-array": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", - "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", - "license": "MIT" - }, - "node_modules/@visx/grid/node_modules/@types/d3-format": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", - "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", - "license": "MIT" - }, - "node_modules/@visx/grid/node_modules/@types/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", - "license": "MIT", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@visx/grid/node_modules/@types/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", - "license": "MIT", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@visx/grid/node_modules/@types/d3-time": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", - "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", - "license": "MIT" - }, - "node_modules/@visx/grid/node_modules/@types/d3-time-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", - "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", - "license": "MIT" - }, - "node_modules/@visx/grid/node_modules/@visx/scale": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", - "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", - "license": "MIT", - "dependencies": { - "@visx/vendor": "4.0.0" - } - }, - "node_modules/@visx/grid/node_modules/@visx/vendor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", - "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", - "license": "MIT and ISC", - "dependencies": { - "@types/d3-array": "3.0.3", - "@types/d3-color": "3.1.0", - "@types/d3-delaunay": "6.0.1", - "@types/d3-format": "3.0.1", - "@types/d3-geo": "3.1.0", - "@types/d3-interpolate": "3.0.1", - "@types/d3-path": "3.1.1", - "@types/d3-scale": "4.0.2", - "@types/d3-shape": "3.1.7", - "@types/d3-time": "3.0.0", - "@types/d3-time-format": "2.1.0", - "d3-array": "3.2.1", - "d3-color": "3.1.0", - "d3-delaunay": "6.0.2", - "d3-format": "3.1.0", - "d3-geo": "3.1.0", - "d3-interpolate": "3.0.1", - "d3-path": "3.1.0", - "d3-scale": "4.0.2", - "d3-shape": "3.2.0", - "d3-time": "3.1.0", - "d3-time-format": "4.1.0", - "internmap": "2.0.3" - } - }, "node_modules/@visx/group": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/group/-/group-4.0.0.tgz", @@ -13328,57 +13018,6 @@ } } }, - "node_modules/@visx/react-spring/node_modules/@types/d3-array": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", - "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", - "license": "MIT" - }, - "node_modules/@visx/react-spring/node_modules/@types/d3-format": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", - "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", - "license": "MIT" - }, - "node_modules/@visx/react-spring/node_modules/@types/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", - "license": "MIT", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@visx/react-spring/node_modules/@types/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", - "license": "MIT", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@visx/react-spring/node_modules/@types/d3-time": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", - "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", - "license": "MIT" - }, - "node_modules/@visx/react-spring/node_modules/@types/d3-time-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", - "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", - "license": "MIT" - }, - "node_modules/@visx/react-spring/node_modules/@visx/scale": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", - "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", - "license": "MIT", - "dependencies": { - "@visx/vendor": "4.0.0" - } - }, "node_modules/@visx/react-spring/node_modules/@visx/text": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", @@ -13398,37 +13037,6 @@ } } }, - "node_modules/@visx/react-spring/node_modules/@visx/vendor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", - "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", - "license": "MIT and ISC", - "dependencies": { - "@types/d3-array": "3.0.3", - "@types/d3-color": "3.1.0", - "@types/d3-delaunay": "6.0.1", - "@types/d3-format": "3.0.1", - "@types/d3-geo": "3.1.0", - "@types/d3-interpolate": "3.0.1", - "@types/d3-path": "3.1.1", - "@types/d3-scale": "4.0.2", - "@types/d3-shape": "3.1.7", - "@types/d3-time": "3.0.0", - "@types/d3-time-format": "2.1.0", - "d3-array": "3.2.1", - "d3-color": "3.1.0", - "d3-delaunay": "6.0.2", - "d3-format": "3.1.0", - "d3-geo": "3.1.0", - "d3-interpolate": "3.0.1", - "d3-path": "3.1.0", - "d3-scale": "4.0.2", - "d3-shape": "3.2.0", - "d3-time": "3.1.0", - "d3-time-format": "4.1.0", - "internmap": "2.0.3" - } - }, "node_modules/@visx/responsive": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/responsive/-/responsive-4.0.0.tgz", @@ -13445,12 +13053,12 @@ } }, "node_modules/@visx/scale": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-3.12.0.tgz", - "integrity": "sha512-+ubijrZ2AwWCsNey0HGLJ0YKNeC/XImEFsr9rM+Uef1CM3PNM43NDdNTrdBejSlzRq0lcfQPWYMYQFSlkLcPOg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", + "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", "license": "MIT", "dependencies": { - "@visx/vendor": "3.12.0" + "@visx/vendor": "4.0.0" } }, "node_modules/@visx/shape": { @@ -13475,88 +13083,6 @@ } } }, - "node_modules/@visx/shape/node_modules/@types/d3-array": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", - "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", - "license": "MIT" - }, - "node_modules/@visx/shape/node_modules/@types/d3-format": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", - "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", - "license": "MIT" - }, - "node_modules/@visx/shape/node_modules/@types/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", - "license": "MIT", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@visx/shape/node_modules/@types/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", - "license": "MIT", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@visx/shape/node_modules/@types/d3-time": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", - "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", - "license": "MIT" - }, - "node_modules/@visx/shape/node_modules/@types/d3-time-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", - "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", - "license": "MIT" - }, - "node_modules/@visx/shape/node_modules/@visx/scale": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", - "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", - "license": "MIT", - "dependencies": { - "@visx/vendor": "4.0.0" - } - }, - "node_modules/@visx/shape/node_modules/@visx/vendor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", - "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", - "license": "MIT and ISC", - "dependencies": { - "@types/d3-array": "3.0.3", - "@types/d3-color": "3.1.0", - "@types/d3-delaunay": "6.0.1", - "@types/d3-format": "3.0.1", - "@types/d3-geo": "3.1.0", - "@types/d3-interpolate": "3.0.1", - "@types/d3-path": "3.1.1", - "@types/d3-scale": "4.0.2", - "@types/d3-shape": "3.1.7", - "@types/d3-time": "3.0.0", - "@types/d3-time-format": "2.1.0", - "d3-array": "3.2.1", - "d3-color": "3.1.0", - "d3-delaunay": "6.0.2", - "d3-format": "3.1.0", - "d3-geo": "3.1.0", - "d3-interpolate": "3.0.1", - "d3-path": "3.1.0", - "d3-scale": "4.0.2", - "d3-shape": "3.2.0", - "d3-time": "3.1.0", - "d3-time-format": "4.1.0", - "internmap": "2.0.3" - } - }, "node_modules/@visx/tooltip": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/tooltip/-/tooltip-4.0.0.tgz", @@ -13583,9 +13109,9 @@ } }, "node_modules/@visx/vendor": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-3.12.0.tgz", - "integrity": "sha512-SVO+G0xtnL9dsNpGDcjCgoiCnlB3iLSM9KLz1sLbSrV7RaVXwY3/BTm2X9OWN1jH2a9M+eHt6DJ6sE6CXm4cUg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", + "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", "license": "MIT and ISC", "dependencies": { "@types/d3-array": "3.0.3", @@ -13594,7 +13120,9 @@ "@types/d3-format": "3.0.1", "@types/d3-geo": "3.1.0", "@types/d3-interpolate": "3.0.1", + "@types/d3-path": "3.1.1", "@types/d3-scale": "4.0.2", + "@types/d3-shape": "3.1.7", "@types/d3-time": "3.0.0", "@types/d3-time-format": "2.1.0", "d3-array": "3.2.1", @@ -13603,7 +13131,9 @@ "d3-format": "3.1.0", "d3-geo": "3.1.0", "d3-interpolate": "3.0.1", + "d3-path": "3.1.0", "d3-scale": "4.0.2", + "d3-shape": "3.2.0", "d3-time": "3.1.0", "d3-time-format": "4.1.0", "internmap": "2.0.3" @@ -13710,57 +13240,6 @@ } } }, - "node_modules/@visx/xychart/node_modules/@types/d3-array": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz", - "integrity": "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==", - "license": "MIT" - }, - "node_modules/@visx/xychart/node_modules/@types/d3-format": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", - "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", - "license": "MIT" - }, - "node_modules/@visx/xychart/node_modules/@types/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", - "license": "MIT", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@visx/xychart/node_modules/@types/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==", - "license": "MIT", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@visx/xychart/node_modules/@types/d3-time": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", - "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", - "license": "MIT" - }, - "node_modules/@visx/xychart/node_modules/@types/d3-time-format": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.1.0.tgz", - "integrity": "sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==", - "license": "MIT" - }, - "node_modules/@visx/xychart/node_modules/@visx/scale": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/scale/-/scale-4.0.0.tgz", - "integrity": "sha512-Q3VaSLKlsrxxSl9CwS2D3Mvz4/4kIp/6NMKRY8Im0Au1hrQh2egU806p0+JwN0ccuGGDe03jyAxX4BSRAH8Plg==", - "license": "MIT", - "dependencies": { - "@visx/vendor": "4.0.0" - } - }, "node_modules/@visx/xychart/node_modules/@visx/text": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@visx/text/-/text-4.0.0.tgz", @@ -13780,37 +13259,6 @@ } } }, - "node_modules/@visx/xychart/node_modules/@visx/vendor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@visx/vendor/-/vendor-4.0.0.tgz", - "integrity": "sha512-LoBNzWjTXzBfu095BQxB14IwZQHHOLs8ZMzM6t2FL4ZGORaACgLcmXRRLhFo0VmRR8L7iNTM4HHc1j6yFvzsAA==", - "license": "MIT and ISC", - "dependencies": { - "@types/d3-array": "3.0.3", - "@types/d3-color": "3.1.0", - "@types/d3-delaunay": "6.0.1", - "@types/d3-format": "3.0.1", - "@types/d3-geo": "3.1.0", - "@types/d3-interpolate": "3.0.1", - "@types/d3-path": "3.1.1", - "@types/d3-scale": "4.0.2", - "@types/d3-shape": "3.1.7", - "@types/d3-time": "3.0.0", - "@types/d3-time-format": "2.1.0", - "d3-array": "3.2.1", - "d3-color": "3.1.0", - "d3-delaunay": "6.0.2", - "d3-format": "3.1.0", - "d3-geo": "3.1.0", - "d3-interpolate": "3.0.1", - "d3-path": "3.1.0", - "d3-scale": "4.0.2", - "d3-shape": "3.2.0", - "d3-time": "3.1.0", - "d3-time-format": "4.1.0", - "internmap": "2.0.3" - } - }, "node_modules/@vitest/expect": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 8b462477d79..5d72058c23e 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -161,7 +161,7 @@ "@visx/axis": "^4.0.0", "@visx/grid": "^4.0.0", "@visx/responsive": "^4.0.0", - "@visx/scale": "^3.5.0", + "@visx/scale": "^4.0.0", "@visx/tooltip": "^4.0.0", "@visx/xychart": "^4.0.0", "ag-grid-community": "35.3.1", From 2d5df6625bd5b7401d158907f4aa65efc24eef7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Sat, 20 Jun 2026 10:48:10 +0700 Subject: [PATCH 31/37] build(deps): update major versions for `memoize-one`, `json-stringify-pretty-compact` and `webpack-cli` (#38793) Signed-off-by: hainenber --- superset-frontend/jest.config.js | 2 +- superset-frontend/package-lock.json | 50 ++++++------------- superset-frontend/package.json | 4 +- .../superset-ui-chart-controls/package.json | 2 +- .../BigNumberTotal/transformProps.test.ts | 4 +- 5 files changed, 23 insertions(+), 39 deletions(-) diff --git a/superset-frontend/jest.config.js b/superset-frontend/jest.config.js index adac3fdf028..a4d3fcc67fa 100644 --- a/superset-frontend/jest.config.js +++ b/superset-frontend/jest.config.js @@ -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|storybook/*.|json-stringify-pretty-compact)', ], preset: 'ts-jest', transform: { diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 31da8ad759e..cf155d28a32 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -108,12 +108,12 @@ "jquery": "^4.0.0", "js-levenshtein": "^1.1.6", "json-bigint": "^1.0.0", - "json-stringify-pretty-compact": "^2.0.0", + "json-stringify-pretty-compact": "^4.0.0", "lodash": "^4.18.1", "mapbox-gl": "^3.24.0", "markdown-to-jsx": "^9.8.2", "match-sorter": "^8.3.0", - "memoize-one": "^5.2.1", + "memoize-one": "^6.0.0", "mousetrap": "^1.6.5", "mustache": "^4.2.0", "nanoid": "^5.1.11", @@ -289,7 +289,7 @@ "webpack-cli": "^7.0.3", "webpack-dev-server": "^5.2.5", "webpack-manifest-plugin": "^6.0.1", - "webpack-sources": "^3.5.0", + "webpack-sources": "^3.3.4", "webpack-visualizer-plugin2": "^2.0.0" }, "engines": { @@ -6400,12 +6400,6 @@ "gl-style-validate": "dist/gl-style-validate.mjs" } }, - "node_modules/@maplibre/maplibre-gl-style-spec/node_modules/json-stringify-pretty-compact": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", - "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", - "license": "MIT" - }, "node_modules/@maplibre/mlt": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.1.8.tgz", @@ -26385,9 +26379,9 @@ } }, "node_modules/json-stringify-pretty-compact": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-2.0.0.tgz", - "integrity": "sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", "license": "MIT" }, "node_modules/json-stringify-safe": { @@ -28905,9 +28899,9 @@ } }, "node_modules/memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", "license": "MIT" }, "node_modules/meow": { @@ -35679,12 +35673,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/react-diff-viewer-continued/node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", - "license": "MIT" - }, "node_modules/react-dnd": { "version": "11.1.3", "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-11.1.3.tgz", @@ -36313,6 +36301,12 @@ "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/react-window/node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "license": "MIT" + }, "node_modules/reactable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reactable/-/reactable-1.1.0.tgz", @@ -44547,7 +44541,7 @@ "@testing-library/user-event": "*", "ace-builds": "^1.4.14", "brace": "^0.11.1", - "memoize-one": "^5.1.1", + "memoize-one": "^6.0.0", "react": "^18.3.0", "react-ace": "^10.1.0", "react-dom": "^18.3.0" @@ -45116,12 +45110,6 @@ "node": ">=12" } }, - "plugins/plugin-chart-ag-grid-table/node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", - "license": "MIT" - }, "plugins/plugin-chart-cartodiagram": { "name": "@superset-ui/plugin-chart-cartodiagram", "version": "0.0.1", @@ -45315,12 +45303,6 @@ "node": ">=12" } }, - "plugins/plugin-chart-table/node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", - "license": "MIT" - }, "plugins/plugin-chart-word-cloud": { "name": "@superset-ui/plugin-chart-word-cloud", "version": "0.20.4", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 5d72058c23e..0a2ff7fe679 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -191,12 +191,12 @@ "jquery": "^4.0.0", "js-levenshtein": "^1.1.6", "json-bigint": "^1.0.0", - "json-stringify-pretty-compact": "^2.0.0", + "json-stringify-pretty-compact": "^4.0.0", "lodash": "^4.18.1", "mapbox-gl": "^3.24.0", "markdown-to-jsx": "^9.8.2", "match-sorter": "^8.3.0", - "memoize-one": "^5.2.1", + "memoize-one": "^6.0.0", "mousetrap": "^1.6.5", "mustache": "^4.2.0", "nanoid": "^5.1.11", diff --git a/superset-frontend/packages/superset-ui-chart-controls/package.json b/superset-frontend/packages/superset-ui-chart-controls/package.json index 2d66eb26f45..6a09858cbde 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/package.json +++ b/superset-frontend/packages/superset-ui-chart-controls/package.json @@ -39,7 +39,7 @@ "@testing-library/user-event": "*", "ace-builds": "^1.4.14", "brace": "^0.11.1", - "memoize-one": "^5.1.1", + "memoize-one": "^6.0.0", "react": "^18.3.0", "react-ace": "^10.1.0", "react-dom": "^18.3.0" diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.test.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.test.ts index 2b2f38a0ac2..c4868ac61e7 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.test.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.test.ts @@ -234,7 +234,9 @@ describe('BigNumberTotal transformProps', () => { test('should propagate colorThresholdFormatters from getColorFormatters', () => { // Override the getColorFormatters mock to return specific value const mockFormatters = [{ formatter: 'red' }]; - (getColorFormatters as jest.Mock).mockReturnValueOnce(mockFormatters); + (getColorFormatters as unknown as jest.Mock).mockReturnValueOnce( + mockFormatters, + ); const chartProps = { width: 800, From 0d92d0dbb7366537bd45084cd1e7f68c7bc7f328 Mon Sep 17 00:00:00 2001 From: Mehmet Salih Yavuz Date: Sat, 20 Jun 2026 06:56:25 +0300 Subject: [PATCH 32/37] =?UTF-8?q?chore(deps):=20finish=20pip=E2=86=92uv=20?= =?UTF-8?q?swap=20in=20Makefile=20and=20CI=20(#41197)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/bashlib.sh | 4 ++-- .github/workflows/superset-app-cli.yml | 2 +- .../workflows/superset-python-presto-hive.yml | 2 +- Makefile | 17 ++++++++++++----- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/bashlib.sh b/.github/workflows/bashlib.sh index b7be35f7585..e1b622b6afa 100644 --- a/.github/workflows/bashlib.sh +++ b/.github/workflows/bashlib.sh @@ -114,7 +114,7 @@ testdata() { say "::group::Load test data" # must specify PYTHONPATH to make `tests.superset_test_config` importable export PYTHONPATH="$GITHUB_WORKSPACE" - pip install -e . + uv pip install --system -e . superset db upgrade superset load_test_users superset load_examples --load-test-data @@ -127,7 +127,7 @@ playwright_testdata() { say "::group::Load all examples for Playwright tests" # must specify PYTHONPATH to make `tests.superset_test_config` importable export PYTHONPATH="$GITHUB_WORKSPACE" - pip install -e . + uv pip install --system -e . superset db upgrade superset load_test_users superset load_examples diff --git a/.github/workflows/superset-app-cli.yml b/.github/workflows/superset-app-cli.yml index 8ebb2e6539c..e08cea4a4fb 100644 --- a/.github/workflows/superset-app-cli.yml +++ b/.github/workflows/superset-app-cli.yml @@ -61,7 +61,7 @@ jobs: - name: superset init if: steps.check.outputs.python run: | - pip install -e . + uv pip install --system -e . superset db upgrade superset load_test_users - name: superset load_examples diff --git a/.github/workflows/superset-python-presto-hive.yml b/.github/workflows/superset-python-presto-hive.yml index ee797119866..b91122e6b16 100644 --- a/.github/workflows/superset-python-presto-hive.yml +++ b/.github/workflows/superset-python-presto-hive.yml @@ -149,7 +149,7 @@ jobs: run: celery-worker - name: Python unit tests (PostgreSQL) run: | - pip install -e .[hive] + uv pip install --system -e .[hive] ./scripts/python_tests.sh -m 'chart_data_flow or sql_json_flow' - name: Upload code coverage uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 diff --git a/Makefile b/Makefile index 3c35fb4c60d..b1db1d6bf9c 100644 --- a/Makefile +++ b/Makefile @@ -23,11 +23,14 @@ PYTHON=`command -v python3.11 || command -v python3.10` install: superset pre-commit superset: + # Bootstrap uv (the project's installer) into the active environment + pip install uv + # Install external dependencies - pip install -r requirements/development.txt + uv pip install -r requirements/development.txt # Install Superset in editable (development) mode - pip install -e . + uv pip install -e . # Create an admin user in your metadata database superset fab create-admin \ @@ -52,11 +55,14 @@ superset: update: update-py update-js update-py: + # Bootstrap uv (the project's installer) into the active environment + pip install uv + # Install external dependencies - pip install -r requirements/development.txt + uv pip install -r requirements/development.txt # Install Superset in editable (development) mode - pip install -e . + uv pip install -e . # Initialize the database superset db upgrade @@ -79,7 +85,8 @@ activate: pre-commit: # setup pre commit dependencies - pip3 install -r requirements/development.txt + pip install uv + uv pip install -r requirements/development.txt pre-commit install format: py-format js-format From 3aa1218f9b54825454ba704d608d80a780be6aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Sat, 20 Jun 2026 13:03:26 +0700 Subject: [PATCH 33/37] feat(ci): do not run expensive E2E tests on draft PRs (#40720) Signed-off-by: hainenber Co-authored-by: Evan Rusackas --- .github/workflows/superset-e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/superset-e2e.yml b/.github/workflows/superset-e2e.yml index 3b61b1f4e4a..b7b917585da 100644 --- a/.github/workflows/superset-e2e.yml +++ b/.github/workflows/superset-e2e.yml @@ -49,7 +49,7 @@ jobs: cypress-matrix: needs: changes - if: needs.changes.outputs.python == 'true' || needs.changes.outputs.frontend == 'true' + if: (needs.changes.outputs.python == 'true' || needs.changes.outputs.frontend == 'true') && github.event.pull_request.draft == false # Somehow one test flakes on 24.04 for unknown reasons, this is the only GHA left on 22.04 runs-on: ubuntu-22.04 timeout-minutes: 30 From 686beb9117653354701dd6cbec927f9aa2d23cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Sat, 20 Jun 2026 21:44:02 +0700 Subject: [PATCH 34/37] chore(build): replace `d3-color` usage with existing `tinycolor2` (#39468) Signed-off-by: hainenber --- superset-frontend/package-lock.json | 11 +++++------ superset-frontend/package.json | 3 +-- .../legacy-plugin-chart-world-map/package.json | 2 +- .../src/transformProps.ts | 4 ++-- .../plugins/preset-chart-deckgl/package.json | 2 +- .../plugins/preset-chart-deckgl/src/utils/colors.ts | 4 ++-- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index cf155d28a32..d0a106fa262 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -87,7 +87,6 @@ "chrono-node": "^2.9.1", "classnames": "^2.2.5", "content-disposition": "^2.0.1", - "d3-color": "^3.1.0", "d3-scale": "^4.0.2", "dayjs": "^1.11.21", "dom-to-image-more": "^3.10.0", @@ -150,7 +149,7 @@ "scroll-into-view-if-needed": "^3.1.0", "simple-zstd": "^2.1.0", "stream-browserify": "^3.0.0", - "tinycolor2": "^1.4.2", + "tinycolor2": "^1.6.0", "urijs": "^1.19.8", "use-event-callback": "^0.1.0", "use-immer": "^0.11.0", @@ -289,7 +288,7 @@ "webpack-cli": "^7.0.3", "webpack-dev-server": "^5.2.5", "webpack-manifest-plugin": "^6.0.1", - "webpack-sources": "^3.3.4", + "webpack-sources": "^3.5.0", "webpack-visualizer-plugin2": "^2.0.0" }, "engines": { @@ -44962,9 +44961,9 @@ "dependencies": { "d3": "^3.5.17", "d3-array": "^3.2.4", - "d3-color": "^3.1.0", "datamaps": "^0.5.10", - "prop-types": "^15.8.1" + "prop-types": "^15.8.1", + "tinycolor2": "^1.6.0" }, "peerDependencies": { "@apache-superset/core": "*", @@ -45356,7 +45355,6 @@ "@types/geojson": "^7946.0.16", "bootstrap-slider": "^11.0.2", "d3-array": "^3.2.4", - "d3-color": "^3.1.0", "d3-scale": "^4.0.2", "handlebars": "^4.7.9", "lodash": "^4.18.1", @@ -45365,6 +45363,7 @@ "ngeohash": "^0.6.3", "prop-types": "^15.8.1", "react-map-gl": "^8.1.1", + "tinycolor2": "^1.6.0", "underscore": "^1.13.7", "urijs": "^1.19.11", "xss": "^1.0.15" diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 0a2ff7fe679..951fb8b7a11 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -170,7 +170,6 @@ "chrono-node": "^2.9.1", "classnames": "^2.2.5", "content-disposition": "^2.0.1", - "d3-color": "^3.1.0", "d3-scale": "^4.0.2", "dayjs": "^1.11.21", "dom-to-image-more": "^3.10.0", @@ -233,7 +232,7 @@ "scroll-into-view-if-needed": "^3.1.0", "simple-zstd": "^2.1.0", "stream-browserify": "^3.0.0", - "tinycolor2": "^1.4.2", + "tinycolor2": "^1.6.0", "urijs": "^1.19.8", "use-event-callback": "^0.1.0", "use-immer": "^0.11.0", diff --git a/superset-frontend/plugins/legacy-plugin-chart-world-map/package.json b/superset-frontend/plugins/legacy-plugin-chart-world-map/package.json index 718b6f0a0b6..cf9ed4f39fe 100644 --- a/superset-frontend/plugins/legacy-plugin-chart-world-map/package.json +++ b/superset-frontend/plugins/legacy-plugin-chart-world-map/package.json @@ -31,7 +31,7 @@ "dependencies": { "d3": "^3.5.17", "d3-array": "^3.2.4", - "d3-color": "^3.1.0", + "tinycolor2": "^1.6.0", "datamaps": "^0.5.10", "prop-types": "^15.8.1" }, diff --git a/superset-frontend/plugins/legacy-plugin-chart-world-map/src/transformProps.ts b/superset-frontend/plugins/legacy-plugin-chart-world-map/src/transformProps.ts index 0c541297fcb..16d84a44400 100644 --- a/superset-frontend/plugins/legacy-plugin-chart-world-map/src/transformProps.ts +++ b/superset-frontend/plugins/legacy-plugin-chart-world-map/src/transformProps.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { rgb } from 'd3-color'; +import tinycolor from 'tinycolor2'; import { ChartProps, getValueFormatter } from '@superset-ui/core'; export default function transformProps(chartProps: ChartProps) { @@ -75,7 +75,7 @@ export default function transformProps(chartProps: ChartProps) { maxBubbleSize: parseInt(maxBubbleSize, 10), showBubbles, linearColorScheme, - color: rgb(r, g, b).hex(), + color: tinycolor({ r, g, b }).toHexString(), colorBy, colorScheme, sliceId, diff --git a/superset-frontend/plugins/preset-chart-deckgl/package.json b/superset-frontend/plugins/preset-chart-deckgl/package.json index 1d7bcf14c43..ca416c8ad02 100644 --- a/superset-frontend/plugins/preset-chart-deckgl/package.json +++ b/superset-frontend/plugins/preset-chart-deckgl/package.json @@ -42,7 +42,6 @@ "@types/geojson": "^7946.0.16", "bootstrap-slider": "^11.0.2", "d3-array": "^3.2.4", - "d3-color": "^3.1.0", "d3-scale": "^4.0.2", "handlebars": "^4.7.9", "lodash": "^4.18.1", @@ -51,6 +50,7 @@ "ngeohash": "^0.6.3", "prop-types": "^15.8.1", "react-map-gl": "^8.1.1", + "tinycolor2": "^1.6.0", "underscore": "^1.13.7", "urijs": "^1.19.11", "xss": "^1.0.15" diff --git a/superset-frontend/plugins/preset-chart-deckgl/src/utils/colors.ts b/superset-frontend/plugins/preset-chart-deckgl/src/utils/colors.ts index 7f562dbca23..4673de4cfa9 100644 --- a/superset-frontend/plugins/preset-chart-deckgl/src/utils/colors.ts +++ b/superset-frontend/plugins/preset-chart-deckgl/src/utils/colors.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { rgb } from 'd3-color'; +import tinycolor from 'tinycolor2'; // eslint-disable-next-line import/prefer-default-export export function hexToRGB( @@ -26,7 +26,7 @@ export function hexToRGB( if (!hex) { return [0, 0, 0, alpha]; } - const { r, g, b } = rgb(hex); + const { r, g, b } = tinycolor(hex).toRgb(); return [r, g, b, alpha]; } From 14d44328435b6f0ccbdcfd30cdd6bd6ae209be3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20H=C3=B6gberg?= <119532259+vhogberg@users.noreply.github.com> Date: Sat, 20 Jun 2026 17:15:00 +0200 Subject: [PATCH 35/37] fix: remove erroneous box shadow when bulk selecting (#41198) --- superset-frontend/src/components/ListView/ListView.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/superset-frontend/src/components/ListView/ListView.tsx b/superset-frontend/src/components/ListView/ListView.tsx index 3ba1242b324..a08a9448461 100644 --- a/superset-frontend/src/components/ListView/ListView.tsx +++ b/superset-frontend/src/components/ListView/ListView.tsx @@ -166,7 +166,6 @@ const BulkSelectWrapper = styled(Alert)` margin: ${`${-theme.sizeUnit * 2}px 0 ${-theme.sizeUnit * 2}px ${theme.sizeUnit * 4}px`}; width: 1px; height: ${theme.sizeUnit * 8}px; - box-shadow: inset -1px 0px 0px ${theme.colorBorder}; display: inline-flex; vertical-align: middle; position: relative; From 99ffaf3694a857916161b272b02a496ef78146a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 20 Jun 2026 23:33:49 +0700 Subject: [PATCH 36/37] chore(deps-dev): update sqlalchemy-solr requirement from >=0.2.0 to >=0.2.4.3 (#41257) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b5f540c0433..45077575842 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -143,7 +143,7 @@ drill = ["sqlalchemy-drill>=1.1.10, <2"] druid = ["pydruid>=0.6.5,<0.7"] duckdb = ["duckdb>=1.5.2,<2", "duckdb-engine>=0.17.0"] dynamodb = ["pydynamodb>=0.4.2"] -solr = ["sqlalchemy-solr >= 0.2.0"] +solr = ["sqlalchemy-solr >= 0.2.4.3"] elasticsearch = ["elasticsearch-dbapi>=0.2.13, <0.3.0"] exasol = ["sqlalchemy-exasol>=2.4.0, <8.0"] excel = ["xlrd>=2.0.2, <2.1"] From b612f573d75717134a2e513da7f75aac10b04954 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 20 Jun 2026 23:34:37 +0700 Subject: [PATCH 37/37] chore(deps-dev): update ydb-sqlalchemy requirement from >=0.1.2 to >=0.1.22 (#41253) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 45077575842..8c39c148eb2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -210,7 +210,7 @@ netezza = ["nzalchemy>=11.0.2"] starrocks = ["starrocks>=1.3.3, <2"] doris = ["pydoris>=1.0.0, <2.0.0"] oceanbase = ["oceanbase_py>=0.0.1.2"] -ydb = ["ydb-sqlalchemy>=0.1.2", "ydb-sqlglot-plugin>=0.2.5"] +ydb = ["ydb-sqlalchemy>=0.1.22", "ydb-sqlglot-plugin>=0.2.5"] development = [ # no bounds for apache-superset-extensions-cli until a stable version "apache-superset-extensions-cli",