@quiltt/react 4.3.3 → 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 CHANGED
@@ -1,5 +1,46 @@
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
+
3
44
  ## 4.3.3
4
45
 
5
46
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -117,6 +117,20 @@ declare const useQuilttConnector: (connectorId?: string, options?: ConnectorSDKC
117
117
  open: () => void;
118
118
  };
119
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
+
120
134
  type UseQuilttInstitutions = (connectorId: string, onErrorCallback?: (msg: string) => void) => {
121
135
  searchTerm: string;
122
136
  searchResults: InstitutionsData;
@@ -182,5 +196,5 @@ declare const QuilttSettingsProvider: FC<QuilttSettingsProviderProps>;
182
196
  type QuilttProviderProps = QuilttSettingsProviderProps & QuilttAuthProviderProps;
183
197
  declare const QuilttProvider: FC<QuilttProviderProps>;
184
198
 
185
- export { QuilttAuthProvider, QuilttButton, QuilttContainer, QuilttProvider, QuilttSettingsProvider, useAuthenticateSession, useEventListener, useIdentifySession, useImportSession, useIsomorphicLayoutEffect, useQuilttClient, useQuilttConnector, useQuilttInstitutions, useQuilttSession, useQuilttSettings, useRevokeSession, useSession, useStorage };
186
- 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,13 +1,14 @@
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-DTl-EiqV.js';
4
+ import { u as useQuilttConnector } from './useQuilttConnector-12s-BiIbmt7I.js';
5
5
  import { i as isDeepEqual, Q as QuilttAuthProvider } from './QuilttAuthProvider-12s-4hQ7iysR.js';
6
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 useQuilttInstitutions } from './useQuilttInstitutions-12s-Cg4OA77c.js';
10
+ export { u as useQuilttResolvable } from './useQuilttResolvable-12s-C2mjy5zs.js';
11
+ export { u as useQuilttInstitutions } from './useQuilttInstitutions-12s-0_y37UHg.js';
11
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';
@@ -5,7 +5,7 @@ import { u as useQuilttSession } from './useQuilttSession-12s-BCq3OL9S.js';
5
5
  import { u as useScript } from './useScript-12s-JCgaTW9n.js';
6
6
  import { i as isDeepEqual } from './QuilttAuthProvider-12s-4hQ7iysR.js';
7
7
 
8
- var version = "4.3.3";
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}`, {
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  import { useMemo, useState, useRef, useEffect, useCallback } from 'react';
3
- import { InstitutionsAPI } from '@quiltt/core';
3
+ import { ConnectorsAPI } from '@quiltt/core';
4
4
  import { useDebounce } from 'use-debounce';
5
- import { v as version } from './useQuilttConnector-12s-DTl-EiqV.js';
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 institutionsAPI = useMemo(()=>new InstitutionsAPI(connectorId, agent), [
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
- institutionsAPI.search(session?.token, connectorId, searchTerm, abortController.signal).then((response)=>{
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
- institutionsAPI,
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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quiltt/react",
3
- "version": "4.3.3",
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.3.3"
39
+ "@quiltt/core": "4.4.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@biomejs/biome": "2.2.4",
@@ -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'
@@ -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 { InstitutionsAPI } from '@quiltt/core'
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 institutionsAPI = useMemo(
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
- institutionsAPI
97
- .search(session?.token, connectorId, searchTerm, abortController.signal)
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, institutionsAPI, handleError])
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