✨ Add working sign-in / sign-out, add working registration with token
This commit is contained in:
128
src/utils/i18n-zod-resolver.ts
Normal file
128
src/utils/i18n-zod-resolver.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import { zodResolver } from '@mantine/form';
|
||||
import { TFunction } from 'i18next';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { ErrorMapCtx, ZodIssueCode, ZodSchema, ZodTooBigIssue, ZodTooSmallIssue, z } from 'zod';
|
||||
|
||||
export const useI18nZodResolver = () => {
|
||||
const { t } = useTranslation('zod');
|
||||
return {
|
||||
i18nZodResolver: i18nZodResolver(t),
|
||||
};
|
||||
};
|
||||
|
||||
const i18nZodResolver =
|
||||
(t: TFunction<'zod', undefined, 'zod'>) =>
|
||||
<TSchema extends ZodSchema<Record<string, any>>>(schema: TSchema) => {
|
||||
z.setErrorMap(zodErrorMap(t));
|
||||
return zodResolver(schema);
|
||||
};
|
||||
|
||||
const handleStringError = (issue: z.ZodInvalidStringIssue, ctx: ErrorMapCtx) => {
|
||||
if (typeof issue.validation === 'object') {
|
||||
if ('startsWith' in issue.validation) {
|
||||
return {
|
||||
key: 'errors.string.startsWith',
|
||||
params: {
|
||||
startsWith: issue.validation.startsWith,
|
||||
},
|
||||
};
|
||||
} else if ('endsWith' in issue.validation) {
|
||||
return {
|
||||
key: 'errors.string.endsWith',
|
||||
params: {
|
||||
endsWith: issue.validation.endsWith,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
key: 'errors.invalid_string.includes',
|
||||
params: {
|
||||
includes: issue.validation.includes,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
message: issue.message,
|
||||
};
|
||||
};
|
||||
|
||||
const handleTooSmallError = (issue: ZodTooSmallIssue, ctx: ErrorMapCtx) => {
|
||||
if (issue.type !== 'string' && issue.type !== 'number') {
|
||||
return {
|
||||
message: issue.message,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
key: `errors.too_small.${issue.type}`,
|
||||
params: {
|
||||
minimum: issue.minimum,
|
||||
count: issue.minimum,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const handleTooBigError = (issue: ZodTooBigIssue, ctx: ErrorMapCtx) => {
|
||||
if (issue.type !== 'string' && issue.type !== 'number') {
|
||||
return {
|
||||
message: issue.message,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
key: `errors.too_big.${issue.type}`,
|
||||
params: {
|
||||
maximum: issue.maximum,
|
||||
count: issue.maximum,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const handleZodError = (issue: z.ZodIssueOptionalMessage, ctx: ErrorMapCtx) => {
|
||||
if (ctx.defaultError === 'Required') {
|
||||
return {
|
||||
key: 'errors.required',
|
||||
params: {},
|
||||
};
|
||||
}
|
||||
if (issue.code === ZodIssueCode.invalid_string) {
|
||||
return handleStringError(issue, ctx);
|
||||
}
|
||||
if (issue.code === ZodIssueCode.too_small) {
|
||||
return handleTooSmallError(issue, ctx);
|
||||
}
|
||||
if (issue.code === ZodIssueCode.too_big) {
|
||||
return handleTooBigError(issue, ctx);
|
||||
}
|
||||
if (issue.code === ZodIssueCode.custom && issue.params?.i18n) {
|
||||
return {
|
||||
key: `errors.custom.${issue.params.i18n.key}`,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
message: issue.message,
|
||||
};
|
||||
};
|
||||
|
||||
function zodErrorMap(t: TFunction<'zod', undefined, 'zod'>) {
|
||||
return (issue: z.ZodIssueOptionalMessage, ctx: ErrorMapCtx) => {
|
||||
const error = handleZodError(issue, ctx);
|
||||
if ('message' in error && error.message)
|
||||
return {
|
||||
message: error.message ?? ctx.defaultError,
|
||||
};
|
||||
return {
|
||||
message: t(error.key ?? 'errors.default', error.params ?? {}),
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export type CustomErrorParams = {
|
||||
i18n: {
|
||||
key: string;
|
||||
params?: Record<string, any>;
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user