Files
web/scripts/i18n/syncDefaultMessage/syncIntlFormatMessage.ts
Joakim Jäderberg bf6ed7778e Merged in feat/syncDefaultMessage (pull request #3022)
Sync defaultMessage from lokalise

* Enhance translation sync functionality and tests

- Added logging for found component files during sync.
- Introduced tests for handling complex components with replacements.
- Updated regex in syncIntlFormatMessage to support optional second arguments.
- Removed unused test files.

* feat(syncDefaultMessage): add script for syncing default message with lokalise

* feat(syncDefaultMessage): add script for syncing default message with lokalise


Approved-by: Matilda Landström
2025-10-30 08:38:50 +00:00

52 lines
2.1 KiB
TypeScript

export function syncIntlFormatMessage({
translations,
fileContent,
}: {
translations: Record<string, string>;
fileContent: string;
}): { updated: boolean; fileContent: string } {
let updated = false;
const entries = Object.entries(translations);
for (const [messageId, messageValue] of entries) {
const escapedId = messageId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
// Find intl.formatMessage({...}) or intl.formatMessage({...}, secondArg) blocks that contain the specific id
const outerRegex = new RegExp(
// group 1 = inner object content (without surrounding braces)
// group 2 = optional second argument (anything until the closing parenthesis, non-greedy)
`intl\\.formatMessage\\(\\s*\\{([^}]*?\\bid\\s*:\\s*['"]${escapedId}['"][^}]*?)\\}\\s*(?:,\\s*([^)]*?))?\\s*\\)`,
"gs"
);
fileContent = fileContent.replace(
outerRegex,
(fullMatch: string, innerObject: string, secondArg?: string) => {
// Find defaultMessage: '...' or "..."
const dmRegex =
/defaultMessage\s*:\s*(['"])((?:\\.|[\s\S])*?)\1/;
if (!dmRegex.test(innerObject)) return fullMatch;
const newInner = innerObject.replace(
dmRegex,
(_m: unknown, quote: string, _old: unknown) => {
// Escape backslashes first, then the surrounding quote, and newlines
const escaped = messageValue
.replace(/\\/g, "\\\\")
.replace(new RegExp(quote, "g"), `\\${quote}`)
.replace(/\n/g, "\\n");
return `defaultMessage: ${quote}${escaped}${quote}`;
}
);
updated = true;
// Preserve secondArg if present
const secondArgPart = secondArg ? `, ${secondArg}` : "";
return `intl.formatMessage({${newInner}}${secondArgPart})`;
}
);
}
return { updated, fileContent };
}