Skip to content

Commit b9524e8

Browse files
committed
feat: add isDuration validator
1 parent 88e0d3d commit b9524e8

3 files changed

Lines changed: 105 additions & 0 deletions

File tree

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import isIPRange from './lib/isIPRange';
1414
import isFQDN from './lib/isFQDN';
1515
import isDate from './lib/isDate';
1616
import isTime from './lib/isTime';
17+
import isDuration from './lib/isDuration';
1718

1819
import isBoolean from './lib/isBoolean';
1920
import isLocale from './lib/isLocale';
@@ -245,6 +246,7 @@ const validator = {
245246
isLicensePlate,
246247
isVAT,
247248
ibanLocales,
249+
isDuration,
248250
};
249251

250252
export default validator;

src/lib/isDuration.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import assertString from './util/assertString';
2+
3+
const BaseDurationUnits = [
4+
'Years',
5+
'Year',
6+
'Yrs',
7+
'Yr',
8+
'Y',
9+
'Weeks',
10+
'Week',
11+
'W',
12+
'Days',
13+
'Day',
14+
'D',
15+
'Hours',
16+
'Hour',
17+
'Hrs',
18+
'Hr',
19+
'H',
20+
'Minutes',
21+
'Minute',
22+
'Mins',
23+
'Min',
24+
'M',
25+
'Seconds',
26+
'Second',
27+
'Secs',
28+
'Sec',
29+
's',
30+
'Milliseconds',
31+
'Millisecond',
32+
'Msecs',
33+
'Msec',
34+
'Ms',
35+
];
36+
37+
const AllDurationUnits = new Set(BaseDurationUnits.flatMap(unit => [
38+
unit, unit.toUpperCase(), unit.toLowerCase(),
39+
]));
40+
41+
/**
42+
* Checks if the string is a valid duration.
43+
* It is designed to match the format used by the [ms](https://github.com/vercel/ms) package.
44+
* The duration can be "1 week","2 days","1h", "30m", "15 s", etc.
45+
*/
46+
export default function isDuration(value) {
47+
assertString(value);
48+
49+
// using the same number regex used in the `ms` package
50+
const match = value.match(/^(?<nbr>-?(?:\d+)?\.?\d+)(?:\s?(?<unit>[a-zA-Z]+))?$/);
51+
52+
if (!match || !match.groups) {
53+
return false;
54+
}
55+
56+
const { unit } = match.groups;
57+
58+
return unit === undefined || AllDurationUnits.has(unit);
59+
}

test/validators/isDuration.test.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { describe } from 'mocha';
2+
import test from '../testFunctions';
3+
4+
describe('isDuration', () => {
5+
it('should validate duration strings', () => {
6+
test({
7+
validator: 'isDuration',
8+
valid: [
9+
'1 week',
10+
'2 days',
11+
'1h',
12+
'30m',
13+
'15 s',
14+
'100ms',
15+
'1.5h',
16+
'2.5 weeks',
17+
'-1d',
18+
'-200',
19+
],
20+
invalid: [
21+
'',
22+
'abc',
23+
'1 invalid',
24+
'week 1',
25+
'1.2.3h',
26+
'+1h', // plus sign is not allowed as in `ms` package
27+
'+200', // plus sign is not allowed as in `ms` package
28+
],
29+
});
30+
});
31+
32+
it('should accept various unit formats', () => {
33+
test({
34+
validator: 'isDuration',
35+
valid: [
36+
'1 Year',
37+
'2 WEEKS',
38+
'3 days',
39+
'4H',
40+
'5m',
41+
],
42+
});
43+
});
44+
});

0 commit comments

Comments
 (0)