@emailr/sdk 1.0.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.js ADDED
@@ -0,0 +1,700 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AuthenticationError: () => AuthenticationError,
24
+ Emailr: () => Emailr,
25
+ EmailrClient: () => Emailr,
26
+ EmailrError: () => EmailrError,
27
+ NetworkError: () => NetworkError,
28
+ NotFoundError: () => NotFoundError,
29
+ RateLimitError: () => RateLimitError,
30
+ ValidationError: () => ValidationError
31
+ });
32
+ module.exports = __toCommonJS(index_exports);
33
+
34
+ // src/errors.ts
35
+ var EmailrError = class _EmailrError extends Error {
36
+ constructor(message, statusCode, code, requestId) {
37
+ super(message);
38
+ this.name = "EmailrError";
39
+ this.statusCode = statusCode;
40
+ this.code = code;
41
+ this.requestId = requestId;
42
+ if (Error.captureStackTrace) {
43
+ Error.captureStackTrace(this, _EmailrError);
44
+ }
45
+ }
46
+ };
47
+ var NetworkError = class extends EmailrError {
48
+ constructor(message, cause) {
49
+ super(message, 0, "NETWORK_ERROR");
50
+ this.name = "NetworkError";
51
+ this.originalError = cause;
52
+ }
53
+ };
54
+ var AuthenticationError = class extends EmailrError {
55
+ constructor(message = "Invalid API key", requestId) {
56
+ super(message, 401, "AUTHENTICATION_ERROR", requestId);
57
+ this.name = "AuthenticationError";
58
+ }
59
+ };
60
+ var RateLimitError = class extends EmailrError {
61
+ constructor(message = "Rate limit exceeded", retryAfter, requestId) {
62
+ super(message, 429, "RATE_LIMIT_ERROR", requestId);
63
+ this.name = "RateLimitError";
64
+ this.retryAfter = retryAfter;
65
+ }
66
+ };
67
+ var NotFoundError = class extends EmailrError {
68
+ constructor(message = "Resource not found", requestId) {
69
+ super(message, 404, "NOT_FOUND", requestId);
70
+ this.name = "NotFoundError";
71
+ }
72
+ };
73
+ var ValidationError = class extends EmailrError {
74
+ constructor(message, details, requestId) {
75
+ super(message, 400, "VALIDATION_ERROR", requestId);
76
+ this.name = "ValidationError";
77
+ this.details = details;
78
+ }
79
+ };
80
+
81
+ // src/http.ts
82
+ var HttpClient = class {
83
+ constructor(config) {
84
+ this.apiKey = config.apiKey;
85
+ this.baseUrl = config.baseUrl;
86
+ this.timeout = config.timeout;
87
+ }
88
+ async get(path, options) {
89
+ return this.request("GET", path, void 0, options);
90
+ }
91
+ async post(path, body, options) {
92
+ return this.request("POST", path, body, options);
93
+ }
94
+ async put(path, body, options) {
95
+ return this.request("PUT", path, body, options);
96
+ }
97
+ async patch(path, body, options) {
98
+ return this.request("PATCH", path, body, options);
99
+ }
100
+ async delete(path, options) {
101
+ return this.request("DELETE", path, void 0, options);
102
+ }
103
+ async request(method, path, body, options) {
104
+ const url = this.buildUrl(path, options?.params);
105
+ const headers = {
106
+ "Authorization": `Bearer ${this.apiKey}`,
107
+ "Content-Type": "application/json",
108
+ ...options?.headers
109
+ };
110
+ const controller = new AbortController();
111
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
112
+ try {
113
+ const response = await fetch(url, {
114
+ method,
115
+ headers,
116
+ body: body ? JSON.stringify(body) : void 0,
117
+ signal: controller.signal
118
+ });
119
+ clearTimeout(timeoutId);
120
+ const requestId = response.headers.get("x-request-id") ?? void 0;
121
+ if (!response.ok) {
122
+ await this.handleErrorResponse(response, requestId);
123
+ }
124
+ if (response.status === 204) {
125
+ return {};
126
+ }
127
+ const data = await response.json();
128
+ return data;
129
+ } catch (error) {
130
+ clearTimeout(timeoutId);
131
+ if (error instanceof EmailrError) {
132
+ throw error;
133
+ }
134
+ if (error instanceof Error) {
135
+ if (error.name === "AbortError") {
136
+ throw new NetworkError(`Request timeout after ${this.timeout}ms`);
137
+ }
138
+ throw new NetworkError(error.message, error);
139
+ }
140
+ throw new NetworkError("An unknown error occurred");
141
+ }
142
+ }
143
+ buildUrl(path, params) {
144
+ const url = new URL(path, this.baseUrl);
145
+ if (params) {
146
+ Object.entries(params).forEach(([key, value]) => {
147
+ if (value !== void 0) {
148
+ url.searchParams.append(key, String(value));
149
+ }
150
+ });
151
+ }
152
+ return url.toString();
153
+ }
154
+ async handleErrorResponse(response, requestId) {
155
+ let errorData;
156
+ try {
157
+ errorData = await response.json();
158
+ } catch {
159
+ errorData = { error: response.statusText || "Unknown error" };
160
+ }
161
+ const message = errorData.error || "An error occurred";
162
+ switch (response.status) {
163
+ case 400:
164
+ throw new ValidationError(message, errorData.details, requestId);
165
+ case 401:
166
+ throw new AuthenticationError(message, requestId);
167
+ case 404:
168
+ throw new NotFoundError(message, requestId);
169
+ case 429:
170
+ const retryAfter = response.headers.get("retry-after");
171
+ throw new RateLimitError(
172
+ message,
173
+ retryAfter ? parseInt(retryAfter, 10) : void 0,
174
+ requestId
175
+ );
176
+ default:
177
+ throw new EmailrError(message, response.status, errorData.code, requestId);
178
+ }
179
+ }
180
+ };
181
+
182
+ // src/resources/emails.ts
183
+ var EmailsResource = class {
184
+ constructor(http) {
185
+ this.http = http;
186
+ }
187
+ /**
188
+ * Send an email to one or multiple recipients
189
+ */
190
+ async send(data) {
191
+ return this.http.post("/v1/emails/send", data);
192
+ }
193
+ /**
194
+ * Get email by ID
195
+ */
196
+ async get(id) {
197
+ return this.http.get(`/v1/emails/${id}`);
198
+ }
199
+ /**
200
+ * List emails with pagination
201
+ */
202
+ async list(params) {
203
+ return this.http.get("/v1/emails", {
204
+ params
205
+ });
206
+ }
207
+ /**
208
+ * Forward an email to other recipients
209
+ */
210
+ async forward(data) {
211
+ return this.http.post("/v1/emails/forward", data);
212
+ }
213
+ /**
214
+ * Create an email forwarding rule
215
+ */
216
+ async createForwardingRule(data) {
217
+ return this.http.post("/v1/emails/forwarding-rules", data);
218
+ }
219
+ /**
220
+ * List all forwarding rules
221
+ */
222
+ async listForwardingRules() {
223
+ return this.http.get("/v1/emails/forwarding-rules");
224
+ }
225
+ /**
226
+ * Delete a forwarding rule
227
+ */
228
+ async deleteForwardingRule(id) {
229
+ return this.http.delete(`/v1/emails/forwarding-rules/${id}`);
230
+ }
231
+ };
232
+
233
+ // src/resources/contacts.ts
234
+ var ContactsResource = class {
235
+ constructor(http) {
236
+ this.http = http;
237
+ }
238
+ /**
239
+ * Create a new contact
240
+ */
241
+ async create(data) {
242
+ return this.http.post("/v1/contacts", data);
243
+ }
244
+ /**
245
+ * Get contact by ID
246
+ */
247
+ async get(id) {
248
+ return this.http.get(`/v1/contacts/${id}`);
249
+ }
250
+ /**
251
+ * List contacts with optional filtering
252
+ */
253
+ async list(params) {
254
+ return this.http.get("/v1/contacts", {
255
+ params
256
+ });
257
+ }
258
+ /**
259
+ * Update a contact
260
+ */
261
+ async update(id, data) {
262
+ return this.http.put(`/v1/contacts/${id}`, data);
263
+ }
264
+ /**
265
+ * Delete a contact
266
+ */
267
+ async delete(id) {
268
+ return this.http.delete(`/v1/contacts/${id}`);
269
+ }
270
+ /**
271
+ * Bulk create contacts
272
+ */
273
+ async bulkCreate(data) {
274
+ return this.http.post("/v1/contacts/bulk", data);
275
+ }
276
+ /**
277
+ * Unsubscribe a contact
278
+ */
279
+ async unsubscribe(id) {
280
+ return this.http.post(`/v1/contacts/${id}/unsubscribe`);
281
+ }
282
+ /**
283
+ * Resubscribe a contact
284
+ */
285
+ async resubscribe(id) {
286
+ return this.http.post(`/v1/contacts/${id}/resubscribe`);
287
+ }
288
+ };
289
+
290
+ // src/resources/templates.ts
291
+ var TemplatesResource = class {
292
+ constructor(http) {
293
+ this.http = http;
294
+ }
295
+ /**
296
+ * Create a new template
297
+ */
298
+ async create(data) {
299
+ return this.http.post("/v1/templates", data);
300
+ }
301
+ /**
302
+ * Get template by ID
303
+ */
304
+ async get(id) {
305
+ return this.http.get(`/v1/templates/${id}`);
306
+ }
307
+ /**
308
+ * List templates with pagination
309
+ */
310
+ async list(params) {
311
+ return this.http.get("/v1/templates", {
312
+ params
313
+ });
314
+ }
315
+ /**
316
+ * Update a template
317
+ */
318
+ async update(id, data) {
319
+ return this.http.put(`/v1/templates/${id}`, data);
320
+ }
321
+ /**
322
+ * Delete a template
323
+ */
324
+ async delete(id) {
325
+ return this.http.delete(`/v1/templates/${id}`);
326
+ }
327
+ /**
328
+ * Duplicate a template
329
+ */
330
+ async duplicate(id) {
331
+ return this.http.post(`/v1/templates/${id}/duplicate`);
332
+ }
333
+ };
334
+
335
+ // src/resources/domains.ts
336
+ var DomainsResource = class {
337
+ constructor(http) {
338
+ this.http = http;
339
+ }
340
+ /**
341
+ * Add a new domain
342
+ */
343
+ async add(data) {
344
+ return this.http.post("/v1/domains", data);
345
+ }
346
+ /**
347
+ * Get domain by ID
348
+ */
349
+ async get(id) {
350
+ return this.http.get(`/v1/domains/${id}`);
351
+ }
352
+ /**
353
+ * List all domains
354
+ */
355
+ async list() {
356
+ return this.http.get("/v1/domains");
357
+ }
358
+ /**
359
+ * Update domain settings
360
+ */
361
+ async update(id, data) {
362
+ return this.http.patch(`/v1/domains/${id}`, data);
363
+ }
364
+ /**
365
+ * Delete a domain
366
+ */
367
+ async delete(id) {
368
+ return this.http.delete(`/v1/domains/${id}`);
369
+ }
370
+ /**
371
+ * Verify domain DNS records
372
+ */
373
+ async verify(id) {
374
+ return this.http.post(`/v1/domains/${id}/verify`);
375
+ }
376
+ /**
377
+ * Check DNS verification status
378
+ */
379
+ async checkDns(id) {
380
+ return this.http.get(`/v1/domains/${id}/dns-status`);
381
+ }
382
+ };
383
+
384
+ // src/resources/webhooks.ts
385
+ var WebhooksResource = class {
386
+ constructor(http) {
387
+ this.http = http;
388
+ }
389
+ /**
390
+ * Create a new webhook
391
+ */
392
+ async create(data) {
393
+ return this.http.post("/v1/webhooks", data);
394
+ }
395
+ /**
396
+ * Get webhook by ID
397
+ */
398
+ async get(id) {
399
+ return this.http.get(`/v1/webhooks/${id}`);
400
+ }
401
+ /**
402
+ * List webhooks with pagination
403
+ */
404
+ async list(params) {
405
+ return this.http.get("/v1/webhooks", {
406
+ params
407
+ });
408
+ }
409
+ /**
410
+ * Update a webhook
411
+ */
412
+ async update(id, data) {
413
+ return this.http.put(`/v1/webhooks/${id}`, data);
414
+ }
415
+ /**
416
+ * Delete a webhook
417
+ */
418
+ async delete(id) {
419
+ return this.http.delete(`/v1/webhooks/${id}`);
420
+ }
421
+ /**
422
+ * Enable a webhook
423
+ */
424
+ async enable(id) {
425
+ return this.http.post(`/v1/webhooks/${id}/enable`);
426
+ }
427
+ /**
428
+ * Disable a webhook
429
+ */
430
+ async disable(id) {
431
+ return this.http.post(`/v1/webhooks/${id}/disable`);
432
+ }
433
+ /**
434
+ * List webhook deliveries
435
+ */
436
+ async listDeliveries(id) {
437
+ return this.http.get(`/v1/webhooks/${id}/deliveries`);
438
+ }
439
+ /**
440
+ * Retry a failed webhook delivery
441
+ */
442
+ async retryDelivery(webhookId, deliveryId) {
443
+ return this.http.post(`/v1/webhooks/${webhookId}/deliveries/${deliveryId}/retry`);
444
+ }
445
+ };
446
+
447
+ // src/resources/broadcasts.ts
448
+ var BroadcastsResource = class {
449
+ constructor(http) {
450
+ this.http = http;
451
+ }
452
+ /**
453
+ * Create a new broadcast
454
+ */
455
+ async create(data) {
456
+ return this.http.post("/v1/broadcasts", data);
457
+ }
458
+ /**
459
+ * Get broadcast by ID
460
+ */
461
+ async get(id) {
462
+ return this.http.get(`/v1/broadcasts/${id}`);
463
+ }
464
+ /**
465
+ * List broadcasts
466
+ */
467
+ async list(params) {
468
+ const queryParams = {};
469
+ if (params?.page) queryParams.page = String(params.page);
470
+ if (params?.limit) queryParams.limit = String(params.limit);
471
+ if (params?.status) queryParams.status = params.status;
472
+ const data = await this.http.get("/v1/broadcasts", queryParams);
473
+ if (Array.isArray(data)) {
474
+ return data;
475
+ }
476
+ return data.data || [];
477
+ }
478
+ /**
479
+ * Update a broadcast
480
+ */
481
+ async update(id, data) {
482
+ return this.http.put(`/v1/broadcasts/${id}`, data);
483
+ }
484
+ /**
485
+ * Delete a broadcast
486
+ */
487
+ async delete(id) {
488
+ return this.http.delete(`/v1/broadcasts/${id}`);
489
+ }
490
+ /**
491
+ * Send a broadcast immediately
492
+ */
493
+ async send(id) {
494
+ return this.http.post(`/v1/broadcasts/${id}/send`);
495
+ }
496
+ /**
497
+ * Schedule a broadcast
498
+ */
499
+ async schedule(id, scheduledAt) {
500
+ return this.http.post(`/v1/broadcasts/${id}/schedule`, { scheduled_at: scheduledAt });
501
+ }
502
+ /**
503
+ * Cancel a scheduled broadcast
504
+ */
505
+ async cancel(id) {
506
+ return this.http.post(`/v1/broadcasts/${id}/cancel`);
507
+ }
508
+ /**
509
+ * Get broadcast statistics
510
+ */
511
+ async getStats(id) {
512
+ return this.http.get(`/v1/broadcasts/${id}/stats`);
513
+ }
514
+ };
515
+
516
+ // src/resources/segments.ts
517
+ var SegmentsResource = class {
518
+ constructor(http) {
519
+ this.http = http;
520
+ }
521
+ /**
522
+ * Create a new segment
523
+ */
524
+ async create(data) {
525
+ return this.http.post("/v1/segments", data);
526
+ }
527
+ /**
528
+ * Get segment by ID
529
+ */
530
+ async get(id) {
531
+ return this.http.get(`/v1/segments/${id}`);
532
+ }
533
+ /**
534
+ * List segments with pagination
535
+ */
536
+ async list(params) {
537
+ return this.http.get("/v1/segments", {
538
+ params
539
+ });
540
+ }
541
+ /**
542
+ * Update a segment
543
+ */
544
+ async update(id, data) {
545
+ return this.http.put(`/v1/segments/${id}`, data);
546
+ }
547
+ /**
548
+ * Delete a segment
549
+ */
550
+ async delete(id) {
551
+ return this.http.delete(`/v1/segments/${id}`);
552
+ }
553
+ /**
554
+ * Get contacts in a segment
555
+ */
556
+ async getContacts(id, params) {
557
+ return this.http.get(`/v1/segments/${id}/contacts`, {
558
+ params
559
+ });
560
+ }
561
+ /**
562
+ * Get segment contact count
563
+ */
564
+ async getCount(id) {
565
+ return this.http.get(`/v1/segments/${id}/count`);
566
+ }
567
+ };
568
+
569
+ // src/resources/api-keys.ts
570
+ var ApiKeysResource = class {
571
+ constructor(http) {
572
+ this.http = http;
573
+ }
574
+ /**
575
+ * Create a new API key.
576
+ * Note: The full key is only returned once upon creation.
577
+ */
578
+ async create(data) {
579
+ return this.http.post("/v1/api-keys", data);
580
+ }
581
+ /**
582
+ * List all active API keys.
583
+ * Note: Full keys are not returned for security.
584
+ */
585
+ async list() {
586
+ return this.http.get("/v1/api-keys");
587
+ }
588
+ /**
589
+ * Revoke an API key.
590
+ */
591
+ async revoke(id) {
592
+ return this.http.delete(`/v1/api-keys/${id}`);
593
+ }
594
+ };
595
+
596
+ // src/resources/smtp.ts
597
+ var SmtpResource = class {
598
+ constructor(http) {
599
+ this.http = http;
600
+ }
601
+ /**
602
+ * Get SMTP credentials for sending emails.
603
+ * The password is your API key.
604
+ */
605
+ async getCredentials() {
606
+ return this.http.get("/v1/smtp/credentials");
607
+ }
608
+ };
609
+
610
+ // src/resources/settings.ts
611
+ var SettingsResource = class {
612
+ constructor(http) {
613
+ this.http = http;
614
+ }
615
+ /**
616
+ * Get organization settings.
617
+ */
618
+ async getOrganization() {
619
+ return this.http.get("/v1/settings/organization");
620
+ }
621
+ /**
622
+ * Update organization settings.
623
+ */
624
+ async updateOrganization(data) {
625
+ return this.http.put("/v1/settings/organization", data);
626
+ }
627
+ /**
628
+ * Get team members.
629
+ */
630
+ async getTeam() {
631
+ return this.http.get("/v1/settings/team");
632
+ }
633
+ /**
634
+ * Get unsubscribe settings.
635
+ */
636
+ async getUnsubscribeSettings() {
637
+ return this.http.get("/v1/settings/unsubscribe");
638
+ }
639
+ /**
640
+ * Update unsubscribe settings.
641
+ */
642
+ async updateUnsubscribeSettings(data) {
643
+ return this.http.put("/v1/settings/unsubscribe", data);
644
+ }
645
+ };
646
+
647
+ // src/resources/metrics.ts
648
+ var MetricsResource = class {
649
+ constructor(http) {
650
+ this.http = http;
651
+ }
652
+ /**
653
+ * Get usage metrics for a specified number of days.
654
+ */
655
+ async getUsage(days = 30) {
656
+ return this.http.get("/v1/metrics/usage", { params: { days } });
657
+ }
658
+ /**
659
+ * Get aggregated email delivery metrics.
660
+ */
661
+ async getEmailMetrics() {
662
+ return this.http.get("/v1/metrics/emails");
663
+ }
664
+ };
665
+
666
+ // src/client.ts
667
+ var Emailr = class {
668
+ constructor(config) {
669
+ if (!config.apiKey) {
670
+ throw new Error("API key is required");
671
+ }
672
+ this.http = new HttpClient({
673
+ apiKey: config.apiKey,
674
+ baseUrl: config.baseUrl ?? "https://api.emailr.dev",
675
+ timeout: config.timeout ?? 3e4
676
+ });
677
+ this.emails = new EmailsResource(this.http);
678
+ this.contacts = new ContactsResource(this.http);
679
+ this.templates = new TemplatesResource(this.http);
680
+ this.domains = new DomainsResource(this.http);
681
+ this.webhooks = new WebhooksResource(this.http);
682
+ this.broadcasts = new BroadcastsResource(this.http);
683
+ this.segments = new SegmentsResource(this.http);
684
+ this.apiKeys = new ApiKeysResource(this.http);
685
+ this.smtp = new SmtpResource(this.http);
686
+ this.settings = new SettingsResource(this.http);
687
+ this.metrics = new MetricsResource(this.http);
688
+ }
689
+ };
690
+ // Annotate the CommonJS export names for ESM import in node:
691
+ 0 && (module.exports = {
692
+ AuthenticationError,
693
+ Emailr,
694
+ EmailrClient,
695
+ EmailrError,
696
+ NetworkError,
697
+ NotFoundError,
698
+ RateLimitError,
699
+ ValidationError
700
+ });