kristianmandrup / schema-to-yup

Schema to Yup validation

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to order errors?

cloudever opened this issue · comments

It would be nice to first create required errors and then others like maxlength

Found solution like below

YupBuilder.prototype.normalizeRequired = function normalizeRequired() {
  const properties = {
    ...this.properties,
  }
  const required = [...this.required] || []
  const propKeys = Object.keys(properties)
  return propKeys.reduce((acc, key) => {
    const value = properties[key]
    const isRequired = required.indexOf(key) >= 0
    if (isObjectType(value)) {
      value.required = this.isRequired(value) || isRequired
    } else {
      this.warn(`Bad value: ${value} must be an object`)
    }

    // LOOK THERE 
    acc[key] = {
      required: value.required,
      ...value,
    }
    return acc
  }, {})
}

Or is there any other elegant solution?

Interesting. The normal "solution" would be to subclass the YupBuilder class and then override normalizeRequired.
Would be even better to rename normalizeRequired to normalizeProperties or simply buildProperties and allow this function to be passed in on the config object perhaps https://github.com/kristianmandrup/schema-to-yup/blob/master/src/yup-builder.js#L54

const buildProperties = (config.buildProperties || this.buildProperties).bind(this)
const properties = buildProperties(schema, this);
  buildProperties() {
    const properties = {
      ...this.properties
    };
    const required = [...this.required] || [];
    const propKeys = Object.keys(properties);
    const buildProp = (config.buildProp || this.buildProp).bind(this)
    return propKeys.reduce(buildProp, {});
  }

  buildProp(propObj, key) {
      const value = properties[key];
      const isRequired = required.indexOf(key) >= 0;
      if (isObjectType(value)) {
        value.required = this.isRequired(value) || isRequired;
      } else {
        this.warn(`Bad value: ${value} must be an object`);
      }
      const setPropEntry = (config.setPropEntry || this.setPropEntry).bind(this)
      setPropEntry(propObj, key, value)
      return propObj;
  }

  setPropEntry(propObj, key, value) {
    propObj[key] = {
      required: value.required,
      ...value,
    }
  }

Much more elegant design. Would love to see a PR for this ;)

I've made the changes above and published it to version 1.11.6. Have also improved the Readme significantly on how to customize, see https://github.com/kristianmandrup/schema-to-yup#custom-builder