samva 0.16.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 (167) hide show
  1. package/AGENTS.md +9 -1
  2. package/README.md +57 -1
  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/client/sdk.gen.d.ts +174 -3
  14. package/dist/{promises-KrA2nSLg.js → client/sdk.gen.js} +464 -2289
  15. package/dist/client/types.gen.d.ts +1126 -11
  16. package/dist/client-attribution.js +9 -0
  17. package/dist/effect/analytics.d.ts +6 -6
  18. package/dist/effect/analytics.js +11 -9
  19. package/dist/effect/api-keys.d.ts +13 -13
  20. package/dist/effect/api-keys.js +13 -12
  21. package/dist/effect/attachments.d.ts +4 -4
  22. package/dist/effect/attachments.js +9 -7
  23. package/dist/effect/brands.d.ts +7 -7
  24. package/dist/effect/brands.js +12 -10
  25. package/dist/effect/campaigns.d.ts +18 -18
  26. package/dist/effect/campaigns.js +17 -15
  27. package/dist/effect/categories.d.ts +2 -2
  28. package/dist/effect/categories.js +95 -1
  29. package/dist/effect/client.d.ts +1 -1
  30. package/dist/effect/client.js +4 -5
  31. package/dist/effect/contact-groups.d.ts +14 -14
  32. package/dist/effect/contact-groups.js +15 -13
  33. package/dist/effect/contacts.d.ts +77 -25
  34. package/dist/effect/contacts.js +27 -22
  35. package/dist/effect/conversations.d.ts +17 -17
  36. package/dist/effect/conversations.js +18 -16
  37. package/dist/effect/custom-fields.d.ts +4 -4
  38. package/dist/effect/custom-fields.js +9 -7
  39. package/dist/effect/email.d.ts +78 -77
  40. package/dist/effect/email.js +68 -65
  41. package/dist/effect/errors.d.ts +2 -0
  42. package/dist/effect/errors.js +3 -0
  43. package/dist/effect/events.d.ts +121 -0
  44. package/dist/effect/events.js +17 -0
  45. package/dist/effect/extension-installations.d.ts +11 -11
  46. package/dist/effect/extension-installations.js +14 -12
  47. package/dist/effect/extensions.d.ts +9 -9
  48. package/dist/effect/extensions.js +10 -8
  49. package/dist/effect/feedback.d.ts +2 -2
  50. package/dist/effect/feedback.js +6 -5
  51. package/dist/effect/generated/analytics.d.ts +715 -0
  52. package/dist/effect/generated/analytics.js +188 -0
  53. package/dist/effect/generated/api-keys.d.ts +1627 -0
  54. package/dist/effect/generated/api-keys.js +249 -0
  55. package/dist/effect/generated/attachments.d.ts +554 -0
  56. package/dist/effect/generated/attachments.js +125 -0
  57. package/dist/effect/generated/brands.d.ts +1118 -0
  58. package/dist/effect/generated/brands.js +155 -0
  59. package/dist/effect/generated/campaigns.d.ts +3783 -0
  60. package/dist/effect/generated/campaigns.js +491 -0
  61. package/dist/effect/generated/contact-events.d.ts +158 -0
  62. package/dist/effect/generated/contact-events.js +37 -0
  63. package/dist/effect/generated/contact-groups.d.ts +1445 -0
  64. package/dist/effect/generated/contact-groups.js +419 -0
  65. package/dist/effect/generated/contacts.d.ts +3789 -0
  66. package/dist/effect/generated/contacts.js +709 -0
  67. package/dist/effect/generated/conversations.d.ts +2870 -0
  68. package/dist/effect/generated/conversations.js +461 -0
  69. package/dist/effect/generated/custom-fields.d.ts +562 -0
  70. package/dist/effect/generated/custom-fields.js +162 -0
  71. package/dist/effect/generated/email.d.ts +10622 -0
  72. package/dist/effect/generated/email.js +2347 -0
  73. package/dist/effect/generated/events.d.ts +463 -0
  74. package/dist/effect/generated/events.js +70 -0
  75. package/dist/effect/generated/extension-installations.d.ts +1786 -0
  76. package/dist/effect/generated/extension-installations.js +382 -0
  77. package/dist/effect/generated/extensions.d.ts +927 -0
  78. package/dist/effect/generated/extensions.js +203 -0
  79. package/dist/effect/generated/feedback.d.ts +116 -0
  80. package/dist/effect/generated/feedback.js +43 -0
  81. package/dist/effect/generated/index.d.ts +61 -0
  82. package/dist/effect/generated/journeys.d.ts +6135 -0
  83. package/dist/effect/generated/journeys.js +464 -0
  84. package/dist/effect/generated/mailboxes.d.ts +13641 -0
  85. package/dist/effect/generated/mailboxes.js +2312 -0
  86. package/dist/effect/generated/media.d.ts +741 -0
  87. package/dist/effect/generated/media.js +181 -0
  88. package/dist/effect/generated/messages.d.ts +2355 -0
  89. package/dist/effect/generated/messages.js +671 -0
  90. package/dist/effect/generated/namespaces.d.ts +654 -0
  91. package/dist/effect/generated/namespaces.js +135 -0
  92. package/dist/effect/generated/operations.d.ts +514 -0
  93. package/dist/effect/generated/operations.js +80 -0
  94. package/dist/effect/generated/organizations.d.ts +1111 -0
  95. package/dist/effect/generated/organizations.js +231 -0
  96. package/dist/effect/generated/scheduled-messages.d.ts +1798 -0
  97. package/dist/effect/generated/scheduled-messages.js +190 -0
  98. package/dist/effect/generated/shared.d.ts +3250 -0
  99. package/dist/effect/generated/shared.js +1053 -0
  100. package/dist/effect/generated/subscriptions.d.ts +188 -0
  101. package/dist/effect/generated/subscriptions.js +61 -0
  102. package/dist/effect/generated/templates.d.ts +8177 -0
  103. package/dist/effect/generated/templates.js +2214 -0
  104. package/dist/effect/generated/unsubscribe-groups.d.ts +1153 -0
  105. package/dist/effect/generated/unsubscribe-groups.js +267 -0
  106. package/dist/effect/generated/webhooks.d.ts +1697 -0
  107. package/dist/effect/generated/webhooks.js +500 -0
  108. package/dist/effect/generated/whoami.d.ts +291 -0
  109. package/dist/effect/generated/whoami.js +54 -0
  110. package/dist/effect/generated-metadata.d.ts +1627 -0
  111. package/dist/effect/generated-metadata.js +919 -0
  112. package/dist/effect/index.d.ts +3 -2
  113. package/dist/effect/index.js +33 -31
  114. package/dist/effect/internal/client.d.ts +10 -7
  115. package/dist/effect/internal/client.js +69 -0
  116. package/dist/effect/internal/email-sender.d.ts +17 -0
  117. package/dist/effect/internal/email-sender.js +21 -0
  118. package/dist/effect/internal/mailbox-events.js +33 -0
  119. package/dist/effect/internal/operation.d.ts +12 -72
  120. package/dist/effect/internal/operation.js +116 -0
  121. package/dist/effect/internal/send.d.ts +60 -0
  122. package/dist/effect/internal/send.js +56 -0
  123. package/dist/effect/journeys.d.ts +2153 -0
  124. package/dist/effect/journeys.js +39 -0
  125. package/dist/effect/mailboxes.d.ts +80 -80
  126. package/dist/effect/mailboxes.js +135 -3
  127. package/dist/effect/media.d.ts +5 -5
  128. package/dist/effect/media.js +10 -8
  129. package/dist/effect/messages.d.ts +16 -16
  130. package/dist/effect/messages.js +15 -12
  131. package/dist/effect/namespaces.d.ts +7 -7
  132. package/dist/effect/namespaces.js +10 -8
  133. package/dist/effect/operations.d.ts +5 -5
  134. package/dist/effect/operations.js +8 -6
  135. package/dist/effect/organizations.d.ts +7 -7
  136. package/dist/effect/organizations.js +12 -10
  137. package/dist/effect/pagination.js +39 -0
  138. package/dist/effect/retry.js +3 -3
  139. package/dist/effect/runtime.js +25 -0
  140. package/dist/effect/scheduled-messages.d.ts +7 -7
  141. package/dist/effect/scheduled-messages.js +10 -8
  142. package/dist/effect/subscriptions.d.ts +1 -1
  143. package/dist/effect/subscriptions.js +5 -4
  144. package/dist/effect/templates.d.ts +40 -40
  145. package/dist/effect/templates.js +39 -37
  146. package/dist/effect/unsubscribe-groups.d.ts +11 -11
  147. package/dist/effect/unsubscribe-groups.js +14 -12
  148. package/dist/effect/webhooks.d.ts +23 -23
  149. package/dist/effect/webhooks.js +16 -14
  150. package/dist/effect/whoami.d.ts +1 -1
  151. package/dist/effect/whoami.js +5 -4
  152. package/dist/index.js +4 -3
  153. package/dist/{inline-attachments-Cegg6tTF.js → inline-attachments.js} +13 -7
  154. package/dist/{mailbox-events-VKR4f3qq.js → mailbox-events.js} +2 -2
  155. package/dist/{normalize-B79uJIeb.js → normalize.js} +2 -2
  156. package/dist/package.js +6 -0
  157. package/dist/promises/errors.gen.js +1340 -0
  158. package/dist/promises/index.d.ts +7 -3
  159. package/dist/promises/index.js +288 -3
  160. package/dist/promises/types.gen.d.ts +1 -1
  161. package/dist/service-map.d.ts +85 -0
  162. package/dist/{operation-BTXjPrwf.js → service-map.js} +58 -219
  163. package/package.json +17 -3
  164. package/dist/categories-DV51kr2H.js +0 -187
  165. package/dist/client-BMUew5Wp.js +0 -13794
  166. package/dist/effect/generated.d.ts +0 -64004
  167. package/dist/mailboxes-Thp5z0oX.js +0 -161
@@ -82,6 +82,7 @@ export declare const SDK_SERVICE_OPERATIONS: {
82
82
  readonly export: "contactsExport";
83
83
  readonly getActivityTimeline: "contactsGetActivityTimeline";
84
84
  readonly getGroupMemberships: "contactsGetGroupMemberships";
85
+ readonly listEvents: "contactEventsListEvents";
85
86
  };
86
87
  readonly conversations: {
87
88
  readonly list: "conversationsList";
@@ -169,9 +170,29 @@ export declare const SDK_SERVICE_OPERATIONS: {
169
170
  readonly updateForwardingRule: "emailUpdateForwardingRule";
170
171
  readonly getForwardingLog: "emailGetForwardingLog";
171
172
  };
173
+ readonly events: {
174
+ readonly create: "eventsCreate";
175
+ readonly batch: "eventsBatch";
176
+ };
172
177
  readonly feedback: {
173
178
  readonly send: "feedbackSend";
174
179
  };
180
+ readonly journeys: {
181
+ readonly list: "journeysList";
182
+ readonly create: "journeysCreate";
183
+ readonly get: "journeysGet";
184
+ readonly update: "journeysUpdate";
185
+ readonly remove: "journeysRemove";
186
+ readonly replaceDraft: "journeysReplaceDraft";
187
+ readonly publish: "journeysPublish";
188
+ readonly pause: "journeysPause";
189
+ readonly resume: "journeysResume";
190
+ readonly archive: "journeysArchive";
191
+ readonly getVersion: "journeysGetVersion";
192
+ readonly stats: "journeysStats";
193
+ readonly listRuns: "journeysListRuns";
194
+ readonly getRun: "journeysGetRun";
195
+ };
175
196
  readonly messages: {
176
197
  readonly list: "messagesList";
177
198
  readonly send: "messagesSend";
@@ -793,6 +814,70 @@ export declare const SDK_OPERATION_CALLS: {
793
814
  readonly kind: "pathPayload";
794
815
  readonly paths: readonly ["id"];
795
816
  };
817
+ readonly journeysList: {
818
+ readonly kind: "params";
819
+ };
820
+ readonly journeysCreate: {
821
+ readonly kind: "payload";
822
+ };
823
+ readonly journeysGet: {
824
+ readonly kind: "path";
825
+ readonly paths: readonly ["id"];
826
+ };
827
+ readonly journeysUpdate: {
828
+ readonly kind: "pathPayload";
829
+ readonly paths: readonly ["id"];
830
+ };
831
+ readonly journeysRemove: {
832
+ readonly kind: "path";
833
+ readonly paths: readonly ["id"];
834
+ };
835
+ readonly journeysReplaceDraft: {
836
+ readonly kind: "pathPayload";
837
+ readonly paths: readonly ["id"];
838
+ };
839
+ readonly journeysPublish: {
840
+ readonly kind: "pathPayload";
841
+ readonly paths: readonly ["id"];
842
+ };
843
+ readonly journeysPause: {
844
+ readonly kind: "path";
845
+ readonly paths: readonly ["id"];
846
+ };
847
+ readonly journeysResume: {
848
+ readonly kind: "path";
849
+ readonly paths: readonly ["id"];
850
+ };
851
+ readonly journeysArchive: {
852
+ readonly kind: "path";
853
+ readonly paths: readonly ["id"];
854
+ };
855
+ readonly journeysGetVersion: {
856
+ readonly kind: "path";
857
+ readonly paths: readonly ["id", "version"];
858
+ };
859
+ readonly journeysStats: {
860
+ readonly kind: "pathParams";
861
+ readonly paths: readonly ["id"];
862
+ };
863
+ readonly journeysListRuns: {
864
+ readonly kind: "pathParams";
865
+ readonly paths: readonly ["id"];
866
+ };
867
+ readonly journeysGetRun: {
868
+ readonly kind: "path";
869
+ readonly paths: readonly ["id", "runId"];
870
+ };
871
+ readonly eventsCreate: {
872
+ readonly kind: "payload";
873
+ };
874
+ readonly eventsBatch: {
875
+ readonly kind: "payload";
876
+ };
877
+ readonly contactEventsListEvents: {
878
+ readonly kind: "pathParams";
879
+ readonly paths: readonly ["id"];
880
+ };
796
881
  readonly contactsList: {
797
882
  readonly kind: "params";
798
883
  };
@@ -1,8 +1,3 @@
1
- import { a as withUploadedAttachments, n as mediaCreateBody, r as planInlineUploads } from "./inline-attachments-Cegg6tTF.js";
2
- import { n as buildMessagesSendPayload, r as replyToEmailsPayload, t as buildEmailSendPayload } from "./normalize-B79uJIeb.js";
3
- import { k as SamvaApi, t as Service } from "./client-BMUew5Wp.js";
4
- import { generateIdempotencyKey, withRetry } from "./effect/retry.js";
5
- import { Effect, Option, Predicate, Stream } from "effect";
6
1
  //#region src/service-map.ts
7
2
  /** How each generated Effect operation is adapted to the Promise facade's direct input shape. */
8
3
  const SDK_OPERATION_CALLS = {
@@ -359,6 +354,62 @@ const SDK_OPERATION_CALLS = {
359
354
  kind: "pathPayload",
360
355
  paths: ["id"]
361
356
  },
357
+ journeysList: { kind: "params" },
358
+ journeysCreate: { kind: "payload" },
359
+ journeysGet: {
360
+ kind: "path",
361
+ paths: ["id"]
362
+ },
363
+ journeysUpdate: {
364
+ kind: "pathPayload",
365
+ paths: ["id"]
366
+ },
367
+ journeysRemove: {
368
+ kind: "path",
369
+ paths: ["id"]
370
+ },
371
+ journeysReplaceDraft: {
372
+ kind: "pathPayload",
373
+ paths: ["id"]
374
+ },
375
+ journeysPublish: {
376
+ kind: "pathPayload",
377
+ paths: ["id"]
378
+ },
379
+ journeysPause: {
380
+ kind: "path",
381
+ paths: ["id"]
382
+ },
383
+ journeysResume: {
384
+ kind: "path",
385
+ paths: ["id"]
386
+ },
387
+ journeysArchive: {
388
+ kind: "path",
389
+ paths: ["id"]
390
+ },
391
+ journeysGetVersion: {
392
+ kind: "path",
393
+ paths: ["id", "version"]
394
+ },
395
+ journeysStats: {
396
+ kind: "pathParams",
397
+ paths: ["id"]
398
+ },
399
+ journeysListRuns: {
400
+ kind: "pathParams",
401
+ paths: ["id"]
402
+ },
403
+ journeysGetRun: {
404
+ kind: "path",
405
+ paths: ["id", "runId"]
406
+ },
407
+ eventsCreate: { kind: "payload" },
408
+ eventsBatch: { kind: "payload" },
409
+ contactEventsListEvents: {
410
+ kind: "pathParams",
411
+ paths: ["id"]
412
+ },
362
413
  contactsList: { kind: "params" },
363
414
  contactsCreate: { kind: "payload" },
364
415
  contactsFind: { kind: "payload" },
@@ -995,218 +1046,6 @@ const SDK_OPERATION_CALLS = {
995
1046
  }
996
1047
  };
997
1048
  //#endregion
998
- //#region src/effect/pagination.ts
999
- /**
1000
- * Stream pagination for the Effect SDK.
1001
- *
1002
- * Every list operation whose success value is a page envelope gains `.pages()`
1003
- * and `.items()` companions on its domain operation. `.pages()` streams the raw
1004
- * envelopes; `.items()` flattens them into a stream of items. Every list pages
1005
- * by cursor, `{ items, nextCursor }`: each step passes the previous page's
1006
- * `nextCursor` as `cursor`, and the walk stops at a null `nextCursor`.
1007
- *
1008
- * The traversal is **lazy**: built on `Stream.paginate` (a pull-based source),
1009
- * so each page is fetched only as the stream is consumed — `Stream.take(n)`
1010
- * stops requesting further pages. Caller params (the start `cursor`,
1011
- * `limit`, filters) are respected; only the position is advanced per step.
1012
- *
1013
- * Retry is **not** re-applied here: the underlying domain operation is already
1014
- * wrapped in the ambient {@link import("./retry").Service} policy (reads are
1015
- * retry-safe), so each page fetch retries on its own and pagination composes
1016
- * with retry instead of nesting retries.
1017
- */
1018
- /** Honor a caller-supplied start `cursor`; default to the first page otherwise. */
1019
- const startCursorOf = (input) => {
1020
- const cursor = input?.cursor;
1021
- return typeof cursor === "string" ? cursor : void 0;
1022
- };
1023
- /** Fetch the page at `cursor`, preserving all other caller params. */
1024
- const fetchCursorPage = (operation, input, cursor) => operation({
1025
- ...input,
1026
- cursor
1027
- });
1028
- /** Stream the raw cursor page envelopes, one per request, from the caller's start cursor. */
1029
- const streamCursorPages = (operation, input) => Stream.paginate(startCursorOf(input), (cursor) => fetchCursorPage(operation, input, cursor).pipe(Effect.map((result) => [[result], Option.fromNullishOr(result.nextCursor)])));
1030
- /** Stream individual items across cursor pages, fetching the next page only when pulled. */
1031
- const streamCursorItems = (operation, input) => Stream.paginate(startCursorOf(input), (cursor) => fetchCursorPage(operation, input, cursor).pipe(Effect.map((result) => [result.items, Option.fromNullishOr(result.nextCursor)])));
1032
- //#endregion
1033
- //#region src/effect/internal/operation.ts
1034
- const hasField = (node, name) => node?.propertySignatures?.some((property) => property.name === name) ?? false;
1035
- const isCursorPaged = (success) => {
1036
- if (!(success instanceof Set)) return false;
1037
- for (const schema of success) for (const node of [
1038
- schema.ast,
1039
- schema.ast?.to,
1040
- schema.ast?.from
1041
- ]) if (hasField(node, "items") && hasField(node, "nextCursor")) return true;
1042
- return false;
1043
- };
1044
- const paginatedOperations = () => {
1045
- const paginated = /* @__PURE__ */ new Set();
1046
- const groups = SamvaApi.groups;
1047
- for (const group of Object.values(groups)) for (const [name, endpoint] of Object.entries(group.endpoints)) if (isCursorPaged(endpoint.success)) paginated.add(name);
1048
- return paginated;
1049
- };
1050
- const PAGINATED_OPERATIONS = paginatedOperations();
1051
- const READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
1052
- const readOperations = () => {
1053
- const reads = /* @__PURE__ */ new Set();
1054
- const groups = SamvaApi.groups;
1055
- for (const group of Object.values(groups)) for (const [name, endpoint] of Object.entries(group.endpoints)) if (READ_METHODS.has(endpoint.method)) reads.add(name);
1056
- return reads;
1057
- };
1058
- const READ_OPERATIONS = readOperations();
1059
- const MODULE_NAMES = {
1060
- analytics: "Analytics",
1061
- apiKeys: "ApiKeys",
1062
- attachments: "Attachments",
1063
- brands: "Brands",
1064
- campaigns: "Campaigns",
1065
- contactGroups: "ContactGroups",
1066
- contacts: "Contacts",
1067
- conversations: "Conversations",
1068
- customFields: "CustomFields",
1069
- email: "Email",
1070
- extensions: "Extensions",
1071
- feedback: "Feedback",
1072
- mailboxes: "Mailboxes",
1073
- media: "Media",
1074
- messages: "Messages",
1075
- namespaces: "Namespaces",
1076
- operations: "Operations",
1077
- organizations: "Organizations",
1078
- scheduledMessages: "ScheduledMessages",
1079
- templates: "Templates",
1080
- unsubscribe: "UnsubscribeGroups",
1081
- webhooks: "Webhooks",
1082
- whoami: "Whoami"
1083
- };
1084
- const traceName = (operationName) => {
1085
- for (const [prefix, moduleName] of Object.entries(MODULE_NAMES)) {
1086
- if (!operationName.startsWith(prefix)) continue;
1087
- const method = operationName.slice(prefix.length);
1088
- return `${moduleName}.${method[0].toLowerCase()}${method.slice(1)}`;
1089
- }
1090
- return `Samva.${operationName}`;
1091
- };
1092
- const stripUndefined = (input) => {
1093
- if (!Predicate.isObject(input)) return input;
1094
- if (Array.isArray(input)) return input.map(stripUndefined);
1095
- if (Object.getPrototypeOf(input) !== Object.prototype) return input;
1096
- return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0).map(([key, value]) => [key, stripUndefined(value)]));
1097
- };
1098
- const rawOperation = (client, name) => client.operation(name);
1099
- const adapt = (operationName, rawCall, input) => {
1100
- const descriptor = SDK_OPERATION_CALLS[operationName];
1101
- const call = READ_OPERATIONS.has(operationName) ? (request) => withRetry(rawCall(request)) : rawCall;
1102
- if (descriptor.kind === "none") return call();
1103
- if (descriptor.kind === "params") return call({ query: stripUndefined(input) });
1104
- if (descriptor.kind === "payload") return call({ payload: stripUndefined(input) });
1105
- if (descriptor.kind === "idempotentPayload") {
1106
- const { idempotencyKey, ...payload } = input;
1107
- return call({
1108
- headers: { "idempotency-key": idempotencyKey },
1109
- payload: stripUndefined(payload)
1110
- });
1111
- }
1112
- const pathDescriptor = descriptor;
1113
- const inputRecord = input ?? {};
1114
- const params = {};
1115
- for (const path of pathDescriptor.paths) {
1116
- if (inputRecord[path] === void 0) return Effect.die(/* @__PURE__ */ new Error(`${operationName} requires path field ${path}`));
1117
- params[path] = inputRecord[path];
1118
- }
1119
- if (pathDescriptor.kind === "path") return call({ params });
1120
- if (pathDescriptor.kind === "idempotentPath") return call({
1121
- params,
1122
- headers: { "idempotency-key": inputRecord.idempotencyKey }
1123
- });
1124
- const optionalKeyHeaders = { headers: inputRecord.idempotencyKey === void 0 ? {} : { "idempotency-key": inputRecord.idempotencyKey } };
1125
- if (pathDescriptor.kind === "optionalIdempotentPath") return call({
1126
- params,
1127
- ...optionalKeyHeaders
1128
- });
1129
- const headerKey = pathDescriptor.kind === "optionalIdempotentPathPayload";
1130
- const remainingInput = stripUndefined(Object.fromEntries(Object.entries(inputRecord).filter(([key]) => !pathDescriptor.paths.includes(key) && !(headerKey && key === "idempotencyKey"))));
1131
- if (pathDescriptor.kind === "optionalIdempotentPathPayload") return call({
1132
- params,
1133
- payload: remainingInput,
1134
- ...optionalKeyHeaders
1135
- });
1136
- return call({
1137
- params,
1138
- [pathDescriptor.kind === "pathParams" ? "query" : "payload"]: remainingInput
1139
- });
1140
- };
1141
- const isCursorPageEnvelope = (value) => Predicate.isObject(value) && Array.isArray(value.items) && (value.nextCursor === null || typeof value.nextCursor === "string");
1142
- const make = (operationName) => {
1143
- const call = Effect.fn(traceName(operationName))((input) => Effect.flatMap(Service, (client) => adapt(operationName, rawOperation(client, operationName), input)));
1144
- const operation = call;
1145
- if (PAGINATED_OPERATIONS.has(operationName)) {
1146
- const list = (input) => Effect.filterOrElse(call(input), isCursorPageEnvelope, () => Effect.die(/* @__PURE__ */ new Error(`${operationName} did not return a cursor page envelope`)));
1147
- Object.assign(operation, {
1148
- pages: (input) => streamCursorPages(list, input ?? {}),
1149
- items: (input) => streamCursorItems(list, input ?? {})
1150
- });
1151
- }
1152
- return operation;
1153
- };
1154
- /**
1155
- * Inline attachment content over the API's request cap travels as media instead: the largest
1156
- * attachments are uploaded (create, put to the presigned URL, complete) and replaced by their
1157
- * `mediaId`. The returned payload is the one request every send attempt reuses, so nothing is
1158
- * uploaded twice.
1159
- */
1160
- const uploadOversizedAttachments = (client, payload) => Effect.gen(function* () {
1161
- const plan = planInlineUploads(payload);
1162
- if (plan.length === 0) return payload;
1163
- const uploaded = /* @__PURE__ */ new Map();
1164
- for (const upload of plan) {
1165
- const created = yield* rawOperation(client, "mediaCreate")({ payload: mediaCreateBody(upload) });
1166
- yield* client.putUpload({
1167
- filename: upload.filename,
1168
- mediaId: created.id,
1169
- url: created.upload.url,
1170
- method: created.upload.method,
1171
- headers: created.upload.headers,
1172
- bytes: upload.bytes
1173
- });
1174
- yield* rawOperation(client, "mediaComplete")({ params: { id: created.id } });
1175
- uploaded.set(upload.index, {
1176
- mediaId: created.id,
1177
- upload
1178
- });
1179
- }
1180
- return withUploadedAttachments(payload, uploaded);
1181
- });
1182
- const sendPayload = (payload, options) => Effect.gen(function* () {
1183
- const client = yield* Service;
1184
- const idempotencyKey = options?.idempotencyKey ?? (yield* generateIdempotencyKey);
1185
- const prepared = yield* uploadOversizedAttachments(client, payload);
1186
- return yield* withRetry(rawOperation(client, "messagesSend")({
1187
- payload: stripUndefined(prepared),
1188
- headers: { "idempotency-key": idempotencyKey }
1189
- }));
1190
- });
1191
- const sendMessage = Effect.fn("Messages.send")(function* (input, options) {
1192
- return yield* sendPayload(buildMessagesSendPayload(input), options);
1193
- });
1194
- const sendEmail = Effect.fn("Email.send")(function* (input, options) {
1195
- return yield* sendPayload(buildEmailSendPayload(input), options);
1196
- });
1197
- const addEmailSender = Effect.fn("Email.addSender")(function* (input, options) {
1198
- const client = yield* Service;
1199
- const idempotencyKey = options?.idempotencyKey ?? (yield* generateIdempotencyKey);
1200
- const { replyToEmails, ...sender } = input;
1201
- return yield* withRetry(rawOperation(client, "emailAddSender")({
1202
- headers: { "idempotency-key": idempotencyKey },
1203
- payload: stripUndefined({
1204
- ...sender,
1205
- ...replyToEmailsPayload(replyToEmails)
1206
- })
1207
- }));
1208
- });
1209
- //#endregion
1210
- export { sendMessage as i, make as n, sendEmail as r, addEmailSender as t };
1049
+ export { SDK_OPERATION_CALLS };
1211
1050
 
1212
- //# sourceMappingURL=operation-BTXjPrwf.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.16.0",
3
+ "version": "0.18.0",
4
4
  "description": "TypeScript SDK for the Samva email API",
5
5
  "keywords": [
6
6
  "api-client",
@@ -33,6 +33,7 @@
33
33
  "LICENSE"
34
34
  ],
35
35
  "type": "module",
36
+ "sideEffects": false,
36
37
  "exports": {
37
38
  ".": {
38
39
  "types": "./dist/index.d.ts",
@@ -46,6 +47,10 @@
46
47
  "types": "./dist/effect/index.d.ts",
47
48
  "import": "./dist/effect/index.js"
48
49
  },
50
+ "./effect/errors": {
51
+ "types": "./dist/effect/errors.d.ts",
52
+ "import": "./dist/effect/errors.js"
53
+ },
49
54
  "./effect/categories": {
50
55
  "types": "./dist/effect/categories.d.ts",
51
56
  "import": "./dist/effect/categories.js"
@@ -106,10 +111,18 @@
106
111
  "types": "./dist/effect/extensions.d.ts",
107
112
  "import": "./dist/effect/extensions.js"
108
113
  },
114
+ "./effect/events": {
115
+ "types": "./dist/effect/events.d.ts",
116
+ "import": "./dist/effect/events.js"
117
+ },
109
118
  "./effect/feedback": {
110
119
  "types": "./dist/effect/feedback.d.ts",
111
120
  "import": "./dist/effect/feedback.js"
112
121
  },
122
+ "./effect/journeys": {
123
+ "types": "./dist/effect/journeys.d.ts",
124
+ "import": "./dist/effect/journeys.js"
125
+ },
113
126
  "./effect/mailboxes": {
114
127
  "types": "./dist/effect/mailboxes.d.ts",
115
128
  "import": "./dist/effect/mailboxes.js"
@@ -175,18 +188,19 @@
175
188
  "prepack": "bun run build",
176
189
  "generate:openapi": "bun run scripts/openapi.ts",
177
190
  "generate:promises": "bun run codegen/generate-promises.ts && bun run scripts/generate-promise-errors.ts && oxfmt --config=../../oxfmt.config.ts src/client src/promises/errors.gen.ts src/promises/types.gen.ts",
178
- "generate:effect": "bun run codegen/generate-effect.ts && oxfmt --config=../../oxfmt.config.ts src/effect/generated.ts src/effect/generated-metadata.ts && bun run codegen/normalize-effect.ts",
191
+ "generate:effect": "bun run codegen/generate-effect.ts && oxfmt --config=../../oxfmt.config.ts src/effect/generated src/effect/generated-metadata.ts && bun run codegen/normalize-effect.ts",
179
192
  "generate": "bun generate:openapi && bun generate:promises && bun generate:effect",
180
193
  "test": "vitest run --root ../.. --project packages",
181
194
  "test:generation": "bun scripts/check-generation.ts",
182
195
  "test:packed": "bun run build && bun scripts/test-packed-consumers.ts",
183
196
  "test:tarball": "bun run build && bun scripts/check-tarball.ts",
197
+ "test:startup": "bun run build && bun scripts/check-startup.ts",
184
198
  "test:tree-shaking": "bun run build && bun scripts/check-tree-shaking.ts",
185
199
  "test:types": "tsc --noEmit --project tests/parity/tsconfig.json",
186
200
  "typecheck": "tsc --noEmit && tsc --noEmit -p codegen/tsconfig.json && tsc --noEmit -p tests/tsconfig.json"
187
201
  },
188
202
  "dependencies": {
189
- "@samva/webhooks": "0.16.0"
203
+ "@samva/webhooks": "0.18.0"
190
204
  },
191
205
  "devDependencies": {
192
206
  "@effect/openapi-generator": "4.0.0",
@@ -1,187 +0,0 @@
1
- import { Effect } from "effect";
2
- import * as Predicate$1 from "effect/Predicate";
3
- //#region src/effect/generated-metadata.ts
4
- const SamvaErrorMetadata = {
5
- AnalyticsQueryError: {
6
- categories: [],
7
- retryable: false
8
- },
9
- BillingProviderError: {
10
- categories: ["transient"],
11
- retryable: true
12
- },
13
- BrandAddressRequiredError: {
14
- categories: [],
15
- retryable: false
16
- },
17
- CampaignFooterRequiredError: {
18
- categories: [],
19
- retryable: false
20
- },
21
- ConflictError: {
22
- categories: ["conflict"],
23
- retryable: false
24
- },
25
- DeliveryUnavailableError: {
26
- categories: ["transient"],
27
- retryable: true
28
- },
29
- EmailChannelError: {
30
- categories: [],
31
- retryable: false
32
- },
33
- ExternalServiceError: {
34
- categories: ["transient"],
35
- retryable: true
36
- },
37
- FlagDisabledError: {
38
- categories: [],
39
- retryable: false
40
- },
41
- ForbiddenError: {
42
- categories: ["auth"],
43
- retryable: false
44
- },
45
- GatewayTimeoutError: {
46
- categories: ["transient"],
47
- retryable: true
48
- },
49
- InternalError: {
50
- categories: ["transient"],
51
- retryable: true
52
- },
53
- MailboxChannelUnsupportedError: {
54
- categories: [],
55
- retryable: false
56
- },
57
- MailboxSendConflictError: {
58
- categories: [],
59
- retryable: false
60
- },
61
- MailboxSendRefusedError: {
62
- categories: [],
63
- retryable: false
64
- },
65
- OnboardingReviewRequiredError: {
66
- categories: ["validation"],
67
- retryable: false
68
- },
69
- PaymentRequiredError: {
70
- categories: ["billing"],
71
- retryable: false
72
- },
73
- RateLimitedError: {
74
- categories: ["throttling", "transient"],
75
- retryable: true
76
- },
77
- ResourceNotFoundError: {
78
- categories: ["notFound"],
79
- retryable: false
80
- },
81
- SenderNotReadyError: {
82
- categories: ["transient"],
83
- retryable: true
84
- },
85
- UnauthorizedError: {
86
- categories: ["auth"],
87
- retryable: false
88
- },
89
- ValidationError: {
90
- categories: ["validation"],
91
- retryable: false
92
- }
93
- };
94
- //#endregion
95
- //#region src/effect/categories.ts
96
- /**
97
- * Semantic error-category helpers for the Effect SDK.
98
- *
99
- * Every operation's error channel carries the server's real tagged errors
100
- * ({@link import("./index").ConflictError} …). These helpers let callers catch
101
- * or test by *category* — auth, validation, throttling, transient … — without
102
- * enumerating tags, and cover the raw transport/decode errors too. The category
103
- * assignments are generated from the OpenAPI category extensions.
104
- *
105
- * @example
106
- * ```ts
107
- * import { catchAuthError, isRetryable } from "samva/effect";
108
- *
109
- * samva.messages.send(input).pipe(
110
- * catchAuthError((error) => Effect.logError(`auth failed: ${error.message}`)),
111
- * Effect.retry({ while: isRetryable }),
112
- * );
113
- * ```
114
- */
115
- const emailChannelCategories = (reason) => {
116
- switch (reason) {
117
- case "auth": return ["auth"];
118
- case "rejected": return ["validation"];
119
- case "rate_limited": return ["throttling", "transient"];
120
- case "transport": return ["transient"];
121
- default: return [];
122
- }
123
- };
124
- const categoriesOf = (error) => {
125
- if (!Predicate$1.isObject(error) || typeof error._tag !== "string") return [];
126
- if (error._tag === "EmailChannelError") return emailChannelCategories(error.reason);
127
- return SamvaErrorMetadata[error._tag]?.categories ?? [];
128
- };
129
- const hasCategory = (error, category) => categoriesOf(error).includes(category);
130
- const isRetryableError = (error) => {
131
- if (!Predicate$1.isObject(error) || typeof error._tag !== "string") return false;
132
- if (error._tag === "EmailChannelError") return categoriesOf(error).includes("transient");
133
- return SamvaErrorMetadata[error._tag]?.retryable ?? false;
134
- };
135
- const categoryGuard = (category) => (error) => hasCategory(error, category);
136
- const isAuthError = categoryGuard("auth");
137
- const isValidationError = categoryGuard("validation");
138
- const isNotFoundError = categoryGuard("notFound");
139
- const isConflictError = categoryGuard("conflict");
140
- const isThrottlingError = categoryGuard("throttling");
141
- const isBillingError = categoryGuard("billing");
142
- /**
143
- * Network-level request failure (no HTTP response). Only `TransportError` is
144
- * transient/retryable: `EncodeError` and `InvalidUrlError` are deterministic
145
- * programmer errors (bad input, bad URL) that would fail identically on every
146
- * attempt — retrying them would loop forever.
147
- */
148
- const isRequestTransportError = (error) => {
149
- if (!Predicate$1.isTagged(error, "HttpClientError")) return false;
150
- const reason = error.reason;
151
- return Predicate$1.isObject(reason) && Predicate$1.isTagged(reason, "TransportError");
152
- };
153
- /** True for transient failures, including raw request-transport errors. */
154
- const isTransient = (error) => hasCategory(error, "transient") || isRequestTransportError(error);
155
- /** True when an error is declared safe to retry (throttling / transient / transport). */
156
- const isRetryable = (error) => isRetryableError(error) || isRequestTransportError(error);
157
- /**
158
- * Catch every error in `category`. The handler receives the category's error
159
- * union — including `EmailChannelError` where its `reason` can place it in the
160
- * category — while only total-membership classes are narrowed out of the error
161
- * channel (`EmailChannelError` stays: instances with other reasons pass through).
162
- */
163
- const catchCategory = (category, handler) => (effect) => {
164
- const inCategory = (error) => hasCategory(error, category);
165
- const outsideCategory = (error) => !hasCategory(error, category);
166
- return Effect.catch(effect, (error) => {
167
- if (inCategory(error)) return handler(error);
168
- if (outsideCategory(error)) return Effect.fail(error);
169
- return Effect.die(error);
170
- });
171
- };
172
- const catchAuthError = (handler) => catchCategory("auth", handler);
173
- const catchValidationError = (handler) => catchCategory("validation", handler);
174
- const catchNotFoundError = (handler) => catchCategory("notFound", handler);
175
- const catchConflictError = (handler) => catchCategory("conflict", handler);
176
- const catchThrottlingError = (handler) => catchCategory("throttling", handler);
177
- const catchBillingError = (handler) => catchCategory("billing", handler);
178
- /**
179
- * Catch transient failures — including raw request-transport errors — for
180
- * fallback/degrade paths. The declared error channel is left intact because
181
- * transient covers untyped transport errors as well.
182
- */
183
- const catchTransient = (handler) => (effect) => Effect.catchIf(effect, isTransient, handler);
184
- //#endregion
185
- export { isTransient as _, catchNotFoundError as a, catchValidationError as c, isAuthError as d, isBillingError as f, isThrottlingError as g, isRetryable as h, catchConflictError as i, categoriesOf as l, isNotFoundError as m, catchBillingError as n, catchThrottlingError as o, isConflictError as p, catchCategory as r, catchTransient as s, catchAuthError as t, hasCategory as u, isValidationError as v };
186
-
187
- //# sourceMappingURL=categories-DV51kr2H.js.map