zod-v3-to-v4 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/migrate.js +5 -1
- package/dist/replace-deleted-types.js +75 -0
- package/package.json +1 -1
package/dist/migrate.js
CHANGED
|
@@ -3,6 +3,7 @@ import { findRootExpression } from "./ast.js";
|
|
|
3
3
|
import { collectZodImportDeclarations, collectZodReferences, getZodName, } from "./collect-imports.js";
|
|
4
4
|
import { convertZArrayPatternsToTopLevelApi, convertZCoercePatternsToTopLevelApi, convertZFunctionPatternsToTopLevelApi, convertZNumberPatternsToZInt, convertZObjectPatternsToTopLevelApi, convertZRecordPatternsToTopLevelApi, convertZStringPatternsToTopLevelApi, } from "./convert-name-to-top-level-api.js";
|
|
5
5
|
import { convertDeprecatedErrorKeysToErrorFunction, convertErrorMapToErrorFunction, convertMessageKeyToError, convertZodErrorAddIssueToDirectPushes, convertZodErrorToTreeifyError, } from "./convert-zod-errors.js";
|
|
6
|
+
import { replaceDeletedTypes } from "./replace-deleted-types.js";
|
|
6
7
|
import { isZodNode } from "./zod-node.js";
|
|
7
8
|
export function migrateZodV3ToV4(sourceFile, options = {}) {
|
|
8
9
|
const importDeclarations = collectZodImportDeclarations(sourceFile);
|
|
@@ -17,7 +18,10 @@ export function migrateZodV3ToV4(sourceFile, options = {}) {
|
|
|
17
18
|
declaration.setModuleSpecifier("zod/v4");
|
|
18
19
|
}
|
|
19
20
|
});
|
|
20
|
-
|
|
21
|
+
// Collect references before modifying imports
|
|
22
|
+
const zodReferences = collectZodReferences(importDeclarations);
|
|
23
|
+
replaceDeletedTypes(importDeclarations, zodReferences);
|
|
24
|
+
zodReferences.forEach((node) => {
|
|
21
25
|
if (node.wasForgotten()) {
|
|
22
26
|
return;
|
|
23
27
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { SyntaxKind } from "ts-morph";
|
|
2
|
+
const DELETED_TYPES = [
|
|
3
|
+
{
|
|
4
|
+
name: "AnyZodObject",
|
|
5
|
+
importName: "ZodRecord",
|
|
6
|
+
getReplacement: () => "ZodRecord<any, any>",
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
name: "SafeParseReturnType",
|
|
10
|
+
importName: "ZodSafeParseResult",
|
|
11
|
+
getReplacement: (node) => {
|
|
12
|
+
// SafeParseReturnType<I, O> -> ZodSafeParseResult<O>
|
|
13
|
+
// Keep only the second type argument for consistency
|
|
14
|
+
// See https://github.com/colinhacks/zod/issues/5195
|
|
15
|
+
const typeRef = node.getFirstAncestorByKind(SyntaxKind.TypeReference);
|
|
16
|
+
const secondArg = typeRef?.getTypeArguments()?.[1];
|
|
17
|
+
return secondArg
|
|
18
|
+
? `ZodSafeParseResult<${secondArg.getText()}>`
|
|
19
|
+
: "ZodSafeParseResult<unknown>";
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: "ZodTypeAny",
|
|
24
|
+
importName: "ZodType",
|
|
25
|
+
getReplacement: () => "ZodType",
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
export function replaceDeletedTypes(importDeclarations, zodReferences) {
|
|
29
|
+
// Update imports: remove deleted types and add replacements
|
|
30
|
+
importDeclarations.forEach((declaration) => {
|
|
31
|
+
for (const { name, importName } of DELETED_TYPES) {
|
|
32
|
+
const namedImports = declaration.getNamedImports();
|
|
33
|
+
const deletedImport = namedImports.find((i) => i.getName() === name);
|
|
34
|
+
if (deletedImport) {
|
|
35
|
+
const hasReplacementImport = namedImports.some((i) => i.getName() === importName);
|
|
36
|
+
deletedImport.remove();
|
|
37
|
+
if (!hasReplacementImport) {
|
|
38
|
+
declaration.addNamedImport(importName);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
// Replace references in code
|
|
44
|
+
zodReferences.forEach((node) => {
|
|
45
|
+
if (node.wasForgotten()) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
for (const { name, importName, getReplacement } of DELETED_TYPES) {
|
|
49
|
+
// Handle direct imports (e.g., `import { AnyZodObject }`)
|
|
50
|
+
if (node.getText() === name) {
|
|
51
|
+
const typeRef = node.getFirstAncestorByKind(SyntaxKind.TypeReference);
|
|
52
|
+
if (typeRef) {
|
|
53
|
+
typeRef.replaceWithText(getReplacement(node));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
node.replaceWithText(getReplacement(node));
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Handle prefixed access (e.g., `z.AnyZodObject`)
|
|
61
|
+
const qualifiedName = node.getFirstAncestorByKind(SyntaxKind.QualifiedName);
|
|
62
|
+
if (qualifiedName?.getText().endsWith(`.${name}`)) {
|
|
63
|
+
const typeRef = qualifiedName.getFirstAncestorByKind(SyntaxKind.TypeReference);
|
|
64
|
+
const zodPrefix = node.getText();
|
|
65
|
+
if (typeRef) {
|
|
66
|
+
typeRef.replaceWithText(`${zodPrefix}.${getReplacement(node)}`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
qualifiedName.replaceWithText(`${zodPrefix}.${importName}`);
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|