@quiltt/react 4.3.2 → 4.4.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/CHANGELOG.md +50 -0
- package/dist/{QuilttAuthProvider-12s-D-Wr7LUT.js → QuilttAuthProvider-12s-4hQ7iysR.js} +4 -1
- package/dist/index.d.ts +17 -2
- package/dist/index.js +6 -5
- package/dist/{useQuilttConnector-12s-BJljrsWT.js → useQuilttConnector-12s-BiIbmt7I.js} +3 -3
- package/dist/{useQuilttInstitutions-12s-PJd2C3BF.js → useQuilttInstitutions-12s-0_y37UHg.js} +5 -5
- package/dist/useQuilttResolvable-12s-C2mjy5zs.js +79 -0
- package/dist/{useQuilttSession-12s-CwVw-aOM.js → useQuilttSession-12s-BCq3OL9S.js} +1 -1
- package/package.json +2 -2
- package/src/hooks/index.ts +1 -0
- package/src/hooks/session/useIdentifySession.ts +5 -0
- package/src/hooks/useQuilttInstitutions.ts +5 -8
- package/src/hooks/useQuilttResolvable.ts +127 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# @quiltt/react
|
|
2
2
|
|
|
3
|
+
## 4.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#378](https://github.com/quiltt/quiltt-js/pull/378) [`0af4e66`](https://github.com/quiltt/quiltt-js/commit/0af4e6622d1542e0c0c02ac7e897e3e4f9219cbd) Thanks [@sirwolfgang](https://github.com/sirwolfgang)! - Add connector institution search and provider migration support.
|
|
8
|
+
|
|
9
|
+
## New APIs
|
|
10
|
+
|
|
11
|
+
### `useQuilttResolvable` Hook
|
|
12
|
+
|
|
13
|
+
Check if external provider institution IDs (e.g., Plaid) can be migrated to your connector.
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { useQuilttResolvable } from "@quiltt/react";
|
|
17
|
+
import { useEffect } from "react";
|
|
18
|
+
|
|
19
|
+
function ResolvableConnector({ plaidInstitutionId, children }) {
|
|
20
|
+
const { checkResolvable, isResolvable, isLoading } =
|
|
21
|
+
useQuilttResolvable("my-connector-id");
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
checkResolvable({ plaid: plaidInstitutionId });
|
|
25
|
+
}, [plaidInstitutionId]);
|
|
26
|
+
|
|
27
|
+
if (isLoading) return <div>Checking...</div>;
|
|
28
|
+
if (!isResolvable) return null;
|
|
29
|
+
|
|
30
|
+
return <>{children}</>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Usage
|
|
34
|
+
<ResolvableConnector plaidInstitutionId="ins_3">
|
|
35
|
+
<QuilttButton connectorId="my-connector-id" />
|
|
36
|
+
</ResolvableConnector>;
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Patch Changes
|
|
40
|
+
|
|
41
|
+
- Updated dependencies [[`0af4e66`](https://github.com/quiltt/quiltt-js/commit/0af4e6622d1542e0c0c02ac7e897e3e4f9219cbd)]:
|
|
42
|
+
- @quiltt/core@4.4.0
|
|
43
|
+
|
|
44
|
+
## 4.3.3
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- [#375](https://github.com/quiltt/quiltt-js/pull/375) [`fdc91e3`](https://github.com/quiltt/quiltt-js/commit/fdc91e3efb3f63659580f2d1d2ea0ff7fcaee8f5) Thanks [@sirwolfgang](https://github.com/sirwolfgang)! - Add 403 callback to Auth useIdentifySession
|
|
49
|
+
|
|
50
|
+
- Updated dependencies [[`fdc91e3`](https://github.com/quiltt/quiltt-js/commit/fdc91e3efb3f63659580f2d1d2ea0ff7fcaee8f5)]:
|
|
51
|
+
- @quiltt/core@4.3.3
|
|
52
|
+
|
|
3
53
|
## 4.3.2
|
|
4
54
|
|
|
5
55
|
### Patch Changes
|
|
@@ -7,7 +7,7 @@ import './useSession-12s-7GOn4sUn.js';
|
|
|
7
7
|
import 'use-debounce';
|
|
8
8
|
import { jsx } from 'react/jsx-runtime';
|
|
9
9
|
import { ApolloProvider } from '@apollo/client/react/context/ApolloProvider.js';
|
|
10
|
-
import { u as useQuilttSession } from './useQuilttSession-12s-
|
|
10
|
+
import { u as useQuilttSession } from './useQuilttSession-12s-BCq3OL9S.js';
|
|
11
11
|
|
|
12
12
|
const useAuthenticateSession = (auth, setSession)=>{
|
|
13
13
|
const authenticateSession = useCallback(async (payload, callbacks)=>{
|
|
@@ -44,6 +44,9 @@ const useIdentifySession = (auth, setSession)=>{
|
|
|
44
44
|
case 202:
|
|
45
45
|
if (callbacks.onChallenged) return callbacks.onChallenged();
|
|
46
46
|
break;
|
|
47
|
+
case 403:
|
|
48
|
+
if (callbacks.onForbidden) return callbacks.onForbidden();
|
|
49
|
+
break;
|
|
47
50
|
case 422:
|
|
48
51
|
if (callbacks.onError) return callbacks.onError(response.data);
|
|
49
52
|
break;
|
package/dist/index.d.ts
CHANGED
|
@@ -94,6 +94,7 @@ type IdentifySessionCallbacks = {
|
|
|
94
94
|
onSuccess?: () => unknown;
|
|
95
95
|
onChallenged?: () => unknown;
|
|
96
96
|
onError?: (errors: UnprocessableData) => unknown;
|
|
97
|
+
onForbidden?: () => unknown;
|
|
97
98
|
};
|
|
98
99
|
type IdentifySession = (payload: UsernamePayload, callbacks: IdentifySessionCallbacks) => Promise<unknown>;
|
|
99
100
|
type UseIdentifySession = (auth: AuthAPI, setSession: SetSession) => IdentifySession;
|
|
@@ -116,6 +117,20 @@ declare const useQuilttConnector: (connectorId?: string, options?: ConnectorSDKC
|
|
|
116
117
|
open: () => void;
|
|
117
118
|
};
|
|
118
119
|
|
|
120
|
+
type UseQuilttResolvable = (connectorId: string, onErrorCallback?: (msg: string) => void) => {
|
|
121
|
+
checkResolvable: (providerId: {
|
|
122
|
+
plaid?: string;
|
|
123
|
+
mock?: string;
|
|
124
|
+
mx?: string;
|
|
125
|
+
finicity?: string;
|
|
126
|
+
akoya?: string;
|
|
127
|
+
}) => Promise<boolean | null>;
|
|
128
|
+
isLoading: boolean;
|
|
129
|
+
isResolvable: boolean | null;
|
|
130
|
+
error: string | null;
|
|
131
|
+
};
|
|
132
|
+
declare const useQuilttResolvable: UseQuilttResolvable;
|
|
133
|
+
|
|
119
134
|
type UseQuilttInstitutions = (connectorId: string, onErrorCallback?: (msg: string) => void) => {
|
|
120
135
|
searchTerm: string;
|
|
121
136
|
searchResults: InstitutionsData;
|
|
@@ -181,5 +196,5 @@ declare const QuilttSettingsProvider: FC<QuilttSettingsProviderProps>;
|
|
|
181
196
|
type QuilttProviderProps = QuilttSettingsProviderProps & QuilttAuthProviderProps;
|
|
182
197
|
declare const QuilttProvider: FC<QuilttProviderProps>;
|
|
183
198
|
|
|
184
|
-
export { QuilttAuthProvider, QuilttButton, QuilttContainer, QuilttProvider, QuilttSettingsProvider, useAuthenticateSession, useEventListener, useIdentifySession, useImportSession, useIsomorphicLayoutEffect, useQuilttClient, useQuilttConnector, useQuilttInstitutions, useQuilttSession, useQuilttSettings, useRevokeSession, useSession, useStorage };
|
|
185
|
-
export type { AuthenticateSession, IdentifySession, ImportSession, QuilttAuthProviderProps, QuilttSettingsProviderProps, RevokeSession, SetSession, UseQuilttInstitutions, UseQuilttSession };
|
|
199
|
+
export { QuilttAuthProvider, QuilttButton, QuilttContainer, QuilttProvider, QuilttSettingsProvider, useAuthenticateSession, useEventListener, useIdentifySession, useImportSession, useIsomorphicLayoutEffect, useQuilttClient, useQuilttConnector, useQuilttInstitutions, useQuilttResolvable, useQuilttSession, useQuilttSettings, useRevokeSession, useSession, useStorage };
|
|
200
|
+
export type { AuthenticateSession, IdentifySession, ImportSession, QuilttAuthProviderProps, QuilttSettingsProviderProps, RevokeSession, SetSession, UseQuilttInstitutions, UseQuilttResolvable, UseQuilttSession };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
export * from '@quiltt/core';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { useRef, useEffect } from 'react';
|
|
4
|
-
import { u as useQuilttConnector } from './useQuilttConnector-12s-
|
|
5
|
-
import { i as isDeepEqual, Q as QuilttAuthProvider } from './QuilttAuthProvider-12s-
|
|
6
|
-
export { b as useAuthenticateSession, a as useIdentifySession, u as useImportSession, c as useRevokeSession } from './QuilttAuthProvider-12s-
|
|
4
|
+
import { u as useQuilttConnector } from './useQuilttConnector-12s-BiIbmt7I.js';
|
|
5
|
+
import { i as isDeepEqual, Q as QuilttAuthProvider } from './QuilttAuthProvider-12s-4hQ7iysR.js';
|
|
6
|
+
export { b as useAuthenticateSession, a as useIdentifySession, u as useImportSession, c as useRevokeSession } from './QuilttAuthProvider-12s-4hQ7iysR.js';
|
|
7
7
|
export { u as useEventListener } from './useEventListener-12s-D_-6QIXa.js';
|
|
8
8
|
export { u as useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect-12s-DeTHOKz1.js';
|
|
9
9
|
export { u as useQuilttClient } from './useQuilttClient-12s-CAAUait1.js';
|
|
10
|
-
export { u as
|
|
11
|
-
export { u as
|
|
10
|
+
export { u as useQuilttResolvable } from './useQuilttResolvable-12s-C2mjy5zs.js';
|
|
11
|
+
export { u as useQuilttInstitutions } from './useQuilttInstitutions-12s-0_y37UHg.js';
|
|
12
|
+
export { u as useQuilttSession } from './useQuilttSession-12s-BCq3OL9S.js';
|
|
12
13
|
export { u as useQuilttSettings } from './useQuilttSettings-12s--rCJoNHD.js';
|
|
13
14
|
export { u as useSession } from './useSession-12s-7GOn4sUn.js';
|
|
14
15
|
export { u as useStorage } from './useStorage-12s-DHcq3Kuh.js';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
3
|
import { cdnBase } from '@quiltt/core';
|
|
4
|
-
import { u as useQuilttSession } from './useQuilttSession-12s-
|
|
4
|
+
import { u as useQuilttSession } from './useQuilttSession-12s-BCq3OL9S.js';
|
|
5
5
|
import { u as useScript } from './useScript-12s-JCgaTW9n.js';
|
|
6
|
-
import { i as isDeepEqual } from './QuilttAuthProvider-12s-
|
|
6
|
+
import { i as isDeepEqual } from './QuilttAuthProvider-12s-4hQ7iysR.js';
|
|
7
7
|
|
|
8
|
-
var version = "4.
|
|
8
|
+
var version = "4.4.0";
|
|
9
9
|
|
|
10
10
|
const useQuilttConnector = (connectorId, options)=>{
|
|
11
11
|
const status = useScript(`${cdnBase}/v1/connector.js?agent=react-${version}`, {
|
package/dist/{useQuilttInstitutions-12s-PJd2C3BF.js → useQuilttInstitutions-12s-0_y37UHg.js}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useMemo, useState, useRef, useEffect, useCallback } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { ConnectorsAPI } from '@quiltt/core';
|
|
4
4
|
import { useDebounce } from 'use-debounce';
|
|
5
|
-
import { v as version } from './useQuilttConnector-12s-
|
|
5
|
+
import { v as version } from './useQuilttConnector-12s-BiIbmt7I.js';
|
|
6
6
|
import { u as useSession } from './useSession-12s-7GOn4sUn.js';
|
|
7
7
|
|
|
8
8
|
const useQuilttInstitutions = (connectorId, onErrorCallback)=>{
|
|
@@ -18,7 +18,7 @@ const useQuilttInstitutions = (connectorId, onErrorCallback)=>{
|
|
|
18
18
|
typeof navigator !== 'undefined');
|
|
19
19
|
return isReactNative ? `react-native-${version}` : `react-${version}`;
|
|
20
20
|
}, []);
|
|
21
|
-
const
|
|
21
|
+
const connectorsAPI = useMemo(()=>new ConnectorsAPI(connectorId, agent), [
|
|
22
22
|
connectorId,
|
|
23
23
|
agent
|
|
24
24
|
]);
|
|
@@ -58,7 +58,7 @@ const useQuilttInstitutions = (connectorId, onErrorCallback)=>{
|
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
const abortController = new AbortController();
|
|
61
|
-
|
|
61
|
+
connectorsAPI.searchInstitutions(session?.token, connectorId, searchTerm, abortController.signal).then((response)=>{
|
|
62
62
|
if (!abortController.signal.aborted) {
|
|
63
63
|
if (response.status === 200) {
|
|
64
64
|
setSearchResults(response.data);
|
|
@@ -78,7 +78,7 @@ const useQuilttInstitutions = (connectorId, onErrorCallback)=>{
|
|
|
78
78
|
session?.token,
|
|
79
79
|
connectorId,
|
|
80
80
|
searchTerm,
|
|
81
|
-
|
|
81
|
+
connectorsAPI,
|
|
82
82
|
handleError
|
|
83
83
|
]);
|
|
84
84
|
return {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useMemo, useState, useCallback } from 'react';
|
|
3
|
+
import { ConnectorsAPI } from '@quiltt/core';
|
|
4
|
+
import { v as version } from './useQuilttConnector-12s-BiIbmt7I.js';
|
|
5
|
+
import { u as useSession } from './useSession-12s-7GOn4sUn.js';
|
|
6
|
+
|
|
7
|
+
const useQuilttResolvable = (connectorId, onErrorCallback)=>{
|
|
8
|
+
const agent = useMemo(()=>{
|
|
9
|
+
// Try deprecated navigator.product first (still used in some RN versions)
|
|
10
|
+
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
|
|
11
|
+
return `react-native-${version}`;
|
|
12
|
+
}
|
|
13
|
+
// Detect React Native by its unique environment characteristics
|
|
14
|
+
const isReactNative = !!// Has window (unlike Node.js)
|
|
15
|
+
(typeof window !== 'undefined' && // No document in window (unlike browsers)
|
|
16
|
+
typeof window.document === 'undefined' && // Has navigator (unlike Node.js)
|
|
17
|
+
typeof navigator !== 'undefined');
|
|
18
|
+
return isReactNative ? `react-native-${version}` : `react-${version}`;
|
|
19
|
+
}, []);
|
|
20
|
+
const connectorsAPI = useMemo(()=>new ConnectorsAPI(connectorId, agent), [
|
|
21
|
+
connectorId,
|
|
22
|
+
agent
|
|
23
|
+
]);
|
|
24
|
+
const [session] = useSession();
|
|
25
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
26
|
+
const [isResolvable, setIsResolvable] = useState(null);
|
|
27
|
+
const [error, setError] = useState(null);
|
|
28
|
+
const handleError = useCallback((message)=>{
|
|
29
|
+
const errorMessage = message || 'Unknown error occurred while checking resolvability';
|
|
30
|
+
setError(errorMessage);
|
|
31
|
+
console.error('Quiltt Connector Resolvable Error:', errorMessage);
|
|
32
|
+
if (onErrorCallback) onErrorCallback(errorMessage);
|
|
33
|
+
}, [
|
|
34
|
+
onErrorCallback
|
|
35
|
+
]);
|
|
36
|
+
const checkResolvable = useCallback(async (providerId)=>{
|
|
37
|
+
if (!session?.token || !connectorId) {
|
|
38
|
+
handleError('Missing session token or connector ID');
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const hasProviderId = Object.values(providerId).some((id)=>!!id);
|
|
42
|
+
if (!hasProviderId) {
|
|
43
|
+
handleError('No provider ID specified');
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
setIsLoading(true);
|
|
47
|
+
setError(null);
|
|
48
|
+
try {
|
|
49
|
+
const response = await connectorsAPI.checkResolvable(session.token, connectorId, providerId);
|
|
50
|
+
if (response.status === 200) {
|
|
51
|
+
const result = response.data.resolvable;
|
|
52
|
+
setIsResolvable(result);
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
handleError(response.data.message || 'Failed to check resolvability');
|
|
56
|
+
setIsResolvable(null);
|
|
57
|
+
return null;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
handleError(error?.message);
|
|
60
|
+
setIsResolvable(null);
|
|
61
|
+
return null;
|
|
62
|
+
} finally{
|
|
63
|
+
setIsLoading(false);
|
|
64
|
+
}
|
|
65
|
+
}, [
|
|
66
|
+
session?.token,
|
|
67
|
+
connectorId,
|
|
68
|
+
connectorsAPI,
|
|
69
|
+
handleError
|
|
70
|
+
]);
|
|
71
|
+
return {
|
|
72
|
+
checkResolvable,
|
|
73
|
+
isLoading,
|
|
74
|
+
isResolvable,
|
|
75
|
+
error
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export { useQuilttResolvable as u };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
3
|
import { AuthAPI } from '@quiltt/core';
|
|
4
|
-
import { u as useImportSession, a as useIdentifySession, b as useAuthenticateSession, c as useRevokeSession } from './QuilttAuthProvider-12s-
|
|
4
|
+
import { u as useImportSession, a as useIdentifySession, b as useAuthenticateSession, c as useRevokeSession } from './QuilttAuthProvider-12s-4hQ7iysR.js';
|
|
5
5
|
import { u as useQuilttSettings } from './useQuilttSettings-12s--rCJoNHD.js';
|
|
6
6
|
import { u as useSession } from './useSession-12s-7GOn4sUn.js';
|
|
7
7
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quiltt/react",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"description": "React Components and Hooks for Quiltt Connector",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"quiltt",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@apollo/client": "^3.14.0",
|
|
38
38
|
"use-debounce": "^10.0.4",
|
|
39
|
-
"@quiltt/core": "4.
|
|
39
|
+
"@quiltt/core": "4.4.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@biomejs/biome": "2.2.4",
|
package/src/hooks/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './helpers'
|
|
|
2
2
|
export * from './session'
|
|
3
3
|
export * from './useQuilttClient'
|
|
4
4
|
export * from './useQuilttConnector'
|
|
5
|
+
export * from './useQuilttResolvable'
|
|
5
6
|
export * from './useQuilttInstitutions'
|
|
6
7
|
export * from './useQuilttSession'
|
|
7
8
|
export * from './useQuilttSettings'
|
|
@@ -14,6 +14,7 @@ type IdentifySessionCallbacks = {
|
|
|
14
14
|
onSuccess?: () => unknown
|
|
15
15
|
onChallenged?: () => unknown
|
|
16
16
|
onError?: (errors: UnprocessableData) => unknown
|
|
17
|
+
onForbidden?: () => unknown
|
|
17
18
|
}
|
|
18
19
|
export type IdentifySession = (
|
|
19
20
|
payload: UsernamePayload,
|
|
@@ -37,6 +38,10 @@ export const useIdentifySession: UseIdentifySession = (auth, setSession) => {
|
|
|
37
38
|
if (callbacks.onChallenged) return callbacks.onChallenged()
|
|
38
39
|
break
|
|
39
40
|
|
|
41
|
+
case 403: // Forbidden (signups disabled)
|
|
42
|
+
if (callbacks.onForbidden) return callbacks.onForbidden()
|
|
43
|
+
break
|
|
44
|
+
|
|
40
45
|
case 422: // Unprocessable Content
|
|
41
46
|
if (callbacks.onError) return callbacks.onError((response as UnprocessableResponse).data)
|
|
42
47
|
break
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
4
4
|
|
|
5
5
|
import type { ErrorData, InstitutionsData } from '@quiltt/core'
|
|
6
|
-
import {
|
|
6
|
+
import { ConnectorsAPI } from '@quiltt/core'
|
|
7
7
|
import { useDebounce } from 'use-debounce'
|
|
8
8
|
|
|
9
9
|
import { version } from '../version'
|
|
@@ -41,10 +41,7 @@ export const useQuilttInstitutions: UseQuilttInstitutions = (connectorId, onErro
|
|
|
41
41
|
return isReactNative ? `react-native-${version}` : `react-${version}`
|
|
42
42
|
}, [])
|
|
43
43
|
|
|
44
|
-
const
|
|
45
|
-
() => new InstitutionsAPI(connectorId, agent),
|
|
46
|
-
[connectorId, agent]
|
|
47
|
-
)
|
|
44
|
+
const connectorsAPI = useMemo(() => new ConnectorsAPI(connectorId, agent), [connectorId, agent])
|
|
48
45
|
const [session] = useSession()
|
|
49
46
|
|
|
50
47
|
const [searchTermInput, setSearchTermInput] = useState('')
|
|
@@ -93,8 +90,8 @@ export const useQuilttInstitutions: UseQuilttInstitutions = (connectorId, onErro
|
|
|
93
90
|
|
|
94
91
|
const abortController = new AbortController()
|
|
95
92
|
|
|
96
|
-
|
|
97
|
-
.
|
|
93
|
+
connectorsAPI
|
|
94
|
+
.searchInstitutions(session?.token, connectorId, searchTerm, abortController.signal)
|
|
98
95
|
.then((response) => {
|
|
99
96
|
if (!abortController.signal.aborted) {
|
|
100
97
|
if (response.status === 200) {
|
|
@@ -113,7 +110,7 @@ export const useQuilttInstitutions: UseQuilttInstitutions = (connectorId, onErro
|
|
|
113
110
|
})
|
|
114
111
|
|
|
115
112
|
return () => abortController.abort()
|
|
116
|
-
}, [session?.token, connectorId, searchTerm,
|
|
113
|
+
}, [session?.token, connectorId, searchTerm, connectorsAPI, handleError])
|
|
117
114
|
|
|
118
115
|
return {
|
|
119
116
|
searchTerm,
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useCallback, useMemo, useState } from 'react'
|
|
4
|
+
|
|
5
|
+
import type { ErrorData, ResolvableData } from '@quiltt/core'
|
|
6
|
+
import { ConnectorsAPI } from '@quiltt/core'
|
|
7
|
+
|
|
8
|
+
import { version } from '../version'
|
|
9
|
+
import useSession from './useSession'
|
|
10
|
+
|
|
11
|
+
export type UseQuilttResolvable = (
|
|
12
|
+
connectorId: string,
|
|
13
|
+
onErrorCallback?: (msg: string) => void,
|
|
14
|
+
) => {
|
|
15
|
+
checkResolvable: (providerId: {
|
|
16
|
+
plaid?: string
|
|
17
|
+
mock?: string
|
|
18
|
+
mx?: string
|
|
19
|
+
finicity?: string
|
|
20
|
+
akoya?: string
|
|
21
|
+
}) => Promise<boolean | null>
|
|
22
|
+
isLoading: boolean
|
|
23
|
+
isResolvable: boolean | null
|
|
24
|
+
error: string | null
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const useQuilttResolvable: UseQuilttResolvable = (
|
|
28
|
+
connectorId,
|
|
29
|
+
onErrorCallback,
|
|
30
|
+
) => {
|
|
31
|
+
const agent = useMemo(() => {
|
|
32
|
+
// Try deprecated navigator.product first (still used in some RN versions)
|
|
33
|
+
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
|
|
34
|
+
return `react-native-${version}`
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Detect React Native by its unique environment characteristics
|
|
38
|
+
const isReactNative = !!(
|
|
39
|
+
// Has window (unlike Node.js)
|
|
40
|
+
(
|
|
41
|
+
typeof window !== 'undefined' &&
|
|
42
|
+
// No document in window (unlike browsers)
|
|
43
|
+
typeof window.document === 'undefined' &&
|
|
44
|
+
// Has navigator (unlike Node.js)
|
|
45
|
+
typeof navigator !== 'undefined'
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
return isReactNative ? `react-native-${version}` : `react-${version}`
|
|
50
|
+
}, [])
|
|
51
|
+
|
|
52
|
+
const connectorsAPI = useMemo(() => new ConnectorsAPI(connectorId, agent), [connectorId, agent])
|
|
53
|
+
const [session] = useSession()
|
|
54
|
+
|
|
55
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
56
|
+
const [isResolvable, setIsResolvable] = useState<boolean | null>(null)
|
|
57
|
+
const [error, setError] = useState<string | null>(null)
|
|
58
|
+
|
|
59
|
+
const handleError = useCallback(
|
|
60
|
+
(message: string) => {
|
|
61
|
+
const errorMessage = message || 'Unknown error occurred while checking resolvability'
|
|
62
|
+
|
|
63
|
+
setError(errorMessage)
|
|
64
|
+
console.error('Quiltt Connector Resolvable Error:', errorMessage)
|
|
65
|
+
if (onErrorCallback) onErrorCallback(errorMessage)
|
|
66
|
+
},
|
|
67
|
+
[onErrorCallback],
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
const checkResolvable = useCallback(
|
|
71
|
+
async (providerId: {
|
|
72
|
+
plaid?: string
|
|
73
|
+
mock?: string
|
|
74
|
+
mx?: string
|
|
75
|
+
finicity?: string
|
|
76
|
+
akoya?: string
|
|
77
|
+
}): Promise<boolean | null> => {
|
|
78
|
+
if (!session?.token || !connectorId) {
|
|
79
|
+
handleError('Missing session token or connector ID')
|
|
80
|
+
return null
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const hasProviderId = Object.values(providerId).some((id) => !!id)
|
|
84
|
+
if (!hasProviderId) {
|
|
85
|
+
handleError('No provider ID specified')
|
|
86
|
+
return null
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
setIsLoading(true)
|
|
90
|
+
setError(null)
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const response = await connectorsAPI.checkResolvable(
|
|
94
|
+
session.token,
|
|
95
|
+
connectorId,
|
|
96
|
+
providerId,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
if (response.status === 200) {
|
|
100
|
+
const result = (response.data as ResolvableData).resolvable
|
|
101
|
+
setIsResolvable(result)
|
|
102
|
+
return result
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
handleError((response.data as ErrorData).message || 'Failed to check resolvability')
|
|
106
|
+
setIsResolvable(null)
|
|
107
|
+
return null
|
|
108
|
+
} catch (error: any) {
|
|
109
|
+
handleError(error?.message)
|
|
110
|
+
setIsResolvable(null)
|
|
111
|
+
return null
|
|
112
|
+
} finally {
|
|
113
|
+
setIsLoading(false)
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
[session?.token, connectorId, connectorsAPI, handleError],
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
checkResolvable,
|
|
121
|
+
isLoading,
|
|
122
|
+
isResolvable,
|
|
123
|
+
error,
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export default useQuilttResolvable
|