fix: allow any type of phone number

This commit is contained in:
Simon Emanuelsson
2025-05-22 17:21:13 +02:00
committed by Michael Zetterberg
parent 79e669020a
commit 9580281421
22 changed files with 400 additions and 459 deletions

View File

@@ -1,86 +1,20 @@
import {
isPossiblePhoneNumber,
ParseError,
parsePhoneNumberWithError,
validatePhoneNumberLength,
} from "libphonenumber-js"
import { z } from "zod"
const enum ParseErrorMessage {
INVALID_COUNTRY = "INVALID_COUNTRY",
INVALID_LENGTH = "INVALID_LENGTH",
NOT_A_NUMBER = "NOT_A_NUMBER",
TOO_LONG = "TOO_LONG",
TOO_SHORT = "TOO_SHORT",
}
export function phoneValidator(
msg = "Required field",
invalidMsg = "Invalid type"
) {
return z
.string({ invalid_type_error: invalidMsg, required_error: msg })
.min(1, { message: msg })
.min(5, { message: "The number you have entered is too short" })
.superRefine((value, ctx) => {
if (value) {
try {
const phoneNumber = parsePhoneNumberWithError(value)
if (phoneNumber) {
if (isPossiblePhoneNumber(value, phoneNumber.country)) {
return validatePhoneNumberLength(value, phoneNumber.country)
} else {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Please enter a valid phone number",
})
}
}
} catch (error) {
if (error instanceof ParseError) {
/**
* Only setup for when we need proper validation,
* should probably move to .superRefine to be able
* to return different messages depending on error.
*/
switch (error.message) {
case ParseErrorMessage.INVALID_COUNTRY:
ctx.addIssue({
code: z.ZodIssueCode.custom,
message:
"The country selected and country code doesn't match",
})
break
case ParseErrorMessage.INVALID_LENGTH:
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Please enter a valid phone number",
})
break
case ParseErrorMessage.NOT_A_NUMBER:
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Please enter a number",
})
break
case ParseErrorMessage.TOO_LONG:
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "The number you have entered is too long",
})
break
case ParseErrorMessage.TOO_SHORT:
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "The number you have entered is too short",
})
break
}
} else {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "The number you have entered is not valid",
})
}
const containsAlphabeticChars = /[a-z]/gi.test(value)
if (containsAlphabeticChars) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Please enter a valid phone number",
})
}
}
})