@eusend_dev/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,385 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/emails.ts
3
+ function toApiPayload(options) {
4
+ return {
5
+ from: options.from,
6
+ to: options.to,
7
+ cc: options.cc,
8
+ bcc: options.bcc,
9
+ reply_to: options.replyTo,
10
+ subject: options.subject,
11
+ html: options.html,
12
+ text: options.text,
13
+ template_id: options.templateId,
14
+ variables: options.variables,
15
+ headers: options.headers,
16
+ track_opens: options.trackOpens,
17
+ track_clicks: options.trackClicks
18
+ };
19
+ }
20
+ var Emails = class {
21
+ constructor(client) {
22
+ this.client = client;
23
+ }
24
+ async send(options, requestOptions) {
25
+ const extraHeaders = {};
26
+ if (requestOptions?.idempotencyKey) extraHeaders["Idempotency-Key"] = requestOptions.idempotencyKey;
27
+ return this.client.post("/emails", toApiPayload(options), extraHeaders);
28
+ }
29
+ async batch(emails) {
30
+ return this.client.post("/emails/batch", { emails: emails.map(toApiPayload) });
31
+ }
32
+ async list(options = {}) {
33
+ const params = new URLSearchParams();
34
+ if (options.limit != null) params.set("limit", String(options.limit));
35
+ if (options.cursor) params.set("cursor", options.cursor);
36
+ if (options.status) params.set("status", options.status);
37
+ if (options.from) params.set("from", options.from);
38
+ if (options.to) params.set("to", options.to);
39
+ const qs = params.toString();
40
+ const res = await this.client.get(qs ? `/emails?${qs}` : "/emails");
41
+ if (res.error) return res;
42
+ return {
43
+ data: {
44
+ data: res.data.data,
45
+ nextCursor: res.data.next_cursor
46
+ },
47
+ error: null,
48
+ headers: res.headers
49
+ };
50
+ }
51
+ get(id) {
52
+ return this.client.get(`/emails/${id}`);
53
+ }
54
+ };
55
+ //#endregion
56
+ //#region src/domains.ts
57
+ var Domains = class {
58
+ constructor(client) {
59
+ this.client = client;
60
+ }
61
+ create(name) {
62
+ return this.client.post("/domains", { name });
63
+ }
64
+ list() {
65
+ return this.client.get("/domains");
66
+ }
67
+ get(id) {
68
+ return this.client.get(`/domains/${id}`);
69
+ }
70
+ delete(id) {
71
+ return this.client.delete(`/domains/${id}`);
72
+ }
73
+ verify(id) {
74
+ return this.client.post(`/domains/${id}/verify`);
75
+ }
76
+ };
77
+ //#endregion
78
+ //#region src/api-keys.ts
79
+ var ApiKeys = class {
80
+ constructor(client) {
81
+ this.client = client;
82
+ }
83
+ async create(options) {
84
+ const res = await this.client.post("/api-keys", {
85
+ name: options.name,
86
+ test_mode: options.testMode ?? false
87
+ });
88
+ if (res.error) return res;
89
+ return {
90
+ data: {
91
+ id: res.data.id,
92
+ name: res.data.name,
93
+ key: res.data.key,
94
+ prefix: res.data.prefix,
95
+ testMode: res.data.test_mode,
96
+ createdAt: res.data.created_at
97
+ },
98
+ error: null,
99
+ headers: res.headers
100
+ };
101
+ }
102
+ list() {
103
+ return this.client.get("/api-keys");
104
+ }
105
+ delete(id) {
106
+ return this.client.delete(`/api-keys/${id}`);
107
+ }
108
+ };
109
+ //#endregion
110
+ //#region src/audiences.ts
111
+ var Audiences = class {
112
+ constructor(client) {
113
+ this.client = client;
114
+ }
115
+ create(name) {
116
+ return this.client.post("/audiences", { name });
117
+ }
118
+ async list() {
119
+ const res = await this.client.get("/audiences");
120
+ if (res.error) return res;
121
+ return {
122
+ data: res.data.data,
123
+ error: null,
124
+ headers: res.headers
125
+ };
126
+ }
127
+ delete(id) {
128
+ return this.client.delete(`/audiences/${id}`);
129
+ }
130
+ createContact(audienceId, options) {
131
+ return this.client.post(`/audiences/${audienceId}/contacts`, {
132
+ email: options.email,
133
+ first_name: options.firstName,
134
+ last_name: options.lastName
135
+ });
136
+ }
137
+ async listContacts(audienceId, options = {}) {
138
+ const params = new URLSearchParams();
139
+ if (options.limit != null) params.set("limit", String(options.limit));
140
+ if (options.cursor) params.set("cursor", options.cursor);
141
+ if (options.search) params.set("search", options.search);
142
+ if (options.subscribed != null) params.set("subscribed", String(options.subscribed));
143
+ const qs = params.toString();
144
+ return this.client.get(qs ? `/audiences/${audienceId}/contacts?${qs}` : `/audiences/${audienceId}/contacts`);
145
+ }
146
+ getContact(audienceId, contactId) {
147
+ return this.client.get(`/audiences/${audienceId}/contacts/${contactId}`);
148
+ }
149
+ updateContact(audienceId, contactId, options) {
150
+ return this.client.patch(`/audiences/${audienceId}/contacts/${contactId}`, {
151
+ first_name: options.firstName,
152
+ last_name: options.lastName,
153
+ unsubscribed: options.unsubscribed
154
+ });
155
+ }
156
+ deleteContact(audienceId, contactId) {
157
+ return this.client.delete(`/audiences/${audienceId}/contacts/${contactId}`);
158
+ }
159
+ batchCreateContacts(audienceId, options) {
160
+ return this.client.post(`/audiences/${audienceId}/contacts/batch`, { contacts: options.contacts.map((c) => ({
161
+ email: c.email,
162
+ first_name: c.firstName,
163
+ last_name: c.lastName
164
+ })) });
165
+ }
166
+ };
167
+ //#endregion
168
+ //#region src/templates.ts
169
+ var Templates = class {
170
+ constructor(client) {
171
+ this.client = client;
172
+ }
173
+ create(options) {
174
+ return this.client.post("/templates", {
175
+ name: options.name,
176
+ subject: options.subject,
177
+ html: options.html,
178
+ react_source: options.reactSource
179
+ });
180
+ }
181
+ async list() {
182
+ const res = await this.client.get("/templates");
183
+ if (res.error) return res;
184
+ return {
185
+ data: res.data.data,
186
+ error: null,
187
+ headers: res.headers
188
+ };
189
+ }
190
+ get(id) {
191
+ return this.client.get(`/templates/${id}`);
192
+ }
193
+ update(id, options) {
194
+ return this.client.patch(`/templates/${id}`, {
195
+ name: options.name,
196
+ subject: options.subject,
197
+ html: options.html,
198
+ react_source: options.reactSource
199
+ });
200
+ }
201
+ delete(id) {
202
+ return this.client.delete(`/templates/${id}`);
203
+ }
204
+ };
205
+ //#endregion
206
+ //#region src/webhooks.ts
207
+ var Webhooks = class {
208
+ constructor(client) {
209
+ this.client = client;
210
+ }
211
+ create(options) {
212
+ return this.client.post("/webhooks", {
213
+ url: options.url,
214
+ events: options.events
215
+ });
216
+ }
217
+ async list() {
218
+ const res = await this.client.get("/webhooks");
219
+ if (res.error) return res;
220
+ return {
221
+ data: res.data.data,
222
+ error: null,
223
+ headers: res.headers
224
+ };
225
+ }
226
+ get(id) {
227
+ return this.client.get(`/webhooks/${id}`);
228
+ }
229
+ update(id, options) {
230
+ return this.client.patch(`/webhooks/${id}`, {
231
+ url: options.url,
232
+ events: options.events
233
+ });
234
+ }
235
+ delete(id) {
236
+ return this.client.delete(`/webhooks/${id}`);
237
+ }
238
+ };
239
+ //#endregion
240
+ //#region src/broadcasts.ts
241
+ var Broadcasts = class {
242
+ constructor(client) {
243
+ this.client = client;
244
+ }
245
+ create(options) {
246
+ return this.client.post("/broadcasts", {
247
+ name: options.name,
248
+ audience_id: options.audienceId,
249
+ from: options.from,
250
+ subject: options.subject,
251
+ html: options.html,
252
+ template_id: options.templateId,
253
+ template_variables: options.templateVariables
254
+ });
255
+ }
256
+ async list() {
257
+ const res = await this.client.get("/broadcasts");
258
+ if (res.error) return res;
259
+ return {
260
+ data: res.data.data,
261
+ error: null,
262
+ headers: res.headers
263
+ };
264
+ }
265
+ get(id) {
266
+ return this.client.get(`/broadcasts/${id}`);
267
+ }
268
+ update(id, options) {
269
+ return this.client.patch(`/broadcasts/${id}`, {
270
+ name: options.name,
271
+ audience_id: options.audienceId,
272
+ from: options.from,
273
+ subject: options.subject,
274
+ html: options.html,
275
+ template_id: options.templateId,
276
+ template_variables: options.templateVariables,
277
+ scheduled_at: options.scheduledAt
278
+ });
279
+ }
280
+ send(id, options = {}) {
281
+ return this.client.post(`/broadcasts/${id}/send`, { scheduled_at: options.scheduledAt });
282
+ }
283
+ cancel(id) {
284
+ return this.client.post(`/broadcasts/${id}/cancel`);
285
+ }
286
+ delete(id) {
287
+ return this.client.delete(`/broadcasts/${id}`);
288
+ }
289
+ };
290
+ //#endregion
291
+ //#region src/eusend.ts
292
+ const DEFAULT_BASE_URL = "https://api.eusend.dev";
293
+ const SDK_VERSION = "0.1.0";
294
+ var Eusend = class {
295
+ constructor(key, options) {
296
+ const apiKey = key ?? (typeof process !== "undefined" ? process.env["EUSEND_API_KEY"] : void 0);
297
+ if (!apiKey) throw new Error("Missing Eusend API key. Pass it to the constructor or set the EUSEND_API_KEY environment variable.");
298
+ this.apiKey = apiKey;
299
+ this.baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
300
+ this.emails = new Emails(this);
301
+ this.domains = new Domains(this);
302
+ this.apiKeys = new ApiKeys(this);
303
+ this.audiences = new Audiences(this);
304
+ this.templates = new Templates(this);
305
+ this.webhooks = new Webhooks(this);
306
+ this.broadcasts = new Broadcasts(this);
307
+ }
308
+ async fetchRequest(path, init = {}, extraHeaders = {}) {
309
+ const headers = {
310
+ Authorization: `Bearer ${this.apiKey}`,
311
+ "Content-Type": "application/json",
312
+ "User-Agent": `eusend-node/${SDK_VERSION}`,
313
+ ...extraHeaders
314
+ };
315
+ try {
316
+ const res = await fetch(`${this.baseUrl}${path}`, {
317
+ ...init,
318
+ headers
319
+ });
320
+ const responseHeaders = Object.fromEntries(res.headers.entries());
321
+ if (!res.ok) {
322
+ let error;
323
+ try {
324
+ const json = await res.json();
325
+ error = {
326
+ message: json.error ?? "Unknown error",
327
+ statusCode: res.status,
328
+ name: json.code ?? "INTERNAL_ERROR"
329
+ };
330
+ } catch {
331
+ error = {
332
+ message: "Request failed",
333
+ statusCode: res.status,
334
+ name: "INTERNAL_ERROR"
335
+ };
336
+ }
337
+ return {
338
+ data: null,
339
+ error,
340
+ headers: responseHeaders
341
+ };
342
+ }
343
+ if (res.status === 204 || res.headers.get("content-length") === "0") return {
344
+ data: {},
345
+ error: null,
346
+ headers: responseHeaders
347
+ };
348
+ return {
349
+ data: await res.json(),
350
+ error: null,
351
+ headers: responseHeaders
352
+ };
353
+ } catch {
354
+ return {
355
+ data: null,
356
+ error: {
357
+ message: "Network request failed. The request could not be resolved.",
358
+ statusCode: null,
359
+ name: "application_error"
360
+ },
361
+ headers: null
362
+ };
363
+ }
364
+ }
365
+ get(path, extraHeaders) {
366
+ return this.fetchRequest(path, { method: "GET" }, extraHeaders);
367
+ }
368
+ post(path, body, extraHeaders) {
369
+ return this.fetchRequest(path, {
370
+ method: "POST",
371
+ body: body != null ? JSON.stringify(body) : void 0
372
+ }, extraHeaders);
373
+ }
374
+ patch(path, body) {
375
+ return this.fetchRequest(path, {
376
+ method: "PATCH",
377
+ body: body != null ? JSON.stringify(body) : void 0
378
+ });
379
+ }
380
+ delete(path) {
381
+ return this.fetchRequest(path, { method: "DELETE" });
382
+ }
383
+ };
384
+ //#endregion
385
+ exports.Eusend = Eusend;