From 972c14ff3ad0ffcdb0ba52571b994f69d247d3bb Mon Sep 17 00:00:00 2001 From: Kevin Peraza Date: Mon, 17 Mar 2025 22:45:53 +0100 Subject: [PATCH] fix: add types for card number element events (#82) * feat: upgrade btjs * fix: use cvcLength in cvc validator * docs: update demo to use dynamic cvc instead * fix: remove unused import * docs: update readme --- README.md | 13 +++++-- demo/Collect.tsx | 10 ++++- src/BaseElementTypes.ts | 37 +++++++++++++++++++ .../CardVerificationCodeElement.hook.ts | 2 +- src/utils/validation.ts | 19 +++++++--- 5 files changed, 70 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e206205..85aa750 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,14 @@ # Basis Theory React Native SDK -[![Version](https://img.shields.io/npm/v/@basis-theory/react-native-elements.svg)](https://www.npmjs.org/package/@basis-theory/react-native-elements) -[![Downloads](https://img.shields.io/npm/dm/@basis-theory/react-native-elements.svg)](https://www.npmjs.org/package/@basis-theory/react-native-elements) -[![Verify](https://github.com/Basis-Theory/react-native-elements/actions/workflows/release.yml/badge.svg)](https://github.com/Basis-Theory/react-native-elements/actions/workflows/release.yml) +> [!CAUTION] +> This SDK has been deprecated. +> +> Our new SDK can be found at https://github.com/Basis-Theory/react-native-elements +> +> See our documentation site for more information. [https://developers.basistheory.com/docs/sdks/mobile/react-native](https://developers.basistheory.com/docs/sdks/mobile/react-native/) + +[![Version](https://img.shields.io/npm/v/@basis-theory/basis-theory-react-native.svg)](https://www.npmjs.org/package/@basis-theory/basis-theory-react-native) +[![Downloads](https://img.shields.io/npm/dm/@basis-theory/basis-theory-react-native.svg)](https://www.npmjs.org/package/@basis-theory/basis-theory-react-native) +[![Verify](https://github.com/Basis-Theory/basis-theory-react-native/actions/workflows/release.yml/badge.svg)](https://github.com/Basis-Theory/basis-theory-react-native/actions/workflows/release.yml) The [Basis Theory](https://basistheory.com/) React Native SDK diff --git a/demo/Collect.tsx b/demo/Collect.tsx index 1fa86de..cdc5971 100644 --- a/demo/Collect.tsx +++ b/demo/Collect.tsx @@ -47,6 +47,8 @@ export const Collect = () => { const { bt, error } = useBasisTheory(''); + const [cvcLength, setCvcLength] = useState(); + useEffect(() => { if (error) { console.log(error); @@ -56,6 +58,10 @@ export const Collect = () => { const updateElementsEvents = (eventSource: 'cardExpirationDate' | 'cardNumber' | 'cvc') => (event: ElementEvent) => { + if (event.cvcLength) { + setCvcLength(event.cvcLength); + } + setElementsEvents({ ...elementsEvents, [eventSource]: event, @@ -177,10 +183,10 @@ export const Collect = () => { /> diff --git a/src/BaseElementTypes.ts b/src/BaseElementTypes.ts index ad4772e..19709a3 100644 --- a/src/BaseElementTypes.ts +++ b/src/BaseElementTypes.ts @@ -71,6 +71,43 @@ type ElementEvent = { * Array of objects that indicates if an element is invalid or incomplete. */ errors?: FieldError[]; + + /** + * Card brand identifier + * Only present for card number elements + */ + brand?: + | string + | 'american-express' + | 'diners-club' + | 'discover' + | 'ebt' + | 'elo' + | 'hiper' + | 'hipercard' + | 'jcb' + | 'maestro' + | 'mastercard' + | 'mir' + | 'private-label' + | 'proprietary' + | 'unionpay' + | 'visa'; + /** + * Last 4 digits of the card number + * Only present for card number elements + */ + cardLast4?: string; + /** + * Required length of the CVC for the detected card brand + * Only present for card number elements + */ + cvcLength?: number; + /** + * Bank Identification Number (first 6-8 digits of card number) + * Only present for card number elements + */ + cardBin?: string; }; type EventConsumer = (event: ElementEvent) => void; diff --git a/src/components/CardVerificationCodeElement.hook.ts b/src/components/CardVerificationCodeElement.hook.ts index 7fa95e6..a5300a5 100644 --- a/src/components/CardVerificationCodeElement.hook.ts +++ b/src/components/CardVerificationCodeElement.hook.ts @@ -51,7 +51,7 @@ export const useCardVerificationCodeElement = ({ setElementValue, element: { id, - validatorOptions: { mask }, + validatorOptions: { mask, cvcLength: [cvcLength] }, type, }, onBlur, diff --git a/src/utils/validation.ts b/src/utils/validation.ts index 303d86f..1510a27 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -1,5 +1,5 @@ import { cvv, expirationDate, number } from 'card-validator'; -import { flip, isEmpty, partial, split } from 'ramda'; +import { isEmpty, partial, split } from 'ramda'; import type { Mask, ValidationResult } from '../BaseElementTypes'; import { ElementType } from '../BaseElementTypes'; import { @@ -16,7 +16,8 @@ type ValidatorResult = { type ValidatorFunction = (value: string) => ValidatorResult; -const _cardCvvValidator = partial(flip(cvv), [[3, 4]]); +const _cardCvvValidator = (length = [3, 4], value: string) => + cvv(value, length); interface CardNumberValidatorOptions { skipLuhnValidation?: boolean; @@ -26,8 +27,13 @@ interface TextValidatorOptions { mask?: Mask; } +interface CvcValidatorOptions { + cvcLength?: number[]; +} + export type ValidatorOptions = CardNumberValidatorOptions & - TextValidatorOptions; + TextValidatorOptions & + CvcValidatorOptions; const _cardNumberValidator = ( options: CardNumberValidatorOptions = {}, @@ -148,8 +154,11 @@ const cardExpirationDateValidator = ( expirationDate: string ): ValidationResult => runValidator(expirationDate, _expirationDateValidator); -const cardVerificationCodeValidator = (cvc: string): ValidationResult => - runValidator(cvc, _cardCvvValidator); +const cardVerificationCodeValidator = ( + cvc: string, + validatorOptions?: ValidatorOptions +): ValidationResult => + runValidator(cvc, partial(_cardCvvValidator, [validatorOptions?.cvcLength])); const textMaskValidator = ( value: string,