diff --git a/README.md b/README.md index 911d3b530..bf31c8a8e 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,8 @@ Passing anything other than a string is an error. - **contains(str, seed)** - check if the string contains the seed. - **equals(str, comparison)** - check if the string matches the comparison. - **isAfter(str [, date])** - check if the string is a date that's after the specified date (defaults to now). -- **isAlpha(str [, locale])** - check if the string contains only letters (a-zA-Z). Locale is one of `['ar', 'ar-AE', 'ar-BH', 'ar-DZ', 'ar-EG', 'ar-IQ', 'ar-JO', 'ar-KW', 'ar-LB', 'ar-LY', 'ar-MA', 'ar-QA', 'ar-QM', 'ar-SA', 'ar-SD', 'ar-SY', 'ar-TN', 'ar-YE', 'cs-CZ', 'de-DE', 'en-AU', 'en-GB', 'en-HK', 'en-IN', 'en-NZ', 'en-US', 'en-ZA', 'en-ZM', 'es-ES', 'fr-FR', 'hu-HU', 'nl-NL', 'pl-PL', 'pt-PT', 'ru-RU', 'tr-TR']`) and defaults to `en-US`. -- **isAlphanumeric(str [, locale])** - check if the string contains only letters and numbers. Locale is one of `['ar', 'ar-AE', 'ar-BH', 'ar-DZ', 'ar-EG', 'ar-IQ', 'ar-JO', 'ar-KW', 'ar-LB', 'ar-LY', 'ar-MA', 'ar-QA', 'ar-QM', 'ar-SA', 'ar-SD', 'ar-SY', 'ar-TN', 'ar-YE', 'cs-CZ', 'de-DE', 'en-AU', 'en-GB', 'en-HK', 'en-IN', 'en-NZ', 'en-US', 'en-ZA', 'en-ZM', 'es-ES', 'fr-FR', 'hu-HU', 'nl-NL', 'pl-PL', 'pt-PT', 'ru-RU', 'tr-TR']`) and defaults to `en-US`. +- **isAlpha(str [, locale])** - check if the string contains only letters (a-zA-Z). Locale is one of `['ar', 'ar-AE', 'ar-BH', 'ar-DZ', 'ar-EG', 'ar-IQ', 'ar-JO', 'ar-KW', 'ar-LB', 'ar-LY', 'ar-MA', 'ar-QA', 'ar-QM', 'ar-SA', 'ar-SD', 'ar-SY', 'ar-TN', 'ar-YE', 'cs-CZ', 'de-DE', 'en-AU', 'en-GB', 'en-HK', 'en-IN', 'en-NZ', 'en-US', 'en-ZA', 'en-ZM', 'es-ES', 'fr-FR', 'hu-HU', 'nl-NL', 'pl-PL', 'pt-PT', 'ru-RU', sr-RS, 'sr-RS@latin', 'tr-TR']`) and defaults to `en-US`. +- **isAlphanumeric(str [, locale])** - check if the string contains only letters and numbers. Locale is one of `['ar', 'ar-AE', 'ar-BH', 'ar-DZ', 'ar-EG', 'ar-IQ', 'ar-JO', 'ar-KW', 'ar-LB', 'ar-LY', 'ar-MA', 'ar-QA', 'ar-QM', 'ar-SA', 'ar-SD', 'ar-SY', 'ar-TN', 'ar-YE', 'cs-CZ', 'de-DE', 'en-AU', 'en-GB', 'en-HK', 'en-IN', 'en-NZ', 'en-US', 'en-ZA', 'en-ZM', 'es-ES', 'fr-FR', 'hu-HU', 'nl-NL', 'pl-PL', 'pt-PT', 'ru-RU', sr-RS, 'sr-RS@latin', 'tr-TR']`) and defaults to `en-US`. - **isAscii(str)** - check if the string contains ASCII chars only. - **isBase64(str)** - check if a string is base64 encoded. - **isBefore(str [, date])** - check if the string is a date that's before the specified date. @@ -86,7 +86,7 @@ Passing anything other than a string is an error. - **isLowercase(str)** - check if the string is lowercase. - **isMACAddress(str)** - check if the string is a MAC address. - **isMD5(str)** - check if the string is a MD5 hash. -- **isMobilePhone(str, locale)** - check if the string is a mobile phone number, (locale is one of `['ar-DZ', 'ar-SA', 'ar-SY', 'cs-CZ', 'de-DE', 'da-DK', 'el-GR', 'en-AU', 'en-GB', 'en-HK', 'en-IN', 'en-NZ', 'en-US', 'en-CA', 'en-ZA', 'en-ZM', 'es-ES', 'fi-FI', 'fr-FR', 'hu-HU', 'ms-MY', 'nb-NO', 'nn-NO', 'pl-PL', 'pt-PT', 'ru-RU', 'tr-TR', 'vi-VN', 'zh-CN', 'zh-TW']`). +- **isMobilePhone(str, locale)** - check if the string is a mobile phone number, (locale is one of `['ar-DZ', 'ar-SA', 'ar-SY', 'cs-CZ', 'de-DE', 'da-DK', 'el-GR', 'en-AU', 'en-GB', 'en-HK', 'en-IN', 'en-NZ', 'en-US', 'en-CA', 'en-ZA', 'en-ZM', 'es-ES', 'fi-FI', 'fr-FR', 'hu-HU', 'ms-MY', 'nb-NO', 'nn-NO', 'pl-PL', 'pt-PT', 'ru-RU', sr-RS, 'sr-RS@latin', 'tr-TR', 'vi-VN', 'zh-CN', 'zh-TW']`). - **isMongoId(str)** - check if the string is a valid hex-encoded representation of a [MongoDB ObjectId][mongoid]. - **isMultibyte(str)** - check if the string contains one or more multibyte chars. - **isNull(str)** - check if the string is null (has a length of zero). diff --git a/lib/alpha.js b/lib/alpha.js index 1d97cd37b..f721da538 100644 --- a/lib/alpha.js +++ b/lib/alpha.js @@ -13,9 +13,11 @@ var alpha = exports.alpha = { 'hu-HU': /^[A-ZÁÉÍÓÖŐÚÜŰ]+$/i, 'pl-PL': /^[A-ZĄĆĘŚŁŃÓŻŹ]+$/i, 'pt-PT': /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]+$/i, - 'ru-RU': /^[А-ЯЁа-яё]+$/i, + 'ru-RU': /^[А-ЯЁ]+$/i, + 'sr-RS@latin': /^[A-ZČĆŽŠĐ]+$/i, + 'sr-RS': /^[А-ЯЂЈЉЊЋЏ]+$/i, 'tr-TR': /^[A-ZÇĞİıÖŞÜ]+$/i, - ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/ + 'ar': /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/ }; var alphanumeric = exports.alphanumeric = { @@ -28,9 +30,11 @@ var alphanumeric = exports.alphanumeric = { 'nl-NL': /^[0-9A-ZÉËÏÓÖÜ]+$/i, 'pl-PL': /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]+$/i, 'pt-PT': /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]+$/i, - 'ru-RU': /^[0-9А-ЯЁа-яё]+$/i, + 'ru-RU': /^[0-9А-ЯЁ]+$/i, + 'sr-RS@latin': /^[0-9A-ZČĆŽŠĐ]+$/i, + 'sr-RS':/^[0-9А-ЯЂЈЉЊЋЏ]+$/i, 'tr-TR': /^[0-9A-ZÇĞİıÖŞÜ]+$/i, - ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/ + 'ar': /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/ }; var englishLocales = exports.englishLocales = ['AU', 'GB', 'HK', 'IN', 'NZ', 'ZA', 'ZM']; diff --git a/lib/isMobilePhone.js b/lib/isMobilePhone.js index 95b460484..15fd2093d 100644 --- a/lib/isMobilePhone.js +++ b/lib/isMobilePhone.js @@ -39,6 +39,7 @@ var phones = { 'pt-BR': /^(\+?55|0)\-?[1-9]{2}\-?[2-9]{1}\d{3,4}\-?\d{4}$/, 'pt-PT': /^(\+?351)?9[1236]\d{7}$/, 'ru-RU': /^(\+?7|8)?9\d{9}$/, + 'sr-RS': /^(\+3816|06)[- \d]{5,9}$/, 'tr-TR': /^(\+?90|0)?5\d{9}$/, 'vi-VN': /^(\+?84|0)?((1(2([0-9])|6([2-9])|88|99))|(9((?!5)[0-9])))([0-9]{7})$/, 'zh-CN': /^(\+?0?86\-?)?1[345789]\d{9}$/, diff --git a/src/lib/alpha.js b/src/lib/alpha.js index 112eb5e2c..e05105b40 100644 --- a/src/lib/alpha.js +++ b/src/lib/alpha.js @@ -8,9 +8,11 @@ export const alpha = { 'hu-HU': /^[A-ZÁÉÍÓÖŐÚÜŰ]+$/i, 'pl-PL': /^[A-ZĄĆĘŚŁŃÓŻŹ]+$/i, 'pt-PT': /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]+$/i, - 'ru-RU': /^[А-ЯЁа-яё]+$/i, + 'ru-RU': /^[А-ЯЁ]+$/i, + 'sr-RS@latin': /^[A-ZČĆŽŠĐ]+$/i, + 'sr-RS': /^[А-ЯЂЈЉЊЋЏ]+$/i, 'tr-TR': /^[A-ZÇĞİıÖŞÜ]+$/i, - ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/, + 'ar': /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/, }; export const alphanumeric = { @@ -23,9 +25,11 @@ export const alphanumeric = { 'nl-NL': /^[0-9A-ZÉËÏÓÖÜ]+$/i, 'pl-PL': /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]+$/i, 'pt-PT': /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]+$/i, - 'ru-RU': /^[0-9А-ЯЁа-яё]+$/i, + 'ru-RU': /^[0-9А-ЯЁ]+$/i, + 'sr-RS@latin': /^[0-9A-ZČĆŽŠĐ]+$/i, + 'sr-RS':/^[0-9А-ЯЂЈЉЊЋЏ]+$/i, 'tr-TR': /^[0-9A-ZÇĞİıÖŞÜ]+$/i, - ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/, + 'ar': /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/, }; export const englishLocales = ['AU', 'GB', 'HK', 'IN', 'NZ', 'ZA', 'ZM']; diff --git a/src/lib/isMobilePhone.js b/src/lib/isMobilePhone.js index 42db9c959..09765c7cf 100644 --- a/src/lib/isMobilePhone.js +++ b/src/lib/isMobilePhone.js @@ -28,6 +28,7 @@ const phones = { 'pt-BR': /^(\+?55|0)\-?[1-9]{2}\-?[2-9]{1}\d{3,4}\-?\d{4}$/, 'pt-PT': /^(\+?351)?9[1236]\d{7}$/, 'ru-RU': /^(\+?7|8)?9\d{9}$/, + 'sr-RS': /^(\+3816|06)[- \d]{5,9}$/, 'tr-TR': /^(\+?90|0)?5\d{9}$/, 'vi-VN': /^(\+?84|0)?((1(2([0-9])|6([2-9])|88|99))|(9((?!5)[0-9])))([0-9]{7})$/, 'zh-CN': /^(\+?0?86\-?)?1[345789]\d{9}$/, diff --git a/test/validators.js b/test/validators.js index d77b0ca7b..582ca3378 100644 --- a/test/validators.js +++ b/test/validators.js @@ -635,6 +635,39 @@ describe('Validators', function () { }); }); + it('should validate serbian cyrillic alpha strings', function () { + test({ + validator: 'isAlphanumeric', + args: ['sr-RS'], + valid: [ + 'ШћжЂљЕ', + 'ЧПСТЋЏ', + ], + invalid: [ + 'řiď ', + 'blé33!!', + 'föö!!', + ], + }); + }); + + it('should validate serbian latin alpha strings', function () { + test({ + validator: 'isAlphanumeric', + args: ['sr-RS@latin'], + valid: [ + 'ŠAabčšđćž', + 'ŠATROĆčđš', + ], + invalid: [ + '12řiď ', + 'blé!!', + 'föö!2!', + ], + }); + }); + + it('should validate defined arabic locales alpha strings', function () { test({ validator: 'isAlpha', @@ -809,6 +842,38 @@ describe('Validators', function () { }); }); + it('should validate serbian cyrillic alphanumeric strings', function () { + test({ + validator: 'isAlphanumeric', + args: ['sr-RS'], + valid: [ + 'ШћжЂљЕ123', + 'ЧПСТ132ЋЏ', + ], + invalid: [ + 'řiď ', + 'blé!!', + 'föö!!', + ], + }); + }); + + it('should validate serbian latin alphanumeric strings', function () { + test({ + validator: 'isAlphanumeric', + args: ['sr-RS@latin'], + valid: [ + 'ŠAabčšđćž123', + 'ŠATRO11Ćčđš', + ], + invalid: [ + 'řiď ', + 'blé!!', + 'föö!!', + ], + }); + }); + it('should validate turkish alphanumeric strings', function () { test({ validator: 'isAlphanumeric', @@ -2164,6 +2229,29 @@ describe('Validators', function () { args: ['ru-RU'], }); + test({ + validator: 'isMobilePhone', + valid: [ + '0640133338', + '063333133', + '0668888878', + '+381645678912', + '+381611314000', + '0655885010' + ], + invalid: [ + '12345', + '', + 'Vml2YW11cyBmZXJtZtesting123', + '010-38238383', + '+9676338855', + '19676338855', + '6676338855', + '+99676338855', + ], + args: ['sr-RS'], + }); + test({ validator: 'isMobilePhone', valid: [