@stacksjs/email 0.74.48 → 0.74.51

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 (2) hide show
  1. package/dist/drivers/ses.js +1 -1
  2. package/package.json +13 -13
@@ -1,4 +1,4 @@
1
- import{config}from"@stacksjs/config";import{SESClient}from"@stacksjs/ts-cloud";import{templateByName}from"../template";import{buildMimeMessage}from"../mime";import{filterStringHeaders}from"../validation";import{BaseEmailDriver}from"./base";export class SESDriver extends BaseEmailDriver{name="ses";client=null;getClient(){if(!this.client){const sesConfig=config?.services?.ses,explicit=sesConfig?.credentials,hasExplicit=!!(explicit?.accessKeyId&&explicit?.secretAccessKey);this.client=new SESClient(sesConfig?.region||"us-east-1",hasExplicit?{accessKeyId:explicit.accessKeyId,secretAccessKey:explicit.secretAccessKey,sessionToken:explicit.sessionToken}:void 0)}return this.client}async send(message,options){try{this.validateMessage(message);let htmlContent;if(message.template){const templ=await templateByName(message.template,options);if(templ&&"html"in templ)htmlContent=templ.html}const finalHtml=htmlContent||message.html;if(!finalHtml&&!message.text)throw Error("Email must have either HTML or text content");const fromAddress=this.formatSourceAddress({address:message.from?.address||config.email.from?.address||"",name:message.from?.name||config.email.from?.name}),toAddresses=this.formatAddresses(message.to),ccAddresses=this.formatAddresses(message.cc),bccAddresses=this.formatAddresses(message.bcc),replyToAddresses=message.replyTo?this.formatAddressList(message.replyTo):[],customHeaders=filterStringHeaders(message.headers);if(!!(message.attachments&&message.attachments.length>0)||!!customHeaders){const raw=buildMimeMessage({from:fromAddress,to:toAddresses.join(", "),cc:ccAddresses.length>0?ccAddresses.join(", "):void 0,replyTo:replyToAddresses.length>0?replyToAddresses.join(", "):void 0,customHeaders,subject:message.subject,text:message.text,html:finalHtml,attachments:message.attachments,messageIdDomain:config.email.domain}),result=await this.getClient().sendRawEmail({source:fromAddress,destinations:[...toAddresses,...ccAddresses,...bccAddresses],rawMessage:raw});return this.handleSuccess(message,result.MessageId)}const body={};if(finalHtml)body.Html={Charset:config.email.charset||"UTF-8",Data:finalHtml};if(message.text)body.Text={Charset:config.email.charset||"UTF-8",Data:message.text};const result=await this.getClient().sendEmail({FromEmailAddress:fromAddress,Destination:{ToAddresses:toAddresses,CcAddresses:ccAddresses,BccAddresses:bccAddresses},...replyToAddresses.length>0?{ReplyToAddresses:replyToAddresses}:{},Content:{Simple:{Subject:{Charset:config.email.charset||"UTF-8",Data:message.subject},Body:body}}});return this.handleSuccess(message,result.MessageId)}catch(error){return this.handleError(this.enrichSesError(error),message)}}formatSourceAddress(from){if(!from.name)return from.address;return`${/[",()<>[\]:;@\\]/.test(from.name)?`"${from.name.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`:from.name} <${from.address}>`}enrichSesError(error){const err=error instanceof Error?error:Error(String(error)),text=`${err.message} ${err.name??""}`.toLowerCase(),region=config?.services?.ses?.region||"us-east-1";if(text.includes("email address is not verified")||text.includes("not authorized to send")||text.includes("messagerejected")&&text.includes("verified")){err.message=`${err.message}
1
+ import{config}from"@stacksjs/config";import{templateByName}from"../template";import{buildMimeMessage}from"../mime";import{filterStringHeaders}from"../validation";import{BaseEmailDriver}from"./base";export class SESDriver extends BaseEmailDriver{name="ses";client=null;clientPromise=null;async getClient(){if(this.client)return this.client;if(!this.clientPromise)this.clientPromise=import("@stacksjs/ts-cloud").then(({SESClient})=>{const sesConfig=config?.services?.ses,explicit=sesConfig?.credentials,hasExplicit=!!(explicit?.accessKeyId&&explicit?.secretAccessKey);this.client=new SESClient(sesConfig?.region||"us-east-1",hasExplicit?{accessKeyId:explicit.accessKeyId,secretAccessKey:explicit.secretAccessKey,sessionToken:explicit.sessionToken}:void 0);return this.client});return this.clientPromise}async send(message,options){try{this.validateMessage(message);let htmlContent;if(message.template){const templ=await templateByName(message.template,options);if(templ&&"html"in templ)htmlContent=templ.html}const finalHtml=htmlContent||message.html;if(!finalHtml&&!message.text)throw Error("Email must have either HTML or text content");const fromAddress=this.formatSourceAddress({address:message.from?.address||config.email.from?.address||"",name:message.from?.name||config.email.from?.name}),toAddresses=this.formatAddresses(message.to),ccAddresses=this.formatAddresses(message.cc),bccAddresses=this.formatAddresses(message.bcc),replyToAddresses=message.replyTo?this.formatAddressList(message.replyTo):[],customHeaders=filterStringHeaders(message.headers),hasAttachments=!!(message.attachments&&message.attachments.length>0),hasCustomHeaders=!!customHeaders,client=await this.getClient();if(hasAttachments||hasCustomHeaders){const raw=buildMimeMessage({from:fromAddress,to:toAddresses.join(", "),cc:ccAddresses.length>0?ccAddresses.join(", "):void 0,replyTo:replyToAddresses.length>0?replyToAddresses.join(", "):void 0,customHeaders,subject:message.subject,text:message.text,html:finalHtml,attachments:message.attachments,messageIdDomain:config.email.domain}),result=await client.sendRawEmail({source:fromAddress,destinations:[...toAddresses,...ccAddresses,...bccAddresses],rawMessage:raw});return this.handleSuccess(message,result.MessageId)}const body={};if(finalHtml)body.Html={Charset:config.email.charset||"UTF-8",Data:finalHtml};if(message.text)body.Text={Charset:config.email.charset||"UTF-8",Data:message.text};const result=await client.sendEmail({FromEmailAddress:fromAddress,Destination:{ToAddresses:toAddresses,CcAddresses:ccAddresses,BccAddresses:bccAddresses},...replyToAddresses.length>0?{ReplyToAddresses:replyToAddresses}:{},Content:{Simple:{Subject:{Charset:config.email.charset||"UTF-8",Data:message.subject},Body:body}}});return this.handleSuccess(message,result.MessageId)}catch(error){return this.handleError(this.enrichSesError(error),message)}}formatSourceAddress(from){if(!from.name)return from.address;return`${/[",()<>[\]:;@\\]/.test(from.name)?`"${from.name.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`:from.name} <${from.address}>`}enrichSesError(error){const err=error instanceof Error?error:Error(String(error)),text=`${err.message} ${err.name??""}`.toLowerCase(),region=config?.services?.ses?.region||"us-east-1";if(text.includes("email address is not verified")||text.includes("not authorized to send")||text.includes("messagerejected")&&text.includes("verified")){err.message=`${err.message}
2
2
 
3
3
  SES sandbox restriction: the From and (in sandbox) every To address must be verified. Verify identities in the SES console under "Verified identities" (region: ${region}), or request production access to lift the recipient restriction.`;return err}if(text.includes("signaturedoesnotmatch")||text.includes("invalidclienttokenid")||text.includes("unable to locate credentials")||text.includes("the security token included in the request is invalid")){err.message=`${err.message}
4
4
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/email",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.74.48",
5
+ "version": "0.74.51",
6
6
  "description": "The Stacks Email integration. Painlessly create & manage your inboxes, templates, and send emails.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -61,26 +61,26 @@
61
61
  "prepublishOnly": "bun run build"
62
62
  },
63
63
  "dependencies": {
64
- "@stacksjs/config": "0.74.48",
65
- "@stacksjs/database": "0.74.48",
66
- "@stacksjs/events": "0.74.48",
67
- "@stacksjs/logging": "0.74.48",
64
+ "@stacksjs/config": "0.74.51",
65
+ "@stacksjs/database": "0.74.51",
66
+ "@stacksjs/events": "0.74.51",
67
+ "@stacksjs/logging": "0.74.51",
68
68
  "@stacksjs/mail": "^0.3.6",
69
- "@stacksjs/path": "0.74.48",
70
- "@stacksjs/storage": "0.74.48",
71
- "@stacksjs/strings": "0.74.48",
69
+ "@stacksjs/path": "0.74.51",
70
+ "@stacksjs/storage": "0.74.51",
71
+ "@stacksjs/strings": "0.74.51",
72
72
  "@stacksjs/stx": "^0.2.286",
73
73
  "@stacksjs/ts-cloud": "^0.16.0",
74
- "@stacksjs/utils": "0.74.48"
74
+ "@stacksjs/utils": "0.74.51"
75
75
  },
76
76
  "devDependencies": {
77
- "@stacksjs/cli": "0.74.48",
78
- "@stacksjs/error-handling": "0.74.48",
79
- "@stacksjs/types": "0.74.48",
77
+ "@stacksjs/cli": "0.74.51",
78
+ "@stacksjs/error-handling": "0.74.51",
79
+ "@stacksjs/types": "0.74.51",
80
80
  "better-dx": "^0.2.24"
81
81
  },
82
82
  "peerDependencies": {
83
- "@stacksjs/queue": "0.74.48"
83
+ "@stacksjs/queue": "0.74.51"
84
84
  },
85
85
  "peerDependenciesMeta": {
86
86
  "@stacksjs/queue": {