card-validator
Advanced tools
Comparing version 6.1.0 to 6.2.0
@@ -0,1 +1,6 @@ | ||
6.2.0 | ||
===== | ||
- Adjust expiration date to accept dates formatted as `YYYY-MM` (the HTML autofill spec). Closes #69 (thanks @schuylr) | ||
6.1.0 | ||
@@ -2,0 +7,0 @@ ===== |
{ | ||
"name": "card-validator", | ||
"version": "6.1.0", | ||
"version": "6.2.0", | ||
"description": "A library for validating credit card fields", | ||
@@ -18,8 +18,8 @@ "main": "index.js", | ||
"devDependencies": { | ||
"chai": "^2.1.2", | ||
"eslint": "2.7.0", | ||
"eslint-config-braintree": "1.0.0", | ||
"mocha": "^3.0.0", | ||
"sinon": "^1.14.1", | ||
"sinon-chai": "^2.7.0" | ||
"chai": "^4.2.0", | ||
"eslint": "^5.16.0", | ||
"eslint-config-braintree": "^2.0.0", | ||
"mocha": "^6.1.4", | ||
"sinon": "^7.3.2", | ||
"sinon-chai": "^3.3.0" | ||
}, | ||
@@ -26,0 +26,0 @@ "dependencies": { |
@@ -266,2 +266,3 @@ # Credit Card Validator [![Build Status](https://travis-ci.org/braintree/card-validator.svg)](https://travis-ci.org/braintree/card-validator) [![npm version](https://badge.fury.io/js/card-validator.svg)](http://badge.fury.io/js/card-validator) | ||
| `'10/2019'`<br/>`'10 / 2019'`<br />`'102019'`<br/>`'10 2019'`<br/>`'10 19'` | `{month: '10', year: '2019'}` | | ||
| `'2019-10'` | `{month: '10', year: '2019'}` | | ||
| `{month: '01', year: '19'}`<br/>`{month: '1', year: '19'}`<br/>`{month: 1, year: 19}` | `{month: '01', year: '19'}` | | ||
@@ -268,0 +269,0 @@ | `{month: '10', year: '2019'}`<br/>`{month: '1', year: '2019'}`<br/>`{month: 1, year: 19}` | `{month: '10', year: '2019'}` | |
@@ -53,2 +53,3 @@ 'use strict'; | ||
isPotentiallyValid = value.length < maxLength || isValid; | ||
return verification(cardType, isPotentiallyValid, isValid); | ||
@@ -55,0 +56,0 @@ } |
@@ -37,2 +37,3 @@ 'use strict'; | ||
isValidForThisYear = monthValid.isValidForThisYear; | ||
return verification(isValidForThisYear, isValidForThisYear, date.month, date.year); | ||
@@ -39,0 +40,0 @@ } |
@@ -40,2 +40,3 @@ 'use strict'; | ||
currentFirstTwo = String(currentYear).slice(0, 2); | ||
return verification(false, firstTwo === currentFirstTwo); | ||
@@ -42,0 +43,0 @@ } |
@@ -6,33 +6,106 @@ 'use strict'; | ||
function parseDate(value) { | ||
var month, len, year, yearValid; | ||
function getNumberOfMonthDigitsInDateString(dateString) { | ||
var firstCharacter = Number(dateString[0]); | ||
var assumedYear; | ||
if (/\//.test(value)) { | ||
value = value.split(/\s*\/\s*/g); | ||
} else if (/\s/.test(value)) { | ||
value = value.split(/ +/g); | ||
/* | ||
if the first character in the string starts with `0`, | ||
we know that the month will be 2 digits. | ||
'0122' => {month: '01', year: '22'} | ||
*/ | ||
if (firstCharacter === 0) { | ||
return 2; | ||
} | ||
if (isArray(value)) { | ||
/* | ||
if the first character in the string starts with | ||
number greater than 1, it must be a 1 digit month | ||
'322' => {month: '3', year: '22'} | ||
*/ | ||
if (firstCharacter > 1) { | ||
return 1; | ||
} | ||
/* | ||
if the first 2 characters make up a number between | ||
13-19, we know that the month portion must be 1 | ||
'139' => {month: '1', year: '39'} | ||
*/ | ||
if (firstCharacter === 1 && Number(dateString[1]) > 2) { | ||
return 1; | ||
} | ||
/* | ||
if the first 2 characters make up a number between | ||
10-12, we check if the year portion would be considered | ||
valid if we assumed that the month was 1. If it is | ||
not potentially valid, we assume the month must have | ||
2 digits. | ||
'109' => {month: '10', year: '9'} | ||
'120' => {month: '1', year: '20'} // when checked in the year 2019 | ||
'120' => {month: '12', year: '0'} // when checked in the year 2021 | ||
*/ | ||
if (firstCharacter === 1) { | ||
assumedYear = dateString.substr(1); | ||
return expirationYear(assumedYear).isPotentiallyValid ? 1 : 2; | ||
} | ||
/* | ||
If the length of the value is exactly 5 characters, | ||
we assume a full year was passed in, meaning the remaining | ||
single leading digit must be the month value. | ||
'12202' => {month: '1', year: '2202'} | ||
*/ | ||
if (dateString.length === 5) { | ||
return 1; | ||
} | ||
/* | ||
If the length of the value is more than five characters, | ||
we assume a full year was passed in addition to the month | ||
and therefore the month portion must be 2 digits. | ||
'112020' => {month: '11', year: '2020'} | ||
*/ | ||
if (dateString.length > 5) { | ||
return 2; | ||
} | ||
/* | ||
By default, the month value is the first value | ||
*/ | ||
return 1; | ||
} | ||
function parseDate(date) { | ||
var month, numberOfDigitsInMonth; | ||
if (/^\d{4}-\d{1,2}$/.test(date)) { | ||
date = date.split('-').reverse(); | ||
} else if (/\//.test(date)) { | ||
date = date.split(/\s*\/\s*/g); | ||
} else if (/\s/.test(date)) { | ||
date = date.split(/ +/g); | ||
} | ||
if (isArray(date)) { | ||
return { | ||
month: value[0], | ||
year: value.slice(1).join() | ||
month: date[0] || '', | ||
year: date.slice(1).join() | ||
}; | ||
} | ||
len = value[0] === '0' || value.length > 5 ? 2 : 1; | ||
numberOfDigitsInMonth = getNumberOfMonthDigitsInDateString(date); | ||
if (value[0] === '1') { | ||
year = value.substr(1); | ||
yearValid = expirationYear(year); | ||
if (!yearValid.isPotentiallyValid) { | ||
len = 2; | ||
} | ||
} | ||
month = date.substr(0, numberOfDigitsInMonth); | ||
month = value.substr(0, len); | ||
return { | ||
month: month, | ||
year: value.substr(month.length) | ||
year: date.substr(month.length) | ||
}; | ||
@@ -39,0 +112,0 @@ } |
28143
356
373