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

cant read multiple types in an array and cant have a property named "type" #52

Closed
StevieSeccombe1 opened this issue Nov 20, 2019 · 8 comments

Comments

@StevieSeccombe1
Copy link

schema-to-yup - v 1.9.14
yup - 0.27.0

I have a json schema with properties of type ["string, "null"] but it cant read this properly. How do I go about adding my own custom type handler for this?

I also have a property called "type" which it tries to use as the property's type. Is there a way of getting around this too?

thanks

@kristianmandrup
Copy link
Owner

kristianmandrup commented Nov 21, 2019

Please update to the latest version which has better support for these scenarios.

However, your concrete example (mixed multi type) is not currently supported out of the box.

You would need to either extend YupBuilder for propToYupSchemaEntry or pass in a custom factory function createYupSchemaEntry as part of the config object.

  createYupSchemaEntry({ schema, name, key, value, config }) {
    const yupEntry = config.createYupSchemaEntry({
      schema,
      name,
      key,
      value,
      config
    });
    return yupEntry; 
  }

In your case the value would then be["string, "null"] and you would have to take it from there...

The default function is

import { YupSchemaEntry } from "./entry";

function createYupSchemaEntry(opts = {}) {
  // const { schema, name, key, value, config } = opts;
  return new YupSchemaEntry(opts).toEntry();
}

So likely you would need to extend the class YupSchemaEntry defined in entry.js

The key method is toEntry

In particular I would extract out the part from line 61 into a function toSingleTypeEntry and then do:

  return this.toMultiTypeEntry() || this.toSingleTypeEntry() || this.toDefaultEntry()

and then implement toMultiTypeEntry as you see fit.

@kristianmandrup
Copy link
Owner

Would love to see a PR for that :)

@kristianmandrup
Copy link
Owner

kristianmandrup commented Nov 21, 2019

I've just started a multi-type branch you can play with and have a look at to get a better feel for it.

See custom entry builders docs

@kristianmandrup
Copy link
Owner

Could you please a PR with a failing spec that illustrates the problem:

"I also have a property called "type" which it tries to use as the property's type"

Thanks

@kristianmandrup
Copy link
Owner

I've added (failing) tests for the scenarios described.

@kristianmandrup
Copy link
Owner

In this case above it would result in a shape of string().nullable().

Otherwise you would have to use mixed() with some custom validation logic as far as I understand yup.

See also using yup test for custom validation logic

@kristianmandrup
Copy link
Owner

const createValueSchema = (value, schema = yup) => {
  if (value === 'string') {
    return schema.string()
  }
  if (value === 'null') {
    return schema.nullable()
  }
  return schema
}

let constraintListValue = ['string', 'null']
let schema = yup.mixed().test({
  name,
  exclusive: true,
  params: {},
  message: '${path} must be less than ${max} characters',
  test: value => {
      const schema = constraintListValue.reduce((accSchema, constraintValue) => {
        return createValueSchema(constraintValue, accSchema)
    }, null)
    return schema.validateSync(value)
  }
});

@kristianmandrup
Copy link
Owner

Latest commit includes better support for this and some better implementation suggestions for how to achieve this

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

No branches or pull requests

2 participants