Compare commits

..
Author SHA1 Message Date
Elizabeth ThompsonandClaude a45f1ddbf5 fix(charts/data): return 400 instead of 500 on reversed date range (SC-118279)
When a user submits a chart data request with a reversed custom date range
(since > until), get_since_until() in superset/utils/date_parser.py raises a
bare ValueError("From date cannot be larger than to date"). This propagates
through ChartDataQueryContextSchema().load() (via its make_query_context
@post_load hook) and out of _create_query_context_from_form(), which only
caught KeyError. The callers catch marshmallow.ValidationError but not
ValueError, so it surfaced as an unhandled 500.

Add a ValueError arm next to the existing KeyError arm in
_create_query_context_from_form(), re-raising as marshmallow.ValidationError so
the API returns a 400. The raised type of get_since_until() is deliberately
left unchanged, since other call sites explicitly catch ValueError today.

Fixes SUPERSET-PYTHON-NA4

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-25 15:10:24 +00:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>rusackasClaude Opus 4.8
fd3849cef1 chore(deps): bump antd from 6.6.0 to 6.6.1 in /superset-frontend (#43509)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: rusackas <evan@rusackas.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-25 05:56:18 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> ef0ad01aa5 chore(deps-dev): bump the storybook group across 1 directory with 5 updates (#43507)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-25 05:52:46 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> d480152735 chore(deps): bump the storybook group in /docs with 2 updates (#43505)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-25 02:46:30 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> cbfa94c4dd chore(deps): bump antd from 6.6.0 to 6.6.1 in /docs (#43506)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-25 02:46:26 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> d2aeb29223 chore(deps-dev): bump baseline-browser-mapping from 2.11.14 to 2.11.15 in /superset-frontend (#43508)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-25 02:46:22 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 7bad69f523 chore(deps): bump dayjs from 1.11.22 to 1.11.23 in /superset-frontend (#43510)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-25 02:46:17 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 9dd8c42f3d chore(deps): bump dompurify from 3.4.12 to 3.4.13 in /superset-frontend (#43511)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-25 02:46:12 -07:00
15 changed files with 174 additions and 654 deletions
+3 -3
View File
@@ -58,10 +58,10 @@
"@fontsource/inter": "^5.3.0",
"@mdx-js/react": "^3.1.1",
"@saucelabs/theme-github-codeblock": "^0.3.0",
"@storybook/addon-docs": "^10.5.8",
"@storybook/addon-docs": "^10.5.9",
"@superset-ui/core": "^0.20.4",
"@swc/core": "^1.16.0",
"antd": "^6.6.0",
"antd": "^6.6.1",
"baseline-browser-mapping": "^2.11.15",
"caniuse-lite": "^1.0.30001809",
"docusaurus-plugin-openapi-docs": "^5.2.0",
@@ -77,7 +77,7 @@
"react-table": "^7.8.0",
"remark-import-partial": "^0.0.2",
"reselect": "^5.2.0",
"storybook": "^10.5.8",
"storybook": "^10.5.9",
"swagger-ui-react": "^5.32.13",
"swc-loader": "^0.2.7",
"tinycolor2": "^1.4.2",
+28 -28
View File
@@ -3789,7 +3789,7 @@
"@rc-component/util" "^1.3.0"
clsx "^2.1.1"
"@rc-component/select@~1.10.0":
"@rc-component/select@~1.10.0", "@rc-component/select@~1.10.1":
version "1.10.1"
resolved "https://registry.yarnpkg.com/@rc-component/select/-/select-1.10.1.tgz#323b2f458a637e8e752f8341094783741c613c34"
integrity sha512-H+yQsl+qED9NilQ3g6zdpsMwUgwVjrcMTkNHAWRVU/MoNCYgTbDgU+MIMgZDK+rVdd2JUfI/MkysMcZZ0cyQKw==
@@ -3824,7 +3824,7 @@
"@rc-component/util" "^1.3.0"
clsx "^2.1.1"
"@rc-component/table@~1.11.0":
"@rc-component/table@~1.11.1":
version "1.11.1"
resolved "https://registry.yarnpkg.com/@rc-component/table/-/table-1.11.1.tgz#7b5c2a7c26fd37b6a403082029b5a72fcb330a4d"
integrity sha512-OWdS6DMmeWb7bJBGqPxYZpQbzBlBiXZUu2sqo6Ii7Sjs9GeK1IsrXrWk26SL2c6KEseabswdxrRj7WUm9LdECw==
@@ -3866,7 +3866,7 @@
"@rc-component/util" "^1.7.0"
clsx "^2.1.1"
"@rc-component/tree-select@~1.16.0":
"@rc-component/tree-select@~1.16.1":
version "1.16.1"
resolved "https://registry.yarnpkg.com/@rc-component/tree-select/-/tree-select-1.16.1.tgz#dcaea96e396e98108cb29cc051840d4fbdda38cc"
integrity sha512-a1Oi6EJhqAhdOxxupdJi6fP0RPHMKn5TcfkX2+llaQ4lF4nwfH7b6SCHcnsybaa2s+pk1yZYwVyeOYkDnEBRdg==
@@ -4122,23 +4122,23 @@
resolved "https://registry.yarnpkg.com/@standard-schema/utils/-/utils-0.3.0.tgz#3d5e608f16c2390c10528e98e59aef6bf73cae7b"
integrity sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==
"@storybook/addon-docs@^10.5.8":
version "10.5.8"
resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-10.5.8.tgz#767c10c7a4cc1b625b93f869b2a2b09fc8514f2e"
integrity sha512-NlHiMKW/UvW/uL8HXFDCEVwoH3qZeGYZ/qlWax4d7H471b/T54MBq2KcB4ZrdA785FfIH3numAJdBb5jwn00Mg==
"@storybook/addon-docs@^10.5.9":
version "10.5.9"
resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-10.5.9.tgz#6d871977f7ad833dc142d12ee43490105dec4d07"
integrity sha512-8sFsMkZYrrdqCLdV+hnwTwDF7RaBsBPRwl4wfc8ve9Q/7Yhi5REe/Xjvd8x1yn6fBPPw9tnID9dx6Agdnr81fw==
dependencies:
"@mdx-js/react" "^3.0.0"
"@storybook/csf-plugin" "10.5.8"
"@storybook/csf-plugin" "10.5.9"
"@storybook/icons" "^2.0.2"
"@storybook/react-dom-shim" "10.5.8"
"@storybook/react-dom-shim" "10.5.9"
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"
"@storybook/csf-plugin@10.5.8":
version "10.5.8"
resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-10.5.8.tgz#c626c5bfe55d0e279b2457e5cf150a788d1fc637"
integrity sha512-/FHiMyOWWEXfwK/lM0WxmkP9GLzbSJJuzGtfeuNWSOVDnvAMbjavitxfHb5wSbWKIQo0XYC1EJ2Y7x91XNYP4w==
"@storybook/csf-plugin@10.5.9":
version "10.5.9"
resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-10.5.9.tgz#805e4c93a1704b220351d62bb0c74ce3b78c5e10"
integrity sha512-4H5QIHQVtQYCuL43GCRLGjNQhZpQg9gL03ja0DV80kO2Dn9LEt6ol87bSnSjn4VDgcAXtgTzXFvRLknfVgAAqg==
dependencies:
unplugin "^2.3.5"
@@ -4152,10 +4152,10 @@
resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-2.1.0.tgz#edfc2450a39c5e780f28c6cbc49acd7bff59b41a"
integrity sha512-Fxh9vYpX9bQqFeHRiY8h2ApeRGDzRSMLwJwNZ/AIRqnyOKHxRKL+yFe+ctEkVJmuptRE9u1Hrn8ZZNHyfDKKNg==
"@storybook/react-dom-shim@10.5.8":
version "10.5.8"
resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-10.5.8.tgz#40cc3e32af424baa2e4109a325dae2ede29999e2"
integrity sha512-N8D13/Xny+V3kfe1KBgsAHS0nKWXLLdgOOXS9poKdYzVwVCN+CGEGBxWX0zMMtdCptqa6/57em9coPlZMoO+bg==
"@storybook/react-dom-shim@10.5.9":
version "10.5.9"
resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-10.5.9.tgz#549793845bb8b966acd36002d33d7b54cc5c92d4"
integrity sha512-7qZD6CSa64p1m/zX9tG4ALcEHlEk0Bx+5++4RL3MFlRCgCFfAomXsCHTzF0RyF8cI4vl+hS7Y0ryjQchVs6UQA==
"@superset-ui/core@^0.20.4":
version "0.20.4"
@@ -6181,10 +6181,10 @@ ansis@^3.2.0:
resolved "https://registry.yarnpkg.com/ansis/-/ansis-3.17.0.tgz#fa8d9c2a93fe7d1177e0c17f9eeb562a58a832d7"
integrity sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==
antd@^6.6.0:
version "6.6.0"
resolved "https://registry.yarnpkg.com/antd/-/antd-6.6.0.tgz#8acb84c54b36594b5c1a9084c8acb6a03b79961b"
integrity sha512-UDwWIbpmrCHB9ZQ+bPh4vQfB6DTI2ulIyoQ0Tc9xxalFblttiNGHl3ySBD9SyV/8+gUjFzfSx1+iU1Fog2i46w==
antd@^6.6.1:
version "6.6.1"
resolved "https://registry.yarnpkg.com/antd/-/antd-6.6.1.tgz#3235d76413b525b1f3287b87bdaf6ba0e7148521"
integrity sha512-QHIHYoUk9N9nJy1T9fyxWKjY0qApdTEDd/6lzqYng8Uryv9FejNmbhKvYF7obGqB+TuLXQsPVF7fOVgyzM1KrQ==
dependencies:
"@ant-design/colors" "^8.0.1"
"@ant-design/cssinjs" "^2.1.2"
@@ -6217,16 +6217,16 @@ antd@^6.6.0:
"@rc-component/rate" "~1.0.1"
"@rc-component/resize-observer" "^1.1.2"
"@rc-component/segmented" "~1.3.0"
"@rc-component/select" "~1.10.0"
"@rc-component/select" "~1.10.1"
"@rc-component/slider" "~1.1.1"
"@rc-component/steps" "~1.2.2"
"@rc-component/switch" "~1.0.3"
"@rc-component/table" "~1.11.0"
"@rc-component/table" "~1.11.1"
"@rc-component/tabs" "~1.12.0"
"@rc-component/tooltip" "~1.5.0"
"@rc-component/tour" "~2.4.0"
"@rc-component/tree" "~1.4.0"
"@rc-component/tree-select" "~1.16.0"
"@rc-component/tree-select" "~1.16.1"
"@rc-component/trigger" "^3.10.1"
"@rc-component/upload" "~1.1.1"
"@rc-component/util" "^1.12.0"
@@ -14783,10 +14783,10 @@ stop-iteration-iterator@^1.1.0:
es-errors "^1.3.0"
internal-slot "^1.1.0"
storybook@^10.5.8:
version "10.5.8"
resolved "https://registry.yarnpkg.com/storybook/-/storybook-10.5.8.tgz#d5f051983e6232c0a73ea02149a72c7bafb43275"
integrity sha512-rR4oFMSiWBSqI0lvsJPtcQUPj8+hzj3TkLu+Mw61Wo6YxPSb5FsLSHai0jZnuaIdKIlmu25KCfwlSQl4e1uvnA==
storybook@^10.5.9:
version "10.5.9"
resolved "https://registry.yarnpkg.com/storybook/-/storybook-10.5.9.tgz#61f476fd73785dcf09e9198ddf404b9b8c06964a"
integrity sha512-UfdMKSjEhIKr8LbqYyIE5r7vT/drL/PxN75YaouJ+UG0FssEy6cf49OdTF3kstAqVMHskc+zEqyRoiQHZXHwgA==
dependencies:
"@storybook/global" "^5.0.0"
"@storybook/icons" "^2.0.2"
+86 -270
View File
@@ -81,12 +81,12 @@
"@visx/xychart": "^4.0.0",
"ag-grid-community": "36.1.0",
"ag-grid-react": "36.1.0",
"antd": "^6.6.0",
"antd": "^6.6.1",
"chrono-node": "^2.10.1",
"classnames": "^2.2.5",
"content-disposition": "^2.0.1",
"d3-scale": "^4.0.2",
"dayjs": "^1.11.22",
"dayjs": "^1.11.23",
"dom-to-image-more": "^3.10.2",
"dom-to-pdf": "^0.3.2",
"echarts": "^6.1.0",
@@ -180,9 +180,9 @@
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@playwright/test": "^1.62.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.2",
"@storybook/addon-docs": "10.5.8",
"@storybook/addon-links": "10.5.8",
"@storybook/react-webpack5": "10.5.8",
"@storybook/addon-docs": "10.5.9",
"@storybook/addon-links": "10.5.9",
"@storybook/react-webpack5": "10.5.9",
"@storybook/test-runner": "0.24.4",
"@svgr/webpack": "^8.1.0",
"@swc/core": "^1.16.0",
@@ -218,7 +218,7 @@
"babel-loader": "^10.1.1",
"babel-plugin-dynamic-import-node": "^2.3.3",
"babel-plugin-jsx-remove-data-test-id": "^3.0.0",
"baseline-browser-mapping": "^2.11.14",
"baseline-browser-mapping": "^2.11.15",
"cheerio": "1.2.0",
"concurrently": "^10.0.5",
"copy-webpack-plugin": "^14.0.0",
@@ -235,7 +235,7 @@
"eslint-plugin-no-only-tests": "^3.4.0",
"eslint-plugin-react-prefer-function-component": "^5.0.0",
"eslint-plugin-react-you-might-not-need-an-effect": "^1.0.1",
"eslint-plugin-storybook": "10.5.8",
"eslint-plugin-storybook": "10.5.9",
"eslint-plugin-testing-library": "^7.16.2",
"eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors",
"fetch-mock": "^12.6.0",
@@ -266,7 +266,7 @@
"source-map": "^0.8.0",
"source-map-support": "^0.5.21",
"speed-measure-webpack-plugin": "^1.6.0",
"storybook": "10.5.8",
"storybook": "10.5.9",
"style-loader": "^4.0.0",
"stylelint": "^17.14.1",
"swc-loader": "^0.2.7",
@@ -9946,9 +9946,9 @@
}
},
"node_modules/@rc-component/select": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@rc-component/select/-/select-1.10.0.tgz",
"integrity": "sha512-u/3yuF2kEXvTJXPy3P7qkVBkGGZcQo+m1uTuQqJa6qCnwdmDoEn1Rs3zTTi6y/RsLGiQGM0drPN5c/RfflCnow==",
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/@rc-component/select/-/select-1.10.1.tgz",
"integrity": "sha512-H+yQsl+qED9NilQ3g6zdpsMwUgwVjrcMTkNHAWRVU/MoNCYgTbDgU+MIMgZDK+rVdd2JUfI/MkysMcZZ0cyQKw==",
"license": "MIT",
"dependencies": {
"@rc-component/overflow": "^1.0.0",
@@ -10765,16 +10765,16 @@
"license": "MIT"
},
"node_modules/@storybook/addon-docs": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.5.8.tgz",
"integrity": "sha512-NlHiMKW/UvW/uL8HXFDCEVwoH3qZeGYZ/qlWax4d7H471b/T54MBq2KcB4ZrdA785FfIH3numAJdBb5jwn00Mg==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.5.9.tgz",
"integrity": "sha512-8sFsMkZYrrdqCLdV+hnwTwDF7RaBsBPRwl4wfc8ve9Q/7Yhi5REe/Xjvd8x1yn6fBPPw9tnID9dx6Agdnr81fw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@mdx-js/react": "^3.0.0",
"@storybook/csf-plugin": "10.5.8",
"@storybook/csf-plugin": "10.5.9",
"@storybook/icons": "^2.0.2",
"@storybook/react-dom-shim": "10.5.8",
"@storybook/react-dom-shim": "10.5.9",
"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"
@@ -10785,7 +10785,7 @@
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"storybook": "10.5.8"
"storybook": "10.5.9"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -10794,9 +10794,9 @@
}
},
"node_modules/@storybook/addon-docs/node_modules/@storybook/csf-plugin": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.5.8.tgz",
"integrity": "sha512-/FHiMyOWWEXfwK/lM0WxmkP9GLzbSJJuzGtfeuNWSOVDnvAMbjavitxfHb5wSbWKIQo0XYC1EJ2Y7x91XNYP4w==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.5.9.tgz",
"integrity": "sha512-4H5QIHQVtQYCuL43GCRLGjNQhZpQg9gL03ja0DV80kO2Dn9LEt6ol87bSnSjn4VDgcAXtgTzXFvRLknfVgAAqg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -10809,7 +10809,7 @@
"peerDependencies": {
"esbuild": "*",
"rollup": "*",
"storybook": "10.5.8",
"storybook": "10.5.9",
"vite": "*",
"webpack": "*"
},
@@ -10829,9 +10829,9 @@
}
},
"node_modules/@storybook/addon-docs/node_modules/@storybook/react-dom-shim": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.5.8.tgz",
"integrity": "sha512-N8D13/Xny+V3kfe1KBgsAHS0nKWXLLdgOOXS9poKdYzVwVCN+CGEGBxWX0zMMtdCptqa6/57em9coPlZMoO+bg==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.5.9.tgz",
"integrity": "sha512-7qZD6CSa64p1m/zX9tG4ALcEHlEk0Bx+5++4RL3MFlRCgCFfAomXsCHTzF0RyF8cI4vl+hS7Y0ryjQchVs6UQA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -10843,7 +10843,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.5.8"
"storybook": "10.5.9"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -10855,9 +10855,9 @@
}
},
"node_modules/@storybook/addon-links": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-10.5.8.tgz",
"integrity": "sha512-mpWw4alBJVGqgVh897LZ2keN/xnMHcH93wKJG+oGg4+cdEUA+06hCs5T4k+AS5Aa+EZ6LvdOoi2VPHssyQlCCA==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-10.5.9.tgz",
"integrity": "sha512-ZDbPl6ia6hqjoV+CpQU3DjkXpc0TxUq6+y/rFD8w21dJMdqNWzY8zajHC8r4CfTWANjM1pGPUYisWtTKi1MxZw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -10870,7 +10870,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.5.8"
"storybook": "10.5.9"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -10964,15 +10964,15 @@
}
},
"node_modules/@storybook/react-webpack5": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/react-webpack5/-/react-webpack5-10.5.8.tgz",
"integrity": "sha512-HkPi42WaoNSHC0DAERsJEF7Vhnluzsp/aiuhnH65GGYG5TmdLL9G8KDiYvXHGDCyb4RfoAPYrtzxaLMFfPPFvQ==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/react-webpack5/-/react-webpack5-10.5.9.tgz",
"integrity": "sha512-mrCJub/WAt6RAU1P+bpBvcdTHMHePXLuNM+TuJl0Sl3r9Ta0YjDvtdODweud9sTEpVN3ao/fk0LpiaDMfLd84w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/builder-webpack5": "10.5.8",
"@storybook/preset-react-webpack": "10.5.8",
"@storybook/react": "10.5.8"
"@storybook/builder-webpack5": "10.5.9",
"@storybook/preset-react-webpack": "10.5.9",
"@storybook/react": "10.5.9"
},
"funding": {
"type": "opencollective",
@@ -10981,7 +10981,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"storybook": "10.5.8",
"storybook": "10.5.9",
"typescript": ">= 4.9.x"
},
"peerDependenciesMeta": {
@@ -10991,13 +10991,13 @@
}
},
"node_modules/@storybook/react-webpack5/node_modules/@storybook/builder-webpack5": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-10.5.8.tgz",
"integrity": "sha512-ke5x27gtWQ4gpXCLWxdGkr8ZlJwBykV/KjbBTAlC04dmS9OkI9MBzGj+TteUlgrcaN7LwoNTR5zRmxKStOZYzQ==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-10.5.9.tgz",
"integrity": "sha512-XTLC95jP75V9NfhoUzDNKDCn9r0ZqXz4ZhrNzQXVDz4vNWkjU3/uDL6Ywh9WFu6Xrb+onQqSR9hlHjS/DOZj7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/core-webpack": "10.5.8",
"@storybook/core-webpack": "10.5.9",
"case-sensitive-paths-webpack-plugin": "^2.4.0",
"cjs-module-lexer": "^1.2.3",
"css-loader": "^7.1.2",
@@ -11019,7 +11019,7 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
"storybook": "10.5.8"
"storybook": "10.5.9"
},
"peerDependenciesMeta": {
"typescript": {
@@ -11028,9 +11028,9 @@
}
},
"node_modules/@storybook/react-webpack5/node_modules/@storybook/builder-webpack5/node_modules/@storybook/core-webpack": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-10.5.8.tgz",
"integrity": "sha512-HccINB0UbTtnyJtKpaX+C35BRTSnAwnreIMwwI+LpeUd4x9mQg0G9orB7lfBBZwd5LQf8YhM2Vkjiawzo41GLg==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-10.5.9.tgz",
"integrity": "sha512-YmXR9RJdQpH8EtWEIjLTr5LMGiCXSmZp/A9UkATY5xHM4qG2QwJB++jU2wv4nGDyaPiUcbzT2PQSXN6RXhiUZA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11041,17 +11041,17 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
"storybook": "10.5.8"
"storybook": "10.5.9"
}
},
"node_modules/@storybook/react-webpack5/node_modules/@storybook/preset-react-webpack": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-10.5.8.tgz",
"integrity": "sha512-0JjgVoX5t9Wb+gwddYHx/Ej7KFqwd65lpHXEhBoT4pFWRqVI0pvfHu42M+DRGjsgOye3uE+3pH4yHR3+0/fCHA==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-10.5.9.tgz",
"integrity": "sha512-LOr8SoM2CejVCHeLyxbdRMiKuQb2q95CE5D75oK3+513mMZ8LxVPVApxy8B6FvFYNe9CTqVK+95jETefOqabTw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/core-webpack": "10.5.8",
"@storybook/core-webpack": "10.5.9",
"@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0",
"@types/semver": "^7.7.1",
"magic-string": "^0.30.5",
@@ -11068,7 +11068,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"storybook": "10.5.8"
"storybook": "10.5.9"
},
"peerDependenciesMeta": {
"typescript": {
@@ -11077,9 +11077,9 @@
}
},
"node_modules/@storybook/react-webpack5/node_modules/@storybook/preset-react-webpack/node_modules/@storybook/core-webpack": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-10.5.8.tgz",
"integrity": "sha512-HccINB0UbTtnyJtKpaX+C35BRTSnAwnreIMwwI+LpeUd4x9mQg0G9orB7lfBBZwd5LQf8YhM2Vkjiawzo41GLg==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-10.5.9.tgz",
"integrity": "sha512-YmXR9RJdQpH8EtWEIjLTr5LMGiCXSmZp/A9UkATY5xHM4qG2QwJB++jU2wv4nGDyaPiUcbzT2PQSXN6RXhiUZA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11090,18 +11090,18 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
"storybook": "10.5.8"
"storybook": "10.5.9"
}
},
"node_modules/@storybook/react-webpack5/node_modules/@storybook/react": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.5.8.tgz",
"integrity": "sha512-6qqkmqX6imtL+0Z9Uan2tIfYivOI0FiVmWr0zpqqQR15AkJ18JfNcNTQoyjeAlCO0Kei56SWqnu2qLq52TYplg==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.5.9.tgz",
"integrity": "sha512-kApGOuNT26NkpioTsr1iT/Q2c44tA7OIsNUSyFqtT7W8k3fRn/jQWfrDegYxty0WG0wxdNMZq2ndRfOOF8HaHw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/global": "^5.0.0",
"@storybook/react-dom-shim": "10.5.8",
"@storybook/react-dom-shim": "10.5.9",
"react-docgen": "^8.0.2",
"react-docgen-typescript": "^2.2.2"
},
@@ -11114,7 +11114,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.5.8",
"storybook": "10.5.9",
"typescript": ">= 4.9.x"
},
"peerDependenciesMeta": {
@@ -11130,9 +11130,9 @@
}
},
"node_modules/@storybook/react-webpack5/node_modules/@storybook/react/node_modules/@storybook/react-dom-shim": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.5.8.tgz",
"integrity": "sha512-N8D13/Xny+V3kfe1KBgsAHS0nKWXLLdgOOXS9poKdYzVwVCN+CGEGBxWX0zMMtdCptqa6/57em9coPlZMoO+bg==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.5.9.tgz",
"integrity": "sha512-7qZD6CSa64p1m/zX9tG4ALcEHlEk0Bx+5++4RL3MFlRCgCFfAomXsCHTzF0RyF8cI4vl+hS7Y0ryjQchVs6UQA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -11144,7 +11144,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.5.8"
"storybook": "10.5.9"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -14928,9 +14928,9 @@
}
},
"node_modules/antd": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/antd/-/antd-6.6.0.tgz",
"integrity": "sha512-UDwWIbpmrCHB9ZQ+bPh4vQfB6DTI2ulIyoQ0Tc9xxalFblttiNGHl3ySBD9SyV/8+gUjFzfSx1+iU1Fog2i46w==",
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/antd/-/antd-6.6.1.tgz",
"integrity": "sha512-QHIHYoUk9N9nJy1T9fyxWKjY0qApdTEDd/6lzqYng8Uryv9FejNmbhKvYF7obGqB+TuLXQsPVF7fOVgyzM1KrQ==",
"license": "MIT",
"dependencies": {
"@ant-design/colors": "^8.0.1",
@@ -14964,16 +14964,16 @@
"@rc-component/rate": "~1.0.1",
"@rc-component/resize-observer": "^1.1.2",
"@rc-component/segmented": "~1.3.0",
"@rc-component/select": "~1.10.0",
"@rc-component/select": "~1.10.1",
"@rc-component/slider": "~1.1.1",
"@rc-component/steps": "~1.2.2",
"@rc-component/switch": "~1.0.3",
"@rc-component/table": "~1.11.0",
"@rc-component/table": "~1.11.1",
"@rc-component/tabs": "~1.12.0",
"@rc-component/tooltip": "~1.5.0",
"@rc-component/tour": "~2.4.0",
"@rc-component/tree": "~1.4.0",
"@rc-component/tree-select": "~1.16.0",
"@rc-component/tree-select": "~1.16.1",
"@rc-component/trigger": "^3.10.1",
"@rc-component/upload": "~1.1.1",
"@rc-component/util": "^1.12.0",
@@ -15715,9 +15715,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
"version": "2.11.14",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.14.tgz",
"integrity": "sha512-JyJ954WzuIR8/FFzX0o5krdSTrBAkcCSRfWSleRsIHSWV+cZe2FI1PKggVkFke1hBldRs+LRxUczzE9iPmgZww==",
"version": "2.11.15",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.15.tgz",
"integrity": "sha512-FwMjJJ7HnyZpWe+oWxegG0fezZyBZUagI5LZEoO3GCbtbKNwRfMH9Ue5d5v01PNePBy1QSfPSDTTeVL0Hb9EzA==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -18559,9 +18559,9 @@
}
},
"node_modules/dayjs": {
"version": "1.11.22",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.22.tgz",
"integrity": "sha512-1YRnxzt/AabP3GHxnaB9/b+ZScCKu5TeF+co+BWG+lnWVIwEcTFc1FVE0WLNmNO3sA6GGXL40i5qkHfbLzpwrg==",
"version": "1.11.23",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.23.tgz",
"integrity": "sha512-QDTCU0M0MxR3hQfnlDJfwekQiaanm1ubOD231u73WBckQ/fsamwRLiE2GBz6D3a/xF1NgfiDLJjXBa1hYOYTtQ==",
"license": "MIT"
},
"node_modules/debounce": {
@@ -19140,11 +19140,10 @@
}
},
"node_modules/dompurify": {
"version": "3.4.12",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.12.tgz",
"integrity": "sha512-zQvGet8Z2sWbQhCmfFz/T5QWH2oBmjnqK3qvOjaqaNLrLEF912WamU+ohnTp0TCep/MFVHpdJuCZEdFOdTnEFg==",
"version": "3.4.13",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.13.tgz",
"integrity": "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==",
"license": "(MPL-2.0 OR Apache-2.0)",
"optional": true,
"optionalDependencies": {
"@types/trusted-types": "^2.0.7"
}
@@ -20237,9 +20236,9 @@
}
},
"node_modules/eslint-plugin-storybook": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-10.5.8.tgz",
"integrity": "sha512-bf9W5nZyWdIaCUZf4aEZnEeD1mn+csNYX8dYUQjAo6L7/DkSLtr65R4zFZ1xeS4m6dOXO6UtUySesCSw4e8w1g==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-10.5.9.tgz",
"integrity": "sha512-4Hrqccy/zttV0S/32TSUbqtizzj4sbkgYvv7UzHveH58v96PhrO+fSpOFAqYvzNDzdOU6smKwObFtzX+RZqj4w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -20248,7 +20247,7 @@
},
"peerDependencies": {
"eslint": ">=8",
"storybook": "10.5.8"
"storybook": "10.5.9"
}
},
"node_modules/eslint-plugin-testing-library": {
@@ -37735,9 +37734,9 @@
}
},
"node_modules/storybook": {
"version": "10.5.8",
"resolved": "https://registry.npmjs.org/storybook/-/storybook-10.5.8.tgz",
"integrity": "sha512-rR4oFMSiWBSqI0lvsJPtcQUPj8+hzj3TkLu+Mw61Wo6YxPSb5FsLSHai0jZnuaIdKIlmu25KCfwlSQl4e1uvnA==",
"version": "10.5.9",
"resolved": "https://registry.npmjs.org/storybook/-/storybook-10.5.9.tgz",
"integrity": "sha512-UfdMKSjEhIKr8LbqYyIE5r7vT/drL/PxN75YaouJ+UG0FssEy6cf49OdTF3kstAqVMHskc+zEqyRoiQHZXHwgA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -42986,7 +42985,7 @@
"d3-scale": "^4.0.2",
"d3-time": "^3.1.0",
"d3-time-format": "^4.1.0",
"dayjs": "^1.11.22",
"dayjs": "^1.11.23",
"dompurify": "^3.4.13",
"fetch-retry": "^6.0.0",
"handlebars": "^4.7.9",
@@ -43146,189 +43145,6 @@
"version": "0.20.3",
"license": "Apache-2.0"
},
"plugins/legacy-plugin-chart-calendar": {
"name": "@superset-ui/legacy-plugin-chart-calendar",
"version": "0.20.3",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"d3-array": "^3.2.4",
"d3-selection": "^3.0.0",
"d3-tip": "^0.9.1",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@emotion/react": "^11.4.1",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
}
},
"plugins/legacy-plugin-chart-chord": {
"name": "@superset-ui/legacy-plugin-chart-chord",
"version": "0.20.3",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"d3": "^3.5.17",
"prop-types": "^15.8.1",
"react": "^19.2.7"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*"
}
},
"plugins/legacy-plugin-chart-country-map": {
"name": "@superset-ui/legacy-plugin-chart-country-map",
"version": "0.20.3",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"d3": "^3.5.17",
"d3-array": "^3.2.4",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
}
},
"plugins/legacy-plugin-chart-horizon": {
"name": "@superset-ui/legacy-plugin-chart-horizon",
"version": "0.20.3",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"d3-array": "^3.2.4",
"d3-scale": "^4.0.2",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
}
},
"plugins/legacy-plugin-chart-paired-t-test": {
"name": "@superset-ui/legacy-plugin-chart-paired-t-test",
"version": "0.20.3",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"distributions": "^2.2.0",
"prop-types": "^15.8.1",
"reactable": "^1.1.0"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
}
},
"plugins/legacy-plugin-chart-parallel-coordinates": {
"name": "@superset-ui/legacy-plugin-chart-parallel-coordinates",
"version": "0.20.3",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"d3v3": "npm:d3@3.5.17",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
}
},
"plugins/legacy-plugin-chart-partition": {
"name": "@superset-ui/legacy-plugin-chart-partition",
"version": "0.20.3",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"d3": "^3.5.17",
"d3-hierarchy": "^3.1.2",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@testing-library/jest-dom": "*",
"@testing-library/react": "^15.0.0",
"react": "^18.3.0",
"react-dom": "^18.3.0"
}
},
"plugins/legacy-plugin-chart-rose": {
"name": "@superset-ui/legacy-plugin-chart-rose",
"version": "0.20.3",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"d3": "^3.5.17",
"nvd3-fork": "^2.0.5",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@emotion/react": "^11.4.1",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
}
},
"plugins/legacy-plugin-chart-world-map": {
"name": "@superset-ui/legacy-plugin-chart-world-map",
"version": "0.20.3",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"d3": "^3.5.17",
"d3-array": "^3.2.4",
"datamaps": "^0.5.10",
"prop-types": "^15.8.1",
"tinycolor2": "^1.6.0"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"react": "^18.3.0"
}
},
"plugins/legacy-preset-chart-nvd3": {
"name": "@superset-ui/legacy-preset-chart-nvd3",
"version": "0.20.3",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"d3": "^3.5.17",
"d3-tip": "^0.9.1",
"dompurify": "^3.4.12",
"fast-safe-stringify": "^2.1.1",
"lodash": "^4.18.1",
"lodash-es": "^4.18.1",
"nvd3-fork": "^2.0.5",
"prop-types": "^15.8.1",
"urijs": "^1.19.11"
},
"peerDependencies": {
"@apache-superset/core": "*",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"dayjs": "^1.11.21",
"react": "^18.3.0"
}
},
"plugins/plugin-chart-ag-grid-table": {
"name": "@superset-ui/plugin-chart-ag-grid-table",
"version": "0.20.3",
+8 -8
View File
@@ -158,12 +158,12 @@
"@visx/xychart": "^4.0.0",
"ag-grid-community": "36.1.0",
"ag-grid-react": "36.1.0",
"antd": "^6.6.0",
"antd": "^6.6.1",
"chrono-node": "^2.10.1",
"classnames": "^2.2.5",
"content-disposition": "^2.0.1",
"d3-scale": "^4.0.2",
"dayjs": "^1.11.22",
"dayjs": "^1.11.23",
"dom-to-image-more": "^3.10.2",
"dom-to-pdf": "^0.3.2",
"echarts": "^6.1.0",
@@ -257,9 +257,9 @@
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@playwright/test": "^1.62.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.2",
"@storybook/addon-docs": "10.5.8",
"@storybook/addon-links": "10.5.8",
"@storybook/react-webpack5": "10.5.8",
"@storybook/addon-docs": "10.5.9",
"@storybook/addon-links": "10.5.9",
"@storybook/react-webpack5": "10.5.9",
"@storybook/test-runner": "0.24.4",
"@svgr/webpack": "^8.1.0",
"@swc/core": "^1.16.0",
@@ -295,7 +295,7 @@
"babel-loader": "^10.1.1",
"babel-plugin-dynamic-import-node": "^2.3.3",
"babel-plugin-jsx-remove-data-test-id": "^3.0.0",
"baseline-browser-mapping": "^2.11.14",
"baseline-browser-mapping": "^2.11.15",
"cheerio": "1.2.0",
"concurrently": "^10.0.5",
"copy-webpack-plugin": "^14.0.0",
@@ -312,7 +312,7 @@
"eslint-plugin-no-only-tests": "^3.4.0",
"eslint-plugin-react-prefer-function-component": "^5.0.0",
"eslint-plugin-react-you-might-not-need-an-effect": "^1.0.1",
"eslint-plugin-storybook": "10.5.8",
"eslint-plugin-storybook": "10.5.9",
"eslint-plugin-testing-library": "^7.16.2",
"eslint-plugin-theme-colors": "file:eslint-rules/eslint-plugin-theme-colors",
"fetch-mock": "^12.6.0",
@@ -343,7 +343,7 @@
"source-map": "^0.8.0",
"source-map-support": "^0.5.21",
"speed-measure-webpack-plugin": "^1.6.0",
"storybook": "10.5.8",
"storybook": "10.5.9",
"style-loader": "^4.0.0",
"stylelint": "^17.14.1",
"swc-loader": "^0.2.7",
@@ -67,7 +67,7 @@
"d3-scale": "^4.0.2",
"d3-time": "^3.1.0",
"d3-time-format": "^4.1.0",
"dayjs": "^1.11.22",
"dayjs": "^1.11.23",
"dompurify": "^3.4.13",
"fetch-retry": "^6.0.0",
"handlebars": "^4.7.9",
@@ -669,11 +669,11 @@ describe('UploadDataModal Collapse Tabs', () => {
useRedux: true,
});
const generalInfoTab = screen.getByRole('tab', {
name: /expanded General information/i,
name: /General information/i,
});
expect(generalInfoTab).toHaveAttribute('aria-expanded', 'true');
const fileSettingsTab = screen.getByRole('tab', {
name: /collapsed File settings/i,
name: /File settings/i,
});
await userEvent.click(fileSettingsTab);
await waitFor(() => {
@@ -689,11 +689,11 @@ describe('UploadDataModal Collapse Tabs', () => {
useRedux: true,
});
const generalInfoTab = screen.getByRole('tab', {
name: /expanded General information/i,
name: /General information/i,
});
expect(generalInfoTab).toHaveAttribute('aria-expanded', 'true');
const fileSettingsTab = screen.getByRole('tab', {
name: /collapsed File settings/i,
name: /File settings/i,
});
await userEvent.click(fileSettingsTab);
await waitFor(() => {
@@ -709,11 +709,11 @@ describe('UploadDataModal Collapse Tabs', () => {
useRedux: true,
});
const generalInfoTab = screen.getByRole('tab', {
name: /expanded General information/i,
name: /General information/i,
});
expect(generalInfoTab).toHaveAttribute('aria-expanded', 'true');
const fileSettingsTab = screen.getByRole('tab', {
name: /collapsed File settings/i,
name: /File settings/i,
});
await userEvent.click(fileSettingsTab);
await waitFor(() => {
@@ -182,7 +182,7 @@ test('With sql role - renders all panels on the page on page load', async () =>
test('With sql role - renders distinct recent activities', async () => {
await renderWelcome();
const recentPanel = screen.getByRole('button', { name: 'collapsed Recents' });
const recentPanel = screen.getByRole('button', { name: 'Recents' });
userEvent.click(recentPanel);
await waitFor(() =>
expect(
+2
View File
@@ -729,6 +729,8 @@ class ChartDataRestApi(ChartRestApi):
return ChartDataQueryContextSchema().load(form_data)
except KeyError as ex:
raise ValidationError("Request is incorrect") from ex
except ValueError as ex:
raise ValidationError(str(ex)) from ex
def _should_use_streaming(
self, result: dict[Any, Any], form_data: dict[str, Any] | None = None
-12
View File
@@ -32,13 +32,11 @@ from superset.commands.chart.exceptions import (
DashboardsForbiddenError,
DashboardsNotFoundValidationError,
)
from superset.commands.exceptions import DatasourceTypeInvalidError
from superset.commands.utils import get_datasource_by_id, populate_subjects
from superset.daos.chart import ChartDAO
from superset.daos.dashboard import DashboardDAO
from superset.exceptions import SupersetSecurityException
from superset.utils import json
from superset.utils.core import DatasourceType
from superset.utils.decorators import on_error, transaction
logger = logging.getLogger(__name__)
@@ -73,16 +71,6 @@ class CreateChartCommand(CreateMixin, BaseCommand):
# Validate/Populate datasource
try:
# Slice.datasource only ever resolves the ``table`` relationship
# (see Slice.datasource in superset/models/slice.py), so a chart
# pointed at any other datasource_type would "create"
# successfully but could never actually render. Reject those
# up front instead of failing later -- either at this lookup
# (SavedQuery/Query have no ``.name`` attribute, so accessing it
# below raises an unhandled AttributeError) or silently, by
# producing a permanently broken chart.
if datasource_type != DatasourceType.TABLE:
raise DatasourceTypeInvalidError()
datasource = get_datasource_by_id(datasource_id, datasource_type)
self._properties["datasource_name"] = datasource.name
security_manager.raise_for_access(datasource=datasource)
+9 -25
View File
@@ -35,7 +35,6 @@ from superset.commands.chart.exceptions import (
DashboardsNotFoundValidationError,
DatasourceTypeUpdateRequiredValidationError,
)
from superset.commands.exceptions import DatasourceTypeInvalidError
from superset.commands.utils import (
compute_subjects,
get_datasource_by_id,
@@ -50,7 +49,6 @@ from superset.models.dashboard import Dashboard
from superset.models.slice import Slice
from superset.tags.models import ObjectType
from superset.utils import json
from superset.utils.core import DatasourceType
from superset.utils.decorators import on_error, transaction
from superset.versioning.changes.normalization import (
register_matching_normalization_context,
@@ -185,9 +183,11 @@ class UpdateChartCommand(UpdateMixin, BaseCommand):
# Validate if datasource_id is provided datasource_type is required
datasource_id = self._properties.get("datasource_id")
datasource_type = self._properties.get("datasource_type", "")
if datasource_id is not None and not datasource_type:
exceptions.append(DatasourceTypeUpdateRequiredValidationError())
datasource_type = ""
if datasource_id is not None:
datasource_type = self._properties.get("datasource_type", "")
if not datasource_type:
exceptions.append(DatasourceTypeUpdateRequiredValidationError())
# Validate/populate model exists
self._model = ChartDAO.find_by_id(self._model_id)
@@ -221,27 +221,11 @@ class UpdateChartCommand(UpdateMixin, BaseCommand):
exceptions.append(ex)
# Validate/Populate datasource
# An empty datasource_type was already flagged above via
# DatasourceTypeUpdateRequiredValidationError; skip this block so
# we don't clobber that message with DatasourceTypeInvalidError.
if datasource_type:
if datasource_id is not None:
try:
# Slice.datasource only ever resolves the ``table``
# relationship (see Slice.datasource in
# superset/models/slice.py), so setting datasource_type to
# anything else would "succeed" but leave the chart
# permanently unable to render -- even for a type-only
# update that leaves datasource_id untouched. Reject those
# up front instead of failing later -- either at the lookup
# below (SavedQuery/Query have no ``.name`` attribute, so
# accessing it raises an unhandled AttributeError) or
# silently.
if datasource_type != DatasourceType.TABLE:
raise DatasourceTypeInvalidError()
if datasource_id is not None:
datasource = get_datasource_by_id(datasource_id, datasource_type)
self._properties["datasource_name"] = datasource.name
security_manager.raise_for_access(datasource=datasource)
datasource = get_datasource_by_id(datasource_id, datasource_type)
self._properties["datasource_name"] = datasource.name
security_manager.raise_for_access(datasource=datasource)
except SupersetSecurityException as ex:
raise ChartForbiddenError() from ex
except ValidationError as ex:
@@ -35,14 +35,12 @@ from superset.extensions import cache_manager, db, security_manager
from superset.models.core import Database, FavStar, FavStarClassName
from superset.models.dashboard import Dashboard
from superset.models.slice import Slice
from superset.models.sql_lab import SavedQuery
from superset.reports.models import ReportSchedule, ReportScheduleType
from superset.subjects.models import Subject
from superset.subjects.types import SubjectType
from superset.tags.models import ObjectType, Tag, TaggedObject, TagType
from superset.utils import json
from superset.utils.core import get_example_default_schema
from superset.utils.database import get_example_database
from tests.integration_tests.base_api_tests import ApiEditorsTestCaseMixin
from tests.integration_tests.base_tests import (
subjects_from_users,
@@ -662,47 +660,6 @@ class TestChartApi(ApiEditorsTestCaseMixin, InsertChartMixin, SupersetTestCase):
response = json.loads(rv.data.decode("utf-8"))
assert response == {"message": {"datasource_id": ["Datasource does not exist"]}}
def test_create_chart_from_saved_query_rejected_cleanly(self):
"""
Chart API: creating a chart with datasource_type="saved_query" must
fail with a clean validation error, not the unhandled 500 "Fatal
error" reported in apache/superset#29697. Slice.datasource only
ever resolves the "table" relationship, so even a chart that
"created" successfully with this datasource_type could never
actually render -- "saved_query" is a real, existing row here
(not a bad ID), reproducing the original report exactly rather
than a not-found case.
"""
self.login(ADMIN_USERNAME)
example_db = get_example_database()
saved_query = SavedQuery(
db_id=example_db.id,
label="issue-29697-repro",
schema=get_example_default_schema(),
sql="SELECT 1 AS value",
)
db.session.add(saved_query)
db.session.commit()
saved_query_id = saved_query.id
chart_data = {
"slice_name": "issue-29697-repro-chart",
"datasource_id": saved_query_id,
"datasource_type": "saved_query",
"viz_type": "table",
}
try:
rv = self.post_assert_metric("/api/v1/chart/", chart_data, "post")
assert rv.status_code == 422
response = json.loads(rv.data.decode("utf-8"))
assert response == {
"message": {"datasource_type": ["Datasource type is invalid"]}
}
finally:
db.session.delete(db.session.query(SavedQuery).get(saved_query_id))
db.session.commit()
@pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
def test_create_chart_validate_user_is_dashboard_editor(self):
"""
@@ -363,6 +363,15 @@ class TestPostChartDataApi(BaseTestChartDataApi):
rv = self.post_assert_metric(CHART_DATA_URI, self.query_context_payload, "data")
assert rv.status_code == 400
def test_with_reversed_time_range__400(self):
# A reversed custom date range (since > until) makes get_since_until
# raise a ValueError; the API must convert it to a 400, not a 500.
self.query_context_payload["queries"][0]["time_range"] = (
"2024-01-01T00:00:00 : 2020-01-01T00:00:00"
)
rv = self.post_assert_metric(CHART_DATA_URI, self.query_context_payload, "data")
assert rv.status_code == 400
@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
def test_with_invalid_payload__400(self):
invalid_query_context = {"form_data": "NOT VALID JSON"}
@@ -858,3 +858,23 @@ def test_send_chart_response_does_not_double_extension_for_csv_filename() -> Non
content_disposition = response.headers["Content-Disposition"]
assert "my_export.csv.csv" not in content_disposition
assert "my_export.csv" in content_disposition
def test_create_query_context_from_form_converts_value_error_to_400() -> None:
"""
A ValueError raised while loading the query context (e.g. a reversed date
range where since > until) is re-raised as a marshmallow ValidationError so
the API returns a 400 instead of an unhandled 500.
"""
from marshmallow import ValidationError
api = ChartDataRestApi()
message = "From date cannot be larger than to date"
with patch(
"superset.charts.data.api.ChartDataQueryContextSchema.load",
side_effect=ValueError(message),
):
with pytest.raises(ValidationError) as excinfo:
api._create_query_context_from_form({})
assert message in str(excinfo.value)
@@ -1,154 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Unit tests for CreateChartCommand.
Regression coverage for apache/superset#29697: POST /api/v1/chart/ with
datasource_type="saved_query" (or "query") crashes with an unhandled
AttributeError -- reported to API clients as an opaque 500 "Fatal error" --
because SavedQuery and Query models have no ``.name`` attribute, and because
Slice.datasource only ever resolves a ``table``-typed datasource, so even a
successfully created chart of another type could never actually render.
"""
import pytest
from pytest_mock import MockerFixture
from superset.commands.chart.create import CreateChartCommand
from superset.commands.chart.exceptions import ChartForbiddenError, ChartInvalidError
from superset.commands.exceptions import DatasourceTypeInvalidError
from superset.errors import ErrorLevel, SupersetError, SupersetErrorType
from superset.exceptions import SupersetSecurityException
def _base_mocks(mocker: MockerFixture) -> None:
mocker.patch(
"superset.commands.chart.create.DashboardDAO.find_by_ids", return_value=[]
)
mocker.patch(
"superset.commands.chart.create.populate_subjects",
side_effect=lambda properties, exceptions: None,
)
@pytest.mark.parametrize("datasource_type", ["saved_query", "query"])
def test_create_chart_rejects_non_table_datasource_type(
mocker: MockerFixture, datasource_type: str
) -> None:
"""A chart can only ever query a table-backed datasource -- Slice.datasource
only ever resolves the ``table`` relationship, so any other type would
produce a chart that "creates" successfully but can never render.
The two types fail differently before this fix, which is exactly why
both are covered here:
- "saved_query": SavedQuery has no ``.name`` attribute, so validation
crashes with an unhandled AttributeError -- surfaced to API clients as
an opaque 500 "Fatal error" (apache/superset#29697).
- "query": Query *does* define a synthetic ``.name`` property (used for
CTAS table naming, not as a real display name), so this one doesn't
crash -- it silently "succeeds" and creates a chart with a nonsense
name and a datasource that Slice.datasource can never resolve.
``get_datasource_by_id`` is mocked with ``spec=`` the real model classes
so accessing ``.name`` on the mock behaves exactly like the real ORM
objects do if the new guard doesn't stop the code from getting there;
``raise_for_access`` is mocked to a no-op so nothing downstream masks
that behavior.
"""
from superset.models.sql_lab import Query, SavedQuery
_base_mocks(mocker)
model_cls = SavedQuery if datasource_type == "saved_query" else Query
get_datasource_by_id = mocker.patch(
"superset.commands.chart.create.get_datasource_by_id",
return_value=mocker.MagicMock(spec=model_cls),
)
mocker.patch("superset.commands.chart.create.security_manager.raise_for_access")
with pytest.raises(ChartInvalidError) as exc_info:
CreateChartCommand(
{
"datasource_id": 11,
"datasource_type": datasource_type,
"slice_name": "some_name",
"viz_type": "table",
}
).validate()
assert any(
isinstance(ex, DatasourceTypeInvalidError) for ex in exc_info.value._exceptions
)
# The invalid type must be rejected before ever touching the datasource
# lookup, not caught incidentally by some downstream failure.
get_datasource_by_id.assert_not_called()
def test_create_chart_accepts_table_datasource(mocker: MockerFixture) -> None:
"""The one supported datasource_type must keep working."""
_base_mocks(mocker)
datasource = mocker.MagicMock(name="table_datasource")
datasource.name = "my_table"
mocker.patch(
"superset.commands.chart.create.get_datasource_by_id",
return_value=datasource,
)
mocker.patch("superset.commands.chart.create.security_manager.raise_for_access")
cmd = CreateChartCommand(
{
"datasource_id": 11,
"datasource_type": "table",
"slice_name": "some_name",
"viz_type": "table",
}
)
cmd.validate()
assert cmd._properties["datasource_name"] == "my_table"
def test_create_chart_datasource_access_denied_still_raises_forbidden(
mocker: MockerFixture,
) -> None:
"""The invalid-type guard must not shadow the existing access-denied path
for a legitimately table-typed datasource the user can't access."""
_base_mocks(mocker)
datasource = mocker.MagicMock()
datasource.name = "my_table"
mocker.patch(
"superset.commands.chart.create.get_datasource_by_id",
return_value=datasource,
)
mocker.patch(
"superset.commands.chart.create.security_manager.raise_for_access",
side_effect=SupersetSecurityException(
SupersetError(
error_type=SupersetErrorType.DATASOURCE_SECURITY_ACCESS_ERROR,
message="No access",
level=ErrorLevel.ERROR,
)
),
)
with pytest.raises(ChartForbiddenError):
CreateChartCommand(
{
"datasource_id": 11,
"datasource_type": "table",
"slice_name": "some_name",
"viz_type": "table",
}
).validate()
+1 -103
View File
@@ -17,13 +17,8 @@
import pytest
from pytest_mock import MockerFixture
from superset.commands.chart.exceptions import (
ChartForbiddenError,
ChartInvalidError,
DatasourceTypeUpdateRequiredValidationError,
)
from superset.commands.chart.exceptions import ChartForbiddenError, ChartInvalidError
from superset.commands.chart.update import UpdateChartCommand
from superset.commands.exceptions import DatasourceTypeInvalidError
from superset.errors import ErrorLevel, SupersetError, SupersetErrorType
from superset.exceptions import SupersetSecurityException
from superset.utils import json
@@ -243,100 +238,3 @@ def test_update_chart_query_context_without_datasource_is_allowed(
1,
{"query_context": query_context, "query_context_generation": True},
).validate()
@pytest.mark.parametrize("datasource_type", ["saved_query", "query"])
def test_update_chart_rejects_repointing_to_non_table_datasource(
mocker: MockerFixture, datasource_type: str
) -> None:
"""Repointing a chart's datasource_id must be rejected the same way
CreateChartCommand rejects it (apache/superset#29697): Slice.datasource
only ever resolves the ``table`` relationship, so repointing at a
saved_query or query datasource would "succeed" but leave the chart
permanently unable to render -- or, for saved_query specifically, crash
on SavedQuery's missing ``.name`` attribute before that point is even
reached. This is a regular (non-query-context) update, so it goes
through editorship + compute_subjects, unlike the query-context-only
tests above."""
find_by_id = mocker.patch("superset.commands.chart.update.ChartDAO.find_by_id")
find_by_id.return_value = mocker.MagicMock(id=1, tags=[], dashboards=[])
mocker.patch("superset.commands.chart.update.security_manager.raise_for_editorship")
mocker.patch(
"superset.commands.chart.update.compute_subjects",
side_effect=lambda model, properties, exceptions: None,
)
get_datasource_by_id = mocker.patch(
"superset.commands.chart.update.get_datasource_by_id"
)
with pytest.raises(ChartInvalidError) as exc_info:
UpdateChartCommand(
1, {"datasource_id": 11, "datasource_type": datasource_type}
).validate()
assert any(
isinstance(ex, DatasourceTypeInvalidError) for ex in exc_info.value._exceptions
)
get_datasource_by_id.assert_not_called()
def test_update_chart_missing_datasource_type_keeps_required_error(
mocker: MockerFixture,
) -> None:
"""When datasource_id is given without datasource_type, the response
must keep reporting DatasourceTypeUpdateRequiredValidationError
("Datasource type is required") rather than having it overwritten by
DatasourceTypeInvalidError ("Datasource type is invalid") -- both
exceptions key their message under ``datasource_type``, and
normalized_messages() only keeps the last one written for a given key."""
find_by_id = mocker.patch("superset.commands.chart.update.ChartDAO.find_by_id")
find_by_id.return_value = mocker.MagicMock(id=1, tags=[], dashboards=[])
mocker.patch("superset.commands.chart.update.security_manager.raise_for_editorship")
mocker.patch(
"superset.commands.chart.update.compute_subjects",
side_effect=lambda model, properties, exceptions: None,
)
get_datasource_by_id = mocker.patch(
"superset.commands.chart.update.get_datasource_by_id"
)
with pytest.raises(ChartInvalidError) as exc_info:
UpdateChartCommand(1, {"datasource_id": 11}).validate()
assert any(
isinstance(ex, DatasourceTypeUpdateRequiredValidationError)
for ex in exc_info.value._exceptions
)
assert not any(
isinstance(ex, DatasourceTypeInvalidError) for ex in exc_info.value._exceptions
)
get_datasource_by_id.assert_not_called()
@pytest.mark.parametrize("datasource_type", ["saved_query", "query"])
def test_update_chart_rejects_type_only_non_table_datasource(
mocker: MockerFixture, datasource_type: str
) -> None:
"""A type-only update (datasource_type given without datasource_id)
must be rejected the same way a repointing update is: leaving
datasource_id untouched while flipping datasource_type away from
``table`` would still break Slice.datasource, since its relationship
only ever resolves the ``table`` type."""
find_by_id = mocker.patch("superset.commands.chart.update.ChartDAO.find_by_id")
find_by_id.return_value = mocker.MagicMock(id=1, tags=[], dashboards=[])
mocker.patch("superset.commands.chart.update.security_manager.raise_for_editorship")
mocker.patch(
"superset.commands.chart.update.compute_subjects",
side_effect=lambda model, properties, exceptions: None,
)
get_datasource_by_id = mocker.patch(
"superset.commands.chart.update.get_datasource_by_id"
)
with pytest.raises(ChartInvalidError) as exc_info:
UpdateChartCommand(1, {"datasource_type": datasource_type}).validate()
assert any(
isinstance(ex, DatasourceTypeInvalidError) for ex in exc_info.value._exceptions
)
get_datasource_by_id.assert_not_called()