diff --git a/README.md b/README.md index 886712dd7..1460c4e3e 100644 --- a/README.md +++ b/README.md @@ -874,6 +874,7 @@ isBoolean(value); | `@IsLatitude()` | Checks if the string or number is a valid latitude coordinate. | | `@IsLongitude()` | Checks if the string or number is a valid longitude coordinate. | | `@IsMobilePhone(locale: string)` | Checks if the string is a mobile phone number. | +| `@IsISO6391()` | Checks if the string is a valid ISO 639-1 officially assigned language code. | | `@IsISO31661Alpha2()` | Checks if the string is a valid ISO 3166-1 alpha-2 officially assigned country code. | | `@IsISO31661Alpha3()` | Checks if the string is a valid ISO 3166-1 alpha-3 officially assigned country code. | | `@IsLocale()` | Checks if the string is a locale. | diff --git a/src/decorator/string/isISO6391.ts b/src/decorator/string/isISO6391.ts new file mode 100644 index 000000000..514e5443f --- /dev/null +++ b/src/decorator/string/isISO6391.ts @@ -0,0 +1,31 @@ +import { ValidationOptions } from '../ValidationOptions'; +import { buildMessage, ValidateBy } from '../common/ValidateBy'; +import isISO6391Validator from 'validator/lib/isISO6391'; + +export const IS_ISO6391 = 'isISO6391'; + +/** + * Check if the string is a valid [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) officially assigned language code. + */ +export function isISO6391(value: unknown): boolean { + return typeof value === 'string' && isISO6391Validator(value); +} + +/** + * Check if the string is a valid [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) officially assigned language code. + */ +export function IsISO6391(validationOptions?: ValidationOptions): PropertyDecorator { + return ValidateBy( + { + name: IS_ISO6391, + validator: { + validate: (value, args): boolean => isISO6391(value), + defaultMessage: buildMessage( + eachPrefix => eachPrefix + '$property must be a valid ISO 639-1 language code', + validationOptions + ), + }, + }, + validationOptions + ); +} diff --git a/test/functional/validation-functions-and-decorators.spec.ts b/test/functional/validation-functions-and-decorators.spec.ts index 9f938616c..0ba115ccd 100644 --- a/test/functional/validation-functions-and-decorators.spec.ts +++ b/test/functional/validation-functions-and-decorators.spec.ts @@ -193,6 +193,7 @@ import { isTaxId, IsTaxId, IsISO4217CurrencyCode, + IsISO6391, } from '../../src/decorator/decorators'; import { Validator } from '../../src/validation/Validator'; import { ValidatorOptions } from '../../src/validation/ValidatorOptions'; @@ -4789,3 +4790,20 @@ describe('IsISO4217', () => { return checkInvalidValues(new MyClass(), invalidValues); }); }); + +describe('IsISO6391', () => { + class MyClass { + @IsISO6391() + someProperty: string; + } + + it('should not fail for a valid ISO 639-1 language code', () => { + const validValues = ['de', 'en', 'eo', 'fy', 'nl']; + return checkValidValues(new MyClass(), validValues); + }); + + it('should fail for invalid values', () => { + const invalidValues = [undefined, null, '', 'FR', 'xx', 'tok']; + return checkInvalidValues(new MyClass(), invalidValues); + }); +});