From e4fde699cc7b545e66eaec7a36fe4f626290b72f Mon Sep 17 00:00:00 2001 From: Petar Skelin Date: Wed, 10 Dec 2025 10:37:23 +0200 Subject: [PATCH 1/2] fix(i18n): handle utf-8 escape sequences in message bundle properties files --- packages/tools/lib/i18n/toJSON.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/tools/lib/i18n/toJSON.js b/packages/tools/lib/i18n/toJSON.js index 6fef316fe523..f0ba499aef06 100644 --- a/packages/tools/lib/i18n/toJSON.js +++ b/packages/tools/lib/i18n/toJSON.js @@ -14,8 +14,32 @@ const assets = require('../../assets-meta.js'); const allLanguages = assets.languages.all; +/** + * The translation system has a configuration whether to return UTF-8 sequences + * or the actual characters. This function inlines UTF-8 sequences to actual characters. + * + * For example, it converts "Keine Produkte erf\u00FCgbar" to "Keine Produkte verfügbar" + * This makes the JSON files more readable and smaller. + */ +function inlineUTF(properties) { + for (const key in properties) { + if (Object.prototype.hasOwnProperty.call(properties, key)) { + try { + // escape double quotes to avoid JSON parse error + const escaped = properties[key].replaceAll("\"", "\\\""); + properties[key] = JSON.parse(`"${escaped}"`); // utilize JSON parser to decode UTF-8 sequences + } catch (e) { + // in case of error, just keep the original string + console.log(`Warning: failed to inline UTF-8 for key "${key}" with value "${properties[key]}"`); + } + } + } + return properties; +} + const convertToJSON = async (file, distPath) => { const properties = PropertiesReader(file)._properties; + inlineUTF(properties); const filename = path.basename(file, path.extname(file)); const language = filename.match(/^messagebundle_(.*?)$/)[1]; if (!allLanguages.includes(language)) { From e5d43d57cc352980f40350597d7756aab447c696 Mon Sep 17 00:00:00 2001 From: Petar Skelin Date: Tue, 16 Dec 2025 07:51:26 +0200 Subject: [PATCH 2/2] chore: improve func call --- packages/tools/lib/i18n/toJSON.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/tools/lib/i18n/toJSON.js b/packages/tools/lib/i18n/toJSON.js index f0ba499aef06..6802ed32c7b5 100644 --- a/packages/tools/lib/i18n/toJSON.js +++ b/packages/tools/lib/i18n/toJSON.js @@ -38,8 +38,7 @@ function inlineUTF(properties) { } const convertToJSON = async (file, distPath) => { - const properties = PropertiesReader(file)._properties; - inlineUTF(properties); + const properties = inlineUTF(PropertiesReader(file)._properties); const filename = path.basename(file, path.extname(file)); const language = filename.match(/^messagebundle_(.*?)$/)[1]; if (!allLanguages.includes(language)) {