@groundbrick/sveltekit-adapter 0.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/README.md +554 -0
- package/dist/analytics/components/GoogleAnalytics.svelte +96 -0
- package/dist/analytics/config/analytics.config.d.ts +6 -0
- package/dist/analytics/config/analytics.config.d.ts.map +1 -0
- package/dist/analytics/config/analytics.config.js +27 -0
- package/dist/analytics/config/analytics.config.js.map +1 -0
- package/dist/analytics/index.d.ts +7 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +9 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/interfaces/IAnalyticsService.d.ts +40 -0
- package/dist/analytics/interfaces/IAnalyticsService.d.ts.map +1 -0
- package/dist/analytics/interfaces/IAnalyticsService.js +2 -0
- package/dist/analytics/interfaces/IAnalyticsService.js.map +1 -0
- package/dist/analytics/services/AnalyticsService.d.ts +37 -0
- package/dist/analytics/services/AnalyticsService.d.ts.map +1 -0
- package/dist/analytics/services/AnalyticsService.js +261 -0
- package/dist/analytics/services/AnalyticsService.js.map +1 -0
- package/dist/analytics/utils/consent.d.ts +52 -0
- package/dist/analytics/utils/consent.d.ts.map +1 -0
- package/dist/analytics/utils/consent.js +138 -0
- package/dist/analytics/utils/consent.js.map +1 -0
- package/dist/auth/index.d.ts +10 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +49 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/client/ApiClient.d.ts +17 -0
- package/dist/client/ApiClient.d.ts.map +1 -0
- package/dist/client/ApiClient.js +184 -0
- package/dist/client/ApiClient.js.map +1 -0
- package/dist/client/NotificationComponent.d.ts +7 -0
- package/dist/client/NotificationComponent.d.ts.map +1 -0
- package/dist/client/NotificationComponent.js +131 -0
- package/dist/client/NotificationComponent.js.map +1 -0
- package/dist/client/apiWrapper.d.ts +324 -0
- package/dist/client/apiWrapper.d.ts.map +1 -0
- package/dist/client/apiWrapper.js +257 -0
- package/dist/client/apiWrapper.js.map +1 -0
- package/dist/client/authErrorHandler.d.ts +19 -0
- package/dist/client/authErrorHandler.d.ts.map +1 -0
- package/dist/client/authErrorHandler.js +40 -0
- package/dist/client/authErrorHandler.js.map +1 -0
- package/dist/client/hooks.d.ts +11 -0
- package/dist/client/hooks.d.ts.map +1 -0
- package/dist/client/hooks.js +28 -0
- package/dist/client/hooks.js.map +1 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +13 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/jwtDecoder.d.ts +56 -0
- package/dist/client/jwtDecoder.d.ts.map +1 -0
- package/dist/client/jwtDecoder.js +114 -0
- package/dist/client/jwtDecoder.js.map +1 -0
- package/dist/client/notifications.d.ts +55 -0
- package/dist/client/notifications.d.ts.map +1 -0
- package/dist/client/notifications.js +160 -0
- package/dist/client/notifications.js.map +1 -0
- package/dist/client/stores.d.ts +26 -0
- package/dist/client/stores.d.ts.map +1 -0
- package/dist/client/stores.js +196 -0
- package/dist/client/stores.js.map +1 -0
- package/dist/consent/components/CookieConsent.svelte +580 -0
- package/dist/consent/config/consent.config.d.ts +7 -0
- package/dist/consent/config/consent.config.d.ts.map +1 -0
- package/dist/consent/config/consent.config.js +194 -0
- package/dist/consent/config/consent.config.js.map +1 -0
- package/dist/consent/index.d.ts +5 -0
- package/dist/consent/index.d.ts.map +1 -0
- package/dist/consent/index.js +7 -0
- package/dist/consent/index.js.map +1 -0
- package/dist/consent/interfaces/IConsentService.d.ts +121 -0
- package/dist/consent/interfaces/IConsentService.d.ts.map +1 -0
- package/dist/consent/interfaces/IConsentService.js +2 -0
- package/dist/consent/interfaces/IConsentService.js.map +1 -0
- package/dist/consent/services/ConsentService.d.ts +39 -0
- package/dist/consent/services/ConsentService.d.ts.map +1 -0
- package/dist/consent/services/ConsentService.js +302 -0
- package/dist/consent/services/ConsentService.js.map +1 -0
- package/dist/consent/utils/analytics.d.ts +52 -0
- package/dist/consent/utils/analytics.d.ts.map +1 -0
- package/dist/consent/utils/analytics.js +181 -0
- package/dist/consent/utils/analytics.js.map +1 -0
- package/dist/hooks/index.d.ts +14 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +218 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +88 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for controlling API wrapper behavior
|
|
3
|
+
*
|
|
4
|
+
* These options allow fine-grained control over how API calls are handled,
|
|
5
|
+
* including loading states, error handling, notifications, and authentication.
|
|
6
|
+
* All properties are optional and have sensible defaults.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Basic usage with default options
|
|
11
|
+
* await apiWrapper.get('/api/users');
|
|
12
|
+
*
|
|
13
|
+
* // Silent API call (no loading or error notifications)
|
|
14
|
+
* await apiWrapper.get('/api/background-sync', {
|
|
15
|
+
* showLoading: false,
|
|
16
|
+
* showErrorNotification: false
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Login endpoint (skip auth error handling to prevent redirect loops)
|
|
20
|
+
* await apiWrapper.post('/api/auth/login', credentials, {
|
|
21
|
+
* skipAuthHandling: true,
|
|
22
|
+
* customErrorMessage: 'Invalid credentials. Please try again.'
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export interface ApiWrapperOptions {
|
|
27
|
+
/**
|
|
28
|
+
* Controls whether to show loading state in the apiStore
|
|
29
|
+
*
|
|
30
|
+
* When true (default), the apiStore loading state will be set to true
|
|
31
|
+
* during the API call and false when completed. This is useful for
|
|
32
|
+
* showing loading spinners or disabling UI elements.
|
|
33
|
+
*
|
|
34
|
+
* Set to false for background operations or when you want to handle
|
|
35
|
+
* loading states manually.
|
|
36
|
+
*
|
|
37
|
+
* @default true
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* // Show loading state (default behavior)
|
|
42
|
+
* await apiWrapper.get('/api/users', { showLoading: true });
|
|
43
|
+
*
|
|
44
|
+
* // Silent background operation
|
|
45
|
+
* await apiWrapper.get('/api/background-sync', { showLoading: false });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
showLoading?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Controls whether to automatically show error notifications
|
|
51
|
+
*
|
|
52
|
+
* When true (default), errors will be displayed to the user via
|
|
53
|
+
* the notification system (toast messages). Set to false when you
|
|
54
|
+
* want to handle errors manually or for silent operations.
|
|
55
|
+
*
|
|
56
|
+
* @default true
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* // Show error notifications (default)
|
|
61
|
+
* await apiWrapper.get('/api/users', { showErrorNotification: true });
|
|
62
|
+
*
|
|
63
|
+
* // Handle errors manually
|
|
64
|
+
* try {
|
|
65
|
+
* await apiWrapper.get('/api/data', { showErrorNotification: false });
|
|
66
|
+
* } catch (error) {
|
|
67
|
+
* // Custom error handling
|
|
68
|
+
* console.log('Custom error handling:', error);
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
showErrorNotification?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Custom error message to display instead of the server-provided error
|
|
75
|
+
*
|
|
76
|
+
* When provided, this message will be shown to the user instead of
|
|
77
|
+
* the error message from the server. Useful for providing user-friendly
|
|
78
|
+
* error messages or localization.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* // User-friendly error message
|
|
83
|
+
* await apiWrapper.delete('/api/users/123', {
|
|
84
|
+
* customErrorMessage: 'Could not delete user. Please try again later.'
|
|
85
|
+
* });
|
|
86
|
+
*
|
|
87
|
+
* // Localized error message
|
|
88
|
+
* await apiWrapper.post('/api/appointments', data, {
|
|
89
|
+
* customErrorMessage: 'Não foi possível criar o agendamento.'
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
customErrorMessage?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Skip authentication error handling for login/logout endpoints
|
|
96
|
+
*
|
|
97
|
+
* When true, 401/403 errors will not trigger automatic authentication
|
|
98
|
+
* error handling (like redirecting to login page). This is essential
|
|
99
|
+
* for login/logout endpoints to prevent redirect loops.
|
|
100
|
+
*
|
|
101
|
+
* @default false
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* // Login endpoint - prevent redirect loops
|
|
106
|
+
* await apiWrapper.post('/api/auth/login', credentials, {
|
|
107
|
+
* skipAuthHandling: true
|
|
108
|
+
* });
|
|
109
|
+
*
|
|
110
|
+
* // Logout endpoint - prevent redirect loops
|
|
111
|
+
* await apiWrapper.post('/api/auth/logout', {}, {
|
|
112
|
+
* skipAuthHandling: true
|
|
113
|
+
* });
|
|
114
|
+
*
|
|
115
|
+
* // Regular protected endpoint (default behavior)
|
|
116
|
+
* await apiWrapper.get('/api/profile'); // Will redirect on 401/403
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
skipAuthHandling?: boolean;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Wraps API client calls with common error handling, loading states, and notifications
|
|
123
|
+
*
|
|
124
|
+
* Provides a unified interface for making API calls with automatic:
|
|
125
|
+
* - Loading state management
|
|
126
|
+
* - Error handling and notifications
|
|
127
|
+
* - Authentication error processing
|
|
128
|
+
* - Parallel request handling
|
|
129
|
+
*/
|
|
130
|
+
export declare class ApiWrapper {
|
|
131
|
+
private apiClient;
|
|
132
|
+
/**
|
|
133
|
+
* Creates a new ApiWrapper instance
|
|
134
|
+
*
|
|
135
|
+
* @param apiClient - The underlying API client instance (e.g., axios, fetch wrapper)
|
|
136
|
+
* Should provide methods: get, post, put, patch, delete
|
|
137
|
+
*/
|
|
138
|
+
constructor(apiClient: any);
|
|
139
|
+
private isClientReady;
|
|
140
|
+
/**
|
|
141
|
+
* Wraps a single API call with comprehensive error handling and loading state management
|
|
142
|
+
*
|
|
143
|
+
* This is the core method that provides:
|
|
144
|
+
* - Automatic loading state management via apiStore
|
|
145
|
+
* - Authentication error handling (401/403 redirects)
|
|
146
|
+
* - Error notifications via toast system
|
|
147
|
+
* - Error state management in the store
|
|
148
|
+
*
|
|
149
|
+
* @template T - The expected return type of the API call
|
|
150
|
+
* @param apiCall - A function that returns a Promise with the API call
|
|
151
|
+
* @param options - Configuration options for handling the call
|
|
152
|
+
* @param options.showLoading - Whether to show loading state in apiStore (default: true)
|
|
153
|
+
* @param options.showErrorNotification - Whether to show error notifications (default: true)
|
|
154
|
+
* @param options.customErrorMessage - Custom error message to display instead of server error
|
|
155
|
+
* @param options.skipAuthHandling - Skip authentication error handling for login/logout (default: false)
|
|
156
|
+
*
|
|
157
|
+
* @returns Promise that resolves to the API response or void on error
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* const result = await apiWrapper.call(
|
|
162
|
+
* () => fetch('/api/users'),
|
|
163
|
+
* { showLoading: true, customErrorMessage: 'Failed to load users' }
|
|
164
|
+
* );
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
call<T>(apiCall: () => Promise<T>, options?: ApiWrapperOptions): Promise<T | void | any>;
|
|
168
|
+
/**
|
|
169
|
+
* Makes a GET request to the specified endpoint
|
|
170
|
+
*
|
|
171
|
+
* @template T - The expected response type
|
|
172
|
+
* @param endpoint - The API endpoint to call (e.g., '/api/users')
|
|
173
|
+
* @param options - Optional configuration for error handling and loading state
|
|
174
|
+
* @returns Promise resolving to the response data
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```typescript
|
|
178
|
+
* const users = await apiWrapper.get<User[]>('/api/users');
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
get<T>(endpoint: string, options?: ApiWrapperOptions): Promise<T>;
|
|
182
|
+
/**
|
|
183
|
+
* Makes a POST request to the specified endpoint with optional data
|
|
184
|
+
*
|
|
185
|
+
* @template T - The expected response type
|
|
186
|
+
* @param endpoint - The API endpoint to call (e.g., '/api/users')
|
|
187
|
+
* @param data - Optional request body data to send
|
|
188
|
+
* @param options - Optional configuration for error handling and loading state
|
|
189
|
+
* @returns Promise resolving to the response data
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* const newUser = await apiWrapper.post<User>('/api/users', {
|
|
194
|
+
* name: 'John Doe',
|
|
195
|
+
* email: 'john@example.com'
|
|
196
|
+
* });
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
post<T>(endpoint: string, data?: unknown, options?: ApiWrapperOptions): Promise<T>;
|
|
200
|
+
/**
|
|
201
|
+
* Makes a PUT request to the specified endpoint with optional data
|
|
202
|
+
* Typically used for full resource updates
|
|
203
|
+
*
|
|
204
|
+
* @template T - The expected response type
|
|
205
|
+
* @param endpoint - The API endpoint to call (e.g., '/api/users/123')
|
|
206
|
+
* @param data - Optional request body data to send
|
|
207
|
+
* @param options - Optional configuration for error handling and loading state
|
|
208
|
+
* @returns Promise resolving to the response data
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* const updatedUser = await apiWrapper.put<User>('/api/users/123', {
|
|
213
|
+
* name: 'Jane Doe',
|
|
214
|
+
* email: 'jane@example.com'
|
|
215
|
+
* });
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
put<T>(endpoint: string, data?: unknown, options?: ApiWrapperOptions): Promise<T>;
|
|
219
|
+
/**
|
|
220
|
+
* Makes a PATCH request to the specified endpoint with optional data
|
|
221
|
+
* Typically used for partial resource updates
|
|
222
|
+
*
|
|
223
|
+
* @template T - The expected response type
|
|
224
|
+
* @param endpoint - The API endpoint to call (e.g., '/api/users/123')
|
|
225
|
+
* @param data - Optional request body data to send (partial update)
|
|
226
|
+
* @param options - Optional configuration for error handling and loading state
|
|
227
|
+
* @returns Promise resolving to the response data
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* const updatedUser = await apiWrapper.patch<User>('/api/users/123', {
|
|
232
|
+
* email: 'newemail@example.com'
|
|
233
|
+
* });
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
patch<T>(endpoint: string, data?: unknown, options?: ApiWrapperOptions): Promise<T>;
|
|
237
|
+
/**
|
|
238
|
+
* Makes a DELETE request to the specified endpoint
|
|
239
|
+
*
|
|
240
|
+
* @template T - The expected response type
|
|
241
|
+
* @param endpoint - The API endpoint to call (e.g., '/api/users/123')
|
|
242
|
+
* @param options - Optional configuration for error handling and loading state
|
|
243
|
+
* @returns Promise resolving to the response data
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```typescript
|
|
247
|
+
* await apiWrapper.delete('/api/users/123', {
|
|
248
|
+
* customErrorMessage: 'Failed to delete user'
|
|
249
|
+
* });
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
delete<T>(endpoint: string, options?: ApiWrapperOptions): Promise<T>;
|
|
253
|
+
/**
|
|
254
|
+
* Executes multiple API calls in parallel with shared error handling and loading state
|
|
255
|
+
*
|
|
256
|
+
* All API calls will be executed simultaneously using Promise.all(), providing better
|
|
257
|
+
* performance than sequential calls. If any call fails, the entire operation fails
|
|
258
|
+
* and error handling is applied to the first error encountered.
|
|
259
|
+
*
|
|
260
|
+
* @template T - Tuple type representing the return types of all API calls
|
|
261
|
+
* @param apiCalls - Array of functions that return API call promises
|
|
262
|
+
* @param options - Optional configuration for error handling and loading state
|
|
263
|
+
* @returns Promise resolving to an array of all API call results
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```typescript
|
|
267
|
+
* const [users, posts, comments] = await apiWrapper.parallel([
|
|
268
|
+
* () => apiClient.get('/api/users'),
|
|
269
|
+
* () => apiClient.get('/api/posts'),
|
|
270
|
+
* () => apiClient.get('/api/comments')
|
|
271
|
+
* ]);
|
|
272
|
+
* ```
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```typescript
|
|
276
|
+
* // With error handling options
|
|
277
|
+
* const results = await apiWrapper.parallel(
|
|
278
|
+
* [() => fetch('/api/data1'), () => fetch('/api/data2')],
|
|
279
|
+
* { customErrorMessage: 'Failed to load dashboard data' }
|
|
280
|
+
* );
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
parallel<T extends any[]>(apiCalls: (() => Promise<any>)[], options?: ApiWrapperOptions): Promise<T>;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Factory function to create an ApiWrapper instance
|
|
287
|
+
*
|
|
288
|
+
* Provides a convenient way to create an ApiWrapper with the specified API client.
|
|
289
|
+
* The API client should implement standard HTTP methods (get, post, put, patch, delete)
|
|
290
|
+
* that return promises.
|
|
291
|
+
*
|
|
292
|
+
* @param apiClient - The underlying API client instance (e.g., axios instance, custom fetch wrapper)
|
|
293
|
+
* Must provide methods: get, post, put, patch, delete
|
|
294
|
+
* @returns A new ApiWrapper instance configured with the provided client
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```typescript
|
|
298
|
+
* import axios from 'axios';
|
|
299
|
+
*
|
|
300
|
+
* const apiClient = axios.create({
|
|
301
|
+
* baseURL: 'https://api.example.com',
|
|
302
|
+
* timeout: 10000
|
|
303
|
+
* });
|
|
304
|
+
*
|
|
305
|
+
* const apiWrapper = createApiWrapper(apiClient);
|
|
306
|
+
*
|
|
307
|
+
* // Now use the wrapper
|
|
308
|
+
* const users = await apiWrapper.get<User[]>('/users');
|
|
309
|
+
* ```
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* ```typescript
|
|
313
|
+
* // With custom fetch wrapper
|
|
314
|
+
* const fetchClient = {
|
|
315
|
+
* get: (url) => fetch(url).then(r => r.json()),
|
|
316
|
+
* post: (url, data) => fetch(url, { method: 'POST', body: JSON.stringify(data) })
|
|
317
|
+
* // ... other methods
|
|
318
|
+
* };
|
|
319
|
+
*
|
|
320
|
+
* const apiWrapper = createApiWrapper(fetchClient);
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
export declare function createApiWrapper(apiClient: any): ApiWrapper;
|
|
324
|
+
//# sourceMappingURL=apiWrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiWrapper.d.ts","sourceRoot":"","sources":["../../src/client/apiWrapper.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,qBAAa,UAAU;IAOP,OAAO,CAAC,SAAS;IAN7B;;;;;OAKG;gBACiB,SAAS,EAAE,GAAG;IAElC,OAAO,CAAC,aAAa,CAA0C;IAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACG,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC;IAgDlG;;;;;;;;;;;;OAYG;IACG,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC;IAIvE;;;;;;;;;;;;;;;;OAgBG;IACG,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC;IAIxF;;;;;;;;;;;;;;;;;OAiBG;IACG,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC;IAIvF;;;;;;;;;;;;;;;;OAgBG;IACG,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC;IAIzF;;;;;;;;;;;;;;OAcG;IACG,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC;IAI1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACG,QAAQ,CAAC,CAAC,SAAS,GAAG,EAAE,EAC1B,QAAQ,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAChC,OAAO,CAAC,EAAE,iBAAiB,GAC5B,OAAO,CAAC,CAAC,CAAC;CAGhB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,GAAG,GAAG,UAAU,CAE3D"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { apiStore } from './stores.js';
|
|
2
|
+
import { handleAuthError } from './authErrorHandler.js';
|
|
3
|
+
import { showError } from './notifications.js';
|
|
4
|
+
/**
|
|
5
|
+
* Wraps API client calls with common error handling, loading states, and notifications
|
|
6
|
+
*
|
|
7
|
+
* Provides a unified interface for making API calls with automatic:
|
|
8
|
+
* - Loading state management
|
|
9
|
+
* - Error handling and notifications
|
|
10
|
+
* - Authentication error processing
|
|
11
|
+
* - Parallel request handling
|
|
12
|
+
*/
|
|
13
|
+
export class ApiWrapper {
|
|
14
|
+
apiClient;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new ApiWrapper instance
|
|
17
|
+
*
|
|
18
|
+
* @param apiClient - The underlying API client instance (e.g., axios, fetch wrapper)
|
|
19
|
+
* Should provide methods: get, post, put, patch, delete
|
|
20
|
+
*/
|
|
21
|
+
constructor(apiClient) {
|
|
22
|
+
this.apiClient = apiClient;
|
|
23
|
+
}
|
|
24
|
+
isClientReady = typeof window !== 'undefined';
|
|
25
|
+
/**
|
|
26
|
+
* Wraps a single API call with comprehensive error handling and loading state management
|
|
27
|
+
*
|
|
28
|
+
* This is the core method that provides:
|
|
29
|
+
* - Automatic loading state management via apiStore
|
|
30
|
+
* - Authentication error handling (401/403 redirects)
|
|
31
|
+
* - Error notifications via toast system
|
|
32
|
+
* - Error state management in the store
|
|
33
|
+
*
|
|
34
|
+
* @template T - The expected return type of the API call
|
|
35
|
+
* @param apiCall - A function that returns a Promise with the API call
|
|
36
|
+
* @param options - Configuration options for handling the call
|
|
37
|
+
* @param options.showLoading - Whether to show loading state in apiStore (default: true)
|
|
38
|
+
* @param options.showErrorNotification - Whether to show error notifications (default: true)
|
|
39
|
+
* @param options.customErrorMessage - Custom error message to display instead of server error
|
|
40
|
+
* @param options.skipAuthHandling - Skip authentication error handling for login/logout (default: false)
|
|
41
|
+
*
|
|
42
|
+
* @returns Promise that resolves to the API response or void on error
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const result = await apiWrapper.call(
|
|
47
|
+
* () => fetch('/api/users'),
|
|
48
|
+
* { showLoading: true, customErrorMessage: 'Failed to load users' }
|
|
49
|
+
* );
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
async call(apiCall, options = {}) {
|
|
53
|
+
const { showLoading = true, showErrorNotification = true, customErrorMessage, skipAuthHandling = false, } = options;
|
|
54
|
+
if (showLoading) {
|
|
55
|
+
apiStore.setLoading(true);
|
|
56
|
+
}
|
|
57
|
+
let result;
|
|
58
|
+
try {
|
|
59
|
+
result = await apiCall();
|
|
60
|
+
if (result?.success)
|
|
61
|
+
return result;
|
|
62
|
+
else
|
|
63
|
+
throw result?.error;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
// Handle auth errors (401/403)
|
|
67
|
+
if (!skipAuthHandling && (error.status === 401 || error.status === 403)) {
|
|
68
|
+
await handleAuthError(error);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Show error notification
|
|
72
|
+
if (showErrorNotification && this.isClientReady) {
|
|
73
|
+
const errorMessage = customErrorMessage || error.message || 'Ocorreu um erro';
|
|
74
|
+
showError(errorMessage);
|
|
75
|
+
}
|
|
76
|
+
// Set error in store
|
|
77
|
+
apiStore.setError(error.message || 'Ocorreu um erro.');
|
|
78
|
+
return error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
if (showLoading) {
|
|
83
|
+
apiStore.setLoading(false);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Makes a GET request to the specified endpoint
|
|
89
|
+
*
|
|
90
|
+
* @template T - The expected response type
|
|
91
|
+
* @param endpoint - The API endpoint to call (e.g., '/api/users')
|
|
92
|
+
* @param options - Optional configuration for error handling and loading state
|
|
93
|
+
* @returns Promise resolving to the response data
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* const users = await apiWrapper.get<User[]>('/api/users');
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
async get(endpoint, options) {
|
|
101
|
+
return this.call(() => this.apiClient.get(endpoint), options);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Makes a POST request to the specified endpoint with optional data
|
|
105
|
+
*
|
|
106
|
+
* @template T - The expected response type
|
|
107
|
+
* @param endpoint - The API endpoint to call (e.g., '/api/users')
|
|
108
|
+
* @param data - Optional request body data to send
|
|
109
|
+
* @param options - Optional configuration for error handling and loading state
|
|
110
|
+
* @returns Promise resolving to the response data
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* const newUser = await apiWrapper.post<User>('/api/users', {
|
|
115
|
+
* name: 'John Doe',
|
|
116
|
+
* email: 'john@example.com'
|
|
117
|
+
* });
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
async post(endpoint, data, options) {
|
|
121
|
+
return this.call(() => this.apiClient.post(endpoint, data), options);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Makes a PUT request to the specified endpoint with optional data
|
|
125
|
+
* Typically used for full resource updates
|
|
126
|
+
*
|
|
127
|
+
* @template T - The expected response type
|
|
128
|
+
* @param endpoint - The API endpoint to call (e.g., '/api/users/123')
|
|
129
|
+
* @param data - Optional request body data to send
|
|
130
|
+
* @param options - Optional configuration for error handling and loading state
|
|
131
|
+
* @returns Promise resolving to the response data
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* const updatedUser = await apiWrapper.put<User>('/api/users/123', {
|
|
136
|
+
* name: 'Jane Doe',
|
|
137
|
+
* email: 'jane@example.com'
|
|
138
|
+
* });
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
async put(endpoint, data, options) {
|
|
142
|
+
return this.call(() => this.apiClient.put(endpoint, data), options);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Makes a PATCH request to the specified endpoint with optional data
|
|
146
|
+
* Typically used for partial resource updates
|
|
147
|
+
*
|
|
148
|
+
* @template T - The expected response type
|
|
149
|
+
* @param endpoint - The API endpoint to call (e.g., '/api/users/123')
|
|
150
|
+
* @param data - Optional request body data to send (partial update)
|
|
151
|
+
* @param options - Optional configuration for error handling and loading state
|
|
152
|
+
* @returns Promise resolving to the response data
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```typescript
|
|
156
|
+
* const updatedUser = await apiWrapper.patch<User>('/api/users/123', {
|
|
157
|
+
* email: 'newemail@example.com'
|
|
158
|
+
* });
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
async patch(endpoint, data, options) {
|
|
162
|
+
return this.call(() => this.apiClient.patch(endpoint, data), options);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Makes a DELETE request to the specified endpoint
|
|
166
|
+
*
|
|
167
|
+
* @template T - The expected response type
|
|
168
|
+
* @param endpoint - The API endpoint to call (e.g., '/api/users/123')
|
|
169
|
+
* @param options - Optional configuration for error handling and loading state
|
|
170
|
+
* @returns Promise resolving to the response data
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* await apiWrapper.delete('/api/users/123', {
|
|
175
|
+
* customErrorMessage: 'Failed to delete user'
|
|
176
|
+
* });
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
async delete(endpoint, options) {
|
|
180
|
+
return this.call(() => this.apiClient.delete(endpoint), options);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Executes multiple API calls in parallel with shared error handling and loading state
|
|
184
|
+
*
|
|
185
|
+
* All API calls will be executed simultaneously using Promise.all(), providing better
|
|
186
|
+
* performance than sequential calls. If any call fails, the entire operation fails
|
|
187
|
+
* and error handling is applied to the first error encountered.
|
|
188
|
+
*
|
|
189
|
+
* @template T - Tuple type representing the return types of all API calls
|
|
190
|
+
* @param apiCalls - Array of functions that return API call promises
|
|
191
|
+
* @param options - Optional configuration for error handling and loading state
|
|
192
|
+
* @returns Promise resolving to an array of all API call results
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* const [users, posts, comments] = await apiWrapper.parallel([
|
|
197
|
+
* () => apiClient.get('/api/users'),
|
|
198
|
+
* () => apiClient.get('/api/posts'),
|
|
199
|
+
* () => apiClient.get('/api/comments')
|
|
200
|
+
* ]);
|
|
201
|
+
* ```
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* // With error handling options
|
|
206
|
+
* const results = await apiWrapper.parallel(
|
|
207
|
+
* [() => fetch('/api/data1'), () => fetch('/api/data2')],
|
|
208
|
+
* { customErrorMessage: 'Failed to load dashboard data' }
|
|
209
|
+
* );
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
async parallel(apiCalls, options) {
|
|
213
|
+
return this.call(() => Promise.all(apiCalls), options);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Factory function to create an ApiWrapper instance
|
|
218
|
+
*
|
|
219
|
+
* Provides a convenient way to create an ApiWrapper with the specified API client.
|
|
220
|
+
* The API client should implement standard HTTP methods (get, post, put, patch, delete)
|
|
221
|
+
* that return promises.
|
|
222
|
+
*
|
|
223
|
+
* @param apiClient - The underlying API client instance (e.g., axios instance, custom fetch wrapper)
|
|
224
|
+
* Must provide methods: get, post, put, patch, delete
|
|
225
|
+
* @returns A new ApiWrapper instance configured with the provided client
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```typescript
|
|
229
|
+
* import axios from 'axios';
|
|
230
|
+
*
|
|
231
|
+
* const apiClient = axios.create({
|
|
232
|
+
* baseURL: 'https://api.example.com',
|
|
233
|
+
* timeout: 10000
|
|
234
|
+
* });
|
|
235
|
+
*
|
|
236
|
+
* const apiWrapper = createApiWrapper(apiClient);
|
|
237
|
+
*
|
|
238
|
+
* // Now use the wrapper
|
|
239
|
+
* const users = await apiWrapper.get<User[]>('/users');
|
|
240
|
+
* ```
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* // With custom fetch wrapper
|
|
245
|
+
* const fetchClient = {
|
|
246
|
+
* get: (url) => fetch(url).then(r => r.json()),
|
|
247
|
+
* post: (url, data) => fetch(url, { method: 'POST', body: JSON.stringify(data) })
|
|
248
|
+
* // ... other methods
|
|
249
|
+
* };
|
|
250
|
+
*
|
|
251
|
+
* const apiWrapper = createApiWrapper(fetchClient);
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
export function createApiWrapper(apiClient) {
|
|
255
|
+
return new ApiWrapper(apiClient);
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=apiWrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiWrapper.js","sourceRoot":"","sources":["../../src/client/apiWrapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface AuthError extends Error {
|
|
2
|
+
status?: number;
|
|
3
|
+
redirectTo?: string;
|
|
4
|
+
originalError?: any;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Simple authentication error handler for client-side
|
|
8
|
+
*/
|
|
9
|
+
export declare class AuthErrorHandler {
|
|
10
|
+
private redirectPath;
|
|
11
|
+
constructor(redirectPath?: string);
|
|
12
|
+
/**
|
|
13
|
+
* Handle authentication errors from API responses
|
|
14
|
+
*/
|
|
15
|
+
handleAuthError(error: AuthError): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare const authErrorHandler: AuthErrorHandler;
|
|
18
|
+
export declare const handleAuthError: (error: AuthError) => Promise<void>;
|
|
19
|
+
//# sourceMappingURL=authErrorHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authErrorHandler.d.ts","sourceRoot":"","sources":["../../src/client/authErrorHandler.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAU,SAAQ,KAAK;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,GAAG,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,YAAY,CAAS;gBAEjB,YAAY,GAAE,MAAiB;IAI3C;;OAEG;IACG,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAwBzD;AAGD,eAAO,MAAM,gBAAgB,kBAAyB,CAAC;AAGvD,eAAO,MAAM,eAAe,GAAI,OAAO,SAAS,kBAA4C,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { goto } from '$app/navigation';
|
|
2
|
+
import { browser } from '$app/environment';
|
|
3
|
+
import { createLogger } from '@groundbrick/logger';
|
|
4
|
+
import { authStore } from './stores.js';
|
|
5
|
+
const logger = createLogger().child('auth-handler');
|
|
6
|
+
/**
|
|
7
|
+
* Simple authentication error handler for client-side
|
|
8
|
+
*/
|
|
9
|
+
export class AuthErrorHandler {
|
|
10
|
+
redirectPath;
|
|
11
|
+
constructor(redirectPath = '/login') {
|
|
12
|
+
this.redirectPath = redirectPath;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Handle authentication errors from API responses
|
|
16
|
+
*/
|
|
17
|
+
async handleAuthError(error) {
|
|
18
|
+
if (!browser)
|
|
19
|
+
return;
|
|
20
|
+
logger.warn('Handling authentication error', {
|
|
21
|
+
status: error.status,
|
|
22
|
+
message: error.message,
|
|
23
|
+
});
|
|
24
|
+
authStore.logout();
|
|
25
|
+
// Redirect to login page if needed
|
|
26
|
+
const redirectTo = error.redirectTo || this.redirectPath;
|
|
27
|
+
logger.info('Redirecting to login page', { redirectTo });
|
|
28
|
+
// Add current page as return URL
|
|
29
|
+
const currentPath = window.location.pathname;
|
|
30
|
+
const returnUrl = currentPath !== '/' && currentPath !== redirectTo
|
|
31
|
+
? `?returnUrl=${encodeURIComponent(currentPath)}`
|
|
32
|
+
: '';
|
|
33
|
+
await goto(`${redirectTo}${returnUrl}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Create a default instance
|
|
37
|
+
export const authErrorHandler = new AuthErrorHandler();
|
|
38
|
+
// Utility function for easy use
|
|
39
|
+
export const handleAuthError = (error) => authErrorHandler.handleAuthError(error);
|
|
40
|
+
//# sourceMappingURL=authErrorHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authErrorHandler.js","sourceRoot":"","sources":["../../src/client/authErrorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;AAQpD;;GAEG;AACH,MAAM,OAAO,gBAAgB;IACjB,YAAY,CAAS;IAE7B,YAAY,eAAuB,QAAQ;QACvC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,KAAgB;QAClC,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE;YACzC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,OAAO,EAAE,KAAK,CAAC,OAAO;SACzB,CAAC,CAAC;QAEH,SAAS,CAAC,MAAM,EAAE,CAAC;QAEnB,mCAAmC;QAEnC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QAEzD,iCAAiC;QACjC,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC7C,MAAM,SAAS,GAAG,WAAW,KAAK,GAAG,IAAI,WAAW,KAAK,UAAU;YAC/D,CAAC,CAAC,cAAc,kBAAkB,CAAC,WAAW,CAAC,EAAE;YACjD,CAAC,CAAC,EAAE,CAAC;QAET,MAAM,IAAI,CAAC,GAAG,UAAU,GAAG,SAAS,EAAE,CAAC,CAAC;IAE5C,CAAC;CACJ;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC;AAEvD,gCAAgC;AAChC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAgB,EAAE,EAAE,CAAC,gBAAgB,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook that automatically clears non-persistent notifications when navigating.
|
|
3
|
+
* Call this function in your app's root layout to enable auto-clearing.
|
|
4
|
+
*/
|
|
5
|
+
export declare function useNavigationNotificationClear(): void;
|
|
6
|
+
/**
|
|
7
|
+
* Alternative hook that can be used in specific pages/components
|
|
8
|
+
* to clear notifications when the component is mounted
|
|
9
|
+
*/
|
|
10
|
+
export declare function useClearNotificationsOnMount(): void;
|
|
11
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/client/hooks.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,8BAA8B,SAU7C;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,SAI3C"}
|