GithubHelp home page GithubHelp logo

Comments (14)

t-rosa avatar t-rosa commented on July 16, 2024 2

Maaaybe this? (Sorry, it's not very clean and I'm not sure at all)

import { safeParse, safeParseAsync } from 'valibot'
import type { BaseIssue, BaseSchema, BaseSchemaAsync } from 'valibot'
import type { Validator } from '@tanstack/form-core'

type Params = {
  errorMap?: (
    errors: [BaseIssue<unknown>, ...BaseIssue<unknown>[]],
  ) => BaseIssue<unknown>
}
type validateValue = { value: unknown }
type validateFn =
  | BaseSchema<unknown, unknown, BaseIssue<unknown>>
  | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>

export const valibotValidator = ((params: Params = {}) => {
  return {
    validate({ value }: validateValue, fn: validateFn) {
      if (fn.async) return
      const result = safeParse(fn, value)
      if (result.success) return
      if (params.errorMap) {
        return params.errorMap(result.issues)
      }
      return result.issues.map((i) => i.message).join(', ')
    },
    async validateAsync({ value }: validateValue, fn: validateFn) {
      const result = await safeParseAsync(fn, value)
      if (result.success) return
      if (params.errorMap) {
        return params.errorMap(result.issues)
      }
      return result.issues.map((i) => i.message).join(', ')
    },
  }
}) as Validator<
  unknown,
  | BaseSchema<unknown, unknown, BaseIssue<unknown>>
  | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>
> &
  ((
    params: Params,
  ) => Validator<
    unknown,
    | BaseSchema<unknown, unknown, BaseIssue<unknown>>
    | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>
  >)

from form.

t-rosa avatar t-rosa commented on July 16, 2024 1

I quickly passed by here and was seeing something like this, it probably doesn't work and I don't have time to test/research in depth but maybe it will help:

import { safeParse, safeParseAsync } from 'valibot'
import type { BaseIssue, BaseSchema, BaseSchemaAsync } from 'valibot'
import type { Validator } from '@tanstack/form-core'

type Params = {
  errorMap?: (
    errors: [BaseIssue<unknown>, ...BaseIssue<unknown>[]],
  ) => BaseIssue<unknown>
}

export const valibotValidator = (params: Params) =>
  (() => {
    return {
      validate({ value }, fn) {
        if (fn.async) return
        const result = safeParse(fn, value)
        if (result.success) return
        if (params.errorMap) {
          return params.errorMap(result.issues)
        }
        return result.issues.map((i) => i.message).join(', ')
      },
      async validateAsync({ value }, fn) {
        const result = await safeParseAsync(fn, value)
        if (result.success) return
        if (params.errorMap) {
          return params.errorMap(result.issues)
        }
        return result.issues.map((i) => i.message).join(', ')
      },
    }
  }) as Validator<
    unknown,
    | BaseSchema<unknown, unknown, BaseIssue<unknown>>
    | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>
  >

from form.

t-rosa avatar t-rosa commented on July 16, 2024 1

I'm sorry for my slow understanding.

The current type of validatorAdapter:

export type Validator<Type, Fn = unknown> = () => {
    validate(options: {
        value: Type;
    }, fn: Fn): ValidationError;
    validateAsync(options: {
        value: Type;
    }, fn: Fn): Promise<ValidationError>;
};

But if i use valibotValidator like this with @t-rosa 's code

 validatorAdapter: valibotValidator({ errorMap: (errors) => errors[0] }),

valibotValidator return just

 {
    validate({ value }: validateValue, fn: validateFn) {
      if (fn.async) return
      const result = safeParse(fn, value)
      if (result.success) return
      if (params.errorMap) {
        return params.errorMap(result.issues)
      }
      return result.issues.map((i) => i.message).join(', ')
    },
    async validateAsync({ value }: validateValue, fn: validateFn) {
      const result = await safeParseAsync(fn, value)
      if (result.success) return
      if (params.errorMap) {
        return params.errorMap(result.issues)
      }
      return result.issues.map((i) => i.message).join(', ')
    },
  }

Not function, just object.

So the types don't match. How can this be solved?

Yes, you're right.

I think we should use the first version, even if it's a mini breaking change. as crutchcorn said it shouldn't be a problem :)

So this one maybe the best option:

import { safeParse, safeParseAsync } from 'valibot'
import type { BaseIssue, BaseSchema, BaseSchemaAsync } from 'valibot'
import type { Validator } from '@tanstack/form-core'

type Params = {
  errorMap?: (
    errors: [BaseIssue<unknown>, ...BaseIssue<unknown>[]],
  ) => BaseIssue<unknown>
}

export const valibotValidator = (params: Params = {}) =>
  (() => {
    return {
      validate({ value }, fn) {
        if (fn.async) return
        const result = safeParse(fn, value)
        if (result.success) return
        if (params.errorMap) {
          return params.errorMap(result.issues)
        }
        return result.issues.map((i) => i.message).join(', ')
      },
      async validateAsync({ value }, fn) {
        const result = await safeParseAsync(fn, value)
        if (result.success) return
        if (params.errorMap) {
          return params.errorMap(result.issues)
        }
        return result.issues.map((i) => i.message).join(', ')
      },
    }
  }) as Validator<
    unknown,
    | BaseSchema<unknown, unknown, BaseIssue<unknown>>
    | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>
  >

from form.

crutchcorn avatar crutchcorn commented on July 16, 2024

This should be done at the validator level where you can pass transformErrors to transformErrors: errors => errors[0] rather than transformErrors: errors => errors.join(', ')

Will mark this as "Good first issue" and a feature request

from form.

seobbang avatar seobbang commented on July 16, 2024

@crutchcorn Hello, can I work on this issue? If possible, please assign it to me. 😊

from form.

jessekelly881 avatar jessekelly881 commented on July 16, 2024

Not sure if this is relevant to this issue or if I should create a separate one but being able to return an array from

validators={{
    onChange: ["err1", "err2"] // string | string[]
}}

instead of having to return a single .join("\n")ed string would be a very nice addition as well.

from form.

crutchcorn avatar crutchcorn commented on July 16, 2024

@jessekelly881 let's open a different issue on it :)

@seobbang PRs welcome! No need to assign it out, but do feel free to tackle the issue :)

from form.

TheKnightCoder avatar TheKnightCoder commented on July 16, 2024

Would love this fixed @seobbang did you manage to work on this?

from form.

seobbang avatar seobbang commented on July 16, 2024

@TheKnightCoder I'm going to try again 🤗

from form.

ha1fstack avatar ha1fstack commented on July 16, 2024

It would be nice to accept ValidatonError[] as return value for FieldValidateOrFn since there could be some cases when we want all errors to be shown from a single validation.
For example, when setting password we may want to show multiple errors under the input like 'length should be longer than 8', 'should contain special characters', ...

from form.

seobbang avatar seobbang commented on July 16, 2024

@t-rosa @crutchcorn
I have a question.

According to what you(@t-rosa ) suggested, when valibotValidator is used in useForm it can be used like:

validatorAdapter: valibotValidator({errorMap: errors => errors[0]}),

But the problem is that even if I want to use the default value, I have to use it with function call:

validatorAdapter: valibotValidator(),

But because we've been used like:

validatorAdapter: valibotValidator,

it's going to be a problem for people who are already using this validator.

So, should I make another validator, for example, valibotValidatorWithOption`?
Please tell me if I'm wrong or if there's any other way.

Thank you for your help

from form.

crutchcorn avatar crutchcorn commented on July 16, 2024

@t-rosa this looks awesome! Let's move forward with it in a PR :)

@seobbang this WILL be a breaking change, but a very minor one. We're prior to 1.0 so that shouldn't be a problem

from form.

seobbang avatar seobbang commented on July 16, 2024

I'm sorry for my slow understanding.

The current type of validatorAdapter:

export type Validator<Type, Fn = unknown> = () => {
    validate(options: {
        value: Type;
    }, fn: Fn): ValidationError;
    validateAsync(options: {
        value: Type;
    }, fn: Fn): Promise<ValidationError>;
};

But if i use valibotValidator like this with @t-rosa 's code

 validatorAdapter: valibotValidator({ errorMap: (errors) => errors[0] }),

valibotValidator return just

 {
    validate({ value }: validateValue, fn: validateFn) {
      if (fn.async) return
      const result = safeParse(fn, value)
      if (result.success) return
      if (params.errorMap) {
        return params.errorMap(result.issues)
      }
      return result.issues.map((i) => i.message).join(', ')
    },
    async validateAsync({ value }: validateValue, fn: validateFn) {
      const result = await safeParseAsync(fn, value)
      if (result.success) return
      if (params.errorMap) {
        return params.errorMap(result.issues)
      }
      return result.issues.map((i) => i.message).join(', ')
    },
  }

Not function, just object.

So the types don't match.
How can this be solved?

from form.

t-rosa avatar t-rosa commented on July 16, 2024

It should be ok for valibot, the PR is open, we should be able to do the same for the other validators

from form.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.