supersendtx 0.2.0 → 0.4.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.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ type ApiErrorCode = 'validation_error' | 'unauthorized' | 'forbidden' | 'not_found' | 'conflict' | 'plan_limit' | 'domain_limit' | 'idempotency_conflict' | 'rate_limited' | 'upstream_error' | 'not_configured' | 'internal_error';
1
2
  type SendEmailParams = {
2
3
  from: string | {
3
4
  email: string;
@@ -11,6 +12,8 @@ type SendEmailParams = {
11
12
  reply_to?: string;
12
13
  cc?: string | string[];
13
14
  bcc?: string | string[];
15
+ /** Optional Idempotency-Key (24h TTL). */
16
+ idempotencyKey?: string;
14
17
  };
15
18
  type SendEmailResult = {
16
19
  id: string;
@@ -31,6 +34,42 @@ type EmailListItem = {
31
34
  };
32
35
  type ListEmailsParams = {
33
36
  limit?: number;
37
+ cursor?: string;
38
+ };
39
+ type ListEmailsResult = {
40
+ emails: EmailListItem[];
41
+ has_more: boolean;
42
+ next_cursor: string | null;
43
+ };
44
+ type ApiKeyScope = 'full' | 'sending';
45
+ type ApiKey = {
46
+ id: string;
47
+ name: string;
48
+ scope: ApiKeyScope;
49
+ prefix: string;
50
+ created_at: string;
51
+ last_used_at: string | null;
52
+ };
53
+ type ListApiKeysParams = {
54
+ limit?: number;
55
+ cursor?: string;
56
+ };
57
+ type ListApiKeysResult = {
58
+ data: ApiKey[];
59
+ has_more: boolean;
60
+ next_cursor: string | null;
61
+ };
62
+ type CreateApiKeyParams = {
63
+ name?: string;
64
+ scope?: ApiKeyScope;
65
+ };
66
+ type CreateApiKeyResult = {
67
+ id: string;
68
+ name: string;
69
+ scope: ApiKeyScope;
70
+ prefix: string;
71
+ token: string;
72
+ created_at: string;
34
73
  };
35
74
  type WebhookEventType = 'email.delivered' | 'email.bounced';
36
75
  type WebhookEndpoint = {
@@ -111,14 +150,21 @@ type ApiErrorBody = {
111
150
  error?: string | {
112
151
  message?: string;
113
152
  details?: unknown;
153
+ code?: string;
154
+ upgrade_url?: string;
114
155
  };
115
156
  };
116
157
 
117
158
  declare class DomainsResource {
118
159
  private readonly client;
119
160
  constructor(client: SuperSendTX);
120
- list(): Promise<{
161
+ list(params?: {
162
+ limit?: number;
163
+ cursor?: string;
164
+ }): Promise<{
121
165
  domains: Domain[];
166
+ has_more: boolean;
167
+ next_cursor: string | null;
122
168
  }>;
123
169
  get(idOrName: string): Promise<{
124
170
  domain: Domain;
@@ -129,6 +175,13 @@ declare class DomainsResource {
129
175
  delete(idOrName: string): Promise<{
130
176
  ok: boolean;
131
177
  }>;
178
+ /**
179
+ * Apply DNS using a Cloudflare token stored in the SuperSend TX dashboard
180
+ * (Settings → Integrations).
181
+ */
182
+ apply(idOrName: string, options?: {
183
+ provider?: 'cloudflare';
184
+ }): Promise<ApplyDnsResult$1>;
132
185
  /**
133
186
  * Fetch SuperSend TX DNS records, then write them at Cloudflare or GoDaddy
134
187
  * using the caller's provider credentials (never sent to SuperSend TX).
@@ -139,17 +192,33 @@ declare class DomainsResource {
139
192
  declare class EmailsResource {
140
193
  private readonly client;
141
194
  constructor(client: SuperSendTX);
142
- list(params?: ListEmailsParams): Promise<{
143
- emails: EmailListItem[];
195
+ list(params?: ListEmailsParams): Promise<ListEmailsResult>;
196
+ get(id: string): Promise<{
197
+ email: EmailListItem;
144
198
  }>;
145
199
  send(params: SendEmailParams): Promise<SendEmailResult>;
146
200
  }
147
201
 
202
+ declare class KeysResource {
203
+ private readonly client;
204
+ constructor(client: SuperSendTX);
205
+ list(params?: ListApiKeysParams): Promise<ListApiKeysResult>;
206
+ create(params?: CreateApiKeyParams): Promise<CreateApiKeyResult>;
207
+ remove(id: string): Promise<{
208
+ ok: boolean;
209
+ }>;
210
+ }
211
+
148
212
  declare class WebhooksResource {
149
213
  private readonly client;
150
214
  constructor(client: SuperSendTX);
151
- list(): Promise<{
215
+ list(params?: {
216
+ limit?: number;
217
+ cursor?: string;
218
+ }): Promise<{
152
219
  webhooks: WebhookEndpoint[];
220
+ has_more: boolean;
221
+ next_cursor: string | null;
153
222
  }>;
154
223
  create(params: CreateWebhookParams): Promise<WebhookEndpointWithSecret>;
155
224
  delete(id: string): Promise<{
@@ -164,6 +233,7 @@ declare class SuperSendTX {
164
233
  readonly domains: DomainsResource;
165
234
  readonly emails: EmailsResource;
166
235
  readonly webhooks: WebhooksResource;
236
+ readonly apiKeys: KeysResource;
167
237
  constructor(apiKey: string, options?: SuperSendTXOptions);
168
238
  get baseUrl(): string;
169
239
  get fetchImpl(): typeof fetch;
@@ -173,7 +243,12 @@ declare class SuperSendTX {
173
243
  declare class SuperSendTXError extends Error {
174
244
  readonly status: number;
175
245
  readonly details?: unknown;
176
- constructor(message: string, status: number, details?: unknown);
246
+ readonly code?: string;
247
+ readonly upgradeUrl?: string;
248
+ constructor(message: string, status: number, details?: unknown, options?: {
249
+ code?: string;
250
+ upgradeUrl?: string;
251
+ });
177
252
  static fromResponse(status: number, body: ApiErrorBody): SuperSendTXError;
178
253
  }
179
254
 
@@ -207,4 +282,4 @@ declare function applyDnsRecords(input: {
207
282
  fetchImpl?: typeof fetch;
208
283
  }): Promise<ApplyDnsResult>;
209
284
 
210
- export { type ApplyDnsParams, type ApplyDnsRecordResult$1 as ApplyDnsRecordResult, type ApplyDnsResult$1 as ApplyDnsResult, type CreateDomainParams, type CreateDomainResult, type CreateWebhookParams, DEFAULT_API_BASE_URL, type DnsProviderName$1 as DnsProviderName, type DnsRecord, type Domain, type DomainStatus, type EmailListItem, type ListEmailsParams, type SendEmailParams, type SendEmailResult, SuperSendTX, SuperSendTXError, type SuperSendTXOptions, type VerifyDomainResult, type WebhookEndpoint, type WebhookEndpointWithSecret, type WebhookEventType, applyDnsRecords, mergeSpfInclude };
285
+ export { type ApiErrorCode, type ApiKey, type ApiKeyScope, type ApplyDnsParams, type ApplyDnsRecordResult$1 as ApplyDnsRecordResult, type ApplyDnsResult$1 as ApplyDnsResult, type CreateApiKeyParams, type CreateApiKeyResult, type CreateDomainParams, type CreateDomainResult, type CreateWebhookParams, DEFAULT_API_BASE_URL, type DnsProviderName$1 as DnsProviderName, type DnsRecord, type Domain, type DomainStatus, type EmailListItem, type ListApiKeysParams, type ListApiKeysResult, type ListEmailsParams, type ListEmailsResult, type SendEmailParams, type SendEmailResult, SuperSendTX, SuperSendTXError, type SuperSendTXOptions, type VerifyDomainResult, type WebhookEndpoint, type WebhookEndpointWithSecret, type WebhookEventType, applyDnsRecords, mergeSpfInclude };
package/dist/index.js CHANGED
@@ -1,16 +1,20 @@
1
1
  // src/errors.ts
2
2
  var SuperSendTXError = class _SuperSendTXError extends Error {
3
- constructor(message, status, details) {
3
+ constructor(message, status, details, options) {
4
4
  super(message);
5
5
  this.name = "SuperSendTXError";
6
6
  this.status = status;
7
7
  this.details = details;
8
+ this.code = options?.code;
9
+ this.upgradeUrl = options?.upgradeUrl;
8
10
  }
9
11
  static fromResponse(status, body) {
10
12
  const err = body.error;
11
13
  const message = typeof err === "string" ? err : err?.message || `Request failed with status ${status}`;
12
14
  const details = typeof err === "object" && err ? err.details : void 0;
13
- return new _SuperSendTXError(message, status, details);
15
+ const code = typeof err === "object" && err && "code" in err ? String(err.code) : void 0;
16
+ const upgradeUrl = typeof err === "object" && err && "upgrade_url" in err ? String(err.upgrade_url) : void 0;
17
+ return new _SuperSendTXError(message, status, details, { code, upgradeUrl });
14
18
  }
15
19
  };
16
20
 
@@ -337,8 +341,12 @@ var DomainsResource = class {
337
341
  constructor(client) {
338
342
  this.client = client;
339
343
  }
340
- async list() {
341
- return this.client.request("/domains", { method: "GET" });
344
+ async list(params = {}) {
345
+ const search = new URLSearchParams();
346
+ if (params.limit != null) search.set("limit", String(params.limit));
347
+ if (params.cursor) search.set("cursor", params.cursor);
348
+ const query = search.toString();
349
+ return this.client.request(`/domains${query ? `?${query}` : ""}`, { method: "GET" });
342
350
  }
343
351
  async get(idOrName) {
344
352
  return this.client.request(`/domains/${encodeURIComponent(idOrName)}`, { method: "GET" });
@@ -360,6 +368,19 @@ var DomainsResource = class {
360
368
  method: "DELETE"
361
369
  });
362
370
  }
371
+ /**
372
+ * Apply DNS using a Cloudflare token stored in the SuperSend TX dashboard
373
+ * (Settings → Integrations).
374
+ */
375
+ async apply(idOrName, options = {}) {
376
+ return this.client.request(`/domains/${encodeURIComponent(idOrName)}`, {
377
+ method: "POST",
378
+ body: JSON.stringify({
379
+ action: "apply",
380
+ provider: options.provider || "cloudflare"
381
+ })
382
+ });
383
+ }
363
384
  /**
364
385
  * Fetch SuperSend TX DNS records, then write them at Cloudflare or GoDaddy
365
386
  * using the caller's provider credentials (never sent to SuperSend TX).
@@ -387,8 +408,16 @@ var EmailsResource = class {
387
408
  this.client = client;
388
409
  }
389
410
  async list(params = {}) {
390
- const query = params.limit ? `?limit=${params.limit}` : "";
391
- return this.client.request(`/emails${query}`, {
411
+ const search = new URLSearchParams();
412
+ if (params.limit != null) search.set("limit", String(params.limit));
413
+ if (params.cursor) search.set("cursor", params.cursor);
414
+ const query = search.toString();
415
+ return this.client.request(`/emails${query ? `?${query}` : ""}`, {
416
+ method: "GET"
417
+ });
418
+ }
419
+ async get(id) {
420
+ return this.client.request(`/emails/${encodeURIComponent(id)}`, {
392
421
  method: "GET"
393
422
  });
394
423
  }
@@ -404,20 +433,59 @@ var EmailsResource = class {
404
433
  if (replyTo) payload.reply_to = replyTo;
405
434
  if (params.cc) payload.cc = params.cc;
406
435
  if (params.bcc) payload.bcc = params.bcc;
436
+ const headers = {};
437
+ if (params.idempotencyKey) {
438
+ headers["Idempotency-Key"] = params.idempotencyKey;
439
+ }
407
440
  return this.client.request("/emails", {
408
441
  method: "POST",
442
+ headers,
409
443
  body: JSON.stringify(payload)
410
444
  });
411
445
  }
412
446
  };
413
447
 
448
+ // src/keys.ts
449
+ var KeysResource = class {
450
+ constructor(client) {
451
+ this.client = client;
452
+ }
453
+ async list(params = {}) {
454
+ const search = new URLSearchParams();
455
+ if (params.limit != null) search.set("limit", String(params.limit));
456
+ if (params.cursor) search.set("cursor", params.cursor);
457
+ const query = search.toString();
458
+ return this.client.request(`/api-keys${query ? `?${query}` : ""}`, {
459
+ method: "GET"
460
+ });
461
+ }
462
+ async create(params = {}) {
463
+ return this.client.request("/api-keys", {
464
+ method: "POST",
465
+ body: JSON.stringify({
466
+ ...params.name ? { name: params.name } : {},
467
+ ...params.scope ? { scope: params.scope } : {}
468
+ })
469
+ });
470
+ }
471
+ async remove(id) {
472
+ return this.client.request(`/api-keys/${encodeURIComponent(id)}`, {
473
+ method: "DELETE"
474
+ });
475
+ }
476
+ };
477
+
414
478
  // src/webhooks.ts
415
479
  var WebhooksResource = class {
416
480
  constructor(client) {
417
481
  this.client = client;
418
482
  }
419
- async list() {
420
- return this.client.request("/webhooks", { method: "GET" });
483
+ async list(params = {}) {
484
+ const search = new URLSearchParams();
485
+ if (params.limit != null) search.set("limit", String(params.limit));
486
+ if (params.cursor) search.set("cursor", params.cursor);
487
+ const query = search.toString();
488
+ return this.client.request(`/webhooks${query ? `?${query}` : ""}`, { method: "GET" });
421
489
  }
422
490
  async create(params) {
423
491
  return this.client.request("/webhooks", {
@@ -442,6 +510,7 @@ var SuperSendTX = class {
442
510
  this.domains = new DomainsResource(this);
443
511
  this.emails = new EmailsResource(this);
444
512
  this.webhooks = new WebhooksResource(this);
513
+ this.apiKeys = new KeysResource(this);
445
514
  }
446
515
  get baseUrl() {
447
516
  return (this.options.baseUrl || DEFAULT_API_BASE_URL).replace(/\/$/, "");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "supersendtx",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "SuperSend TX transactional email API client",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,7 +12,9 @@
12
12
  "import": "./dist/index.js"
13
13
  }
14
14
  },
15
- "files": ["dist"],
15
+ "files": [
16
+ "dist"
17
+ ],
16
18
  "repository": {
17
19
  "type": "git",
18
20
  "url": "git+https://github.com/Super-Send/superTX-app.git",