@quiltt/core 5.0.0 → 5.0.2
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 +20 -0
- package/README.md +19 -12
- package/dist/api/browser.cjs +14 -0
- package/dist/api/browser.d.ts +128 -0
- package/dist/api/browser.js +12 -0
- package/dist/api/graphql/SubscriptionLink-12s-ufJBKwu1.js +149 -0
- package/dist/api/graphql/SubscriptionLink-12s-wjkChfxO.cjs +150 -0
- package/dist/api/graphql/index.cjs +218 -0
- package/dist/api/graphql/index.d.ts +82 -0
- package/dist/api/graphql/index.js +184 -0
- package/dist/api/index.cjs +26 -0
- package/dist/api/index.d.ts +3 -0
- package/dist/api/index.js +3 -0
- package/dist/api/rest/index.cjs +225 -0
- package/dist/api/rest/index.d.ts +128 -0
- package/dist/api/rest/index.js +217 -0
- package/dist/auth/index.cjs +21 -0
- package/dist/auth/index.d.ts +29 -0
- package/dist/auth/index.js +19 -0
- package/dist/config/index.cjs +44 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.js +36 -0
- package/dist/index.cjs +61 -0
- package/dist/index.d.ts +8 -524
- package/dist/index.js +8 -449
- package/dist/observables/index.cjs +30 -0
- package/dist/observables/index.d.ts +21 -0
- package/dist/observables/index.js +28 -0
- package/dist/storage/index.cjs +272 -0
- package/dist/storage/index.d.ts +91 -0
- package/dist/{SubscriptionLink-12s-C2VbF8Tf.js → storage/index.js} +2 -139
- package/dist/timing/index.cjs +30 -0
- package/dist/timing/index.d.ts +15 -0
- package/dist/timing/index.js +28 -0
- package/dist/types.cjs +1 -0
- package/dist/types.d.ts +28 -0
- package/dist/types.js +1 -0
- package/dist/utils/index.cjs +61 -0
- package/dist/utils/index.d.ts +18 -0
- package/dist/utils/index.js +57 -0
- package/package.json +62 -6
- package/src/api/graphql/client.ts +1 -1
- package/src/api/graphql/links/ActionCableLink.ts +7 -6
- package/src/api/graphql/links/AuthLink.ts +13 -9
- package/src/api/graphql/links/BatchHttpLink.ts +1 -1
- package/src/api/graphql/links/ErrorLink.ts +4 -0
- package/src/api/graphql/links/HttpLink.ts +1 -1
- package/src/api/graphql/links/VersionLink.ts +1 -1
- package/src/api/rest/auth.ts +1 -1
- package/src/api/rest/connectors.ts +1 -1
- package/src/auth/index.ts +1 -0
- package/src/{JsonWebToken.ts → auth/json-web-token.ts} +1 -1
- package/src/{configuration.ts → config/configuration.ts} +1 -1
- package/src/config/index.ts +1 -0
- package/src/index.ts +5 -5
- package/src/observables/index.ts +1 -0
- package/src/{Observable.ts → observables/observable.ts} +1 -1
- package/src/storage/Local.ts +1 -1
- package/src/storage/Memory.ts +2 -2
- package/src/storage/Storage.ts +1 -1
- package/src/timing/index.ts +1 -0
- package/src/{Timeoutable.ts → timing/timeoutable.ts} +1 -1
- package/src/utils/index.ts +1 -0
- package/src/utils/token-validation.ts +67 -0
package/dist/index.js
CHANGED
|
@@ -1,449 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import { HttpLink as HttpLink$1 } from '@apollo/client/link/http';
|
|
10
|
-
import { RetryLink as RetryLink$1 } from '@apollo/client/link/retry';
|
|
11
|
-
export { InMemoryCache } from '@apollo/client/cache';
|
|
12
|
-
export { useMutation, useQuery, useSubscription } from '@apollo/client/react';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Enum representing the different types of events emitted by the Connector.
|
|
16
|
-
*/ var ConnectorSDKEventType = /*#__PURE__*/ function(ConnectorSDKEventType) {
|
|
17
|
-
/** The Connector modal has been opened */ ConnectorSDKEventType["Open"] = "opened";
|
|
18
|
-
/** The Connector has loaded successfully */ ConnectorSDKEventType["Load"] = "loaded";
|
|
19
|
-
/** The end-user successfully completed the flow */ ConnectorSDKEventType["ExitSuccess"] = "exited.successful";
|
|
20
|
-
/** The end-user exited the Connector before completing the flow */ ConnectorSDKEventType["ExitAbort"] = "exited.aborted";
|
|
21
|
-
/** The end-user experienced an error during the flow */ ConnectorSDKEventType["ExitError"] = "exited.errored";
|
|
22
|
-
return ConnectorSDKEventType;
|
|
23
|
-
}({});
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* unauthorizedCallback only triggers in the event the token is present, and
|
|
27
|
-
* returns the token; This allows sessions to be forgotten without race conditions
|
|
28
|
-
* causing null sessions to kill valid sessions, or invalid sessions for killing
|
|
29
|
-
* valid sessions during rotation and networking weirdness.
|
|
30
|
-
*/ class AuthLink extends ApolloLink {
|
|
31
|
-
request(operation, forward) {
|
|
32
|
-
const token = GlobalStorage.get('session');
|
|
33
|
-
if (!token) {
|
|
34
|
-
console.warn('QuilttLink attempted to send an unauthenticated Query');
|
|
35
|
-
return new Observable((observer)=>{
|
|
36
|
-
observer.error(new Error('No authentication token available'));
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
operation.setContext(({ headers = {} })=>({
|
|
40
|
-
headers: {
|
|
41
|
-
...headers,
|
|
42
|
-
authorization: `Bearer ${token}`
|
|
43
|
-
}
|
|
44
|
-
}));
|
|
45
|
-
return forward(operation);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Use `cross-fetch` only if `fetch` is not available on the `globalThis` object
|
|
50
|
-
const effectiveFetch$2 = typeof fetch === 'undefined' ? crossfetch : fetch;
|
|
51
|
-
const BatchHttpLink = new BatchHttpLink$1({
|
|
52
|
-
uri: endpointGraphQL,
|
|
53
|
-
fetch: effectiveFetch$2
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
const ErrorLink = new ErrorLink$1(({ error, result })=>{
|
|
57
|
-
// In Apollo Client 4, errors are consolidated to the 'error' and 'result' properties
|
|
58
|
-
// Handle GraphQL errors from result
|
|
59
|
-
if (result?.errors) {
|
|
60
|
-
result.errors.forEach((graphQLError)=>{
|
|
61
|
-
const { message, path, extensions } = graphQLError;
|
|
62
|
-
const formattedPath = Array.isArray(path) ? path.join('.') : path ?? 'N/A';
|
|
63
|
-
const parts = [
|
|
64
|
-
`[Quiltt][GraphQL Error]: ${message}`,
|
|
65
|
-
`Path: ${formattedPath}`
|
|
66
|
-
];
|
|
67
|
-
if (extensions) {
|
|
68
|
-
if (extensions.code) parts.push(`Code: ${extensions.code}`);
|
|
69
|
-
if (extensions.errorId) parts.push(`Error ID: ${extensions.errorId}`);
|
|
70
|
-
}
|
|
71
|
-
console.warn(parts.join(' | '));
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
// Handle network/server errors
|
|
75
|
-
if (error) {
|
|
76
|
-
if ('statusCode' in error && error.statusCode === 401) {
|
|
77
|
-
console.warn('[Quiltt][Authentication Error]:', error);
|
|
78
|
-
GlobalStorage.set('session', null);
|
|
79
|
-
} else if ('statusCode' in error) {
|
|
80
|
-
console.warn('[Quiltt][Server Error]:', error);
|
|
81
|
-
} else {
|
|
82
|
-
console.warn('[Quiltt][Network Error]:', error);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const ForwardableLink = new ApolloLink((operation, forward)=>forward(operation));
|
|
88
|
-
|
|
89
|
-
// Use `cross-fetch` only if `fetch` is not available on the `globalThis` object
|
|
90
|
-
const effectiveFetch$1 = typeof fetch === 'undefined' ? crossfetch : fetch;
|
|
91
|
-
const HttpLink = new HttpLink$1({
|
|
92
|
-
uri: endpointGraphQL,
|
|
93
|
-
fetch: effectiveFetch$1
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const RetryLink = new RetryLink$1({
|
|
97
|
-
attempts: {
|
|
98
|
-
retryIf: (error, _operation)=>{
|
|
99
|
-
if (!error) return false;
|
|
100
|
-
const statusCode = 'statusCode' in error ? error.statusCode : undefined;
|
|
101
|
-
return !statusCode || statusCode >= 500;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
const TerminatingLink = new ApolloLink(()=>{
|
|
107
|
-
return new Observable((observer)=>{
|
|
108
|
-
observer.complete();
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Extracts version number from formatted version string
|
|
114
|
-
* @param formattedVersion - Formatted version like "@quiltt/core: v4.5.1"
|
|
115
|
-
* @returns Version number like "4.5.1" or "unknown" if not found
|
|
116
|
-
*/ const extractVersionNumber = (formattedVersion)=>{
|
|
117
|
-
// Find the 'v' prefix and extract version after it
|
|
118
|
-
const vIndex = formattedVersion.indexOf('v');
|
|
119
|
-
if (vIndex === -1) return 'unknown';
|
|
120
|
-
const versionPart = formattedVersion.substring(vIndex + 1);
|
|
121
|
-
const parts = versionPart.split('.');
|
|
122
|
-
// Validate we have at least major.minor.patch
|
|
123
|
-
if (parts.length < 3) return 'unknown';
|
|
124
|
-
// Extract numeric parts (handles cases like "4.5.1-beta")
|
|
125
|
-
const major = parts[0].match(/^\d+/)?.[0];
|
|
126
|
-
const minor = parts[1].match(/^\d+/)?.[0];
|
|
127
|
-
const patch = parts[2].match(/^\d+/)?.[0];
|
|
128
|
-
if (!major || !minor || !patch) return 'unknown';
|
|
129
|
-
return `${major}.${minor}.${patch}`;
|
|
130
|
-
};
|
|
131
|
-
/**
|
|
132
|
-
* Generates a User-Agent string following standard format
|
|
133
|
-
* Format: Quiltt/<version> (<platform-info>)
|
|
134
|
-
*/ const getUserAgent = (sdkVersion, platformInfo)=>{
|
|
135
|
-
return `Quiltt/${sdkVersion} (${platformInfo})`;
|
|
136
|
-
};
|
|
137
|
-
/**
|
|
138
|
-
* Detects browser information from user agent string
|
|
139
|
-
* Returns browser name and version, or 'Unknown' if not detected
|
|
140
|
-
*/ const getBrowserInfo = ()=>{
|
|
141
|
-
if (typeof navigator === 'undefined' || !navigator.userAgent) {
|
|
142
|
-
return 'Unknown';
|
|
143
|
-
}
|
|
144
|
-
const ua = navigator.userAgent;
|
|
145
|
-
// Edge (must be checked before Chrome)
|
|
146
|
-
if (ua.includes('Edg/')) {
|
|
147
|
-
const version = ua.match(/Edg\/(\d+)/)?.[1] || 'Unknown';
|
|
148
|
-
return `Edge/${version}`;
|
|
149
|
-
}
|
|
150
|
-
// Chrome
|
|
151
|
-
if (ua.includes('Chrome/') && !ua.includes('Edg/')) {
|
|
152
|
-
const version = ua.match(/Chrome\/(\d+)/)?.[1] || 'Unknown';
|
|
153
|
-
return `Chrome/${version}`;
|
|
154
|
-
}
|
|
155
|
-
// Safari (must be checked after Chrome)
|
|
156
|
-
if (ua.includes('Safari/') && !ua.includes('Chrome/')) {
|
|
157
|
-
const version = ua.match(/Version\/(\d+)/)?.[1] || 'Unknown';
|
|
158
|
-
return `Safari/${version}`;
|
|
159
|
-
}
|
|
160
|
-
// Firefox
|
|
161
|
-
if (ua.includes('Firefox/')) {
|
|
162
|
-
const version = ua.match(/Firefox\/(\d+)/)?.[1] || 'Unknown';
|
|
163
|
-
return `Firefox/${version}`;
|
|
164
|
-
}
|
|
165
|
-
return 'Unknown';
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
const createVersionLink = (platformInfo)=>{
|
|
169
|
-
const versionNumber = extractVersionNumber(version);
|
|
170
|
-
const userAgent = getUserAgent(versionNumber, platformInfo);
|
|
171
|
-
return new ApolloLink((operation, forward)=>{
|
|
172
|
-
operation.setContext(({ headers = {} })=>({
|
|
173
|
-
headers: {
|
|
174
|
-
...headers,
|
|
175
|
-
'Quiltt-Client-Version': version,
|
|
176
|
-
'User-Agent': userAgent
|
|
177
|
-
}
|
|
178
|
-
}));
|
|
179
|
-
return forward(operation);
|
|
180
|
-
});
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
class QuilttClient extends ApolloClient {
|
|
184
|
-
constructor(options){
|
|
185
|
-
const finalOptions = {
|
|
186
|
-
...options,
|
|
187
|
-
devtools: {
|
|
188
|
-
enabled: options.devtools?.enabled ?? debugging
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
const initialLinks = options.customLinks ? [
|
|
192
|
-
...options.customLinks
|
|
193
|
-
] : [];
|
|
194
|
-
const isOperationDefinition = (def)=>def.kind === 'OperationDefinition';
|
|
195
|
-
const isSubscriptionOperation = (operation)=>{
|
|
196
|
-
return operation.query.definitions.some((definition)=>isOperationDefinition(definition) && definition.operation === 'subscription');
|
|
197
|
-
};
|
|
198
|
-
const isBatchable = (operation)=>{
|
|
199
|
-
return operation.getContext().batchable ?? true;
|
|
200
|
-
};
|
|
201
|
-
const authLink = new AuthLink();
|
|
202
|
-
const subscriptionsLink = new SubscriptionLink();
|
|
203
|
-
const quilttLink = ApolloLink.from([
|
|
204
|
-
...initialLinks,
|
|
205
|
-
options.versionLink,
|
|
206
|
-
authLink,
|
|
207
|
-
ErrorLink,
|
|
208
|
-
RetryLink
|
|
209
|
-
]).split(isSubscriptionOperation, subscriptionsLink, ForwardableLink).split(isBatchable, BatchHttpLink, HttpLink);
|
|
210
|
-
super({
|
|
211
|
-
link: quilttLink,
|
|
212
|
-
...finalOptions
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Use `cross-fetch` only if `fetch` is not available on the `globalThis` object
|
|
218
|
-
const effectiveFetch = typeof fetch === 'undefined' ? crossfetch : fetch;
|
|
219
|
-
const RETRY_DELAY = 150 // ms
|
|
220
|
-
;
|
|
221
|
-
const RETRIES = 10 // 150, 300, 450, 600, 750, 900, 1050, 1200, 1350, 1500 = 8.250s
|
|
222
|
-
;
|
|
223
|
-
/**
|
|
224
|
-
* A wrapper around the native `fetch` function that adds automatic retries on failure, including network errors and HTTP 429 responses.
|
|
225
|
-
* Now treats any response with status < 500 as valid.
|
|
226
|
-
*/ const fetchWithRetry = async (url, options = {
|
|
227
|
-
retry: false
|
|
228
|
-
})=>{
|
|
229
|
-
const { retry, retriesRemaining, validateStatus = (status)=>status >= 200 && status < 300, ...fetchOptions } = options;
|
|
230
|
-
try {
|
|
231
|
-
const response = await effectiveFetch(url, fetchOptions);
|
|
232
|
-
const isResponseOk = validateStatus(response.status);
|
|
233
|
-
if (isResponseOk) {
|
|
234
|
-
return {
|
|
235
|
-
data: await response.json().catch(()=>null),
|
|
236
|
-
status: response.status,
|
|
237
|
-
statusText: response.statusText,
|
|
238
|
-
headers: response.headers,
|
|
239
|
-
ok: isResponseOk
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
// If validateStatus fails, and retry is enabled, prepare to retry for eligible status codes
|
|
243
|
-
if (retry && (response.status >= 500 || response.status === 429)) {
|
|
244
|
-
throw new Error('Retryable failure');
|
|
245
|
-
}
|
|
246
|
-
throw new Error(`HTTP error with status ${response.status}`);
|
|
247
|
-
} catch (error) {
|
|
248
|
-
if (retry) {
|
|
249
|
-
const currentRetriesRemaining = retriesRemaining !== undefined ? retriesRemaining : RETRIES;
|
|
250
|
-
if (currentRetriesRemaining > 0) {
|
|
251
|
-
const delayTime = RETRY_DELAY * (RETRIES - currentRetriesRemaining);
|
|
252
|
-
await new Promise((resolve)=>setTimeout(resolve, delayTime));
|
|
253
|
-
return fetchWithRetry(url, {
|
|
254
|
-
...options,
|
|
255
|
-
retriesRemaining: currentRetriesRemaining - 1
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return Promise.reject(error);
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
var AuthStrategies = /*#__PURE__*/ function(AuthStrategies) {
|
|
264
|
-
AuthStrategies["Email"] = "email";
|
|
265
|
-
AuthStrategies["Phone"] = "phone";
|
|
266
|
-
return AuthStrategies;
|
|
267
|
-
}({});
|
|
268
|
-
// https://www.quiltt.dev/api-reference/auth
|
|
269
|
-
class AuthAPI {
|
|
270
|
-
constructor(clientId){
|
|
271
|
-
/**
|
|
272
|
-
* Response Statuses:
|
|
273
|
-
* - 200: OK -> Session is Valid
|
|
274
|
-
* - 401: Unauthorized -> Session is Invalid
|
|
275
|
-
*/ this.ping = async (token)=>{
|
|
276
|
-
const response = await fetchWithRetry(endpointAuth, {
|
|
277
|
-
method: 'GET',
|
|
278
|
-
...this.config(token)
|
|
279
|
-
});
|
|
280
|
-
return response;
|
|
281
|
-
};
|
|
282
|
-
/**
|
|
283
|
-
* Response Statuses:
|
|
284
|
-
* - 201: Created -> Profile Created, New Session Returned
|
|
285
|
-
* - 202: Accepted -> Profile Found, MFA Code Sent for `authenticate`
|
|
286
|
-
* - 422: Unprocessable Entity -> Invalid Payload
|
|
287
|
-
*/ this.identify = async (payload)=>{
|
|
288
|
-
const response = await fetchWithRetry(endpointAuth, {
|
|
289
|
-
method: 'POST',
|
|
290
|
-
body: JSON.stringify(this.body(payload)),
|
|
291
|
-
...this.config()
|
|
292
|
-
});
|
|
293
|
-
return response;
|
|
294
|
-
};
|
|
295
|
-
/**
|
|
296
|
-
* Response Statuses:
|
|
297
|
-
* - 201: Created -> MFA Validated, New Session Returned
|
|
298
|
-
* - 401: Unauthorized -> MFA Invalid
|
|
299
|
-
* - 422: Unprocessable Entity -> Invalid Payload
|
|
300
|
-
*/ this.authenticate = async (payload)=>{
|
|
301
|
-
const response = await fetchWithRetry(endpointAuth, {
|
|
302
|
-
method: 'PUT',
|
|
303
|
-
body: JSON.stringify(this.body(payload)),
|
|
304
|
-
...this.config()
|
|
305
|
-
});
|
|
306
|
-
return response;
|
|
307
|
-
};
|
|
308
|
-
/**
|
|
309
|
-
* Response Statuses:
|
|
310
|
-
* - 204: No Content -> Session Revoked
|
|
311
|
-
* - 401: Unauthorized -> Session Not Found
|
|
312
|
-
*/ this.revoke = async (token)=>{
|
|
313
|
-
const response = await fetchWithRetry(endpointAuth, {
|
|
314
|
-
method: 'DELETE',
|
|
315
|
-
...this.config(token)
|
|
316
|
-
});
|
|
317
|
-
return response;
|
|
318
|
-
};
|
|
319
|
-
this.config = (token)=>{
|
|
320
|
-
const headers = new Headers();
|
|
321
|
-
headers.set('Content-Type', 'application/json');
|
|
322
|
-
headers.set('Accept', 'application/json');
|
|
323
|
-
if (token) {
|
|
324
|
-
headers.set('Authorization', `Bearer ${token}`);
|
|
325
|
-
}
|
|
326
|
-
return {
|
|
327
|
-
headers,
|
|
328
|
-
validateStatus: this.validateStatus,
|
|
329
|
-
retry: true
|
|
330
|
-
};
|
|
331
|
-
};
|
|
332
|
-
this.validateStatus = (status)=>status < 500 && status !== 429;
|
|
333
|
-
this.body = (payload)=>{
|
|
334
|
-
if (!this.clientId) {
|
|
335
|
-
console.error('Quiltt Client ID is not set. Unable to identify & authenticate');
|
|
336
|
-
}
|
|
337
|
-
return {
|
|
338
|
-
session: {
|
|
339
|
-
clientId: this.clientId,
|
|
340
|
-
...payload
|
|
341
|
-
}
|
|
342
|
-
};
|
|
343
|
-
};
|
|
344
|
-
this.clientId = clientId;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
class ConnectorsAPI {
|
|
349
|
-
constructor(clientId, userAgent = getUserAgent(extractVersionNumber(version), 'Unknown')){
|
|
350
|
-
/**
|
|
351
|
-
* Response Statuses:
|
|
352
|
-
* - 200: OK -> Institutions Found
|
|
353
|
-
* - 401: Unauthorized -> Invalid Token
|
|
354
|
-
* - 403: Forbidden -> Unsupported SDK
|
|
355
|
-
* - 400: Bad Request -> Invalid Request
|
|
356
|
-
*/ this.searchInstitutions = async (token, connectorId, term, signal)=>{
|
|
357
|
-
const params = new URLSearchParams();
|
|
358
|
-
params.append('term', term);
|
|
359
|
-
const response = await fetchWithRetry(`${endpointRest}/sdk/connectors/${connectorId}/institutions?${params}`, {
|
|
360
|
-
method: 'GET',
|
|
361
|
-
signal,
|
|
362
|
-
...this.config(token)
|
|
363
|
-
});
|
|
364
|
-
return response;
|
|
365
|
-
};
|
|
366
|
-
/**
|
|
367
|
-
* Response Statuses:
|
|
368
|
-
* - 200: OK -> Provider API ID is resolvable or not
|
|
369
|
-
* - 401: Unauthorized -> Invalid Token
|
|
370
|
-
* - 403: Forbidden -> Unsupported SDK
|
|
371
|
-
* - 400: Bad Request -> Missing provider API ID parameter
|
|
372
|
-
* - 404: Not Found -> Connector not found
|
|
373
|
-
*/ this.checkResolvable = async (token, connectorId, providerId, signal)=>{
|
|
374
|
-
const params = new URLSearchParams();
|
|
375
|
-
const providerKey = Object.keys(providerId)[0];
|
|
376
|
-
if (providerKey && providerId[providerKey]) {
|
|
377
|
-
params.append(providerKey, providerId[providerKey]);
|
|
378
|
-
}
|
|
379
|
-
const response = await fetchWithRetry(`${endpointRest}/sdk/connectors/${connectorId}/resolvable?${params}`, {
|
|
380
|
-
method: 'GET',
|
|
381
|
-
signal,
|
|
382
|
-
...this.config(token)
|
|
383
|
-
});
|
|
384
|
-
return response;
|
|
385
|
-
};
|
|
386
|
-
this.config = (token)=>{
|
|
387
|
-
const headers = new Headers();
|
|
388
|
-
headers.set('Content-Type', 'application/json');
|
|
389
|
-
headers.set('Accept', 'application/json');
|
|
390
|
-
headers.set('User-Agent', this.userAgent);
|
|
391
|
-
headers.set('Authorization', `Bearer ${token}`);
|
|
392
|
-
return {
|
|
393
|
-
headers,
|
|
394
|
-
validateStatus: this.validateStatus,
|
|
395
|
-
retry: true
|
|
396
|
-
};
|
|
397
|
-
};
|
|
398
|
-
this.validateStatus = (status)=>status < 500 && status !== 429;
|
|
399
|
-
this.clientId = clientId;
|
|
400
|
-
this.userAgent = userAgent;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const MATCHER = /^(?:[\w-]+\.){2}[\w-]+$/;
|
|
405
|
-
const JsonWebTokenParse = (token)=>{
|
|
406
|
-
if (typeof token === 'undefined' || token === null) return token;
|
|
407
|
-
if (!MATCHER.test(token)) {
|
|
408
|
-
console.error(`Invalid Session Token: ${token}`);
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
const [_header, payload, _signature] = token.split('.');
|
|
412
|
-
try {
|
|
413
|
-
return {
|
|
414
|
-
token,
|
|
415
|
-
claims: JSON.parse(atob(payload))
|
|
416
|
-
};
|
|
417
|
-
} catch (error) {
|
|
418
|
-
console.error(`Invalid Session Token: ${error}`);
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* This is designed to support singletons to timeouts that can broadcast
|
|
424
|
-
* to any observers, preventing race conditions with multiple timeouts.
|
|
425
|
-
*/ class Timeoutable {
|
|
426
|
-
constructor(){
|
|
427
|
-
this.observers = [];
|
|
428
|
-
this.set = (callback, delay)=>{
|
|
429
|
-
if (this.timeout) {
|
|
430
|
-
clearTimeout(this.timeout);
|
|
431
|
-
}
|
|
432
|
-
// Replace all observers with the new one
|
|
433
|
-
this.observers = [
|
|
434
|
-
callback
|
|
435
|
-
];
|
|
436
|
-
this.timeout = setTimeout(this.broadcast.bind(this), delay);
|
|
437
|
-
};
|
|
438
|
-
this.clear = (observer)=>{
|
|
439
|
-
this.observers = this.observers.filter((callback)=>callback !== observer);
|
|
440
|
-
};
|
|
441
|
-
// Only sends to the 1st listener, but ensures that someone is notified
|
|
442
|
-
this.broadcast = ()=>{
|
|
443
|
-
if (this.observers.length === 0) return;
|
|
444
|
-
this.observers[0](undefined);
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
export { AuthAPI, AuthLink, AuthStrategies, BatchHttpLink, ConnectorSDKEventType, ConnectorsAPI, ErrorLink, ForwardableLink, GlobalStorage, HttpLink, JsonWebTokenParse, QuilttClient, RetryLink, SubscriptionLink, TerminatingLink, Timeoutable, createVersionLink, debugging, endpointAuth, endpointGraphQL, endpointRest, extractVersionNumber, getBrowserInfo, getUserAgent, version };
|
|
1
|
+
export * from './api/index.js';
|
|
2
|
+
export * from './auth/index.js';
|
|
3
|
+
export * from './config/index.js';
|
|
4
|
+
export * from './observables/index.js';
|
|
5
|
+
export * from './storage/index.js';
|
|
6
|
+
export * from './timing/index.js';
|
|
7
|
+
export * from './types.js';
|
|
8
|
+
export * from './utils/index.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This is designed to support singletons to share the memory states across all
|
|
5
|
+
* instance of hooks to ensure that updates only process once, by storing a value
|
|
6
|
+
* then notifying all subscribers when it's updated.
|
|
7
|
+
*/ class Observable {
|
|
8
|
+
constructor(initialState){
|
|
9
|
+
this.observers = [];
|
|
10
|
+
this.get = ()=>{
|
|
11
|
+
return this.state;
|
|
12
|
+
};
|
|
13
|
+
this.set = (nextState)=>{
|
|
14
|
+
if (this.state === nextState) return;
|
|
15
|
+
this.state = nextState;
|
|
16
|
+
this.observers.forEach((update)=>{
|
|
17
|
+
update(nextState);
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
this.subscribe = (observer)=>{
|
|
21
|
+
this.observers.push(observer);
|
|
22
|
+
};
|
|
23
|
+
this.unsubscribe = (observer)=>{
|
|
24
|
+
this.observers = this.observers.filter((update)=>update !== observer);
|
|
25
|
+
};
|
|
26
|
+
this.state = initialState;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
exports.Observable = Observable;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import { Maybe } from '../types.js';
|
|
3
|
+
|
|
4
|
+
type Observer<T> = Dispatch<SetStateAction<Maybe<T> | undefined>>;
|
|
5
|
+
/**
|
|
6
|
+
* This is designed to support singletons to share the memory states across all
|
|
7
|
+
* instance of hooks to ensure that updates only process once, by storing a value
|
|
8
|
+
* then notifying all subscribers when it's updated.
|
|
9
|
+
*/
|
|
10
|
+
declare class Observable<T> {
|
|
11
|
+
private state?;
|
|
12
|
+
private observers;
|
|
13
|
+
constructor(initialState?: Maybe<T>);
|
|
14
|
+
get: () => Maybe<T> | undefined;
|
|
15
|
+
set: (nextState: Maybe<T> | undefined) => void;
|
|
16
|
+
subscribe: (observer: Observer<T>) => void;
|
|
17
|
+
unsubscribe: (observer: Observer<T>) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { Observable };
|
|
21
|
+
export type { Observer };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is designed to support singletons to share the memory states across all
|
|
3
|
+
* instance of hooks to ensure that updates only process once, by storing a value
|
|
4
|
+
* then notifying all subscribers when it's updated.
|
|
5
|
+
*/ class Observable {
|
|
6
|
+
constructor(initialState){
|
|
7
|
+
this.observers = [];
|
|
8
|
+
this.get = ()=>{
|
|
9
|
+
return this.state;
|
|
10
|
+
};
|
|
11
|
+
this.set = (nextState)=>{
|
|
12
|
+
if (this.state === nextState) return;
|
|
13
|
+
this.state = nextState;
|
|
14
|
+
this.observers.forEach((update)=>{
|
|
15
|
+
update(nextState);
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
this.subscribe = (observer)=>{
|
|
19
|
+
this.observers.push(observer);
|
|
20
|
+
};
|
|
21
|
+
this.unsubscribe = (observer)=>{
|
|
22
|
+
this.observers = this.observers.filter((update)=>update !== observer);
|
|
23
|
+
};
|
|
24
|
+
this.state = initialState;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { Observable };
|