@churnkey/dunning-render
v0.1.7
Published
Shared rendering logic for dunning/reactivation emails: merge fields, CTA, design resolution, custom HTML sanitization
Keywords
Readme
@churnkey/dunning-render
Shared rendering logic for dunning and reactivation emails: merge-field substitution, CTA resolution, design (colors/fonts) resolution, and custom HTML sanitization. Single source of truth consumed by apps/web, churnkey-api, and churnkey-dunning so previews and real sends can never drift.
Plain CommonJS, no build step.
Install
npm install @churnkey/dunning-renderEntry points
@churnkey/dunning-render— browser-safe: constants and pure transforms. Never pulls insanitize-html.@churnkey/dunning-render/server— everything above plussanitizeCustomHtml. Server-only.
API
Constants
CTA_MODE/CTA_MODE_LIST—AUTO(CTA rendered at the[[...]]marker, or auto-appended) |HIDDENFONT_FAMILY/FONT_FAMILY_LIST/FONT_STACKS— curated web-safe font list with email-client-safe CSS stacks (remote/Google fonts were dropped in 0.1.2 — Gmail and Outlook strip them)DEFAULT_COLORS,EMAIL_MERGE_FIELDS,RECOVERY_LINK,CTA_MARKER_REGEX,EMPTY_CTA_MARKER_REGEX
Functions
composeEmail(options)— main orchestrator. Substitutes merge fields, resolves the CTA, and picks the render path:TEMPLATE(content fragment for a Postmark template) orCUSTOM_HTML(full self-contained document). Returns{ renderPath, content, fullHtml, subject, previewText, meta }. Pure — callers buildvaluesMapthemselves.resolveEffectiveDesign(orgDesign, sequenceDesign)— org default ⊕ sequence override merge.resolveDesignTemplateVars(design)— PostmarkTemplateModelvariables (design_background,design_body_text,design_link,design_cta_text,design_font_family,design_font_import) for the shared template shells.substituteMergeFields(content, valuesMap)—{{ KEY }}and{{ KEY | fallback }}substitution.resolveCta(content, options)— replaces[[...]]markers with the CTA button (or strips them when hidden).sanitizeCustomHtml(html)(server only) — allowlist-based sanitization of customer-supplied HTML. Strips all script surface; keeps email-safe layout markup.
Full signatures in index.d.ts.
Development
npm test # node --test, no build neededReleasing
Publishing is manual (this package is not in the monorepo's nx release scope). Follow the
release runbook:
changelog + version bump → npm test → commit → npm publish → tag → bump the range in
churnkey-api/churnkey-dunning (apps/web uses workspace:*, nothing to do).
Lives in the Churnkey monorepo at packages/dunning-render. Keep exports as plain shorthand properties in index.js/server.js — Node's cjs-module-lexer needs that shape to expose named exports to ESM import.
