@scalemule/nextjs 0.0.41 → 0.0.42

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.
Files changed (3) hide show
  1. package/dist/index.js +202 -37
  2. package/dist/index.mjs +202 -37
  3. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1560,6 +1560,52 @@ var AuthService = class extends ServiceModule {
1560
1560
  async me(options) {
1561
1561
  return this._get("/me", options);
1562
1562
  }
1563
+ // --------------------------------------------------------------------------
1564
+ // User directory (customer-scoped)
1565
+ // --------------------------------------------------------------------------
1566
+ //
1567
+ // Search / fetch users within the caller's application. These endpoints are
1568
+ // scoped by the gateway-injected x-app-id header, so when invoked with a
1569
+ // customer API key + user session they will only return users belonging to
1570
+ // the caller's application. They replace the prior pattern of customer apps
1571
+ // reaching for platform admin credentials to hit admin-only user routes.
1572
+ //
1573
+ // DO NOT call these with platform admin credentials from customer-facing
1574
+ // applications. Use the standard customer auth path (API key + user session)
1575
+ // and let the gateway inject x-app-id on your behalf.
1576
+ /**
1577
+ * Search users within the caller's application.
1578
+ *
1579
+ * Results are automatically scoped to the caller's application via the
1580
+ * x-app-id header injected by the gateway. Server-side page size is fixed
1581
+ * at 50 (the `per_page` query param is not honored upstream).
1582
+ *
1583
+ * @example
1584
+ * const res = await sm.auth.searchUsers({ search: 'alice' });
1585
+ * res.data?.users.forEach(u => console.log(u.email));
1586
+ */
1587
+ async searchUsers(params, options) {
1588
+ const query = {};
1589
+ if (params?.search !== void 0) query.search = params.search;
1590
+ if (params?.status !== void 0) query.status = params.status;
1591
+ if (params?.email_verified !== void 0) {
1592
+ query.email_verified = params.email_verified ? "true" : "false";
1593
+ }
1594
+ if (params?.phone_verified !== void 0) {
1595
+ query.phone_verified = params.phone_verified ? "true" : "false";
1596
+ }
1597
+ if (params?.page !== void 0) query.page = params.page;
1598
+ return this._get(this.withQuery("/users", query), options);
1599
+ }
1600
+ /**
1601
+ * Fetch a single user by ID within the caller's application.
1602
+ *
1603
+ * Returns 404 if the user is not in the caller's application — cross-tenant
1604
+ * reads are blocked at the gateway via the x-app-id header scope.
1605
+ */
1606
+ async getUser(userId, options) {
1607
+ return this._get(`/users/${encodeURIComponent(userId)}`, options);
1608
+ }
1563
1609
  /** Refresh the session. Alias: refreshToken() */
1564
1610
  async refreshSession(data, options) {
1565
1611
  return this.post("/refresh", data ?? {}, options);
@@ -2745,7 +2791,10 @@ var StorageService = class extends ServiceModule {
2745
2791
  const stallTimeout = DEFAULT_STALL_TIMEOUT_MS;
2746
2792
  const controller = new AbortController();
2747
2793
  let parentSignalCleanup;
2748
- const combinedSignal = signal ? AbortSignal.any?.([signal, controller.signal]) ?? (() => {
2794
+ const combinedSignal = signal ? AbortSignal.any?.([
2795
+ signal,
2796
+ controller.signal
2797
+ ]) ?? (() => {
2749
2798
  const onAbort = () => controller.abort();
2750
2799
  signal.addEventListener("abort", onAbort, { once: true });
2751
2800
  parentSignalCleanup = () => signal.removeEventListener("abort", onAbort);
@@ -2926,7 +2975,10 @@ var StorageService = class extends ServiceModule {
2926
2975
  }
2927
2976
  const controller = new AbortController();
2928
2977
  let partSignalCleanup;
2929
- const combinedSignal = signal ? AbortSignal.any?.([signal, controller.signal]) ?? (() => {
2978
+ const combinedSignal = signal ? AbortSignal.any?.([
2979
+ signal,
2980
+ controller.signal
2981
+ ]) ?? (() => {
2930
2982
  const onAbort = () => controller.abort();
2931
2983
  signal.addEventListener("abort", onAbort, { once: true });
2932
2984
  partSignalCleanup = () => signal.removeEventListener("abort", onAbort);
@@ -3090,6 +3142,7 @@ var RealtimeService = class extends ServiceModule {
3090
3142
  super(...arguments);
3091
3143
  this.basePath = "/v1/realtime";
3092
3144
  this.ws = null;
3145
+ this.usedTicketAuth = false;
3093
3146
  this.subscriptions = /* @__PURE__ */ new Map();
3094
3147
  this.presenceCallbacks = /* @__PURE__ */ new Map();
3095
3148
  this.statusCallbacks = /* @__PURE__ */ new Set();
@@ -3218,10 +3271,31 @@ var RealtimeService = class extends ServiceModule {
3218
3271
  // --------------------------------------------------------------------------
3219
3272
  connect() {
3220
3273
  if (this._status === "connecting" || this._status === "connected") return;
3221
- const baseUrl = this.client.getBaseUrl();
3222
- const wsUrl = baseUrl.replace(/^http/, "ws") + "/v1/realtime/ws";
3223
3274
  this.setStatus(this.reconnectAttempt > 0 ? "reconnecting" : "connecting");
3275
+ this.fetchTicketAndConnect();
3276
+ }
3277
+ async fetchTicketAndConnect() {
3278
+ const baseUrl = this.client.getBaseUrl();
3224
3279
  try {
3280
+ const headers = { "Content-Type": "application/json" };
3281
+ const apiKey = this.client.getApiKey();
3282
+ if (apiKey) headers["x-api-key"] = apiKey;
3283
+ const token = this.client.getSessionToken();
3284
+ if (token) headers["Authorization"] = `Bearer ${token}`;
3285
+ const ticketRes = await fetch(`${baseUrl}/v1/realtime/ws/ticket`, {
3286
+ method: "POST",
3287
+ headers
3288
+ });
3289
+ let wsUrl;
3290
+ if (ticketRes.ok) {
3291
+ const ticketData = await ticketRes.json();
3292
+ const ticket = ticketData.ticket;
3293
+ wsUrl = baseUrl.replace(/^http/, "ws") + `/v1/realtime/ws?ticket=${encodeURIComponent(ticket)}`;
3294
+ this.usedTicketAuth = true;
3295
+ } else {
3296
+ wsUrl = baseUrl.replace(/^http/, "ws") + "/v1/realtime/ws";
3297
+ this.usedTicketAuth = false;
3298
+ }
3225
3299
  this.ws = new WebSocket(wsUrl);
3226
3300
  } catch {
3227
3301
  this.scheduleReconnect();
@@ -3229,8 +3303,21 @@ var RealtimeService = class extends ServiceModule {
3229
3303
  }
3230
3304
  this.ws.onopen = () => {
3231
3305
  this.reconnectAttempt = 0;
3232
- this.authenticate();
3306
+ if (!this.usedTicketAuth) {
3307
+ this.authenticate();
3308
+ }
3233
3309
  this.startHeartbeat();
3310
+ if (this.usedTicketAuth) {
3311
+ setTimeout(() => {
3312
+ if (!this.authenticated) {
3313
+ this.authenticated = true;
3314
+ this.setStatus("connected");
3315
+ for (const channel of this.subscriptions.keys()) {
3316
+ this.sendWs({ type: "subscribe", channel });
3317
+ }
3318
+ }
3319
+ }, 2e3);
3320
+ }
3234
3321
  };
3235
3322
  this.ws.onmessage = (event) => {
3236
3323
  try {
@@ -3682,6 +3769,9 @@ var ChatService = class extends ServiceModule {
3682
3769
  async sendMessage(conversationId, data, options) {
3683
3770
  return this.post(`/conversations/${conversationId}/messages`, data, options);
3684
3771
  }
3772
+ async getThreadReplies(messageId, params, requestOptions) {
3773
+ return this._get(this.withQuery(`/messages/${messageId}/replies`, params), requestOptions);
3774
+ }
3685
3775
  async getMessages(conversationId, options, requestOptions) {
3686
3776
  return this._get(
3687
3777
  this.withQuery(`/conversations/${conversationId}/messages`, options),
@@ -3717,6 +3807,66 @@ var ChatService = class extends ServiceModule {
3717
3807
  return this.createConversation(data);
3718
3808
  }
3719
3809
  };
3810
+ var ConferenceService = class extends ServiceModule {
3811
+ constructor() {
3812
+ super(...arguments);
3813
+ this.basePath = "/v1/conference";
3814
+ }
3815
+ // --------------------------------------------------------------------------
3816
+ // Call Lifecycle
3817
+ // --------------------------------------------------------------------------
3818
+ async createCall(data, options) {
3819
+ return this.post("/calls", data, options);
3820
+ }
3821
+ async getCall(callId, options) {
3822
+ return this._get(`/calls/${callId}`, options);
3823
+ }
3824
+ async listCalls(params, options) {
3825
+ return this._get(this.withQuery("/calls", params), options);
3826
+ }
3827
+ async endCall(callId, options) {
3828
+ return this.post(`/calls/${callId}/end`, void 0, options);
3829
+ }
3830
+ // --------------------------------------------------------------------------
3831
+ // Participants
3832
+ // --------------------------------------------------------------------------
3833
+ async joinCall(callId, options) {
3834
+ return this.post(`/calls/${callId}/join`, void 0, options);
3835
+ }
3836
+ async leaveCall(callId, options) {
3837
+ return this.post(`/calls/${callId}/leave`, void 0, options);
3838
+ }
3839
+ async listParticipants(callId, options) {
3840
+ return this._get(`/calls/${callId}/participants`, options);
3841
+ }
3842
+ // --------------------------------------------------------------------------
3843
+ // Recording
3844
+ // --------------------------------------------------------------------------
3845
+ async startRecording(callId, options) {
3846
+ return this.post(`/calls/${callId}/recording/start`, void 0, options);
3847
+ }
3848
+ async stopRecording(callId, options) {
3849
+ return this.post(`/calls/${callId}/recording/stop`, void 0, options);
3850
+ }
3851
+ async consentToRecording(callId, options) {
3852
+ return this.post(`/calls/${callId}/recording/consent`, void 0, options);
3853
+ }
3854
+ // --------------------------------------------------------------------------
3855
+ // Settings
3856
+ // --------------------------------------------------------------------------
3857
+ async getSettings(options) {
3858
+ return this._get("/settings", options);
3859
+ }
3860
+ async updateSettings(data, options) {
3861
+ return this.put("/settings", data, options);
3862
+ }
3863
+ // --------------------------------------------------------------------------
3864
+ // Stats
3865
+ // --------------------------------------------------------------------------
3866
+ async submitStats(callId, stats, options) {
3867
+ return this.post(`/calls/${callId}/stats`, stats, options);
3868
+ }
3869
+ };
3720
3870
  var SocialService = class extends ServiceModule {
3721
3871
  constructor() {
3722
3872
  super(...arguments);
@@ -3838,7 +3988,14 @@ var ReferralsService = class extends ServiceModule {
3838
3988
  var BillingService = class extends ServiceModule {
3839
3989
  constructor() {
3840
3990
  super(...arguments);
3841
- this.basePath = "/v1/billing";
3991
+ this.basePath = "/v1/money/billing";
3992
+ }
3993
+ retiredSurface(route) {
3994
+ return Promise.reject(
3995
+ new Error(
3996
+ `${route} was retired after the money-services cutover. Use the dedicated money services instead of BillingService for this operation.`
3997
+ )
3998
+ );
3842
3999
  }
3843
4000
  // --------------------------------------------------------------------------
3844
4001
  // Customers
@@ -3853,28 +4010,28 @@ var BillingService = class extends ServiceModule {
3853
4010
  // Subscriptions
3854
4011
  // --------------------------------------------------------------------------
3855
4012
  async subscribe(data, options) {
3856
- return this.post("/subscriptions", data, options);
4013
+ return this.retiredSurface("/v1/money/billing/subscriptions");
3857
4014
  }
3858
4015
  async listSubscriptions(params, options) {
3859
- return this._list("/subscriptions", params, options);
4016
+ return this.retiredSurface("/v1/money/billing/subscriptions");
3860
4017
  }
3861
4018
  async cancelSubscription(id, options) {
3862
- return this.post(`/subscriptions/${id}/cancel`, void 0, options);
4019
+ return this.retiredSurface(`/v1/money/billing/subscriptions/${id}/cancel`);
3863
4020
  }
3864
4021
  async resumeSubscription(id, options) {
3865
- return this.post(`/subscriptions/${id}/resume`, void 0, options);
4022
+ return this.retiredSurface(`/v1/money/billing/subscriptions/${id}/resume`);
3866
4023
  }
3867
4024
  async upgradeSubscription(id, data, options) {
3868
- return this.patch(`/subscriptions/${id}/upgrade`, data, options);
4025
+ return this.retiredSurface(`/v1/money/billing/subscriptions/${id}/upgrade`);
3869
4026
  }
3870
4027
  // --------------------------------------------------------------------------
3871
4028
  // Usage
3872
4029
  // --------------------------------------------------------------------------
3873
4030
  async reportUsage(data, options) {
3874
- return this.post("/usage", data, options);
4031
+ return this.retiredSurface("/v1/money/billing/usage");
3875
4032
  }
3876
4033
  async getUsageSummary(options) {
3877
- return this._get("/usage/summary", options);
4034
+ return this.retiredSurface("/v1/money/billing/usage/summary");
3878
4035
  }
3879
4036
  // --------------------------------------------------------------------------
3880
4037
  // Invoices
@@ -3907,7 +4064,7 @@ var BillingService = class extends ServiceModule {
3907
4064
  return this.post(`/connected-accounts/${id}/onboarding-link`, data, options);
3908
4065
  }
3909
4066
  async getAccountBalance(id, options) {
3910
- return this._get(`/connected-accounts/${id}/balance`, options);
4067
+ return this.retiredSurface(`/v1/money/billing/connected-accounts/${id}/balance`);
3911
4068
  }
3912
4069
  async createAccountSession(id, options) {
3913
4070
  return this.post(`/connected-accounts/${id}/account-session`, void 0, options);
@@ -3922,25 +4079,25 @@ var BillingService = class extends ServiceModule {
3922
4079
  // Payments (Marketplace)
3923
4080
  // --------------------------------------------------------------------------
3924
4081
  async createPayment(data, options) {
3925
- return this.post("/payments", data, options);
4082
+ return this.retiredSurface("/v1/money/billing/payments");
3926
4083
  }
3927
4084
  async getPayment(id, options) {
3928
- return this._get(`/payments/${id}`, options);
4085
+ return this.retiredSurface(`/v1/money/billing/payments/${id}`);
3929
4086
  }
3930
4087
  async listPayments(params, options) {
3931
- return this._list("/payments", params, options);
4088
+ return this.retiredSurface("/v1/money/billing/payments");
3932
4089
  }
3933
4090
  // --------------------------------------------------------------------------
3934
4091
  // Refunds
3935
4092
  // --------------------------------------------------------------------------
3936
4093
  async refundPayment(id, data, options) {
3937
- return this.post(`/payments/${id}/refund`, data, options);
4094
+ return this.retiredSurface(`/v1/money/billing/payments/${id}/refund`);
3938
4095
  }
3939
4096
  // --------------------------------------------------------------------------
3940
4097
  // Payouts
3941
4098
  // --------------------------------------------------------------------------
3942
4099
  async getPayoutHistory(accountId, params, options) {
3943
- return this._list(`/connected-accounts/${accountId}/payouts`, params, options);
4100
+ return this.retiredSurface(`/v1/money/billing/connected-accounts/${accountId}/payouts`);
3944
4101
  }
3945
4102
  async getPayoutSchedule(accountId, options) {
3946
4103
  return this._get(`/connected-accounts/${accountId}/payout-schedule`, options);
@@ -3952,13 +4109,10 @@ var BillingService = class extends ServiceModule {
3952
4109
  // Ledger
3953
4110
  // --------------------------------------------------------------------------
3954
4111
  async getTransactions(params, options) {
3955
- return this._list("/transactions", params, options);
4112
+ return this.retiredSurface("/v1/money/billing/transactions");
3956
4113
  }
3957
4114
  async getTransactionSummary(params, options) {
3958
- return this._get(
3959
- this.withQuery("/transactions/summary", params),
3960
- options
3961
- );
4115
+ return this.retiredSurface("/v1/money/billing/transactions/summary");
3962
4116
  }
3963
4117
  // --------------------------------------------------------------------------
3964
4118
  // Setup Sessions
@@ -3970,35 +4124,35 @@ var BillingService = class extends ServiceModule {
3970
4124
  // Connected Account Operations: Products, Prices, Subscriptions, Transfers
3971
4125
  // --------------------------------------------------------------------------
3972
4126
  async createProduct(data, options) {
3973
- return this.post("/products", data, options);
4127
+ return this.retiredSurface("/v1/money/billing/products");
3974
4128
  }
3975
4129
  async createPrice(data, options) {
3976
- return this.post("/prices", data, options);
4130
+ return this.retiredSurface("/v1/money/billing/prices");
3977
4131
  }
3978
4132
  async deactivatePrice(id, options) {
3979
- return this.post(`/prices/${id}/deactivate`, void 0, options);
4133
+ return this.retiredSurface(`/v1/money/billing/prices/${id}/deactivate`);
3980
4134
  }
3981
4135
  async createConnectedSubscription(data, options) {
3982
- return this.post("/connected-subscriptions", data, options);
4136
+ return this.retiredSurface("/v1/money/billing/connected-subscriptions");
3983
4137
  }
3984
4138
  async cancelConnectedSubscription(id, data, options) {
3985
- return this.post(`/connected-subscriptions/${id}/cancel`, data, options);
4139
+ return this.retiredSurface(
4140
+ `/v1/money/billing/connected-subscriptions/${id}/cancel`
4141
+ );
3986
4142
  }
3987
4143
  async listConnectedSubscriptions(params, options) {
3988
- return this._list(
3989
- "/connected-subscriptions",
3990
- params,
3991
- options
4144
+ return this.retiredSurface(
4145
+ "/v1/money/billing/connected-subscriptions"
3992
4146
  );
3993
4147
  }
3994
4148
  async createConnectedSetupIntent(data, options) {
3995
- return this.post("/connected-setup-intents", data, options);
4149
+ return this.retiredSurface("/v1/money/billing/connected-setup-intents");
3996
4150
  }
3997
4151
  async createTransfer(data, options) {
3998
- return this.post("/transfers", data, options);
4152
+ return this.retiredSurface("/v1/money/billing/transfers");
3999
4153
  }
4000
4154
  async syncPaymentStatus(id, options) {
4001
- return this.post(`/payments/${id}/sync`, void 0, options);
4155
+ return this.retiredSurface(`/v1/money/billing/payments/${id}/sync`);
4002
4156
  }
4003
4157
  // --------------------------------------------------------------------------
4004
4158
  // Legacy methods (backward compat)
@@ -5011,7 +5165,7 @@ var SearchService = class extends ServiceModule {
5011
5165
  return this.post("/documents", data);
5012
5166
  }
5013
5167
  };
5014
- var PHOTO_BREAKPOINTS = [150, 320, 640, 1080];
5168
+ var PHOTO_BREAKPOINTS = [36, 150, 320, 640, 1080];
5015
5169
  var PhotoService = class extends ServiceModule {
5016
5170
  constructor() {
5017
5171
  super(...arguments);
@@ -5070,6 +5224,9 @@ var PhotoService = class extends ServiceModule {
5070
5224
  *
5071
5225
  * // Profile avatar at 48px -> snaps to 150px
5072
5226
  * const url = sm.photo.getOptimalUrl(photoId, 48)
5227
+ *
5228
+ * // Tiny avatar at 36px -> exact cache hit on 36px micro-thumbnail
5229
+ * const url = sm.photo.getOptimalUrl(photoId, 36)
5073
5230
  * ```
5074
5231
  */
5075
5232
  getOptimalUrl(photoId, displayWidth, options) {
@@ -5080,6 +5237,13 @@ var PhotoService = class extends ServiceModule {
5080
5237
  const size = PHOTO_BREAKPOINTS.find((bp) => bp >= physicalWidth) ?? PHOTO_BREAKPOINTS[PHOTO_BREAKPOINTS.length - 1];
5081
5238
  return this.getTransformUrl(photoId, { width: size, height: size, fit: "cover" });
5082
5239
  }
5240
+ /**
5241
+ * Get the 36px avatar micro-thumbnail URL for a photo.
5242
+ * Hits the pre-generated 36x36 bicubic-resized cached variant.
5243
+ */
5244
+ getAvatarThumbnailUrl(photoId) {
5245
+ return this.getOptimalUrl(photoId, 36);
5246
+ }
5083
5247
  /**
5084
5248
  * Generate an HTML srcset string for responsive square photo display.
5085
5249
  *
@@ -5951,6 +6115,7 @@ var ScaleMule = class {
5951
6115
  this.video = new VideoService(this._client);
5952
6116
  this.data = new DataService(this._client);
5953
6117
  this.chat = new ChatService(this._client);
6118
+ this.conference = new ConferenceService(this._client);
5954
6119
  this.social = new SocialService(this._client);
5955
6120
  this.referrals = new ReferralsService(this._client);
5956
6121
  this.billing = new BillingService(this._client);
package/dist/index.mjs CHANGED
@@ -1559,6 +1559,52 @@ var AuthService = class extends ServiceModule {
1559
1559
  async me(options) {
1560
1560
  return this._get("/me", options);
1561
1561
  }
1562
+ // --------------------------------------------------------------------------
1563
+ // User directory (customer-scoped)
1564
+ // --------------------------------------------------------------------------
1565
+ //
1566
+ // Search / fetch users within the caller's application. These endpoints are
1567
+ // scoped by the gateway-injected x-app-id header, so when invoked with a
1568
+ // customer API key + user session they will only return users belonging to
1569
+ // the caller's application. They replace the prior pattern of customer apps
1570
+ // reaching for platform admin credentials to hit admin-only user routes.
1571
+ //
1572
+ // DO NOT call these with platform admin credentials from customer-facing
1573
+ // applications. Use the standard customer auth path (API key + user session)
1574
+ // and let the gateway inject x-app-id on your behalf.
1575
+ /**
1576
+ * Search users within the caller's application.
1577
+ *
1578
+ * Results are automatically scoped to the caller's application via the
1579
+ * x-app-id header injected by the gateway. Server-side page size is fixed
1580
+ * at 50 (the `per_page` query param is not honored upstream).
1581
+ *
1582
+ * @example
1583
+ * const res = await sm.auth.searchUsers({ search: 'alice' });
1584
+ * res.data?.users.forEach(u => console.log(u.email));
1585
+ */
1586
+ async searchUsers(params, options) {
1587
+ const query = {};
1588
+ if (params?.search !== void 0) query.search = params.search;
1589
+ if (params?.status !== void 0) query.status = params.status;
1590
+ if (params?.email_verified !== void 0) {
1591
+ query.email_verified = params.email_verified ? "true" : "false";
1592
+ }
1593
+ if (params?.phone_verified !== void 0) {
1594
+ query.phone_verified = params.phone_verified ? "true" : "false";
1595
+ }
1596
+ if (params?.page !== void 0) query.page = params.page;
1597
+ return this._get(this.withQuery("/users", query), options);
1598
+ }
1599
+ /**
1600
+ * Fetch a single user by ID within the caller's application.
1601
+ *
1602
+ * Returns 404 if the user is not in the caller's application — cross-tenant
1603
+ * reads are blocked at the gateway via the x-app-id header scope.
1604
+ */
1605
+ async getUser(userId, options) {
1606
+ return this._get(`/users/${encodeURIComponent(userId)}`, options);
1607
+ }
1562
1608
  /** Refresh the session. Alias: refreshToken() */
1563
1609
  async refreshSession(data, options) {
1564
1610
  return this.post("/refresh", data ?? {}, options);
@@ -2744,7 +2790,10 @@ var StorageService = class extends ServiceModule {
2744
2790
  const stallTimeout = DEFAULT_STALL_TIMEOUT_MS;
2745
2791
  const controller = new AbortController();
2746
2792
  let parentSignalCleanup;
2747
- const combinedSignal = signal ? AbortSignal.any?.([signal, controller.signal]) ?? (() => {
2793
+ const combinedSignal = signal ? AbortSignal.any?.([
2794
+ signal,
2795
+ controller.signal
2796
+ ]) ?? (() => {
2748
2797
  const onAbort = () => controller.abort();
2749
2798
  signal.addEventListener("abort", onAbort, { once: true });
2750
2799
  parentSignalCleanup = () => signal.removeEventListener("abort", onAbort);
@@ -2925,7 +2974,10 @@ var StorageService = class extends ServiceModule {
2925
2974
  }
2926
2975
  const controller = new AbortController();
2927
2976
  let partSignalCleanup;
2928
- const combinedSignal = signal ? AbortSignal.any?.([signal, controller.signal]) ?? (() => {
2977
+ const combinedSignal = signal ? AbortSignal.any?.([
2978
+ signal,
2979
+ controller.signal
2980
+ ]) ?? (() => {
2929
2981
  const onAbort = () => controller.abort();
2930
2982
  signal.addEventListener("abort", onAbort, { once: true });
2931
2983
  partSignalCleanup = () => signal.removeEventListener("abort", onAbort);
@@ -3089,6 +3141,7 @@ var RealtimeService = class extends ServiceModule {
3089
3141
  super(...arguments);
3090
3142
  this.basePath = "/v1/realtime";
3091
3143
  this.ws = null;
3144
+ this.usedTicketAuth = false;
3092
3145
  this.subscriptions = /* @__PURE__ */ new Map();
3093
3146
  this.presenceCallbacks = /* @__PURE__ */ new Map();
3094
3147
  this.statusCallbacks = /* @__PURE__ */ new Set();
@@ -3217,10 +3270,31 @@ var RealtimeService = class extends ServiceModule {
3217
3270
  // --------------------------------------------------------------------------
3218
3271
  connect() {
3219
3272
  if (this._status === "connecting" || this._status === "connected") return;
3220
- const baseUrl = this.client.getBaseUrl();
3221
- const wsUrl = baseUrl.replace(/^http/, "ws") + "/v1/realtime/ws";
3222
3273
  this.setStatus(this.reconnectAttempt > 0 ? "reconnecting" : "connecting");
3274
+ this.fetchTicketAndConnect();
3275
+ }
3276
+ async fetchTicketAndConnect() {
3277
+ const baseUrl = this.client.getBaseUrl();
3223
3278
  try {
3279
+ const headers = { "Content-Type": "application/json" };
3280
+ const apiKey = this.client.getApiKey();
3281
+ if (apiKey) headers["x-api-key"] = apiKey;
3282
+ const token = this.client.getSessionToken();
3283
+ if (token) headers["Authorization"] = `Bearer ${token}`;
3284
+ const ticketRes = await fetch(`${baseUrl}/v1/realtime/ws/ticket`, {
3285
+ method: "POST",
3286
+ headers
3287
+ });
3288
+ let wsUrl;
3289
+ if (ticketRes.ok) {
3290
+ const ticketData = await ticketRes.json();
3291
+ const ticket = ticketData.ticket;
3292
+ wsUrl = baseUrl.replace(/^http/, "ws") + `/v1/realtime/ws?ticket=${encodeURIComponent(ticket)}`;
3293
+ this.usedTicketAuth = true;
3294
+ } else {
3295
+ wsUrl = baseUrl.replace(/^http/, "ws") + "/v1/realtime/ws";
3296
+ this.usedTicketAuth = false;
3297
+ }
3224
3298
  this.ws = new WebSocket(wsUrl);
3225
3299
  } catch {
3226
3300
  this.scheduleReconnect();
@@ -3228,8 +3302,21 @@ var RealtimeService = class extends ServiceModule {
3228
3302
  }
3229
3303
  this.ws.onopen = () => {
3230
3304
  this.reconnectAttempt = 0;
3231
- this.authenticate();
3305
+ if (!this.usedTicketAuth) {
3306
+ this.authenticate();
3307
+ }
3232
3308
  this.startHeartbeat();
3309
+ if (this.usedTicketAuth) {
3310
+ setTimeout(() => {
3311
+ if (!this.authenticated) {
3312
+ this.authenticated = true;
3313
+ this.setStatus("connected");
3314
+ for (const channel of this.subscriptions.keys()) {
3315
+ this.sendWs({ type: "subscribe", channel });
3316
+ }
3317
+ }
3318
+ }, 2e3);
3319
+ }
3233
3320
  };
3234
3321
  this.ws.onmessage = (event) => {
3235
3322
  try {
@@ -3681,6 +3768,9 @@ var ChatService = class extends ServiceModule {
3681
3768
  async sendMessage(conversationId, data, options) {
3682
3769
  return this.post(`/conversations/${conversationId}/messages`, data, options);
3683
3770
  }
3771
+ async getThreadReplies(messageId, params, requestOptions) {
3772
+ return this._get(this.withQuery(`/messages/${messageId}/replies`, params), requestOptions);
3773
+ }
3684
3774
  async getMessages(conversationId, options, requestOptions) {
3685
3775
  return this._get(
3686
3776
  this.withQuery(`/conversations/${conversationId}/messages`, options),
@@ -3716,6 +3806,66 @@ var ChatService = class extends ServiceModule {
3716
3806
  return this.createConversation(data);
3717
3807
  }
3718
3808
  };
3809
+ var ConferenceService = class extends ServiceModule {
3810
+ constructor() {
3811
+ super(...arguments);
3812
+ this.basePath = "/v1/conference";
3813
+ }
3814
+ // --------------------------------------------------------------------------
3815
+ // Call Lifecycle
3816
+ // --------------------------------------------------------------------------
3817
+ async createCall(data, options) {
3818
+ return this.post("/calls", data, options);
3819
+ }
3820
+ async getCall(callId, options) {
3821
+ return this._get(`/calls/${callId}`, options);
3822
+ }
3823
+ async listCalls(params, options) {
3824
+ return this._get(this.withQuery("/calls", params), options);
3825
+ }
3826
+ async endCall(callId, options) {
3827
+ return this.post(`/calls/${callId}/end`, void 0, options);
3828
+ }
3829
+ // --------------------------------------------------------------------------
3830
+ // Participants
3831
+ // --------------------------------------------------------------------------
3832
+ async joinCall(callId, options) {
3833
+ return this.post(`/calls/${callId}/join`, void 0, options);
3834
+ }
3835
+ async leaveCall(callId, options) {
3836
+ return this.post(`/calls/${callId}/leave`, void 0, options);
3837
+ }
3838
+ async listParticipants(callId, options) {
3839
+ return this._get(`/calls/${callId}/participants`, options);
3840
+ }
3841
+ // --------------------------------------------------------------------------
3842
+ // Recording
3843
+ // --------------------------------------------------------------------------
3844
+ async startRecording(callId, options) {
3845
+ return this.post(`/calls/${callId}/recording/start`, void 0, options);
3846
+ }
3847
+ async stopRecording(callId, options) {
3848
+ return this.post(`/calls/${callId}/recording/stop`, void 0, options);
3849
+ }
3850
+ async consentToRecording(callId, options) {
3851
+ return this.post(`/calls/${callId}/recording/consent`, void 0, options);
3852
+ }
3853
+ // --------------------------------------------------------------------------
3854
+ // Settings
3855
+ // --------------------------------------------------------------------------
3856
+ async getSettings(options) {
3857
+ return this._get("/settings", options);
3858
+ }
3859
+ async updateSettings(data, options) {
3860
+ return this.put("/settings", data, options);
3861
+ }
3862
+ // --------------------------------------------------------------------------
3863
+ // Stats
3864
+ // --------------------------------------------------------------------------
3865
+ async submitStats(callId, stats, options) {
3866
+ return this.post(`/calls/${callId}/stats`, stats, options);
3867
+ }
3868
+ };
3719
3869
  var SocialService = class extends ServiceModule {
3720
3870
  constructor() {
3721
3871
  super(...arguments);
@@ -3837,7 +3987,14 @@ var ReferralsService = class extends ServiceModule {
3837
3987
  var BillingService = class extends ServiceModule {
3838
3988
  constructor() {
3839
3989
  super(...arguments);
3840
- this.basePath = "/v1/billing";
3990
+ this.basePath = "/v1/money/billing";
3991
+ }
3992
+ retiredSurface(route) {
3993
+ return Promise.reject(
3994
+ new Error(
3995
+ `${route} was retired after the money-services cutover. Use the dedicated money services instead of BillingService for this operation.`
3996
+ )
3997
+ );
3841
3998
  }
3842
3999
  // --------------------------------------------------------------------------
3843
4000
  // Customers
@@ -3852,28 +4009,28 @@ var BillingService = class extends ServiceModule {
3852
4009
  // Subscriptions
3853
4010
  // --------------------------------------------------------------------------
3854
4011
  async subscribe(data, options) {
3855
- return this.post("/subscriptions", data, options);
4012
+ return this.retiredSurface("/v1/money/billing/subscriptions");
3856
4013
  }
3857
4014
  async listSubscriptions(params, options) {
3858
- return this._list("/subscriptions", params, options);
4015
+ return this.retiredSurface("/v1/money/billing/subscriptions");
3859
4016
  }
3860
4017
  async cancelSubscription(id, options) {
3861
- return this.post(`/subscriptions/${id}/cancel`, void 0, options);
4018
+ return this.retiredSurface(`/v1/money/billing/subscriptions/${id}/cancel`);
3862
4019
  }
3863
4020
  async resumeSubscription(id, options) {
3864
- return this.post(`/subscriptions/${id}/resume`, void 0, options);
4021
+ return this.retiredSurface(`/v1/money/billing/subscriptions/${id}/resume`);
3865
4022
  }
3866
4023
  async upgradeSubscription(id, data, options) {
3867
- return this.patch(`/subscriptions/${id}/upgrade`, data, options);
4024
+ return this.retiredSurface(`/v1/money/billing/subscriptions/${id}/upgrade`);
3868
4025
  }
3869
4026
  // --------------------------------------------------------------------------
3870
4027
  // Usage
3871
4028
  // --------------------------------------------------------------------------
3872
4029
  async reportUsage(data, options) {
3873
- return this.post("/usage", data, options);
4030
+ return this.retiredSurface("/v1/money/billing/usage");
3874
4031
  }
3875
4032
  async getUsageSummary(options) {
3876
- return this._get("/usage/summary", options);
4033
+ return this.retiredSurface("/v1/money/billing/usage/summary");
3877
4034
  }
3878
4035
  // --------------------------------------------------------------------------
3879
4036
  // Invoices
@@ -3906,7 +4063,7 @@ var BillingService = class extends ServiceModule {
3906
4063
  return this.post(`/connected-accounts/${id}/onboarding-link`, data, options);
3907
4064
  }
3908
4065
  async getAccountBalance(id, options) {
3909
- return this._get(`/connected-accounts/${id}/balance`, options);
4066
+ return this.retiredSurface(`/v1/money/billing/connected-accounts/${id}/balance`);
3910
4067
  }
3911
4068
  async createAccountSession(id, options) {
3912
4069
  return this.post(`/connected-accounts/${id}/account-session`, void 0, options);
@@ -3921,25 +4078,25 @@ var BillingService = class extends ServiceModule {
3921
4078
  // Payments (Marketplace)
3922
4079
  // --------------------------------------------------------------------------
3923
4080
  async createPayment(data, options) {
3924
- return this.post("/payments", data, options);
4081
+ return this.retiredSurface("/v1/money/billing/payments");
3925
4082
  }
3926
4083
  async getPayment(id, options) {
3927
- return this._get(`/payments/${id}`, options);
4084
+ return this.retiredSurface(`/v1/money/billing/payments/${id}`);
3928
4085
  }
3929
4086
  async listPayments(params, options) {
3930
- return this._list("/payments", params, options);
4087
+ return this.retiredSurface("/v1/money/billing/payments");
3931
4088
  }
3932
4089
  // --------------------------------------------------------------------------
3933
4090
  // Refunds
3934
4091
  // --------------------------------------------------------------------------
3935
4092
  async refundPayment(id, data, options) {
3936
- return this.post(`/payments/${id}/refund`, data, options);
4093
+ return this.retiredSurface(`/v1/money/billing/payments/${id}/refund`);
3937
4094
  }
3938
4095
  // --------------------------------------------------------------------------
3939
4096
  // Payouts
3940
4097
  // --------------------------------------------------------------------------
3941
4098
  async getPayoutHistory(accountId, params, options) {
3942
- return this._list(`/connected-accounts/${accountId}/payouts`, params, options);
4099
+ return this.retiredSurface(`/v1/money/billing/connected-accounts/${accountId}/payouts`);
3943
4100
  }
3944
4101
  async getPayoutSchedule(accountId, options) {
3945
4102
  return this._get(`/connected-accounts/${accountId}/payout-schedule`, options);
@@ -3951,13 +4108,10 @@ var BillingService = class extends ServiceModule {
3951
4108
  // Ledger
3952
4109
  // --------------------------------------------------------------------------
3953
4110
  async getTransactions(params, options) {
3954
- return this._list("/transactions", params, options);
4111
+ return this.retiredSurface("/v1/money/billing/transactions");
3955
4112
  }
3956
4113
  async getTransactionSummary(params, options) {
3957
- return this._get(
3958
- this.withQuery("/transactions/summary", params),
3959
- options
3960
- );
4114
+ return this.retiredSurface("/v1/money/billing/transactions/summary");
3961
4115
  }
3962
4116
  // --------------------------------------------------------------------------
3963
4117
  // Setup Sessions
@@ -3969,35 +4123,35 @@ var BillingService = class extends ServiceModule {
3969
4123
  // Connected Account Operations: Products, Prices, Subscriptions, Transfers
3970
4124
  // --------------------------------------------------------------------------
3971
4125
  async createProduct(data, options) {
3972
- return this.post("/products", data, options);
4126
+ return this.retiredSurface("/v1/money/billing/products");
3973
4127
  }
3974
4128
  async createPrice(data, options) {
3975
- return this.post("/prices", data, options);
4129
+ return this.retiredSurface("/v1/money/billing/prices");
3976
4130
  }
3977
4131
  async deactivatePrice(id, options) {
3978
- return this.post(`/prices/${id}/deactivate`, void 0, options);
4132
+ return this.retiredSurface(`/v1/money/billing/prices/${id}/deactivate`);
3979
4133
  }
3980
4134
  async createConnectedSubscription(data, options) {
3981
- return this.post("/connected-subscriptions", data, options);
4135
+ return this.retiredSurface("/v1/money/billing/connected-subscriptions");
3982
4136
  }
3983
4137
  async cancelConnectedSubscription(id, data, options) {
3984
- return this.post(`/connected-subscriptions/${id}/cancel`, data, options);
4138
+ return this.retiredSurface(
4139
+ `/v1/money/billing/connected-subscriptions/${id}/cancel`
4140
+ );
3985
4141
  }
3986
4142
  async listConnectedSubscriptions(params, options) {
3987
- return this._list(
3988
- "/connected-subscriptions",
3989
- params,
3990
- options
4143
+ return this.retiredSurface(
4144
+ "/v1/money/billing/connected-subscriptions"
3991
4145
  );
3992
4146
  }
3993
4147
  async createConnectedSetupIntent(data, options) {
3994
- return this.post("/connected-setup-intents", data, options);
4148
+ return this.retiredSurface("/v1/money/billing/connected-setup-intents");
3995
4149
  }
3996
4150
  async createTransfer(data, options) {
3997
- return this.post("/transfers", data, options);
4151
+ return this.retiredSurface("/v1/money/billing/transfers");
3998
4152
  }
3999
4153
  async syncPaymentStatus(id, options) {
4000
- return this.post(`/payments/${id}/sync`, void 0, options);
4154
+ return this.retiredSurface(`/v1/money/billing/payments/${id}/sync`);
4001
4155
  }
4002
4156
  // --------------------------------------------------------------------------
4003
4157
  // Legacy methods (backward compat)
@@ -5010,7 +5164,7 @@ var SearchService = class extends ServiceModule {
5010
5164
  return this.post("/documents", data);
5011
5165
  }
5012
5166
  };
5013
- var PHOTO_BREAKPOINTS = [150, 320, 640, 1080];
5167
+ var PHOTO_BREAKPOINTS = [36, 150, 320, 640, 1080];
5014
5168
  var PhotoService = class extends ServiceModule {
5015
5169
  constructor() {
5016
5170
  super(...arguments);
@@ -5069,6 +5223,9 @@ var PhotoService = class extends ServiceModule {
5069
5223
  *
5070
5224
  * // Profile avatar at 48px -> snaps to 150px
5071
5225
  * const url = sm.photo.getOptimalUrl(photoId, 48)
5226
+ *
5227
+ * // Tiny avatar at 36px -> exact cache hit on 36px micro-thumbnail
5228
+ * const url = sm.photo.getOptimalUrl(photoId, 36)
5072
5229
  * ```
5073
5230
  */
5074
5231
  getOptimalUrl(photoId, displayWidth, options) {
@@ -5079,6 +5236,13 @@ var PhotoService = class extends ServiceModule {
5079
5236
  const size = PHOTO_BREAKPOINTS.find((bp) => bp >= physicalWidth) ?? PHOTO_BREAKPOINTS[PHOTO_BREAKPOINTS.length - 1];
5080
5237
  return this.getTransformUrl(photoId, { width: size, height: size, fit: "cover" });
5081
5238
  }
5239
+ /**
5240
+ * Get the 36px avatar micro-thumbnail URL for a photo.
5241
+ * Hits the pre-generated 36x36 bicubic-resized cached variant.
5242
+ */
5243
+ getAvatarThumbnailUrl(photoId) {
5244
+ return this.getOptimalUrl(photoId, 36);
5245
+ }
5082
5246
  /**
5083
5247
  * Generate an HTML srcset string for responsive square photo display.
5084
5248
  *
@@ -5950,6 +6114,7 @@ var ScaleMule = class {
5950
6114
  this.video = new VideoService(this._client);
5951
6115
  this.data = new DataService(this._client);
5952
6116
  this.chat = new ChatService(this._client);
6117
+ this.conference = new ConferenceService(this._client);
5953
6118
  this.social = new SocialService(this._client);
5954
6119
  this.referrals = new ReferralsService(this._client);
5955
6120
  this.billing = new BillingService(this._client);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalemule/nextjs",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "description": "ScaleMule SDK for Next.js applications - authentication, storage, and user management",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "dependencies": {
55
55
  "@scalemule/money": "^0.0.1",
56
- "@scalemule/sdk": "^0.0.29"
56
+ "@scalemule/sdk": "^0.0.36"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "next": ">=14.0.0",