@tolgee/cli 2.13.0 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/errorFromLoadable.js +8 -2
- package/dist/commands/pull.js +1 -0
- package/dist/commands/push.js +33 -9
- package/dist/commands/sync/sync.js +1 -0
- package/dist/commands/sync/syncUtils.js +9 -4
- package/dist/utils/getStackTrace.js +7 -5
- package/dist/utils/printFailedKeys.js +26 -0
- package/package.json +1 -1
- package/schema.json +16 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { getUnresolvedConflictsMessage } from '../utils/printFailedKeys.js';
|
|
1
2
|
export const addErrorDetails = (loadable, showBeError = true) => {
|
|
2
|
-
var _a, _b, _c;
|
|
3
|
+
var _a, _b, _c, _d, _e;
|
|
4
|
+
let additionalInfo = '';
|
|
3
5
|
const items = [];
|
|
4
6
|
items.push(`status: ${loadable.response.status}`);
|
|
5
7
|
if (showBeError && ((_a = loadable.error) === null || _a === void 0 ? void 0 : _a.code)) {
|
|
@@ -8,7 +10,11 @@ export const addErrorDetails = (loadable, showBeError = true) => {
|
|
|
8
10
|
if (loadable.response.status === 403 && ((_c = (_b = loadable.error) === null || _b === void 0 ? void 0 : _b.params) === null || _c === void 0 ? void 0 : _c[0])) {
|
|
9
11
|
items.push(`missing scope: ${loadable.error.params[0]}`);
|
|
10
12
|
}
|
|
11
|
-
|
|
13
|
+
if (((_d = loadable.error) === null || _d === void 0 ? void 0 : _d.code) === 'conflict_is_not_resolved' &&
|
|
14
|
+
typeof ((_e = loadable.error.params) === null || _e === void 0 ? void 0 : _e[0]) === 'object') {
|
|
15
|
+
additionalInfo += getUnresolvedConflictsMessage(loadable.error.params, true);
|
|
16
|
+
}
|
|
17
|
+
return `[${items.join(', ')}]${additionalInfo ? '\n' + additionalInfo : ''}`;
|
|
12
18
|
};
|
|
13
19
|
export const errorFromLoadable = (loadable) => {
|
|
14
20
|
switch (loadable.response.status) {
|
package/dist/commands/pull.js
CHANGED
package/dist/commands/push.js
CHANGED
|
@@ -18,6 +18,7 @@ import { mapImportFormat } from '../utils/mapImportFormat.js';
|
|
|
18
18
|
import { handleLoadableError } from '../client/TolgeeClient.js';
|
|
19
19
|
import { findFilesByTemplate } from '../utils/filesTemplate.js';
|
|
20
20
|
import { valueToArray } from '../utils/valueToArray.js';
|
|
21
|
+
import { printUnresolvedConflicts } from '../utils/printFailedKeys.js';
|
|
21
22
|
function allInPattern(pattern) {
|
|
22
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
23
24
|
const files = [];
|
|
@@ -100,7 +101,7 @@ function handleMappingError(fileMappings) {
|
|
|
100
101
|
}
|
|
101
102
|
const pushHandler = (config) => function () {
|
|
102
103
|
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
-
var _a, _b, _c, _d;
|
|
104
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
104
105
|
const opts = this.optsWithGlobals();
|
|
105
106
|
let allMatchers = [];
|
|
106
107
|
const filesTemplate = opts.filesTemplate;
|
|
@@ -130,12 +131,25 @@ const pushHandler = (config) => function () {
|
|
|
130
131
|
error('Nothing to import.');
|
|
131
132
|
return;
|
|
132
133
|
}
|
|
134
|
+
let errorOnUnresolvedConflict;
|
|
135
|
+
switch (opts.errorOnUnresolvedConflict) {
|
|
136
|
+
case 'auto':
|
|
137
|
+
errorOnUnresolvedConflict = undefined;
|
|
138
|
+
break;
|
|
139
|
+
case 'yes':
|
|
140
|
+
errorOnUnresolvedConflict = true;
|
|
141
|
+
break;
|
|
142
|
+
case 'no':
|
|
143
|
+
errorOnUnresolvedConflict = false;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
133
146
|
const params = {
|
|
134
147
|
createNewKeys: true,
|
|
135
148
|
forceMode: opts.forceMode,
|
|
136
149
|
overrideKeyDescriptions: opts.overrideKeyDescriptions,
|
|
137
150
|
convertPlaceholdersToIcu: opts.convertPlaceholdersToIcu,
|
|
138
151
|
tagNewKeys: (_d = opts.tagNewKeys) !== null && _d !== void 0 ? _d : [],
|
|
152
|
+
overrideMode: (_e = opts.overrideMode) !== null && _e !== void 0 ? _e : 'RECOMMENDED',
|
|
139
153
|
fileMappings: files.map((f) => {
|
|
140
154
|
var _a;
|
|
141
155
|
const format = mapImportFormat(opts.format, extname(f.name));
|
|
@@ -153,30 +167,34 @@ const pushHandler = (config) => function () {
|
|
|
153
167
|
};
|
|
154
168
|
}),
|
|
155
169
|
removeOtherKeys: opts.removeOtherKeys,
|
|
170
|
+
errorOnUnresolvedConflict: errorOnUnresolvedConflict,
|
|
156
171
|
};
|
|
157
|
-
|
|
172
|
+
let attempt = yield loading('Importing...', importData(opts.client, {
|
|
158
173
|
files,
|
|
159
174
|
params,
|
|
160
175
|
}));
|
|
161
|
-
if (
|
|
162
|
-
if (
|
|
176
|
+
if (attempt.error) {
|
|
177
|
+
if (attempt.error.code === 'existing_language_not_selected') {
|
|
163
178
|
handleMappingError(params.fileMappings);
|
|
164
179
|
}
|
|
165
|
-
if (
|
|
166
|
-
handleLoadableError(
|
|
180
|
+
if (attempt.error.code !== 'conflict_is_not_resolved') {
|
|
181
|
+
handleLoadableError(attempt);
|
|
167
182
|
}
|
|
168
183
|
const forceMode = yield promptConflicts(opts);
|
|
169
|
-
|
|
184
|
+
attempt = yield loading('Overriding...', importData(opts.client, {
|
|
170
185
|
files,
|
|
171
186
|
params: Object.assign(Object.assign({}, params), { forceMode }),
|
|
172
187
|
}));
|
|
173
|
-
handleLoadableError(
|
|
188
|
+
handleLoadableError(attempt);
|
|
189
|
+
}
|
|
190
|
+
if ((_g = (_f = attempt.data) === null || _f === void 0 ? void 0 : _f.unresolvedConflicts) === null || _g === void 0 ? void 0 : _g.length) {
|
|
191
|
+
printUnresolvedConflicts(attempt.data.unresolvedConflicts, false);
|
|
174
192
|
}
|
|
175
193
|
success('Done!');
|
|
176
194
|
});
|
|
177
195
|
};
|
|
178
196
|
export default (config) => {
|
|
179
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
197
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
180
198
|
return new Command()
|
|
181
199
|
.name('push')
|
|
182
200
|
.description('Pushes translations to Tolgee')
|
|
@@ -191,5 +209,11 @@ export default (config) => {
|
|
|
191
209
|
.addOption(new Option('-n, --namespaces <namespaces...>', 'Specifies which namespaces should be pushed (see push.files in config).').default((_h = config.push) === null || _h === void 0 ? void 0 : _h.namespaces))
|
|
192
210
|
.addOption(new Option('--tag-new-keys <tags...>', 'Specify tags that will be added to newly created keys.').default((_j = config.push) === null || _j === void 0 ? void 0 : _j.tagNewKeys))
|
|
193
211
|
.addOption(new Option('--remove-other-keys', 'Remove keys which are not present in the import (within imported namespaces).').default((_k = config.push) === null || _k === void 0 ? void 0 : _k.removeOtherKeys))
|
|
212
|
+
.addOption(new Option('--override-mode <mode>', 'Specifies what is considered non-overridable translation.')
|
|
213
|
+
.choices(['RECOMMENDED', 'ALL'])
|
|
214
|
+
.default((_l = config.push) === null || _l === void 0 ? void 0 : _l.overrideMode))
|
|
215
|
+
.addOption(new Option('--error-on-unresolved-conflict <choice>', 'Fail the whole import if there are unresolved conflicts.')
|
|
216
|
+
.choices(['yes', 'no', 'auto'])
|
|
217
|
+
.default((_o = (_m = config.push) === null || _m === void 0 ? void 0 : _m.errorOnUnresolvedConflict) !== null && _o !== void 0 ? _o : 'auto'))
|
|
194
218
|
.action(pushHandler(config));
|
|
195
219
|
};
|
|
@@ -5,15 +5,20 @@ import ansi from 'ansi-colors';
|
|
|
5
5
|
* @param key The key to print.
|
|
6
6
|
* @param deletion True if the key is about to be deleted.
|
|
7
7
|
*/
|
|
8
|
-
export function printKey(key, deletion) {
|
|
8
|
+
export function printKey(key, deletion, color, note) {
|
|
9
|
+
const colorFunc = color !== null && color !== void 0 ? color : (deletion ? ansi.red : ansi.green);
|
|
9
10
|
const namespace = key.namespace
|
|
10
11
|
? ` ${ansi.italic(`(namespace: ${key.namespace})`)}`
|
|
11
12
|
: '';
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
const renderedNote = note ? ` ${note}` : '';
|
|
14
|
+
if (deletion === undefined) {
|
|
15
|
+
console.log(`${colorFunc(`${key.keyName}`)}${namespace}${renderedNote}`);
|
|
16
|
+
}
|
|
17
|
+
else if (deletion) {
|
|
18
|
+
console.log(`${colorFunc(`- ${key.keyName}`)}${namespace}${renderedNote}`);
|
|
14
19
|
}
|
|
15
20
|
else {
|
|
16
|
-
console.log(`${
|
|
21
|
+
console.log(`${colorFunc(`+ ${key.keyName}`)}${namespace}${renderedNote}`);
|
|
17
22
|
}
|
|
18
23
|
}
|
|
19
24
|
/**
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export const getStackTrace = () => {
|
|
2
|
-
|
|
3
|
-
Error.captureStackTrace
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
var _a, _b;
|
|
3
|
+
if (typeof Error.captureStackTrace === 'function') {
|
|
4
|
+
const obj = {};
|
|
5
|
+
Error.captureStackTrace(obj, getStackTrace);
|
|
6
|
+
return (_a = obj.stack) !== null && _a !== void 0 ? _a : '';
|
|
7
|
+
}
|
|
8
|
+
return (_b = new Error().stack) !== null && _b !== void 0 ? _b : '';
|
|
7
9
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import ansi from 'ansi-colors';
|
|
2
|
+
export function renderKey(key, note) {
|
|
3
|
+
const colorFunc = ansi.yellow;
|
|
4
|
+
const namespace = key.namespace
|
|
5
|
+
? ` ${ansi.italic(`(namespace: ${key.namespace})`)}`
|
|
6
|
+
: '';
|
|
7
|
+
const renderedNote = note ? ` ${note}` : '';
|
|
8
|
+
return `${colorFunc(`${key.keyName}`)}${namespace}${renderedNote}`;
|
|
9
|
+
}
|
|
10
|
+
export function getUnresolvedConflictsMessage(translations, isError) {
|
|
11
|
+
const someOverridable = Boolean(translations.find((c) => c.isOverridable));
|
|
12
|
+
const result = [''];
|
|
13
|
+
result.push(`🟡 Some translations cannot be updated:`);
|
|
14
|
+
translations.forEach((c) => {
|
|
15
|
+
result.push(renderKey({ keyName: c.keyName, namespace: c.keyNamespace }, `${c.language}` + (c.isOverridable ? ' (overridable)' : '')));
|
|
16
|
+
});
|
|
17
|
+
result.push('');
|
|
18
|
+
if (someOverridable) {
|
|
19
|
+
result.push('HINT: Overridable translations can be updated with the `--override-mode ALL`');
|
|
20
|
+
result.push('');
|
|
21
|
+
}
|
|
22
|
+
return result.join('\n');
|
|
23
|
+
}
|
|
24
|
+
export function printUnresolvedConflicts(translations, isError) {
|
|
25
|
+
console.log(getUnresolvedConflictsMessage(translations, isError));
|
|
26
|
+
}
|
package/package.json
CHANGED
package/schema.json
CHANGED
|
@@ -90,6 +90,12 @@
|
|
|
90
90
|
"removeOtherKeys": {
|
|
91
91
|
"description": "Remove keys which are not present in the import (within imported namespaces).",
|
|
92
92
|
"type": "boolean"
|
|
93
|
+
},
|
|
94
|
+
"errorOnUnresolvedConflict": {
|
|
95
|
+
"$ref": "#/$defs/errorOnUnresolvedConflict"
|
|
96
|
+
},
|
|
97
|
+
"overrideMode": {
|
|
98
|
+
"$ref": "#/$defs/overrideMode"
|
|
93
99
|
}
|
|
94
100
|
}
|
|
95
101
|
},
|
|
@@ -251,6 +257,16 @@
|
|
|
251
257
|
"type": "string",
|
|
252
258
|
"enum": ["OVERRIDE", "KEEP", "NO_FORCE"]
|
|
253
259
|
},
|
|
260
|
+
"overrideMode": {
|
|
261
|
+
"description": "Specifies what is considered non-overridable translation: \n - RECOMMENDED - protected reviewed translations are considered as non-overridable\n - ALL - translations that user has permissions for",
|
|
262
|
+
"type": "string",
|
|
263
|
+
"enum": ["ALL", "RECOMMENDED"]
|
|
264
|
+
},
|
|
265
|
+
"errorOnUnresolvedConflict": {
|
|
266
|
+
"description": "Fail the whole import if there are unresolved conflicts in import: \n - yes - fail if any unresolved conflict is present\n no - don't fail and just print unresolved conflicts\n auto - fails when when forceMode=KEEP, otherwise doesn't fail",
|
|
267
|
+
"type": "string",
|
|
268
|
+
"enum": ["yes", "no", "auto"]
|
|
269
|
+
},
|
|
254
270
|
"path": {
|
|
255
271
|
"description": "File glob specifying which files to include.",
|
|
256
272
|
"type": "string"
|