diff --git a/.env.example b/.env.example
index 84bd766f6..6773227c8 100644
--- a/.env.example
+++ b/.env.example
@@ -11,3 +11,10 @@ MAPTILER_API_KEY=123
# SEO
PREVENT_SEARCH_BOTS=false
+
+# CSP
+# Set to "true" to emit Content-Security-Policy-Report-Only instead of the
+# enforcing header. Useful when rolling out tighter CSP changes — violations
+# are reported to the browser console but not blocked. Leave unset in normal
+# operation.
+CSP_REPORT_ONLY=false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 06b62e8b9..7a89cbf45 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,7 +18,9 @@ You can also check the
- Incorporate the Swiss-Federal-CI library into this repository.
- Fixes
- Sanitize urls for links in tables
+ - Improve CSP header configuration
- Maintenance
+ - Remove Google Analytics integration (it is no longer in use)
- Set Maptiler API key from `MAPTILER_API_KEY` environment variable at
runtime, to avoid having to rebuild the application when the key is rotated
- Use AGENTS.md instead of CLAUDE.md and adjust context according to recent
@@ -1438,7 +1440,6 @@ visualize.admin.ch are now noticeable faster.
#### Performance
- Improved performance of cube data fetching
-
- Added LRU cache to min max queries
- Added query cache to bulk queries
- Ordered filter so that non-discriminant filter are last
diff --git a/app/domain/env.ts b/app/domain/env.ts
index f204edbe6..414948e4f 100644
--- a/app/domain/env.ts
+++ b/app/domain/env.ts
@@ -42,9 +42,6 @@ export const SQL_ENDPOINT =
export const GRAPHQL_ENDPOINT =
clientEnv?.GRAPHQL_ENDPOINT ?? process.env.GRAPHQL_ENDPOINT ?? "/api/graphql";
-export const GA_TRACKING_ID =
- clientEnv?.GA_TRACKING_ID ?? process.env.GA_TRACKING_ID;
-
export const ADFS_PROFILE_URL =
clientEnv?.ADFS_PROFILE_URL ?? process.env.ADFS_PROFILE_URL;
diff --git a/app/next.config.js b/app/next.config.js
index 80c1a9904..27a8fe5c5 100644
--- a/app/next.config.js
+++ b/app/next.config.js
@@ -39,128 +39,176 @@ if (process.env.NEXT_PUBLIC_SENTRY_DSN) {
console.log("Sentry DSN:", process.env.NEXT_PUBLIC_SENTRY_DSN);
}
-module.exports = withSentryConfig(withPreconstruct(
- withBundleAnalyzer(
- withMDX({
- output: "standalone",
- i18n: {
- locales,
- defaultLocale,
- },
-
- experimental: {
- instrumentationHook: true,
- },
-
- headers: async () => {
- const headers = [];
-
- headers.push({
- source: "/:path*",
- headers: [
- {
- key: "X-Content-Type-Options",
- value: "nosniff",
- },
- ],
- });
-
- // See https://content-security-policy.com/ & https://developers.google.com/tag-platform/security/guides/csp
- if (!(process.env.DISABLE_CSP && process.env.DISABLE_CSP === "true")) {
- const sentryCSP = process.env.NEXT_PUBLIC_SENTRY_CSP ? ` ${process.env.NEXT_PUBLIC_SENTRY_CSP}` : "";
- headers[0].headers.push({
- key: "Content-Security-Policy",
- value: [
- `default-src 'self' 'unsafe-inline'${process.env.NODE_ENV === "development" ? " 'unsafe-eval'" : ""
- }${sentryCSP} https://vercel.live/ https://vercel.com https://*.googletagmanager.com`,
- `script-src 'self' 'unsafe-inline'${process.env.NODE_ENV === "development" ? " 'unsafe-eval'" : ""
- }${sentryCSP} https://vercel.live/ https://vercel.com https://*.googletagmanager.com https://api.mapbox.com https://api.maptiler.com`,
- `style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net`,
+module.exports = withSentryConfig(
+ withPreconstruct(
+ withBundleAnalyzer(
+ withMDX({
+ output: "standalone",
+ i18n: {
+ locales,
+ defaultLocale,
+ },
+
+ experimental: {
+ instrumentationHook: true,
+ },
+
+ headers: async () => {
+ // See https://content-security-policy.com/ & https://developers.google.com/tag-platform/security/guides/csp
+ const isDev = process.env.NODE_ENV === "development";
+ const isVercel = !!process.env.VERCEL;
+ const sentryCSP = process.env.NEXT_PUBLIC_SENTRY_CSP
+ ? ` ${process.env.NEXT_PUBLIC_SENTRY_CSP}`
+ : "";
+ const unsafeEval = isDev ? " 'unsafe-eval'" : "";
+ // Vercel Toolbar / Live Comments hosts — only needed on Vercel deployments
+ const vercelDefault = isVercel
+ ? " https://vercel.live/ https://vercel.com"
+ : "";
+ const vercelScript = isVercel
+ ? " https://vercel.live/ https://vercel.com"
+ : "";
+ const vercelScriptElem = isVercel
+ ? " https://vercel.live https://vercel.com https://*.vercel.app"
+ : "";
+ const vercelWorker = isVercel ? " https://*.vercel.app" : "";
+
+ const buildCSP = (frameAncestors) =>
+ [
+ `default-src 'self' 'unsafe-inline'${unsafeEval}${sentryCSP}${vercelDefault}`,
+ `script-src 'self' 'unsafe-inline'${unsafeEval}${sentryCSP}${vercelScript} https://api.mapbox.com https://api.maptiler.com`,
+ `script-src-elem 'self' 'unsafe-inline' https://*.admin.ch https://visualize.admin.ch https://*.visualize.admin.ch${vercelScriptElem} https://api.mapbox.com`,
+ `style-src 'self' 'unsafe-inline' https://fonts.googleapis.com`,
`font-src 'self'`,
- `form-action 'self'`,
+
+ // * to allow loading legend images from custom WMS / WMTS endpoints and data: to allow downloading images
+ `img-src 'self' * data: blob:`,
// * to allow WMS / WMTS endpoints
`connect-src 'self' *`,
- // * to allow loading legend images from custom WMS / WMTS endpoints and data: to allow downloading images
- `img-src 'self' * data: blob:`,
- `script-src-elem 'self' 'unsafe-inline' https://*.admin.ch https://visualize.admin.ch https://*.visualize.admin.ch https://vercel.live https://vercel.com https://*.vercel.app https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com https://api.mapbox.com https://cdn.jsdelivr.net`,
- `worker-src 'self' blob: https://*.admin.ch https://*.vercel.app`,
- ].join("; "),
- });
- }
+ `worker-src 'self' blob: https://*.admin.ch${vercelWorker}`,
+ `form-action 'self'`,
+ `frame-ancestors ${frameAncestors}`,
+ `object-src 'none'`,
+ `base-uri 'self'`,
+ `upgrade-insecure-requests`,
+ ].join("; ");
+
+ // When CSP_REPORT_ONLY=true, emit the report-only header so violations
+ // are surfaced to the browser console without being enforced. Useful
+ // for rolling out tighter policies. The header is otherwise always
+ // present — there is intentionally no kill-switch to fully disable CSP.
+ const reportOnly =
+ process.env.CSP_REPORT_ONLY &&
+ process.env.CSP_REPORT_ONLY === "true";
+ const cspKey = reportOnly
+ ? "Content-Security-Policy-Report-Only"
+ : "Content-Security-Policy";
+
+ const baseHeaders = [
+ { key: "X-Content-Type-Options", value: "nosniff" },
+ ];
+ if (process.env.PREVENT_SEARCH_BOTS === "true") {
+ baseHeaders.push({
+ key: "X-Robots-Tag",
+ value: "noindex, nofollow",
+ });
+ }
- if (process.env.PREVENT_SEARCH_BOTS === "true") {
- headers[0].headers.push({
- key: "X-Robots-Tag",
- value: "noindex, nofollow",
+ const headers = [];
+
+ // Catch-all — block iframing to prevent clickjacking on the editor / browser / login UI.
+ // Must come first: when multiple Next.js header rules match the same path,
+ // later rules override earlier ones for the same header key.
+ headers.push({
+ source: "/:path*",
+ headers: [
+ ...baseHeaders,
+ { key: cspKey, value: buildCSP("'self'") },
+ ],
});
- }
-
- return headers;
- },
-
- pageExtensions: ["js", "ts", "tsx", "mdx"],
-
- eslint: {
- // Warning: Dangerously allow production builds to successfully complete even if
- // your project has ESLint errors.
- ignoreDuringBuilds: true,
- },
-
- webpack (config, { dev }) {
- config.module.rules.push({
- test: /\.(graphql|gql)$/,
- exclude: /node_modules/,
- loader: "graphql-tag/loader",
- });
-
- /* Enable source maps in production */
- if (!dev) {
- config.devtool = "source-map";
-
- for (const plugin of config.plugins) {
- if (plugin.constructor.name === "UglifyJsPlugin") {
- plugin.options.sourceMap = true;
- break;
- }
+
+ // Routes that are intended to be embedded in third-party iframes.
+ // These override the catch-all CSP to allow `frame-ancestors *`.
+ // `/api/embed-aem-ext/*` serves the AEM external-embed HTML wrapper,
+ // which partner sites may iframe directly.
+ const embeddableSources = [
+ "/embed/:path*",
+ "/preview",
+ "/api/embed-aem-ext/:path*",
+ ];
+ for (const source of embeddableSources) {
+ headers.push({
+ source,
+ headers: [...baseHeaders, { key: cspKey, value: buildCSP("*") }],
+ });
}
- if (config.optimization && config.optimization.minimizer) {
- for (const plugin of config.optimization.minimizer) {
- if (plugin.constructor.name === "TerserPlugin") {
+ return headers;
+ },
+
+ pageExtensions: ["js", "ts", "tsx", "mdx"],
+
+ eslint: {
+ // Warning: Dangerously allow production builds to successfully complete even if
+ // your project has ESLint errors.
+ ignoreDuringBuilds: true,
+ },
+
+ webpack(config, { dev }) {
+ config.module.rules.push({
+ test: /\.(graphql|gql)$/,
+ exclude: /node_modules/,
+ loader: "graphql-tag/loader",
+ });
+
+ /* Enable source maps in production */
+ if (!dev) {
+ config.devtool = "source-map";
+
+ for (const plugin of config.plugins) {
+ if (plugin.constructor.name === "UglifyJsPlugin") {
plugin.options.sourceMap = true;
break;
}
}
+
+ if (config.optimization && config.optimization.minimizer) {
+ for (const plugin of config.optimization.minimizer) {
+ if (plugin.constructor.name === "TerserPlugin") {
+ plugin.options.sourceMap = true;
+ break;
+ }
+ }
+ }
}
- }
-
- config.resolve.extensions.push(dev ? ".dev.ts" : ".prod.ts");
- config.resolve.alias = {
- ...config.resolve.alias,
- "mapbox-gl": "maplibre-gl",
- };
- // For some reason these need to be ignored for serverless target
- config.plugins.push(
- new IgnorePlugin({ resourceRegExp: /^(pg-native|vue)$/ })
- );
-
- return config;
- },
-
- async redirects () {
- return [
- {
- source: "/storybook",
- destination: "/storybook/index.html",
- permanent: true,
- },
- ];
- },
- })
- ),
- { silent: true },
- { hideSourcemaps: true }
-));
+ config.resolve.extensions.push(dev ? ".dev.ts" : ".prod.ts");
+ config.resolve.alias = {
+ ...config.resolve.alias,
+ "mapbox-gl": "maplibre-gl",
+ };
+ // For some reason these need to be ignored for serverless target
+ config.plugins.push(
+ new IgnorePlugin({ resourceRegExp: /^(pg-native|vue)$/ })
+ );
+
+ return config;
+ },
+
+ async redirects() {
+ return [
+ {
+ source: "/storybook",
+ destination: "/storybook/index.html",
+ permanent: true,
+ },
+ ];
+ },
+ })
+ ),
+ { silent: true },
+ { hideSourcemaps: true }
+ )
+);
diff --git a/app/pages/_app.tsx b/app/pages/_app.tsx
index 29b6e6dc8..1adacf70b 100644
--- a/app/pages/_app.tsx
+++ b/app/pages/_app.tsx
@@ -20,10 +20,9 @@ import * as federalTheme from "@/themes/theme";
import { AsyncLocalizationProvider } from "@/utils/async-localization-provider";
import { EventEmitterProvider } from "@/utils/event-emitter";
import { Flashes } from "@/utils/flashes";
-import { analyticsPageView } from "@/utils/google-analytics";
-import "@/utils/nprogress.css";
import { useNProgress } from "@/utils/use-nprogress";
+import "@/utils/nprogress.css";
import "@/configurator/components/color-picker.css";
const GQLDebugPanel = dynamic(
@@ -45,12 +44,8 @@ export default function App({
i18n.activate(locale);
}
- // Initialize analytics
+ // Activate the right locale on route change
useEffect(() => {
- const handleRouteChange = (url: string) => {
- analyticsPageView(url);
- };
-
const handleRouteStart = (url: string) => {
const locale = parseLocaleString(url.slice(1));
if (i18n.locale !== locale) {
@@ -59,10 +54,8 @@ export default function App({
};
routerEvents.on("routeChangeStart", handleRouteStart);
- routerEvents.on("routeChangeComplete", handleRouteChange);
return () => {
routerEvents.off("routeChangeStart", handleRouteStart);
- routerEvents.off("routeChangeComplete", handleRouteChange);
};
}, [routerEvents]);
diff --git a/app/pages/_document.tsx b/app/pages/_document.tsx
index 770cf42c1..15a298102 100644
--- a/app/pages/_document.tsx
+++ b/app/pages/_document.tsx
@@ -1,7 +1,5 @@
import Document, { Head, Html, Main, NextScript } from "next/document";
-import { GA_TRACKING_ID } from "@/domain/env";
-
class MyDocument extends Document {
render() {
return (
@@ -9,19 +7,6 @@ class MyDocument extends Document {
{/* eslint-disable-next-line @next/next/no-sync-scripts */}
- {GA_TRACKING_ID && (
- <>
-
-
- >
- )}
diff --git a/app/pages/api/client-env.ts b/app/pages/api/client-env.ts
index c5c177a23..1bc463af9 100644
--- a/app/pages/api/client-env.ts
+++ b/app/pages/api/client-env.ts
@@ -13,7 +13,6 @@ export default async function clientEnvApi(
case "GET":
try {
const result = `window.__clientEnv__=${JSON.stringify({
- GA_TRACKING_ID: process.env.GA_TRACKING_ID,
ENDPOINT: process.env.ENDPOINT,
WHITELISTED_DATA_SOURCES:
process.env.WHITELISTED_DATA_SOURCES !== undefined
diff --git a/app/pages/embed/[chartId].tsx b/app/pages/embed/[chartId].tsx
index 3deefefa7..0f2554353 100644
--- a/app/pages/embed/[chartId].tsx
+++ b/app/pages/embed/[chartId].tsx
@@ -2,7 +2,6 @@ import { Config as PrismaConfig } from "@prisma/client";
import "iframe-resizer/js/iframeResizer.contentWindow.js";
import { GetServerSideProps } from "next";
import ErrorPage from "next/error";
-import Head from "next/head";
import "@open-iframe-resizer/core";
import { ChartPublished } from "@/components/chart-published";
@@ -62,30 +61,12 @@ const EmbedPage = (props: PageProps) => {
} = props;
return (
- <>
-
-
-
-
-
-
- >
+
+
+
);
};
diff --git a/app/utils/google-analytics.ts b/app/utils/google-analytics.ts
deleted file mode 100644
index 11df25da3..000000000
--- a/app/utils/google-analytics.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { GA_TRACKING_ID } from "../domain/env";
-
-declare global {
- interface Window {
- gtag?: (...args: $IntentionalAny) => void;
- }
-}
-
-// https://developers.google.com/analytics/devguides/collection/gtagjs/ip-anonymization
-
-// https://developers.google.com/analytics/devguides/collection/gtagjs/pages
-export const analyticsPageView = (path: string) => {
- window.gtag?.("config", GA_TRACKING_ID, {
- page_path: path,
- anonymize_ip: true,
- });
-};
-
-// https://developers.google.com/analytics/devguides/collection/gtagjs/events
-/** @internal */
-export const analyticsEvent = ({
- action,
- category,
- label,
- value,
-}: {
- action: string;
- category: string;
- label: string;
- value?: number;
-}) => {
- window.gtag?.("event", action, {
- event_category: category,
- event_label: label,
- value: value,
- anonymize_ip: true,
- });
-};
diff --git a/yarn.lock b/yarn.lock
index a17219b32..d825895d1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -277,29 +277,7 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.6.tgz#103f466803fa0f059e82ccac271475470570d74c"
integrity sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==
-"@babel/core@7.12.9":
- version "7.12.9"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8"
- integrity sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==
- dependencies:
- "@babel/code-frame" "^7.10.4"
- "@babel/generator" "^7.12.5"
- "@babel/helper-module-transforms" "^7.12.1"
- "@babel/helpers" "^7.12.5"
- "@babel/parser" "^7.12.7"
- "@babel/template" "^7.12.7"
- "@babel/traverse" "^7.12.9"
- "@babel/types" "^7.12.7"
- convert-source-map "^1.7.0"
- debug "^4.1.0"
- gensync "^1.0.0-beta.1"
- json5 "^2.1.2"
- lodash "^4.17.19"
- resolve "^1.3.2"
- semver "^5.4.1"
- source-map "^0.5.0"
-
-"@babel/core@^7.0.0", "@babel/core@^7.10.5", "@babel/core@^7.12.3", "@babel/core@^7.12.9", "@babel/core@^7.18.9", "@babel/core@^7.21.0", "@babel/core@^7.23.0", "@babel/core@^7.24.4", "@babel/core@^7.26.10", "@babel/core@^7.7.7":
+"@babel/core@7.12.9", "@babel/core@^7.0.0", "@babel/core@^7.10.5", "@babel/core@^7.12.3", "@babel/core@^7.12.9", "@babel/core@^7.14.6", "@babel/core@^7.18.9", "@babel/core@^7.21.0", "@babel/core@^7.23.0", "@babel/core@^7.24.4", "@babel/core@^7.26.10", "@babel/core@^7.7.7":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322"
integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==
@@ -329,17 +307,6 @@
jsesc "^2.5.1"
source-map "^0.5.0"
-"@babel/generator@^7.12.5", "@babel/generator@^7.29.0":
- version "7.29.1"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50"
- integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==
- dependencies:
- "@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/generator@^7.21.1":
version "7.28.3"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.3.tgz#9626c1741c650cbac39121694a0f2d7451b8ef3e"
@@ -404,6 +371,17 @@
"@jridgewell/trace-mapping" "^0.3.28"
jsesc "^3.0.2"
+"@babel/generator@^7.29.0":
+ version "7.29.1"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50"
+ integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==
+ dependencies:
+ "@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@^7.14.5":
version "7.14.5"
resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz"
@@ -682,15 +660,6 @@
"@babel/traverse" "^7.28.6"
"@babel/types" "^7.28.6"
-"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e"
- integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==
- dependencies:
- "@babel/helper-module-imports" "^7.28.6"
- "@babel/helper-validator-identifier" "^7.28.5"
- "@babel/traverse" "^7.28.6"
-
"@babel/helper-module-transforms@^7.14.5":
version "7.15.8"
resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz"
@@ -725,6 +694,15 @@
"@babel/helper-validator-identifier" "^7.25.9"
"@babel/traverse" "^7.25.9"
+"@babel/helper-module-transforms@^7.28.6":
+ version "7.28.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e"
+ integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==
+ dependencies:
+ "@babel/helper-module-imports" "^7.28.6"
+ "@babel/helper-validator-identifier" "^7.28.5"
+ "@babel/traverse" "^7.28.6"
+
"@babel/helper-optimise-call-expression@^7.14.5", "@babel/helper-optimise-call-expression@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz"
@@ -988,14 +966,6 @@
"@babel/template" "^7.22.15"
"@babel/types" "^7.22.19"
-"@babel/helpers@^7.12.5":
- version "7.29.2"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.29.2.tgz#9cfbccb02b8e229892c0b07038052cc1a8709c49"
- integrity sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==
- dependencies:
- "@babel/template" "^7.28.6"
- "@babel/types" "^7.29.0"
-
"@babel/helpers@^7.28.6":
version "7.28.6"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.6.tgz#fca903a313ae675617936e8998b814c415cbf5d7"
@@ -1041,15 +1011,10 @@
js-tokens "^4.0.0"
picocolors "^1.0.0"
-"@babel/parser@7.12.16":
- version "7.12.16"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.16.tgz#cc31257419d2c3189d394081635703f549fc1ed4"
- integrity sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==
-
-"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.12.7", "@babel/parser@^7.15.4", "@babel/parser@^7.20.7", "@babel/parser@^7.21.4", "@babel/parser@^7.22.0", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0", "@babel/parser@^7.24.0", "@babel/parser@^7.24.4", "@babel/parser@^7.24.5", "@babel/parser@^7.25.4", "@babel/parser@^7.25.9", "@babel/parser@^7.26.2", "@babel/parser@^7.27.0", "@babel/parser@^7.28.3", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0":
- version "7.29.2"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.2.tgz#58bd50b9a7951d134988a1ae177a35ef9a703ba1"
- integrity sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==
+"@babel/parser@7.12.16", "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.14.6", "@babel/parser@^7.15.4", "@babel/parser@^7.20.7", "@babel/parser@^7.21.4", "@babel/parser@^7.22.0", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0", "@babel/parser@^7.24.0", "@babel/parser@^7.24.4", "@babel/parser@^7.24.5", "@babel/parser@^7.25.4", "@babel/parser@^7.25.9", "@babel/parser@^7.26.2", "@babel/parser@^7.27.0", "@babel/parser@^7.28.3", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0":
+ version "7.29.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.3.tgz#116f70a77958307fceac27747573032f8a62f88e"
+ integrity sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==
dependencies:
"@babel/types" "^7.29.0"
@@ -2242,15 +2207,6 @@
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.26.10.tgz#1fce13e5a331a9dafff192b5db41350d72d44bed"
integrity sha512-AYXK0hLWfEaK9WAePJqs30qro09a8w7X3YZzjukqtLXreE7xBZYdi5EMrP87T4UrVqmQ9tIX6L6SeTu5LDh3zw==
-"@babel/template@^7.12.7", "@babel/template@^7.28.6":
- version "7.28.6"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57"
- integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==
- dependencies:
- "@babel/code-frame" "^7.28.6"
- "@babel/parser" "^7.28.6"
- "@babel/types" "^7.28.6"
-
"@babel/template@^7.15.4":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz"
@@ -2296,6 +2252,15 @@
"@babel/parser" "^7.27.0"
"@babel/types" "^7.27.0"
+"@babel/template@^7.28.6":
+ version "7.28.6"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57"
+ integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==
+ dependencies:
+ "@babel/code-frame" "^7.28.6"
+ "@babel/parser" "^7.28.6"
+ "@babel/types" "^7.28.6"
+
"@babel/traverse@7.12.13":
version "7.12.13"
resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz"
@@ -2326,19 +2291,6 @@
debug "^4.1.0"
globals "^11.1.0"
-"@babel/traverse@^7.12.9", "@babel/traverse@^7.29.0":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a"
- integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==
- dependencies:
- "@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"
-
"@babel/traverse@^7.18.9":
version "7.24.0"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.0.tgz#4a408fbf364ff73135c714a2ab46a5eab2831b1e"
@@ -2410,6 +2362,19 @@
"@babel/types" "^7.28.6"
debug "^4.3.1"
+"@babel/traverse@^7.29.0":
+ version "7.29.0"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a"
+ integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==
+ dependencies:
+ "@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"
+
"@babel/types@7.12.13":
version "7.12.13"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz"
@@ -2427,14 +2392,6 @@
"@babel/helper-validator-identifier" "^7.14.9"
to-fast-properties "^2.0.0"
-"@babel/types@^7.12.7", "@babel/types@^7.25.4", "@babel/types@^7.29.0":
- version "7.29.0"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7"
- integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==
- dependencies:
- "@babel/helper-string-parser" "^7.27.1"
- "@babel/helper-validator-identifier" "^7.28.5"
-
"@babel/types@^7.16.7":
version "7.17.0"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz"
@@ -2505,6 +2462,14 @@
"@babel/helper-validator-identifier" "^7.24.5"
to-fast-properties "^2.0.0"
+"@babel/types@^7.25.4", "@babel/types@^7.29.0":
+ version "7.29.0"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7"
+ integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==
+ dependencies:
+ "@babel/helper-string-parser" "^7.27.1"
+ "@babel/helper-validator-identifier" "^7.28.5"
+
"@babel/types@^7.25.9", "@babel/types@^7.26.0":
version "7.26.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff"
@@ -15980,7 +15945,7 @@ fwd-stream@^1.0.4:
dependencies:
readable-stream "~1.0.26-4"
-gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2:
+gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz"
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
@@ -17489,7 +17454,7 @@ is-core-module@^2.13.0:
dependencies:
hasown "^2.0.0"
-is-core-module@^2.15.1, is-core-module@^2.16.0, is-core-module@^2.16.1:
+is-core-module@^2.15.1, is-core-module@^2.16.0:
version "2.16.1"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
@@ -23222,16 +23187,6 @@ resolve@^1.21.0, resolve@^1.22.1:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
-resolve@^1.3.2:
- version "1.22.12"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.12.tgz#f5b2a680897c69c238a13cd16b15671f8b73549f"
- integrity sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==
- dependencies:
- es-errors "^1.3.0"
- is-core-module "^2.16.1"
- path-parse "^1.0.7"
- supports-preserve-symlinks-flag "^1.0.0"
-
resolve@^2.0.0-next.5:
version "2.0.0-next.5"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c"
@@ -23585,11 +23540,6 @@ semver-compare@^1.0.0:
resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-semver@^5.4.1:
- version "5.7.2"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
- integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
-
semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
version "6.3.0"
resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"