UNPKG

ibankit

Version:

Validation, field extraction and creation of IBAN, BBAN, BIC numbers

188 lines (159 loc) 4.95 kB
import { randInt } from "./randInt"; import { BbanStructure } from "./bbanStructure"; export enum PartType { BANK_CODE, BRANCH_CODE, ACCOUNT_NUMBER, BRANCH_CHECK_DIGIT, NATIONAL_CHECK_DIGIT, CURRENCY_TYPE, ACCOUNT_TYPE, OWNER_ACCOUNT_NUMBER, IDENTIFICATION_NUMBER, } /** * Bban Structure Entry representation. */ export enum CharacterType { /** * Digits (numeric characters 0 to 9 only) */ n, /** * Upper case letters (alphabetic characters A-Z only) */ a, /** * Upper case alphanumeric characters (A-Z, a-z and 0-9) */ c, /** * Blank space */ e, } // Use by random string generation const charByCharacterType: Record<CharacterType, string> = { [CharacterType.n]: "0123456789", [CharacterType.a]: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", [CharacterType.c]: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", [CharacterType.e]: " ", }; // Used by validation const charByCharacterRE: Record<CharacterType, RegExp> = { [CharacterType.n]: /^[0-9]+$/, [CharacterType.a]: /^[A-Z]+$/, [CharacterType.c]: /^[0-9A-Za-z]+$/, [CharacterType.e]: /^ +$/, }; type GenerateValue = (bban: string, structure: BbanStructure) => string; export class BbanStructurePart { private entryType: PartType; private characterType: CharacterType; private length: number; trailingSeparator: boolean; generate: GenerateValue; hasGenerator: boolean; private constructor( entryType: PartType, characterType: CharacterType, length: number, trailingSeparator: boolean, generate?: GenerateValue, ) { this.entryType = entryType; this.characterType = characterType; this.length = length; this.generate = generate || this.defaultGenerator; this.hasGenerator = !!generate; this.trailingSeparator = trailingSeparator; } static bankCode(length: number, characterType: CharacterType, trailingSeparator: boolean = true): BbanStructurePart { return new BbanStructurePart(PartType.BANK_CODE, characterType, length, trailingSeparator); } static branchCode( length: number, characterType: CharacterType, trailingSeparator: boolean = true, ): BbanStructurePart { return new BbanStructurePart(PartType.BRANCH_CODE, characterType, length, trailingSeparator); } static accountNumber( length: number, characterType: CharacterType, trailingSeparator: boolean = true, ): BbanStructurePart { return new BbanStructurePart(PartType.ACCOUNT_NUMBER, characterType, length, trailingSeparator); } static nationalCheckDigit( length: number, characterType: CharacterType, generate?: GenerateValue, trailingSeparator: boolean = false, ): BbanStructurePart { return new BbanStructurePart(PartType.NATIONAL_CHECK_DIGIT, characterType, length, trailingSeparator, generate); } static branchCheckDigit( length: number, characterType: CharacterType, generate?: GenerateValue, trailingSeparator: boolean = false, ): BbanStructurePart { return new BbanStructurePart(PartType.BRANCH_CHECK_DIGIT, characterType, length, trailingSeparator, generate); } static accountType( length: number, characterType: CharacterType, trailingSeparator: boolean = false, ): BbanStructurePart { return new BbanStructurePart(PartType.ACCOUNT_TYPE, characterType, length, trailingSeparator); } static currencyType( length: number, characterType: CharacterType, trailingSeparator: boolean = false, ): BbanStructurePart { return new BbanStructurePart(PartType.CURRENCY_TYPE, characterType, length, trailingSeparator); } static ownerAccountNumber( length: number, characterType: CharacterType, trailingSeparator: boolean = true, ): BbanStructurePart { return new BbanStructurePart(PartType.OWNER_ACCOUNT_NUMBER, characterType, length, trailingSeparator); } static identificationNumber( length: number, characterType: CharacterType, trailingSeparator: boolean = true, ): BbanStructurePart { return new BbanStructurePart(PartType.IDENTIFICATION_NUMBER, characterType, length, trailingSeparator); } getPartType(): PartType { return this.entryType; } getCharacterType(): CharacterType { return this.characterType; } getLength(): number { return this.length; } /** * Check to see if the string value is valid for the entry */ validate(value: string): boolean { return charByCharacterRE[this.characterType].test(value); } /** * Default generator to use -- just generate random sequence */ // eslint-disable-next-line @typescript-eslint/no-unused-vars private defaultGenerator(bban: string, structure: BbanStructure): string { const charChoices = charByCharacterType[this.characterType]; const s: string[] = []; for (let i = 0; i < this.getLength(); i += 1) { s.push(charChoices[randInt(charChoices.length)]); } return s.join(""); } }