@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.
Files changed (96) hide show
  1. package/README.md +554 -0
  2. package/dist/analytics/components/GoogleAnalytics.svelte +96 -0
  3. package/dist/analytics/config/analytics.config.d.ts +6 -0
  4. package/dist/analytics/config/analytics.config.d.ts.map +1 -0
  5. package/dist/analytics/config/analytics.config.js +27 -0
  6. package/dist/analytics/config/analytics.config.js.map +1 -0
  7. package/dist/analytics/index.d.ts +7 -0
  8. package/dist/analytics/index.d.ts.map +1 -0
  9. package/dist/analytics/index.js +9 -0
  10. package/dist/analytics/index.js.map +1 -0
  11. package/dist/analytics/interfaces/IAnalyticsService.d.ts +40 -0
  12. package/dist/analytics/interfaces/IAnalyticsService.d.ts.map +1 -0
  13. package/dist/analytics/interfaces/IAnalyticsService.js +2 -0
  14. package/dist/analytics/interfaces/IAnalyticsService.js.map +1 -0
  15. package/dist/analytics/services/AnalyticsService.d.ts +37 -0
  16. package/dist/analytics/services/AnalyticsService.d.ts.map +1 -0
  17. package/dist/analytics/services/AnalyticsService.js +261 -0
  18. package/dist/analytics/services/AnalyticsService.js.map +1 -0
  19. package/dist/analytics/utils/consent.d.ts +52 -0
  20. package/dist/analytics/utils/consent.d.ts.map +1 -0
  21. package/dist/analytics/utils/consent.js +138 -0
  22. package/dist/analytics/utils/consent.js.map +1 -0
  23. package/dist/auth/index.d.ts +10 -0
  24. package/dist/auth/index.d.ts.map +1 -0
  25. package/dist/auth/index.js +49 -0
  26. package/dist/auth/index.js.map +1 -0
  27. package/dist/client/ApiClient.d.ts +17 -0
  28. package/dist/client/ApiClient.d.ts.map +1 -0
  29. package/dist/client/ApiClient.js +184 -0
  30. package/dist/client/ApiClient.js.map +1 -0
  31. package/dist/client/NotificationComponent.d.ts +7 -0
  32. package/dist/client/NotificationComponent.d.ts.map +1 -0
  33. package/dist/client/NotificationComponent.js +131 -0
  34. package/dist/client/NotificationComponent.js.map +1 -0
  35. package/dist/client/apiWrapper.d.ts +324 -0
  36. package/dist/client/apiWrapper.d.ts.map +1 -0
  37. package/dist/client/apiWrapper.js +257 -0
  38. package/dist/client/apiWrapper.js.map +1 -0
  39. package/dist/client/authErrorHandler.d.ts +19 -0
  40. package/dist/client/authErrorHandler.d.ts.map +1 -0
  41. package/dist/client/authErrorHandler.js +40 -0
  42. package/dist/client/authErrorHandler.js.map +1 -0
  43. package/dist/client/hooks.d.ts +11 -0
  44. package/dist/client/hooks.d.ts.map +1 -0
  45. package/dist/client/hooks.js +28 -0
  46. package/dist/client/hooks.js.map +1 -0
  47. package/dist/client/index.d.ts +8 -0
  48. package/dist/client/index.d.ts.map +1 -0
  49. package/dist/client/index.js +13 -0
  50. package/dist/client/index.js.map +1 -0
  51. package/dist/client/jwtDecoder.d.ts +56 -0
  52. package/dist/client/jwtDecoder.d.ts.map +1 -0
  53. package/dist/client/jwtDecoder.js +114 -0
  54. package/dist/client/jwtDecoder.js.map +1 -0
  55. package/dist/client/notifications.d.ts +55 -0
  56. package/dist/client/notifications.d.ts.map +1 -0
  57. package/dist/client/notifications.js +160 -0
  58. package/dist/client/notifications.js.map +1 -0
  59. package/dist/client/stores.d.ts +26 -0
  60. package/dist/client/stores.d.ts.map +1 -0
  61. package/dist/client/stores.js +196 -0
  62. package/dist/client/stores.js.map +1 -0
  63. package/dist/consent/components/CookieConsent.svelte +580 -0
  64. package/dist/consent/config/consent.config.d.ts +7 -0
  65. package/dist/consent/config/consent.config.d.ts.map +1 -0
  66. package/dist/consent/config/consent.config.js +194 -0
  67. package/dist/consent/config/consent.config.js.map +1 -0
  68. package/dist/consent/index.d.ts +5 -0
  69. package/dist/consent/index.d.ts.map +1 -0
  70. package/dist/consent/index.js +7 -0
  71. package/dist/consent/index.js.map +1 -0
  72. package/dist/consent/interfaces/IConsentService.d.ts +121 -0
  73. package/dist/consent/interfaces/IConsentService.d.ts.map +1 -0
  74. package/dist/consent/interfaces/IConsentService.js +2 -0
  75. package/dist/consent/interfaces/IConsentService.js.map +1 -0
  76. package/dist/consent/services/ConsentService.d.ts +39 -0
  77. package/dist/consent/services/ConsentService.d.ts.map +1 -0
  78. package/dist/consent/services/ConsentService.js +302 -0
  79. package/dist/consent/services/ConsentService.js.map +1 -0
  80. package/dist/consent/utils/analytics.d.ts +52 -0
  81. package/dist/consent/utils/analytics.d.ts.map +1 -0
  82. package/dist/consent/utils/analytics.js +181 -0
  83. package/dist/consent/utils/analytics.js.map +1 -0
  84. package/dist/hooks/index.d.ts +14 -0
  85. package/dist/hooks/index.d.ts.map +1 -0
  86. package/dist/hooks/index.js +218 -0
  87. package/dist/hooks/index.js.map +1 -0
  88. package/dist/index.d.ts +5 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.js +10 -0
  91. package/dist/index.js.map +1 -0
  92. package/dist/types/index.d.ts +88 -0
  93. package/dist/types/index.d.ts.map +1 -0
  94. package/dist/types/index.js +2 -0
  95. package/dist/types/index.js.map +1 -0
  96. 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"}