diff --git a/CHANGELOG.md b/CHANGELOG.md index b18f2373f..45a7f6715 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ #### HEAD +- Added Spanish, French, Portuguese and Dutch support for `isAlpha()` and `isAlphanumeric()` + ([#492](https://github.com/chriso/validator.js/pull/492)) - Added a Brazilian locale to `isMobilePhone()` ([#489](https://github.com/chriso/validator.js/pull/489)) - Reject IPv4 addresses with invalid zero padding diff --git a/test/validators.js b/test/validators.js index dd3920421..1c8740cf4 100644 --- a/test/validators.js +++ b/test/validators.js @@ -598,6 +598,23 @@ describe('Validators', function () { }); }); + it('should validate defined english aliases', function () { + test({ + validator: 'isAlphanumeric' + , valid: [ + 'abc123' + , 'ABC11' + ] + , invalid: [ + 'abc ' + , 'foo!!' + , 'ÄBC' + , 'FÜübar' + , 'Jön' + ] + }); + }); + it('should validate german alphanumeric strings', function () { test({ validator: 'isAlphanumeric' @@ -613,6 +630,31 @@ describe('Validators', function () { }); }); + it('should validate spanish alphanumeric strings', function () { + test({ + validator: 'isAlphanumeric' + , args: ['es-ES'] + , valid: [ + 'ábcó123' + , 'ÁBCÓ11' + ] + , invalid: [ + 'äca ' + , 'abcß' + , 'föö!!' + ] + }); + }); + + it('should error on invalid locale', function () { + try { + validator.isAlphanumeric("abc123", "in-INVALID"); + assert(false); + } catch (err) { + assert(true); + } + }); + it('should validate numeric strings', function () { test({ validator: 'isNumeric' diff --git a/validator.js b/validator.js index c3c46fd2e..53df530e3 100644 --- a/validator.js +++ b/validator.js @@ -67,12 +67,37 @@ var alpha = { 'en-US': /^[A-Z]+$/i, 'de-DE': /^[A-ZÄÖÜß]+$/i, + 'es-ES': /^[A-ZÁÉÍÑÓÚÜ]+$/i, + 'fr-FR': /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]+$/i, + 'nl-NL': /^[A-ZÉËÏÓÖÜ]+$/i, + 'pt-PT': /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]+$/i } , alphanumeric = { 'en-US': /^[0-9A-Z]+$/i, - 'de-DE': /^[0-9A-ZÄÖÜß]+$/i - } - , numeric = /^[-+]?[0-9]+$/ + 'de-DE': /^[0-9A-ZÄÖÜß]+$/i, + 'es-ES': /^[0-9A-ZÁÉÍÑÓÚÜ]+$/i, + 'fr-FR': /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]+$/i, + 'nl-NL': /^[0-9A-ZÉËÏÓÖÜ]+$/i, + 'pt-PT': /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]+$/i + }; + + alpha['en-AU'] = alpha['en-US']; + alpha['en-GB'] = alpha['en-US']; + alpha['en-HK'] = alpha['en-US']; + alpha['en-IN'] = alpha['en-US']; + alpha['en-NZ'] = alpha['en-US']; + alpha['en-ZA'] = alpha['en-US']; + alpha['en-ZM'] = alpha['en-US']; + + alphanumeric['en-AU'] = alphanumeric['en-US']; + alphanumeric['en-GB'] = alphanumeric['en-US']; + alphanumeric['en-HK'] = alphanumeric['en-US']; + alphanumeric['en-IN'] = alphanumeric['en-US']; + alphanumeric['en-NZ'] = alphanumeric['en-US']; + alphanumeric['en-ZA'] = alphanumeric['en-US']; + alphanumeric['en-ZM'] = alphanumeric['en-US']; + + var numeric = /^[-+]?[0-9]+$/ , int = /^(?:[-+]?(?:0|[1-9][0-9]*))$/ , float = /^(?:[-+]?(?:[0-9]+))?(?:\.[0-9]*)?(?:[eE][\+\-]?(?:[0-9]+))?$/ , hexadecimal = /^[0-9A-F]+$/i @@ -89,27 +114,27 @@ var base64 = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i; var phones = { - 'zh-CN': /^(\+?0?86\-?)?((13\d|14[57]|15[^4,\D]|17[678]|18\d)\d{8}|170[059]\d{7})$/, - 'zh-TW': /^(\+?886\-?|0)?9\d{8}$/, - 'en-ZA': /^(\+?27|0)\d{9}$/, + 'en-US': /^(\+?1)?[2-9]\d{2}[2-9](?!11)\d{6}$/, + 'de-DE': /^(\+?49[ \.\-])?([\(]{1}[0-9]{1,6}[\)])?([0-9 \.\-\/]{3,20})((x|ext|extension)[ ]?[0-9]{1,4})?$/, + 'el-GR': /^(\+?30)?(69\d{8})$/, 'en-AU': /^(\+?61|0)4\d{8}$/, + 'en-GB': /^(\+?44|0)7\d{9}$/, 'en-HK': /^(\+?852\-?)?[569]\d{3}\-?\d{4}$/, + 'en-IN': /^(\+?91|0)?[789]\d{9}$/, + 'en-NZ': /^(\+?64|0)2\d{7,9}$/, + 'en-ZA': /^(\+?27|0)\d{9}$/, + 'en-ZM': /^(\+?26)?09[567]\d{7}$/, + 'es-ES': /^(\+?34)?(6\d{1}|7[1234])\d{7}$/, + 'fi-FI': /^(\+?358|0)\s?(4(0|1|2|4|5)?|50)\s?(\d\s?){4,8}\d$/, 'fr-FR': /^(\+?33|0)[67]\d{8}$/, + 'nb-NO': /^(\+?47)?[49]\d{7}$/, + 'nn-NO': /^(\+?47)?[49]\d{7}$/, 'pt-BR': /^(\+?55|0)\-?[1-9]{2}\-?[2-9]{1}\d{3,4}\-?\d{4}$/, 'pt-PT': /^(\+?351)?9[1236]\d{7}$/, - 'el-GR': /^(\+?30)?(69\d{8})$/, - 'en-GB': /^(\+?44|0)7\d{9}$/, - 'en-US': /^(\+?1)?[2-9]\d{2}[2-9](?!11)\d{6}$/, - 'en-ZM': /^(\+?26)?09[567]\d{7}$/, 'ru-RU': /^(\+?7|8)?9\d{9}$/, - 'nb-NO': /^(\+?47)?[49]\d{7}$/, - 'nn-NO': /^(\+?47)?[49]\d{7}$/, 'vi-VN': /^(\+?84|0)?((1(2([0-9])|6([2-9])|88|99))|(9((?!5)[0-9])))([0-9]{7})$/, - 'en-NZ': /^(\+?64|0)2\d{7,9}$/, - 'en-IN': /^(\+?91|0)?[789]\d{9}$/, - 'es-ES': /^(\+?34)?(6\d{1}|7[1234])\d{7}$/, - 'de-DE': /^(\+?49[ \.\-])?([\(]{1}[0-9]{1,6}[\)])?([0-9 \.\-\/]{3,20})((x|ext|extension)[ ]?[0-9]{1,4})?$/, - 'fi-FI': /^(\+?358|0)\s?(4(0|1|2|4|5)?|50)\s?(\d\s?){4,8}\d$/ + 'zh-CN': /^(\+?0?86\-?)?((13\d|14[57]|15[^4,\D]|17[678]|18\d)\d{8}|170[059]\d{7})$/, + 'zh-TW': /^(\+?886\-?|0)?9\d{8}$/ }; // from http://goo.gl/0ejHHW @@ -451,12 +476,18 @@ validator.isAlpha = function (str, locale) { locale = locale || 'en-US'; - return alpha[locale].test(str); + if (locale in alpha) { + return alpha[locale].test(str); + } + throw new Error('Invalid locale \'' + locale + '\''); }; validator.isAlphanumeric = function (str, locale) { locale = locale || 'en-US'; - return alphanumeric[locale].test(str); + if (locale in alphanumeric) { + return alphanumeric[locale].test(str); + } + throw new Error('Invalid locale \'' + locale + '\''); }; validator.isNumeric = function (str) {