@scalemule/nextjs 0.0.38 → 0.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var react = require('react');
4
+ var money = require('@scalemule/money');
4
5
  var jsxRuntime = require('react/jsx-runtime');
5
6
 
6
7
  var __defProp = Object.defineProperty;
@@ -3217,29 +3218,10 @@ var RealtimeService = class extends ServiceModule {
3217
3218
  // --------------------------------------------------------------------------
3218
3219
  connect() {
3219
3220
  if (this._status === "connecting" || this._status === "connected") return;
3220
- this.setStatus(this.reconnectAttempt > 0 ? "reconnecting" : "connecting");
3221
- this.fetchTicketAndConnect();
3222
- }
3223
- async fetchTicketAndConnect() {
3224
3221
  const baseUrl = this.client.getBaseUrl();
3222
+ const wsUrl = baseUrl.replace(/^http/, "ws") + "/v1/realtime/ws";
3223
+ this.setStatus(this.reconnectAttempt > 0 ? "reconnecting" : "connecting");
3225
3224
  try {
3226
- const headers = { "Content-Type": "application/json" };
3227
- const apiKey = this.client.getApiKey();
3228
- if (apiKey) headers["x-api-key"] = apiKey;
3229
- const token = this.client.getSessionToken();
3230
- if (token) headers["Authorization"] = `Bearer ${token}`;
3231
- const ticketRes = await fetch(`${baseUrl}/v1/realtime/ws/ticket`, {
3232
- method: "POST",
3233
- headers
3234
- });
3235
- let wsUrl;
3236
- if (ticketRes.ok) {
3237
- const ticketData = await ticketRes.json();
3238
- const ticket = ticketData.ticket;
3239
- wsUrl = baseUrl.replace(/^http/, "ws") + `/v1/realtime/ws?ticket=${encodeURIComponent(ticket)}`;
3240
- } else {
3241
- wsUrl = baseUrl.replace(/^http/, "ws") + "/v1/realtime/ws";
3242
- }
3243
3225
  this.ws = new WebSocket(wsUrl);
3244
3226
  } catch {
3245
3227
  this.scheduleReconnect();
@@ -6935,6 +6917,8 @@ function ScaleMuleProvider({
6935
6917
  analyticsProxyUrl,
6936
6918
  authProxyUrl,
6937
6919
  publishableKey,
6920
+ enableAccountSwitcher,
6921
+ accountSwitcherPrivacy,
6938
6922
  children,
6939
6923
  onLogin,
6940
6924
  onLogout,
@@ -6944,20 +6928,30 @@ function ScaleMuleProvider({
6944
6928
  const [user, setUser] = react.useState(null);
6945
6929
  const [initializing, setInitializing] = react.useState(true);
6946
6930
  const [error, setError] = react.useState(null);
6931
+ const resolvedGatewayUrl = gatewayUrl || (environment === "dev" ? "https://api-dev.scalemule.com" : "https://api.scalemule.com");
6947
6932
  const client = react.useMemo(
6948
6933
  () => createClient({
6949
6934
  apiKey,
6950
6935
  applicationId,
6951
6936
  environment,
6952
- gatewayUrl,
6937
+ gatewayUrl: resolvedGatewayUrl,
6953
6938
  debug,
6954
6939
  storage,
6955
6940
  pendingSessionInit: !!authProxyUrl
6956
6941
  }),
6957
- [apiKey, applicationId, environment, gatewayUrl, debug, storage, authProxyUrl]
6942
+ [apiKey, applicationId, environment, resolvedGatewayUrl, debug, storage, authProxyUrl]
6943
+ );
6944
+ const money$1 = react.useMemo(
6945
+ () => money.createMoneyClient({
6946
+ apiKey,
6947
+ gatewayUrl: resolvedGatewayUrl,
6948
+ environment,
6949
+ accessToken: client.getSessionToken() || void 0,
6950
+ fetch: globalThis.fetch.bind(globalThis)
6951
+ }),
6952
+ [apiKey, resolvedGatewayUrl, environment, client]
6958
6953
  );
6959
6954
  const baseClient = react.useMemo(() => {
6960
- const resolvedGatewayUrl = gatewayUrl || (environment === "dev" ? "https://api-dev.scalemule.com" : "https://api.scalemule.com");
6961
6955
  return new ScaleMule({
6962
6956
  apiKey,
6963
6957
  applicationId,
@@ -6965,15 +6959,17 @@ function ScaleMuleProvider({
6965
6959
  environment,
6966
6960
  debug
6967
6961
  });
6968
- }, [apiKey, applicationId, environment, gatewayUrl, debug]);
6962
+ }, [apiKey, applicationId, environment, resolvedGatewayUrl, debug]);
6969
6963
  react.useEffect(() => {
6970
6964
  const token = client.getSessionToken();
6971
6965
  if (token) {
6972
6966
  baseClient.setAccessToken(token);
6967
+ money$1.setAccessToken(token);
6973
6968
  } else {
6974
6969
  baseClient.clearAccessToken();
6970
+ money$1.setAccessToken(void 0);
6975
6971
  }
6976
- }, [client, baseClient, user]);
6972
+ }, [client, baseClient, money$1, user]);
6977
6973
  react.useEffect(() => {
6978
6974
  let mounted = true;
6979
6975
  async function initialize() {
@@ -7061,6 +7057,7 @@ function ScaleMuleProvider({
7061
7057
  const value = react.useMemo(
7062
7058
  () => ({
7063
7059
  client,
7060
+ money: money$1,
7064
7061
  realtime: baseClient.realtime,
7065
7062
  user,
7066
7063
  setUser: handleSetUser,
@@ -7070,11 +7067,13 @@ function ScaleMuleProvider({
7070
7067
  analyticsProxyUrl,
7071
7068
  authProxyUrl,
7072
7069
  publishableKey,
7073
- gatewayUrl: gatewayUrl || (environment === "dev" ? "https://api-dev.scalemule.com" : "https://api.scalemule.com"),
7070
+ gatewayUrl: resolvedGatewayUrl,
7074
7071
  environment: environment || void 0,
7072
+ enableAccountSwitcher,
7073
+ accountSwitcherPrivacy,
7075
7074
  bootstrapFlags
7076
7075
  }),
7077
- [client, baseClient, user, handleSetUser, initializing, error, analyticsProxyUrl, authProxyUrl, publishableKey, gatewayUrl, environment, bootstrapFlags]
7076
+ [client, money$1, baseClient, user, handleSetUser, initializing, error, analyticsProxyUrl, authProxyUrl, publishableKey, resolvedGatewayUrl, environment, enableAccountSwitcher, accountSwitcherPrivacy, bootstrapFlags]
7078
7077
  );
7079
7078
  return /* @__PURE__ */ jsxRuntime.jsx(ScaleMuleContext.Provider, { value, children });
7080
7079
  }
@@ -7091,6 +7090,45 @@ function useScaleMuleClient() {
7091
7090
  const { client } = useScaleMule();
7092
7091
  return client;
7093
7092
  }
7093
+ function useMoneyClient() {
7094
+ const { money } = useScaleMule();
7095
+ return money;
7096
+ }
7097
+ function maskEmail2(email) {
7098
+ const [local, domain] = email.split("@");
7099
+ if (!domain) return "***@***.***";
7100
+ const tldDot = domain.lastIndexOf(".");
7101
+ const tld = tldDot > 0 ? domain.slice(tldDot) : "";
7102
+ const domainBase = tldDot > 0 ? domain.slice(0, tldDot) : domain;
7103
+ return `${local[0] || "*"}***@${domainBase[0] || "*"}***${tld}`;
7104
+ }
7105
+ function stableColorIndex2(userId) {
7106
+ let hash = 0;
7107
+ for (let i = 0; i < userId.length; i++) {
7108
+ hash = (hash << 5) - hash + userId.charCodeAt(i) | 0;
7109
+ }
7110
+ return Math.abs(hash) % 8;
7111
+ }
7112
+ function applyClientPrivacy(entry, privacy) {
7113
+ if (!privacy || privacy === "full") return entry;
7114
+ if (privacy === "masked") {
7115
+ return {
7116
+ userId: entry.userId,
7117
+ email: entry.email ? maskEmail2(entry.email) : void 0,
7118
+ fullName: entry.fullName ? `${entry.fullName[0].toUpperCase()}.` : void 0,
7119
+ provider: entry.provider,
7120
+ lastActiveAt: entry.lastActiveAt,
7121
+ colorIndex: stableColorIndex2(entry.userId)
7122
+ };
7123
+ }
7124
+ return {
7125
+ userId: entry.userId,
7126
+ provider: entry.provider,
7127
+ lastActiveAt: entry.lastActiveAt,
7128
+ displayLabel: "Account",
7129
+ colorIndex: stableColorIndex2(entry.userId)
7130
+ };
7131
+ }
7094
7132
  function getCookie(name) {
7095
7133
  if (typeof document === "undefined") return void 0;
7096
7134
  const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));
@@ -7119,7 +7157,7 @@ async function proxyFetch(proxyUrl, path, options = {}) {
7119
7157
  return data;
7120
7158
  }
7121
7159
  function useAuth() {
7122
- const { client, user, setUser, initializing, error, setError, authProxyUrl } = useScaleMule();
7160
+ const { client, user, setUser, initializing, error, setError, authProxyUrl, enableAccountSwitcher, accountSwitcherPrivacy } = useScaleMule();
7123
7161
  const register = react.useCallback(
7124
7162
  async (data) => {
7125
7163
  setError(null);
@@ -7727,6 +7765,63 @@ function useAuth() {
7727
7765
  },
7728
7766
  [client, setUser, setError, authProxyUrl]
7729
7767
  );
7768
+ const readKnownAccountsCookie = react.useCallback(() => {
7769
+ if (!enableAccountSwitcher) return [];
7770
+ if (typeof document === "undefined") return [];
7771
+ const match = document.cookie.match(/(?:^|; )sm_known_accounts=([^;]*)/);
7772
+ if (!match) return [];
7773
+ try {
7774
+ const decoded = decodeURIComponent(match[1]);
7775
+ const accounts = JSON.parse(decoded);
7776
+ let entries = Object.values(accounts);
7777
+ if (accountSwitcherPrivacy && accountSwitcherPrivacy !== "full") {
7778
+ entries = entries.map((e) => applyClientPrivacy(e, accountSwitcherPrivacy));
7779
+ }
7780
+ return entries;
7781
+ } catch {
7782
+ return [];
7783
+ }
7784
+ }, [enableAccountSwitcher, accountSwitcherPrivacy]);
7785
+ const [knownAccounts, setKnownAccounts] = react.useState([]);
7786
+ react.useEffect(() => {
7787
+ setKnownAccounts(readKnownAccountsCookie());
7788
+ }, [readKnownAccountsCookie, user]);
7789
+ const switchAccount = react.useCallback(
7790
+ async (userId) => {
7791
+ const target = knownAccounts.find((a) => a.userId === userId) || null;
7792
+ if (!target) return null;
7793
+ if (authProxyUrl) {
7794
+ await proxyFetch(authProxyUrl, "switch-account");
7795
+ } else {
7796
+ const sessionToken = client.getSessionToken();
7797
+ if (sessionToken) {
7798
+ try {
7799
+ await client.post("/v1/auth/logout", { session_token: sessionToken });
7800
+ } catch {
7801
+ }
7802
+ }
7803
+ await client.clearSession();
7804
+ }
7805
+ setUser(null);
7806
+ return target;
7807
+ },
7808
+ [client, setUser, knownAccounts, authProxyUrl]
7809
+ );
7810
+ const removeKnownAccount = react.useCallback(
7811
+ async (userId) => {
7812
+ if (authProxyUrl) {
7813
+ await proxyFetch(authProxyUrl, "forget-account", { body: { user_id: userId } });
7814
+ }
7815
+ setKnownAccounts((prev) => prev.filter((a) => a.userId !== userId));
7816
+ },
7817
+ [authProxyUrl]
7818
+ );
7819
+ const clearKnownAccounts = react.useCallback(async () => {
7820
+ if (authProxyUrl) {
7821
+ await proxyFetch(authProxyUrl, "forget-all-accounts");
7822
+ }
7823
+ setKnownAccounts([]);
7824
+ }, [authProxyUrl]);
7730
7825
  return react.useMemo(
7731
7826
  () => ({
7732
7827
  user,
@@ -7758,7 +7853,12 @@ function useAuth() {
7758
7853
  // Phone auth
7759
7854
  sendPhoneCode,
7760
7855
  verifyPhone,
7761
- loginWithPhone
7856
+ loginWithPhone,
7857
+ // Account switcher
7858
+ knownAccounts,
7859
+ switchAccount,
7860
+ removeKnownAccount,
7861
+ clearKnownAccounts
7762
7862
  }),
7763
7863
  [
7764
7864
  user,
@@ -7785,10 +7885,20 @@ function useAuth() {
7785
7885
  regenerateBackupCodes,
7786
7886
  sendPhoneCode,
7787
7887
  verifyPhone,
7788
- loginWithPhone
7888
+ loginWithPhone,
7889
+ knownAccounts,
7890
+ switchAccount,
7891
+ removeKnownAccount,
7892
+ clearKnownAccounts
7789
7893
  ]
7790
7894
  );
7791
7895
  }
7896
+ function retiredBillingRouteError(route) {
7897
+ return {
7898
+ code: "MONEY_BILLING_ROUTE_RETIRED",
7899
+ message: `${route} was retired after the money-services cutover. Use @scalemule/money for subscriptions, pricing, and asset operations.`
7900
+ };
7901
+ }
7792
7902
  function useBilling() {
7793
7903
  const { client } = useScaleMule();
7794
7904
  const [loading, setLoading] = react.useState(false);
@@ -7798,7 +7908,7 @@ function useBilling() {
7798
7908
  setError(null);
7799
7909
  setLoading(true);
7800
7910
  try {
7801
- return await client.post("/v1/billing/connected-accounts", data);
7911
+ return await client.post("/v1/money/billing/connected-accounts", data);
7802
7912
  } catch (err) {
7803
7913
  const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
7804
7914
  setError(apiError);
@@ -7813,7 +7923,7 @@ function useBilling() {
7813
7923
  setError(null);
7814
7924
  setLoading(true);
7815
7925
  try {
7816
- return await client.get("/v1/billing/connected-accounts/me");
7926
+ return await client.get("/v1/money/billing/connected-accounts/me");
7817
7927
  } catch (err) {
7818
7928
  const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
7819
7929
  setError(apiError);
@@ -7827,7 +7937,7 @@ function useBilling() {
7827
7937
  setError(null);
7828
7938
  setLoading(true);
7829
7939
  try {
7830
- return await client.get(`/v1/billing/connected-accounts/${id}`);
7940
+ return await client.get(`/v1/money/billing/connected-accounts/${id}`);
7831
7941
  } catch (err) {
7832
7942
  const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
7833
7943
  setError(apiError);
@@ -7844,7 +7954,7 @@ function useBilling() {
7844
7954
  setLoading(true);
7845
7955
  try {
7846
7956
  const result = await client.post(
7847
- `/v1/billing/connected-accounts/${id}/onboarding-link`,
7957
+ `/v1/money/billing/connected-accounts/${id}/onboarding-link`,
7848
7958
  data
7849
7959
  );
7850
7960
  return result.url;
@@ -7863,11 +7973,7 @@ function useBilling() {
7863
7973
  setError(null);
7864
7974
  setLoading(true);
7865
7975
  try {
7866
- return await client.get(
7867
- `/v1/billing/connected-accounts/${id}/balance`
7868
- );
7869
- } catch (err) {
7870
- const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
7976
+ const apiError = retiredBillingRouteError(`/v1/money/billing/connected-accounts/${id}/balance`);
7871
7977
  setError(apiError);
7872
7978
  return null;
7873
7979
  } finally {
@@ -7881,9 +7987,8 @@ function useBilling() {
7881
7987
  setError(null);
7882
7988
  setLoading(true);
7883
7989
  try {
7884
- return await client.post("/v1/billing/payments", data);
7885
- } catch (err) {
7886
- const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
7990
+ void data;
7991
+ const apiError = retiredBillingRouteError("/v1/money/billing/payments");
7887
7992
  setError(apiError);
7888
7993
  return null;
7889
7994
  } finally {
@@ -7897,9 +8002,7 @@ function useBilling() {
7897
8002
  setError(null);
7898
8003
  setLoading(true);
7899
8004
  try {
7900
- return await client.get(`/v1/billing/payments/${id}`);
7901
- } catch (err) {
7902
- const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
8005
+ const apiError = retiredBillingRouteError(`/v1/money/billing/payments/${id}`);
7903
8006
  setError(apiError);
7904
8007
  return null;
7905
8008
  } finally {
@@ -7913,10 +8016,8 @@ function useBilling() {
7913
8016
  setError(null);
7914
8017
  setLoading(true);
7915
8018
  try {
7916
- const query = params ? "?" + Object.entries(params).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&") : "";
7917
- return await client.get(`/v1/billing/payments${query}`);
7918
- } catch (err) {
7919
- const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
8019
+ void params;
8020
+ const apiError = retiredBillingRouteError("/v1/money/billing/payments");
7920
8021
  setError(apiError);
7921
8022
  return [];
7922
8023
  } finally {
@@ -7930,9 +8031,8 @@ function useBilling() {
7930
8031
  setError(null);
7931
8032
  setLoading(true);
7932
8033
  try {
7933
- return await client.post(`/v1/billing/payments/${id}/refund`, data);
7934
- } catch (err) {
7935
- const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
8034
+ void data;
8035
+ const apiError = retiredBillingRouteError(`/v1/money/billing/payments/${id}/refund`);
7936
8036
  setError(apiError);
7937
8037
  return null;
7938
8038
  } finally {
@@ -7946,12 +8046,8 @@ function useBilling() {
7946
8046
  setError(null);
7947
8047
  setLoading(true);
7948
8048
  try {
7949
- const query = params ? "?" + Object.entries(params).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&") : "";
7950
- return await client.get(
7951
- `/v1/billing/connected-accounts/${accountId}/payouts${query}`
7952
- );
7953
- } catch (err) {
7954
- const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
8049
+ void params;
8050
+ const apiError = retiredBillingRouteError(`/v1/money/billing/connected-accounts/${accountId}/payouts`);
7955
8051
  setError(apiError);
7956
8052
  return [];
7957
8053
  } finally {
@@ -7966,7 +8062,7 @@ function useBilling() {
7966
8062
  setLoading(true);
7967
8063
  try {
7968
8064
  return await client.get(
7969
- `/v1/billing/connected-accounts/${accountId}/payout-schedule`
8065
+ `/v1/money/billing/connected-accounts/${accountId}/payout-schedule`
7970
8066
  );
7971
8067
  } catch (err) {
7972
8068
  const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
@@ -7984,7 +8080,7 @@ function useBilling() {
7984
8080
  setLoading(true);
7985
8081
  try {
7986
8082
  return await client.put(
7987
- `/v1/billing/connected-accounts/${accountId}/payout-schedule`,
8083
+ `/v1/money/billing/connected-accounts/${accountId}/payout-schedule`,
7988
8084
  data
7989
8085
  );
7990
8086
  } catch (err) {
@@ -8002,10 +8098,8 @@ function useBilling() {
8002
8098
  setError(null);
8003
8099
  setLoading(true);
8004
8100
  try {
8005
- const query = params ? "?" + Object.entries(params).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&") : "";
8006
- return await client.get(`/v1/billing/transactions${query}`);
8007
- } catch (err) {
8008
- const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
8101
+ void params;
8102
+ const apiError = retiredBillingRouteError("/v1/money/billing/transactions");
8009
8103
  setError(apiError);
8010
8104
  return [];
8011
8105
  } finally {
@@ -8019,12 +8113,8 @@ function useBilling() {
8019
8113
  setError(null);
8020
8114
  setLoading(true);
8021
8115
  try {
8022
- const query = params ? "?" + Object.entries(params).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join("&") : "";
8023
- return await client.get(
8024
- `/v1/billing/transactions/summary${query}`
8025
- );
8026
- } catch (err) {
8027
- const apiError = err instanceof ScaleMuleApiError ? err : { code: "UNKNOWN", message: err instanceof Error ? err.message : "Unknown error" };
8116
+ void params;
8117
+ const apiError = retiredBillingRouteError("/v1/money/billing/transactions/summary");
8028
8118
  setError(apiError);
8029
8119
  return null;
8030
8120
  } finally {
@@ -8039,7 +8129,7 @@ function useBilling() {
8039
8129
  setLoading(true);
8040
8130
  try {
8041
8131
  const result = await client.post(
8042
- "/v1/billing/setup-sessions",
8132
+ "/v1/money/billing/setup-sessions",
8043
8133
  data
8044
8134
  );
8045
8135
  return result.client_secret;
@@ -8281,6 +8371,9 @@ function useContent(options = {}) {
8281
8371
  ]
8282
8372
  );
8283
8373
  }
8374
+
8375
+ // src/hooks/useMoney.ts
8376
+ var useMoney = useMoneyClient;
8284
8377
  function useUser() {
8285
8378
  const { client, user, setUser, setError } = useScaleMule();
8286
8379
  const [loading, setLoading] = react.useState(false);
@@ -9636,6 +9729,14 @@ function createSafeLogger(prefix) {
9636
9729
  };
9637
9730
  }
9638
9731
 
9732
+ Object.defineProperty(exports, "MoneyClient", {
9733
+ enumerable: true,
9734
+ get: function () { return money.MoneyClient; }
9735
+ });
9736
+ Object.defineProperty(exports, "createMoneyClient", {
9737
+ enumerable: true,
9738
+ get: function () { return money.createMoneyClient; }
9739
+ });
9639
9740
  exports.ScaleMuleApiError = ScaleMuleApiError;
9640
9741
  exports.ScaleMuleClient = ScaleMuleClient2;
9641
9742
  exports.ScaleMuleProvider = ScaleMuleProvider;
@@ -9650,6 +9751,8 @@ exports.useAuth = useAuth;
9650
9751
  exports.useBilling = useBilling;
9651
9752
  exports.useContent = useContent;
9652
9753
  exports.useFeatureFlags = useFeatureFlags;
9754
+ exports.useMoney = useMoney;
9755
+ exports.useMoneyClient = useMoneyClient;
9653
9756
  exports.usePushNotifications = usePushNotifications;
9654
9757
  exports.useRealtime = useRealtime;
9655
9758
  exports.useScaleMule = useScaleMule;