'@IsPhoneNumber() npm class validator how to add multiple countries code

In Nest js dto I want to validate user mobile number with multiple countries Regex. How can I do this?

@IsPhoneNumber('IN', {
    message: (args: ValidationArguments) => {
        if (args.value.length !== 10) {
            throw new BadRequestException(`${args.value} Wrong Phone Number`);
        } else {
            throw new InternalServerErrorException();
        }
    },
})


Solution 1:[1]

Different countries has different length of phone numbers. And my suggestion is to keep list of country codes instead of custom regex. It's easier to maintain, and it's more readable. So solution is:

  1. parse phone number
  2. if it's valid check country code
  3. if it's valid pass to next built-in decorator

So I've created my own decorator with libphonenumber-js

Usage in DTO:

export class PhoneDto {
  @ToPhone
  @IsString({ message: 'must be a valid number' })
  readonly phone!: string;
}

Implementation:

import { Transform } from 'class-transformer';
import { parsePhoneNumberFromString } from 'libphonenumber-js';

const validCountries = ['US', 'UK'];

export const ToPhone = Transform(
  (value: any) => {
    if (typeof value !== 'string') return undefined;

    const parsed = parsePhoneNumberFromString(value);

    if (!parsed) return undefined;
    if (!validCountries.includes(parsed.country)) return undefined;

    return parsed.number;
  },
  { toClassOnly: true },
);

And yes, this solution adds one more library, it could be slower (actually it depends on your countries list) because of parsing, but as I said before It's more readable and maintainable.

Solution 2:[2]

Passing a restricted set of locations to @IsPhoneNumber(region: string) is currently not supported.

Your only chance is to pass "ZZ" as region which will force users to enter numbers with the intl. prefix (see docs)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Felix K.