@parafin/react 6.4.1 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/index.d.ts +2 -57
- package/out/index.js +73 -53
- package/package.json +5 -4
package/out/index.d.ts
CHANGED
|
@@ -1,58 +1,3 @@
|
|
|
1
|
+
import { LinkOpenedMetadata, WidgetProps, WidgetEvent, WidgetEventMetadata } from '@parafin/core';
|
|
1
2
|
declare const ParafinWidget: (props: WidgetProps) => import("react/jsx-runtime").JSX.Element;
|
|
2
|
-
export { ParafinWidget };
|
|
3
|
-
export type WidgetEvent = 'opted_in' | 'opted_out';
|
|
4
|
-
export type LinkOpenedMetadata = {
|
|
5
|
-
type: 'auth' | 'document' | 'webpage' | 'phone' | 'email';
|
|
6
|
-
};
|
|
7
|
-
export type WidgetProps = {
|
|
8
|
-
token: string;
|
|
9
|
-
product: 'capital' | 'spend_card' | 'cash_account';
|
|
10
|
-
externalBusinessId?: string;
|
|
11
|
-
onEvent?: (eventType: WidgetEvent) => Promise<void> | void;
|
|
12
|
-
onExit?: () => void;
|
|
13
|
-
/** @deprecated Use onEvent with 'opted_in' event type instead */
|
|
14
|
-
onOptIn?: () => Promise<OptInFields>;
|
|
15
|
-
openInNewTab?: boolean;
|
|
16
|
-
onLinkOpened?: (url: string, metadata: LinkOpenedMetadata) => void;
|
|
17
|
-
inWebView?: boolean;
|
|
18
|
-
};
|
|
19
|
-
type USStates = 'AL' | 'AK' | 'AZ' | 'AR' | 'CA' | 'CO' | 'CT' | 'DE' | 'DC' | 'FL' | 'GA' | 'HI' | 'ID' | 'IL' | 'IN' | 'IA' | 'KS' | 'KY' | 'LA' | 'ME' | 'MD' | 'MA' | 'MI' | 'MN' | 'MS' | 'MO' | 'MT' | 'NE' | 'NV' | 'NH' | 'NJ' | 'NM' | 'NY' | 'NC' | 'ND' | 'OH' | 'OK' | 'OR' | 'PA' | 'RI' | 'SC' | 'SD' | 'TN' | 'TX' | 'UT' | 'VT' | 'VA' | 'WA' | 'WV' | 'WI' | 'WY';
|
|
20
|
-
type USTerritories = 'AS' | 'GU' | 'MP' | 'PR' | 'VI';
|
|
21
|
-
type CanadianProvinces = 'AB' | 'BC' | 'MB' | 'NB' | 'NL' | 'NS' | 'QC' | 'ON' | 'PE' | 'SK';
|
|
22
|
-
type CanadianTerritories = 'NT' | 'NU' | 'YT';
|
|
23
|
-
type Address = {
|
|
24
|
-
addressLine1: string;
|
|
25
|
-
addressLine2?: string;
|
|
26
|
-
city: string;
|
|
27
|
-
state: USStates | USTerritories | CanadianProvinces | CanadianTerritories;
|
|
28
|
-
postalCode: string;
|
|
29
|
-
country: 'US' | 'CA';
|
|
30
|
-
};
|
|
31
|
-
export type OptInFields = {
|
|
32
|
-
businessExternalId: string;
|
|
33
|
-
accountManagers?: {
|
|
34
|
-
name: string;
|
|
35
|
-
email: string;
|
|
36
|
-
}[];
|
|
37
|
-
owner: {
|
|
38
|
-
firstName: string;
|
|
39
|
-
lastName: string;
|
|
40
|
-
email: string;
|
|
41
|
-
phoneNumber?: string;
|
|
42
|
-
/** yyyy-mm-dd */
|
|
43
|
-
dateOfBirth?: string;
|
|
44
|
-
address?: Address;
|
|
45
|
-
};
|
|
46
|
-
business: {
|
|
47
|
-
legalName: string;
|
|
48
|
-
dbaName?: string;
|
|
49
|
-
address?: Address;
|
|
50
|
-
/** yyyy-mm-dd */
|
|
51
|
-
dateEstablished?: string;
|
|
52
|
-
};
|
|
53
|
-
bank?: {
|
|
54
|
-
routingNumber?: string;
|
|
55
|
-
accountNumberLastFour?: string;
|
|
56
|
-
currencyCode?: 'USD' | 'CAD';
|
|
57
|
-
};
|
|
58
|
-
};
|
|
3
|
+
export { ParafinWidget, type WidgetEvent, type WidgetEventMetadata, type WidgetProps, type LinkOpenedMetadata, };
|
package/out/index.js
CHANGED
|
@@ -7,33 +7,41 @@ const openParafinDashboard = (props) => {
|
|
|
7
7
|
// @ts-ignore
|
|
8
8
|
props.dashboardUrlOverride ?? 'https://app.parafin.com');
|
|
9
9
|
const route = 'route' in props ? props.route : '/';
|
|
10
|
-
const addPropIfExists = (key) => {
|
|
11
|
-
if (key in props && props[key] !== undefined && props[key] !== null) {
|
|
12
|
-
return { [key]: props[key] };
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
return {};
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
10
|
const query = {
|
|
19
11
|
product: props.product,
|
|
20
12
|
referrer: 'partner',
|
|
21
|
-
...
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
...
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
...('token' in props &&
|
|
14
|
+
props.token !== undefined &&
|
|
15
|
+
props.token !== null && { token: props.token }),
|
|
16
|
+
...('partner' in props &&
|
|
17
|
+
props.partner !== undefined &&
|
|
18
|
+
props.partner !== null && { partner: props.partner }),
|
|
19
|
+
...('externalBusinessId' in props &&
|
|
20
|
+
props.externalBusinessId !== undefined &&
|
|
21
|
+
props.externalBusinessId !== null && {
|
|
22
|
+
externalBusinessId: props.externalBusinessId,
|
|
23
|
+
}),
|
|
24
|
+
...('orderId' in props &&
|
|
25
|
+
props.orderId !== undefined &&
|
|
26
|
+
props.orderId !== null && { orderId: props.orderId }),
|
|
27
|
+
...('lineOfCreditApplicationId' in props &&
|
|
28
|
+
props.lineOfCreditApplicationId !== undefined &&
|
|
29
|
+
props.lineOfCreditApplicationId !== null && {
|
|
30
|
+
lineOfCreditApplicationId: props.lineOfCreditApplicationId,
|
|
31
|
+
}),
|
|
32
|
+
...('inWebView' in props &&
|
|
33
|
+
props.inWebView !== undefined &&
|
|
34
|
+
props.inWebView !== null && { inWebView: props.inWebView.toString() }),
|
|
27
35
|
...Object.fromEntries(searchParams),
|
|
28
36
|
};
|
|
29
37
|
const url = `${origin}${route}?${new URLSearchParams(query).toString()}`;
|
|
30
38
|
if ('openInNewTab' in props && props.openInNewTab) {
|
|
31
39
|
window.open(url, '_blank');
|
|
32
|
-
return;
|
|
40
|
+
return () => { }; // noop
|
|
33
41
|
}
|
|
34
42
|
if ('mode' in props && props.mode === 'redirect') {
|
|
35
43
|
window.location.href = url;
|
|
36
|
-
return;
|
|
44
|
+
return () => { }; // noop
|
|
37
45
|
}
|
|
38
46
|
const existingParafinDashboard = document.getElementById('parafin-dashboard');
|
|
39
47
|
if (existingParafinDashboard) {
|
|
@@ -72,17 +80,25 @@ const openParafinDashboard = (props) => {
|
|
|
72
80
|
props.onExit?.();
|
|
73
81
|
}
|
|
74
82
|
};
|
|
83
|
+
let cleanedUp = false;
|
|
84
|
+
const cleanup = ({ withOnExit }) => {
|
|
85
|
+
if (cleanedUp)
|
|
86
|
+
return; // noop
|
|
87
|
+
cleanedUp = true;
|
|
88
|
+
window.removeEventListener('message', messageListener);
|
|
89
|
+
frame.style.opacity = '0';
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
if (withOnExit)
|
|
92
|
+
onExit();
|
|
93
|
+
dashboardTargetElement.removeChild(frame);
|
|
94
|
+
document.body.style.removeProperty('overflow');
|
|
95
|
+
}, 200);
|
|
96
|
+
};
|
|
75
97
|
const messageListener = async (event) => {
|
|
76
98
|
if (event.origin === origin) {
|
|
77
99
|
switch (event.data?.message) {
|
|
78
100
|
case 'close-dashboard':
|
|
79
|
-
|
|
80
|
-
frame.style.opacity = '0';
|
|
81
|
-
setTimeout(() => {
|
|
82
|
-
onExit();
|
|
83
|
-
dashboardTargetElement.removeChild(frame);
|
|
84
|
-
document.body.style.removeProperty('overflow');
|
|
85
|
-
}, 200);
|
|
101
|
+
cleanup({ withOnExit: true });
|
|
86
102
|
break;
|
|
87
103
|
case 'link-opened':
|
|
88
104
|
if (props.onLinkOpened && event.data?.url && event.data?.metadata) {
|
|
@@ -97,20 +113,33 @@ const openParafinDashboard = (props) => {
|
|
|
97
113
|
setTimeout(() => {
|
|
98
114
|
frame.style.opacity = '1';
|
|
99
115
|
document.body.style.overflow = 'hidden';
|
|
100
|
-
},
|
|
116
|
+
}, 0);
|
|
117
|
+
return () => cleanup({ withOnExit: false });
|
|
101
118
|
}
|
|
102
119
|
catch (error) {
|
|
103
120
|
console.error('Error loading Parafin dashboard', error);
|
|
121
|
+
return () => { }; // noop
|
|
104
122
|
}
|
|
105
123
|
};
|
|
106
|
-
|
|
107
|
-
|
|
124
|
+
const defaultWidgetStyles = {
|
|
125
|
+
width: '100%',
|
|
126
|
+
height: '258px',
|
|
127
|
+
backgroundColor: '#fff',
|
|
128
|
+
border: '1px solid #E8E8E8',
|
|
129
|
+
borderRadius: '16px',
|
|
130
|
+
transition: 'border 0.2s, border-radius 0.2s',
|
|
131
|
+
boxSizing: 'border-box',
|
|
132
|
+
};
|
|
133
|
+
const emptyMetadata = {
|
|
134
|
+
timeToLoadInMs: null,
|
|
135
|
+
};
|
|
136
|
+
const initializeParafinWidget = (iframe, props) => {
|
|
137
|
+
const initStartTime = Date.now();
|
|
108
138
|
// @ts-ignore
|
|
109
139
|
const url = new URL(props.widgetUrlOverride ?? 'https://widget.parafin.com');
|
|
110
140
|
const query = {
|
|
111
141
|
token: props.token,
|
|
112
142
|
product: props.product,
|
|
113
|
-
hasOptIn: props.onOptIn ? 'true' : 'false',
|
|
114
143
|
host: window.location.origin,
|
|
115
144
|
externalBusinessId: props.externalBusinessId ?? '',
|
|
116
145
|
...Object.fromEntries(url.searchParams),
|
|
@@ -133,6 +162,9 @@ const initializeWidget = (iframe, props) => {
|
|
|
133
162
|
}
|
|
134
163
|
break;
|
|
135
164
|
case 'open-dashboard':
|
|
165
|
+
if (props.onEvent) {
|
|
166
|
+
props.onEvent('dashboard_opened', emptyMetadata);
|
|
167
|
+
}
|
|
136
168
|
openParafinDashboard({
|
|
137
169
|
...props,
|
|
138
170
|
route: data?.route,
|
|
@@ -142,24 +174,10 @@ const initializeWidget = (iframe, props) => {
|
|
|
142
174
|
},
|
|
143
175
|
});
|
|
144
176
|
break;
|
|
145
|
-
case 'opt-in':
|
|
146
|
-
if (props.onOptIn) {
|
|
147
|
-
try {
|
|
148
|
-
const optInFields = await props.onOptIn();
|
|
149
|
-
sendMessage({ message: 'opt-in', optInFields });
|
|
150
|
-
}
|
|
151
|
-
catch {
|
|
152
|
-
sendMessage({ message: 'opt-in', optInFields: undefined });
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
sendMessage({ message: 'opt-in', optInFields: undefined });
|
|
157
|
-
}
|
|
158
|
-
break;
|
|
159
177
|
case 'person-opt-in':
|
|
160
178
|
if (props.onEvent) {
|
|
161
179
|
try {
|
|
162
|
-
await props.onEvent('opted_in');
|
|
180
|
+
await props.onEvent('opted_in', emptyMetadata);
|
|
163
181
|
sendMessage({ message: 'person-opt-in', state: 'success' });
|
|
164
182
|
}
|
|
165
183
|
catch {
|
|
@@ -173,7 +191,7 @@ const initializeWidget = (iframe, props) => {
|
|
|
173
191
|
case 'person-opt-out':
|
|
174
192
|
if (props.onEvent) {
|
|
175
193
|
try {
|
|
176
|
-
await props.onEvent('opted_out');
|
|
194
|
+
await props.onEvent('opted_out', emptyMetadata);
|
|
177
195
|
sendMessage({ message: 'person-opt-out', state: 'success' });
|
|
178
196
|
}
|
|
179
197
|
catch {
|
|
@@ -189,27 +207,29 @@ const initializeWidget = (iframe, props) => {
|
|
|
189
207
|
iframe.style.height = data.height;
|
|
190
208
|
}
|
|
191
209
|
break;
|
|
210
|
+
case 'widget-error':
|
|
211
|
+
if (props.onEvent) {
|
|
212
|
+
props.onEvent('widget_error', emptyMetadata);
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
case 'widget-load-complete':
|
|
216
|
+
if (props.onEvent) {
|
|
217
|
+
const timeToLoadInMs = Date.now() - initStartTime;
|
|
218
|
+
props.onEvent('widget_loaded', { timeToLoadInMs });
|
|
219
|
+
}
|
|
220
|
+
break;
|
|
192
221
|
}
|
|
193
222
|
}
|
|
194
223
|
};
|
|
195
224
|
window.addEventListener('message', messageListener);
|
|
196
225
|
return () => window.removeEventListener('message', messageListener);
|
|
197
226
|
};
|
|
198
|
-
const defaultWidgetStyles = {
|
|
199
|
-
width: '100%',
|
|
200
|
-
height: '258px',
|
|
201
|
-
backgroundColor: '#fff',
|
|
202
|
-
border: '1px solid #E8E8E8',
|
|
203
|
-
borderRadius: '16px',
|
|
204
|
-
transition: 'border 0.2s, border-radius 0.2s',
|
|
205
|
-
boxSizing: 'border-box',
|
|
206
|
-
};
|
|
207
227
|
|
|
208
228
|
const ParafinWidget = (props) => {
|
|
209
229
|
const frameRef = useRef(null);
|
|
210
230
|
useEffect(() => {
|
|
211
231
|
if (frameRef.current) {
|
|
212
|
-
const cleanup =
|
|
232
|
+
const cleanup = initializeParafinWidget(frameRef.current, props);
|
|
213
233
|
return cleanup;
|
|
214
234
|
}
|
|
215
235
|
}, [props]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parafin/react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.1.0",
|
|
4
4
|
"description": "Parafin React widget",
|
|
5
5
|
"author": "Parafin (https://www.parafin.com)",
|
|
6
6
|
"module": "out/index.js",
|
|
@@ -23,8 +23,9 @@
|
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/react": ">=16.8.0",
|
|
26
|
-
"typescript": "^4.9.5"
|
|
27
|
-
"@parafin/widget": "*"
|
|
26
|
+
"typescript": "^4.9.5"
|
|
28
27
|
},
|
|
29
|
-
"dependencies": {
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@parafin/core": "^3.1.0"
|
|
30
|
+
}
|
|
30
31
|
}
|