From dba3733dd204270162b7c23247a3b8f7d63d424b Mon Sep 17 00:00:00 2001 From: Nariman Jelveh Date: Wed, 19 Aug 2026 18:25:06 -0700 Subject: [PATCH] fix: widen the template map to the interface before compiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Object.entries` over the literal map yields a union with a distinct type per template, and only the share digests carry a `text` part — reading it off the union is an error the build tsconfig hides (`noCheck: true`) and `npm run typecheck` catches. --- src/backend/clients/email/EmailClient.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/backend/clients/email/EmailClient.ts b/src/backend/clients/email/EmailClient.ts index 74d3887f9..c6e6a0e3e 100644 --- a/src/backend/clients/email/EmailClient.ts +++ b/src/backend/clients/email/EmailClient.ts @@ -22,7 +22,11 @@ import handlebars, { template } from 'handlebars'; import nodemailer from 'nodemailer'; import type { IConfig } from '../../types'; import { PuterClient } from '../types'; -import { EMAIL_TEMPLATES, type EmailTemplateName } from './templates'; +import { + EMAIL_TEMPLATES, + type EmailTemplate, + type EmailTemplateName, +} from './templates'; /** Attachment shape passed through to the underlying transport. */ export interface EmailAttachment { @@ -287,7 +291,11 @@ export class EmailClient extends PuterClient { } private compileTemplates(): void { - for (const [name, template] of Object.entries(EMAIL_TEMPLATES)) { + // Widened to the interface: the literal map keeps a distinct type per + // template, and only some of them carry a `text` part. + const templates: Record = + EMAIL_TEMPLATES; + for (const [name, template] of Object.entries(templates)) { this.compiledTemplates[name as EmailTemplateName] = { // Subjects are plain-text headers: HTML-escaping would put // literal entities in front of the recipient (& etc.).