tzmail
v1.0.5
Published
Email library for Next.js with customizable templates and themes
Downloads
92
Maintainers
Readme
Mikeprogrammer973/tzMail
Primeiros passos e uso básico/Inicialização SMTP e primeiro fluxo funcional
Primeiros passos e uso básico - Inicialização SMTP e primeiro fluxo funcional
Visão geral
Este fluxo mostra o caminho mínimo para sair da configuração SMTP e disparar o primeiro email funcional com tzMail. O ponto de partida é , onde dotenv.config() carrega as credenciais do ambiente, SMTP_CONFIG é montado com IEmailConfig, e EmailFactory.initialize() cria a instância única que passa a coordenar envio, templates e anexos.
Na prática, o usuário do pacote monta o SMTP_CONFIG, obtém TemplateService a partir de EmailFactory, cria um template com ThemeType e ITemplateConfig, e envia o email por emailFactory.sendEmail(). Quando template é informado e html não existe, o HTML final é gerado por TemplateService e TemplateBuilder, e o envio real ocorre via Nodemailer no EmailService.
Arquitetura do fluxo mínimo
flowchart TB
subgraph Boot [Bootstrap da demonstracao]
Dotenv[dotenv config]
Index[src index ts]
Config[SMTP_CONFIG]
Route[GET test]
Dotenv --> Config
Index --> Config
Index --> Route
end
subgraph Factory [EmailFactory]
FactoryInit[EmailFactory initialize]
FactoryInstance[Instancia unica]
EmailSvc[EmailService]
TemplateSvc[TemplateService]
AttachSvc[AttachmentService]
FactoryInit --> FactoryInstance
FactoryInstance --> EmailSvc
FactoryInstance --> TemplateSvc
FactoryInstance --> AttachSvc
end
subgraph Templating [Templates e renderizacao]
TemplateFactory[TemplateFactory]
TemplateBuilder[TemplateBuilder]
ThemeSet[Temas]
TemplateSvc --> TemplateFactory
TemplateFactory --> ThemeSet
TemplateFactory --> TemplateBuilder
end
subgraph SMTP [Envio SMTP]
Nodemailer[Transporter Nodemailer]
SMTPServer[Servidor SMTP]
EmailSvc --> Nodemailer
Nodemailer --> SMTPServer
end
Route --> AttachSvc
Route --> FactoryInstance
FactoryInstance --> TemplateSvc
FactoryInstance --> EmailSvcConfiguração SMTP mínima com IEmailConfig
IEmailConfig
EmailFactory.initialize() é idempotente: a primeira chamada cria a instância e as chamadas seguintes retornam a mesma instância já configurada. Isso faz com que o SMTP_CONFIG definido no bootstrap seja o ponto único de inicialização do transporte SMTP.
src/core/interfaces/email.interface.ts
IEmailConfig define tudo o que EmailFactory precisa para montar o transporter do Nodemailer e repassar o remetente padrão para EmailService.
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| host | string | Host SMTP usado por nodemailer.createTransport. |
| port | number | Porta do servidor SMTP. |
| secure | boolean | Indica uso de conexão segura no transporte. |
| auth.user | string | Usuário SMTP lido do ambiente em . |
| auth.pass | string | Senha SMTP lida do ambiente em . |
| defaultFrom? | string | Remetente padrão aplicado por EmailService quando options.from não é informado. |
Bootstrap do SMTP em
src/index.ts
O exemplo de demonstração monta o objeto SMTP com credenciais vindas de variáveis de ambiente e um defaultFrom fixo.
dotenv.config();
const SMTP_CONFIG = {
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
user: process.env.SMTP_USER!,
pass: process.env.SMTP_PASS!
},
defaultFrom: 'LyraX Corp <[email protected]>'
};
const emailFactory = EmailFactory.initialize(SMTP_CONFIG);As credenciais SMTP_USER e SMTP_PASS são lidas antes da criação da fábrica. O valor de defaultFrom é repassado para EmailService, que o usa como remetente quando options.from não é enviado em sendEmail().
Relação entre EmailFactory, TemplateService e EmailService
EmailFactoryé a fachada de entrada do fluxo.EmailFactory.initialize()cria:-EmailService, com otransporterdo Nodemailer edefaultFrom.TemplateService, com as opções de template.AttachmentService, para anexos.EmailFactory.getTemplateService()expõeTemplateServicepara criação e renderização de templates.EmailFactory.sendEmail()delega o envio paraEmailService.send().EmailService.send()resolvehtmldiretamente ou renderizaoptions.templatequandohtmlnão foi informado.
Contratos de email e anexo
IEmailOptions
src/core/interfaces/email.interface.ts
IEmailOptions representa os dados de envio recebidos por EmailService.send() e por EmailFactory.sendEmail().
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| to | string | string[] | Destinatário único ou lista de destinatários. |
| subject | string | Assunto do email. |
| from? | string | Remetente opcional que sobrescreve defaultFrom. |
| cc? | string | string[] | Cópia carbono opcional. |
| bcc? | string | string[] | Cópia oculta opcional. |
| attachments? | IAttachment[] | Lista de anexos em formato Nodemailer. |
| template? | ITemplate | Template a ser renderizado quando html não existir. |
| text? | string | Corpo textual opcional. |
| html? | string | HTML final; tem prioridade sobre template. |
IAttachment
src/core/interfaces/email.interface.ts
IAttachment é o formato usado em attachments por EmailService.send() e pelas saídas de AttachmentService.
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| filename | string | Nome exibido do arquivo anexado. |
| content? | string | Buffer | Conteúdo em memória do anexo. |
| path? | string | Caminho local do arquivo anexado. |
| contentType? | string | MIME type opcional. |
| cid? | string | Content ID para uso em imagens embutidas. |
EmailService
src/services/email.service.ts
EmailService encapsula o envio real e monta mailOptions a partir de IEmailOptions.
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| transporter | Transporter | Instância Nodemailer usada em sendMail(). |
| defaultFrom | string | undefined | Remetente padrão aplicado quando options.from não existe. |
Dependências do construtor
| Tipo | Descrição |
| --- | --- |
| Transporter | Transporte Nodemailer criado por EmailFactory. |
| string | defaultFrom opcional recebido de IEmailConfig. |
Métodos públicos
| Método | Descrição |
| --- | --- |
| send | Monta mailOptions, renderiza template quando necessário e chama transporter.sendMail(). |
Comportamento do envio
fromusaoptions.fromquando existe; caso contrário, usadefaultFrom.toaceitastring[]e converte para uma string separada por vírgula.htmltem prioridade absoluta.- Quando
htmlnão é informado etemplateexiste,template.render(options)gera o HTML. attachments,cc,bcc,subjectetextsão repassados aotransporter.
Resultado retornado
- Sucesso:
{ success: true, messageId, response } - Falha:
{ success: false, error }
AttachmentService
src/services/attachment.service.ts
AttachmentService transforma arquivos locais ou buffers em IAttachment prontos para Nodemailer.
Propriedades
Não há campos de instância declarados.
Dependências do construtor
Não possui construtor explícito.
Métodos públicos
| Método | Descrição |
| --- | --- |
| addFromPath | Valida um caminho local e retorna um IAttachment com path. |
| addFromBuffer | Retorna um IAttachment com content a partir de um Buffer. |
| addFromUrl | Lança erro de método não implementado. |
Comportamento de addFromPath
addFromUrl() sempre lança Error('Method not implemented yet'). O fluxo de demonstração que usa anexos só funciona com addFromPath() ou addFromBuffer().
- Faz
fs.promises.stat(filePath). - Exige que o caminho seja um arquivo.
- Usa
path.basename(filePath)quandooptions.filenamenão é informado. - Retorna
path,contentTypeecidquando informados.
Contratos e renderização de template
ITemplate
src/core/interfaces/template.interface.ts
ITemplate representa o objeto de template criado por TemplateFactory e consumido por EmailService.
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| name | string | Nome do template, como modern_light. |
| theme | ThemeType | Tema associado ao template. |
| variant | 'light' | 'dark' | Variação visual do template. |
| config | ITemplateConfig | Configuração estrutural do template. |
Métodos
| Método | Descrição |
| --- | --- |
| render | Gera o HTML final a partir dos dados recebidos. |
ITemplateConfig
src/core/interfaces/template.interface.ts
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| header? | IHeaderConfig | Configuração do cabeçalho. |
| body? | IBodyConfig | Configuração do corpo. |
| footer? | IFooterConfig | Configuração do rodapé. |
| layout? | 'full' 'minimal' | Layout geral do email. |
| spacing? | 'compact' 'normal' 'relaxed' | Espaçamento global. |
| borderRadius? | 'none' 'small' 'medium' 'large' | Raio de borda do container. |
IBodyConfig
src/core/interfaces/template.interface.ts
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| title? | string | Título principal do corpo. |
| message? | string | Mensagem principal do corpo. |
| content? | string | HTML do corpo quando já pronto. |
| buttonText? | string | Texto do botão. |
| buttonUrl? | string | URL do botão. |
| buttonVariant? | 'primary' 'secondary' 'success' 'danger' | Variante visual do botão. |
| alignment? | 'left' 'center' 'right' | Alinhamento do conteúdo. |
| backgroundColor? | string | Cor de fundo do bloco. |
| textColor? | string | Cor do texto do bloco. |
| fontSize? | number | Tamanho base da fonte em pixels. |
IHeaderConfig
src/core/interfaces/template.interface.ts
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| show | boolean | Define se o cabeçalho será renderizado. |
| logo? | { type: 'text' 'image'; text?; imageUrl?; alt?; size? } | Dados do logo textual ou em imagem. |
| backgroundColor? | string | Cor de fundo do cabeçalho. |
| textColor? | string | Cor do texto do cabeçalho. |
IFooterConfig
src/core/interfaces/template.interface.ts
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| show | boolean | Define se o rodapé será renderizado. |
| links? | Array<{ text: string; url: string }> | Links do rodapé. |
| socialLinks? | Array<{ platform: 'facebook' 'twitter' 'linkedin' 'github'; url: string }> | Links sociais com ícones. |
| copyrightText? | string | Texto de copyright. |
| unsubscribeText? | string | Texto do link de cancelamento. |
| backgroundColor? | string | Cor de fundo do rodapé. |
| textColor? | string | Cor do texto do rodapé. |
TemplateFactory
src/factories/template-factory.ts
TemplateFactory transforma ThemeType, variante e configuração em um ITemplate com render().
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| themes | Map<ThemeType, ITheme> | Catálogo estático de temas disponíveis. |
Métodos públicos
| Método | Descrição |
| --- | --- |
| createTemplate | Cria um template com name, theme, variant, config e render(). |
| getTheme | Recupera a instância do tema pelo ThemeType. |
| listThemes | Lista os temas disponíveis. |
| getThemeInfo | Retorna nome, descrição e features do tema. |
Como createTemplate monta o HTML
- Lê
data.template.config.body. - Usa
body.contentquando existe. - Caso contrário, monta um bloco padrão com:-
titleouHello! messageouThis is an email generated with tzMail.- Usa
TemplateBuilderpara montar:- cabeçalho combuildHeader() - corpo com
buildBody() - botão opcional com
buildButton() - rodapé com
buildFooter() - HTML final com
build()
TemplateBuilder
src/templates/base/template-builder.ts
TemplateBuilder constrói a estrutura HTML final e aplica variações específicas de tema nas seções de header, body, button e footer.
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| template | string | HTML acumulado durante a construção. |
| theme | ITheme | Tema ativo na renderização. |
| config | ITemplateConfig | Configuração do template. |
| variant | 'light' 'dark' | Variante de cor usada na renderização. |
Dependências do construtor
| Tipo | Descrição |
| --- | --- |
| ITheme | Tema concreto, como ModernTheme ou MinimalTheme. |
| ITemplateConfig | Configuração de header, body, footer e layout. |
| 'light' 'dark' | Variante do template. |
Métodos públicos
| Método | Descrição |
| --- | --- |
| buildHeader | Adiciona o bloco de cabeçalho ao HTML. |
| buildBody | Adiciona o bloco principal do corpo ao HTML. |
| buildButton | Adiciona o botão de CTA ao HTML. |
| buildFooter | Adiciona o rodapé ao HTML. |
| build | Finaliza o documento HTML completo. |
Comportamento relevante
buildHeader()retorna cedo quandoconfig.header.showé falso.buildBody()ajusta estilos e processa conteúdo conforme o tema.buildButton()usaprimaryousecondarye aplica estilos específicos por tema.buildFooter()incluilinks,socialLinks,copyrightTexteunsubscribeText.build()define o container central e o<html>completo.
TemplateService
src/services/template.service.ts
TemplateService é a camada central de criação, cache, histórico, renderização e pré-visualização de templates.
Tipos internos
TemplateCache
src/services/template.service.ts
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| template | ITemplate | Template armazenado no cache. |
| createdAt | Date | Data de criação do cache entry. |
| expiresAt | Date | Data de expiração. |
| hits | number | Quantidade de acessos ao cache. |
TemplateOptions
src/services/template.service.ts
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| cache? | boolean | Ativa ou desativa o cache. |
| cacheTTL? | number | TTL em segundos. |
| validateConfig? | boolean | Ativa validação da configuração. |
| minify? | boolean | Ativa minificação do HTML. |
| preview? | boolean | Marca o render como pré-visualização. |
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| templateCache | Map<string, TemplateCache> | Cache in-memory por template. |
| defaultTTL | number | TTL padrão em segundos. |
| templateHistory | Map<string, ITemplate[]> | Histórico de versões por template. |
| options | TemplateOptions | Configuração global do serviço. |
Dependências do construtor
| Tipo | Descrição |
| --- | --- |
| TemplateOptions | Opções de cache, validação, minificação e preview. |
Métodos públicos
| Método | Descrição |
| --- | --- |
| createTemplate | Cria ou reaproveita um template no cache. |
| cloneTemplate | Clona um template com modificações parciais. |
| renderTemplate | Renderiza um template e adiciona metadados _meta. |
| previewTemplate | Cria e renderiza um template sem persistir no cache. |
| getThemeInfo | Retorna informações detalhadas de tema e configuração padrão. |
| listThemes | Lista os ThemeType disponíveis. |
| getTemplateStats | Retorna métricas do cache e do histórico. |
| clearCache | Remove cache globalmente ou por tema. |
| getTemplateHistory | Retorna o histórico de versões de um template. |
| restoreTemplateVersion | Reconstrói uma versão anterior. |
| preloadTemplates | Pré-carrega templates no cache. |
| exportTemplate | Exporta o template para JSON. |
| importTemplate | Importa um template a partir de JSON. |
| generateExampleTemplate | Gera um template de demonstração. |
| isValidTemplate | Valida a estrutura de um objeto template. |
| getTemplateDetails | Retorna template atual, histórico, cache e uso. |
Fluxo de estado e cache
createTemplate()gera umtemplateIdcomthemeType,variante hash do JSON da config.- Se o cache estiver ativo e existir entrada válida, incrementa
hitse retorna o template cacheado. - Se não houver cache, cria o template por
TemplateFactory.createTemplate(). - O template é enriquecido com métodos dinâmicos:-
getVersion() getId()clone()- O histórico mantém as últimas 10 versões por
templateId. cleanExpiredCache()remove entradas vencidas a cada hora viasetInterval().
Validação de configuração
validateTemplateConfig() agrega erros e lança uma única exceção quando encontra problemas em:
- logo de imagem sem
imageUrl - logo textual sem
text - links de footer sem
textouurl layoutfora defullouminimalspacingfora decompact,normalourelaxedborderRadiusfora denone,small,mediumoularge
Metadados adicionados no render
renderTemplate() injeta _meta no payload:
isPreviewrenderDatetemplateNamethemevariant
ThemeType
src/core/enums/theme.enum.ts
ThemeType define os temas usados em TemplateFactory e TemplateService.
Valores: SYSTEM, MONOKAI, MODERN, CORPORATE, MINIMAL.
TemplatePart
src/core/enums/template-part.enum.ts
TemplatePart descreve as partes estruturais do email renderizado.
Valores: HEADER, BODY, FOOTER, BUTTON.
Temas disponíveis
ITheme
src/templates/themes/theme.interface.ts
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| id | ThemeType | Identificador do tema. |
| name | string | Nome humano do tema. |
| light | IThemeColors | Paleta para variante clara. |
| dark | IThemeColors | Paleta para variante escura. |
| typography | ITypography | Tipografia do tema. |
| spacing | ISpacing | Escala de espaçamento do tema. |
IThemeColors
src/templates/themes/theme.interface.ts
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| primary | string | Cor principal. |
| secondary | string | Cor secundária. |
| background | string | Cor de fundo. |
| text | string | Cor de texto principal. |
| textMuted | string | Cor de texto secundário. |
| border | string | Cor de borda. |
| success | string | Cor de sucesso. |
| error | string | Cor de erro. |
| warning | string | Cor de aviso. |
ITypography
src/templates/themes/theme.interface.ts
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| fontFamily | string | Família tipográfica base. |
| fontSizes | { small: string; medium: string; large: string; xlarge: string } | Escala de tamanhos. |
| fontWeights | { normal: number; medium: number; bold: number } | Pesos tipográficos. |
ISpacing
src/templates/themes/theme.interface.ts
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| xs | string | Espaçamento extra pequeno. |
| sm | string | Espaçamento pequeno. |
| md | string | Espaçamento médio. |
| lg | string | Espaçamento grande. |
| xl | string | Espaçamento extra grande. |
SystemTheme
src/templates/themes/system.theme.ts
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| id | ThemeType | Valor SYSTEM. |
| name | string | Nome System. |
| light | { primary; secondary; background; text; textMuted; border; success; error; warning } | Paleta clara. |
| dark | { primary; secondary; background; text; textMuted; border; success; error; warning } | Paleta escura. |
| typography | { fontFamily; fontSizes; fontWeights } | Tipografia base do tema. |
| spacing | { xs; sm; md; lg; xl } | Escala de espaçamento. |
MonokaiTheme
src/templates/themes/monokai.theme.ts
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| id | ThemeType | Valor MONOKAI. |
| name | string | Nome Monokai. |
| light | IThemeColors | Paleta clara com acentos fortes. |
| dark | IThemeColors | Paleta escura Monokai. |
| typography | ITypography | Tipografia monoespaçada. |
| spacing | ISpacing | Escala compacta. |
| codeHighlight | { comment; keyword; string; number; function; variable } | Cores de destaque para blocos de código. |
| borderStyle | { radius: string; width: string; style: string } | Estilo de borda do tema. |
| effects | { glow; shadow; transition } | Efeitos visuais do tema. |
ModernTheme
src/templates/themes/modern.theme.ts
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| id | ThemeType | Valor MODERN. |
| name | string | Nome Modern. |
| light | IThemeColors | Paleta clara contemporânea. |
| dark | IThemeColors | Paleta escura contemporânea. |
| typography | ITypography | Tipografia moderna. |
| spacing | ISpacing | Escala de espaçamento. |
| gradients | { primary; secondary; accent; dark; light } | Gradientes usados pelo builder. |
| borderStyle | { radius: { small; medium; large; full }; width: string; style: string } | Raio e borda do tema. |
| glassmorphism | { light; dark; blur } | Cores e blur para efeito glass. |
| animations | { hover; fade; slide } | Transições do tema. |
CorporateTheme
src/templates/themes/corporate.theme.ts
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| id | ThemeType | Valor CORPORATE. |
| name | string | Nome Corporate. |
| light | IThemeColors | Paleta clara corporativa. |
| dark | IThemeColors | Paleta escura corporativa. |
| typography | ITypography | Tipografia serifada. |
| spacing | ISpacing | Escala de espaçamento. |
| corporateColors | { gold; silver; bronze; navy; charcoal; ivory } | Paleta de apoio corporativa. |
| borderStyle | { radius: { small; medium; large; pill }; width: { thin; medium; thick }; style: string } | Bordas do tema. |
| elevation | { shadow; card; modal; hover } | Sombras e elevação. |
| branding | { logoSize; letterSpacing; textTransform } | Regras de marca. |
| layout | { maxWidth; contentWidth; sidebarWidth; headerHeight; footerHeight } | Medidas de layout. |
MinimalTheme
src/templates/themes/minimal.theme.ts
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| id | ThemeType | Valor MINIMAL. |
| name | string | Nome Minimal. |
| light | IThemeColors | Paleta clara minimalista. |
| dark | IThemeColors | Paleta escura minimalista. |
| typography | ITypography | Tipografia sem serifa. |
| spacing | ISpacing | Escala expandida. |
| minimalColors | { white; black; gray100; gray200; gray300; gray400; gray500; gray600; gray700; gray800; gray900 } | Paleta neutra. |
| borderStyle | { radius: { none; small; medium; large; full }; width: { thin; medium }; style: string } | Bordas minimalistas. |
| effects | { shadow; transition; opacity } | Efeitos suaves e opacidade. |
| layout | { maxWidth; contentWidth; spacingMultiplier; lineHeight; paragraphSpacing } | Regras de layout. |
| designSystem | { grid; breakpoints; zIndex } | Grid e breakpoints do tema. |
Fábrica de email e inicialização do fluxo
EmailFactory
src/factories/email-factory.ts
EmailFactory centraliza a criação do transporte SMTP, o serviço de email, o serviço de templates e o serviço de anexos. A classe funciona como singleton global do pacote.
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| instance | EmailFactory undefined | Instância única mantida pela fábrica. |
| emailService | EmailService | Serviço de envio usado por sendEmail(). |
| templateService | TemplateService | Serviço de criação e renderização de templates. |
| attachmentService | AttachmentService | Serviço de anexos criado junto com a fábrica. |
Dependências do construtor
| Tipo | Descrição |
| --- | --- |
| IEmailConfig | Configuração SMTP e defaultFrom. |
| any | templateOptions repassado para TemplateService. |
Métodos públicos
| Método | Descrição |
| --- | --- |
| initialize | Cria a instância única com SMTP e serviços internos. |
| getInstance | Retorna a instância criada ou lança erro se não houver inicialização. |
| sendEmail | Encaminha o envio para EmailService.send(). |
| getTemplateService | Expõe a instância de TemplateService. |
| getAttachmentService | Expõe a instância de AttachmentService. |
| previewTemplate | Delegada para TemplateService.previewTemplate(). |
| getThemeInfo | Delegada para TemplateService.getThemeInfo(). |
| listThemes | Delegada para TemplateService.listThemes(). |
| getTemplateStats | Delegada para TemplateService.getTemplateStats(). |
Relação de uso no bootstrap
EmailFactory.initialize(SMTP_CONFIG)cria otransportercomnodemailer.createTransport(config).- O
EmailServicerecebe otransportereconfig.defaultFrom. - O
TemplateServiceé criado comtemplateOptionsquando fornecidas. - O
AttachmentServicefica disponível para montagem de anexos. - A aplicação recupera
templateServicecomgetTemplateService()e gera os templates usados no primeiro envio.
Nota sobre reconfiguração
Fluxo funcional do primeiro email
Funções de demonstração em
A fábrica não recria o transporte após a primeira inicialização. Isso significa que mudanças em SMTP_CONFIG só têm efeito antes da primeira chamada de initialize().
src/index.ts
Estas funções mostram como a fábrica é consumida no exemplo de servidor Express.
| Função | Descrição |
| --- | --- |
| sendWelcomeEmail | Envia um email com modernTemplate e assunto de boas-vindas. |
| sendTechNewsletter | Envia uma newsletter técnica com monokaiTemplate. |
| sendCorporateReport | Envia um relatório corporativo com corporateTemplate. |
| sendMinimalNewsletter | Envia uma newsletter minimalista com anexo vindo de AttachmentService.addFromPath(). |
Fluxo mínimo usado no exemplo
dotenv.config()carregaSMTP_USEReSMTP_PASS.SMTP_CONFIGé montado comhost,port,secure,auth.user,auth.passedefaultFrom.EmailFactory.initialize(SMTP_CONFIG)cria a fábrica.emailFactory.getTemplateService()expõe o serviço de templates.templateService.createTemplate(...)monta um template com tema e configuração.emailFactory.sendEmail({ to, subject, template })envia a mensagem.EmailService.send()resolvefromcomdefaultFrom, renderiza o template e chama otransporter.- O resultado retorna como JSON.
Exemplo mínimo de envio
const templateService = emailFactory.getTemplateService();
const modernTemplate = templateService.createTemplate(
ThemeType.MODERN,
'light',
{
header: {
show: true,
logo: {
type: 'image',
imageUrl: 'https://talkspace-ten.vercel.app/_next/image?url=%2Flogo%2Ftalkspace-banner.png&w=640&q=75',
size: 'large'
}
},
body: {
title: 'Bem-vindo ao LyraX!',
message: 'Estamos felizes em tê-lo conosco.',
buttonText: 'Começar Agora',
buttonUrl: 'https://meuapp.com/get-started',
buttonVariant: 'primary',
alignment: 'center',
fontSize: 16
},
footer: {
show: true,
copyrightText: '© 2024 Meu App'
},
layout: 'full',
spacing: 'normal',
borderRadius: 'medium'
}
);
await emailFactory.sendEmail({
to: '[email protected]',
subject: 'Bem-vindo ao Meu App!',
template: modernTemplate
});Fluxo com anexo no exemplo
sendMinimalNewsletter() cria um AttachmentService localmente, chama addFromPath('uploads/PHOTO.jpg') e injeta o retorno em attachments. O envio segue o mesmo caminho do email comum, mas com o anexo repassado para Nodemailer.
sequenceDiagram
participant U as Usuario
participant E as Express
participant S as sendMinimalNewsletter
participant A as AttachmentService
participant F as EmailFactory
participant M as EmailService
participant T as Template
participant B as TemplateBuilder
participant N as Nodemailer
participant Smtp as SMTP
U->>E: GET test
E->>S: sendMinimalNewsletter
S->>A: addFromPath uploads PHOTO jpg
A-->>S: IAttachment
S->>F: sendEmail
F->>M: send
M->>T: render
T->>B: buildHeader buildBody buildFooter build
B-->>T: HTML
T-->>M: HTML final
M->>N: sendMail
N->>Smtp: entregar email
Smtp-->>N: resposta SMTP
N-->>M: info
M-->>F: { success, messageId, response }
F-->>E: JSON
E-->>U: resposta do endpointServidor de demonstração e ponto de entrada
Endpoint de teste
Executar envio de teste
src/index.ts
{
"title": "Executar envio de teste",
"description": "Dispara o fluxo de demonstra\u00e7\u00e3o que cria um anexo a partir de uploads/PHOTO.jpg, envia um email com o tema Minimal em modo dark e retorna o resultado do envio em JSON.",
"method": "GET",
"baseUrl": "<DemoServerBaseUrl>",
"endpoint": "/test",
"headers": [],
"queryParams": [],
"pathParams": [],
"bodyType": "none",
"requestBody": "",
"formData": [],
"rawBody": "",
"responses": {
"200": {
"description": "Resultado retornado diretamente por res.json(result).",
"body": "{\n \"success\": true,\n \"messageId\": \"[email protected]\",\n \"response\": \"250 2.0.0 OK\"\n}"
}
}
}Comportamento real do endpoint
- O endpoint é
GET /test. - Ele chama
sendMinimalNewsletter('[email protected]'). - O retorno de
emailFactory.sendEmail()é enviado diretamente comres.json(result). - Não há middleware de autenticação nem validação adicional além dos middlewares globais
express.json()eexpress.urlencoded()montados no bootstrap.
Inicialização do servidor
sendMinimalNewsletter() não possui try/catch. Se addFromPath('uploads/PHOTO.jpg') falhar ou se o envio SMTP lançar exceção antes de retornar, a requisição deixa de responder com o objeto de sucesso e a exceção sobe para o fluxo do Express.
também define:
PORT = 3001app.use(express.json())app.use(express.urlencoded({ extended: true }))app.listen(PORT, ...)com banner de inicialização no console
Estado, cache e tratamento de erros
Estado de inicialização
EmailFactorymantém estado global por meio deprivate static instance.TemplateServicemantém estado em memória portemplateCacheetemplateHistory.TemplateServiceagenda limpeza automática comsetInterval(..., 3600000).
Cache de templates
| Elemento | Valor |
| --- | --- |
| Chave do cache | ${themeType}_${variant}_${hash} |
| Dado armazenado | ITemplate enriquecido |
| Contador de uso | hits |
| Expiração | expiresAt calculado em segundos e convertido para milissegundos |
| Limpeza automática | cleanExpiredCache() a cada hora |
| Limpeza manual | clearCache() |
| Histórico | Últimas 10 versões por templateId |
Tratamento de erros por componente
EmailFactory.getInstance()lança erro seinitialize()ainda não foi chamado.TemplateFactory.createTemplate()lança erro quando o tema não existe no mapathemes.TemplateService.validateTemplateConfig()lança um único erro com todos os problemas encontrados.TemplateService.renderTemplate()captura falhas e relança com contexto:Failed to render template: ...EmailService.send()nunca lança erro diretamente; retornasuccess: falsecom o objeto de erro.AttachmentService.addFromPath()lança erro se o caminho não for arquivo.AttachmentService.addFromUrl()lança erro fixo de método não implementado.
Dependências e integração
Dependências externas
expressnodemailerdotenvfspath
Entradas de ambiente usadas no bootstrap
SMTP_USERSMTP_PASS
Integrações internas
- consome
EmailFactoryeTemplateService. EmailFactoryinstanciaEmailService,TemplateServiceeAttachmentService.TemplateServicedepende deTemplateFactory.TemplateFactorydepende das classes de tema e deTemplateBuilder.EmailServicedepende doTransporterdo Nodemailer.AttachmentServiceé usado tanto no exemplo de anexo quanto como serviço exposto pela fábrica.
Considerações de teste
- Validar que
EmailFactory.initialize()foi chamado antes de qualquergetInstance(). - Verificar se
SMTP_USEReSMTP_PASSestão definidos antes do bootstrap. - Confirmar que
defaultFromaparece no envelope do email quandooptions.fromnão é enviado. - Testar
sendEmail()com:-templateapenas htmlapenastemplateehtmljuntosattachmentscom arquivo válido- Confirmar que
addFromPath()falha para diretório ou caminho inexistente. - Confirmar que
GET /testretorna JSON com o formato devolvido porsendEmail().
Referência rápida das classes-chave
| Class | Responsibility |
| --- | --- |
| email-factory.ts | Centraliza a inicialização SMTP e expõe EmailService, TemplateService e AttachmentService. |
| email.service.ts | Constrói mailOptions e envia emails via Nodemailer. |
| template.service.ts | Cria, renderiza, cacheia e versiona templates. |
| template-factory.ts | Transforma tema e configuração em um ITemplate renderizável. |
| template-builder.ts | Monta o HTML final do email com header, body, button e footer. |
| attachment.service.ts | Converte arquivos e buffers em anexos Nodemailer. |
| system.theme.ts | Define o tema base SYSTEM. |
| monokai.theme.ts | Define o tema MONOKAI com destaque de código. |
| modern.theme.ts | Define o tema MODERN com gradientes e glassmorphism. |
| corporate.theme.ts | Define o tema CORPORATE com linguagem visual executiva. |
| minimal.theme.ts | Define o tema MINIMAL com layout enxuto e neutro. |
Gerenciamento de Templates/Temas concretos: System, Monokai, Modern, Corporate e Minimal
Gerenciamento de Templates - Temas concretos
Visão geral
Este recorte concentra os cinco temas concretos do mecanismo de templates de email do projeto: System, Monokai, Modern, Corporate e Minimal. Eles formam a camada visual base que define cores, tipografia, espaçamento e extensões temáticas usadas na composição final do HTML.
O fluxo visível no código parte do contrato ITheme, passa pelo registro de temas em TemplateFactory e chega à montagem visual em TemplateBuilder. Na prática, o tema selecionado determina como cabeçalho, corpo, botão e rodapé são estilizados, além de habilitar comportamentos especiais como realce de código, gradientes, glassmorphism, branding corporativo e layout minimalista.
Comparação rápida dos temas
| Tema | Paleta visual | Tipografia | Espaçamento | Extensões específicas |
| --- | --- | --- | --- | --- |
| System | Azul padrão e neutros claros/escuros | Sans system default | Compacto a normal | Nenhuma extensão extra |
| Monokai | Paleta técnica com magenta, verde e roxo | Monospace | Compacto | codeHighlight, effects, borderStyle |
| Modern | Neutros com azul e gradientes | Inter com suporte a UI moderna | Médio a relaxado | gradients, glassmorphism, animations, borderStyle |
| Corporate | Azul executivo com dourado e tons institucionais | Serifada | Médio | corporateColors, branding, elevation, layout, borderStyle |
| Minimal | Preto, branco e cinzas | Inter limpa | Generoso | minimalColors, effects, layout, designSystem, borderStyle |
Arquitetura de composição dos temas
flowchart LR
subgraph Contratos[Contratos]
ThemeType[ThemeType]
ITheme[ITheme]
IThemeColors[IThemeColors]
ITypography[ITypography]
ISpacing[ISpacing]
end
subgraph TemasConcretos[Temas concretos]
SystemTheme[SystemTheme]
MonokaiTheme[MonokaiTheme]
ModernTheme[ModernTheme]
CorporateTheme[CorporateTheme]
MinimalTheme[MinimalTheme]
end
subgraph Composicao[Composição]
TemplateFactory[TemplateFactory]
TemplateBuilder[TemplateBuilder]
end
ThemeType --> TemplateFactory
ITheme --> SystemTheme
ITheme --> MonokaiTheme
ITheme --> ModernTheme
ITheme --> CorporateTheme
ITheme --> MinimalTheme
TemplateFactory --> SystemTheme
TemplateFactory --> MonokaiTheme
TemplateFactory --> ModernTheme
TemplateFactory --> CorporateTheme
TemplateFactory --> MinimalTheme
TemplateBuilder --> SystemTheme
TemplateBuilder --> MonokaiTheme
TemplateBuilder --> ModernTheme
TemplateBuilder --> CorporateTheme
TemplateBuilder --> MinimalThemeO contrato ITheme padroniza os tokens visuais obrigatórios. TemplateFactory mantém a instância concreta em um Map<ThemeType, ITheme>, enquanto TemplateBuilder lê esses tokens e monta as variações de HTML conforme variant e theme.id.
Contratos compartilhados
theme.interface.ts
src/templates/themes/theme.interface.ts
ITheme
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| id | ThemeType | Identificador do tema |
| name | string | Nome legível do tema |
| light | IThemeColors | Paleta para modo claro |
| dark | IThemeColors | Paleta para modo escuro |
| typography | ITypography | Sistema tipográfico do tema |
| spacing | ISpacing | Escala de espaçamento do tema |
IThemeColors
| Propriedade | Tipo |
| --- | --- |
| primary | string |
| secondary | string |
| background | string |
| text | string |
| textMuted | string |
| border | string |
| success | string |
| error | string |
| warning | string |
ITypography
| Propriedade | Tipo |
| --- | --- |
| fontFamily | string |
| fontSizes.small | string |
| fontSizes.medium | string |
| fontSizes.large | string |
| fontSizes.xlarge | string |
| fontWeights.normal | number |
| fontWeights.medium | number |
| fontWeights.bold | number |
ISpacing
| Propriedade | Tipo |
| --- | --- |
| xs | string |
| sm | string |
| md | string |
| lg | string |
| xl | string |
ThemeType
Valores definidos: system, monokai, modern, corporate, minimal.
TemplateFactory
src/factories/template-factory.ts
A fábrica registra os cinco temas concretos em um Map<ThemeType, ITheme> e materializa um ITemplate com name, theme, variant, config e render.
Métodos públicos
| Método | Descrição |
| --- | --- |
| createTemplate | Resolve o tema pelo ThemeType, cria um ITemplate e associa o render à montagem via TemplateBuilder |
| getTheme | Retorna a instância concreta do tema para um ThemeType |
| listThemes | Lista os temas registrados no mapa interno |
| getThemeInfo | Expõe nome, descrição e lista de recursos do tema |
Metadados de tema expostos por getThemeInfo
| Tema | Nome | Descrição | Recursos |
| --- | --- | --- | --- |
| SYSTEM | System | Tema limpo e profissional com cores adaptativas | Design minimalista, alta acessibilidade, compatibilidade total |
| MONOKAI | Monokai | Inspirado no tema de código, ideal para conteúdo técnico | Cores vibrantes, destaque de sintaxe, efeitos glow |
| MODERN | Modern | Design contemporâneo com gradientes e efeitos modernos | Gradientes elegantes, glassmorphism, animações suaves |
| CORPORATE | Corporate | Design profissional e elegante para empresas | Tipografia serifada, detalhes em dourado, layout estruturado |
| MINIMAL | Minimal | Design clean e focado no conteúdo | Sem distrações, espaçamento generoso, tipografia limpa |
TemplateBuilder
src/templates/base/template-builder.ts
O TemplateBuilder consome o tema concreto em cada etapa da composição do email. Ele aplica estilos de cabeçalho, corpo, botão, rodapé e container final com ramificações específicas para monokai, modern, corporate e minimal.
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| template | string | HTML acumulado durante a construção |
| theme | ITheme | Tema concreto usado na renderização |
| config | ITemplateConfig | Configuração visual do template |
| variant | 'light' 'dark' | Variante visual ativa |
Métodos públicos
| Método | Descrição |
| --- | --- |
| buildHeader | Monta o cabeçalho e aplica ajustes específicos por tema |
| buildBody | Monta o corpo do email e processa conteúdo especial por tema |
| buildButton | Monta o botão de CTA com variações visuais por tema |
| buildFooter | Monta o rodapé com links, redes sociais e texto institucional |
| build | Finaliza o HTML completo do template |
Extensões específicas aplicadas por tema
| Tema | Propriedades consumidas | Efeito gerado |
| --- | --- | --- |
| System | light, dark, typography, spacing | Estilo base com bordas e espaçamentos padrão |
| Monokai | codeHighlight, effects, borderStyle | Realce de código, brilho, transições e borda técnica |
| Modern | gradients, glassmorphism, animations, borderStyle | Botões com gradiente, blur e cantos arredondados |
| Corporate | corporateColors, branding, elevation, borderStyle | Dourado institucional, caixa com sombra e tipografia serifada |
| Minimal | layout, designSystem, effects, borderStyle | Layout centralizado, conteúdo arejado e aparência sem distrações |
Helpers internos relevantes
| Método | Função |
| --- | --- |
| buildLogo | Renderiza logo em texto ou imagem com ajustes por tema |
| formatCorporateContent | Adiciona estilos corporativos a blockquote e highlight |
| formatMinimalContent | Simplifica títulos e parágrafos para o tema minimalista |
| highlightCode | Converte blocos <code> em <pre> com estilização Monokai |
| applySyntaxHighlighting | Aplica coloração por palavra-chave, string, número e função |
| buildFooterLinks | Monta links do rodapé com variações por tema |
| buildSocialLinks | Monta ícones sociais a partir de URLs fixas |
| getSocialIcon | Resolve o ícone do serviço social pela plataforma |
Fluxo de criação e renderização de um tema
sequenceDiagram
participant Dev as Desenvolvedor
participant TemplateFactory as TemplateFactory
participant ITemplate as ITemplate
participant TemplateBuilder as TemplateBuilder
Dev->>TemplateFactory: createTemplate
TemplateFactory->>TemplateFactory: resolve tema por ThemeType
TemplateFactory-->>Dev: ITemplate
Dev->>ITemplate: render
ITemplate->>TemplateBuilder: buildHeader
ITemplate->>TemplateBuilder: buildBody
ITemplate->>TemplateBuilder: buildButton
ITemplate->>TemplateBuilder: buildFooter
ITemplate->>TemplateBuilder: build
TemplateBuilder-->>ITemplate: HTML final
ITemplate-->>Dev: HTML renderizadoOs blocos de estilo criados em buildButton, buildFooterLinks e trechos similares incluem &:hover dentro de atributos style. O HTML inline gerado por build() preserva esse texto, mas pseudo-classes não são interpretadas como CSS ativo no markup final.
Esse fluxo é o mesmo para os cinco temas concretos; o que muda é o conjunto de tokens expostos pelo tema e as ramificações internas que TemplateBuilder ativa com base em theme.id.
Temas concretos
SystemTheme
src/templates/themes/system.theme.ts
Tema base com visual neutro e suporte direto a modos claro e escuro. Ele usa azul como cor primária e neutros para texto, borda e superfícies, com tipografia sans-serif do sistema.
Propriedades
| Propriedade | Tipo |
| --- | --- |
| id | ThemeType.SYSTEM |
| name | string |
| light | IThemeColors |
| dark | IThemeColors |
| typography | ITypography |
| spacing | ISpacing |
Paleta
| Token | Light | Dark |
| --- | --- | --- |
| primary | #3b82f6 | #3b82f6 |
| secondary | #6b7280 | #9ca3af |
| background | #ffffff | #111827 |
| text | #111827 | #f9fafb |
| textMuted | #6b7280 | #9ca3af |
| border | #e5e7eb | #374151 |
| success | #10b981 | #10b981 |
| error | #ef4444 | #ef4444 |
| warning | #f59e0b | #f59e0b |
Tipografia
| Propriedade | Valor |
| --- | --- |
| fontFamily | -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif |
| fontSizes.small | 12px |
| fontSizes.medium | 14px |
| fontSizes.large | 16px |
| fontSizes.xlarge | 20px |
| fontWeights.normal | 400 |
| fontWeights.medium | 500 |
| fontWeights.bold | 700 |
Espaçamento
| Propriedade | Valor |
| --- | --- |
| xs | 4px |
| sm | 8px |
| md | 16px |
| lg | 24px |
| xl | 32px |
Leitura visual
- Cabeçalho e rodapé usam os tokens base de fundo, borda e texto.
- Não há propriedades extras além do contrato
ITheme. - A aplicação em
TemplateBuildersegue o caminho padrão, sem ramificações visuais adicionais.
MonokaiTheme
src/templates/themes/monokai.theme.ts
Tema voltado para conteúdo técnico, com identidade inspirada em editores de código. A paleta mantém magenta e verde como destaques, e o tema adiciona realce semântico para blocos de código.
Propriedades
| Propriedade | Tipo |
| --- | --- |
| id | ThemeType.MONOKAI |
| name | string |
| light | IThemeColors |
| dark | IThemeColors |
| typography | ITypography |
| spacing | ISpacing |
| codeHighlight | { comment: string; keyword: string; string: string; number: string; function: string; variable: string } |
| borderStyle | { radius: string; width: string; style: string } |
| effects | { glow: string; shadow: string; transition: string } |
Paleta
| Token | Light | Dark |
| --- | --- | --- |
| primary | #f92672 | #f92672 |
| secondary | #a6e22e | #a6e22e |
| background | #f9f9f9 | #272822 |
| text | #272822 | #f8f8f2 |
| textMuted | #75715e | #75715e |
| border | #e5e5e5 | #3e3d32 |
| success | #a6e22e | #a6e22e |
| error | #f92672 | #f92672 |
| warning | #fd971f | #fd971f |
Tipografia
| Propriedade | Valor |
| --- | --- |
| fontFamily | SF Mono, Monaco, Inconsolata, Fira Code, monospace |
| fontSizes.small | 12px |
| fontSizes.medium | 14px |
| fontSizes.large | 16px |
| fontSizes.xlarge | 20px |
| fontWeights.normal | 400 |
| fontWeights.medium | 500 |
| fontWeights.bold | 700 |
Espaçamento
| Propriedade | Valor |
| --- | --- |
| xs | 4px |
| sm | 8px |
| md | 16px |
| lg | 24px |
| xl | 32px |
Extensões específicas
codeHighlight
| Token | Cor |
| --- | --- |
| comment | #75715e |
| keyword | #f92672 |
| string | #e6db74 |
| number | #ae81ff |
| function | #a6e22e |
| variable | #fd971f |
borderStyle
| Propriedade | Valor |
| --- | --- |
| radius | 4px |
| width | 2px |
| style | solid |
effects
| Propriedade | Valor |
| --- | --- |
| glow | 0 0 10px rgba(249, 38, 114, 0.3) |
| shadow | 0 4px 6px rgba(0, 0, 0, 0.1) |
| transition | all 0.3s ease |
Leitura visual
TemplateBuilder.highlightCodeusacodeHighlightpara colorir keywords, strings, números e nomes de função.- O cabeçalho e os botões recebem brilho e transição via
effects. - O layout privilegia blocos com borda técnica e acento visual marcante.
ModernTheme
src/templates/themes/modern.theme.ts
Tema contemporâneo com uso de gradientes, blur e transições suaves. O conjunto de tokens foi desenhado para dar mais profundidade visual a botões, contêineres e cabeçalhos.
Propriedades
| Propriedade | Tipo |
| --- | --- |
| id | ThemeType.MODERN |
| name | string |
| light | IThemeColors |
| dark | IThemeColors |
| typography | ITypography |
| spacing | ISpacing |
| gradients | { primary: string; secondary: string; accent: string; dark: string; light: string } |
| borderStyle | { radius: { small: string; medium: string; large: string; full: string }; width: string; style: string } |
| glassmorphism | { light: string; dark: string; blur: string } |
| animations | { hover: string; fade: string; slide: string } |
Paleta
| Token | Light | Dark |
| --- | --- | --- |
| primary | #0f172a | #38bdf8 |
| secondary | #64748b | #94a3b8 |
| background | #ffffff | #0f172a |
| text | #0f172a | #f1f5f9 |
| textMuted | #64748b | #94a3b8 |
| border | #e2e8f0 | #1e293b |
| success | #10b981 | #34d399 |
| error | #ef4444 | #f87171 |
| warning | #f59e0b | #fbbf24 |
Tipografia
| Propriedade | Valor |
| --- | --- |
| fontFamily | Inter, SF Pro Display, Segoe UI, system-ui, sans-serif |
| fontSizes.small | 13px |
| fontSizes.medium | 15px |
| fontSizes.large | 17px |
| fontSizes.xlarge | 24px |
| fontWeights.normal | 400 |
| fontWeights.medium | 500 |
| fontWeights.bold | 600 |
Espaçamento
| Propriedade | Valor |
| --- | --- |
| xs | 6px |
| sm | 12px |
| md | 20px |
| lg | 32px |
| xl | 48px |
Extensões específicas
gradients
| Token | Valor |
| --- | --- |
| primary | linear-gradient(135deg, #0f172a 0%, #1e293b 100%) |
| secondary | linear-gradient(135deg, #64748b 0%, #94a3b8 100%) |
| accent | linear-gradient(135deg, #38bdf8 0%, #0f172a 100%) |
| dark | linear-gradient(135deg, #0f172a 0%, #020617 100%) |
| light | linear-gradient(135deg, #f8fafc 0%, #ffffff 100%) |
borderStyle
| Propriedade | Valor |
| --- | --- |
| radius.small | 8px |
| radius.medium | 12px |
| radius.large | 16px |
| radius.full | 9999px |
| width | 1px |
| style | solid |
glassmorphism
| Propriedade | Valor |
| --- | --- |
| light | rgba(255, 255, 255, 0.8) |
| dark | rgba(15, 23, 42, 0.8) |
| blur | 12px |
animations
| Propriedade | Valor |
| --- | --- |
| hover | transform 0.2s ease, box-shadow 0.2s ease |
| fade | opacity 0.3s ease |
| slide | transform 0.3s cubic-bezier(0.4, 0, 0.2, 1) |
Leitura visual
TemplateBuilderusagradients.primaryno botão principal e no texto do logo.glassmorphism.blurentra no cabeçalho e no rodapé para criar profundidade.animations.hoveré aplicado a botões e links de navegação do tema.
CorporateTheme
src/templates/themes/corporate.theme.ts
Tema voltado para comunicação empresarial, com base serifada, tons institucionais e acentos dourados. O tema expande o contrato base com tokens de marca, elevação e layout.
Propriedades
| Propriedade | Tipo |
| --- | --- |
| id | ThemeType.CORPORATE |
| name | string |
| light | IThemeColors |
| dark | IThemeColors |
| typography | ITypography |
| spacing | ISpacing |
| corporateColors | { gold: string; silver: string; bronze: string; navy: string; charcoal: string; ivory: string } |
| borderStyle | { radius: { small: string; medium: string; large: string; pill: string }; width: { thin: string; medium: string; thick: string }; style: string } |
| elevation | { shadow: string; card: string; modal: string; hover: string } |
| branding | { logoSize: { small: string; medium: string; large: string }; letterSpacing: { tight: string; normal: string; wide: string; wider: string }; textTransform: { uppercase: string; lowercase: string; capitalize: string; normal: string } } |
| layout | { maxWidth: string; contentWidth: string; sidebarWidth: string; headerHeight: string; footerHeight: string } |
Paleta
| Token | Light | Dark |
| --- | --- | --- |
| primary | #1e40af | #3b82f6 |
| secondary | #334155 | #64748b |
| background | #ffffff | #0f172a |
| text | #0f172a | #f1f5f9 |
| textMuted | #475569 | #94a3b8 |
| border | #e2e8f0 | #1e293b |
| success | #059669 | #10b981 |
| error | #dc2626 | #ef4444 |
| warning | #d97706 | #f59e0b |
Tipografia
| Propriedade | Valor |
| --- | --- |
| fontFamily | "Playfair Display", "Georgia", "Times New Roman", serif |
| fontSizes.small | 12px |
| fontSizes.medium | 14px |
| fontSizes.large | 16px |
| fontSizes.xlarge | 24px |
| fontWeights.normal | 400 |
| fontWeights.medium | 500 |
| fontWeights.bold | 700 |
Espaçamento
| Propriedade | Valor |
| --- | --- |
| xs | 4px |
| sm | 8px |
| md | 16px |
| lg | 24px |
| xl | 32px |
Extensões específicas
corporateColors
| Token | Valor |
| --- | --- |
| gold | #d4af37 |
| silver | #c0c0c0 |
| bronze | #cd7f32 |
| navy | #0a2540 |
| charcoal | #36454f |
| ivory | #fffff0 |
borderStyle
| Propriedade | Valor |
| --- | --- |
| radius.small | 2px |
| radius.medium | 4px |
| radius.large | 8px |
| radius.pill | 20px |
| width.thin | 1px |
| width.medium | 2px |
| width.thick | 3px |
| style | solid |
elevation
| Propriedade | Valor |
| --- | --- |
| shadow | 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04) |
| card | 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06) |
| modal | 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.02) |
| hover | 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05) |
branding
| Propriedade | Valor |
| --- | --- |
| logoSize.small | 32px |
| logoSize.medium | 48px |
| logoSize.large | 64px |
| letterSpacing.tight | -0.5px |
| letterSpacing.normal | 0px |
| letterSpacing.wide | 0.5px |
| letterSpacing.wider | 1px |
| textTransform.uppercase | uppercase |
| textTransform.lowercase | lowercase |
| textTransform.capitalize | capitalize |
| textTransform.normal | none |
layout
| Propriedade | Valor |
| --- | --- |
| maxWidth | 600px |
| contentWidth | 560px |
| sidebarWidth | 200px |
| headerHeight | 80px |
| footerHeight | 120px |
Leitura visual
- O cabeçalho recebe dourado corporativo,
uppercasee tracking mais largo. buildBodyadiciona borda lateral dourada e sombra de cartão.- O rodapé usa fonte menor,
letterSpacing.normale borda superior mais forte.
MinimalTheme
src/templates/themes/minimal.theme.ts
Tema orientado ao conteúdo, com menos elementos decorativos e maior respiro entre blocos. A superfície visual é reduzida ao essencial, com um sistema de layout e design próprio.
Propriedades
| Propriedade | Tipo |
| --- | --- |
| id | ThemeType.MINIMAL |
| name | string |
| light | IThemeColors |
| dark | IThemeColors |
| typography | ITypography |
| spacing | ISpacing |
| minimalColors | { white: string; black: string; gray100: string; gray200: string; gray300: string; gray400: string; gray500: string; gray600: string; gray700: string; gray800: string; gray900: string } |
| borderStyle | { radius: { none: string; small: string; medium: string; large: string; full: string }; width: { thin: string; medium: string }; style: string } |
| effects | { shadow: string; transition: string; opacity: { hover: string; disabled: string } } |
| layout | { maxWidth: string; contentWidth: string; spacingMultiplier: number; lineHeight: number; paragraphSpacing: string } |
| designSystem | { grid: { columns: number; gutter: string; margin: string }; breakpoints: { mobile: string; tablet: string; desktop: string }; zIndex: { base: number; overlay: number; modal: number } } |
Paleta
| Token | Light | Dark |
| --- | --- | --- |
| primary | #000000 | #ffffff |
| secondary | #404040 | #a3a3a3 |
| background | #ffffff | #000000 |
| text | #111111 | #ffffff |
| textMuted | #666666 | #737373 |
| border | #e5e5e5 | #262626 |
| success | #22c55e | #22c55e |
| error | #ef4444 | #ef4444 |
| warning | #f97316 | #f97316 |
Tipografia
| Propriedade | Valor |
| --- | --- |
| fontFamily | Inter, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif |
| fontSizes.small | 13px |
| fontSizes.medium | 15px |
| fontSizes.large | 17px |
| fontSizes.xlarge | 21px |
| fontWeights.normal | 400 |
| fontWeights.medium | 500 |
| fontWeights.bold | 600 |
Espaçamento
| Propriedade | Valor |
| --- | --- |
| xs | 8px |
| sm | 16px |
| md | 24px |
| lg | 32px |
| xl | 48px |
Extensões específicas
minimalColors
| Token | Valor |
| --- | --- |
| white | #ffffff |
| black | #000000 |
| gray100 | #f5f5f5 |
| gray200 | #e5e5e5 |
| gray300 | #d4d4d4 |
| gray400 | #a3a3a3 |
| gray500 | #737373 |
| gray600 | #525252 |
| gray700 | #404040 |
| gray800 | #262626 |
| gray900 | #171717 |
borderStyle
| Propriedade | Valor |
| --- | --- |
| radius.none | 0px |
| radius.small | 2px |
| radius.medium | 4px |
| radius.large | 8px |
| radius.full | 9999px |
| width.thin | 1px |
| width.medium | 2px |
| style | solid |
effects
| Propriedade | Valor |
| --- | --- |
| shadow | none |
| transition | all 0.2s ease |
| opacity.hover | 0.7 |
| opacity.disabled | 0.5 |
layout
| Propriedade | Valor |
| --- | --- |
| maxWidth | 640px |
| contentWidth | 560px |
| spacingMultiplier | 1.5 |
| lineHeight | 1.6 |
| paragraphSpacing | 1.5em |
designSystem
| Bloco | Propriedade | Valor |
| --- | --- | --- |
| grid | columns | 12 |
| grid | gutter | 20px |
| grid | margin | 20px |
| breakpoints | mobile | 480px |
| breakpoints | tablet | 768px |
| breakpoints | desktop | 1024px |
| zIndex | base | 1 |
| zIndex | overlay | 10 |
| zIndex | modal | 100 |
Leitura visual
buildBodycentraliza o conteúdo emcontentWidthe amplia o respiro lateral.buildajusta a largura máxima para640pxe remove bordas no contêiner final.- O sistema
designSystemformaliza grid, breakpoints e camadas visuais para uso do tema.
Referência rápida das decisões por tema
| Tema | Cabeçalho | Corpo | Botão | Rodapé |
| --- | --- | --- | --- | --- |
| SystemTheme | Borda simples e cores base | Texto e fundo do contrato padrão | Botão padrão | Links e textos padrão |
| MonokaiTheme | Borda técnica, sombra e transição | codeHighlight e borda lateral magenta | Borda magenta e glow | Borda superior destacada |
| ModernTheme | Blur e borda suave | Margem e raio moderados | Gradiente e sombra leve | Glassmorphism e radius |
| CorporateTheme | Dourado, uppercase e tracking | Borda lateral dourada e sombra de cartão | Letras em uppercase e hover com elevação | Borda superior dourada |
| MinimalTheme | Borda fina e peso tipográfico contido | Max width e layout centralizado | Botão contornado e sem preenchimento | Rodapé enxuto e espaçado |
Key Classes Reference
| Class | Responsibility |
| --- | --- |
| theme.interface.ts | Define o contrato comum ITheme e os tokens de cor, tipografia e espaçamento |
| system.theme.ts | Implementa o tema base com paleta neutra e tipografia do sistema |
| monokai.theme.ts | Implementa o tema técnico com realce de código e efeitos visuais |
| modern.theme.ts | Implementa o tema contemporâneo com gradientes, blur e animações |
| corporate.theme.ts | Implementa o tema corporativo com branding, dourado e layout executivo |
| minimal.theme.ts | Implementa o tema minimalista com layout enxuto e design system próprio |
| template-factory.ts | Registra e instancia os temas concretos por ThemeType |
| template-builder.ts | Aplica os tokens dos temas na construção final do HTML do email |
Primeiros passos e uso básico/Instalação, scripts de execução e artefatos publicados
Primeiros passos e uso básico
package.json, tsconfig.json, src/index.ts, dist/index.js, dist/index.d.ts
Visão geral
A biblioteca é publicada como um pacote TypeScript centrado em Node.js + SMTP/Nodemailer, com artefatos prontos para consumo em dist/. O objetivo prático do primeiro uso é simples: instalar as dependências, compilar o projeto e consumir o ponto de entrada publicado sem depender do código-fonte em src/.
O pacote declara next e nodemailer em peerDependencies, então o projeto que instala a biblioteca precisa resolver essas dependências por conta própria. Isso é relevante tanto para consumidores quanto para contribuidores, porque a saída compilada e os tipos publicados são o contrato real do pacote.
Arquitetura de publicação
flowchart TB
subgraph Repo [tzMail]
Pkg[package json]
TsConfig[tsconfig json]
SrcIndex[src index ts]
Build[build]
Dev[dev]
Start[start]
Test[test]
Lint[lint]
DistJS[dist index js]
DistDTS[dist index d ts]
end
subgraph Consumer [Projeto consumidor]
App[Aplicação Node.js ou Next.js]
NextDep[next peer dependency]
NodemailerDep[nodemailer peer dependency]
end
Pkg --> Build
Pkg --> Dev
Pkg --> Start
Pkg --> Test
Pkg --> Lint
TsConfig --> Build
SrcIndex --> Build
Build --> DistJS
Build --> DistDTS
App --> DistJS
App --> DistDTS
App --> NextDep
App --> NodemailerDepInstalação
npm install tzmailGerenciamento de Templates/Catálogo de temas e seleção por metadados
Gerenciamento de Templates - Catálogo de temas e seleção por metadados
Visão geral
Esta parte do projeto concentra o registro dos temas visuais disponíveis e a descoberta guiada por metadados para que a escolha do template seja feita antes da renderização. O fluxo começa em TemplateFactory, que mantém o catálogo concreto de temas, e continua em TemplateService, que expõe uma visão pronta para consumo com nome amigável, descrição, recursos, variantes suportadas e configuração padrão por tema.
Na prática, esse catálogo permite que a aplicação apresente opções visuais coerentes ao usuário, sem exigir que ele conheça os detalhes internos de cada tema. O resultado é uma seleção mais previsível de ThemeType, variant e ITemplateConfig, com defaults específicos que orientam a composição correta do email.
Arquitetura do catálogo de temas
flowchart TB
subgraph DemoApp [Servidor de Demonstração]
Demo[src index ts]
end
subgraph Catalog [Catálogo de Temas]
Service[TemplateService]
Factory[TemplateFactory]
Registry[Map ThemeType to ITheme]
SystemTheme[SystemTheme]
MonokaiTheme[MonokaiTheme]
ModernTheme[ModernTheme]
CorporateTheme[CorporateTheme]
MinimalTheme[MinimalTheme]
Builder[TemplateBuilder]
end
subgraph Metadata [Metadados para seleção]
ThemeInfo[getThemeInfo]
ThemeList[listThemes]
DefaultConfig[defaultConfig]
Variants[availableVariants]
end
Demo -->|createTemplate| Service
Demo -->|getThemeInfo| Service
Demo -->|listThemes| Service
Service -->|delegates| Factory
Service -->|adds metadata| Metadata
Factory -->|resolves| Registry
Registry --> SystemTheme
Registry --> MonokaiTheme
Registry --> ModernTheme
Registry --> CorporateTheme
Registry --> MinimalTheme
Factory -->|builds template| Builder
Factory --> ThemeInfo
Factory --> ThemeList
Service --> DefaultConfig
Service --> VariantsComponentes principais
TemplateFactory
src/factories/template-factory.ts
TemplateFactory é o registro estático do catálogo de temas. Ela associa cada ThemeType a uma instância concreta de ITheme, resolve o tema solicitado, lista os temas cadastrados e produz o objeto de template usado pelo restante do fluxo.
Propriedades
| Propriedade | Tipo | Descrição |
| --- | --- | --- |
| themes | Map<ThemeType, ITheme> | Catálogo estático com SystemTheme, MonokaiTheme, ModernTheme, CorporateTheme e MinimalTheme. |
Métodos públicos
| Método | Descrição |
| --- | --- |
| createTemplate | Resolve o tema pelo ThemeType, valida a existência no catálogo e retorna um ITemplate com name, theme, variant, config e render. |
| getTheme | Retorna a instância concreta de ITheme associada ao ThemeType solicitado. |
| listThemes | Retorna a lista de ThemeType atualmente registrados no catálogo. |
| getThemeInfo | Retorna metadados estáticos do tema: name, description e features. |
Registro de temas
A ordem de listThemes() segue a ordem de inserção do Map:
systemmonokaimoderncorporateminimal
Como o template é montado
`createTempl
