@scoutello/i18n-magic 0.52.0 → 0.54.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/src/lib/utils.ts CHANGED
@@ -688,17 +688,19 @@ export class TranslationError extends Error {
688
688
  }
689
689
 
690
690
  /**
691
- * Add a translation key with an English value to the locale files.
692
- * This function always adds to the "en" locale, and if the defaultLocale is different,
693
- * it will also translate and save to the defaultLocale right away.
691
+ * Add a translation key with a value in a specific language to the locale files.
692
+ * This function adds to the specified language locale, and will also translate
693
+ * and save to other locales if OpenAI is configured.
694
694
  */
695
695
  export const addTranslationKey = async ({
696
696
  key,
697
697
  value,
698
+ language = "en",
698
699
  config,
699
700
  }: {
700
701
  key: string
701
702
  value: string
703
+ language?: string
702
704
  config: Configuration
703
705
  }) => {
704
706
  const { loadPath, savePath, defaultNamespace, namespaces, globPatterns, defaultLocale, openai, context, model } = config
@@ -745,16 +747,19 @@ export const addTranslationKey = async ({
745
747
  )
746
748
  }
747
749
 
748
- // Always use "en" as the locale for adding keys (English)
749
- const locale = "en"
750
+ // Use the specified language as the locale for adding keys
751
+ const locale = language
750
752
 
751
753
  // Use console.error for logging when called from MCP server (console.log is suppressed)
752
754
  const log = console.log
753
755
 
756
+ // Track which locales were successfully saved
757
+ const savedLocales = new Set<string>([locale])
758
+
754
759
  for (const targetNamespace of affectedNamespaces) {
755
760
  log(`➕ Adding translation key "${key}" to namespace "${targetNamespace}" (${locale})`)
756
761
 
757
- // Load existing keys for the English locale
762
+ // Load existing keys for the specified locale
758
763
  let existingKeys: Record<string, string>
759
764
  try {
760
765
  existingKeys = await loadLocalesFile(loadPath, locale, targetNamespace)
@@ -777,40 +782,52 @@ export const addTranslationKey = async ({
777
782
  await writeLocalesFile(savePath, locale, targetNamespace, existingKeys)
778
783
  log(`✅ Successfully saved key to ${locale}/${targetNamespace}`)
779
784
 
780
- // If defaultLocale is different from "en", translate and save to defaultLocale
781
- if (defaultLocale !== "en" && openai) {
782
- log(`🌐 Translating key "${key}" to ${defaultLocale}...`)
785
+ // If OpenAI is configured, translate to other locales automatically
786
+ if (openai) {
787
+ const otherLocales = config.locales.filter(l => l !== locale)
783
788
 
784
- try {
785
- // Translate the single key
786
- const translatedValue = await translateKey({
787
- inputLanguage: "en",
788
- outputLanguage: defaultLocale,
789
- context: context || "",
790
- object: { [key]: value },
791
- openai,
792
- model,
793
- })
794
-
795
- // Load existing keys for the default locale
796
- let defaultLocaleKeys: Record<string, string>
789
+ if (otherLocales.length > 0) {
790
+ log(`🌐 Translating key "${key}" to ${otherLocales.length} other locale(s)...`)
791
+
797
792
  try {
798
- defaultLocaleKeys = await loadLocalesFile(loadPath, defaultLocale, targetNamespace)
793
+ // Translate to all other locales in parallel
794
+ await Promise.all(
795
+ otherLocales.map(async (targetLocale) => {
796
+ try {
797
+ const translatedValue = await translateKey({
798
+ inputLanguage: locale,
799
+ outputLanguage: targetLocale,
800
+ context: context || "",
801
+ object: { [key]: value },
802
+ openai,
803
+ model,
804
+ })
805
+
806
+ // Load existing keys for the target locale
807
+ let targetLocaleKeys: Record<string, string>
808
+ try {
809
+ targetLocaleKeys = await loadLocalesFile(loadPath, targetLocale, targetNamespace)
810
+ } catch (error) {
811
+ log(`📄 Creating new namespace file for ${targetLocale}/${targetNamespace}`)
812
+ targetLocaleKeys = {}
813
+ }
814
+
815
+ // Add the translated key
816
+ targetLocaleKeys[key] = translatedValue[key]
817
+
818
+ // Save the updated keys
819
+ await writeLocalesFile(savePath, targetLocale, targetNamespace, targetLocaleKeys)
820
+ savedLocales.add(targetLocale)
821
+ log(`✅ Successfully translated and saved key to ${targetLocale}/${targetNamespace}`)
822
+ } catch (error) {
823
+ log(`⚠️ Failed to translate key to ${targetLocale}: ${error instanceof Error ? error.message : "Unknown error"}`)
824
+ }
825
+ })
826
+ )
799
827
  } catch (error) {
800
- // If file doesn't exist, start with empty object
801
- log(`📄 Creating new namespace file for ${defaultLocale}/${targetNamespace}`)
802
- defaultLocaleKeys = {}
828
+ log(`⚠️ Translation error: ${error instanceof Error ? error.message : "Unknown error"}`)
829
+ log(` You can run 'i18n-magic sync' to translate this key later`)
803
830
  }
804
-
805
- // Add the translated key
806
- defaultLocaleKeys[key] = translatedValue[key]
807
-
808
- // Save the updated keys
809
- await writeLocalesFile(savePath, defaultLocale, targetNamespace, defaultLocaleKeys)
810
- log(`✅ Successfully translated and saved key to ${defaultLocale}/${targetNamespace}`)
811
- } catch (error) {
812
- log(`⚠️ Failed to translate key to ${defaultLocale}: ${error instanceof Error ? error.message : "Unknown error"}`)
813
- log(` You can run 'i18n-magic sync' to translate this key later`)
814
831
  }
815
832
  }
816
833
  }
@@ -818,7 +835,7 @@ export const addTranslationKey = async ({
818
835
  return {
819
836
  key,
820
837
  value,
821
- namespace: affectedNamespaces.join(", "), // Return all affected namespaces
822
- locale: defaultLocale !== "en" ? `en, ${defaultLocale}` : locale,
838
+ namespace: affectedNamespaces.join(", "),
839
+ locale: Array.from(savedLocales).sort().join(", "),
823
840
  }
824
841
  }