@whooshbang/sdk 3.1.0 → 4.0.0

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/client.js CHANGED
@@ -568,10 +568,11 @@ export class WhooshBangClient {
568
568
  strictResponse: true,
569
569
  });
570
570
  }
571
- async sendOperatorMessage(projectId, environmentId, request, options) {
571
+ async sendOperatorMessage(projectId, environmentId, request, options = {}) {
572
572
  const operation = "sendOperatorMessage";
573
573
  assertInput(operation, request, validateCreateOperatorMessageRequest);
574
- assertIdempotencyKey(operation, options.idempotencyKey);
574
+ if (options.idempotencyKey !== undefined)
575
+ assertIdempotencyKey(operation, options.idempotencyKey);
575
576
  return this.#request({
576
577
  method: "POST",
577
578
  operation,
@@ -584,10 +585,11 @@ export class WhooshBangClient {
584
585
  body: request,
585
586
  });
586
587
  }
587
- async broadcastOperators(projectId, environmentId, request, options) {
588
+ async broadcastOperators(projectId, environmentId, request, options = {}) {
588
589
  const operation = "broadcastOperators";
589
590
  assertInput(operation, request, validateCreateGroupBroadcastRequest);
590
- assertIdempotencyKey(operation, options.idempotencyKey);
591
+ if (options.idempotencyKey !== undefined)
592
+ assertIdempotencyKey(operation, options.idempotencyKey);
591
593
  return this.#request({
592
594
  method: "POST",
593
595
  operation,
@@ -638,10 +640,11 @@ export class WhooshBangClient {
638
640
  body: request,
639
641
  });
640
642
  }
641
- async connectOperatorChannel(projectId, environmentId, request, options) {
643
+ async connectOperatorChannel(projectId, environmentId, request, options = {}) {
642
644
  const operation = "connectOperatorChannel";
643
645
  assertInput(operation, request, validateOperatorConnectRequest);
644
- assertIdempotencyKey(operation, options.idempotencyKey);
646
+ if (options.idempotencyKey !== undefined)
647
+ assertIdempotencyKey(operation, options.idempotencyKey);
645
648
  return this.#request({
646
649
  method: "POST",
647
650
  operation,
@@ -659,7 +662,7 @@ export class WhooshBangClient {
659
662
  #fetch;
660
663
  #logger;
661
664
  constructor(options) {
662
- this.#baseUrl = normalizeBaseUrl(options.baseUrl);
665
+ this.#baseUrl = normalizeBaseUrl(options.baseUrl ?? "https://api.whooshbang.com");
663
666
  validateCredential(options.credential);
664
667
  this.#credential = options.credential;
665
668
  const runtimeFetch = options.fetch ?? globalThis.fetch;
@@ -689,10 +692,11 @@ export class WhooshBangClient {
689
692
  validator: validateBillingProjectSlots,
690
693
  });
691
694
  }
692
- async assignBillingProjectSlots(request, options) {
695
+ async assignBillingProjectSlots(request, options = {}) {
693
696
  const operation = "assignBillingProjectSlots";
694
697
  assertInput(operation, request, validateAssignBillingProjectSlotsRequest);
695
- assertIdempotencyKey(operation, options.idempotencyKey);
698
+ if (options.idempotencyKey !== undefined)
699
+ assertIdempotencyKey(operation, options.idempotencyKey);
696
700
  return this.#request({
697
701
  method: "PUT",
698
702
  operation,
@@ -714,10 +718,11 @@ export class WhooshBangClient {
714
718
  validator: validateBillingPromotions,
715
719
  });
716
720
  }
717
- async redeemBillingPromotion(request, options) {
721
+ async redeemBillingPromotion(request, options = {}) {
718
722
  const operation = "redeemBillingPromotion";
719
723
  assertInput(operation, request, validateRedeemBillingPromotionRequest);
720
- assertIdempotencyKey(operation, options.idempotencyKey);
724
+ if (options.idempotencyKey !== undefined)
725
+ assertIdempotencyKey(operation, options.idempotencyKey);
721
726
  return this.#request({
722
727
  method: "POST",
723
728
  operation,
@@ -729,10 +734,11 @@ export class WhooshBangClient {
729
734
  validator: validateBillingPromotion,
730
735
  });
731
736
  }
732
- async createSubscriptionChange(request, options) {
737
+ async createSubscriptionChange(request, options = {}) {
733
738
  const operation = "createSubscriptionChange";
734
739
  assertInput(operation, request, validateSubscriptionSelection);
735
- assertIdempotencyKey(operation, options.idempotencyKey);
740
+ if (options.idempotencyKey !== undefined)
741
+ assertIdempotencyKey(operation, options.idempotencyKey);
736
742
  return this.#request({
737
743
  body: request,
738
744
  idempotencyKey: options.idempotencyKey,
@@ -850,7 +856,8 @@ export class WhooshBangClient {
850
856
  * enters the card in the browser; nothing is charged. */
851
857
  async createCardSetup(options) {
852
858
  const operation = "createCardSetup";
853
- assertIdempotencyKey(operation, options.idempotencyKey);
859
+ if (options.idempotencyKey !== undefined)
860
+ assertIdempotencyKey(operation, options.idempotencyKey);
854
861
  return this.#request({
855
862
  method: "POST",
856
863
  operation,
@@ -874,10 +881,11 @@ export class WhooshBangClient {
874
881
  }
875
882
  /** Charges the default card for one credit pack. Credit is granted only
876
883
  * after a verified payment; a retry with the same key never charges twice. */
877
- async createCreditPurchase(request, options) {
884
+ async createCreditPurchase(request, options = {}) {
878
885
  const operation = "createCreditPurchase";
879
886
  assertInput(operation, request, validateCreateCreditPurchaseRequest);
880
- assertIdempotencyKey(operation, options.idempotencyKey);
887
+ if (options.idempotencyKey !== undefined)
888
+ assertIdempotencyKey(operation, options.idempotencyKey);
881
889
  return this.#request({
882
890
  body: request,
883
891
  idempotencyKey: options.idempotencyKey,
@@ -1177,7 +1185,7 @@ export class WhooshBangClient {
1177
1185
  validator: validateProjectCollection,
1178
1186
  });
1179
1187
  }
1180
- async createProject(request, options) {
1188
+ async createProject(request, options = {}) {
1181
1189
  assertInput("createProject", request, validateCreateProjectRequest);
1182
1190
  return this.#request({
1183
1191
  body: request,
@@ -1303,7 +1311,7 @@ export class WhooshBangClient {
1303
1311
  validator: validateRecipientBrandLogoUpload,
1304
1312
  });
1305
1313
  }
1306
- async uploadNotificationImageAsset(projectId, environmentId, image, options) {
1314
+ async uploadNotificationImageAsset(projectId, environmentId, image, options = {}) {
1307
1315
  const operation = "uploadNotificationImageAsset";
1308
1316
  if (image instanceof Blob && image.type.toLowerCase() !== "image/png") {
1309
1317
  throw validationError(operation, "image", "invalid_media_type", "image must be an image/png Blob or PNG Uint8Array.");
@@ -1417,7 +1425,7 @@ export class WhooshBangClient {
1417
1425
  strictResponse: true,
1418
1426
  });
1419
1427
  }
1420
- async createRecipientSession(request, options) {
1428
+ async createRecipientSession(request, options = {}) {
1421
1429
  const operation = "createRecipientSession";
1422
1430
  assertInput(operation, request, validateCreateRecipientSessionRequest);
1423
1431
  return this.#request({
@@ -1462,14 +1470,14 @@ export class WhooshBangClient {
1462
1470
  * other. A difference between them would be a bug, not a feature, so there
1463
1471
  * is nowhere for one to appear.
1464
1472
  */
1465
- async assertEmailConsent(request, options) {
1473
+ async assertEmailConsent(request, options = {}) {
1466
1474
  return this.#assertEmailConsent("assertEmailConsent", "v1", request, options);
1467
1475
  }
1468
- async assertEmailConsentInEnvironment(projectId, environmentId, request, options) {
1476
+ async assertEmailConsentInEnvironment(projectId, environmentId, request, options = {}) {
1469
1477
  const operation = "assertEmailConsentInEnvironment";
1470
1478
  return this.#assertEmailConsent(operation, environmentRoot(operation, projectId, environmentId), request, options);
1471
1479
  }
1472
- async #assertEmailConsent(operation, root, request, options) {
1480
+ async #assertEmailConsent(operation, root, request, options = {}) {
1473
1481
  assertInput(operation, request, validateAssertEmailConsentRequest);
1474
1482
  return this.#request({
1475
1483
  body: request,
@@ -1482,10 +1490,10 @@ export class WhooshBangClient {
1482
1490
  validator: validateBindingSummary,
1483
1491
  });
1484
1492
  }
1485
- async createSubscriber(request, options) {
1493
+ async createSubscriber(request, options = {}) {
1486
1494
  return this.#createSubscriber("createSubscriber", "v1", request, options);
1487
1495
  }
1488
- async createSubscriberInEnvironment(projectId, environmentId, request, options) {
1496
+ async createSubscriberInEnvironment(projectId, environmentId, request, options = {}) {
1489
1497
  const operation = "createSubscriberInEnvironment";
1490
1498
  return this.#createSubscriber(operation, environmentRoot(operation, projectId, environmentId), request, options);
1491
1499
  }
@@ -1525,10 +1533,10 @@ export class WhooshBangClient {
1525
1533
  const operation = "listSubscriberGroupsInEnvironment";
1526
1534
  return this.#listSubscriberGroups(operation, environmentRoot(operation, projectId, environmentId), options);
1527
1535
  }
1528
- async createSubscriberGroup(request, options) {
1536
+ async createSubscriberGroup(request, options = {}) {
1529
1537
  return this.#createSubscriberGroup("createSubscriberGroup", "v1", request, options);
1530
1538
  }
1531
- async createSubscriberGroupInEnvironment(projectId, environmentId, request, options) {
1539
+ async createSubscriberGroupInEnvironment(projectId, environmentId, request, options = {}) {
1532
1540
  const operation = "createSubscriberGroupInEnvironment";
1533
1541
  return this.#createSubscriberGroup(operation, environmentRoot(operation, projectId, environmentId), request, options);
1534
1542
  }
@@ -1581,10 +1589,10 @@ export class WhooshBangClient {
1581
1589
  const operation = "removeSubscriberGroupMemberInEnvironment";
1582
1590
  return this.#removeSubscriberGroupMember(operation, environmentRoot(operation, projectId, environmentId), groupKey, subscriberId, options);
1583
1591
  }
1584
- async createGroupBroadcast(groupKey, request, options) {
1592
+ async createGroupBroadcast(groupKey, request, options = {}) {
1585
1593
  return this.#createGroupBroadcast("createGroupBroadcast", "v1", groupKey, request, options);
1586
1594
  }
1587
- async createGroupBroadcastInEnvironment(projectId, environmentId, groupKey, request, options) {
1595
+ async createGroupBroadcastInEnvironment(projectId, environmentId, groupKey, request, options = {}) {
1588
1596
  const operation = "createGroupBroadcastInEnvironment";
1589
1597
  return this.#createGroupBroadcast(operation, environmentRoot(operation, projectId, environmentId), groupKey, request, options);
1590
1598
  }
@@ -1707,7 +1715,7 @@ export class WhooshBangClient {
1707
1715
  validator: validateApiCredential,
1708
1716
  });
1709
1717
  }
1710
- async createSubscriptionLink(request, options) {
1718
+ async createSubscriptionLink(request, options = {}) {
1711
1719
  assertInput("createSubscriptionLink", request, validateCreateSubscriptionLinkRequest);
1712
1720
  return this.#request({
1713
1721
  body: request,
@@ -1731,7 +1739,7 @@ export class WhooshBangClient {
1731
1739
  validator: validateSubscriptionLink,
1732
1740
  });
1733
1741
  }
1734
- async cancelSubscriptionLink(subscriptionLinkId, options) {
1742
+ async cancelSubscriptionLink(subscriptionLinkId, options = {}) {
1735
1743
  const operation = "cancelSubscriptionLink";
1736
1744
  let link;
1737
1745
  try {
@@ -1770,7 +1778,7 @@ export class WhooshBangClient {
1770
1778
  * failure: a person can revoke their channel at any time, and the branch
1771
1779
  * a caller takes is to invite them again.
1772
1780
  */
1773
- async createMessage(request, options) {
1781
+ async createMessage(request, options = {}) {
1774
1782
  assertInput("createMessage", request, validateCreateMessageRequest);
1775
1783
  return messageCreation(() => this.#request({
1776
1784
  body: request,
@@ -1927,7 +1935,7 @@ export class WhooshBangClient {
1927
1935
  * `idempotencyKey` replays the send — the service returns the original
1928
1936
  * message and asks nothing twice — and resumes the wait.
1929
1937
  */
1930
- async ask(request, options) {
1938
+ async ask(request, options = {}) {
1931
1939
  const operation = "ask";
1932
1940
  assertInput(operation, request, validateCreateMessageRequest);
1933
1941
  if (request.interaction === undefined) {
@@ -1960,7 +1968,7 @@ export class WhooshBangClient {
1960
1968
  * `sending`, `provider_accepted`, or `outcome_unknown` returns it with
1961
1969
  * `cancellation_effective: false` and never claims provider-side deletion.
1962
1970
  */
1963
- async cancelMessage(messageId, options) {
1971
+ async cancelMessage(messageId, options = {}) {
1964
1972
  const operation = "cancelMessage";
1965
1973
  const message = await this.#request({
1966
1974
  idempotencyKey: options.idempotencyKey,
@@ -1989,6 +1997,159 @@ export class WhooshBangClient {
1989
1997
  validator: validateProviderCapabilitiesCollection,
1990
1998
  });
1991
1999
  }
2000
+ /** Project-credential routes derive project and environment from the bearer. */
2001
+ async listCustomerEndpointsWithCredential(options = {}) {
2002
+ const operation = "listCustomerEndpointsWithCredential";
2003
+ return this.#request({
2004
+ method: "GET",
2005
+ operation,
2006
+ options,
2007
+ path: "/v1/customer-endpoints" +
2008
+ listPageQuery(operation, options, "customer endpoint"),
2009
+ sideEffect: false,
2010
+ validator: validateCustomerEndpointCollection,
2011
+ });
2012
+ }
2013
+ async createCustomerEndpointWithCredential(request, options = {}) {
2014
+ const operation = "createCustomerEndpointWithCredential";
2015
+ assertInput(operation, request, validateCreateCustomerEndpointRequest);
2016
+ return this.#request({
2017
+ body: request,
2018
+ idempotencyKey: options.idempotencyKey,
2019
+ method: "POST",
2020
+ operation,
2021
+ options,
2022
+ path: "/v1/customer-endpoints",
2023
+ sideEffect: true,
2024
+ validator: validateCustomerEndpointMutationResult,
2025
+ });
2026
+ }
2027
+ async getCustomerEndpointWithCredential(endpointId, options = {}) {
2028
+ const operation = "getCustomerEndpointWithCredential";
2029
+ return this.#request({
2030
+ method: "GET",
2031
+ operation,
2032
+ options,
2033
+ path: `/v1/customer-endpoints/${pathSegment(operation, endpointId, "endpointId")}`,
2034
+ sideEffect: false,
2035
+ validator: validateCustomerEndpoint,
2036
+ });
2037
+ }
2038
+ async verifyCustomerEndpointWithCredential(endpointId, options = {}) {
2039
+ const operation = "verifyCustomerEndpointWithCredential";
2040
+ return this.#request({
2041
+ method: "POST",
2042
+ operation,
2043
+ options,
2044
+ path: `/v1/customer-endpoints/${pathSegment(operation, endpointId, "endpointId")}/verify`,
2045
+ sideEffect: true,
2046
+ validator: validateCustomerEndpoint,
2047
+ });
2048
+ }
2049
+ async rotateCustomerEndpointWithCredential(endpointId, request, options = {}) {
2050
+ const operation = "rotateCustomerEndpointWithCredential";
2051
+ assertInput(operation, request, validateRotateCustomerEndpointRequest);
2052
+ return this.#request({
2053
+ body: request,
2054
+ idempotencyKey: options.idempotencyKey,
2055
+ method: "POST",
2056
+ operation,
2057
+ options,
2058
+ path: `/v1/customer-endpoints/${pathSegment(operation, endpointId, "endpointId")}/rotate`,
2059
+ sideEffect: true,
2060
+ validator: validateCustomerEndpointMutationResult,
2061
+ });
2062
+ }
2063
+ async listCustomerEndpointAttemptsWithCredential(endpointId, options = {}) {
2064
+ const operation = "listCustomerEndpointAttemptsWithCredential";
2065
+ return this.#request({
2066
+ method: "GET",
2067
+ operation,
2068
+ options,
2069
+ path: `/v1/customer-endpoints/${pathSegment(operation, endpointId, "endpointId")}/attempts${listPageQuery(operation, options, "endpoint attempt")}`,
2070
+ sideEffect: false,
2071
+ validator: validateCustomerEndpointAttemptCollection,
2072
+ });
2073
+ }
2074
+ async sendOperatorMessageWithCredential(request, options = {}) {
2075
+ const operation = "sendOperatorMessageWithCredential";
2076
+ assertInput(operation, request, validateCreateOperatorMessageRequest);
2077
+ if (options.idempotencyKey !== undefined)
2078
+ assertIdempotencyKey(operation, options.idempotencyKey);
2079
+ return this.#request({
2080
+ method: "POST",
2081
+ operation,
2082
+ options,
2083
+ idempotencyKey: options.idempotencyKey,
2084
+ sideEffect: true,
2085
+ path: "/v1/operator-messages",
2086
+ validator: validateOperatorMessageResult,
2087
+ strictResponse: true,
2088
+ body: request,
2089
+ });
2090
+ }
2091
+ async broadcastOperatorsWithCredential(request, options = {}) {
2092
+ const operation = "broadcastOperatorsWithCredential";
2093
+ assertInput(operation, request, validateCreateGroupBroadcastRequest);
2094
+ if (options.idempotencyKey !== undefined)
2095
+ assertIdempotencyKey(operation, options.idempotencyKey);
2096
+ return this.#request({
2097
+ method: "POST",
2098
+ operation,
2099
+ options,
2100
+ idempotencyKey: options.idempotencyKey,
2101
+ sideEffect: true,
2102
+ path: "/v1/operators/broadcasts",
2103
+ validator: validateOperatorBroadcast,
2104
+ strictResponse: true,
2105
+ body: request,
2106
+ });
2107
+ }
2108
+ async getOperatorBroadcastWithCredential(broadcastId, options = {}) {
2109
+ const operation = "getOperatorBroadcastWithCredential";
2110
+ return this.#request({
2111
+ method: "GET",
2112
+ operation,
2113
+ options,
2114
+ sideEffect: false,
2115
+ path: `/v1/operators/broadcasts/${pathSegment(operation, broadcastId, "broadcastId")}`,
2116
+ validator: validateOperatorBroadcast,
2117
+ strictResponse: true,
2118
+ });
2119
+ }
2120
+ async pauseCustomerEndpointWithCredential(endpointId, options = {}) {
2121
+ const operation = "pauseCustomerEndpointWithCredential";
2122
+ return this.#request({
2123
+ method: "POST",
2124
+ operation,
2125
+ options,
2126
+ path: `/v1/customer-endpoints/${pathSegment(operation, endpointId, "endpointId")}/pause`,
2127
+ sideEffect: true,
2128
+ validator: validateCustomerEndpoint,
2129
+ });
2130
+ }
2131
+ async resumeCustomerEndpointWithCredential(endpointId, options = {}) {
2132
+ const operation = "resumeCustomerEndpointWithCredential";
2133
+ return this.#request({
2134
+ method: "POST",
2135
+ operation,
2136
+ options,
2137
+ path: `/v1/customer-endpoints/${pathSegment(operation, endpointId, "endpointId")}/resume`,
2138
+ sideEffect: true,
2139
+ validator: validateCustomerEndpoint,
2140
+ });
2141
+ }
2142
+ async disableCustomerEndpointWithCredential(endpointId, options = {}) {
2143
+ const operation = "disableCustomerEndpointWithCredential";
2144
+ return this.#request({
2145
+ method: "POST",
2146
+ operation,
2147
+ options,
2148
+ path: `/v1/customer-endpoints/${pathSegment(operation, endpointId, "endpointId")}/disable`,
2149
+ sideEffect: true,
2150
+ validator: validateCustomerEndpoint,
2151
+ });
2152
+ }
1992
2153
  async listCustomerEndpoints(projectId, environmentId, options = {}) {
1993
2154
  const operation = "listCustomerEndpoints";
1994
2155
  return this.#request({
@@ -2008,7 +2169,7 @@ export class WhooshBangClient {
2008
2169
  * idempotent replay returns the same logical endpoint without it, so a caller
2009
2170
  * that loses the value must rotate rather than re-read.
2010
2171
  */
2011
- async createCustomerEndpoint(projectId, environmentId, request, options) {
2172
+ async createCustomerEndpoint(projectId, environmentId, request, options = {}) {
2012
2173
  const operation = "createCustomerEndpoint";
2013
2174
  assertInput(operation, request, validateCreateCustomerEndpointRequest);
2014
2175
  return this.#request({
@@ -2050,7 +2211,7 @@ export class WhooshBangClient {
2050
2211
  * Both secrets verify for `overlap_seconds`, so a receiver that accepts the
2051
2212
  * previous and the new secret together has no verification gap.
2052
2213
  */
2053
- async rotateCustomerEndpoint(projectId, environmentId, endpointId, request, options) {
2214
+ async rotateCustomerEndpoint(projectId, environmentId, endpointId, request, options = {}) {
2054
2215
  const operation = "rotateCustomerEndpoint";
2055
2216
  assertInput(operation, request, validateRotateCustomerEndpointRequest);
2056
2217
  return this.#request({
@@ -2227,7 +2388,7 @@ export class WhooshBangClient {
2227
2388
  validator: validateChannelConnection,
2228
2389
  });
2229
2390
  }
2230
- async revokeMachineClientInEnvironment(projectId, environmentId, machineClientId, options) {
2391
+ async revokeMachineClientInEnvironment(projectId, environmentId, machineClientId, options = {}) {
2231
2392
  const operation = "revokeMachineClientInEnvironment";
2232
2393
  return this.#request({
2233
2394
  idempotencyKey: options.idempotencyKey,
@@ -2293,7 +2454,7 @@ export class WhooshBangClient {
2293
2454
  validator: validateChannelConnectionCollection,
2294
2455
  });
2295
2456
  }
2296
- async createChannelConnection(projectId, environmentId, request, options) {
2457
+ async createChannelConnection(projectId, environmentId, request, options = {}) {
2297
2458
  const operation = "createChannelConnection";
2298
2459
  assertInput(operation, request, validateCreateChannelConnectionRequest);
2299
2460
  return this.#request({
@@ -2379,7 +2540,7 @@ export class WhooshBangClient {
2379
2540
  * code is exchanged by WhooshBang and never enters the SDK request or
2380
2541
  * response, while the server pins completion to the recorded workspace.
2381
2542
  */
2382
- async reauthorizeChannelConnection(projectId, environmentId, connectionId, options) {
2543
+ async reauthorizeChannelConnection(projectId, environmentId, connectionId, options = {}) {
2383
2544
  const operation = "reauthorizeChannelConnection";
2384
2545
  return this.#request({
2385
2546
  idempotencyKey: options.idempotencyKey,
@@ -2510,7 +2671,7 @@ export class WhooshBangClient {
2510
2671
  * refused, because a diagnostic that leaves no trace is exactly what a
2511
2672
  * failure history cannot afford.
2512
2673
  */
2513
- async createConnectionTest(projectId, environmentId, connectionId, request, options) {
2674
+ async createConnectionTest(projectId, environmentId, connectionId, request, options = {}) {
2514
2675
  const operation = "createConnectionTest";
2515
2676
  assertInput(operation, request, validateCreateConnectionTestRequest);
2516
2677
  return this.#request({
@@ -2636,7 +2797,7 @@ export class WhooshBangClient {
2636
2797
  * and semantics are otherwise identical, so a caller that changes authority
2637
2798
  * changes which method it calls and nothing else.
2638
2799
  */
2639
- async createSubscriptionLinkInEnvironment(projectId, environmentId, request, options) {
2800
+ async createSubscriptionLinkInEnvironment(projectId, environmentId, request, options = {}) {
2640
2801
  const operation = "createSubscriptionLinkInEnvironment";
2641
2802
  assertInput(operation, request, validateCreateSubscriptionLinkRequest);
2642
2803
  return this.#request({
@@ -2662,7 +2823,7 @@ export class WhooshBangClient {
2662
2823
  validator: validateSubscriptionLink,
2663
2824
  });
2664
2825
  }
2665
- async createMessageInEnvironment(projectId, environmentId, request, options) {
2826
+ async createMessageInEnvironment(projectId, environmentId, request, options = {}) {
2666
2827
  const operation = "createMessageInEnvironment";
2667
2828
  assertInput(operation, request, validateCreateMessageRequest);
2668
2829
  return messageCreation(() => this.#request({
@@ -2702,7 +2863,7 @@ export class WhooshBangClient {
2702
2863
  validator: validateInteractionSummary,
2703
2864
  });
2704
2865
  }
2705
- async createMachineClientInEnvironment(projectId, environmentId, request, options) {
2866
+ async createMachineClientInEnvironment(projectId, environmentId, request, options = {}) {
2706
2867
  const operation = "createMachineClientInEnvironment";
2707
2868
  assertInput(operation, request, validateCreateMachineClientRequest);
2708
2869
  return this.#request({
@@ -2727,7 +2888,7 @@ export class WhooshBangClient {
2727
2888
  validator: validateProviderCapabilitiesCollection,
2728
2889
  });
2729
2890
  }
2730
- async createMachineClient(request, options) {
2891
+ async createMachineClient(request, options = {}) {
2731
2892
  assertInput("createMachineClient", request, validateCreateMachineClientRequest);
2732
2893
  return this.#request({
2733
2894
  body: request,
@@ -2757,7 +2918,7 @@ export class WhooshBangClient {
2757
2918
  * The readable secret never leaves the caller's process. See
2758
2919
  * `createMachineCredential` for the generator that produces the pair.
2759
2920
  */
2760
- async registerMachineCredential(machineClientId, request, options) {
2921
+ async registerMachineCredential(machineClientId, request, options = {}) {
2761
2922
  const operation = "registerMachineCredential";
2762
2923
  assertInput(operation, request, validateRegisterMachineCredentialRequest);
2763
2924
  return this.#request({
@@ -2778,7 +2939,7 @@ export class WhooshBangClient {
2778
2939
  * authority that carries none of its own — an OAuth grant, or an organization
2779
2940
  * credential — can finish a bootstrap it started.
2780
2941
  */
2781
- async registerMachineCredentialInEnvironment(projectId, environmentId, machineClientId, request, options) {
2942
+ async registerMachineCredentialInEnvironment(projectId, environmentId, machineClientId, request, options = {}) {
2782
2943
  const operation = "registerMachineCredentialInEnvironment";
2783
2944
  assertInput(operation, request, validateRegisterMachineCredentialRequest);
2784
2945
  return this.#request({
@@ -2793,7 +2954,7 @@ export class WhooshBangClient {
2793
2954
  validator: validateMachineCredential,
2794
2955
  });
2795
2956
  }
2796
- async revokeMachineCredential(machineClientId, credentialId, options) {
2957
+ async revokeMachineCredential(machineClientId, credentialId, options = {}) {
2797
2958
  const operation = "revokeMachineCredential";
2798
2959
  return this.#request({
2799
2960
  idempotencyKey: options.idempotencyKey,
@@ -2806,7 +2967,7 @@ export class WhooshBangClient {
2806
2967
  validator: validateMachineCredential,
2807
2968
  });
2808
2969
  }
2809
- async revokeMachineClient(machineClientId, options) {
2970
+ async revokeMachineClient(machineClientId, options = {}) {
2810
2971
  const operation = "revokeMachineClient";
2811
2972
  return this.#request({
2812
2973
  idempotencyKey: options.idempotencyKey,
@@ -2841,7 +3002,7 @@ export class WhooshBangClient {
2841
3002
  validator: validateMachineEventPollResponse,
2842
3003
  });
2843
3004
  }
2844
- async acknowledgeMachineEvent(eventId, request, options) {
3005
+ async acknowledgeMachineEvent(eventId, request, options = {}) {
2845
3006
  const operation = "acknowledgeMachineEvent";
2846
3007
  assertInput(operation, request, validateMachineEventAckRequest);
2847
3008
  return this.#request({
@@ -2855,7 +3016,7 @@ export class WhooshBangClient {
2855
3016
  validator: validateMachineEventAckResponse,
2856
3017
  });
2857
3018
  }
2858
- async #createSubscriber(operation, root, request, options) {
3019
+ async #createSubscriber(operation, root, request, options = {}) {
2859
3020
  assertInput(operation, request, validateCreateSubscriberRequest);
2860
3021
  return this.#request({
2861
3022
  body: request,
@@ -2912,7 +3073,7 @@ export class WhooshBangClient {
2912
3073
  validator: validateSubscriberGroupCollection,
2913
3074
  });
2914
3075
  }
2915
- async #createSubscriberGroup(operation, root, request, options) {
3076
+ async #createSubscriberGroup(operation, root, request, options = {}) {
2916
3077
  assertInput(operation, request, validateCreateSubscriberGroupRequest);
2917
3078
  return this.#request({
2918
3079
  body: request,
@@ -3015,7 +3176,7 @@ export class WhooshBangClient {
3015
3176
  sideEffect: true,
3016
3177
  });
3017
3178
  }
3018
- async #createGroupBroadcast(operation, root, groupKey, request, options) {
3179
+ async #createGroupBroadcast(operation, root, groupKey, request, options = {}) {
3019
3180
  assertInput(operation, request, validateCreateGroupBroadcastRequest);
3020
3181
  return this.#request({
3021
3182
  body: request,
@@ -3068,6 +3229,11 @@ export class WhooshBangClient {
3068
3229
  * own call site, where it is already unmissable.
3069
3230
  */
3070
3231
  async #request(descriptor) {
3232
+ if (descriptor.sideEffect &&
3233
+ Object.hasOwn(descriptor, "idempotencyKey") &&
3234
+ descriptor.idempotencyKey === undefined) {
3235
+ descriptor = { ...descriptor, idempotencyKey: crypto.randomUUID() };
3236
+ }
3071
3237
  if (descriptor.idempotencyKey !== undefined) {
3072
3238
  assertIdempotencyKey(descriptor.operation, descriptor.idempotencyKey);
3073
3239
  }
@@ -3207,7 +3373,7 @@ export class WhooshBangRecipientSessionClient {
3207
3373
  #browserCapability;
3208
3374
  #fetch;
3209
3375
  constructor(options) {
3210
- this.#baseUrl = normalizeBaseUrl(options.baseUrl);
3376
+ this.#baseUrl = normalizeBaseUrl(options.baseUrl ?? "https://api.whooshbang.com");
3211
3377
  validateRecipientCapability(options.browserCapability);
3212
3378
  this.#browserCapability = options.browserCapability;
3213
3379
  const runtimeFetch = options.fetch ?? globalThis.fetch;
@@ -3278,6 +3444,11 @@ export class WhooshBangRecipientSessionClient {
3278
3444
  });
3279
3445
  }
3280
3446
  async #request(descriptor) {
3447
+ if (descriptor.sideEffect &&
3448
+ Object.hasOwn(descriptor, "idempotencyKey") &&
3449
+ descriptor.idempotencyKey === undefined) {
3450
+ descriptor = { ...descriptor, idempotencyKey: crypto.randomUUID() };
3451
+ }
3281
3452
  const resolved = resolveSignal(descriptor.operation, descriptor.options);
3282
3453
  const headers = new Headers({
3283
3454
  accept: "application/json, application/problem+json",