feat(Form): add superstruct validation (#2357)

This commit is contained in:
rizkyyy
2024-10-11 16:02:51 +07:00
committed by GitHub
parent 428ee44fc0
commit 3cda6c6478
5 changed files with 81 additions and 3 deletions

View File

@@ -13,6 +13,7 @@ import type { ObjectSchema as YupObjectSchema, ValidationError as YupError } fro
import type { BaseSchema as ValibotSchema30, BaseSchemaAsync as ValibotSchemaAsync30 } from 'valibot30'
import type { GenericSchema as ValibotSchema31, GenericSchemaAsync as ValibotSchemaAsync31, SafeParser as ValibotSafeParser31, SafeParserAsync as ValibotSafeParserAsync31 } from 'valibot31'
import type { GenericSchema as ValibotSchema, GenericSchemaAsync as ValibotSchemaAsync, SafeParser as ValibotSafeParser, SafeParserAsync as ValibotSafeParserAsync } from 'valibot'
import type { Struct } from 'superstruct'
import type { FormError, FormEvent, FormEventType, FormSubmitEvent, FormErrorEvent, Form } from '../../types/form'
import { useId } from '#imports'
@@ -35,7 +36,7 @@ export default defineComponent({
| PropType<ValibotSchema31 | ValibotSchemaAsync31>
| PropType<ValibotSafeParser31<any, any> | ValibotSafeParserAsync31<any, any>>
| PropType<ValibotSchema | ValibotSchemaAsync>
| PropType<ValibotSafeParser<any, any> | ValibotSafeParserAsync<any, any>>,
| PropType<ValibotSafeParser<any, any> | ValibotSafeParserAsync<any, any>> | PropType<Struct<any, any>>,
default: undefined
},
state: {
@@ -88,6 +89,8 @@ export default defineComponent({
errs = errs.concat(await getJoiErrors(props.state, props.schema))
} else if (isValibotSchema(props.schema)) {
errs = errs.concat(await getValibotError(props.state, props.schema))
} else if (isSuperStructSchema(props.schema)) {
errs = errs.concat(await getSuperStructErrors(props.state, props.schema))
} else {
throw new Error('Form validation failed: Unsupported form schema')
}
@@ -195,6 +198,15 @@ function isYupError (error: any): error is YupError {
return error.inner !== undefined
}
function isSuperStructSchema (schema: any): schema is Struct<any, any> {
return (
'schema' in schema &&
typeof schema.coercer === 'function' &&
typeof schema.validator === 'function' &&
typeof schema.refiner === 'function'
)
}
async function getYupErrors (
state: any,
schema: YupObjectSchema<any>
@@ -218,6 +230,18 @@ function isZodSchema (schema: any): schema is ZodSchema {
return schema.parse !== undefined
}
async function getSuperStructErrors (state: any, schema: Struct<any, any>): Promise<FormError[]> {
const [err] = schema.validate(state)
if (err) {
const errors = err.failures()
return errors.map((error) => ({
message: error.message,
path: error.path.join('.')
}))
}
return []
}
async function getZodErrors (
state: any,
schema: ZodSchema
@@ -259,6 +283,7 @@ async function getJoiErrors (
}
}
function isValibotSchema (schema: any): schema is ValibotSchema30 | ValibotSchemaAsync30 | ValibotSchema31 | ValibotSchemaAsync31 | ValibotSafeParser31<any, any> | ValibotSafeParserAsync31<any, any> | ValibotSchema | ValibotSchemaAsync | ValibotSafeParser<any, any> | ValibotSafeParserAsync<any, any> {
return '_parse' in schema || '_run' in schema || (typeof schema === 'function' && 'schema' in schema)
}