@quiltt/vue 5.1.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/LICENSE.md +9 -0
- package/README.md +212 -0
- package/dist/components/index.cjs +707 -0
- package/dist/components/index.d.ts +278 -0
- package/dist/components/index.js +703 -0
- package/dist/composables/index.cjs +617 -0
- package/dist/composables/index.d.ts +191 -0
- package/dist/composables/index.js +609 -0
- package/dist/index.cjs +75 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/plugin/index.cjs +176 -0
- package/dist/plugin/index.d.ts +48 -0
- package/dist/plugin/index.js +171 -0
- package/package.json +81 -0
- package/src/components/QuilttButton.ts +121 -0
- package/src/components/QuilttConnector.ts +215 -0
- package/src/components/QuilttContainer.ts +130 -0
- package/src/components/index.ts +3 -0
- package/src/composables/index.ts +7 -0
- package/src/composables/useQuilttConnector.ts +312 -0
- package/src/composables/useQuilttInstitutions.ts +114 -0
- package/src/composables/useQuilttResolvable.ts +94 -0
- package/src/composables/useQuilttSession.ts +239 -0
- package/src/composables/useQuilttSettings.ts +15 -0
- package/src/composables/useSession.ts +74 -0
- package/src/composables/useStorage.ts +47 -0
- package/src/constants/deprecation-warnings.ts +2 -0
- package/src/index.ts +34 -0
- package/src/plugin/QuilttPlugin.ts +204 -0
- package/src/plugin/index.ts +23 -0
- package/src/plugin/keys.ts +26 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/telemetry.ts +73 -0
- package/src/version.ts +1 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from '@quiltt/core/api';
|
|
2
|
+
export * from '@quiltt/core/auth';
|
|
3
|
+
export * from '@quiltt/core/config';
|
|
4
|
+
export * from '@quiltt/core/observables';
|
|
5
|
+
export * from '@quiltt/core/storage';
|
|
6
|
+
export * from '@quiltt/core/timing';
|
|
7
|
+
export * from '@quiltt/core/types';
|
|
8
|
+
export * from './components/index.js';
|
|
9
|
+
export * from './composables/index.js';
|
|
10
|
+
export * from './plugin/index.js';
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
|
|
3
|
+
var vue = require('vue');
|
|
4
|
+
var core = require('@quiltt/core');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Injection keys and types for Quiltt Vue plugin
|
|
8
|
+
*/ // Injection keys for Quiltt state
|
|
9
|
+
const QuilttSessionKey = Symbol.for('quiltt-session');
|
|
10
|
+
const QuilttSetSessionKey = Symbol.for('quiltt-set-session');
|
|
11
|
+
const QuilttClientIdKey = Symbol.for('quiltt-client-id');
|
|
12
|
+
|
|
13
|
+
// Initialize JWT parser with our specific claims type
|
|
14
|
+
const parse = core.JsonWebTokenParse;
|
|
15
|
+
// Storage key for session persistence
|
|
16
|
+
const STORAGE_KEY = 'quiltt:session';
|
|
17
|
+
/**
|
|
18
|
+
* Get stored token from localStorage (browser only)
|
|
19
|
+
*/ const getStoredToken = ()=>{
|
|
20
|
+
if (typeof window === 'undefined' || typeof localStorage === 'undefined') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
return localStorage.getItem(STORAGE_KEY);
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Store token in localStorage (browser only)
|
|
31
|
+
*/ const setStoredToken = (token)=>{
|
|
32
|
+
if (typeof window === 'undefined' || typeof localStorage === 'undefined') {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
if (token) {
|
|
37
|
+
localStorage.setItem(STORAGE_KEY, token);
|
|
38
|
+
} else {
|
|
39
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
// Storage not available
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Quiltt Vue Plugin
|
|
47
|
+
*
|
|
48
|
+
* Provides session management across your Vue application.
|
|
49
|
+
* Use with `app.use(QuilttPlugin, options)`.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* import { createApp } from 'vue'
|
|
54
|
+
* import { QuilttPlugin } from '@quiltt/vue'
|
|
55
|
+
*
|
|
56
|
+
* const app = createApp(App)
|
|
57
|
+
* app.use(QuilttPlugin, { token: '<SESSION_TOKEN>' })
|
|
58
|
+
* app.mount('#app')
|
|
59
|
+
* ```
|
|
60
|
+
*/ const QuilttPlugin = {
|
|
61
|
+
install (app, options) {
|
|
62
|
+
// Instance-scoped timeout for session expiration
|
|
63
|
+
let sessionTimeout;
|
|
64
|
+
let isCleanedUp = false;
|
|
65
|
+
let stopSessionWatcher;
|
|
66
|
+
/**
|
|
67
|
+
* Clear the session timeout for this app instance
|
|
68
|
+
*/ const clearSessionTimeout = ()=>{
|
|
69
|
+
if (sessionTimeout) {
|
|
70
|
+
clearTimeout(sessionTimeout);
|
|
71
|
+
sessionTimeout = undefined;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
// Initialize with provided token or stored token
|
|
75
|
+
const initialToken = options?.token ?? getStoredToken();
|
|
76
|
+
const initialSession = parse(initialToken);
|
|
77
|
+
// Reactive session state
|
|
78
|
+
const session = vue.ref(initialSession);
|
|
79
|
+
const clientId = vue.ref(options?.clientId);
|
|
80
|
+
/**
|
|
81
|
+
* Set session token
|
|
82
|
+
* Parses token, updates storage, and sets expiration timer
|
|
83
|
+
*/ const setSession = (token)=>{
|
|
84
|
+
const parsed = parse(token);
|
|
85
|
+
session.value = parsed;
|
|
86
|
+
setStoredToken(token ?? null);
|
|
87
|
+
// Clear any existing expiration timer
|
|
88
|
+
clearSessionTimeout();
|
|
89
|
+
// Set new expiration timer if session is valid
|
|
90
|
+
if (parsed) {
|
|
91
|
+
const expirationMS = parsed.claims.exp * 1000;
|
|
92
|
+
const timeUntilExpiry = expirationMS - Date.now();
|
|
93
|
+
if (timeUntilExpiry > 0) {
|
|
94
|
+
sessionTimeout = setTimeout(()=>{
|
|
95
|
+
session.value = null;
|
|
96
|
+
setStoredToken(null);
|
|
97
|
+
}, timeUntilExpiry);
|
|
98
|
+
} else {
|
|
99
|
+
// Token already expired
|
|
100
|
+
session.value = null;
|
|
101
|
+
setStoredToken(null);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
// Storage event handler for cross-tab synchronization
|
|
106
|
+
let storageHandler;
|
|
107
|
+
// Listen for storage changes from other tabs/windows
|
|
108
|
+
if (typeof window !== 'undefined') {
|
|
109
|
+
storageHandler = (event)=>{
|
|
110
|
+
if (event.key === STORAGE_KEY) {
|
|
111
|
+
const newSession = parse(event.newValue);
|
|
112
|
+
session.value = newSession;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
window.addEventListener('storage', storageHandler);
|
|
116
|
+
}
|
|
117
|
+
// Cleanup function for when the app is unmounted
|
|
118
|
+
const cleanup = ()=>{
|
|
119
|
+
if (isCleanedUp) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
isCleanedUp = true;
|
|
123
|
+
clearSessionTimeout();
|
|
124
|
+
if (stopSessionWatcher) {
|
|
125
|
+
stopSessionWatcher();
|
|
126
|
+
stopSessionWatcher = undefined;
|
|
127
|
+
}
|
|
128
|
+
if (typeof window !== 'undefined' && storageHandler) {
|
|
129
|
+
window.removeEventListener('storage', storageHandler);
|
|
130
|
+
storageHandler = undefined;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
// Register cleanup on app unmount (Vue 3.5+)
|
|
134
|
+
if (typeof app.onUnmount === 'function') {
|
|
135
|
+
app.onUnmount(cleanup);
|
|
136
|
+
}
|
|
137
|
+
// Ensure cleanup runs on all supported Vue versions (3.3+)
|
|
138
|
+
if (typeof app.unmount === 'function') {
|
|
139
|
+
const originalUnmount = app.unmount.bind(app);
|
|
140
|
+
app.unmount = (...args)=>{
|
|
141
|
+
cleanup();
|
|
142
|
+
return originalUnmount(...args);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// Watch for session changes to update expiration timer
|
|
146
|
+
stopSessionWatcher = vue.watch(()=>session.value, (newSession)=>{
|
|
147
|
+
if (!newSession) {
|
|
148
|
+
clearSessionTimeout();
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const expirationMS = newSession.claims.exp * 1000;
|
|
152
|
+
const timeUntilExpiry = expirationMS - Date.now();
|
|
153
|
+
if (timeUntilExpiry <= 0) {
|
|
154
|
+
session.value = null;
|
|
155
|
+
setStoredToken(null);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
clearSessionTimeout();
|
|
159
|
+
sessionTimeout = setTimeout(()=>{
|
|
160
|
+
session.value = null;
|
|
161
|
+
setStoredToken(null);
|
|
162
|
+
}, timeUntilExpiry);
|
|
163
|
+
}, {
|
|
164
|
+
immediate: true
|
|
165
|
+
});
|
|
166
|
+
// Provide session state to all components
|
|
167
|
+
app.provide(QuilttSessionKey, session);
|
|
168
|
+
app.provide(QuilttSetSessionKey, setSession);
|
|
169
|
+
app.provide(QuilttClientIdKey, clientId);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
exports.QuilttClientIdKey = QuilttClientIdKey;
|
|
174
|
+
exports.QuilttPlugin = QuilttPlugin;
|
|
175
|
+
exports.QuilttSessionKey = QuilttSessionKey;
|
|
176
|
+
exports.QuilttSetSessionKey = QuilttSetSessionKey;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { InjectionKey, Ref, Plugin } from 'vue';
|
|
2
|
+
import { Maybe, QuilttJWT } from '@quiltt/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Injection keys and types for Quiltt Vue plugin
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare const QuilttSessionKey: InjectionKey<Ref<Maybe<QuilttJWT> | undefined>>;
|
|
9
|
+
declare const QuilttSetSessionKey: InjectionKey<(token: Maybe<string>) => void>;
|
|
10
|
+
declare const QuilttClientIdKey: InjectionKey<Ref<string | undefined>>;
|
|
11
|
+
interface QuilttPluginOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Initial session token
|
|
14
|
+
*/
|
|
15
|
+
token?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Quiltt Client ID (Environment ID)
|
|
18
|
+
*/
|
|
19
|
+
clientId?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Quiltt Vue Plugin implementation
|
|
24
|
+
*
|
|
25
|
+
* Provides session state management via Vue's provide/inject system.
|
|
26
|
+
* Handles token parsing, storage synchronization, and automatic expiration.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Quiltt Vue Plugin
|
|
31
|
+
*
|
|
32
|
+
* Provides session management across your Vue application.
|
|
33
|
+
* Use with `app.use(QuilttPlugin, options)`.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* import { createApp } from 'vue'
|
|
38
|
+
* import { QuilttPlugin } from '@quiltt/vue'
|
|
39
|
+
*
|
|
40
|
+
* const app = createApp(App)
|
|
41
|
+
* app.use(QuilttPlugin, { token: '<SESSION_TOKEN>' })
|
|
42
|
+
* app.mount('#app')
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
declare const QuilttPlugin: Plugin<[QuilttPluginOptions?]>;
|
|
46
|
+
|
|
47
|
+
export { QuilttClientIdKey, QuilttPlugin, QuilttSessionKey, QuilttSetSessionKey };
|
|
48
|
+
export type { QuilttPluginOptions };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { ref, watch } from 'vue';
|
|
2
|
+
import { JsonWebTokenParse } from '@quiltt/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Injection keys and types for Quiltt Vue plugin
|
|
6
|
+
*/ // Injection keys for Quiltt state
|
|
7
|
+
const QuilttSessionKey = Symbol.for('quiltt-session');
|
|
8
|
+
const QuilttSetSessionKey = Symbol.for('quiltt-set-session');
|
|
9
|
+
const QuilttClientIdKey = Symbol.for('quiltt-client-id');
|
|
10
|
+
|
|
11
|
+
// Initialize JWT parser with our specific claims type
|
|
12
|
+
const parse = JsonWebTokenParse;
|
|
13
|
+
// Storage key for session persistence
|
|
14
|
+
const STORAGE_KEY = 'quiltt:session';
|
|
15
|
+
/**
|
|
16
|
+
* Get stored token from localStorage (browser only)
|
|
17
|
+
*/ const getStoredToken = ()=>{
|
|
18
|
+
if (typeof window === 'undefined' || typeof localStorage === 'undefined') {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
return localStorage.getItem(STORAGE_KEY);
|
|
23
|
+
} catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Store token in localStorage (browser only)
|
|
29
|
+
*/ const setStoredToken = (token)=>{
|
|
30
|
+
if (typeof window === 'undefined' || typeof localStorage === 'undefined') {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
if (token) {
|
|
35
|
+
localStorage.setItem(STORAGE_KEY, token);
|
|
36
|
+
} else {
|
|
37
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
// Storage not available
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Quiltt Vue Plugin
|
|
45
|
+
*
|
|
46
|
+
* Provides session management across your Vue application.
|
|
47
|
+
* Use with `app.use(QuilttPlugin, options)`.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* import { createApp } from 'vue'
|
|
52
|
+
* import { QuilttPlugin } from '@quiltt/vue'
|
|
53
|
+
*
|
|
54
|
+
* const app = createApp(App)
|
|
55
|
+
* app.use(QuilttPlugin, { token: '<SESSION_TOKEN>' })
|
|
56
|
+
* app.mount('#app')
|
|
57
|
+
* ```
|
|
58
|
+
*/ const QuilttPlugin = {
|
|
59
|
+
install (app, options) {
|
|
60
|
+
// Instance-scoped timeout for session expiration
|
|
61
|
+
let sessionTimeout;
|
|
62
|
+
let isCleanedUp = false;
|
|
63
|
+
let stopSessionWatcher;
|
|
64
|
+
/**
|
|
65
|
+
* Clear the session timeout for this app instance
|
|
66
|
+
*/ const clearSessionTimeout = ()=>{
|
|
67
|
+
if (sessionTimeout) {
|
|
68
|
+
clearTimeout(sessionTimeout);
|
|
69
|
+
sessionTimeout = undefined;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
// Initialize with provided token or stored token
|
|
73
|
+
const initialToken = options?.token ?? getStoredToken();
|
|
74
|
+
const initialSession = parse(initialToken);
|
|
75
|
+
// Reactive session state
|
|
76
|
+
const session = ref(initialSession);
|
|
77
|
+
const clientId = ref(options?.clientId);
|
|
78
|
+
/**
|
|
79
|
+
* Set session token
|
|
80
|
+
* Parses token, updates storage, and sets expiration timer
|
|
81
|
+
*/ const setSession = (token)=>{
|
|
82
|
+
const parsed = parse(token);
|
|
83
|
+
session.value = parsed;
|
|
84
|
+
setStoredToken(token ?? null);
|
|
85
|
+
// Clear any existing expiration timer
|
|
86
|
+
clearSessionTimeout();
|
|
87
|
+
// Set new expiration timer if session is valid
|
|
88
|
+
if (parsed) {
|
|
89
|
+
const expirationMS = parsed.claims.exp * 1000;
|
|
90
|
+
const timeUntilExpiry = expirationMS - Date.now();
|
|
91
|
+
if (timeUntilExpiry > 0) {
|
|
92
|
+
sessionTimeout = setTimeout(()=>{
|
|
93
|
+
session.value = null;
|
|
94
|
+
setStoredToken(null);
|
|
95
|
+
}, timeUntilExpiry);
|
|
96
|
+
} else {
|
|
97
|
+
// Token already expired
|
|
98
|
+
session.value = null;
|
|
99
|
+
setStoredToken(null);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
// Storage event handler for cross-tab synchronization
|
|
104
|
+
let storageHandler;
|
|
105
|
+
// Listen for storage changes from other tabs/windows
|
|
106
|
+
if (typeof window !== 'undefined') {
|
|
107
|
+
storageHandler = (event)=>{
|
|
108
|
+
if (event.key === STORAGE_KEY) {
|
|
109
|
+
const newSession = parse(event.newValue);
|
|
110
|
+
session.value = newSession;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
window.addEventListener('storage', storageHandler);
|
|
114
|
+
}
|
|
115
|
+
// Cleanup function for when the app is unmounted
|
|
116
|
+
const cleanup = ()=>{
|
|
117
|
+
if (isCleanedUp) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
isCleanedUp = true;
|
|
121
|
+
clearSessionTimeout();
|
|
122
|
+
if (stopSessionWatcher) {
|
|
123
|
+
stopSessionWatcher();
|
|
124
|
+
stopSessionWatcher = undefined;
|
|
125
|
+
}
|
|
126
|
+
if (typeof window !== 'undefined' && storageHandler) {
|
|
127
|
+
window.removeEventListener('storage', storageHandler);
|
|
128
|
+
storageHandler = undefined;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
// Register cleanup on app unmount (Vue 3.5+)
|
|
132
|
+
if (typeof app.onUnmount === 'function') {
|
|
133
|
+
app.onUnmount(cleanup);
|
|
134
|
+
}
|
|
135
|
+
// Ensure cleanup runs on all supported Vue versions (3.3+)
|
|
136
|
+
if (typeof app.unmount === 'function') {
|
|
137
|
+
const originalUnmount = app.unmount.bind(app);
|
|
138
|
+
app.unmount = (...args)=>{
|
|
139
|
+
cleanup();
|
|
140
|
+
return originalUnmount(...args);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Watch for session changes to update expiration timer
|
|
144
|
+
stopSessionWatcher = watch(()=>session.value, (newSession)=>{
|
|
145
|
+
if (!newSession) {
|
|
146
|
+
clearSessionTimeout();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const expirationMS = newSession.claims.exp * 1000;
|
|
150
|
+
const timeUntilExpiry = expirationMS - Date.now();
|
|
151
|
+
if (timeUntilExpiry <= 0) {
|
|
152
|
+
session.value = null;
|
|
153
|
+
setStoredToken(null);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
clearSessionTimeout();
|
|
157
|
+
sessionTimeout = setTimeout(()=>{
|
|
158
|
+
session.value = null;
|
|
159
|
+
setStoredToken(null);
|
|
160
|
+
}, timeUntilExpiry);
|
|
161
|
+
}, {
|
|
162
|
+
immediate: true
|
|
163
|
+
});
|
|
164
|
+
// Provide session state to all components
|
|
165
|
+
app.provide(QuilttSessionKey, session);
|
|
166
|
+
app.provide(QuilttSetSessionKey, setSession);
|
|
167
|
+
app.provide(QuilttClientIdKey, clientId);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export { QuilttClientIdKey, QuilttPlugin, QuilttSessionKey, QuilttSetSessionKey };
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quiltt/vue",
|
|
3
|
+
"version": "5.1.2",
|
|
4
|
+
"description": "Vue 3 Composables and Components for Quiltt Connector",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"quiltt",
|
|
7
|
+
"quiltt-connector",
|
|
8
|
+
"vue",
|
|
9
|
+
"vue3",
|
|
10
|
+
"typescript"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/quiltt/quiltt-js/tree/main/packages/vue#readme",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/quiltt/quiltt-js.git",
|
|
16
|
+
"directory": "packages/vue"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/quiltt/quiltt-js/issues"
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": [],
|
|
23
|
+
"type": "module",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"require": "./dist/index.cjs",
|
|
28
|
+
"import": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./composables": {
|
|
31
|
+
"types": "./dist/composables/index.d.ts",
|
|
32
|
+
"require": "./dist/composables/index.cjs",
|
|
33
|
+
"import": "./dist/composables/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./components": {
|
|
36
|
+
"types": "./dist/components/index.d.ts",
|
|
37
|
+
"require": "./dist/components/index.cjs",
|
|
38
|
+
"import": "./dist/components/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./plugin": {
|
|
41
|
+
"types": "./dist/plugin/index.d.ts",
|
|
42
|
+
"require": "./dist/plugin/index.cjs",
|
|
43
|
+
"import": "./dist/plugin/index.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"types": "./dist/index.d.ts",
|
|
47
|
+
"files": [
|
|
48
|
+
"dist/**",
|
|
49
|
+
"src/**",
|
|
50
|
+
"CHANGELOG.md"
|
|
51
|
+
],
|
|
52
|
+
"main": "dist/index.js",
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@quiltt/core": "5.1.2"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@biomejs/biome": "2.4.3",
|
|
58
|
+
"@types/node": "24.11.0",
|
|
59
|
+
"bunchee": "6.9.4",
|
|
60
|
+
"rimraf": "6.1.3",
|
|
61
|
+
"typescript": "5.9.3",
|
|
62
|
+
"vue": "3.5.28"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"vue": "^3.3.0"
|
|
66
|
+
},
|
|
67
|
+
"tags": [
|
|
68
|
+
"quiltt",
|
|
69
|
+
"vue"
|
|
70
|
+
],
|
|
71
|
+
"publishConfig": {
|
|
72
|
+
"access": "public"
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "bunchee",
|
|
76
|
+
"clean": "rimraf .turbo dist",
|
|
77
|
+
"dev": "bunchee --watch",
|
|
78
|
+
"lint": "TIMING=1 biome check src/ tests/ --fix",
|
|
79
|
+
"typecheck": "tsc --project tsconfig.json --noEmit"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QuilttButton - Button component that opens Quiltt Connector modal
|
|
3
|
+
*
|
|
4
|
+
* Wraps a button (or custom element) that opens the Quiltt Connector
|
|
5
|
+
* in a modal overlay when clicked.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```vue
|
|
9
|
+
* <QuilttButton
|
|
10
|
+
* :connector-id="connectorId"
|
|
11
|
+
* @exit-success="handleSuccess"
|
|
12
|
+
* >
|
|
13
|
+
* Add Bank Account
|
|
14
|
+
* </QuilttButton>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { computed, defineComponent, h, type PropType, watch } from 'vue'
|
|
19
|
+
|
|
20
|
+
import type { ConnectorSDKCallbackMetadata, ConnectorSDKEventType } from '@quiltt/core'
|
|
21
|
+
|
|
22
|
+
import { useQuilttConnector } from '../composables/useQuilttConnector'
|
|
23
|
+
import { oauthRedirectUrlDeprecationWarning } from '../constants/deprecation-warnings'
|
|
24
|
+
|
|
25
|
+
export const QuilttButton = defineComponent({
|
|
26
|
+
name: 'QuilttButton',
|
|
27
|
+
|
|
28
|
+
props: {
|
|
29
|
+
/** Quiltt Connector ID */
|
|
30
|
+
connectorId: {
|
|
31
|
+
type: String,
|
|
32
|
+
required: true,
|
|
33
|
+
},
|
|
34
|
+
/** Existing connection ID for reconnection */
|
|
35
|
+
connectionId: {
|
|
36
|
+
type: String as PropType<string | undefined>,
|
|
37
|
+
default: undefined,
|
|
38
|
+
},
|
|
39
|
+
/** Pre-select a specific institution */
|
|
40
|
+
institution: {
|
|
41
|
+
type: String as PropType<string | undefined>,
|
|
42
|
+
default: undefined,
|
|
43
|
+
},
|
|
44
|
+
/** Deep link URL for OAuth callbacks (mobile apps) */
|
|
45
|
+
appLauncherUrl: {
|
|
46
|
+
type: String as PropType<string | undefined>,
|
|
47
|
+
default: undefined,
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* @deprecated Use `appLauncherUrl` instead. This property will be removed in a future version.
|
|
51
|
+
* The OAuth redirect URL for mobile or embedded webview flows.
|
|
52
|
+
*/
|
|
53
|
+
oauthRedirectUrl: {
|
|
54
|
+
type: String as PropType<string | undefined>,
|
|
55
|
+
default: undefined,
|
|
56
|
+
},
|
|
57
|
+
/** Render as a different element */
|
|
58
|
+
as: {
|
|
59
|
+
type: String,
|
|
60
|
+
default: 'button',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
emits: {
|
|
65
|
+
/** Connector loaded */
|
|
66
|
+
load: (_metadata: ConnectorSDKCallbackMetadata) => true,
|
|
67
|
+
/** Connector opened */
|
|
68
|
+
open: (_metadata: ConnectorSDKCallbackMetadata) => true,
|
|
69
|
+
/** Connection successful */
|
|
70
|
+
'exit-success': (_metadata: ConnectorSDKCallbackMetadata) => true,
|
|
71
|
+
/** User cancelled */
|
|
72
|
+
'exit-abort': (_metadata: ConnectorSDKCallbackMetadata) => true,
|
|
73
|
+
/** Error occurred */
|
|
74
|
+
'exit-error': (_metadata: ConnectorSDKCallbackMetadata) => true,
|
|
75
|
+
/** Connector exited (any reason) */
|
|
76
|
+
exit: (_type: ConnectorSDKEventType, _metadata: ConnectorSDKCallbackMetadata) => true,
|
|
77
|
+
/** Any connector event */
|
|
78
|
+
event: (_type: ConnectorSDKEventType, _metadata: ConnectorSDKCallbackMetadata) => true,
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
setup(props, { emit, slots }) {
|
|
82
|
+
watch(
|
|
83
|
+
() => props.oauthRedirectUrl,
|
|
84
|
+
(value) => {
|
|
85
|
+
if (value !== undefined) {
|
|
86
|
+
console.warn(oauthRedirectUrlDeprecationWarning)
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
{ immediate: true }
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
const effectiveAppLauncherUri = computed(() => props.appLauncherUrl ?? props.oauthRedirectUrl)
|
|
93
|
+
|
|
94
|
+
const { open } = useQuilttConnector(() => props.connectorId, {
|
|
95
|
+
connectionId: () => props.connectionId,
|
|
96
|
+
institution: () => props.institution,
|
|
97
|
+
appLauncherUrl: effectiveAppLauncherUri,
|
|
98
|
+
onEvent: (type, metadata) => emit('event', type, metadata),
|
|
99
|
+
onOpen: (metadata) => emit('open', metadata),
|
|
100
|
+
onLoad: (metadata) => emit('load', metadata),
|
|
101
|
+
onExit: (type, metadata) => emit('exit', type, metadata),
|
|
102
|
+
onExitSuccess: (metadata) => emit('exit-success', metadata),
|
|
103
|
+
onExitAbort: (metadata) => emit('exit-abort', metadata),
|
|
104
|
+
onExitError: (metadata) => emit('exit-error', metadata),
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
const handleClick = () => {
|
|
108
|
+
open()
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return () =>
|
|
112
|
+
h(
|
|
113
|
+
props.as,
|
|
114
|
+
{
|
|
115
|
+
class: 'quiltt-button',
|
|
116
|
+
onClick: handleClick,
|
|
117
|
+
},
|
|
118
|
+
slots.default?.()
|
|
119
|
+
)
|
|
120
|
+
},
|
|
121
|
+
})
|