diff --git a/.gitignore b/.gitignore index 5f9cde8..2df6284 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *~ my.cnf *.reject +node_modules diff --git a/src/javascript/iban.js b/src/javascript/iban.js index bddbbff..28670e7 100644 --- a/src/javascript/iban.js +++ b/src/javascript/iban.js @@ -6,8 +6,8 @@ */ function isValidIBAN( accNumber ) { var isValid = false; - var countryCode = accNumber.substr( 0, 2 ); - var writenDigits = accNumber.substr( 2, 2 ); + var countryCode = accNumber.substr( 0, 2 ); //IT + var writenDigits = accNumber.substr( 2, 2 ); // 44 if ( isSepaCountry( countryCode ) ) { if ( accNumber.length == getAccountLength( countryCode ) ) { @@ -38,7 +38,6 @@ if ( getAccountLength( countryCode ) != 0 ) { isSepa = true; } - return isSepa; } @@ -96,7 +95,6 @@ var part = divident.substring(0, partLength); divident = (part % divisor) + divident.substring(partLength); } - return divident % divisor; } @@ -125,7 +123,8 @@ if( accNumber.length == accountLength ) { /* Replace the two check digits by 00 (e.g., GB00 for the UK) and Move the four initial characters to the end of the string. */ - accRearranged = + + accRearranged = accNumber.substr( 4 - accNumber.length ) + accNumber.substr( 0, 2 ) + '00'; /* Replace the letters in the string with digits, expanding the string as necessary, @@ -146,7 +145,6 @@ } } - return digits; } @@ -237,25 +235,43 @@ /* * replaceLetterWithDigits changes letters in a given string with its - * correspondent numbers, as described in ECBS EBS204 V3.2 [August 2003] - * document: A=1, B=2, ..., Y=34, Z=35. + * correspondent numbers: A=10, B=11, ..., Y=34, Z=35. * * @link https://github.com/amnesty/dataquality/wiki/replaceLetterWithDigits */ function replaceLetterWithDigits( accNumber ) { - var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - var findLetter = ""; - var replaceWith = 0; - var i = 0; - while( i <= letters.length ) { - findLetter = letters.substr( i-1, 1 ); - replaceWith = letters.indexOf( findLetter ) + 10; - accNumber = accNumber.replace( findLetter, replaceWith ); - - i++; + regExAllLetters = /[A-Z]/g; + + var AllLetters = accNumber.matchAll(regExAllLetters); + var AllLettersNoDuplicates = [...new Set(AllLetters)] + + const letterToDigits = { + 'A': '10', + 'B': '11', 'C': '12', 'D': '13', 'E': '14', 'F': '15', + 'G': '16', 'H': '17', 'I': '18', 'J': '19', 'K': '20', + 'L': '21', 'M': '22', 'N': '23', 'O': '24', 'P': '25', + 'Q': '26', 'R': '27', 'S': '28', 'T': '29', 'U': '30', + 'V': '30', 'W': '31', 'X': '32', 'Y': '33', 'Z': '35' } + + + var positionLetter = [] + + AllLettersNoDuplicates.forEach(match => positionLetter.push({"position": match.index, "letter": match[0] })) - return accNumber; + arrayAccNumber = [...accNumber]; + positionLetter.forEach(item => arrayAccNumber.splice(item.position, 1, letterToDigits[item.letter]) ) + accNumber = arrayAccNumber.join(""); + + return accNumber; } + var validIbanDE = 'DE29100100100987654321' + var notValidIbanDE = 'DE28100100100987654321' + + console.log("ibanDE: ", validIbanDE); + console.log("ibanDE: ", isValidIBAN(validIbanDE)); + console.log("ibanDE: ", notValidIbanDE); + console.log("ibanDE: ", isValidIBAN(notValidIbanDE)); + \ No newline at end of file diff --git a/src/typescript/iban.js b/src/typescript/iban.js new file mode 100644 index 0000000..7f96ef4 --- /dev/null +++ b/src/typescript/iban.js @@ -0,0 +1,238 @@ +var __spreadArrays = (this && this.__spreadArrays) || function () { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +}; +/* + * isValidIBAN validates an IBAN by verifying its structure and + * check digits. + * + * @link https://github.com/amnesty/dataquality/wiki/isValidIBAN + */ +function isValidIBAN(accNumber) { + var isValid = false; + var countryCode = accNumber.substr(0, 2); + var writenDigits = accNumber.substr(2, 2); + if (isSepaCountry(countryCode)) { + if (accNumber.length == getAccountLength(countryCode)) { + if (writenDigits == getIBANCheckDigits(accNumber)) { + isValid = true; + } + } + } + return isValid; +} +/* +* isSepaCountry helps to check the first two digits of an IBAN. +* These two digits are referring to the country where the +* account was created, so they only can correspond to one +* of the countries in the Single Euro Payments Area (SEPA) area. +* +* A document with a full list of the SEPA countries, its +* corresponding IBAN structures and more is available at +* the Swift website as IBAN Registry. +* +* @link https://github.com/amnesty/dataquality/wiki/isSepaCountry +*/ +function isSepaCountry(countryCode) { + var isSepa = false; + if (getAccountLength(countryCode) != 0) { + isSepa = true; + } + return isSepa; +} +/* +* getAccountLength returns the expected length for an IBAN given +* its first two digits. For instance, British accounts have 22 +* characters when written in IBAN electronic format. +* +* @link https://github.com/amnesty/dataquality/wiki/getAccountLength +*/ +function getAccountLength(countryCode) { + var accountLength = 0; + /* Information Source: IBAN Registry about all ISO 13616-compliant + national IBAN formats (Release 45 – April 2013). + http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf */ + var accountLengthPerCountry = { + 'AL': 28, 'AD': 24, 'AT': 20, 'AZ': 28, 'BH': 22, + 'BE': 16, 'BA': 20, 'BR': 29, 'BG': 22, 'CR': 21, + 'HR': 21, 'CY': 28, 'CZ': 24, 'DK': 18, 'DO': 28, + 'EE': 20, 'FO': 18, 'FI': 18, 'FR': 27, 'GE': 22, + 'DE': 22, 'GI': 23, 'GR': 27, 'GL': 18, 'GT': 28, + 'HU': 28, 'IS': 26, 'IE': 22, 'IL': 23, 'IT': 27, + 'KZ': 20, 'KW': 30, 'LV': 21, 'LB': 28, 'LI': 21, + 'LT': 20, 'LU': 20, 'MK': 19, 'MT': 31, 'MR': 27, + 'MU': 30, 'MC': 27, 'MD': 24, 'ME': 22, 'NL': 18, + 'NO': 15, 'PK': 24, 'PS': 29, 'PL': 28, 'PT': 25, + 'RO': 24, 'SM': 27, 'SA': 24, 'RS': 22, 'SK': 24, + 'SI': 19, 'ES': 24, 'SE': 24, 'CH': 21, 'TN': 24, + 'TR': 26, 'AE': 23, 'GB': 22, 'VG': 24, 'AO': 25, + 'BJ': 28, 'BF': 27, 'BI': 16, 'CM': 27, 'CV': 25, + 'IR': 26, 'CI': 28, 'MG': 27, 'ML': 28, 'MZ': 25, + 'SN': 28 + }; + if (countryCode) { + if (countryCode in accountLengthPerCountry) { + accountLength = accountLengthPerCountry[countryCode]; + } + } + return accountLength; +} +/* + * Auxiliary function. Helps to calculate modulus when working + * with big integers. + * + * @link http://stackoverflow.com/questions/929910/modulo-in-javascript-large-number + */ +function modulus(divident, divisor) { + var partLength = 10; + while (divident.length > partLength) { + var part = divident.substring(0, partLength); + divident = (Number(part) % divisor) + divident.substring(partLength); + } + return Number(divident) % divisor; +} +/* +* This function expects the entire account number in the electronic +* format (without spaces), as described in the ISO 13616-Compliant +* IBAN Formats document. +* +* You can replace check digits with zeros when calling the function. +* +* @link https://github.com/amnesty/dataquality/wiki/getIBANCheckDigits +*/ +function getIBANCheckDigits(accNumber) { + var countryCode = ""; + var accountLength = 0; + var accRearranged = ""; + var accWithoutLetters = ""; + var accMod97 = 0; + var digits = ""; + var digitsWithZeros = ""; + countryCode = accNumber.substr(0, 2); + accountLength = getAccountLength(countryCode); + if (isSepaCountry(countryCode)) { + if (accNumber.length == accountLength) { + /* Replace the two check digits by 00 (e.g., GB00 for the UK) and + Move the four initial characters to the end of the string. */ + accRearranged = + accNumber.substr(4 - accNumber.length) + accNumber.substr(0, 2) + '00'; + /* Replace the letters in the string with digits, expanding the string as necessary, + such that A or a = 10, B or b = 11, and Z or z = 35. + Each alphabetic character is therefore replaced by 2 digits. */ + accWithoutLetters = replaceLetterWithDigits(accRearranged); + /* Convert the string to an integer (i.e., ignore leading zeroes) and + Calculate mod-97 of the new number, which results in the remainder. */ + accMod97 = modulus(accWithoutLetters, 97); + /* Subtract the remainder from 98, and use the result for the two check digits. */ + digits = String(98 - accMod97); + /* If the result is a single digit number, pad it with a leading 0 to make a two-digit number. */ + digitsWithZeros = '00' + digits.toString(); + digits = digitsWithZeros.substr(-2); + } + } + return digits; +} +/* +* This "global identifier" refers to the code AT-02 created for the +* C19.14. The C19.14 is a temporary file format to be used in Spain +* until the ISO 20022 XML format is finally adopted. +* +* If the IBAN is built by adding a few digits to the national bank +* accounts, the AT-02 is build by adding digits to the national +* identifier. In the case of Spain, this identifiers are NIFs, +* NIEs and CIFs. +* +* For instance, the Spanish CIF G28667152, can be expressed +* internationally as ES03000G28667152. +* +* @link https://github.com/amnesty/dataquality/wiki/getGlobalIdentifier +*/ +function getGlobalIdentifier(localId, countryCode, suffix) { + var alphaNumerical = ""; + var withCountry = ""; + var withoutLetters = ""; + var mod97 = 0; + var digitsWithZeros = ""; + var digits = ""; + var suffixWithZeros = ""; + var globalId = ""; + /* Removes non alpha-numerical characters */ + alphaNumerical = replaceCharactersNotInPattern(localId, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', ''); + /* Concatenate localId plus country code and two zeros (00) */ + withCountry = alphaNumerical + countryCode + '00'; + /* Replace the letters in the string with digits, expanding the string as necessary, + such that A or a = 10, B or b = 11, and Z or z = 35. + Each alphabetic character is therefore replaced by 2 digits. */ + withoutLetters = replaceLetterWithDigits(withCountry); + /* Convert the string to an integer (i.e., ignore leading zeroes) and + Calculate mod-97 of the new number, which results in the remainder. */ + mod97 = Number(withoutLetters) % 97; + /* Subtract the remainder from 98, and use the result for the two check digits. */ + digits = String(98 - mod97); + /* If the result is a single digit number, pad it with a leading 0 to make a two-digit number. */ + digitsWithZeros = '00' + digits; + digits = digitsWithZeros.substr(-2); + /* Suffix must be a number from 000 to 999 */ + suffix = replaceCharactersNotInPattern(suffix, '0123456789', '0'); + suffixWithZeros = '000' + suffix; + suffix = suffixWithZeros.substr(-3); + return countryCode + digits + suffix + localId; +} +/* +* replaceCharactersNotInPattern replaces unwanted characters from a string +* with a given character. +* +* An example: +* - We have this string: 1!2/3·A|B@C# +* - This are the characters we accept: 123ABC +* - This is the character we want to replace extra characters with: 0 +* - The example would return: 102030A0B0C0 +* +* @link https://github.com/amnesty/dataquality/wiki/replaceCharactersNotInPattern +*/ +function replaceCharactersNotInPattern(givenString, pattern, replaceWith) { + var verifyLetter = ""; + var i = 1; + while (i <= givenString.length) { + verifyLetter = givenString.substr(i - 1, 1); + if (pattern.indexOf(verifyLetter) < 0) { + givenString = givenString.replace(verifyLetter, replaceWith); + } + i++; + } + return givenString; +} +/* +* replaceLetterWithDigits changes letters in a given string with its +* correspondent numbers: A=10, B=11, ..., Y=34, Z=35. +* +* @link https://github.com/amnesty/dataquality/wiki/replaceLetterWithDigits +*/ +function replaceLetterWithDigits(accNumber) { + var regExAllLetters = /[A-Z]/g; + var AllLetters = accNumber.matchAll(regExAllLetters); + var AllLettersNoDuplicates = __spreadArrays(Array.from(new Set(AllLetters))); + var letterToDigits = { + 'A': '10', + 'B': '11', 'C': '12', 'D': '13', 'E': '14', 'F': '15', + 'G': '16', 'H': '17', 'I': '18', 'J': '19', 'K': '20', + 'L': '21', 'M': '22', 'N': '23', 'O': '24', 'P': '25', + 'Q': '26', 'R': '27', 'S': '28', 'T': '29', 'U': '30', + 'V': '30', 'W': '31', 'X': '32', 'Y': '33', 'Z': '35' + }; + var positionLetter = []; + AllLettersNoDuplicates.forEach(function (match) { return positionLetter.push({ "position": match.index, "letter": match[0] }); }); + var arrayAccNumber = __spreadArrays(Array.from(accNumber)); + positionLetter.forEach(function (item) { return arrayAccNumber.splice(item.position, 1, letterToDigits[item.letter]); }); + accNumber = arrayAccNumber.join(""); + return accNumber; +} +var validIbanDE = 'DE29100100100987654321'; +var notValidIbanDE = 'DE28100100100987654321'; +console.log("ibanDE: ", validIbanDE); +console.log("ibanDE: ", isValidIBAN(validIbanDE)); +console.log("ibanDE: ", notValidIbanDE); +console.log("ibanDE: ", isValidIBAN(notValidIbanDE)); diff --git a/src/typescript/iban.ts b/src/typescript/iban.ts new file mode 100644 index 0000000..b828fd8 --- /dev/null +++ b/src/typescript/iban.ts @@ -0,0 +1,279 @@ + /* + * isValidIBAN validates an IBAN by verifying its structure and + * check digits. + * + * @link https://github.com/amnesty/dataquality/wiki/isValidIBAN + */ + function isValidIBAN( accNumber: string ) { + var isValid = false; + var countryCode = accNumber.substr( 0, 2 ); + var writenDigits = accNumber.substr( 2, 2 ); + + if ( isSepaCountry( countryCode ) ) { + if ( accNumber.length == getAccountLength( countryCode ) ) { + if ( writenDigits == getIBANCheckDigits( accNumber ) ) { + isValid = true; + } + } + } + + return isValid; +} + +/* +* isSepaCountry helps to check the first two digits of an IBAN. +* These two digits are referring to the country where the +* account was created, so they only can correspond to one +* of the countries in the Single Euro Payments Area (SEPA) area. +* +* A document with a full list of the SEPA countries, its +* corresponding IBAN structures and more is available at +* the Swift website as IBAN Registry. +* +* @link https://github.com/amnesty/dataquality/wiki/isSepaCountry +*/ +function isSepaCountry( countryCode: string ) { + let isSepa = false; + + if ( getAccountLength( countryCode ) != 0 ) { + isSepa = true; + } + return isSepa; +} + +/* +* getAccountLength returns the expected length for an IBAN given +* its first two digits. For instance, British accounts have 22 +* characters when written in IBAN electronic format. +* +* @link https://github.com/amnesty/dataquality/wiki/getAccountLength +*/ +function getAccountLength( countryCode: string ) { + var accountLength = 0; + + /* Information Source: IBAN Registry about all ISO 13616-compliant + national IBAN formats (Release 45 – April 2013). + http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf */ + + const accountLengthPerCountry: {[key: string]: number} = { + 'AL': 28, 'AD': 24, 'AT': 20, 'AZ': 28, 'BH': 22, + 'BE': 16, 'BA': 20, 'BR': 29, 'BG': 22, 'CR': 21, + 'HR': 21, 'CY': 28, 'CZ': 24, 'DK': 18, 'DO': 28, + 'EE': 20, 'FO': 18, 'FI': 18, 'FR': 27, 'GE': 22, + 'DE': 22, 'GI': 23, 'GR': 27, 'GL': 18, 'GT': 28, + 'HU': 28, 'IS': 26, 'IE': 22, 'IL': 23, 'IT': 27, + 'KZ': 20, 'KW': 30, 'LV': 21, 'LB': 28, 'LI': 21, + 'LT': 20, 'LU': 20, 'MK': 19, 'MT': 31, 'MR': 27, + 'MU': 30, 'MC': 27, 'MD': 24, 'ME': 22, 'NL': 18, + 'NO': 15, 'PK': 24, 'PS': 29, 'PL': 28, 'PT': 25, + 'RO': 24, 'SM': 27, 'SA': 24, 'RS': 22, 'SK': 24, + 'SI': 19, 'ES': 24, 'SE': 24, 'CH': 21, 'TN': 24, + 'TR': 26, 'AE': 23, 'GB': 22, 'VG': 24, 'AO': 25, + 'BJ': 28, 'BF': 27, 'BI': 16, 'CM': 27, 'CV': 25, + 'IR': 26, 'CI': 28, 'MG': 27, 'ML': 28, 'MZ': 25, + 'SN': 28 }; + + if( countryCode ) { + if( countryCode in accountLengthPerCountry ) { + accountLength = accountLengthPerCountry[countryCode]; + } + } + + return accountLength; +} + +/* + * Auxiliary function. Helps to calculate modulus when working + * with big integers. + * + * @link http://stackoverflow.com/questions/929910/modulo-in-javascript-large-number + */ +function modulus(divident: string , divisor: number) { + var partLength = 10; + + while (divident.length > partLength) { + var part = divident.substring(0, partLength); + divident = (Number(part) % divisor) + divident.substring(partLength); + } + + return Number(divident) % divisor; +} + +/* +* This function expects the entire account number in the electronic +* format (without spaces), as described in the ISO 13616-Compliant +* IBAN Formats document. +* +* You can replace check digits with zeros when calling the function. +* +* @link https://github.com/amnesty/dataquality/wiki/getIBANCheckDigits +*/ +function getIBANCheckDigits( accNumber: string ) { + var countryCode = ""; + var accountLength = 0; + var accRearranged = ""; + var accWithoutLetters = ""; + var accMod97 = 0; + var digits = ""; + var digitsWithZeros = ""; + + countryCode = accNumber.substr( 0, 2 ); + accountLength = getAccountLength( countryCode ); + + if( isSepaCountry( countryCode ) ) { + if( accNumber.length == accountLength ) { + /* Replace the two check digits by 00 (e.g., GB00 for the UK) and + Move the four initial characters to the end of the string. */ + + accRearranged = + accNumber.substr( 4 - accNumber.length ) + accNumber.substr( 0, 2 ) + '00'; + + /* Replace the letters in the string with digits, expanding the string as necessary, + such that A or a = 10, B or b = 11, and Z or z = 35. + Each alphabetic character is therefore replaced by 2 digits. */ + accWithoutLetters = replaceLetterWithDigits( accRearranged ); + + /* Convert the string to an integer (i.e., ignore leading zeroes) and + Calculate mod-97 of the new number, which results in the remainder. */ + accMod97 = modulus( accWithoutLetters, 97 ); + + /* Subtract the remainder from 98, and use the result for the two check digits. */ + digits = String(98 - accMod97) ; + + /* If the result is a single digit number, pad it with a leading 0 to make a two-digit number. */ + digitsWithZeros = '00' + digits.toString(); + digits = digitsWithZeros.substr( -2 ); + + } + } + return digits; +} + +/* +* This "global identifier" refers to the code AT-02 created for the +* C19.14. The C19.14 is a temporary file format to be used in Spain +* until the ISO 20022 XML format is finally adopted. +* +* If the IBAN is built by adding a few digits to the national bank +* accounts, the AT-02 is build by adding digits to the national +* identifier. In the case of Spain, this identifiers are NIFs, +* NIEs and CIFs. +* +* For instance, the Spanish CIF G28667152, can be expressed +* internationally as ES03000G28667152. +* +* @link https://github.com/amnesty/dataquality/wiki/getGlobalIdentifier +*/ +function getGlobalIdentifier( localId: string, countryCode: string, suffix: string ) { + var alphaNumerical = ""; + var withCountry = ""; + var withoutLetters = ""; + var mod97 = 0; + var digitsWithZeros = ""; + var digits = ""; + var suffixWithZeros = ""; + var globalId = ""; + + /* Removes non alpha-numerical characters */ + alphaNumerical = replaceCharactersNotInPattern( localId, + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', '' ); + + /* Concatenate localId plus country code and two zeros (00) */ + withCountry = alphaNumerical + countryCode + '00'; + + /* Replace the letters in the string with digits, expanding the string as necessary, + such that A or a = 10, B or b = 11, and Z or z = 35. + Each alphabetic character is therefore replaced by 2 digits. */ + withoutLetters = replaceLetterWithDigits( withCountry ); + + /* Convert the string to an integer (i.e., ignore leading zeroes) and + Calculate mod-97 of the new number, which results in the remainder. */ + mod97 = Number(withoutLetters) % 97; + + /* Subtract the remainder from 98, and use the result for the two check digits. */ + digits = String (98 - mod97); + + /* If the result is a single digit number, pad it with a leading 0 to make a two-digit number. */ + digitsWithZeros = '00' + digits; + digits = digitsWithZeros.substr( -2 ); + + /* Suffix must be a number from 000 to 999 */ + suffix = replaceCharactersNotInPattern( suffix, '0123456789', '0' ); + suffixWithZeros = '000' + suffix; + suffix = suffixWithZeros.substr( -3 ); + + return countryCode + digits + suffix + localId; +} + +/* +* replaceCharactersNotInPattern replaces unwanted characters from a string +* with a given character. +* +* An example: +* - We have this string: 1!2/3·A|B@C# +* - This are the characters we accept: 123ABC +* - This is the character we want to replace extra characters with: 0 +* - The example would return: 102030A0B0C0 +* +* @link https://github.com/amnesty/dataquality/wiki/replaceCharactersNotInPattern +*/ +function replaceCharactersNotInPattern( givenString: string, pattern: string , replaceWith: string ) { + var verifyLetter = ""; + var i = 1; + + while( i <= givenString.length ) { + verifyLetter = givenString.substr( i-1, 1 ); + + if( pattern.indexOf( verifyLetter ) < 0 ) { + givenString = givenString.replace( verifyLetter, replaceWith ); + } + + i++; + } + + return givenString; +} + +/* +* replaceLetterWithDigits changes letters in a given string with its +* correspondent numbers: A=10, B=11, ..., Y=34, Z=35. +* +* @link https://github.com/amnesty/dataquality/wiki/replaceLetterWithDigits +*/ +function replaceLetterWithDigits( accNumber: string ) { + + const regExAllLetters = /[A-Z]/g; + + var AllLetters = accNumber.matchAll(regExAllLetters); + var AllLettersNoDuplicates = [...Array.from(new Set(AllLetters))] + + var letterToDigits: {[key: string]: string} = { + 'A': '10', + 'B': '11', 'C': '12', 'D': '13', 'E': '14', 'F': '15', + 'G': '16', 'H': '17', 'I': '18', 'J': '19', 'K': '20', + 'L': '21', 'M': '22', 'N': '23', 'O': '24', 'P': '25', + 'Q': '26', 'R': '27', 'S': '28', 'T': '29', 'U': '30', + 'V': '30', 'W': '31', 'X': '32', 'Y': '33', 'Z': '35' + } + + var positionLetter: { position: number ; letter: string; }[] = [] + + AllLettersNoDuplicates.forEach(match => positionLetter.push({"position": match.index! , "letter": match[0] })) + + let arrayAccNumber = [...Array.from(accNumber)]; + positionLetter.forEach(item => arrayAccNumber.splice(item.position, 1, letterToDigits[item.letter]) ) + + accNumber = arrayAccNumber.join(""); + + return accNumber; +} + + var validIbanDE = 'DE29100100100987654321' + var notValidIbanDE = 'DE28100100100987654321' + + console.log("ibanDE: ", validIbanDE); + console.log("ibanDE: ", isValidIBAN(validIbanDE)); + console.log("ibanDE: ", notValidIbanDE); + console.log("ibanDE: ", isValidIBAN(notValidIbanDE)); + + \ No newline at end of file diff --git a/src/typescript/package-lock.json b/src/typescript/package-lock.json new file mode 100644 index 0000000..7d65905 --- /dev/null +++ b/src/typescript/package-lock.json @@ -0,0 +1,17 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@types/node": { + "version": "16.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", + "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==", + "dev": true + }, + "typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==" + } + } +} diff --git a/src/typescript/tsconfig.json b/src/typescript/tsconfig.json new file mode 100644 index 0000000..778f57b --- /dev/null +++ b/src/typescript/tsconfig.json @@ -0,0 +1,101 @@ +{ + "compilerOptions": { + "downlevelIteration": true, + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Projects */ + // "incremental": true, /* Enable incremental compilation */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es6", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ + // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "resolveJsonModule": true, /* Enable importing .json files */ + // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +}