Skip to content

Commit 00c39a1

Browse files
authored
feat: support domain capability methods on SDK (#743)
1 parent 7aa9f77 commit 00c39a1

File tree

8 files changed

+322
-3
lines changed

8 files changed

+322
-3
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import type { DomainCapabilities } from '../../domains/interfaces/domain';
2+
13
export interface DomainApiOptions {
24
name: string;
35
region?: string;
46
custom_return_path?: string;
7+
capabilities?: Partial<DomainCapabilities>;
58
}

src/common/utils/parse-domain-to-api-options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ export function parseDomainToApiOptions(
88
name: domain.name,
99
region: domain.region,
1010
custom_return_path: domain.customReturnPath,
11+
capabilities: domain.capabilities,
1112
};
1213
}

src/domains/domains.spec.ts

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,226 @@ describe('Domains', () => {
448448
`);
449449
});
450450
});
451+
452+
describe('with capabilities', () => {
453+
it('creates a domain with sending only', async () => {
454+
const response: CreateDomainResponseSuccess = {
455+
id: '3d4a472d-bc6d-4dd2-aa9d-d3d50ce87222',
456+
name: 'resend.com',
457+
created_at: '2023-04-07T22:48:33.420498+00:00',
458+
status: 'not_started',
459+
capabilities: {
460+
sending: 'enabled',
461+
receiving: 'disabled',
462+
},
463+
records: [
464+
{
465+
record: 'DKIM',
466+
name: 'resend._domainkey',
467+
value: 'nu22pfdfqaxdybogtw3ebaokmalv5mxg.dkim.com.',
468+
type: 'CNAME',
469+
status: 'not_started',
470+
ttl: 'Auto',
471+
},
472+
],
473+
region: 'us-east-1',
474+
};
475+
476+
fetchMock.mockOnce(JSON.stringify(response), {
477+
status: 200,
478+
headers: {
479+
'content-type': 'application/json',
480+
},
481+
});
482+
483+
const payload: CreateDomainOptions = {
484+
name: 'resend.com',
485+
capabilities: {
486+
sending: 'enabled',
487+
receiving: 'disabled',
488+
},
489+
};
490+
491+
const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
492+
const result = await resend.domains.create(payload);
493+
494+
expect(result.data?.capabilities).toEqual({
495+
sending: 'enabled',
496+
receiving: 'disabled',
497+
});
498+
expect(result.error).toBeNull();
499+
});
500+
501+
it('creates a domain with receiving only', async () => {
502+
const response: CreateDomainResponseSuccess = {
503+
id: '3d4a472d-bc6d-4dd2-aa9d-d3d50ce87222',
504+
name: 'resend.com',
505+
created_at: '2023-04-07T22:48:33.420498+00:00',
506+
status: 'not_started',
507+
capabilities: {
508+
sending: 'disabled',
509+
receiving: 'enabled',
510+
},
511+
records: [
512+
{
513+
record: 'DKIM',
514+
name: 'resend._domainkey',
515+
value: 'nu22pfdfqaxdybogtw3ebaokmalv5mxg.dkim.com.',
516+
type: 'CNAME',
517+
status: 'not_started',
518+
ttl: 'Auto',
519+
},
520+
{
521+
record: 'Receiving',
522+
name: 'resend.com',
523+
value: 'inbound-mx.resend.com',
524+
type: 'MX',
525+
ttl: 'Auto',
526+
status: 'not_started',
527+
priority: 10,
528+
},
529+
],
530+
region: 'us-east-1',
531+
};
532+
533+
fetchMock.mockOnce(JSON.stringify(response), {
534+
status: 200,
535+
headers: {
536+
'content-type': 'application/json',
537+
},
538+
});
539+
540+
const payload: CreateDomainOptions = {
541+
name: 'resend.com',
542+
capabilities: {
543+
sending: 'disabled',
544+
receiving: 'enabled',
545+
},
546+
};
547+
548+
const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
549+
const result = await resend.domains.create(payload);
550+
551+
expect(result.data?.capabilities).toEqual({
552+
sending: 'disabled',
553+
receiving: 'enabled',
554+
});
555+
expect(result.error).toBeNull();
556+
});
557+
558+
it('creates a domain with both sending and receiving', async () => {
559+
const response: CreateDomainResponseSuccess = {
560+
id: '3d4a472d-bc6d-4dd2-aa9d-d3d50ce87222',
561+
name: 'resend.com',
562+
created_at: '2023-04-07T22:48:33.420498+00:00',
563+
status: 'not_started',
564+
capabilities: {
565+
sending: 'enabled',
566+
receiving: 'enabled',
567+
},
568+
records: [
569+
{
570+
record: 'DKIM',
571+
name: 'resend._domainkey',
572+
value: 'nu22pfdfqaxdybogtw3ebaokmalv5mxg.dkim.com.',
573+
type: 'CNAME',
574+
status: 'not_started',
575+
ttl: 'Auto',
576+
},
577+
{
578+
record: 'SPF',
579+
name: 'bounces',
580+
type: 'MX',
581+
ttl: 'Auto',
582+
status: 'not_started',
583+
value: 'feedback-smtp.us-east-1.com',
584+
priority: 10,
585+
},
586+
{
587+
record: 'Receiving',
588+
name: 'resend.com',
589+
value: 'inbound-mx.resend.com',
590+
type: 'MX',
591+
ttl: 'Auto',
592+
status: 'not_started',
593+
priority: 10,
594+
},
595+
],
596+
region: 'us-east-1',
597+
};
598+
599+
fetchMock.mockOnce(JSON.stringify(response), {
600+
status: 200,
601+
headers: {
602+
'content-type': 'application/json',
603+
},
604+
});
605+
606+
const payload: CreateDomainOptions = {
607+
name: 'resend.com',
608+
capabilities: {
609+
sending: 'enabled',
610+
receiving: 'enabled',
611+
},
612+
};
613+
614+
const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
615+
const result = await resend.domains.create(payload);
616+
617+
expect(result.data?.capabilities).toEqual({
618+
sending: 'enabled',
619+
receiving: 'enabled',
620+
});
621+
expect(result.error).toBeNull();
622+
});
623+
624+
it('creates a domain with partial capabilities (only specifying sending)', async () => {
625+
const response: CreateDomainResponseSuccess = {
626+
id: '3d4a472d-bc6d-4dd2-aa9d-d3d50ce87222',
627+
name: 'resend.com',
628+
created_at: '2023-04-07T22:48:33.420498+00:00',
629+
status: 'not_started',
630+
capabilities: {
631+
sending: 'disabled',
632+
receiving: 'enabled',
633+
},
634+
records: [
635+
{
636+
record: 'DKIM',
637+
name: 'resend._domainkey',
638+
value: 'nu22pfdfqaxdybogtw3ebaokmalv5mxg.dkim.com.',
639+
type: 'CNAME',
640+
status: 'not_started',
641+
ttl: 'Auto',
642+
},
643+
],
644+
region: 'us-east-1',
645+
};
646+
647+
fetchMock.mockOnce(JSON.stringify(response), {
648+
status: 200,
649+
headers: {
650+
'content-type': 'application/json',
651+
},
652+
});
653+
654+
const payload: CreateDomainOptions = {
655+
name: 'resend.com',
656+
capabilities: {
657+
sending: 'disabled',
658+
},
659+
};
660+
661+
const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
662+
const result = await resend.domains.create(payload);
663+
664+
expect(result.data?.capabilities).toEqual({
665+
sending: 'disabled',
666+
receiving: 'enabled',
667+
});
668+
expect(result.error).toBeNull();
669+
});
670+
});
451671
});
452672

453673
describe('list', () => {
@@ -760,6 +980,81 @@ describe('Domains', () => {
760980
}
761981
`);
762982
});
983+
984+
it('update domain capabilities', async () => {
985+
const id = '5262504e-8ed7-4fac-bd16-0d4be94bc9f2';
986+
const response: UpdateDomainsResponseSuccess = {
987+
object: 'domain',
988+
id,
989+
};
990+
991+
fetchMock.mockOnce(JSON.stringify(response), {
992+
status: 200,
993+
headers: {
994+
'content-type': 'application/json',
995+
},
996+
});
997+
998+
const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
999+
1000+
await expect(
1001+
resend.domains.update({
1002+
id,
1003+
capabilities: {
1004+
sending: 'enabled',
1005+
receiving: 'enabled',
1006+
},
1007+
}),
1008+
).resolves.toMatchInlineSnapshot(`
1009+
{
1010+
"data": {
1011+
"id": "5262504e-8ed7-4fac-bd16-0d4be94bc9f2",
1012+
"object": "domain",
1013+
},
1014+
"error": null,
1015+
"headers": {
1016+
"content-type": "application/json",
1017+
},
1018+
}
1019+
`);
1020+
});
1021+
1022+
it('update domain with partial capabilities', async () => {
1023+
const id = '5262504e-8ed7-4fac-bd16-0d4be94bc9f2';
1024+
const response: UpdateDomainsResponseSuccess = {
1025+
object: 'domain',
1026+
id,
1027+
};
1028+
1029+
fetchMock.mockOnce(JSON.stringify(response), {
1030+
status: 200,
1031+
headers: {
1032+
'content-type': 'application/json',
1033+
},
1034+
});
1035+
1036+
const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
1037+
1038+
await expect(
1039+
resend.domains.update({
1040+
id,
1041+
capabilities: {
1042+
receiving: 'enabled',
1043+
},
1044+
}),
1045+
).resolves.toMatchInlineSnapshot(`
1046+
{
1047+
"data": {
1048+
"id": "5262504e-8ed7-4fac-bd16-0d4be94bc9f2",
1049+
"object": "domain",
1050+
},
1051+
"error": null,
1052+
"headers": {
1053+
"content-type": "application/json",
1054+
},
1055+
}
1056+
`);
1057+
});
7631058
});
7641059

7651060
describe('verify', () => {

src/domains/domains.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export class Domains {
6868
click_tracking: payload.clickTracking,
6969
open_tracking: payload.openTracking,
7070
tls: payload.tls,
71+
capabilities: payload.capabilities,
7172
},
7273
);
7374
return data;
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
import type { PostOptions } from '../../common/interfaces';
22
import type { Response } from '../../interfaces';
3-
import type { Domain, DomainRecords, DomainRegion } from './domain';
3+
import type {
4+
Domain,
5+
DomainCapabilities,
6+
DomainRecords,
7+
DomainRegion,
8+
} from './domain';
49

510
export interface CreateDomainOptions {
611
name: string;
712
region?: DomainRegion;
813
customReturnPath?: string;
14+
capabilities?: Partial<DomainCapabilities>;
915
}
1016

1117
export interface CreateDomainRequestOptions extends PostOptions {}
1218

1319
export interface CreateDomainResponseSuccess
1420
extends Pick<Domain, 'name' | 'id' | 'status' | 'created_at' | 'region'> {
1521
records: DomainRecords[];
22+
capabilities: DomainCapabilities;
1623
}
1724

1825
export type CreateDomainResponse = Response<CreateDomainResponseSuccess>;

src/domains/interfaces/domain.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ export type DomainRegion =
44
| 'sa-east-1'
55
| 'ap-northeast-1';
66

7+
export type DomainCapabilityStatus = 'enabled' | 'disabled';
8+
9+
export interface DomainCapabilities {
10+
sending: DomainCapabilityStatus;
11+
receiving: DomainCapabilityStatus;
12+
}
13+
714
export type DomainNameservers =
815
| 'Amazon Route 53'
916
| 'Cloudflare'
@@ -66,4 +73,5 @@ export interface Domain {
6673
status: DomainStatus;
6774
created_at: string;
6875
region: DomainRegion;
76+
capabilities: DomainCapabilities;
6977
}

src/domains/interfaces/get-domain.interface.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import type { Response } from '../../interfaces';
22
import type { Domain, DomainRecords } from './domain';
33

44
export interface GetDomainResponseSuccess
5-
extends Pick<Domain, 'id' | 'name' | 'created_at' | 'region' | 'status'> {
5+
extends Pick<
6+
Domain,
7+
'id' | 'name' | 'created_at' | 'region' | 'status' | 'capabilities'
8+
> {
69
object: 'domain';
710
records: DomainRecords[];
811
}

0 commit comments

Comments
 (0)