From ce7ef761820a71265934c77e5a4b8404e9ca6bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 4 Sep 2024 00:09:45 +0200 Subject: [PATCH] makeSchemaFormValidator --- bun.lockb | Bin 103366 -> 104113 bytes package.json | 1 + .../TanStackForm/makeSchemaFormValidator.ts | 138 ++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 src/Schema/TanStackForm/makeSchemaFormValidator.ts diff --git a/bun.lockb b/bun.lockb index 4ef05ddd59066eb842acdbc439ff15ea13c01c3d..22706bc996ac2568b292fd7a9aaeffed48e21e27 100755 GIT binary patch delta 15290 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 delta 14926 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 K&@6V+@4o;pR0h2O diff --git a/package.json b/package.json index cdf297a..2adc4f6 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "devDependencies": { "@effect/schema": "^0.72.0", "@prisma/studio-server": "^0.502.0", + "@tanstack/form-core": "^0.30.0", "@types/jsonwebtoken": "^9.0.6", "bun-types": "^1.1.26", "effect": "^3.7.0", diff --git a/src/Schema/TanStackForm/makeSchemaFormValidator.ts b/src/Schema/TanStackForm/makeSchemaFormValidator.ts new file mode 100644 index 0000000..4349e3a --- /dev/null +++ b/src/Schema/TanStackForm/makeSchemaFormValidator.ts @@ -0,0 +1,138 @@ +import { ArrayFormatter, Schema } from "@effect/schema" +import type { ParseOptions } from "@effect/schema/AST" +import type { DeepKeys, DeepValue, FieldApi, FormApi, FormValidationError, ValidationError, Validator } from "@tanstack/react-form" +import { Array, Effect, Either, flow, Layer, ManagedRuntime, pipe } from "effect" +import { mapValues } from "remeda" + + +export const makeSchemaFormValidator = ( + schema: Schema.Schema, + options?: ParseOptions, +) => { + const decodeEither = Schema.decodeEither(schema, options) + + return < + TFormData extends I, + TFormValidator extends Validator | undefined, + >(props: { + value: TFormData + formApi: FormApi + }): FormValidationError => + decodeEither(props.value).pipe(result => + Either.isLeft(result) + ? { + form: "Please check the fields", + fields: issuesToFieldsRecord(ArrayFormatter.formatErrorSync(result.left), props.formApi) as any, + } + : null + ) +} + +export const makeSchemaAsyncFormValidator = ( + schema: Schema.Schema, + options?: ParseOptions, +) => { + const runtime = ManagedRuntime.make(Layer.empty) + const decode = Schema.decode(schema, options) + + return < + TFormData extends I, + TFormValidator extends Validator | undefined, + >(props: { + value: TFormData + formApi: FormApi + signal: AbortSignal + }): Promise> => + decode(props.value).pipe( + Effect.matchEffect({ + onSuccess: () => Effect.succeed(null), + + onFailure: e => ArrayFormatter.formatError(e).pipe( + Effect.map(issues => ({ + form: "Please check the fields", + fields: issuesToFieldsRecord(issues, props.formApi) as any, + })) + ), + }), + + prgm => runtime.runPromise(prgm, { signal: props.signal }), + ) +} + +/** + * TODO: handle nested array fields + */ +const issuesToFieldsRecord = < + TFormData, + TFormValidator extends Validator | undefined = undefined, +>( + issues: readonly ArrayFormatter.Issue[], + _formApi: FormApi, +) => pipe(issues, + Array.groupBy(issue => issue.path.join(".")), + + mapValues(flow( + Array.map(issue => issue.message), + Array.join("\n"), + )), +) + + +export const makeSchemaFieldValidator = ( + schema: Schema.Schema, + options?: ParseOptions, +) => { + const decodeEither = Schema.decodeEither(schema, options) + + return < + TParentData, + TName extends DeepKeys, + TFieldValidator extends Validator, unknown> | undefined, + TFormValidator extends Validator | undefined, + TData extends I & DeepValue, + >(props: { + value: TData + fieldApi: FieldApi + }): ValidationError => + decodeEither(props.value).pipe(result => + Either.isLeft(result) + ? ArrayFormatter.formatErrorSync(result.left) + .map(issue => issue.message) + .join("\n") + : null + ) +} + +export const makeSchemaAsyncFieldValidator = ( + schema: Schema.Schema, + options?: ParseOptions, +) => { + const runtime = ManagedRuntime.make(Layer.empty) + const decode = Schema.decode(schema, options) + + return < + TParentData, + TName extends DeepKeys, + TFieldValidator extends Validator, unknown> | undefined, + TFormValidator extends Validator | undefined, + TData extends I & DeepValue, + >(props: { + value: TData + fieldApi: FieldApi + signal: AbortSignal + }): Promise => + decode(props.value).pipe( + Effect.matchEffect({ + onSuccess: () => Effect.succeed(null), + + onFailure: e => ArrayFormatter.formatError(e).pipe( + Effect.map(flow( + Array.map(issue => issue.message), + Array.join("\n"), + )) + ), + }), + + prgm => runtime.runPromise(prgm, { signal: props.signal }), + ) +}