Giter Club home page Giter Club logo

zod-formik-adapter's Introduction

zod-formik-adapter

codecov

This library adapts a zod schema to work as a validationSchema prop or validate prop on Formik

Install

# npm
$ npm install zod-formik-adapter

# yarn
$ yarn add zod-formik-adapter

Usage

import { z } from 'zod';
import { Formik } from 'formik';
import { toFormikValidationSchema } from 'zod-formik-adapter';

const Schema = z.object({
  name: z.string(),
  age: z.number(),
});

const Component = () => (
  <Formik
    validationSchema={toFormikValidationSchema(Schema)}
  >
    {...}
  </Formik>
);
import { z } from 'zod';
import { Formik } from 'formik';
import { toFormikValidate } from 'zod-formik-adapter';

const Schema = z.object({
  name: z.string(),
  age: z.number(),
});

const Component = () => (
  <Formik
    validate={toFormikValidate(Schema)}
  >
    {...}
  </Formik>
);

zod-formik-adapter's People

Contributors

amatiasq avatar awkaiser-tr avatar cbelsole avatar mkreuzmayr avatar robertlichtnow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

zod-formik-adapter's Issues

[BUG] Null exception handling

Describe the bug
The function 'toFormikValidationSchema' throws a null ref exception because zod throws an null ref exception.
I'm not sure at which party this should be fixed but the simplest way was to not bubble up the zod exception, if this is the desired behavior.

Zod error

TypeError: Cannot read properties of undefined (reading 'status')
    at ParseStatus.mergeArray (index.mjs:408:19)

zod-formik-adapter error

TypeError: Cannot read properties of undefined (reading 'map')
    at createValidationError (index.js:68:28)

To Reproduce
I'll try to reproduce it within tests as i have time.

My schema is:

const measuringSchema = z
	.object({
		measuringId: z.string().uuid().optional(),
		value: z.string(),
	})
	.optional()

const measurementSchema = z.object({
	measurementId: z.string().uuid(),
	values: z.array(measuringSchema).optional(),
})

const formSchema = z.object({
	items: z.array(measurementSchema).optional(),
})

type FormSchemaType = z.infer<typeof formSchema>

My form data is:

const data: FormSchemaType = {
	items: [
		{
			measurementId: 'c66ee4a8-fef9-41a8-94b9-36522338db01',
			values: [
				{
					value: '405',
				},
			],
		},
		{
			measurementId: '91e8b93c-895e-430c-af28-15f3b0dec3a0',
			values: [
				{
					measuringId: '225fd710-914e-4579-be13-103eb02c76ae',
					value: '1',
				},
			],
		},
		{
			measurementId: '17d0940b-ace1-4e2d-9314-93e30ae67edb',
			values: [
+				null!,
				{
					measuringId: 'b3d25b19-7020-4e5a-88da-fe7648c8b635',
					value: '999',
				},
			],
		},
	],
}

Expected behavior
No exception and handling all other schema validations. Please correct me.

Desktop (please complete the following information):

  • OS: windows
  • Browser brave
  • Version

Node version:
node v16.17.0

Zod, Formik and zod-formik-adapter versions:
"zod": "^3.17.3",
"formik": "^2.2.9",
"zod-formik-adapter": "^1.1.1",

Additional context
My current fix to avoid this behavior:

function createValidationError(e: z.ZodError) {
+	if (!e?.errors) {
+		return new ValidationError('')
+	}

	const error = new ValidationError(e.message)

	error.inner = e.errors.map(err => ({
		message: err.message,
		path: err.path.join('.'),
	}))

	return error
}

Support flattened `union` errors

Is your feature request related to a problem? Please describe.
When schema validation takes place for a union type, the end result is an error object with a single message of Invalid input, which strips a lot of useful information out of the validation flow.

Describe the solution you'd like
Some method of specifying (or preferably a breaking change that would make this behavior default) to essentially flatten the errors into a root object like any other validation result.

Describe alternatives you've considered
Trying to refactor my schema to prevent a union from being necessary, which I don't think is possible...

Additional context
Add any other context or screenshots about the feature request here.

[BUG] - Type instantiation is excessively deep and possibly infinite.

Describe the bug
Not sure if a bug, but when I tried to use the toFormikValidationSchema(Schema), I get a warning saying Type instantiation is excessively deep and possibly infinite.. This seems to stress the typescript server in vs code. If I comment out this line validationSchema={toFormikValidationSchema(Schema)} then VS Code works as expected. Not sure why this is. I have not had this problem in the past. I just updated to version 1.2.0.

To Reproduce
Steps to reproduce the behavior:

  1. Update to version 1.2.0
  2. Add validationSchema={toFormikValidationSchema(Schema)} to your Formik component
  3. It should give a warning about Type instantiation is excessively deep and possibly infinite

Expected behavior
I expect the code to not give errors and validate my form as expected

Screenshots
image

Desktop (please complete the following information):

  • MacOS Ventura 13.1

Node version:

Zod, Formik and zod-formik-adapter versions:
zod: "^3.20.2",
zod-formik-adapter: "^1.2.0",
formik: "^2.2.9"
Typescript: 4.9.4

Additional context
I have tried to turn my computer on and off, restarted the ts server in vs code, and restarted vs code. It only seems to be working correctly if I do not include the validationSchema.

import { BodyLong, Heading, TextField } from "@navikt/ds-react";
import { FieldHookConfig, Form, Formik, useField } from "formik";
import { z } from "zod";
import { toFormikValidationSchema } from "zod-formik-adapter";
import styles from "../tiltaksgjennomforinger/Oversikt.module.scss";

const Schema = z.object({
  tiltakstypenavn: z.string({ required_error: "Tiltakstypen må ha et navn" }),
});

type SchemaValues = z.infer<typeof Schema>;

function Tekstfelt({
  label,
  name,
  ...props
}: { name: keyof SchemaValues; label: string } & FieldHookConfig<any>) {
  const [field, meta] = useField({ name, ...props });
  return <TextField label={label} {...field} error={meta.error} />;
}

export function OpprettTiltakstype() {
  const initialValues = { tiltakstypenavn: "" };
  return (
    <>
      <Heading className={styles.overskrift} size="large">
        Opprett ny tiltakstype
      </Heading>
      <BodyLong className={styles.body} size="small">
        Her kan du opprette eller redigere en tiltakstype
      </BodyLong>
      <Formik<SchemaValues>
        initialValues={initialValues}
        validationSchema={toFormikValidationSchema(Schema)} // TODO Se på toFormikValidationSchema og hvorfor den kneler Typescript-serveren
        onSubmit={(values, actions) => {
          setTimeout(() => {
            alert(JSON.stringify(values, null, 2));
            actions.setSubmitting(false);
          }, 1000);
        }}
      >
        {() => (
          <Form>
            <Tekstfelt name="tiltakstypenavn" label="Navn" />
            <button type="submit">Opprett</button>
          </Form>
        )}
      </Formik>
    </>
  );
}

[BUG] schema with transform has type mismatch

Describe the bug
When describing a schema that has one or more transform()s.
Right now a type error is shown when using validationSchema: toFormikValidationSchema(mySchema),.

To Reproduce
Steps to reproduce the behavior:

  1. Create a schema containing transform e.g. string => number
  2. Use toFormikValidationSchema with that schema
  3. See error
The types of '_input.age' are incompatible between these types.
    Type 'string' is not assignable to type 'number'.

Expected behavior
The TypeError should not be shown as only the fully transformed type should be considered.

Node version: 19.12.0

Zod, Formik and zod-formik-adapter versions:

  • Zod: 3.20.6
  • Formik: 2.2.9
  • zod-formik-adapter: 1.2.0

Additional context
Check this CodeSandbox for example https://codesandbox.io/s/formik-zod-test-forked-eyoy4j?file=/index.tsx

[BUG] parameters/values to validate have the wrong type

Describe the bug
toFormikValidate and toFormikValidationSchema are both returning a function with a typed parameter T.

This doesn't make sens, if a form value type is different from the schema, I should still be allowed to use the validation even if it invalidates the output.

In my case, a form value is undefined or a boolean, my schema validates booleans only, toFormikValidate will not be able to invalidate undefined

Note: toFormikValidationSchema always works because validationSchema in formik is any

Expected behavior
Parameters should be unknown like for parse from a zod schema

Node version:

Zod, Formik and zod-formik-adapter versions:

  • zod-formik-adapter: 1.3.0

Additional context
Add any other context about the problem here.

[BUG] Array errors not working

Describe the bug
When a schema has an array of objects, the errorrs are not been formated correctly

The boolean filtering, is filtering the 0 index

function createValidationResult(error: z.ZodError) {
  const result: Record<string, string> = {};

  for (const x of error.errors) {
    result[x.path.filter(Boolean).join(".")] = x.message;
  }

  return result;
}

.array not working

Describe the bug
Fields defined in zod as an array are not working with formik

To Reproduce
Create a zod validator:

const zAsegurado = z.object({
  name: z.string(),
  nif: zodDni,
  email: z.string(),
});

const zFormSchema = z.object({
  numPoliza: z.string().min(3, { message: 'Minimo 3' }),
  nif: zodDni,
  email: z.string().email(),
  name: z.string().min(3, { message: 'Minimo 3' }),
  insured: z.array(zAsegurado),
});

And just use formik fieldArray for the insured property.

Expected behavior
component should work out of the box

Zod, Formik and zod-formik-adapter versions:

Additional context
The problem is that formik touched property would be an array containing objects. The errors of this library would be in the form of insured.nif, insured.1.nif and so on, so you will need a custom ErrorMessage for this to work

API suggestion

It would be cool to ship a zod-formik-adapter/auto export with a getter such that it automatically wraps the first z.object() call in the adapter... allowing for more straight-forward usage:

import {z} from 'zod-formik-adapter/auto'

const schema = z.object({})

<Formik validationSchema={schema} />

check using enum does not validate

given the following schema:

const NonOccupantType = z.object({
    product: z.enum(['Ho3', 'Dp3']),
    occupantType: z.null(),
});
const RequireOccupantType = z.object({
    product: z.literal('Ho6'),
    occupantType: z.nativeEnum(OCCUPANT),
});
const validationSchema = z.union([NonOccupantType, RequireOccupantType]);

validating using formik the following object passes (the onSubmit gets called):
{product: "Ho6", occupantType: ""}
and passing that same object using .parse() correctly throws on the enum value validation

Does not support errors coming from zodSchema.refine()

Describe the bug
Does not parse properly if the error is coming from refine or superRefine

To Reproduce

const formSchema = z
  .object({
    username: z.string().email(),
    firstName: z.string(),
    middlerName: z.string().optional(),
    lastName: z.string(),
    password: z.string(),
    confirmPassword: z.string(),
    status: z.enum(['active', 'inactive']),
  })
  .refine((data) => data.password !== data.confirmPassword, {
    message: "Passwords don't match",
    path: ['confirmPassword'], // path of error
  });

if the values are these

{
      username: 'name',
      firstName: 'fname',
      lastName: 'lname',
      middlerName: 'mname',
      password: 'ss',
      confirmPassword: 'ssad',
      status: 'active',
}

It does not add any error for confirmPassword field with message "Passwords don't match"

Node version:
v16.15.0

Zod, Formik and zod-formik-adapter versions:

  • Zod: 3.19.1
  • Formik: 2.2.9
  • zod-formik-adapter: 1.1.1

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.