@localheroai/cli 0.0.18 → 0.0.20
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 +28 -2
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.js +22 -11
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/push.js +7 -2
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/translate.js +25 -13
- package/dist/commands/translate.js.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/config.js +10 -4
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/files.js +1 -1
- package/dist/utils/files.js.map +1 -1
- package/dist/utils/git-changes.js +266 -0
- package/dist/utils/git-changes.js.map +1 -0
- package/dist/utils/git-diff.js +251 -0
- package/dist/utils/git-diff.js.map +1 -0
- package/dist/utils/github.js +1 -0
- package/dist/utils/github.js.map +1 -1
- package/dist/utils/import-service.js +20 -3
- package/dist/utils/import-service.js.map +1 -1
- package/dist/utils/po-surgical.js +103 -131
- package/dist/utils/po-surgical.js.map +1 -1
- package/dist/utils/po-utils.js +76 -70
- package/dist/utils/po-utils.js.map +1 -1
- package/dist/utils/translation-processor.js +1 -1
- package/dist/utils/translation-utils.js +41 -30
- package/dist/utils/translation-utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { parseFile, flattenTranslations } from './files.js';
|
|
5
|
+
import { PLURAL_PREFIX } from './po-utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* Git integration for --changed-only flag
|
|
8
|
+
* This module filters translations to only include keys that changed in the current branch
|
|
9
|
+
*/
|
|
10
|
+
export function hasFileChanged(file, baseBranch) {
|
|
11
|
+
try {
|
|
12
|
+
const sanitizedPath = sanitizeGitPath(file.path);
|
|
13
|
+
const oldContent = execSync(`git show ${baseBranch}:"${sanitizedPath}"`, {
|
|
14
|
+
encoding: 'utf-8',
|
|
15
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
16
|
+
stdio: ['pipe', 'pipe', 'ignore']
|
|
17
|
+
});
|
|
18
|
+
const newContent = readFileSync(file.path, 'utf-8');
|
|
19
|
+
return oldContent !== newContent;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function filterFilesByGitChanges(files, config, verbose) {
|
|
26
|
+
if (!isGitAvailable()) {
|
|
27
|
+
if (verbose) {
|
|
28
|
+
console.log(chalk.dim('Git not available - pushing all files'));
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const baseBranch = getBaseBranch(config);
|
|
33
|
+
if (!branchExists(baseBranch)) {
|
|
34
|
+
if (verbose) {
|
|
35
|
+
console.log(chalk.dim(`Base branch '${baseBranch}' not found - pushing all files`));
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const changedFiles = files.filter(file => hasFileChanged(file, baseBranch));
|
|
40
|
+
if (verbose) {
|
|
41
|
+
const skipped = files.length - changedFiles.length;
|
|
42
|
+
if (changedFiles.length > 0) {
|
|
43
|
+
console.log(chalk.blue(`Detected ${changedFiles.length} changed file${changedFiles.length === 1 ? '' : 's'} (comparing against ${baseBranch})`));
|
|
44
|
+
if (skipped > 0) {
|
|
45
|
+
console.log(chalk.dim(`Skipped ${skipped} unchanged file${skipped === 1 ? '' : 's'}`));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return changedFiles;
|
|
50
|
+
}
|
|
51
|
+
export function filterByGitChanges(sourceFiles, missingByLocale, config, verbose) {
|
|
52
|
+
try {
|
|
53
|
+
if (!isGitAvailable()) {
|
|
54
|
+
if (verbose) {
|
|
55
|
+
console.log(chalk.dim('Git not available or not in a repository'));
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const baseBranch = getBaseBranch(config);
|
|
60
|
+
if (verbose) {
|
|
61
|
+
console.log(chalk.blue(`Comparing against: ${baseBranch}`));
|
|
62
|
+
}
|
|
63
|
+
if (!branchExists(baseBranch)) {
|
|
64
|
+
if (verbose) {
|
|
65
|
+
console.log(chalk.yellow(`Base branch '${baseBranch}' not found`));
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
// Get changed keys from source files
|
|
70
|
+
const changedKeys = getChangedKeys(sourceFiles, baseBranch, verbose);
|
|
71
|
+
if (changedKeys.size === 0) {
|
|
72
|
+
if (verbose) {
|
|
73
|
+
console.log(chalk.dim('No changes detected in source files'));
|
|
74
|
+
}
|
|
75
|
+
return {};
|
|
76
|
+
}
|
|
77
|
+
if (verbose) {
|
|
78
|
+
console.log(chalk.blue(`Found ${changedKeys.size} changed key${changedKeys.size === 1 ? '' : 's'}:`));
|
|
79
|
+
const keysArray = Array.from(changedKeys);
|
|
80
|
+
const displayKeys = keysArray.slice(0, 10);
|
|
81
|
+
displayKeys.forEach(key => {
|
|
82
|
+
console.log(chalk.dim(` - ${key}`));
|
|
83
|
+
});
|
|
84
|
+
if (keysArray.length > 10) {
|
|
85
|
+
console.log(chalk.dim(` ... and ${keysArray.length - 10} more`));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return filterMissing(missingByLocale, changedKeys);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
if (verbose) {
|
|
92
|
+
const err = error;
|
|
93
|
+
console.log(chalk.yellow(`Filter by git failed: ${err.message}`));
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Extract keys from PO file parsed object
|
|
100
|
+
* PO files have structure: { msgid: { value: '...', metadata: ... } }
|
|
101
|
+
* We extract just msgid -> value for comparison
|
|
102
|
+
*/
|
|
103
|
+
function extractPoKeys(poObject) {
|
|
104
|
+
const result = {};
|
|
105
|
+
for (const [key, data] of Object.entries(poObject)) {
|
|
106
|
+
// For PO files, extract the value without creating nested .value keys
|
|
107
|
+
result[key] = typeof data === 'object' && data !== null && data.value !== undefined ? data.value : data;
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Check if git is available and we're in a repository
|
|
113
|
+
*/
|
|
114
|
+
export function isGitAvailable() {
|
|
115
|
+
try {
|
|
116
|
+
execSync('git rev-parse --git-dir', { stdio: 'ignore' });
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get base branch from config, environment, or default
|
|
125
|
+
*/
|
|
126
|
+
function getBaseBranch(config) {
|
|
127
|
+
return config.translationFiles?.baseBranch
|
|
128
|
+
|| process.env.GITHUB_BASE_REF
|
|
129
|
+
|| 'main';
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Sanitize file path for use in git commands
|
|
133
|
+
* Removes characters that could break out of quotes
|
|
134
|
+
*/
|
|
135
|
+
function sanitizeGitPath(path) {
|
|
136
|
+
return path.replace(/["'`$\\]/g, '');
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Check if a branch exists (local or remote)
|
|
140
|
+
*/
|
|
141
|
+
function branchExists(branch) {
|
|
142
|
+
try {
|
|
143
|
+
execSync(`git rev-parse --verify ${branch}`, { stdio: 'ignore' });
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get all changed keys from source files using object-based diff
|
|
152
|
+
* Compares parsed and flattened objects from base branch vs current working directory
|
|
153
|
+
*/
|
|
154
|
+
function getChangedKeys(sourceFiles, baseBranch, verbose) {
|
|
155
|
+
const allChangedKeys = new Set();
|
|
156
|
+
for (const file of sourceFiles) {
|
|
157
|
+
try {
|
|
158
|
+
const sanitizedPath = sanitizeGitPath(file.path);
|
|
159
|
+
const isPo = file.format === 'po';
|
|
160
|
+
let oldFlat = {};
|
|
161
|
+
try {
|
|
162
|
+
const oldContent = execSync(`git show ${baseBranch}:"${sanitizedPath}"`, {
|
|
163
|
+
encoding: 'utf-8',
|
|
164
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
165
|
+
stdio: ['pipe', 'pipe', 'ignore']
|
|
166
|
+
});
|
|
167
|
+
const oldObj = parseFile(oldContent, file.format, file.path);
|
|
168
|
+
oldFlat = isPo ? extractPoKeys(oldObj) : flattenTranslations(oldObj);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
const err = error;
|
|
172
|
+
if (verbose) {
|
|
173
|
+
// Check if it's a git error (file doesn't exist) or parse error
|
|
174
|
+
if (err.message.includes('exists on disk, but not in') || err.message.includes('does not exist')) {
|
|
175
|
+
console.log(chalk.dim(` ${file.path}: new file (all keys changed)`));
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
console.log(chalk.yellow(` ${file.path}: Parse error - ${err.message}`));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// If parse fails or file doesn't exist, oldFlat remains {} - all keys will be treated as new
|
|
182
|
+
}
|
|
183
|
+
// Get current version from working directory
|
|
184
|
+
const newContent = readFileSync(file.path, 'utf-8');
|
|
185
|
+
const newObj = parseFile(newContent, file.format, file.path);
|
|
186
|
+
const newFlat = isPo ? extractPoKeys(newObj) : flattenTranslations(newObj);
|
|
187
|
+
// Compare flattened objects to find changed keys
|
|
188
|
+
const fileChangedKeys = [];
|
|
189
|
+
const MAX_KEYS_TO_COLLECT = 100; // Cap to prevent memory issues
|
|
190
|
+
let totalChangedInFile = 0;
|
|
191
|
+
for (const [key, value] of Object.entries(newFlat)) {
|
|
192
|
+
const keyExistsInOld = key in oldFlat;
|
|
193
|
+
if (!keyExistsInOld || oldFlat[key] !== value) {
|
|
194
|
+
allChangedKeys.add(key);
|
|
195
|
+
totalChangedInFile++;
|
|
196
|
+
if (verbose && fileChangedKeys.length < MAX_KEYS_TO_COLLECT) {
|
|
197
|
+
fileChangedKeys.push(key);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (verbose && totalChangedInFile > 0) {
|
|
202
|
+
console.log(chalk.dim(` ${file.path}: ${totalChangedInFile} changed key${totalChangedInFile === 1 ? '' : 's'}`));
|
|
203
|
+
const displayKeys = fileChangedKeys.slice(0, 5);
|
|
204
|
+
displayKeys.forEach(key => {
|
|
205
|
+
const status = (key in oldFlat) ? 'modified' : 'new';
|
|
206
|
+
console.log(chalk.dim(` - ${key} (${status})`));
|
|
207
|
+
});
|
|
208
|
+
if (totalChangedInFile > 5) {
|
|
209
|
+
console.log(chalk.dim(` ... and ${totalChangedInFile - 5} more`));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
if (verbose) {
|
|
215
|
+
const err = error;
|
|
216
|
+
console.log(chalk.dim(` Skipping ${file.path}: ${err.message}`));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return allChangedKeys;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Filter missing translations by changed keys
|
|
224
|
+
*
|
|
225
|
+
* For plural forms, if ANY variant changed, include ALL variants for the target language.
|
|
226
|
+
* This handles cases where source and target languages have different plural form counts.
|
|
227
|
+
*/
|
|
228
|
+
function filterMissing(missingByLocale, changedKeys) {
|
|
229
|
+
const filtered = {};
|
|
230
|
+
// Extract base keys from plural forms in changedKeys
|
|
231
|
+
// E.g., "key__plural_1" -> "key"
|
|
232
|
+
const baseChangedKeys = new Set();
|
|
233
|
+
for (const key of changedKeys) {
|
|
234
|
+
const baseKey = key.replace(new RegExp(`${PLURAL_PREFIX.replace('_', '\\_')}\\d+$`), '');
|
|
235
|
+
baseChangedKeys.add(baseKey);
|
|
236
|
+
}
|
|
237
|
+
for (const [localeKey, entry] of Object.entries(missingByLocale)) {
|
|
238
|
+
const filteredKeys = {};
|
|
239
|
+
let count = 0;
|
|
240
|
+
for (const [key, details] of Object.entries(entry.keys)) {
|
|
241
|
+
if (changedKeys.has(key)) {
|
|
242
|
+
filteredKeys[key] = details;
|
|
243
|
+
count++;
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
// For plural forms, check if base key changed
|
|
247
|
+
const baseKey = key.replace(new RegExp(`${PLURAL_PREFIX.replace('_', '\\_')}\\d+$`), '');
|
|
248
|
+
if (baseKey !== key && baseChangedKeys.has(baseKey)) {
|
|
249
|
+
// This is a plural variant of a changed key - include it
|
|
250
|
+
// even if the source language doesn't have this many plural forms
|
|
251
|
+
filteredKeys[key] = details;
|
|
252
|
+
count++;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (count > 0) {
|
|
257
|
+
filtered[localeKey] = {
|
|
258
|
+
...entry,
|
|
259
|
+
keys: filteredKeys,
|
|
260
|
+
keyCount: count
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return filtered;
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=git-changes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-changes.js","sourceRoot":"","sources":["../../src/utils/git-changes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { parseFile, flattenTranslations } from './files.js';
|
|
5
|
+
/**
|
|
6
|
+
* Git diff integration for --changed-only flag
|
|
7
|
+
* This module filters translations to only include keys that changed in the current branch
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Main entry point for git diff filtering
|
|
11
|
+
* Returns null to fall back, {} for no changes, or filtered data for success
|
|
12
|
+
*/
|
|
13
|
+
export function filterByGitChanges(sourceFiles, missingByLocale, config, verbose) {
|
|
14
|
+
try {
|
|
15
|
+
// Quick validation
|
|
16
|
+
if (!canUseGitDiff()) {
|
|
17
|
+
if (verbose) {
|
|
18
|
+
console.log(chalk.dim('Git not available or not in a repository'));
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const baseBranch = getBaseBranch(config);
|
|
23
|
+
if (verbose) {
|
|
24
|
+
console.log(chalk.blue(`Comparing against: ${baseBranch}`));
|
|
25
|
+
}
|
|
26
|
+
// Validate and check if base branch exists
|
|
27
|
+
let safeBranch;
|
|
28
|
+
try {
|
|
29
|
+
safeBranch = sanitizeBranchName(baseBranch);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (verbose) {
|
|
33
|
+
const err = error;
|
|
34
|
+
console.log(chalk.yellow(`Invalid branch name: ${err.message}`));
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
if (!branchExists(safeBranch)) {
|
|
39
|
+
if (verbose) {
|
|
40
|
+
console.log(chalk.yellow(`Base branch '${baseBranch}' not found`));
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
// Get changed keys from source files
|
|
45
|
+
const changedKeys = getChangedKeys(sourceFiles, safeBranch, verbose);
|
|
46
|
+
if (changedKeys.size === 0) {
|
|
47
|
+
if (verbose) {
|
|
48
|
+
console.log(chalk.dim('No changes detected in source files'));
|
|
49
|
+
}
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
if (verbose) {
|
|
53
|
+
console.log(chalk.blue(`Found ${changedKeys.size} changed key${changedKeys.size === 1 ? '' : 's'}:`));
|
|
54
|
+
// Show first 10 keys, with indication if there are more
|
|
55
|
+
const keysArray = Array.from(changedKeys);
|
|
56
|
+
const displayKeys = keysArray.slice(0, 10);
|
|
57
|
+
displayKeys.forEach(key => {
|
|
58
|
+
console.log(chalk.dim(` - ${key}`));
|
|
59
|
+
});
|
|
60
|
+
if (keysArray.length > 10) {
|
|
61
|
+
console.log(chalk.dim(` ... and ${keysArray.length - 10} more`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Filter missing translations by changed keys
|
|
65
|
+
return filterMissing(missingByLocale, changedKeys);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (verbose) {
|
|
69
|
+
const err = error;
|
|
70
|
+
console.log(chalk.yellow(`Git diff failed: ${err.message}`));
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if git is available and we're in a repository
|
|
77
|
+
*/
|
|
78
|
+
export function canUseGitDiff() {
|
|
79
|
+
try {
|
|
80
|
+
execSync('git rev-parse --git-dir', { stdio: 'ignore' });
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get base branch from config, environment, or default
|
|
89
|
+
*/
|
|
90
|
+
function getBaseBranch(config) {
|
|
91
|
+
return config.translationFiles?.baseBranch
|
|
92
|
+
|| process.env.GITHUB_BASE_REF
|
|
93
|
+
|| 'main';
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Sanitize branch name to prevent command injection
|
|
97
|
+
* Allows only alphanumeric, hyphen, and underscore
|
|
98
|
+
* Supports remote branches like origin/main explicitly
|
|
99
|
+
*/
|
|
100
|
+
function sanitizeBranchName(branch) {
|
|
101
|
+
// Handle remote branches explicitly (e.g., origin/main)
|
|
102
|
+
if (branch.startsWith('origin/')) {
|
|
103
|
+
const remotePart = 'origin/';
|
|
104
|
+
const branchPart = branch.slice(remotePart.length).replace(/[^a-zA-Z0-9_\-]/g, '');
|
|
105
|
+
if (!branchPart) {
|
|
106
|
+
throw new Error(`Invalid branch name: ${branch}`);
|
|
107
|
+
}
|
|
108
|
+
return remotePart + branchPart;
|
|
109
|
+
}
|
|
110
|
+
// For local branches, no slashes allowed (prevents path traversal)
|
|
111
|
+
const sanitized = branch.replace(/[^a-zA-Z0-9_\-]/g, '');
|
|
112
|
+
if (!sanitized) {
|
|
113
|
+
throw new Error(`Invalid branch name: ${branch}`);
|
|
114
|
+
}
|
|
115
|
+
return sanitized;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Sanitize file path for use in git commands
|
|
119
|
+
* Removes characters that could break out of quotes
|
|
120
|
+
*/
|
|
121
|
+
function sanitizeGitPath(path) {
|
|
122
|
+
return path.replace(/["'`$\\]/g, '');
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if a branch exists (local or remote)
|
|
126
|
+
* @param branch - Already sanitized branch name
|
|
127
|
+
*/
|
|
128
|
+
function branchExists(branch) {
|
|
129
|
+
try {
|
|
130
|
+
execSync(`git rev-parse --verify ${branch}`, { stdio: 'ignore' });
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// If not a remote branch already, try with origin/ prefix
|
|
135
|
+
if (!branch.startsWith('origin/')) {
|
|
136
|
+
try {
|
|
137
|
+
execSync(`git rev-parse --verify origin/${branch}`, { stdio: 'ignore' });
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get all changed keys from source files using object-based diff
|
|
149
|
+
* Compares parsed and flattened objects from base branch vs current working directory
|
|
150
|
+
* @param baseBranch - Already sanitized branch name
|
|
151
|
+
*/
|
|
152
|
+
function getChangedKeys(sourceFiles, baseBranch, verbose) {
|
|
153
|
+
const allChangedKeys = new Set();
|
|
154
|
+
for (const file of sourceFiles) {
|
|
155
|
+
try {
|
|
156
|
+
// Sanitize file path for git command
|
|
157
|
+
const sanitizedPath = sanitizeGitPath(file.path);
|
|
158
|
+
// Get old version from base branch
|
|
159
|
+
let oldFlat = {};
|
|
160
|
+
try {
|
|
161
|
+
const oldContent = execSync(`git show ${baseBranch}:"${sanitizedPath}"`, {
|
|
162
|
+
encoding: 'utf-8',
|
|
163
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
164
|
+
stdio: ['pipe', 'pipe', 'ignore']
|
|
165
|
+
});
|
|
166
|
+
const oldObj = parseFile(oldContent, file.format, file.path);
|
|
167
|
+
oldFlat = flattenTranslations(oldObj);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
const err = error;
|
|
171
|
+
if (verbose) {
|
|
172
|
+
// Check if it's a git error (file doesn't exist) or parse error
|
|
173
|
+
if (err.message.includes('exists on disk, but not in') || err.message.includes('does not exist')) {
|
|
174
|
+
console.log(chalk.dim(` ${file.path}: new file (all keys changed)`));
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
console.log(chalk.yellow(` ${file.path}: Parse error - ${err.message}`));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// If parse fails or file doesn't exist, oldFlat remains {} - all keys will be treated as new
|
|
181
|
+
}
|
|
182
|
+
// Get current version from working directory
|
|
183
|
+
const newContent = readFileSync(file.path, 'utf-8');
|
|
184
|
+
const newObj = parseFile(newContent, file.format, file.path);
|
|
185
|
+
const newFlat = flattenTranslations(newObj);
|
|
186
|
+
// Compare flattened objects to find changed keys
|
|
187
|
+
const fileChangedKeys = [];
|
|
188
|
+
const MAX_KEYS_TO_COLLECT = 100; // Cap to prevent memory issues
|
|
189
|
+
let totalChangedInFile = 0;
|
|
190
|
+
for (const [key, value] of Object.entries(newFlat)) {
|
|
191
|
+
// Check if key exists in old using 'in' operator (handles falsy values correctly)
|
|
192
|
+
const keyExistsInOld = key in oldFlat;
|
|
193
|
+
if (!keyExistsInOld || oldFlat[key] !== value) {
|
|
194
|
+
allChangedKeys.add(key);
|
|
195
|
+
totalChangedInFile++;
|
|
196
|
+
// Only collect keys for verbose output up to a limit
|
|
197
|
+
if (verbose && fileChangedKeys.length < MAX_KEYS_TO_COLLECT) {
|
|
198
|
+
fileChangedKeys.push(key);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (verbose && totalChangedInFile > 0) {
|
|
203
|
+
console.log(chalk.dim(` ${file.path}: ${totalChangedInFile} changed key${totalChangedInFile === 1 ? '' : 's'}`));
|
|
204
|
+
// Show first 5 keys per file
|
|
205
|
+
const displayKeys = fileChangedKeys.slice(0, 5);
|
|
206
|
+
displayKeys.forEach(key => {
|
|
207
|
+
const status = (key in oldFlat) ? 'modified' : 'new';
|
|
208
|
+
console.log(chalk.dim(` - ${key} (${status})`));
|
|
209
|
+
});
|
|
210
|
+
if (totalChangedInFile > 5) {
|
|
211
|
+
console.log(chalk.dim(` ... and ${totalChangedInFile - 5} more`));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
// Skip this file, continue with others
|
|
217
|
+
if (verbose) {
|
|
218
|
+
const err = error;
|
|
219
|
+
console.log(chalk.dim(` Skipping ${file.path}: ${err.message}`));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return allChangedKeys;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Filter missing translations by changed keys
|
|
227
|
+
*/
|
|
228
|
+
function filterMissing(missingByLocale, changedKeys) {
|
|
229
|
+
const filtered = {};
|
|
230
|
+
for (const [localeKey, entry] of Object.entries(missingByLocale)) {
|
|
231
|
+
// Filter the keys Record to only include changed keys
|
|
232
|
+
const filteredKeys = {};
|
|
233
|
+
let count = 0;
|
|
234
|
+
for (const [key, details] of Object.entries(entry.keys)) {
|
|
235
|
+
if (changedKeys.has(key)) {
|
|
236
|
+
filteredKeys[key] = details;
|
|
237
|
+
count++;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// Only include this entry if it has matching keys
|
|
241
|
+
if (count > 0) {
|
|
242
|
+
filtered[localeKey] = {
|
|
243
|
+
...entry,
|
|
244
|
+
keys: filteredKeys,
|
|
245
|
+
keyCount: count
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return filtered;
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=git-diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-diff.js","sourceRoot":"","sources":["../../src/utils/git-diff.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/github.js
CHANGED
package/dist/utils/github.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/utils/github.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAmB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,IAAI,MAAM,MAAM,CAAC;AAaxB,MAAM,mBAAmB,GAAuB;IAC9C,IAAI,EAAE,CAAC,GAAW,EAAE,OAAyB,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACxE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE;IACzB,IAAI;IACJ,GAAG,EAAE,OAAO,CAAC,GAAG;CACjB,CAAC;AAEF,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAEnD,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,EAAE,GAAG,mBAAmB,EAAE;IAEhC;;OAEG;IACH,eAAe,CAAC,aAA0C,EAAE;QAC1D,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,mBAAmB,EAAE,GAAG,UAAU,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,CAAC;IACjD,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,QAAgB;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,+BAA+B,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjF,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,QAAgB;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAC/D,CAAC;IAED;;;OAGG;IACH,+BAA+B,CAAC,QAAgB;QAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC9E,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,sBAAsB,CAAC,QAAgB,EAAE,gBAA0B;QACvE,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,YAAY,GAAG,IAAI,CAAC,+BAA+B,CAAC,QAAQ,CAAC,CAAC;QAEpE,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEjD,MAAM,aAAa,GAAG;;;;;QAKlB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAC7B,8DAA8D;YAC9D,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACpC,2DAA2D;YAC3D,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YAC7E,OAAO,MAAM,aAAa,GAAG,CAAC;QAChC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/utils/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
3
4
|
import { createImport, checkImportStatus, bulkUpdateTranslations } from '../api/imports.js';
|
|
4
5
|
import { findTranslationFiles as findFiles, flattenTranslations } from './files.js';
|
|
5
6
|
import { parsePoFile, poEntriesToApiFormat } from './po-utils.js';
|
|
7
|
+
import { filterFilesByGitChanges } from './git-changes.js';
|
|
6
8
|
/**
|
|
7
9
|
* Get the file format based on extension
|
|
8
10
|
* @param filePath Path to the file
|
|
@@ -40,7 +42,7 @@ async function readFileContent(filePath, options) {
|
|
|
40
42
|
if (format === 'po') {
|
|
41
43
|
try {
|
|
42
44
|
const parsed = parsePoFile(content);
|
|
43
|
-
const apiFormat = poEntriesToApiFormat(parsed
|
|
45
|
+
const apiFormat = poEntriesToApiFormat(parsed, options);
|
|
44
46
|
return Buffer.from(JSON.stringify(apiFormat)).toString('base64');
|
|
45
47
|
}
|
|
46
48
|
catch {
|
|
@@ -160,11 +162,26 @@ export const importService = {
|
|
|
160
162
|
* @param basePath Base path to look for files (defaults to cwd)
|
|
161
163
|
* @returns Result of the push operation
|
|
162
164
|
*/
|
|
163
|
-
async pushTranslations(config, basePath = process.cwd()) {
|
|
164
|
-
|
|
165
|
+
async pushTranslations(config, basePath = process.cwd(), options = {}) {
|
|
166
|
+
let files = await this.findTranslationFiles(config, basePath);
|
|
165
167
|
if (!files.length) {
|
|
166
168
|
return { status: 'no_files' };
|
|
167
169
|
}
|
|
170
|
+
if (!options.force) {
|
|
171
|
+
const filteredFiles = filterFilesByGitChanges(files, config, options.verbose || false);
|
|
172
|
+
if (filteredFiles !== null) {
|
|
173
|
+
if (filteredFiles.length === 0) {
|
|
174
|
+
return {
|
|
175
|
+
status: 'no_changes',
|
|
176
|
+
files: { source: [], target: [] }
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
files = filteredFiles;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
else if (options.verbose) {
|
|
183
|
+
console.log(chalk.dim('--force flag set - pushing all files'));
|
|
184
|
+
}
|
|
168
185
|
const sourceFiles = files.filter(file => file.language === config.sourceLocale);
|
|
169
186
|
const targetFiles = files.filter(file => file.language !== config.sourceLocale);
|
|
170
187
|
const allTranslations = [];
|