[compiler] Update for Zod v3/v4 compatibility (#34717)
Partial redo of #34710. The changes there tried to use `z.function(args, return)` to be compatible across Zod v3 and v4, but Zod 4's function API has completely changed. Instead, I've updated to just use `z.any()` where we expect a function, and manually validate that it's a function before we call the value. We already have validation of the return type (also using Zod). Co-authored-by: kolvian <eliot@pontarelli.com>
Joseph Savona committed
Oct 3, 2025 at 10:08 UTC
d6eb735938bc67b41ad723206ea395ba4d761139
8 files changed
+31
-50
compiler/packages/babel-plugin-react-compiler/package.json
+2
-2
@@ -52,8 +52,8 @@
52
"react-dom": "0.0.0-experimental-4beb1fd8-20241118",
53
"ts-jest": "^29.1.1",
54
"ts-node": "^10.9.2",
55
- "zod": "^3.22.4",
56
- "zod-validation-error": "^2.1.0"
55
+ "zod": "^3.22.4 || ^4.0.0",
56
+ "zod-validation-error": "^3.0.3 || ^4.0.0"
57
},
58
"resolutions": {
59
"./**/@babel/parser": "7.7.4",
compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts
+8
-2
@@ -159,7 +159,7 @@ export const EnvironmentConfigSchema = z.object({
159
* A function that, given the name of a module, can optionally return a description
160
* of that module's type signature.
161
*/
162
- moduleTypeProvider: z.nullable(z.function().args(z.string())).default(null),
162
+ moduleTypeProvider: z.nullable(z.any()).default(null),
163
164
/**
165
* A list of functions which the application compiles as macros, where
@@ -249,7 +249,7 @@ export const EnvironmentConfigSchema = z.object({
249
* Allows specifying a function that can populate HIR with type information from
250
* Flow
251
*/
252
- flowTypeProvider: z.nullable(z.function().args(z.string())).default(null),
252
+ flowTypeProvider: z.nullable(z.any()).default(null),
253
254
/**
255
* Enables inference of optional dependency chains. Without this flag
@@ -906,6 +906,12 @@ export class Environment {
906
if (moduleTypeProvider == null) {
907
return null;
908
}
909
+ if (typeof moduleTypeProvider !== 'function') {
910
+ CompilerError.throwInvalidConfig({
911
+ reason: `Expected a function for \`moduleTypeProvider\``,
912
+ loc,
913
+ });
914
+ }
915
const unparsedModuleConfig = moduleTypeProvider(moduleName);
916
if (unparsedModuleConfig != null) {
917
const parsedModuleConfig = TypeSchema.safeParse(unparsedModuleConfig);
compiler/packages/babel-plugin-react-compiler/src/__tests__/envConfig-test.ts
+2
-2
@@ -20,7 +20,7 @@ describe('parseConfigPragma()', () => {
20
validateHooksUsage: 1,
21
} as any);
22
}).toThrowErrorMatchingInlineSnapshot(
23
- `"Error: Could not validate environment config. Update React Compiler config to fix the error. Validation error: Expected boolean, received number at "validateHooksUsage"."`,
23
+ `"Error: Could not validate environment config. Update React Compiler config to fix the error. Validation error: Invalid input: expected boolean, received number at "validateHooksUsage"."`,
24
);
25
});
26
@@ -38,7 +38,7 @@ describe('parseConfigPragma()', () => {
38
],
39
} as any);
40
}).toThrowErrorMatchingInlineSnapshot(
41
- `"Error: Could not validate environment config. Update React Compiler config to fix the error. Validation error: autodepsIndex must be > 0 at "inferEffectDependencies[0].autodepsIndex"."`,
41
+ `"Error: Could not validate environment config. Update React Compiler config to fix the error. Validation error: AutodepsIndex must be > 0 at "inferEffectDependencies[0].autodepsIndex"."`,
42
);
43
});
44
compiler/packages/eslint-plugin-react-compiler/package.json
+2
-2
@@ -15,8 +15,8 @@
15
"@babel/core": "^7.24.4",
16
"@babel/parser": "^7.24.4",
17
"hermes-parser": "^0.25.1",
18
- "zod": "^3.22.4",
19
- "zod-validation-error": "^3.0.3"
18
+ "zod": "^3.22.4 || ^4.0.0",
19
+ "zod-validation-error": "^3.0.3 || ^4.0.0"
20
},
21
"devDependencies": {
22
"@babel/preset-env": "^7.22.4",
compiler/packages/react-compiler-healthcheck/package.json
+2
-2
@@ -17,8 +17,8 @@
17
"fast-glob": "^3.3.2",
18
"ora": "5.4.1",
19
"yargs": "^17.7.2",
20
- "zod": "^3.22.4",
21
- "zod-validation-error": "^3.0.3"
20
+ "zod": "^3.22.4 || ^4.0.0",
21
+ "zod-validation-error": "^3.0.3 || ^4.0.0"
22
},
23
"devDependencies": {},
24
"engines": {
compiler/packages/react-mcp-server/package.json
+1
-1
@@ -24,7 +24,7 @@
24
"html-to-text": "^9.0.5",
25
"prettier": "^3.3.3",
26
"puppeteer": "^24.7.2",
27
- "zod": "^3.23.8"
27
+ "zod": "^3.22.4 || ^4.0.0"
28
},
29
"devDependencies": {
30
"@types/html-to-text": "^9.0.4",
compiler/yarn.lock
+12
-37
@@ -10486,16 +10486,7 @@ string-length@^4.0.1:
10486
char-regex "^1.0.2"
10487
strip-ansi "^6.0.0"
10488
10489
-"string-width-cjs@npm:string-width@^4.2.0":
10490
- version "4.2.3"
10491
- resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
10492
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
10493
- dependencies:
10494
- emoji-regex "^8.0.0"
10495
- is-fullwidth-code-point "^3.0.0"
10496
- strip-ansi "^6.0.1"
10497
-
10498
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
10489
+"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
10490
version "4.2.3"
10491
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
10492
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -10568,14 +10559,7 @@ string_decoder@~1.1.1:
10559
dependencies:
10560
safe-buffer "~5.1.0"
10561
10571
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
10572
- version "6.0.1"
10573
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
10574
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
10575
- dependencies:
10576
- ansi-regex "^5.0.1"
10577
-
10578
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
10562
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
10563
version "6.0.1"
10564
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
10565
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -11352,7 +11336,7 @@ workerpool@^6.5.1:
11336
resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz"
11337
integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==
11338
11355
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
11339
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
11340
version "7.0.0"
11341
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
11342
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -11370,15 +11354,6 @@ wrap-ansi@^6.2.0:
11354
string-width "^4.1.0"
11355
strip-ansi "^6.0.0"
11356
11373
-wrap-ansi@^7.0.0:
11374
- version "7.0.0"
11375
- resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
11376
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
11377
- dependencies:
11378
- ansi-styles "^4.0.0"
11379
- string-width "^4.1.0"
11380
- strip-ansi "^6.0.0"
11381
-
11357
wrap-ansi@^8.1.0:
11358
version "8.1.0"
11359
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz"
@@ -11530,17 +11505,17 @@ zod-to-json-schema@^3.24.1:
11505
resolved "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz"
11506
integrity sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==
11507
11533
-zod-validation-error@^2.1.0:
11534
- version "2.1.0"
11535
- resolved "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-2.1.0.tgz"
11536
- integrity sha512-VJh93e2wb4c3tWtGgTa0OF/dTt/zoPCPzXq4V11ZjxmEAFaPi/Zss1xIZdEB5RD8GD00U0/iVXgqkF77RV7pdQ==
11508
+"zod-validation-error@^3.0.3 || ^4.0.0":
11509
+ version "4.0.2"
11510
+ resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-4.0.2.tgz#bc605eba49ce0fcd598c127fee1c236be3f22918"
11511
+ integrity sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==
11512
11538
-zod-validation-error@^3.0.3:
11539
- version "3.0.3"
11540
- resolved "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.0.3.tgz"
11541
- integrity sha512-cETTrcMq3Ze58vhdR0zD37uJm/694I6mAxcf/ei5bl89cC++fBNxrC2z8lkFze/8hVMPwrbtrwXHR2LB50fpHw==
11513
+"zod@^3.22.4 || ^4.0.0":
11514
+ version "4.1.11"
11515
+ resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.11.tgz#4aab62f76cfd45e6c6166519ba31b2ea019f75f5"
11516
+ integrity sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==
11517
11543
-zod@^3.22.4, zod@^3.23.8, zod@^3.24.1:
11518
+zod@^3.23.8, zod@^3.24.1:
11519
version "3.24.3"
11520
resolved "https://registry.npmjs.org/zod/-/zod-3.24.3.tgz"
11521
integrity sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==
packages/eslint-plugin-react-hooks/package.json
+2
-2
@@ -41,8 +41,8 @@
41
"dependencies": {
42
"@babel/core": "^7.24.4",
43
"@babel/parser": "^7.24.4",
44
- "zod": "^3.22.4",
45
- "zod-validation-error": "^3.0.3"
44
+ "zod": "^3.22.4 || ^4.0.0",
45
+ "zod-validation-error": "^3.0.3 || ^4.0.0"
46
},
47
"devDependencies": {
48
"@babel/eslint-parser": "^7.11.4",