@scoutello/i18n-magic 0.64.0 → 0.66.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/README.md +13 -7
- package/dist/cli.js +20 -15
- package/dist/cli.js.map +1 -1
- package/dist/commands/check-missing.d.ts +11 -1
- package/dist/commands/check-missing.d.ts.map +1 -1
- package/dist/commands/check-missing.js +56 -96
- package/dist/commands/check-missing.js.map +1 -1
- package/dist/commands/replace.d.ts +6 -0
- package/dist/commands/replace.d.ts.map +1 -1
- package/dist/commands/replace.js +48 -29
- package/dist/commands/replace.js.map +1 -1
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +114 -80
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/sync-locales.d.ts.map +1 -1
- package/dist/commands/sync-locales.js +90 -50
- package/dist/commands/sync-locales.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/languges.d.ts.map +1 -1
- package/dist/lib/languges.js +20 -0
- package/dist/lib/languges.js.map +1 -1
- package/dist/lib/locale-storage.d.ts +7 -0
- package/dist/lib/locale-storage.d.ts.map +1 -0
- package/dist/lib/locale-storage.js +49 -0
- package/dist/lib/locale-storage.js.map +1 -0
- package/dist/lib/translation-response.d.ts +8 -0
- package/dist/lib/translation-response.d.ts.map +1 -0
- package/dist/lib/translation-response.js +43 -0
- package/dist/lib/translation-response.js.map +1 -0
- package/dist/lib/types.d.ts +1 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/update-translation-key.d.ts +16 -0
- package/dist/lib/update-translation-key.d.ts.map +1 -0
- package/dist/lib/update-translation-key.js +67 -0
- package/dist/lib/update-translation-key.js.map +1 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +69 -51
- package/dist/lib/utils.js.map +1 -1
- package/dist/mcp-server.js +28 -79
- package/dist/mcp-server.js.map +1 -1
- package/package.json +5 -9
- package/src/cli.ts +26 -18
- package/src/commands/check-missing.ts +83 -137
- package/src/commands/replace.ts +81 -43
- package/src/commands/scan.ts +130 -108
- package/src/commands/sync-locales.ts +125 -86
- package/src/index.ts +6 -1
- package/src/lib/languges.ts +20 -0
- package/src/lib/locale-storage.ts +76 -0
- package/src/lib/translation-response.ts +59 -0
- package/src/lib/types.ts +1 -1
- package/src/lib/update-translation-key.ts +119 -0
- package/src/lib/utils.ts +92 -76
- package/src/mcp-server.ts +31 -112
package/src/mcp-server.ts
CHANGED
|
@@ -10,6 +10,7 @@ import path from "path"
|
|
|
10
10
|
import { fileURLToPath } from "url"
|
|
11
11
|
import { z } from "zod"
|
|
12
12
|
import type { Configuration } from "./lib/types.js"
|
|
13
|
+
import { updateTranslationKeyOperation } from "./lib/update-translation-key.js"
|
|
13
14
|
import {
|
|
14
15
|
addTranslationKey,
|
|
15
16
|
addTranslationKeys,
|
|
@@ -162,7 +163,7 @@ const AddTranslationKeySchema = z.object({
|
|
|
162
163
|
.string()
|
|
163
164
|
.optional()
|
|
164
165
|
.describe(
|
|
165
|
-
|
|
166
|
+
"The configured language code of the provided value. Defaults to config.defaultLocale if not specified.",
|
|
166
167
|
),
|
|
167
168
|
})
|
|
168
169
|
|
|
@@ -181,7 +182,7 @@ const AddTranslationKeysSchema = z.object({
|
|
|
181
182
|
.string()
|
|
182
183
|
.optional()
|
|
183
184
|
.describe(
|
|
184
|
-
|
|
185
|
+
"The configured language code of the provided value. Defaults to config.defaultLocale if not specified.",
|
|
185
186
|
),
|
|
186
187
|
}),
|
|
187
188
|
)
|
|
@@ -210,7 +211,7 @@ const UpdateTranslationKeySchema = z.object({
|
|
|
210
211
|
.string()
|
|
211
212
|
.optional()
|
|
212
213
|
.describe(
|
|
213
|
-
|
|
214
|
+
"The configured language code of the provided value. Defaults to config.defaultLocale if not specified.",
|
|
214
215
|
),
|
|
215
216
|
})
|
|
216
217
|
|
|
@@ -299,7 +300,7 @@ class I18nMagicServer {
|
|
|
299
300
|
{
|
|
300
301
|
name: "add_translation_key",
|
|
301
302
|
description:
|
|
302
|
-
"Add a new translation key with a text value. The destination translation file is resolved automatically from project configuration and code usage.
|
|
303
|
+
"Add a new translation key with a text value. The destination translation file is resolved automatically from project configuration and code usage. The language defaults to the configured defaultLocale. For adding multiple keys at once, use add_translation_keys instead for better performance. NOTE: This tool can only ADD keys, it will NEVER remove any existing keys.",
|
|
303
304
|
inputSchema: {
|
|
304
305
|
type: "object",
|
|
305
306
|
properties: {
|
|
@@ -315,7 +316,7 @@ class I18nMagicServer {
|
|
|
315
316
|
language: {
|
|
316
317
|
type: "string",
|
|
317
318
|
description:
|
|
318
|
-
|
|
319
|
+
"The configured language code of the provided value. Defaults to config.defaultLocale if not specified.",
|
|
319
320
|
},
|
|
320
321
|
},
|
|
321
322
|
required: ["key", "value"],
|
|
@@ -346,7 +347,7 @@ class I18nMagicServer {
|
|
|
346
347
|
language: {
|
|
347
348
|
type: "string",
|
|
348
349
|
description:
|
|
349
|
-
|
|
350
|
+
"The configured language code of the provided value. Defaults to config.defaultLocale if not specified.",
|
|
350
351
|
},
|
|
351
352
|
},
|
|
352
353
|
required: ["key", "value"],
|
|
@@ -385,7 +386,7 @@ class I18nMagicServer {
|
|
|
385
386
|
{
|
|
386
387
|
name: "update_translation_key",
|
|
387
388
|
description:
|
|
388
|
-
"Update an existing translation key with a new text value.
|
|
389
|
+
"Update an existing translation key with a new text value. The language defaults to the configured defaultLocale. With a provider, every locale is translated before writes begin. Without a provider, only the supplied/default locale is updated and other locales are returned as pending. NOTE: This tool can only UPDATE existing keys, it will NEVER remove any keys.",
|
|
389
390
|
inputSchema: {
|
|
390
391
|
type: "object",
|
|
391
392
|
properties: {
|
|
@@ -401,7 +402,7 @@ class I18nMagicServer {
|
|
|
401
402
|
language: {
|
|
402
403
|
type: "string",
|
|
403
404
|
description:
|
|
404
|
-
|
|
405
|
+
"The configured language code of the provided value. Defaults to config.defaultLocale if not specified.",
|
|
405
406
|
},
|
|
406
407
|
},
|
|
407
408
|
required: ["key", "value"],
|
|
@@ -448,7 +449,7 @@ class I18nMagicServer {
|
|
|
448
449
|
return await addTranslationKey({
|
|
449
450
|
key: params.key,
|
|
450
451
|
value: params.value,
|
|
451
|
-
language: params.language
|
|
452
|
+
language: params.language,
|
|
452
453
|
config,
|
|
453
454
|
})
|
|
454
455
|
})
|
|
@@ -467,7 +468,7 @@ class I18nMagicServer {
|
|
|
467
468
|
message: `Successfully added translation key "${result.key}"`,
|
|
468
469
|
key: result.key,
|
|
469
470
|
value: result.value,
|
|
470
|
-
providedLanguage:
|
|
471
|
+
providedLanguage: result.providedLanguage,
|
|
471
472
|
locales: result.locale,
|
|
472
473
|
nextStep: result.locale.includes(",")
|
|
473
474
|
? "Key was automatically translated to multiple locales"
|
|
@@ -564,7 +565,7 @@ class I18nMagicServer {
|
|
|
564
565
|
keys: params.keys.map((k) => ({
|
|
565
566
|
key: k.key,
|
|
566
567
|
value: k.value,
|
|
567
|
-
language: k.language
|
|
568
|
+
language: k.language,
|
|
568
569
|
})),
|
|
569
570
|
config,
|
|
570
571
|
})
|
|
@@ -892,102 +893,14 @@ class I18nMagicServer {
|
|
|
892
893
|
console.log = () => {}
|
|
893
894
|
|
|
894
895
|
try {
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
const keys = await loadLocalesFile(
|
|
904
|
-
config.loadPath,
|
|
905
|
-
"en",
|
|
906
|
-
namespace,
|
|
907
|
-
)
|
|
908
|
-
if (Object.hasOwn(keys, params.key)) {
|
|
909
|
-
targetNamespaces.push(namespace)
|
|
910
|
-
}
|
|
911
|
-
} catch (error) {
|
|
912
|
-
// Namespace file doesn't exist, continue
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
if (targetNamespaces.length === 0) {
|
|
917
|
-
throw new Error(
|
|
918
|
-
`Key "${params.key}" does not exist in translation files. Use add_translation_key to create it.`,
|
|
919
|
-
)
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
// Build translation cache with new value
|
|
923
|
-
const inputLanguage = params.language || "en"
|
|
924
|
-
const translationCache: Record<string, string> = {
|
|
925
|
-
[inputLanguage]: params.value,
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
// Translate to all other locales
|
|
929
|
-
const otherLocales = config.locales.filter(
|
|
930
|
-
(l) => l !== inputLanguage,
|
|
931
|
-
)
|
|
932
|
-
if (otherLocales.length > 0 && config.openai) {
|
|
933
|
-
const { translateKey } = await import("./lib/utils.js")
|
|
934
|
-
|
|
935
|
-
await Promise.all(
|
|
936
|
-
otherLocales.map(async (locale) => {
|
|
937
|
-
const translation = await translateKey({
|
|
938
|
-
context: config.context || "",
|
|
939
|
-
inputLanguage: inputLanguage,
|
|
940
|
-
outputLanguage: locale,
|
|
941
|
-
object: {
|
|
942
|
-
[params.key]: params.value,
|
|
943
|
-
},
|
|
944
|
-
openai: config.openai!,
|
|
945
|
-
model: config.model,
|
|
946
|
-
})
|
|
947
|
-
translationCache[locale] = translation[params.key]
|
|
948
|
-
}),
|
|
949
|
-
)
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
// Update the key in all relevant namespaces and locales
|
|
953
|
-
// Process sequentially to avoid race conditions
|
|
954
|
-
const { writeLocalesFile } = await import("./lib/utils.js")
|
|
955
|
-
|
|
956
|
-
for (const namespace of targetNamespaces) {
|
|
957
|
-
for (const locale of config.locales) {
|
|
958
|
-
const newValue = translationCache[locale] || params.value
|
|
959
|
-
|
|
960
|
-
// Load existing keys
|
|
961
|
-
const existingKeys = await loadLocalesFile(
|
|
962
|
-
config.loadPath,
|
|
963
|
-
locale,
|
|
964
|
-
namespace,
|
|
965
|
-
)
|
|
966
|
-
|
|
967
|
-
const originalKeyCount = Object.keys(existingKeys).length
|
|
968
|
-
|
|
969
|
-
// Update the specific key
|
|
970
|
-
existingKeys[params.key] = newValue
|
|
971
|
-
|
|
972
|
-
const newKeyCount = Object.keys(existingKeys).length
|
|
973
|
-
|
|
974
|
-
// Safety check: we should only be updating, not removing
|
|
975
|
-
// Key count should stay same (update) or increase by 1 (add)
|
|
976
|
-
if (newKeyCount < originalKeyCount) {
|
|
977
|
-
throw new Error(
|
|
978
|
-
`Safety check failed: Updating locale "${locale}" would reduce keys from ${originalKeyCount} to ${newKeyCount}. Aborting.`,
|
|
979
|
-
)
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
await writeLocalesFile(
|
|
983
|
-
config.savePath,
|
|
984
|
-
locale,
|
|
985
|
-
namespace,
|
|
986
|
-
existingKeys,
|
|
987
|
-
)
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
})
|
|
896
|
+
const result = await translationMutex.withLock(async () =>
|
|
897
|
+
updateTranslationKeyOperation({
|
|
898
|
+
config,
|
|
899
|
+
key: params.key,
|
|
900
|
+
value: params.value,
|
|
901
|
+
language: params.language,
|
|
902
|
+
}),
|
|
903
|
+
)
|
|
991
904
|
|
|
992
905
|
return {
|
|
993
906
|
content: [
|
|
@@ -996,11 +909,17 @@ class I18nMagicServer {
|
|
|
996
909
|
text: JSON.stringify(
|
|
997
910
|
{
|
|
998
911
|
success: true,
|
|
999
|
-
message: `Successfully updated translation key "${
|
|
1000
|
-
key:
|
|
1001
|
-
newValue:
|
|
1002
|
-
providedLanguage:
|
|
1003
|
-
|
|
912
|
+
message: `Successfully updated translation key "${result.key}" in ${result.updatedLocales.length} locale(s)`,
|
|
913
|
+
key: result.key,
|
|
914
|
+
newValue: result.value,
|
|
915
|
+
providedLanguage: result.sourceLocale,
|
|
916
|
+
updatedLocales: result.updatedLocales,
|
|
917
|
+
pendingLocales: result.pendingLocales,
|
|
918
|
+
locales: result.updatedLocales,
|
|
919
|
+
nextStep:
|
|
920
|
+
result.pendingLocales.length > 0
|
|
921
|
+
? "Run 'i18n-magic sync' with a configured provider to translate pending locales."
|
|
922
|
+
: "All configured locales were updated.",
|
|
1004
923
|
},
|
|
1005
924
|
null,
|
|
1006
925
|
2,
|