@scoutello/i18n-magic 0.18.0 → 0.20.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 +55 -44
- package/dist/cli.js +0 -6
- package/dist/cli.js.map +1 -1
- package/dist/commands/clean.d.ts.map +1 -1
- package/dist/commands/clean.js +16 -28
- package/dist/commands/clean.js.map +1 -1
- package/dist/commands/create-pruned-namespace.d.ts.map +1 -1
- package/dist/commands/create-pruned-namespace.js +2 -1
- package/dist/commands/create-pruned-namespace.js.map +1 -1
- package/dist/commands/replace.d.ts.map +1 -1
- package/dist/commands/replace.js +79 -32
- package/dist/commands/replace.js.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/types.d.ts +4 -6
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +27 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +93 -14
- package/dist/lib/utils.js.map +1 -1
- package/package.json +3 -2
- package/src/cli.ts +1 -6
- package/src/commands/clean.ts +19 -29
- package/src/commands/replace.ts +97 -46
- package/src/index.ts +3 -8
- package/src/lib/types.ts +4 -6
- package/src/lib/utils.ts +127 -19
- package/src/commands/create-pruned-namespace-automated.ts +0 -165
- package/src/commands/create-pruned-namespace.ts +0 -165
package/dist/lib/utils.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.TranslationError = exports.checkAllKeysExist = exports.getTextInput = exports.getMissingKeys = exports.getPureKey = exports.writeLocalesFile = exports.loadLocalesFile = exports.translateKey = exports.loadConfig = void 0;
|
|
6
|
+
exports.TranslationError = exports.checkAllKeysExist = exports.getTextInput = exports.getMissingKeys = exports.getKeysWithNamespaces = exports.getGlobPatternsForNamespace = exports.getNamespacesForFile = exports.extractGlobPatterns = exports.getPureKey = exports.writeLocalesFile = exports.loadLocalesFile = exports.translateKey = exports.loadConfig = void 0;
|
|
7
7
|
exports.removeDuplicatesFromArray = removeDuplicatesFromArray;
|
|
8
8
|
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
9
9
|
const i18next_scanner_1 = require("i18next-scanner");
|
|
@@ -119,31 +119,110 @@ const getPureKey = (key, namespace, isDefault) => {
|
|
|
119
119
|
return null;
|
|
120
120
|
};
|
|
121
121
|
exports.getPureKey = getPureKey;
|
|
122
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Extracts all glob patterns from the configuration, handling both string and object formats
|
|
124
|
+
*/
|
|
125
|
+
const extractGlobPatterns = (globPatterns) => {
|
|
126
|
+
return globPatterns.map((pattern) => typeof pattern === "string" ? pattern : pattern.pattern);
|
|
127
|
+
};
|
|
128
|
+
exports.extractGlobPatterns = extractGlobPatterns;
|
|
129
|
+
/**
|
|
130
|
+
* Gets the namespaces associated with a specific file path based on glob pattern configuration
|
|
131
|
+
*/
|
|
132
|
+
const getNamespacesForFile = (filePath, globPatterns, defaultNamespace) => {
|
|
133
|
+
const matchingNamespaces = [];
|
|
134
|
+
for (const pattern of globPatterns) {
|
|
135
|
+
if (typeof pattern === "object") {
|
|
136
|
+
// Use minimatch or similar logic to check if file matches pattern
|
|
137
|
+
const globPattern = pattern.pattern;
|
|
138
|
+
// For now, using a simple includes check - in production you'd want proper glob matching
|
|
139
|
+
if (filePath.includes(globPattern.replace("**/*", "").replace("*", ""))) {
|
|
140
|
+
matchingNamespaces.push(...pattern.namespaces);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// If no specific namespaces found, use default namespace
|
|
145
|
+
return matchingNamespaces.length > 0
|
|
146
|
+
? [...new Set(matchingNamespaces)]
|
|
147
|
+
: [defaultNamespace];
|
|
148
|
+
};
|
|
149
|
+
exports.getNamespacesForFile = getNamespacesForFile;
|
|
150
|
+
/**
|
|
151
|
+
* Gets all glob patterns that should be used for a specific namespace
|
|
152
|
+
*/
|
|
153
|
+
const getGlobPatternsForNamespace = (namespace, globPatterns) => {
|
|
154
|
+
const patterns = [];
|
|
155
|
+
for (const pattern of globPatterns) {
|
|
156
|
+
if (typeof pattern === "string") {
|
|
157
|
+
// String patterns apply to all namespaces
|
|
158
|
+
patterns.push(pattern);
|
|
159
|
+
}
|
|
160
|
+
else if (pattern.namespaces.includes(namespace)) {
|
|
161
|
+
// Object patterns only apply to specified namespaces
|
|
162
|
+
patterns.push(pattern.pattern);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return patterns;
|
|
166
|
+
};
|
|
167
|
+
exports.getGlobPatternsForNamespace = getGlobPatternsForNamespace;
|
|
168
|
+
/**
|
|
169
|
+
* Extracts keys with their associated namespaces based on the files they're found in
|
|
170
|
+
*/
|
|
171
|
+
const getKeysWithNamespaces = async ({ globPatterns, defaultNamespace, }) => {
|
|
123
172
|
const parser = new i18next_scanner_1.Parser({
|
|
124
173
|
nsSeparator: false,
|
|
125
174
|
keySeparator: false,
|
|
126
175
|
});
|
|
127
|
-
const
|
|
128
|
-
const
|
|
176
|
+
const allPatterns = (0, exports.extractGlobPatterns)(globPatterns);
|
|
177
|
+
const files = await (0, fast_glob_1.default)([...allPatterns, "!**/node_modules/**"]);
|
|
178
|
+
const keysWithNamespaces = [];
|
|
129
179
|
for (const file of files) {
|
|
130
180
|
const content = node_fs_1.default.readFileSync(file, "utf-8");
|
|
181
|
+
const fileKeys = [];
|
|
131
182
|
parser.parseFuncFromString(content, { list: ["t"] }, (key) => {
|
|
132
|
-
|
|
183
|
+
fileKeys.push(key);
|
|
133
184
|
});
|
|
185
|
+
// Get namespaces for this file
|
|
186
|
+
const fileNamespaces = (0, exports.getNamespacesForFile)(file, globPatterns, defaultNamespace);
|
|
187
|
+
// Add each key with its associated namespaces
|
|
188
|
+
for (const key of fileKeys) {
|
|
189
|
+
keysWithNamespaces.push({
|
|
190
|
+
key,
|
|
191
|
+
namespaces: fileNamespaces,
|
|
192
|
+
file,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
134
195
|
}
|
|
135
|
-
|
|
196
|
+
return keysWithNamespaces;
|
|
197
|
+
};
|
|
198
|
+
exports.getKeysWithNamespaces = getKeysWithNamespaces;
|
|
199
|
+
const getMissingKeys = async ({ globPatterns, namespaces, defaultNamespace, defaultLocale, loadPath, }) => {
|
|
200
|
+
const keysWithNamespaces = await (0, exports.getKeysWithNamespaces)({
|
|
201
|
+
globPatterns,
|
|
202
|
+
defaultNamespace,
|
|
203
|
+
});
|
|
136
204
|
const newKeys = [];
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
for (const
|
|
205
|
+
// Group keys by namespace
|
|
206
|
+
const keysByNamespace = {};
|
|
207
|
+
for (const { key, namespaces: keyNamespaces } of keysWithNamespaces) {
|
|
208
|
+
for (const namespace of keyNamespaces) {
|
|
209
|
+
if (!keysByNamespace[namespace]) {
|
|
210
|
+
keysByNamespace[namespace] = new Set();
|
|
211
|
+
}
|
|
141
212
|
const pureKey = (0, exports.getPureKey)(key, namespace, namespace === defaultNamespace);
|
|
142
|
-
if (
|
|
143
|
-
|
|
213
|
+
if (pureKey) {
|
|
214
|
+
keysByNamespace[namespace].add(pureKey);
|
|
144
215
|
}
|
|
145
|
-
|
|
146
|
-
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Check for missing keys in each namespace
|
|
219
|
+
for (const namespace of namespaces) {
|
|
220
|
+
const existingKeys = await (0, exports.loadLocalesFile)(loadPath, defaultLocale, namespace);
|
|
221
|
+
console.log(Object.keys(existingKeys).length, "existing keys in", namespace);
|
|
222
|
+
const keysForNamespace = keysByNamespace[namespace] || new Set();
|
|
223
|
+
for (const key of keysForNamespace) {
|
|
224
|
+
if (!existingKeys[key]) {
|
|
225
|
+
newKeys.push({ key, namespace });
|
|
147
226
|
}
|
|
148
227
|
}
|
|
149
228
|
}
|
package/dist/lib/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scoutello/i18n-magic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Intelligent CLI toolkit that automates internationalization workflows with AI-powered translations for JavaScript/TypeScript projects",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"openai": "^4.94.0"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
65
66
|
"chalk": "^5.4.1",
|
|
66
67
|
"commander": "^13.1.0",
|
|
67
68
|
"dotenv": "^16.5.0",
|
|
@@ -73,10 +74,10 @@
|
|
|
73
74
|
"devDependencies": {
|
|
74
75
|
"@biomejs/biome": "1.9.4",
|
|
75
76
|
"@tsconfig/recommended": "^1.0.8",
|
|
77
|
+
"@types/jest": "^29.5.12",
|
|
76
78
|
"@types/node": "^20.12.12",
|
|
77
79
|
"@types/prompts": "^2.4.9",
|
|
78
80
|
"jest": "^29.7.0",
|
|
79
|
-
"@types/jest": "^29.5.12",
|
|
80
81
|
"openai": "^4.94.0",
|
|
81
82
|
"tslib": "^2.8.1",
|
|
82
83
|
"typescript": "^5.8.3"
|
package/src/cli.ts
CHANGED
|
@@ -3,7 +3,7 @@ import dotenv from "dotenv"
|
|
|
3
3
|
import OpenAI from "openai"
|
|
4
4
|
import { checkMissing } from "./commands/check-missing"
|
|
5
5
|
import { removeUnusedKeys } from "./commands/clean"
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
import { replaceTranslation } from "./commands/replace"
|
|
8
8
|
import { translateMissing } from "./commands/scan"
|
|
9
9
|
import { syncLocales } from "./commands/sync-locales"
|
|
@@ -52,11 +52,6 @@ const commands: CommandType[] = [
|
|
|
52
52
|
"Remove unused translations from all locales. Useful for a CI/CD pipeline or husky hook.",
|
|
53
53
|
action: removeUnusedKeys,
|
|
54
54
|
},
|
|
55
|
-
{
|
|
56
|
-
name: "prune",
|
|
57
|
-
description: "Create a pruned namespace from the other namespaces.",
|
|
58
|
-
action: createPrunedNamespace,
|
|
59
|
-
},
|
|
60
55
|
]
|
|
61
56
|
|
|
62
57
|
for (const command of commands) {
|
package/src/commands/clean.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import glob from "fast-glob"
|
|
2
|
-
import { Parser } from "i18next-scanner"
|
|
3
|
-
import fs from "node:fs"
|
|
4
1
|
import type { Configuration } from "../lib/types"
|
|
5
2
|
import {
|
|
3
|
+
getKeysWithNamespaces,
|
|
6
4
|
getPureKey,
|
|
7
5
|
loadLocalesFile,
|
|
8
|
-
removeDuplicatesFromArray,
|
|
9
6
|
writeLocalesFile,
|
|
10
7
|
} from "../lib/utils"
|
|
11
8
|
|
|
@@ -19,44 +16,37 @@ export const removeUnusedKeys = async (config: Configuration) => {
|
|
|
19
16
|
savePath,
|
|
20
17
|
} = config
|
|
21
18
|
|
|
22
|
-
//
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
// Get all keys with their associated namespaces from the codebase
|
|
20
|
+
const keysWithNamespaces = await getKeysWithNamespaces({
|
|
21
|
+
globPatterns,
|
|
22
|
+
defaultNamespace,
|
|
26
23
|
})
|
|
27
24
|
|
|
28
|
-
// Find all files to scan
|
|
29
|
-
const files = await glob([...globPatterns, "!**/node_modules/**"])
|
|
30
|
-
|
|
31
|
-
// Extract all translation keys from the codebase
|
|
32
|
-
const extractedKeys = []
|
|
33
|
-
for (const file of files) {
|
|
34
|
-
const content = fs.readFileSync(file, "utf-8")
|
|
35
|
-
parser.parseFuncFromString(content, { list: ["t"] }, (key: string) => {
|
|
36
|
-
extractedKeys.push(key)
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Remove duplicates
|
|
41
|
-
const uniqueExtractedKeys = removeDuplicatesFromArray(extractedKeys)
|
|
42
|
-
|
|
43
25
|
// Track stats for reporting
|
|
44
26
|
const stats = {
|
|
45
27
|
total: 0,
|
|
46
28
|
removed: 0,
|
|
47
29
|
}
|
|
48
30
|
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
31
|
+
// Group keys by namespace
|
|
32
|
+
const keysByNamespace: Record<string, Set<string>> = {}
|
|
33
|
+
|
|
34
|
+
for (const { key, namespaces: keyNamespaces } of keysWithNamespaces) {
|
|
35
|
+
for (const namespace of keyNamespaces) {
|
|
36
|
+
if (!keysByNamespace[namespace]) {
|
|
37
|
+
keysByNamespace[namespace] = new Set()
|
|
38
|
+
}
|
|
53
39
|
|
|
54
|
-
for (const key of uniqueExtractedKeys) {
|
|
55
40
|
const pureKey = getPureKey(key, namespace, namespace === defaultNamespace)
|
|
56
41
|
if (pureKey) {
|
|
57
|
-
|
|
42
|
+
keysByNamespace[namespace].add(pureKey)
|
|
58
43
|
}
|
|
59
44
|
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Process each namespace and locale
|
|
48
|
+
for (const namespace of namespaces) {
|
|
49
|
+
const usedKeysSet = keysByNamespace[namespace] || new Set()
|
|
60
50
|
|
|
61
51
|
// Process each locale
|
|
62
52
|
for (const locale of locales) {
|
package/src/commands/replace.ts
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
import type { Configuration } from "../lib/types"
|
|
2
2
|
import {
|
|
3
|
+
getKeysWithNamespaces,
|
|
4
|
+
getPureKey,
|
|
3
5
|
getTextInput,
|
|
4
6
|
loadLocalesFile,
|
|
5
7
|
translateKey,
|
|
6
8
|
writeLocalesFile,
|
|
7
9
|
} from "../lib/utils"
|
|
8
10
|
|
|
9
|
-
const getKeyToReplace = async (
|
|
11
|
+
const getKeyToReplace = async (
|
|
12
|
+
allAvailableKeys: Record<string, { namespace: string; value: string }[]>,
|
|
13
|
+
): Promise<{ key: string; namespaces: string[] }> => {
|
|
10
14
|
const keyToReplace = await getTextInput(
|
|
11
15
|
"Enter the key to replace the translation for: ",
|
|
12
16
|
)
|
|
13
17
|
|
|
14
|
-
if (!
|
|
18
|
+
if (!allAvailableKeys[keyToReplace]) {
|
|
15
19
|
console.log(`The key "${keyToReplace}" does not exist.`)
|
|
16
|
-
return await getKeyToReplace(
|
|
20
|
+
return await getKeyToReplace(allAvailableKeys)
|
|
17
21
|
}
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
const namespaces = allAvailableKeys[keyToReplace].map((k) => k.namespace)
|
|
24
|
+
console.log(
|
|
25
|
+
`The key "${keyToReplace}" exists in namespaces: ${namespaces.join(", ")}.`,
|
|
26
|
+
)
|
|
27
|
+
return { key: keyToReplace, namespaces }
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
export const replaceTranslation = async (
|
|
@@ -36,63 +43,107 @@ export const replaceTranslation = async (
|
|
|
36
43
|
openai,
|
|
37
44
|
} = config
|
|
38
45
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
)
|
|
46
|
+
// Find all keys with their namespaces from the codebase
|
|
47
|
+
const keysWithNamespaces = await getKeysWithNamespaces({
|
|
48
|
+
globPatterns,
|
|
49
|
+
defaultNamespace,
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// Build a map of all available keys across all namespaces
|
|
53
|
+
const allAvailableKeys: Record<
|
|
54
|
+
string,
|
|
55
|
+
{ namespace: string; value: string }[]
|
|
56
|
+
> = {}
|
|
57
|
+
|
|
58
|
+
for (const namespace of namespaces) {
|
|
59
|
+
const keys = await loadLocalesFile(loadPath, defaultLocale, namespace)
|
|
60
|
+
for (const [keyName, value] of Object.entries(keys)) {
|
|
61
|
+
if (!allAvailableKeys[keyName]) {
|
|
62
|
+
allAvailableKeys[keyName] = []
|
|
63
|
+
}
|
|
64
|
+
allAvailableKeys[keyName].push({ namespace, value })
|
|
65
|
+
}
|
|
66
|
+
}
|
|
44
67
|
|
|
45
68
|
let keyToReplace: string
|
|
69
|
+
let targetNamespaces: string[] = []
|
|
46
70
|
|
|
47
71
|
if (key) {
|
|
48
|
-
if (
|
|
72
|
+
if (allAvailableKeys[key]) {
|
|
49
73
|
keyToReplace = key
|
|
50
|
-
|
|
74
|
+
// Determine which namespaces this key should be updated in based on usage
|
|
75
|
+
const keyUsage = keysWithNamespaces.filter((k) => {
|
|
76
|
+
const pureKey = getPureKey(k.key, defaultNamespace, true)
|
|
77
|
+
return pureKey === key || k.key === key
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
if (keyUsage.length > 0) {
|
|
81
|
+
// Use namespaces from actual usage
|
|
82
|
+
const allNamespaces: string[] = []
|
|
83
|
+
for (const k of keyUsage) {
|
|
84
|
+
allNamespaces.push(...k.namespaces)
|
|
85
|
+
}
|
|
86
|
+
targetNamespaces = [...new Set(allNamespaces)]
|
|
87
|
+
} else {
|
|
88
|
+
// Fallback to all namespaces where the key exists
|
|
89
|
+
targetNamespaces = allAvailableKeys[key].map((k) => k.namespace)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.log(
|
|
93
|
+
`The key "${keyToReplace}" exists in namespaces: ${targetNamespaces.join(", ")}.`,
|
|
94
|
+
)
|
|
51
95
|
} else {
|
|
52
96
|
console.log(`The key "${key}" does not exist.`)
|
|
53
|
-
|
|
97
|
+
const result = await getKeyToReplace(allAvailableKeys)
|
|
98
|
+
keyToReplace = result.key
|
|
99
|
+
targetNamespaces = result.namespaces
|
|
54
100
|
}
|
|
55
101
|
} else {
|
|
56
|
-
|
|
102
|
+
const result = await getKeyToReplace(allAvailableKeys)
|
|
103
|
+
keyToReplace = result.key
|
|
104
|
+
targetNamespaces = result.namespaces
|
|
57
105
|
}
|
|
58
106
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
107
|
+
// Show current translations across namespaces
|
|
108
|
+
for (const namespace of targetNamespaces) {
|
|
109
|
+
const keys = await loadLocalesFile(loadPath, defaultLocale, namespace)
|
|
110
|
+
if (keys[keyToReplace]) {
|
|
111
|
+
console.log(
|
|
112
|
+
`Current translation in ${defaultLocale} (${namespace}): "${keys[keyToReplace]}"`,
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
62
116
|
|
|
63
117
|
const newTranslation = await getTextInput("Enter the new translation: ")
|
|
64
118
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
newValue =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
119
|
+
// Update the key in all relevant namespaces and locales
|
|
120
|
+
for (const namespace of targetNamespaces) {
|
|
121
|
+
for (const locale of locales) {
|
|
122
|
+
let newValue = ""
|
|
123
|
+
if (locale === defaultLocale) {
|
|
124
|
+
newValue = newTranslation
|
|
125
|
+
} else {
|
|
126
|
+
const translation = await translateKey({
|
|
127
|
+
context,
|
|
128
|
+
inputLanguage: defaultLocale,
|
|
129
|
+
outputLanguage: locale,
|
|
130
|
+
object: {
|
|
131
|
+
[keyToReplace]: newTranslation,
|
|
132
|
+
},
|
|
133
|
+
openai,
|
|
134
|
+
model: config.model,
|
|
135
|
+
})
|
|
83
136
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
locale,
|
|
87
|
-
defaultNamespace,
|
|
88
|
-
)
|
|
137
|
+
newValue = translation[keyToReplace]
|
|
138
|
+
}
|
|
89
139
|
|
|
90
|
-
|
|
140
|
+
const existingKeys = await loadLocalesFile(loadPath, locale, namespace)
|
|
141
|
+
existingKeys[keyToReplace] = newValue
|
|
142
|
+
await writeLocalesFile(savePath, locale, namespace, existingKeys)
|
|
91
143
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
)
|
|
144
|
+
console.log(
|
|
145
|
+
`Updated "${keyToReplace}" in ${locale} (${namespace}): "${newValue}"`,
|
|
146
|
+
)
|
|
147
|
+
}
|
|
97
148
|
}
|
|
98
149
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// Export command functions for programmatic usage
|
|
2
2
|
export { checkMissing } from "./commands/check-missing"
|
|
3
3
|
export { removeUnusedKeys } from "./commands/clean"
|
|
4
|
-
|
|
5
|
-
export { createPrunedNamespaceAutomated } from "./commands/create-pruned-namespace-automated"
|
|
4
|
+
|
|
6
5
|
export { replaceTranslation } from "./commands/replace"
|
|
7
6
|
export { translateMissing } from "./commands/scan"
|
|
8
7
|
export { syncLocales } from "./commands/sync-locales"
|
|
@@ -11,13 +10,9 @@ export { syncLocales } from "./commands/sync-locales"
|
|
|
11
10
|
export { loadConfig } from "./lib/utils"
|
|
12
11
|
|
|
13
12
|
// Export types
|
|
14
|
-
|
|
15
|
-
PruneOptions,
|
|
16
|
-
PruneResponse,
|
|
17
|
-
PruneResult,
|
|
18
|
-
} from "./commands/create-pruned-namespace-automated"
|
|
13
|
+
|
|
19
14
|
export type {
|
|
20
15
|
CommandType,
|
|
21
16
|
Configuration,
|
|
22
|
-
|
|
17
|
+
GlobPatternConfig,
|
|
23
18
|
} from "./lib/types"
|
package/src/lib/types.ts
CHANGED
|
@@ -7,10 +7,9 @@ type Model =
|
|
|
7
7
|
| "gemini-2.0-flash"
|
|
8
8
|
| "gemini-2.0-flash-lite"
|
|
9
9
|
|
|
10
|
-
export interface
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
globPatterns: string[]
|
|
10
|
+
export interface GlobPatternConfig {
|
|
11
|
+
pattern: string
|
|
12
|
+
namespaces: string[]
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
export interface Configuration {
|
|
@@ -28,7 +27,7 @@ export interface Configuration {
|
|
|
28
27
|
defaultNamespace: string
|
|
29
28
|
namespaces: string[]
|
|
30
29
|
locales: string[]
|
|
31
|
-
globPatterns: string[]
|
|
30
|
+
globPatterns: (string | GlobPatternConfig)[]
|
|
32
31
|
context?: string
|
|
33
32
|
disableTranslation?: boolean
|
|
34
33
|
autoClear?: boolean
|
|
@@ -36,7 +35,6 @@ export interface Configuration {
|
|
|
36
35
|
GEMINI_API_KEY?: string
|
|
37
36
|
model?: Model
|
|
38
37
|
openai?: OpenAI
|
|
39
|
-
pruneNamespaces?: NamespacePruneConfig[]
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
export interface CommandType {
|