@fluxbase/sdk 0.0.1-rc.25 → 0.0.1-rc.27

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/dist/index.cjs CHANGED
@@ -165,16 +165,19 @@ var FluxbaseAuth = class {
165
165
  }
166
166
  }
167
167
  /**
168
- * Get the current session
168
+ * Get the current session (Supabase-compatible)
169
+ * Returns the session from the client-side cache without making a network request
169
170
  */
170
- getSession() {
171
- return this.session;
171
+ async getSession() {
172
+ return { data: { session: this.session }, error: null };
172
173
  }
173
174
  /**
174
- * Get the current user
175
+ * Get the current user (Supabase-compatible)
176
+ * Returns the user from the client-side session without making a network request
177
+ * For server-side validation, use getCurrentUser() instead
175
178
  */
176
- getUser() {
177
- return this.session?.user ?? null;
179
+ async getUser() {
180
+ return { data: { user: this.session?.user ?? null }, error: null };
178
181
  }
179
182
  /**
180
183
  * Get the current access token
@@ -183,9 +186,9 @@ var FluxbaseAuth = class {
183
186
  return this.session?.access_token ?? null;
184
187
  }
185
188
  /**
186
- * Listen to auth state changes
189
+ * Listen to auth state changes (Supabase-compatible)
187
190
  * @param callback - Function called when auth state changes
188
- * @returns Subscription object with unsubscribe method
191
+ * @returns Object containing subscription data
189
192
  *
190
193
  * @example
191
194
  * ```typescript
@@ -199,11 +202,12 @@ var FluxbaseAuth = class {
199
202
  */
200
203
  onAuthStateChange(callback) {
201
204
  this.stateChangeListeners.add(callback);
202
- return {
205
+ const subscription = {
203
206
  unsubscribe: () => {
204
207
  this.stateChangeListeners.delete(callback);
205
208
  }
206
209
  };
210
+ return { data: { subscription } };
207
211
  }
208
212
  /**
209
213
  * Sign in with email and password
@@ -220,7 +224,7 @@ var FluxbaseAuth = class {
220
224
  ...authResponse,
221
225
  expires_at: Date.now() + authResponse.expires_in * 1e3
222
226
  };
223
- this.setSession(session);
227
+ this.setSessionInternal(session);
224
228
  return session;
225
229
  });
226
230
  }
@@ -245,7 +249,7 @@ var FluxbaseAuth = class {
245
249
  ...response,
246
250
  expires_at: Date.now() + response.expires_in * 1e3
247
251
  };
248
- this.setSession(session);
252
+ this.setSessionInternal(session);
249
253
  return { user: session.user, session };
250
254
  });
251
255
  }
@@ -262,9 +266,10 @@ var FluxbaseAuth = class {
262
266
  });
263
267
  }
264
268
  /**
265
- * Refresh the access token
269
+ * Refresh the session (Supabase-compatible)
270
+ * Returns a new session with refreshed tokens
266
271
  */
267
- async refreshToken() {
272
+ async refreshSession() {
268
273
  return wrapAsync(async () => {
269
274
  if (!this.session?.refresh_token) {
270
275
  throw new Error("No refresh token available");
@@ -279,8 +284,8 @@ var FluxbaseAuth = class {
279
284
  ...response,
280
285
  expires_at: Date.now() + response.expires_in * 1e3
281
286
  };
282
- this.setSession(session, "TOKEN_REFRESHED");
283
- return { session };
287
+ this.setSessionInternal(session, "TOKEN_REFRESHED");
288
+ return { session, user: session.user };
284
289
  });
285
290
  }
286
291
  /**
@@ -313,10 +318,28 @@ var FluxbaseAuth = class {
313
318
  });
314
319
  }
315
320
  /**
316
- * Set the auth token manually
321
+ * Set the session manually (Supabase-compatible)
322
+ * Useful for restoring a session from storage or SSR scenarios
323
+ * @param session - Object containing access_token and refresh_token
324
+ * @returns Promise with session data
317
325
  */
318
- setToken(token) {
319
- this.fetch.setAuthToken(token);
326
+ async setSession(session) {
327
+ return wrapAsync(async () => {
328
+ const authSession = {
329
+ access_token: session.access_token,
330
+ refresh_token: session.refresh_token,
331
+ user: null,
332
+ // Will be populated by getCurrentUser
333
+ expires_in: 3600,
334
+ // Default, will be updated on refresh
335
+ expires_at: Date.now() + 3600 * 1e3
336
+ };
337
+ this.fetch.setAuthToken(session.access_token);
338
+ const user = await this.fetch.get("/api/v1/auth/user");
339
+ authSession.user = user;
340
+ this.setSessionInternal(authSession, "SIGNED_IN");
341
+ return { user, session: authSession };
342
+ });
320
343
  }
321
344
  /**
322
345
  * Setup 2FA for the current user
@@ -389,7 +412,7 @@ var FluxbaseAuth = class {
389
412
  ...response,
390
413
  expires_at: Date.now() + response.expires_in * 1e3
391
414
  };
392
- this.setSession(session, "MFA_CHALLENGE_VERIFIED");
415
+ this.setSessionInternal(session, "MFA_CHALLENGE_VERIFIED");
393
416
  return { user: session.user, session };
394
417
  });
395
418
  }
@@ -478,7 +501,7 @@ var FluxbaseAuth = class {
478
501
  ...response,
479
502
  expires_at: Date.now() + response.expires_in * 1e3
480
503
  };
481
- this.setSession(session);
504
+ this.setSessionInternal(session);
482
505
  return { user: session.user, session };
483
506
  });
484
507
  }
@@ -495,7 +518,7 @@ var FluxbaseAuth = class {
495
518
  ...response,
496
519
  expires_at: Date.now() + response.expires_in * 1e3
497
520
  };
498
- this.setSession(session);
521
+ this.setSessionInternal(session);
499
522
  return { user: session.user, session };
500
523
  });
501
524
  }
@@ -544,7 +567,7 @@ var FluxbaseAuth = class {
544
567
  ...response,
545
568
  expires_at: Date.now() + response.expires_in * 1e3
546
569
  };
547
- this.setSession(session);
570
+ this.setSessionInternal(session);
548
571
  return { user: session.user, session };
549
572
  });
550
573
  }
@@ -574,7 +597,7 @@ var FluxbaseAuth = class {
574
597
  /**
575
598
  * Internal: Set the session and persist it
576
599
  */
577
- setSession(session, event = "SIGNED_IN") {
600
+ setSessionInternal(session, event = "SIGNED_IN") {
578
601
  this.session = session;
579
602
  this.fetch.setAuthToken(session.access_token);
580
603
  this.saveSession();
@@ -618,7 +641,7 @@ var FluxbaseAuth = class {
618
641
  const delay = refreshAt - Date.now();
619
642
  if (delay > 0) {
620
643
  this.refreshTimer = setTimeout(async () => {
621
- const result = await this.refreshToken();
644
+ const result = await this.refreshSession();
622
645
  if (result.error) {
623
646
  console.error("Failed to refresh token:", result.error);
624
647
  this.clearSession();
@@ -939,15 +962,20 @@ var StorageBucket = class {
939
962
  if (options?.upsert !== void 0) {
940
963
  formData.append("upsert", String(options.upsert));
941
964
  }
942
- const response = await this.fetch.request(
943
- `/api/v1/storage/${this.bucketName}/${path}`,
944
- {
945
- method: "POST",
946
- body: formData,
947
- headers: {}
948
- // Let browser set Content-Type for FormData
949
- }
950
- );
965
+ let response;
966
+ if (options?.onUploadProgress) {
967
+ response = await this.uploadWithProgress(path, formData, options.onUploadProgress);
968
+ } else {
969
+ response = await this.fetch.request(
970
+ `/api/v1/storage/${this.bucketName}/${path}`,
971
+ {
972
+ method: "POST",
973
+ body: formData,
974
+ headers: {}
975
+ // Let browser set Content-Type for FormData
976
+ }
977
+ );
978
+ }
951
979
  return {
952
980
  data: {
953
981
  id: response.id || response.key || path,
@@ -960,6 +988,57 @@ var StorageBucket = class {
960
988
  return { data: null, error };
961
989
  }
962
990
  }
991
+ /**
992
+ * Upload with progress tracking using XMLHttpRequest
993
+ * @private
994
+ */
995
+ uploadWithProgress(path, formData, onProgress) {
996
+ return new Promise((resolve, reject) => {
997
+ const xhr = new XMLHttpRequest();
998
+ const url = `${this.fetch["baseUrl"]}/api/v1/storage/${this.bucketName}/${path}`;
999
+ xhr.upload.addEventListener("progress", (event) => {
1000
+ if (event.lengthComputable) {
1001
+ const percentage = Math.round(event.loaded / event.total * 100);
1002
+ onProgress({
1003
+ loaded: event.loaded,
1004
+ total: event.total,
1005
+ percentage
1006
+ });
1007
+ }
1008
+ });
1009
+ xhr.addEventListener("load", () => {
1010
+ if (xhr.status >= 200 && xhr.status < 300) {
1011
+ try {
1012
+ const response = JSON.parse(xhr.responseText);
1013
+ resolve(response);
1014
+ } catch (e) {
1015
+ resolve(xhr.responseText);
1016
+ }
1017
+ } else {
1018
+ try {
1019
+ const errorData = JSON.parse(xhr.responseText);
1020
+ reject(new Error(errorData.error || xhr.statusText));
1021
+ } catch (e) {
1022
+ reject(new Error(xhr.statusText));
1023
+ }
1024
+ }
1025
+ });
1026
+ xhr.addEventListener("error", () => {
1027
+ reject(new Error("Upload failed"));
1028
+ });
1029
+ xhr.addEventListener("abort", () => {
1030
+ reject(new Error("Upload aborted"));
1031
+ });
1032
+ xhr.open("POST", url);
1033
+ const headers = this.fetch["defaultHeaders"];
1034
+ for (const [key, value] of Object.entries(headers)) {
1035
+ if (key.toLowerCase() !== "content-type") {
1036
+ xhr.setRequestHeader(key, value);
1037
+ }
1038
+ }
1039
+ xhr.send(formData);
1040
+ });
1041
+ }
963
1042
  /**
964
1043
  * Download a file from the bucket
965
1044
  * @param path - The path/key of the file