nodemailer 10.0.0 → 10.0.2

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.
Files changed (100) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/addressparser/index.d.ts +1 -3
  3. package/dist/cjs/base64/index.d.ts +2 -6
  4. package/dist/cjs/base64/index.js +2 -0
  5. package/dist/cjs/dkim/index.d.ts +4 -4
  6. package/dist/cjs/dkim/message-parser.d.ts +1 -3
  7. package/dist/cjs/dkim/message-parser.js +2 -0
  8. package/dist/cjs/dkim/relaxed-body.d.ts +3 -22
  9. package/dist/cjs/dkim/relaxed-body.js +5 -0
  10. package/dist/cjs/dkim/sign.d.ts +5 -5
  11. package/dist/cjs/errors.d.ts +8 -8
  12. package/dist/cjs/fetch/cookies.d.ts +8 -8
  13. package/dist/cjs/fetch/index.d.ts +15 -15
  14. package/dist/cjs/json-transport/index.d.ts +2 -2
  15. package/dist/cjs/mail-composer/index.d.ts +49 -104
  16. package/dist/cjs/mail-composer/index.js +6 -0
  17. package/dist/cjs/mailer/index.d.ts +21 -28
  18. package/dist/cjs/mailer/index.js +19 -5
  19. package/dist/cjs/mailer/mail-message.d.ts +8 -12
  20. package/dist/cjs/mailer/mail-message.js +2 -0
  21. package/dist/cjs/mime-funcs/index.d.ts +1 -1
  22. package/dist/cjs/mime-node/index.d.ts +37 -191
  23. package/dist/cjs/mime-node/index.js +45 -7
  24. package/dist/cjs/mime-node/last-newline.d.ts +1 -3
  25. package/dist/cjs/mime-node/last-newline.js +2 -0
  26. package/dist/cjs/mime-node/le-unix.d.ts +1 -5
  27. package/dist/cjs/mime-node/le-unix.js +1 -0
  28. package/dist/cjs/mime-node/le-windows.d.ts +1 -5
  29. package/dist/cjs/mime-node/le-windows.js +1 -0
  30. package/dist/cjs/nodemailer.d.ts +2 -2
  31. package/dist/cjs/package-info.d.ts +1 -1
  32. package/dist/cjs/package-info.js +1 -1
  33. package/dist/cjs/qp/index.d.ts +2 -5
  34. package/dist/cjs/qp/index.js +2 -0
  35. package/dist/cjs/sendmail-transport/index.d.ts +4 -6
  36. package/dist/cjs/ses-transport/index.d.ts +2 -2
  37. package/dist/cjs/shared/index.d.ts +31 -37
  38. package/dist/cjs/shared/index.js +19 -7
  39. package/dist/cjs/smtp-connection/data-stream.d.ts +1 -9
  40. package/dist/cjs/smtp-connection/data-stream.js +2 -0
  41. package/dist/cjs/smtp-connection/http-proxy-client.d.ts +1 -1
  42. package/dist/cjs/smtp-connection/index.d.ts +62 -403
  43. package/dist/cjs/smtp-connection/index.js +37 -1
  44. package/dist/cjs/smtp-pool/index.d.ts +8 -46
  45. package/dist/cjs/smtp-pool/index.js +9 -0
  46. package/dist/cjs/smtp-pool/pool-resource.d.ts +2 -4
  47. package/dist/cjs/smtp-transport/index.d.ts +16 -16
  48. package/dist/cjs/stream-transport/index.d.ts +3 -3
  49. package/dist/cjs/well-known/index.d.ts +9 -9
  50. package/dist/cjs/xoauth2/index.d.ts +18 -18
  51. package/dist/esm/addressparser/index.d.ts +1 -3
  52. package/dist/esm/base64/index.d.ts +2 -6
  53. package/dist/esm/base64/index.js +2 -0
  54. package/dist/esm/dkim/index.d.ts +4 -4
  55. package/dist/esm/dkim/message-parser.d.ts +1 -3
  56. package/dist/esm/dkim/message-parser.js +2 -0
  57. package/dist/esm/dkim/relaxed-body.d.ts +3 -22
  58. package/dist/esm/dkim/relaxed-body.js +5 -0
  59. package/dist/esm/dkim/sign.d.ts +5 -5
  60. package/dist/esm/errors.d.ts +8 -8
  61. package/dist/esm/fetch/cookies.d.ts +8 -8
  62. package/dist/esm/fetch/index.d.ts +15 -15
  63. package/dist/esm/json-transport/index.d.ts +2 -2
  64. package/dist/esm/mail-composer/index.d.ts +49 -104
  65. package/dist/esm/mail-composer/index.js +6 -0
  66. package/dist/esm/mailer/index.d.ts +21 -28
  67. package/dist/esm/mailer/index.js +19 -5
  68. package/dist/esm/mailer/mail-message.d.ts +8 -12
  69. package/dist/esm/mailer/mail-message.js +2 -0
  70. package/dist/esm/mime-funcs/index.d.ts +1 -1
  71. package/dist/esm/mime-node/index.d.ts +37 -191
  72. package/dist/esm/mime-node/index.js +45 -7
  73. package/dist/esm/mime-node/last-newline.d.ts +1 -3
  74. package/dist/esm/mime-node/last-newline.js +2 -0
  75. package/dist/esm/mime-node/le-unix.d.ts +1 -5
  76. package/dist/esm/mime-node/le-unix.js +1 -0
  77. package/dist/esm/mime-node/le-windows.d.ts +1 -5
  78. package/dist/esm/mime-node/le-windows.js +1 -0
  79. package/dist/esm/nodemailer.d.ts +2 -2
  80. package/dist/esm/package-info.d.ts +1 -1
  81. package/dist/esm/package-info.js +1 -1
  82. package/dist/esm/qp/index.d.ts +2 -5
  83. package/dist/esm/qp/index.js +2 -0
  84. package/dist/esm/sendmail-transport/index.d.ts +4 -6
  85. package/dist/esm/ses-transport/index.d.ts +2 -2
  86. package/dist/esm/shared/index.d.ts +31 -37
  87. package/dist/esm/shared/index.js +19 -7
  88. package/dist/esm/smtp-connection/data-stream.d.ts +1 -9
  89. package/dist/esm/smtp-connection/data-stream.js +2 -0
  90. package/dist/esm/smtp-connection/http-proxy-client.d.ts +1 -1
  91. package/dist/esm/smtp-connection/index.d.ts +62 -403
  92. package/dist/esm/smtp-connection/index.js +37 -1
  93. package/dist/esm/smtp-pool/index.d.ts +8 -46
  94. package/dist/esm/smtp-pool/index.js +9 -0
  95. package/dist/esm/smtp-pool/pool-resource.d.ts +2 -4
  96. package/dist/esm/smtp-transport/index.d.ts +16 -16
  97. package/dist/esm/stream-transport/index.d.ts +3 -3
  98. package/dist/esm/well-known/index.d.ts +9 -9
  99. package/dist/esm/xoauth2/index.d.ts +18 -18
  100. package/package.json +1 -1
@@ -954,6 +954,7 @@ class MimeNode {
954
954
  *
955
955
  * @param flag Either 'disableFileAccess' or 'disableUrlAccess'
956
956
  * @return true if this node or an ancestor closed that access
957
+ * @internal
957
958
  */
958
959
  _accessDisabled(flag) {
959
960
  // eslint-disable-next-line @typescript-eslint/no-this-alias
@@ -971,6 +972,7 @@ class MimeNode {
971
972
  *
972
973
  * @param content Node content
973
974
  * @returns Stream object
975
+ * @internal
974
976
  */
975
977
  _getStream(content) {
976
978
  let contentStream;
@@ -1037,19 +1039,41 @@ class MimeNode {
1037
1039
  *
1038
1040
  * @param addresses Addresses to be parsed
1039
1041
  * @return An array of address objects
1042
+ * @internal
1040
1043
  */
1041
1044
  _parseAddresses(addresses) {
1042
- // Collected into one list as we go. concat.apply spreads the entries into arguments
1043
- // and throws a RangeError once a recipient array is long enough to pass the
1044
- // argument limit, which a large Bcc list reaches on its own.
1045
1045
  const flattened = [];
1046
- [].concat(addresses).forEach(address => {
1046
+ // Nested arrays are flattened iteratively. concat.apply throws once a recipient list
1047
+ // is long enough to pass the argument limit, and an array handed to addressparser is
1048
+ // stringified, which recurses once per nesting level and exhausts the call stack on
1049
+ // a deep enough value. Every array is walked once, which also ends a self-referential
1050
+ // input
1051
+ const seen = new WeakSet();
1052
+ const stack = [];
1053
+ const enter = (list) => {
1054
+ if (!seen.has(list)) {
1055
+ seen.add(list);
1056
+ stack.push({ list, pos: 0 });
1057
+ }
1058
+ };
1059
+ enter(Array.isArray(addresses) ? addresses : [addresses]);
1060
+ while (stack.length) {
1061
+ const frame = stack[stack.length - 1];
1062
+ if (frame.pos >= frame.list.length) {
1063
+ stack.pop();
1064
+ continue;
1065
+ }
1066
+ const address = frame.list[frame.pos++];
1067
+ if (Array.isArray(address)) {
1068
+ enter(address);
1069
+ continue;
1070
+ }
1047
1071
  if (address && address.address) {
1048
1072
  const normalized = this._normalizeAddress(address.address);
1049
1073
  if (normalized === address.address && typeof address.name === 'string') {
1050
1074
  // there is nothing to rewrite, so there is nothing to keep off the original
1051
1075
  flattened.push(address);
1052
- return;
1076
+ continue;
1053
1077
  }
1054
1078
  // rewriting would land on the object the caller passed in and might
1055
1079
  // still hold a reference to, so rewrite a copy of it instead. An own
@@ -1059,13 +1083,13 @@ class MimeNode {
1059
1083
  copy.address = normalized;
1060
1084
  copy.name = address.name || '';
1061
1085
  flattened.push(copy);
1062
- return;
1086
+ continue;
1063
1087
  }
1064
1088
  const parsed = this._normalizeParsedAddresses((0, index_js_1.default)(address));
1065
1089
  for (let i = 0; i < parsed.length; i++) {
1066
1090
  flattened.push(parsed[i]);
1067
1091
  }
1068
- });
1092
+ }
1069
1093
  return flattened;
1070
1094
  }
1071
1095
  /**
@@ -1078,6 +1102,7 @@ class MimeNode {
1078
1102
  *
1079
1103
  * @param parsed An array of address objects, as returned by addressparser
1080
1104
  * @return The same array, with every address normalized
1105
+ * @internal
1081
1106
  */
1082
1107
  _normalizeParsedAddresses(parsed) {
1083
1108
  // addressparser builds these objects, so no caller holds a reference to rewrite around
@@ -1100,6 +1125,7 @@ class MimeNode {
1100
1125
  *
1101
1126
  * @param addresses Addresses to be parsed
1102
1127
  * @return An array of address objects
1128
+ * @internal
1103
1129
  */
1104
1130
  _parseEnvelopeAddresses(addresses) {
1105
1131
  return this._parseAddresses(addresses).map(entry => {
@@ -1114,6 +1140,7 @@ class MimeNode {
1114
1140
  *
1115
1141
  * @param key Key to be normalized
1116
1142
  * @return key in Camel-Case form
1143
+ * @internal
1117
1144
  */
1118
1145
  _normalizeHeaderKey(key) {
1119
1146
  key = (key || '')
@@ -1136,6 +1163,7 @@ class MimeNode {
1136
1163
  * Doesn't return anything, modifies object argument instead.
1137
1164
  *
1138
1165
  * @param structured Parsed header value for 'Content-Type' key
1166
+ * @internal
1139
1167
  */
1140
1168
  _handleContentType(structured) {
1141
1169
  this.contentType = structured.value.trim().toLowerCase();
@@ -1152,6 +1180,7 @@ class MimeNode {
1152
1180
  * Generates a multipart boundary value
1153
1181
  *
1154
1182
  * @return boundary value
1183
+ * @internal
1155
1184
  */
1156
1185
  _generateBoundary() {
1157
1186
  return this.rootNode.boundaryPrefix + '-' + this.rootNode.baseBoundary + '-Part_' + this._nodeId;
@@ -1161,6 +1190,7 @@ class MimeNode {
1161
1190
  *
1162
1191
  * @param key Header key
1163
1192
  * @param value Header value
1193
+ * @internal
1164
1194
  */
1165
1195
  _encodeHeaderValue(key, value) {
1166
1196
  key = this._normalizeHeaderKey(key);
@@ -1233,6 +1263,7 @@ class MimeNode {
1233
1263
  * @param addresses An array of address objects
1234
1264
  * @param [uniqueList] An array to be populated with addresses
1235
1265
  * @return address string
1266
+ * @internal
1236
1267
  */
1237
1268
  _convertAddresses(addresses, uniqueList, seenAddresses) {
1238
1269
  const values = [];
@@ -1277,6 +1308,7 @@ class MimeNode {
1277
1308
  *
1278
1309
  * @param address An array of address objects
1279
1310
  * @return address string
1311
+ * @internal
1280
1312
  */
1281
1313
  _normalizeAddress(address) {
1282
1314
  address = (address || '')
@@ -1323,6 +1355,7 @@ class MimeNode {
1323
1355
  *
1324
1356
  * @param user Local part of an address
1325
1357
  * @return Local part as a dot-atom or as a quoted-string
1358
+ * @internal
1326
1359
  */
1327
1360
  _normalizeLocalPart(user) {
1328
1361
  if (DOT_ATOM.test(user) || QUOTED_STRING.test(user)) {
@@ -1335,6 +1368,7 @@ class MimeNode {
1335
1368
  *
1336
1369
  * @param name Name part of an address
1337
1370
  * @returns Mime word encoded string if needed
1371
+ * @internal
1338
1372
  */
1339
1373
  _encodeAddressName(name) {
1340
1374
  if (!/^[\w ]*$/.test(name)) {
@@ -1354,6 +1388,7 @@ class MimeNode {
1354
1388
  *
1355
1389
  * @param value Header value to encode
1356
1390
  * @returns Mime word encoded string if needed
1391
+ * @internal
1357
1392
  */
1358
1393
  _encodeHeaderText(value) {
1359
1394
  return /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/.test(value)
@@ -1366,6 +1401,7 @@ class MimeNode {
1366
1401
  *
1367
1402
  * @param name Name part of an address
1368
1403
  * @returns Mime word encoded string if needed
1404
+ * @internal
1369
1405
  */
1370
1406
  _encodeWords(value) {
1371
1407
  // set encodeAll parameter to true even though it is against the recommendation of RFC2047,
@@ -1378,6 +1414,7 @@ class MimeNode {
1378
1414
  *
1379
1415
  * @param value Value to check for
1380
1416
  * @return either 'Q' or 'B'
1417
+ * @internal
1381
1418
  */
1382
1419
  _getTextEncoding(value) {
1383
1420
  value = (value || '').toString();
@@ -1405,6 +1442,7 @@ class MimeNode {
1405
1442
  * Generates a message id
1406
1443
  *
1407
1444
  * @return Random Message-ID value
1445
+ * @internal
1408
1446
  */
1409
1447
  _generateMessageId() {
1410
1448
  return ('<' +
@@ -1,7 +1,5 @@
1
- import { Transform, type TransformCallback } from 'node:stream';
1
+ import { Transform } from 'node:stream';
2
2
  export default class LastNewline extends Transform {
3
3
  lastByte: number | false;
4
4
  constructor();
5
- _transform(chunk: Buffer, encoding: BufferEncoding, done: TransformCallback): void;
6
- _flush(done: TransformCallback): void;
7
5
  }
@@ -6,6 +6,7 @@ class LastNewline extends node_stream_1.Transform {
6
6
  super();
7
7
  this.lastByte = false;
8
8
  }
9
+ /** @internal */
9
10
  _transform(chunk, encoding, done) {
10
11
  if (chunk.length) {
11
12
  this.lastByte = chunk[chunk.length - 1];
@@ -13,6 +14,7 @@ class LastNewline extends node_stream_1.Transform {
13
14
  this.push(chunk);
14
15
  done();
15
16
  }
17
+ /** @internal */
16
18
  _flush(done) {
17
19
  if (this.lastByte === 0x0a) {
18
20
  return done();
@@ -1,4 +1,4 @@
1
- import { Transform, type TransformCallback, type TransformOptions } from 'node:stream';
1
+ import { Transform, type TransformOptions } from 'node:stream';
2
2
  /**
3
3
  * Ensures that only <LF> is used for linebreaks
4
4
  *
@@ -6,8 +6,4 @@ import { Transform, type TransformCallback, type TransformOptions } from 'node:s
6
6
  */
7
7
  export default class LeUnix extends Transform {
8
8
  constructor(options?: TransformOptions);
9
- /**
10
- * Escapes dots
11
- */
12
- _transform(chunk: Buffer, encoding: BufferEncoding, done: TransformCallback): void;
13
9
  }
@@ -12,6 +12,7 @@ class LeUnix extends node_stream_1.Transform {
12
12
  }
13
13
  /**
14
14
  * Escapes dots
15
+ * @internal
15
16
  */
16
17
  _transform(chunk, encoding, done) {
17
18
  let buf;
@@ -1,4 +1,4 @@
1
- import { Transform, type TransformCallback, type TransformOptions } from 'node:stream';
1
+ import { Transform, type TransformOptions } from 'node:stream';
2
2
  /**
3
3
  * Ensures that only <CR><LF> sequences are used for linebreaks
4
4
  *
@@ -7,8 +7,4 @@ import { Transform, type TransformCallback, type TransformOptions } from 'node:s
7
7
  export default class LeWindows extends Transform {
8
8
  lastByte: number | false;
9
9
  constructor(options?: TransformOptions);
10
- /**
11
- * Escapes dots
12
- */
13
- _transform(chunk: Buffer, encoding: BufferEncoding, done: TransformCallback): void;
14
10
  }
@@ -13,6 +13,7 @@ class LeWindows extends node_stream_1.Transform {
13
13
  }
14
14
  /**
15
15
  * Escapes dots
16
+ * @internal
16
17
  */
17
18
  _transform(chunk, encoding, done) {
18
19
  let buf;
@@ -25,7 +25,7 @@ export interface TestAccount {
25
25
  pop3: TestAccountService;
26
26
  web: string;
27
27
  /** true if the account can also receive external mail */
28
- mxEnabled?: boolean;
28
+ mxEnabled?: boolean | undefined;
29
29
  [key: string]: unknown;
30
30
  }
31
31
  /**
@@ -77,7 +77,7 @@ export declare function createTestAccount(apiUrl?: string | false | null): Promi
77
77
  * @returns URL of the message in the Ethereal web interface, or false if the response does not carry one
78
78
  */
79
79
  export declare function getTestMessageUrl(info?: {
80
- response?: string | Buffer | null;
80
+ response?: string | Buffer | null | undefined;
81
81
  } | false | null): string | false;
82
82
  declare const nodemailer: {
83
83
  createTransport: typeof createTransport;
@@ -1,3 +1,3 @@
1
1
  export declare const name = "nodemailer";
2
- export declare const version = "10.0.0";
2
+ export declare const version = "10.0.2";
3
3
  export declare const homepage = "https://nodemailer.com/";
@@ -3,5 +3,5 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.homepage = exports.version = exports.name = void 0;
5
5
  exports.name = 'nodemailer';
6
- exports.version = '10.0.0';
6
+ exports.version = '10.0.2';
7
7
  exports.homepage = 'https://nodemailer.com/';
@@ -1,4 +1,4 @@
1
- import { Transform, type TransformCallback } from 'node:stream';
1
+ import { Transform } from 'node:stream';
2
2
  export declare function encode(buffer: Buffer | string): string;
3
3
  /**
4
4
  * Adds soft line breaks to a Quoted-Printable string
@@ -13,7 +13,7 @@ export declare function wrap(str: string, lineLength?: number): string;
13
13
  */
14
14
  export interface QPEncoderOptions {
15
15
  /** Maximum length for lines, set to false to disable wrapping */
16
- lineLength?: number | false;
16
+ lineLength?: number | false | undefined;
17
17
  }
18
18
  /**
19
19
  * Creates a transform stream for encoding data to Quoted-Printable encoding
@@ -26,8 +26,5 @@ export declare class Encoder extends Transform {
26
26
  options: QPEncoderOptions;
27
27
  inputBytes: number;
28
28
  outputBytes: number;
29
- _curLine: string;
30
29
  constructor(options?: QPEncoderOptions);
31
- _transform(chunk: Buffer | string, encoding: BufferEncoding | 'buffer', done: TransformCallback): void;
32
- _flush(done: TransformCallback): void;
33
30
  }
@@ -157,6 +157,7 @@ class Encoder extends node_stream_1.Transform {
157
157
  this.inputBytes = 0;
158
158
  this.outputBytes = 0;
159
159
  }
160
+ /** @internal */
160
161
  _transform(chunk, encoding, done) {
161
162
  let qp;
162
163
  if (encoding !== 'buffer') {
@@ -185,6 +186,7 @@ class Encoder extends node_stream_1.Transform {
185
186
  }
186
187
  done();
187
188
  }
189
+ /** @internal */
188
190
  _flush(done) {
189
191
  if (this._curLine) {
190
192
  this.outputBytes += this._curLine.length;
@@ -1,4 +1,3 @@
1
- import { spawn } from 'node:child_process';
2
1
  import type { Logger } from '../shared/index.js';
3
2
  import type { MimeNodeEnvelope } from '../mime-node/index.js';
4
3
  import type MailMessage from '../mailer/mail-message.js';
@@ -8,13 +7,13 @@ import type { default as Mail, SentMessageInfo, SendMailOptions, TransportOption
8
7
  */
9
8
  export interface SendmailTransportOptions extends TransportOptions {
10
9
  /** Selects this transport in createTransport, the binary itself is set with `path` */
11
- sendmail?: boolean | string;
10
+ sendmail?: boolean | string | undefined;
12
11
  /** Path to the sendmail binary, defaults to 'sendmail' */
13
- path?: string;
12
+ path?: string | undefined;
14
13
  /** Either 'windows' or 'unix', the line ending of the message piped to sendmail */
15
- newline?: string;
14
+ newline?: string | undefined;
16
15
  /** Arguments for the sendmail binary, replaces the default '-f <sender>' */
17
- args?: string[];
16
+ args?: string[] | undefined;
18
17
  }
19
18
  /**
20
19
  * The value the Sendmail transport hands to the send callback
@@ -41,7 +40,6 @@ export interface SendmailSentMessageInfo extends SentMessageInfo {
41
40
  */
42
41
  declare class SendmailTransport {
43
42
  mailer: Mail<SendmailSentMessageInfo>;
44
- _spawn: typeof spawn;
45
43
  options: SendmailTransportOptions;
46
44
  name: string;
47
45
  version: string;
@@ -12,9 +12,9 @@ export interface SESTransportOptions extends TransportOptions {
12
12
  /** SESv2Client instance. Its config.region provider is resolved for the domain of the returned Message-ID */
13
13
  sesClient: {
14
14
  config?: {
15
- region?: () => Promise<string>;
15
+ region?: (() => Promise<string>) | undefined;
16
16
  [key: string]: any;
17
- };
17
+ } | undefined;
18
18
  send(command: unknown): Promise<any>;
19
19
  };
20
20
  /** SendEmailCommand class, constructed with the SendEmailCommandInput of every message */
@@ -9,39 +9,36 @@ export { isProtoKey, copyOwnKeys };
9
9
  */
10
10
  export interface ResolveHostnameOptions {
11
11
  /** Hostname or IP address to resolve */
12
- host?: string;
12
+ host?: string | undefined;
13
13
  /** Server name for TLS, used as the host when no host is set */
14
- servername?: string;
14
+ servername?: string | undefined;
15
15
  /** Count loopback interfaces when checking which address families are usable */
16
- allowInternalNetworkInterfaces?: boolean;
16
+ allowInternalNetworkInterfaces?: boolean | undefined;
17
17
  /** How long a resolved value stays cached, in milliseconds (default 5 minutes) */
18
- dnsTtl?: number;
18
+ dnsTtl?: number | undefined;
19
19
  /** Query timeout in milliseconds, passed to dns.Resolver */
20
- timeout?: number;
20
+ timeout?: number | undefined;
21
21
  /** Number of query attempts, passed to dns.Resolver */
22
- tries?: number;
22
+ tries?: number | undefined;
23
23
  }
24
24
  /**
25
25
  * Resolved value handed to the resolveHostname callback
26
26
  */
27
27
  export interface ResolvedHostname {
28
28
  /** Server name to use for TLS, false when an IP literal was given without one */
29
- servername?: string | false;
29
+ servername?: string | false | undefined;
30
30
  /** Address to connect to, picked at random from the resolved addresses */
31
- host?: string | null;
32
- /** All resolved addresses, for connection fallback support */
33
- _addresses?: string[];
31
+ host?: string | null | undefined;
34
32
  /** Whether the value came from the DNS cache */
35
- cached?: boolean;
33
+ cached?: boolean | undefined;
36
34
  /** The resolver error when a cached value was used because of it */
37
- error?: Error;
35
+ error?: Error | undefined;
38
36
  }
39
37
  /**
40
38
  * Resolved addresses as stored in the DNS cache
41
39
  */
42
40
  export interface DnsCacheValue {
43
41
  addresses: string[];
44
- servername: string | false;
45
42
  }
46
43
  /**
47
44
  * A DNS cache entry
@@ -49,26 +46,26 @@ export interface DnsCacheValue {
49
46
  export interface DnsCacheEntry {
50
47
  value: DnsCacheValue;
51
48
  /** Expiration time as a timestamp, entries without one never expire */
52
- expires?: number;
49
+ expires?: number | undefined;
53
50
  }
54
51
  /**
55
52
  * Configuration object parsed from a connection url. Query parameters become
56
53
  * top level keys, `tls.*` parameters go into `tls`
57
54
  */
58
55
  export interface ConnectionUrlOptions {
59
- secure?: boolean;
60
- direct?: boolean;
61
- port?: number;
62
- host?: string;
56
+ secure?: boolean | undefined;
57
+ direct?: boolean | undefined;
58
+ port?: number | undefined;
59
+ host?: string | undefined;
63
60
  /** Well-known service name from the ?service= query parameter */
64
- service?: string;
61
+ service?: string | undefined;
65
62
  auth?: {
66
63
  user: string;
67
64
  pass: string;
68
- };
65
+ } | undefined;
69
66
  tls?: {
70
67
  [key: string]: unknown;
71
- };
68
+ } | undefined;
72
69
  [key: string]: unknown;
73
70
  }
74
71
  /**
@@ -77,12 +74,12 @@ export interface ConnectionUrlOptions {
77
74
  */
78
75
  export interface LogEntry {
79
76
  /** 'server' or 'client' for SMTP transaction lines */
80
- tnx?: string;
77
+ tnx?: string | undefined;
81
78
  /** Session id */
82
- sid?: string;
79
+ sid?: string | undefined;
83
80
  /** Connection id */
84
- cid?: string | number;
85
- level?: string;
81
+ cid?: string | number | undefined;
82
+ level?: string | undefined;
86
83
  [key: string]: any;
87
84
  }
88
85
  export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
@@ -105,7 +102,7 @@ export interface ExternalLogger {
105
102
  */
106
103
  export interface GetLoggerOptions {
107
104
  /** A bunyan compatible logger, true for the default console logger, false or unset for no logging */
108
- logger?: ExternalLogger | boolean;
105
+ logger?: ExternalLogger | boolean | undefined;
109
106
  }
110
107
  /**
111
108
  * The bunyan compatible logger interface returned by getLogger
@@ -137,9 +134,9 @@ export interface ParsedDataURI {
137
134
  */
138
135
  export interface ResolveContentOptions {
139
136
  /** Reject content that points to a file path */
140
- disableFileAccess?: boolean;
137
+ disableFileAccess?: boolean | undefined;
141
138
  /** Reject content that points to a URL */
142
- disableUrlAccess?: boolean;
139
+ disableUrlAccess?: boolean | undefined;
143
140
  }
144
141
  /**
145
142
  * An object value resolveContent understands. A plain string or Buffer value is returned as
@@ -148,23 +145,21 @@ export interface ResolveContentOptions {
148
145
  */
149
146
  export interface ContentDescriptor {
150
147
  /** The content itself, a string, a Buffer or a readable stream */
151
- content?: string | Buffer | Readable;
148
+ content?: string | Buffer | Readable | undefined;
152
149
  /** Encoding of a string `content`, it is decoded into a Buffer unless it is utf8 or ascii */
153
- encoding?: string;
150
+ encoding?: string | undefined;
154
151
  /** File path, http(s) URL or data URI to read the content from */
155
- path?: string;
152
+ path?: string | undefined;
156
153
  /** URL to fetch the content from */
157
- href?: string;
154
+ href?: string | undefined;
158
155
  /** Request headers for a URL fetch */
159
- httpHeaders?: OutgoingHttpHeaders;
156
+ httpHeaders?: OutgoingHttpHeaders | undefined;
160
157
  /** TLS settings for a URL fetch, see nmfetch */
161
158
  tls?: {
162
159
  [key: string]: any;
163
- };
160
+ } | undefined;
164
161
  }
165
162
  export type ResolveContentCallback = (err: Error | null, value?: any) => void;
166
- export declare const _lastCacheCleanup: () => number;
167
- export declare const _resetCacheCleanup: () => void;
168
163
  export declare let networkInterfaces: NodeJS.Dict<os.NetworkInterfaceInfo[]> | undefined;
169
164
  export declare const dnsCache: Map<string, DnsCacheEntry>;
170
165
  export declare const resolveHostname: (options: ResolveHostnameOptions | undefined, callback: (err: Error | null, result?: ResolvedHostname) => void) => void;
@@ -175,7 +170,6 @@ export declare const resolveHostname: (options: ResolveHostnameOptions | undefin
175
170
  * @return Configuration object
176
171
  */
177
172
  export declare const parseConnectionUrl: (str?: string | null) => ConnectionUrlOptions;
178
- export declare const _logFunc: (logger: ExternalLogger, level: string, defaults: LogEntry | undefined, data: LogEntry | undefined, message?: string, ...args: any[]) => void;
179
173
  /**
180
174
  * Returns a bunyan-compatible logger interface. Uses either provided logger or
181
175
  * creates a default console logger
@@ -54,8 +54,10 @@ const DNS_TTL = 5 * 60 * 1000;
54
54
  const CACHE_CLEANUP_INTERVAL = 30 * 1000; // Minimum 30 seconds between cleanups
55
55
  const MAX_CACHE_SIZE = 1000; // Maximum number of entries in cache
56
56
  let lastCacheCleanup = 0;
57
+ /** @internal */
57
58
  const _lastCacheCleanup = () => lastCacheCleanup;
58
59
  exports._lastCacheCleanup = _lastCacheCleanup;
60
+ /** @internal */
59
61
  const _resetCacheCleanup = () => {
60
62
  lastCacheCleanup = 0;
61
63
  };
@@ -107,7 +109,6 @@ const formatDNSValue = (value, extra) => {
107
109
  // Select a random address from available addresses, or null if none
108
110
  const host = addresses.length > 0 ? addresses[Math.floor(Math.random() * addresses.length)] : null;
109
111
  return Object.assign({
110
- servername: value.servername,
111
112
  host,
112
113
  // Include all addresses for connection fallback support
113
114
  _addresses: addresses
@@ -121,14 +122,19 @@ const resolveHostname = (options, callback) => {
121
122
  if (!options.host || node_net_1.default.isIP(options.host)) {
122
123
  // nothing to do here
123
124
  const value = {
124
- addresses: [options.host],
125
- servername: options.servername || false
125
+ addresses: [options.host]
126
126
  };
127
127
  return callback(null, formatDNSValue(value, {
128
+ servername: options.servername || false,
128
129
  cached: false
129
130
  }));
130
131
  }
131
132
  const host = options.host;
133
+ // The TLS server name belongs to the connection asking, not to the host it resolves. The
134
+ // cache is shared by every transport of the process and keyed by host alone, so a server
135
+ // name stored in it would be the one of whichever transport resolved the host first, and a
136
+ // later transport with its own tls.servername would present and verify that name instead
137
+ const servername = options.servername || host;
132
138
  let cached;
133
139
  if (exports.dnsCache.has(options.host)) {
134
140
  cached = exports.dnsCache.get(options.host);
@@ -151,6 +157,7 @@ const resolveHostname = (options, callback) => {
151
157
  }
152
158
  if (!cached.expires || cached.expires >= now) {
153
159
  return callback(null, formatDNSValue(cached.value, {
160
+ servername,
154
161
  cached: true
155
162
  }));
156
163
  }
@@ -178,14 +185,14 @@ const resolveHostname = (options, callback) => {
178
185
  const allAddresses = ipv4Addresses.concat(ipv6Addresses);
179
186
  if (allAddresses.length) {
180
187
  const value = {
181
- addresses: allAddresses,
182
- servername: options.servername || host
188
+ addresses: allAddresses
183
189
  };
184
190
  exports.dnsCache.set(host, {
185
191
  value,
186
192
  expires: Date.now() + (options.dnsTtl || DNS_TTL)
187
193
  });
188
194
  return callback(null, formatDNSValue(value, {
195
+ servername,
189
196
  cached: false
190
197
  }));
191
198
  }
@@ -198,6 +205,7 @@ const resolveHostname = (options, callback) => {
198
205
  expires: Date.now() + (options.dnsTtl || DNS_TTL)
199
206
  });
200
207
  return callback(null, formatDNSValue(cached.value, {
208
+ servername,
201
209
  cached: true,
202
210
  error: ipv4Error
203
211
  }));
@@ -212,6 +220,7 @@ const resolveHostname = (options, callback) => {
212
220
  expires: Date.now() + (options.dnsTtl || DNS_TTL)
213
221
  });
214
222
  return callback(null, formatDNSValue(cached.value, {
223
+ servername,
215
224
  cached: true,
216
225
  error: err
217
226
  }));
@@ -229,18 +238,19 @@ const resolveHostname = (options, callback) => {
229
238
  if (!supportedAddresses.length && cached) {
230
239
  // nothing was found, fallback to cached value
231
240
  return callback(null, formatDNSValue(cached.value, {
241
+ servername,
232
242
  cached: true
233
243
  }));
234
244
  }
235
245
  const value = {
236
- addresses: supportedAddresses.length ? supportedAddresses : [host],
237
- servername: options.servername || host
246
+ addresses: supportedAddresses.length ? supportedAddresses : [host]
238
247
  };
239
248
  exports.dnsCache.set(host, {
240
249
  value,
241
250
  expires: Date.now() + (options.dnsTtl || DNS_TTL)
242
251
  });
243
252
  return callback(null, formatDNSValue(value, {
253
+ servername,
244
254
  cached: false
245
255
  }));
246
256
  });
@@ -252,6 +262,7 @@ const resolveHostname = (options, callback) => {
252
262
  expires: Date.now() + (options.dnsTtl || DNS_TTL)
253
263
  });
254
264
  return callback(null, formatDNSValue(cached.value, {
265
+ servername,
255
266
  cached: true,
256
267
  error: lookupErr
257
268
  }));
@@ -331,6 +342,7 @@ const parseConnectionUrl = (str) => {
331
342
  return options;
332
343
  };
333
344
  exports.parseConnectionUrl = parseConnectionUrl;
345
+ /** @internal */
334
346
  const _logFunc = (logger, level, defaults, data, message, ...args) => {
335
347
  const entry = Object.assign({}, defaults || {}, data || {});
336
348
  delete entry.level;
@@ -1,4 +1,4 @@
1
- import { Transform, type TransformCallback, type TransformOptions } from 'node:stream';
1
+ import { Transform, type TransformOptions } from 'node:stream';
2
2
  /**
3
3
  * Escapes dots in the beginning of lines. Ends the stream with <CR><LF>.<CR><LF>
4
4
  * Also makes sure that only <CR><LF> sequences are used for linebreaks
@@ -11,12 +11,4 @@ export default class DataStream extends Transform {
11
11
  outByteCount: number;
12
12
  lastByte: number | false;
13
13
  constructor(options?: TransformOptions);
14
- /**
15
- * Escapes dots
16
- */
17
- _transform(chunk: Buffer | string, encoding: BufferEncoding, done: TransformCallback): void;
18
- /**
19
- * Finalizes the stream with a dot on a single line
20
- */
21
- _flush(done: TransformCallback): void;
22
14
  }