samva 0.17.0 → 0.18.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 (124) hide show
  1. package/AGENTS.md +5 -0
  2. package/README.md +16 -3
  3. package/dist/{rolldown-runtime-D7D4PA-g.js → _virtual/_rolldown/runtime.js} +1 -1
  4. package/dist/client/client/client.gen.js +174 -0
  5. package/dist/client/client/utils.gen.js +177 -0
  6. package/dist/client/client.gen.js +8 -0
  7. package/dist/client/core/auth.gen.js +12 -0
  8. package/dist/client/core/bodySerializer.gen.js +6 -0
  9. package/dist/client/core/params.gen.js +77 -0
  10. package/dist/client/core/pathSerializer.gen.js +82 -0
  11. package/dist/client/core/serverSentEvents.gen.js +96 -0
  12. package/dist/client/core/utils.gen.js +78 -0
  13. package/dist/{promises---Kbh-7z.js → client/sdk.gen.js} +4 -2293
  14. package/dist/client-attribution.js +9 -0
  15. package/dist/effect/analytics.d.ts +6 -6
  16. package/dist/effect/analytics.js +23 -2
  17. package/dist/effect/api-keys.d.ts +12 -12
  18. package/dist/effect/api-keys.js +29 -2
  19. package/dist/effect/attachments.d.ts +4 -4
  20. package/dist/effect/attachments.js +19 -2
  21. package/dist/effect/brands.d.ts +6 -6
  22. package/dist/effect/brands.js +26 -3
  23. package/dist/effect/campaigns.d.ts +18 -18
  24. package/dist/effect/campaigns.js +35 -2
  25. package/dist/effect/categories.d.ts +2 -2
  26. package/dist/effect/categories.js +95 -1
  27. package/dist/effect/client.js +3 -3
  28. package/dist/effect/contact-groups.d.ts +14 -14
  29. package/dist/effect/contact-groups.js +31 -2
  30. package/dist/effect/contacts.d.ts +28 -28
  31. package/dist/effect/contacts.js +52 -2
  32. package/dist/effect/conversations.d.ts +17 -17
  33. package/dist/effect/conversations.js +37 -2
  34. package/dist/effect/custom-fields.d.ts +4 -4
  35. package/dist/effect/custom-fields.js +19 -2
  36. package/dist/effect/email.d.ts +75 -75
  37. package/dist/effect/email.js +140 -2
  38. package/dist/effect/errors.d.ts +2 -0
  39. package/dist/effect/errors.js +3 -0
  40. package/dist/effect/events.d.ts +2 -2
  41. package/dist/effect/events.js +17 -3
  42. package/dist/effect/extension-installations.d.ts +11 -11
  43. package/dist/effect/extension-installations.js +29 -2
  44. package/dist/effect/extensions.d.ts +9 -9
  45. package/dist/effect/extensions.js +21 -2
  46. package/dist/effect/feedback.d.ts +1 -1
  47. package/dist/effect/feedback.js +14 -3
  48. package/dist/{analytics-CaqPRsry.js → effect/generated/analytics.js} +4 -23
  49. package/dist/{api-keys-Ce1Y4_Ip.js → effect/generated/api-keys.js} +4 -29
  50. package/dist/{attachments-DYqVIraC.js → effect/generated/attachments.js} +3 -18
  51. package/dist/{brands-ZwuOGIWO.js → effect/generated/brands.js} +5 -25
  52. package/dist/{campaigns-DZlz1E9E.js → effect/generated/campaigns.js} +4 -35
  53. package/dist/effect/generated/contact-events.js +37 -0
  54. package/dist/{contact-groups-BLbFXnjq.js → effect/generated/contact-groups.js} +3 -30
  55. package/dist/{contacts-BbsoXXB4.js → effect/generated/contacts.js} +3 -81
  56. package/dist/{conversations-_sRHueML.js → effect/generated/conversations.js} +3 -36
  57. package/dist/{custom-fields-BHWbwlKn.js → effect/generated/custom-fields.js} +5 -19
  58. package/dist/{email-R0NAA9PW.js → effect/generated/email.js} +995 -1146
  59. package/dist/{events-CxbTUHYT.js → effect/generated/events.js} +3 -15
  60. package/dist/{extension-installations-CD94LPmk.js → effect/generated/extension-installations.js} +4 -29
  61. package/dist/{extensions-BKyNQLvu.js → effect/generated/extensions.js} +3 -20
  62. package/dist/{feedback-Bpa09JOS.js → effect/generated/feedback.js} +3 -12
  63. package/dist/{journeys-CARo_BJT.js → effect/generated/journeys.js} +3 -38
  64. package/dist/{mailboxes-BRDn7BIK.js → effect/generated/mailboxes.js} +793 -951
  65. package/dist/{media-VrrtNnft.js → effect/generated/media.js} +3 -3
  66. package/dist/effect/generated/messages.js +671 -0
  67. package/dist/{namespaces-CcvEbG-y.js → effect/generated/namespaces.js} +3 -20
  68. package/dist/{operations-CmB3FHwf.js → effect/generated/operations.js} +3 -16
  69. package/dist/{organizations-A-plufWc.js → effect/generated/organizations.js} +3 -24
  70. package/dist/{scheduled-messages-DkKZRRaN.js → effect/generated/scheduled-messages.js} +4 -21
  71. package/dist/effect/generated/shared.js +1053 -0
  72. package/dist/{subscriptions-DEXYtMXg.js → effect/generated/subscriptions.js} +3 -9
  73. package/dist/{templates-DZomxsG7.js → effect/generated/templates.js} +3 -78
  74. package/dist/{unsubscribe-groups-Iqk4Isf9.js → effect/generated/unsubscribe-groups.js} +5 -29
  75. package/dist/{webhooks-CPXuu8Xf.js → effect/generated/webhooks.js} +4 -34
  76. package/dist/{whoami-Ccz0jwlt.js → effect/generated/whoami.js} +5 -10
  77. package/dist/{categories-CA4XIQAb.js → effect/generated-metadata.js} +2 -94
  78. package/dist/effect/index.d.ts +1 -2
  79. package/dist/effect/index.js +32 -32
  80. package/dist/effect/internal/client.js +69 -0
  81. package/dist/effect/internal/email-sender.js +21 -0
  82. package/dist/effect/internal/mailbox-events.js +33 -0
  83. package/dist/effect/internal/operation.js +116 -0
  84. package/dist/effect/internal/send.js +56 -0
  85. package/dist/effect/journeys.d.ts +18 -18
  86. package/dist/effect/journeys.js +39 -2
  87. package/dist/effect/mailboxes.d.ts +191 -191
  88. package/dist/effect/mailboxes.js +135 -3
  89. package/dist/effect/media.d.ts +5 -5
  90. package/dist/effect/media.js +10 -10
  91. package/dist/effect/messages.d.ts +14 -14
  92. package/dist/effect/messages.js +15 -14
  93. package/dist/effect/namespaces.d.ts +7 -7
  94. package/dist/effect/namespaces.js +21 -2
  95. package/dist/effect/operations.d.ts +5 -5
  96. package/dist/effect/operations.js +17 -2
  97. package/dist/effect/organizations.d.ts +7 -7
  98. package/dist/effect/organizations.js +25 -2
  99. package/dist/effect/pagination.js +39 -0
  100. package/dist/effect/retry.js +3 -3
  101. package/dist/{runtime-P0l1_2-C.js → effect/runtime.js} +2 -2
  102. package/dist/effect/scheduled-messages.d.ts +7 -7
  103. package/dist/effect/scheduled-messages.js +21 -2
  104. package/dist/effect/subscriptions.d.ts +1 -1
  105. package/dist/effect/subscriptions.js +10 -2
  106. package/dist/effect/templates.d.ts +39 -39
  107. package/dist/effect/templates.js +80 -3
  108. package/dist/effect/unsubscribe-groups.d.ts +11 -11
  109. package/dist/effect/unsubscribe-groups.js +29 -2
  110. package/dist/effect/webhooks.d.ts +14 -14
  111. package/dist/effect/webhooks.js +35 -3
  112. package/dist/effect/whoami.d.ts +9 -9
  113. package/dist/effect/whoami.js +10 -2
  114. package/dist/index.js +4 -3
  115. package/dist/{inline-attachments-Bi1hDltp.js → inline-attachments.js} +13 -7
  116. package/dist/{mailbox-events-VKR4f3qq.js → mailbox-events.js} +2 -2
  117. package/dist/{normalize-B79uJIeb.js → normalize.js} +2 -2
  118. package/dist/package.js +6 -0
  119. package/dist/promises/errors.gen.js +1340 -0
  120. package/dist/promises/index.js +288 -3
  121. package/dist/{operation-n_IYgNVK.js → service-map.js} +2 -148
  122. package/package.json +6 -2
  123. package/dist/client-DOzUrdTE.js +0 -1115
  124. package/dist/send-Bxc0XfGE.js +0 -722
@@ -1,4 +1,289 @@
1
- import { t as MediaUploadError } from "../inline-attachments-Bi1hDltp.js";
2
- import { C as SenderNotReadyError, E as fromApiError, S as SamvaTransportError, T as ValidationError, _ as OnboardingReviewRequiredError, a as CampaignFooterRequiredError, b as ResourceNotFoundError, c as EmailChannelError, d as ForbiddenError, f as GatewayTimeoutError, g as MailboxSendRefusedError, h as MailboxSendConflictError, i as BrandAddressRequiredError, l as ExternalServiceError, m as MailboxChannelUnsupportedError, n as AnalyticsQueryError, o as ConflictError, p as InternalError, r as BillingProviderError, s as DeliveryUnavailableError, t as createClient, u as FlagDisabledError, v as PaymentRequiredError, w as UnauthorizedError, x as SamvaApiError, y as RateLimitedError } from "../promises---Kbh-7z.js";
3
- import { n as MailboxEventStreamError, t as MailboxEventStream } from "../mailbox-events-VKR4f3qq.js";
1
+ import { CLIENT_ATTRIBUTION_HEADER, clientAttribution } from "../client-attribution.js";
2
+ import { mergeHeaders } from "../client/client/utils.gen.js";
3
+ import { createClient as createClient$1 } from "../client/client/client.gen.js";
4
+ import { Analytics, ApiKeys, Attachments, Brands, Campaigns, ContactEvents, ContactGroups, Contacts, Conversations, CustomFields, Email, Events, ExtensionInstallations, Extensions, Feedback, Journeys, Mailboxes, Media, Messages, Namespaces, Operations, Organizations, ScheduledMessages, Subscriptions, Templates, Unsubscribe, Webhooks, Whoami } from "../client/sdk.gen.js";
5
+ import { MediaUploadError, mediaCreateBody, planInlineUploads, withUploadedAttachments } from "../inline-attachments.js";
6
+ import { MailboxEventStream, MailboxEventStreamError } from "../mailbox-events.js";
7
+ import { buildEmailSendPayload, buildMessagesSendPayload, replyToEmailsPayload } from "../normalize.js";
8
+ import { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, DeliveryUnavailableError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError, MailboxChannelUnsupportedError, MailboxSendConflictError, MailboxSendRefusedError, OnboardingReviewRequiredError, PaymentRequiredError, RateLimitedError, ResourceNotFoundError, SamvaApiError, SamvaTransportError, SenderNotReadyError, UnauthorizedError, ValidationError, fromApiError } from "./errors.gen.js";
9
+ //#region src/promises/index.ts
10
+ /**
11
+ * Samva SDK - TypeScript client for the Samva API.
12
+ *
13
+ * Ergonomic methods resolve with decoded success values and throw generated
14
+ * plain-JavaScript error classes. The bound Hey API result surface remains
15
+ * available under `client.raw` for transport-level access.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { createClient, RateLimitedError } from "samva";
20
+ *
21
+ * const samva = createClient({ apiKey: "<samva-api-key>" });
22
+ *
23
+ * try {
24
+ * const { contact } = await samva.contacts.findOrCreate({
25
+ * create: { name: "Ada Lovelace" },
26
+ * lookup: { type: "email", value: "ada@example.com" },
27
+ * });
28
+ * await samva.email.send({
29
+ * to: contact,
30
+ * subject: "Hello",
31
+ * html: "<p>Hi there!</p>",
32
+ * });
33
+ * } catch (error) {
34
+ * if (error instanceof RateLimitedError) console.log(error.retryAfterSeconds);
35
+ * }
36
+ * ```
37
+ */
38
+ const isObject = (value) => typeof value === "object" && value !== null;
39
+ /**
40
+ * The key a retry-safe call sends as `idempotency-key`: the `idempotencyKey`
41
+ * option, else one the caller set in `headers`, else a fresh UUID. The
42
+ * generated header parameter is applied after request headers, so it must carry
43
+ * a caller-set header value rather than overwrite it.
44
+ */
45
+ function resolveIdempotencyKey(options) {
46
+ const { idempotencyKey, ...requestOptions } = options ?? {};
47
+ return {
48
+ idempotencyKey: idempotencyKey ?? mergeHeaders(requestOptions.headers).get("idempotency-key") ?? crypto.randomUUID(),
49
+ requestOptions
50
+ };
51
+ }
52
+ /**
53
+ * Inline attachment content over the API's request cap travels as media instead: the largest
54
+ * attachments are uploaded (create, put to the presigned URL, complete) and replaced by their
55
+ * `mediaId`. The returned payload is the one request every send attempt reuses, so nothing is
56
+ * uploaded twice.
57
+ */
58
+ async function uploadOversizedAttachments(clientInstance, payload, requestOptions) {
59
+ const plan = planInlineUploads(payload);
60
+ if (plan.length === 0) return payload;
61
+ const uploaded = /* @__PURE__ */ new Map();
62
+ const directMedia = createDirectService(createBoundService(Media, clientInstance));
63
+ for (const upload of plan) {
64
+ const created = await directMedia.create(mediaCreateBody(upload), requestOptions);
65
+ await putUpload(clientInstance, upload, created, requestOptions.signal ?? void 0);
66
+ await directMedia.complete({ id: created.id }, requestOptions);
67
+ uploaded.set(upload.index, {
68
+ mediaId: created.id,
69
+ upload
70
+ });
71
+ }
72
+ return withUploadedAttachments(payload, uploaded);
73
+ }
74
+ /**
75
+ * Send with oversized inline attachments uploaded first. Within the cap this is the send call
76
+ * itself, one request and no extra await, so its result is returned unchanged.
77
+ */
78
+ function sendWithUploads(clientInstance, payload, requestOptions, send) {
79
+ if (planInlineUploads(payload).length === 0) return send(payload);
80
+ return uploadOversizedAttachments(clientInstance, payload, requestOptions).then(send);
81
+ }
82
+ async function putUpload(clientInstance, upload, created, signal) {
83
+ const fail = (status, cause) => new MediaUploadError({
84
+ filename: upload.filename,
85
+ mediaId: created.id,
86
+ status,
87
+ cause
88
+ });
89
+ let response;
90
+ try {
91
+ response = await (clientInstance.getConfig().fetch ?? globalThis.fetch)(new Request(created.upload.url, {
92
+ method: created.upload.method,
93
+ headers: created.upload.headers,
94
+ body: upload.bytes,
95
+ signal: signal ?? null
96
+ }));
97
+ } catch (error) {
98
+ throw fail(void 0, error);
99
+ }
100
+ if (!response.ok) throw fail(response.status);
101
+ }
102
+ function createPromiseMessagesTransport(clientInstance) {
103
+ const boundMessages = createBoundService(Messages, clientInstance);
104
+ return {
105
+ list: boundMessages.list,
106
+ remove: boundMessages.remove,
107
+ get: boundMessages.get,
108
+ getEmail: boundMessages.getEmail,
109
+ getStatus: boundMessages.getStatus,
110
+ getEvents: boundMessages.getEvents,
111
+ listDeliveries: boundMessages.listDeliveries,
112
+ getContent: boundMessages.getContent,
113
+ validateEmail: boundMessages.validateEmail,
114
+ send: (input, options) => {
115
+ const { idempotencyKey, requestOptions } = resolveIdempotencyKey(options);
116
+ return sendWithUploads(clientInstance, buildMessagesSendPayload(input), requestOptions, (payload) => Messages.send({
117
+ "idempotency-key": idempotencyKey,
118
+ ...payload
119
+ }, {
120
+ ...requestOptions,
121
+ client: clientInstance
122
+ }));
123
+ }
124
+ };
125
+ }
126
+ function createPromiseEmailTransport(clientInstance) {
127
+ const boundEmail = createBoundService(Email, clientInstance);
128
+ return Object.assign(boundEmail, {
129
+ addSender: (input, options) => {
130
+ const { replyToEmails, ...sender } = input;
131
+ const { idempotencyKey, requestOptions } = resolveIdempotencyKey(options);
132
+ return Email.addSender({
133
+ "idempotency-key": idempotencyKey,
134
+ ...sender,
135
+ ...replyToEmailsPayload(replyToEmails)
136
+ }, {
137
+ ...requestOptions,
138
+ client: clientInstance
139
+ });
140
+ },
141
+ send: (input, options) => {
142
+ const { idempotencyKey, requestOptions } = resolveIdempotencyKey(options);
143
+ return sendWithUploads(clientInstance, buildEmailSendPayload(input), requestOptions, (payload) => Messages.send({
144
+ "idempotency-key": idempotencyKey,
145
+ ...payload
146
+ }, {
147
+ ...requestOptions,
148
+ client: clientInstance
149
+ }));
150
+ }
151
+ });
152
+ }
153
+ function createPromiseTemplatesTransport(clientInstance) {
154
+ return createBoundService(Templates, clientInstance);
155
+ }
156
+ function createBoundService(service, clientInstance) {
157
+ const bound = {};
158
+ for (const key of Object.getOwnPropertyNames(service)) {
159
+ if (key === "length" || key === "name" || key === "prototype") continue;
160
+ const value = service[key];
161
+ if (typeof value === "function") bound[key] = value.length >= 2 ? (parameters, options) => value(parameters ?? {}, {
162
+ ...options,
163
+ client: clientInstance
164
+ }) : (options) => value({
165
+ ...options,
166
+ client: clientInstance
167
+ });
168
+ else if (isObject(value)) bound[key] = createBoundService(value, clientInstance);
169
+ else bound[key] = value;
170
+ }
171
+ return bound;
172
+ }
173
+ const directOptions = (options) => ({
174
+ ...isObject(options) ? options : {},
175
+ responseStyle: "fields",
176
+ throwOnError: false
177
+ });
178
+ async function unwrap(method, arguments_) {
179
+ let result;
180
+ try {
181
+ result = await method(...arguments_);
182
+ } catch (error) {
183
+ if (error instanceof MediaUploadError) throw error;
184
+ throw fromApiError(error);
185
+ }
186
+ if (!isObject(result)) throw new SamvaTransportError(result);
187
+ const raw = result;
188
+ const context = {
189
+ request: raw.request,
190
+ response: raw.response
191
+ };
192
+ if (raw.error !== void 0) throw fromApiError(raw.error, context);
193
+ if ("data" in raw) return raw.data;
194
+ throw new SamvaTransportError(result, context);
195
+ }
196
+ function createDirectService(service) {
197
+ const direct = {};
198
+ for (const [key, value] of Object.entries(service)) if (typeof value === "function") direct[key] = value.length >= 2 ? (parameters = {}, options = {}) => unwrap(value, [parameters, directOptions(options)]) : (options = {}) => unwrap(value, [directOptions(options)]);
199
+ else if (isObject(value)) direct[key] = createDirectService(value);
200
+ else direct[key] = value;
201
+ return direct;
202
+ }
203
+ /** Create a configured Promise client. */
204
+ function createClient(config) {
205
+ const authHeaders = config.authToken !== void 0 ? { Authorization: `Bearer ${config.authToken}` } : { "X-API-Key": config.apiKey };
206
+ const clientInstance = createClient$1({
207
+ ...config,
208
+ baseUrl: config.baseUrl ?? "https://api.samva.dev",
209
+ headers: mergeHeaders({ [CLIENT_ATTRIBUTION_HEADER]: clientAttribution("typescript-promise") }, config.headers, authHeaders),
210
+ responseStyle: "fields",
211
+ throwOnError: false
212
+ });
213
+ clientInstance.interceptors.request.use((request) => {
214
+ const headers = new Headers(request.headers);
215
+ for (const [name, value] of Object.entries(authHeaders)) headers.set(name, value);
216
+ return new Request(request, { headers });
217
+ });
218
+ const raw = {
219
+ client: clientInstance,
220
+ messages: createBoundService(Messages, clientInstance),
221
+ scheduledMessages: createBoundService(ScheduledMessages, clientInstance),
222
+ brands: createBoundService(Brands, clientInstance),
223
+ campaigns: createBoundService(Campaigns, clientInstance),
224
+ email: createBoundService(Email, clientInstance),
225
+ media: createBoundService(Media, clientInstance),
226
+ templates: createPromiseTemplatesTransport(clientInstance),
227
+ contacts: Object.assign(createBoundService(Contacts, clientInstance), createBoundService(ContactEvents, clientInstance)),
228
+ events: createBoundService(Events, clientInstance),
229
+ conversations: createBoundService(Conversations, clientInstance),
230
+ webhooks: createBoundService(Webhooks, clientInstance),
231
+ operations: createBoundService(Operations, clientInstance),
232
+ apiKeys: createBoundService(ApiKeys, clientInstance),
233
+ organizations: createBoundService(Organizations, clientInstance),
234
+ attachments: createBoundService(Attachments, clientInstance),
235
+ contactGroups: createBoundService(ContactGroups, clientInstance),
236
+ customFields: createBoundService(CustomFields, clientInstance),
237
+ subscriptions: createBoundService(Subscriptions, clientInstance),
238
+ unsubscribeGroups: createBoundService(Unsubscribe, clientInstance),
239
+ analytics: createBoundService(Analytics, clientInstance),
240
+ feedback: createBoundService(Feedback, clientInstance),
241
+ whoami: createBoundService(Whoami, clientInstance),
242
+ journeys: createBoundService(Journeys, clientInstance),
243
+ mailboxes: createBoundService(Mailboxes, clientInstance),
244
+ namespaces: createBoundService(Namespaces, clientInstance),
245
+ extensions: createBoundService(Extensions, clientInstance),
246
+ extensionInstallations: createBoundService(ExtensionInstallations, clientInstance)
247
+ };
248
+ const streamConnection = {
249
+ baseUrl: config.baseUrl ?? "https://api.samva.dev",
250
+ headers: async () => Object.fromEntries(mergeHeaders({ [CLIENT_ATTRIBUTION_HEADER]: clientAttribution("typescript-promise") }, config.headers, authHeaders).entries()),
251
+ fetch: config.fetch
252
+ };
253
+ const promiseMessages = createPromiseMessagesTransport(clientInstance);
254
+ const promiseEmail = createPromiseEmailTransport(clientInstance);
255
+ return {
256
+ raw,
257
+ messages: createDirectService(promiseMessages),
258
+ scheduledMessages: createDirectService(raw.scheduledMessages),
259
+ brands: createDirectService(raw.brands),
260
+ campaigns: createDirectService(raw.campaigns),
261
+ email: createDirectService(promiseEmail),
262
+ media: createDirectService(raw.media),
263
+ templates: createDirectService(raw.templates),
264
+ contacts: createDirectService(raw.contacts),
265
+ events: createDirectService(raw.events),
266
+ conversations: createDirectService(raw.conversations),
267
+ webhooks: createDirectService(raw.webhooks),
268
+ operations: createDirectService(raw.operations),
269
+ apiKeys: createDirectService(raw.apiKeys),
270
+ organizations: createDirectService(raw.organizations),
271
+ attachments: createDirectService(raw.attachments),
272
+ contactGroups: createDirectService(raw.contactGroups),
273
+ customFields: createDirectService(raw.customFields),
274
+ subscriptions: createDirectService(raw.subscriptions),
275
+ unsubscribeGroups: createDirectService(raw.unsubscribeGroups),
276
+ analytics: createDirectService(raw.analytics),
277
+ feedback: createDirectService(raw.feedback),
278
+ whoami: createDirectService(raw.whoami),
279
+ journeys: createDirectService(raw.journeys),
280
+ mailboxes: Object.assign(createDirectService(raw.mailboxes), { events: (options) => new MailboxEventStream(streamConnection, options) }),
281
+ namespaces: createDirectService(raw.namespaces),
282
+ extensions: createDirectService(raw.extensions),
283
+ extensionInstallations: createDirectService(raw.extensionInstallations)
284
+ };
285
+ }
286
+ //#endregion
4
287
  export { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, DeliveryUnavailableError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError, MailboxChannelUnsupportedError, MailboxEventStream, MailboxEventStreamError, MailboxSendConflictError, MailboxSendRefusedError, MediaUploadError, OnboardingReviewRequiredError, PaymentRequiredError, RateLimitedError, ResourceNotFoundError, SamvaApiError, SamvaTransportError, SenderNotReadyError, UnauthorizedError, ValidationError, createClient, fromApiError };
288
+
289
+ //# sourceMappingURL=index.js.map
@@ -1,7 +1,3 @@
1
- import { t as Service } from "./client-DOzUrdTE.js";
2
- import { y as SamvaOperations } from "./categories-CA4XIQAb.js";
3
- import { withRetry } from "./effect/retry.js";
4
- import { Effect, Option, Predicate, Stream } from "effect";
5
1
  //#region src/service-map.ts
6
2
  /** How each generated Effect operation is adapted to the Promise facade's direct input shape. */
7
3
  const SDK_OPERATION_CALLS = {
@@ -1050,148 +1046,6 @@ const SDK_OPERATION_CALLS = {
1050
1046
  }
1051
1047
  };
1052
1048
  //#endregion
1053
- //#region src/effect/pagination.ts
1054
- /**
1055
- * Stream pagination for the Effect SDK.
1056
- *
1057
- * Every list operation whose success value is a page envelope gains `.pages()`
1058
- * and `.items()` companions on its domain operation. `.pages()` streams the raw
1059
- * envelopes; `.items()` flattens them into a stream of items. Every list pages
1060
- * by cursor, `{ items, nextCursor }`: each step passes the previous page's
1061
- * `nextCursor` as `cursor`, and the walk stops at a null `nextCursor`.
1062
- *
1063
- * The traversal is **lazy**: built on `Stream.paginate` (a pull-based source),
1064
- * so each page is fetched only as the stream is consumed — `Stream.take(n)`
1065
- * stops requesting further pages. Caller params (the start `cursor`,
1066
- * `limit`, filters) are respected; only the position is advanced per step.
1067
- *
1068
- * Retry is **not** re-applied here: the underlying domain operation is already
1069
- * wrapped in the ambient {@link import("./retry").Service} policy (reads are
1070
- * retry-safe), so each page fetch retries on its own and pagination composes
1071
- * with retry instead of nesting retries.
1072
- */
1073
- /** Honor a caller-supplied start `cursor`; default to the first page otherwise. */
1074
- const startCursorOf = (input) => {
1075
- const cursor = input?.cursor;
1076
- return typeof cursor === "string" ? cursor : void 0;
1077
- };
1078
- /** Fetch the page at `cursor`, preserving all other caller params. */
1079
- const fetchCursorPage = (operation, input, cursor) => operation({
1080
- ...input,
1081
- cursor
1082
- });
1083
- /** Stream the raw cursor page envelopes, one per request, from the caller's start cursor. */
1084
- const streamCursorPages = (operation, input) => Stream.paginate(startCursorOf(input), (cursor) => fetchCursorPage(operation, input, cursor).pipe(Effect.map((result) => [[result], Option.fromNullishOr(result.nextCursor)])));
1085
- /** Stream individual items across cursor pages, fetching the next page only when pulled. */
1086
- const streamCursorItems = (operation, input) => Stream.paginate(startCursorOf(input), (cursor) => fetchCursorPage(operation, input, cursor).pipe(Effect.map((result) => [result.items, Option.fromNullishOr(result.nextCursor)])));
1087
- //#endregion
1088
- //#region src/effect/internal/operation.ts
1089
- const READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
1090
- const MODULE_NAMES = {
1091
- analytics: "Analytics",
1092
- apiKeys: "ApiKeys",
1093
- attachments: "Attachments",
1094
- brands: "Brands",
1095
- campaigns: "Campaigns",
1096
- contactGroups: "ContactGroups",
1097
- contacts: "Contacts",
1098
- conversations: "Conversations",
1099
- customFields: "CustomFields",
1100
- email: "Email",
1101
- extensions: "Extensions",
1102
- feedback: "Feedback",
1103
- mailboxes: "Mailboxes",
1104
- media: "Media",
1105
- messages: "Messages",
1106
- namespaces: "Namespaces",
1107
- operations: "Operations",
1108
- organizations: "Organizations",
1109
- scheduledMessages: "ScheduledMessages",
1110
- templates: "Templates",
1111
- unsubscribe: "UnsubscribeGroups",
1112
- webhooks: "Webhooks",
1113
- whoami: "Whoami"
1114
- };
1115
- const traceName = (operationName) => {
1116
- for (const [prefix, moduleName] of Object.entries(MODULE_NAMES)) {
1117
- if (!operationName.startsWith(prefix)) continue;
1118
- const method = operationName.slice(prefix.length);
1119
- return `${moduleName}.${method[0].toLowerCase()}${method.slice(1)}`;
1120
- }
1121
- return `Samva.${operationName}`;
1122
- };
1123
- const stripUndefined = (input) => {
1124
- if (!Predicate.isObject(input)) return input;
1125
- if (Array.isArray(input)) return input.map(stripUndefined);
1126
- if (Object.getPrototypeOf(input) !== Object.prototype) return input;
1127
- return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0).map(([key, value]) => [key, stripUndefined(value)]));
1128
- };
1129
- const adapt = (operationName, rawCall, input) => {
1130
- const descriptor = SDK_OPERATION_CALLS[operationName];
1131
- const call = READ_METHODS.has(SamvaOperations[operationName].method) ? (request) => withRetry(rawCall(request)) : rawCall;
1132
- if (descriptor.kind === "none") return call();
1133
- if (descriptor.kind === "params") return call({ query: stripUndefined(input) });
1134
- if (descriptor.kind === "payload") return call({ payload: stripUndefined(input) });
1135
- if (descriptor.kind === "idempotentPayload") {
1136
- const { idempotencyKey, ...payload } = input;
1137
- return call({
1138
- headers: { "idempotency-key": idempotencyKey },
1139
- payload: stripUndefined(payload)
1140
- });
1141
- }
1142
- const pathDescriptor = descriptor;
1143
- const inputRecord = input ?? {};
1144
- const params = {};
1145
- for (const path of pathDescriptor.paths) {
1146
- if (inputRecord[path] === void 0) return Effect.die(/* @__PURE__ */ new Error(`${operationName} requires path field ${path}`));
1147
- params[path] = inputRecord[path];
1148
- }
1149
- if (pathDescriptor.kind === "path") return call({ params });
1150
- if (pathDescriptor.kind === "idempotentPath") return call({
1151
- params,
1152
- headers: { "idempotency-key": inputRecord.idempotencyKey }
1153
- });
1154
- const optionalKeyHeaders = { headers: inputRecord.idempotencyKey === void 0 ? {} : { "idempotency-key": inputRecord.idempotencyKey } };
1155
- if (pathDescriptor.kind === "optionalIdempotentPath") return call({
1156
- params,
1157
- ...optionalKeyHeaders
1158
- });
1159
- const headerKey = pathDescriptor.kind === "optionalIdempotentPathPayload";
1160
- const remainingInput = stripUndefined(Object.fromEntries(Object.entries(inputRecord).filter(([key]) => !pathDescriptor.paths.includes(key) && !(headerKey && key === "idempotencyKey"))));
1161
- if (pathDescriptor.kind === "optionalIdempotentPathPayload") return call({
1162
- params,
1163
- payload: remainingInput,
1164
- ...optionalKeyHeaders
1165
- });
1166
- return call({
1167
- params,
1168
- [pathDescriptor.kind === "pathParams" ? "query" : "payload"]: remainingInput
1169
- });
1170
- };
1171
- const isCursorPageEnvelope = (value) => Predicate.isObject(value) && Array.isArray(value.items) && (value.nextCursor === null || typeof value.nextCursor === "string");
1172
- /**
1173
- * Operation factory for one API group. Each domain module binds its own group, so importing it
1174
- * loads that group's schemas and nothing else.
1175
- */
1176
- const forGroup = (group) => (operationName) => {
1177
- if (SamvaOperations[operationName].group !== group.identifier) throw new Error(`${operationName} is not an endpoint of ${group.identifier}`);
1178
- return make(group, operationName);
1179
- };
1180
- /** Call one endpoint with an already-shaped request, outside the direct-operation adapter. */
1181
- const callEndpoint = (group, name, request) => Effect.flatMap(Service, (client) => Effect.flatMap(client.endpoint(group, name), (call) => call(request)));
1182
- const make = (group, operationName) => {
1183
- const call = Effect.fn(traceName(operationName))((input) => Effect.flatMap(Service, (client) => Effect.flatMap(client.endpoint(group, operationName), (rawCall) => adapt(operationName, rawCall, input))));
1184
- const operation = call;
1185
- if (SamvaOperations[operationName].paginated) {
1186
- const list = (input) => Effect.filterOrElse(call(input), isCursorPageEnvelope, () => Effect.die(/* @__PURE__ */ new Error(`${operationName} did not return a cursor page envelope`)));
1187
- Object.assign(operation, {
1188
- pages: (input) => streamCursorPages(list, input ?? {}),
1189
- items: (input) => streamCursorItems(list, input ?? {})
1190
- });
1191
- }
1192
- return operation;
1193
- };
1194
- //#endregion
1195
- export { forGroup as n, stripUndefined as r, callEndpoint as t };
1049
+ export { SDK_OPERATION_CALLS };
1196
1050
 
1197
- //# sourceMappingURL=operation-n_IYgNVK.js.map
1051
+ //# sourceMappingURL=service-map.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "samva",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "description": "TypeScript SDK for the Samva email API",
5
5
  "keywords": [
6
6
  "api-client",
@@ -47,6 +47,10 @@
47
47
  "types": "./dist/effect/index.d.ts",
48
48
  "import": "./dist/effect/index.js"
49
49
  },
50
+ "./effect/errors": {
51
+ "types": "./dist/effect/errors.d.ts",
52
+ "import": "./dist/effect/errors.js"
53
+ },
50
54
  "./effect/categories": {
51
55
  "types": "./dist/effect/categories.d.ts",
52
56
  "import": "./dist/effect/categories.js"
@@ -196,7 +200,7 @@
196
200
  "typecheck": "tsc --noEmit && tsc --noEmit -p codegen/tsconfig.json && tsc --noEmit -p tests/tsconfig.json"
197
201
  },
198
202
  "dependencies": {
199
- "@samva/webhooks": "0.17.0"
203
+ "@samva/webhooks": "0.18.0"
200
204
  },
201
205
  "devDependencies": {
202
206
  "@effect/openapi-generator": "4.0.0",