mirror of
https://github.com/twentyhq/twenty.git
synced 2024-09-11 15:35:36 +03:00
Enforce email templating (#3355)
* Add react-email * WIP * Fix import error * Rename services * Update logging * Update email template * Update email template * Add Base Email template * Move to proper place * Remove test files * Update logo * Add email theme * Revert "Remove test files" This reverts commitfe062dd051
. * Add email theme 2 * Revert "Revert "Remove test files"" This reverts commit6c6471273a
. * Revert "Revert "Revert "Remove test files""" This reverts commitf851333c24
. * Revert "Revert "Revert "Revert "Remove test files"""" This reverts commit7838e19e88
. * Fix theme
This commit is contained in:
parent
e2bdf0ce45
commit
b3d9bed91d
@ -39,6 +39,8 @@
|
||||
"@octokit/graphql": "^7.0.2",
|
||||
"@ptc-org/nestjs-query-core": "^4.2.0",
|
||||
"@ptc-org/nestjs-query-typeorm": "4.2.1-alpha.2",
|
||||
"@react-email/components": "0.0.12",
|
||||
"@react-email/render": "0.0.10",
|
||||
"@sentry/node": "^7.66.0",
|
||||
"@sentry/profiling-node": "^1.2.6",
|
||||
"@sentry/react": "^7.88.0",
|
||||
|
48
packages/twenty-server/src/emails/common-style.ts
Normal file
48
packages/twenty-server/src/emails/common-style.ts
Normal file
@ -0,0 +1,48 @@
|
||||
const grayScale = {
|
||||
gray100: '#000000',
|
||||
gray90: '#141414',
|
||||
gray85: '#171717',
|
||||
gray80: '#1b1b1b',
|
||||
gray75: '#1d1d1d',
|
||||
gray70: '#222222',
|
||||
gray65: '#292929',
|
||||
gray60: '#333333',
|
||||
gray55: '#4c4c4c',
|
||||
gray50: '#666666',
|
||||
gray45: '#818181',
|
||||
gray40: '#999999',
|
||||
gray35: '#b3b3b3',
|
||||
gray30: '#cccccc',
|
||||
gray25: '#d6d6d6',
|
||||
gray20: '#ebebeb',
|
||||
gray15: '#f1f1f1',
|
||||
gray10: '#fcfcfc',
|
||||
gray0: '#ffffff',
|
||||
};
|
||||
|
||||
export const emailTheme = {
|
||||
font: {
|
||||
colors: {
|
||||
highlighted: grayScale.gray60,
|
||||
primary: grayScale.gray50,
|
||||
inverted: grayScale.gray0,
|
||||
},
|
||||
weight: {
|
||||
regular: 400,
|
||||
bold: 600,
|
||||
},
|
||||
size: {
|
||||
md: '13px',
|
||||
lg: '16px',
|
||||
},
|
||||
},
|
||||
background: {
|
||||
colors: { highlight: grayScale.gray15 },
|
||||
radialGradient: `radial-gradient(50% 62.62% at 50% 0%, #505050 0%, ${grayScale.gray60} 100%)`,
|
||||
radialGradientHover: `radial-gradient(76.32% 95.59% at 50% 0%, #505050 0%, ${grayScale.gray60} 100%)`,
|
||||
transparent: {
|
||||
medium: 'rgba(0, 0, 0, 0.08)',
|
||||
light: 'rgba(0, 0, 0, 0.04)',
|
||||
},
|
||||
},
|
||||
};
|
17
packages/twenty-server/src/emails/components/BaseEmail.tsx
Normal file
17
packages/twenty-server/src/emails/components/BaseEmail.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import * as React from 'react';
|
||||
import { Container, Html } from '@react-email/components';
|
||||
|
||||
import { BaseHead } from 'src/emails/components/BaseHead';
|
||||
import { Logo } from 'src/emails/components/Logo';
|
||||
|
||||
export const BaseEmail = ({ children }) => {
|
||||
return (
|
||||
<Html lang="en">
|
||||
<BaseHead />
|
||||
<Container width={290}>
|
||||
<Logo />
|
||||
{children}
|
||||
</Container>
|
||||
</Html>
|
||||
);
|
||||
};
|
22
packages/twenty-server/src/emails/components/BaseHead.tsx
Normal file
22
packages/twenty-server/src/emails/components/BaseHead.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { Font, Head } from '@react-email/components';
|
||||
import * as React from 'react';
|
||||
|
||||
import { emailTheme } from 'src/emails/common-style';
|
||||
|
||||
export const BaseHead = () => {
|
||||
return (
|
||||
<Head>
|
||||
<title>Twenty email</title>
|
||||
<Font
|
||||
fontFamily="Inter"
|
||||
fallbackFontFamily="sans-serif"
|
||||
webFont={{
|
||||
url: 'https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap',
|
||||
format: 'woff2',
|
||||
}}
|
||||
fontStyle="normal"
|
||||
fontWeight={emailTheme.font.weight.regular}
|
||||
/>
|
||||
</Head>
|
||||
);
|
||||
};
|
@ -0,0 +1,23 @@
|
||||
import { Button } from '@react-email/button';
|
||||
import * as React from 'react';
|
||||
|
||||
import { emailTheme } from 'src/emails/common-style';
|
||||
const callToActionStyle = {
|
||||
display: 'flex',
|
||||
padding: '8px 32px',
|
||||
borderRadius: '8px',
|
||||
border: `1px solid ${emailTheme.background.transparent.light}`,
|
||||
background: emailTheme.background.radialGradient,
|
||||
boxShadow: `0px 2px 4px 0px ${emailTheme.background.transparent.light}, 0px 0px 4px 0px ${emailTheme.background.transparent.medium}`,
|
||||
color: emailTheme.font.colors.inverted,
|
||||
fontSize: emailTheme.font.size.md,
|
||||
fontWeight: emailTheme.font.weight.bold,
|
||||
};
|
||||
|
||||
export const CallToAction = ({ value, href }) => {
|
||||
return (
|
||||
<Button href={href} style={callToActionStyle}>
|
||||
{value}
|
||||
</Button>
|
||||
);
|
||||
};
|
@ -0,0 +1,30 @@
|
||||
import * as React from 'react';
|
||||
import { Row } from '@react-email/row';
|
||||
import { Text } from '@react-email/text';
|
||||
import { Column } from '@react-email/components';
|
||||
|
||||
import { emailTheme } from 'src/emails/common-style';
|
||||
|
||||
const rowStyle = {
|
||||
display: 'flex',
|
||||
};
|
||||
|
||||
const highlightedStyle = {
|
||||
borderRadius: '4px',
|
||||
background: emailTheme.background.colors.highlight,
|
||||
padding: '4px 8px',
|
||||
margin: 0,
|
||||
fontSize: emailTheme.font.size.lg,
|
||||
fontWeight: emailTheme.font.weight.bold,
|
||||
color: emailTheme.font.colors.highlighted,
|
||||
};
|
||||
|
||||
export const HighlightedText = ({ value }) => {
|
||||
return (
|
||||
<Row style={rowStyle}>
|
||||
<Column>
|
||||
<Text style={highlightedStyle}>{value}</Text>
|
||||
</Column>
|
||||
</Row>
|
||||
);
|
||||
};
|
17
packages/twenty-server/src/emails/components/Logo.tsx
Normal file
17
packages/twenty-server/src/emails/components/Logo.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { Img } from '@react-email/components';
|
||||
|
||||
const logoStyle = {
|
||||
marginBottom: '40px',
|
||||
};
|
||||
|
||||
export const Logo = () => {
|
||||
return (
|
||||
<Img
|
||||
src="https://app.twenty.com/icons/windows11/Square150x150Logo.scale-100.png"
|
||||
alt="Twenty logo"
|
||||
width="40"
|
||||
height="40"
|
||||
style={logoStyle}
|
||||
/>
|
||||
);
|
||||
};
|
14
packages/twenty-server/src/emails/components/MainText.tsx
Normal file
14
packages/twenty-server/src/emails/components/MainText.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { Text } from '@react-email/text';
|
||||
import * as React from 'react';
|
||||
|
||||
import { emailTheme } from 'src/emails/common-style';
|
||||
|
||||
const mainTextStyle = {
|
||||
fontSize: emailTheme.font.size.md,
|
||||
fontWeight: emailTheme.font.weight.regular,
|
||||
color: emailTheme.font.colors.primary,
|
||||
};
|
||||
|
||||
export const MainText = ({ children }) => {
|
||||
return <Text style={mainTextStyle}>{children}</Text>;
|
||||
};
|
6
packages/twenty-server/src/emails/components/Title.tsx
Normal file
6
packages/twenty-server/src/emails/components/Title.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
import { Heading } from '@react-email/components';
|
||||
import * as React from 'react';
|
||||
|
||||
export const Title = ({ value }) => {
|
||||
return <Heading as="h1">{value}</Heading>;
|
||||
};
|
@ -0,0 +1,18 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { SendMailOptions } from 'nodemailer';
|
||||
|
||||
import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface';
|
||||
|
||||
import { EmailSenderService } from 'src/integrations/email/email-sender.service';
|
||||
|
||||
@Injectable()
|
||||
export class EmailSenderJob implements MessageQueueJob<SendMailOptions> {
|
||||
constructor(private readonly emailSenderService: EmailSenderService) {}
|
||||
|
||||
async handle(data: SendMailOptions): Promise<void> {
|
||||
process.stdout.write(`Sending email to ${data.to} ...`);
|
||||
await this.emailSenderService.send(data);
|
||||
console.log(' done!');
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
|
||||
import { SendMailOptions } from 'nodemailer';
|
||||
|
||||
import { EmailDriver } from 'src/integrations/email/drivers/interfaces/email-driver.interface';
|
||||
|
||||
import { EMAIL_DRIVER } from 'src/integrations/email/email.constants';
|
||||
|
||||
@Injectable()
|
||||
export class EmailSenderService implements EmailDriver {
|
||||
constructor(@Inject(EMAIL_DRIVER) private driver: EmailDriver) {}
|
||||
|
||||
async send(sendMailOptions: SendMailOptions): Promise<void> {
|
||||
await this.driver.send(sendMailOptions);
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import { EMAIL_DRIVER } from 'src/integrations/email/email.constants';
|
||||
import { LoggerDriver } from 'src/integrations/email/drivers/logger.driver';
|
||||
import { SmtpDriver } from 'src/integrations/email/drivers/smtp.driver';
|
||||
import { EmailService } from 'src/integrations/email/email.service';
|
||||
import { EmailSenderService } from 'src/integrations/email/email-sender.service';
|
||||
|
||||
@Global()
|
||||
export class EmailModule {
|
||||
@ -22,8 +23,8 @@ export class EmailModule {
|
||||
|
||||
return {
|
||||
module: EmailModule,
|
||||
providers: [EmailService, provider],
|
||||
exports: [EmailService],
|
||||
providers: [EmailSenderService, EmailService, provider],
|
||||
exports: [EmailSenderService, EmailService],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,22 @@ import { Inject, Injectable } from '@nestjs/common';
|
||||
|
||||
import { SendMailOptions } from 'nodemailer';
|
||||
|
||||
import { EmailDriver } from 'src/integrations/email/drivers/interfaces/email-driver.interface';
|
||||
|
||||
import { EMAIL_DRIVER } from 'src/integrations/email/email.constants';
|
||||
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
||||
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
||||
import { EmailSenderJob } from 'src/integrations/email/email-sender.job';
|
||||
|
||||
@Injectable()
|
||||
export class EmailService implements EmailDriver {
|
||||
constructor(@Inject(EMAIL_DRIVER) private driver: EmailDriver) {}
|
||||
export class EmailService {
|
||||
constructor(
|
||||
@Inject(MessageQueue.emailQueue)
|
||||
private readonly messageQueueService: MessageQueueService,
|
||||
) {}
|
||||
|
||||
async send(sendMailOptions: SendMailOptions): Promise<void> {
|
||||
await this.driver.send(sendMailOptions);
|
||||
await this.messageQueueService.add<SendMailOptions>(
|
||||
EmailSenderJob.name,
|
||||
sendMailOptions,
|
||||
{ retryLimit: 3 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ import { exceptionHandlerModuleFactory } from 'src/integrations/exception-handle
|
||||
import { fileStorageModuleFactory } from 'src/integrations/file-storage/file-storage.module-factory';
|
||||
import { loggerModuleFactory } from 'src/integrations/logger/logger.module-factory';
|
||||
import { messageQueueModuleFactory } from 'src/integrations/message-queue/message-queue.module-factory';
|
||||
import { emailModuleFactory } from 'src/integrations/email/email.module-factory';
|
||||
import { EmailModule } from 'src/integrations/email/email.module';
|
||||
import { emailModuleFactory } from 'src/integrations/email/email.module-factory';
|
||||
|
||||
import { EnvironmentModule } from './environment/environment.module';
|
||||
import { EnvironmentService } from './environment/environment.service';
|
||||
|
@ -10,6 +10,7 @@ import { ObjectMetadataModule } from 'src/metadata/object-metadata/object-metada
|
||||
import { DataSourceModule } from 'src/metadata/data-source/data-source.module';
|
||||
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
|
||||
import { FetchWorkspaceMessagesModule } from 'src/workspace/messaging/services/fetch-workspace-messages.module';
|
||||
import { EmailSenderJob } from 'src/integrations/email/email-sender.job';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -33,6 +34,10 @@ import { FetchWorkspaceMessagesModule } from 'src/workspace/messaging/services/f
|
||||
provide: CallWebhookJob.name,
|
||||
useClass: CallWebhookJob,
|
||||
},
|
||||
{
|
||||
provide: EmailSenderJob.name,
|
||||
useClass: EmailSenderJob,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class JobsModule {
|
||||
|
@ -5,4 +5,5 @@ export enum MessageQueue {
|
||||
messagingQueue = 'messaging-queue',
|
||||
webhookQueue = 'webhook-queue',
|
||||
cronQueue = 'cron-queue',
|
||||
emailQueue = 'email-queue',
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import { loggerModuleFactory } from 'src/integrations/logger/logger.module-facto
|
||||
import { JobsModule } from 'src/integrations/message-queue/jobs.module';
|
||||
import { MessageQueueModule } from 'src/integrations/message-queue/message-queue.module';
|
||||
import { messageQueueModuleFactory } from 'src/integrations/message-queue/message-queue.module-factory';
|
||||
import { IntegrationsModule } from 'src/integrations/integrations.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -20,6 +21,7 @@ import { messageQueueModuleFactory } from 'src/integrations/message-queue/messag
|
||||
inject: [EnvironmentService],
|
||||
}),
|
||||
JobsModule,
|
||||
IntegrationsModule,
|
||||
],
|
||||
})
|
||||
export class QueueWorkerModule {}
|
||||
|
@ -22,6 +22,7 @@
|
||||
"forceConsistentCasingInFileNames": false,
|
||||
"noFallthroughCasesInSwitch": false,
|
||||
"resolveJsonModule": true,
|
||||
"types": ["jest", "node"]
|
||||
"types": ["jest", "node"],
|
||||
"jsx": "react-jsx"
|
||||
}
|
||||
}
|
||||
|
297
yarn.lock
297
yarn.lock
@ -8416,6 +8416,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@one-ini/wasm@npm:0.1.1":
|
||||
version: 0.1.1
|
||||
resolution: "@one-ini/wasm@npm:0.1.1"
|
||||
checksum: 54700e055037f1a63bfcc86d24822203b25759598c2c3e295d1435130a449108aebc119c9c2e467744767dbe0b6ab47a182c61aa1071ba7368f5e20ab197ba65
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@open-draft/deferred-promise@npm:^2.1.0, @open-draft/deferred-promise@npm:^2.2.0":
|
||||
version: 2.2.0
|
||||
resolution: "@open-draft/deferred-promise@npm:2.2.0"
|
||||
@ -9795,6 +9802,205 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/body@npm:0.0.4":
|
||||
version: 0.0.4
|
||||
resolution: "@react-email/body@npm:0.0.4"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 756a184bc1284e8ce1828cd3abc0ea3aa24262e6c677b4e4de48fd6c298717fbc0164e7af7ac4c72262bc3138222ab7fc30c63b0520178315fece2bd78d12f98
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/button@npm:0.0.11":
|
||||
version: 0.0.11
|
||||
resolution: "@react-email/button@npm:0.0.11"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 91de881f33adec7f5ff311dc8259771fff638cbb736a851a6d4a7e634378555177eb112bc38abb18af7e4bc8ccc899f5bce5b20d409e377d289904d37a20c0ce
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/column@npm:0.0.8":
|
||||
version: 0.0.8
|
||||
resolution: "@react-email/column@npm:0.0.8"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 5a937dbe7a69c1db8078f84cf70b66224be187dafa78e683103ccbbdb5d3ad2267f7b92c4fbd73922e8c8dda2a4372f37c1a7efac38501cb356d20c028a87574
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/components@npm:0.0.12":
|
||||
version: 0.0.12
|
||||
resolution: "@react-email/components@npm:0.0.12"
|
||||
dependencies:
|
||||
"@react-email/body": "npm:0.0.4"
|
||||
"@react-email/button": "npm:0.0.11"
|
||||
"@react-email/column": "npm:0.0.8"
|
||||
"@react-email/container": "npm:0.0.10"
|
||||
"@react-email/font": "npm:0.0.4"
|
||||
"@react-email/head": "npm:0.0.6"
|
||||
"@react-email/heading": "npm:0.0.9"
|
||||
"@react-email/hr": "npm:0.0.6"
|
||||
"@react-email/html": "npm:0.0.6"
|
||||
"@react-email/img": "npm:0.0.6"
|
||||
"@react-email/link": "npm:0.0.6"
|
||||
"@react-email/preview": "npm:0.0.7"
|
||||
"@react-email/render": "npm:0.0.9"
|
||||
"@react-email/row": "npm:0.0.6"
|
||||
"@react-email/section": "npm:0.0.10"
|
||||
"@react-email/tailwind": "npm:0.0.13"
|
||||
"@react-email/text": "npm:0.0.6"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 1cc01198e5eeb42aac79b11e1a0ceaddd75d3164425899d6fc676ddbcd84cb869cebb0c6feb1f4383ba92d150c32e94d1fe5eec2ee74711b9309569e3d9bc6ac
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/container@npm:0.0.10":
|
||||
version: 0.0.10
|
||||
resolution: "@react-email/container@npm:0.0.10"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: d074fad448f6033d232b890b9d1a9914d0f92908ba494feaa627828718f4fa6e639636f239eb8eeb8b597c220da9019e90cb72ee2b0328c2ec908fd73e48fc13
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/font@npm:0.0.4":
|
||||
version: 0.0.4
|
||||
resolution: "@react-email/font@npm:0.0.4"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 066a0016fa78267c83665d5e3846421f7d787361b11f4e712bd32353d0de947a72a42036fdfd35b75eff479ca77deba0f5c220bee43ace8594f7c6345c30a0bc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/head@npm:0.0.6":
|
||||
version: 0.0.6
|
||||
resolution: "@react-email/head@npm:0.0.6"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: aa2362c965c6f1fa2bcd41be04c1ce8695864153768b4ba4f4b102dd1e1adb28ba067c54f71ded592799aacfa348813cae0f442797b3448bb87feb4588443546
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/heading@npm:0.0.9":
|
||||
version: 0.0.9
|
||||
resolution: "@react-email/heading@npm:0.0.9"
|
||||
dependencies:
|
||||
"@radix-ui/react-slot": "npm:1.0.2"
|
||||
react: "npm:18.2.0"
|
||||
checksum: d082d2a4d3db312cbaa0d62419cc1b29c6b6c3ee1467a220c97c9cb009be1af5f6409370b9caac054d8aee8d326fb6e894a72073ff429f05ed097ba471e12a43
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/hr@npm:0.0.6":
|
||||
version: 0.0.6
|
||||
resolution: "@react-email/hr@npm:0.0.6"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: b965c176192a06b39d2c696a8b747cdf4060ba7229a7d45eaf1d5729c59920fefe90f43fbc5f8d203a8e5d77645ee62745d06ec5ec5c9b030815f0642a8ac4ab
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/html@npm:0.0.6":
|
||||
version: 0.0.6
|
||||
resolution: "@react-email/html@npm:0.0.6"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 9046476ccb20e405a64e33ca3a80f1ed7645bacec0601001fd36efd95497a5999daebf0ad141f0c08387190582e23ff2b2f7fc536461ec9b27d0b397a311fe4f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/img@npm:0.0.6":
|
||||
version: 0.0.6
|
||||
resolution: "@react-email/img@npm:0.0.6"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 046f0b60bdf9c7c04a2033b39967de96e31ffedae8922f9f187ce39f6040deee33f02e5695f56c26cf1691cce7de937bcbd303c3804b9a824d0aabc71427a462
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/link@npm:0.0.6":
|
||||
version: 0.0.6
|
||||
resolution: "@react-email/link@npm:0.0.6"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 3e5eb2e222abe99bdcec6127a20d4ac8ed584189527a2bced119b09d08625b74f0ffa8a1de009974b4cd47249ade4081e108ca4fd65daa0ca811a7c6058cf838
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/preview@npm:0.0.7":
|
||||
version: 0.0.7
|
||||
resolution: "@react-email/preview@npm:0.0.7"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 9125597760e69d36b9caf1a94595913f52364642351728a5ff91b7d97fce26fad74bae5f1c9baade8831f4154d4c88c773adcbc1f9f1d602b4113c50bf21eb30
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/render@npm:0.0.10":
|
||||
version: 0.0.10
|
||||
resolution: "@react-email/render@npm:0.0.10"
|
||||
dependencies:
|
||||
html-to-text: "npm:9.0.5"
|
||||
pretty: "npm:2.0.0"
|
||||
react: "npm:18.2.0"
|
||||
react-dom: "npm:18.2.0"
|
||||
checksum: ea0db578ef58734160ac512d04de5b09f558d192fbb74c0b9bdb3006e91d0d73ee7d77007f4740bef0d587f8b231f8dba5ef01e16e18d2deb37859ddd2e7d09a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/render@npm:0.0.9":
|
||||
version: 0.0.9
|
||||
resolution: "@react-email/render@npm:0.0.9"
|
||||
dependencies:
|
||||
html-to-text: "npm:9.0.5"
|
||||
pretty: "npm:2.0.0"
|
||||
react: "npm:18.2.0"
|
||||
react-dom: "npm:18.2.0"
|
||||
checksum: 128b3a7c65e77a14600e48fb24183e182de82b4ddc8ff11bb239c421fa68bd6eb8b063822b5abe9f8599e34ece315cdb961b4133c59285cebcc517d2ec0ae8da
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/row@npm:0.0.6":
|
||||
version: 0.0.6
|
||||
resolution: "@react-email/row@npm:0.0.6"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: ca1d92094a5ccc35c93560538311c38989162e9f0235a71897296bc43f2c0ba31d53df9c7db1688f7be0d77ccc03a0094cc227c4d095787f3b3ea0c3d262e520
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/section@npm:0.0.10":
|
||||
version: 0.0.10
|
||||
resolution: "@react-email/section@npm:0.0.10"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: d1af5dc3ff9a5bd2675a82f976df79ab5acded5ca305536df36ad84440b3828b021f8026d721e34fe92853bc3dfe8b9aa4603c25bf2f901b22049748ed6a7fbc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/tailwind@npm:0.0.13":
|
||||
version: 0.0.13
|
||||
resolution: "@react-email/tailwind@npm:0.0.13"
|
||||
dependencies:
|
||||
react: "npm:18.2.0"
|
||||
react-dom: "npm:18.2.0"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 5980a8593b699e9a0e0a8178120d206e74ccb525ba5fedb02e7048f8efff7ca41f82308584624a9701dc021d2ccfd8fa224f11a191d78e567a77f8d35bd47bb4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-email/text@npm:0.0.6":
|
||||
version: 0.0.6
|
||||
resolution: "@react-email/text@npm:0.0.6"
|
||||
peerDependencies:
|
||||
react: 18.2.0
|
||||
checksum: 1e960838bfe81bf33b42db1aa1d84446fc36911b4d9e9a79570d9a43fe9cc29d9271f7e1b25448383d8fe950a73130f8bed5c65cd8dbc786a2e6fe02e0c16202
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-hook/debounce@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "@react-hook/debounce@npm:3.0.0"
|
||||
@ -19889,7 +20095,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"config-chain@npm:^1.1.11":
|
||||
"condense-newlines@npm:^0.2.1":
|
||||
version: 0.2.1
|
||||
resolution: "condense-newlines@npm:0.2.1"
|
||||
dependencies:
|
||||
extend-shallow: "npm:^2.0.1"
|
||||
is-whitespace: "npm:^0.3.0"
|
||||
kind-of: "npm:^3.0.2"
|
||||
checksum: 19485db92a5d4658b50ab250626ece0cebe57f73af126b348604309894ed9a2b05f88f1802a090fd1897156eda0af69d8f14446bc62f978e0d048b5135e91694
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"config-chain@npm:^1.1.11, config-chain@npm:^1.1.13":
|
||||
version: 1.1.13
|
||||
resolution: "config-chain@npm:1.1.13"
|
||||
dependencies:
|
||||
@ -21842,6 +22059,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"editorconfig@npm:^1.0.3":
|
||||
version: 1.0.4
|
||||
resolution: "editorconfig@npm:1.0.4"
|
||||
dependencies:
|
||||
"@one-ini/wasm": "npm:0.1.1"
|
||||
commander: "npm:^10.0.0"
|
||||
minimatch: "npm:9.0.1"
|
||||
semver: "npm:^7.5.3"
|
||||
bin:
|
||||
editorconfig: bin/editorconfig
|
||||
checksum: ed6985959d7b34a56e1c09bef118758c81c969489b768d152c93689fce8403b0452462e934f665febaba3478eebc0fd41c0a36100783eaadf6d926c4abc87a3d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ee-first@npm:1.1.1":
|
||||
version: 1.1.1
|
||||
resolution: "ee-first@npm:1.1.1"
|
||||
@ -24670,7 +24901,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7":
|
||||
"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.3, glob@npm:^10.3.7":
|
||||
version: 10.3.10
|
||||
resolution: "glob@npm:10.3.10"
|
||||
dependencies:
|
||||
@ -27074,7 +27305,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"is-buffer@npm:^1.1.0":
|
||||
"is-buffer@npm:^1.1.0, is-buffer@npm:^1.1.5":
|
||||
version: 1.1.6
|
||||
resolution: "is-buffer@npm:1.1.6"
|
||||
checksum: ae18aa0b6e113d6c490ad1db5e8df9bdb57758382b313f5a22c9c61084875c6396d50bbf49315f5b1926d142d74dfb8d31b40d993a383e0a158b15fea7a82234
|
||||
@ -27635,6 +27866,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"is-whitespace@npm:^0.3.0":
|
||||
version: 0.3.0
|
||||
resolution: "is-whitespace@npm:0.3.0"
|
||||
checksum: 2f4ef13e0195170bbb587437133ef81ed9d6aec1c5e88f4c2b9055a18a1e70f75d9a9376f0cdae64f3c519e05e5f734d6b8f9682e5cb50384843480bade785ae
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"is-windows@npm:^0.2.0":
|
||||
version: 0.2.0
|
||||
resolution: "is-windows@npm:0.2.0"
|
||||
@ -28608,6 +28846,22 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"js-beautify@npm:^1.6.12":
|
||||
version: 1.14.11
|
||||
resolution: "js-beautify@npm:1.14.11"
|
||||
dependencies:
|
||||
config-chain: "npm:^1.1.13"
|
||||
editorconfig: "npm:^1.0.3"
|
||||
glob: "npm:^10.3.3"
|
||||
nopt: "npm:^7.2.0"
|
||||
bin:
|
||||
css-beautify: js/bin/css-beautify.js
|
||||
html-beautify: js/bin/html-beautify.js
|
||||
js-beautify: js/bin/js-beautify.js
|
||||
checksum: 23267f8e68a4cf190274906fbec98c4fa44025e1b7e1fa701480867c9ab6b2b90a1bb2b358cd487c34d735a1039c16bcb51f82d390bcc6384172cc540aa11c9b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"js-cookie@npm:^2.2.1":
|
||||
version: 2.2.1
|
||||
resolution: "js-cookie@npm:2.2.1"
|
||||
@ -29167,6 +29421,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"kind-of@npm:^3.0.2":
|
||||
version: 3.2.2
|
||||
resolution: "kind-of@npm:3.2.2"
|
||||
dependencies:
|
||||
is-buffer: "npm:^1.1.5"
|
||||
checksum: 7e34bc29d4b02c997f92f080de34ebb92033a96736bbb0bb2410e033a7e5ae6571f1fa37b2d7710018f95361473b816c604234197f4f203f9cf149d8ef1574d9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"kind-of@npm:^6.0.0, kind-of@npm:^6.0.2":
|
||||
version: 6.0.3
|
||||
resolution: "kind-of@npm:6.0.3"
|
||||
@ -32285,6 +32548,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimatch@npm:9.0.1":
|
||||
version: 9.0.1
|
||||
resolution: "minimatch@npm:9.0.1"
|
||||
dependencies:
|
||||
brace-expansion: "npm:^2.0.1"
|
||||
checksum: aa043eb8822210b39888a5d0d28df0017b365af5add9bd522f180d2a6962de1cbbf1bdeacdb1b17f410dc3336bc8d76fb1d3e814cdc65d00c2f68e01f0010096
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimatch@npm:9.0.3, minimatch@npm:^9.0.0, minimatch@npm:^9.0.1":
|
||||
version: 9.0.3
|
||||
resolution: "minimatch@npm:9.0.3"
|
||||
@ -33222,7 +33494,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nopt@npm:^7.0.0":
|
||||
"nopt@npm:^7.0.0, nopt@npm:^7.2.0":
|
||||
version: 7.2.0
|
||||
resolution: "nopt@npm:7.2.0"
|
||||
dependencies:
|
||||
@ -35916,6 +36188,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pretty@npm:2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "pretty@npm:2.0.0"
|
||||
dependencies:
|
||||
condense-newlines: "npm:^0.2.1"
|
||||
extend-shallow: "npm:^2.0.1"
|
||||
js-beautify: "npm:^1.6.12"
|
||||
checksum: 2fcd72f331d0afae3893ba88a5c05f6fdd62b059cb309028aa3309fc8a90410d81dfe66ae95677bc6d6d4a68f3cc1a247c13e5872bd35686f99acb33acc51164
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettyjson@npm:^1.2.1":
|
||||
version: 1.2.5
|
||||
resolution: "prettyjson@npm:1.2.5"
|
||||
@ -36728,7 +37011,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-dom@npm:^18.2.0":
|
||||
"react-dom@npm:18.2.0, react-dom@npm:^18.2.0":
|
||||
version: 18.2.0
|
||||
resolution: "react-dom@npm:18.2.0"
|
||||
dependencies:
|
||||
@ -37263,7 +37546,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react@npm:^18, react@npm:^18.2.0":
|
||||
"react@npm:18.2.0, react@npm:^18, react@npm:^18.2.0":
|
||||
version: 18.2.0
|
||||
resolution: "react@npm:18.2.0"
|
||||
dependencies:
|
||||
@ -41529,6 +41812,8 @@ __metadata:
|
||||
"@octokit/graphql": "npm:^7.0.2"
|
||||
"@ptc-org/nestjs-query-core": "npm:^4.2.0"
|
||||
"@ptc-org/nestjs-query-typeorm": "npm:4.2.1-alpha.2"
|
||||
"@react-email/components": "npm:0.0.12"
|
||||
"@react-email/render": "npm:0.0.10"
|
||||
"@sentry/node": "npm:^7.66.0"
|
||||
"@sentry/profiling-node": "npm:^1.2.6"
|
||||
"@sentry/react": "npm:^7.88.0"
|
||||
|
Loading…
Reference in New Issue
Block a user