feat: Ability to overwrite locale on contact level with locale key on data
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import {type Contact, Prisma} from '@plunk/db';
|
||||
import {isValidLanguageCode} from '@plunk/shared';
|
||||
import type {FilterCondition, FilterGroup} from '@plunk/types';
|
||||
|
||||
import {prisma} from '../database/prisma.js';
|
||||
@@ -229,6 +230,20 @@ export class ContactService {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Validate locale field
|
||||
if (key === 'locale') {
|
||||
if (typeof value === 'string') {
|
||||
if (!isValidLanguageCode(value)) {
|
||||
throw new HttpException(
|
||||
400,
|
||||
`Invalid locale code: ${value}. Must be one of: en, nl, fr, hi, de`,
|
||||
);
|
||||
}
|
||||
} else if (value !== null && value !== undefined) {
|
||||
throw new HttpException(400, 'Locale must be a string');
|
||||
}
|
||||
}
|
||||
|
||||
// Handle non-persistent data format: { value: "...", persistent: false }
|
||||
if (
|
||||
typeof value === 'object' &&
|
||||
@@ -297,6 +312,12 @@ export class ContactService {
|
||||
Object.assign(mergedData, contact.data);
|
||||
}
|
||||
|
||||
// Explicitly expose locale as a predefined field (available in templates)
|
||||
// This ensures locale is always accessible even if not in contact.data
|
||||
if (mergedData.locale === undefined) {
|
||||
mergedData.locale = null;
|
||||
}
|
||||
|
||||
// Add temporary (non-persistent) data
|
||||
if (temporaryData) {
|
||||
for (const [key, value] of Object.entries(temporaryData)) {
|
||||
|
||||
@@ -604,8 +604,18 @@ export class EmailService {
|
||||
|
||||
const unsubscribeHtml = includeUnsubscribe
|
||||
? (() => {
|
||||
// Get translator for project's language
|
||||
const translator = createTranslatorSync(project.language || 'en');
|
||||
// Get contact-level locale (overrides project language)
|
||||
const contactLocale =
|
||||
contact.data &&
|
||||
typeof contact.data === 'object' &&
|
||||
!Array.isArray(contact.data) &&
|
||||
'locale' in contact.data &&
|
||||
typeof contact.data.locale === 'string'
|
||||
? contact.data.locale
|
||||
: null;
|
||||
|
||||
// Get translator for contact's locale or project's language
|
||||
const translator = createTranslatorSync(contactLocale || project.language || 'en');
|
||||
const unsubscribeText = translator.t('email.footer.unsubscribeText', {
|
||||
projectName: project.name,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user