@scoutello/i18n-magic 0.57.5 → 0.57.6

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/cli.js CHANGED
@@ -5,6 +5,7 @@ import OpenAI from "openai";
5
5
  import { checkMissing } from "./commands/check-missing.js";
6
6
  import { removeUnusedKeys } from "./commands/clean.js";
7
7
  import { replaceTranslation } from "./commands/replace.js";
8
+ import { restoreFromNamespaces } from "./commands/restore-from-namespaces.js";
8
9
  import { translateMissing } from "./commands/scan.js";
9
10
  import { syncLocales } from "./commands/sync-locales.js";
10
11
  import { loadConfig } from "./lib/utils.js";
@@ -41,6 +42,11 @@ const commands = [
41
42
  description: "Remove unused translations from all locales. Useful for a CI/CD pipeline or husky hook.",
42
43
  action: removeUnusedKeys,
43
44
  },
45
+ {
46
+ name: "restore-from-namespaces",
47
+ description: "Restore missing keys by searching for them in other namespace files across all locales.",
48
+ action: restoreFromNamespaces,
49
+ },
44
50
  ];
45
51
  for (const command of commands) {
46
52
  const cmd = program.command(command.name).description(command.description);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAQpD,eAAO,MAAM,gBAAgB,GAAU,QAAQ,aAAa,kBAyF3D,CAAA"}
1
+ {"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAQpD,eAAO,MAAM,gBAAgB,GAAU,QAAQ,aAAa,kBA0F3D,CAAA"}
@@ -19,8 +19,9 @@ export const removeUnusedKeys = async (config) => {
19
19
  keysByNamespace[namespace] = new Set();
20
20
  }
21
21
  const pureKey = getPureKey(key, namespace, namespace === defaultNamespace);
22
- if (pureKey) {
23
- keysByNamespace[namespace].add(pureKey);
22
+ const finalKey = pureKey || (!key.includes(":") ? key : null);
23
+ if (finalKey) {
24
+ keysByNamespace[namespace].add(finalKey);
24
25
  }
25
26
  }
26
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"clean.js","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"clean.js","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Configuration } from "../lib/types.js";
2
+ export declare const restoreFromNamespaces: (config: Configuration) => Promise<void>;
3
+ //# sourceMappingURL=restore-from-namespaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restore-from-namespaces.d.ts","sourceRoot":"","sources":["../../src/commands/restore-from-namespaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AASpD,eAAO,MAAM,qBAAqB,GAAU,QAAQ,aAAa,kBA+IhE,CAAA"}
@@ -0,0 +1,102 @@
1
+ import { getKeysWithNamespaces, getPureKey, loadLocalesFile, writeLocalesFile, findExistingTranslations, } from "../lib/utils.js";
2
+ export const restoreFromNamespaces = async (config) => {
3
+ const { globPatterns, namespaces, defaultNamespace, locales, loadPath, savePath, defaultLocale, } = config;
4
+ console.log("šŸ”„ Starting restoration from other namespaces...\n");
5
+ // Get all keys with their associated namespaces from the codebase
6
+ const keysWithNamespaces = await getKeysWithNamespaces({
7
+ globPatterns,
8
+ defaultNamespace,
9
+ });
10
+ // Group keys by namespace
11
+ const keysByNamespace = {};
12
+ for (const { key, namespaces: keyNamespaces } of keysWithNamespaces) {
13
+ for (const namespace of keyNamespaces) {
14
+ if (!keysByNamespace[namespace]) {
15
+ keysByNamespace[namespace] = new Set();
16
+ }
17
+ const pureKey = getPureKey(key, namespace, namespace === defaultNamespace);
18
+ const finalKey = pureKey || (!key.includes(":") ? key : null);
19
+ if (finalKey) {
20
+ keysByNamespace[namespace].add(finalKey);
21
+ }
22
+ }
23
+ }
24
+ // Track stats for reporting
25
+ const stats = {
26
+ totalMissing: 0,
27
+ restored: 0,
28
+ notFound: 0,
29
+ };
30
+ // Process each namespace
31
+ for (const namespace of namespaces) {
32
+ const expectedKeys = keysByNamespace[namespace] || new Set();
33
+ if (expectedKeys.size === 0) {
34
+ console.log(`ā­ļø Skipping ${namespace}: no keys expected in codebase\n`);
35
+ continue;
36
+ }
37
+ console.log(`šŸ“¦ Processing namespace: ${namespace}`);
38
+ console.log(` Expected keys in codebase: ${expectedKeys.size}`);
39
+ // Load existing keys for default locale in this namespace
40
+ const existingKeys = await loadLocalesFile(loadPath, defaultLocale, namespace);
41
+ const existingKeysSet = new Set(Object.keys(existingKeys));
42
+ // Find missing keys
43
+ const missingKeys = Array.from(expectedKeys).filter((key) => !existingKeysSet.has(key));
44
+ if (missingKeys.length === 0) {
45
+ console.log(` āœ… No missing keys in ${namespace}\n`);
46
+ continue;
47
+ }
48
+ console.log(` āŒ Missing keys: ${missingKeys.length}`);
49
+ stats.totalMissing += missingKeys.length;
50
+ // Search for these keys in other namespaces
51
+ const otherNamespaces = namespaces.filter((ns) => ns !== namespace);
52
+ console.log(` šŸ” Searching in: ${otherNamespaces.join(", ")}`);
53
+ // For each locale, find and restore missing keys
54
+ const restoredByLocale = {};
55
+ for (const locale of locales) {
56
+ const existingTranslations = await findExistingTranslations(missingKeys, otherNamespaces, locale, loadPath, { silent: true });
57
+ // Count how many we found
58
+ const foundKeys = Object.entries(existingTranslations).filter(([_, value]) => value !== null);
59
+ if (foundKeys.length === 0) {
60
+ continue;
61
+ }
62
+ // Load the current namespace file for this locale
63
+ const currentKeys = await loadLocalesFile(loadPath, locale, namespace);
64
+ // Add the found keys
65
+ for (const [key, value] of foundKeys) {
66
+ if (value !== null) {
67
+ currentKeys[key] = value;
68
+ }
69
+ }
70
+ // Save the updated file
71
+ await writeLocalesFile(savePath, locale, namespace, currentKeys);
72
+ restoredByLocale[locale] = foundKeys.length;
73
+ // Track stats (only count once per key, not per locale)
74
+ if (locale === defaultLocale) {
75
+ stats.restored += foundKeys.length;
76
+ }
77
+ }
78
+ // Log results
79
+ const restoredInDefault = restoredByLocale[defaultLocale] || 0;
80
+ const stillMissing = missingKeys.length - restoredInDefault;
81
+ stats.notFound += stillMissing;
82
+ console.log(` āœ… Restored: ${restoredInDefault} keys across ${Object.keys(restoredByLocale).length} locales`);
83
+ if (stillMissing > 0) {
84
+ console.log(` āš ļø Still missing: ${stillMissing} keys (not found in any namespace)`);
85
+ }
86
+ console.log("");
87
+ }
88
+ // Final summary
89
+ console.log("=".repeat(60));
90
+ console.log("šŸ“Š Restoration Summary:");
91
+ console.log(` Total missing keys found: ${stats.totalMissing}`);
92
+ console.log(` Successfully restored: ${stats.restored}`);
93
+ console.log(` Not found in any namespace: ${stats.notFound}`);
94
+ if (stats.notFound > 0) {
95
+ console.log(`\nšŸ’” Next steps:`);
96
+ console.log(` Run 'pnpm trans' to add the ${stats.notFound} missing keys manually`);
97
+ }
98
+ else {
99
+ console.log("\n✨ All keys successfully restored!");
100
+ }
101
+ };
102
+ //# sourceMappingURL=restore-from-namespaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restore-from-namespaces.js","sourceRoot":"","sources":["../../src/commands/restore-from-namespaces.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.57.5",
3
+ "version": "0.57.6",
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",
package/src/cli.ts CHANGED
@@ -5,6 +5,7 @@ import { checkMissing } from "./commands/check-missing.js"
5
5
  import { removeUnusedKeys } from "./commands/clean.js"
6
6
 
7
7
  import { replaceTranslation } from "./commands/replace.js"
8
+ import { restoreFromNamespaces } from "./commands/restore-from-namespaces.js"
8
9
  import { translateMissing } from "./commands/scan.js"
9
10
  import { syncLocales } from "./commands/sync-locales.js"
10
11
  import type { CommandType, Configuration } from "./lib/types.js"
@@ -52,6 +53,12 @@ const commands: CommandType[] = [
52
53
  "Remove unused translations from all locales. Useful for a CI/CD pipeline or husky hook.",
53
54
  action: removeUnusedKeys,
54
55
  },
56
+ {
57
+ name: "restore-from-namespaces",
58
+ description:
59
+ "Restore missing keys by searching for them in other namespace files across all locales.",
60
+ action: restoreFromNamespaces,
61
+ },
55
62
  ]
56
63
 
57
64
  for (const command of commands) {
@@ -38,8 +38,9 @@ export const removeUnusedKeys = async (config: Configuration) => {
38
38
  }
39
39
 
40
40
  const pureKey = getPureKey(key, namespace, namespace === defaultNamespace)
41
- if (pureKey) {
42
- keysByNamespace[namespace].add(pureKey)
41
+ const finalKey = pureKey || (!key.includes(":") ? key : null)
42
+ if (finalKey) {
43
+ keysByNamespace[namespace].add(finalKey)
43
44
  }
44
45
  }
45
46
  }
@@ -0,0 +1,153 @@
1
+ import type { Configuration } from "../lib/types.js"
2
+ import {
3
+ getKeysWithNamespaces,
4
+ getPureKey,
5
+ loadLocalesFile,
6
+ writeLocalesFile,
7
+ findExistingTranslations,
8
+ } from "../lib/utils.js"
9
+
10
+ export const restoreFromNamespaces = async (config: Configuration) => {
11
+ const {
12
+ globPatterns,
13
+ namespaces,
14
+ defaultNamespace,
15
+ locales,
16
+ loadPath,
17
+ savePath,
18
+ defaultLocale,
19
+ } = config
20
+
21
+ console.log("šŸ”„ Starting restoration from other namespaces...\n")
22
+
23
+ // Get all keys with their associated namespaces from the codebase
24
+ const keysWithNamespaces = await getKeysWithNamespaces({
25
+ globPatterns,
26
+ defaultNamespace,
27
+ })
28
+
29
+ // Group keys by namespace
30
+ const keysByNamespace: Record<string, Set<string>> = {}
31
+
32
+ for (const { key, namespaces: keyNamespaces } of keysWithNamespaces) {
33
+ for (const namespace of keyNamespaces) {
34
+ if (!keysByNamespace[namespace]) {
35
+ keysByNamespace[namespace] = new Set()
36
+ }
37
+
38
+ const pureKey = getPureKey(key, namespace, namespace === defaultNamespace)
39
+ const finalKey = pureKey || (!key.includes(":") ? key : null)
40
+ if (finalKey) {
41
+ keysByNamespace[namespace].add(finalKey)
42
+ }
43
+ }
44
+ }
45
+
46
+ // Track stats for reporting
47
+ const stats = {
48
+ totalMissing: 0,
49
+ restored: 0,
50
+ notFound: 0,
51
+ }
52
+
53
+ // Process each namespace
54
+ for (const namespace of namespaces) {
55
+ const expectedKeys = keysByNamespace[namespace] || new Set()
56
+
57
+ if (expectedKeys.size === 0) {
58
+ console.log(`ā­ļø Skipping ${namespace}: no keys expected in codebase\n`)
59
+ continue
60
+ }
61
+
62
+ console.log(`šŸ“¦ Processing namespace: ${namespace}`)
63
+ console.log(` Expected keys in codebase: ${expectedKeys.size}`)
64
+
65
+ // Load existing keys for default locale in this namespace
66
+ const existingKeys = await loadLocalesFile(loadPath, defaultLocale, namespace)
67
+ const existingKeysSet = new Set(Object.keys(existingKeys))
68
+
69
+ // Find missing keys
70
+ const missingKeys = Array.from(expectedKeys).filter(
71
+ (key) => !existingKeysSet.has(key)
72
+ )
73
+
74
+ if (missingKeys.length === 0) {
75
+ console.log(` āœ… No missing keys in ${namespace}\n`)
76
+ continue
77
+ }
78
+
79
+ console.log(` āŒ Missing keys: ${missingKeys.length}`)
80
+ stats.totalMissing += missingKeys.length
81
+
82
+ // Search for these keys in other namespaces
83
+ const otherNamespaces = namespaces.filter((ns) => ns !== namespace)
84
+
85
+ console.log(` šŸ” Searching in: ${otherNamespaces.join(", ")}`)
86
+
87
+ // For each locale, find and restore missing keys
88
+ const restoredByLocale: Record<string, number> = {}
89
+
90
+ for (const locale of locales) {
91
+ const existingTranslations = await findExistingTranslations(
92
+ missingKeys,
93
+ otherNamespaces,
94
+ locale,
95
+ loadPath,
96
+ { silent: true }
97
+ )
98
+
99
+ // Count how many we found
100
+ const foundKeys = Object.entries(existingTranslations).filter(
101
+ ([_, value]) => value !== null
102
+ )
103
+
104
+ if (foundKeys.length === 0) {
105
+ continue
106
+ }
107
+
108
+ // Load the current namespace file for this locale
109
+ const currentKeys = await loadLocalesFile(loadPath, locale, namespace)
110
+
111
+ // Add the found keys
112
+ for (const [key, value] of foundKeys) {
113
+ if (value !== null) {
114
+ currentKeys[key] = value
115
+ }
116
+ }
117
+
118
+ // Save the updated file
119
+ await writeLocalesFile(savePath, locale, namespace, currentKeys)
120
+ restoredByLocale[locale] = foundKeys.length
121
+
122
+ // Track stats (only count once per key, not per locale)
123
+ if (locale === defaultLocale) {
124
+ stats.restored += foundKeys.length
125
+ }
126
+ }
127
+
128
+ // Log results
129
+ const restoredInDefault = restoredByLocale[defaultLocale] || 0
130
+ const stillMissing = missingKeys.length - restoredInDefault
131
+ stats.notFound += stillMissing
132
+
133
+ console.log(` āœ… Restored: ${restoredInDefault} keys across ${Object.keys(restoredByLocale).length} locales`)
134
+ if (stillMissing > 0) {
135
+ console.log(` āš ļø Still missing: ${stillMissing} keys (not found in any namespace)`)
136
+ }
137
+ console.log("")
138
+ }
139
+
140
+ // Final summary
141
+ console.log("=" .repeat(60))
142
+ console.log("šŸ“Š Restoration Summary:")
143
+ console.log(` Total missing keys found: ${stats.totalMissing}`)
144
+ console.log(` Successfully restored: ${stats.restored}`)
145
+ console.log(` Not found in any namespace: ${stats.notFound}`)
146
+
147
+ if (stats.notFound > 0) {
148
+ console.log(`\nšŸ’” Next steps:`)
149
+ console.log(` Run 'pnpm trans' to add the ${stats.notFound} missing keys manually`)
150
+ } else {
151
+ console.log("\n✨ All keys successfully restored!")
152
+ }
153
+ }