diff --git a/.changeset/silly-colts-brush.md b/.changeset/silly-colts-brush.md
new file mode 100644
index 0000000000..be1c72ea14
--- /dev/null
+++ b/.changeset/silly-colts-brush.md
@@ -0,0 +1,8 @@
+---
+"@cloudoperators/juno-app-greenhouse": patch
+"@cloudoperators/juno-app-supernova": patch
+"@cloudoperators/juno-app-heureka": patch
+"@cloudoperators/juno-app-doop": patch
+---
+
+Makes route search validation Zod v4–ready (filter by prefix before parse) and upgrade zod to v4
diff --git a/apps/carbon/src/components/ErrorBoundary/ErrorFallback.tsx b/apps/carbon/src/components/ErrorBoundary/ErrorFallback.tsx
index fdfb985dc5..f5855eebff 100644
--- a/apps/carbon/src/components/ErrorBoundary/ErrorFallback.tsx
+++ b/apps/carbon/src/components/ErrorBoundary/ErrorFallback.tsx
@@ -8,7 +8,7 @@ import { FallbackProps } from "react-error-boundary"
import { Message } from "@cloudoperators/juno-ui-components"
const ErrorFallback = ({ error }: FallbackProps) => (
-
+
)
export default ErrorFallback
diff --git a/apps/doop/src/lib/helpers.ts b/apps/doop/src/lib/helpers.ts
index 1ef8544c01..6d3a1443f2 100644
--- a/apps/doop/src/lib/helpers.ts
+++ b/apps/doop/src/lib/helpers.ts
@@ -39,3 +39,30 @@ export function capitalize(string: any) {
export const isObjectWithKeys = (value: any) =>
value !== null && typeof value === "object" && Object.keys(value).length > 0
+
+/**
+ * Filters raw URL search params to only known keys and keys that start with any allowed prefix.
+ * Use this before Zod parsing when you need prefix-based catchall validation
+ * (Zod v4 no longer provides ctx.path in preprocess).
+ *
+ * Reusable pattern for route validateSearch: filter first, then parse with a schema that has
+ * .catchall(z.union([z.string(), z.array(z.string()), z.undefined()])).
+ */
+export function filterSearchParamsByPrefix(
+ raw: Record,
+ knownKeys: string[],
+ allowedPrefixes: string[]
+): Record {
+ const result: Record = {}
+ for (const key of knownKeys) {
+ if (Object.prototype.hasOwnProperty.call(raw, key)) {
+ result[key] = raw[key]
+ }
+ }
+ for (const key of Object.keys(raw)) {
+ if (allowedPrefixes.some((p) => key.startsWith(p))) {
+ result[key] = raw[key]
+ }
+ }
+ return result
+}
diff --git a/apps/doop/src/routes/violations.tsx b/apps/doop/src/routes/violations.tsx
index 540f7f0034..217f2251bd 100644
--- a/apps/doop/src/routes/violations.tsx
+++ b/apps/doop/src/routes/violations.tsx
@@ -17,26 +17,24 @@ import {
} from "../components/StoreProvider"
import { parseInitialFilters } from "../lib/store/createFiltersSlice"
import { isObjectWithKeys } from "../lib/helpers"
+import { filterSearchParamsByPrefix } from "../lib/helpers"
+
+const filterValueSchema = z.union([z.string(), z.array(z.string()), z.undefined()])
const searchSchema = z
.object({
searchTerm: z.string().optional(),
violationGroup: z.string().optional(),
})
- .catchall(
- z.preprocess(
- (val, ctx) => {
- if (ctx.path.length > 0 && typeof ctx.path[0] === "string" && !ctx.path[0].startsWith(ACTIVE_FILTERS_PREFIX)) {
- return undefined
- }
- return val
- },
- z.union([z.string(), z.array(z.string()), z.undefined()])
- )
- )
+ .catchall(filterValueSchema)
+
+function validateViolationsSearch(search: Record): z.infer {
+ const filtered = filterSearchParamsByPrefix(search, Object.keys(searchSchema.shape), [ACTIVE_FILTERS_PREFIX])
+ return searchSchema.parse(filtered)
+}
export const Route = createFileRoute("/violations")({
- validateSearch: searchSchema,
+ validateSearch: validateViolationsSearch,
beforeLoad: ({ search }) => {
// extract alerts specific state from the URL search params
const { activeFilters, searchTerm, violationGroup } = convertUrlStateToAppState(search)
diff --git a/apps/greenhouse/src/lib/helpers.ts b/apps/greenhouse/src/lib/helpers.ts
index 1286aa03f7..e8b5244893 100644
--- a/apps/greenhouse/src/lib/helpers.ts
+++ b/apps/greenhouse/src/lib/helpers.ts
@@ -18,3 +18,30 @@ export const parseError = (error: any) => {
// @ts-expect-error TS(2304): Cannot find name 'errMsg'.
return errMsg
}
+
+/**
+ * Filters raw URL search params to only known keys and keys that start with any allowed prefix.
+ * Use this before Zod parsing when you need prefix-based catchall validation
+ * (Zod v4 no longer provides ctx.path in preprocess).
+ *
+ * Reusable pattern for route validateSearch: filter first, then parse with a schema that has
+ * .catchall(z.union([z.string(), z.array(z.string()), z.undefined()])).
+ */
+export function filterSearchParamsByPrefix(
+ raw: Record,
+ knownKeys: string[],
+ allowedPrefixes: string[]
+): Record {
+ const result: Record = {}
+ for (const key of knownKeys) {
+ if (Object.prototype.hasOwnProperty.call(raw, key)) {
+ result[key] = raw[key]
+ }
+ }
+ for (const key of Object.keys(raw)) {
+ if (allowedPrefixes.some((p) => key.startsWith(p))) {
+ result[key] = raw[key]
+ }
+ }
+ return result
+}
diff --git a/apps/greenhouse/src/routes/admin/plugin-presets/index.tsx b/apps/greenhouse/src/routes/admin/plugin-presets/index.tsx
index 65b93580b1..02515551ab 100644
--- a/apps/greenhouse/src/routes/admin/plugin-presets/index.tsx
+++ b/apps/greenhouse/src/routes/admin/plugin-presets/index.tsx
@@ -8,28 +8,26 @@ import { z } from "zod"
import { PluginPresets } from "../../../components/admin/PluginPresets"
import { SELECTED_FILTER_PREFIX } from "../../../components/admin/constants"
import { extractFilterSettingsFromSearchParams } from "../../../components/admin/utils"
+import { filterSearchParamsByPrefix } from "../../../lib/helpers"
+
+const filterValueSchema = z.union([z.string(), z.array(z.string()), z.undefined()])
const searchParamsSchema = z
.object({
searchTerm: z.string().optional(),
})
- .catchall(
- z.preprocess(
- (val, ctx) => {
- if (ctx.path.length > 0 && typeof ctx.path[0] === "string" && !ctx.path[0].startsWith(SELECTED_FILTER_PREFIX)) {
- return undefined
- }
- return val
- },
- z.union([z.string(), z.array(z.string()), z.undefined()])
- )
- )
+ .catchall(filterValueSchema)
export type PluginPresetSearchParams = z.infer
+function validatePluginPresetsSearch(search: Record): PluginPresetSearchParams {
+ const filtered = filterSearchParamsByPrefix(search, Object.keys(searchParamsSchema.shape), [SELECTED_FILTER_PREFIX])
+ return searchParamsSchema.parse(filtered)
+}
+
export const Route = createFileRoute("/admin/plugin-presets/")({
component: PluginPresets,
- validateSearch: (search: Record) => searchParamsSchema.parse(search),
+ validateSearch: validatePluginPresetsSearch,
loaderDeps: (search) => ({
...search,
}),
diff --git a/apps/heureka/src/routes/services/index.tsx b/apps/heureka/src/routes/services/index.tsx
index 19f6a8b716..6425a66421 100644
--- a/apps/heureka/src/routes/services/index.tsx
+++ b/apps/heureka/src/routes/services/index.tsx
@@ -13,29 +13,26 @@ import { SELECTED_FILTER_PREFIX } from "../../constants"
import { fetchServices } from "../../api/fetchServices"
import { fetchServicesFilters } from "../../api/fetchServicesFilters"
import { extractFilterSettingsFromSearchParams } from "../../components/Services/utils"
+import { filterSearchParamsByPrefix } from "../../utils"
+
+const filterValueSchema = z.union([z.string(), z.array(z.string()), z.undefined()])
-// Schema for validating and transforming search parameters related to /services page.
const servicesSearchSchema = z
.object({
service: z.string().optional(),
searchTerm: z.string().optional(),
})
- .catchall(
- z.preprocess(
- (val, ctx) => {
- if (ctx.path.length > 0 && typeof ctx.path[0] === "string" && !ctx.path[0].startsWith(SELECTED_FILTER_PREFIX)) {
- return undefined
- }
- return val
- },
- z.union([z.string(), z.array(z.string()), z.undefined()])
- )
- )
+ .catchall(filterValueSchema)
export type ServicesSearchParams = z.infer
+function validateServicesSearch(search: Record): ServicesSearchParams {
+ const filtered = filterSearchParamsByPrefix(search, Object.keys(servicesSearchSchema.shape), [SELECTED_FILTER_PREFIX])
+ return servicesSearchSchema.parse(filtered) as ServicesSearchParams
+}
+
export const Route = createFileRoute("/services/")({
- validateSearch: servicesSearchSchema,
+ validateSearch: validateServicesSearch,
loaderDeps: ({ search }) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { service, ...rest } = search // we're omitting 'service' from the deps so route does not reload when it changes
diff --git a/apps/heureka/src/routes/vulnerabilities/index.tsx b/apps/heureka/src/routes/vulnerabilities/index.tsx
index 6f29e5f49e..3a2be9f963 100644
--- a/apps/heureka/src/routes/vulnerabilities/index.tsx
+++ b/apps/heureka/src/routes/vulnerabilities/index.tsx
@@ -10,28 +10,28 @@ import { SELECTED_FILTER_PREFIX } from "../../constants"
import { fetchVulnerabilities } from "../../api/fetchVulnerabilities"
import { fetchVulnerabilityFilters } from "../../api/fetchVulnerabilityFilters"
import { extractFilterSettingsFromSearchParams } from "../../components/Vulnerabilities/utils"
+import { filterSearchParamsByPrefix } from "../../utils"
+
+const filterValueSchema = z.union([z.string(), z.array(z.string()), z.undefined()])
const vulnerabilitiesSearchSchema = z
.object({
vulnerability: z.string().optional(),
searchTerm: z.preprocess((val) => (typeof val === "number" ? val.toString() : val), z.string().optional()),
})
- .catchall(
- z.preprocess(
- (val, ctx) => {
- if (ctx.path.length > 0 && typeof ctx.path[0] === "string" && !ctx.path[0].startsWith(SELECTED_FILTER_PREFIX)) {
- return undefined
- }
- return val
- },
- z.union([z.string(), z.array(z.string()), z.undefined()])
- )
- )
+ .catchall(filterValueSchema)
export type VulnerabilitiesSearchParams = z.infer
+function validateVulnerabilitiesSearch(search: Record): VulnerabilitiesSearchParams {
+ const filtered = filterSearchParamsByPrefix(search, Object.keys(vulnerabilitiesSearchSchema.shape), [
+ SELECTED_FILTER_PREFIX,
+ ])
+ return vulnerabilitiesSearchSchema.parse(filtered) as VulnerabilitiesSearchParams
+}
+
export const Route = createFileRoute("/vulnerabilities/")({
- validateSearch: vulnerabilitiesSearchSchema,
+ validateSearch: validateVulnerabilitiesSearch,
loaderDeps: ({ search }) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { vulnerability, ...rest } = search // we're omitting 'service' from the deps so route does not reload when it changes
diff --git a/apps/heureka/src/utils.ts b/apps/heureka/src/utils.ts
index 10ae355c9d..5abd956350 100644
--- a/apps/heureka/src/utils.ts
+++ b/apps/heureka/src/utils.ts
@@ -94,3 +94,30 @@ export const mapObject = (obj: Record, iteratee: (value: T, key
})
return result
}
+
+/**
+ * Filters raw URL search params to only known keys and keys that start with any allowed prefix.
+ * Use this before Zod parsing when you need prefix-based catchall validation
+ * (Zod v4 no longer provides ctx.path in preprocess).
+ *
+ * Reusable pattern for route validateSearch: filter first, then parse with a schema that has
+ * .catchall(z.union([z.string(), z.array(z.string()), z.undefined()])).
+ */
+export function filterSearchParamsByPrefix(
+ raw: Record,
+ knownKeys: string[],
+ allowedPrefixes: string[]
+): Record {
+ const result: Record = {}
+ for (const key of knownKeys) {
+ if (Object.prototype.hasOwnProperty.call(raw, key)) {
+ result[key] = raw[key]
+ }
+ }
+ for (const key of Object.keys(raw)) {
+ if (allowedPrefixes.some((p) => key.startsWith(p))) {
+ result[key] = raw[key]
+ }
+ }
+ return result
+}
diff --git a/apps/supernova/src/lib/urlStateUtils.ts b/apps/supernova/src/lib/urlStateUtils.ts
index 30fc04d61d..2ec2056059 100644
--- a/apps/supernova/src/lib/urlStateUtils.ts
+++ b/apps/supernova/src/lib/urlStateUtils.ts
@@ -50,18 +50,13 @@ export const extractSearchStringFromHashFragment = (searchString: string) => {
return searchString.slice(postHashParams, preHashParams === -1 ? undefined : preHashParams)
}
-export const getFiltersForUrl = (prefix: string, filters: any) => {
- return {
- ...Object.entries(filters)
- .map(([key, value]) => {
- if (value === undefined || value === null) return {}
- if (Array.isArray(value)) {
- return { [`${prefix}${key}`]: value }
- }
- return { [`${prefix}${key}`]: value }
- })
- .reduce((acc, curr) => ({ ...acc, ...curr }), {}),
- }
+export const getFiltersForUrl = (prefix: string, filters: any): Record => {
+ return Object.entries(filters ?? {})
+ .filter(([, value]) => value !== undefined && value !== null)
+ .reduce>((acc, [key, value]) => {
+ acc[`${prefix}${key}`] = Array.isArray(value) ? value : (value as string)
+ return acc
+ }, {})
}
export const convertAppStateToUrlState = (appState: any) => {
diff --git a/apps/supernova/src/lib/utils.ts b/apps/supernova/src/lib/utils.ts
index 3a8018f86a..cb9c9e850b 100644
--- a/apps/supernova/src/lib/utils.ts
+++ b/apps/supernova/src/lib/utils.ts
@@ -140,3 +140,30 @@ export const sortAlerts = (items: any) => {
export const isObjectWithKeys = (value: any) =>
value !== null && typeof value === "object" && Object.keys(value).length > 0
+
+/**
+ * Filters raw URL search params to only known keys and keys that start with any allowed prefix.
+ * Use this before Zod parsing when you need prefix-based catchall validation
+ * (Zod v4 no longer provides ctx.path in preprocess).
+ *
+ * Reusable pattern for route validateSearch: filter first, then parse with a schema that has
+ * .catchall(z.union([z.string(), z.array(z.string()), z.undefined()])).
+ */
+export function filterSearchParamsByPrefix(
+ raw: Record,
+ knownKeys: string[],
+ allowedPrefixes: string[]
+): Record {
+ const result: Record = {}
+ for (const key of knownKeys) {
+ if (Object.prototype.hasOwnProperty.call(raw, key)) {
+ result[key] = raw[key]
+ }
+ }
+ for (const key of Object.keys(raw)) {
+ if (allowedPrefixes.some((p) => key.startsWith(p))) {
+ result[key] = raw[key]
+ }
+ }
+ return result
+}
diff --git a/apps/supernova/src/routes/alerts.tsx b/apps/supernova/src/routes/alerts.tsx
index 10a6f3c855..4bf24e57cc 100644
--- a/apps/supernova/src/routes/alerts.tsx
+++ b/apps/supernova/src/routes/alerts.tsx
@@ -14,6 +14,9 @@ import { ACTIVE_FILTERS_PREFIX, PAUSED_FILTERS_PREFIX } from "../constants"
import { convertUrlStateToAppState, getFiltersForUrl } from "../lib/urlStateUtils"
import { useGlobalsActions, useFilterActions, useGlobalsInitialFiltersApplied } from "../components/StoreProvider"
import { isObjectWithKeys } from "../lib/utils"
+import { filterSearchParamsByPrefix } from "../lib/utils"
+
+const filterValueSchema = z.union([z.string(), z.array(z.string()), z.undefined()])
const searchSchema = z
.object({
@@ -21,25 +24,18 @@ const searchSchema = z
showDetailsFor: z.string().optional(),
predefinedFilter: z.string().optional(),
})
- .catchall(
- z.preprocess(
- (val, ctx) => {
- if (
- ctx.path.length > 0 &&
- typeof ctx.path[0] === "string" &&
- !ctx.path[0].startsWith(ACTIVE_FILTERS_PREFIX) &&
- !ctx.path[0].startsWith(PAUSED_FILTERS_PREFIX)
- ) {
- return undefined
- }
- return val
- },
- z.union([z.string(), z.array(z.string()), z.undefined()])
- )
- )
+ .catchall(filterValueSchema)
+
+function validateAlertsSearch(search: Record): z.infer {
+ const filtered = filterSearchParamsByPrefix(search, Object.keys(searchSchema.shape), [
+ ACTIVE_FILTERS_PREFIX,
+ PAUSED_FILTERS_PREFIX,
+ ])
+ return searchSchema.parse(filtered)
+}
export const Route = createFileRoute("/alerts")({
- validateSearch: searchSchema,
+ validateSearch: validateAlertsSearch,
beforeLoad: ({ search }) => {
// extract alerts specific state from the URL search params
const { activeFilters, pausedFilters, predefinedFilter, searchTerm, showDetailsFor } =
diff --git a/package.json b/package.json
index 65b6c23d69..118cb1cd31 100644
--- a/package.json
+++ b/package.json
@@ -41,6 +41,6 @@
"packageManager": "pnpm@10.28.2",
"dependencies": {
"@tanstack/react-query": "5.89.0",
- "zod": "3.25.76"
+ "zod": "4.3.6"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3e99b2828f..d7a32a13c1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -12,8 +12,8 @@ importers:
specifier: 5.89.0
version: 5.89.0(react@19.2.3)
zod:
- specifier: 3.25.76
- version: 3.25.76
+ specifier: 4.3.6
+ version: 4.3.6
devDependencies:
'@changesets/cli':
specifier: 2.29.7
@@ -742,7 +742,7 @@ importers:
version: 9.1.2(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-prettier:
specifier: 5.5.4
- version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@9.1.2(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.6.2)
+ version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@9.1.2(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.8.0)
eslint-plugin-react:
specifier: 7.37.5
version: 7.37.5(eslint@9.39.2(jiti@2.6.1))
@@ -766,10 +766,10 @@ importers:
version: 7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)
vite-plugin-dts:
specifier: 4.5.4
- version: 4.5.4(@types/node@24.10.4)(rollup@4.50.1)(typescript@5.9.2)(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0))
+ version: 4.5.4(@types/node@24.10.4)(rollup@4.50.1)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0))
vitest:
specifier: 3.2.4
- version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.2))(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)
+ version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.3))(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)
packages/messages-provider:
dependencies:
@@ -915,7 +915,7 @@ importers:
version: 4.7.0(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0))
eslint-plugin-storybook:
specifier: 9.1.17
- version: 9.1.17(eslint@9.35.0(jiti@2.6.1))(storybook@9.1.17(@testing-library/dom@10.4.0)(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.3))(prettier@3.8.0)(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)))(typescript@5.9.3)
+ version: 9.1.17(eslint@9.39.2(jiti@2.6.1))(storybook@9.1.17(@testing-library/dom@10.4.0)(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.3))(prettier@3.8.0)(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)))(typescript@5.9.3)
flatpickr:
specifier: 4.6.13
version: 4.6.13
@@ -7503,6 +7503,9 @@ packages:
zod@3.25.76:
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+ zod@4.3.6:
+ resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
+
zustand@4.5.7:
resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==}
engines: {node: '>=12.7.0'}
@@ -10704,13 +10707,13 @@ snapshots:
- supports-color
- typescript
- '@typescript-eslint/utils@8.51.0(eslint@9.35.0(jiti@2.6.1))(typescript@5.9.3)':
+ '@typescript-eslint/utils@8.51.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
- '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.6.1))
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1))
'@typescript-eslint/scope-manager': 8.51.0
'@typescript-eslint/types': 8.51.0
'@typescript-eslint/typescript-estree': 8.51.0(typescript@5.9.3)
- eslint: 9.35.0(jiti@2.6.1)
+ eslint: 9.39.2(jiti@2.6.1)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@@ -10771,15 +10774,6 @@ snapshots:
chai: 5.2.0
tinyrainbow: 2.0.0
- '@vitest/mocker@3.2.4(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.2))(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0))':
- dependencies:
- '@vitest/spy': 3.2.4
- estree-walker: 3.0.3
- magic-string: 0.30.19
- optionalDependencies:
- msw: 2.12.7(@types/node@24.10.4)(typescript@5.9.2)
- vite: 7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)
-
'@vitest/mocker@3.2.4(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.3))(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0))':
dependencies:
'@vitest/spy': 3.2.4
@@ -10856,19 +10850,6 @@ snapshots:
de-indent: 1.0.2
he: 1.2.0
- '@vue/language-core@2.2.0(typescript@5.9.2)':
- dependencies:
- '@volar/language-core': 2.4.14
- '@vue/compiler-dom': 3.5.14
- '@vue/compiler-vue2': 2.7.16
- '@vue/shared': 3.5.14
- alien-signals: 0.4.14
- minimatch: 9.0.5
- muggle-string: 0.4.1
- path-browserify: 1.0.1
- optionalDependencies:
- typescript: 5.9.2
-
'@vue/language-core@2.2.0(typescript@5.9.3)':
dependencies:
'@volar/language-core': 2.4.14
@@ -11944,16 +11925,6 @@ snapshots:
dependencies:
eslint: 9.39.2(jiti@2.6.1)
- eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@9.1.2(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.6.2):
- dependencies:
- eslint: 9.39.2(jiti@2.6.1)
- prettier: 3.6.2
- prettier-linter-helpers: 1.0.0
- synckit: 0.11.8
- optionalDependencies:
- '@types/eslint': 9.6.1
- eslint-config-prettier: 9.1.2(eslint@9.39.2(jiti@2.6.1))
-
eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@9.1.2(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.8.0):
dependencies:
eslint: 9.39.2(jiti@2.6.1)
@@ -11990,10 +11961,10 @@ snapshots:
string.prototype.matchall: 4.0.12
string.prototype.repeat: 1.0.0
- eslint-plugin-storybook@9.1.17(eslint@9.35.0(jiti@2.6.1))(storybook@9.1.17(@testing-library/dom@10.4.0)(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.3))(prettier@3.8.0)(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)))(typescript@5.9.3):
+ eslint-plugin-storybook@9.1.17(eslint@9.39.2(jiti@2.6.1))(storybook@9.1.17(@testing-library/dom@10.4.0)(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.3))(prettier@3.8.0)(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)))(typescript@5.9.3):
dependencies:
- '@typescript-eslint/utils': 8.51.0(eslint@9.35.0(jiti@2.6.1))(typescript@5.9.3)
- eslint: 9.35.0(jiti@2.6.1)
+ '@typescript-eslint/utils': 8.51.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ eslint: 9.39.2(jiti@2.6.1)
storybook: 9.1.17(@testing-library/dom@10.4.0)(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.3))(prettier@3.8.0)(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0))
transitivePeerDependencies:
- supports-color
@@ -13519,32 +13490,6 @@ snapshots:
ms@2.1.3: {}
- msw@2.12.7(@types/node@24.10.4)(typescript@5.9.2):
- dependencies:
- '@inquirer/confirm': 5.1.10(@types/node@24.10.4)
- '@mswjs/interceptors': 0.40.0
- '@open-draft/deferred-promise': 2.2.0
- '@types/statuses': 2.0.6
- cookie: 1.0.2
- graphql: 16.12.0
- headers-polyfill: 4.0.3
- is-node-process: 1.2.0
- outvariant: 1.4.3
- path-to-regexp: 6.3.0
- picocolors: 1.1.1
- rettime: 0.7.0
- statuses: 2.0.2
- strict-event-emitter: 0.5.1
- tough-cookie: 6.0.0
- type-fest: 5.3.0
- until-async: 3.0.2
- yargs: 17.7.2
- optionalDependencies:
- typescript: 5.9.2
- transitivePeerDependencies:
- - '@types/node'
- optional: true
-
msw@2.12.7(@types/node@24.10.4)(typescript@5.9.3):
dependencies:
'@inquirer/confirm': 5.1.10(@types/node@24.10.4)
@@ -14977,25 +14922,6 @@ snapshots:
- tsx
- yaml
- vite-plugin-dts@4.5.4(@types/node@24.10.4)(rollup@4.50.1)(typescript@5.9.2)(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)):
- dependencies:
- '@microsoft/api-extractor': 7.52.8(@types/node@24.10.4)
- '@rollup/pluginutils': 5.3.0(rollup@4.50.1)
- '@volar/typescript': 2.4.14
- '@vue/language-core': 2.2.0(typescript@5.9.2)
- compare-versions: 6.1.1
- debug: 4.4.1
- kolorist: 1.8.0
- local-pkg: 1.1.1
- magic-string: 0.30.19
- typescript: 5.9.2
- optionalDependencies:
- vite: 7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)
- transitivePeerDependencies:
- - '@types/node'
- - rollup
- - supports-color
-
vite-plugin-dts@4.5.4(@types/node@24.10.4)(rollup@4.50.1)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)):
dependencies:
'@microsoft/api-extractor': 7.52.8(@types/node@24.10.4)
@@ -15063,50 +14989,6 @@ snapshots:
tsx: 4.19.4
yaml: 2.8.0
- vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.2))(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0):
- dependencies:
- '@types/chai': 5.2.2
- '@vitest/expect': 3.2.4
- '@vitest/mocker': 3.2.4(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.2))(vite@7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0))
- '@vitest/pretty-format': 3.2.4
- '@vitest/runner': 3.2.4
- '@vitest/snapshot': 3.2.4
- '@vitest/spy': 3.2.4
- '@vitest/utils': 3.2.4
- chai: 5.2.0
- debug: 4.4.1
- expect-type: 1.2.1
- magic-string: 0.30.19
- pathe: 2.0.3
- picomatch: 4.0.3
- std-env: 3.9.0
- tinybench: 2.9.0
- tinyexec: 0.3.2
- tinyglobby: 0.2.15
- tinypool: 1.1.1
- tinyrainbow: 2.0.0
- vite: 7.3.1(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)
- vite-node: 3.2.4(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0)
- why-is-node-running: 2.3.0
- optionalDependencies:
- '@types/debug': 4.1.12
- '@types/node': 24.10.4
- '@vitest/ui': 3.2.4(vitest@3.2.4)
- jsdom: 26.1.0
- transitivePeerDependencies:
- - jiti
- - less
- - lightningcss
- - msw
- - sass
- - sass-embedded
- - stylus
- - sugarss
- - supports-color
- - terser
- - tsx
- - yaml
-
vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.10.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.3))(sass@1.81.1)(terser@5.39.2)(tsx@4.19.4)(yaml@2.8.0):
dependencies:
'@types/chai': 5.2.2
@@ -15357,6 +15239,8 @@ snapshots:
zod@3.25.76: {}
+ zod@4.3.6: {}
+
zustand@4.5.7(@types/react@19.2.7)(immer@10.2.0)(react@19.2.3):
dependencies:
use-sync-external-store: 1.5.0(react@19.2.3)