-
Notifications
You must be signed in to change notification settings - Fork 8
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
Addition of refine
and/or superRefine
methods
#70
Comments
refine
and/or superRefine
methods
Hey! We have the building blocks for something like this. In fact you can already create errors in a raw way by doing: // inside a preTransform, test or anything really you get access to z.Ctx or z.ParseCtx (depricated)
// method interface = NewError(internals.PathBuilder path, e z.ZogError)
ctx.NewError(pathbuilder, e) But pathbuilder type is inside the zog internals, and helper functions for creating zogErrors mostly depend on a test. So I don't recommend using any of it as it will most likely change. Regarding the user facing API, I'm interested on how you would like it. Currently we have opted for "Tests" as the names rather than This is the current API (which is not very well documented now that I look at it, we should have a page on the docs that goes over custom tests):
However, non of the current options handle adding errors in custom paths. You can do it by doing it manually but it would be a mess and you would get duplicate errors. I think the key features that we are missing at the moment are:
I'm interested in your thoughts on what you would like the API to look like for all of this. Here are some half baked ideas on my end: // Path option for errors?
schema := z.Struct(z.Schema{
"hidden": z.String().Required(z.Path("shown")),
"shown": z.String(),
})
errs := schema.Validate(&data)
/*
errs =
{
"shown": ["field is required"]
}
*/
// Optional Second argument on message for error path:
schema := z.Struct(z.Schema{
"hidden": z.String().Required(z.Message("hidden is required", "shown")),
"shown": z.String(),
})
errs := schema.Validate(&data)
/*
errs =
{
"shown": ["hidden is required"]
}
*/
// Super refine = z.Test + manual flag?
// you would still need to return a bool so APi is a little clunky
z.String().Test(z.Test{
ValidateFunc: func (val any, ctx z.Ctx) bool {
},
ManualErrors: true,
}) I'm not sure about the API for creating errors. Zog keeps a lot of info on the error struct. So it can be a little annoying to create them. type ZogError interface {
// returns the error code for the error. This is a unique identifier for the error. Generally also the ID for the Test that caused the error.
Code() zconst.ZogErrCode
// returns the data value that caused the error.
// if using Schema.Parse(data, dest) then this will be the value of data.
Value() any
// Returns destination type. i.e The zconst.ZogType of the value that was validated.
// if Using Schema.Parse(data, dest) then this will be the type of dest.
Dtype() string
// returns the params map for the error. Taken from the Test that caused the error. This may be nil if Test has no params.
Params() map[string]any
// returns the human readable, user-friendly message for the error. This is safe to expose to the user.
Message() string
// returns the wrapped error or nil if none
Unwrap() error
} These are the methods that Zog uses to create errors, let me know if you like these APIs or would prefer something different and why: // Helper struct for dealing with zog errors. Beware this API may change
var Errors = errHelpers{}
// Create error from (originValue any, destinationValue any, test *p.Test)
func (e *errHelpers) FromTest(o any, destType zconst.ZogType, t *p.Test, p ParseCtx)
func (e *errHelpers) FromErr(o any, destType zconst.ZogType, err error)
func (e *errHelpers) WrapUnknown(o any, destType zconst.ZogType, err error) p.ZogError
func (e *errHelpers) New(code zconst.ZogErrCode, o any, destType zconst.ZogType, params map[string]any, msg string, err error) p.ZogError |
Zod has a
refine
method that lets you provide custom validation logic or apply additional validation rules to a schema. One use case of this is checking if two fields match. Below is a code snippet of how to check if passwords match in zod.This example allows for asynchronous validation
superRefine
on the other hand is suitable for managing complex validation rules. It can perform multiple validation checks and provides detailed error handling. For example, you might use it to validate both an email address and a username during a user registration process.The text was updated successfully, but these errors were encountered: