@scalemule/nextjs 0.0.1 → 0.0.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.mjs CHANGED
@@ -3,6 +3,16 @@ import { jsx } from 'react/jsx-runtime';
3
3
 
4
4
  // src/provider.tsx
5
5
 
6
+ // src/types/index.ts
7
+ var ScaleMuleApiError = class extends Error {
8
+ constructor(error) {
9
+ super(error.message);
10
+ this.name = "ScaleMuleApiError";
11
+ this.code = error.code;
12
+ this.field = error.field;
13
+ }
14
+ };
15
+
6
16
  // src/client.ts
7
17
  var GATEWAY_URLS = {
8
18
  dev: "https://api-dev.scalemule.com",
@@ -85,14 +95,14 @@ var RateLimitQueue = class {
85
95
  try {
86
96
  this.requestsInWindow++;
87
97
  const result = await request.execute();
88
- if (!result.success && result.error?.code === "RATE_LIMITED") {
98
+ request.resolve(result);
99
+ } catch (error) {
100
+ if (error instanceof ScaleMuleApiError && error.code === "RATE_LIMITED") {
89
101
  this.queue.unshift(request);
90
102
  this.rateLimitedUntil = Date.now() + 6e4;
91
103
  } else {
92
- request.resolve(result);
104
+ request.reject(error);
93
105
  }
94
- } catch (error) {
95
- request.reject(error);
96
106
  }
97
107
  }
98
108
  this.processing = false;
@@ -435,11 +445,12 @@ var ScaleMuleClient = class {
435
445
  signal: controller.signal
436
446
  });
437
447
  clearTimeout(timeoutId);
438
- const data = await response.json();
448
+ const text = await response.text();
449
+ const responseData = text ? JSON.parse(text) : null;
439
450
  if (!response.ok) {
440
- const error = data.error || {
451
+ const error = responseData?.error || {
441
452
  code: `HTTP_${response.status}`,
442
- message: data.message || response.statusText
453
+ message: responseData?.message || response.statusText
443
454
  };
444
455
  if (attempt < maxRetries && RETRYABLE_STATUS_CODES.has(response.status)) {
445
456
  lastError = error;
@@ -453,11 +464,15 @@ var ScaleMuleClient = class {
453
464
  if (this.debug) {
454
465
  console.error("[ScaleMule] Request failed:", error);
455
466
  }
456
- return { success: false, error };
467
+ throw new ScaleMuleApiError(error);
457
468
  }
469
+ const data = responseData?.data !== void 0 ? responseData.data : responseData;
458
470
  return data;
459
471
  } catch (err) {
460
472
  clearTimeout(timeoutId);
473
+ if (err instanceof ScaleMuleApiError) {
474
+ throw err;
475
+ }
461
476
  const error = {
462
477
  code: err instanceof Error && err.name === "AbortError" ? "TIMEOUT" : "NETWORK_ERROR",
463
478
  message: err instanceof Error ? err.message : "Network request failed"
@@ -474,10 +489,10 @@ var ScaleMuleClient = class {
474
489
  if (this.debug) {
475
490
  console.error("[ScaleMule] Network error:", err);
476
491
  }
477
- return { success: false, error };
492
+ throw new ScaleMuleApiError(error);
478
493
  }
479
494
  }
480
- return { success: false, error: lastError || { code: "UNKNOWN", message: "Request failed" } };
495
+ throw new ScaleMuleApiError(lastError || { code: "UNKNOWN", message: "Request failed" });
481
496
  }
482
497
  /**
483
498
  * GET request
@@ -573,11 +588,12 @@ var ScaleMuleClient = class {
573
588
  headers,
574
589
  body: retryFormData
575
590
  });
576
- const data = await response.json();
591
+ const uploadText = await response.text();
592
+ const responseData = uploadText ? JSON.parse(uploadText) : null;
577
593
  if (!response.ok) {
578
- const error = data.error || {
594
+ const error = responseData?.error || {
579
595
  code: `HTTP_${response.status}`,
580
- message: data.message || response.statusText
596
+ message: responseData?.message || response.statusText
581
597
  };
582
598
  if (attempt < maxRetries && RETRYABLE_STATUS_CODES.has(response.status)) {
583
599
  lastError = error;
@@ -588,10 +604,14 @@ var ScaleMuleClient = class {
588
604
  await sleep(delay);
589
605
  continue;
590
606
  }
591
- return { success: false, error };
607
+ throw new ScaleMuleApiError(error);
592
608
  }
609
+ const data = responseData?.data !== void 0 ? responseData.data : responseData;
593
610
  return data;
594
611
  } catch (err) {
612
+ if (err instanceof ScaleMuleApiError) {
613
+ throw err;
614
+ }
595
615
  lastError = {
596
616
  code: "UPLOAD_ERROR",
597
617
  message: err instanceof Error ? err.message : "Upload failed"
@@ -606,10 +626,7 @@ var ScaleMuleClient = class {
606
626
  }
607
627
  }
608
628
  }
609
- return {
610
- success: false,
611
- error: lastError || { code: "UPLOAD_ERROR", message: "Upload failed after retries" }
612
- };
629
+ throw new ScaleMuleApiError(lastError || { code: "UPLOAD_ERROR", message: "Upload failed after retries" });
613
630
  }
614
631
  /**
615
632
  * Upload with progress using XMLHttpRequest (with retry)
@@ -617,35 +634,35 @@ var ScaleMuleClient = class {
617
634
  async uploadWithProgress(url, formData, onProgress, maxRetries = 2) {
618
635
  let lastError = null;
619
636
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
620
- const result = await this.singleUploadWithProgress(url, formData, onProgress);
621
- if (result.success) {
622
- return result;
623
- }
624
- const errorCode = result.error?.code || "";
625
- const isNetworkError = errorCode === "UPLOAD_ERROR" || errorCode === "NETWORK_ERROR";
626
- const isRetryableHttp = errorCode.startsWith("HTTP_") && RETRYABLE_STATUS_CODES.has(parseInt(errorCode.replace("HTTP_", ""), 10));
627
- if (attempt < maxRetries && (isNetworkError || isRetryableHttp)) {
628
- lastError = result.error || null;
629
- const delay = getBackoffDelay(attempt);
630
- if (this.debug) {
631
- console.log(`[ScaleMule] Upload retry ${attempt + 1}/${maxRetries} after ${delay}ms`);
637
+ try {
638
+ return await this.singleUploadWithProgress(url, formData, onProgress);
639
+ } catch (err) {
640
+ if (!(err instanceof ScaleMuleApiError)) {
641
+ throw err;
632
642
  }
633
- await sleep(delay);
634
- onProgress(0);
635
- continue;
643
+ const errorCode = err.code;
644
+ const isNetworkError = errorCode === "UPLOAD_ERROR" || errorCode === "NETWORK_ERROR";
645
+ const isRetryableHttp = errorCode.startsWith("HTTP_") && RETRYABLE_STATUS_CODES.has(parseInt(errorCode.replace("HTTP_", ""), 10));
646
+ if (attempt < maxRetries && (isNetworkError || isRetryableHttp)) {
647
+ lastError = { code: err.code, message: err.message };
648
+ const delay = getBackoffDelay(attempt);
649
+ if (this.debug) {
650
+ console.log(`[ScaleMule] Upload retry ${attempt + 1}/${maxRetries} after ${delay}ms`);
651
+ }
652
+ await sleep(delay);
653
+ onProgress(0);
654
+ continue;
655
+ }
656
+ throw err;
636
657
  }
637
- return result;
638
658
  }
639
- return {
640
- success: false,
641
- error: lastError || { code: "UPLOAD_ERROR", message: "Upload failed after retries" }
642
- };
659
+ throw new ScaleMuleApiError(lastError || { code: "UPLOAD_ERROR", message: "Upload failed after retries" });
643
660
  }
644
661
  /**
645
662
  * Single upload attempt with progress using XMLHttpRequest
646
663
  */
647
664
  singleUploadWithProgress(url, formData, onProgress) {
648
- return new Promise((resolve) => {
665
+ return new Promise((resolve, reject) => {
649
666
  const xhr = new XMLHttpRequest();
650
667
  xhr.upload.addEventListener("progress", (event) => {
651
668
  if (event.lengthComputable) {
@@ -657,34 +674,23 @@ var ScaleMuleClient = class {
657
674
  try {
658
675
  const data = JSON.parse(xhr.responseText);
659
676
  if (xhr.status >= 200 && xhr.status < 300) {
660
- resolve(data);
677
+ const unwrapped = data?.data !== void 0 ? data.data : data;
678
+ resolve(unwrapped);
661
679
  } else {
662
- resolve({
663
- success: false,
664
- error: data.error || {
665
- code: `HTTP_${xhr.status}`,
666
- message: data.message || "Upload failed"
667
- }
668
- });
680
+ reject(new ScaleMuleApiError(data.error || {
681
+ code: `HTTP_${xhr.status}`,
682
+ message: data.message || "Upload failed"
683
+ }));
669
684
  }
670
685
  } catch {
671
- resolve({
672
- success: false,
673
- error: { code: "PARSE_ERROR", message: "Failed to parse response" }
674
- });
686
+ reject(new ScaleMuleApiError({ code: "PARSE_ERROR", message: "Failed to parse response" }));
675
687
  }
676
688
  });
677
689
  xhr.addEventListener("error", () => {
678
- resolve({
679
- success: false,
680
- error: { code: "UPLOAD_ERROR", message: "Upload failed" }
681
- });
690
+ reject(new ScaleMuleApiError({ code: "UPLOAD_ERROR", message: "Upload failed" }));
682
691
  });
683
692
  xhr.addEventListener("abort", () => {
684
- resolve({
685
- success: false,
686
- error: { code: "UPLOAD_ABORTED", message: "Upload cancelled" }
687
- });
693
+ reject(new ScaleMuleApiError({ code: "UPLOAD_ABORTED", message: "Upload cancelled" }));
688
694
  });
689
695
  xhr.open("POST", url);
690
696
  xhr.setRequestHeader("x-api-key", this.apiKey);
@@ -784,17 +790,19 @@ function ScaleMuleProvider({
784
790
  setUser(cachedUser);
785
791
  setInitializing(false);
786
792
  }
787
- const response = await client.get("/v1/auth/me");
788
- if (mounted) {
789
- if (response.success && response.data) {
790
- setUser(response.data);
791
- setCachedUser(response.data);
792
- } else {
793
+ try {
794
+ const userData = await client.get("/v1/auth/me");
795
+ if (mounted) {
796
+ setUser(userData);
797
+ setCachedUser(userData);
798
+ }
799
+ } catch (authErr) {
800
+ if (mounted) {
793
801
  setUser(null);
794
802
  setCachedUser(null);
795
803
  await client.clearSession();
796
- if (response.error && onAuthError) {
797
- onAuthError(response.error);
804
+ if (onAuthError && authErr && typeof authErr === "object" && "code" in authErr) {
805
+ onAuthError(authErr);
798
806
  }
799
807
  }
800
808
  }
@@ -889,31 +897,29 @@ function useAuth() {
889
897
  async (data) => {
890
898
  setError(null);
891
899
  if (authProxyUrl) {
892
- const response2 = await proxyFetch(
900
+ const response = await proxyFetch(
893
901
  authProxyUrl,
894
902
  "register",
895
903
  { body: data }
896
904
  );
897
- if (!response2.success || !response2.data) {
898
- const err = response2.error || {
905
+ if (!response.success || !response.data) {
906
+ const err = response.error || {
899
907
  code: "REGISTER_FAILED",
900
908
  message: "Registration failed"
901
909
  };
902
910
  setError(err);
903
911
  throw err;
904
912
  }
905
- return response2.data.user;
913
+ return response.data.user;
906
914
  }
907
- const response = await client.post("/v1/auth/register", data);
908
- if (!response.success || !response.data) {
909
- const err = response.error || {
910
- code: "REGISTER_FAILED",
911
- message: "Registration failed"
912
- };
913
- setError(err);
915
+ try {
916
+ return await client.post("/v1/auth/register", data);
917
+ } catch (err) {
918
+ if (err instanceof ScaleMuleApiError) {
919
+ setError(err);
920
+ }
914
921
  throw err;
915
922
  }
916
- return response.data;
917
923
  },
918
924
  [client, setError, authProxyUrl]
919
925
  );
@@ -921,42 +927,42 @@ function useAuth() {
921
927
  async (data) => {
922
928
  setError(null);
923
929
  if (authProxyUrl) {
924
- const response2 = await proxyFetch(
930
+ const response = await proxyFetch(
925
931
  authProxyUrl,
926
932
  "login",
927
933
  { body: data }
928
934
  );
929
- if (!response2.success || !response2.data) {
930
- const err = response2.error || {
935
+ if (!response.success || !response.data) {
936
+ const err = response.error || {
931
937
  code: "LOGIN_FAILED",
932
938
  message: "Login failed"
933
939
  };
934
940
  setError(err);
935
941
  throw err;
936
942
  }
937
- if ("requires_mfa" in response2.data && response2.data.requires_mfa) {
938
- return response2.data;
943
+ if ("requires_mfa" in response.data && response.data.requires_mfa) {
944
+ return response.data;
939
945
  }
940
- const loginData2 = response2.data;
946
+ const loginData2 = response.data;
941
947
  const responseUser = "user" in loginData2 ? loginData2.user : null;
942
948
  if (responseUser) {
943
949
  setUser(responseUser);
944
950
  }
945
- return response2.data;
951
+ return response.data;
946
952
  }
947
- const response = await client.post("/v1/auth/login", data);
948
- if (!response.success || !response.data) {
949
- const err = response.error || {
950
- code: "LOGIN_FAILED",
951
- message: "Login failed"
952
- };
953
- setError(err);
953
+ let loginResult;
954
+ try {
955
+ loginResult = await client.post("/v1/auth/login", data);
956
+ } catch (err) {
957
+ if (err instanceof ScaleMuleApiError) {
958
+ setError(err);
959
+ }
954
960
  throw err;
955
961
  }
956
- if ("requires_mfa" in response.data && response.data.requires_mfa) {
957
- return response.data;
962
+ if ("requires_mfa" in loginResult && loginResult.requires_mfa) {
963
+ return loginResult;
958
964
  }
959
- const loginData = response.data;
965
+ const loginData = loginResult;
960
966
  await client.setSession(loginData.session_token, loginData.user.id);
961
967
  setUser(loginData.user);
962
968
  return loginData;
@@ -986,14 +992,25 @@ function useAuth() {
986
992
  const forgotPassword = useCallback(
987
993
  async (email) => {
988
994
  setError(null);
989
- const response = authProxyUrl ? await proxyFetch(authProxyUrl, "forgot-password", { body: { email } }) : await client.post("/v1/auth/forgot-password", { email });
990
- if (!response.success) {
991
- const err = response.error || {
992
- code: "FORGOT_PASSWORD_FAILED",
993
- message: "Failed to send password reset email"
994
- };
995
- setError(err);
996
- throw err;
995
+ if (authProxyUrl) {
996
+ const response = await proxyFetch(authProxyUrl, "forgot-password", { body: { email } });
997
+ if (!response.success) {
998
+ const err = response.error || {
999
+ code: "FORGOT_PASSWORD_FAILED",
1000
+ message: "Failed to send password reset email"
1001
+ };
1002
+ setError(err);
1003
+ throw err;
1004
+ }
1005
+ } else {
1006
+ try {
1007
+ await client.post("/v1/auth/forgot-password", { email });
1008
+ } catch (err) {
1009
+ if (err instanceof ScaleMuleApiError) {
1010
+ setError(err);
1011
+ }
1012
+ throw err;
1013
+ }
997
1014
  }
998
1015
  },
999
1016
  [client, setError, authProxyUrl]
@@ -1001,14 +1018,25 @@ function useAuth() {
1001
1018
  const resetPassword = useCallback(
1002
1019
  async (token, newPassword) => {
1003
1020
  setError(null);
1004
- const response = authProxyUrl ? await proxyFetch(authProxyUrl, "reset-password", { body: { token, new_password: newPassword } }) : await client.post("/v1/auth/reset-password", { token, new_password: newPassword });
1005
- if (!response.success) {
1006
- const err = response.error || {
1007
- code: "RESET_PASSWORD_FAILED",
1008
- message: "Failed to reset password"
1009
- };
1010
- setError(err);
1011
- throw err;
1021
+ if (authProxyUrl) {
1022
+ const response = await proxyFetch(authProxyUrl, "reset-password", { body: { token, new_password: newPassword } });
1023
+ if (!response.success) {
1024
+ const err = response.error || {
1025
+ code: "RESET_PASSWORD_FAILED",
1026
+ message: "Failed to reset password"
1027
+ };
1028
+ setError(err);
1029
+ throw err;
1030
+ }
1031
+ } else {
1032
+ try {
1033
+ await client.post("/v1/auth/reset-password", { token, new_password: newPassword });
1034
+ } catch (err) {
1035
+ if (err instanceof ScaleMuleApiError) {
1036
+ setError(err);
1037
+ }
1038
+ throw err;
1039
+ }
1012
1040
  }
1013
1041
  },
1014
1042
  [client, setError, authProxyUrl]
@@ -1016,14 +1044,25 @@ function useAuth() {
1016
1044
  const verifyEmail = useCallback(
1017
1045
  async (token) => {
1018
1046
  setError(null);
1019
- const response = authProxyUrl ? await proxyFetch(authProxyUrl, "verify-email", { body: { token } }) : await client.post("/v1/auth/verify-email", { token });
1020
- if (!response.success) {
1021
- const err = response.error || {
1022
- code: "VERIFY_EMAIL_FAILED",
1023
- message: "Failed to verify email"
1024
- };
1025
- setError(err);
1026
- throw err;
1047
+ if (authProxyUrl) {
1048
+ const response = await proxyFetch(authProxyUrl, "verify-email", { body: { token } });
1049
+ if (!response.success) {
1050
+ const err = response.error || {
1051
+ code: "VERIFY_EMAIL_FAILED",
1052
+ message: "Failed to verify email"
1053
+ };
1054
+ setError(err);
1055
+ throw err;
1056
+ }
1057
+ } else {
1058
+ try {
1059
+ await client.post("/v1/auth/verify-email", { token });
1060
+ } catch (err) {
1061
+ if (err instanceof ScaleMuleApiError) {
1062
+ setError(err);
1063
+ }
1064
+ throw err;
1065
+ }
1027
1066
  }
1028
1067
  if (user) {
1029
1068
  if (authProxyUrl) {
@@ -1032,9 +1071,10 @@ function useAuth() {
1032
1071
  setUser(userResponse.data.user);
1033
1072
  }
1034
1073
  } else {
1035
- const userResponse = await client.get("/v1/auth/me");
1036
- if (userResponse.success && userResponse.data) {
1037
- setUser(userResponse.data);
1074
+ try {
1075
+ const userData = await client.get("/v1/auth/me");
1076
+ setUser(userData);
1077
+ } catch {
1038
1078
  }
1039
1079
  }
1040
1080
  }
@@ -1043,7 +1083,17 @@ function useAuth() {
1043
1083
  );
1044
1084
  const resendVerification = useCallback(async () => {
1045
1085
  setError(null);
1046
- const response = authProxyUrl ? await proxyFetch(authProxyUrl, "resend-verification", { body: user ? {} : void 0 }) : (() => {
1086
+ if (authProxyUrl) {
1087
+ const response = await proxyFetch(authProxyUrl, "resend-verification", { body: user ? {} : void 0 });
1088
+ if (!response.success) {
1089
+ const err = response.error || {
1090
+ code: "RESEND_FAILED",
1091
+ message: "Failed to resend verification email"
1092
+ };
1093
+ setError(err);
1094
+ throw err;
1095
+ }
1096
+ } else {
1047
1097
  if (!user) {
1048
1098
  const err = {
1049
1099
  code: "NOT_AUTHENTICATED",
@@ -1051,36 +1101,34 @@ function useAuth() {
1051
1101
  };
1052
1102
  throw err;
1053
1103
  }
1054
- return client.post("/v1/auth/resend-verification");
1055
- })();
1056
- const result = await response;
1057
- if (!result.success) {
1058
- const err = result.error || {
1059
- code: "RESEND_FAILED",
1060
- message: "Failed to resend verification email"
1061
- };
1062
- setError(err);
1063
- throw err;
1104
+ try {
1105
+ await client.post("/v1/auth/resend-verification");
1106
+ } catch (err) {
1107
+ if (err instanceof ScaleMuleApiError) {
1108
+ setError(err);
1109
+ }
1110
+ throw err;
1111
+ }
1064
1112
  }
1065
1113
  }, [client, user, setError, authProxyUrl]);
1066
1114
  const refreshSession = useCallback(async () => {
1067
1115
  setError(null);
1068
1116
  if (authProxyUrl) {
1069
- const response2 = await proxyFetch(
1117
+ const response = await proxyFetch(
1070
1118
  authProxyUrl,
1071
1119
  "refresh"
1072
1120
  );
1073
- if (!response2.success) {
1121
+ if (!response.success) {
1074
1122
  setUser(null);
1075
- const err = response2.error || {
1123
+ const err = response.error || {
1076
1124
  code: "REFRESH_FAILED",
1077
1125
  message: "Session expired"
1078
1126
  };
1079
1127
  setError(err);
1080
1128
  throw err;
1081
1129
  }
1082
- if (response2.data?.user) {
1083
- setUser(response2.data.user);
1130
+ if (response.data?.user) {
1131
+ setUser(response.data.user);
1084
1132
  }
1085
1133
  return;
1086
1134
  }
@@ -1093,46 +1141,45 @@ function useAuth() {
1093
1141
  setError(err);
1094
1142
  throw err;
1095
1143
  }
1096
- const response = await client.post(
1097
- "/v1/auth/refresh",
1098
- { session_token: sessionToken }
1099
- );
1100
- if (!response.success || !response.data) {
1144
+ try {
1145
+ const refreshData = await client.post(
1146
+ "/v1/auth/refresh",
1147
+ { session_token: sessionToken }
1148
+ );
1149
+ const userId = client.getUserId();
1150
+ if (userId) {
1151
+ await client.setSession(refreshData.session_token, userId);
1152
+ }
1153
+ } catch (err) {
1101
1154
  await client.clearSession();
1102
1155
  setUser(null);
1103
- const err = response.error || {
1104
- code: "REFRESH_FAILED",
1105
- message: "Session expired"
1106
- };
1107
- setError(err);
1156
+ if (err instanceof ScaleMuleApiError) {
1157
+ setError(err);
1158
+ }
1108
1159
  throw err;
1109
1160
  }
1110
- const userId = client.getUserId();
1111
- if (userId) {
1112
- await client.setSession(response.data.session_token, userId);
1113
- }
1114
1161
  }, [client, setUser, setError, authProxyUrl]);
1115
1162
  const startOAuth = useCallback(
1116
1163
  async (config) => {
1117
1164
  setError(null);
1118
- const response = await client.post("/v1/auth/oauth/start", {
1119
- provider: config.provider,
1120
- redirect_url: config.redirectUrl,
1121
- scopes: config.scopes,
1122
- state: config.state
1123
- });
1124
- if (!response.success || !response.data) {
1125
- const err = response.error || {
1126
- code: "OAUTH_START_FAILED",
1127
- message: "Failed to start OAuth flow"
1128
- };
1129
- setError(err);
1165
+ let oauthData;
1166
+ try {
1167
+ oauthData = await client.post("/v1/auth/oauth/start", {
1168
+ provider: config.provider,
1169
+ redirect_url: config.redirectUrl,
1170
+ scopes: config.scopes,
1171
+ state: config.state
1172
+ });
1173
+ } catch (err) {
1174
+ if (err instanceof ScaleMuleApiError) {
1175
+ setError(err);
1176
+ }
1130
1177
  throw err;
1131
1178
  }
1132
1179
  if (typeof sessionStorage !== "undefined") {
1133
- sessionStorage.setItem("scalemule_oauth_state", response.data.state);
1180
+ sessionStorage.setItem("scalemule_oauth_state", oauthData.state);
1134
1181
  }
1135
- return response.data;
1182
+ return oauthData;
1136
1183
  },
1137
1184
  [client, setError]
1138
1185
  );
@@ -1151,33 +1198,32 @@ function useAuth() {
1151
1198
  }
1152
1199
  sessionStorage.removeItem("scalemule_oauth_state");
1153
1200
  }
1154
- const response = await client.post("/v1/auth/oauth/callback", request);
1155
- if (!response.success || !response.data) {
1156
- const err = response.error || {
1157
- code: "OAUTH_CALLBACK_FAILED",
1158
- message: "Failed to complete OAuth flow"
1159
- };
1160
- setError(err);
1201
+ let callbackData;
1202
+ try {
1203
+ callbackData = await client.post("/v1/auth/oauth/callback", request);
1204
+ } catch (err) {
1205
+ if (err instanceof ScaleMuleApiError) {
1206
+ setError(err);
1207
+ }
1161
1208
  throw err;
1162
1209
  }
1163
- await client.setSession(response.data.session_token, response.data.user.id);
1164
- setUser(response.data.user);
1165
- return response.data;
1210
+ await client.setSession(callbackData.session_token, callbackData.user.id);
1211
+ setUser(callbackData.user);
1212
+ return callbackData;
1166
1213
  },
1167
1214
  [client, setUser, setError]
1168
1215
  );
1169
1216
  const getLinkedAccounts = useCallback(async () => {
1170
1217
  setError(null);
1171
- const response = await client.get("/v1/auth/oauth/accounts");
1172
- if (!response.success || !response.data) {
1173
- const err = response.error || {
1174
- code: "GET_ACCOUNTS_FAILED",
1175
- message: "Failed to get linked accounts"
1176
- };
1177
- setError(err);
1218
+ try {
1219
+ const data = await client.get("/v1/auth/oauth/accounts");
1220
+ return data.accounts;
1221
+ } catch (err) {
1222
+ if (err instanceof ScaleMuleApiError) {
1223
+ setError(err);
1224
+ }
1178
1225
  throw err;
1179
1226
  }
1180
- return response.data.accounts;
1181
1227
  }, [client, setError]);
1182
1228
  const linkAccount = useCallback(
1183
1229
  async (config) => {
@@ -1190,36 +1236,35 @@ function useAuth() {
1190
1236
  setError(err);
1191
1237
  throw err;
1192
1238
  }
1193
- const response = await client.post("/v1/auth/oauth/link", {
1194
- provider: config.provider,
1195
- redirect_url: config.redirectUrl,
1196
- scopes: config.scopes
1197
- });
1198
- if (!response.success || !response.data) {
1199
- const err = response.error || {
1200
- code: "LINK_ACCOUNT_FAILED",
1201
- message: "Failed to start account linking"
1202
- };
1203
- setError(err);
1239
+ let linkData;
1240
+ try {
1241
+ linkData = await client.post("/v1/auth/oauth/link", {
1242
+ provider: config.provider,
1243
+ redirect_url: config.redirectUrl,
1244
+ scopes: config.scopes
1245
+ });
1246
+ } catch (err) {
1247
+ if (err instanceof ScaleMuleApiError) {
1248
+ setError(err);
1249
+ }
1204
1250
  throw err;
1205
1251
  }
1206
1252
  if (typeof sessionStorage !== "undefined") {
1207
- sessionStorage.setItem("scalemule_oauth_state", response.data.state);
1253
+ sessionStorage.setItem("scalemule_oauth_state", linkData.state);
1208
1254
  }
1209
- return response.data;
1255
+ return linkData;
1210
1256
  },
1211
1257
  [client, user, setError]
1212
1258
  );
1213
1259
  const unlinkAccount = useCallback(
1214
1260
  async (provider) => {
1215
1261
  setError(null);
1216
- const response = await client.delete(`/v1/auth/oauth/accounts/${provider}`);
1217
- if (!response.success) {
1218
- const err = response.error || {
1219
- code: "UNLINK_ACCOUNT_FAILED",
1220
- message: "Failed to unlink account"
1221
- };
1222
- setError(err);
1262
+ try {
1263
+ await client.delete(`/v1/auth/oauth/accounts/${provider}`);
1264
+ } catch (err) {
1265
+ if (err instanceof ScaleMuleApiError) {
1266
+ setError(err);
1267
+ }
1223
1268
  throw err;
1224
1269
  }
1225
1270
  },
@@ -1227,46 +1272,41 @@ function useAuth() {
1227
1272
  );
1228
1273
  const getMFAStatus = useCallback(async () => {
1229
1274
  setError(null);
1230
- const response = await client.get("/v1/auth/mfa/status");
1231
- if (!response.success || !response.data) {
1232
- const err = response.error || {
1233
- code: "GET_MFA_STATUS_FAILED",
1234
- message: "Failed to get MFA status"
1235
- };
1236
- setError(err);
1275
+ try {
1276
+ return await client.get("/v1/auth/mfa/status");
1277
+ } catch (err) {
1278
+ if (err instanceof ScaleMuleApiError) {
1279
+ setError(err);
1280
+ }
1237
1281
  throw err;
1238
1282
  }
1239
- return response.data;
1240
1283
  }, [client, setError]);
1241
1284
  const setupMFA = useCallback(
1242
1285
  async (request) => {
1243
1286
  setError(null);
1244
- const response = await client.post(
1245
- "/v1/auth/mfa/setup",
1246
- request
1247
- );
1248
- if (!response.success || !response.data) {
1249
- const err = response.error || {
1250
- code: "MFA_SETUP_FAILED",
1251
- message: "Failed to setup MFA"
1252
- };
1253
- setError(err);
1287
+ try {
1288
+ return await client.post(
1289
+ "/v1/auth/mfa/setup",
1290
+ request
1291
+ );
1292
+ } catch (err) {
1293
+ if (err instanceof ScaleMuleApiError) {
1294
+ setError(err);
1295
+ }
1254
1296
  throw err;
1255
1297
  }
1256
- return response.data;
1257
1298
  },
1258
1299
  [client, setError]
1259
1300
  );
1260
1301
  const verifyMFA = useCallback(
1261
1302
  async (request) => {
1262
1303
  setError(null);
1263
- const response = await client.post("/v1/auth/mfa/verify", request);
1264
- if (!response.success) {
1265
- const err = response.error || {
1266
- code: "MFA_VERIFY_FAILED",
1267
- message: "Failed to verify MFA code"
1268
- };
1269
- setError(err);
1304
+ try {
1305
+ await client.post("/v1/auth/mfa/verify", request);
1306
+ } catch (err) {
1307
+ if (err instanceof ScaleMuleApiError) {
1308
+ setError(err);
1309
+ }
1270
1310
  throw err;
1271
1311
  }
1272
1312
  },
@@ -1275,35 +1315,34 @@ function useAuth() {
1275
1315
  const completeMFAChallenge = useCallback(
1276
1316
  async (challengeToken, code, method) => {
1277
1317
  setError(null);
1278
- const response = await client.post("/v1/auth/mfa/challenge", {
1279
- challenge_token: challengeToken,
1280
- code,
1281
- method
1282
- });
1283
- if (!response.success || !response.data) {
1284
- const err = response.error || {
1285
- code: "MFA_CHALLENGE_FAILED",
1286
- message: "Failed to complete MFA challenge"
1287
- };
1288
- setError(err);
1318
+ let mfaResult;
1319
+ try {
1320
+ mfaResult = await client.post("/v1/auth/mfa/challenge", {
1321
+ challenge_token: challengeToken,
1322
+ code,
1323
+ method
1324
+ });
1325
+ } catch (err) {
1326
+ if (err instanceof ScaleMuleApiError) {
1327
+ setError(err);
1328
+ }
1289
1329
  throw err;
1290
1330
  }
1291
- await client.setSession(response.data.session_token, response.data.user.id);
1292
- setUser(response.data.user);
1293
- return response.data;
1331
+ await client.setSession(mfaResult.session_token, mfaResult.user.id);
1332
+ setUser(mfaResult.user);
1333
+ return mfaResult;
1294
1334
  },
1295
1335
  [client, setUser, setError]
1296
1336
  );
1297
1337
  const disableMFA = useCallback(
1298
1338
  async (password) => {
1299
1339
  setError(null);
1300
- const response = await client.post("/v1/auth/mfa/disable", { password });
1301
- if (!response.success) {
1302
- const err = response.error || {
1303
- code: "MFA_DISABLE_FAILED",
1304
- message: "Failed to disable MFA"
1305
- };
1306
- setError(err);
1340
+ try {
1341
+ await client.post("/v1/auth/mfa/disable", { password });
1342
+ } catch (err) {
1343
+ if (err instanceof ScaleMuleApiError) {
1344
+ setError(err);
1345
+ }
1307
1346
  throw err;
1308
1347
  }
1309
1348
  },
@@ -1312,32 +1351,42 @@ function useAuth() {
1312
1351
  const regenerateBackupCodes = useCallback(
1313
1352
  async (password) => {
1314
1353
  setError(null);
1315
- const response = await client.post("/v1/auth/mfa/backup-codes", {
1316
- password
1317
- });
1318
- if (!response.success || !response.data) {
1319
- const err = response.error || {
1320
- code: "REGENERATE_CODES_FAILED",
1321
- message: "Failed to regenerate backup codes"
1322
- };
1323
- setError(err);
1354
+ try {
1355
+ const data = await client.post("/v1/auth/mfa/backup-codes", {
1356
+ password
1357
+ });
1358
+ return data.backup_codes;
1359
+ } catch (err) {
1360
+ if (err instanceof ScaleMuleApiError) {
1361
+ setError(err);
1362
+ }
1324
1363
  throw err;
1325
1364
  }
1326
- return response.data.backup_codes;
1327
1365
  },
1328
1366
  [client, setError]
1329
1367
  );
1330
1368
  const sendPhoneCode = useCallback(
1331
1369
  async (request) => {
1332
1370
  setError(null);
1333
- const response = authProxyUrl ? await proxyFetch(authProxyUrl, "phone/send-code", { body: request }) : await client.post("/v1/auth/phone/send-code", request);
1334
- if (!response.success) {
1335
- const err = response.error || {
1336
- code: "SEND_CODE_FAILED",
1337
- message: "Failed to send verification code"
1338
- };
1339
- setError(err);
1340
- throw err;
1371
+ if (authProxyUrl) {
1372
+ const response = await proxyFetch(authProxyUrl, "phone/send-code", { body: request });
1373
+ if (!response.success) {
1374
+ const err = response.error || {
1375
+ code: "SEND_CODE_FAILED",
1376
+ message: "Failed to send verification code"
1377
+ };
1378
+ setError(err);
1379
+ throw err;
1380
+ }
1381
+ } else {
1382
+ try {
1383
+ await client.post("/v1/auth/phone/send-code", request);
1384
+ } catch (err) {
1385
+ if (err instanceof ScaleMuleApiError) {
1386
+ setError(err);
1387
+ }
1388
+ throw err;
1389
+ }
1341
1390
  }
1342
1391
  },
1343
1392
  [client, setError, authProxyUrl]
@@ -1345,14 +1394,25 @@ function useAuth() {
1345
1394
  const verifyPhone = useCallback(
1346
1395
  async (request) => {
1347
1396
  setError(null);
1348
- const response = authProxyUrl ? await proxyFetch(authProxyUrl, "phone/verify", { body: request }) : await client.post("/v1/auth/phone/verify", request);
1349
- if (!response.success) {
1350
- const err = response.error || {
1351
- code: "VERIFY_PHONE_FAILED",
1352
- message: "Failed to verify phone number"
1353
- };
1354
- setError(err);
1355
- throw err;
1397
+ if (authProxyUrl) {
1398
+ const response = await proxyFetch(authProxyUrl, "phone/verify", { body: request });
1399
+ if (!response.success) {
1400
+ const err = response.error || {
1401
+ code: "VERIFY_PHONE_FAILED",
1402
+ message: "Failed to verify phone number"
1403
+ };
1404
+ setError(err);
1405
+ throw err;
1406
+ }
1407
+ } else {
1408
+ try {
1409
+ await client.post("/v1/auth/phone/verify", request);
1410
+ } catch (err) {
1411
+ if (err instanceof ScaleMuleApiError) {
1412
+ setError(err);
1413
+ }
1414
+ throw err;
1415
+ }
1356
1416
  }
1357
1417
  if (user) {
1358
1418
  if (authProxyUrl) {
@@ -1361,9 +1421,10 @@ function useAuth() {
1361
1421
  setUser(userResponse.data.user);
1362
1422
  }
1363
1423
  } else {
1364
- const userResponse = await client.get("/v1/auth/me");
1365
- if (userResponse.success && userResponse.data) {
1366
- setUser(userResponse.data);
1424
+ try {
1425
+ const userData = await client.get("/v1/auth/me");
1426
+ setUser(userData);
1427
+ } catch {
1367
1428
  }
1368
1429
  }
1369
1430
  }
@@ -1374,38 +1435,38 @@ function useAuth() {
1374
1435
  async (request) => {
1375
1436
  setError(null);
1376
1437
  if (authProxyUrl) {
1377
- const response2 = await proxyFetch(
1438
+ const response = await proxyFetch(
1378
1439
  authProxyUrl,
1379
1440
  "phone/login",
1380
1441
  { body: request }
1381
1442
  );
1382
- if (!response2.success || !response2.data) {
1383
- const err = response2.error || {
1443
+ if (!response.success || !response.data) {
1444
+ const err = response.error || {
1384
1445
  code: "PHONE_LOGIN_FAILED",
1385
1446
  message: "Failed to login with phone"
1386
1447
  };
1387
1448
  setError(err);
1388
1449
  throw err;
1389
1450
  }
1390
- const loginData = response2.data;
1451
+ const loginData = response.data;
1391
1452
  const responseUser = "user" in loginData ? loginData.user : null;
1392
1453
  if (responseUser) {
1393
1454
  setUser(responseUser);
1394
1455
  }
1395
- return response2.data;
1456
+ return response.data;
1396
1457
  }
1397
- const response = await client.post("/v1/auth/phone/login", request);
1398
- if (!response.success || !response.data) {
1399
- const err = response.error || {
1400
- code: "PHONE_LOGIN_FAILED",
1401
- message: "Failed to login with phone"
1402
- };
1403
- setError(err);
1458
+ let phoneLoginData;
1459
+ try {
1460
+ phoneLoginData = await client.post("/v1/auth/phone/login", request);
1461
+ } catch (err) {
1462
+ if (err instanceof ScaleMuleApiError) {
1463
+ setError(err);
1464
+ }
1404
1465
  throw err;
1405
1466
  }
1406
- await client.setSession(response.data.session_token, response.data.user.id);
1407
- setUser(response.data.user);
1408
- return response.data;
1467
+ await client.setSession(phoneLoginData.session_token, phoneLoginData.user.id);
1468
+ setUser(phoneLoginData.user);
1469
+ return phoneLoginData;
1409
1470
  },
1410
1471
  [client, setUser, setError, authProxyUrl]
1411
1472
  );
@@ -1480,12 +1541,11 @@ function useBilling() {
1480
1541
  setError(null);
1481
1542
  setLoading(true);
1482
1543
  try {
1483
- const response = await client.post("/v1/billing/connected-accounts", data);
1484
- if (!response.success || !response.data) {
1485
- setError(response.error || null);
1486
- return null;
1487
- }
1488
- return response.data;
1544
+ return await client.post("/v1/billing/connected-accounts", data);
1545
+ } catch (err) {
1546
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1547
+ setError(apiError);
1548
+ return null;
1489
1549
  } finally {
1490
1550
  setLoading(false);
1491
1551
  }
@@ -1496,12 +1556,11 @@ function useBilling() {
1496
1556
  setError(null);
1497
1557
  setLoading(true);
1498
1558
  try {
1499
- const response = await client.get("/v1/billing/connected-accounts/me");
1500
- if (!response.success || !response.data) {
1501
- setError(response.error || null);
1502
- return null;
1503
- }
1504
- return response.data;
1559
+ return await client.get("/v1/billing/connected-accounts/me");
1560
+ } catch (err) {
1561
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1562
+ setError(apiError);
1563
+ return null;
1505
1564
  } finally {
1506
1565
  setLoading(false);
1507
1566
  }
@@ -1511,12 +1570,11 @@ function useBilling() {
1511
1570
  setError(null);
1512
1571
  setLoading(true);
1513
1572
  try {
1514
- const response = await client.get(`/v1/billing/connected-accounts/${id}`);
1515
- if (!response.success || !response.data) {
1516
- setError(response.error || null);
1517
- return null;
1518
- }
1519
- return response.data;
1573
+ return await client.get(`/v1/billing/connected-accounts/${id}`);
1574
+ } catch (err) {
1575
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1576
+ setError(apiError);
1577
+ return null;
1520
1578
  } finally {
1521
1579
  setLoading(false);
1522
1580
  }
@@ -1528,15 +1586,15 @@ function useBilling() {
1528
1586
  setError(null);
1529
1587
  setLoading(true);
1530
1588
  try {
1531
- const response = await client.post(
1589
+ const result = await client.post(
1532
1590
  `/v1/billing/connected-accounts/${id}/onboarding-link`,
1533
1591
  data
1534
1592
  );
1535
- if (!response.success || !response.data) {
1536
- setError(response.error || null);
1537
- return null;
1538
- }
1539
- return response.data.url;
1593
+ return result.url;
1594
+ } catch (err) {
1595
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1596
+ setError(apiError);
1597
+ return null;
1540
1598
  } finally {
1541
1599
  setLoading(false);
1542
1600
  }
@@ -1548,14 +1606,13 @@ function useBilling() {
1548
1606
  setError(null);
1549
1607
  setLoading(true);
1550
1608
  try {
1551
- const response = await client.get(
1609
+ return await client.get(
1552
1610
  `/v1/billing/connected-accounts/${id}/balance`
1553
1611
  );
1554
- if (!response.success || !response.data) {
1555
- setError(response.error || null);
1556
- return null;
1557
- }
1558
- return response.data;
1612
+ } catch (err) {
1613
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1614
+ setError(apiError);
1615
+ return null;
1559
1616
  } finally {
1560
1617
  setLoading(false);
1561
1618
  }
@@ -1567,12 +1624,11 @@ function useBilling() {
1567
1624
  setError(null);
1568
1625
  setLoading(true);
1569
1626
  try {
1570
- const response = await client.post("/v1/billing/payments", data);
1571
- if (!response.success || !response.data) {
1572
- setError(response.error || null);
1573
- return null;
1574
- }
1575
- return response.data;
1627
+ return await client.post("/v1/billing/payments", data);
1628
+ } catch (err) {
1629
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1630
+ setError(apiError);
1631
+ return null;
1576
1632
  } finally {
1577
1633
  setLoading(false);
1578
1634
  }
@@ -1584,12 +1640,11 @@ function useBilling() {
1584
1640
  setError(null);
1585
1641
  setLoading(true);
1586
1642
  try {
1587
- const response = await client.get(`/v1/billing/payments/${id}`);
1588
- if (!response.success || !response.data) {
1589
- setError(response.error || null);
1590
- return null;
1591
- }
1592
- return response.data;
1643
+ return await client.get(`/v1/billing/payments/${id}`);
1644
+ } catch (err) {
1645
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1646
+ setError(apiError);
1647
+ return null;
1593
1648
  } finally {
1594
1649
  setLoading(false);
1595
1650
  }
@@ -1602,12 +1657,11 @@ function useBilling() {
1602
1657
  setLoading(true);
1603
1658
  try {
1604
1659
  const query = params ? "?" + Object.entries(params).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&") : "";
1605
- const response = await client.get(`/v1/billing/payments${query}`);
1606
- if (!response.success || !response.data) {
1607
- setError(response.error || null);
1608
- return [];
1609
- }
1610
- return response.data;
1660
+ return await client.get(`/v1/billing/payments${query}`);
1661
+ } catch (err) {
1662
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1663
+ setError(apiError);
1664
+ return [];
1611
1665
  } finally {
1612
1666
  setLoading(false);
1613
1667
  }
@@ -1619,12 +1673,11 @@ function useBilling() {
1619
1673
  setError(null);
1620
1674
  setLoading(true);
1621
1675
  try {
1622
- const response = await client.post(`/v1/billing/payments/${id}/refund`, data);
1623
- if (!response.success || !response.data) {
1624
- setError(response.error || null);
1625
- return null;
1626
- }
1627
- return response.data;
1676
+ return await client.post(`/v1/billing/payments/${id}/refund`, data);
1677
+ } catch (err) {
1678
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1679
+ setError(apiError);
1680
+ return null;
1628
1681
  } finally {
1629
1682
  setLoading(false);
1630
1683
  }
@@ -1637,14 +1690,13 @@ function useBilling() {
1637
1690
  setLoading(true);
1638
1691
  try {
1639
1692
  const query = params ? "?" + Object.entries(params).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&") : "";
1640
- const response = await client.get(
1693
+ return await client.get(
1641
1694
  `/v1/billing/connected-accounts/${accountId}/payouts${query}`
1642
1695
  );
1643
- if (!response.success || !response.data) {
1644
- setError(response.error || null);
1645
- return [];
1646
- }
1647
- return response.data;
1696
+ } catch (err) {
1697
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1698
+ setError(apiError);
1699
+ return [];
1648
1700
  } finally {
1649
1701
  setLoading(false);
1650
1702
  }
@@ -1656,14 +1708,13 @@ function useBilling() {
1656
1708
  setError(null);
1657
1709
  setLoading(true);
1658
1710
  try {
1659
- const response = await client.get(
1711
+ return await client.get(
1660
1712
  `/v1/billing/connected-accounts/${accountId}/payout-schedule`
1661
1713
  );
1662
- if (!response.success || !response.data) {
1663
- setError(response.error || null);
1664
- return null;
1665
- }
1666
- return response.data;
1714
+ } catch (err) {
1715
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1716
+ setError(apiError);
1717
+ return null;
1667
1718
  } finally {
1668
1719
  setLoading(false);
1669
1720
  }
@@ -1675,15 +1726,14 @@ function useBilling() {
1675
1726
  setError(null);
1676
1727
  setLoading(true);
1677
1728
  try {
1678
- const response = await client.put(
1729
+ return await client.put(
1679
1730
  `/v1/billing/connected-accounts/${accountId}/payout-schedule`,
1680
1731
  data
1681
1732
  );
1682
- if (!response.success || !response.data) {
1683
- setError(response.error || null);
1684
- return null;
1685
- }
1686
- return response.data;
1733
+ } catch (err) {
1734
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1735
+ setError(apiError);
1736
+ return null;
1687
1737
  } finally {
1688
1738
  setLoading(false);
1689
1739
  }
@@ -1696,12 +1746,11 @@ function useBilling() {
1696
1746
  setLoading(true);
1697
1747
  try {
1698
1748
  const query = params ? "?" + Object.entries(params).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&") : "";
1699
- const response = await client.get(`/v1/billing/transactions${query}`);
1700
- if (!response.success || !response.data) {
1701
- setError(response.error || null);
1702
- return [];
1703
- }
1704
- return response.data;
1749
+ return await client.get(`/v1/billing/transactions${query}`);
1750
+ } catch (err) {
1751
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1752
+ setError(apiError);
1753
+ return [];
1705
1754
  } finally {
1706
1755
  setLoading(false);
1707
1756
  }
@@ -1714,14 +1763,13 @@ function useBilling() {
1714
1763
  setLoading(true);
1715
1764
  try {
1716
1765
  const query = params ? "?" + Object.entries(params).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&") : "";
1717
- const response = await client.get(
1766
+ return await client.get(
1718
1767
  `/v1/billing/transactions/summary${query}`
1719
1768
  );
1720
- if (!response.success || !response.data) {
1721
- setError(response.error || null);
1722
- return null;
1723
- }
1724
- return response.data;
1769
+ } catch (err) {
1770
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1771
+ setError(apiError);
1772
+ return null;
1725
1773
  } finally {
1726
1774
  setLoading(false);
1727
1775
  }
@@ -1733,15 +1781,15 @@ function useBilling() {
1733
1781
  setError(null);
1734
1782
  setLoading(true);
1735
1783
  try {
1736
- const response = await client.post(
1784
+ const result = await client.post(
1737
1785
  "/v1/billing/setup-sessions",
1738
1786
  data
1739
1787
  );
1740
- if (!response.success || !response.data) {
1741
- setError(response.error || null);
1742
- return null;
1743
- }
1744
- return response.data.client_secret;
1788
+ return result.client_secret;
1789
+ } catch (err) {
1790
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1791
+ setError(apiError);
1792
+ return null;
1745
1793
  } finally {
1746
1794
  setLoading(false);
1747
1795
  }
@@ -1809,17 +1857,9 @@ function useContent(options = {}) {
1809
1857
  if (p.offset) queryParams.set("offset", p.offset.toString());
1810
1858
  const query = queryParams.toString();
1811
1859
  const path = `/v1/storage/my-files${query ? `?${query}` : ""}`;
1812
- const response = await client.get(path);
1813
- if (!response.success || !response.data) {
1814
- const err = response.error || {
1815
- code: "LIST_FAILED",
1816
- message: "Failed to list files"
1817
- };
1818
- setLocalError(err);
1819
- throw err;
1820
- }
1821
- setFiles(response.data.files);
1822
- return response.data;
1860
+ const data = await client.get(path);
1861
+ setFiles(data.files);
1862
+ return data;
1823
1863
  } finally {
1824
1864
  setLoading(false);
1825
1865
  }
@@ -1846,22 +1886,14 @@ function useContent(options = {}) {
1846
1886
  setUploadProgress(progress);
1847
1887
  options2?.onProgress?.(progress);
1848
1888
  };
1849
- const response = await client.upload(
1889
+ const data = await client.upload(
1850
1890
  "/v1/storage/upload",
1851
1891
  file,
1852
1892
  additionalFields,
1853
1893
  { onProgress }
1854
1894
  );
1855
- if (!response.success || !response.data) {
1856
- const err = response.error || {
1857
- code: "UPLOAD_FAILED",
1858
- message: "Failed to upload file"
1859
- };
1860
- setLocalError(err);
1861
- throw err;
1862
- }
1863
1895
  await list();
1864
- return response.data;
1896
+ return data;
1865
1897
  } finally {
1866
1898
  setLoading(false);
1867
1899
  setUploadProgress(null);
@@ -1874,15 +1906,7 @@ function useContent(options = {}) {
1874
1906
  setLocalError(null);
1875
1907
  setLoading(true);
1876
1908
  try {
1877
- const response = await client.delete(`/v1/storage/files/${fileId}`);
1878
- if (!response.success) {
1879
- const err = response.error || {
1880
- code: "DELETE_FAILED",
1881
- message: "Failed to delete file"
1882
- };
1883
- setLocalError(err);
1884
- throw err;
1885
- }
1909
+ await client.delete(`/v1/storage/files/${fileId}`);
1886
1910
  setFiles((prev) => prev.filter((f) => f.id !== fileId));
1887
1911
  } finally {
1888
1912
  setLoading(false);
@@ -1893,16 +1917,7 @@ function useContent(options = {}) {
1893
1917
  const get = useCallback(
1894
1918
  async (fileId) => {
1895
1919
  setLocalError(null);
1896
- const response = await client.get(`/v1/storage/files/${fileId}/info`);
1897
- if (!response.success || !response.data) {
1898
- const err = response.error || {
1899
- code: "GET_FAILED",
1900
- message: "Failed to get file info"
1901
- };
1902
- setLocalError(err);
1903
- throw err;
1904
- }
1905
- return response.data;
1920
+ return await client.get(`/v1/storage/files/${fileId}/info`);
1906
1921
  },
1907
1922
  [client]
1908
1923
  );
@@ -1912,16 +1927,7 @@ function useContent(options = {}) {
1912
1927
  const getSignedUploadUrl = useCallback(
1913
1928
  async (request) => {
1914
1929
  setLocalError(null);
1915
- const response = await client.post("/v1/storage/signed-upload", request);
1916
- if (!response.success || !response.data) {
1917
- const err = response.error || {
1918
- code: "SIGNED_URL_FAILED",
1919
- message: "Failed to get signed upload URL"
1920
- };
1921
- setLocalError(err);
1922
- throw err;
1923
- }
1924
- return response.data;
1930
+ return await client.post("/v1/storage/signed-upload", request);
1925
1931
  },
1926
1932
  [client]
1927
1933
  );
@@ -1976,17 +1982,9 @@ function useContent(options = {}) {
1976
1982
  const completeSignedUpload = useCallback(
1977
1983
  async (fileId) => {
1978
1984
  setLocalError(null);
1979
- const response = await client.post(`/v1/storage/signed-upload/${fileId}/complete`);
1980
- if (!response.success || !response.data) {
1981
- const err = response.error || {
1982
- code: "COMPLETE_UPLOAD_FAILED",
1983
- message: "Failed to complete upload"
1984
- };
1985
- setLocalError(err);
1986
- throw err;
1987
- }
1985
+ const data = await client.post(`/v1/storage/signed-upload/${fileId}/complete`);
1988
1986
  await list();
1989
- return response.data;
1987
+ return data;
1990
1988
  },
1991
1989
  [client, list]
1992
1990
  );
@@ -2035,17 +2033,9 @@ function useUser() {
2035
2033
  setLocalError(null);
2036
2034
  setLoading(true);
2037
2035
  try {
2038
- const response = await client.patch("/v1/auth/profile", data);
2039
- if (!response.success || !response.data) {
2040
- const err = response.error || {
2041
- code: "UPDATE_FAILED",
2042
- message: "Failed to update profile"
2043
- };
2044
- setLocalError(err);
2045
- throw err;
2046
- }
2047
- setUser(response.data);
2048
- return response.data;
2036
+ const profileData = await client.patch("/v1/auth/profile", data);
2037
+ setUser(profileData);
2038
+ return profileData;
2049
2039
  } finally {
2050
2040
  setLoading(false);
2051
2041
  }
@@ -2057,18 +2047,10 @@ function useUser() {
2057
2047
  setLocalError(null);
2058
2048
  setLoading(true);
2059
2049
  try {
2060
- const response = await client.post("/v1/auth/change-password", {
2050
+ await client.post("/v1/auth/change-password", {
2061
2051
  current_password: currentPassword,
2062
2052
  new_password: newPassword
2063
2053
  });
2064
- if (!response.success) {
2065
- const err = response.error || {
2066
- code: "CHANGE_PASSWORD_FAILED",
2067
- message: "Failed to change password"
2068
- };
2069
- setLocalError(err);
2070
- throw err;
2071
- }
2072
2054
  } finally {
2073
2055
  setLoading(false);
2074
2056
  }
@@ -2080,18 +2062,10 @@ function useUser() {
2080
2062
  setLocalError(null);
2081
2063
  setLoading(true);
2082
2064
  try {
2083
- const response = await client.post("/v1/auth/change-email", {
2065
+ await client.post("/v1/auth/change-email", {
2084
2066
  new_email: newEmail,
2085
2067
  password
2086
2068
  });
2087
- if (!response.success) {
2088
- const err = response.error || {
2089
- code: "CHANGE_EMAIL_FAILED",
2090
- message: "Failed to change email"
2091
- };
2092
- setLocalError(err);
2093
- throw err;
2094
- }
2095
2069
  } finally {
2096
2070
  setLoading(false);
2097
2071
  }
@@ -2103,17 +2077,9 @@ function useUser() {
2103
2077
  setLocalError(null);
2104
2078
  setLoading(true);
2105
2079
  try {
2106
- const response = await client.post("/v1/auth/delete-account", {
2080
+ await client.post("/v1/auth/delete-account", {
2107
2081
  password
2108
2082
  });
2109
- if (!response.success) {
2110
- const err = response.error || {
2111
- code: "DELETE_ACCOUNT_FAILED",
2112
- message: "Failed to delete account"
2113
- };
2114
- setLocalError(err);
2115
- throw err;
2116
- }
2117
2083
  await client.clearSession();
2118
2084
  setUser(null);
2119
2085
  } finally {
@@ -2126,18 +2092,9 @@ function useUser() {
2126
2092
  setLocalError(null);
2127
2093
  setLoading(true);
2128
2094
  try {
2129
- const response = await client.post(
2095
+ return await client.post(
2130
2096
  "/v1/auth/export-data"
2131
2097
  );
2132
- if (!response.success || !response.data) {
2133
- const err = response.error || {
2134
- code: "EXPORT_FAILED",
2135
- message: "Failed to export data"
2136
- };
2137
- setLocalError(err);
2138
- throw err;
2139
- }
2140
- return response.data;
2141
2098
  } finally {
2142
2099
  setLoading(false);
2143
2100
  }
@@ -2619,15 +2576,7 @@ function useAnalytics(options = {}) {
2619
2576
  return { tracked: 1, session_id: sessionIdRef.current || void 0 };
2620
2577
  }
2621
2578
  const endpoint = useV2 ? "/v1/analytics/v2/events" : "/v1/analytics/events";
2622
- const response = await client.post(endpoint, fullEvent);
2623
- if (!response.success) {
2624
- const err = response.error || {
2625
- code: "TRACK_FAILED",
2626
- message: "Failed to track event"
2627
- };
2628
- throw err;
2629
- }
2630
- return response.data || { tracked: 1, session_id: sessionIdRef.current || void 0 };
2579
+ return await client.post(endpoint, fullEvent);
2631
2580
  },
2632
2581
  // Note: sessionId removed - we use ref to keep this stable
2633
2582
  [client, buildFullEvent, useV2, analyticsProxyUrl, publishableKey, gatewayUrl]
@@ -2645,7 +2594,7 @@ function useAnalytics(options = {}) {
2645
2594
  }
2646
2595
  return await sendEvent(event);
2647
2596
  } catch (err) {
2648
- if (err && typeof err === "object" && "code" in err) {
2597
+ if (err instanceof ScaleMuleApiError) {
2649
2598
  setError(err);
2650
2599
  }
2651
2600
  throw err;
@@ -2707,18 +2656,9 @@ function useAnalytics(options = {}) {
2707
2656
  return { tracked: events.length, session_id: sessionIdRef.current || void 0 };
2708
2657
  }
2709
2658
  const endpoint = useV2 ? "/v1/analytics/v2/events/batch" : "/v1/analytics/events/batch";
2710
- const response = await client.post(endpoint, {
2659
+ return await client.post(endpoint, {
2711
2660
  events: fullEvents
2712
2661
  });
2713
- if (!response.success) {
2714
- const err = response.error || {
2715
- code: "BATCH_TRACK_FAILED",
2716
- message: "Failed to track events"
2717
- };
2718
- setError(err);
2719
- throw err;
2720
- }
2721
- return response.data || { tracked: events.length, session_id: sessionIdRef.current || void 0 };
2722
2662
  } finally {
2723
2663
  setLoading(false);
2724
2664
  }
@@ -3081,4 +3021,4 @@ function createSafeLogger(prefix) {
3081
3021
  };
3082
3022
  }
3083
3023
 
3084
- export { ScaleMuleClient, ScaleMuleProvider, composePhone, createClient, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useRealtime, useScaleMule, useScaleMuleClient, useUser, validateForm, validators };
3024
+ export { ScaleMuleApiError, ScaleMuleClient, ScaleMuleProvider, composePhone, createClient, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useRealtime, useScaleMule, useScaleMuleClient, useUser, validateForm, validators };