chore(deps): bump zod from 3.25.76 to 4.6.6 in /frontend (#7392)

* chore(deps): bump zod from 3.25.76 to 4.6.6 in /frontend

Bumps [zod](https://github.com/colinhacks/zod) from 3.25.76 to 4.6.6.
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v3.25.76...v4.6.6)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 4.6.6
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(frontend): complete Zod 4 migration

Use explicit string keys for extension setting records so the discovery
schema remains assignable to the extension loader contract under Zod 4.
Cover accepted primitives, rejected non-primitive settings and inferred
public types through the discovery API.

Keep Nextra 4.6.1 and its docs theme on their previous Zod 4.3.6 dependency
until upstream fixes required children validation. The app remains on Zod
4.6.6. Document and lock the targeted compatibility overrides.

* docs: keep frontend guidance within hard budget

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit is contained in:
dependabot[bot] 2026-10-24 22:36:41 +08:00 committed by GitHub
parent 2055991eb2
commit 04691473d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 112 additions and 31 deletions

View File

@ -12,11 +12,11 @@ Core dependencies: `@langchain/langgraph-sdk` ^1.5.3 for orchestration/streaming
`@langchain/core` ^1.1.15, and `@tanstack/react-query` ^5.90.17 for server state.
Registry UI: Shadcn, MagicUI, React Bits, Vercel AI SDK (see Code Style).
`pnpm-workspace.yaml` overrides vulnerable `@xmldom/xmldom` 0.9.x releases to
0.9.12 for GHSA-965w-775f-mr7g. Nextra pulls it in through MathJax and
`speech-rule-engine@4.1.2`, which pins 0.9.8. Keep the override until the
upstream dependency chain resolves a patched version without it; regenerate
`pnpm-lock.yaml` and verify the docs build when changing this constraint.
`pnpm-workspace.yaml` pins vulnerable `@xmldom/xmldom` 0.9.x to patched
0.9.12 (GHSA-965w-775f-mr7g) and Nextra 4.6.1's Zod dependencies to 4.3.6
until upstream fixes missing-`children` validation. App schemas use Zod 4.6.6.
Remove each override after its upstream fix; refresh the lockfile and test
docs builds after changes.
## Commands

View File

@ -101,7 +101,7 @@
"unist-util-visit": "^5.0.0",
"use-stick-to-bottom": "^1.1.1",
"uuid": "^14.0.0",
"zod": "^3.24.2"
"zod": "^4.6.6"
},
"devDependencies": {
"@eslint/eslintrc": "^3.3.1",

View File

@ -6,6 +6,8 @@ settings:
overrides:
'@xmldom/xmldom@>=0.9.0 <0.9.12': 0.9.12
nextra@4.6.1>zod: 4.3.6
nextra-theme-docs@4.6.1>zod: 4.3.6
importers:
@ -100,7 +102,7 @@ importers:
version: 1.0.2(react@19.2.4)
'@t3-oss/env-nextjs':
specifier: ^0.12.0
version: 0.12.0(typescript@5.9.3)(zod@3.25.76)
version: 0.12.0(typescript@5.9.3)(zod@4.6.6)
'@tanstack/react-query':
specifier: ^5.90.17
version: 5.90.20(react@19.2.4)
@ -124,7 +126,7 @@ importers:
version: 12.10.0(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
ai:
specifier: ^6.0.33
version: 6.0.78(zod@3.25.76)
version: 6.0.78(zod@4.6.6)
best-effort-json-parser:
specifier: ^1.2.1
version: 1.2.1
@ -252,8 +254,8 @@ importers:
specifier: ^14.0.0
version: 14.0.0
zod:
specifier: ^3.24.2
version: 3.25.76
specifier: ^4.6.6
version: 4.6.6
devDependencies:
'@eslint/eslintrc':
specifier: ^3.3.1
@ -5985,12 +5987,12 @@ packages:
yoga-wasm-web@0.3.3:
resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==}
zod@3.25.76:
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
zod@4.3.6:
resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
zod@4.6.6:
resolution: {integrity: sha512-4UmzQUF5fxvfcYHlbjBmejU+w+hbDnWFx4aS8kBx7nPBHcO2SqPbpAG8snbdg+Xse4pRefR98hgjFgIMCI/UhA==}
zustand@4.5.7:
resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==}
engines: {node: '>=12.7.0'}
@ -6029,19 +6031,19 @@ packages:
snapshots:
'@ai-sdk/gateway@3.0.39(zod@3.25.76)':
'@ai-sdk/gateway@3.0.39(zod@4.6.6)':
dependencies:
'@ai-sdk/provider': 3.0.8
'@ai-sdk/provider-utils': 4.0.14(zod@3.25.76)
'@ai-sdk/provider-utils': 4.0.14(zod@4.6.6)
'@vercel/oidc': 3.1.0
zod: 3.25.76
zod: 4.6.6
'@ai-sdk/provider-utils@4.0.14(zod@3.25.76)':
'@ai-sdk/provider-utils@4.0.14(zod@4.6.6)':
dependencies:
'@ai-sdk/provider': 3.0.8
'@standard-schema/spec': 1.1.0
eventsource-parser: 3.0.6
zod: 3.25.76
zod: 4.6.6
'@ai-sdk/provider@3.0.8':
dependencies:
@ -6702,7 +6704,7 @@ snapshots:
mustache: 4.2.0
p-queue: 6.6.2
uuid: 10.0.0
zod: 3.25.76
zod: 4.6.6
transitivePeerDependencies:
- '@opentelemetry/api'
- '@opentelemetry/exporter-trace-otlp-proto'
@ -7907,17 +7909,17 @@ snapshots:
dependencies:
tslib: 2.8.1
'@t3-oss/env-core@0.12.0(typescript@5.9.3)(zod@3.25.76)':
'@t3-oss/env-core@0.12.0(typescript@5.9.3)(zod@4.6.6)':
optionalDependencies:
typescript: 5.9.3
zod: 3.25.76
zod: 4.6.6
'@t3-oss/env-nextjs@0.12.0(typescript@5.9.3)(zod@3.25.76)':
'@t3-oss/env-nextjs@0.12.0(typescript@5.9.3)(zod@4.6.6)':
dependencies:
'@t3-oss/env-core': 0.12.0(typescript@5.9.3)(zod@3.25.76)
'@t3-oss/env-core': 0.12.0(typescript@5.9.3)(zod@4.6.6)
optionalDependencies:
typescript: 5.9.3
zod: 3.25.76
zod: 4.6.6
'@tailwindcss/node@4.1.18':
dependencies:
@ -8578,13 +8580,13 @@ snapshots:
acorn@8.15.0: {}
ai@6.0.78(zod@3.25.76):
ai@6.0.78(zod@4.6.6):
dependencies:
'@ai-sdk/gateway': 3.0.39(zod@3.25.76)
'@ai-sdk/gateway': 3.0.39(zod@4.6.6)
'@ai-sdk/provider': 3.0.8
'@ai-sdk/provider-utils': 4.0.14(zod@3.25.76)
'@ai-sdk/provider-utils': 4.0.14(zod@4.6.6)
'@opentelemetry/api': 1.9.0
zod: 3.25.76
zod: 4.6.6
ajv@6.12.6:
dependencies:
@ -12578,10 +12580,10 @@ snapshots:
yoga-wasm-web@0.3.3: {}
zod@3.25.76: {}
zod@4.3.6: {}
zod@4.6.6: {}
zustand@4.5.7(@types/react@19.2.13)(react@19.2.4):
dependencies:
use-sync-external-store: 1.6.0(react@19.2.4)

View File

@ -2,6 +2,10 @@ packages: []
overrides:
# GHSA-965w-775f-mr7g: speech-rule-engine 4.1.2 pins vulnerable 0.9.8.
"@xmldom/xmldom@>=0.9.0 <0.9.12": 0.9.12
# Nextra 4.6.1 strips children before validating required Layout props.
# Keep its previous Zod until https://github.com/shuding/nextra/issues/5036 is fixed.
"nextra@4.6.1>zod": 4.3.6
"nextra-theme-docs@4.6.1>zod": 4.3.6
ignoredBuiltDependencies:
- esbuild
- sharp

View File

@ -14,7 +14,10 @@ const contributions = z.array(
transport: z.string().nullable().optional(),
title: z.string(),
description: z.string(),
settings: z.record(z.union([z.boolean(), z.number(), z.string()])),
settings: z.record(
z.string(),
z.union([z.boolean(), z.number(), z.string()]),
),
}),
);

View File

@ -0,0 +1,72 @@
import { afterEach, expect, rs, test } from "@rstest/core";
import { fetchFrontendExtensions } from "@/core/extensions/api";
import type { FrontendContribution } from "@/core/extensions/contracts";
rs.mock("@/core/config", () => ({ getBackendBaseURL: () => "" }));
rs.mock("@/core/static-mode", () => ({ isStaticWebsiteOnly: () => false }));
rs.mock("@/core/api/static-response", () => ({ staticApiResponse: rs.fn() }));
const entry = {
namespace: "community.bookmarks",
module: "bookmarks.v1",
entry: `/api/plugins/modules/bookmarks.v1/${"a".repeat(64)}.mjs`,
title: "Bookmarks",
description: "",
};
afterEach(() => {
rs.restoreAllMocks();
});
for (const [label, settings] of [
["empty", {}],
[
"mixed primitive",
{
enabled: true,
disabled: false,
limit: 3,
zero: 0,
label: "Bookmarks",
empty: "",
},
],
] as const) {
test(`discovery preserves ${label} settings for the extension loader`, async () => {
const request = rs
.spyOn(globalThis, "fetch")
.mockResolvedValue(
new Response(JSON.stringify([{ ...entry, settings }])),
);
// pnpm typecheck verifies the discovery schema's inferred public contract.
const discovered: FrontendContribution[] = await fetchFrontendExtensions();
expect(discovered).toEqual([{ ...entry, settings }]);
expect(request).toHaveBeenCalledWith(
"/api/plugins",
expect.objectContaining({ credentials: "include", cache: "no-store" }),
);
});
}
for (const [label, settings] of [
["null value", { enabled: null }],
["nested object", { options: { enabled: true } }],
["array value", { options: ["bookmarks"] }],
["null record", null],
["array record", []],
["string record", "enabled"],
["missing record", undefined],
] as const) {
test(`discovery rejects settings with a ${label}`, async () => {
rs.spyOn(globalThis, "fetch").mockResolvedValue(
new Response(JSON.stringify([{ ...entry, settings }])),
);
await expect(fetchFrontendExtensions()).rejects.toMatchObject({
name: "ZodError",
});
});
}