Skip to content
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: add schema.asContext and array.indexContextKey #1872

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

danielpza
Copy link

This is a proof of concept to give more access in the schema to the parent/any element in the schema. Adds two new methods:

  • schema.asContext

Adds the whole value as a context, this allows to access any random property of the schema from any node or sub property.

Eg

let schema = object()
  .asContext('root')
  .shape({
    foo: number(),
    inner: object({
      bar: number().moreThan(ref('$root.foo')),
    }),
  });

schema.isValid({ foo: 3, inner: { bar: 5 } }); // true
schema.isValid({ foo: 3, inner: { bar: 2 } }); // false
  • array.indexContextKey

Adds the current element index as a context value, this is useful when comparing the element to previous elements in the array

Eg to make sure array is sorted

const schema = array()
  .asContext('root')
  .indexContextKey('idx')
  .of(
    number().when(['$root', '$idx'], ([root, idx], schema) =>
      idx > 0 ? schema.moreThan(root[idx - 1]) : schema,
    ),
  );

schema.isValid([1, 2, 3]); // true
schema.isValid([1, 3, 2]); // false

@danielpza
Copy link
Author

Hello @jquense, hope all is good.

Please let me know what you think about this approach.

Cheers

@jquense
Copy link
Owner

jquense commented Jan 13, 2023

Hey @danielpza this is cool! I think API wise though it feels like it's more complicated than it needs to be? Ultimately this API is solving the problem of not being able to reference ancestors with plain paths right? Maybe we should just solve that problem instead of adding an alternative API? W/D/T?

@danielpza
Copy link
Author

Hey @jquense thanks for your response.

Ultimately this API is solving the problem of not being able to reference ancestors with plain paths right?

yes, this is mainly the issue I was trying to solve but leaving it more open to solve other problems (eg accessing ancestors/cousins, but thats not my main goal)

Maybe we should just solve that problem instead of adding an alternative API?

That would be good, ideally whatever solution we end up with we can use it together with other yup ecosystem (other schemas validation, yup.ref, etc).

Do you have any ideas on alternatives implementation? Has there been any proposed solutions in the past?

@jquense
Copy link
Owner

jquense commented Jan 14, 2023

Do you have any ideas on alternatives implementation? Has there been any proposed solutions in the past?

we added the from property to the test context a while ago that should have all the ancestors we just never made refs/conditions work with it if you want to explore that

@danielpza
Copy link
Author

we added the from property to the test context a while ago that should have all the ancestors we just never made refs/conditions work with it if you want to explore that

we tried the from property but found it not very intuitive

  • is there a way to access the index of the current element in the array?
  • some schemas like { arr: [{ nestedprop: number }] } can get very verbose using the from properties
  • is it possible to use yup schemas validations with from? eg using number.min like:
number().when(['$root', '$idx'], ([root, idx], schema) =>
      idx > 0 ? schema.moreThan(root[idx - 1]) : schema,
    ),

@jquense
Copy link
Owner

jquense commented Jan 16, 2023

we tried the from property but found it not very intuitive

Yes thats what i'm suggesting changing, from isn't intended as the "api" for this this, it's just the plumbing to enable better APIs, e.g string().when('../.../parent')

is it possible to use yup schemas validations with from? eg using number.min like:

Not at the moment, but it could be via refs

is there a way to access the index of the current element in the array?

I think this is a distinct and separate feature from accessing root properties, I would like to consider it separately if that's ok

@danielpza
Copy link
Author

I think this is a distinct and separate feature from accessing root properties, I would like to consider it separately if that's ok

Makes sense, I'll separate the indexContextKey property into another PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants