Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
AlemTuzlak committed Oct 28, 2023
1 parent 2fefe5e commit 110698e
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 10 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "remix-hook-form",
"version": "3.0.2",
"version": "3.0.3",
"description": "Utility wrapper around react-hook-form for use with Remix.run",
"type": "module",
"main": "./dist/index.cjs",
Expand Down
54 changes: 46 additions & 8 deletions src/testing-app/app/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,50 @@ import {
RemixFormProvider,
} from "remix-hook-form";
import { z } from "zod";
import {
generateObjectSchema,
stringOptional,
stringRequired,
dateOfBirthRequired,
emailOptional,
booleanOptional,
booleanRequired,
} from "~/zod";
const MAX_FILE_SIZE = 500000;
const ACCEPTED_IMAGE_TYPES = [
"image/jpeg",
"image/jpg",
"image/png",
"image/webp",
];
export const patientBaseSchema = generateObjectSchema({
id: stringOptional(),
firstName: stringRequired(),
lastName: stringRequired(),
primaryCareProvider: stringOptional(),
dateOfBirth: dateOfBirthRequired(),
email: emailOptional(),
hasThirdPartyCoverage: booleanOptional(),
isForeignCitizen: booleanOptional(),
allergies: z.array(stringRequired()).optional(),
healthCardNumber: stringOptional(),
hasHealthCardNumber: booleanRequired(),
city: stringRequired(),
province: stringRequired(),
street: stringRequired(),
postalCode: stringRequired(),
healthCardProvince: stringRequired(),
});
const FormDataZodSchema = z.object({
email: z.string().trim().nonempty("validation.required"),
password: z.string().trim().nonempty("validation.required"),
number: z.number({ coerce: true }).int().positive(),
redirectTo: z.string().optional(),
});

type FormData = z.infer<typeof FormDataZodSchema>;
type FormData = z.infer<typeof patientBaseSchema>;

const resolver = zodResolver(FormDataZodSchema);
const resolver = zodResolver(patientBaseSchema);

export const action = async ({ request }: ActionFunctionArgs) => {
const { data, errors, receivedValues } = await getValidatedFormData(
Expand All @@ -57,10 +84,23 @@ export default function Index() {
const methods = useRemixForm<FormData>({
resolver,
defaultValues: {
email: "[email protected]",
password: "12345678",
redirectTo: undefined,
number: 1,
firstName: "a",
lastName: "t",
primaryCareProvider: "",
dateOfBirth: new Date("1997-09-05T00:00:00.000Z"),

email: "",

hasThirdPartyCoverage: false,
isForeignCitizen: false,
allergies: [],
city: "Sarajevo",
street: "Radenka Abazovića",
province: "ON",
postalCode: "a5t 5a5",
hasHealthCardNumber: true,
healthCardNumber: "5555555555",
healthCardProvince: "ON",
},
submitConfig: {
method: "POST",
Expand All @@ -76,8 +116,6 @@ export default function Index() {
<Form method="post" onSubmit={handleSubmit}>
<div className="flex flex-col gap-2">
<input type="text" {...register("email")} />
<input type="text" {...register("password")} />
<input type="number" {...register("number")} />
</div>
<div>
<button type="submit" className="button">
Expand Down
87 changes: 87 additions & 0 deletions src/testing-app/app/zod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import type { ZodRawShape } from "zod";
import { z } from "zod";

const errorMessages = {
required_error: "validation.required",
invalid_type_error: "validation.required",
};
const customErrorMap: z.ZodErrorMap = (issue, ctx) => {
if (issue.code === z.ZodIssueCode.invalid_union) {
return { message: "validation.required" };
}
return { message: ctx.defaultError };
};

z.setErrorMap(customErrorMap);

export const stringRequired = () =>
z.string(errorMessages).trim().nonempty("validation.required");

export const stringOptional = () => z.string(errorMessages).trim().nullish();

export const numberRequired = () => z.number(errorMessages);

export const numberOptional = () => z.number(errorMessages).nullish();

export const booleanRequired = () => z.boolean(errorMessages);

export const booleanOptional = () => z.boolean(errorMessages).optional();

export const passwordRequired = () =>
stringRequired().min(8, "validation.min8");

const dateOrStringDate = stringRequired()
.pipe(
z.date({
coerce: true,
...errorMessages,
}),
)
.or(z.date(errorMessages));

export const dateOfBirthRequired = () =>
stringRequired()
.pipe(
z
.date({
coerce: true,
...errorMessages,
})
.min(new Date("1.1.1900"), "validation.min_year")
.max(new Date(), "validation.dob_future"),
)
.or(
z
.date(errorMessages)
.min(new Date("1.1.1900"), "validation.min_year")
.max(new Date(), "validation.dob_future"),
);

export const dateRequired = () => dateOrStringDate;

export const dateOptional = () => dateOrStringDate.nullish();

export const generateObjectSchema = <T extends ZodRawShape>(obj: T) =>
z.object(obj);

export const generateObjectArraySchema = (
obj: Record<string, z.ZodSchema>,
required?: boolean,
) =>
required
? z.array(generateObjectSchema(obj)).min(1, "validation.required")
: z.array(generateObjectSchema(obj));

export const confirmEmail = <T extends { email: string; confirmEmail: string }>(
data: T,
) => data.email === data.confirmEmail;

export const confirmPassword = <
T extends { password: string; confirmPassword: string },
>(
data: T,
) => data.password === data.confirmPassword;

export const emailRequired = () => stringRequired().email("validation.email");

export const emailOptional = () => emailRequired().nullish().or(z.literal(""));
6 changes: 5 additions & 1 deletion src/utilities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ const tryParseJSON = (jsonString: string) => {
}
try {
const json = JSON.parse(jsonString);
if (typeof json === "object") {
if (
typeof json === "object" ||
typeof json === "boolean" ||
typeof json === "string"
) {
return json;
}
return jsonString;
Expand Down

0 comments on commit 110698e

Please sign in to comment.