Skip to content

Commit 89e856c

Browse files
authored
fix(isUUID): fully support rfc9562 (#2421)
1 parent f81d857 commit 89e856c

File tree

3 files changed

+57
-13
lines changed

3 files changed

+57
-13
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ Validator | Description
167167
**isTime(str [, options])** | check if the string is a valid time e.g. [`23:01:59`, new Date().toLocaleTimeString()].<br/><br/> `options` is an object which can contain the keys `hourFormat` or `mode`.<br/><br/>`hourFormat` is a key and defaults to `'hour24'`.<br/><br/>`mode` is a key and defaults to `'default'`. <br/><br/>`hourFormat` can contain the values `'hour12'` or `'hour24'`, `'hour24'` will validate hours in 24 format and `'hour12'` will validate hours in 12 format. <br/><br/>`mode` can contain the values `'default'` or `'withSeconds'`, `'default'` will validate `HH:MM` format, `'withSeconds'` will validate the `HH:MM:SS` format.
168168
**isTaxID(str, locale)** | check if the string is a valid Tax Identification Number. Default locale is `en-US`.<br/><br/>More info about exact TIN support can be found in `src/lib/isTaxID.js`.<br/><br/>Supported locales: `[ 'bg-BG', 'cs-CZ', 'de-AT', 'de-DE', 'dk-DK', 'el-CY', 'el-GR', 'en-CA', 'en-GB', 'en-IE', 'en-US', 'es-AR', 'es-ES', 'et-EE', 'fi-FI', 'fr-BE', 'fr-CA', 'fr-FR', 'fr-LU', 'hr-HR', 'hu-HU', 'it-IT', 'lb-LU', 'lt-LT', 'lv-LV', 'mt-MT', 'nl-BE', 'nl-NL', 'pl-PL', 'pt-BR', 'pt-PT', 'ro-RO', 'sk-SK', 'sl-SI', 'sv-SE', 'uk-UA']`.
169169
**isURL(str [, options])** | check if the string is a URL.<br/><br/>`options` is an object which defaults to `{ protocols: ['http','https','ftp'], require_tld: true, require_protocol: false, require_host: true, require_port: false, require_valid_protocol: true, allow_underscores: false, host_whitelist: false, host_blacklist: false, allow_trailing_dot: false, allow_protocol_relative_urls: false, allow_fragments: true, allow_query_components: true, disallow_auth: false, validate_length: true }`.<br/><br/>`require_protocol` - if set to true isURL will return false if protocol is not present in the URL.<br/>`require_valid_protocol` - isURL will check if the URL's protocol is present in the protocols option.<br/>`protocols` - valid protocols can be modified with this option.<br/>`require_host` - if set to false isURL will not check if host is present in the URL.<br/>`require_port` - if set to true isURL will check if port is present in the URL.<br/>`allow_protocol_relative_urls` - if set to true protocol relative URLs will be allowed.<br/>`allow_fragments` - if set to false isURL will return false if fragments are present.<br/>`allow_query_components` - if set to false isURL will return false if query components are present.<br/>`validate_length` - if set to false isURL will skip string length validation (2083 characters is IE max URL length).
170-
**isUUID(str [, version])** | check if the string is a UUID (version 1, 2, 3, 4, 5 or 7).
170+
**isUUID(str [, version])** | check if the string is an RFC9562 UUID.<br/>`version` is one of `'1'`-`'8'`, `'nil'`, `'max'`, or `'all'`.
171171
**isVariableWidth(str)** | check if the string contains a mixture of full and half-width chars.
172172
**isVAT(str, countryCode)** | check if the string is a [valid VAT number][VAT Number] if validation is available for the given country code matching [ISO 3166-1 alpha-2][ISO 3166-1 alpha-2]. <br/><br/>`countryCode` is one of `['AL', 'AR', 'AT', 'AU', 'BE', 'BG', 'BO', 'BR', 'BY', 'CA', 'CH', 'CL', 'CO', 'CR', 'CY', 'CZ', 'DE', 'DK', 'DO', 'EC', 'EE', 'EL', 'ES', 'FI', 'FR', 'GB', 'GT', 'HN', 'HR', 'HU', 'ID', 'IE', 'IL', 'IN', 'IS', 'IT', 'KZ', 'LT', 'LU', 'LV', 'MK', 'MT', 'MX', 'NG', 'NI', 'NL', 'NO', 'NZ', 'PA', 'PE', 'PH', 'PL', 'PT', 'PY', 'RO', 'RS', 'RU', 'SA', 'SE', 'SI', 'SK', 'SM', 'SV', 'TR', 'UA', 'UY', 'UZ', 'VE']`.
173173
**isWhitelisted(str, chars)** | check if the string consists only of characters that appear in the whitelist `chars`.

src/lib/isUUID.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
11
import assertString from './util/assertString';
22

33
const uuid = {
4-
1: /^[0-9A-F]{8}-[0-9A-F]{4}-1[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
5-
2: /^[0-9A-F]{8}-[0-9A-F]{4}-2[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
6-
3: /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
4+
1: /^[0-9A-F]{8}-[0-9A-F]{4}-1[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
5+
2: /^[0-9A-F]{8}-[0-9A-F]{4}-2[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
6+
3: /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
77
4: /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
88
5: /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
9+
6: /^[0-9A-F]{8}-[0-9A-F]{4}-6[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
910
7: /^[0-9A-F]{8}-[0-9A-F]{4}-7[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
10-
all: /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
11+
8: /^[0-9A-F]{8}-[0-9A-F]{4}-8[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
12+
13+
nil: /^00000000-0000-0000-0000-000000000000$/i,
14+
max: /^ffffffff-ffff-ffff-ffff-ffffffffffff$/i,
15+
16+
// From https://github.com/uuidjs/uuid/blob/main/src/regex.js
17+
all: /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i,
1118
};
1219

1320
export default function isUUID(str, version) {
1421
assertString(str);
15-
const pattern = uuid[![undefined, null].includes(version) ? version : 'all'];
16-
return !!pattern && pattern.test(str);
22+
23+
if (version === undefined || version === null) {
24+
version = 'all';
25+
}
26+
27+
return version in uuid ? uuid[version].test(str) : false;
1728
}

test/validators.test.js

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5424,14 +5424,17 @@ describe('Validators', () => {
54245424
test({
54255425
validator: 'isUUID',
54265426
valid: [
5427-
'A987FBC9-4BED-3078-CF07-9141BA07C9F3',
5427+
'9deb20fe-a6e0-355c-81ea-288b009e4f6d',
54285428
'A987FBC9-4BED-4078-8F07-9141BA07C9F3',
54295429
'A987FBC9-4BED-5078-AF07-9141BA07C9F3',
5430+
'A987FBC9-4BED-6078-AF07-9141BA07C9F3',
54305431
'018C544A-D384-7000-BB74-3B1738ABE43C',
5432+
'A987FBC9-4BED-8078-AF07-9141BA07C9F3',
54315433
],
54325434
invalid: [
54335435
'',
54345436
'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3',
5437+
'A987FBC9-4BED-3078-CF07-9141BA07C9F3',
54355438
'A987FBC9-4BED-3078-CF07-9141BA07C9F3xxx',
54365439
'A987FBC94BED3078CF079141BA07C9F3',
54375440
'934859',
@@ -5443,12 +5446,13 @@ describe('Validators', () => {
54435446
validator: 'isUUID',
54445447
args: [undefined],
54455448
valid: [
5446-
'A117FBC9-4BED-3078-CF07-9141BA07C9F3',
5449+
'9deb20fe-a6e0-355c-81ea-288b009e4f6d',
54475450
'A117FBC9-4BED-5078-AF07-9141BA07C9F3',
54485451
'018C544A-D384-7000-BB74-3B1738ABE43C',
54495452
],
54505453
invalid: [
54515454
'',
5455+
'A117FBC9-4BED-3078-CF07-9141BA07C9F3',
54525456
'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3',
54535457
'A987FBC94BED3078CF079141BA07C9F3',
54545458
'A11AAAAA-1111-1111-AAAG-111111111111',
@@ -5458,12 +5462,13 @@ describe('Validators', () => {
54585462
validator: 'isUUID',
54595463
args: [null],
54605464
valid: [
5461-
'A127FBC9-4BED-3078-CF07-9141BA07C9F3',
5465+
'A127FBC9-4BED-3078-AF07-9141BA07C9F3',
54625466
'018C544A-D384-7000-BB74-3B1738ABE43C',
54635467
],
54645468
invalid: [
54655469
'',
54665470
'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3',
5471+
'A127FBC9-4BED-3078-CF07-9141BA07C9F3',
54675472
'A127FBC9-4BED-3078-CF07-9141BA07C9F3xxx',
54685473
'912859',
54695474
'A12AAAAA-1111-1111-AAAG-111111111111',
@@ -5488,13 +5493,14 @@ describe('Validators', () => {
54885493
validator: 'isUUID',
54895494
args: [2],
54905495
valid: [
5491-
'A987FBC9-4BED-2078-CF07-9141BA07C9F3',
5496+
'A987FBC9-4BED-2078-AF07-9141BA07C9F3',
54925497
],
54935498
invalid: [
54945499
'',
54955500
'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3',
54965501
'11111',
54975502
'AAAAAAAA-1111-1111-AAAG-111111111111',
5503+
'A987FBC9-4BED-2078-CF07-9141BA07C9F3',
54985504
'A987FBC9-4BED-4078-8F07-9141BA07C9F3',
54995505
'A987FBC9-4BED-5078-AF07-9141BA07C9F3',
55005506
'018C544A-D384-7000-BB74-3B1738ABE43C',
@@ -5504,10 +5510,11 @@ describe('Validators', () => {
55045510
validator: 'isUUID',
55055511
args: [3],
55065512
valid: [
5507-
'A987FBC9-4BED-3078-CF07-9141BA07C9F3',
5513+
'9deb20fe-a6e0-355c-81ea-288b009e4f6d',
55085514
],
55095515
invalid: [
55105516
'',
5517+
'A987FBC9-4BED-3078-CF07-9141BA07C9F3',
55115518
'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3',
55125519
'934859',
55135520
'AAAAAAAA-1111-1111-AAAG-111111111111',
@@ -5557,14 +5564,17 @@ describe('Validators', () => {
55575564
test({
55585565
validator: 'isUUID',
55595566
args: [6],
5560-
valid: [],
5567+
valid: [
5568+
'1ef29908-cde1-69d0-be16-bfc8518a95f0',
5569+
],
55615570
invalid: [
55625571
'987FBC97-4BED-1078-AF07-9141BA07C9F3',
55635572
'987FBC97-4BED-2078-AF07-9141BA07C9F3',
55645573
'987FBC97-4BED-3078-AF07-9141BA07C9F3',
55655574
'987FBC97-4BED-4078-AF07-9141BA07C9F3',
55665575
'987FBC97-4BED-5078-AF07-9141BA07C9F3',
55675576
'018C544A-D384-7000-BB74-3B1738ABE43C',
5577+
'987FBC97-4BED-8078-AF07-9141BA07C9F3',
55685578
],
55695579
});
55705580
test({
@@ -5580,6 +5590,29 @@ describe('Validators', () => {
55805590
'AAAAAAAA-1111-1111-AAAG-111111111111',
55815591
'A987FBC9-4BED-5078-AF07-9141BA07C9F3',
55825592
'A987FBC9-4BED-3078-CF07-9141BA07C9F3',
5593+
'A987FBC9-4BED-6078-AF07-9141BA07C9F3',
5594+
'A987FBC9-4BED-8078-AF07-9141BA07C9F3',
5595+
'713ae7e3-cb32-45f9-adcb-7c4fa86b90c1',
5596+
'625e63f3-58f5-40b7-83a1-a72ad31acffb',
5597+
'57b73598-8764-4ad0-a76a-679bb6640eb1',
5598+
'9c858901-8a57-4791-81fe-4c455b099bc9',
5599+
],
5600+
});
5601+
test({
5602+
validator: 'isUUID',
5603+
args: [8],
5604+
valid: [
5605+
'018C544A-D384-8000-BB74-3B1738ABE43C',
5606+
],
5607+
invalid: [
5608+
'',
5609+
'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3',
5610+
'934859',
5611+
'AAAAAAAA-1111-1111-AAAG-111111111111',
5612+
'A987FBC9-4BED-5078-AF07-9141BA07C9F3',
5613+
'A987FBC9-4BED-3078-CF07-9141BA07C9F3',
5614+
'A987FBC9-4BED-6078-AF07-9141BA07C9F3',
5615+
'A987FBC9-4BED-7078-AF07-9141BA07C9F3',
55835616
'713ae7e3-cb32-45f9-adcb-7c4fa86b90c1',
55845617
'625e63f3-58f5-40b7-83a1-a72ad31acffb',
55855618
'57b73598-8764-4ad0-a76a-679bb6640eb1',

0 commit comments

Comments
 (0)