@rovela-ai/sdk 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/api/emails.d.ts +17 -0
- package/dist/admin/api/emails.d.ts.map +1 -0
- package/dist/admin/api/emails.js +214 -0
- package/dist/admin/api/emails.js.map +1 -0
- package/dist/admin/components/AdminNav.d.ts.map +1 -1
- package/dist/admin/components/AdminNav.js +1 -0
- package/dist/admin/components/AdminNav.js.map +1 -1
- package/dist/admin/components/EmailsManager.d.ts +5 -0
- package/dist/admin/components/EmailsManager.d.ts.map +1 -0
- package/dist/admin/components/EmailsManager.js +306 -0
- package/dist/admin/components/EmailsManager.js.map +1 -0
- package/dist/admin/components/index.d.ts +2 -0
- package/dist/admin/components/index.d.ts.map +1 -1
- package/dist/admin/components/index.js +1 -0
- package/dist/admin/components/index.js.map +1 -1
- package/dist/admin/index.d.ts +1 -1
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/core/db/queries.d.ts +26 -3
- package/dist/core/db/queries.d.ts.map +1 -1
- package/dist/core/db/queries.js +124 -0
- package/dist/core/db/queries.js.map +1 -1
- package/dist/core/db/schema.d.ts +173 -1
- package/dist/core/db/schema.d.ts.map +1 -1
- package/dist/core/db/schema.js +22 -0
- package/dist/core/db/schema.js.map +1 -1
- package/dist/core/i18n/LanguageSwitcher.d.ts.map +1 -1
- package/dist/core/i18n/LanguageSwitcher.js +8 -2
- package/dist/core/i18n/LanguageSwitcher.js.map +1 -1
- package/dist/core/i18n/LocaleLink.d.ts.map +1 -1
- package/dist/core/i18n/LocaleLink.js +6 -2
- package/dist/core/i18n/LocaleLink.js.map +1 -1
- package/dist/core/i18n/context.d.ts +19 -1
- package/dist/core/i18n/context.d.ts.map +1 -1
- package/dist/core/i18n/context.js +15 -2
- package/dist/core/i18n/context.js.map +1 -1
- package/dist/emails/config.d.ts.map +1 -1
- package/dist/emails/config.js +5 -0
- package/dist/emails/config.js.map +1 -1
- package/dist/emails/index.d.ts +6 -0
- package/dist/emails/index.d.ts.map +1 -1
- package/dist/emails/index.js +4 -0
- package/dist/emails/index.js.map +1 -1
- package/dist/emails/overrides.d.ts +40 -0
- package/dist/emails/overrides.d.ts.map +1 -0
- package/dist/emails/overrides.js +70 -0
- package/dist/emails/overrides.js.map +1 -0
- package/dist/emails/registry.d.ts +40 -0
- package/dist/emails/registry.d.ts.map +1 -0
- package/dist/emails/registry.js +270 -0
- package/dist/emails/registry.js.map +1 -0
- package/dist/emails/send/auth.d.ts.map +1 -1
- package/dist/emails/send/auth.js +38 -3
- package/dist/emails/send/auth.js.map +1 -1
- package/dist/emails/send/orders.d.ts.map +1 -1
- package/dist/emails/send/orders.js +86 -6
- package/dist/emails/send/orders.js.map +1 -1
- package/dist/emails/templates/base.d.ts +30 -12
- package/dist/emails/templates/base.d.ts.map +1 -1
- package/dist/emails/templates/base.js +51 -8
- package/dist/emails/templates/base.js.map +1 -1
- package/dist/emails/theme.d.ts +65 -0
- package/dist/emails/theme.d.ts.map +1 -0
- package/dist/emails/theme.js +173 -0
- package/dist/emails/theme.js.map +1 -0
- package/dist/emails/types.d.ts +2 -0
- package/dist/emails/types.d.ts.map +1 -1
- package/package.json +5 -1
package/dist/emails/config.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { Resend } from 'resend';
|
|
11
11
|
import { findSettings } from '../core/db';
|
|
12
|
+
import { applyEmailTheme } from './theme';
|
|
12
13
|
// =============================================================================
|
|
13
14
|
// Resend Client
|
|
14
15
|
// =============================================================================
|
|
@@ -104,10 +105,14 @@ export async function getLogoUrl() {
|
|
|
104
105
|
* Assembles config from database and environment variables.
|
|
105
106
|
*/
|
|
106
107
|
export async function getEmailConfig() {
|
|
108
|
+
// Phase D: resolve + apply the store's email theme (brand-derived by
|
|
109
|
+
// default) onto the shared STYLES before any template renders. Every
|
|
110
|
+
// sender calls getEmailConfig, so this is the single theming chokepoint.
|
|
107
111
|
const [storeName, supportEmail, logoUrl] = await Promise.all([
|
|
108
112
|
getStoreName(),
|
|
109
113
|
getSupportEmail(),
|
|
110
114
|
getLogoUrl(),
|
|
115
|
+
applyEmailTheme(),
|
|
111
116
|
]);
|
|
112
117
|
return {
|
|
113
118
|
logoUrl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/emails/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,IAAI,YAAY,GAAkB,IAAI,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;QAEzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,kDAAkD;gBAChD,iDAAiD;gBACjD,uBAAuB,CAC1B,CAAA;QACH,CAAC;QAED,YAAY,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAA;IACnC,CAAC;IAED,OAAO,YAAY,CAAA;AACrB,CAAC;AAED,gFAAgF;AAChF,wEAAwE;AACxE,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,qBAAqB,CAAA;IACpE,MAAM,SAAS,GAAG,MAAM,YAAY,EAAE,CAAA;IAEtC,OAAO,GAAG,SAAS,KAAK,KAAK,GAAG,CAAA;AAClC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,uDAAuD;IACvD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAA;QACrC,IAAI,QAAQ,EAAE,SAAS,EAAE,CAAC;YACxB,OAAO,QAAQ,CAAC,SAAS,CAAA;QAC3B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;IAED,oCAAoC;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,WAAW,CAAA;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAA;AAC1E,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,uDAAuD;IACvD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAA;QACrC,IAAI,QAAQ,EAAE,OAAO,EAAE,CAAC;YACtB,OAAO,QAAQ,CAAC,OAAO,CAAA;QACzB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;IAED,oCAAoC;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAA;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC3D,YAAY,EAAE;QACd,eAAe,EAAE;QACjB,UAAU,EAAE;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/emails/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAEzC,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,IAAI,YAAY,GAAkB,IAAI,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;QAEzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,kDAAkD;gBAChD,iDAAiD;gBACjD,uBAAuB,CAC1B,CAAA;QACH,CAAC;QAED,YAAY,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAA;IACnC,CAAC;IAED,OAAO,YAAY,CAAA;AACrB,CAAC;AAED,gFAAgF;AAChF,wEAAwE;AACxE,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,qBAAqB,CAAA;IACpE,MAAM,SAAS,GAAG,MAAM,YAAY,EAAE,CAAA;IAEtC,OAAO,GAAG,SAAS,KAAK,KAAK,GAAG,CAAA;AAClC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,uDAAuD;IACvD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAA;QACrC,IAAI,QAAQ,EAAE,SAAS,EAAE,CAAC;YACxB,OAAO,QAAQ,CAAC,SAAS,CAAA;QAC3B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;IAED,oCAAoC;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,WAAW,CAAA;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAA;AAC1E,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,uDAAuD;IACvD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAA;QACrC,IAAI,QAAQ,EAAE,OAAO,EAAE,CAAC;YACtB,OAAO,QAAQ,CAAC,OAAO,CAAA;QACzB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;IAED,oCAAoC;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAA;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,qEAAqE;IACrE,qEAAqE;IACrE,yEAAyE;IACzE,MAAM,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC3D,YAAY,EAAE;QACd,eAAe,EAAE;QACjB,UAAU,EAAE;QACZ,eAAe,EAAE;KAClB,CAAC,CAAA;IAEF,OAAO;QACL,OAAO;QACP,SAAS;QACT,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE;QAC7C,YAAY;QACZ,OAAO,EAAE,WAAW,EAAE;KACvB,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,uDAAuD;IACvD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAA;QACrC,IAAI,QAAQ,EAAE,UAAU,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC,UAAU,CAAA;QAC5B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;IAED,qCAAqC;IACrC,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,aAAa;QACzB,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,qBAAqB,CACtB,CAAA;AACH,CAAC"}
|
package/dist/emails/index.d.ts
CHANGED
|
@@ -78,6 +78,12 @@
|
|
|
78
78
|
export type { EmailConfig, SendEmailOptions, SendEmailResult, EmailAddress, EmailOrderItem, EmailVerificationData, WelcomeEmailData, PasswordResetEmailData, OrderConfirmationData, OrderShippedData, OrderDeliveredData, OrderCancelledData, RefundProcessedData, EmailTemplateType, EmailData, } from './types';
|
|
79
79
|
export { getResend, getFromEmail, getStoreName, getStoreUrl, getEmailConfig, getSupportEmail, } from './config';
|
|
80
80
|
export { sendEmail, sendEmailAsync, sendEmailBatch } from './sender';
|
|
81
|
+
export { EMAIL_FONTS, deriveBrandEmailTheme, sanitizeEmailTheme, resolveEmailTheme, invalidateEmailTheme, applyEmailTheme, } from './theme';
|
|
82
|
+
export type { EmailTheme, EmailButtonRadius } from './theme';
|
|
83
|
+
export { EMAIL_REGISTRY, getEmailRegistryEntry } from './registry';
|
|
84
|
+
export type { EmailRegistryEntry, EmailCategory } from './registry';
|
|
85
|
+
export { prepareEmail, applyEmailVars, DEFAULT_LOCALE_ROW } from './overrides';
|
|
86
|
+
export type { PreparedEmail } from './overrides';
|
|
81
87
|
export { formatDate, formatDateTime, formatPrice, formatAddressLine, formatAddressHtml, escapeHtml, emailButton, emailFooter, formatOrderNumber, } from './utils';
|
|
82
88
|
export { baseLayout, primaryButton, heading, paragraph, infoBox, linkFallback, detailBox, statusBadge, highlightBox, secondaryButton, addressSection, sectionHeading, STYLES, renderEmailVerification, getEmailVerificationSubject, renderWelcomeEmail, getWelcomeEmailSubject, renderPasswordResetEmail, getPasswordResetSubject, renderOrderConfirmation, getOrderConfirmationSubject, renderOrderShipped, getOrderShippedSubject, renderOrderDelivered, getOrderDeliveredSubject, renderOrderCancelled, getOrderCancelledSubject, renderRefundProcessed, getRefundProcessedSubject, } from './templates';
|
|
83
89
|
export { sendVerificationEmail, sendVerificationEmailAsync, sendWelcomeEmail, sendWelcomeEmailAsync, sendPasswordResetEmail, sendPasswordResetEmailAsync, sendAdminPasswordResetEmail, sendAdminPasswordResetEmailAsync, sendAdminInviteEmail, sendAdminInviteEmailAsync, sendOrderConfirmation, sendOrderConfirmationAsync, sendOrderShipped, sendOrderShippedAsync, sendOrderReadyForPickup, sendOrderReadyForPickupAsync, sendOrderDelivered, sendOrderDeliveredAsync, sendOrderCancelled, sendOrderCancelledAsync, sendRefundProcessed, sendRefundProcessedAsync, } from './send';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emails/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AAMH,YAAY,EAEV,WAAW,EACX,gBAAgB,EAChB,eAAe,EAEf,YAAY,EACZ,cAAc,EAEd,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EAEtB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EAEnB,iBAAiB,EACjB,SAAS,GACV,MAAM,SAAS,CAAA;AAMhB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,eAAe,GAChB,MAAM,UAAU,CAAA;AAMjB,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emails/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AAMH,YAAY,EAEV,WAAW,EACX,gBAAgB,EAChB,eAAe,EAEf,YAAY,EACZ,cAAc,EAEd,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EAEtB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EAEnB,iBAAiB,EACjB,SAAS,GACV,MAAM,SAAS,CAAA;AAMhB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,eAAe,GAChB,MAAM,UAAU,CAAA;AAMjB,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAGpE,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,GAChB,MAAM,SAAS,CAAA;AAChB,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAClE,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAC9E,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAMhD,OAAO,EACL,UAAU,EACV,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,SAAS,CAAA;AAMhB,OAAO,EAEL,UAAU,EACV,aAAa,EACb,OAAO,EACP,SAAS,EACT,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,MAAM,EAEN,uBAAuB,EACvB,2BAA2B,EAC3B,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,EAEvB,uBAAuB,EACvB,2BAA2B,EAC3B,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,aAAa,CAAA;AAMpB,OAAO,EAEL,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,EAE3B,2BAA2B,EAC3B,gCAAgC,EAChC,oBAAoB,EACpB,yBAAyB,EAEzB,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,4BAA4B,EAC5B,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,QAAQ,CAAA;AAGf,YAAY,EACV,2BAA2B,EAC3B,sBAAsB,EACtB,4BAA4B,EAC5B,iCAAiC,EACjC,0BAA0B,EAC1B,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,QAAQ,CAAA"}
|
package/dist/emails/index.js
CHANGED
|
@@ -83,6 +83,10 @@ export { getResend, getFromEmail, getStoreName, getStoreUrl, getEmailConfig, get
|
|
|
83
83
|
// Core Sender
|
|
84
84
|
// =============================================================================
|
|
85
85
|
export { sendEmail, sendEmailAsync, sendEmailBatch } from './sender';
|
|
86
|
+
// Phase D — emails module (shared theme, registry, per-email overrides)
|
|
87
|
+
export { EMAIL_FONTS, deriveBrandEmailTheme, sanitizeEmailTheme, resolveEmailTheme, invalidateEmailTheme, applyEmailTheme, } from './theme';
|
|
88
|
+
export { EMAIL_REGISTRY, getEmailRegistryEntry } from './registry';
|
|
89
|
+
export { prepareEmail, applyEmailVars, DEFAULT_LOCALE_ROW } from './overrides';
|
|
86
90
|
// =============================================================================
|
|
87
91
|
// Utilities
|
|
88
92
|
// =============================================================================
|
package/dist/emails/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/emails/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AA6BH,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,OAAO,EACL,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,eAAe,GAChB,MAAM,UAAU,CAAA;AAEjB,gFAAgF;AAChF,cAAc;AACd,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAEpE,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,OAAO,EACL,UAAU,EACV,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,SAAS,CAAA;AAEhB,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAEhF,OAAO;AACL,kBAAkB;AAClB,UAAU,EACV,aAAa,EACb,OAAO,EACP,SAAS,EACT,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,MAAM;AACN,iBAAiB;AACjB,uBAAuB,EACvB,2BAA2B,EAC3B,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB;AACvB,kBAAkB;AAClB,uBAAuB,EACvB,2BAA2B,EAC3B,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,aAAa,CAAA;AAEpB,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAEhF,OAAO;AACL,yBAAyB;AACzB,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B;AAC3B,oBAAoB;AACpB,2BAA2B,EAC3B,gCAAgC,EAChC,oBAAoB,EACpB,yBAAyB;AACzB,eAAe;AACf,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,4BAA4B,EAC5B,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,QAAQ,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/emails/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AA6BH,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,OAAO,EACL,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,eAAe,GAChB,MAAM,UAAU,CAAA;AAEjB,gFAAgF;AAChF,cAAc;AACd,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAEpE,wEAAwE;AACxE,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,GAChB,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAElE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAG9E,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,OAAO,EACL,UAAU,EACV,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,SAAS,CAAA;AAEhB,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAEhF,OAAO;AACL,kBAAkB;AAClB,UAAU,EACV,aAAa,EACb,OAAO,EACP,SAAS,EACT,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,MAAM;AACN,iBAAiB;AACjB,uBAAuB,EACvB,2BAA2B,EAC3B,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB;AACvB,kBAAkB;AAClB,uBAAuB,EACvB,2BAA2B,EAC3B,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,aAAa,CAAA;AAEpB,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAEhF,OAAO;AACL,yBAAyB;AACzB,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B;AAC3B,oBAAoB;AACpB,2BAA2B,EAC3B,gCAAgC,EAChC,oBAAoB,EACpB,yBAAyB;AACzB,eAAe;AACf,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,4BAA4B,EAC5B,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,QAAQ,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rovela/sdk/emails/overrides
|
|
3
|
+
*
|
|
4
|
+
* Per-email merchant customization at the send boundary (Phase D).
|
|
5
|
+
*
|
|
6
|
+
* The merchant edits three text slots per email (+ an on/off switch where
|
|
7
|
+
* safe) in /admin/emails; rows live in store_emails keyed (email_key,
|
|
8
|
+
* locale). `prepareEmail()` is the ONE call a sender makes before
|
|
9
|
+
* rendering:
|
|
10
|
+
*
|
|
11
|
+
* - resolves the override row for the send's locale (exact locale row →
|
|
12
|
+
* '_default' row → nothing),
|
|
13
|
+
* - stages the intro/outro blocks for the next baseLayout render
|
|
14
|
+
* (single-use module state — see templates/base.ts),
|
|
15
|
+
* - returns the subject override (with {{variable}} slots still raw; the
|
|
16
|
+
* sender interpolates via applyEmailVars) and the enabled flag.
|
|
17
|
+
*
|
|
18
|
+
* FAIL-OPEN CONTRACT: prepareEmail never throws; any failure returns the
|
|
19
|
+
* no-override shape and the shipped template renders byte-identical.
|
|
20
|
+
*/
|
|
21
|
+
/** The store-default-language row key in store_emails. */
|
|
22
|
+
export declare const DEFAULT_LOCALE_ROW = "_default";
|
|
23
|
+
export interface PreparedEmail {
|
|
24
|
+
/** false ONLY when the merchant disabled a disableable email. */
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
/** Subject override with raw {{slots}}, or null → use the template default. */
|
|
27
|
+
subjectOverride: string | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolve overrides for one email send. Also stages intro/outro for the
|
|
31
|
+
* upcoming render. `canDisable` mirrors the registry — non-disableable
|
|
32
|
+
* emails ignore a stray enabled=false row (defense in depth).
|
|
33
|
+
*/
|
|
34
|
+
export declare function prepareEmail(emailKey: string, locale: string | null | undefined, canDisable: boolean): Promise<PreparedEmail>;
|
|
35
|
+
/**
|
|
36
|
+
* Replace {{name}} slots in merchant-authored subjects. Unknown slots are
|
|
37
|
+
* left verbatim (loud + greppable, same contract as the i18n translator).
|
|
38
|
+
*/
|
|
39
|
+
export declare function applyEmailVars(template: string, vars: Record<string, string | undefined>): string;
|
|
40
|
+
//# sourceMappingURL=overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../src/emails/overrides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,0DAA0D;AAC1D,eAAO,MAAM,kBAAkB,aAAa,CAAA;AAE5C,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,+EAA+E;IAC/E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAaD;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,UAAU,EAAE,OAAO,GAClB,OAAO,CAAC,aAAa,CAAC,CAmBxB;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACvC,MAAM,CAKR"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rovela/sdk/emails/overrides
|
|
3
|
+
*
|
|
4
|
+
* Per-email merchant customization at the send boundary (Phase D).
|
|
5
|
+
*
|
|
6
|
+
* The merchant edits three text slots per email (+ an on/off switch where
|
|
7
|
+
* safe) in /admin/emails; rows live in store_emails keyed (email_key,
|
|
8
|
+
* locale). `prepareEmail()` is the ONE call a sender makes before
|
|
9
|
+
* rendering:
|
|
10
|
+
*
|
|
11
|
+
* - resolves the override row for the send's locale (exact locale row →
|
|
12
|
+
* '_default' row → nothing),
|
|
13
|
+
* - stages the intro/outro blocks for the next baseLayout render
|
|
14
|
+
* (single-use module state — see templates/base.ts),
|
|
15
|
+
* - returns the subject override (with {{variable}} slots still raw; the
|
|
16
|
+
* sender interpolates via applyEmailVars) and the enabled flag.
|
|
17
|
+
*
|
|
18
|
+
* FAIL-OPEN CONTRACT: prepareEmail never throws; any failure returns the
|
|
19
|
+
* no-override shape and the shipped template renders byte-identical.
|
|
20
|
+
*/
|
|
21
|
+
import { getEmailOverridesCached } from '../core/db/queries';
|
|
22
|
+
import { setEmailCustomBlocks } from './templates/base';
|
|
23
|
+
/** The store-default-language row key in store_emails. */
|
|
24
|
+
export const DEFAULT_LOCALE_ROW = '_default';
|
|
25
|
+
const NO_OVERRIDE = { enabled: true, subjectOverride: null };
|
|
26
|
+
function pickRow(rows, locale) {
|
|
27
|
+
const defaultRow = rows.find((r) => r.locale === DEFAULT_LOCALE_ROW) ?? null;
|
|
28
|
+
const localeRow = locale ? (rows.find((r) => r.locale === locale) ?? null) : null;
|
|
29
|
+
return { textRow: localeRow ?? defaultRow, defaultRow };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve overrides for one email send. Also stages intro/outro for the
|
|
33
|
+
* upcoming render. `canDisable` mirrors the registry — non-disableable
|
|
34
|
+
* emails ignore a stray enabled=false row (defense in depth).
|
|
35
|
+
*/
|
|
36
|
+
export async function prepareEmail(emailKey, locale, canDisable) {
|
|
37
|
+
try {
|
|
38
|
+
const rows = await getEmailOverridesCached(emailKey);
|
|
39
|
+
if (rows.length === 0) {
|
|
40
|
+
setEmailCustomBlocks(null, null);
|
|
41
|
+
return NO_OVERRIDE;
|
|
42
|
+
}
|
|
43
|
+
const { textRow, defaultRow } = pickRow(rows, locale);
|
|
44
|
+
// The on/off switch lives on the '_default' row (one switch per email).
|
|
45
|
+
const enabled = canDisable ? (defaultRow?.enabled ?? true) : true;
|
|
46
|
+
setEmailCustomBlocks(textRow?.intro?.trim() || null, textRow?.outro?.trim() || null);
|
|
47
|
+
return {
|
|
48
|
+
enabled,
|
|
49
|
+
subjectOverride: textRow?.subject?.trim() || null,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
setEmailCustomBlocks(null, null);
|
|
54
|
+
return NO_OVERRIDE;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// =============================================================================
|
|
58
|
+
// {{variable}} interpolation (subjects)
|
|
59
|
+
// =============================================================================
|
|
60
|
+
/**
|
|
61
|
+
* Replace {{name}} slots in merchant-authored subjects. Unknown slots are
|
|
62
|
+
* left verbatim (loud + greppable, same contract as the i18n translator).
|
|
63
|
+
*/
|
|
64
|
+
export function applyEmailVars(template, vars) {
|
|
65
|
+
return template.replace(/\{\{\s*(\w+)\s*\}\}/g, (match, name) => {
|
|
66
|
+
const value = vars[name];
|
|
67
|
+
return value !== undefined ? value : match;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=overrides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overrides.js","sourceRoot":"","sources":["../../src/emails/overrides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,uBAAuB,EAA2B,MAAM,oBAAoB,CAAA;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAEvD,0DAA0D;AAC1D,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAA;AAS5C,MAAM,WAAW,GAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAA;AAE3E,SAAS,OAAO,CACd,IAA0B,EAC1B,MAAiC;IAEjC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,kBAAkB,CAAC,IAAI,IAAI,CAAA;IAC5E,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACjF,OAAO,EAAE,OAAO,EAAE,SAAS,IAAI,UAAU,EAAE,UAAU,EAAE,CAAA;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,MAAiC,EACjC,UAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,uBAAuB,CAAC,QAAQ,CAAC,CAAA;QACpD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAChC,OAAO,WAAW,CAAA;QACpB,CAAC;QACD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACrD,wEAAwE;QACxE,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACjE,oBAAoB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,CAAA;QACpF,OAAO;YACL,OAAO;YACP,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI;SAClD,CAAA;IACH,CAAC;IAAC,MAAM,CAAC;QACP,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAChC,OAAO,WAAW,CAAA;IACpB,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,wCAAwC;AACxC,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAgB,EAChB,IAAwC;IAExC,OAAO,QAAQ,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;QACtE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;QACxB,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;IAC5C,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rovela/sdk/emails/registry
|
|
3
|
+
*
|
|
4
|
+
* The typed registry of every transactional email the store sends (Phase
|
|
5
|
+
* D). This single object powers the whole /admin/emails surface: the list
|
|
6
|
+
* page (name, trigger, category), the HTML previews (renderSample calls the
|
|
7
|
+
* REAL template with realistic demo data), the test sends, and the
|
|
8
|
+
* per-email variable chips for subject editing.
|
|
9
|
+
*
|
|
10
|
+
* No registry entry, no store_emails row, no saved theme = the emails ship
|
|
11
|
+
* byte-identical to today.
|
|
12
|
+
*/
|
|
13
|
+
import type { EmailConfig, EmailTemplateType } from './types';
|
|
14
|
+
export type EmailCategory = 'orders' | 'account';
|
|
15
|
+
export interface EmailRegistryEntry {
|
|
16
|
+
key: EmailTemplateType;
|
|
17
|
+
/** Merchant-facing name ("Order confirmation"). */
|
|
18
|
+
name: string;
|
|
19
|
+
category: EmailCategory;
|
|
20
|
+
/** One human sentence: when this email goes out. */
|
|
21
|
+
trigger: string;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the merchant may switch this email off. Conservative: only
|
|
24
|
+
* nice-to-have emails are disableable — confirmations, shipping and auth
|
|
25
|
+
* emails always send.
|
|
26
|
+
*/
|
|
27
|
+
canDisable: boolean;
|
|
28
|
+
/** {{variable}} slots available in a custom subject. */
|
|
29
|
+
variables: string[];
|
|
30
|
+
/** Render the REAL template with realistic sample data. */
|
|
31
|
+
renderSample: (config: EmailConfig) => {
|
|
32
|
+
subject: string;
|
|
33
|
+
html: string;
|
|
34
|
+
};
|
|
35
|
+
/** Values for the sample's subject variables (preview interpolation). */
|
|
36
|
+
sampleVars: (config: EmailConfig) => Record<string, string>;
|
|
37
|
+
}
|
|
38
|
+
export declare const EMAIL_REGISTRY: EmailRegistryEntry[];
|
|
39
|
+
export declare function getEmailRegistryEntry(key: string): EmailRegistryEntry | undefined;
|
|
40
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/emails/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AA0B7D,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAA;AAEhD,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,iBAAiB,CAAA;IACtB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,aAAa,CAAA;IACvB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAA;IACnB,wDAAwD;IACxD,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,2DAA2D;IAC3D,YAAY,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACxE,yEAAyE;IACzE,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC5D;AA2BD,eAAO,MAAM,cAAc,EAAE,kBAAkB,EAyO9C,CAAA;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEjF"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rovela/sdk/emails/registry
|
|
3
|
+
*
|
|
4
|
+
* The typed registry of every transactional email the store sends (Phase
|
|
5
|
+
* D). This single object powers the whole /admin/emails surface: the list
|
|
6
|
+
* page (name, trigger, category), the HTML previews (renderSample calls the
|
|
7
|
+
* REAL template with realistic demo data), the test sends, and the
|
|
8
|
+
* per-email variable chips for subject editing.
|
|
9
|
+
*
|
|
10
|
+
* No registry entry, no store_emails row, no saved theme = the emails ship
|
|
11
|
+
* byte-identical to today.
|
|
12
|
+
*/
|
|
13
|
+
import { renderEmailVerification, getEmailVerificationSubject, renderWelcomeEmail, getWelcomeEmailSubject, renderPasswordResetEmail, getPasswordResetSubject, renderOrderConfirmation, getOrderConfirmationSubject, renderOrderShipped, getOrderShippedSubject, renderOrderReadyForPickup, getOrderReadyForPickupSubject, renderOrderDelivered, getOrderDeliveredSubject, renderOrderCancelled, getOrderCancelledSubject, renderRefundProcessed, getRefundProcessedSubject, } from './templates';
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// Sample data (realistic, shared across previews)
|
|
16
|
+
// =============================================================================
|
|
17
|
+
const SAMPLE_ADDRESS = {
|
|
18
|
+
name: 'Alex Martin',
|
|
19
|
+
line1: '12 Riverside Avenue',
|
|
20
|
+
line2: 'Apt 4B',
|
|
21
|
+
city: 'Springfield',
|
|
22
|
+
state: 'IL',
|
|
23
|
+
postalCode: '62701',
|
|
24
|
+
country: 'US',
|
|
25
|
+
};
|
|
26
|
+
const SAMPLE_ITEMS = [
|
|
27
|
+
{ name: 'Classic Ceramic Mug — Set of 2', quantity: 1, price: '$34.00' },
|
|
28
|
+
{ name: 'Organic Cotton Tote', quantity: 2, price: '$18.00' },
|
|
29
|
+
];
|
|
30
|
+
const SAMPLE_ORDER_NUMBER = 'A1B2C3D4';
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// Registry
|
|
33
|
+
// =============================================================================
|
|
34
|
+
export const EMAIL_REGISTRY = [
|
|
35
|
+
// ── Orders ────────────────────────────────────────────────────────────────
|
|
36
|
+
{
|
|
37
|
+
key: 'order-confirmation',
|
|
38
|
+
name: 'Order confirmation',
|
|
39
|
+
category: 'orders',
|
|
40
|
+
trigger: 'Sent to the customer the moment their order is placed.',
|
|
41
|
+
canDisable: false,
|
|
42
|
+
variables: ['storeName', 'orderNumber', 'customerName'],
|
|
43
|
+
renderSample: (config) => ({
|
|
44
|
+
subject: getOrderConfirmationSubject(config.storeName, SAMPLE_ORDER_NUMBER),
|
|
45
|
+
html: renderOrderConfirmation({
|
|
46
|
+
config,
|
|
47
|
+
customerName: 'Alex',
|
|
48
|
+
customerEmail: 'alex@example.com',
|
|
49
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
50
|
+
orderDate: 'March 12, 2026',
|
|
51
|
+
paymentStatus: 'Paid',
|
|
52
|
+
items: SAMPLE_ITEMS,
|
|
53
|
+
subtotal: '$70.00',
|
|
54
|
+
discount: '-$10.00',
|
|
55
|
+
discountCode: 'WELCOME10',
|
|
56
|
+
shippingCost: '$6.00',
|
|
57
|
+
tax: '$5.28',
|
|
58
|
+
total: '$71.28',
|
|
59
|
+
shippingAddress: SAMPLE_ADDRESS,
|
|
60
|
+
orderTrackingUrl: `${config.shopUrl}/account/orders`,
|
|
61
|
+
}),
|
|
62
|
+
}),
|
|
63
|
+
sampleVars: (config) => ({
|
|
64
|
+
storeName: config.storeName,
|
|
65
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
66
|
+
customerName: 'Alex',
|
|
67
|
+
}),
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
key: 'order-shipped',
|
|
71
|
+
name: 'Order shipped',
|
|
72
|
+
category: 'orders',
|
|
73
|
+
trigger: 'Sent when you mark an order as shipped (with tracking when available).',
|
|
74
|
+
canDisable: false,
|
|
75
|
+
variables: ['storeName', 'orderNumber', 'customerName'],
|
|
76
|
+
renderSample: (config) => ({
|
|
77
|
+
subject: getOrderShippedSubject(config.storeName, SAMPLE_ORDER_NUMBER),
|
|
78
|
+
html: renderOrderShipped({
|
|
79
|
+
config,
|
|
80
|
+
customerName: 'Alex',
|
|
81
|
+
customerEmail: 'alex@example.com',
|
|
82
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
83
|
+
trackingNumber: '1Z999AA10123456784',
|
|
84
|
+
carrierName: 'UPS',
|
|
85
|
+
estimatedDeliveryDate: 'March 16, 2026',
|
|
86
|
+
shippingAddress: SAMPLE_ADDRESS,
|
|
87
|
+
trackingUrl: 'https://www.ups.com/track?tracknum=1Z999AA10123456784',
|
|
88
|
+
}),
|
|
89
|
+
}),
|
|
90
|
+
sampleVars: (config) => ({
|
|
91
|
+
storeName: config.storeName,
|
|
92
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
93
|
+
customerName: 'Alex',
|
|
94
|
+
}),
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
key: 'order-ready-for-pickup',
|
|
98
|
+
name: 'Ready for pickup',
|
|
99
|
+
category: 'orders',
|
|
100
|
+
trigger: 'Sent on click & collect orders when you mark them ready to collect.',
|
|
101
|
+
canDisable: false,
|
|
102
|
+
variables: ['storeName', 'orderNumber', 'customerName'],
|
|
103
|
+
renderSample: (config) => ({
|
|
104
|
+
subject: getOrderReadyForPickupSubject(config.storeName, SAMPLE_ORDER_NUMBER),
|
|
105
|
+
html: renderOrderReadyForPickup({
|
|
106
|
+
config,
|
|
107
|
+
customerName: 'Alex',
|
|
108
|
+
customerEmail: 'alex@example.com',
|
|
109
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
110
|
+
locationName: 'Downtown Store',
|
|
111
|
+
pickupAddress: { ...SAMPLE_ADDRESS, name: 'Downtown Store', line2: undefined },
|
|
112
|
+
openingHoursLines: ['Mon–Fri 9:00–18:00', 'Sat 10:00–16:00'],
|
|
113
|
+
pickupInstructions: 'Come to the collection counter with your order number.',
|
|
114
|
+
locationPhone: '+1 (555) 010-0100',
|
|
115
|
+
orderUrl: `${config.shopUrl}/account/orders`,
|
|
116
|
+
}),
|
|
117
|
+
}),
|
|
118
|
+
sampleVars: (config) => ({
|
|
119
|
+
storeName: config.storeName,
|
|
120
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
121
|
+
customerName: 'Alex',
|
|
122
|
+
}),
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
key: 'order-delivered',
|
|
126
|
+
name: 'Order delivered',
|
|
127
|
+
category: 'orders',
|
|
128
|
+
trigger: 'Sent when you mark an order as delivered.',
|
|
129
|
+
canDisable: true,
|
|
130
|
+
variables: ['storeName', 'orderNumber', 'customerName'],
|
|
131
|
+
renderSample: (config) => ({
|
|
132
|
+
subject: getOrderDeliveredSubject(config.storeName, SAMPLE_ORDER_NUMBER),
|
|
133
|
+
html: renderOrderDelivered({
|
|
134
|
+
config,
|
|
135
|
+
customerName: 'Alex',
|
|
136
|
+
customerEmail: 'alex@example.com',
|
|
137
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
138
|
+
deliveryDate: 'March 16, 2026',
|
|
139
|
+
deliveryLocation: 'Front door',
|
|
140
|
+
returnCenterUrl: `${config.shopUrl}/account/orders`,
|
|
141
|
+
}),
|
|
142
|
+
}),
|
|
143
|
+
sampleVars: (config) => ({
|
|
144
|
+
storeName: config.storeName,
|
|
145
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
146
|
+
customerName: 'Alex',
|
|
147
|
+
}),
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
key: 'order-cancelled',
|
|
151
|
+
name: 'Order cancelled',
|
|
152
|
+
category: 'orders',
|
|
153
|
+
trigger: 'Sent when an order is cancelled.',
|
|
154
|
+
canDisable: false,
|
|
155
|
+
variables: ['storeName', 'orderNumber', 'customerName'],
|
|
156
|
+
renderSample: (config) => ({
|
|
157
|
+
subject: getOrderCancelledSubject(config.storeName, SAMPLE_ORDER_NUMBER),
|
|
158
|
+
html: renderOrderCancelled({
|
|
159
|
+
config,
|
|
160
|
+
customerName: 'Alex',
|
|
161
|
+
customerEmail: 'alex@example.com',
|
|
162
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
163
|
+
cancellationReason: 'Requested by the customer',
|
|
164
|
+
cancellationDate: 'March 13, 2026',
|
|
165
|
+
refundMessage: 'Your payment has been refunded to your original payment method.',
|
|
166
|
+
}),
|
|
167
|
+
}),
|
|
168
|
+
sampleVars: (config) => ({
|
|
169
|
+
storeName: config.storeName,
|
|
170
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
171
|
+
customerName: 'Alex',
|
|
172
|
+
}),
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
key: 'refund-processed',
|
|
176
|
+
name: 'Refund processed',
|
|
177
|
+
category: 'orders',
|
|
178
|
+
trigger: 'Sent when a refund is issued (full or from an approved return).',
|
|
179
|
+
canDisable: false,
|
|
180
|
+
variables: ['storeName', 'orderNumber', 'customerName'],
|
|
181
|
+
renderSample: (config) => ({
|
|
182
|
+
subject: getRefundProcessedSubject(config.storeName, SAMPLE_ORDER_NUMBER),
|
|
183
|
+
html: renderRefundProcessed({
|
|
184
|
+
config,
|
|
185
|
+
customerName: 'Alex',
|
|
186
|
+
customerEmail: 'alex@example.com',
|
|
187
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
188
|
+
refundAmount: '$71.28',
|
|
189
|
+
refundDate: 'March 14, 2026',
|
|
190
|
+
paymentMethod: 'Original payment method',
|
|
191
|
+
estimatedArrival: '5-10 business days',
|
|
192
|
+
businessDays: '5-10',
|
|
193
|
+
}),
|
|
194
|
+
}),
|
|
195
|
+
sampleVars: (config) => ({
|
|
196
|
+
storeName: config.storeName,
|
|
197
|
+
orderNumber: SAMPLE_ORDER_NUMBER,
|
|
198
|
+
customerName: 'Alex',
|
|
199
|
+
}),
|
|
200
|
+
},
|
|
201
|
+
// ── Account ───────────────────────────────────────────────────────────────
|
|
202
|
+
{
|
|
203
|
+
key: 'email-verification',
|
|
204
|
+
name: 'Email verification',
|
|
205
|
+
category: 'account',
|
|
206
|
+
trigger: 'Sent when a customer creates an account, to confirm their address.',
|
|
207
|
+
canDisable: false,
|
|
208
|
+
variables: ['storeName', 'customerName'],
|
|
209
|
+
renderSample: (config) => ({
|
|
210
|
+
subject: getEmailVerificationSubject(config.storeName),
|
|
211
|
+
html: renderEmailVerification({
|
|
212
|
+
config,
|
|
213
|
+
customerName: 'Alex',
|
|
214
|
+
customerEmail: 'alex@example.com',
|
|
215
|
+
verificationLink: `${config.shopUrl}/auth/verify-email?token=sample`,
|
|
216
|
+
expiryTime: '24',
|
|
217
|
+
}),
|
|
218
|
+
}),
|
|
219
|
+
sampleVars: (config) => ({
|
|
220
|
+
storeName: config.storeName,
|
|
221
|
+
customerName: 'Alex',
|
|
222
|
+
}),
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
key: 'welcome',
|
|
226
|
+
name: 'Welcome',
|
|
227
|
+
category: 'account',
|
|
228
|
+
trigger: 'Sent once, right after a customer verifies their email.',
|
|
229
|
+
canDisable: true,
|
|
230
|
+
variables: ['storeName', 'customerName'],
|
|
231
|
+
renderSample: (config) => ({
|
|
232
|
+
subject: getWelcomeEmailSubject(config.storeName),
|
|
233
|
+
html: renderWelcomeEmail({
|
|
234
|
+
config,
|
|
235
|
+
customerName: 'Alex',
|
|
236
|
+
customerEmail: 'alex@example.com',
|
|
237
|
+
createdDate: 'March 12, 2026',
|
|
238
|
+
}),
|
|
239
|
+
}),
|
|
240
|
+
sampleVars: (config) => ({
|
|
241
|
+
storeName: config.storeName,
|
|
242
|
+
customerName: 'Alex',
|
|
243
|
+
}),
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
key: 'password-reset',
|
|
247
|
+
name: 'Password reset',
|
|
248
|
+
category: 'account',
|
|
249
|
+
trigger: 'Sent when a customer asks to reset their password.',
|
|
250
|
+
canDisable: false,
|
|
251
|
+
variables: ['storeName', 'customerName'],
|
|
252
|
+
renderSample: (config) => ({
|
|
253
|
+
subject: getPasswordResetSubject(config.storeName),
|
|
254
|
+
html: renderPasswordResetEmail({
|
|
255
|
+
config,
|
|
256
|
+
customerName: 'Alex',
|
|
257
|
+
resetLink: `${config.shopUrl}/auth/reset-password?token=sample`,
|
|
258
|
+
expiryTime: '1',
|
|
259
|
+
}),
|
|
260
|
+
}),
|
|
261
|
+
sampleVars: (config) => ({
|
|
262
|
+
storeName: config.storeName,
|
|
263
|
+
customerName: 'Alex',
|
|
264
|
+
}),
|
|
265
|
+
},
|
|
266
|
+
];
|
|
267
|
+
export function getEmailRegistryEntry(key) {
|
|
268
|
+
return EMAIL_REGISTRY.find((e) => e.key === key);
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/emails/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/emails/send/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/emails/send/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAc/C,MAAM,WAAW,2BAA2B;IAC1C,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,4BAA4B;IAC5B,gBAAgB,EAAE,MAAM,CAAA;IACxB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,eAAe,CAAC,CAoC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,gDAAgD;IAChD,WAAW,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAmC1B;AAED,MAAM,WAAW,4BAA4B;IAC3C,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC,eAAe,CAAC,CAmC1B;AAMD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,2BAA2B,GAClC,IAAI,CAIN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAI1E;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,4BAA4B,GACnC,IAAI,CAIN"}
|
package/dist/emails/send/auth.js
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Send functions for authentication emails.
|
|
5
5
|
*/
|
|
6
6
|
import { sendEmail } from '../sender';
|
|
7
|
+
import { prepareEmail, applyEmailVars } from '../overrides';
|
|
8
|
+
import { getEmailRegistryEntry } from '../registry';
|
|
7
9
|
import { getEmailConfig, getStoreName } from '../config';
|
|
8
10
|
import { formatDate } from '../utils';
|
|
9
11
|
import { renderEmailVerification, getEmailVerificationSubject, renderWelcomeEmail, getWelcomeEmailSubject, renderPasswordResetEmail, getPasswordResetSubject, } from '../templates';
|
|
@@ -26,6 +28,12 @@ export async function sendVerificationEmail(params) {
|
|
|
26
28
|
getEmailConfig(),
|
|
27
29
|
getStoreName(),
|
|
28
30
|
]);
|
|
31
|
+
// Phase D — merchant customization (see send/orders.ts).
|
|
32
|
+
const prep = await prepareEmail('email-verification', params.locale, getEmailRegistryEntry('email-verification')?.canDisable ?? false);
|
|
33
|
+
if (!prep.enabled) {
|
|
34
|
+
console.log('[Email] email-verification disabled in admin — skipped for:', params.to);
|
|
35
|
+
return { success: true, skipped: true };
|
|
36
|
+
}
|
|
29
37
|
const html = renderEmailVerification({
|
|
30
38
|
config,
|
|
31
39
|
customerName: params.customerName,
|
|
@@ -36,7 +44,12 @@ export async function sendVerificationEmail(params) {
|
|
|
36
44
|
return sendEmail({
|
|
37
45
|
locale: params.locale,
|
|
38
46
|
to: params.to,
|
|
39
|
-
subject:
|
|
47
|
+
subject: prep.subjectOverride
|
|
48
|
+
? applyEmailVars(prep.subjectOverride, {
|
|
49
|
+
storeName,
|
|
50
|
+
customerName: params.customerName,
|
|
51
|
+
})
|
|
52
|
+
: getEmailVerificationSubject(storeName),
|
|
40
53
|
html,
|
|
41
54
|
});
|
|
42
55
|
}
|
|
@@ -58,6 +71,12 @@ export async function sendWelcomeEmail(params) {
|
|
|
58
71
|
getEmailConfig(),
|
|
59
72
|
getStoreName(),
|
|
60
73
|
]);
|
|
74
|
+
// Phase D — merchant customization (see send/orders.ts).
|
|
75
|
+
const prep = await prepareEmail('welcome', params.locale, getEmailRegistryEntry('welcome')?.canDisable ?? false);
|
|
76
|
+
if (!prep.enabled) {
|
|
77
|
+
console.log('[Email] welcome disabled in admin — skipped for:', params.to);
|
|
78
|
+
return { success: true, skipped: true };
|
|
79
|
+
}
|
|
61
80
|
const html = renderWelcomeEmail({
|
|
62
81
|
config,
|
|
63
82
|
customerName: params.customerName,
|
|
@@ -67,7 +86,12 @@ export async function sendWelcomeEmail(params) {
|
|
|
67
86
|
return sendEmail({
|
|
68
87
|
locale: params.locale,
|
|
69
88
|
to: params.to,
|
|
70
|
-
subject:
|
|
89
|
+
subject: prep.subjectOverride
|
|
90
|
+
? applyEmailVars(prep.subjectOverride, {
|
|
91
|
+
storeName,
|
|
92
|
+
customerName: params.customerName,
|
|
93
|
+
})
|
|
94
|
+
: getWelcomeEmailSubject(storeName),
|
|
71
95
|
html,
|
|
72
96
|
});
|
|
73
97
|
}
|
|
@@ -90,6 +114,12 @@ export async function sendPasswordResetEmail(params) {
|
|
|
90
114
|
getEmailConfig(),
|
|
91
115
|
getStoreName(),
|
|
92
116
|
]);
|
|
117
|
+
// Phase D — merchant customization (see send/orders.ts).
|
|
118
|
+
const prep = await prepareEmail('password-reset', params.locale, getEmailRegistryEntry('password-reset')?.canDisable ?? false);
|
|
119
|
+
if (!prep.enabled) {
|
|
120
|
+
console.log('[Email] password-reset disabled in admin — skipped for:', params.to);
|
|
121
|
+
return { success: true, skipped: true };
|
|
122
|
+
}
|
|
93
123
|
const html = renderPasswordResetEmail({
|
|
94
124
|
config,
|
|
95
125
|
customerName: params.customerName,
|
|
@@ -99,7 +129,12 @@ export async function sendPasswordResetEmail(params) {
|
|
|
99
129
|
return sendEmail({
|
|
100
130
|
locale: params.locale,
|
|
101
131
|
to: params.to,
|
|
102
|
-
subject:
|
|
132
|
+
subject: prep.subjectOverride
|
|
133
|
+
? applyEmailVars(prep.subjectOverride, {
|
|
134
|
+
storeName,
|
|
135
|
+
customerName: params.customerName,
|
|
136
|
+
})
|
|
137
|
+
: getPasswordResetSubject(storeName),
|
|
103
138
|
html,
|
|
104
139
|
});
|
|
105
140
|
}
|