@whooshbang/sdk 6.0.0 → 7.1.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.
Files changed (58) hide show
  1. package/dist/browser-confirmation.d.ts +35 -2
  2. package/dist/browser-confirmation.js +85 -30
  3. package/dist/browser-confirmation.js.map +1 -1
  4. package/dist/client.d.ts +146 -1
  5. package/dist/client.js +328 -1
  6. package/dist/client.js.map +1 -1
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.js +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/recipient/digest-section.d.ts +29 -0
  11. package/dist/recipient/digest-section.js +400 -0
  12. package/dist/recipient/digest-section.js.map +1 -0
  13. package/dist/recipient/element.js +153 -10
  14. package/dist/recipient/element.js.map +1 -1
  15. package/dist/recipient/i18n/ar.js +37 -0
  16. package/dist/recipient/i18n/ar.js.map +1 -1
  17. package/dist/recipient/i18n/catalog.d.ts +38 -0
  18. package/dist/recipient/i18n/catalog.js.map +1 -1
  19. package/dist/recipient/i18n/de.js +37 -0
  20. package/dist/recipient/i18n/de.js.map +1 -1
  21. package/dist/recipient/i18n/en.js +37 -0
  22. package/dist/recipient/i18n/en.js.map +1 -1
  23. package/dist/recipient/i18n/es.js +37 -0
  24. package/dist/recipient/i18n/es.js.map +1 -1
  25. package/dist/recipient/i18n/fa.js +37 -0
  26. package/dist/recipient/i18n/fa.js.map +1 -1
  27. package/dist/recipient/i18n/fr.js +37 -0
  28. package/dist/recipient/i18n/fr.js.map +1 -1
  29. package/dist/recipient/i18n/hi.js +37 -0
  30. package/dist/recipient/i18n/hi.js.map +1 -1
  31. package/dist/recipient/i18n/id.js +37 -0
  32. package/dist/recipient/i18n/id.js.map +1 -1
  33. package/dist/recipient/i18n/it.js +37 -0
  34. package/dist/recipient/i18n/it.js.map +1 -1
  35. package/dist/recipient/i18n/nl.js +37 -0
  36. package/dist/recipient/i18n/nl.js.map +1 -1
  37. package/dist/recipient/i18n/pl.js +37 -0
  38. package/dist/recipient/i18n/pl.js.map +1 -1
  39. package/dist/recipient/i18n/pt-BR.js +37 -0
  40. package/dist/recipient/i18n/pt-BR.js.map +1 -1
  41. package/dist/recipient/i18n/ru.js +37 -0
  42. package/dist/recipient/i18n/ru.js.map +1 -1
  43. package/dist/recipient/i18n/tr.js +37 -0
  44. package/dist/recipient/i18n/tr.js.map +1 -1
  45. package/dist/recipient/i18n/uk.js +37 -0
  46. package/dist/recipient/i18n/uk.js.map +1 -1
  47. package/dist/recipient/i18n/zh-Hans.js +37 -0
  48. package/dist/recipient/i18n/zh-Hans.js.map +1 -1
  49. package/dist/recipient/mount.d.ts +5 -0
  50. package/dist/recipient/mount.js +2 -0
  51. package/dist/recipient/mount.js.map +1 -1
  52. package/dist/recipient/quiet-section.d.ts +7 -3
  53. package/dist/recipient/quiet-section.js +134 -7
  54. package/dist/recipient/quiet-section.js.map +1 -1
  55. package/dist/recipient/quiet-view.d.ts +20 -0
  56. package/dist/recipient/quiet-view.js +54 -0
  57. package/dist/recipient/quiet-view.js.map +1 -1
  58. package/package.json +2 -2
package/dist/client.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { validateWhoAmI, validateOperatorCollection, validateOperatorResolution, validateCreateOperatorMessageRequest, validateOperatorMessageResult, validateOperatorBroadcast, validateOperatorPreferences, validateOperatorConnectRequest, } from "@whooshbang/contracts";
2
2
  import { validateAssertEmailConsentRequest, validateBindingSummary, } from "@whooshbang/contracts";
3
- import { contractValidationErrors, validateOrganizationCredential, validateOrganizationCredentialCollection, validateOrganizationCredentialRotation, validateOrganizationCredentialSecretReveal, validateBillingProjectSlots, validateBillingPromotions, validateBillingPromotion, validateRedeemBillingPromotionRequest, validateAssignBillingProjectSlotsRequest, validateSubscriptionChange, validateConfirmSubscriptionChangeRequest, validateBillingEntitlements, validateSubscriptionSelection, validateProjectAttribution, validateUpdateProjectAttributionRequest, validateAutoTopUpSettings, validateUpdateAutoTopUpSettingsRequest, validateBillingAccount, validateCardSetup, validateCreateCreditPurchaseRequest, validateCreditPurchase, validateBillingInvoiceCollection, validateUpdateBillingReceiptEmailRequest, validateOrganizationProjection, validateApiCredential, validateApiCredentialCollection, validateApiCredentialRotation, validateApiCredentialSecretReveal, validateAttachNotifierConnectionRequest, validateChannelConnection, validateChannelConnectionCollection, validateConnectionProviderCollection, validateUsageReport, validateMessageListPage, validateMessageDeliveryHistory, validateMessageNotificationImage, validateInteractionTimeline, validateUpdateEmailSenderRequest, validateCustomerEventDeliveryHistory, validateCustomerEventDeliveryAttempt, validateDeliveryHolds, validateMachineClientOperationsList, validateRecipientCopyCatalogue, validateNotifierConnectionCollection, validateProjectRecipientExperience, validateRecipientBrandLogoUpload, validateNotificationImageAsset, validateUpdateProjectRecipientExperienceRequest, validateEnvironmentRecipientExperience, validateUpdateEnvironmentRecipientExperienceRequest, validateSubscriberChannelSettings, validateAcknowledgeEmailRemediationRequest, validateCreateRecipientSessionRequest, validateCreateRecipientSessionResponse, validateRecipientSession, validateCreateProviderHandoffRequest, validateProviderHandoff, validateSetPreferredBindingRequest, validatePreferredBinding, validateCreateSubscriberRequest, validateSubscriber, validateSubscriberDataExport, validateUpdateSubscriberRequest, validateSubscriberCollection, validateCloseOrganizationRequest, validateInviteTeammateRequest, validateTeammate, validateTeammateAccessRequest, validateTeammateCollection, validateOrganizationClosureResult, validateCreateSubscriberGroupRequest, validateUpdateSubscriberGroupRequest, validateSubscriberGroup, validateSubscriberGroupCollection, validateSubscriberGroupMembership, validateSubscriberGroupMembershipCollection, validateCreateGroupBroadcastRequest, validateGroupBroadcast, validateCreateOrganizationCredentialRequest, validateCreateApiCredentialRequest, validateCreateChannelConnectionRequest, validateCreateCustomerEndpointRequest, validateCreateMachineClientRequest, validateCreateMessageRequest, validateCancelEscalationByKeyRequest, validateEscalationPathPreview, validateEscalationOrder, validateEscalationOrderCollection, validateSaveEscalationOrderRequest, validateQuietHours, validateSaveQuietHoursRequest, validateEscalationPolicy, validateEscalationPolicyCollection, validateEscalationLimits, validateUpdateEscalationLimitsRequest, validateEscalationPagingLimitReport, validateUpdateEscalationPolicyRequest, validateCancelEscalationRequest, validateEscalation, validateMessageCategory, validateMessageCategoryCollection, validateCreateMessageCategoryRequest, validateUpdateMessageCategoryRequest, validateSubscriberCategoryPreference, validateSubscriberCategoryPreferenceCollection, validateSetSubscriberCategoryPreferenceRequest, validateCreateProjectRequest, validateUpdateProjectRequest, validateCreateSubscriptionLinkRequest, validateCustomerEndpoint, validateCustomerEndpointAttemptCollection, validateCustomerEndpointCollection, validateCustomerEndpointMutationResult, validateInteractionSummary, validateMachineClient, validateMachineCredential, validateMachineEventAckRequest, validateMachineEventAckResponse, validateMachineEventPollResponse, validateMessage, validateProblem, validateProject, validateProjectCollection, validateRecipientCopyOverride, validateRecipientCopyOverrideCollection, validateProviderCapabilitiesCollection, validateProviderInstallationCollection, validateEmailDomainCollection, validateCreateEmailDomainRequest, validateRegisterMachineCredentialRequest, validateRotateOrganizationCredentialRequest, validateRotateApiCredentialRequest, validateConnectionTest, validateConnectionTestCollection, validateCreateConnectionTestRequest, validateCustomerApplicationManifest, validateRotateChannelConnectionCredentialRequest, validateRotateCustomerEndpointRequest, validateSubscriptionLink, validateUpdateChannelConnectionRequest, validateUpdateRecipientCopyOverrideRequest, } from "@whooshbang/contracts";
3
+ import { contractValidationErrors, validateOrganizationCredential, validateOrganizationCredentialCollection, validateOrganizationCredentialRotation, validateOrganizationCredentialSecretReveal, validateBillingProjectSlots, validateBillingPromotions, validateBillingPromotion, validateRedeemBillingPromotionRequest, validateAssignBillingProjectSlotsRequest, validateSubscriptionChange, validateConfirmSubscriptionChangeRequest, validateBillingEntitlements, validateSubscriptionSelection, validateProjectAttribution, validateUpdateProjectAttributionRequest, validateAutoTopUpSettings, validateUpdateAutoTopUpSettingsRequest, validateBillingAccount, validateCardSetup, validateCreateCreditPurchaseRequest, validateCreditPurchase, validateBillingInvoiceCollection, validateUpdateBillingReceiptEmailRequest, validateOrganizationProjection, validateApiCredential, validateApiCredentialCollection, validateApiCredentialRotation, validateApiCredentialSecretReveal, validateAttachNotifierConnectionRequest, validateChannelConnection, validateChannelConnectionCollection, validateConnectionProviderCollection, validateUsageReport, validateMessageListPage, validateMessageDeliveryHistory, validateMessageNotificationImage, validateInteractionTimeline, validateUpdateEmailSenderRequest, validateCustomerEventDeliveryHistory, validateCustomerEventDeliveryAttempt, validateDeliveryHolds, validateMachineClientOperationsList, validateRecipientCopyCatalogue, validateNotifierConnectionCollection, validateProjectRecipientExperience, validateRecipientBrandLogoUpload, validateNotificationImageAsset, validateUpdateProjectRecipientExperienceRequest, validateEnvironmentRecipientExperience, validateUpdateEnvironmentRecipientExperienceRequest, validateSubscriberChannelSettings, validateAcknowledgeEmailRemediationRequest, validateCreateRecipientSessionRequest, validateCreateRecipientSessionResponse, validateRecipientSession, validateCreateProviderHandoffRequest, validateProviderHandoff, validateSetPreferredBindingRequest, validatePreferredBinding, validateCreateSubscriberRequest, validateSubscriber, validateSubscriberDataExport, validateUpdateSubscriberRequest, validateSubscriberCollection, validateCloseOrganizationRequest, validateInviteTeammateRequest, validateTeammate, validateTeammateAccessRequest, validateTeammateCollection, validateOrganizationClosureResult, validateCreateSubscriberGroupRequest, validateUpdateSubscriberGroupRequest, validateSubscriberGroup, validateSubscriberGroupCollection, validateSubscriberGroupMembership, validateSubscriberGroupMembershipCollection, validateCreateGroupBroadcastRequest, validateGroupBroadcast, validateCreateOrganizationCredentialRequest, validateCreateApiCredentialRequest, validateCreateChannelConnectionRequest, validateCreateCustomerEndpointRequest, validateCreateMachineClientRequest, validateCreateMessageRequest, validateCancelEscalationByKeyRequest, validateEscalationPathPreview, validateEscalationOrder, validateEscalationOrderCollection, validateSaveEscalationOrderRequest, validateQuietHours, validateSaveQuietHoursRequest, validateSetDigestPreferenceRequest, validateSetSubscriberDigestSettingRequest, validateSubscriberDigestSettings, validateEscalationPolicy, validateEscalationPolicyCollection, validateEscalationLimits, validateUpdateEscalationLimitsRequest, validateEscalationPagingLimitReport, validateUpdateEscalationPolicyRequest, validateCancelEscalationRequest, validateEscalation, validateMessageCategory, validateMessageCategoryCollection, validateCreateMessageCategoryRequest, validateUpdateMessageCategoryRequest, validateSubscriberCategoryPreference, validateSubscriberCategoryPreferenceCollection, validateSetSubscriberCategoryPreferenceRequest, validateCreateProjectRequest, validateUpdateProjectRequest, validateCreateSubscriptionLinkRequest, validateCustomerEndpoint, validateCustomerEndpointAttemptCollection, validateCustomerEndpointCollection, validateCustomerEndpointMutationResult, validateInteractionSummary, validateMachineClient, validateMachineCredential, validateMachineEventAckRequest, validateMachineEventAckResponse, validateMachineEventPollResponse, validateMessage, validateProblem, validateProject, validateProjectCollection, validateRecipientCopyOverride, validateRecipientCopyOverrideCollection, validateProviderCapabilitiesCollection, validateProviderInstallationCollection, validateEmailDomainCollection, validateCreateEmailDomainRequest, validateRegisterMachineCredentialRequest, validateRotateOrganizationCredentialRequest, validateRotateApiCredentialRequest, validateConnectionTest, validateConnectionTestCollection, validateCreateConnectionTestRequest, validateCustomerApplicationManifest, validateRotateChannelConnectionCredentialRequest, validateRotateCustomerEndpointRequest, validateSubscriptionLink, validateUpdateChannelConnectionRequest, validateUpdateRecipientCopyOverrideRequest, } from "@whooshbang/contracts";
4
4
  import { validateAdditiveCompatible } from "./additive-compatibility.js";
5
5
  import { WhooshBangContractError, WhooshBangOutcomeUnknownError, WhooshBangProblemError, WhooshBangProtocolError, WhooshBangTransportError, WhooshBangValidationError, validationError, } from "./errors.js";
6
6
  import { interactionAnswer } from "./interactions.js";
@@ -80,6 +80,45 @@ function usageQuery(operation, options) {
80
80
  return search.size === 0 ? "" : `?${search.toString()}`;
81
81
  }
82
82
  const templateRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
83
+ function validateAuthoredTemplate(value) {
84
+ return (validateTemplateCatalogEntry(value) &&
85
+ Number.isSafeInteger(value.draftVersion));
86
+ }
87
+ function validatePublishedRevision(value) {
88
+ return (templateRecord(value) &&
89
+ Number.isSafeInteger(value.revision) &&
90
+ templateRecord(value.definition) &&
91
+ typeof value.publishedAt === "string");
92
+ }
93
+ function validateRevisionCollection(value) {
94
+ return (templateRecord(value) &&
95
+ Array.isArray(value.items) &&
96
+ value.items.every((item) => validatePublishedRevision(item)));
97
+ }
98
+ function validateTemplatePreview(value) {
99
+ return (templateRecord(value) &&
100
+ typeof value.channel === "string" &&
101
+ templateRecord(value.normalizedInput) &&
102
+ typeof value.templateLocale === "string");
103
+ }
104
+ function validateEmailLayout(value) {
105
+ return (templateRecord(value) &&
106
+ typeof value.id === "string" &&
107
+ typeof value.name === "string" &&
108
+ typeof value.isDefault === "boolean" &&
109
+ typeof value.disabled === "boolean" &&
110
+ templateRecord(value.draft) &&
111
+ Number.isSafeInteger(value.draftVersion) &&
112
+ Number.isSafeInteger(value.latestPublishedRevision));
113
+ }
114
+ function validateEmailLayoutCollection(value) {
115
+ return (templateRecord(value) &&
116
+ Array.isArray(value.items) &&
117
+ value.items.every((item) => validateEmailLayout(item)));
118
+ }
119
+ function validateDefaultLayout(value) {
120
+ return templateRecord(value) && typeof value.default_layout_id === "string";
121
+ }
83
122
  function validateTemplateCatalog(value) {
84
123
  return (templateRecord(value) &&
85
124
  Array.isArray(value.items) &&
@@ -1477,6 +1516,202 @@ export class WhooshBangClient {
1477
1516
  strictResponse: true,
1478
1517
  });
1479
1518
  }
1519
+ /** The template as its author sees it, including the editable draft. */
1520
+ async getMessageTemplateForAuthoring(projectId, reference, options = {}) {
1521
+ const operation = "getMessageTemplate";
1522
+ return this.#request({
1523
+ method: "GET",
1524
+ operation,
1525
+ options,
1526
+ sideEffect: false,
1527
+ path: `${templateRoot(operation, projectId)}/${pathSegment(operation, reference, "reference")}`,
1528
+ validator: validateAuthoredTemplate,
1529
+ });
1530
+ }
1531
+ /** Every template, drafts and disabled ones included, for authoring. */
1532
+ async listMessageTemplatesForAuthoring(projectId, query = {}, options = {}) {
1533
+ const operation = "listMessageTemplates";
1534
+ const params = new URLSearchParams();
1535
+ if (query.search !== undefined)
1536
+ params.set("search", query.search);
1537
+ if (query.category !== undefined)
1538
+ params.set("category", query.category);
1539
+ if (query.after !== undefined)
1540
+ params.set("after", query.after);
1541
+ if (query.limit !== undefined)
1542
+ params.set("limit", String(query.limit));
1543
+ if (query.page !== undefined)
1544
+ params.set("page", String(query.page));
1545
+ const suffix = params.size === 0 ? "" : `?${params}`;
1546
+ return this.#request({
1547
+ method: "GET",
1548
+ operation,
1549
+ options,
1550
+ sideEffect: false,
1551
+ path: `${templateRoot(operation, projectId)}${suffix}`,
1552
+ validator: (value) => validateTemplateCatalog(value) &&
1553
+ value.items.every((item) => validateAuthoredTemplate(item)),
1554
+ });
1555
+ }
1556
+ async createMessageTemplate(projectId, request, options = {}) {
1557
+ const operation = "createMessageTemplate";
1558
+ return this.#request({
1559
+ body: request,
1560
+ method: "POST",
1561
+ operation,
1562
+ options,
1563
+ sideEffect: true,
1564
+ path: templateRoot(operation, projectId),
1565
+ validator: validateAuthoredTemplate,
1566
+ });
1567
+ }
1568
+ /** Renames, recategorises, disables or re-enables a template. */
1569
+ async updateMessageTemplate(projectId, templateId, request, options = {}) {
1570
+ const operation = "updateMessageTemplateMetadata";
1571
+ return this.#request({
1572
+ body: request,
1573
+ method: "PATCH",
1574
+ operation,
1575
+ options,
1576
+ sideEffect: true,
1577
+ path: `${templateRoot(operation, projectId)}/${pathSegment(operation, templateId, "templateId")}`,
1578
+ validator: validateAuthoredTemplate,
1579
+ });
1580
+ }
1581
+ /** Replaces the draft. `draftVersion` is the version last read; a newer save refuses this one. */
1582
+ async saveMessageTemplateDraft(projectId, templateId, draftVersion, definition, options = {}) {
1583
+ const operation = "saveMessageTemplateDraft";
1584
+ return this.#request({
1585
+ body: { draft_version: draftVersion, definition },
1586
+ method: "PUT",
1587
+ operation,
1588
+ options,
1589
+ sideEffect: true,
1590
+ path: `${templateRoot(operation, projectId)}/${pathSegment(operation, templateId, "templateId")}/draft`,
1591
+ validator: validateAuthoredTemplate,
1592
+ });
1593
+ }
1594
+ /** Validates the draft completely and publishes it as the next revision. */
1595
+ async publishMessageTemplate(projectId, templateId, draftVersion, options = {}) {
1596
+ const operation = "publishMessageTemplate";
1597
+ return this.#request({
1598
+ body: { draft_version: draftVersion },
1599
+ method: "POST",
1600
+ operation,
1601
+ options,
1602
+ sideEffect: true,
1603
+ path: `${templateRoot(operation, projectId)}/${pathSegment(operation, templateId, "templateId")}/publish`,
1604
+ validator: validatePublishedRevision,
1605
+ });
1606
+ }
1607
+ async listMessageTemplateRevisions(projectId, templateId, options = {}) {
1608
+ const operation = "listMessageTemplateRevisions";
1609
+ return this.#request({
1610
+ method: "GET",
1611
+ operation,
1612
+ options,
1613
+ sideEffect: false,
1614
+ path: `${templateRoot(operation, projectId)}/${pathSegment(operation, templateId, "templateId")}/revisions`,
1615
+ validator: validateRevisionCollection,
1616
+ });
1617
+ }
1618
+ /** Renders the draft, a revision or an unsaved definition. Nothing is sent. */
1619
+ async previewMessageTemplate(projectId, templateId, request, options = {}) {
1620
+ const operation = "previewMessageTemplate";
1621
+ return this.#request({
1622
+ body: request,
1623
+ method: "POST",
1624
+ operation,
1625
+ options,
1626
+ sideEffect: false,
1627
+ path: `${templateRoot(operation, projectId)}/${pathSegment(operation, templateId, "templateId")}/preview`,
1628
+ validator: validateTemplatePreview,
1629
+ });
1630
+ }
1631
+ /** Sends the exact draft to one subscriber as a test. It never publishes. */
1632
+ async testSendMessageTemplateDraft(projectId, environmentId, templateId, request, options = {}) {
1633
+ const operation = "testSendMessageTemplateDraft";
1634
+ return this.#request({
1635
+ body: request,
1636
+ method: "POST",
1637
+ operation,
1638
+ options,
1639
+ idempotencyKey: options.idempotencyKey,
1640
+ sideEffect: true,
1641
+ path: `${environmentRoot(operation, projectId, environmentId)}/message-templates/${pathSegment(operation, templateId, "templateId")}/test-send`,
1642
+ validator: validateTemplateMessageSendResult,
1643
+ });
1644
+ }
1645
+ async listEmailLayouts(projectId, options = {}) {
1646
+ const operation = "listEmailLayouts";
1647
+ return this.#request({
1648
+ method: "GET",
1649
+ operation,
1650
+ options,
1651
+ sideEffect: false,
1652
+ path: layoutRoot(operation, projectId),
1653
+ validator: validateEmailLayoutCollection,
1654
+ });
1655
+ }
1656
+ async getEmailLayout(projectId, layoutId, options = {}) {
1657
+ const operation = "getEmailLayout";
1658
+ return this.#request({
1659
+ method: "GET",
1660
+ operation,
1661
+ options,
1662
+ sideEffect: false,
1663
+ path: `${layoutRoot(operation, projectId)}/${pathSegment(operation, layoutId, "layoutId")}`,
1664
+ validator: validateEmailLayout,
1665
+ });
1666
+ }
1667
+ async createEmailLayout(projectId, request, options = {}) {
1668
+ const operation = "createEmailLayout";
1669
+ return this.#request({
1670
+ body: request,
1671
+ method: "POST",
1672
+ operation,
1673
+ options,
1674
+ sideEffect: true,
1675
+ path: layoutRoot(operation, projectId),
1676
+ validator: validateEmailLayout,
1677
+ });
1678
+ }
1679
+ async saveEmailLayoutDraft(projectId, layoutId, draftVersion, definition, options = {}) {
1680
+ const operation = "saveEmailLayoutDraft";
1681
+ return this.#request({
1682
+ body: { draft_version: draftVersion, definition },
1683
+ method: "PUT",
1684
+ operation,
1685
+ options,
1686
+ sideEffect: true,
1687
+ path: `${layoutRoot(operation, projectId)}/${pathSegment(operation, layoutId, "layoutId")}/draft`,
1688
+ validator: validateEmailLayout,
1689
+ });
1690
+ }
1691
+ async publishEmailLayout(projectId, layoutId, draftVersion, options = {}) {
1692
+ const operation = "publishEmailLayout";
1693
+ return this.#request({
1694
+ body: { draft_version: draftVersion },
1695
+ method: "POST",
1696
+ operation,
1697
+ options,
1698
+ sideEffect: true,
1699
+ path: `${layoutRoot(operation, projectId)}/${pathSegment(operation, layoutId, "layoutId")}/publish`,
1700
+ validator: validatePublishedRevision,
1701
+ });
1702
+ }
1703
+ /** Makes a published layout the project's default for email templates. */
1704
+ async setDefaultEmailLayout(projectId, layoutId, options = {}) {
1705
+ const operation = "setDefaultEmailLayout";
1706
+ return this.#request({
1707
+ method: "POST",
1708
+ operation,
1709
+ options,
1710
+ sideEffect: true,
1711
+ path: `${layoutRoot(operation, projectId)}/${pathSegment(operation, layoutId, "layoutId")}/default`,
1712
+ validator: validateDefaultLayout,
1713
+ });
1714
+ }
1480
1715
  async createMessageCategory(projectId, request, options = {}) {
1481
1716
  const operation = "createMessageCategory";
1482
1717
  assertInput(operation, request, validateCreateMessageCategoryRequest);
@@ -1688,6 +1923,40 @@ export class WhooshBangClient {
1688
1923
  validator: validateQuietHours,
1689
1924
  });
1690
1925
  }
1926
+ /**
1927
+ * One subscriber's digest settings: for each category, the policy in
1928
+ * effect, where each setting comes from, what the subscriber may change,
1929
+ * their saved choices and your setting for them (FXO-3729).
1930
+ */
1931
+ async getSubscriberDigestSettings(projectId, environmentId, subscriberId, options = {}) {
1932
+ const operation = "getSubscriberDigestSettings";
1933
+ return this.#request({
1934
+ method: "GET",
1935
+ operation,
1936
+ options,
1937
+ sideEffect: false,
1938
+ path: `${environmentRoot(operation, projectId, environmentId)}/subscribers/${pathSegment(operation, subscriberId, "subscriberId")}/digest-settings`,
1939
+ validator: validateSubscriberDigestSettings,
1940
+ });
1941
+ }
1942
+ /**
1943
+ * Your digest setting for one subscriber and category, and which settings
1944
+ * they can't change; `{ setting: null }` removes it. Their own choice is
1945
+ * kept and returns when you unlock.
1946
+ */
1947
+ async setSubscriberDigestSetting(projectId, environmentId, subscriberId, categoryKey, request, options = {}) {
1948
+ const operation = "setSubscriberDigestSetting";
1949
+ assertInput(operation, request, validateSetSubscriberDigestSettingRequest);
1950
+ return this.#request({
1951
+ body: request,
1952
+ method: "PUT",
1953
+ operation,
1954
+ options,
1955
+ sideEffect: true,
1956
+ path: `${environmentRoot(operation, projectId, environmentId)}/subscribers/${pathSegment(operation, subscriberId, "subscriberId")}/digest-settings/categories/${pathSegment(operation, categoryKey, "categoryKey")}`,
1957
+ validator: validateSubscriberDigestSettings,
1958
+ });
1959
+ }
1691
1960
  async transitionSubscriberBinding(projectId, environmentId, subscriberId, bindingId, action, options = {}) {
1692
1961
  const operation = "transitionSubscriberBinding";
1693
1962
  if (!["pause", "resume", "unsubscribe"].includes(action)) {
@@ -4069,6 +4338,58 @@ export class WhooshBangRecipientSessionClient {
4069
4338
  validator: validateQuietHours,
4070
4339
  });
4071
4340
  }
4341
+ /**
4342
+ * This subscriber's digest settings: only the categories whose owner lets
4343
+ * them choose something, with what is in effect and what they can change,
4344
+ * plus their Default (FXO-3729).
4345
+ */
4346
+ async getDigestSettings(options = {}) {
4347
+ const operation = "getDigestSettings";
4348
+ return this.#request({
4349
+ method: "GET",
4350
+ operation,
4351
+ options,
4352
+ path: "v1/recipient-session/digest-settings",
4353
+ sideEffect: false,
4354
+ validator: validateSubscriberDigestSettings,
4355
+ });
4356
+ }
4357
+ /**
4358
+ * Sets this subscriber's Default digest choice, or clears it with
4359
+ * `{ preference: null }`. A setting the owner doesn't offer fails with
4360
+ * `request_invalid` naming it, and the previous setting stays.
4361
+ */
4362
+ async setDefaultDigestPreference(request, options = {}) {
4363
+ const operation = "setDefaultDigestPreference";
4364
+ assertInput(operation, request, validateSetDigestPreferenceRequest);
4365
+ return this.#request({
4366
+ body: request,
4367
+ method: "PUT",
4368
+ operation,
4369
+ options,
4370
+ path: "v1/recipient-session/digest-settings/default",
4371
+ sideEffect: true,
4372
+ validator: validateSubscriberDigestSettings,
4373
+ });
4374
+ }
4375
+ /**
4376
+ * Sets this subscriber's digest choice for one category, or clears it so
4377
+ * the category follows the Default again. Locked or unoffered settings
4378
+ * fail with `request_invalid` and the previous setting stays.
4379
+ */
4380
+ async setCategoryDigestPreference(categoryKey, request, options = {}) {
4381
+ const operation = "setCategoryDigestPreference";
4382
+ assertInput(operation, request, validateSetDigestPreferenceRequest);
4383
+ return this.#request({
4384
+ body: request,
4385
+ method: "PUT",
4386
+ operation,
4387
+ options,
4388
+ path: `v1/recipient-session/digest-settings/categories/${pathSegment(operation, categoryKey, "categoryKey")}`,
4389
+ sideEffect: true,
4390
+ validator: validateSubscriberDigestSettings,
4391
+ });
4392
+ }
4072
4393
  /** Turns off this subscriber's quiet hours. */
4073
4394
  async resetQuietHours(options = {}) {
4074
4395
  const operation = "resetQuietHours";
@@ -4171,6 +4492,12 @@ function environmentRoot(operation, projectId, environmentId) {
4171
4492
  const environment = pathSegment(operation, environmentId, "environmentId");
4172
4493
  return `v1/projects/${project}/environments/${environment}`;
4173
4494
  }
4495
+ function templateRoot(operation, projectId) {
4496
+ return `v1/projects/${pathSegment(operation, projectId, "projectId")}/message-templates`;
4497
+ }
4498
+ function layoutRoot(operation, projectId) {
4499
+ return `v1/projects/${pathSegment(operation, projectId, "projectId")}/email-layouts`;
4500
+ }
4174
4501
  function subscriberGroupPath(operation, root, groupKey) {
4175
4502
  return `${root}/subscriber-groups/${pathSegment(operation, groupKey, "groupKey")}`;
4176
4503
  }