- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 40
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
[FEATURE] [v7] Support custom validation errors shape #98
Comments
Conform uses yet another format for the errors: https://conform.guide/api/zod/parseWithZod It would be nice to change the way schema is parsed so that it would be flexible for any case. |
next-safe-action v7 (currently next branch/channel) follows Zod's format() output to build validation errors, since it correctly handles validation for nested objects in schemas, see #51. I agree that in some cases it's better to just deal with a flattened error object, for instance when you don't need to use nested schemas. My idea is to export a Supposing we have defined this schema using Zod: import { z } from "zod";
const schema = z.object({
username: z.string().min(3).max(30),
email: z.string().email(),
age: z.number().positive(),
}); We can import import { flattenValidationErrors } from "next-safe-action";
const flattenedErrors = flattenValidationErrors(result.validationErrors);
type FlattenedErrors = {
formErrors: string[],
fieldErrors: {
username?: string[] | undefined,
email?: string[] | undefined,
age?: string[] | undefined,
}
} Please let me know your thoughts on this, thanks! |
It would be nice to have that directly in the action, so that it could be flexible and the frontend wouldn't need to do anything. const editProfile = authActionClient
.metadata({ actionName: "editProfile" })
.schema(z.object({ newUsername: z.string() }), (errors) => flattenValidationErrors(errors).fieldErrors)
.action(...); I believe the server action should be responsible for giving back the correct values, and thinking of supporting react aria and Another issue with the schema is i18n. If you use something like import { makeZodI18nMap } from "zod-i18n-map"
z.setErrorMap(makeZodI18nMap({ t })) My understanding is that this will be fixed with v7 because the middleware functions can be run before the schema function: const deleteUser = authActionClient
.use(async ({ next, ctx }) => {
z.setErrorMap(makeZodI18nMap({ t }))
return next({ ctx });
})
.metadata({ actionName: "deleteUser" })
.schema(z.void())
.action(...); If this is correct then the problem of the i18n of the schema is solved. |
Yeah, I agree, this is a good idea. As a default though, I think it's good to keep Zod's emulated
I'm not familiar with |
@TheEdoRan I thought that by using If the only purpose of the schema is typing, I believe it would be clearer to have the schema as a type instead of a value: const editProfile = authActionClient<SchemaXYZ>
.metadata({ actionName: "editProfile" })
.action(...) I still think it would be nice to have the validation done on the server automatically. |
It's not the schema that gets validated server side, it's the input data, thanks to the schema. What you pass to You can check out the relevant code here, for the |
@TheEdoRan got it! Thanks for explain it 🙏 If I understand correctly, in the recursive middleware function they only have access to the raw input, not to the validated input: https://github.com/TheEdoRan/next-safe-action/blob/next/packages/next-safe-action/src/index.ts#L110 I had a different model in my mind. I thought the sequence in the chained functions mattered, e.g.: const editProfile = authActionClient
.metadata({ actionName: "editProfile" })
.use(...) // <-- runs before schema and only has access to the raw input
.schema(...) // <-- input is validated and returns the validated input to continue the chain or returns errors to the client
.use(...) // <-- runs after schema validation and has access to the validated input
.action(...) From what I understand this is what really happens: const editProfile = authActionClient
.metadata({ actionName: "editProfile" })
.use(...) // <-- is put on a queue [0] to run before the schema validation
.schema(...) // <-- sets the schema to be run after the middleware queue
.use(...) // <-- is put on a queue [1] to run before the schema validation
.action(...) I feel this API can be misleading because of the chaining of functions, but maybe it's just me 😊 |
As arguments of middleware functions, yes, but they return a
You can't use
It works the same way as the tRPC middleware implementation, which I think is great (very composable, flexible and powerful). So:
|
next-safe-action now supports this feature in v7.0.0-next.21. Documentation for it is currently available here. |
Is there an existing issue for this?
Library version (optional)
No response
Ask a question
In React Aria Components the Form takes a flattened error list: https://react-spectrum.adobe.com/react-aria/forms.html#schema-validation
Any ideas on how to change the handling of validation errors from the library, instead of having to manipulate the result from the response?
Additional context
No response
The text was updated successfully, but these errors were encountered: