@scoutello/i18n-magic 0.16.0 โ†’ 0.19.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.
Files changed (64) hide show
  1. package/README.md +207 -19
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +101 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/check-missing.d.ts +1 -0
  7. package/dist/commands/check-missing.d.ts.map +1 -0
  8. package/dist/commands/check-missing.js +13 -0
  9. package/dist/commands/check-missing.js.map +1 -0
  10. package/dist/commands/clean.d.ts +1 -0
  11. package/dist/commands/clean.d.ts.map +1 -0
  12. package/dist/commands/clean.js +82 -0
  13. package/dist/commands/clean.js.map +1 -0
  14. package/dist/commands/create-pruned-namespace-automated.d.ts +20 -0
  15. package/dist/commands/create-pruned-namespace-automated.d.ts.map +1 -0
  16. package/dist/commands/create-pruned-namespace-automated.js +98 -0
  17. package/dist/commands/create-pruned-namespace-automated.js.map +1 -0
  18. package/dist/commands/create-pruned-namespace.d.ts +3 -0
  19. package/dist/commands/create-pruned-namespace.d.ts.map +1 -0
  20. package/dist/commands/create-pruned-namespace.js +123 -0
  21. package/dist/commands/create-pruned-namespace.js.map +1 -0
  22. package/dist/commands/replace.d.ts +1 -0
  23. package/dist/commands/replace.d.ts.map +1 -0
  24. package/dist/commands/replace.js +58 -0
  25. package/dist/commands/replace.js.map +1 -0
  26. package/dist/commands/scan.d.ts +1 -0
  27. package/dist/commands/scan.d.ts.map +1 -0
  28. package/dist/commands/scan.js +70 -0
  29. package/dist/commands/scan.js.map +1 -0
  30. package/dist/commands/sync-locales.d.ts +1 -0
  31. package/dist/commands/sync-locales.d.ts.map +1 -0
  32. package/dist/commands/sync-locales.js +78 -0
  33. package/dist/commands/sync-locales.js.map +1 -0
  34. package/dist/i18n-magic.cjs.development.js +348 -130
  35. package/dist/i18n-magic.cjs.development.js.map +1 -1
  36. package/dist/i18n-magic.cjs.production.min.js +1 -1
  37. package/dist/i18n-magic.cjs.production.min.js.map +1 -1
  38. package/dist/i18n-magic.esm.js +339 -130
  39. package/dist/i18n-magic.esm.js.map +1 -1
  40. package/dist/index.d.ts +11 -1
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +22 -9
  43. package/dist/index.js.map +1 -0
  44. package/dist/lib/languges.d.ts +1 -0
  45. package/dist/lib/languges.d.ts.map +1 -0
  46. package/dist/lib/languges.js +146 -0
  47. package/dist/lib/languges.js.map +1 -0
  48. package/dist/lib/types.d.ts +7 -1
  49. package/dist/lib/types.d.ts.map +1 -0
  50. package/dist/lib/types.js +3 -0
  51. package/dist/lib/types.js.map +1 -0
  52. package/dist/lib/utils.d.ts +20 -1
  53. package/dist/lib/utils.d.ts.map +1 -0
  54. package/dist/lib/utils.js +264 -0
  55. package/dist/lib/utils.js.map +1 -0
  56. package/package.json +38 -14
  57. package/src/cli.ts +117 -0
  58. package/src/commands/clean.ts +4 -1
  59. package/src/commands/create-pruned-namespace-automated.ts +165 -0
  60. package/src/commands/create-pruned-namespace.ts +168 -0
  61. package/src/commands/scan.ts +12 -0
  62. package/src/index.ts +23 -113
  63. package/src/lib/types.ts +7 -1
  64. package/src/lib/utils.ts +59 -2
package/README.md CHANGED
@@ -1,25 +1,78 @@
1
- # i18n Magic
1
+ # i18n Magic โœจ
2
2
 
3
- Your CLI toolkit to help you with managing your translations in your project.
3
+ **The intelligent CLI toolkit that automates your internationalization workflow with AI-powered translations.**
4
4
 
5
- This currently works for JSON based translation systems
5
+ i18n Magic streamlines the entire translation management process for your JavaScript/TypeScript projects. Say goodbye to manually maintaining translation files and hello to automated, context-aware translations that keep your international users happy.
6
6
 
7
- To use:
7
+ ## ๐Ÿš€ What it does
8
8
 
9
- 1. Create an API key in your `.env` file (either `OPENAI_API_KEY` or `GEMINI_API_KEY`)
10
- 2. Create a config file, called `i18n-magic.js` in your project root.
9
+ - **๐Ÿ” Smart Detection**: Automatically scans your codebase to find translation keys
10
+ - **๐Ÿค– AI Translation**: Generates high-quality translations using OpenAI or Gemini models
11
+ - **๐Ÿ”„ Sync & Maintain**: Keeps all your locales in perfect sync
12
+ - **๐Ÿงน Clean & Optimize**: Removes unused translations and creates optimized bundles
13
+ - **โšก CI/CD Ready**: Perfect for automated workflows and deployment pipelines
11
14
 
12
- The content of the file should look something like this:
15
+ ## ๐Ÿ“‹ Requirements
16
+
17
+ - JSON-based i18n libraries (react-i18next, next-i18next, vue-i18n, etc.)
18
+ - Node.js 16+
19
+ - An OpenAI or Google Gemini API key
20
+
21
+ ## ๐Ÿ› ๏ธ Quick Setup
22
+
23
+ ### 1. Install the package
24
+
25
+ ```bash
26
+ npm install -g @scoutello/i18n-magic
27
+ # or use directly with npx
28
+ npx @scoutello/i18n-magic
29
+ ```
30
+
31
+ ### 2. Set up your API key
32
+
33
+ Create a `.env` file in your project root:
34
+
35
+ ```bash
36
+ # Choose one:
37
+ OPENAI_API_KEY=your_openai_api_key_here
38
+ # OR
39
+ GEMINI_API_KEY=your_gemini_api_key_here
40
+ ```
41
+
42
+ ### 3. Create your configuration
43
+
44
+ Create an `i18n-magic.js` file in your project root with your project-specific settings:
13
45
 
14
46
  ```js
15
47
  module.exports = {
16
- globPatterns: ['./components/**/*.tsx', './pages/**/*.tsx', './lib/**/*.ts'],
48
+ globPatterns: [
49
+ './components/**/*.tsx',
50
+ './pages/**/*.tsx',
51
+ './lib/**/*.ts',
52
+ // Namespace-specific patterns for pruned translations
53
+ {
54
+ pattern: './apps/dashboard/**/*.tsx',
55
+ namespaces: ['dashboard'],
56
+ },
57
+ {
58
+ pattern: './apps/dashboard/**/*.ts',
59
+ namespaces: ['dashboard'],
60
+ },
61
+ {
62
+ pattern: './apps/mobile/**/*.tsx',
63
+ namespaces: ['mobile'],
64
+ },
65
+ {
66
+ pattern: './apps/mobile/**/*.ts',
67
+ namespaces: ['mobile'],
68
+ },
69
+ ],
17
70
  loadPath: 'locales/{{lng}}/{{ns}}.json',
18
71
  savePath: 'locales/{{lng}}/{{ns}}.json',
19
72
  locales: ['en', 'de'],
20
73
  defaultLocale: 'de',
21
74
  defaultNamespace: 'common',
22
- namespaces: ['common', 'forms'],
75
+ namespaces: ['common', 'forms', 'dashboard', 'mobile'],
23
76
  context:
24
77
  'This is a context which increases the quality of the translations by giving context to the LLM',
25
78
  // Optional configurations
@@ -27,10 +80,48 @@ module.exports = {
27
80
  OPENAI_API_KEY: '.', // Alternative to using .env file
28
81
  GEMINI_API_KEY: '', // Alternative to using .env file
29
82
  disableTranslation: false, // Set to true to skip automatic translations during the scan step. Useful if you want to sync the other languages during CI/CD using sync.
83
+ autoClear: true, // When using the scan command, always run the clean before
30
84
  };
31
85
  ```
32
86
 
33
- You can also provide custom functions for `loadPath` and `savePath` to store translations in other systems like S3:
87
+ #### Glob Patterns Configuration
88
+
89
+ The `globPatterns` array supports two formats:
90
+
91
+ 1. **String patterns**: Simple glob patterns that apply to all namespaces
92
+
93
+ ```js
94
+ './components/**/*.tsx';
95
+ ```
96
+
97
+ 2. **Object patterns**: Patterns with namespace-specific configuration for pruned translations
98
+ ```js
99
+ {
100
+ pattern: './apps/dashboard/**/*.tsx',
101
+ namespaces: ['dashboard']
102
+ }
103
+ ```
104
+
105
+ When using object patterns, translation keys found in files matching that pattern will be associated with the specified namespaces. This enables automatic creation of namespace-specific translation bundles.
106
+
107
+ ### 4. Start using i18n Magic
108
+
109
+ ```bash
110
+ # Scan for missing translations and add them
111
+ npx @scoutello/i18n-magic scan
112
+
113
+ # Check what's missing without making changes
114
+ npx @scoutello/i18n-magic check-missing
115
+
116
+ # Sync all locales from your default language
117
+ npx @scoutello/i18n-magic sync
118
+ ```
119
+
120
+ ## ๐Ÿ”ง Advanced Configuration
121
+
122
+ ### Custom Storage Solutions
123
+
124
+ You can provide custom functions for `loadPath` and `savePath` to store translations in other systems like S3, databases, or CDNs:
34
125
 
35
126
  ```js
36
127
  const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3")
@@ -73,19 +164,42 @@ module.exports = {
73
164
  };
74
165
  ```
75
166
 
76
- then just run:
167
+ ## ๐Ÿ“š Available Commands
168
+
169
+ All commands can be run with:
77
170
 
78
171
  ```bash
79
172
  npx @scoutello/i18n-magic [command]
80
173
  ```
81
174
 
82
- `scan`
175
+ ### `scan`
176
+
177
+ Scan your codebase for missing translations and automatically generate them. This command analyzes your code to find translation keys that don't exist in your translation files yet.
83
178
 
84
- Scan for missing translations, get prompted for each, translate it to the other locales and save it to the JSON file.
179
+ The command will:
85
180
 
86
- `replace`
181
+ 1. Scan all files matching your glob patterns for translation usage
182
+ 2. Identify missing translation keys in your default locale
183
+ 3. Prompt you to provide translations for each missing key
184
+ 4. Automatically translate to all other configured locales using AI
185
+ 5. Save the new translations to your JSON files
87
186
 
88
- Replace a translation based on the key, and translate it to the other locales and save it to the JSON file.
187
+ This is useful for:
188
+
189
+ - Adding new translations during development
190
+ - Ensuring all translation keys have corresponding values
191
+ - Maintaining translation consistency across locales
192
+
193
+ ### `replace`
194
+
195
+ Update an existing translation key with a new value and automatically translate it to all other locales. This command allows you to modify existing translations while maintaining consistency across all languages.
196
+
197
+ The command will:
198
+
199
+ 1. Prompt you to select or specify the translation key to replace
200
+ 2. Ask for the new translation value in your default locale
201
+ 3. Automatically translate the new value to all other configured locales using AI
202
+ 4. Update all translation files with the new values
89
203
 
90
204
  You can specify the key in two ways:
91
205
 
@@ -94,10 +208,84 @@ You can specify the key in two ways:
94
208
 
95
209
  If no key is provided, you will be prompted to enter one.
96
210
 
97
- `check-missing`
211
+ This is useful for:
212
+
213
+ - Updating existing translations that need changes
214
+ - Fixing translation errors across all locales
215
+ - Maintaining consistency when modifying content
216
+
217
+ ### `check-missing`
218
+
219
+ Check if there are any missing translations without making any changes. This command performs a dry-run analysis to identify translation gaps in your project.
220
+
221
+ The command will:
222
+
223
+ 1. Scan all files matching your glob patterns for translation usage
224
+ 2. Check if all found translation keys exist in your translation files
225
+ 3. Report any missing translations without prompting for input
226
+ 4. Exit with an error code if missing translations are found
227
+
228
+ This is useful for:
229
+
230
+ - CI/CD pipelines to ensure translation completeness
231
+ - Pre-commit hooks to catch missing translations early
232
+ - Quality assurance checks before deployment
233
+ - Automated testing of translation coverage
234
+
235
+ ### `sync`
236
+
237
+ Synchronize translations from your default locale to all other configured locales using AI translation. This command takes existing translations in your default language and generates corresponding translations for all other locales.
238
+
239
+ The command will:
240
+
241
+ 1. Load all translation keys from your default locale
242
+ 2. Identify keys that are missing in other locales
243
+ 3. Automatically translate missing keys using AI
244
+ 4. Update translation files for all non-default locales
245
+ 5. Preserve existing translations (only adds missing ones)
246
+
247
+ This is useful for:
248
+
249
+ - CI/CD pipelines to ensure all locales are up-to-date
250
+ - Batch translation of new content
251
+ - Maintaining translation parity across languages
252
+ - Automated deployment workflows
253
+
254
+ **Note**: This command works best when used with `disableTranslation: true` in your config to separate the scanning and translation phases.
255
+
256
+ ### `prune`
257
+
258
+ Create a pruned namespace from an existing namespace, containing only the translation keys that are actually used in specific files. This is useful for creating optimized translation bundles for different parts of your application (e.g., dashboard, mobile app, etc.).
259
+
260
+ The command will:
261
+
262
+ 1. Prompt you to select a source namespace to prune from
263
+ 2. Ask for a name for the new namespace
264
+ 3. Ask for glob patterns to scan for translation usage
265
+ 4. Extract all translation keys used in the matched files
266
+ 5. Create new translation files for all locales containing only the used keys
267
+
268
+ This is particularly useful for:
269
+
270
+ - Creating namespace-specific translation bundles
271
+ - Reducing bundle size by including only necessary translations
272
+ - Optimizing performance in micro-frontends or modular applications
273
+
274
+ You can also automate this process using the `pruneNamespaces` configuration in your `i18n-magic.js` file (see configuration example above).
275
+
276
+ ### `clean`
277
+
278
+ Remove unused translation keys from all locales. This command scans your codebase to find which translation keys are actually being used and removes any keys that are no longer referenced in your code.
279
+
280
+ The command will:
98
281
 
99
- Checks if there are any missing translations. Useful for CI/CD or for a husky hook.
282
+ 1. Scan all files matching your glob patterns for translation usage
283
+ 2. Compare found keys with existing translation files
284
+ 3. Remove unused keys from all locale files
285
+ 4. Report how many keys were removed
100
286
 
101
- `sync`
287
+ This is useful for:
102
288
 
103
- Sync the translations from the default locale to the other locales. Useful for a CI/CD pipeline or husky hook. Should be used together with `disableTranslation: true`
289
+ - Keeping translation files clean and maintainable
290
+ - Reducing bundle size by removing dead translations
291
+ - Regular maintenance in CI/CD pipelines
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const commander_1 = require("commander");
8
+ const dotenv_1 = __importDefault(require("dotenv"));
9
+ const openai_1 = __importDefault(require("openai"));
10
+ const check_missing_1 = require("./commands/check-missing");
11
+ const clean_1 = require("./commands/clean");
12
+ const create_pruned_namespace_1 = require("./commands/create-pruned-namespace");
13
+ const replace_1 = require("./commands/replace");
14
+ const scan_1 = require("./commands/scan");
15
+ const sync_locales_1 = require("./commands/sync-locales");
16
+ const utils_1 = require("./lib/utils");
17
+ const program = new commander_1.Command();
18
+ program
19
+ .name("i18n-magic")
20
+ .description("CLI to help you manage your locales JSON with translations, replacements, etc. with OpenAI.")
21
+ .version("0.2.0")
22
+ .option("-c, --config <path>", "path to config file")
23
+ .option("-e, --env <path>", "path to .env file");
24
+ const commands = [
25
+ {
26
+ name: "scan",
27
+ description: "Scan for missing translations, get prompted for each, translate it to the other locales and save it to the JSON file.",
28
+ action: scan_1.translateMissing,
29
+ },
30
+ {
31
+ name: "replace",
32
+ description: "Replace a translation based on the key, and translate it to the other locales and save it to the JSON file.",
33
+ action: replace_1.replaceTranslation,
34
+ },
35
+ {
36
+ name: "check-missing",
37
+ description: "Check if there are any missing translations. Useful for a CI/CD pipeline or husky hook.",
38
+ action: check_missing_1.checkMissing,
39
+ },
40
+ {
41
+ name: "sync",
42
+ description: "Sync the translations from the default locale to the other locales. Useful for a CI/CD pipeline or husky hook.",
43
+ action: sync_locales_1.syncLocales,
44
+ },
45
+ {
46
+ name: "clean",
47
+ description: "Remove unused translations from all locales. Useful for a CI/CD pipeline or husky hook.",
48
+ action: clean_1.removeUnusedKeys,
49
+ },
50
+ {
51
+ name: "prune",
52
+ description: "Create a pruned namespace from the other namespaces.",
53
+ action: create_pruned_namespace_1.createPrunedNamespace,
54
+ },
55
+ ];
56
+ for (const command of commands) {
57
+ const cmd = program.command(command.name).description(command.description);
58
+ // Add key option to replace command
59
+ if (command.name === "replace") {
60
+ cmd
61
+ .option("-k, --key <key>", "translation key to replace")
62
+ .allowExcessArguments(true)
63
+ .argument("[key]", "translation key to replace");
64
+ }
65
+ cmd.action(async (arg, options) => {
66
+ const res = dotenv_1.default.config({
67
+ path: program.opts().env || ".env",
68
+ });
69
+ const config = await (0, utils_1.loadConfig)({
70
+ configPath: program.opts().config,
71
+ });
72
+ const isGemini = config.model?.includes("gemini");
73
+ // Get API key from environment or config
74
+ const openaiKey = res.parsed.OPENAI_API_KEY || config.OPENAI_API_KEY;
75
+ const geminiKey = res.parsed.GEMINI_API_KEY || config.GEMINI_API_KEY;
76
+ // Select appropriate key based on model type
77
+ const key = isGemini ? geminiKey : openaiKey;
78
+ if (!key) {
79
+ const keyType = isGemini ? "GEMINI_API_KEY" : "OPENAI_API_KEY";
80
+ console.error(`Please provide a${isGemini ? " Gemini" : "n OpenAI"} API key in your .env file or config, called ${keyType}.`);
81
+ process.exit(1);
82
+ }
83
+ const openai = new openai_1.default({
84
+ apiKey: key,
85
+ ...(isGemini && {
86
+ baseURL: "https://generativelanguage.googleapis.com/v1beta/openai/",
87
+ }),
88
+ });
89
+ // For replace command, check for key in argument or option
90
+ if (command.name === "replace") {
91
+ // If key is provided as positional argument, use that first
92
+ const keyToUse = typeof arg === "string" ? arg : options.key;
93
+ command.action({ ...config, openai }, keyToUse);
94
+ }
95
+ else {
96
+ command.action({ ...config, openai });
97
+ }
98
+ });
99
+ }
100
+ program.parse(process.argv);
101
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,3 @@
1
1
  import type { Configuration } from "../lib/types";
2
2
  export declare const checkMissing: (config: Configuration) => Promise<void>;
3
+ //# sourceMappingURL=check-missing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-missing.d.ts","sourceRoot":"","sources":["../../src/commands/check-missing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAGjD,eAAO,MAAM,YAAY,GAAU,QAAQ,aAAa,kBAOvD,CAAA"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkMissing = void 0;
4
+ const utils_1 = require("../lib/utils");
5
+ const checkMissing = async (config) => {
6
+ const newKeys = await (0, utils_1.getMissingKeys)(config);
7
+ if (newKeys.length > 0) {
8
+ console.error("Error: Missing translations found!");
9
+ process.exit(1);
10
+ }
11
+ };
12
+ exports.checkMissing = checkMissing;
13
+ //# sourceMappingURL=check-missing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-missing.js","sourceRoot":"","sources":["../../src/commands/check-missing.ts"],"names":[],"mappings":";;;AACA,wCAA6C;AAEtC,MAAM,YAAY,GAAG,KAAK,EAAE,MAAqB,EAAE,EAAE;IAC1D,MAAM,OAAO,GAAG,MAAM,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAA;IAE5C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAA;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC,CAAA;AAPY,QAAA,YAAY,gBAOxB"}
@@ -1,2 +1,3 @@
1
1
  import type { Configuration } from "../lib/types";
2
2
  export declare const removeUnusedKeys: (config: Configuration) => Promise<void>;
3
+ //# sourceMappingURL=clean.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAQjD,eAAO,MAAM,gBAAgB,GAAU,QAAQ,aAAa,kBAgG3D,CAAA"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.removeUnusedKeys = void 0;
7
+ const fast_glob_1 = __importDefault(require("fast-glob"));
8
+ const i18next_scanner_1 = require("i18next-scanner");
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const utils_1 = require("../lib/utils");
11
+ const removeUnusedKeys = async (config) => {
12
+ const { globPatterns, namespaces, defaultNamespace, locales, loadPath, savePath, } = config;
13
+ // Set up the parser
14
+ const parser = new i18next_scanner_1.Parser({
15
+ nsSeparator: false,
16
+ keySeparator: false,
17
+ });
18
+ // Find all files to scan
19
+ const allPatterns = globPatterns.map((pattern) => typeof pattern === "string" ? pattern : pattern.pattern);
20
+ const files = await (0, fast_glob_1.default)([...allPatterns, "!**/node_modules/**"]);
21
+ // Extract all translation keys from the codebase
22
+ const extractedKeys = [];
23
+ for (const file of files) {
24
+ const content = node_fs_1.default.readFileSync(file, "utf-8");
25
+ parser.parseFuncFromString(content, { list: ["t"] }, (key) => {
26
+ extractedKeys.push(key);
27
+ });
28
+ }
29
+ // Remove duplicates
30
+ const uniqueExtractedKeys = (0, utils_1.removeDuplicatesFromArray)(extractedKeys);
31
+ // Track stats for reporting
32
+ const stats = {
33
+ total: 0,
34
+ removed: 0,
35
+ };
36
+ // Process each namespace and locale
37
+ for (const namespace of namespaces) {
38
+ // Build a set of pure keys that are actually used in the codebase for this namespace
39
+ const usedKeysSet = new Set();
40
+ for (const key of uniqueExtractedKeys) {
41
+ const pureKey = (0, utils_1.getPureKey)(key, namespace, namespace === defaultNamespace);
42
+ if (pureKey) {
43
+ usedKeysSet.add(pureKey);
44
+ }
45
+ }
46
+ // Process each locale
47
+ for (const locale of locales) {
48
+ // Load existing keys for this locale and namespace
49
+ const existingKeys = await (0, utils_1.loadLocalesFile)(loadPath, locale, namespace);
50
+ const existingKeysCount = Object.keys(existingKeys).length;
51
+ stats.total += existingKeysCount;
52
+ // Create a new object with only the keys that are used
53
+ const cleanedKeys = {};
54
+ let removedCount = 0;
55
+ for (const [key, value] of Object.entries(existingKeys)) {
56
+ if (usedKeysSet.has(key)) {
57
+ cleanedKeys[key] = value;
58
+ }
59
+ else {
60
+ removedCount++;
61
+ }
62
+ }
63
+ stats.removed += removedCount;
64
+ // Only write the file if keys were removed
65
+ if (removedCount > 0) {
66
+ await (0, utils_1.writeLocalesFile)(savePath, locale, namespace, cleanedKeys);
67
+ console.log(`โœ“ Removed ${removedCount} unused keys from ${locale}:${namespace} (${Object.keys(cleanedKeys).length} keys remaining)`);
68
+ }
69
+ else {
70
+ console.log(`No unused keys found in ${locale}:${namespace}`);
71
+ }
72
+ }
73
+ }
74
+ if (stats.removed > 0) {
75
+ console.log(`โœ… Removed ${stats.removed} unused keys (out of ${stats.total} total keys)`);
76
+ }
77
+ else {
78
+ console.log(`โœ… No unused keys found in the project (${stats.total} total keys)`);
79
+ }
80
+ };
81
+ exports.removeUnusedKeys = removeUnusedKeys;
82
+ //# sourceMappingURL=clean.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean.js","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { Configuration } from "../lib/types";
2
+ export interface PruneOptions {
3
+ sourceNamespace: string;
4
+ newNamespace: string;
5
+ globPatterns: string[];
6
+ }
7
+ export interface PruneResult {
8
+ locale: string;
9
+ keyCount: number;
10
+ success: boolean;
11
+ error?: string;
12
+ }
13
+ export interface PruneResponse {
14
+ success: boolean;
15
+ message: string;
16
+ keysCount: number;
17
+ results?: PruneResult[];
18
+ }
19
+ export declare const createPrunedNamespaceAutomated: (config: Configuration, options: PruneOptions) => Promise<PruneResponse>;
20
+ //# sourceMappingURL=create-pruned-namespace-automated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-pruned-namespace-automated.d.ts","sourceRoot":"","sources":["../../src/commands/create-pruned-namespace-automated.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAQjD,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,WAAW,EAAE,CAAA;CACxB;AAED,eAAO,MAAM,8BAA8B,GACzC,QAAQ,aAAa,EACrB,SAAS,YAAY,KACpB,OAAO,CAAC,aAAa,CAkIvB,CAAA"}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createPrunedNamespaceAutomated = void 0;
7
+ const fast_glob_1 = __importDefault(require("fast-glob"));
8
+ const i18next_scanner_1 = require("i18next-scanner");
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const utils_1 = require("../lib/utils");
11
+ const createPrunedNamespaceAutomated = async (config, options) => {
12
+ const { namespaces, loadPath, savePath, locales, defaultNamespace } = config;
13
+ const { sourceNamespace, newNamespace, globPatterns } = options;
14
+ // Validate inputs
15
+ if (!namespaces.includes(sourceNamespace)) {
16
+ throw new Error(`Source namespace '${sourceNamespace}' not found in configuration`);
17
+ }
18
+ if (namespaces.includes(newNamespace)) {
19
+ throw new Error(`Namespace '${newNamespace}' already exists`);
20
+ }
21
+ console.log(`Creating pruned namespace '${newNamespace}' from '${sourceNamespace}'`);
22
+ console.log(`Using glob patterns: ${globPatterns.join(", ")}`);
23
+ // Extract keys from files matching the glob patterns
24
+ const parser = new i18next_scanner_1.Parser({
25
+ nsSeparator: false,
26
+ keySeparator: false,
27
+ });
28
+ const files = await (0, fast_glob_1.default)([...globPatterns, "!**/node_modules/**"]);
29
+ console.log(`Found ${files.length} files to scan`);
30
+ const extractedKeys = [];
31
+ for (const file of files) {
32
+ const content = node_fs_1.default.readFileSync(file, "utf-8");
33
+ parser.parseFuncFromString(content, { list: ["t"] }, (key) => {
34
+ extractedKeys.push(key);
35
+ });
36
+ }
37
+ const uniqueExtractedKeys = (0, utils_1.removeDuplicatesFromArray)(extractedKeys);
38
+ console.log(`Found ${uniqueExtractedKeys.length} unique translation keys`);
39
+ // Filter keys that belong to the source namespace
40
+ const relevantKeys = [];
41
+ for (const key of uniqueExtractedKeys) {
42
+ const pureKey = (0, utils_1.getPureKey)(key, sourceNamespace, sourceNamespace === defaultNamespace);
43
+ if (pureKey) {
44
+ relevantKeys.push(pureKey);
45
+ }
46
+ }
47
+ console.log(`Found ${relevantKeys.length} keys from namespace '${sourceNamespace}'`);
48
+ if (relevantKeys.length === 0) {
49
+ console.log("No relevant keys found. Exiting...");
50
+ return {
51
+ success: false,
52
+ message: "No relevant keys found",
53
+ keysCount: 0,
54
+ };
55
+ }
56
+ // Get translations from source namespace and create new namespace files
57
+ const results = [];
58
+ for (const locale of locales) {
59
+ try {
60
+ // Load source namespace translations
61
+ const sourceTranslations = await (0, utils_1.loadLocalesFile)(loadPath, locale, sourceNamespace);
62
+ // Create new namespace with only the keys used in the glob pattern files
63
+ const newNamespaceTranslations = {};
64
+ for (const key of relevantKeys) {
65
+ if (sourceTranslations[key]) {
66
+ newNamespaceTranslations[key] = sourceTranslations[key];
67
+ }
68
+ }
69
+ // Write the new namespace file
70
+ await (0, utils_1.writeLocalesFile)(savePath, locale, newNamespace, newNamespaceTranslations);
71
+ const keyCount = Object.keys(newNamespaceTranslations).length;
72
+ console.log(`Created pruned namespace '${newNamespace}' for locale '${locale}' with ${keyCount} keys`);
73
+ results.push({
74
+ locale,
75
+ keyCount,
76
+ success: true,
77
+ });
78
+ }
79
+ catch (error) {
80
+ console.error(`Error creating pruned namespace for locale '${locale}':`, error);
81
+ results.push({
82
+ locale,
83
+ keyCount: 0,
84
+ success: false,
85
+ error: error instanceof Error ? error.message : String(error),
86
+ });
87
+ }
88
+ }
89
+ console.log(`โœ… Successfully created pruned namespace '${newNamespace}'`);
90
+ return {
91
+ success: true,
92
+ message: `Created pruned namespace '${newNamespace}' with ${relevantKeys.length} keys`,
93
+ keysCount: relevantKeys.length,
94
+ results,
95
+ };
96
+ };
97
+ exports.createPrunedNamespaceAutomated = createPrunedNamespaceAutomated;
98
+ //# sourceMappingURL=create-pruned-namespace-automated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-pruned-namespace-automated.js","sourceRoot":"","sources":["../../src/commands/create-pruned-namespace-automated.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Configuration } from "../lib/types";
2
+ export declare const createPrunedNamespace: (config: Configuration) => Promise<void>;
3
+ //# sourceMappingURL=create-pruned-namespace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-pruned-namespace.d.ts","sourceRoot":"","sources":["../../src/commands/create-pruned-namespace.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAQjD,eAAO,MAAM,qBAAqB,GAAU,QAAQ,aAAa,kBA2JhE,CAAA"}