poly-lexis 0.8.1 → 0.9.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/index.d.ts CHANGED
@@ -184,6 +184,8 @@ interface TranslationConfig {
184
184
  searchPaths?: string[];
185
185
  /** File extensions to search for key usage (default: ['.ts', '.tsx', '.js', '.jsx', '.vue', '.svelte']) */
186
186
  searchExtensions?: string[];
187
+ /** Words or phrases that should never be translated (e.g. brand names, product names) */
188
+ protectedTerms?: string[];
187
189
  }
188
190
  interface TranslationEntry {
189
191
  namespace: string;
@@ -376,6 +378,8 @@ interface TranslateOptions {
376
378
  apiKey?: string;
377
379
  /** Enable automatic language fallback for unsupported regional variants (default: true) */
378
380
  useFallbackLanguages?: boolean;
381
+ /** Words or phrases that should never be translated (e.g. brand names, product names) */
382
+ protectedTerms?: string[];
379
383
  /** Additional provider-specific options */
380
384
  [key: string]: unknown;
381
385
  }
@@ -464,7 +468,7 @@ declare function resetTranslationProvider(): void;
464
468
  * @param useFallbackLanguages - Enable automatic language fallback (default: true)
465
469
  * @returns Promise resolving to translated text
466
470
  */
467
- declare function translateText(text: string, targetLang: string, sourceLang?: string, apiKey?: string, useFallbackLanguages?: boolean): Promise<string>;
471
+ declare function translateText(text: string, targetLang: string, sourceLang?: string, apiKey?: string, useFallbackLanguages?: boolean, protectedTerms?: string[]): Promise<string>;
468
472
  /**
469
473
  * Translate multiple texts in batch
470
474
  *
package/dist/index.js CHANGED
@@ -834,7 +834,8 @@ var init_types = __esm({
834
834
  provider: "deepl",
835
835
  useFallbackLanguages: true,
836
836
  searchPaths: ["src", "app", "pages", "components"],
837
- searchExtensions: [".ts", ".tsx", ".js", ".jsx", ".vue", ".svelte"]
837
+ searchExtensions: [".ts", ".tsx", ".js", ".jsx", ".vue", ".svelte"],
838
+ protectedTerms: []
838
839
  };
839
840
  DEFAULT_LANGUAGES = ["en", "fr", "it", "pl", "es", "pt", "de", "nl", "sv", "hu", "cs", "ja"];
840
841
  }
@@ -977,10 +978,20 @@ import * as path4 from "path";
977
978
 
978
979
  // src/translations/utils/deepl-translate-provider.ts
979
980
  init_language_fallback();
980
- function preserveVariables(text) {
981
+ function preserveVariables(text, protectedTerms = []) {
981
982
  const variableMap = /* @__PURE__ */ new Map();
982
983
  let placeholderIndex = 0;
983
- const textWithPlaceholders = text.replace(/\{\{([^}]+)\}\}/g, (match) => {
984
+ let result = text;
985
+ for (const term of protectedTerms) {
986
+ const escaped = term.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
987
+ result = result.replace(new RegExp(escaped, "g"), () => {
988
+ const placeholder = `XXX_${placeholderIndex}_XXX`;
989
+ variableMap.set(placeholder, term);
990
+ placeholderIndex++;
991
+ return placeholder;
992
+ });
993
+ }
994
+ const textWithPlaceholders = result.replace(/\{\{([^}]+)\}\}/g, (match) => {
984
995
  const placeholder = `XXX_${placeholderIndex}_XXX`;
985
996
  variableMap.set(placeholder, match);
986
997
  placeholderIndex++;
@@ -1012,7 +1023,7 @@ var DeepLTranslateProvider = class {
1012
1023
  return this.isFreeApi ? "https://api-free.deepl.com/v2/translate" : "https://api.deepl.com/v2/translate";
1013
1024
  }
1014
1025
  async translate(options) {
1015
- const { text, sourceLang, targetLang, apiKey, useFallbackLanguages = true } = options;
1026
+ const { text, sourceLang, targetLang, apiKey, useFallbackLanguages = true, protectedTerms = [] } = options;
1016
1027
  if (!apiKey) {
1017
1028
  throw new Error(
1018
1029
  "DeepL API key is required. Set DEEPL_API_KEY environment variable or provide apiKey in options."
@@ -1026,7 +1037,7 @@ var DeepLTranslateProvider = class {
1026
1037
  logLanguageFallback(sourceLangResult, "deepl");
1027
1038
  resolvedSourceLang = sourceLangResult.resolvedLanguage;
1028
1039
  }
1029
- const { textWithPlaceholders, variableMap } = preserveVariables(text);
1040
+ const { textWithPlaceholders, variableMap } = preserveVariables(text, protectedTerms);
1030
1041
  const body = {
1031
1042
  text: [textWithPlaceholders],
1032
1043
  target_lang: normalizeLanguageCode(targetLangResult.resolvedLanguage),
@@ -1075,10 +1086,20 @@ var DeepLTranslateProvider = class {
1075
1086
 
1076
1087
  // src/translations/utils/google-translate-provider.ts
1077
1088
  init_language_fallback();
1078
- function preserveVariables2(text) {
1089
+ function preserveVariables2(text, protectedTerms = []) {
1079
1090
  const variableMap = /* @__PURE__ */ new Map();
1080
1091
  let placeholderIndex = 0;
1081
- const textWithPlaceholders = text.replace(/\{\{([^}]+)\}\}/g, (match) => {
1092
+ let result = text;
1093
+ for (const term of protectedTerms) {
1094
+ const escaped = term.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1095
+ result = result.replace(new RegExp(escaped, "g"), () => {
1096
+ const placeholder = `XXX_${placeholderIndex}_XXX`;
1097
+ variableMap.set(placeholder, term);
1098
+ placeholderIndex++;
1099
+ return placeholder;
1100
+ });
1101
+ }
1102
+ const textWithPlaceholders = result.replace(/\{\{([^}]+)\}\}/g, (match) => {
1082
1103
  const placeholder = `XXX_${placeholderIndex}_XXX`;
1083
1104
  variableMap.set(placeholder, match);
1084
1105
  placeholderIndex++;
@@ -1100,7 +1121,7 @@ function restoreVariables2(text, variableMap) {
1100
1121
  }
1101
1122
  var GoogleTranslateProvider = class {
1102
1123
  async translate(options) {
1103
- const { text, sourceLang, targetLang, apiKey, useFallbackLanguages = true } = options;
1124
+ const { text, sourceLang, targetLang, apiKey, useFallbackLanguages = true, protectedTerms = [] } = options;
1104
1125
  if (!apiKey) {
1105
1126
  throw new Error(
1106
1127
  "Google Translate API key is required. Set GOOGLE_TRANSLATE_API_KEY environment variable or provide apiKey in options."
@@ -1114,7 +1135,7 @@ var GoogleTranslateProvider = class {
1114
1135
  logLanguageFallback(sourceLangResult, "google");
1115
1136
  resolvedSourceLang = sourceLangResult.resolvedLanguage;
1116
1137
  }
1117
- const { textWithPlaceholders, variableMap } = preserveVariables2(text);
1138
+ const { textWithPlaceholders, variableMap } = preserveVariables2(text, protectedTerms);
1118
1139
  const url = `https://translation.googleapis.com/language/translate/v2?key=${apiKey}`;
1119
1140
  const sourceForGoogle = resolvedSourceLang?.includes("_") ? resolvedSourceLang.split("_")[0] : resolvedSourceLang;
1120
1141
  const targetForGoogle = targetLangResult.resolvedLanguage.includes("_") ? targetLangResult.resolvedLanguage.split("_")[0] : targetLangResult.resolvedLanguage;
@@ -1171,14 +1192,15 @@ function getTranslationProvider() {
1171
1192
  function resetTranslationProvider() {
1172
1193
  customProvider = null;
1173
1194
  }
1174
- async function translateText(text, targetLang, sourceLang = "en", apiKey, useFallbackLanguages = true) {
1195
+ async function translateText(text, targetLang, sourceLang = "en", apiKey, useFallbackLanguages = true, protectedTerms = []) {
1175
1196
  const provider = getTranslationProvider();
1176
1197
  return provider.translate({
1177
1198
  text,
1178
1199
  sourceLang,
1179
1200
  targetLang,
1180
1201
  apiKey,
1181
- useFallbackLanguages
1202
+ useFallbackLanguages,
1203
+ protectedTerms
1182
1204
  });
1183
1205
  }
1184
1206
  async function translateBatch(texts, targetLang, sourceLang = "en", apiKey, delayMs = 100) {
@@ -1311,7 +1333,14 @@ async function addTranslationKey(projectRoot, options) {
1311
1333
  targetTranslations[namespace] = {};
1312
1334
  }
1313
1335
  if (!targetTranslations[namespace][key] || targetTranslations[namespace][key].trim() === "") {
1314
- const translated = await translateText(value, lang, sourceLang, apiKey, config.useFallbackLanguages ?? true);
1336
+ const translated = await translateText(
1337
+ value,
1338
+ lang,
1339
+ sourceLang,
1340
+ apiKey,
1341
+ config.useFallbackLanguages,
1342
+ config.protectedTerms
1343
+ );
1315
1344
  targetTranslations[namespace][key] = translated;
1316
1345
  const sorted = sortKeys(targetTranslations[namespace]);
1317
1346
  writeTranslation(translationsPath, lang, namespace, sorted);
@@ -1566,7 +1595,8 @@ Processing language: ${language}`);
1566
1595
  language,
1567
1596
  config.sourceLanguage,
1568
1597
  apiKey,
1569
- config.useFallbackLanguages ?? true
1598
+ config.useFallbackLanguages,
1599
+ config.protectedTerms
1570
1600
  );
1571
1601
  console.log(` ${language.toUpperCase()}: "${translated}"`);
1572
1602
  if (!dryRun) {
@@ -1631,7 +1661,8 @@ async function fillNamespace(projectRoot, language, namespace, apiKey) {
1631
1661
  language,
1632
1662
  config.sourceLanguage,
1633
1663
  apiKey,
1634
- config.useFallbackLanguages ?? true
1664
+ config.useFallbackLanguages ?? true,
1665
+ config.protectedTerms ?? []
1635
1666
  );
1636
1667
  targetKeys[key] = translated;
1637
1668
  count++;