Skip to content

Commit 37ca828

Browse files
🤖 Merge PR DefinitelyTyped#74249 [nodemailer] Remove AWS SDK from dependencies, use structural types by @benjaminpjones
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 3d01071 commit 37ca828

File tree

4 files changed

+97
-15
lines changed

4 files changed

+97
-15
lines changed

‎types/nodemailer/lib/ses-transport/index.d.ts‎

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/// <reference types="node" />
22

3-
import * as aws from "@aws-sdk/client-sesv2";
43
import { EventEmitter } from "node:events";
54

65
import { Transport, TransportOptions } from "../..";
@@ -12,25 +11,66 @@ import MailMessage = require("../mailer/mail-message");
1211
import MimeNode = require("../mime-node");
1312

1413
declare namespace SESTransport {
14+
/**
15+
* Minimal structural shape of SESv2 SendEmail input.
16+
* This is intentionally structural so @types/nodemailer does not require
17+
* installing @aws-sdk/client-sesv2.
18+
*
19+
* If you want the full, exact type, install @aws-sdk/client-sesv2 in your
20+
* app and use its types directly in your own code.
21+
*/
22+
interface SendEmailRequestLike {
23+
FromEmailAddress?: string;
24+
Destination?: {
25+
ToAddresses?: string[];
26+
CcAddresses?: string[];
27+
BccAddresses?: string[];
28+
};
29+
ReplyToAddresses?: string[];
30+
Content?: unknown;
31+
EmailTags?: Array<{ Name?: string; Value?: string }>;
32+
ConfigurationSetName?: string;
33+
ListManagementOptions?: unknown;
34+
FeedbackForwardingEmailAddress?: string;
35+
// Allow extra fields without forcing the SDK type package
36+
[key: string]: unknown;
37+
}
38+
39+
/** Structural type matching SESv2Client from @aws-sdk/client-sesv2 */
40+
interface SESv2ClientLike {
41+
send(command: unknown, options?: unknown): Promise<{ MessageId?: string }>;
42+
config?: {
43+
region?: string | (() => Promise<string>);
44+
};
45+
}
46+
47+
/**
48+
* Constructor type for SendEmailCommand from @aws-sdk/client-sesv2.
49+
* The real type is: new(input: SendEmailCommandInput) => SendEmailCommand
50+
* Contravariance prevents typing this more strictly without pulling in aws-sdk as a dependency.
51+
*/
52+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
53+
type SendEmailCommandConstructorLike = new(input: any) => unknown;
54+
1555
interface MailOptions extends Mail.Options {
16-
/** list of keys that SendRawEmail method can take */
56+
/** Options passed to AWS SESv2 SendEmailCommand */
1757
ses?: MailSesOptions | undefined;
1858
}
1959

2060
// Keep it as an interface for backward-compatibility
2161
// eslint-disable-next-line @typescript-eslint/no-empty-interface
22-
interface MailSesOptions extends Partial<aws.SendEmailRequest> {}
62+
interface MailSesOptions extends Partial<SendEmailRequestLike> {}
2363

2464
interface Options extends MailOptions, TransportOptions {
25-
/** is an option that expects an instantiated aws.SES object */
65+
/** An object containing an instantiated SESv2Client and the SendEmailCommand class */
2666
SES: {
27-
sesClient: aws.SESv2Client;
28-
SendEmailCommand: typeof aws.SendEmailCommand;
67+
sesClient: SESv2ClientLike;
68+
SendEmailCommand: SendEmailCommandConstructorLike;
2969
};
3070
}
3171

3272
interface SentMessageInfo {
33-
/** an envelope object {from:‘address’, to:[‘address’]} */
73+
/** an envelope object {from:'address', to:['address']} */
3474
envelope: MimeNode.Envelope;
3575
/** the Message-ID header value. This value is derived from the response of SES API, so it differs from the Message-ID values used in logging. */
3676
messageId: string;

‎types/nodemailer/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
"https://nodemailer.com"
88
],
99
"dependencies": {
10-
"@aws-sdk/client-sesv2": "^3.839.0",
1110
"@types/node": "*"
1211
},
1312
"devDependencies": {
13+
"@aws-sdk/client-sesv2": "^3.839.0",
1414
"@types/nodemailer": "workspace:."
1515
},
1616
"owners": [

‎types/nodemailer/v6/lib/ses-transport/index.d.ts‎

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/// <reference types="node" />
22

3-
import * as aws from "@aws-sdk/client-ses";
43
import { EventEmitter } from "node:events";
54

65
import { Transport, TransportOptions } from "../..";
@@ -10,31 +9,74 @@ import MailMessage = require("../mailer/mail-message");
109
import MimeNode = require("../mime-node");
1110

1211
declare namespace SESTransport {
12+
/**
13+
* Minimal structural shape of SES SendEmail input.
14+
* This is intentionally structural so @types/nodemailer does not require
15+
* installing @aws-sdk/client-ses.
16+
*
17+
* If you want the full, exact type, install @aws-sdk/client-ses in your
18+
* app and use its types directly in your own code.
19+
*/
20+
interface SendEmailRequestLike {
21+
Source?: string;
22+
Destination?: {
23+
ToAddresses?: string[];
24+
CcAddresses?: string[];
25+
BccAddresses?: string[];
26+
};
27+
Message?: unknown;
28+
ReplyToAddresses?: string[];
29+
ReturnPath?: string;
30+
SourceArn?: string;
31+
ReturnPathArn?: string;
32+
Tags?: Array<{ Name?: string; Value?: string }>;
33+
ConfigurationSetName?: string;
34+
// Allow extra fields without forcing the SDK type package
35+
[key: string]: unknown;
36+
}
37+
38+
/** Structural type matching SES client from @aws-sdk/client-ses */
39+
interface SESClientLike {
40+
/** Used with v3 low-level client + SendRawEmailCommand */
41+
send?(command: unknown): Promise<{ MessageId?: string }>;
42+
/** Used with v3 high-level SES class or v2 SDK */
43+
sendRawEmail?(params: unknown, options?: unknown): Promise<{ MessageId?: string }>;
44+
config?: {
45+
region?: string | (() => Promise<string>);
46+
};
47+
}
48+
49+
/** Structural type matching the aws module shape */
50+
interface AwsModuleLike {
51+
SendRawEmailCommand?: unknown;
52+
[key: string]: unknown;
53+
}
54+
1355
interface MailOptions extends Mail.Options {
1456
/** list of keys that SendRawEmail method can take */
1557
ses?: MailSesOptions | undefined;
1658
}
1759

1860
// Keep it as an interface for backward-compatibility
1961
// eslint-disable-next-line @typescript-eslint/no-empty-interface
20-
interface MailSesOptions extends Partial<aws.SendEmailRequest> {}
62+
interface MailSesOptions extends Partial<SendEmailRequestLike> {}
2163

2264
interface Options extends MailOptions, TransportOptions {
2365
/** An option that expects an instantiated aws.SES object */
2466
SES:
2567
| {
26-
ses: aws.SES;
27-
aws: typeof aws;
68+
ses: SESClientLike;
69+
aws: AwsModuleLike;
2870
}
29-
| aws.SES;
71+
| SESClientLike;
3072
/** How many messages per second is allowed to be delivered to SES */
3173
maxConnections?: number | undefined;
3274
/** How many parallel connections to allow towards SES */
3375
sendingRate?: number | undefined;
3476
}
3577

3678
interface SentMessageInfo {
37-
/** an envelope object {from:‘address’, to:[‘address’]} */
79+
/** an envelope object {from:'address', to:['address']} */
3880
envelope: MimeNode.Envelope;
3981
/** the Message-ID header value. This value is derived from the response of SES API, so it differs from the Message-ID values used in logging. */
4082
messageId: string;

‎types/nodemailer/v6/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
"https://nodemailer.com"
88
],
99
"dependencies": {
10-
"@aws-sdk/client-ses": "^3.731.1",
1110
"@types/node": "*"
1211
},
1312
"devDependencies": {
13+
"@aws-sdk/client-ses": "^3.731.1",
1414
"@types/nodemailer": "workspace:."
1515
},
1616
"owners": [

0 commit comments

Comments
 (0)