@insforge/sdk 1.2.1-dev.0 → 1.2.1-dev.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/dist/index.js CHANGED
@@ -232,6 +232,95 @@ var Logger = class {
232
232
  }
233
233
  };
234
234
 
235
+ // src/lib/token-manager.ts
236
+ var CSRF_TOKEN_COOKIE = "insforge_csrf_token";
237
+ function getCsrfToken() {
238
+ if (typeof document === "undefined") return null;
239
+ const match = document.cookie.split(";").find((c) => c.trim().startsWith(`${CSRF_TOKEN_COOKIE}=`));
240
+ if (!match) return null;
241
+ return match.split("=")[1] || null;
242
+ }
243
+ function setCsrfToken(token) {
244
+ if (typeof document === "undefined") return;
245
+ const maxAge = 7 * 24 * 60 * 60;
246
+ const secure = typeof window !== "undefined" && window.location.protocol === "https:" ? "; Secure" : "";
247
+ document.cookie = `${CSRF_TOKEN_COOKIE}=${encodeURIComponent(token)}; path=/; max-age=${maxAge}; SameSite=Lax${secure}`;
248
+ }
249
+ function clearCsrfToken() {
250
+ if (typeof document === "undefined") return;
251
+ const secure = typeof window !== "undefined" && window.location.protocol === "https:" ? "; Secure" : "";
252
+ document.cookie = `${CSRF_TOKEN_COOKIE}=; path=/; max-age=0; SameSite=Lax${secure}`;
253
+ }
254
+ var TokenManager = class {
255
+ constructor() {
256
+ // In-memory storage
257
+ this.accessToken = null;
258
+ this.user = null;
259
+ // Callback for token changes (used by realtime to reconnect with new token)
260
+ this.onTokenChange = null;
261
+ }
262
+ /**
263
+ * Save session in memory
264
+ */
265
+ saveSession(session) {
266
+ const tokenChanged = session.accessToken !== this.accessToken;
267
+ this.accessToken = session.accessToken;
268
+ this.user = session.user;
269
+ if (tokenChanged && this.onTokenChange) {
270
+ this.onTokenChange();
271
+ }
272
+ }
273
+ /**
274
+ * Get current session
275
+ */
276
+ getSession() {
277
+ if (!this.accessToken || !this.user) return null;
278
+ return {
279
+ accessToken: this.accessToken,
280
+ user: this.user
281
+ };
282
+ }
283
+ /**
284
+ * Get access token
285
+ */
286
+ getAccessToken() {
287
+ return this.accessToken;
288
+ }
289
+ /**
290
+ * Set access token
291
+ */
292
+ setAccessToken(token) {
293
+ const tokenChanged = token !== this.accessToken;
294
+ this.accessToken = token;
295
+ if (tokenChanged && this.onTokenChange) {
296
+ this.onTokenChange();
297
+ }
298
+ }
299
+ /**
300
+ * Get user
301
+ */
302
+ getUser() {
303
+ return this.user;
304
+ }
305
+ /**
306
+ * Set user
307
+ */
308
+ setUser(user) {
309
+ this.user = user;
310
+ }
311
+ /**
312
+ * Clear in-memory session
313
+ */
314
+ clearSession() {
315
+ const hadToken = this.accessToken !== null;
316
+ this.accessToken = null;
317
+ this.user = null;
318
+ if (hadToken && this.onTokenChange) {
319
+ this.onTokenChange();
320
+ }
321
+ }
322
+ };
323
+
235
324
  // src/lib/http-client.ts
236
325
  var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
237
326
  var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
@@ -239,16 +328,23 @@ var HttpClient = class {
239
328
  /**
240
329
  * Creates a new HttpClient instance.
241
330
  * @param config - SDK configuration including baseUrl, timeout, retry settings, and fetch implementation.
331
+ * @param tokenManager - Token manager for session persistence.
242
332
  * @param logger - Optional logger instance for request/response debugging.
243
333
  */
244
- constructor(config, logger) {
334
+ constructor(config, tokenManager, logger) {
245
335
  this.userToken = null;
336
+ this.autoRefreshToken = true;
337
+ this.isRefreshing = false;
338
+ this.refreshPromise = null;
339
+ this.refreshToken = null;
246
340
  this.baseUrl = config.baseUrl || "http://localhost:7130";
341
+ this.autoRefreshToken = config.autoRefreshToken ?? true;
247
342
  this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
248
343
  this.anonKey = config.anonKey;
249
344
  this.defaultHeaders = {
250
345
  ...config.headers
251
346
  };
347
+ this.tokenManager = tokenManager ?? new TokenManager();
252
348
  this.logger = logger || new Logger(false);
253
349
  this.timeout = config.timeout ?? 3e4;
254
350
  this.retryCount = config.retryCount ?? 3;
@@ -302,8 +398,14 @@ var HttpClient = class {
302
398
  * @returns Parsed response data.
303
399
  * @throws {InsForgeError} On timeout, network failure, or HTTP error responses.
304
400
  */
305
- async request(method, path, options = {}) {
306
- const { params, headers = {}, body, signal: callerSignal, ...fetchOptions } = options;
401
+ async handleRequest(method, path, options = {}) {
402
+ const {
403
+ params,
404
+ headers = {},
405
+ body,
406
+ signal: callerSignal,
407
+ ...fetchOptions
408
+ } = options;
307
409
  const url = this.buildUrl(path, params);
308
410
  const startTime = Date.now();
309
411
  const canRetry = IDEMPOTENT_METHODS.has(method.toUpperCase()) || options.idempotent === true;
@@ -342,7 +444,9 @@ var HttpClient = class {
342
444
  for (let attempt = 0; attempt <= maxAttempts; attempt++) {
343
445
  if (attempt > 0) {
344
446
  const delay = this.computeRetryDelay(attempt);
345
- this.logger.warn(`Retry ${attempt}/${maxAttempts} for ${method} ${url} in ${delay}ms`);
447
+ this.logger.warn(
448
+ `Retry ${attempt}/${maxAttempts} for ${method} ${url} in ${delay}ms`
449
+ );
346
450
  if (callerSignal?.aborted) throw callerSignal.reason;
347
451
  await new Promise((resolve, reject) => {
348
452
  const onAbort = () => {
@@ -350,7 +454,8 @@ var HttpClient = class {
350
454
  reject(callerSignal.reason);
351
455
  };
352
456
  const timer2 = setTimeout(() => {
353
- if (callerSignal) callerSignal.removeEventListener("abort", onAbort);
457
+ if (callerSignal)
458
+ callerSignal.removeEventListener("abort", onAbort);
354
459
  resolve();
355
460
  }, delay);
356
461
  if (callerSignal) {
@@ -370,10 +475,16 @@ var HttpClient = class {
370
475
  controller.abort(callerSignal.reason);
371
476
  } else {
372
477
  const onCallerAbort = () => controller.abort(callerSignal.reason);
373
- callerSignal.addEventListener("abort", onCallerAbort, { once: true });
374
- controller.signal.addEventListener("abort", () => {
375
- callerSignal.removeEventListener("abort", onCallerAbort);
376
- }, { once: true });
478
+ callerSignal.addEventListener("abort", onCallerAbort, {
479
+ once: true
480
+ });
481
+ controller.signal.addEventListener(
482
+ "abort",
483
+ () => {
484
+ callerSignal.removeEventListener("abort", onCallerAbort);
485
+ },
486
+ { once: true }
487
+ );
377
488
  }
378
489
  }
379
490
  }
@@ -417,7 +528,13 @@ var HttpClient = class {
417
528
  }
418
529
  if (timer !== void 0) clearTimeout(timer);
419
530
  if (!response.ok) {
420
- this.logger.logResponse(method, url, response.status, Date.now() - startTime, data);
531
+ this.logger.logResponse(
532
+ method,
533
+ url,
534
+ response.status,
535
+ Date.now() - startTime,
536
+ data
537
+ );
421
538
  if (data && typeof data === "object" && "error" in data) {
422
539
  if (!data.statusCode && !data.status) {
423
540
  data.statusCode = response.status;
@@ -436,7 +553,13 @@ var HttpClient = class {
436
553
  "REQUEST_FAILED"
437
554
  );
438
555
  }
439
- this.logger.logResponse(method, url, response.status, Date.now() - startTime, data);
556
+ this.logger.logResponse(
557
+ method,
558
+ url,
559
+ response.status,
560
+ Date.now() - startTime,
561
+ data
562
+ );
440
563
  return data;
441
564
  } catch (err) {
442
565
  if (timer !== void 0) clearTimeout(timer);
@@ -470,6 +593,33 @@ var HttpClient = class {
470
593
  "NETWORK_ERROR"
471
594
  );
472
595
  }
596
+ async request(method, path, options = {}) {
597
+ try {
598
+ return await this.handleRequest(method, path, { ...options });
599
+ } catch (error) {
600
+ if (error instanceof InsForgeError && error.statusCode === 401 && error.error === "INVALID_TOKEN" && this.autoRefreshToken) {
601
+ try {
602
+ const newTokenData = await this.handleTokenRefresh();
603
+ this.setAuthToken(newTokenData.accessToken);
604
+ this.tokenManager.saveSession(newTokenData);
605
+ if (newTokenData.csrfToken) {
606
+ setCsrfToken(newTokenData.csrfToken);
607
+ }
608
+ if (newTokenData.refreshToken) {
609
+ this.setRefreshToken(newTokenData.refreshToken);
610
+ }
611
+ return await this.handleRequest(method, path, { ...options });
612
+ } catch (error2) {
613
+ this.tokenManager.clearSession();
614
+ this.userToken = null;
615
+ this.refreshToken = null;
616
+ clearCsrfToken();
617
+ throw error2;
618
+ }
619
+ }
620
+ throw error;
621
+ }
622
+ }
473
623
  /** Performs a GET request. */
474
624
  get(path, options) {
475
625
  return this.request("GET", path, options);
@@ -494,6 +644,9 @@ var HttpClient = class {
494
644
  setAuthToken(token) {
495
645
  this.userToken = token;
496
646
  }
647
+ setRefreshToken(token) {
648
+ this.refreshToken = token;
649
+ }
497
650
  /** Returns the current default headers including the authorization header if set. */
498
651
  getHeaders() {
499
652
  const headers = { ...this.defaultHeaders };
@@ -503,94 +656,31 @@ var HttpClient = class {
503
656
  }
504
657
  return headers;
505
658
  }
506
- };
507
-
508
- // src/lib/token-manager.ts
509
- var CSRF_TOKEN_COOKIE = "insforge_csrf_token";
510
- function getCsrfToken() {
511
- if (typeof document === "undefined") return null;
512
- const match = document.cookie.split(";").find((c) => c.trim().startsWith(`${CSRF_TOKEN_COOKIE}=`));
513
- if (!match) return null;
514
- return match.split("=")[1] || null;
515
- }
516
- function setCsrfToken(token) {
517
- if (typeof document === "undefined") return;
518
- const maxAge = 7 * 24 * 60 * 60;
519
- const secure = typeof window !== "undefined" && window.location.protocol === "https:" ? "; Secure" : "";
520
- document.cookie = `${CSRF_TOKEN_COOKIE}=${encodeURIComponent(token)}; path=/; max-age=${maxAge}; SameSite=Lax${secure}`;
521
- }
522
- function clearCsrfToken() {
523
- if (typeof document === "undefined") return;
524
- const secure = typeof window !== "undefined" && window.location.protocol === "https:" ? "; Secure" : "";
525
- document.cookie = `${CSRF_TOKEN_COOKIE}=; path=/; max-age=0; SameSite=Lax${secure}`;
526
- }
527
- var TokenManager = class {
528
- constructor() {
529
- // In-memory storage
530
- this.accessToken = null;
531
- this.user = null;
532
- // Callback for token changes (used by realtime to reconnect with new token)
533
- this.onTokenChange = null;
534
- }
535
- /**
536
- * Save session in memory
537
- */
538
- saveSession(session) {
539
- const tokenChanged = session.accessToken !== this.accessToken;
540
- this.accessToken = session.accessToken;
541
- this.user = session.user;
542
- if (tokenChanged && this.onTokenChange) {
543
- this.onTokenChange();
544
- }
545
- }
546
- /**
547
- * Get current session
548
- */
549
- getSession() {
550
- if (!this.accessToken || !this.user) return null;
551
- return {
552
- accessToken: this.accessToken,
553
- user: this.user
554
- };
555
- }
556
- /**
557
- * Get access token
558
- */
559
- getAccessToken() {
560
- return this.accessToken;
561
- }
562
- /**
563
- * Set access token
564
- */
565
- setAccessToken(token) {
566
- const tokenChanged = token !== this.accessToken;
567
- this.accessToken = token;
568
- if (tokenChanged && this.onTokenChange) {
569
- this.onTokenChange();
570
- }
571
- }
572
- /**
573
- * Get user
574
- */
575
- getUser() {
576
- return this.user;
577
- }
578
- /**
579
- * Set user
580
- */
581
- setUser(user) {
582
- this.user = user;
583
- }
584
- /**
585
- * Clear in-memory session
586
- */
587
- clearSession() {
588
- const hadToken = this.accessToken !== null;
589
- this.accessToken = null;
590
- this.user = null;
591
- if (hadToken && this.onTokenChange) {
592
- this.onTokenChange();
659
+ async handleTokenRefresh() {
660
+ if (this.isRefreshing) {
661
+ return this.refreshPromise;
593
662
  }
663
+ this.isRefreshing = true;
664
+ this.refreshPromise = (async () => {
665
+ try {
666
+ const csrfToken = getCsrfToken();
667
+ const body = this.refreshToken ? { refreshToken: this.refreshToken } : void 0;
668
+ const response = await this.handleRequest(
669
+ "POST",
670
+ "/api/auth/sessions/current",
671
+ {
672
+ body,
673
+ headers: csrfToken ? { "X-CSRF-Token": csrfToken } : {},
674
+ credentials: "include"
675
+ }
676
+ );
677
+ return response;
678
+ } finally {
679
+ this.isRefreshing = false;
680
+ this.refreshPromise = null;
681
+ }
682
+ })();
683
+ return this.refreshPromise;
594
684
  }
595
685
  };
596
686
 
@@ -679,6 +769,7 @@ var Auth = class {
679
769
  this.tokenManager.saveSession(session);
680
770
  }
681
771
  this.http.setAuthToken(response.accessToken);
772
+ this.http.setRefreshToken(response.refreshToken ?? null);
682
773
  return true;
683
774
  }
684
775
  // ============================================================================
@@ -686,7 +777,7 @@ var Auth = class {
686
777
  // ============================================================================
687
778
  /**
688
779
  * Detect and handle OAuth callback parameters in URL
689
- * Supports PKCE flow (insforge_code) and legacy flow (access_token in URL)
780
+ * Supports PKCE flow (insforge_code)
690
781
  */
691
782
  async detectAuthCallback() {
692
783
  if (this.isServerMode() || typeof window === "undefined") return;
@@ -707,31 +798,6 @@ var Auth = class {
707
798
  }
708
799
  return;
709
800
  }
710
- const accessToken = params.get("access_token");
711
- const userId = params.get("user_id");
712
- const email = params.get("email");
713
- if (accessToken && userId && email) {
714
- const csrfToken = params.get("csrf_token");
715
- const name = params.get("name");
716
- if (csrfToken) {
717
- setCsrfToken(csrfToken);
718
- }
719
- const session = {
720
- accessToken,
721
- user: {
722
- id: userId,
723
- email,
724
- profile: { name: name || "" },
725
- metadata: null,
726
- emailVerified: false,
727
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
728
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
729
- }
730
- };
731
- this.tokenManager.saveSession(session);
732
- this.http.setAuthToken(accessToken);
733
- cleanUrlParams("access_token", "user_id", "email", "name", "csrf_token");
734
- }
735
801
  } catch (error) {
736
802
  console.debug("OAuth callback detection skipped:", error);
737
803
  }
@@ -749,6 +815,9 @@ var Auth = class {
749
815
  if (response.accessToken && response.user) {
750
816
  this.saveSessionFromResponse(response);
751
817
  }
818
+ if (response.refreshToken) {
819
+ this.http.setRefreshToken(response.refreshToken);
820
+ }
752
821
  return { data: response, error: null };
753
822
  } catch (error) {
754
823
  return wrapError(error, "An unexpected error occurred during sign up");
@@ -762,6 +831,9 @@ var Auth = class {
762
831
  { credentials: "include" }
763
832
  );
764
833
  this.saveSessionFromResponse(response);
834
+ if (response.refreshToken) {
835
+ this.http.setRefreshToken(response.refreshToken);
836
+ }
765
837
  return { data: response, error: null };
766
838
  } catch (error) {
767
839
  return wrapError(error, "An unexpected error occurred during sign in");
@@ -779,12 +851,15 @@ var Auth = class {
779
851
  }
780
852
  this.tokenManager.clearSession();
781
853
  this.http.setAuthToken(null);
854
+ this.http.setRefreshToken(null);
782
855
  if (!this.isServerMode()) {
783
856
  clearCsrfToken();
784
857
  }
785
858
  return { error: null };
786
859
  } catch {
787
- return { error: new InsForgeError("Failed to sign out", 500, "SIGNOUT_ERROR") };
860
+ return {
861
+ error: new InsForgeError("Failed to sign out", 500, "SIGNOUT_ERROR")
862
+ };
788
863
  }
789
864
  }
790
865
  // ============================================================================
@@ -806,7 +881,9 @@ var Auth = class {
806
881
  providerKey
807
882
  );
808
883
  const oauthPath = isBuiltInProvider ? `/api/auth/oauth/${providerKey}` : `/api/auth/oauth/custom/${providerKey}`;
809
- const response = await this.http.get(oauthPath, { params });
884
+ const response = await this.http.get(oauthPath, {
885
+ params
886
+ });
810
887
  if (!this.isServerMode() && typeof window !== "undefined" && !skipBrowserRedirect) {
811
888
  window.location.href = response.authUrl;
812
889
  return { data: {}, error: null };
@@ -846,7 +923,10 @@ var Auth = class {
846
923
  )
847
924
  };
848
925
  }
849
- const request = { code, code_verifier: verifier };
926
+ const request = {
927
+ code,
928
+ code_verifier: verifier
929
+ };
850
930
  const response = await this.http.post(
851
931
  this.isServerMode() ? "/api/auth/oauth/exchange?client_type=mobile" : "/api/auth/oauth/exchange",
852
932
  request,
@@ -854,16 +934,14 @@ var Auth = class {
854
934
  );
855
935
  this.saveSessionFromResponse(response);
856
936
  return {
857
- data: {
858
- accessToken: response.accessToken,
859
- refreshToken: response.refreshToken,
860
- user: response.user,
861
- redirectTo: response.redirectTo
862
- },
937
+ data: response,
863
938
  error: null
864
939
  };
865
940
  } catch (error) {
866
- return wrapError(error, "An unexpected error occurred during OAuth code exchange");
941
+ return wrapError(
942
+ error,
943
+ "An unexpected error occurred during OAuth code exchange"
944
+ );
867
945
  }
868
946
  }
869
947
  /**
@@ -882,16 +960,18 @@ var Auth = class {
882
960
  { credentials: "include" }
883
961
  );
884
962
  this.saveSessionFromResponse(response);
963
+ if (response.refreshToken) {
964
+ this.http.setRefreshToken(response.refreshToken);
965
+ }
885
966
  return {
886
- data: {
887
- accessToken: response.accessToken,
888
- refreshToken: response.refreshToken,
889
- user: response.user
890
- },
967
+ data: response,
891
968
  error: null
892
969
  };
893
970
  } catch (error) {
894
- return wrapError(error, "An unexpected error occurred during ID token sign in");
971
+ return wrapError(
972
+ error,
973
+ "An unexpected error occurred during ID token sign in"
974
+ );
895
975
  }
896
976
  }
897
977
  // ============================================================================
@@ -932,7 +1012,10 @@ var Auth = class {
932
1012
  }
933
1013
  return { data: response, error: null };
934
1014
  } catch (error) {
935
- return wrapError(error, "An unexpected error occurred during session refresh");
1015
+ return wrapError(
1016
+ error,
1017
+ "An unexpected error occurred during session refresh"
1018
+ );
936
1019
  }
937
1020
  }
938
1021
  /**
@@ -945,7 +1028,9 @@ var Auth = class {
945
1028
  const accessToken = this.tokenManager.getAccessToken();
946
1029
  if (!accessToken) return { data: { user: null }, error: null };
947
1030
  this.http.setAuthToken(accessToken);
948
- const response = await this.http.get("/api/auth/sessions/current");
1031
+ const response = await this.http.get(
1032
+ "/api/auth/sessions/current"
1033
+ );
949
1034
  const user = response.user ?? null;
950
1035
  return { data: { user }, error: null };
951
1036
  }
@@ -983,24 +1068,38 @@ var Auth = class {
983
1068
  // ============================================================================
984
1069
  async getProfile(userId) {
985
1070
  try {
986
- const response = await this.http.get(`/api/auth/profiles/${userId}`);
1071
+ const response = await this.http.get(
1072
+ `/api/auth/profiles/${userId}`
1073
+ );
987
1074
  return { data: response, error: null };
988
1075
  } catch (error) {
989
- return wrapError(error, "An unexpected error occurred while fetching user profile");
1076
+ return wrapError(
1077
+ error,
1078
+ "An unexpected error occurred while fetching user profile"
1079
+ );
990
1080
  }
991
1081
  }
992
1082
  async setProfile(profile) {
993
1083
  try {
994
- const response = await this.http.patch("/api/auth/profiles/current", {
995
- profile
996
- });
1084
+ const response = await this.http.patch(
1085
+ "/api/auth/profiles/current",
1086
+ {
1087
+ profile
1088
+ }
1089
+ );
997
1090
  const currentUser = this.tokenManager.getUser();
998
1091
  if (!this.isServerMode() && currentUser && response.profile !== void 0) {
999
- this.tokenManager.setUser({ ...currentUser, profile: response.profile });
1092
+ this.tokenManager.setUser({
1093
+ ...currentUser,
1094
+ profile: response.profile
1095
+ });
1000
1096
  }
1001
1097
  return { data: response, error: null };
1002
1098
  } catch (error) {
1003
- return wrapError(error, "An unexpected error occurred while updating user profile");
1099
+ return wrapError(
1100
+ error,
1101
+ "An unexpected error occurred while updating user profile"
1102
+ );
1004
1103
  }
1005
1104
  }
1006
1105
  // ============================================================================
@@ -1008,19 +1107,15 @@ var Auth = class {
1008
1107
  // ============================================================================
1009
1108
  async resendVerificationEmail(request) {
1010
1109
  try {
1011
- const response = await this.http.post(
1012
- "/api/auth/email/send-verification",
1013
- request
1014
- );
1110
+ const response = await this.http.post("/api/auth/email/send-verification", request);
1015
1111
  return { data: response, error: null };
1016
1112
  } catch (error) {
1017
- return wrapError(error, "An unexpected error occurred while sending verification code");
1113
+ return wrapError(
1114
+ error,
1115
+ "An unexpected error occurred while sending verification email"
1116
+ );
1018
1117
  }
1019
1118
  }
1020
- /** @deprecated Use `resendVerificationEmail` instead */
1021
- async sendVerificationEmail(request) {
1022
- return this.resendVerificationEmail(request);
1023
- }
1024
1119
  async verifyEmail(request) {
1025
1120
  try {
1026
1121
  const response = await this.http.post(
@@ -1029,9 +1124,15 @@ var Auth = class {
1029
1124
  { credentials: "include" }
1030
1125
  );
1031
1126
  this.saveSessionFromResponse(response);
1127
+ if (response.refreshToken) {
1128
+ this.http.setRefreshToken(response.refreshToken);
1129
+ }
1032
1130
  return { data: response, error: null };
1033
1131
  } catch (error) {
1034
- return wrapError(error, "An unexpected error occurred while verifying email");
1132
+ return wrapError(
1133
+ error,
1134
+ "An unexpected error occurred while verifying email"
1135
+ );
1035
1136
  }
1036
1137
  }
1037
1138
  // ============================================================================
@@ -1039,13 +1140,13 @@ var Auth = class {
1039
1140
  // ============================================================================
1040
1141
  async sendResetPasswordEmail(request) {
1041
1142
  try {
1042
- const response = await this.http.post(
1043
- "/api/auth/email/send-reset-password",
1044
- request
1045
- );
1143
+ const response = await this.http.post("/api/auth/email/send-reset-password", request);
1046
1144
  return { data: response, error: null };
1047
1145
  } catch (error) {
1048
- return wrapError(error, "An unexpected error occurred while sending password reset code");
1146
+ return wrapError(
1147
+ error,
1148
+ "An unexpected error occurred while sending password reset email"
1149
+ );
1049
1150
  }
1050
1151
  }
1051
1152
  async exchangeResetPasswordToken(request) {
@@ -1056,7 +1157,10 @@ var Auth = class {
1056
1157
  );
1057
1158
  return { data: response, error: null };
1058
1159
  } catch (error) {
1059
- return wrapError(error, "An unexpected error occurred while verifying reset code");
1160
+ return wrapError(
1161
+ error,
1162
+ "An unexpected error occurred while verifying reset code"
1163
+ );
1060
1164
  }
1061
1165
  }
1062
1166
  async resetPassword(request) {
@@ -1067,7 +1171,10 @@ var Auth = class {
1067
1171
  );
1068
1172
  return { data: response, error: null };
1069
1173
  } catch (error) {
1070
- return wrapError(error, "An unexpected error occurred while resetting password");
1174
+ return wrapError(
1175
+ error,
1176
+ "An unexpected error occurred while resetting password"
1177
+ );
1071
1178
  }
1072
1179
  }
1073
1180
  // ============================================================================
@@ -1075,10 +1182,15 @@ var Auth = class {
1075
1182
  // ============================================================================
1076
1183
  async getPublicAuthConfig() {
1077
1184
  try {
1078
- const response = await this.http.get("/api/auth/public-config");
1185
+ const response = await this.http.get(
1186
+ "/api/auth/public-config"
1187
+ );
1079
1188
  return { data: response, error: null };
1080
1189
  } catch (error) {
1081
- return wrapError(error, "An unexpected error occurred while fetching auth configuration");
1190
+ return wrapError(
1191
+ error,
1192
+ "An unexpected error occurred while fetching auth configuration"
1193
+ );
1082
1194
  }
1083
1195
  }
1084
1196
  };
@@ -1824,9 +1936,17 @@ var Functions = class _Functions {
1824
1936
  });
1825
1937
  return { data, error: null };
1826
1938
  } catch (error) {
1827
- if (error?.statusCode === 404) {
1939
+ if (error instanceof Error && error.name === "AbortError") throw error;
1940
+ if (error instanceof InsForgeError && error.statusCode === 404) {
1828
1941
  } else {
1829
- return { data: null, error };
1942
+ return {
1943
+ data: null,
1944
+ error: error instanceof InsForgeError ? error : new InsForgeError(
1945
+ error instanceof Error ? error.message : "Function invocation failed",
1946
+ 500,
1947
+ "FUNCTION_ERROR"
1948
+ )
1949
+ };
1830
1950
  }
1831
1951
  }
1832
1952
  }
@@ -1835,7 +1955,15 @@ var Functions = class _Functions {
1835
1955
  const data = await this.http.request(method, path, { body, headers });
1836
1956
  return { data, error: null };
1837
1957
  } catch (error) {
1838
- return { data: null, error };
1958
+ if (error instanceof Error && error.name === "AbortError") throw error;
1959
+ return {
1960
+ data: null,
1961
+ error: error instanceof InsForgeError ? error : new InsForgeError(
1962
+ error instanceof Error ? error.message : "Function invocation failed",
1963
+ 500,
1964
+ "FUNCTION_ERROR"
1965
+ )
1966
+ };
1839
1967
  }
1840
1968
  }
1841
1969
  };
@@ -2106,8 +2234,15 @@ var Emails = class {
2106
2234
  );
2107
2235
  return { data, error: null };
2108
2236
  } catch (error) {
2109
- const normalizedError = error instanceof Error ? error : new Error(String(error));
2110
- return { data: null, error: normalizedError };
2237
+ if (error instanceof Error && error.name === "AbortError") throw error;
2238
+ return {
2239
+ data: null,
2240
+ error: error instanceof InsForgeError ? error : new InsForgeError(
2241
+ error instanceof Error ? error.message : "Email send failed",
2242
+ 500,
2243
+ "EMAIL_ERROR"
2244
+ )
2245
+ };
2111
2246
  }
2112
2247
  }
2113
2248
  };
@@ -2116,8 +2251,8 @@ var Emails = class {
2116
2251
  var InsForgeClient = class {
2117
2252
  constructor(config = {}) {
2118
2253
  const logger = new Logger(config.debug);
2119
- this.http = new HttpClient(config, logger);
2120
2254
  this.tokenManager = new TokenManager();
2255
+ this.http = new HttpClient(config, this.tokenManager, logger);
2121
2256
  if (config.edgeFunctionToken) {
2122
2257
  this.http.setAuthToken(config.edgeFunctionToken);
2123
2258
  this.tokenManager.setAccessToken(config.edgeFunctionToken);
@@ -2129,12 +2264,16 @@ var InsForgeClient = class {
2129
2264
  this.storage = new Storage(this.http);
2130
2265
  this.ai = new AI(this.http);
2131
2266
  this.functions = new Functions(this.http, config.functionsUrl);
2132
- this.realtime = new Realtime(this.http.baseUrl, this.tokenManager, config.anonKey);
2267
+ this.realtime = new Realtime(
2268
+ this.http.baseUrl,
2269
+ this.tokenManager,
2270
+ config.anonKey
2271
+ );
2133
2272
  this.emails = new Emails(this.http);
2134
2273
  }
2135
2274
  /**
2136
2275
  * Get the underlying HTTP client for custom requests
2137
- *
2276
+ *
2138
2277
  * @example
2139
2278
  * ```typescript
2140
2279
  * const httpClient = client.getHttpClient();