UNPKG

credit-card-type

Version:

A library for determining credit card type

152 lines (117 loc) 3.67 kB
import cardTypes = require("./lib/card-types"); import { addMatchingCardsToResults } from "./lib/add-matching-cards-to-results"; import { isValidInputType } from "./lib/is-valid-input-type"; import { findBestMatch } from "./lib/find-best-match"; import { clone } from "./lib/clone"; import type { CreditCardType, CardCollection, CreditCardTypeCardBrandId, } from "./types"; let customCards = {} as CardCollection; const cardNames: Record<string, CreditCardTypeCardBrandId> = { VISA: "visa", MASTERCARD: "mastercard", AMERICAN_EXPRESS: "american-express", DINERS_CLUB: "diners-club", DISCOVER: "discover", JCB: "jcb", UNIONPAY: "unionpay", MAESTRO: "maestro", ELO: "elo", MIR: "mir", HIPER: "hiper", HIPERCARD: "hipercard", }; const ORIGINAL_TEST_ORDER = [ cardNames.VISA, cardNames.MASTERCARD, cardNames.AMERICAN_EXPRESS, cardNames.DINERS_CLUB, cardNames.DISCOVER, cardNames.JCB, cardNames.UNIONPAY, cardNames.MAESTRO, cardNames.ELO, cardNames.MIR, cardNames.HIPER, cardNames.HIPERCARD, ]; let testOrder = clone(ORIGINAL_TEST_ORDER) as string[]; function findType(cardType: string | number): CreditCardType { return customCards[cardType] || cardTypes[cardType]; } function getAllCardTypes(): CreditCardType[] { return testOrder.map( (cardType) => clone(findType(cardType)) as CreditCardType, ); } function getCardPosition( name: string, ignoreErrorForNotExisting = false, ): number { const position = testOrder.indexOf(name); if (!ignoreErrorForNotExisting && position === -1) { throw new Error('"' + name + '" is not a supported card type.'); } return position; } function creditCardType(cardNumber: string): Array<CreditCardType> { const results = [] as CreditCardType[]; if (!isValidInputType(cardNumber)) { return results; } if (cardNumber.length === 0) { return getAllCardTypes(); } testOrder.forEach((cardType) => { const cardConfiguration = findType(cardType); addMatchingCardsToResults(cardNumber, cardConfiguration, results); }); const bestMatch = findBestMatch(results) as CreditCardType; if (bestMatch) { return [bestMatch]; } return results; } creditCardType.getTypeInfo = (cardType: string): CreditCardType => clone(findType(cardType)) as CreditCardType; creditCardType.removeCard = (name: string): void => { const position = getCardPosition(name); testOrder.splice(position, 1); }; creditCardType.addCard = (config: CreditCardType): void => { const existingCardPosition = getCardPosition(config.type, true); customCards[config.type] = config; if (existingCardPosition === -1) { testOrder.push(config.type); } }; creditCardType.updateCard = ( cardType: string, updates: Partial<CreditCardType>, ): void => { const originalObject = customCards[cardType] || cardTypes[cardType]; if (!originalObject) { throw new Error( `"${cardType}" is not a recognized type. Use \`addCard\` instead.'`, ); } if (updates.type && originalObject.type !== updates.type) { throw new Error("Cannot overwrite type parameter."); } let clonedCard = clone(originalObject) as CreditCardType; clonedCard = { ...clonedCard, ...updates }; customCards[clonedCard.type] = clonedCard; }; creditCardType.changeOrder = (name: string, position: number): void => { const currentPosition = getCardPosition(name); testOrder.splice(currentPosition, 1); testOrder.splice(position, 0, name); }; creditCardType.resetModifications = (): void => { testOrder = clone(ORIGINAL_TEST_ORDER) as string[]; customCards = {}; }; creditCardType.types = cardNames; export = creditCardType;