mirror of
https://github.com/apache/superset.git
synced 2026-05-13 11:55:16 +00:00
Compare commits
13 Commits
feat/plugi
...
fix/extens
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4381fd97ea | ||
|
|
e2a8a88d36 | ||
|
|
0d9ecb7664 | ||
|
|
1d220f7172 | ||
|
|
af4dc3a9aa | ||
|
|
fa06989ed7 | ||
|
|
4d0cc1d7a6 | ||
|
|
d8b2c5872b | ||
|
|
86ba63b072 | ||
|
|
4c14e16e58 | ||
|
|
fe22e06011 | ||
|
|
9160da0d27 | ||
|
|
43a89f8710 |
@@ -34,6 +34,7 @@ x-superset-volumes: &superset-volumes
|
||||
- superset_home:/app/superset_home
|
||||
- ./tests:/app/tests
|
||||
- superset_data:/app/data
|
||||
- ./local_extensions:/app/local_extensions
|
||||
x-common-build: &common-build
|
||||
context: .
|
||||
target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean`
|
||||
|
||||
@@ -80,7 +80,9 @@ case "${1}" in
|
||||
;;
|
||||
app)
|
||||
echo "Starting web app (using development server)..."
|
||||
flask run -p $PORT --reload --debugger --host=0.0.0.0 --exclude-patterns "*/node_modules/*:*/.venv/*:*/build/*:*/__pycache__/*:*/superset-frontend/*"
|
||||
flask run -p $PORT --reload --debugger --host=0.0.0.0 \
|
||||
--extra-files "/app/superset/extensions/.reload_trigger" \
|
||||
--exclude-patterns "*/node_modules/*:*/.venv/*:*/build/*:*/__pycache__/*:*/superset-frontend/*:*/superset/__init__.py"
|
||||
;;
|
||||
app-gunicorn)
|
||||
echo "Starting web app..."
|
||||
|
||||
2
docs/static/feature-flags.json
vendored
2
docs/static/feature-flags.json
vendored
@@ -174,7 +174,7 @@
|
||||
"default": false,
|
||||
"lifecycle": "testing",
|
||||
"description": "Allows users to add a superset:// DB that can query across databases. Experimental with potential security/performance risks. See SUPERSET_META_DB_LIMIT.",
|
||||
"docs": "https://superset.apache.org/docs/configuration/databases/#querying-across-databases"
|
||||
"docs": "https://superset.apache.org/user-docs/databases/supported/superset-meta-database"
|
||||
},
|
||||
{
|
||||
"name": "ESTIMATE_QUERY_COST",
|
||||
|
||||
332
docs/yarn.lock
332
docs/yarn.lock
@@ -232,19 +232,14 @@
|
||||
json2mq "^0.2.0"
|
||||
throttle-debounce "^5.0.0"
|
||||
|
||||
"@antfu/install-pkg@^1.0.0":
|
||||
"@antfu/install-pkg@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz"
|
||||
resolved "https://registry.yarnpkg.com/@antfu/install-pkg/-/install-pkg-1.1.0.tgz#78fa036be1a6081b5a77a5cf59f50c7752b6ba26"
|
||||
integrity sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==
|
||||
dependencies:
|
||||
package-manager-detector "^1.3.0"
|
||||
tinyexec "^1.0.1"
|
||||
|
||||
"@antfu/utils@^8.1.0":
|
||||
version "8.1.1"
|
||||
resolved "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz"
|
||||
integrity sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==
|
||||
|
||||
"@apidevtools/json-schema-ref-parser@^15.3.3":
|
||||
version "15.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-15.3.5.tgz#503726178d8d792eea7b195566272aaee6837e2f"
|
||||
@@ -1219,42 +1214,15 @@
|
||||
"@babel/helper-string-parser" "^7.27.1"
|
||||
"@babel/helper-validator-identifier" "^7.28.5"
|
||||
|
||||
"@braintree/sanitize-url@^7.0.4":
|
||||
version "7.1.1"
|
||||
resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz"
|
||||
integrity sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==
|
||||
"@braintree/sanitize-url@^7.1.1":
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz#ca2035b0fefe956a8676ff0c69af73e605fcd81f"
|
||||
integrity sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==
|
||||
|
||||
"@chevrotain/cst-dts-gen@11.0.3":
|
||||
version "11.0.3"
|
||||
resolved "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz"
|
||||
integrity sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==
|
||||
dependencies:
|
||||
"@chevrotain/gast" "11.0.3"
|
||||
"@chevrotain/types" "11.0.3"
|
||||
lodash-es "4.17.21"
|
||||
|
||||
"@chevrotain/gast@11.0.3":
|
||||
version "11.0.3"
|
||||
resolved "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz"
|
||||
integrity sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==
|
||||
dependencies:
|
||||
"@chevrotain/types" "11.0.3"
|
||||
lodash-es "4.17.21"
|
||||
|
||||
"@chevrotain/regexp-to-ast@11.0.3":
|
||||
version "11.0.3"
|
||||
resolved "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz"
|
||||
integrity sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==
|
||||
|
||||
"@chevrotain/types@11.0.3":
|
||||
version "11.0.3"
|
||||
resolved "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz"
|
||||
integrity sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==
|
||||
|
||||
"@chevrotain/utils@11.0.3":
|
||||
version "11.0.3"
|
||||
resolved "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz"
|
||||
integrity sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==
|
||||
"@chevrotain/types@~11.1.1":
|
||||
version "11.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@chevrotain/types/-/types-11.1.2.tgz#e83a1a2704f0c5e49e7592b214031a0f4a34d7e5"
|
||||
integrity sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==
|
||||
|
||||
"@colors/colors@1.5.0":
|
||||
version "1.5.0"
|
||||
@@ -2578,19 +2546,14 @@
|
||||
resolved "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz"
|
||||
integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==
|
||||
|
||||
"@iconify/utils@^2.1.33":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz"
|
||||
integrity sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==
|
||||
"@iconify/utils@^3.0.2":
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@iconify/utils/-/utils-3.1.3.tgz#71efd68f9ed2ea3c91fd3a01c0032f70a87027b7"
|
||||
integrity sha512-LPKOXPn/zV+zis1oOfGWogaXVpqUybF3ZS6SCZIsz8vg0ivVp9+fVqyYB7xq0aiST/VhUQYGO1qo6uoYSiEJqw==
|
||||
dependencies:
|
||||
"@antfu/install-pkg" "^1.0.0"
|
||||
"@antfu/utils" "^8.1.0"
|
||||
"@antfu/install-pkg" "^1.1.0"
|
||||
"@iconify/types" "^2.0.0"
|
||||
debug "^4.4.0"
|
||||
globals "^15.14.0"
|
||||
kolorist "^1.8.0"
|
||||
local-pkg "^1.0.0"
|
||||
mlly "^1.7.4"
|
||||
import-meta-resolve "^4.2.0"
|
||||
|
||||
"@jest/schemas@^29.6.3":
|
||||
version "29.6.3"
|
||||
@@ -2739,12 +2702,12 @@
|
||||
dependencies:
|
||||
"@types/mdx" "^2.0.0"
|
||||
|
||||
"@mermaid-js/parser@^0.6.2":
|
||||
version "0.6.2"
|
||||
resolved "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.2.tgz"
|
||||
integrity sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ==
|
||||
"@mermaid-js/parser@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@mermaid-js/parser/-/parser-1.1.1.tgz#30f3ab68d816912e43f245a72a0d4081bf69d966"
|
||||
integrity sha512-VuHdsYMK1bT6X2JbcAaWAhugTRvRBRyuZgd+c22swUeI9g/ntaxF7CY7dYarhZovofCbUNO0G7JesfmNtjYOCw==
|
||||
dependencies:
|
||||
langium "3.3.1"
|
||||
"@chevrotain/types" "~11.1.1"
|
||||
|
||||
"@module-federation/error-codes@0.22.0":
|
||||
version "0.22.0"
|
||||
@@ -5189,6 +5152,14 @@
|
||||
resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz"
|
||||
integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==
|
||||
|
||||
"@upsetjs/venn.js@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@upsetjs/venn.js/-/venn.js-2.0.0.tgz#3be192038cdda927aa4f8b22ab51af82abf47f34"
|
||||
integrity sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==
|
||||
optionalDependencies:
|
||||
d3-selection "^3.0.0"
|
||||
d3-transition "^3.0.1"
|
||||
|
||||
"@vx/responsive@^0.0.199":
|
||||
version "0.0.199"
|
||||
resolved "https://registry.npmjs.org/@vx/responsive/-/responsive-0.0.199.tgz"
|
||||
@@ -6170,25 +6141,6 @@ cheerio@1.0.0-rc.12:
|
||||
parse5 "^7.0.0"
|
||||
parse5-htmlparser2-tree-adapter "^7.0.0"
|
||||
|
||||
chevrotain-allstar@~0.3.0:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz"
|
||||
integrity sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==
|
||||
dependencies:
|
||||
lodash-es "^4.17.21"
|
||||
|
||||
chevrotain@~11.0.3:
|
||||
version "11.0.3"
|
||||
resolved "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz"
|
||||
integrity sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==
|
||||
dependencies:
|
||||
"@chevrotain/cst-dts-gen" "11.0.3"
|
||||
"@chevrotain/gast" "11.0.3"
|
||||
"@chevrotain/regexp-to-ast" "11.0.3"
|
||||
"@chevrotain/types" "11.0.3"
|
||||
"@chevrotain/utils" "11.0.3"
|
||||
lodash-es "4.17.21"
|
||||
|
||||
chokidar@^3.5.3, chokidar@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz"
|
||||
@@ -6420,16 +6372,6 @@ concat-map@0.0.1:
|
||||
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||
|
||||
confbox@^0.1.8:
|
||||
version "0.1.8"
|
||||
resolved "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz"
|
||||
integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==
|
||||
|
||||
confbox@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz"
|
||||
integrity sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==
|
||||
|
||||
config-chain@^1.1.11:
|
||||
version "1.1.13"
|
||||
resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz"
|
||||
@@ -6801,10 +6743,10 @@ cytoscape-fcose@^2.2.0:
|
||||
dependencies:
|
||||
cose-base "^2.2.0"
|
||||
|
||||
cytoscape@^3.29.3:
|
||||
version "3.33.1"
|
||||
resolved "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz"
|
||||
integrity sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==
|
||||
cytoscape@^3.33.1:
|
||||
version "3.33.3"
|
||||
resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.33.3.tgz#6c885823cb088eb8c31087c35d978661dcde5eae"
|
||||
integrity sha512-Gej7U+OKR+LZ8kvX7rb2HhCYJ0IhvEFsnkud4SB1PR+BUY/TsSO0dmOW59WEVLu51b1Rm+gQRKoz4bLYxGSZ2g==
|
||||
|
||||
"d3-array@1 - 2", d3-array@2, d3-array@^2.3.0:
|
||||
version "2.12.1"
|
||||
@@ -7014,7 +6956,7 @@ d3-scale@^3.0.0:
|
||||
d3-time "^2.1.1"
|
||||
d3-time-format "2 - 3"
|
||||
|
||||
"d3-selection@2 - 3", d3-selection@3:
|
||||
"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz"
|
||||
integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==
|
||||
@@ -7066,7 +7008,7 @@ d3-shape@^1.2.0:
|
||||
resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz"
|
||||
integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
|
||||
|
||||
"d3-transition@2 - 3", d3-transition@3:
|
||||
"d3-transition@2 - 3", d3-transition@3, d3-transition@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz"
|
||||
integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==
|
||||
@@ -7124,10 +7066,10 @@ d3@^7.9.0:
|
||||
d3-transition "3"
|
||||
d3-zoom "3"
|
||||
|
||||
dagre-d3-es@7.0.11:
|
||||
version "7.0.11"
|
||||
resolved "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz"
|
||||
integrity sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==
|
||||
dagre-d3-es@7.0.14:
|
||||
version "7.0.14"
|
||||
resolved "https://registry.yarnpkg.com/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz#1272276e26457cf3b97dac569f8f0531ec33c377"
|
||||
integrity sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==
|
||||
dependencies:
|
||||
d3 "^7.9.0"
|
||||
lodash-es "^4.17.21"
|
||||
@@ -7159,11 +7101,16 @@ data-view-byte-offset@^1.0.1:
|
||||
es-errors "^1.3.0"
|
||||
is-data-view "^1.0.1"
|
||||
|
||||
dayjs@^1.11.11, dayjs@^1.11.13:
|
||||
dayjs@^1.11.11:
|
||||
version "1.11.13"
|
||||
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz"
|
||||
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
|
||||
|
||||
dayjs@^1.11.19:
|
||||
version "1.11.20"
|
||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.20.tgz#88d919fd639dc991415da5f4cb6f1b6650811938"
|
||||
integrity sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==
|
||||
|
||||
debounce@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz"
|
||||
@@ -7176,7 +7123,7 @@ debug@2.6.9:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0, debug@^4.4.1, debug@^4.4.3:
|
||||
debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.1, debug@^4.4.3:
|
||||
version "4.4.3"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz"
|
||||
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
|
||||
@@ -7447,7 +7394,14 @@ domhandler@^5.0.2, domhandler@^5.0.3:
|
||||
dependencies:
|
||||
domelementtype "^2.3.0"
|
||||
|
||||
dompurify@^3.2.5, dompurify@^3.4.0:
|
||||
dompurify@^3.3.1:
|
||||
version "3.4.2"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.2.tgz#f0ff81be682c485505097ba8195a058d8f575218"
|
||||
integrity sha512-lHeS9SA/IKeIFFyYciHBr2n0v1VMPlSj843HdLOwjb2OxNwdq9Xykxqhk+FE42MzAdHvInbAolSE4mhahPpjXA==
|
||||
optionalDependencies:
|
||||
"@types/trusted-types" "^2.0.7"
|
||||
|
||||
dompurify@^3.4.0:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.1.tgz#521d04483ac12631b2aedf434a5f5390933b8789"
|
||||
integrity sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw==
|
||||
@@ -7716,6 +7670,11 @@ es-to-primitive@^1.3.0:
|
||||
is-date-object "^1.0.5"
|
||||
is-symbol "^1.0.4"
|
||||
|
||||
es-toolkit@^1.45.1:
|
||||
version "1.46.1"
|
||||
resolved "https://registry.yarnpkg.com/es-toolkit/-/es-toolkit-1.46.1.tgz#38ca27191a98a867fc544b81cf1477a68947fb06"
|
||||
integrity sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==
|
||||
|
||||
es6-promise@^3.2.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz"
|
||||
@@ -8107,11 +8066,6 @@ express@^4.21.2:
|
||||
utils-merge "1.0.1"
|
||||
vary "~1.1.2"
|
||||
|
||||
exsolve@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz"
|
||||
integrity sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==
|
||||
|
||||
extend-shallow@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz"
|
||||
@@ -8512,11 +8466,6 @@ globals@^14.0.0:
|
||||
resolved "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz"
|
||||
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
|
||||
|
||||
globals@^15.14.0:
|
||||
version "15.15.0"
|
||||
resolved "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz"
|
||||
integrity sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==
|
||||
|
||||
globals@^17.6.0:
|
||||
version "17.6.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-17.6.0.tgz#0f0be018d5cca8690e6375ead1f65c4bb96191fc"
|
||||
@@ -9083,6 +9032,11 @@ import-lazy@^4.0.0:
|
||||
resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz"
|
||||
integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==
|
||||
|
||||
import-meta-resolve@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz#08cb85b5bd37ecc8eb1e0f670dc2767002d43734"
|
||||
integrity sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==
|
||||
|
||||
imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
|
||||
@@ -9792,10 +9746,10 @@ jsonfile@^6.0.1:
|
||||
object.assign "^4.1.4"
|
||||
object.values "^1.1.6"
|
||||
|
||||
katex@^0.16.22:
|
||||
version "0.16.22"
|
||||
resolved "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz"
|
||||
integrity sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==
|
||||
katex@^0.16.25:
|
||||
version "0.16.45"
|
||||
resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.45.tgz#ba60d39c54746b6b8d39ce0e7f6eace07143149c"
|
||||
integrity sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==
|
||||
dependencies:
|
||||
commander "^8.3.0"
|
||||
|
||||
@@ -9826,22 +9780,6 @@ kleur@^4.0.3:
|
||||
resolved "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz"
|
||||
integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
|
||||
|
||||
kolorist@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz"
|
||||
integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==
|
||||
|
||||
langium@3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz"
|
||||
integrity sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==
|
||||
dependencies:
|
||||
chevrotain "~11.0.3"
|
||||
chevrotain-allstar "~0.3.0"
|
||||
vscode-languageserver "~9.0.1"
|
||||
vscode-languageserver-textdocument "~1.0.11"
|
||||
vscode-uri "~3.0.8"
|
||||
|
||||
latest-version@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz"
|
||||
@@ -9992,15 +9930,6 @@ loader-utils@^2.0.0:
|
||||
emojis-list "^3.0.0"
|
||||
json5 "^2.1.2"
|
||||
|
||||
local-pkg@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz"
|
||||
integrity sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==
|
||||
dependencies:
|
||||
mlly "^1.7.4"
|
||||
pkg-types "^2.3.0"
|
||||
quansync "^0.2.11"
|
||||
|
||||
locate-path@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz"
|
||||
@@ -10015,7 +9944,7 @@ locate-path@^7.1.0:
|
||||
dependencies:
|
||||
p-locate "^6.0.0"
|
||||
|
||||
lodash-es@4.17.21, lodash-es@^4.17.21:
|
||||
lodash-es@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz"
|
||||
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
|
||||
@@ -10106,10 +10035,10 @@ markdown-table@^3.0.0:
|
||||
resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz"
|
||||
integrity sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==
|
||||
|
||||
marked@^16.0.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.npmjs.org/marked/-/marked-16.2.0.tgz"
|
||||
integrity sha512-LbbTuye+0dWRz2TS9KJ7wsnD4KAtpj0MVkWc90XvBa6AslXsT0hTBVH5k32pcSyHH1fst9XEFJunXHktVy0zlg==
|
||||
marked@^16.3.0:
|
||||
version "16.4.2"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-16.4.2.tgz#4959a64be6c486f0db7467ead7ce288de54290a3"
|
||||
integrity sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==
|
||||
|
||||
math-expression-evaluator@^1.3.8:
|
||||
version "1.4.0"
|
||||
@@ -10430,30 +10359,31 @@ merge2@^1.3.0, merge2@^1.4.1:
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
mermaid@>=11.6.0:
|
||||
version "11.10.0"
|
||||
resolved "https://registry.npmjs.org/mermaid/-/mermaid-11.10.0.tgz"
|
||||
integrity sha512-oQsFzPBy9xlpnGxUqLbVY8pvknLlsNIJ0NWwi8SUJjhbP1IT0E0o1lfhU4iYV3ubpy+xkzkaOyDUQMn06vQElQ==
|
||||
version "11.15.0"
|
||||
resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-11.15.0.tgz#b485c13ea5e1e74f3328c4bb00427bda87fa1c1e"
|
||||
integrity sha512-pTMbcf3rWdtLiYGpmoTjHEpeY8seiy6sR+9nD7LOs8KfUbHE4lOUAprTRqRAcWSQ6MQpdX+YEsxShtGsINtPtw==
|
||||
dependencies:
|
||||
"@braintree/sanitize-url" "^7.0.4"
|
||||
"@iconify/utils" "^2.1.33"
|
||||
"@mermaid-js/parser" "^0.6.2"
|
||||
"@braintree/sanitize-url" "^7.1.1"
|
||||
"@iconify/utils" "^3.0.2"
|
||||
"@mermaid-js/parser" "^1.1.1"
|
||||
"@types/d3" "^7.4.3"
|
||||
cytoscape "^3.29.3"
|
||||
"@upsetjs/venn.js" "^2.0.0"
|
||||
cytoscape "^3.33.1"
|
||||
cytoscape-cose-bilkent "^4.1.0"
|
||||
cytoscape-fcose "^2.2.0"
|
||||
d3 "^7.9.0"
|
||||
d3-sankey "^0.12.3"
|
||||
dagre-d3-es "7.0.11"
|
||||
dayjs "^1.11.13"
|
||||
dompurify "^3.2.5"
|
||||
katex "^0.16.22"
|
||||
dagre-d3-es "7.0.14"
|
||||
dayjs "^1.11.19"
|
||||
dompurify "^3.3.1"
|
||||
es-toolkit "^1.45.1"
|
||||
katex "^0.16.25"
|
||||
khroma "^2.1.0"
|
||||
lodash-es "^4.17.21"
|
||||
marked "^16.0.0"
|
||||
marked "^16.3.0"
|
||||
roughjs "^4.6.6"
|
||||
stylis "^4.3.6"
|
||||
ts-dedent "^2.2.0"
|
||||
uuid "^11.1.0"
|
||||
uuid "^11.1.0 || ^12 || ^13 || ^14.0.0"
|
||||
|
||||
methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
@@ -11159,16 +11089,6 @@ minimist@^1.2.0:
|
||||
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
|
||||
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||
|
||||
mlly@^1.7.4:
|
||||
version "1.7.4"
|
||||
resolved "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz"
|
||||
integrity sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==
|
||||
dependencies:
|
||||
acorn "^8.14.0"
|
||||
pathe "^2.0.1"
|
||||
pkg-types "^1.3.0"
|
||||
ufo "^1.5.4"
|
||||
|
||||
mri@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz"
|
||||
@@ -11849,11 +11769,6 @@ path@0.12.7:
|
||||
process "^0.11.1"
|
||||
util "^0.10.3"
|
||||
|
||||
pathe@^2.0.1, pathe@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz"
|
||||
integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==
|
||||
|
||||
picocolors@^1.0.0, picocolors@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz"
|
||||
@@ -11881,24 +11796,6 @@ pkg-dir@^7.0.0:
|
||||
dependencies:
|
||||
find-up "^6.3.0"
|
||||
|
||||
pkg-types@^1.3.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz"
|
||||
integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==
|
||||
dependencies:
|
||||
confbox "^0.1.8"
|
||||
mlly "^1.7.4"
|
||||
pathe "^2.0.1"
|
||||
|
||||
pkg-types@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz"
|
||||
integrity sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==
|
||||
dependencies:
|
||||
confbox "^0.2.2"
|
||||
exsolve "^1.0.7"
|
||||
pathe "^2.0.3"
|
||||
|
||||
pluralize@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz"
|
||||
@@ -12644,11 +12541,6 @@ qs@^6.12.3, qs@~6.14.0:
|
||||
dependencies:
|
||||
side-channel "^1.1.0"
|
||||
|
||||
quansync@^0.2.11:
|
||||
version "0.2.11"
|
||||
resolved "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz"
|
||||
integrity sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==
|
||||
|
||||
querystringify@^2.1.1:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz"
|
||||
@@ -14778,11 +14670,6 @@ typescript@~6.0.3:
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-6.0.3.tgz#90251dc007916e972786cb94d74d15b185577d21"
|
||||
integrity sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==
|
||||
|
||||
ufo@^1.5.4:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz"
|
||||
integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==
|
||||
|
||||
un-eval@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/un-eval/-/un-eval-1.2.0.tgz"
|
||||
@@ -15115,10 +15002,10 @@ uuid@8.3.2, uuid@^8.3.2:
|
||||
resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
||||
uuid@^11.1.0:
|
||||
version "11.1.0"
|
||||
resolved "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz"
|
||||
integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==
|
||||
"uuid@^11.1.0 || ^12 || ^13 || ^14.0.0":
|
||||
version "14.0.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-14.0.0.tgz#0af883220163d264ffe0c084f6b8a89b9666966d"
|
||||
integrity sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==
|
||||
|
||||
uvu@^0.5.0:
|
||||
version "0.5.6"
|
||||
@@ -15212,41 +15099,6 @@ vfile@^6.0.0, vfile@^6.0.1:
|
||||
"@types/unist" "^3.0.0"
|
||||
vfile-message "^4.0.0"
|
||||
|
||||
vscode-jsonrpc@8.2.0:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz"
|
||||
integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==
|
||||
|
||||
vscode-languageserver-protocol@3.17.5:
|
||||
version "3.17.5"
|
||||
resolved "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz"
|
||||
integrity sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==
|
||||
dependencies:
|
||||
vscode-jsonrpc "8.2.0"
|
||||
vscode-languageserver-types "3.17.5"
|
||||
|
||||
vscode-languageserver-textdocument@~1.0.11:
|
||||
version "1.0.12"
|
||||
resolved "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz"
|
||||
integrity sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==
|
||||
|
||||
vscode-languageserver-types@3.17.5:
|
||||
version "3.17.5"
|
||||
resolved "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz"
|
||||
integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==
|
||||
|
||||
vscode-languageserver@~9.0.1:
|
||||
version "9.0.1"
|
||||
resolved "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz"
|
||||
integrity sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==
|
||||
dependencies:
|
||||
vscode-languageserver-protocol "3.17.5"
|
||||
|
||||
vscode-uri@~3.0.8:
|
||||
version "3.0.8"
|
||||
resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz"
|
||||
integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==
|
||||
|
||||
warning@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz"
|
||||
|
||||
411
superset-frontend/cypress-base/package-lock.json
generated
411
superset-frontend/cypress-base/package-lock.json
generated
@@ -96,14 +96,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
|
||||
"integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
|
||||
"version": "7.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
|
||||
"integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.23.0",
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
"@jridgewell/trace-mapping": "^0.3.17",
|
||||
"jsesc": "^2.5.1"
|
||||
"@babel/parser": "^7.29.0",
|
||||
"@babel/types": "^7.29.0",
|
||||
"@jridgewell/gen-mapping": "^0.3.12",
|
||||
"@jridgewell/trace-mapping": "^0.3.28",
|
||||
"jsesc": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -224,6 +225,7 @@
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
|
||||
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -244,6 +246,7 @@
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
|
||||
"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.22.15",
|
||||
"@babel/types": "^7.23.0"
|
||||
@@ -252,13 +255,10 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-hoist-variables": {
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
|
||||
"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.22.5"
|
||||
},
|
||||
"node_modules/@babel/helper-globals": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
|
||||
"integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -276,32 +276,31 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-module-imports": {
|
||||
"version": "7.21.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz",
|
||||
"integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
|
||||
"integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.21.4"
|
||||
"@babel/traverse": "^7.28.6",
|
||||
"@babel/types": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-module-transforms": {
|
||||
"version": "7.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz",
|
||||
"integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
|
||||
"integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
|
||||
"dependencies": {
|
||||
"@babel/helper-environment-visitor": "^7.18.9",
|
||||
"@babel/helper-module-imports": "^7.18.6",
|
||||
"@babel/helper-simple-access": "^7.20.2",
|
||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
||||
"@babel/helper-validator-identifier": "^7.19.1",
|
||||
"@babel/template": "^7.20.7",
|
||||
"@babel/traverse": "^7.21.2",
|
||||
"@babel/types": "^7.21.2"
|
||||
"@babel/helper-module-imports": "^7.28.6",
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"@babel/traverse": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-optimise-call-expression": {
|
||||
@@ -317,9 +316,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-plugin-utils": {
|
||||
"version": "7.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
|
||||
"integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
|
||||
"integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -364,6 +363,7 @@
|
||||
"version": "7.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
|
||||
"integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.20.2"
|
||||
},
|
||||
@@ -387,6 +387,7 @@
|
||||
"version": "7.22.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
|
||||
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.22.5"
|
||||
},
|
||||
@@ -395,19 +396,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
|
||||
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
|
||||
"license": "MIT",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
|
||||
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
|
||||
"license": "MIT",
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
|
||||
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -462,12 +461,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz",
|
||||
"integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==",
|
||||
"license": "MIT",
|
||||
"version": "7.29.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz",
|
||||
"integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.26.10"
|
||||
"@babel/types": "^7.29.0"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@@ -1223,15 +1221,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-modules-systemjs": {
|
||||
"version": "7.20.11",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz",
|
||||
"integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==",
|
||||
"version": "7.29.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz",
|
||||
"integrity": "sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-hoist-variables": "^7.18.6",
|
||||
"@babel/helper-module-transforms": "^7.20.11",
|
||||
"@babel/helper-plugin-utils": "^7.20.2",
|
||||
"@babel/helper-validator-identifier": "^7.19.1"
|
||||
"@babel/helper-module-transforms": "^7.28.6",
|
||||
"@babel/helper-plugin-utils": "^7.28.6",
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"@babel/traverse": "^7.29.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1595,73 +1593,68 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.26.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
|
||||
"integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
|
||||
"license": "MIT",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
|
||||
"integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.26.2",
|
||||
"@babel/parser": "^7.26.9",
|
||||
"@babel/types": "^7.26.9"
|
||||
"@babel/code-frame": "^7.28.6",
|
||||
"@babel/parser": "^7.28.6",
|
||||
"@babel/types": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template/node_modules/@babel/code-frame": {
|
||||
"version": "7.26.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
|
||||
"integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
|
||||
"license": "MIT",
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
|
||||
"integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.25.9",
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.0.0"
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
|
||||
"integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
|
||||
"integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.22.13",
|
||||
"@babel/generator": "^7.23.0",
|
||||
"@babel/helper-environment-visitor": "^7.22.20",
|
||||
"@babel/helper-function-name": "^7.23.0",
|
||||
"@babel/helper-hoist-variables": "^7.22.5",
|
||||
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||
"@babel/parser": "^7.23.0",
|
||||
"@babel/types": "^7.23.0",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0"
|
||||
"@babel/code-frame": "^7.29.0",
|
||||
"@babel/generator": "^7.29.0",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/parser": "^7.29.0",
|
||||
"@babel/template": "^7.28.6",
|
||||
"@babel/types": "^7.29.0",
|
||||
"debug": "^4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse/node_modules/@babel/code-frame": {
|
||||
"version": "7.22.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
|
||||
"integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
|
||||
"integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.22.13",
|
||||
"chalk": "^2.4.2"
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz",
|
||||
"integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==",
|
||||
"license": "MIT",
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
|
||||
"integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.25.9",
|
||||
"@babel/helper-validator-identifier": "^7.25.9"
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -2080,16 +2073,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
|
||||
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
|
||||
"version": "0.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
||||
"dependencies": {
|
||||
"@jridgewell/set-array": "^1.2.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
@@ -2100,14 +2089,6 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/set-array": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
|
||||
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/source-map": {
|
||||
"version": "0.3.11",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
|
||||
@@ -2119,14 +2100,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
|
||||
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.25",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
|
||||
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
|
||||
"version": "0.3.31",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
|
||||
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
@@ -4932,6 +4913,7 @@
|
||||
"version": "11.12.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
@@ -5641,14 +5623,14 @@
|
||||
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
|
||||
},
|
||||
"node_modules/jsesc": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
|
||||
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
|
||||
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
|
||||
"bin": {
|
||||
"jsesc": "bin/jsesc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/json-parse-even-better-errors": {
|
||||
@@ -8758,14 +8740,15 @@
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
|
||||
"integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
|
||||
"version": "7.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
|
||||
"integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.23.0",
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
"@jridgewell/trace-mapping": "^0.3.17",
|
||||
"jsesc": "^2.5.1"
|
||||
"@babel/parser": "^7.29.0",
|
||||
"@babel/types": "^7.29.0",
|
||||
"@jridgewell/gen-mapping": "^0.3.12",
|
||||
"@jridgewell/trace-mapping": "^0.3.28",
|
||||
"jsesc": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"@babel/helper-annotate-as-pure": {
|
||||
@@ -8857,7 +8840,8 @@
|
||||
"@babel/helper-environment-visitor": {
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
|
||||
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA=="
|
||||
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
|
||||
"peer": true
|
||||
},
|
||||
"@babel/helper-explode-assignable-expression": {
|
||||
"version": "7.18.6",
|
||||
@@ -8872,18 +8856,16 @@
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
|
||||
"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/template": "^7.22.15",
|
||||
"@babel/types": "^7.23.0"
|
||||
}
|
||||
},
|
||||
"@babel/helper-hoist-variables": {
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
|
||||
"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.22.5"
|
||||
}
|
||||
"@babel/helper-globals": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
|
||||
"integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="
|
||||
},
|
||||
"@babel/helper-member-expression-to-functions": {
|
||||
"version": "7.21.0",
|
||||
@@ -8895,26 +8877,22 @@
|
||||
}
|
||||
},
|
||||
"@babel/helper-module-imports": {
|
||||
"version": "7.21.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz",
|
||||
"integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
|
||||
"integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.21.4"
|
||||
"@babel/traverse": "^7.28.6",
|
||||
"@babel/types": "^7.28.6"
|
||||
}
|
||||
},
|
||||
"@babel/helper-module-transforms": {
|
||||
"version": "7.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz",
|
||||
"integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
|
||||
"integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
|
||||
"requires": {
|
||||
"@babel/helper-environment-visitor": "^7.18.9",
|
||||
"@babel/helper-module-imports": "^7.18.6",
|
||||
"@babel/helper-simple-access": "^7.20.2",
|
||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
||||
"@babel/helper-validator-identifier": "^7.19.1",
|
||||
"@babel/template": "^7.20.7",
|
||||
"@babel/traverse": "^7.21.2",
|
||||
"@babel/types": "^7.21.2"
|
||||
"@babel/helper-module-imports": "^7.28.6",
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"@babel/traverse": "^7.28.6"
|
||||
}
|
||||
},
|
||||
"@babel/helper-optimise-call-expression": {
|
||||
@@ -8927,9 +8905,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/helper-plugin-utils": {
|
||||
"version": "7.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
|
||||
"integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
|
||||
"integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
|
||||
"peer": true
|
||||
},
|
||||
"@babel/helper-remap-async-to-generator": {
|
||||
@@ -8962,6 +8940,7 @@
|
||||
"version": "7.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
|
||||
"integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.20.2"
|
||||
}
|
||||
@@ -8979,19 +8958,20 @@
|
||||
"version": "7.22.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
|
||||
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.22.5"
|
||||
}
|
||||
},
|
||||
"@babel/helper-string-parser": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
|
||||
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="
|
||||
},
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
|
||||
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
|
||||
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="
|
||||
},
|
||||
"@babel/helper-validator-option": {
|
||||
"version": "7.21.0",
|
||||
@@ -9030,11 +9010,11 @@
|
||||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz",
|
||||
"integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==",
|
||||
"version": "7.29.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz",
|
||||
"integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.26.10"
|
||||
"@babel/types": "^7.29.0"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
|
||||
@@ -9523,15 +9503,15 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-modules-systemjs": {
|
||||
"version": "7.20.11",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz",
|
||||
"integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==",
|
||||
"version": "7.29.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz",
|
||||
"integrity": "sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/helper-hoist-variables": "^7.18.6",
|
||||
"@babel/helper-module-transforms": "^7.20.11",
|
||||
"@babel/helper-plugin-utils": "^7.20.2",
|
||||
"@babel/helper-validator-identifier": "^7.19.1"
|
||||
"@babel/helper-module-transforms": "^7.28.6",
|
||||
"@babel/helper-plugin-utils": "^7.28.6",
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"@babel/traverse": "^7.29.0"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-modules-umd": {
|
||||
@@ -9786,62 +9766,60 @@
|
||||
}
|
||||
},
|
||||
"@babel/template": {
|
||||
"version": "7.26.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
|
||||
"integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
|
||||
"integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.26.2",
|
||||
"@babel/parser": "^7.26.9",
|
||||
"@babel/types": "^7.26.9"
|
||||
"@babel/code-frame": "^7.28.6",
|
||||
"@babel/parser": "^7.28.6",
|
||||
"@babel/types": "^7.28.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/code-frame": {
|
||||
"version": "7.26.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
|
||||
"integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
|
||||
"integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.25.9",
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.0.0"
|
||||
"picocolors": "^1.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
|
||||
"integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
|
||||
"integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.22.13",
|
||||
"@babel/generator": "^7.23.0",
|
||||
"@babel/helper-environment-visitor": "^7.22.20",
|
||||
"@babel/helper-function-name": "^7.23.0",
|
||||
"@babel/helper-hoist-variables": "^7.22.5",
|
||||
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||
"@babel/parser": "^7.23.0",
|
||||
"@babel/types": "^7.23.0",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0"
|
||||
"@babel/code-frame": "^7.29.0",
|
||||
"@babel/generator": "^7.29.0",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/parser": "^7.29.0",
|
||||
"@babel/template": "^7.28.6",
|
||||
"@babel/types": "^7.29.0",
|
||||
"debug": "^4.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/code-frame": {
|
||||
"version": "7.22.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
|
||||
"integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
|
||||
"integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
|
||||
"requires": {
|
||||
"@babel/highlight": "^7.22.13",
|
||||
"chalk": "^2.4.2"
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz",
|
||||
"integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==",
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
|
||||
"integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
|
||||
"requires": {
|
||||
"@babel/helper-string-parser": "^7.25.9",
|
||||
"@babel/helper-validator-identifier": "^7.25.9"
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5"
|
||||
}
|
||||
},
|
||||
"@colors/colors": {
|
||||
@@ -10180,12 +10158,11 @@
|
||||
"integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw=="
|
||||
},
|
||||
"@jridgewell/gen-mapping": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
|
||||
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
|
||||
"version": "0.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
||||
"requires": {
|
||||
"@jridgewell/set-array": "^1.2.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
}
|
||||
},
|
||||
@@ -10194,11 +10171,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w=="
|
||||
},
|
||||
"@jridgewell/set-array": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
|
||||
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="
|
||||
},
|
||||
"@jridgewell/source-map": {
|
||||
"version": "0.3.11",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
|
||||
@@ -10210,14 +10182,14 @@
|
||||
}
|
||||
},
|
||||
"@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
|
||||
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="
|
||||
},
|
||||
"@jridgewell/trace-mapping": {
|
||||
"version": "0.3.25",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
|
||||
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
|
||||
"version": "0.3.31",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
|
||||
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
|
||||
"requires": {
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
@@ -12441,7 +12413,8 @@
|
||||
"globals": {
|
||||
"version": "11.12.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
|
||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
||||
"peer": true
|
||||
},
|
||||
"globby": {
|
||||
"version": "11.0.4",
|
||||
@@ -12945,9 +12918,9 @@
|
||||
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
|
||||
},
|
||||
"jsesc": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
|
||||
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
|
||||
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="
|
||||
},
|
||||
"json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
|
||||
167
superset-frontend/package-lock.json
generated
167
superset-frontend/package-lock.json
generated
@@ -194,7 +194,7 @@
|
||||
"@storybook/test": "^8.6.18",
|
||||
"@storybook/test-runner": "^0.17.0",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@swc/core": "^1.15.32",
|
||||
"@swc/core": "^1.15.33",
|
||||
"@swc/plugin-emotion": "^14.9.0",
|
||||
"@swc/plugin-transform-imports": "^12.5.0",
|
||||
"@testing-library/dom": "^9.3.4",
|
||||
@@ -283,7 +283,7 @@
|
||||
"storybook": "8.6.18",
|
||||
"style-loader": "^4.0.0",
|
||||
"swc-loader": "^0.2.7",
|
||||
"terser-webpack-plugin": "^5.5.0",
|
||||
"terser-webpack-plugin": "^5.6.0",
|
||||
"ts-jest": "^29.4.9",
|
||||
"tscw-config": "^1.1.2",
|
||||
"tsx": "^4.21.0",
|
||||
@@ -12485,9 +12485,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.32.tgz",
|
||||
"integrity": "sha512-/eWL0n43D64QWEUHLtTE+jDqjkJhyidjkDhv6f0uJohOUAhywxQ9wXYp845DNNds0JpCdI4Uo0a9bl+vbXf+ew==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.33.tgz",
|
||||
"integrity": "sha512-jOlwnFV2xhuuZeAUILGFULeR6vDPfijEJ57evfocwznQldLU3w2cZ9bSDryY9ip+AsM3r1NJKzf47V2NXebkeQ==",
|
||||
"devOptional": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
@@ -12503,18 +12503,18 @@
|
||||
"url": "https://opencollective.com/swc"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@swc/core-darwin-arm64": "1.15.32",
|
||||
"@swc/core-darwin-x64": "1.15.32",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.15.32",
|
||||
"@swc/core-linux-arm64-gnu": "1.15.32",
|
||||
"@swc/core-linux-arm64-musl": "1.15.32",
|
||||
"@swc/core-linux-ppc64-gnu": "1.15.32",
|
||||
"@swc/core-linux-s390x-gnu": "1.15.32",
|
||||
"@swc/core-linux-x64-gnu": "1.15.32",
|
||||
"@swc/core-linux-x64-musl": "1.15.32",
|
||||
"@swc/core-win32-arm64-msvc": "1.15.32",
|
||||
"@swc/core-win32-ia32-msvc": "1.15.32",
|
||||
"@swc/core-win32-x64-msvc": "1.15.32"
|
||||
"@swc/core-darwin-arm64": "1.15.33",
|
||||
"@swc/core-darwin-x64": "1.15.33",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.15.33",
|
||||
"@swc/core-linux-arm64-gnu": "1.15.33",
|
||||
"@swc/core-linux-arm64-musl": "1.15.33",
|
||||
"@swc/core-linux-ppc64-gnu": "1.15.33",
|
||||
"@swc/core-linux-s390x-gnu": "1.15.33",
|
||||
"@swc/core-linux-x64-gnu": "1.15.33",
|
||||
"@swc/core-linux-x64-musl": "1.15.33",
|
||||
"@swc/core-win32-arm64-msvc": "1.15.33",
|
||||
"@swc/core-win32-ia32-msvc": "1.15.33",
|
||||
"@swc/core-win32-x64-msvc": "1.15.33"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/helpers": ">=0.5.17"
|
||||
@@ -12526,9 +12526,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-arm64": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.32.tgz",
|
||||
"integrity": "sha512-/YWMvJDPu+AAwuUsM2G+DNQ/7zhodURGzdQyewEqcvgklAdDHs3LwQmLLnyn6SJl8DT8UOxkbzK+D1PmPeelRg==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.33.tgz",
|
||||
"integrity": "sha512-N+L0uXhuO7FIfzqwgxmzv0zIpV0qEp8wPX3QQs2p4atjMoywup2JTeDlXPw+z9pWJGCae3JjM+tZ6myclI+2gA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -12542,9 +12542,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-x64": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.32.tgz",
|
||||
"integrity": "sha512-KOTXJXdAhWL+hZ77MYP3z+4pcMFaQhQ74yqyN1uz093q0YnbxpqMtYpPISbYvMHzVRNNx5kN+9RZAXEaadhWVA==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.33.tgz",
|
||||
"integrity": "sha512-/Il4QHSOhV4FekbsDtkrNmKbsX26oSysvgrRswa/RYOHXAkwXDbB4jaeKq6PsJLSPkzJ2KzQ061gtBnk0vNHfA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -12558,9 +12558,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm-gnueabihf": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.32.tgz",
|
||||
"integrity": "sha512-oOoxLweljlc0A4X8ybsgxV7cVaYTwBOg2iMDJcFR3Sr48C+lsv9VzSmqdK/IVIXF4W4GjLc3VqTAdSMXlfVLuQ==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.33.tgz",
|
||||
"integrity": "sha512-C64hBnBxq4viOPQ8hlx+2lJ23bzZBGnjw7ryALmS+0Q3zHmwO8lw1/DArLENw4Q18/0w5wdEO1k3m1wWNtKGqQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -12574,9 +12574,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-gnu": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.32.tgz",
|
||||
"integrity": "sha512-oDzEkdl6D6BAWdMtU5KGO7y3HR5fJcvByNLyEk9+ugj8nP5Ovb7P4kBcStBXc4MPExFGQryehiINMlmY8HlclA==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.33.tgz",
|
||||
"integrity": "sha512-TRJfnJbX3jqpxRDRoieMzRiCBS5jOmXNb3iQXmcgjFEHKLnAgK1RZRU8Cq1MsPqO4jAJp/ld1G4O3fXuxv85uw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -12590,9 +12590,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-musl": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.32.tgz",
|
||||
"integrity": "sha512-omcqjoZP/b8D8PuczVoRwJieC6ibj7qIxTftNYokz4/aSmKFHvsd7nIFfPk5ZvtzncbH4AY7+Dkr/Lp2gWxYeA==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.33.tgz",
|
||||
"integrity": "sha512-il7tYM+CpUNzieQbwAjFT1P8zqAhmGWNAGhQZBnxurXZ0aNn+5nqYFTEUKNZl7QibtT0uQXzTZrNGHCIj6Y1Og==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -12606,9 +12606,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-ppc64-gnu": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.32.tgz",
|
||||
"integrity": "sha512-KGkTMyz/Tbn3PBNu0AVZ4GTDFKnICrYcTiNPZq8DrvK42pnFsf3GNDrIG9E5AtQlTmC0YigkWKmu0eMcfTrmgA==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.33.tgz",
|
||||
"integrity": "sha512-ZtNBwN0Z7CFj9Il0FcPaKdjgP7URyKu/3RfH46vq+0paOBqLj4NYldD6Qo//Duif/7IOtAraUfDOmp0PLAufog==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -12622,9 +12622,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-s390x-gnu": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.32.tgz",
|
||||
"integrity": "sha512-G3Aa4tVS/3OGZBkoNIwUF9F6RAy+Osb4GOlo62SinLmDiErz/ykmM7KH0wkz6l9kM8jJq1HyAM6atJTUEbBk7g==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.33.tgz",
|
||||
"integrity": "sha512-De1IyajoOmhOYYjw/lx66bKlyDpHZTueqwpDrWgf5O7T6d1ODeJJO9/OqMBmrBQc5C+dNnlmIufHsp4QVCWufA==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -12638,9 +12638,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-gnu": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.32.tgz",
|
||||
"integrity": "sha512-ERsjfGcj6CBmj3vJnGDO8m8rTvw6RqMcWo1dogOtNx3/+/0+NNpJiXDobJrr1GwInI/BHAEkvSFIH6d2LqPcUQ==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.33.tgz",
|
||||
"integrity": "sha512-mGTH0YxmUN+x6vRN/I6NOk5X0ogNktkwPnJ94IMvR7QjhRDwL0O8RXEDhyUM0YtwWrryBOqaJQBX4zruxEPRGw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -12654,9 +12654,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-musl": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.32.tgz",
|
||||
"integrity": "sha512-N4Ggahe/8SUbTX50P6EdhbW9YWcgbZVb52R4cq6MK+zsoMjRq7rGvV5ztA05QnbaCYqMYx8rTY7KAIA3Crdo4Q==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.33.tgz",
|
||||
"integrity": "sha512-hj628ZkSEJf6zMf5VMbYrG2O6QqyTIp2qwY6VlCjvIa9lAEZ5c2lfPblCLVGYubTeLJDxadLB/CxqQYOQABeEQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -12670,9 +12670,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-arm64-msvc": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.32.tgz",
|
||||
"integrity": "sha512-01yN0o9jvo8xBTP12aPK2wW8b41jmOlGbDDlAnoynotc4pO6xA0zby9f1z6j++qXDpGBttLySq1omgVrlQKYcw==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.33.tgz",
|
||||
"integrity": "sha512-GV2oohtN2/5+KSccl86VULu3aT+LrISC8uzgSq0FRnikpD+Zwc+sBlXmoKQ+Db6jI57ITUOIB8jRkdGMABC29g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -12686,9 +12686,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-ia32-msvc": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.32.tgz",
|
||||
"integrity": "sha512-fLagI9XZYNpTcmlqAcp3KBtmj7E19WCmYD80Jxj1Kn5tGNa7yxNLd3NNdWxuZGUPl5iC0/KqZru7g08gF6Fsrw==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.33.tgz",
|
||||
"integrity": "sha512-gtyvzSNR8DHKfFEA2uqb8Ld1myqi6uEg2jyeUq3ikn5ytYs7H8RpZYC8mdy4NXr8hfcdJfCLXPlYaqqfBXpoEQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -12702,9 +12702,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-x64-msvc": {
|
||||
"version": "1.15.32",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.32.tgz",
|
||||
"integrity": "sha512-gbc2bQ/T2CiR+w0OvcVKwLOFAcPZBvmWmolbwpg1E8UrpeC03DGtyMUApOHNXNYWA3SHFrYXCQtosrcMza1YFg==",
|
||||
"version": "1.15.33",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.33.tgz",
|
||||
"integrity": "sha512-d6fRqQSkJI+kmMEBWaDQ7TMl8+YjLYbwRUPZQ9DY0ORBJeTzOrG0twvfvlZ2xgw6jA0ScQKgfBm4vHLSLl5Hqg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -13876,12 +13876,12 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "25.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz",
|
||||
"integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
|
||||
"version": "25.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.7.0.tgz",
|
||||
"integrity": "sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.19.0"
|
||||
"undici-types": "~7.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/normalize-package-data": {
|
||||
@@ -24644,9 +24644,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "11.3.4",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz",
|
||||
"integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==",
|
||||
"version": "11.3.5",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz",
|
||||
"integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
@@ -45413,9 +45413,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/terser-webpack-plugin": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.5.0.tgz",
|
||||
"integrity": "sha512-UYhptBwhWvfIjKd/UuFo6D8uq9xpGLDK+z8EDsj/zWhrTaH34cKEbrkMKfV5YWqGBvAYA3tlzZbs2R+qYrbQJA==",
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.0.tgz",
|
||||
"integrity": "sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -45435,12 +45435,39 @@
|
||||
"webpack": "^5.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@minify-html/node": {
|
||||
"optional": true
|
||||
},
|
||||
"@swc/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@swc/css": {
|
||||
"optional": true
|
||||
},
|
||||
"@swc/html": {
|
||||
"optional": true
|
||||
},
|
||||
"clean-css": {
|
||||
"optional": true
|
||||
},
|
||||
"cssnano": {
|
||||
"optional": true
|
||||
},
|
||||
"csso": {
|
||||
"optional": true
|
||||
},
|
||||
"esbuild": {
|
||||
"optional": true
|
||||
},
|
||||
"html-minifier-terser": {
|
||||
"optional": true
|
||||
},
|
||||
"lightningcss": {
|
||||
"optional": true
|
||||
},
|
||||
"postcss": {
|
||||
"optional": true
|
||||
},
|
||||
"uglify-js": {
|
||||
"optional": true
|
||||
}
|
||||
@@ -47052,9 +47079,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.19.2",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz",
|
||||
"integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==",
|
||||
"version": "7.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.21.0.tgz",
|
||||
"integrity": "sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unicode-canonical-property-names-ecmascript": {
|
||||
@@ -49711,9 +49738,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^10.1.0",
|
||||
"fs-extra": "^11.3.4",
|
||||
"fs-extra": "^11.3.5",
|
||||
"jest": "^30.3.0",
|
||||
"yeoman-test": "^11.4.2"
|
||||
"yeoman-test": "^11.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18.0.0",
|
||||
@@ -50199,7 +50226,7 @@
|
||||
"@types/d3-time-format": "^4.0.3",
|
||||
"@types/jquery": "^4.0.0",
|
||||
"@types/lodash": "^4.17.24",
|
||||
"@types/node": "^25.6.0",
|
||||
"@types/node": "^25.7.0",
|
||||
"@types/prop-types": "^15.7.15",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/react-table": "^7.7.20",
|
||||
@@ -50755,7 +50782,7 @@
|
||||
"acorn": "^8.16.0",
|
||||
"d3-array": "^3.2.4",
|
||||
"lodash": "^4.18.1",
|
||||
"zod": "^4.4.3"
|
||||
"zod": "^4.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@apache-superset/core": "*",
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
"@storybook/test": "^8.6.18",
|
||||
"@storybook/test-runner": "^0.17.0",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@swc/core": "^1.15.32",
|
||||
"@swc/core": "^1.15.33",
|
||||
"@swc/plugin-emotion": "^14.9.0",
|
||||
"@swc/plugin-transform-imports": "^12.5.0",
|
||||
"@testing-library/dom": "^9.3.4",
|
||||
@@ -364,7 +364,7 @@
|
||||
"storybook": "8.6.18",
|
||||
"style-loader": "^4.0.0",
|
||||
"swc-loader": "^0.2.7",
|
||||
"terser-webpack-plugin": "^5.5.0",
|
||||
"terser-webpack-plugin": "^5.6.0",
|
||||
"ts-jest": "^29.4.9",
|
||||
"tscw-config": "^1.1.2",
|
||||
"tsx": "^4.21.0",
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^10.1.0",
|
||||
"fs-extra": "^11.3.4",
|
||||
"fs-extra": "^11.3.5",
|
||||
"jest": "^30.3.0",
|
||||
"yeoman-test": "^11.4.2"
|
||||
"yeoman-test": "^11.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">= 4.0.0",
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
"@types/d3-time-format": "^4.0.3",
|
||||
"@types/jquery": "^4.0.0",
|
||||
"@types/lodash": "^4.17.24",
|
||||
"@types/node": "^25.6.0",
|
||||
"@types/node": "^25.7.0",
|
||||
"@types/prop-types": "^15.7.15",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/react-table": "^7.7.20",
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"acorn": "^8.16.0",
|
||||
"d3-array": "^3.2.4",
|
||||
"lodash": "^4.18.1",
|
||||
"zod": "^4.4.3"
|
||||
"zod": "^4.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@apache-superset/core": "*",
|
||||
|
||||
@@ -139,6 +139,7 @@ describe('DashboardBuilder', () => {
|
||||
...overrideState,
|
||||
}),
|
||||
useDnd: true,
|
||||
useRouter: true,
|
||||
useTheme: true,
|
||||
});
|
||||
}
|
||||
@@ -473,6 +474,7 @@ test('should render ParentSize wrapper with height 100% for tabs', async () => {
|
||||
dashboardLayout: undoableDashboardLayoutWithTabs,
|
||||
}),
|
||||
useDnd: true,
|
||||
useRouter: true,
|
||||
useTheme: true,
|
||||
});
|
||||
|
||||
@@ -506,6 +508,7 @@ test('should maintain layout when switching between tabs', async () => {
|
||||
dashboardLayout: undoableDashboardLayoutWithTabs,
|
||||
}),
|
||||
useDnd: true,
|
||||
useRouter: true,
|
||||
useTheme: true,
|
||||
});
|
||||
|
||||
|
||||
@@ -31,6 +31,20 @@ import { DASHBOARD_HEADER_ID } from '../../util/constants';
|
||||
import { UPDATE_COMPONENTS } from '../../actions/dashboardLayout';
|
||||
import { AutoRefreshStatus } from '../../types/autoRefresh';
|
||||
|
||||
const mockHistoryReplace = jest.fn();
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useHistory: () => ({
|
||||
replace: mockHistoryReplace,
|
||||
}),
|
||||
useLocation: jest.fn(() => ({
|
||||
pathname: '/dashboard',
|
||||
search: '?standalone=1',
|
||||
hash: '',
|
||||
state: undefined,
|
||||
})),
|
||||
}));
|
||||
|
||||
const initialState = {
|
||||
dashboardInfo: {
|
||||
id: 1,
|
||||
@@ -223,6 +237,13 @@ beforeAll(() => {
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
const { useLocation } = jest.requireMock('react-router-dom');
|
||||
useLocation.mockReturnValue({
|
||||
pathname: '/dashboard',
|
||||
search: '?standalone=1',
|
||||
hash: '',
|
||||
state: undefined,
|
||||
});
|
||||
|
||||
(useUnsavedChangesPrompt as jest.Mock).mockReturnValue({
|
||||
showModal: false,
|
||||
@@ -984,3 +1005,73 @@ test('should sync theme ref when navigating between dashboards', async () => {
|
||||
expect(setUnsavedChanges).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('should not duplicate subdirectory prefix when toggling fullscreen', async () => {
|
||||
const { useLocation } = jest.requireMock('react-router-dom');
|
||||
// Simulate React Router with basename=/pcs: useLocation returns path relative to basename
|
||||
useLocation.mockReturnValue({
|
||||
pathname: '/dashboard',
|
||||
search: '?standalone=1',
|
||||
hash: '',
|
||||
state: undefined,
|
||||
});
|
||||
// Simulate browser URL including the subdirectory prefix
|
||||
window.history.pushState({}, 'Test page', '/pcs/dashboard?standalone=1');
|
||||
|
||||
setup();
|
||||
await openActionsDropdown();
|
||||
userEvent.click(screen.getByText('Exit fullscreen'));
|
||||
|
||||
// history.replace must be called with the Router-relative path, not window.location.pathname.
|
||||
// If the subdirectory prefix (/pcs) were included, React Router would prepend it again,
|
||||
// producing /pcs/pcs/dashboard (the bug). The path must start with /dashboard, not /pcs/.
|
||||
expect(mockHistoryReplace).toHaveBeenCalledWith(
|
||||
expect.not.stringMatching(/^\/pcs\//),
|
||||
);
|
||||
expect(mockHistoryReplace).toHaveBeenCalledWith(
|
||||
expect.stringMatching(/^\/dashboard(\?|$)/),
|
||||
);
|
||||
});
|
||||
|
||||
test('should not duplicate subdirectory prefix when entering fullscreen', async () => {
|
||||
const { useLocation } = jest.requireMock('react-router-dom');
|
||||
useLocation.mockReturnValue({
|
||||
pathname: '/dashboard',
|
||||
search: '',
|
||||
hash: '',
|
||||
state: undefined,
|
||||
});
|
||||
window.history.pushState({}, 'Test page', '/pcs/dashboard');
|
||||
|
||||
setup();
|
||||
await openActionsDropdown();
|
||||
userEvent.click(screen.getByText('Enter fullscreen'));
|
||||
|
||||
expect(mockHistoryReplace).toHaveBeenCalledWith(
|
||||
expect.not.stringMatching(/^\/pcs\//),
|
||||
);
|
||||
expect(mockHistoryReplace).toHaveBeenCalledWith(
|
||||
expect.stringMatching(/^\/dashboard\?standalone=1$/),
|
||||
);
|
||||
});
|
||||
|
||||
test('share URL should use browser-absolute pathname to preserve subdirectory prefix', () => {
|
||||
const { useLocation } = jest.requireMock('react-router-dom');
|
||||
// Router returns path without the subdirectory prefix
|
||||
useLocation.mockReturnValue({
|
||||
pathname: '/dashboard',
|
||||
search: '',
|
||||
hash: '',
|
||||
state: undefined,
|
||||
});
|
||||
// Browser URL includes the full prefix
|
||||
window.history.pushState({}, 'Test page', '/pcs/dashboard');
|
||||
|
||||
const { container } = setup();
|
||||
// The share/embed URL must use window.location.pathname so that shared links
|
||||
// include the subdirectory prefix and work outside the React Router context.
|
||||
const emailLink = container.querySelector('[data-test="share-by-email"]');
|
||||
if (emailLink) {
|
||||
expect(emailLink.getAttribute('href')).toMatch(/\/pcs\/dashboard/);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import type { Dispatch, ReactElement, SetStateAction } from 'react';
|
||||
import { useState, useEffect, useCallback, useMemo } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { Menu, MenuItem } from '@superset-ui/core/components/Menu';
|
||||
import { t } from '@apache-superset/core/translation';
|
||||
import { isEmpty } from 'lodash';
|
||||
@@ -75,6 +75,7 @@ export const useHeaderActionsMenu = ({
|
||||
const [isDropdownVisible, setIsDropdownVisible] = useState(false);
|
||||
const { canExportImage } = usePermissions();
|
||||
const history = useHistory();
|
||||
const location = useLocation();
|
||||
const directPathToChild = useSelector(
|
||||
(state: RootState) => state.dashboardState.directPathToChild,
|
||||
);
|
||||
@@ -101,8 +102,11 @@ export const useHeaderActionsMenu = ({
|
||||
case MenuKeys.ToggleFullscreen: {
|
||||
const isCurrentlyStandalone =
|
||||
Number(getUrlParam(URL_PARAMS.standalone)) === 1;
|
||||
// Use location.pathname from React Router (relative to basename) rather than
|
||||
// window.location.pathname to avoid duplicating the subdirectory prefix when
|
||||
// history.replace prepends it again.
|
||||
const url = getDashboardUrl({
|
||||
pathname: window.location.pathname,
|
||||
pathname: location.pathname,
|
||||
filters: getActiveFilters(),
|
||||
hash: window.location.hash,
|
||||
standalone: isCurrentlyStandalone ? null : 1,
|
||||
@@ -125,6 +129,7 @@ export const useHeaderActionsMenu = ({
|
||||
showRefreshModal,
|
||||
manageEmbedded,
|
||||
history,
|
||||
location,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -133,6 +138,10 @@ export const useHeaderActionsMenu = ({
|
||||
[dashboardTitle],
|
||||
);
|
||||
|
||||
// window.location.pathname is intentional here: this URL is used for sharing
|
||||
// (email, embed, copy link) and must be a full browser-absolute path that
|
||||
// includes the application root. Do NOT replace with useLocation().pathname —
|
||||
// that would strip the subdirectory prefix and produce a broken share link.
|
||||
const url = useMemo(
|
||||
() =>
|
||||
getDashboardUrl({
|
||||
|
||||
@@ -115,6 +115,16 @@ describe('getChartIdsFromLayout', () => {
|
||||
windowSpy.mockRestore();
|
||||
});
|
||||
|
||||
test('should pass through a router-relative pathname unchanged', () => {
|
||||
const url = getDashboardUrl({
|
||||
pathname: '/dashboard/1/',
|
||||
filters: {},
|
||||
hash: '',
|
||||
standalone: DashboardStandaloneMode.HideNav,
|
||||
});
|
||||
expect(url).toBe(`/dashboard/1/?standalone=${DashboardStandaloneMode.HideNav}`);
|
||||
});
|
||||
|
||||
test('should process native filters key', () => {
|
||||
const windowSpy = jest.spyOn(window, 'window', 'get');
|
||||
windowSpy.mockImplementation(
|
||||
|
||||
@@ -229,3 +229,19 @@ test('ensureAppRoot should prefix unknown schemes instead of passing through', a
|
||||
// Unknown / custom schemes are treated as relative paths
|
||||
expect(ensureAppRoot('foo:bar')).toBe('/superset/foo:bar');
|
||||
});
|
||||
|
||||
test('ensureAppRoot should be idempotent — not double-prefix an already-prefixed path', async () => {
|
||||
const { ensureAppRoot } = await loadPathUtils('/superset/');
|
||||
|
||||
const once = ensureAppRoot('/sqllab');
|
||||
const twice = ensureAppRoot(once);
|
||||
expect(twice).toBe(once); // /superset/sqllab, NOT /superset/superset/sqllab
|
||||
});
|
||||
|
||||
test('makeUrl should be idempotent with subdirectory prefix', async () => {
|
||||
const { makeUrl } = await loadPathUtils('/superset/');
|
||||
|
||||
const once = makeUrl('/sqllab?new=true');
|
||||
const twice = makeUrl(once);
|
||||
expect(twice).toBe(once); // /superset/sqllab?new=true, NOT /superset/superset/sqllab?new=true
|
||||
});
|
||||
|
||||
@@ -41,7 +41,15 @@ export function ensureAppRoot(path: string): string {
|
||||
if (SAFE_ABSOLUTE_URL_RE.test(path) || path.startsWith('//')) {
|
||||
return path;
|
||||
}
|
||||
return `${applicationRoot()}${path.startsWith('/') ? path : `/${path}`}`;
|
||||
const root = applicationRoot();
|
||||
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
||||
if (
|
||||
root &&
|
||||
(normalizedPath === root || normalizedPath.startsWith(`${root}/`))
|
||||
) {
|
||||
return normalizedPath;
|
||||
}
|
||||
return `${root}${normalizedPath}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -115,15 +115,19 @@ def re_encrypt_secrets(previous_secret_key: Optional[str] = None) -> None:
|
||||
"PREVIOUS_SECRET_KEY"
|
||||
)
|
||||
if previous_secret_key is None:
|
||||
click.secho("A previous secret key must be provided", err=True)
|
||||
sys.exit(1)
|
||||
click.secho(
|
||||
"No previous secret key provided; nothing to re-encrypt.",
|
||||
fg="yellow",
|
||||
)
|
||||
return
|
||||
secrets_migrator = SecretsMigrator(previous_secret_key=previous_secret_key)
|
||||
try:
|
||||
secrets_migrator.run()
|
||||
except ValueError as exc:
|
||||
click.secho(
|
||||
f"An error occurred, "
|
||||
f"probably an invalid previous secret key was provided. Error:[{exc}]",
|
||||
err=True,
|
||||
)
|
||||
stats = secrets_migrator.run()
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
click.secho(f"Re-encryption failed: {exc}", err=True)
|
||||
sys.exit(1)
|
||||
click.secho(
|
||||
f"Re-encryption complete: {stats.re_encrypted} re-encrypted, "
|
||||
f"{stats.skipped} skipped, {stats.null} null, {stats.failed} failed.",
|
||||
fg="green",
|
||||
)
|
||||
|
||||
@@ -643,7 +643,7 @@ DEFAULT_FEATURE_FLAGS: dict[str, bool] = {
|
||||
# Experimental with potential security/performance risks.
|
||||
# See SUPERSET_META_DB_LIMIT.
|
||||
# @lifecycle: testing
|
||||
# @docs: https://superset.apache.org/docs/configuration/databases/#querying-across-databases
|
||||
# @docs: https://superset.apache.org/user-docs/databases/supported/superset-meta-database
|
||||
"ENABLE_SUPERSET_META_DB": False,
|
||||
# Enable query cost estimation. Supported in Presto, Postgres, and BigQuery.
|
||||
# Requires `cost_estimate_enabled: true` in database `extra` attribute.
|
||||
|
||||
@@ -169,7 +169,7 @@ class ExtensionsRestApi(BaseApi):
|
||||
|
||||
@protect()
|
||||
@safe
|
||||
@expose("/<publisher>/<name>/<file>", methods=("GET",))
|
||||
@expose("/<publisher>/<name>/<path:file>", methods=("GET",))
|
||||
def content(self, publisher: str, name: str, file: str) -> Response:
|
||||
"""Get a frontend chunk of an extension.
|
||||
---
|
||||
|
||||
@@ -29,37 +29,113 @@ from flask import Flask
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Sentinel file Flask watches via --extra-files. Touching it on a real change
|
||||
# triggers a server reload without depending on cwd or the location of any
|
||||
# Python source file.
|
||||
RELOAD_TRIGGER = Path(__file__).resolve().parent / ".reload_trigger"
|
||||
|
||||
# Guard to prevent multiple initializations
|
||||
_watcher_initialized = False
|
||||
_watcher_lock = threading.Lock()
|
||||
|
||||
|
||||
def _get_file_handler_class() -> Any:
|
||||
def _get_file_handler_class() -> Any: # noqa: C901
|
||||
"""Get the file handler class, importing watchdog only when needed."""
|
||||
try:
|
||||
from watchdog.events import FileSystemEventHandler
|
||||
import hashlib
|
||||
|
||||
from watchdog.events import (
|
||||
FileCreatedEvent,
|
||||
FileModifiedEvent,
|
||||
FileMovedEvent,
|
||||
FileSystemEventHandler,
|
||||
)
|
||||
|
||||
class LocalExtensionFileHandler(FileSystemEventHandler):
|
||||
"""Custom file system event handler for LOCAL_EXTENSIONS directories."""
|
||||
"""Custom file system event handler for LOCAL_EXTENSIONS directories.
|
||||
|
||||
Only reacts to genuine content changes (create / modify / move) in the
|
||||
dist directory, verified by comparing a SHA-256 of the file's content.
|
||||
This avoids the Docker VirtioFS / osxfs problem where reading a file
|
||||
generates inotify events that watchdog surfaces as modifications.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
# sha256 of last-seen content, keyed by absolute path
|
||||
self._file_hashes: dict[str, str] = {}
|
||||
# Deduplicate: only trigger once per second across all files
|
||||
self._last_trigger: float = 0.0
|
||||
self._lock = threading.Lock()
|
||||
|
||||
# ── helpers ──────────────────────────────────────────────────────
|
||||
|
||||
@staticmethod
|
||||
def _sha256(path: str) -> str | None:
|
||||
try:
|
||||
with open(path, "rb") as fh:
|
||||
return hashlib.sha256(fh.read()).hexdigest()
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
def _content_changed(self, path: str) -> bool:
|
||||
"""Return True only when the file's content differs from last seen.
|
||||
|
||||
The first time a path is observed its hash is stored as the baseline
|
||||
and False is returned — that event is a 'first-seen', not a change.
|
||||
Only a subsequent event where the digest differs from the baseline
|
||||
is treated as a genuine content change.
|
||||
"""
|
||||
digest = self._sha256(path)
|
||||
if digest is None:
|
||||
return False
|
||||
old_digest = self._file_hashes.get(path)
|
||||
self._file_hashes[path] = digest
|
||||
if old_digest is None:
|
||||
# First observation — record baseline, do not trigger restart.
|
||||
return False
|
||||
return old_digest != digest
|
||||
|
||||
# ── event handler ─────────────────────────────────────────────────
|
||||
|
||||
def on_any_event(self, event: Any) -> None:
|
||||
"""Handle any file system event in the watched directories."""
|
||||
"""Handle file system events in the watched directories."""
|
||||
if event.is_directory:
|
||||
return
|
||||
|
||||
# Only trigger on changes to files in `dist` directory
|
||||
# Only react to true write events; skip access / close / open etc.
|
||||
if not isinstance(
|
||||
event, (FileCreatedEvent, FileModifiedEvent, FileMovedEvent)
|
||||
):
|
||||
return
|
||||
|
||||
# Only care about files inside a `dist` directory
|
||||
src = getattr(event, "src_path", None)
|
||||
if not isinstance(src, str) or "dist" not in Path(src).parts:
|
||||
return
|
||||
|
||||
# Verify the file content actually changed to ignore spurious
|
||||
# inotify events generated by Docker bind-mount reads.
|
||||
if not self._content_changed(src):
|
||||
return
|
||||
|
||||
# Debounce: one restart per second max, regardless of how many
|
||||
# files webpack writes simultaneously.
|
||||
now = time.monotonic()
|
||||
with self._lock:
|
||||
if now - self._last_trigger < 1.0:
|
||||
return
|
||||
self._last_trigger = now
|
||||
|
||||
logger.info(
|
||||
"File change detected in LOCAL_EXTENSIONS: %s", event.src_path
|
||||
)
|
||||
|
||||
# Touch superset/__init__.py to trigger Flask's file watcher
|
||||
superset_init = Path("superset/__init__.py")
|
||||
logger.info("Triggering restart by touching %s", superset_init)
|
||||
os.utime(superset_init, (time.time(), time.time()))
|
||||
# Touch the dedicated reload-trigger sentinel file.
|
||||
# Flask watches this via --extra-files; it is never read by Python
|
||||
# so Docker VirtioFS will not generate spurious inotify events on it.
|
||||
logger.info("Triggering restart by touching %s", RELOAD_TRIGGER)
|
||||
os.utime(RELOAD_TRIGGER, (time.time(), time.time()))
|
||||
|
||||
return LocalExtensionFileHandler
|
||||
except ImportError:
|
||||
@@ -130,6 +206,14 @@ def setup_local_extensions_watcher(app: Flask) -> None: # noqa: C901
|
||||
if not watch_dirs:
|
||||
return
|
||||
|
||||
# Ensure the sentinel exists so os.utime() and Flask's --extra-files watcher
|
||||
# both have a real path to operate on.
|
||||
try:
|
||||
RELOAD_TRIGGER.touch(exist_ok=True)
|
||||
except OSError as e:
|
||||
logger.warning("Could not create reload trigger %s: %s", RELOAD_TRIGGER, e)
|
||||
return
|
||||
|
||||
try:
|
||||
from watchdog.observers import Observer
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ from superset.utils.core import check_is_safe_zip
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
FRONTEND_REGEX = re.compile(r"^frontend/dist/([^/]+)$")
|
||||
FRONTEND_REGEX = re.compile(r"^frontend/dist/(.+)$")
|
||||
BACKEND_REGEX = re.compile(r"^backend/src/(.+)$")
|
||||
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ from superset.mcp_service.chart.schemas import (
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
SUPPORTED_FORM_DATA_PREVIEW_FORMATS = frozenset({"ascii", "table", "vega_lite"})
|
||||
|
||||
|
||||
def _build_query_columns(form_data: Dict[str, Any]) -> list[str]:
|
||||
"""Build query columns list from form_data, including both x_axis and groupby."""
|
||||
|
||||
@@ -43,6 +43,7 @@ from superset.mcp_service.chart.compile import (
|
||||
CompileResult,
|
||||
validate_and_compile,
|
||||
)
|
||||
from superset.mcp_service.chart.preview_utils import SUPPORTED_FORM_DATA_PREVIEW_FORMATS
|
||||
from superset.mcp_service.chart.schemas import (
|
||||
AccessibilityMetadata,
|
||||
CHART_FORM_DATA_EXCLUDED_FIELD_NAMES,
|
||||
@@ -630,11 +631,7 @@ async def generate_chart( # noqa: C901
|
||||
# For preview-only mode (save_chart=false)
|
||||
# Note: Screenshot-based URL previews are not
|
||||
# supported. Use explore_url to view interactively.
|
||||
if format_type in [
|
||||
"ascii",
|
||||
"table",
|
||||
"vega_lite",
|
||||
]:
|
||||
if format_type in SUPPORTED_FORM_DATA_PREVIEW_FORMATS:
|
||||
# Generate preview from form data
|
||||
from superset.mcp_service.chart.preview_utils import (
|
||||
generate_preview_from_form_data,
|
||||
|
||||
@@ -40,8 +40,13 @@ from superset.mcp_service.chart.chart_utils import (
|
||||
map_config_to_form_data,
|
||||
)
|
||||
from superset.mcp_service.chart.compile import validate_and_compile
|
||||
from superset.mcp_service.chart.preview_utils import (
|
||||
generate_preview_from_form_data,
|
||||
SUPPORTED_FORM_DATA_PREVIEW_FORMATS,
|
||||
)
|
||||
from superset.mcp_service.chart.schemas import (
|
||||
AccessibilityMetadata,
|
||||
ChartError,
|
||||
PerformanceMetadata,
|
||||
UpdateChartPreviewRequest,
|
||||
)
|
||||
@@ -229,9 +234,39 @@ def update_chart_preview( # noqa: C901
|
||||
high_contrast_available=False,
|
||||
)
|
||||
|
||||
# Note: Screenshot-based previews are not supported.
|
||||
# Use the explore_url to view the chart interactively.
|
||||
previews: Dict[str, Any] = {}
|
||||
if request.generate_preview:
|
||||
try:
|
||||
with event_logger.log_context(
|
||||
action="mcp.update_chart_preview.preview"
|
||||
):
|
||||
for format_type in request.preview_formats:
|
||||
# URL previews are represented by explore_url/chart.url.
|
||||
# Screenshot-based previews are not supported.
|
||||
if format_type not in SUPPORTED_FORM_DATA_PREVIEW_FORMATS:
|
||||
continue
|
||||
|
||||
preview_result = generate_preview_from_form_data(
|
||||
form_data=new_form_data,
|
||||
dataset_id=dataset.id,
|
||||
preview_format=format_type,
|
||||
)
|
||||
|
||||
if isinstance(preview_result, ChartError):
|
||||
logger.warning(
|
||||
"Preview '%s' failed: %s",
|
||||
format_type,
|
||||
preview_result.error,
|
||||
)
|
||||
else:
|
||||
previews[format_type] = (
|
||||
preview_result.model_dump(mode="json")
|
||||
if hasattr(preview_result, "model_dump")
|
||||
else preview_result
|
||||
)
|
||||
|
||||
except (CommandException, ValueError, KeyError) as e:
|
||||
logger.warning("Preview generation failed: %s", e)
|
||||
|
||||
# Return enhanced data
|
||||
result = {
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
# under the License.
|
||||
import logging
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Optional
|
||||
|
||||
from flask import Flask
|
||||
from flask_babel import lazy_gettext as _
|
||||
from sqlalchemy import text, TypeDecorator
|
||||
from sqlalchemy import Table, text, TypeDecorator
|
||||
from sqlalchemy.engine import Connection, Dialect, Row
|
||||
from sqlalchemy_utils import EncryptedType as SqlaEncryptedType
|
||||
|
||||
@@ -33,6 +34,16 @@ ENC_ADAPTER_TAG_ATTR_NAME = "__created_by_enc_field_adapter__"
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReEncryptStats:
|
||||
"""Per-value outcome counts for a SecretsMigrator.run() invocation."""
|
||||
|
||||
re_encrypted: int = 0
|
||||
skipped: int = 0
|
||||
null: int = 0
|
||||
failed: int = 0
|
||||
|
||||
|
||||
class AbstractEncryptedFieldAdapter(ABC): # pylint: disable=too-few-public-methods
|
||||
@abstractmethod
|
||||
def create(
|
||||
@@ -97,11 +108,13 @@ class SecretsMigrator:
|
||||
self._previous_secret_key = previous_secret_key
|
||||
self._dialect: Dialect = db.engine.url.get_dialect()
|
||||
|
||||
def discover_encrypted_fields(self) -> dict[str, dict[str, EncryptedType]]:
|
||||
def discover_encrypted_fields(
|
||||
self,
|
||||
) -> dict[str, tuple[Table, dict[str, EncryptedType]]]:
|
||||
"""
|
||||
Iterates over ORM-mapped tables, looking for EncryptedType columns
|
||||
along the way. Builds up a dict of
|
||||
table_name -> dict of col_name: enc type instance
|
||||
table_name -> (Table, dict of col_name: enc type instance)
|
||||
|
||||
Superset's ORM models inherit from Flask-AppBuilder's declarative base
|
||||
(`flask_appbuilder.Model`), whose MetaData is distinct from
|
||||
@@ -109,13 +122,18 @@ class SecretsMigrator:
|
||||
regardless of which base a model uses. FAB's metadata takes precedence
|
||||
when a table name appears in both registries.
|
||||
|
||||
:return: mapping of table name to a dict of {column name: EncryptedType}
|
||||
The Table object is returned alongside the encrypted columns so callers
|
||||
can introspect the schema (notably the primary key) without assuming a
|
||||
conventional `id` column — some tables (e.g. `semantic_layers`) use a
|
||||
`uuid` primary key instead.
|
||||
|
||||
:return: mapping of table name to (Table, {column name: EncryptedType})
|
||||
"""
|
||||
from flask_appbuilder import ( # pylint: disable=import-outside-toplevel
|
||||
Model as FABModel,
|
||||
)
|
||||
|
||||
meta_info: dict[str, Any] = {}
|
||||
meta_info: dict[str, tuple[Table, dict[str, EncryptedType]]] = {}
|
||||
|
||||
tables: dict[str, Any] = dict(FABModel.metadata.tables)
|
||||
for table_name, table in self._db.metadata.tables.items():
|
||||
@@ -124,9 +142,9 @@ class SecretsMigrator:
|
||||
for table_name, table in tables.items():
|
||||
for col_name, col in table.columns.items():
|
||||
if isinstance(col.type, EncryptedType):
|
||||
cols = meta_info.get(table_name, {})
|
||||
_, cols = meta_info.get(table_name, (table, {}))
|
||||
cols[col_name] = col.type
|
||||
meta_info[table_name] = cols
|
||||
meta_info[table_name] = (table, cols)
|
||||
|
||||
return meta_info
|
||||
|
||||
@@ -151,9 +169,13 @@ class SecretsMigrator:
|
||||
|
||||
@staticmethod
|
||||
def _select_columns_from_table(
|
||||
conn: Connection, column_names: list[str], table_name: str
|
||||
conn: Connection,
|
||||
pk_columns: list[str],
|
||||
column_names: list[str],
|
||||
table_name: str,
|
||||
) -> Row:
|
||||
return conn.execute(f"SELECT id, {','.join(column_names)} FROM {table_name}") # noqa: S608
|
||||
cols = ",".join(pk_columns + column_names)
|
||||
return conn.execute(f"SELECT {cols} FROM {table_name}") # noqa: S608
|
||||
|
||||
def _re_encrypt_row(
|
||||
self,
|
||||
@@ -161,62 +183,143 @@ class SecretsMigrator:
|
||||
row: Row,
|
||||
table_name: str,
|
||||
columns: dict[str, EncryptedType],
|
||||
pk_columns: list[str],
|
||||
stats: ReEncryptStats,
|
||||
) -> None:
|
||||
"""
|
||||
Re encrypts all columns in a Row
|
||||
|
||||
Re-encryption is idempotent per column: we first ask whether the
|
||||
current key can already decrypt the value, and skip if so. Only if
|
||||
the current key fails do we fall back to decrypting with the
|
||||
previous key and re-encrypting. Checking the current key first
|
||||
keeps ``run()`` idempotent regardless of what ``previous_secret_key``
|
||||
the caller supplies — even re-running with the same (unchanged)
|
||||
``SECRET_KEY`` will not rewrite rows.
|
||||
|
||||
NULL values are never encrypted, so they are reported separately
|
||||
(neither re-encrypted nor "skipped because already current").
|
||||
|
||||
Per-column outcomes are accumulated onto ``stats`` so the caller can
|
||||
report a summary. Columns whose ciphertext is unreadable under both
|
||||
keys are counted as failures and logged; the exception is not
|
||||
propagated, so processing continues. The caller is responsible for
|
||||
raising once all rows have been scanned.
|
||||
|
||||
If no columns need re-encryption, no UPDATE is issued.
|
||||
|
||||
:param row: Current row to reencrypt
|
||||
:param columns: Meta info from columns
|
||||
:param pk_columns: Primary key column names used to target the row
|
||||
:param stats: Mutable counters updated per column
|
||||
"""
|
||||
re_encrypted_columns = {}
|
||||
|
||||
for column_name, encrypted_type in columns.items():
|
||||
raw_value = self._read_bytes(column_name, row[column_name])
|
||||
|
||||
# NULL values aren't encrypted; there is nothing to migrate.
|
||||
if raw_value is None:
|
||||
stats.null += 1
|
||||
continue
|
||||
|
||||
# Fast path: if the current key can already read the value,
|
||||
# leave it untouched. A failure here simply means we need to try
|
||||
# the previous key below — not a condition worth logging.
|
||||
try:
|
||||
encrypted_type.process_result_value(raw_value, self._dialect)
|
||||
except Exception: # noqa: BLE001, S110 # pylint: disable=broad-except
|
||||
pass
|
||||
else:
|
||||
stats.skipped += 1
|
||||
continue
|
||||
|
||||
# Current key cannot decrypt — try the previous key.
|
||||
previous_encrypted_type = EncryptedType(
|
||||
type_in=encrypted_type.underlying_type, key=self._previous_secret_key
|
||||
)
|
||||
try:
|
||||
unencrypted_value = previous_encrypted_type.process_result_value(
|
||||
self._read_bytes(column_name, row[column_name]), self._dialect
|
||||
raw_value, self._dialect
|
||||
)
|
||||
except ValueError as ex:
|
||||
# Failed to unencrypt
|
||||
try:
|
||||
encrypted_type.process_result_value(
|
||||
self._read_bytes(column_name, row[column_name]), self._dialect
|
||||
)
|
||||
logger.info(
|
||||
"Current secret is able to decrypt value on column [%s.%s],"
|
||||
" nothing to do",
|
||||
table_name,
|
||||
column_name,
|
||||
)
|
||||
return
|
||||
except Exception:
|
||||
raise Exception from ex # pylint: disable=broad-exception-raised
|
||||
except Exception as prev_ex: # noqa: BLE001 # pylint: disable=broad-except
|
||||
logger.error(
|
||||
"Column [%s.%s] cannot be decrypted under the previous"
|
||||
" or current secret key (%s: %s)",
|
||||
table_name,
|
||||
column_name,
|
||||
type(prev_ex).__name__,
|
||||
prev_ex,
|
||||
)
|
||||
stats.failed += 1
|
||||
continue
|
||||
|
||||
re_encrypted_columns[column_name] = encrypted_type.process_bind_param(
|
||||
unencrypted_value,
|
||||
self._dialect,
|
||||
)
|
||||
stats.re_encrypted += 1
|
||||
|
||||
set_cols = ",".join(
|
||||
[f"{name} = :{name}" for name in list(re_encrypted_columns.keys())]
|
||||
)
|
||||
logger.info("Processing table: %s", table_name)
|
||||
if not re_encrypted_columns:
|
||||
return
|
||||
|
||||
set_cols = ",".join(f"{name} = :{name}" for name in re_encrypted_columns)
|
||||
where_clause = " AND ".join(f"{pk} = :_pk_{pk}" for pk in pk_columns)
|
||||
pk_bind = {f"_pk_{pk}": row[pk] for pk in pk_columns}
|
||||
conn.execute(
|
||||
text(f"UPDATE {table_name} SET {set_cols} WHERE id = :id"), # noqa: S608
|
||||
id=row["id"],
|
||||
text(
|
||||
f"UPDATE {table_name} SET {set_cols} WHERE {where_clause}" # noqa: S608
|
||||
),
|
||||
**pk_bind,
|
||||
**re_encrypted_columns,
|
||||
)
|
||||
|
||||
def run(self) -> None:
|
||||
def run(self) -> ReEncryptStats:
|
||||
"""
|
||||
Re-encrypt every encrypted column in the ORM under the current
|
||||
``SECRET_KEY``.
|
||||
|
||||
Returns per-value counts of re-encrypted, skipped (already under the
|
||||
current key), and failed (undecryptable) outcomes. If any failures
|
||||
occurred the transaction is rolled back by raising after the
|
||||
summary is logged, so partial re-encryption never commits.
|
||||
"""
|
||||
encrypted_meta_info = self.discover_encrypted_fields()
|
||||
stats = ReEncryptStats()
|
||||
|
||||
with self._db.engine.begin() as conn:
|
||||
logger.info("Collecting info for re encryption")
|
||||
for table_name, columns in encrypted_meta_info.items():
|
||||
for table_name, (table, columns) in encrypted_meta_info.items():
|
||||
pk_columns = [c.name for c in table.primary_key.columns]
|
||||
if not pk_columns:
|
||||
logger.warning(
|
||||
"Skipping %s: no primary key, cannot target rows for update",
|
||||
table_name,
|
||||
)
|
||||
continue
|
||||
column_names = list(columns.keys())
|
||||
rows = self._select_columns_from_table(conn, column_names, table_name)
|
||||
rows = self._select_columns_from_table(
|
||||
conn, pk_columns, column_names, table_name
|
||||
)
|
||||
|
||||
for row in rows:
|
||||
self._re_encrypt_row(conn, row, table_name, columns)
|
||||
self._re_encrypt_row(
|
||||
conn, row, table_name, columns, pk_columns, stats
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Re-encryption summary: %d re-encrypted, %d skipped,"
|
||||
" %d null, %d failed",
|
||||
stats.re_encrypted,
|
||||
stats.skipped,
|
||||
stats.null,
|
||||
stats.failed,
|
||||
)
|
||||
if stats.failed:
|
||||
raise Exception( # pylint: disable=broad-exception-raised
|
||||
f"Re-encryption failed for {stats.failed} value(s); "
|
||||
"transaction rolled back"
|
||||
)
|
||||
|
||||
logger.info("All tables processed")
|
||||
return stats
|
||||
|
||||
@@ -28,6 +28,7 @@ from freezegun import freeze_time
|
||||
|
||||
import superset.cli.importexport
|
||||
import superset.cli.thumbnails
|
||||
import superset.cli.update
|
||||
from superset import db
|
||||
from superset.models.dashboard import Dashboard
|
||||
from tests.integration_tests.fixtures.birth_names_dashboard import (
|
||||
@@ -322,3 +323,44 @@ def test_compute_thumbnails(thumbnail_mock, app_context, fs):
|
||||
|
||||
thumbnail_mock.assert_called_with(None, dashboard.id, force=False)
|
||||
assert response.exit_code == 0
|
||||
|
||||
|
||||
def test_re_encrypt_secrets_without_previous_key_is_noop(app_context):
|
||||
"""
|
||||
When neither --previous_secret_key nor config.PREVIOUS_SECRET_KEY is set,
|
||||
the command should exit cleanly (0) rather than error out, so that
|
||||
scheduled re-encryption runs don't start failing after a successful
|
||||
rotation is complete.
|
||||
"""
|
||||
current_app.config.pop("PREVIOUS_SECRET_KEY", None)
|
||||
runner = current_app.test_cli_runner()
|
||||
with mock.patch.object(superset.cli.update.SecretsMigrator, "run") as run_mock:
|
||||
response = runner.invoke(superset.cli.update.re_encrypt_secrets, [])
|
||||
|
||||
assert response.exit_code == 0
|
||||
assert "nothing to re-encrypt" in response.output.lower()
|
||||
run_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_re_encrypt_secrets_failure_exits_nonzero(app_context):
|
||||
"""
|
||||
When re-encryption fails for any field, SecretsMigrator.run raises to
|
||||
trigger rollback. The CLI must surface that as a non-zero exit with a
|
||||
clear error message — not as an uncaught exception.
|
||||
"""
|
||||
runner = current_app.test_cli_runner()
|
||||
with mock.patch.object(
|
||||
superset.cli.update.SecretsMigrator,
|
||||
"run",
|
||||
side_effect=Exception("Re-encryption failed for 2 value(s)"),
|
||||
):
|
||||
response = runner.invoke(
|
||||
superset.cli.update.re_encrypt_secrets,
|
||||
["--previous_secret_key", "old-key"],
|
||||
)
|
||||
|
||||
assert response.exit_code == 1
|
||||
assert "Re-encryption failed" in response.output
|
||||
# The failure path must be handled by the CLI, not leaked as an
|
||||
# uncaught exception.
|
||||
assert response.exception is None or isinstance(response.exception, SystemExit)
|
||||
|
||||
@@ -24,6 +24,7 @@ from sqlalchemy_utils.types.encrypted.encrypted_type import StringEncryptedType
|
||||
from superset.extensions import encrypted_field_factory
|
||||
from superset.utils.encrypt import (
|
||||
AbstractEncryptedFieldAdapter,
|
||||
ReEncryptStats,
|
||||
SecretsMigrator,
|
||||
SQLAlchemyUtilsAdapter,
|
||||
)
|
||||
@@ -79,7 +80,7 @@ class EncryptedFieldTest(SupersetTestCase):
|
||||
|
||||
migrator = SecretsMigrator("")
|
||||
encrypted_fields = migrator.discover_encrypted_fields()
|
||||
for table_name, cols in encrypted_fields.items():
|
||||
for table_name, (_table, cols) in encrypted_fields.items():
|
||||
for col_name, field in cols.items():
|
||||
if not encrypted_field_factory.created_by_enc_field_factory(field):
|
||||
self.fail(
|
||||
@@ -101,8 +102,33 @@ class EncryptedFieldTest(SupersetTestCase):
|
||||
"dbs table not found in encrypted fields — "
|
||||
"discover_encrypted_fields may be using the wrong MetaData instance"
|
||||
)
|
||||
dbs_cols = set(encrypted_fields["dbs"].keys())
|
||||
assert {"password", "encrypted_extra", "server_cert"}.issubset(dbs_cols)
|
||||
_table, dbs_cols = encrypted_fields["dbs"]
|
||||
assert {"password", "encrypted_extra", "server_cert"}.issubset(
|
||||
set(dbs_cols.keys())
|
||||
)
|
||||
|
||||
def test_discover_encrypted_fields_returns_table_with_non_id_pk(self):
|
||||
"""
|
||||
Ensure discover_encrypted_fields surfaces the Table object alongside
|
||||
encrypted columns, and that the PK introspection works for tables
|
||||
whose primary key is not a conventional integer `id` column
|
||||
(e.g. `semantic_layers` uses `uuid` as its PK).
|
||||
"""
|
||||
# Import triggers FAB metadata registration for the semantic_layers table.
|
||||
from superset.semantic_layers.models import SemanticLayer # noqa: F401
|
||||
|
||||
migrator = SecretsMigrator("")
|
||||
encrypted_fields = migrator.discover_encrypted_fields()
|
||||
assert "semantic_layers" in encrypted_fields, (
|
||||
"semantic_layers table not found — it has an encrypted `configuration` "
|
||||
"column and should be discovered"
|
||||
)
|
||||
table, cols = encrypted_fields["semantic_layers"]
|
||||
assert "configuration" in cols
|
||||
pk_columns = [c.name for c in table.primary_key.columns]
|
||||
assert pk_columns == ["uuid"], (
|
||||
f"Expected semantic_layers PK to be ['uuid'], got {pk_columns}"
|
||||
)
|
||||
|
||||
def test_lazy_key_resolution(self):
|
||||
"""
|
||||
@@ -175,3 +201,190 @@ class EncryptedFieldTest(SupersetTestCase):
|
||||
|
||||
# Restore original key
|
||||
self.app.config["SECRET_KEY"] = key_a
|
||||
|
||||
def test_re_encrypt_row_uses_pk_columns(self):
|
||||
"""
|
||||
Verify SecretsMigrator builds UPDATE statements targeting the table's
|
||||
actual primary key columns rather than a hardcoded `id` column.
|
||||
Regression guard for tables like `semantic_layers` whose PK is `uuid`.
|
||||
"""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from sqlalchemy.engine import make_url
|
||||
|
||||
dialect = make_url("sqlite://").get_dialect()
|
||||
previous_key = "PREVIOUS_KEY_FOR_PK_COLUMN_TEST"
|
||||
migrator = SecretsMigrator(previous_key)
|
||||
migrator._dialect = dialect # noqa: SLF001
|
||||
|
||||
# Encrypt under the previous key so the current-key decrypt fails
|
||||
# and the re-encrypt path (which issues the UPDATE) is exercised.
|
||||
previous_field = EncryptedType(type_in=String(1024), key=previous_key)
|
||||
ciphertext = previous_field.process_bind_param("hunter2", dialect)
|
||||
|
||||
current_field = encrypted_field_factory.create(String(1024))
|
||||
conn = MagicMock()
|
||||
row = {"uuid": b"\x00" * 16, "configuration": ciphertext}
|
||||
stats = ReEncryptStats()
|
||||
|
||||
migrator._re_encrypt_row( # noqa: SLF001
|
||||
conn,
|
||||
row,
|
||||
"semantic_layers",
|
||||
{"configuration": current_field},
|
||||
["uuid"],
|
||||
stats,
|
||||
)
|
||||
|
||||
assert conn.execute.call_count == 1
|
||||
stmt = str(conn.execute.call_args.args[0])
|
||||
assert "WHERE uuid = :_pk_uuid" in stmt
|
||||
kwargs = conn.execute.call_args.kwargs
|
||||
assert kwargs["_pk_uuid"] == row["uuid"]
|
||||
assert "configuration" in kwargs
|
||||
assert stats == ReEncryptStats(re_encrypted=1, skipped=0, failed=0)
|
||||
|
||||
def test_re_encrypt_row_is_idempotent(self):
|
||||
"""
|
||||
Re-running re-encryption on a row that is already encrypted under the
|
||||
current key must be a no-op: no UPDATE is issued, no error is raised,
|
||||
and the outcome is counted as skipped.
|
||||
"""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from sqlalchemy.engine import make_url
|
||||
|
||||
dialect = make_url("sqlite://").get_dialect()
|
||||
current_key = self.app.config["SECRET_KEY"]
|
||||
migrator = SecretsMigrator("WRONG_PREVIOUS_KEY_abcdef")
|
||||
migrator._dialect = dialect # noqa: SLF001
|
||||
|
||||
field = encrypted_field_factory.create(String(1024))
|
||||
ciphertext = field.process_bind_param("hunter2", dialect)
|
||||
assert field.process_result_value(ciphertext, dialect) == "hunter2"
|
||||
|
||||
conn = MagicMock()
|
||||
row = {"uuid": b"\x00" * 16, "configuration": ciphertext}
|
||||
stats = ReEncryptStats()
|
||||
|
||||
migrator._re_encrypt_row( # noqa: SLF001
|
||||
conn,
|
||||
row,
|
||||
"semantic_layers",
|
||||
{"configuration": field},
|
||||
["uuid"],
|
||||
stats,
|
||||
)
|
||||
|
||||
assert conn.execute.call_count == 0, (
|
||||
"Row already readable under current key should not trigger UPDATE"
|
||||
)
|
||||
assert stats == ReEncryptStats(re_encrypted=0, skipped=1, failed=0)
|
||||
# Current key must still decrypt the original ciphertext — nothing
|
||||
# was mutated.
|
||||
self.app.config["SECRET_KEY"] = current_key
|
||||
assert field.process_result_value(ciphertext, dialect) == "hunter2"
|
||||
|
||||
def test_re_encrypt_row_idempotent_when_previous_key_also_decrypts(self):
|
||||
"""
|
||||
When the supplied previous_secret_key can also decrypt the value
|
||||
(e.g. re-running after a successful rotation while still passing
|
||||
the original secret, or mistakenly passing the current secret as
|
||||
the previous one), the row must still be skipped. Idempotency is
|
||||
anchored on whether the current key can already read the data,
|
||||
not on whether the previous key fails to decrypt.
|
||||
"""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from sqlalchemy.engine import make_url
|
||||
|
||||
dialect = make_url("sqlite://").get_dialect()
|
||||
# Previous key == current key — this is the "re-run with no actual
|
||||
# rotation" scenario.
|
||||
migrator = SecretsMigrator(self.app.config["SECRET_KEY"])
|
||||
migrator._dialect = dialect # noqa: SLF001
|
||||
|
||||
field = encrypted_field_factory.create(String(1024))
|
||||
ciphertext = field.process_bind_param("hunter2", dialect)
|
||||
|
||||
conn = MagicMock()
|
||||
row = {"uuid": b"\x00" * 16, "configuration": ciphertext}
|
||||
stats = ReEncryptStats()
|
||||
|
||||
migrator._re_encrypt_row( # noqa: SLF001
|
||||
conn,
|
||||
row,
|
||||
"semantic_layers",
|
||||
{"configuration": field},
|
||||
["uuid"],
|
||||
stats,
|
||||
)
|
||||
|
||||
assert conn.execute.call_count == 0, (
|
||||
"Idempotency must hold even when previous_secret_key can also "
|
||||
"decrypt the value"
|
||||
)
|
||||
assert stats == ReEncryptStats(re_encrypted=0, skipped=1, failed=0)
|
||||
|
||||
def test_re_encrypt_row_counts_failures_without_raising(self):
|
||||
"""
|
||||
Per-column failures are accumulated onto the stats counter so the
|
||||
caller can emit a summary covering every row. The row method itself
|
||||
must not raise — run() decides whether to abort based on the totals.
|
||||
"""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from sqlalchemy.engine import make_url
|
||||
|
||||
dialect = make_url("sqlite://").get_dialect()
|
||||
migrator = SecretsMigrator("WRONG_PREVIOUS_KEY_abcdef")
|
||||
migrator._dialect = dialect # noqa: SLF001
|
||||
|
||||
field = encrypted_field_factory.create(String(1024))
|
||||
conn = MagicMock()
|
||||
row = {"uuid": b"\x00" * 16, "configuration": b"not-valid-ciphertext"}
|
||||
stats = ReEncryptStats()
|
||||
|
||||
migrator._re_encrypt_row( # noqa: SLF001
|
||||
conn,
|
||||
row,
|
||||
"semantic_layers",
|
||||
{"configuration": field},
|
||||
["uuid"],
|
||||
stats,
|
||||
)
|
||||
|
||||
assert conn.execute.call_count == 0
|
||||
assert stats == ReEncryptStats(re_encrypted=0, skipped=0, failed=1)
|
||||
|
||||
def test_re_encrypt_row_counts_nulls_separately(self):
|
||||
"""
|
||||
NULL column values are not encrypted and therefore have nothing to
|
||||
migrate. They must be counted as ``null`` (not ``skipped``) and
|
||||
must not trigger an UPDATE, regardless of which key is supplied as
|
||||
the previous secret.
|
||||
"""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from sqlalchemy.engine import make_url
|
||||
|
||||
dialect = make_url("sqlite://").get_dialect()
|
||||
migrator = SecretsMigrator("WRONG_PREVIOUS_KEY_abcdef")
|
||||
migrator._dialect = dialect # noqa: SLF001
|
||||
|
||||
field = encrypted_field_factory.create(String(1024))
|
||||
conn = MagicMock()
|
||||
row = {"uuid": b"\x00" * 16, "configuration": None}
|
||||
stats = ReEncryptStats()
|
||||
|
||||
migrator._re_encrypt_row( # noqa: SLF001
|
||||
conn,
|
||||
row,
|
||||
"semantic_layers",
|
||||
{"configuration": field},
|
||||
["uuid"],
|
||||
stats,
|
||||
)
|
||||
|
||||
assert conn.execute.call_count == 0
|
||||
assert stats == ReEncryptStats(re_encrypted=0, skipped=0, null=1, failed=0)
|
||||
|
||||
@@ -32,6 +32,7 @@ from superset.mcp_service.chart.schemas import (
|
||||
FilterConfig,
|
||||
LegendConfig,
|
||||
TableChartConfig,
|
||||
TablePreview,
|
||||
UpdateChartPreviewRequest,
|
||||
XYChartConfig,
|
||||
)
|
||||
@@ -698,6 +699,79 @@ class TestUpdateChartPreview:
|
||||
assert result["warnings"] == []
|
||||
mock_get_previous_form_data.assert_called_once_with("valid_key_12345")
|
||||
|
||||
@patch.object(update_chart_preview_module, "validate_and_compile")
|
||||
@patch.object(update_chart_preview_module, "has_dataset_access", return_value=True)
|
||||
@patch("superset.daos.dataset.DatasetDAO.find_by_id")
|
||||
@patch.object(update_chart_preview_module, "generate_preview_from_form_data")
|
||||
@patch.object(update_chart_preview_module, "analyze_chart_semantics")
|
||||
@patch.object(update_chart_preview_module, "analyze_chart_capabilities")
|
||||
@patch.object(update_chart_preview_module, "generate_explore_link")
|
||||
@patch.object(update_chart_preview_module, "_get_previous_form_data")
|
||||
@patch("superset.mcp_service.auth.get_user_from_request")
|
||||
@pytest.mark.asyncio
|
||||
async def test_returns_requested_table_preview(
|
||||
self,
|
||||
mock_get_user_from_request,
|
||||
mock_get_previous_form_data,
|
||||
mock_generate_explore_link,
|
||||
mock_analyze_chart_capabilities,
|
||||
mock_analyze_chart_semantics,
|
||||
mock_generate_preview_from_form_data,
|
||||
mock_find_by_id,
|
||||
unused_access_mock,
|
||||
mock_validate_and_compile,
|
||||
) -> None:
|
||||
"""Preview updates honor supported preview_formats."""
|
||||
mock_user = Mock()
|
||||
mock_user.id = 1
|
||||
mock_get_user_from_request.return_value = mock_user
|
||||
mock_find_by_id.return_value = _mock_dataset(id=3)
|
||||
mock_validate_and_compile.return_value = Mock(success=True)
|
||||
mock_get_previous_form_data.return_value = {}
|
||||
mock_generate_explore_link.return_value = (
|
||||
"http://localhost:8088/explore/?form_data_key=new_preview_key"
|
||||
)
|
||||
mock_analyze_chart_capabilities.return_value = None
|
||||
mock_analyze_chart_semantics.return_value = None
|
||||
table_preview = TablePreview(
|
||||
table_data="Table Preview",
|
||||
row_count=1,
|
||||
supports_sorting=True,
|
||||
)
|
||||
expected_table_preview = {
|
||||
"type": "table",
|
||||
"table_data": "Table Preview",
|
||||
"row_count": 1,
|
||||
"supports_sorting": True,
|
||||
}
|
||||
mock_generate_preview_from_form_data.return_value = table_preview
|
||||
|
||||
request = UpdateChartPreviewRequest(
|
||||
form_data_key="valid_key_12345",
|
||||
dataset_id=3,
|
||||
config=TableChartConfig(
|
||||
chart_type="table",
|
||||
columns=[
|
||||
ColumnRef(name="country", label="Country"),
|
||||
ColumnRef(name="sales", label="Sales", aggregate="SUM"),
|
||||
],
|
||||
),
|
||||
generate_preview=True,
|
||||
preview_formats=["url", "table"],
|
||||
)
|
||||
|
||||
result = update_chart_preview_module.update_chart_preview(
|
||||
request=request, ctx=Mock()
|
||||
)
|
||||
|
||||
assert result["success"] is True
|
||||
assert result["previews"] == {"table": expected_table_preview}
|
||||
mock_generate_preview_from_form_data.assert_called_once()
|
||||
preview_kwargs = mock_generate_preview_from_form_data.call_args.kwargs
|
||||
assert preview_kwargs["dataset_id"] == 3
|
||||
assert preview_kwargs["preview_format"] == "table"
|
||||
assert preview_kwargs["form_data"]["viz_type"] == "table"
|
||||
|
||||
|
||||
class TestUpdateChartPreviewValidation:
|
||||
"""Tier-1 validation gate and dataset access checks."""
|
||||
|
||||
Reference in New Issue
Block a user