samva 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/client/sdk.gen.d.ts +94 -36
- package/dist/client/sdk.gen.js +269 -55
- package/dist/client/types.gen.d.ts +497 -106
- package/dist/effect/campaigns.d.ts +35 -3
- package/dist/effect/contact-groups.d.ts +39 -3
- package/dist/effect/contacts.d.ts +240 -17
- package/dist/effect/contacts.js +3 -1
- package/dist/effect/conversations.d.ts +11 -11
- package/dist/effect/email.d.ts +22 -6
- package/dist/effect/errors.d.ts +1 -1
- package/dist/effect/errors.js +2 -2
- package/dist/effect/extension-installations.d.ts +12 -12
- package/dist/effect/extensions.d.ts +3 -3
- package/dist/effect/generated/campaigns.d.ts +73 -4
- package/dist/effect/generated/campaigns.js +18 -1
- package/dist/effect/generated/contact-groups.d.ts +33 -3
- package/dist/effect/generated/contacts.d.ts +608 -55
- package/dist/effect/generated/contacts.js +55 -10
- package/dist/effect/generated/conversations.d.ts +25 -25
- package/dist/effect/generated/conversations.js +1 -1
- package/dist/effect/generated/email.d.ts +162 -1
- package/dist/effect/generated/email.js +31 -11
- package/dist/effect/generated/extension-installations.d.ts +44 -44
- package/dist/effect/generated/extension-installations.js +6 -0
- package/dist/effect/generated/extensions.d.ts +10 -10
- package/dist/effect/generated/extensions.js +2 -0
- package/dist/effect/generated/journeys.d.ts +13 -61
- package/dist/effect/generated/journeys.js +5 -5
- package/dist/effect/generated/mailboxes.d.ts +584 -78
- package/dist/effect/generated/mailboxes.js +65 -24
- package/dist/effect/generated/messages.d.ts +35 -1
- package/dist/effect/generated/messages.js +9 -2
- package/dist/effect/generated/namespaces.d.ts +432 -2
- package/dist/effect/generated/namespaces.js +91 -4
- package/dist/effect/generated/organizations.d.ts +13 -11
- package/dist/effect/generated/organizations.js +7 -3
- package/dist/effect/generated/shared.d.ts +104 -49
- package/dist/effect/generated/shared.js +51 -28
- package/dist/effect/generated/templates.d.ts +44 -1
- package/dist/effect/generated/templates.js +9 -3
- package/dist/effect/generated/unsubscribe-groups.d.ts +173 -78
- package/dist/effect/generated/unsubscribe-groups.js +75 -58
- package/dist/effect/generated/webhooks.d.ts +19 -19
- package/dist/effect/generated/webhooks.js +8 -0
- package/dist/effect/generated-metadata.d.ts +22 -6
- package/dist/effect/generated-metadata.js +334 -329
- package/dist/effect/index.js +2 -2
- package/dist/effect/journeys.d.ts +4 -4
- package/dist/effect/mailboxes.d.ts +144 -12
- package/dist/effect/messages.d.ts +8 -0
- package/dist/effect/namespaces.d.ts +29 -0
- package/dist/effect/namespaces.js +7 -1
- package/dist/effect/organizations.d.ts +4 -4
- package/dist/effect/templates.d.ts +12 -1
- package/dist/effect/unsubscribe-groups.d.ts +29 -18
- package/dist/effect/unsubscribe-groups.js +5 -5
- package/dist/effect/webhooks.d.ts +8 -8
- package/dist/index.js +2 -2
- package/dist/mailbox-events.d.ts +31 -4
- package/dist/mailbox-events.js +39 -11
- package/dist/package.js +1 -1
- package/dist/promises/errors.gen.d.ts +2 -12
- package/dist/promises/errors.gen.js +1 -26
- package/dist/promises/index.d.ts +1 -1
- package/dist/promises/index.js +2 -2
- package/dist/promises/types.gen.d.ts +1 -1
- package/dist/service-map.d.ts +24 -4
- package/dist/service-map.js +26 -2
- package/package.json +2 -2
|
@@ -7,6 +7,7 @@ export declare const list: ((input?: {
|
|
|
7
7
|
readonly status?: "approved" | "archived" | "draft" | "pending" | "published" | "rejected" | null | undefined;
|
|
8
8
|
readonly search?: string | null | undefined;
|
|
9
9
|
readonly projectId?: string | null | undefined;
|
|
10
|
+
readonly namespaceId?: string | null | undefined;
|
|
10
11
|
} | undefined) => import("effect/Effect").Effect<{
|
|
11
12
|
readonly items: readonly {
|
|
12
13
|
readonly id: string & import("effect/Brand").Brand<"TemplateId">;
|
|
@@ -14,6 +15,7 @@ export declare const list: ((input?: {
|
|
|
14
15
|
readonly name: string;
|
|
15
16
|
readonly channel: "email";
|
|
16
17
|
readonly projectId: string & import("effect/Brand").Brand<"TemplateProjectId">;
|
|
18
|
+
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
17
19
|
readonly entryPath: string;
|
|
18
20
|
readonly status: "approved" | "archived" | "draft" | "pending" | "published" | "rejected";
|
|
19
21
|
readonly isActive: boolean;
|
|
@@ -42,6 +44,7 @@ export declare const list: ((input?: {
|
|
|
42
44
|
readonly status?: "approved" | "archived" | "draft" | "pending" | "published" | "rejected" | null | undefined;
|
|
43
45
|
readonly search?: string | null | undefined;
|
|
44
46
|
readonly projectId?: string | null | undefined;
|
|
47
|
+
readonly namespaceId?: string | null | undefined;
|
|
45
48
|
} | undefined) => import("effect/Stream").Stream<{
|
|
46
49
|
readonly items: readonly {
|
|
47
50
|
readonly id: string & import("effect/Brand").Brand<"TemplateId">;
|
|
@@ -49,6 +52,7 @@ export declare const list: ((input?: {
|
|
|
49
52
|
readonly name: string;
|
|
50
53
|
readonly channel: "email";
|
|
51
54
|
readonly projectId: string & import("effect/Brand").Brand<"TemplateProjectId">;
|
|
55
|
+
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
52
56
|
readonly entryPath: string;
|
|
53
57
|
readonly status: "approved" | "archived" | "draft" | "pending" | "published" | "rejected";
|
|
54
58
|
readonly isActive: boolean;
|
|
@@ -77,12 +81,14 @@ export declare const list: ((input?: {
|
|
|
77
81
|
readonly status?: "approved" | "archived" | "draft" | "pending" | "published" | "rejected" | null | undefined;
|
|
78
82
|
readonly search?: string | null | undefined;
|
|
79
83
|
readonly projectId?: string | null | undefined;
|
|
84
|
+
readonly namespaceId?: string | null | undefined;
|
|
80
85
|
} | undefined) => import("effect/Stream").Stream<{
|
|
81
86
|
readonly id: string & import("effect/Brand").Brand<"TemplateId">;
|
|
82
87
|
readonly slug: string;
|
|
83
88
|
readonly name: string;
|
|
84
89
|
readonly channel: "email";
|
|
85
90
|
readonly projectId: string & import("effect/Brand").Brand<"TemplateProjectId">;
|
|
91
|
+
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
86
92
|
readonly entryPath: string;
|
|
87
93
|
readonly status: "approved" | "archived" | "draft" | "pending" | "published" | "rejected";
|
|
88
94
|
readonly isActive: boolean;
|
|
@@ -111,6 +117,7 @@ export declare const create: (input: {
|
|
|
111
117
|
readonly description?: string | null | undefined;
|
|
112
118
|
readonly category?: "alert" | "marketing" | "notification" | "reminder" | "support" | "transactional" | "verification" | null | undefined;
|
|
113
119
|
readonly isActive?: boolean | null | undefined;
|
|
120
|
+
readonly namespaceId?: string | null | undefined;
|
|
114
121
|
readonly idempotencyKey: string;
|
|
115
122
|
}) => import("effect/Effect").Effect<{
|
|
116
123
|
readonly id: string & import("effect/Brand").Brand<"TemplateId">;
|
|
@@ -118,6 +125,7 @@ export declare const create: (input: {
|
|
|
118
125
|
readonly name: string;
|
|
119
126
|
readonly channel: "email";
|
|
120
127
|
readonly projectId: string & import("effect/Brand").Brand<"TemplateProjectId">;
|
|
128
|
+
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
121
129
|
readonly entryPath: string;
|
|
122
130
|
readonly status: "approved" | "archived" | "draft" | "pending" | "published" | "rejected";
|
|
123
131
|
readonly isActive: boolean;
|
|
@@ -155,7 +163,7 @@ export declare const create: (input: {
|
|
|
155
163
|
readonly inputSchema: {
|
|
156
164
|
readonly [x: string]: import("./generated").JsonValue;
|
|
157
165
|
} | null;
|
|
158
|
-
}, import("./errors").ConflictError | import("./errors").ForbiddenError | import("./errors").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./errors").InternalError | import("effect/Schema").SchemaError | import("./errors").UnauthorizedError | import("./errors").ValidationError, import("./client").Service>;
|
|
166
|
+
}, import("./errors").ConflictError | import("./errors").ForbiddenError | import("./errors").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./errors").InternalError | import("./errors").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./errors").UnauthorizedError | import("./errors").ValidationError, import("./client").Service>;
|
|
159
167
|
export declare const addEntry: (input: {
|
|
160
168
|
readonly id: string;
|
|
161
169
|
readonly entryPath: string;
|
|
@@ -169,6 +177,7 @@ export declare const addEntry: (input: {
|
|
|
169
177
|
readonly name: string;
|
|
170
178
|
readonly channel: "email";
|
|
171
179
|
readonly projectId: string & import("effect/Brand").Brand<"TemplateProjectId">;
|
|
180
|
+
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
172
181
|
readonly entryPath: string;
|
|
173
182
|
readonly status: "approved" | "archived" | "draft" | "pending" | "published" | "rejected";
|
|
174
183
|
readonly isActive: boolean;
|
|
@@ -396,6 +405,7 @@ export declare const getById: (input: {
|
|
|
396
405
|
readonly name: string;
|
|
397
406
|
readonly channel: "email";
|
|
398
407
|
readonly projectId: string & import("effect/Brand").Brand<"TemplateProjectId">;
|
|
408
|
+
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
399
409
|
readonly entryPath: string;
|
|
400
410
|
readonly status: "approved" | "archived" | "draft" | "pending" | "published" | "rejected";
|
|
401
411
|
readonly isActive: boolean;
|
|
@@ -460,6 +470,7 @@ export declare const update: (input: {
|
|
|
460
470
|
readonly name: string;
|
|
461
471
|
readonly channel: "email";
|
|
462
472
|
readonly projectId: string & import("effect/Brand").Brand<"TemplateProjectId">;
|
|
473
|
+
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
463
474
|
readonly entryPath: string;
|
|
464
475
|
readonly status: "approved" | "archived" | "draft" | "pending" | "published" | "rejected";
|
|
465
476
|
readonly isActive: boolean;
|
|
@@ -60,9 +60,8 @@ export declare const listMembers: ((input: {
|
|
|
60
60
|
readonly cursor?: string | null | undefined;
|
|
61
61
|
}) => import("effect/Effect").Effect<{
|
|
62
62
|
readonly items: readonly {
|
|
63
|
-
readonly id: string
|
|
64
|
-
readonly
|
|
65
|
-
readonly contactId: string | null;
|
|
63
|
+
readonly id: string & import("effect/Brand").Brand<"UnsubscribeGroupMemberId">;
|
|
64
|
+
readonly contactId: string & import("effect/Brand").Brand<"ContactId">;
|
|
66
65
|
readonly source: "api" | "complaint" | "link" | "manual";
|
|
67
66
|
readonly unsubscribedAt: string;
|
|
68
67
|
readonly createdAt: string;
|
|
@@ -75,9 +74,8 @@ export declare const listMembers: ((input: {
|
|
|
75
74
|
readonly cursor?: string | null | undefined;
|
|
76
75
|
}) => import("effect/Stream").Stream<{
|
|
77
76
|
readonly items: readonly {
|
|
78
|
-
readonly id: string
|
|
79
|
-
readonly
|
|
80
|
-
readonly contactId: string | null;
|
|
77
|
+
readonly id: string & import("effect/Brand").Brand<"UnsubscribeGroupMemberId">;
|
|
78
|
+
readonly contactId: string & import("effect/Brand").Brand<"ContactId">;
|
|
81
79
|
readonly source: "api" | "complaint" | "link" | "manual";
|
|
82
80
|
readonly unsubscribedAt: string;
|
|
83
81
|
readonly createdAt: string;
|
|
@@ -89,33 +87,46 @@ export declare const listMembers: ((input: {
|
|
|
89
87
|
readonly limit?: string | null | undefined;
|
|
90
88
|
readonly cursor?: string | null | undefined;
|
|
91
89
|
}) => import("effect/Stream").Stream<{
|
|
92
|
-
readonly id: string
|
|
93
|
-
readonly
|
|
94
|
-
readonly contactId: string | null;
|
|
90
|
+
readonly id: string & import("effect/Brand").Brand<"UnsubscribeGroupMemberId">;
|
|
91
|
+
readonly contactId: string & import("effect/Brand").Brand<"ContactId">;
|
|
95
92
|
readonly source: "api" | "complaint" | "link" | "manual";
|
|
96
93
|
readonly unsubscribedAt: string;
|
|
97
94
|
readonly createdAt: string;
|
|
98
95
|
}, import("./errors").ForbiddenError | import("./errors").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./errors").InternalError | import("./errors").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./errors").UnauthorizedError | import("./errors").ValidationError, import("./client").Service>;
|
|
99
96
|
};
|
|
100
|
-
export declare const
|
|
97
|
+
export declare const addMembers: (input: {
|
|
101
98
|
readonly id: string;
|
|
102
|
-
readonly
|
|
99
|
+
readonly members: readonly ({
|
|
100
|
+
readonly contactId: string;
|
|
101
|
+
} | {
|
|
102
|
+
readonly email: string;
|
|
103
|
+
} | {
|
|
104
|
+
readonly phone: string;
|
|
105
|
+
})[];
|
|
103
106
|
readonly source?: "api" | "complaint" | "link" | "manual" | null | undefined;
|
|
104
107
|
}) => import("effect/Effect").Effect<{
|
|
105
108
|
readonly added: number;
|
|
106
109
|
readonly skipped: number;
|
|
107
|
-
}, import("./errors").ForbiddenError | import("./errors").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./errors").InternalError | import("./errors").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./errors").UnauthorizedError | import("./errors").ValidationError, import("./client").Service>;
|
|
108
|
-
export declare const
|
|
110
|
+
}, import("./errors").BillingProviderError | import("./errors").ForbiddenError | import("./errors").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./errors").InternalError | import("./errors").PaymentRequiredError | import("./errors").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./errors").UnauthorizedError | import("./errors").ValidationError, import("./client").Service>;
|
|
111
|
+
export declare const removeMembers: (input: {
|
|
109
112
|
readonly id: string;
|
|
110
|
-
readonly
|
|
113
|
+
readonly members: readonly ({
|
|
114
|
+
readonly contactId: string;
|
|
115
|
+
} | {
|
|
116
|
+
readonly email: string;
|
|
117
|
+
} | {
|
|
118
|
+
readonly phone: string;
|
|
119
|
+
})[];
|
|
111
120
|
}) => import("effect/Effect").Effect<{
|
|
112
121
|
readonly removed: number;
|
|
113
122
|
}, import("./errors").ForbiddenError | import("./errors").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./errors").InternalError | import("./errors").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./errors").UnauthorizedError | import("./errors").ValidationError, import("./client").Service>;
|
|
114
|
-
export declare const checkSubscription: (input
|
|
115
|
-
readonly
|
|
123
|
+
export declare const checkSubscription: (input?: {
|
|
124
|
+
readonly contactId?: string | null | undefined;
|
|
125
|
+
readonly email?: string | null | undefined;
|
|
126
|
+
readonly phone?: string | null | undefined;
|
|
116
127
|
readonly groupIds?: string | null | undefined;
|
|
117
|
-
}) => import("effect/Effect").Effect<{
|
|
118
|
-
readonly
|
|
128
|
+
} | undefined) => import("effect/Effect").Effect<{
|
|
129
|
+
readonly contactId: (string & import("effect/Brand").Brand<"ContactId">) | null;
|
|
119
130
|
readonly unsubscribedGroups: readonly {
|
|
120
131
|
readonly groupId: string;
|
|
121
132
|
readonly groupName: string;
|
|
@@ -3,13 +3,13 @@ import { forGroup } from "./internal/operation.js";
|
|
|
3
3
|
import { UnsubscribeGroupsGroup } from "./generated/unsubscribe-groups.js";
|
|
4
4
|
//#region src/effect/unsubscribe-groups.ts
|
|
5
5
|
var unsubscribe_groups_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
-
|
|
6
|
+
addMembers: () => addMembers,
|
|
7
7
|
checkSubscription: () => checkSubscription,
|
|
8
8
|
create: () => create,
|
|
9
9
|
list: () => list,
|
|
10
10
|
listMembers: () => listMembers,
|
|
11
11
|
remove: () => remove,
|
|
12
|
-
|
|
12
|
+
removeMembers: () => removeMembers,
|
|
13
13
|
setDefault: () => setDefault,
|
|
14
14
|
update: () => update
|
|
15
15
|
});
|
|
@@ -20,10 +20,10 @@ const update = /* @__PURE__ */ make("unsubscribeUpdate");
|
|
|
20
20
|
const remove = /* @__PURE__ */ make("unsubscribeRemove");
|
|
21
21
|
const setDefault = /* @__PURE__ */ make("unsubscribeSetDefault");
|
|
22
22
|
const listMembers = /* @__PURE__ */ make("unsubscribeListMembers");
|
|
23
|
-
const
|
|
24
|
-
const
|
|
23
|
+
const addMembers = /* @__PURE__ */ make("unsubscribeAddMembers");
|
|
24
|
+
const removeMembers = /* @__PURE__ */ make("unsubscribeRemoveMembers");
|
|
25
25
|
const checkSubscription = /* @__PURE__ */ make("unsubscribeCheckSubscription");
|
|
26
26
|
//#endregion
|
|
27
|
-
export {
|
|
27
|
+
export { addMembers, checkSubscription, create, list, listMembers, remove, removeMembers, setDefault, unsubscribe_groups_exports, update };
|
|
28
28
|
|
|
29
29
|
//# sourceMappingURL=unsubscribe-groups.js.map
|
|
@@ -9,7 +9,7 @@ export declare const list: ((input?: {
|
|
|
9
9
|
readonly id: string & import("effect/Brand").Brand<"WebhookEndpointId">;
|
|
10
10
|
readonly name: string;
|
|
11
11
|
readonly url: string;
|
|
12
|
-
readonly eventTypes: readonly ("contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
12
|
+
readonly eventTypes: readonly ("contact.consent_changed" | "contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.action.resolved" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
13
13
|
readonly channels: readonly "email"[] | null;
|
|
14
14
|
readonly mailboxIds: readonly (string & import("effect/Brand").Brand<"MailboxId">)[] | null;
|
|
15
15
|
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
@@ -39,7 +39,7 @@ export declare const list: ((input?: {
|
|
|
39
39
|
readonly id: string & import("effect/Brand").Brand<"WebhookEndpointId">;
|
|
40
40
|
readonly name: string;
|
|
41
41
|
readonly url: string;
|
|
42
|
-
readonly eventTypes: readonly ("contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
42
|
+
readonly eventTypes: readonly ("contact.consent_changed" | "contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.action.resolved" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
43
43
|
readonly channels: readonly "email"[] | null;
|
|
44
44
|
readonly mailboxIds: readonly (string & import("effect/Brand").Brand<"MailboxId">)[] | null;
|
|
45
45
|
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
@@ -68,7 +68,7 @@ export declare const list: ((input?: {
|
|
|
68
68
|
readonly id: string & import("effect/Brand").Brand<"WebhookEndpointId">;
|
|
69
69
|
readonly name: string;
|
|
70
70
|
readonly url: string;
|
|
71
|
-
readonly eventTypes: readonly ("contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
71
|
+
readonly eventTypes: readonly ("contact.consent_changed" | "contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.action.resolved" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
72
72
|
readonly channels: readonly "email"[] | null;
|
|
73
73
|
readonly mailboxIds: readonly (string & import("effect/Brand").Brand<"MailboxId">)[] | null;
|
|
74
74
|
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
@@ -90,7 +90,7 @@ export declare const list: ((input?: {
|
|
|
90
90
|
export declare const create: (input: {
|
|
91
91
|
readonly name: string;
|
|
92
92
|
readonly url: string;
|
|
93
|
-
readonly eventTypes: readonly ("contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
93
|
+
readonly eventTypes: readonly ("contact.consent_changed" | "contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.action.resolved" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
94
94
|
readonly channels?: readonly "email"[] | null | undefined;
|
|
95
95
|
readonly mailboxIds?: readonly string[] | null | undefined;
|
|
96
96
|
readonly namespaceId?: string | null | undefined;
|
|
@@ -103,7 +103,7 @@ export declare const create: (input: {
|
|
|
103
103
|
readonly id: string & import("effect/Brand").Brand<"WebhookEndpointId">;
|
|
104
104
|
readonly name: string;
|
|
105
105
|
readonly url: string;
|
|
106
|
-
readonly eventTypes: readonly ("contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
106
|
+
readonly eventTypes: readonly ("contact.consent_changed" | "contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.action.resolved" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
107
107
|
readonly channels: readonly "email"[] | null;
|
|
108
108
|
readonly mailboxIds: readonly (string & import("effect/Brand").Brand<"MailboxId">)[] | null;
|
|
109
109
|
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
@@ -122,7 +122,7 @@ export declare const get: (input: {
|
|
|
122
122
|
readonly id: string & import("effect/Brand").Brand<"WebhookEndpointId">;
|
|
123
123
|
readonly name: string;
|
|
124
124
|
readonly url: string;
|
|
125
|
-
readonly eventTypes: readonly ("contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
125
|
+
readonly eventTypes: readonly ("contact.consent_changed" | "contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.action.resolved" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
126
126
|
readonly channels: readonly "email"[] | null;
|
|
127
127
|
readonly mailboxIds: readonly (string & import("effect/Brand").Brand<"MailboxId">)[] | null;
|
|
128
128
|
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
|
@@ -142,7 +142,7 @@ export declare const update: (input: {
|
|
|
142
142
|
readonly id: string;
|
|
143
143
|
readonly name?: string | null | undefined;
|
|
144
144
|
readonly url?: string | null | undefined;
|
|
145
|
-
readonly eventTypes?: readonly ("contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[] | null | undefined;
|
|
145
|
+
readonly eventTypes?: readonly ("contact.consent_changed" | "contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.action.resolved" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[] | null | undefined;
|
|
146
146
|
readonly channels?: readonly "email"[] | null | undefined;
|
|
147
147
|
readonly mailboxIds?: readonly string[] | null | undefined;
|
|
148
148
|
readonly namespaceId?: string | null | undefined;
|
|
@@ -154,7 +154,7 @@ export declare const update: (input: {
|
|
|
154
154
|
readonly id: string & import("effect/Brand").Brand<"WebhookEndpointId">;
|
|
155
155
|
readonly name: string;
|
|
156
156
|
readonly url: string;
|
|
157
|
-
readonly eventTypes: readonly ("contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
157
|
+
readonly eventTypes: readonly ("contact.consent_changed" | "contact.created" | "contact.deleted" | "contact.resubscribed" | "contact.subscribed" | "contact.unsubscribed" | "contact.updated" | "conversation.archived" | "conversation.created" | "conversation.updated" | "domain.updated" | "domain.warming.updated" | "journey.webhook" | "mailbox.action.pending_approval" | "mailbox.action.resolved" | "mailbox.message.discarded" | "mailbox.message.quarantined" | "mailbox.message.received" | "mailbox.message.released" | "mailbox.message.sent" | "message.bounced" | "message.clicked" | "message.complained" | "message.delivered" | "message.failed" | "message.opened" | "message.read" | "message.received" | "message.sent" | "webhook.created" | "webhook.deleted" | "webhook.test" | "webhook.updated")[];
|
|
158
158
|
readonly channels: readonly "email"[] | null;
|
|
159
159
|
readonly mailboxIds: readonly (string & import("effect/Brand").Brand<"MailboxId">)[] | null;
|
|
160
160
|
readonly namespaceId: (string & import("effect/Brand").Brand<"NamespaceId">) | null;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MediaUploadError } from "./inline-attachments.js";
|
|
2
2
|
import { MailboxEventStream, MailboxEventStreamError } from "./mailbox-events.js";
|
|
3
|
-
import { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, DeliveryUnavailableError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError,
|
|
3
|
+
import { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, DeliveryUnavailableError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError, MailboxSendConflictError, MailboxSendRefusedError, OnboardingReviewRequiredError, PaymentRequiredError, RateLimitedError, ResourceNotFoundError, SamvaApiError, SamvaTransportError, SenderNotReadyError, UnauthorizedError, ValidationError, fromApiError } from "./promises/errors.gen.js";
|
|
4
4
|
import { createClient } from "./promises/index.js";
|
|
5
|
-
export { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, DeliveryUnavailableError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError,
|
|
5
|
+
export { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, DeliveryUnavailableError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError, MailboxEventStream, MailboxEventStreamError, MailboxSendConflictError, MailboxSendRefusedError, MediaUploadError, OnboardingReviewRequiredError, PaymentRequiredError, RateLimitedError, ResourceNotFoundError, SamvaApiError, SamvaTransportError, SenderNotReadyError, UnauthorizedError, ValidationError, createClient, fromApiError };
|
package/dist/mailbox-events.d.ts
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* {@link MailboxEventStream} is an async iterable. The loop body handling an event is the
|
|
6
6
|
* acknowledgement: asking for the next event marks the previous one handled, and the stream
|
|
7
7
|
* resumes from the last handled event whenever it reconnects. Transient closes reconnect by
|
|
8
|
-
* themselves
|
|
8
|
+
* themselves, and a normal close (1000) from the host ends the loop after the events already
|
|
9
|
+
* received; a close the caller has to act on ends the loop with a {@link MailboxEventStreamError}.
|
|
9
10
|
*
|
|
10
11
|
* This module has no runtime dependencies so the Promise and Effect clients share it.
|
|
11
12
|
*/
|
|
@@ -29,7 +30,7 @@ export declare const MailboxEventStreamCloseCode: {
|
|
|
29
30
|
readonly accessUnavailable: 4503;
|
|
30
31
|
};
|
|
31
32
|
/** The event types the stream carries: the `mailbox.*` webhook events. */
|
|
32
|
-
export type MailboxEventType = "mailbox.message.received" | "mailbox.message.sent" | "mailbox.action.pending_approval" | "mailbox.message.quarantined" | "mailbox.message.released" | "mailbox.message.discarded";
|
|
33
|
+
export type MailboxEventType = "mailbox.message.received" | "mailbox.message.sent" | "mailbox.action.pending_approval" | "mailbox.action.resolved" | "mailbox.message.quarantined" | "mailbox.message.released" | "mailbox.message.discarded";
|
|
33
34
|
/** One event, as a webhook delivery of it would carry it, plus its stream position. */
|
|
34
35
|
export interface MailboxEvent {
|
|
35
36
|
/** The stream position of this event. Persist it after handling to resume from here. */
|
|
@@ -44,12 +45,19 @@ export interface MailboxEvent {
|
|
|
44
45
|
/**
|
|
45
46
|
* Why a stream ended, as the `_tag` of its {@link MailboxEventStreamError}. The first nine are the
|
|
46
47
|
* API error tags the events host refuses with, or that a close code stands for. The rest are the
|
|
47
|
-
* client's own: `StreamDisconnectedError` is a close or an unreachable host that
|
|
48
|
-
* because `reconnect` is `false`, `StreamClientError` is a request this client could not make,
|
|
48
|
+
* client's own: `StreamDisconnectedError` is a close, an idle timeout, or an unreachable host that
|
|
49
|
+
* was not retried because `reconnect` is `false`, `StreamClientError` is a request this client could not make,
|
|
49
50
|
* `StreamProtocolError` is a frame from the host it could not read, and `StreamRefusedError` is a refusal whose tag and status this client
|
|
50
51
|
* does not know (`serverTag` carries the tag the host sent).
|
|
51
52
|
*/
|
|
52
53
|
export type MailboxEventStreamErrorTag = "UnauthorizedError" | "ForbiddenError" | "ResourceNotFoundError" | "CursorExpiredError" | "ValidationError" | "UpgradeRequiredError" | "RateLimitedError" | "ServiceUnavailableError" | "MethodNotAllowedError" | "StreamDisconnectedError" | "StreamClientError" | "StreamProtocolError" | "StreamRefusedError";
|
|
54
|
+
/**
|
|
55
|
+
* Why a {@link MailboxEventStreamError} ended a stream, when `_tag` alone does not say.
|
|
56
|
+
* `idleTimeout`: the client heard no frame, not even a pong, for
|
|
57
|
+
* {@link MAILBOX_EVENT_STREAM_IDLE_MILLIS}, so it closed the connection itself. No close code
|
|
58
|
+
* accompanies it; a `closeCode` of `1006` is a close the client observed without a status.
|
|
59
|
+
*/
|
|
60
|
+
export type MailboxEventStreamErrorReason = "idleTimeout";
|
|
53
61
|
/** Field-level validation messages, keyed by dotted path, as a `ValidationError` carries them. */
|
|
54
62
|
export type MailboxEventStreamErrorFields = Readonly<Record<string, ReadonlyArray<string>>>;
|
|
55
63
|
/**
|
|
@@ -76,6 +84,8 @@ export declare class MailboxEventStreamError<Tag extends MailboxEventStreamError
|
|
|
76
84
|
readonly retryAfterSeconds: number | undefined;
|
|
77
85
|
/** The tag the host sent, when it is not one this client maps. */
|
|
78
86
|
readonly serverTag: string | undefined;
|
|
87
|
+
/** Set when the client ended the connection itself; see {@link MailboxEventStreamErrorReason}. */
|
|
88
|
+
readonly reason: MailboxEventStreamErrorReason | undefined;
|
|
79
89
|
constructor(input: {
|
|
80
90
|
readonly _tag: Tag;
|
|
81
91
|
readonly message: string;
|
|
@@ -85,6 +95,7 @@ export declare class MailboxEventStreamError<Tag extends MailboxEventStreamError
|
|
|
85
95
|
readonly fields?: MailboxEventStreamErrorFields | undefined;
|
|
86
96
|
readonly retryAfterSeconds?: number | undefined;
|
|
87
97
|
readonly serverTag?: string | undefined;
|
|
98
|
+
readonly reason?: MailboxEventStreamErrorReason | undefined;
|
|
88
99
|
});
|
|
89
100
|
}
|
|
90
101
|
/** Every stream error as a union over `_tag`, so `Effect.catchTag` can narrow it. */
|
|
@@ -113,6 +124,17 @@ export interface MailboxEventStreamSocket {
|
|
|
113
124
|
export type MailboxEventStreamWebSocket = new (url: string, options: {
|
|
114
125
|
readonly headers: Readonly<Record<string, string>>;
|
|
115
126
|
}) => MailboxEventStreamSocket;
|
|
127
|
+
/** A reconnect the stream is about to make. */
|
|
128
|
+
export interface MailboxEventStreamReconnect {
|
|
129
|
+
/** Why the connection ended: the error the stream would have ended with had it not retried. */
|
|
130
|
+
readonly error: MailboxEventStreamError;
|
|
131
|
+
/** The cursor the next connection resumes from; undefined when the stream started live and has none yet. */
|
|
132
|
+
readonly cursor: string | undefined;
|
|
133
|
+
/** Failed attempts in a row, starting at 1; a connection that went live resets it. */
|
|
134
|
+
readonly attempt: number;
|
|
135
|
+
/** How long the stream waits before connecting again. */
|
|
136
|
+
readonly delayMillis: number;
|
|
137
|
+
}
|
|
116
138
|
export interface MailboxEventStreamOptions {
|
|
117
139
|
/** Resume after this cursor: every retained event after it, then live. Omit to start live. */
|
|
118
140
|
readonly cursor?: string | undefined;
|
|
@@ -124,6 +146,11 @@ export interface MailboxEventStreamOptions {
|
|
|
124
146
|
readonly onLive?: (() => void) | undefined;
|
|
125
147
|
/** Reconnect after transient closes. Defaults to `true`. */
|
|
126
148
|
readonly reconnect?: boolean | undefined;
|
|
149
|
+
/**
|
|
150
|
+
* Called when a transient failure ends a connection and the stream is about to reconnect from
|
|
151
|
+
* its last handled cursor, before the backoff wait. Never called when `reconnect` is `false`.
|
|
152
|
+
*/
|
|
153
|
+
readonly onReconnect?: ((reconnect: MailboxEventStreamReconnect) => void) | undefined;
|
|
127
154
|
/**
|
|
128
155
|
* The events origin, such as `wss://events.samva.dev`. Defaults to the API origin with its
|
|
129
156
|
* `api` host label replaced by `events`.
|
package/dist/mailbox-events.js
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* {@link MailboxEventStream} is an async iterable. The loop body handling an event is the
|
|
7
7
|
* acknowledgement: asking for the next event marks the previous one handled, and the stream
|
|
8
8
|
* resumes from the last handled event whenever it reconnects. Transient closes reconnect by
|
|
9
|
-
* themselves
|
|
9
|
+
* themselves, and a normal close (1000) from the host ends the loop after the events already
|
|
10
|
+
* received; a close the caller has to act on ends the loop with a {@link MailboxEventStreamError}.
|
|
10
11
|
*
|
|
11
12
|
* This module has no runtime dependencies so the Promise and Effect clients share it.
|
|
12
13
|
*/
|
|
@@ -66,6 +67,8 @@ var MailboxEventStreamError = class extends Error {
|
|
|
66
67
|
retryAfterSeconds;
|
|
67
68
|
/** The tag the host sent, when it is not one this client maps. */
|
|
68
69
|
serverTag;
|
|
70
|
+
/** Set when the client ended the connection itself; see {@link MailboxEventStreamErrorReason}. */
|
|
71
|
+
reason;
|
|
69
72
|
constructor(input) {
|
|
70
73
|
super(input.message);
|
|
71
74
|
this._tag = input._tag;
|
|
@@ -75,9 +78,12 @@ var MailboxEventStreamError = class extends Error {
|
|
|
75
78
|
this.fields = input.fields;
|
|
76
79
|
this.retryAfterSeconds = input.retryAfterSeconds;
|
|
77
80
|
this.serverTag = input.serverTag;
|
|
81
|
+
this.reason = input.reason;
|
|
78
82
|
}
|
|
79
83
|
};
|
|
80
84
|
const OPEN = 1;
|
|
85
|
+
/** The close code a host ends a finished stream with. */
|
|
86
|
+
const NORMAL_CLOSE = 1e3;
|
|
81
87
|
/** Acknowledge after this many handled events, well inside the server's window of 256. */
|
|
82
88
|
const ACK_EVERY = 32;
|
|
83
89
|
const RETRY_BASE_MILLIS = 500;
|
|
@@ -300,7 +306,7 @@ var MailboxEventStream = class {
|
|
|
300
306
|
* {@link markHandled} was called, so a resume repeats it. A pending iteration finishes.
|
|
301
307
|
*/
|
|
302
308
|
close() {
|
|
303
|
-
if (this.#
|
|
309
|
+
if (this.#closed) return;
|
|
304
310
|
this.#ack();
|
|
305
311
|
this.#ended = true;
|
|
306
312
|
this.#closed = true;
|
|
@@ -349,10 +355,13 @@ var MailboxEventStream = class {
|
|
|
349
355
|
draining?.resolve();
|
|
350
356
|
this.#ack();
|
|
351
357
|
if (this.#error !== void 0) throw this.#errorAtCursor(this.#error);
|
|
352
|
-
if (this.#ended)
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
358
|
+
if (this.#ended) {
|
|
359
|
+
this.#callerSignal?.removeEventListener("abort", this.#onCallerAbort);
|
|
360
|
+
return {
|
|
361
|
+
done: true,
|
|
362
|
+
value: void 0
|
|
363
|
+
};
|
|
364
|
+
}
|
|
356
365
|
await new Promise((resolve) => {
|
|
357
366
|
this.#waiting = { resolve };
|
|
358
367
|
});
|
|
@@ -418,8 +427,16 @@ var MailboxEventStream = class {
|
|
|
418
427
|
attempt = 0;
|
|
419
428
|
});
|
|
420
429
|
if (this.#ended || outcome.kind === "stopped") return;
|
|
430
|
+
if (outcome.kind === "closed" && outcome.code === NORMAL_CLOSE) {
|
|
431
|
+
this.#finish();
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
421
434
|
let result;
|
|
422
435
|
if (outcome.kind === "closed") result = closeOutcome(outcome.code);
|
|
436
|
+
else if (outcome.kind === "idle") result = outcomeOf("StreamDisconnectedError", true, {
|
|
437
|
+
reason: "idleTimeout",
|
|
438
|
+
message: `No frame from the events host in ${MAILBOX_EVENT_STREAM_IDLE_MILLIS / 1e3} seconds, so the stream closed the connection.`
|
|
439
|
+
});
|
|
423
440
|
else {
|
|
424
441
|
const refusal = await this.#diagnose();
|
|
425
442
|
result = refusal === void 0 ? outcomeOf("StreamDisconnectedError", true) : refusalOutcome(refusal);
|
|
@@ -430,9 +447,23 @@ var MailboxEventStream = class {
|
|
|
430
447
|
}
|
|
431
448
|
const backoff = Math.min(RETRY_MAX_MILLIS, RETRY_BASE_MILLIS * 2 ** attempt);
|
|
432
449
|
attempt += 1;
|
|
433
|
-
|
|
450
|
+
const delayMillis = result.retryAfterMillis ?? backoff / 2 + Math.random() * (backoff / 2);
|
|
451
|
+
this.#options.onReconnect?.({
|
|
452
|
+
error: this.#withCursor(result.error),
|
|
453
|
+
cursor: this.#resumeCursor(),
|
|
454
|
+
attempt,
|
|
455
|
+
delayMillis
|
|
456
|
+
});
|
|
457
|
+
await sleep(delayMillis, this.#stop.signal);
|
|
434
458
|
}
|
|
435
459
|
}
|
|
460
|
+
/** End the iteration after the buffered events, with no error. */
|
|
461
|
+
#finish() {
|
|
462
|
+
if (this.#ended) return;
|
|
463
|
+
this.#ended = true;
|
|
464
|
+
this.#stop.abort();
|
|
465
|
+
this.#wake();
|
|
466
|
+
}
|
|
436
467
|
#withCursor(error) {
|
|
437
468
|
return new MailboxEventStreamError({
|
|
438
469
|
...error,
|
|
@@ -464,10 +495,7 @@ var MailboxEventStream = class {
|
|
|
464
495
|
const armIdle = () => {
|
|
465
496
|
clearTimeout(idleTimer);
|
|
466
497
|
idleTimer = setTimeout(() => {
|
|
467
|
-
settle(opened ? {
|
|
468
|
-
kind: "closed",
|
|
469
|
-
code: 1006
|
|
470
|
-
} : { kind: "refused" });
|
|
498
|
+
settle(opened ? { kind: "idle" } : { kind: "refused" });
|
|
471
499
|
socket.close(1e3);
|
|
472
500
|
}, MAILBOX_EVENT_STREAM_IDLE_MILLIS);
|
|
473
501
|
};
|
package/dist/package.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type SamvaApiErrorTag = "AnalyticsQueryError" | "BillingProviderError" | "BrandAddressRequiredError" | "CampaignFooterRequiredError" | "ConflictError" | "DeliveryUnavailableError" | "EmailChannelError" | "ExternalServiceError" | "FlagDisabledError" | "ForbiddenError" | "GatewayTimeoutError" | "InternalError" | "
|
|
1
|
+
export type SamvaApiErrorTag = "AnalyticsQueryError" | "BillingProviderError" | "BrandAddressRequiredError" | "CampaignFooterRequiredError" | "ConflictError" | "DeliveryUnavailableError" | "EmailChannelError" | "ExternalServiceError" | "FlagDisabledError" | "ForbiddenError" | "GatewayTimeoutError" | "InternalError" | "MailboxSendConflictError" | "MailboxSendRefusedError" | "OnboardingReviewRequiredError" | "PaymentRequiredError" | "RateLimitedError" | "ResourceNotFoundError" | "SenderNotReadyError" | "UnauthorizedError" | "ValidationError";
|
|
2
2
|
export interface SamvaApiErrorContext {
|
|
3
3
|
readonly request?: Request | undefined;
|
|
4
4
|
readonly response?: Response | undefined;
|
|
@@ -132,16 +132,6 @@ export declare class InternalError extends SamvaApiError<"InternalError"> {
|
|
|
132
132
|
readonly _tag: "InternalError";
|
|
133
133
|
constructor(payload: Omit<InternalErrorPayload, "_tag">, context?: SamvaApiErrorContext);
|
|
134
134
|
}
|
|
135
|
-
type MailboxChannelUnsupportedErrorPayload = {
|
|
136
|
-
readonly _tag: "MailboxChannelUnsupportedError";
|
|
137
|
-
readonly channel: string;
|
|
138
|
-
readonly message: string;
|
|
139
|
-
};
|
|
140
|
-
export declare class MailboxChannelUnsupportedError extends SamvaApiError<"MailboxChannelUnsupportedError"> {
|
|
141
|
-
readonly _tag: "MailboxChannelUnsupportedError";
|
|
142
|
-
readonly "channel": string;
|
|
143
|
-
constructor(payload: Omit<MailboxChannelUnsupportedErrorPayload, "_tag">, context?: SamvaApiErrorContext);
|
|
144
|
-
}
|
|
145
135
|
type MailboxSendConflictErrorPayload = {
|
|
146
136
|
readonly _tag: "MailboxSendConflictError";
|
|
147
137
|
readonly id: string;
|
|
@@ -250,7 +240,7 @@ export declare class ValidationError extends SamvaApiError<"ValidationError"> {
|
|
|
250
240
|
readonly "fields"?: Record<string, Array<string>> | null;
|
|
251
241
|
constructor(payload: Omit<ValidationErrorPayload, "_tag">, context?: SamvaApiErrorContext);
|
|
252
242
|
}
|
|
253
|
-
export type AnySamvaApiError = AnalyticsQueryError | BillingProviderError | BrandAddressRequiredError | CampaignFooterRequiredError | ConflictError | DeliveryUnavailableError | EmailChannelError | ExternalServiceError | FlagDisabledError | ForbiddenError | GatewayTimeoutError | InternalError |
|
|
243
|
+
export type AnySamvaApiError = AnalyticsQueryError | BillingProviderError | BrandAddressRequiredError | CampaignFooterRequiredError | ConflictError | DeliveryUnavailableError | EmailChannelError | ExternalServiceError | FlagDisabledError | ForbiddenError | GatewayTimeoutError | InternalError | MailboxSendConflictError | MailboxSendRefusedError | OnboardingReviewRequiredError | PaymentRequiredError | RateLimitedError | ResourceNotFoundError | SenderNotReadyError | UnauthorizedError | ValidationError;
|
|
254
244
|
/** Convert a decoded error payload into its generated JavaScript error class. */
|
|
255
245
|
export declare function fromApiError(error: unknown, context?: SamvaApiErrorContext): AnySamvaApiError | SamvaTransportError;
|
|
256
246
|
export {};
|
|
@@ -117,13 +117,6 @@ var InternalError = class extends SamvaApiError {
|
|
|
117
117
|
Object.assign(this, payload);
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
|
-
var MailboxChannelUnsupportedError = class extends SamvaApiError {
|
|
121
|
-
_tag = "MailboxChannelUnsupportedError";
|
|
122
|
-
constructor(payload, context = {}) {
|
|
123
|
-
super(messageOf("MailboxChannelUnsupportedError", payload), context);
|
|
124
|
-
Object.assign(this, payload);
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
120
|
var MailboxSendConflictError = class extends SamvaApiError {
|
|
128
121
|
_tag = "MailboxSendConflictError";
|
|
129
122
|
constructor(payload, context = {}) {
|
|
@@ -200,7 +193,6 @@ const constructors = {
|
|
|
200
193
|
ForbiddenError,
|
|
201
194
|
GatewayTimeoutError,
|
|
202
195
|
InternalError,
|
|
203
|
-
MailboxChannelUnsupportedError,
|
|
204
196
|
MailboxSendConflictError,
|
|
205
197
|
MailboxSendRefusedError,
|
|
206
198
|
OnboardingReviewRequiredError,
|
|
@@ -411,23 +403,6 @@ const payloadSchemas = {
|
|
|
411
403
|
"x-category": ["transient"],
|
|
412
404
|
"x-retryable": true
|
|
413
405
|
},
|
|
414
|
-
MailboxChannelUnsupportedError: {
|
|
415
|
-
type: "object",
|
|
416
|
-
properties: {
|
|
417
|
-
_tag: {
|
|
418
|
-
type: "string",
|
|
419
|
-
enum: ["MailboxChannelUnsupportedError"]
|
|
420
|
-
},
|
|
421
|
-
message: { type: "string" },
|
|
422
|
-
channel: { type: "string" }
|
|
423
|
-
},
|
|
424
|
-
required: [
|
|
425
|
-
"_tag",
|
|
426
|
-
"message",
|
|
427
|
-
"channel"
|
|
428
|
-
],
|
|
429
|
-
additionalProperties: false
|
|
430
|
-
},
|
|
431
406
|
MailboxSendConflictError: {
|
|
432
407
|
type: "object",
|
|
433
408
|
properties: {
|
|
@@ -1335,6 +1310,6 @@ function fromApiError(error, context = {}) {
|
|
|
1335
1310
|
return new SamvaTransportError(error, context);
|
|
1336
1311
|
}
|
|
1337
1312
|
//#endregion
|
|
1338
|
-
export { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, DeliveryUnavailableError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError,
|
|
1313
|
+
export { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, DeliveryUnavailableError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError, MailboxSendConflictError, MailboxSendRefusedError, OnboardingReviewRequiredError, PaymentRequiredError, RateLimitedError, ResourceNotFoundError, SamvaApiError, SamvaTransportError, SenderNotReadyError, UnauthorizedError, ValidationError, fromApiError };
|
|
1339
1314
|
|
|
1340
1315
|
//# sourceMappingURL=errors.gen.js.map
|
package/dist/promises/index.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ import { MailboxEventStream, type MailboxEventStreamOptions } from "../mailbox-e
|
|
|
33
33
|
export * from "./errors.gen";
|
|
34
34
|
export { MediaUploadError } from "../inline-attachments";
|
|
35
35
|
export type * from "./types.gen";
|
|
36
|
-
export { MailboxEventStream, MailboxEventStreamError, type MailboxEvent, type MailboxEventStreamErrorFields, type MailboxEventStreamErrorTag, type MailboxEventStreamFailure, type MailboxEventStreamOptions, type MailboxEventStreamWebSocket, type MailboxEventType, } from "../mailbox-events";
|
|
36
|
+
export { MailboxEventStream, MailboxEventStreamError, type MailboxEvent, type MailboxEventStreamErrorFields, type MailboxEventStreamErrorReason, type MailboxEventStreamErrorTag, type MailboxEventStreamFailure, type MailboxEventStreamOptions, type MailboxEventStreamReconnect, type MailboxEventStreamWebSocket, type MailboxEventType, } from "../mailbox-events";
|
|
37
37
|
interface SamvaClientConfigBase extends Omit<Config, "baseUrl" | "responseStyle" | "throwOnError"> {
|
|
38
38
|
/** Base URL for the API (defaults to https://api.samva.dev). */
|
|
39
39
|
baseUrl?: string;
|