@upyo/smtp 0.5.0-dev.184 → 0.5.0-dev.188
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.cjs +71 -9
- package/dist/index.js +71 -9
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -669,17 +669,17 @@ var SmtpConnection = class {
|
|
|
669
669
|
}
|
|
670
670
|
async sendMessage(message, signal) {
|
|
671
671
|
const mailResponse = await this.sendCommand(`MAIL FROM:<${message.envelope.from}>`, signal);
|
|
672
|
-
if (mailResponse.code !== 250) throw new
|
|
672
|
+
if (mailResponse.code !== 250) throw new SmtpResponseError(`MAIL FROM failed: ${mailResponse.message}`, mailResponse.code, "MAIL FROM", mailResponse.message);
|
|
673
673
|
for (const recipient of message.envelope.to) {
|
|
674
674
|
signal?.throwIfAborted();
|
|
675
675
|
const rcptResponse = await this.sendCommand(`RCPT TO:<${recipient}>`, signal);
|
|
676
|
-
if (rcptResponse.code !== 250) throw new
|
|
676
|
+
if (rcptResponse.code !== 250) throw new SmtpResponseError(`RCPT TO failed for ${recipient}: ${rcptResponse.message}`, rcptResponse.code, "RCPT TO", rcptResponse.message);
|
|
677
677
|
}
|
|
678
678
|
const dataResponse = await this.sendCommand("DATA", signal);
|
|
679
|
-
if (dataResponse.code !== 354) throw new
|
|
679
|
+
if (dataResponse.code !== 354) throw new SmtpResponseError(`DATA failed: ${dataResponse.message}`, dataResponse.code, "DATA", dataResponse.message);
|
|
680
680
|
const content = message.raw.replace(/\n\./g, "\n..");
|
|
681
681
|
const finalResponse = await this.sendCommand(`${content}\r\n.`, signal);
|
|
682
|
-
if (finalResponse.code !== 250) throw new
|
|
682
|
+
if (finalResponse.code !== 250) throw new SmtpResponseError(`Message send failed: ${finalResponse.message}`, finalResponse.code, "DATA_END", finalResponse.message);
|
|
683
683
|
const messageId = this.extractMessageId(finalResponse.message);
|
|
684
684
|
return messageId;
|
|
685
685
|
}
|
|
@@ -720,6 +720,40 @@ var SmtpConnection = class {
|
|
|
720
720
|
}
|
|
721
721
|
};
|
|
722
722
|
/**
|
|
723
|
+
* Error thrown when an SMTP command receives an unsuccessful server reply.
|
|
724
|
+
*
|
|
725
|
+
* @since 0.5.0
|
|
726
|
+
*/
|
|
727
|
+
var SmtpResponseError = class extends Error {
|
|
728
|
+
/**
|
|
729
|
+
* The numeric SMTP reply code returned by the server.
|
|
730
|
+
*/
|
|
731
|
+
code;
|
|
732
|
+
/**
|
|
733
|
+
* The SMTP command that produced the reply.
|
|
734
|
+
*/
|
|
735
|
+
command;
|
|
736
|
+
/**
|
|
737
|
+
* The textual SMTP reply returned by the server.
|
|
738
|
+
*/
|
|
739
|
+
response;
|
|
740
|
+
/**
|
|
741
|
+
* Creates an SMTP response error.
|
|
742
|
+
*
|
|
743
|
+
* @param message Human-readable error message.
|
|
744
|
+
* @param code The numeric SMTP reply code.
|
|
745
|
+
* @param command The SMTP command that produced the reply.
|
|
746
|
+
* @param response The textual SMTP reply returned by the server.
|
|
747
|
+
*/
|
|
748
|
+
constructor(message, code, command, response) {
|
|
749
|
+
super(message);
|
|
750
|
+
this.name = "SmtpResponseError";
|
|
751
|
+
this.code = code;
|
|
752
|
+
this.command = command;
|
|
753
|
+
this.response = response;
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
/**
|
|
723
757
|
* Decodes the Base64 JSON error challenge a server sends after a failed OAuth
|
|
724
758
|
* SASL exchange, falling back to the raw message when it is not valid Base64.
|
|
725
759
|
*
|
|
@@ -1300,7 +1334,7 @@ var SmtpTransport = class {
|
|
|
1300
1334
|
} catch (error) {
|
|
1301
1335
|
if (connection != null) await this.discardConnection(connection);
|
|
1302
1336
|
options?.signal?.throwIfAborted();
|
|
1303
|
-
return createSmtpFailure(error instanceof Error ? error.message : String(error));
|
|
1337
|
+
return createSmtpFailure(error instanceof Error ? error.message : String(error), error);
|
|
1304
1338
|
}
|
|
1305
1339
|
}
|
|
1306
1340
|
/**
|
|
@@ -1343,7 +1377,7 @@ var SmtpTransport = class {
|
|
|
1343
1377
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1344
1378
|
for await (const _ of messages) {
|
|
1345
1379
|
options?.signal?.throwIfAborted();
|
|
1346
|
-
yield createSmtpFailure(errorMessage);
|
|
1380
|
+
yield createSmtpFailure(errorMessage, error);
|
|
1347
1381
|
}
|
|
1348
1382
|
return;
|
|
1349
1383
|
}
|
|
@@ -1368,7 +1402,7 @@ var SmtpTransport = class {
|
|
|
1368
1402
|
} catch (error) {
|
|
1369
1403
|
options?.signal?.throwIfAborted();
|
|
1370
1404
|
connectionValid = false;
|
|
1371
|
-
yield createSmtpFailure(error instanceof Error ? error.message : String(error));
|
|
1405
|
+
yield createSmtpFailure(error instanceof Error ? error.message : String(error), error);
|
|
1372
1406
|
}
|
|
1373
1407
|
}
|
|
1374
1408
|
else for (const message of messages) {
|
|
@@ -1389,7 +1423,7 @@ var SmtpTransport = class {
|
|
|
1389
1423
|
} catch (error) {
|
|
1390
1424
|
options?.signal?.throwIfAborted();
|
|
1391
1425
|
connectionValid = false;
|
|
1392
|
-
yield createSmtpFailure(error instanceof Error ? error.message : String(error));
|
|
1426
|
+
yield createSmtpFailure(error instanceof Error ? error.message : String(error), error);
|
|
1393
1427
|
}
|
|
1394
1428
|
}
|
|
1395
1429
|
if (connectionValid) await this.returnConnection(connection);
|
|
@@ -1482,12 +1516,40 @@ var SmtpTransport = class {
|
|
|
1482
1516
|
await this.closeAllConnections();
|
|
1483
1517
|
}
|
|
1484
1518
|
};
|
|
1485
|
-
function createSmtpFailure(message) {
|
|
1519
|
+
function createSmtpFailure(message, error) {
|
|
1520
|
+
if (error instanceof SmtpResponseError) {
|
|
1521
|
+
const classification = classifySmtpReply(error.code);
|
|
1522
|
+
return (0, __upyo_core.createFailedReceipt)(message, {
|
|
1523
|
+
provider: "smtp",
|
|
1524
|
+
code: `smtp.${error.code}`,
|
|
1525
|
+
category: classification.category,
|
|
1526
|
+
retryable: classification.retryable,
|
|
1527
|
+
attempts: 1,
|
|
1528
|
+
providerDetails: {
|
|
1529
|
+
command: error.command,
|
|
1530
|
+
response: error.response
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1486
1534
|
return (0, __upyo_core.createFailedReceipt)(message, {
|
|
1487
1535
|
provider: "smtp",
|
|
1488
1536
|
attempts: 1
|
|
1489
1537
|
});
|
|
1490
1538
|
}
|
|
1539
|
+
function classifySmtpReply(code) {
|
|
1540
|
+
if (code >= 400 && code < 500) return {
|
|
1541
|
+
category: "service-unavailable",
|
|
1542
|
+
retryable: true
|
|
1543
|
+
};
|
|
1544
|
+
if (code >= 500 && code < 600) return {
|
|
1545
|
+
category: "rejected",
|
|
1546
|
+
retryable: false
|
|
1547
|
+
};
|
|
1548
|
+
return {
|
|
1549
|
+
category: "unknown",
|
|
1550
|
+
retryable: false
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1491
1553
|
|
|
1492
1554
|
//#endregion
|
|
1493
1555
|
exports.SmtpAuthError = SmtpAuthError;
|
package/dist/index.js
CHANGED
|
@@ -646,17 +646,17 @@ var SmtpConnection = class {
|
|
|
646
646
|
}
|
|
647
647
|
async sendMessage(message, signal) {
|
|
648
648
|
const mailResponse = await this.sendCommand(`MAIL FROM:<${message.envelope.from}>`, signal);
|
|
649
|
-
if (mailResponse.code !== 250) throw new
|
|
649
|
+
if (mailResponse.code !== 250) throw new SmtpResponseError(`MAIL FROM failed: ${mailResponse.message}`, mailResponse.code, "MAIL FROM", mailResponse.message);
|
|
650
650
|
for (const recipient of message.envelope.to) {
|
|
651
651
|
signal?.throwIfAborted();
|
|
652
652
|
const rcptResponse = await this.sendCommand(`RCPT TO:<${recipient}>`, signal);
|
|
653
|
-
if (rcptResponse.code !== 250) throw new
|
|
653
|
+
if (rcptResponse.code !== 250) throw new SmtpResponseError(`RCPT TO failed for ${recipient}: ${rcptResponse.message}`, rcptResponse.code, "RCPT TO", rcptResponse.message);
|
|
654
654
|
}
|
|
655
655
|
const dataResponse = await this.sendCommand("DATA", signal);
|
|
656
|
-
if (dataResponse.code !== 354) throw new
|
|
656
|
+
if (dataResponse.code !== 354) throw new SmtpResponseError(`DATA failed: ${dataResponse.message}`, dataResponse.code, "DATA", dataResponse.message);
|
|
657
657
|
const content = message.raw.replace(/\n\./g, "\n..");
|
|
658
658
|
const finalResponse = await this.sendCommand(`${content}\r\n.`, signal);
|
|
659
|
-
if (finalResponse.code !== 250) throw new
|
|
659
|
+
if (finalResponse.code !== 250) throw new SmtpResponseError(`Message send failed: ${finalResponse.message}`, finalResponse.code, "DATA_END", finalResponse.message);
|
|
660
660
|
const messageId = this.extractMessageId(finalResponse.message);
|
|
661
661
|
return messageId;
|
|
662
662
|
}
|
|
@@ -697,6 +697,40 @@ var SmtpConnection = class {
|
|
|
697
697
|
}
|
|
698
698
|
};
|
|
699
699
|
/**
|
|
700
|
+
* Error thrown when an SMTP command receives an unsuccessful server reply.
|
|
701
|
+
*
|
|
702
|
+
* @since 0.5.0
|
|
703
|
+
*/
|
|
704
|
+
var SmtpResponseError = class extends Error {
|
|
705
|
+
/**
|
|
706
|
+
* The numeric SMTP reply code returned by the server.
|
|
707
|
+
*/
|
|
708
|
+
code;
|
|
709
|
+
/**
|
|
710
|
+
* The SMTP command that produced the reply.
|
|
711
|
+
*/
|
|
712
|
+
command;
|
|
713
|
+
/**
|
|
714
|
+
* The textual SMTP reply returned by the server.
|
|
715
|
+
*/
|
|
716
|
+
response;
|
|
717
|
+
/**
|
|
718
|
+
* Creates an SMTP response error.
|
|
719
|
+
*
|
|
720
|
+
* @param message Human-readable error message.
|
|
721
|
+
* @param code The numeric SMTP reply code.
|
|
722
|
+
* @param command The SMTP command that produced the reply.
|
|
723
|
+
* @param response The textual SMTP reply returned by the server.
|
|
724
|
+
*/
|
|
725
|
+
constructor(message, code, command, response) {
|
|
726
|
+
super(message);
|
|
727
|
+
this.name = "SmtpResponseError";
|
|
728
|
+
this.code = code;
|
|
729
|
+
this.command = command;
|
|
730
|
+
this.response = response;
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
/**
|
|
700
734
|
* Decodes the Base64 JSON error challenge a server sends after a failed OAuth
|
|
701
735
|
* SASL exchange, falling back to the raw message when it is not valid Base64.
|
|
702
736
|
*
|
|
@@ -1277,7 +1311,7 @@ var SmtpTransport = class {
|
|
|
1277
1311
|
} catch (error) {
|
|
1278
1312
|
if (connection != null) await this.discardConnection(connection);
|
|
1279
1313
|
options?.signal?.throwIfAborted();
|
|
1280
|
-
return createSmtpFailure(error instanceof Error ? error.message : String(error));
|
|
1314
|
+
return createSmtpFailure(error instanceof Error ? error.message : String(error), error);
|
|
1281
1315
|
}
|
|
1282
1316
|
}
|
|
1283
1317
|
/**
|
|
@@ -1320,7 +1354,7 @@ var SmtpTransport = class {
|
|
|
1320
1354
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1321
1355
|
for await (const _ of messages) {
|
|
1322
1356
|
options?.signal?.throwIfAborted();
|
|
1323
|
-
yield createSmtpFailure(errorMessage);
|
|
1357
|
+
yield createSmtpFailure(errorMessage, error);
|
|
1324
1358
|
}
|
|
1325
1359
|
return;
|
|
1326
1360
|
}
|
|
@@ -1345,7 +1379,7 @@ var SmtpTransport = class {
|
|
|
1345
1379
|
} catch (error) {
|
|
1346
1380
|
options?.signal?.throwIfAborted();
|
|
1347
1381
|
connectionValid = false;
|
|
1348
|
-
yield createSmtpFailure(error instanceof Error ? error.message : String(error));
|
|
1382
|
+
yield createSmtpFailure(error instanceof Error ? error.message : String(error), error);
|
|
1349
1383
|
}
|
|
1350
1384
|
}
|
|
1351
1385
|
else for (const message of messages) {
|
|
@@ -1366,7 +1400,7 @@ var SmtpTransport = class {
|
|
|
1366
1400
|
} catch (error) {
|
|
1367
1401
|
options?.signal?.throwIfAborted();
|
|
1368
1402
|
connectionValid = false;
|
|
1369
|
-
yield createSmtpFailure(error instanceof Error ? error.message : String(error));
|
|
1403
|
+
yield createSmtpFailure(error instanceof Error ? error.message : String(error), error);
|
|
1370
1404
|
}
|
|
1371
1405
|
}
|
|
1372
1406
|
if (connectionValid) await this.returnConnection(connection);
|
|
@@ -1459,12 +1493,40 @@ var SmtpTransport = class {
|
|
|
1459
1493
|
await this.closeAllConnections();
|
|
1460
1494
|
}
|
|
1461
1495
|
};
|
|
1462
|
-
function createSmtpFailure(message) {
|
|
1496
|
+
function createSmtpFailure(message, error) {
|
|
1497
|
+
if (error instanceof SmtpResponseError) {
|
|
1498
|
+
const classification = classifySmtpReply(error.code);
|
|
1499
|
+
return createFailedReceipt(message, {
|
|
1500
|
+
provider: "smtp",
|
|
1501
|
+
code: `smtp.${error.code}`,
|
|
1502
|
+
category: classification.category,
|
|
1503
|
+
retryable: classification.retryable,
|
|
1504
|
+
attempts: 1,
|
|
1505
|
+
providerDetails: {
|
|
1506
|
+
command: error.command,
|
|
1507
|
+
response: error.response
|
|
1508
|
+
}
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1463
1511
|
return createFailedReceipt(message, {
|
|
1464
1512
|
provider: "smtp",
|
|
1465
1513
|
attempts: 1
|
|
1466
1514
|
});
|
|
1467
1515
|
}
|
|
1516
|
+
function classifySmtpReply(code) {
|
|
1517
|
+
if (code >= 400 && code < 500) return {
|
|
1518
|
+
category: "service-unavailable",
|
|
1519
|
+
retryable: true
|
|
1520
|
+
};
|
|
1521
|
+
if (code >= 500 && code < 600) return {
|
|
1522
|
+
category: "rejected",
|
|
1523
|
+
retryable: false
|
|
1524
|
+
};
|
|
1525
|
+
return {
|
|
1526
|
+
category: "unknown",
|
|
1527
|
+
retryable: false
|
|
1528
|
+
};
|
|
1529
|
+
}
|
|
1468
1530
|
|
|
1469
1531
|
//#endregion
|
|
1470
1532
|
export { SmtpAuthError, SmtpTransport };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@upyo/smtp",
|
|
3
|
-
"version": "0.5.0-dev.
|
|
3
|
+
"version": "0.5.0-dev.188",
|
|
4
4
|
"description": "SMTP transport for Upyo email library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"email",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"sideEffects": false,
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@upyo/core": "0.5.0-dev.
|
|
56
|
+
"@upyo/core": "0.5.0-dev.188+e2358766"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"tsdown": "^0.12.7",
|