@sqrzro/server 2.0.0-bz.64 → 2.0.0-bz.65

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.
@@ -1,3 +1,3 @@
1
- 'use strict';var m=require('@sendgrid/mail'),p=require('stream');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var m__default=/*#__PURE__*/_interopDefault(m);var p__default=/*#__PURE__*/_interopDefault(p);function w(t,e){return {subject:t,template:e}}async function u(t){let e=(await import('react-dom/server')).default;return new Promise(o=>{let r=new p__default.default.Writable,n="";function s(c,l,g){n+=c.toString(),g();}r._write=s;let{pipe:a}=e.renderToPipeableStream(t,{onShellReady:()=>{a(r),o(n);}});})}async function f(t,e){let{subject:o,template:r}=t,n=await r(e),s=await u(n);return {subject:o,html:s}}function h(){if(!process.env.MAIL_FROM)throw new Error("Mail from address has not been set");let t=/^(?<name>[^<]+)<(?<email>[^>]+)>$/u.exec(process.env.MAIL_FROM);if(!t?.groups?.name||!t?.groups?.email)throw new Error('Mail from address is not the correct format. It should be "Name <email>".');return {email:t.groups.email.trim(),name:t.groups.name.trim()}}function i(t){return t?Array.isArray(t)?t.map(e=>({email:e})):[{email:t}]:[]}async function M(t){if(!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");let[e,o]=process.env.MAIL_API_KEY.split("."),r=Array.isArray(t.to)?t.to.map(n=>({email:n})):[{email:t.to}];try{return (await(await fetch(`https://sandbox.api.mailtrap.io/api/send/${e}`,{method:"POST",headers:{"Api-Token":o,"Content-Type":"application/json"},body:JSON.stringify({attachments:t.attachments,bcc:i(t.bcc),cc:i(t.cc),from:t.from,html:t.html,subject:t.subject,to:r})})).json()).success}catch{return !1}}async function b(t){if(process.env.APP_ENV!=="production")throw new Error("Trying to run production mail in a development environment");if(!process.env.MAIL_ENABLE_PRODUCTION)throw new Error("Mail has not been enabled in production. Please add MAIL_ENABLE_PRODUCTION to your environment variables.");if(!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");m__default.default.setApiKey(process.env.MAIL_API_KEY);try{let e=await m__default.default.send({attachments:t.attachments,bcc:i(t.bcc),cc:i(t.cc),from:t.from,html:t.html,to:i(t.to),subject:t.subject});return console.log(e),e[0].statusCode.toString().startsWith("2")}catch(e){return console.log(e),!1}}async function E(t,e,o,r,n){if(console.log(1),!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");let s=h(),{subject:a,html:c}=await f(t,e),l={attachments:n,bcc:r?.bcc,cc:r?.cc,from:s,html:c,subject:a,to:o};return process.env.APP_ENV==="production"?(console.log(2),b(l)):(console.log(3),M(l))}
2
- exports.createMail=w;exports.getMail=f;exports.sendMail=E;//# sourceMappingURL=index.cjs.map
1
+ 'use strict';var l=require('@sendgrid/mail'),u=require('stream');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var l__default=/*#__PURE__*/_interopDefault(l);var u__default=/*#__PURE__*/_interopDefault(u);function A(t,e){return {subject:t,template:e}}async function g(t){let e=(await import('react-dom/server')).default;return new Promise(o=>{let n=new u__default.default.Writable,r="";function i(c,m,p){r+=c.toString(),p();}n._write=i;let{pipe:a}=e.renderToPipeableStream(t,{onShellReady:()=>{a(n),o(r);}});})}async function f(t,e){let{subject:o,template:n}=t,r=await n(e),i=await g(r);return {subject:o,html:i}}function h(){if(!process.env.MAIL_FROM)throw new Error("Mail from address has not been set");let t=/^(?<name>[^<]+)<(?<email>[^>]+)>$/u.exec(process.env.MAIL_FROM);if(!t?.groups?.name||!t?.groups?.email)throw new Error('Mail from address is not the correct format. It should be "Name <email>".');return {email:t.groups.email.trim(),name:t.groups.name.trim()}}function s(t){return t?Array.isArray(t)?t.map(e=>({email:e})):[{email:t}]:[]}async function M(t){if(!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");let[e,o]=process.env.MAIL_API_KEY.split("."),n=Array.isArray(t.to)?t.to.map(r=>({email:r})):[{email:t.to}];try{return (await(await fetch(`https://sandbox.api.mailtrap.io/api/send/${e}`,{method:"POST",headers:{"Api-Token":o,"Content-Type":"application/json"},body:JSON.stringify({attachments:t.attachments,bcc:s(t.bcc),cc:s(t.cc),from:t.from,html:t.html,subject:t.subject,to:n})})).json()).success}catch{return !1}}async function b(t){if(process.env.APP_ENV!=="production")throw new Error("Trying to run production mail in a development environment");if(!process.env.MAIL_ENABLE_PRODUCTION)throw new Error("Mail has not been enabled in production. Please add MAIL_ENABLE_PRODUCTION to your environment variables.");if(!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");l__default.default.setApiKey(process.env.MAIL_API_KEY);let e=await l__default.default.send({attachments:t.attachments,bcc:s(t.bcc),cc:s(t.cc),from:t.from,html:t.html,to:s(t.to),subject:t.subject});if(!e[0].statusCode.toString().startsWith("2"))throw new Error(`Mail not sent. ${JSON.stringify(e)}`);return !0}async function E(t,e,o,n,r){if(!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");let i=h(),{subject:a,html:c}=await f(t,e),m={attachments:r,bcc:n?.bcc,cc:n?.cc,from:i,html:c,subject:a,to:o};return process.env.APP_ENV==="production"?b(m):M(m)}
2
+ exports.createMail=A;exports.getMail=f;exports.sendMail=E;//# sourceMappingURL=index.cjs.map
3
3
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mail/MailService.ts"],"names":["createMail","subject","template","renderMail","element","ReactDOMServer","resolve","ws","stream","content","write","chunk","enc","next","pipe","getMail","mail","data","html","getSenderDetails","matches","transformEmailData","emails","email","sendDevelopmentMail","sendObject","id","key","to","sendProductionMail","sgMail","response","err","sendMail","options","attachments","from"],"mappings":"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","file":"index.cjs","sourcesContent":["import sgMail from '@sendgrid/mail';\n\nimport stream from 'node:stream';\n\nexport interface MailObject<T extends object> {\n subject: string;\n template: (data: T) => Promise<React.ReactElement> | React.ReactElement;\n}\n\nexport function createMail<T extends object>(\n subject: string,\n template: (data: T) => Promise<React.ReactElement> | React.ReactElement\n): MailObject<T> {\n return { subject, template };\n}\n\nasync function renderMail(element: React.ReactElement): Promise<string> {\n const ReactDOMServer = (await import('react-dom/server')).default;\n\n return new Promise((resolve) => {\n const ws = new stream.Writable();\n let content = '';\n\n function write<T extends { toString: () => string }>(\n chunk: T,\n enc: BufferEncoding,\n next: (error?: Error | null) => void\n ): void {\n content += chunk.toString();\n next();\n }\n\n ws._write = write; // eslint-disable-line no-underscore-dangle\n\n const { pipe } = ReactDOMServer.renderToPipeableStream(element, {\n onShellReady: () => {\n pipe(ws);\n resolve(content);\n },\n });\n });\n}\n\nexport async function getMail<T extends object>(\n mail: MailObject<T>,\n data: T\n): Promise<{ subject: string; html: string }> {\n const { subject, template } = mail;\n\n const element = await template(data);\n const html = await renderMail(element);\n\n return {\n subject,\n html,\n };\n}\n\nfunction getSenderDetails(): { email: string; name: string } {\n if (!process.env.MAIL_FROM) {\n throw new Error('Mail from address has not been set');\n }\n\n const matches = /^(?<name>[^<]+)<(?<email>[^>]+)>$/u.exec(process.env.MAIL_FROM);\n\n if (!matches?.groups?.name || !matches?.groups?.email) {\n throw new Error(\n 'Mail from address is not the correct format. It should be \"Name <email>\".'\n );\n }\n\n return {\n email: matches.groups.email.trim(),\n name: matches.groups.name.trim(),\n };\n}\n\nfunction transformEmailData(emails?: string[] | string): { email: string }[] {\n if (!emails) {\n return [];\n }\n return Array.isArray(emails) ? emails.map((email) => ({ email })) : [{ email: emails }];\n}\n\ninterface SendMailObject {\n attachments?: { content: string; filename: string; type: string }[];\n bcc?: string[] | string;\n cc?: string[] | string;\n from: { email: string; name: string };\n html: string;\n subject: string;\n to: string[] | string;\n}\n\nasync function sendDevelopmentMail(sendObject: SendMailObject): Promise<boolean> {\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n /*\n * The account id and api key are both in the MAIL_API_KEY variable, separated by a `.`. We need\n * to split them.\n */\n\n const [id, key] = process.env.MAIL_API_KEY.split('.');\n\n const to = Array.isArray(sendObject.to)\n ? sendObject.to.map((email) => ({ email }))\n : [{ email: sendObject.to }];\n\n try {\n const response = await fetch(`https://sandbox.api.mailtrap.io/api/send/${id}`, {\n method: 'POST',\n headers: { 'Api-Token': key, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n attachments: sendObject.attachments,\n bcc: transformEmailData(sendObject.bcc),\n cc: transformEmailData(sendObject.cc),\n from: sendObject.from,\n html: sendObject.html,\n subject: sendObject.subject,\n to,\n }),\n });\n const json = (await response.json()) as { success: boolean };\n return json.success;\n } catch (err) {\n return false;\n }\n}\n\nasync function sendProductionMail(sendObject: SendMailObject): Promise<boolean> {\n if (process.env.APP_ENV !== 'production') {\n throw new Error('Trying to run production mail in a development environment');\n }\n\n if (!process.env.MAIL_ENABLE_PRODUCTION) {\n throw new Error(\n 'Mail has not been enabled in production. Please add MAIL_ENABLE_PRODUCTION to your environment variables.'\n );\n }\n\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n sgMail.setApiKey(process.env.MAIL_API_KEY);\n\n try {\n const response = await sgMail.send({\n attachments: sendObject.attachments,\n bcc: transformEmailData(sendObject.bcc),\n cc: transformEmailData(sendObject.cc),\n from: sendObject.from,\n html: sendObject.html,\n to: transformEmailData(sendObject.to),\n subject: sendObject.subject,\n });\n console.log(response);\n return response[0].statusCode.toString().startsWith('2');\n } catch (err) {\n console.log(err);\n return false;\n }\n}\n\nexport async function sendMail<T extends object>(\n mail: MailObject<T>,\n data: T,\n to: string[] | string,\n options?: { cc?: string[]; bcc?: string[] },\n attachments?: { content: string; filename: string; type: string }[]\n): Promise<boolean> {\n console.log(1);\n\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n const from = getSenderDetails();\n const { subject, html } = await getMail(mail, data);\n\n const sendObject: SendMailObject = {\n attachments,\n bcc: options?.bcc,\n cc: options?.cc,\n from,\n html,\n subject,\n to,\n };\n\n if (process.env.APP_ENV === 'production') {\n console.log(2);\n return sendProductionMail(sendObject);\n }\n\n console.log(3);\n return sendDevelopmentMail(sendObject);\n}\n"]}
1
+ {"version":3,"sources":["../../src/mail/MailService.ts"],"names":["createMail","subject","template","renderMail","element","ReactDOMServer","resolve","ws","stream","content","write","chunk","enc","next","pipe","getMail","mail","data","html","getSenderDetails","matches","transformEmailData","emails","email","sendDevelopmentMail","sendObject","id","key","to","sendProductionMail","sgMail","response","sendMail","options","attachments","from"],"mappings":"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","file":"index.cjs","sourcesContent":["import sgMail from '@sendgrid/mail';\n\nimport stream from 'node:stream';\n\nexport interface MailObject<T extends object> {\n subject: string;\n template: (data: T) => Promise<React.ReactElement> | React.ReactElement;\n}\n\nexport function createMail<T extends object>(\n subject: string,\n template: (data: T) => Promise<React.ReactElement> | React.ReactElement\n): MailObject<T> {\n return { subject, template };\n}\n\nasync function renderMail(element: React.ReactElement): Promise<string> {\n const ReactDOMServer = (await import('react-dom/server')).default;\n\n return new Promise((resolve) => {\n const ws = new stream.Writable();\n let content = '';\n\n function write<T extends { toString: () => string }>(\n chunk: T,\n enc: BufferEncoding,\n next: (error?: Error | null) => void\n ): void {\n content += chunk.toString();\n next();\n }\n\n ws._write = write; // eslint-disable-line no-underscore-dangle\n\n const { pipe } = ReactDOMServer.renderToPipeableStream(element, {\n onShellReady: () => {\n pipe(ws);\n resolve(content);\n },\n });\n });\n}\n\nexport async function getMail<T extends object>(\n mail: MailObject<T>,\n data: T\n): Promise<{ subject: string; html: string }> {\n const { subject, template } = mail;\n\n const element = await template(data);\n const html = await renderMail(element);\n\n return {\n subject,\n html,\n };\n}\n\nfunction getSenderDetails(): { email: string; name: string } {\n if (!process.env.MAIL_FROM) {\n throw new Error('Mail from address has not been set');\n }\n\n const matches = /^(?<name>[^<]+)<(?<email>[^>]+)>$/u.exec(process.env.MAIL_FROM);\n\n if (!matches?.groups?.name || !matches?.groups?.email) {\n throw new Error(\n 'Mail from address is not the correct format. It should be \"Name <email>\".'\n );\n }\n\n return {\n email: matches.groups.email.trim(),\n name: matches.groups.name.trim(),\n };\n}\n\nfunction transformEmailData(emails?: string[] | string): { email: string }[] {\n if (!emails) {\n return [];\n }\n return Array.isArray(emails) ? emails.map((email) => ({ email })) : [{ email: emails }];\n}\n\ninterface SendMailObject {\n attachments?: { content: string; filename: string; type: string }[];\n bcc?: string[] | string;\n cc?: string[] | string;\n from: { email: string; name: string };\n html: string;\n subject: string;\n to: string[] | string;\n}\n\nasync function sendDevelopmentMail(sendObject: SendMailObject): Promise<boolean> {\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n /*\n * The account id and api key are both in the MAIL_API_KEY variable, separated by a `.`. We need\n * to split them.\n */\n\n const [id, key] = process.env.MAIL_API_KEY.split('.');\n\n const to = Array.isArray(sendObject.to)\n ? sendObject.to.map((email) => ({ email }))\n : [{ email: sendObject.to }];\n\n try {\n const response = await fetch(`https://sandbox.api.mailtrap.io/api/send/${id}`, {\n method: 'POST',\n headers: { 'Api-Token': key, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n attachments: sendObject.attachments,\n bcc: transformEmailData(sendObject.bcc),\n cc: transformEmailData(sendObject.cc),\n from: sendObject.from,\n html: sendObject.html,\n subject: sendObject.subject,\n to,\n }),\n });\n const json = (await response.json()) as { success: boolean };\n return json.success;\n } catch (err) {\n return false;\n }\n}\n\nasync function sendProductionMail(sendObject: SendMailObject): Promise<boolean> {\n if (process.env.APP_ENV !== 'production') {\n throw new Error('Trying to run production mail in a development environment');\n }\n\n if (!process.env.MAIL_ENABLE_PRODUCTION) {\n throw new Error(\n 'Mail has not been enabled in production. Please add MAIL_ENABLE_PRODUCTION to your environment variables.'\n );\n }\n\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n sgMail.setApiKey(process.env.MAIL_API_KEY);\n\n const response = await sgMail.send({\n attachments: sendObject.attachments,\n bcc: transformEmailData(sendObject.bcc),\n cc: transformEmailData(sendObject.cc),\n from: sendObject.from,\n html: sendObject.html,\n to: transformEmailData(sendObject.to),\n subject: sendObject.subject,\n });\n\n if (!response[0].statusCode.toString().startsWith('2')) {\n throw new Error(`Mail not sent. ${JSON.stringify(response)}`);\n }\n\n return true;\n}\n\nexport async function sendMail<T extends object>(\n mail: MailObject<T>,\n data: T,\n to: string[] | string,\n options?: { cc?: string[]; bcc?: string[] },\n attachments?: { content: string; filename: string; type: string }[]\n): Promise<boolean> {\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n const from = getSenderDetails();\n const { subject, html } = await getMail(mail, data);\n\n const sendObject: SendMailObject = {\n attachments,\n bcc: options?.bcc,\n cc: options?.cc,\n from,\n html,\n subject,\n to,\n };\n\n if (process.env.APP_ENV === 'production') {\n return sendProductionMail(sendObject);\n }\n\n return sendDevelopmentMail(sendObject);\n}\n"]}
@@ -1,3 +1,3 @@
1
- import m from'@sendgrid/mail';import p from'stream';function w(t,e){return {subject:t,template:e}}async function u(t){let e=(await import('react-dom/server')).default;return new Promise(o=>{let r=new p.Writable,n="";function s(c,l,g){n+=c.toString(),g();}r._write=s;let{pipe:a}=e.renderToPipeableStream(t,{onShellReady:()=>{a(r),o(n);}});})}async function f(t,e){let{subject:o,template:r}=t,n=await r(e),s=await u(n);return {subject:o,html:s}}function h(){if(!process.env.MAIL_FROM)throw new Error("Mail from address has not been set");let t=/^(?<name>[^<]+)<(?<email>[^>]+)>$/u.exec(process.env.MAIL_FROM);if(!t?.groups?.name||!t?.groups?.email)throw new Error('Mail from address is not the correct format. It should be "Name <email>".');return {email:t.groups.email.trim(),name:t.groups.name.trim()}}function i(t){return t?Array.isArray(t)?t.map(e=>({email:e})):[{email:t}]:[]}async function M(t){if(!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");let[e,o]=process.env.MAIL_API_KEY.split("."),r=Array.isArray(t.to)?t.to.map(n=>({email:n})):[{email:t.to}];try{return (await(await fetch(`https://sandbox.api.mailtrap.io/api/send/${e}`,{method:"POST",headers:{"Api-Token":o,"Content-Type":"application/json"},body:JSON.stringify({attachments:t.attachments,bcc:i(t.bcc),cc:i(t.cc),from:t.from,html:t.html,subject:t.subject,to:r})})).json()).success}catch{return !1}}async function b(t){if(process.env.APP_ENV!=="production")throw new Error("Trying to run production mail in a development environment");if(!process.env.MAIL_ENABLE_PRODUCTION)throw new Error("Mail has not been enabled in production. Please add MAIL_ENABLE_PRODUCTION to your environment variables.");if(!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");m.setApiKey(process.env.MAIL_API_KEY);try{let e=await m.send({attachments:t.attachments,bcc:i(t.bcc),cc:i(t.cc),from:t.from,html:t.html,to:i(t.to),subject:t.subject});return console.log(e),e[0].statusCode.toString().startsWith("2")}catch(e){return console.log(e),!1}}async function E(t,e,o,r,n){if(console.log(1),!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");let s=h(),{subject:a,html:c}=await f(t,e),l={attachments:n,bcc:r?.bcc,cc:r?.cc,from:s,html:c,subject:a,to:o};return process.env.APP_ENV==="production"?(console.log(2),b(l)):(console.log(3),M(l))}
2
- export{w as createMail,f as getMail,E as sendMail};//# sourceMappingURL=index.js.map
1
+ import l from'@sendgrid/mail';import u from'stream';function A(t,e){return {subject:t,template:e}}async function g(t){let e=(await import('react-dom/server')).default;return new Promise(o=>{let n=new u.Writable,r="";function i(c,m,p){r+=c.toString(),p();}n._write=i;let{pipe:a}=e.renderToPipeableStream(t,{onShellReady:()=>{a(n),o(r);}});})}async function f(t,e){let{subject:o,template:n}=t,r=await n(e),i=await g(r);return {subject:o,html:i}}function h(){if(!process.env.MAIL_FROM)throw new Error("Mail from address has not been set");let t=/^(?<name>[^<]+)<(?<email>[^>]+)>$/u.exec(process.env.MAIL_FROM);if(!t?.groups?.name||!t?.groups?.email)throw new Error('Mail from address is not the correct format. It should be "Name <email>".');return {email:t.groups.email.trim(),name:t.groups.name.trim()}}function s(t){return t?Array.isArray(t)?t.map(e=>({email:e})):[{email:t}]:[]}async function M(t){if(!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");let[e,o]=process.env.MAIL_API_KEY.split("."),n=Array.isArray(t.to)?t.to.map(r=>({email:r})):[{email:t.to}];try{return (await(await fetch(`https://sandbox.api.mailtrap.io/api/send/${e}`,{method:"POST",headers:{"Api-Token":o,"Content-Type":"application/json"},body:JSON.stringify({attachments:t.attachments,bcc:s(t.bcc),cc:s(t.cc),from:t.from,html:t.html,subject:t.subject,to:n})})).json()).success}catch{return !1}}async function b(t){if(process.env.APP_ENV!=="production")throw new Error("Trying to run production mail in a development environment");if(!process.env.MAIL_ENABLE_PRODUCTION)throw new Error("Mail has not been enabled in production. Please add MAIL_ENABLE_PRODUCTION to your environment variables.");if(!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");l.setApiKey(process.env.MAIL_API_KEY);let e=await l.send({attachments:t.attachments,bcc:s(t.bcc),cc:s(t.cc),from:t.from,html:t.html,to:s(t.to),subject:t.subject});if(!e[0].statusCode.toString().startsWith("2"))throw new Error(`Mail not sent. ${JSON.stringify(e)}`);return !0}async function E(t,e,o,n,r){if(!process.env.MAIL_API_KEY)throw new Error("Mail API key has not been set");let i=h(),{subject:a,html:c}=await f(t,e),m={attachments:r,bcc:n?.bcc,cc:n?.cc,from:i,html:c,subject:a,to:o};return process.env.APP_ENV==="production"?b(m):M(m)}
2
+ export{A as createMail,f as getMail,E as sendMail};//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mail/MailService.ts"],"names":["createMail","subject","template","renderMail","element","ReactDOMServer","resolve","ws","stream","content","write","chunk","enc","next","pipe","getMail","mail","data","html","getSenderDetails","matches","transformEmailData","emails","email","sendDevelopmentMail","sendObject","id","key","to","sendProductionMail","sgMail","response","err","sendMail","options","attachments","from"],"mappings":"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","file":"index.js","sourcesContent":["import sgMail from '@sendgrid/mail';\n\nimport stream from 'node:stream';\n\nexport interface MailObject<T extends object> {\n subject: string;\n template: (data: T) => Promise<React.ReactElement> | React.ReactElement;\n}\n\nexport function createMail<T extends object>(\n subject: string,\n template: (data: T) => Promise<React.ReactElement> | React.ReactElement\n): MailObject<T> {\n return { subject, template };\n}\n\nasync function renderMail(element: React.ReactElement): Promise<string> {\n const ReactDOMServer = (await import('react-dom/server')).default;\n\n return new Promise((resolve) => {\n const ws = new stream.Writable();\n let content = '';\n\n function write<T extends { toString: () => string }>(\n chunk: T,\n enc: BufferEncoding,\n next: (error?: Error | null) => void\n ): void {\n content += chunk.toString();\n next();\n }\n\n ws._write = write; // eslint-disable-line no-underscore-dangle\n\n const { pipe } = ReactDOMServer.renderToPipeableStream(element, {\n onShellReady: () => {\n pipe(ws);\n resolve(content);\n },\n });\n });\n}\n\nexport async function getMail<T extends object>(\n mail: MailObject<T>,\n data: T\n): Promise<{ subject: string; html: string }> {\n const { subject, template } = mail;\n\n const element = await template(data);\n const html = await renderMail(element);\n\n return {\n subject,\n html,\n };\n}\n\nfunction getSenderDetails(): { email: string; name: string } {\n if (!process.env.MAIL_FROM) {\n throw new Error('Mail from address has not been set');\n }\n\n const matches = /^(?<name>[^<]+)<(?<email>[^>]+)>$/u.exec(process.env.MAIL_FROM);\n\n if (!matches?.groups?.name || !matches?.groups?.email) {\n throw new Error(\n 'Mail from address is not the correct format. It should be \"Name <email>\".'\n );\n }\n\n return {\n email: matches.groups.email.trim(),\n name: matches.groups.name.trim(),\n };\n}\n\nfunction transformEmailData(emails?: string[] | string): { email: string }[] {\n if (!emails) {\n return [];\n }\n return Array.isArray(emails) ? emails.map((email) => ({ email })) : [{ email: emails }];\n}\n\ninterface SendMailObject {\n attachments?: { content: string; filename: string; type: string }[];\n bcc?: string[] | string;\n cc?: string[] | string;\n from: { email: string; name: string };\n html: string;\n subject: string;\n to: string[] | string;\n}\n\nasync function sendDevelopmentMail(sendObject: SendMailObject): Promise<boolean> {\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n /*\n * The account id and api key are both in the MAIL_API_KEY variable, separated by a `.`. We need\n * to split them.\n */\n\n const [id, key] = process.env.MAIL_API_KEY.split('.');\n\n const to = Array.isArray(sendObject.to)\n ? sendObject.to.map((email) => ({ email }))\n : [{ email: sendObject.to }];\n\n try {\n const response = await fetch(`https://sandbox.api.mailtrap.io/api/send/${id}`, {\n method: 'POST',\n headers: { 'Api-Token': key, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n attachments: sendObject.attachments,\n bcc: transformEmailData(sendObject.bcc),\n cc: transformEmailData(sendObject.cc),\n from: sendObject.from,\n html: sendObject.html,\n subject: sendObject.subject,\n to,\n }),\n });\n const json = (await response.json()) as { success: boolean };\n return json.success;\n } catch (err) {\n return false;\n }\n}\n\nasync function sendProductionMail(sendObject: SendMailObject): Promise<boolean> {\n if (process.env.APP_ENV !== 'production') {\n throw new Error('Trying to run production mail in a development environment');\n }\n\n if (!process.env.MAIL_ENABLE_PRODUCTION) {\n throw new Error(\n 'Mail has not been enabled in production. Please add MAIL_ENABLE_PRODUCTION to your environment variables.'\n );\n }\n\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n sgMail.setApiKey(process.env.MAIL_API_KEY);\n\n try {\n const response = await sgMail.send({\n attachments: sendObject.attachments,\n bcc: transformEmailData(sendObject.bcc),\n cc: transformEmailData(sendObject.cc),\n from: sendObject.from,\n html: sendObject.html,\n to: transformEmailData(sendObject.to),\n subject: sendObject.subject,\n });\n console.log(response);\n return response[0].statusCode.toString().startsWith('2');\n } catch (err) {\n console.log(err);\n return false;\n }\n}\n\nexport async function sendMail<T extends object>(\n mail: MailObject<T>,\n data: T,\n to: string[] | string,\n options?: { cc?: string[]; bcc?: string[] },\n attachments?: { content: string; filename: string; type: string }[]\n): Promise<boolean> {\n console.log(1);\n\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n const from = getSenderDetails();\n const { subject, html } = await getMail(mail, data);\n\n const sendObject: SendMailObject = {\n attachments,\n bcc: options?.bcc,\n cc: options?.cc,\n from,\n html,\n subject,\n to,\n };\n\n if (process.env.APP_ENV === 'production') {\n console.log(2);\n return sendProductionMail(sendObject);\n }\n\n console.log(3);\n return sendDevelopmentMail(sendObject);\n}\n"]}
1
+ {"version":3,"sources":["../../src/mail/MailService.ts"],"names":["createMail","subject","template","renderMail","element","ReactDOMServer","resolve","ws","stream","content","write","chunk","enc","next","pipe","getMail","mail","data","html","getSenderDetails","matches","transformEmailData","emails","email","sendDevelopmentMail","sendObject","id","key","to","sendProductionMail","sgMail","response","sendMail","options","attachments","from"],"mappings":"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","file":"index.js","sourcesContent":["import sgMail from '@sendgrid/mail';\n\nimport stream from 'node:stream';\n\nexport interface MailObject<T extends object> {\n subject: string;\n template: (data: T) => Promise<React.ReactElement> | React.ReactElement;\n}\n\nexport function createMail<T extends object>(\n subject: string,\n template: (data: T) => Promise<React.ReactElement> | React.ReactElement\n): MailObject<T> {\n return { subject, template };\n}\n\nasync function renderMail(element: React.ReactElement): Promise<string> {\n const ReactDOMServer = (await import('react-dom/server')).default;\n\n return new Promise((resolve) => {\n const ws = new stream.Writable();\n let content = '';\n\n function write<T extends { toString: () => string }>(\n chunk: T,\n enc: BufferEncoding,\n next: (error?: Error | null) => void\n ): void {\n content += chunk.toString();\n next();\n }\n\n ws._write = write; // eslint-disable-line no-underscore-dangle\n\n const { pipe } = ReactDOMServer.renderToPipeableStream(element, {\n onShellReady: () => {\n pipe(ws);\n resolve(content);\n },\n });\n });\n}\n\nexport async function getMail<T extends object>(\n mail: MailObject<T>,\n data: T\n): Promise<{ subject: string; html: string }> {\n const { subject, template } = mail;\n\n const element = await template(data);\n const html = await renderMail(element);\n\n return {\n subject,\n html,\n };\n}\n\nfunction getSenderDetails(): { email: string; name: string } {\n if (!process.env.MAIL_FROM) {\n throw new Error('Mail from address has not been set');\n }\n\n const matches = /^(?<name>[^<]+)<(?<email>[^>]+)>$/u.exec(process.env.MAIL_FROM);\n\n if (!matches?.groups?.name || !matches?.groups?.email) {\n throw new Error(\n 'Mail from address is not the correct format. It should be \"Name <email>\".'\n );\n }\n\n return {\n email: matches.groups.email.trim(),\n name: matches.groups.name.trim(),\n };\n}\n\nfunction transformEmailData(emails?: string[] | string): { email: string }[] {\n if (!emails) {\n return [];\n }\n return Array.isArray(emails) ? emails.map((email) => ({ email })) : [{ email: emails }];\n}\n\ninterface SendMailObject {\n attachments?: { content: string; filename: string; type: string }[];\n bcc?: string[] | string;\n cc?: string[] | string;\n from: { email: string; name: string };\n html: string;\n subject: string;\n to: string[] | string;\n}\n\nasync function sendDevelopmentMail(sendObject: SendMailObject): Promise<boolean> {\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n /*\n * The account id and api key are both in the MAIL_API_KEY variable, separated by a `.`. We need\n * to split them.\n */\n\n const [id, key] = process.env.MAIL_API_KEY.split('.');\n\n const to = Array.isArray(sendObject.to)\n ? sendObject.to.map((email) => ({ email }))\n : [{ email: sendObject.to }];\n\n try {\n const response = await fetch(`https://sandbox.api.mailtrap.io/api/send/${id}`, {\n method: 'POST',\n headers: { 'Api-Token': key, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n attachments: sendObject.attachments,\n bcc: transformEmailData(sendObject.bcc),\n cc: transformEmailData(sendObject.cc),\n from: sendObject.from,\n html: sendObject.html,\n subject: sendObject.subject,\n to,\n }),\n });\n const json = (await response.json()) as { success: boolean };\n return json.success;\n } catch (err) {\n return false;\n }\n}\n\nasync function sendProductionMail(sendObject: SendMailObject): Promise<boolean> {\n if (process.env.APP_ENV !== 'production') {\n throw new Error('Trying to run production mail in a development environment');\n }\n\n if (!process.env.MAIL_ENABLE_PRODUCTION) {\n throw new Error(\n 'Mail has not been enabled in production. Please add MAIL_ENABLE_PRODUCTION to your environment variables.'\n );\n }\n\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n sgMail.setApiKey(process.env.MAIL_API_KEY);\n\n const response = await sgMail.send({\n attachments: sendObject.attachments,\n bcc: transformEmailData(sendObject.bcc),\n cc: transformEmailData(sendObject.cc),\n from: sendObject.from,\n html: sendObject.html,\n to: transformEmailData(sendObject.to),\n subject: sendObject.subject,\n });\n\n if (!response[0].statusCode.toString().startsWith('2')) {\n throw new Error(`Mail not sent. ${JSON.stringify(response)}`);\n }\n\n return true;\n}\n\nexport async function sendMail<T extends object>(\n mail: MailObject<T>,\n data: T,\n to: string[] | string,\n options?: { cc?: string[]; bcc?: string[] },\n attachments?: { content: string; filename: string; type: string }[]\n): Promise<boolean> {\n if (!process.env.MAIL_API_KEY) {\n throw new Error('Mail API key has not been set');\n }\n\n const from = getSenderDetails();\n const { subject, html } = await getMail(mail, data);\n\n const sendObject: SendMailObject = {\n attachments,\n bcc: options?.bcc,\n cc: options?.cc,\n from,\n html,\n subject,\n to,\n };\n\n if (process.env.APP_ENV === 'production') {\n return sendProductionMail(sendObject);\n }\n\n return sendDevelopmentMail(sendObject);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sqrzro/server",
3
- "version": "2.0.0-bz.64",
3
+ "version": "2.0.0-bz.65",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",