Skip to content

Commit 6dba289

Browse files
authored
feat(isISBN): allow usage of options object (#2157)
1 parent 753c29d commit 6dba289

File tree

4 files changed

+142
-73
lines changed

4 files changed

+142
-73
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ Validator | Description
127127
**isInt(str [, options])** | check if the string is an integer.<br/><br/>`options` is an object which can contain the keys `min` and/or `max` to check the integer is within boundaries (e.g. `{ min: 10, max: 99 }`). `options` can also contain the key `allow_leading_zeroes`, which when set to false will disallow integer values with leading zeroes (e.g. `{ allow_leading_zeroes: false }`). Finally, `options` can contain the keys `gt` and/or `lt` which will enforce integers being greater than or less than, respectively, the value provided (e.g. `{gt: 1, lt: 4}` for a number between 1 and 4).
128128
**isIP(str [, version])** | check if the string is an IP (version 4 or 6).
129129
**isIPRange(str [, version])** | check if the string is an IP Range (version 4 or 6).
130-
**isISBN(str [, version])** | check if the string is an [ISBN][ISBN] (version 10 or 13).
130+
**isISBN(str [, options])** | check if the string is an [ISBN][ISBN].<br/><br/>`options` is an object that has no default.<br/>**Options:**<br/>`version`: ISBN version to compare to. Accepted values are '10' and '13'. If none provided, both will be tested.
131131
**isISIN(str)** | check if the string is an [ISIN][ISIN] (stock/security identifier).
132132
**isISO6391(str)** | check if the string is a valid [ISO 639-1][ISO 639-1] language code.
133133
**isISO8601(str [, options])** | check if the string is a valid [ISO 8601][ISO 8601] date. <br/>`options` is an object which defaults to `{ strict: false, strictSeparator: false }`. If `strict` is true, date strings with invalid dates like `2009-02-29` will be invalid. If `strictSeparator` is true, date strings with date and time separated by anything other than a T will be invalid.

src/lib/isISBN.js

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,55 @@
11
import assertString from './util/assertString';
22

3-
const isbn10Maybe = /^(?:[0-9]{9}X|[0-9]{10})$/;
4-
const isbn13Maybe = /^(?:[0-9]{13})$/;
3+
const possibleIsbn10 = /^(?:[0-9]{9}X|[0-9]{10})$/;
4+
const possibleIsbn13 = /^(?:[0-9]{13})$/;
55
const factor = [1, 3];
66

7-
export default function isISBN(str, version = '') {
8-
assertString(str);
9-
version = String(version);
10-
if (!version) {
11-
return isISBN(str, 10) || isISBN(str, 13);
7+
export default function isISBN(isbn, options) {
8+
assertString(isbn);
9+
10+
// For backwards compatibility:
11+
// isISBN(str [, version]), i.e. `options` could be used as argument for the legacy `version`
12+
const version = String(options?.version || options);
13+
14+
if (!(options?.version || options)) {
15+
return isISBN(isbn, { version: 10 }) || isISBN(isbn, { version: 13 });
1216
}
13-
const sanitized = str.replace(/[\s-]+/g, '');
17+
18+
const sanitizedIsbn = isbn.replace(/[\s-]+/g, '');
19+
1420
let checksum = 0;
15-
let i;
21+
1622
if (version === '10') {
17-
if (!isbn10Maybe.test(sanitized)) {
23+
if (!possibleIsbn10.test(sanitizedIsbn)) {
1824
return false;
1925
}
20-
for (i = 0; i < 9; i++) {
21-
checksum += (i + 1) * sanitized.charAt(i);
26+
27+
for (let i = 0; i < version - 1; i++) {
28+
checksum += (i + 1) * sanitizedIsbn.charAt(i);
2229
}
23-
if (sanitized.charAt(9) === 'X') {
30+
31+
if (sanitizedIsbn.charAt(9) === 'X') {
2432
checksum += 10 * 10;
2533
} else {
26-
checksum += 10 * sanitized.charAt(9);
34+
checksum += 10 * sanitizedIsbn.charAt(9);
2735
}
36+
2837
if ((checksum % 11) === 0) {
29-
return !!sanitized;
38+
return true;
3039
}
3140
} else if (version === '13') {
32-
if (!isbn13Maybe.test(sanitized)) {
41+
if (!possibleIsbn13.test(sanitizedIsbn)) {
3342
return false;
3443
}
35-
for (i = 0; i < 12; i++) {
36-
checksum += factor[i % 2] * sanitized.charAt(i);
44+
45+
for (let i = 0; i < 12; i++) {
46+
checksum += factor[i % 2] * sanitizedIsbn.charAt(i);
3747
}
38-
if (sanitized.charAt(12) - ((10 - (checksum % 10)) % 10) === 0) {
39-
return !!sanitized;
48+
49+
if (sanitizedIsbn.charAt(12) - ((10 - (checksum % 10)) % 10) === 0) {
50+
return true;
4051
}
4152
}
53+
4254
return false;
4355
}

test/validators.test.js

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5860,58 +5860,6 @@ describe('Validators', () => {
58605860
});
58615861
});
58625862

5863-
it('should validate ISBNs', () => {
5864-
test({
5865-
validator: 'isISBN',
5866-
args: [10],
5867-
valid: [
5868-
'3836221195', '3-8362-2119-5', '3 8362 2119 5',
5869-
'1617290858', '1-61729-085-8', '1 61729 085-8',
5870-
'0007269706', '0-00-726970-6', '0 00 726970 6',
5871-
'3423214120', '3-423-21412-0', '3 423 21412 0',
5872-
'340101319X', '3-401-01319-X', '3 401 01319 X',
5873-
],
5874-
invalid: [
5875-
'3423214121', '3-423-21412-1', '3 423 21412 1',
5876-
'978-3836221191', '9783836221191',
5877-
'123456789a', 'foo', '',
5878-
],
5879-
});
5880-
test({
5881-
validator: 'isISBN',
5882-
args: [13],
5883-
valid: [
5884-
'9783836221191', '978-3-8362-2119-1', '978 3 8362 2119 1',
5885-
'9783401013190', '978-3401013190', '978 3401013190',
5886-
'9784873113685', '978-4-87311-368-5', '978 4 87311 368 5',
5887-
],
5888-
invalid: [
5889-
'9783836221190', '978-3-8362-2119-0', '978 3 8362 2119 0',
5890-
'3836221195', '3-8362-2119-5', '3 8362 2119 5',
5891-
'01234567890ab', 'foo', '',
5892-
],
5893-
});
5894-
test({
5895-
validator: 'isISBN',
5896-
valid: [
5897-
'340101319X',
5898-
'9784873113685',
5899-
],
5900-
invalid: [
5901-
'3423214121',
5902-
'9783836221190',
5903-
],
5904-
});
5905-
test({
5906-
validator: 'isISBN',
5907-
args: ['foo'],
5908-
invalid: [
5909-
'340101319X',
5910-
'9784873113685',
5911-
],
5912-
});
5913-
});
5914-
59155863
it('should validate EANs', () => {
59165864
test({
59175865
validator: 'isEAN',

test/validators/isISBN.test.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import test from '../testFunctions';
2+
3+
describe('isISBN', () => {
4+
it('should validate ISBNs', () => {
5+
test({
6+
validator: 'isISBN',
7+
args: [{ version: 10 }],
8+
valid: [
9+
'3836221195', '3-8362-2119-5', '3 8362 2119 5',
10+
'1617290858', '1-61729-085-8', '1 61729 085-8',
11+
'0007269706', '0-00-726970-6', '0 00 726970 6',
12+
'3423214120', '3-423-21412-0', '3 423 21412 0',
13+
'340101319X', '3-401-01319-X', '3 401 01319 X',
14+
],
15+
invalid: [
16+
'3423214121', '3-423-21412-1', '3 423 21412 1',
17+
'978-3836221191', '9783836221191',
18+
'123456789a', 'foo', '',
19+
],
20+
});
21+
test({
22+
validator: 'isISBN',
23+
args: [{ version: 13 }],
24+
valid: [
25+
'9783836221191', '978-3-8362-2119-1', '978 3 8362 2119 1',
26+
'9783401013190', '978-3401013190', '978 3401013190',
27+
'9784873113685', '978-4-87311-368-5', '978 4 87311 368 5',
28+
],
29+
invalid: [
30+
'9783836221190', '978-3-8362-2119-0', '978 3 8362 2119 0',
31+
'3836221195', '3-8362-2119-5', '3 8362 2119 5',
32+
'01234567890ab', 'foo', '',
33+
],
34+
});
35+
test({
36+
validator: 'isISBN',
37+
valid: [
38+
'340101319X',
39+
'9784873113685',
40+
],
41+
invalid: [
42+
'3423214121',
43+
'9783836221190',
44+
],
45+
});
46+
test({
47+
validator: 'isISBN',
48+
args: [{ version: 'foo' }],
49+
invalid: [
50+
'340101319X',
51+
'9784873113685',
52+
],
53+
});
54+
});
55+
56+
describe('(legacy syntax)', () => {
57+
it('should validate ISBNs', () => {
58+
test({
59+
validator: 'isISBN',
60+
args: [10],
61+
valid: [
62+
'3836221195', '3-8362-2119-5', '3 8362 2119 5',
63+
'1617290858', '1-61729-085-8', '1 61729 085-8',
64+
'0007269706', '0-00-726970-6', '0 00 726970 6',
65+
'3423214120', '3-423-21412-0', '3 423 21412 0',
66+
'340101319X', '3-401-01319-X', '3 401 01319 X',
67+
],
68+
invalid: [
69+
'3423214121', '3-423-21412-1', '3 423 21412 1',
70+
'978-3836221191', '9783836221191',
71+
'123456789a', 'foo', '',
72+
],
73+
});
74+
test({
75+
validator: 'isISBN',
76+
args: [13],
77+
valid: [
78+
'9783836221191', '978-3-8362-2119-1', '978 3 8362 2119 1',
79+
'9783401013190', '978-3401013190', '978 3401013190',
80+
'9784873113685', '978-4-87311-368-5', '978 4 87311 368 5',
81+
],
82+
invalid: [
83+
'9783836221190', '978-3-8362-2119-0', '978 3 8362 2119 0',
84+
'3836221195', '3-8362-2119-5', '3 8362 2119 5',
85+
'01234567890ab', 'foo', '',
86+
],
87+
});
88+
test({
89+
validator: 'isISBN',
90+
valid: [
91+
'340101319X',
92+
'9784873113685',
93+
],
94+
invalid: [
95+
'3423214121',
96+
'9783836221190',
97+
],
98+
});
99+
test({
100+
validator: 'isISBN',
101+
args: ['foo'],
102+
invalid: [
103+
'340101319X',
104+
'9784873113685',
105+
],
106+
});
107+
});
108+
});
109+
});

0 commit comments

Comments
 (0)