-
-
Notifications
You must be signed in to change notification settings - Fork 45
Migrate zod v3 to v4 #269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Migrate zod v3 to v4 #269
Conversation
|
|
||
| switch (issue.code) { | ||
| case 'invalid_enum_value': | ||
| case 'invalid_value': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
z.ZodInvalidEnumValueIssue has merged with ZodIssueInvalidValue
| valid = issue.options; | ||
| valid = issue.values; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.values contains the list of acceptable literals in the case of validating against an enum.
| case 'invalid_string': | ||
| case 'invalid_format': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
z.ZodInvalidStringIssue was renamed to ZodIssueInvalidStringFormat.
| interface: 'toggle', | ||
| width: 'half', | ||
| note: 'Hide the current user\'s avatar from collaborative editing indicators', | ||
| note: "Hide the current user's avatar from collaborative editing indicators", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the result of manually running prettier. I noticed eslint and prettier don't automatically run, but I didn't make any changes there to keep this PR simple and easy to review. I could hook it up in a separate PR.
| "vue-router": "4.5.0" | ||
| "vue-i18n": "11.1.1", | ||
| "vue-router": "4.5.0", | ||
| "zod": "^4.0.14" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4.0.14 is the exact version @directus/api, @directus/extensions, and @directus/extensions-registry currently use. If they update, as long as it is a pathc or minor update, the extension will install without errors.
| thumbnailField: z.string().optional().nullable(), | ||
| fields: z.array(z.string().min(1, 'field name cannot be empty')), | ||
| filter: z.object({}).optional().nullable() as z.ZodType<Filter | undefined>, | ||
| filter: z.object({}).optional().nullable() as z.ZodNullable<z.ZodOptional<z.ZodType<Filter>>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not directly related to the upgrade, but it was causing a type error insystem-colelctions.ts, requiring it explicitly set the filter field to undefined.
| collections: z.array(SearchCollection), | ||
| triggerRate: z.number().gte(0, 'greater than or equal to 0').optional(), | ||
| commandPaletteEnabled: z.boolean().optional().default(true), | ||
| recentSearchLimit: z.number().gte(0, 'greater than or equal to 0').optional(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This field is used by useRecentCommands() to control how many recent commands are shown at most. Was not present in the schema before.
| }, | ||
| "scripts": { | ||
| "build": "directus-extension build", | ||
| "check": "vue-tsc --noEmit", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used vue-tsc to check for any type errors during migrations as some interfaces were authored inside vue modules. There are several unrelated type errors, so this command is not automatically run in CI, though I think it eventually should. I could open a PR for it separately.
| "compilerOptions": { | ||
| "target": "ES2019", | ||
| "lib": ["ES2019", "DOM"], | ||
| "lib": ["ES2021", "DOM"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The extension included uses of String#replaceAll() which is an ES2021 feature.
| "lib": ["ES2021", "DOM"], | ||
| "rootDir": "./src", | ||
| "moduleResolution": "node", | ||
| "moduleResolution": "bundler", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"node" (renamed to "node10" then removed from recent versions of typescript) module resolution does not pick up on ESM packages, which some Directus packages from the main repo have upgraded to. "node16" is an alternative that disallows extension-less imports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR migrates the codebase from Zod v3 to v4 to maintain compatibility with Directus 11.10.2+, which upgraded to Zod v4. The migration addresses breaking API changes in Zod v4's validation schema structure and error handling.
Key Changes:
- Updated Zod API calls to match v4 syntax (
invalid_enum_value→invalid_value,errorMap→error, etc.) - Moved Zod from dependencies to peerDependencies to ensure version compatibility with Directus
- Updated TypeScript configuration to support Zod v4's module resolution requirements
Reviewed Changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/command-palette-module/tsconfig.json | Updated lib and moduleResolution for Zod v4 compatibility |
| packages/command-palette-module/src/utils/errors.ts | Migrated error handling from v3 (invalid_enum_value, options) to v4 (invalid_value, values) |
| packages/command-palette-module/src/types.ts | Updated Zod schema syntax: errorMap → error, type casting for nullable/optional, added recentSearchLimit |
| packages/command-palette-module/package.json | Moved zod to peerDependencies, added vue-tsc for type checking |
| packages/collaborative-editing/src/module/utils/errors.ts | Migrated error handling to Zod v4 API |
| packages/collaborative-editing/src/module/settings-fields.ts | Fixed quote escaping in string |
| packages/collaborative-editing/package.json | Moved zod to devDependencies, reordered dependencies alphabetically |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
pnpm packinside a docker container.zodto peer dependencies to make package managers perform a compatibilty check with Directus.Before
docker runAfter (see "Loaded extensions")
docker run