react-plaid-link
Version:
A React component for Plaid Link
115 lines (100 loc) • 2.49 kB
text/typescript
import {
PlaidLinkOptions,
PlaidHandler,
PlaidHandlerSubmissionData,
CommonPlaidLinkOptions,
} from './types';
export interface PlaidFactory {
open: (() => void) | Function;
submit: ((data: PlaidHandlerSubmissionData) => void)| Function;
exit: ((exitOptions: any, callback: () => void) => void) | Function;
destroy: (() => void) | Function;
}
interface FactoryInternalState {
plaid: PlaidHandler | null;
open: boolean;
onExitCallback: (() => void) | null | Function;
}
const renameKeyInObject = (
o: { [index: string]: any },
oldKey: string,
newKey: string
): object => {
const newObject = {};
delete Object.assign(newObject, o, { [newKey]: o[oldKey] })[oldKey];
return newObject;
};
/**
* Wrap link handler creation and instance to clean up iframe via destroy() method
*/
const createPlaidHandler = <T extends CommonPlaidLinkOptions<{}>>(
config: T,
creator: (config: T) => PlaidHandler
) => {
const state: FactoryInternalState = {
plaid: null,
open: false,
onExitCallback: null,
};
// If Plaid is not available, throw an Error
if (typeof window === 'undefined' || !window.Plaid) {
throw new Error('Plaid not loaded');
}
state.plaid = creator({
...config,
onExit: (error, metadata) => {
state.open = false;
config.onExit && config.onExit(error, metadata);
state.onExitCallback && state.onExitCallback();
},
});
const open = () => {
if (!state.plaid) {
return;
}
state.open = true;
state.onExitCallback = null;
state.plaid.open();
};
const submit = (data: PlaidHandlerSubmissionData) => {
if (!state.plaid) {
return;
}
state.plaid.submit(data)
}
const exit = (exitOptions: any, callback: (() => void) | Function) => {
if (!state.open || !state.plaid) {
callback && callback();
return;
}
state.onExitCallback = callback;
state.plaid.exit(exitOptions);
if (exitOptions && exitOptions.force) {
state.open = false;
}
};
const destroy = () => {
if (!state.plaid) {
return;
}
state.plaid.destroy();
state.plaid = null;
};
return {
open,
submit,
exit,
destroy,
};
};
export const createPlaid = (
options: PlaidLinkOptions,
creator: (options: PlaidLinkOptions) => PlaidHandler
) => {
const config = renameKeyInObject(
options,
'publicKey',
'key'
) as PlaidLinkOptions;
return createPlaidHandler(config, creator);
};