@better-i18n/cli 0.1.4 → 0.1.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/README.md +39 -54
- package/dist/analyzer/index.d.ts +8 -2
- package/dist/analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/index.js +148 -3
- package/dist/analyzer/index.js.map +1 -1
- package/dist/analyzer/rules/index.d.ts +2 -0
- package/dist/analyzer/rules/index.d.ts.map +1 -1
- package/dist/analyzer/rules/index.js +2 -0
- package/dist/analyzer/rules/index.js.map +1 -1
- package/dist/analyzer/rules/string-variable.d.ts +13 -0
- package/dist/analyzer/rules/string-variable.d.ts.map +1 -0
- package/dist/analyzer/rules/string-variable.js +187 -0
- package/dist/analyzer/rules/string-variable.js.map +1 -0
- package/dist/analyzer/rules/toast-message.d.ts +13 -0
- package/dist/analyzer/rules/toast-message.d.ts.map +1 -0
- package/dist/analyzer/rules/toast-message.js +103 -0
- package/dist/analyzer/rules/toast-message.js.map +1 -0
- package/dist/analyzer/rules/translation-function.d.ts.map +1 -1
- package/dist/analyzer/rules/translation-function.js +36 -21
- package/dist/analyzer/rules/translation-function.js.map +1 -1
- package/dist/analyzer/types.d.ts +17 -1
- package/dist/analyzer/types.d.ts.map +1 -1
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +21 -2
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/sync.d.ts +12 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +583 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/commands/extract-keys.d.ts +0 -13
- package/dist/commands/extract-keys.d.ts.map +0 -1
- package/dist/commands/extract-keys.js +0 -418
- package/dist/commands/extract-keys.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CACV,sEAAsE,CACvE;KACA,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;KACtE,MAAM,CACL,uBAAuB,EACvB,oDAAoD,EACpD,QAAQ,CACT;KACA,MAAM,CAAC,OAAO,EAAE,wCAAwC,CAAC;KACzD,MAAM,CAAC,MAAM,EAAE,+CAA+C,CAAC;KAC/D,MAAM,CAAC,UAAU,EAAE,4BAA4B,CAAC;KAChD,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;KACtE,MAAM,CAAC,WAAW,EAAE,0CAA0C,CAAC;KAC/D,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC;KAC3C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extract translation keys command
|
|
3
|
-
*
|
|
4
|
-
* Extracts all t() function calls and compares with remote translations
|
|
5
|
-
*/
|
|
6
|
-
import type { ScanOptions } from "../analyzer/types.js";
|
|
7
|
-
export interface ExtractKeysOptions extends ScanOptions {
|
|
8
|
-
compare?: boolean;
|
|
9
|
-
locale?: string;
|
|
10
|
-
format: "eslint" | "json";
|
|
11
|
-
}
|
|
12
|
-
export declare function extractKeysCommand(options: ExtractKeysOptions): Promise<void>;
|
|
13
|
-
//# sourceMappingURL=extract-keys.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extract-keys.d.ts","sourceRoot":"","sources":["../../src/commands/extract-keys.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAI5E,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;CAC3B;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,iBAkMnE"}
|
|
@@ -1,418 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extract translation keys command
|
|
3
|
-
*
|
|
4
|
-
* Extracts all t() function calls and compares with remote translations
|
|
5
|
-
*/
|
|
6
|
-
import ora from "ora";
|
|
7
|
-
import { collectFiles } from "../analyzer/file-collector.js";
|
|
8
|
-
import { analyzeFile } from "../analyzer/index.js";
|
|
9
|
-
import { detectProjectContext } from "../context/detector.js";
|
|
10
|
-
import { bold, cyan, dim, green, red, yellow } from "../utils/colors.js";
|
|
11
|
-
export async function extractKeysCommand(options) {
|
|
12
|
-
const startTime = Date.now();
|
|
13
|
-
const isJson = options.format === "json";
|
|
14
|
-
// Create spinner (noop for JSON output)
|
|
15
|
-
const spinner = isJson
|
|
16
|
-
? {
|
|
17
|
-
start: (_text) => { },
|
|
18
|
-
succeed: (_text) => { },
|
|
19
|
-
fail: (_text) => { },
|
|
20
|
-
warn: (_text) => { },
|
|
21
|
-
text: "",
|
|
22
|
-
}
|
|
23
|
-
: ora({ text: "Detecting project...", color: "cyan" }).start();
|
|
24
|
-
// Step 1: Detect project context
|
|
25
|
-
const rootDir = options.dir || process.cwd();
|
|
26
|
-
const context = await detectProjectContext(rootDir);
|
|
27
|
-
if (context) {
|
|
28
|
-
spinner.succeed(`Project: ${bold(context.workspaceId + "/" + context.projectSlug)}`);
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
spinner.warn("No i18n.config.ts found, using defaults");
|
|
32
|
-
}
|
|
33
|
-
// Step 2: Fetch manifest to get source language
|
|
34
|
-
let manifest = null;
|
|
35
|
-
let sourceLocale = options.locale || context?.defaultLocale || "en";
|
|
36
|
-
if (context?.cdnBaseUrl) {
|
|
37
|
-
spinner.start("Fetching manifest...");
|
|
38
|
-
try {
|
|
39
|
-
manifest = await fetchManifest(context.cdnBaseUrl, context.workspaceId, context.projectSlug);
|
|
40
|
-
// Get source language from manifest
|
|
41
|
-
const sourceLanguage = manifest.languages.find((l) => l.isSource);
|
|
42
|
-
if (sourceLanguage) {
|
|
43
|
-
sourceLocale = sourceLanguage.code;
|
|
44
|
-
}
|
|
45
|
-
spinner.succeed(`Manifest loaded (source: ${bold(sourceLocale)}, ${manifest.languages.length} languages)`);
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
spinner.warn(`Could not fetch manifest: ${error instanceof Error ? error.message : String(error)}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
// Step 3: Collect files
|
|
52
|
-
spinner.start("Collecting files...");
|
|
53
|
-
const files = await collectFiles({
|
|
54
|
-
rootDir,
|
|
55
|
-
include: context?.lint?.include,
|
|
56
|
-
exclude: context?.lint?.exclude,
|
|
57
|
-
});
|
|
58
|
-
if (files.length === 0) {
|
|
59
|
-
spinner.fail("No .tsx or .jsx files found");
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
spinner.succeed(`Found ${files.length} files`);
|
|
63
|
-
// Step 4: Analyze files for t() calls with progress
|
|
64
|
-
const allIssues = [];
|
|
65
|
-
let processedFiles = 0;
|
|
66
|
-
for (const file of files) {
|
|
67
|
-
processedFiles++;
|
|
68
|
-
// Update spinner with progress every 10 files
|
|
69
|
-
if (!isJson && processedFiles % 10 === 0) {
|
|
70
|
-
spinner.text = `Extracting keys... (${processedFiles}/${files.length})`;
|
|
71
|
-
}
|
|
72
|
-
if (!isJson && processedFiles === 1) {
|
|
73
|
-
spinner.start(`Extracting keys... (${processedFiles}/${files.length})`);
|
|
74
|
-
}
|
|
75
|
-
try {
|
|
76
|
-
const issues = await analyzeFile(file, context?.lint);
|
|
77
|
-
// Filter only translation function calls
|
|
78
|
-
const translationKeys = issues.filter((i) => i.type === "string-variable");
|
|
79
|
-
allIssues.push(...translationKeys);
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
if (options.verbose) {
|
|
83
|
-
console.error(`Error analyzing ${file}:`, error);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
spinner.succeed(`Extracted ${allIssues.length} keys from ${files.length} files`);
|
|
88
|
-
// Step 5: Organize keys by namespace
|
|
89
|
-
const keysByNamespace = groupKeysByNamespace(allIssues);
|
|
90
|
-
const localKeys = {
|
|
91
|
-
project: context
|
|
92
|
-
? `${context.workspaceId}/${context.projectSlug}`
|
|
93
|
-
: "unknown",
|
|
94
|
-
namespaces: keysByNamespace,
|
|
95
|
-
totalCount: allIssues.length,
|
|
96
|
-
filesScanned: files.length,
|
|
97
|
-
};
|
|
98
|
-
// Step 6: Compare with CDN (always if manifest available, or if --compare flag)
|
|
99
|
-
const shouldCompare = manifest || (options.compare && context?.cdnBaseUrl);
|
|
100
|
-
if (shouldCompare && context?.cdnBaseUrl) {
|
|
101
|
-
spinner.start(`Comparing with remote (${sourceLocale})...`);
|
|
102
|
-
try {
|
|
103
|
-
const remoteKeys = await fetchRemoteKeys(context.cdnBaseUrl, context.workspaceId, context.projectSlug, sourceLocale, manifest);
|
|
104
|
-
spinner.succeed(`Fetched ${countTotalKeys(remoteKeys)} keys from remote`);
|
|
105
|
-
// Compare
|
|
106
|
-
const comparison = compareKeys(localKeys.namespaces, remoteKeys);
|
|
107
|
-
const duration = Date.now() - startTime;
|
|
108
|
-
// Report comparison
|
|
109
|
-
if (isJson) {
|
|
110
|
-
const output = {
|
|
111
|
-
project: context
|
|
112
|
-
? {
|
|
113
|
-
workspace: context.workspaceId,
|
|
114
|
-
slug: context.projectSlug,
|
|
115
|
-
sourceLocale,
|
|
116
|
-
}
|
|
117
|
-
: null,
|
|
118
|
-
localKeys: {
|
|
119
|
-
total: localKeys.totalCount,
|
|
120
|
-
namespaces: localKeys.namespaces,
|
|
121
|
-
},
|
|
122
|
-
remoteKeys: {
|
|
123
|
-
total: countTotalKeys(remoteKeys),
|
|
124
|
-
},
|
|
125
|
-
comparison: {
|
|
126
|
-
missingInRemote: comparison.missing,
|
|
127
|
-
unusedInCode: comparison.unused,
|
|
128
|
-
missingCount: countMissingKeys(comparison.missing),
|
|
129
|
-
unusedCount: countMissingKeys(comparison.unused),
|
|
130
|
-
},
|
|
131
|
-
coverage: {
|
|
132
|
-
local: calculateCoverage(localKeys.totalCount, comparison.missing),
|
|
133
|
-
remote: calculateRemoteCoverage(localKeys.namespaces, remoteKeys),
|
|
134
|
-
},
|
|
135
|
-
files: files.length,
|
|
136
|
-
duration,
|
|
137
|
-
};
|
|
138
|
-
console.log(JSON.stringify(output, null, 2));
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
reportComparisonReport(localKeys, remoteKeys, comparison, duration, sourceLocale);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
catch (error) {
|
|
145
|
-
spinner.fail(`Failed to fetch remote keys: ${error instanceof Error ? error.message : String(error)}`);
|
|
146
|
-
reportLocalKeys(localKeys, allIssues.length, Date.now() - startTime);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
// Just report local keys
|
|
151
|
-
const duration = Date.now() - startTime;
|
|
152
|
-
if (isJson) {
|
|
153
|
-
const output = {
|
|
154
|
-
localKeys,
|
|
155
|
-
files: files.length,
|
|
156
|
-
duration,
|
|
157
|
-
};
|
|
158
|
-
console.log(JSON.stringify(output, null, 2));
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
reportLocalKeys(localKeys, allIssues.length, duration);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Fetch manifest from CDN
|
|
167
|
-
*/
|
|
168
|
-
async function fetchManifest(cdnBaseUrl, workspaceId, projectSlug) {
|
|
169
|
-
const url = `${cdnBaseUrl}/${workspaceId}/${projectSlug}/manifest.json`;
|
|
170
|
-
const response = await fetch(url);
|
|
171
|
-
if (!response.ok) {
|
|
172
|
-
throw new Error(`Manifest fetch failed (${response.status})`);
|
|
173
|
-
}
|
|
174
|
-
return response.json();
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Group keys by namespace
|
|
178
|
-
*/
|
|
179
|
-
function groupKeysByNamespace(issues) {
|
|
180
|
-
const result = {};
|
|
181
|
-
for (const issue of issues) {
|
|
182
|
-
if (!issue.key)
|
|
183
|
-
continue;
|
|
184
|
-
const parts = issue.key.split(".");
|
|
185
|
-
const namespace = parts.length > 1 ? parts[0] : "default";
|
|
186
|
-
const fullKey = issue.key;
|
|
187
|
-
if (!result[namespace]) {
|
|
188
|
-
result[namespace] = new Set();
|
|
189
|
-
}
|
|
190
|
-
result[namespace].add(fullKey);
|
|
191
|
-
}
|
|
192
|
-
// Convert Sets to arrays
|
|
193
|
-
const output = {};
|
|
194
|
-
for (const [namespace, keys] of Object.entries(result)) {
|
|
195
|
-
output[namespace] = Array.from(keys).sort();
|
|
196
|
-
}
|
|
197
|
-
return output;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Fetch remote keys from CDN
|
|
201
|
-
*/
|
|
202
|
-
async function fetchRemoteKeys(cdnBaseUrl, workspaceId, projectSlug, locale, manifest) {
|
|
203
|
-
// Use manifest URL if available, otherwise construct URL
|
|
204
|
-
let url;
|
|
205
|
-
if (manifest?.files[locale]?.url) {
|
|
206
|
-
url = manifest.files[locale].url;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
url = `${cdnBaseUrl}/${workspaceId}/${projectSlug}/translations/${locale}.json`;
|
|
210
|
-
}
|
|
211
|
-
const response = await fetch(url);
|
|
212
|
-
if (!response.ok) {
|
|
213
|
-
throw new Error(`CDN fetch failed (${response.status})`);
|
|
214
|
-
}
|
|
215
|
-
return response.json();
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Compare local and remote keys
|
|
219
|
-
*/
|
|
220
|
-
function compareKeys(localKeys, remoteKeys) {
|
|
221
|
-
const missing = {};
|
|
222
|
-
const unused = {};
|
|
223
|
-
// Flatten remote keys to get all key paths
|
|
224
|
-
const remoteFlattened = flattenKeys(remoteKeys);
|
|
225
|
-
const allRemoteKeys = new Set();
|
|
226
|
-
for (const keys of Object.values(remoteFlattened)) {
|
|
227
|
-
for (const key of keys) {
|
|
228
|
-
allRemoteKeys.add(key);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
// Get all local keys
|
|
232
|
-
const allLocalKeys = new Set();
|
|
233
|
-
for (const keys of Object.values(localKeys)) {
|
|
234
|
-
for (const key of keys) {
|
|
235
|
-
allLocalKeys.add(key);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
// Find missing in remote (in local but not in remote)
|
|
239
|
-
for (const [namespace, keys] of Object.entries(localKeys)) {
|
|
240
|
-
const missingKeys = keys.filter((k) => !allRemoteKeys.has(k));
|
|
241
|
-
if (missingKeys.length > 0) {
|
|
242
|
-
missing[namespace] = missingKeys;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
// Find unused in code (in remote but not in local)
|
|
246
|
-
for (const [namespace, keys] of Object.entries(remoteFlattened)) {
|
|
247
|
-
const unusedKeys = keys.filter((k) => !allLocalKeys.has(k));
|
|
248
|
-
if (unusedKeys.length > 0) {
|
|
249
|
-
unused[namespace] = unusedKeys;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return { missing, unused };
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Flatten remote keys to get all namespaces
|
|
256
|
-
*/
|
|
257
|
-
function flattenKeys(remoteKeys) {
|
|
258
|
-
const result = {};
|
|
259
|
-
function traverse(obj, prefix = "") {
|
|
260
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
261
|
-
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
262
|
-
if (typeof value === "string") {
|
|
263
|
-
const namespace = fullKey.split(".")[0] || "default";
|
|
264
|
-
if (!result[namespace])
|
|
265
|
-
result[namespace] = [];
|
|
266
|
-
result[namespace].push(fullKey);
|
|
267
|
-
}
|
|
268
|
-
else if (typeof value === "object" && value !== null) {
|
|
269
|
-
traverse(value, fullKey);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
traverse(remoteKeys);
|
|
274
|
-
return result;
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Count total keys in nested structure
|
|
278
|
-
*/
|
|
279
|
-
function countTotalKeys(remoteKeys) {
|
|
280
|
-
let count = 0;
|
|
281
|
-
function traverse(obj) {
|
|
282
|
-
for (const value of Object.values(obj)) {
|
|
283
|
-
if (typeof value === "string") {
|
|
284
|
-
count++;
|
|
285
|
-
}
|
|
286
|
-
else if (typeof value === "object" && value !== null) {
|
|
287
|
-
traverse(value);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
traverse(remoteKeys);
|
|
292
|
-
return count;
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Count missing keys total
|
|
296
|
-
*/
|
|
297
|
-
function countMissingKeys(keys) {
|
|
298
|
-
return Object.values(keys).reduce((sum, arr) => sum + arr.length, 0);
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* Calculate local coverage (what % of local keys exist in remote)
|
|
302
|
-
*/
|
|
303
|
-
function calculateCoverage(localCount, missing) {
|
|
304
|
-
const missingCount = countMissingKeys(missing);
|
|
305
|
-
if (localCount === 0)
|
|
306
|
-
return 100;
|
|
307
|
-
return Math.round(((localCount - missingCount) / localCount) * 100);
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Calculate remote coverage (what % of remote keys are used)
|
|
311
|
-
*/
|
|
312
|
-
function calculateRemoteCoverage(localKeys, remoteKeys) {
|
|
313
|
-
const remoteFlattened = flattenKeys(remoteKeys);
|
|
314
|
-
let remoteUsedCount = 0;
|
|
315
|
-
let remoteTotalCount = 0;
|
|
316
|
-
const allLocalKeys = new Set();
|
|
317
|
-
for (const keys of Object.values(localKeys)) {
|
|
318
|
-
for (const key of keys) {
|
|
319
|
-
allLocalKeys.add(key);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
for (const keys of Object.values(remoteFlattened)) {
|
|
323
|
-
for (const key of keys) {
|
|
324
|
-
remoteTotalCount++;
|
|
325
|
-
if (allLocalKeys.has(key)) {
|
|
326
|
-
remoteUsedCount++;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
if (remoteTotalCount === 0)
|
|
331
|
-
return 0;
|
|
332
|
-
return Math.round((remoteUsedCount / remoteTotalCount) * 100);
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Report local keys (human-readable)
|
|
336
|
-
*/
|
|
337
|
-
function reportLocalKeys(localKeys, _issueCount, duration) {
|
|
338
|
-
console.log();
|
|
339
|
-
console.log(bold("📦 Local Translation Keys"));
|
|
340
|
-
console.log();
|
|
341
|
-
const sortedNamespaces = Object.keys(localKeys.namespaces).sort();
|
|
342
|
-
for (const namespace of sortedNamespaces) {
|
|
343
|
-
const keys = localKeys.namespaces[namespace];
|
|
344
|
-
console.log(`${dim(`${namespace}:`)} ${keys.length} keys`);
|
|
345
|
-
for (const key of keys) {
|
|
346
|
-
console.log(` ${dim("•")} ${key}`);
|
|
347
|
-
}
|
|
348
|
-
console.log();
|
|
349
|
-
}
|
|
350
|
-
console.log(green(bold(`✓ Found ${localKeys.totalCount} translation keys`)));
|
|
351
|
-
console.log(dim(`Scanned ${localKeys.filesScanned} files in ${(duration / 1000).toFixed(2)}s`));
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Report comparison (human-readable)
|
|
355
|
-
*/
|
|
356
|
-
function reportComparisonReport(localKeys, remoteKeys, comparison, duration, sourceLocale) {
|
|
357
|
-
console.log();
|
|
358
|
-
console.log(bold("📊 Translation Keys Comparison"));
|
|
359
|
-
console.log(dim(`Source locale: ${sourceLocale}`));
|
|
360
|
-
console.log();
|
|
361
|
-
// Coverage
|
|
362
|
-
const localCoverage = calculateCoverage(localKeys.totalCount, comparison.missing);
|
|
363
|
-
const remoteCoverage = calculateRemoteCoverage(localKeys.namespaces, remoteKeys);
|
|
364
|
-
console.log(`${dim("Coverage:")}`);
|
|
365
|
-
console.log(` Local → Remote: ${cyan(localCoverage + "%")}`);
|
|
366
|
-
console.log(` Remote Used: ${cyan(remoteCoverage + "%")}`);
|
|
367
|
-
console.log();
|
|
368
|
-
// Missing keys (in code but not in remote)
|
|
369
|
-
const totalMissing = countMissingKeys(comparison.missing);
|
|
370
|
-
if (totalMissing > 0) {
|
|
371
|
-
console.log(red(bold(`❌ Missing in Remote (${totalMissing} keys):`)));
|
|
372
|
-
console.log(dim(" Keys used in code but not uploaded to Better i18n"));
|
|
373
|
-
console.log();
|
|
374
|
-
for (const [namespace, keys] of Object.entries(comparison.missing)) {
|
|
375
|
-
console.log(`${dim(`${namespace}:`)} ${keys.length} keys`);
|
|
376
|
-
for (const key of keys.slice(0, 5)) {
|
|
377
|
-
console.log(` ${dim("+")} ${key}`);
|
|
378
|
-
}
|
|
379
|
-
if (keys.length > 5) {
|
|
380
|
-
console.log(` ${dim(` ... and ${keys.length - 5} more`)}`);
|
|
381
|
-
}
|
|
382
|
-
console.log();
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
else {
|
|
386
|
-
console.log(green(bold("✓ All local keys exist in remote!")));
|
|
387
|
-
console.log();
|
|
388
|
-
}
|
|
389
|
-
// Unused keys (in remote but not in code)
|
|
390
|
-
const totalUnused = countMissingKeys(comparison.unused);
|
|
391
|
-
if (totalUnused > 0) {
|
|
392
|
-
console.log(yellow(bold(`⚠️ Unused in Code (${totalUnused} keys):`)));
|
|
393
|
-
console.log(dim(" Keys in Better i18n but not used in code"));
|
|
394
|
-
console.log();
|
|
395
|
-
let shown = 0;
|
|
396
|
-
for (const [namespace, keys] of Object.entries(comparison.unused)) {
|
|
397
|
-
if (shown >= 3) {
|
|
398
|
-
const remaining = Object.keys(comparison.unused).length - 3;
|
|
399
|
-
console.log(dim(` ... and ${remaining} more namespaces`));
|
|
400
|
-
break;
|
|
401
|
-
}
|
|
402
|
-
console.log(`${dim(`${namespace}:`)} ${keys.length} keys`);
|
|
403
|
-
for (const key of keys.slice(0, 3)) {
|
|
404
|
-
console.log(` ${dim("-")} ${key}`);
|
|
405
|
-
}
|
|
406
|
-
if (keys.length > 3) {
|
|
407
|
-
console.log(` ${dim(` ... and ${keys.length - 3} more`)}`);
|
|
408
|
-
}
|
|
409
|
-
console.log();
|
|
410
|
-
shown++;
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
// Summary
|
|
414
|
-
console.log();
|
|
415
|
-
console.log(dim(`Scanned ${localKeys.filesScanned} files in ${(duration / 1000).toFixed(2)}s`));
|
|
416
|
-
console.log(green(bold(`✓ Comparison complete`)));
|
|
417
|
-
}
|
|
418
|
-
//# sourceMappingURL=extract-keys.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extract-keys.js","sourceRoot":"","sources":["../../src/commands/extract-keys.ts"],"names":[],"mappings":"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"}
|