-
Notifications
You must be signed in to change notification settings - Fork 934
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
feat: finalize resolve() #447
Conversation
Hey thanks again for taking the time to dig into these hairier issues. I'd like to take a step back on this one and frame the problem we are trying to solve at a higher level. Right now you can't reasonably nest In terms of We would let people deal with that nuance themselves but I would consider users needing to think about In terms of implementation I'd love to make
Yeah this is annoying, and kinda a result of the overly generalized approach to schema implementation yup uses. I'd love to fix this, I'm just a bit concerned about the implementations I need to dig into how it affects |
quick specific thoughts:
|
I think nesting might help with reusability. And that
I agree, but i think that there is some inherit complexity and for advanced users, who use
Assuming that at path 'blah' you have lazy (which can return different types based on a value), i don't really know what do people expect when they do: reach(schema, 'blah', valueA, contextA).validate(valueB, {context: contextB}); Do they want to validate
Hm... i'm opposite. From a user perspective it is better not to finalise here since if
Yes and currently this is not supported. It can be implemented by addition of optional Note: Option: maybe a returned schema from |
Ideally i think this shouldn't be something they have to think about. again i think not finalizing in that case is the preferable one, it's not not terrible if we do (assuming ppl pas the same context both places which is the common case)
I think that would weird depending on the situation, but generally conditions are specific to a broader context, which would have changed if you use it elsewhere. e.g. the target location of the schema may not have the same parent structure or siblings. const Foo = object({
other: bool(),
name: string().when('other', { is: true, then: s => s.required() )
})
const Bar = object({
name: reach(Foo, 'name', options)
}) I think it would be confusing that name still depended on 'other' existing in the above
That may be a good direction, tho i'm not excited about the idea of schema being stateful in this way, it may end up complicating everything over all in terms of ease of use and understanding. I think it's fine to start with not resolving the final return value from |
I am for not resolving result. That would be a better solution, though a breaking one. Proposal for storing What about And for future: what about |
no, i'm fine with breaking changes as long as we preserve required use-cases.
Let's punt on that for right now. this is already inconsistent depending on if you call it after
Yeah it's for internal usage right now, which is why it's not documented. We can try and keep it private until it doesn't make sense anymore |
2ed8456
to
9f7d85e
Compare
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.
looking great 👍
f28d7fd
to
178eb5e
Compare
67d38d6
to
1cba3e9
Compare
9047a4f
to
189b082
Compare
189b082
to
d5f16b7
Compare
This PR allows safely nest
lazy
s andwhen
s in themselves and each other. (Asked in #335 for example)Currently there is a difference between calling
resolve()
onlazy
and onmixed
withwhen
s:lazy.resolve()
will return a schema not connected tolazy
instance. So callingresolve()
on a returned schema does not calllazy
body anymore.mixed.resolve()
will return a schema resulted byconcat
ing base schema and conditional one, as normixed.concat()
normixed.resolve()
remove initialwhen
conditions they are present in resulted schema and those conditions get called and merge their results on subsequentresolve
calls of merged schema.So, in a second case it is not a final resolve, but a partial one (resulted schema will contain conditions). For most cases it does not matter (though it cases unnecessary calls and may cause bugs for example with
reach
).Here all
resolve
s are made equal and expect to return a non-lazy schema without any conditions remaining. So callingresolve()
on a resulted schema will simply return it back. This also allows to make nested conditions and lazy to work without a problem.It is a breaking change though, since before
reach()
ed schema's withwhen
s where only partially resolved and expected to run those conditions again. This should be addressed. I think that there are three possible ways:Do not resolve
reach
ed schema. And if people need some methods which require resolved schema (likemeta()
) tell them aboutresolve()
. So makingresolve()
part of public api.Keep
reach
behaviour the same, but add new functiongetAt
(or something) which will return non resolved schema. And to tell people to use it now for most cases.Modify signature of
reach
, introduce flag for resolving or not. (Plus aparent
option, since it may be used in top levelresolve
call.) So maybe reach will becomereach(schema, {path, value, parent, context, resolve})
.(Personally i think first one is better, maybe third. Just suggestions.)
Half of proposal is to standardise
resolve()
behaviour and other half is to use created opportunity to nest things freely.(This also fixes #381 without #444, as now subsequent
resolve()
calls to do not cause repeats ofconcat
s)What do you think?