Add more typescript types (#867)
This commit is contained in:
		
							parent
							
								
									effbd44f48
								
							
						
					
					
						commit
						c62e1a0eeb
					
				
					 3 changed files with 51 additions and 18 deletions
				
			
		|  | @ -2,20 +2,31 @@ import nodemailer from "nodemailer"; | |||
| 
 | ||||
| import { serverConfig } from "../serverConfig"; | ||||
| 
 | ||||
| export default function createInvitationEmail(data: any, options: any = {}) { | ||||
|   return sendEmail(data, { | ||||
|     provider: { | ||||
|       transport: serverConfig.transport, | ||||
|       from: serverConfig.from, | ||||
|     }, | ||||
|     ...options, | ||||
|   }); | ||||
| export type Invitation = { | ||||
|   from?: string; | ||||
|   toEmail: string; | ||||
|   teamName: string; | ||||
|   token?: string; | ||||
| }; | ||||
| 
 | ||||
| type EmailProvider = { | ||||
|   from: string; | ||||
|   transport: any; | ||||
| }; | ||||
| 
 | ||||
| export function createInvitationEmail(data: Invitation) { | ||||
|   const provider = { | ||||
|     transport: serverConfig.transport, | ||||
|     from: serverConfig.from, | ||||
|   } as EmailProvider; | ||||
|   return sendEmail(data, provider); | ||||
| } | ||||
| 
 | ||||
| const sendEmail = (invitation: any, { provider }) => | ||||
| const sendEmail = (invitation: Invitation, provider: EmailProvider): Promise<void> => | ||||
|   new Promise((resolve, reject) => { | ||||
|     const { transport, from } = provider; | ||||
| 
 | ||||
|     const invitationHtml = html(invitation); | ||||
|     nodemailer.createTransport(transport).sendMail( | ||||
|       { | ||||
|         from: `Cal.com <${from}>`, | ||||
|  | @ -23,8 +34,8 @@ const sendEmail = (invitation: any, { provider }) => | |||
|         subject: | ||||
|           (invitation.from ? invitation.from + " invited you" : "You have been invited") + | ||||
|           ` to join ${invitation.teamName}`, | ||||
|         html: html(invitation), | ||||
|         text: text(invitation), | ||||
|         html: invitationHtml, | ||||
|         text: text(invitationHtml), | ||||
|       }, | ||||
|       (error) => { | ||||
|         if (error) { | ||||
|  | @ -36,7 +47,7 @@ const sendEmail = (invitation: any, { provider }) => | |||
|     ); | ||||
|   }); | ||||
| 
 | ||||
| const html = (invitation: any) => { | ||||
| export function html(invitation: Invitation): string { | ||||
|   let url: string = process.env.BASE_URL + "/settings/teams"; | ||||
|   if (invitation.token) { | ||||
|     url = `${process.env.BASE_URL}/auth/signup?token=${invitation.token}&callbackUrl=${url}`; | ||||
|  | @ -82,10 +93,9 @@ const html = (invitation: any) => { | |||
|     </table> | ||||
|   ` | ||||
|   ); | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| // just strip all HTML and convert <br /> to \n
 | ||||
| const text = (evt: any) => | ||||
|   html(evt) | ||||
|     .replace("<br />", "\n") | ||||
|     .replace(/<[^>]+>/g, ""); | ||||
| export function text(htmlStr: string): string { | ||||
|   return htmlStr.replace("<br />", "\n").replace(/<[^>]+>/g, ""); | ||||
| } | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import type { NextApiRequest, NextApiResponse } from "next"; | |||
| 
 | ||||
| import { getSession } from "@lib/auth"; | ||||
| 
 | ||||
| import createInvitationEmail from "../../../../lib/emails/invitation"; | ||||
| import { createInvitationEmail } from "../../../../lib/emails/invitation"; | ||||
| import prisma from "../../../../lib/prisma"; | ||||
| 
 | ||||
| export default async function handler(req: NextApiRequest, res: NextApiResponse) { | ||||
|  |  | |||
							
								
								
									
										23
									
								
								test/lib/emails/invitation.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								test/lib/emails/invitation.test.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | |||
| import { expect, it } from "@jest/globals"; | ||||
| 
 | ||||
| import { html, text, Invitation } from "@lib/emails/invitation"; | ||||
| 
 | ||||
| it("email text rendering should strip tags and add new lines", () => { | ||||
|   const result = text("<p>hello world</p><br /><div>welcome to the brave <span>new</span> world"); | ||||
|   expect(result).toEqual("hello world\nwelcome to the brave new world"); | ||||
| }); | ||||
| 
 | ||||
| it("email html should render invite email", () => { | ||||
|   const invitation = { | ||||
|     from: "Huxley", | ||||
|     toEmail: "hello@example.com", | ||||
|     teamName: "Calendar Lovers", | ||||
|     token: "invite-token", | ||||
|   } as Invitation; | ||||
|   const result = html(invitation); | ||||
|   expect(result).toContain('<br />Huxley invited you to join the team "Calendar Lovers" in Cal.com.<br />'); | ||||
|   expect(result).toContain("/auth/signup?token=invite-token&"); | ||||
|   expect(result).toContain( | ||||
|     'If you prefer not to use "hello@example.com" as your Cal.com email or already have a Cal.com account, please request another invitation to that email.' | ||||
|   ); | ||||
| }); | ||||
		Loading…
	
		Reference in a new issue
	
	 Anton Podviaznikov
						Anton Podviaznikov