@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/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
- const getMissingKeys = async ({ globPatterns, namespaces, defaultNamespace, defaultLocale, loadPath, }) => {
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 files = await (0, fast_glob_1.default)([...globPatterns, "!**/node_modules/**"]);
128
- const keys = [];
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
- keys.push(key);
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
- const uniqueKeys = removeDuplicatesFromArray(keys);
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
- for (const namespace of namespaces) {
138
- const existingKeys = await (0, exports.loadLocalesFile)(loadPath, defaultLocale, namespace);
139
- console.log(Object.keys(existingKeys).length, "existing keys");
140
- for (const key of uniqueKeys) {
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 (!pureKey) {
143
- continue;
213
+ if (pureKey) {
214
+ keysByNamespace[namespace].add(pureKey);
144
215
  }
145
- if (!existingKeys[pureKey]) {
146
- newKeys.push({ key: pureKey, namespace });
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
  }
@@ -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.18.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
- import { createPrunedNamespace } from "./commands/create-pruned-namespace"
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) {
@@ -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
- // Set up the parser
23
- const parser = new Parser({
24
- nsSeparator: false,
25
- keySeparator: false,
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
- // Process each namespace and locale
50
- for (const namespace of namespaces) {
51
- // Build a set of pure keys that are actually used in the codebase for this namespace
52
- const usedKeysSet = new Set<string>()
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
- usedKeysSet.add(pureKey)
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) {
@@ -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 (keys: Record<string, string>) => {
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 (!keys[keyToReplace]) {
18
+ if (!allAvailableKeys[keyToReplace]) {
15
19
  console.log(`The key "${keyToReplace}" does not exist.`)
16
- return await getKeyToReplace(keys)
20
+ return await getKeyToReplace(allAvailableKeys)
17
21
  }
18
22
 
19
- console.log(`The key "${keyToReplace}" exists.`)
20
- return keyToReplace
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
- const keys = await loadLocalesFile(
40
- config.loadPath,
41
- config.defaultLocale,
42
- config.defaultNamespace,
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 (keys[key]) {
72
+ if (allAvailableKeys[key]) {
49
73
  keyToReplace = key
50
- console.log(`The key "${keyToReplace}" exists.`)
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
- keyToReplace = await getKeyToReplace(keys)
97
+ const result = await getKeyToReplace(allAvailableKeys)
98
+ keyToReplace = result.key
99
+ targetNamespaces = result.namespaces
54
100
  }
55
101
  } else {
56
- keyToReplace = await getKeyToReplace(keys)
102
+ const result = await getKeyToReplace(allAvailableKeys)
103
+ keyToReplace = result.key
104
+ targetNamespaces = result.namespaces
57
105
  }
58
106
 
59
- console.log(
60
- `The current translation in ${defaultLocale} for "${keyToReplace}" is "${keys[keyToReplace]}".`,
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
- for (const locale of locales) {
66
- let newValue = ""
67
- if (locale === defaultLocale) {
68
- newValue = newTranslation
69
- } else {
70
- const translation = await translateKey({
71
- context,
72
- inputLanguage: defaultLocale,
73
- outputLanguage: locale,
74
- object: {
75
- [keyToReplace]: newTranslation,
76
- },
77
- openai,
78
- model: config.model,
79
- })
80
-
81
- newValue = translation[keyToReplace]
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
- const existingKeys = await loadLocalesFile(
85
- loadPath,
86
- locale,
87
- defaultNamespace,
88
- )
137
+ newValue = translation[keyToReplace]
138
+ }
89
139
 
90
- existingKeys[keyToReplace] = newValue
140
+ const existingKeys = await loadLocalesFile(loadPath, locale, namespace)
141
+ existingKeys[keyToReplace] = newValue
142
+ await writeLocalesFile(savePath, locale, namespace, existingKeys)
91
143
 
92
- writeLocalesFile(savePath, locale, defaultNamespace, existingKeys)
93
-
94
- console.log(
95
- `The new translation for "${keyToReplace}" in ${locale} is "${newValue}".`,
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
- export { createPrunedNamespace } from "./commands/create-pruned-namespace"
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
- export type {
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
- NamespacePruneConfig,
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 NamespacePruneConfig {
11
- sourceNamespace: string
12
- newNamespace: string
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 {