@scalemule/nextjs 0.0.1 → 0.0.3

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,16 @@ 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
+ let responseData = null;
450
+ try {
451
+ responseData = text ? JSON.parse(text) : null;
452
+ } catch {
453
+ }
439
454
  if (!response.ok) {
440
- const error = data.error || {
455
+ const error = responseData?.error || {
441
456
  code: `HTTP_${response.status}`,
442
- message: data.message || response.statusText
457
+ message: responseData?.message || text || response.statusText
443
458
  };
444
459
  if (attempt < maxRetries && RETRYABLE_STATUS_CODES.has(response.status)) {
445
460
  lastError = error;
@@ -453,11 +468,15 @@ var ScaleMuleClient = class {
453
468
  if (this.debug) {
454
469
  console.error("[ScaleMule] Request failed:", error);
455
470
  }
456
- return { success: false, error };
471
+ throw new ScaleMuleApiError(error);
457
472
  }
473
+ const data = responseData?.data !== void 0 ? responseData.data : responseData;
458
474
  return data;
459
475
  } catch (err) {
460
476
  clearTimeout(timeoutId);
477
+ if (err instanceof ScaleMuleApiError) {
478
+ throw err;
479
+ }
461
480
  const error = {
462
481
  code: err instanceof Error && err.name === "AbortError" ? "TIMEOUT" : "NETWORK_ERROR",
463
482
  message: err instanceof Error ? err.message : "Network request failed"
@@ -474,10 +493,10 @@ var ScaleMuleClient = class {
474
493
  if (this.debug) {
475
494
  console.error("[ScaleMule] Network error:", err);
476
495
  }
477
- return { success: false, error };
496
+ throw new ScaleMuleApiError(error);
478
497
  }
479
498
  }
480
- return { success: false, error: lastError || { code: "UNKNOWN", message: "Request failed" } };
499
+ throw new ScaleMuleApiError(lastError || { code: "UNKNOWN", message: "Request failed" });
481
500
  }
482
501
  /**
483
502
  * GET request
@@ -573,11 +592,16 @@ var ScaleMuleClient = class {
573
592
  headers,
574
593
  body: retryFormData
575
594
  });
576
- const data = await response.json();
595
+ const uploadText = await response.text();
596
+ let responseData = null;
597
+ try {
598
+ responseData = uploadText ? JSON.parse(uploadText) : null;
599
+ } catch {
600
+ }
577
601
  if (!response.ok) {
578
- const error = data.error || {
602
+ const error = responseData?.error || {
579
603
  code: `HTTP_${response.status}`,
580
- message: data.message || response.statusText
604
+ message: responseData?.message || uploadText || response.statusText
581
605
  };
582
606
  if (attempt < maxRetries && RETRYABLE_STATUS_CODES.has(response.status)) {
583
607
  lastError = error;
@@ -588,10 +612,14 @@ var ScaleMuleClient = class {
588
612
  await sleep(delay);
589
613
  continue;
590
614
  }
591
- return { success: false, error };
615
+ throw new ScaleMuleApiError(error);
592
616
  }
617
+ const data = responseData?.data !== void 0 ? responseData.data : responseData;
593
618
  return data;
594
619
  } catch (err) {
620
+ if (err instanceof ScaleMuleApiError) {
621
+ throw err;
622
+ }
595
623
  lastError = {
596
624
  code: "UPLOAD_ERROR",
597
625
  message: err instanceof Error ? err.message : "Upload failed"
@@ -606,10 +634,7 @@ var ScaleMuleClient = class {
606
634
  }
607
635
  }
608
636
  }
609
- return {
610
- success: false,
611
- error: lastError || { code: "UPLOAD_ERROR", message: "Upload failed after retries" }
612
- };
637
+ throw new ScaleMuleApiError(lastError || { code: "UPLOAD_ERROR", message: "Upload failed after retries" });
613
638
  }
614
639
  /**
615
640
  * Upload with progress using XMLHttpRequest (with retry)
@@ -617,35 +642,35 @@ var ScaleMuleClient = class {
617
642
  async uploadWithProgress(url, formData, onProgress, maxRetries = 2) {
618
643
  let lastError = null;
619
644
  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`);
645
+ try {
646
+ return await this.singleUploadWithProgress(url, formData, onProgress);
647
+ } catch (err) {
648
+ if (!(err instanceof ScaleMuleApiError)) {
649
+ throw err;
650
+ }
651
+ const errorCode = err.code;
652
+ const isNetworkError = errorCode === "UPLOAD_ERROR" || errorCode === "NETWORK_ERROR";
653
+ const isRetryableHttp = errorCode.startsWith("HTTP_") && RETRYABLE_STATUS_CODES.has(parseInt(errorCode.replace("HTTP_", ""), 10));
654
+ if (attempt < maxRetries && (isNetworkError || isRetryableHttp)) {
655
+ lastError = { code: err.code, message: err.message };
656
+ const delay = getBackoffDelay(attempt);
657
+ if (this.debug) {
658
+ console.log(`[ScaleMule] Upload retry ${attempt + 1}/${maxRetries} after ${delay}ms`);
659
+ }
660
+ await sleep(delay);
661
+ onProgress(0);
662
+ continue;
632
663
  }
633
- await sleep(delay);
634
- onProgress(0);
635
- continue;
664
+ throw err;
636
665
  }
637
- return result;
638
666
  }
639
- return {
640
- success: false,
641
- error: lastError || { code: "UPLOAD_ERROR", message: "Upload failed after retries" }
642
- };
667
+ throw new ScaleMuleApiError(lastError || { code: "UPLOAD_ERROR", message: "Upload failed after retries" });
643
668
  }
644
669
  /**
645
670
  * Single upload attempt with progress using XMLHttpRequest
646
671
  */
647
672
  singleUploadWithProgress(url, formData, onProgress) {
648
- return new Promise((resolve) => {
673
+ return new Promise((resolve, reject) => {
649
674
  const xhr = new XMLHttpRequest();
650
675
  xhr.upload.addEventListener("progress", (event) => {
651
676
  if (event.lengthComputable) {
@@ -655,36 +680,29 @@ var ScaleMuleClient = class {
655
680
  });
656
681
  xhr.addEventListener("load", () => {
657
682
  try {
658
- const data = JSON.parse(xhr.responseText);
683
+ let data = null;
684
+ try {
685
+ data = xhr.responseText ? JSON.parse(xhr.responseText) : null;
686
+ } catch {
687
+ }
659
688
  if (xhr.status >= 200 && xhr.status < 300) {
660
- resolve(data);
689
+ const unwrapped = data?.data !== void 0 ? data.data : data;
690
+ resolve(unwrapped);
661
691
  } else {
662
- resolve({
663
- success: false,
664
- error: data.error || {
665
- code: `HTTP_${xhr.status}`,
666
- message: data.message || "Upload failed"
667
- }
668
- });
692
+ reject(new ScaleMuleApiError(data?.error || {
693
+ code: `HTTP_${xhr.status}`,
694
+ message: data?.message || xhr.responseText || "Upload failed"
695
+ }));
669
696
  }
670
697
  } catch {
671
- resolve({
672
- success: false,
673
- error: { code: "PARSE_ERROR", message: "Failed to parse response" }
674
- });
698
+ reject(new ScaleMuleApiError({ code: "PARSE_ERROR", message: "Failed to parse response" }));
675
699
  }
676
700
  });
677
701
  xhr.addEventListener("error", () => {
678
- resolve({
679
- success: false,
680
- error: { code: "UPLOAD_ERROR", message: "Upload failed" }
681
- });
702
+ reject(new ScaleMuleApiError({ code: "UPLOAD_ERROR", message: "Upload failed" }));
682
703
  });
683
704
  xhr.addEventListener("abort", () => {
684
- resolve({
685
- success: false,
686
- error: { code: "UPLOAD_ABORTED", message: "Upload cancelled" }
687
- });
705
+ reject(new ScaleMuleApiError({ code: "UPLOAD_ABORTED", message: "Upload cancelled" }));
688
706
  });
689
707
  xhr.open("POST", url);
690
708
  xhr.setRequestHeader("x-api-key", this.apiKey);
@@ -784,17 +802,19 @@ function ScaleMuleProvider({
784
802
  setUser(cachedUser);
785
803
  setInitializing(false);
786
804
  }
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 {
805
+ try {
806
+ const userData = await client.get("/v1/auth/me");
807
+ if (mounted) {
808
+ setUser(userData);
809
+ setCachedUser(userData);
810
+ }
811
+ } catch (authErr) {
812
+ if (mounted) {
793
813
  setUser(null);
794
814
  setCachedUser(null);
795
815
  await client.clearSession();
796
- if (response.error && onAuthError) {
797
- onAuthError(response.error);
816
+ if (onAuthError && authErr && typeof authErr === "object" && "code" in authErr) {
817
+ onAuthError(authErr);
798
818
  }
799
819
  }
800
820
  }
@@ -889,31 +909,29 @@ function useAuth() {
889
909
  async (data) => {
890
910
  setError(null);
891
911
  if (authProxyUrl) {
892
- const response2 = await proxyFetch(
912
+ const response = await proxyFetch(
893
913
  authProxyUrl,
894
914
  "register",
895
915
  { body: data }
896
916
  );
897
- if (!response2.success || !response2.data) {
898
- const err = response2.error || {
917
+ if (!response.success || !response.data) {
918
+ const err = response.error || {
899
919
  code: "REGISTER_FAILED",
900
920
  message: "Registration failed"
901
921
  };
902
922
  setError(err);
903
923
  throw err;
904
924
  }
905
- return response2.data.user;
925
+ return response.data.user;
906
926
  }
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);
927
+ try {
928
+ return await client.post("/v1/auth/register", data);
929
+ } catch (err) {
930
+ if (err instanceof ScaleMuleApiError) {
931
+ setError(err);
932
+ }
914
933
  throw err;
915
934
  }
916
- return response.data;
917
935
  },
918
936
  [client, setError, authProxyUrl]
919
937
  );
@@ -921,42 +939,42 @@ function useAuth() {
921
939
  async (data) => {
922
940
  setError(null);
923
941
  if (authProxyUrl) {
924
- const response2 = await proxyFetch(
942
+ const response = await proxyFetch(
925
943
  authProxyUrl,
926
944
  "login",
927
945
  { body: data }
928
946
  );
929
- if (!response2.success || !response2.data) {
930
- const err = response2.error || {
947
+ if (!response.success || !response.data) {
948
+ const err = response.error || {
931
949
  code: "LOGIN_FAILED",
932
950
  message: "Login failed"
933
951
  };
934
952
  setError(err);
935
953
  throw err;
936
954
  }
937
- if ("requires_mfa" in response2.data && response2.data.requires_mfa) {
938
- return response2.data;
955
+ if ("requires_mfa" in response.data && response.data.requires_mfa) {
956
+ return response.data;
939
957
  }
940
- const loginData2 = response2.data;
958
+ const loginData2 = response.data;
941
959
  const responseUser = "user" in loginData2 ? loginData2.user : null;
942
960
  if (responseUser) {
943
961
  setUser(responseUser);
944
962
  }
945
- return response2.data;
963
+ return response.data;
946
964
  }
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);
965
+ let loginResult;
966
+ try {
967
+ loginResult = await client.post("/v1/auth/login", data);
968
+ } catch (err) {
969
+ if (err instanceof ScaleMuleApiError) {
970
+ setError(err);
971
+ }
954
972
  throw err;
955
973
  }
956
- if ("requires_mfa" in response.data && response.data.requires_mfa) {
957
- return response.data;
974
+ if ("requires_mfa" in loginResult && loginResult.requires_mfa) {
975
+ return loginResult;
958
976
  }
959
- const loginData = response.data;
977
+ const loginData = loginResult;
960
978
  await client.setSession(loginData.session_token, loginData.user.id);
961
979
  setUser(loginData.user);
962
980
  return loginData;
@@ -986,14 +1004,25 @@ function useAuth() {
986
1004
  const forgotPassword = useCallback(
987
1005
  async (email) => {
988
1006
  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;
1007
+ if (authProxyUrl) {
1008
+ const response = await proxyFetch(authProxyUrl, "forgot-password", { body: { email } });
1009
+ if (!response.success) {
1010
+ const err = response.error || {
1011
+ code: "FORGOT_PASSWORD_FAILED",
1012
+ message: "Failed to send password reset email"
1013
+ };
1014
+ setError(err);
1015
+ throw err;
1016
+ }
1017
+ } else {
1018
+ try {
1019
+ await client.post("/v1/auth/forgot-password", { email });
1020
+ } catch (err) {
1021
+ if (err instanceof ScaleMuleApiError) {
1022
+ setError(err);
1023
+ }
1024
+ throw err;
1025
+ }
997
1026
  }
998
1027
  },
999
1028
  [client, setError, authProxyUrl]
@@ -1001,14 +1030,25 @@ function useAuth() {
1001
1030
  const resetPassword = useCallback(
1002
1031
  async (token, newPassword) => {
1003
1032
  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;
1033
+ if (authProxyUrl) {
1034
+ const response = await proxyFetch(authProxyUrl, "reset-password", { body: { token, new_password: newPassword } });
1035
+ if (!response.success) {
1036
+ const err = response.error || {
1037
+ code: "RESET_PASSWORD_FAILED",
1038
+ message: "Failed to reset password"
1039
+ };
1040
+ setError(err);
1041
+ throw err;
1042
+ }
1043
+ } else {
1044
+ try {
1045
+ await client.post("/v1/auth/reset-password", { token, new_password: newPassword });
1046
+ } catch (err) {
1047
+ if (err instanceof ScaleMuleApiError) {
1048
+ setError(err);
1049
+ }
1050
+ throw err;
1051
+ }
1012
1052
  }
1013
1053
  },
1014
1054
  [client, setError, authProxyUrl]
@@ -1016,14 +1056,25 @@ function useAuth() {
1016
1056
  const verifyEmail = useCallback(
1017
1057
  async (token) => {
1018
1058
  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;
1059
+ if (authProxyUrl) {
1060
+ const response = await proxyFetch(authProxyUrl, "verify-email", { body: { token } });
1061
+ if (!response.success) {
1062
+ const err = response.error || {
1063
+ code: "VERIFY_EMAIL_FAILED",
1064
+ message: "Failed to verify email"
1065
+ };
1066
+ setError(err);
1067
+ throw err;
1068
+ }
1069
+ } else {
1070
+ try {
1071
+ await client.post("/v1/auth/verify-email", { token });
1072
+ } catch (err) {
1073
+ if (err instanceof ScaleMuleApiError) {
1074
+ setError(err);
1075
+ }
1076
+ throw err;
1077
+ }
1027
1078
  }
1028
1079
  if (user) {
1029
1080
  if (authProxyUrl) {
@@ -1032,9 +1083,10 @@ function useAuth() {
1032
1083
  setUser(userResponse.data.user);
1033
1084
  }
1034
1085
  } else {
1035
- const userResponse = await client.get("/v1/auth/me");
1036
- if (userResponse.success && userResponse.data) {
1037
- setUser(userResponse.data);
1086
+ try {
1087
+ const userData = await client.get("/v1/auth/me");
1088
+ setUser(userData);
1089
+ } catch {
1038
1090
  }
1039
1091
  }
1040
1092
  }
@@ -1043,7 +1095,17 @@ function useAuth() {
1043
1095
  );
1044
1096
  const resendVerification = useCallback(async () => {
1045
1097
  setError(null);
1046
- const response = authProxyUrl ? await proxyFetch(authProxyUrl, "resend-verification", { body: user ? {} : void 0 }) : (() => {
1098
+ if (authProxyUrl) {
1099
+ const response = await proxyFetch(authProxyUrl, "resend-verification", { body: user ? {} : void 0 });
1100
+ if (!response.success) {
1101
+ const err = response.error || {
1102
+ code: "RESEND_FAILED",
1103
+ message: "Failed to resend verification email"
1104
+ };
1105
+ setError(err);
1106
+ throw err;
1107
+ }
1108
+ } else {
1047
1109
  if (!user) {
1048
1110
  const err = {
1049
1111
  code: "NOT_AUTHENTICATED",
@@ -1051,36 +1113,34 @@ function useAuth() {
1051
1113
  };
1052
1114
  throw err;
1053
1115
  }
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;
1116
+ try {
1117
+ await client.post("/v1/auth/resend-verification");
1118
+ } catch (err) {
1119
+ if (err instanceof ScaleMuleApiError) {
1120
+ setError(err);
1121
+ }
1122
+ throw err;
1123
+ }
1064
1124
  }
1065
1125
  }, [client, user, setError, authProxyUrl]);
1066
1126
  const refreshSession = useCallback(async () => {
1067
1127
  setError(null);
1068
1128
  if (authProxyUrl) {
1069
- const response2 = await proxyFetch(
1129
+ const response = await proxyFetch(
1070
1130
  authProxyUrl,
1071
1131
  "refresh"
1072
1132
  );
1073
- if (!response2.success) {
1133
+ if (!response.success) {
1074
1134
  setUser(null);
1075
- const err = response2.error || {
1135
+ const err = response.error || {
1076
1136
  code: "REFRESH_FAILED",
1077
1137
  message: "Session expired"
1078
1138
  };
1079
1139
  setError(err);
1080
1140
  throw err;
1081
1141
  }
1082
- if (response2.data?.user) {
1083
- setUser(response2.data.user);
1142
+ if (response.data?.user) {
1143
+ setUser(response.data.user);
1084
1144
  }
1085
1145
  return;
1086
1146
  }
@@ -1093,46 +1153,45 @@ function useAuth() {
1093
1153
  setError(err);
1094
1154
  throw err;
1095
1155
  }
1096
- const response = await client.post(
1097
- "/v1/auth/refresh",
1098
- { session_token: sessionToken }
1099
- );
1100
- if (!response.success || !response.data) {
1156
+ try {
1157
+ const refreshData = await client.post(
1158
+ "/v1/auth/refresh",
1159
+ { session_token: sessionToken }
1160
+ );
1161
+ const userId = client.getUserId();
1162
+ if (userId) {
1163
+ await client.setSession(refreshData.session_token, userId);
1164
+ }
1165
+ } catch (err) {
1101
1166
  await client.clearSession();
1102
1167
  setUser(null);
1103
- const err = response.error || {
1104
- code: "REFRESH_FAILED",
1105
- message: "Session expired"
1106
- };
1107
- setError(err);
1168
+ if (err instanceof ScaleMuleApiError) {
1169
+ setError(err);
1170
+ }
1108
1171
  throw err;
1109
1172
  }
1110
- const userId = client.getUserId();
1111
- if (userId) {
1112
- await client.setSession(response.data.session_token, userId);
1113
- }
1114
1173
  }, [client, setUser, setError, authProxyUrl]);
1115
1174
  const startOAuth = useCallback(
1116
1175
  async (config) => {
1117
1176
  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);
1177
+ let oauthData;
1178
+ try {
1179
+ oauthData = await client.post("/v1/auth/oauth/start", {
1180
+ provider: config.provider,
1181
+ redirect_url: config.redirectUrl,
1182
+ scopes: config.scopes,
1183
+ state: config.state
1184
+ });
1185
+ } catch (err) {
1186
+ if (err instanceof ScaleMuleApiError) {
1187
+ setError(err);
1188
+ }
1130
1189
  throw err;
1131
1190
  }
1132
1191
  if (typeof sessionStorage !== "undefined") {
1133
- sessionStorage.setItem("scalemule_oauth_state", response.data.state);
1192
+ sessionStorage.setItem("scalemule_oauth_state", oauthData.state);
1134
1193
  }
1135
- return response.data;
1194
+ return oauthData;
1136
1195
  },
1137
1196
  [client, setError]
1138
1197
  );
@@ -1151,33 +1210,32 @@ function useAuth() {
1151
1210
  }
1152
1211
  sessionStorage.removeItem("scalemule_oauth_state");
1153
1212
  }
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);
1213
+ let callbackData;
1214
+ try {
1215
+ callbackData = await client.post("/v1/auth/oauth/callback", request);
1216
+ } catch (err) {
1217
+ if (err instanceof ScaleMuleApiError) {
1218
+ setError(err);
1219
+ }
1161
1220
  throw err;
1162
1221
  }
1163
- await client.setSession(response.data.session_token, response.data.user.id);
1164
- setUser(response.data.user);
1165
- return response.data;
1222
+ await client.setSession(callbackData.session_token, callbackData.user.id);
1223
+ setUser(callbackData.user);
1224
+ return callbackData;
1166
1225
  },
1167
1226
  [client, setUser, setError]
1168
1227
  );
1169
1228
  const getLinkedAccounts = useCallback(async () => {
1170
1229
  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);
1230
+ try {
1231
+ const data = await client.get("/v1/auth/oauth/accounts");
1232
+ return data.accounts;
1233
+ } catch (err) {
1234
+ if (err instanceof ScaleMuleApiError) {
1235
+ setError(err);
1236
+ }
1178
1237
  throw err;
1179
1238
  }
1180
- return response.data.accounts;
1181
1239
  }, [client, setError]);
1182
1240
  const linkAccount = useCallback(
1183
1241
  async (config) => {
@@ -1190,36 +1248,35 @@ function useAuth() {
1190
1248
  setError(err);
1191
1249
  throw err;
1192
1250
  }
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);
1251
+ let linkData;
1252
+ try {
1253
+ linkData = await client.post("/v1/auth/oauth/link", {
1254
+ provider: config.provider,
1255
+ redirect_url: config.redirectUrl,
1256
+ scopes: config.scopes
1257
+ });
1258
+ } catch (err) {
1259
+ if (err instanceof ScaleMuleApiError) {
1260
+ setError(err);
1261
+ }
1204
1262
  throw err;
1205
1263
  }
1206
1264
  if (typeof sessionStorage !== "undefined") {
1207
- sessionStorage.setItem("scalemule_oauth_state", response.data.state);
1265
+ sessionStorage.setItem("scalemule_oauth_state", linkData.state);
1208
1266
  }
1209
- return response.data;
1267
+ return linkData;
1210
1268
  },
1211
1269
  [client, user, setError]
1212
1270
  );
1213
1271
  const unlinkAccount = useCallback(
1214
1272
  async (provider) => {
1215
1273
  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);
1274
+ try {
1275
+ await client.delete(`/v1/auth/oauth/accounts/${provider}`);
1276
+ } catch (err) {
1277
+ if (err instanceof ScaleMuleApiError) {
1278
+ setError(err);
1279
+ }
1223
1280
  throw err;
1224
1281
  }
1225
1282
  },
@@ -1227,46 +1284,41 @@ function useAuth() {
1227
1284
  );
1228
1285
  const getMFAStatus = useCallback(async () => {
1229
1286
  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);
1287
+ try {
1288
+ return await client.get("/v1/auth/mfa/status");
1289
+ } catch (err) {
1290
+ if (err instanceof ScaleMuleApiError) {
1291
+ setError(err);
1292
+ }
1237
1293
  throw err;
1238
1294
  }
1239
- return response.data;
1240
1295
  }, [client, setError]);
1241
1296
  const setupMFA = useCallback(
1242
1297
  async (request) => {
1243
1298
  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);
1299
+ try {
1300
+ return await client.post(
1301
+ "/v1/auth/mfa/setup",
1302
+ request
1303
+ );
1304
+ } catch (err) {
1305
+ if (err instanceof ScaleMuleApiError) {
1306
+ setError(err);
1307
+ }
1254
1308
  throw err;
1255
1309
  }
1256
- return response.data;
1257
1310
  },
1258
1311
  [client, setError]
1259
1312
  );
1260
1313
  const verifyMFA = useCallback(
1261
1314
  async (request) => {
1262
1315
  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);
1316
+ try {
1317
+ await client.post("/v1/auth/mfa/verify", request);
1318
+ } catch (err) {
1319
+ if (err instanceof ScaleMuleApiError) {
1320
+ setError(err);
1321
+ }
1270
1322
  throw err;
1271
1323
  }
1272
1324
  },
@@ -1275,35 +1327,34 @@ function useAuth() {
1275
1327
  const completeMFAChallenge = useCallback(
1276
1328
  async (challengeToken, code, method) => {
1277
1329
  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);
1330
+ let mfaResult;
1331
+ try {
1332
+ mfaResult = await client.post("/v1/auth/mfa/challenge", {
1333
+ challenge_token: challengeToken,
1334
+ code,
1335
+ method
1336
+ });
1337
+ } catch (err) {
1338
+ if (err instanceof ScaleMuleApiError) {
1339
+ setError(err);
1340
+ }
1289
1341
  throw err;
1290
1342
  }
1291
- await client.setSession(response.data.session_token, response.data.user.id);
1292
- setUser(response.data.user);
1293
- return response.data;
1343
+ await client.setSession(mfaResult.session_token, mfaResult.user.id);
1344
+ setUser(mfaResult.user);
1345
+ return mfaResult;
1294
1346
  },
1295
1347
  [client, setUser, setError]
1296
1348
  );
1297
1349
  const disableMFA = useCallback(
1298
1350
  async (password) => {
1299
1351
  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);
1352
+ try {
1353
+ await client.post("/v1/auth/mfa/disable", { password });
1354
+ } catch (err) {
1355
+ if (err instanceof ScaleMuleApiError) {
1356
+ setError(err);
1357
+ }
1307
1358
  throw err;
1308
1359
  }
1309
1360
  },
@@ -1312,32 +1363,42 @@ function useAuth() {
1312
1363
  const regenerateBackupCodes = useCallback(
1313
1364
  async (password) => {
1314
1365
  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);
1366
+ try {
1367
+ const data = await client.post("/v1/auth/mfa/backup-codes", {
1368
+ password
1369
+ });
1370
+ return data.backup_codes;
1371
+ } catch (err) {
1372
+ if (err instanceof ScaleMuleApiError) {
1373
+ setError(err);
1374
+ }
1324
1375
  throw err;
1325
1376
  }
1326
- return response.data.backup_codes;
1327
1377
  },
1328
1378
  [client, setError]
1329
1379
  );
1330
1380
  const sendPhoneCode = useCallback(
1331
1381
  async (request) => {
1332
1382
  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;
1383
+ if (authProxyUrl) {
1384
+ const response = await proxyFetch(authProxyUrl, "phone/send-code", { body: request });
1385
+ if (!response.success) {
1386
+ const err = response.error || {
1387
+ code: "SEND_CODE_FAILED",
1388
+ message: "Failed to send verification code"
1389
+ };
1390
+ setError(err);
1391
+ throw err;
1392
+ }
1393
+ } else {
1394
+ try {
1395
+ await client.post("/v1/auth/phone/send-code", request);
1396
+ } catch (err) {
1397
+ if (err instanceof ScaleMuleApiError) {
1398
+ setError(err);
1399
+ }
1400
+ throw err;
1401
+ }
1341
1402
  }
1342
1403
  },
1343
1404
  [client, setError, authProxyUrl]
@@ -1345,14 +1406,25 @@ function useAuth() {
1345
1406
  const verifyPhone = useCallback(
1346
1407
  async (request) => {
1347
1408
  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;
1409
+ if (authProxyUrl) {
1410
+ const response = await proxyFetch(authProxyUrl, "phone/verify", { body: request });
1411
+ if (!response.success) {
1412
+ const err = response.error || {
1413
+ code: "VERIFY_PHONE_FAILED",
1414
+ message: "Failed to verify phone number"
1415
+ };
1416
+ setError(err);
1417
+ throw err;
1418
+ }
1419
+ } else {
1420
+ try {
1421
+ await client.post("/v1/auth/phone/verify", request);
1422
+ } catch (err) {
1423
+ if (err instanceof ScaleMuleApiError) {
1424
+ setError(err);
1425
+ }
1426
+ throw err;
1427
+ }
1356
1428
  }
1357
1429
  if (user) {
1358
1430
  if (authProxyUrl) {
@@ -1361,9 +1433,10 @@ function useAuth() {
1361
1433
  setUser(userResponse.data.user);
1362
1434
  }
1363
1435
  } else {
1364
- const userResponse = await client.get("/v1/auth/me");
1365
- if (userResponse.success && userResponse.data) {
1366
- setUser(userResponse.data);
1436
+ try {
1437
+ const userData = await client.get("/v1/auth/me");
1438
+ setUser(userData);
1439
+ } catch {
1367
1440
  }
1368
1441
  }
1369
1442
  }
@@ -1374,38 +1447,38 @@ function useAuth() {
1374
1447
  async (request) => {
1375
1448
  setError(null);
1376
1449
  if (authProxyUrl) {
1377
- const response2 = await proxyFetch(
1450
+ const response = await proxyFetch(
1378
1451
  authProxyUrl,
1379
1452
  "phone/login",
1380
1453
  { body: request }
1381
1454
  );
1382
- if (!response2.success || !response2.data) {
1383
- const err = response2.error || {
1455
+ if (!response.success || !response.data) {
1456
+ const err = response.error || {
1384
1457
  code: "PHONE_LOGIN_FAILED",
1385
1458
  message: "Failed to login with phone"
1386
1459
  };
1387
1460
  setError(err);
1388
1461
  throw err;
1389
1462
  }
1390
- const loginData = response2.data;
1463
+ const loginData = response.data;
1391
1464
  const responseUser = "user" in loginData ? loginData.user : null;
1392
1465
  if (responseUser) {
1393
1466
  setUser(responseUser);
1394
1467
  }
1395
- return response2.data;
1468
+ return response.data;
1396
1469
  }
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);
1470
+ let phoneLoginData;
1471
+ try {
1472
+ phoneLoginData = await client.post("/v1/auth/phone/login", request);
1473
+ } catch (err) {
1474
+ if (err instanceof ScaleMuleApiError) {
1475
+ setError(err);
1476
+ }
1404
1477
  throw err;
1405
1478
  }
1406
- await client.setSession(response.data.session_token, response.data.user.id);
1407
- setUser(response.data.user);
1408
- return response.data;
1479
+ await client.setSession(phoneLoginData.session_token, phoneLoginData.user.id);
1480
+ setUser(phoneLoginData.user);
1481
+ return phoneLoginData;
1409
1482
  },
1410
1483
  [client, setUser, setError, authProxyUrl]
1411
1484
  );
@@ -1480,12 +1553,11 @@ function useBilling() {
1480
1553
  setError(null);
1481
1554
  setLoading(true);
1482
1555
  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;
1556
+ return await client.post("/v1/billing/connected-accounts", data);
1557
+ } catch (err) {
1558
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1559
+ setError(apiError);
1560
+ return null;
1489
1561
  } finally {
1490
1562
  setLoading(false);
1491
1563
  }
@@ -1496,12 +1568,11 @@ function useBilling() {
1496
1568
  setError(null);
1497
1569
  setLoading(true);
1498
1570
  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;
1571
+ return await client.get("/v1/billing/connected-accounts/me");
1572
+ } catch (err) {
1573
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1574
+ setError(apiError);
1575
+ return null;
1505
1576
  } finally {
1506
1577
  setLoading(false);
1507
1578
  }
@@ -1511,12 +1582,11 @@ function useBilling() {
1511
1582
  setError(null);
1512
1583
  setLoading(true);
1513
1584
  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;
1585
+ return await client.get(`/v1/billing/connected-accounts/${id}`);
1586
+ } catch (err) {
1587
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1588
+ setError(apiError);
1589
+ return null;
1520
1590
  } finally {
1521
1591
  setLoading(false);
1522
1592
  }
@@ -1528,15 +1598,15 @@ function useBilling() {
1528
1598
  setError(null);
1529
1599
  setLoading(true);
1530
1600
  try {
1531
- const response = await client.post(
1601
+ const result = await client.post(
1532
1602
  `/v1/billing/connected-accounts/${id}/onboarding-link`,
1533
1603
  data
1534
1604
  );
1535
- if (!response.success || !response.data) {
1536
- setError(response.error || null);
1537
- return null;
1538
- }
1539
- return response.data.url;
1605
+ return result.url;
1606
+ } catch (err) {
1607
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1608
+ setError(apiError);
1609
+ return null;
1540
1610
  } finally {
1541
1611
  setLoading(false);
1542
1612
  }
@@ -1548,14 +1618,13 @@ function useBilling() {
1548
1618
  setError(null);
1549
1619
  setLoading(true);
1550
1620
  try {
1551
- const response = await client.get(
1621
+ return await client.get(
1552
1622
  `/v1/billing/connected-accounts/${id}/balance`
1553
1623
  );
1554
- if (!response.success || !response.data) {
1555
- setError(response.error || null);
1556
- return null;
1557
- }
1558
- return response.data;
1624
+ } catch (err) {
1625
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1626
+ setError(apiError);
1627
+ return null;
1559
1628
  } finally {
1560
1629
  setLoading(false);
1561
1630
  }
@@ -1567,12 +1636,11 @@ function useBilling() {
1567
1636
  setError(null);
1568
1637
  setLoading(true);
1569
1638
  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;
1639
+ return await client.post("/v1/billing/payments", data);
1640
+ } catch (err) {
1641
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1642
+ setError(apiError);
1643
+ return null;
1576
1644
  } finally {
1577
1645
  setLoading(false);
1578
1646
  }
@@ -1584,12 +1652,11 @@ function useBilling() {
1584
1652
  setError(null);
1585
1653
  setLoading(true);
1586
1654
  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;
1655
+ return await client.get(`/v1/billing/payments/${id}`);
1656
+ } catch (err) {
1657
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1658
+ setError(apiError);
1659
+ return null;
1593
1660
  } finally {
1594
1661
  setLoading(false);
1595
1662
  }
@@ -1602,12 +1669,11 @@ function useBilling() {
1602
1669
  setLoading(true);
1603
1670
  try {
1604
1671
  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;
1672
+ return await client.get(`/v1/billing/payments${query}`);
1673
+ } catch (err) {
1674
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1675
+ setError(apiError);
1676
+ return [];
1611
1677
  } finally {
1612
1678
  setLoading(false);
1613
1679
  }
@@ -1619,12 +1685,11 @@ function useBilling() {
1619
1685
  setError(null);
1620
1686
  setLoading(true);
1621
1687
  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;
1688
+ return await client.post(`/v1/billing/payments/${id}/refund`, data);
1689
+ } catch (err) {
1690
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1691
+ setError(apiError);
1692
+ return null;
1628
1693
  } finally {
1629
1694
  setLoading(false);
1630
1695
  }
@@ -1637,14 +1702,13 @@ function useBilling() {
1637
1702
  setLoading(true);
1638
1703
  try {
1639
1704
  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(
1705
+ return await client.get(
1641
1706
  `/v1/billing/connected-accounts/${accountId}/payouts${query}`
1642
1707
  );
1643
- if (!response.success || !response.data) {
1644
- setError(response.error || null);
1645
- return [];
1646
- }
1647
- return response.data;
1708
+ } catch (err) {
1709
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1710
+ setError(apiError);
1711
+ return [];
1648
1712
  } finally {
1649
1713
  setLoading(false);
1650
1714
  }
@@ -1656,14 +1720,13 @@ function useBilling() {
1656
1720
  setError(null);
1657
1721
  setLoading(true);
1658
1722
  try {
1659
- const response = await client.get(
1723
+ return await client.get(
1660
1724
  `/v1/billing/connected-accounts/${accountId}/payout-schedule`
1661
1725
  );
1662
- if (!response.success || !response.data) {
1663
- setError(response.error || null);
1664
- return null;
1665
- }
1666
- return response.data;
1726
+ } catch (err) {
1727
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1728
+ setError(apiError);
1729
+ return null;
1667
1730
  } finally {
1668
1731
  setLoading(false);
1669
1732
  }
@@ -1675,15 +1738,14 @@ function useBilling() {
1675
1738
  setError(null);
1676
1739
  setLoading(true);
1677
1740
  try {
1678
- const response = await client.put(
1741
+ return await client.put(
1679
1742
  `/v1/billing/connected-accounts/${accountId}/payout-schedule`,
1680
1743
  data
1681
1744
  );
1682
- if (!response.success || !response.data) {
1683
- setError(response.error || null);
1684
- return null;
1685
- }
1686
- return response.data;
1745
+ } catch (err) {
1746
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1747
+ setError(apiError);
1748
+ return null;
1687
1749
  } finally {
1688
1750
  setLoading(false);
1689
1751
  }
@@ -1696,12 +1758,11 @@ function useBilling() {
1696
1758
  setLoading(true);
1697
1759
  try {
1698
1760
  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;
1761
+ return await client.get(`/v1/billing/transactions${query}`);
1762
+ } catch (err) {
1763
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1764
+ setError(apiError);
1765
+ return [];
1705
1766
  } finally {
1706
1767
  setLoading(false);
1707
1768
  }
@@ -1714,14 +1775,13 @@ function useBilling() {
1714
1775
  setLoading(true);
1715
1776
  try {
1716
1777
  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(
1778
+ return await client.get(
1718
1779
  `/v1/billing/transactions/summary${query}`
1719
1780
  );
1720
- if (!response.success || !response.data) {
1721
- setError(response.error || null);
1722
- return null;
1723
- }
1724
- return response.data;
1781
+ } catch (err) {
1782
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1783
+ setError(apiError);
1784
+ return null;
1725
1785
  } finally {
1726
1786
  setLoading(false);
1727
1787
  }
@@ -1733,15 +1793,15 @@ function useBilling() {
1733
1793
  setError(null);
1734
1794
  setLoading(true);
1735
1795
  try {
1736
- const response = await client.post(
1796
+ const result = await client.post(
1737
1797
  "/v1/billing/setup-sessions",
1738
1798
  data
1739
1799
  );
1740
- if (!response.success || !response.data) {
1741
- setError(response.error || null);
1742
- return null;
1743
- }
1744
- return response.data.client_secret;
1800
+ return result.client_secret;
1801
+ } catch (err) {
1802
+ const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
1803
+ setError(apiError);
1804
+ return null;
1745
1805
  } finally {
1746
1806
  setLoading(false);
1747
1807
  }
@@ -1809,17 +1869,9 @@ function useContent(options = {}) {
1809
1869
  if (p.offset) queryParams.set("offset", p.offset.toString());
1810
1870
  const query = queryParams.toString();
1811
1871
  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;
1872
+ const data = await client.get(path);
1873
+ setFiles(data.files);
1874
+ return data;
1823
1875
  } finally {
1824
1876
  setLoading(false);
1825
1877
  }
@@ -1846,22 +1898,14 @@ function useContent(options = {}) {
1846
1898
  setUploadProgress(progress);
1847
1899
  options2?.onProgress?.(progress);
1848
1900
  };
1849
- const response = await client.upload(
1901
+ const data = await client.upload(
1850
1902
  "/v1/storage/upload",
1851
1903
  file,
1852
1904
  additionalFields,
1853
1905
  { onProgress }
1854
1906
  );
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
1907
  await list();
1864
- return response.data;
1908
+ return data;
1865
1909
  } finally {
1866
1910
  setLoading(false);
1867
1911
  setUploadProgress(null);
@@ -1874,15 +1918,7 @@ function useContent(options = {}) {
1874
1918
  setLocalError(null);
1875
1919
  setLoading(true);
1876
1920
  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
- }
1921
+ await client.delete(`/v1/storage/files/${fileId}`);
1886
1922
  setFiles((prev) => prev.filter((f) => f.id !== fileId));
1887
1923
  } finally {
1888
1924
  setLoading(false);
@@ -1893,16 +1929,7 @@ function useContent(options = {}) {
1893
1929
  const get = useCallback(
1894
1930
  async (fileId) => {
1895
1931
  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;
1932
+ return await client.get(`/v1/storage/files/${fileId}/info`);
1906
1933
  },
1907
1934
  [client]
1908
1935
  );
@@ -1912,16 +1939,7 @@ function useContent(options = {}) {
1912
1939
  const getSignedUploadUrl = useCallback(
1913
1940
  async (request) => {
1914
1941
  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;
1942
+ return await client.post("/v1/storage/signed-upload", request);
1925
1943
  },
1926
1944
  [client]
1927
1945
  );
@@ -1976,17 +1994,9 @@ function useContent(options = {}) {
1976
1994
  const completeSignedUpload = useCallback(
1977
1995
  async (fileId) => {
1978
1996
  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
- }
1997
+ const data = await client.post(`/v1/storage/signed-upload/${fileId}/complete`);
1988
1998
  await list();
1989
- return response.data;
1999
+ return data;
1990
2000
  },
1991
2001
  [client, list]
1992
2002
  );
@@ -2035,17 +2045,9 @@ function useUser() {
2035
2045
  setLocalError(null);
2036
2046
  setLoading(true);
2037
2047
  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;
2048
+ const profileData = await client.patch("/v1/auth/profile", data);
2049
+ setUser(profileData);
2050
+ return profileData;
2049
2051
  } finally {
2050
2052
  setLoading(false);
2051
2053
  }
@@ -2057,18 +2059,10 @@ function useUser() {
2057
2059
  setLocalError(null);
2058
2060
  setLoading(true);
2059
2061
  try {
2060
- const response = await client.post("/v1/auth/change-password", {
2062
+ await client.post("/v1/auth/change-password", {
2061
2063
  current_password: currentPassword,
2062
2064
  new_password: newPassword
2063
2065
  });
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
2066
  } finally {
2073
2067
  setLoading(false);
2074
2068
  }
@@ -2080,18 +2074,10 @@ function useUser() {
2080
2074
  setLocalError(null);
2081
2075
  setLoading(true);
2082
2076
  try {
2083
- const response = await client.post("/v1/auth/change-email", {
2077
+ await client.post("/v1/auth/change-email", {
2084
2078
  new_email: newEmail,
2085
2079
  password
2086
2080
  });
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
2081
  } finally {
2096
2082
  setLoading(false);
2097
2083
  }
@@ -2103,17 +2089,9 @@ function useUser() {
2103
2089
  setLocalError(null);
2104
2090
  setLoading(true);
2105
2091
  try {
2106
- const response = await client.post("/v1/auth/delete-account", {
2092
+ await client.post("/v1/auth/delete-account", {
2107
2093
  password
2108
2094
  });
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
2095
  await client.clearSession();
2118
2096
  setUser(null);
2119
2097
  } finally {
@@ -2126,18 +2104,9 @@ function useUser() {
2126
2104
  setLocalError(null);
2127
2105
  setLoading(true);
2128
2106
  try {
2129
- const response = await client.post(
2107
+ return await client.post(
2130
2108
  "/v1/auth/export-data"
2131
2109
  );
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
2110
  } finally {
2142
2111
  setLoading(false);
2143
2112
  }
@@ -2619,15 +2588,7 @@ function useAnalytics(options = {}) {
2619
2588
  return { tracked: 1, session_id: sessionIdRef.current || void 0 };
2620
2589
  }
2621
2590
  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 };
2591
+ return await client.post(endpoint, fullEvent);
2631
2592
  },
2632
2593
  // Note: sessionId removed - we use ref to keep this stable
2633
2594
  [client, buildFullEvent, useV2, analyticsProxyUrl, publishableKey, gatewayUrl]
@@ -2645,7 +2606,7 @@ function useAnalytics(options = {}) {
2645
2606
  }
2646
2607
  return await sendEvent(event);
2647
2608
  } catch (err) {
2648
- if (err && typeof err === "object" && "code" in err) {
2609
+ if (err instanceof ScaleMuleApiError) {
2649
2610
  setError(err);
2650
2611
  }
2651
2612
  throw err;
@@ -2707,18 +2668,9 @@ function useAnalytics(options = {}) {
2707
2668
  return { tracked: events.length, session_id: sessionIdRef.current || void 0 };
2708
2669
  }
2709
2670
  const endpoint = useV2 ? "/v1/analytics/v2/events/batch" : "/v1/analytics/events/batch";
2710
- const response = await client.post(endpoint, {
2671
+ return await client.post(endpoint, {
2711
2672
  events: fullEvents
2712
2673
  });
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
2674
  } finally {
2723
2675
  setLoading(false);
2724
2676
  }
@@ -3081,4 +3033,4 @@ function createSafeLogger(prefix) {
3081
3033
  };
3082
3034
  }
3083
3035
 
3084
- export { ScaleMuleClient, ScaleMuleProvider, composePhone, createClient, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useRealtime, useScaleMule, useScaleMuleClient, useUser, validateForm, validators };
3036
+ export { ScaleMuleApiError, ScaleMuleClient, ScaleMuleProvider, composePhone, createClient, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useRealtime, useScaleMule, useScaleMuleClient, useUser, validateForm, validators };