lingo.dev 0.111.3 → 0.111.5
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/assets/failure.mp3 +0 -0
- package/assets/success.mp3 +0 -0
- package/build/cli.cjs +431 -184
- package/build/cli.cjs.map +1 -1
- package/build/cli.mjs +323 -76
- package/build/cli.mjs.map +1 -1
- package/package.json +3 -2
package/build/cli.mjs
CHANGED
|
@@ -216,6 +216,7 @@ var docLinks = {
|
|
|
216
216
|
};
|
|
217
217
|
var CLIError = class extends Error {
|
|
218
218
|
docUrl;
|
|
219
|
+
errorType = "cli_error";
|
|
219
220
|
constructor({ message, docUrl }) {
|
|
220
221
|
super(message);
|
|
221
222
|
this.docUrl = docLinks[docUrl];
|
|
@@ -223,6 +224,137 @@ var CLIError = class extends Error {
|
|
|
223
224
|
visit: ${this.docUrl}`;
|
|
224
225
|
}
|
|
225
226
|
};
|
|
227
|
+
var ConfigError = class extends CLIError {
|
|
228
|
+
errorType = "config_error";
|
|
229
|
+
constructor({ message, docUrl }) {
|
|
230
|
+
super({ message, docUrl });
|
|
231
|
+
this.name = "ConfigError";
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
var AuthenticationError = class extends CLIError {
|
|
235
|
+
errorType = "auth_error";
|
|
236
|
+
constructor({ message, docUrl }) {
|
|
237
|
+
super({ message, docUrl });
|
|
238
|
+
this.name = "AuthenticationError";
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
var ValidationError = class extends CLIError {
|
|
242
|
+
errorType = "validation_error";
|
|
243
|
+
constructor({ message, docUrl }) {
|
|
244
|
+
super({ message, docUrl });
|
|
245
|
+
this.name = "ValidationError";
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
var LocalizationError = class extends Error {
|
|
249
|
+
errorType = "locale_error";
|
|
250
|
+
bucket;
|
|
251
|
+
sourceLocale;
|
|
252
|
+
targetLocale;
|
|
253
|
+
pathPattern;
|
|
254
|
+
constructor(message, context) {
|
|
255
|
+
super(message);
|
|
256
|
+
this.name = "LocalizationError";
|
|
257
|
+
this.bucket = context?.bucket;
|
|
258
|
+
this.sourceLocale = context?.sourceLocale;
|
|
259
|
+
this.targetLocale = context?.targetLocale;
|
|
260
|
+
this.pathPattern = context?.pathPattern;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
var BucketProcessingError = class extends Error {
|
|
264
|
+
errorType = "bucket_error";
|
|
265
|
+
bucket;
|
|
266
|
+
constructor(message, bucket) {
|
|
267
|
+
super(message);
|
|
268
|
+
this.name = "BucketProcessingError";
|
|
269
|
+
this.bucket = bucket;
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
function isConfigError(error) {
|
|
273
|
+
return error instanceof ConfigError || error.errorType === "config_error";
|
|
274
|
+
}
|
|
275
|
+
function isAuthenticationError(error) {
|
|
276
|
+
return error instanceof AuthenticationError || error.errorType === "auth_error";
|
|
277
|
+
}
|
|
278
|
+
function isValidationError(error) {
|
|
279
|
+
return error instanceof ValidationError || error.errorType === "validation_error";
|
|
280
|
+
}
|
|
281
|
+
function isLocalizationError(error) {
|
|
282
|
+
return error instanceof LocalizationError || error.errorType === "locale_error";
|
|
283
|
+
}
|
|
284
|
+
function isBucketProcessingError(error) {
|
|
285
|
+
return error instanceof BucketProcessingError || error.errorType === "bucket_error";
|
|
286
|
+
}
|
|
287
|
+
function getCLIErrorType(error) {
|
|
288
|
+
if (isConfigError(error)) return "config_error";
|
|
289
|
+
if (isAuthenticationError(error)) return "auth_error";
|
|
290
|
+
if (isValidationError(error)) return "validation_error";
|
|
291
|
+
if (isLocalizationError(error)) return "locale_error";
|
|
292
|
+
if (isBucketProcessingError(error)) return "bucket_error";
|
|
293
|
+
if (error instanceof CLIError) return "cli_error";
|
|
294
|
+
return "unknown_error";
|
|
295
|
+
}
|
|
296
|
+
function createPreviousErrorContext(errorDetails) {
|
|
297
|
+
if (errorDetails.length === 0) return void 0;
|
|
298
|
+
return {
|
|
299
|
+
count: errorDetails.length,
|
|
300
|
+
types: [...new Set(errorDetails.map((e) => e.type))],
|
|
301
|
+
buckets: [...new Set(errorDetails.map((e) => e.bucket).filter(Boolean))]
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function aggregateErrorAnalytics(errorDetails, buckets, targetLocales, i18nConfig) {
|
|
305
|
+
if (errorDetails.length === 0) {
|
|
306
|
+
return {
|
|
307
|
+
errorCount: 0,
|
|
308
|
+
errorTypes: [],
|
|
309
|
+
errorsByBucket: {},
|
|
310
|
+
errorsByType: {},
|
|
311
|
+
firstError: void 0,
|
|
312
|
+
bucketCount: buckets.length,
|
|
313
|
+
localeCount: targetLocales.length,
|
|
314
|
+
i18nConfig: {
|
|
315
|
+
sourceLocale: i18nConfig.locale.source,
|
|
316
|
+
targetLocales: i18nConfig.locale.targets,
|
|
317
|
+
bucketTypes: Object.keys(i18nConfig.buckets)
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
const errorsByBucket = errorDetails.reduce(
|
|
322
|
+
(acc, error) => {
|
|
323
|
+
if (error.bucket) {
|
|
324
|
+
acc[error.bucket] = (acc[error.bucket] || 0) + 1;
|
|
325
|
+
}
|
|
326
|
+
return acc;
|
|
327
|
+
},
|
|
328
|
+
{}
|
|
329
|
+
);
|
|
330
|
+
const errorsByType = errorDetails.reduce(
|
|
331
|
+
(acc, error) => {
|
|
332
|
+
acc[error.type] = (acc[error.type] || 0) + 1;
|
|
333
|
+
return acc;
|
|
334
|
+
},
|
|
335
|
+
{}
|
|
336
|
+
);
|
|
337
|
+
return {
|
|
338
|
+
errorCount: errorDetails.length,
|
|
339
|
+
errorTypes: [...new Set(errorDetails.map((e) => e.type))],
|
|
340
|
+
errorsByBucket,
|
|
341
|
+
errorsByType,
|
|
342
|
+
firstError: {
|
|
343
|
+
type: errorDetails[0].type,
|
|
344
|
+
bucket: errorDetails[0].bucket,
|
|
345
|
+
locale: errorDetails[0].locale,
|
|
346
|
+
pathPattern: errorDetails[0].pathPattern,
|
|
347
|
+
message: errorDetails[0].message
|
|
348
|
+
},
|
|
349
|
+
bucketCount: buckets.length,
|
|
350
|
+
localeCount: targetLocales.length,
|
|
351
|
+
i18nConfig: {
|
|
352
|
+
sourceLocale: i18nConfig.locale.source,
|
|
353
|
+
targetLocales: i18nConfig.locale.targets,
|
|
354
|
+
bucketTypes: Object.keys(i18nConfig.buckets)
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
}
|
|
226
358
|
|
|
227
359
|
// src/cli/utils/cloudflare-status.ts
|
|
228
360
|
async function checkCloudflareStatus() {
|
|
@@ -926,9 +1058,9 @@ function makeGitlabInitializer(spinner) {
|
|
|
926
1058
|
|
|
927
1059
|
// src/cli/cmd/init.ts
|
|
928
1060
|
import open2 from "open";
|
|
929
|
-
var openUrl = (
|
|
1061
|
+
var openUrl = (path18) => {
|
|
930
1062
|
const settings = getSettings(void 0);
|
|
931
|
-
open2(`${settings.auth.webUrl}${
|
|
1063
|
+
open2(`${settings.auth.webUrl}${path18}`, { wait: false });
|
|
932
1064
|
};
|
|
933
1065
|
var throwHelpError = (option, value) => {
|
|
934
1066
|
if (value === "help") {
|
|
@@ -1348,8 +1480,8 @@ var files_default = new Command6().command("files").description("Print out the l
|
|
|
1348
1480
|
} else if (type.target) {
|
|
1349
1481
|
result.push(...targetPaths);
|
|
1350
1482
|
}
|
|
1351
|
-
result.forEach((
|
|
1352
|
-
console.log(
|
|
1483
|
+
result.forEach((path18) => {
|
|
1484
|
+
console.log(path18);
|
|
1353
1485
|
});
|
|
1354
1486
|
}
|
|
1355
1487
|
}
|
|
@@ -1667,8 +1799,8 @@ function extractCommentsFromJsonc(jsoncString) {
|
|
|
1667
1799
|
const keyMatch = line.match(/^\s*["']?([^"':,\s]+)["']?\s*:/);
|
|
1668
1800
|
if (keyMatch) {
|
|
1669
1801
|
const key = keyMatch[1];
|
|
1670
|
-
const
|
|
1671
|
-
keyInfo = { key, path:
|
|
1802
|
+
const path18 = contextStack.map((ctx) => ctx.key).filter(Boolean);
|
|
1803
|
+
keyInfo = { key, path: path18 };
|
|
1672
1804
|
}
|
|
1673
1805
|
} else {
|
|
1674
1806
|
keyInfo = findAssociatedKey(lines, commentData.lineIndex, contextStack);
|
|
@@ -1752,8 +1884,8 @@ function findAssociatedKey(lines, commentLineIndex, contextStack) {
|
|
|
1752
1884
|
const keyMatch = line.match(/^\s*["']?([^"':,\s]+)["']?\s*:/);
|
|
1753
1885
|
if (keyMatch) {
|
|
1754
1886
|
const key = keyMatch[1];
|
|
1755
|
-
const
|
|
1756
|
-
return { key, path:
|
|
1887
|
+
const path18 = contextStack.map((ctx) => ctx.key).filter(Boolean);
|
|
1888
|
+
return { key, path: path18 };
|
|
1757
1889
|
}
|
|
1758
1890
|
}
|
|
1759
1891
|
return { key: null, path: [] };
|
|
@@ -1772,9 +1904,9 @@ function updateContext(contextStack, line, parsedJson) {
|
|
|
1772
1904
|
}
|
|
1773
1905
|
}
|
|
1774
1906
|
}
|
|
1775
|
-
function setCommentAtPath(comments,
|
|
1907
|
+
function setCommentAtPath(comments, path18, key, hint) {
|
|
1776
1908
|
let current = comments;
|
|
1777
|
-
for (const pathKey of
|
|
1909
|
+
for (const pathKey of path18) {
|
|
1778
1910
|
if (!current[pathKey]) {
|
|
1779
1911
|
current[pathKey] = {};
|
|
1780
1912
|
}
|
|
@@ -2435,9 +2567,9 @@ function createHtmlLoader() {
|
|
|
2435
2567
|
const bDepth = b.split("/").length;
|
|
2436
2568
|
return aDepth - bDepth;
|
|
2437
2569
|
});
|
|
2438
|
-
paths.forEach((
|
|
2439
|
-
const value = data[
|
|
2440
|
-
const [nodePath, attribute] =
|
|
2570
|
+
paths.forEach((path18) => {
|
|
2571
|
+
const value = data[path18];
|
|
2572
|
+
const [nodePath, attribute] = path18.split("#");
|
|
2441
2573
|
const [rootTag, ...indices] = nodePath.split("/");
|
|
2442
2574
|
let parent = rootTag === "head" ? document.head : document.body;
|
|
2443
2575
|
let current = parent;
|
|
@@ -4080,24 +4212,24 @@ function createRawDatoValue(parsedDatoValue, originalRawDatoValue, isClean = fal
|
|
|
4080
4212
|
}
|
|
4081
4213
|
function serializeStructuredText(rawStructuredText) {
|
|
4082
4214
|
return serializeStructuredTextNode(rawStructuredText);
|
|
4083
|
-
function serializeStructuredTextNode(node,
|
|
4215
|
+
function serializeStructuredTextNode(node, path18 = [], acc = {}) {
|
|
4084
4216
|
if ("document" in node) {
|
|
4085
4217
|
return serializeStructuredTextNode(
|
|
4086
4218
|
node.document,
|
|
4087
|
-
[...
|
|
4219
|
+
[...path18, "document"],
|
|
4088
4220
|
acc
|
|
4089
4221
|
);
|
|
4090
4222
|
}
|
|
4091
4223
|
if (!_18.isNil(node.value)) {
|
|
4092
|
-
acc[[...
|
|
4224
|
+
acc[[...path18, "value"].join(".")] = node.value;
|
|
4093
4225
|
} else if (_18.get(node, "type") === "block") {
|
|
4094
|
-
acc[[...
|
|
4226
|
+
acc[[...path18, "item"].join(".")] = serializeBlock(node.item);
|
|
4095
4227
|
}
|
|
4096
4228
|
if (node.children) {
|
|
4097
4229
|
for (let i = 0; i < node.children.length; i++) {
|
|
4098
4230
|
serializeStructuredTextNode(
|
|
4099
4231
|
node.children[i],
|
|
4100
|
-
[...
|
|
4232
|
+
[...path18, i.toString()],
|
|
4101
4233
|
acc
|
|
4102
4234
|
);
|
|
4103
4235
|
}
|
|
@@ -4164,8 +4296,8 @@ function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = f
|
|
|
4164
4296
|
}
|
|
4165
4297
|
function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
|
|
4166
4298
|
const result = _18.cloneDeep(originalRawStructuredText);
|
|
4167
|
-
for (const [
|
|
4168
|
-
const realPath = _18.chain(
|
|
4299
|
+
for (const [path18, value] of _18.entries(parsedStructuredText)) {
|
|
4300
|
+
const realPath = _18.chain(path18.split(".")).flatMap((s) => !_18.isNaN(_18.toNumber(s)) ? ["children", s] : s).value();
|
|
4169
4301
|
const deserializedValue = createRawDatoValue(
|
|
4170
4302
|
value,
|
|
4171
4303
|
_18.get(originalRawStructuredText, realPath),
|
|
@@ -4591,15 +4723,15 @@ function parseTypeScript(input2) {
|
|
|
4591
4723
|
function extractStringsFromDefaultExport(ast) {
|
|
4592
4724
|
let extracted = {};
|
|
4593
4725
|
traverse(ast, {
|
|
4594
|
-
ExportDefaultDeclaration(
|
|
4595
|
-
const { declaration } =
|
|
4726
|
+
ExportDefaultDeclaration(path18) {
|
|
4727
|
+
const { declaration } = path18.node;
|
|
4596
4728
|
const decl = unwrapTSAsExpression(declaration);
|
|
4597
4729
|
if (t.isObjectExpression(decl)) {
|
|
4598
4730
|
extracted = objectExpressionToObject(decl);
|
|
4599
4731
|
} else if (t.isArrayExpression(decl)) {
|
|
4600
4732
|
extracted = arrayExpressionToArray(decl);
|
|
4601
4733
|
} else if (t.isIdentifier(decl)) {
|
|
4602
|
-
const binding =
|
|
4734
|
+
const binding = path18.scope.bindings[decl.name];
|
|
4603
4735
|
if (binding && t.isVariableDeclarator(binding.path.node) && binding.path.node.init) {
|
|
4604
4736
|
const initRaw = binding.path.node.init;
|
|
4605
4737
|
const init = initRaw ? unwrapTSAsExpression(initRaw) : initRaw;
|
|
@@ -4664,8 +4796,8 @@ function arrayExpressionToArray(arrayExpression) {
|
|
|
4664
4796
|
function updateStringsInDefaultExport(ast, data) {
|
|
4665
4797
|
let modified = false;
|
|
4666
4798
|
traverse(ast, {
|
|
4667
|
-
ExportDefaultDeclaration(
|
|
4668
|
-
const { declaration } =
|
|
4799
|
+
ExportDefaultDeclaration(path18) {
|
|
4800
|
+
const { declaration } = path18.node;
|
|
4669
4801
|
const decl = unwrapTSAsExpression(declaration);
|
|
4670
4802
|
if (t.isObjectExpression(decl)) {
|
|
4671
4803
|
modified = updateStringsInObjectExpression(decl, data) || modified;
|
|
@@ -4674,7 +4806,7 @@ function updateStringsInDefaultExport(ast, data) {
|
|
|
4674
4806
|
modified = updateStringsInArrayExpression(decl, data) || modified;
|
|
4675
4807
|
}
|
|
4676
4808
|
} else if (t.isIdentifier(decl)) {
|
|
4677
|
-
modified = updateStringsInExportedIdentifier(
|
|
4809
|
+
modified = updateStringsInExportedIdentifier(path18, data) || modified;
|
|
4678
4810
|
}
|
|
4679
4811
|
}
|
|
4680
4812
|
});
|
|
@@ -4745,9 +4877,9 @@ function updateStringsInArrayExpression(arrayExpression, incoming) {
|
|
|
4745
4877
|
});
|
|
4746
4878
|
return modified;
|
|
4747
4879
|
}
|
|
4748
|
-
function updateStringsInExportedIdentifier(
|
|
4749
|
-
const exportName =
|
|
4750
|
-
const binding =
|
|
4880
|
+
function updateStringsInExportedIdentifier(path18, data) {
|
|
4881
|
+
const exportName = path18.node.declaration.name;
|
|
4882
|
+
const binding = path18.scope.bindings[exportName];
|
|
4751
4883
|
if (!binding || !binding.path.node) return false;
|
|
4752
4884
|
if (t.isVariableDeclarator(binding.path.node) && binding.path.node.init) {
|
|
4753
4885
|
const initRaw = binding.path.node.init;
|
|
@@ -6349,11 +6481,11 @@ function _getAllKeys(obj, prefix = "") {
|
|
|
6349
6481
|
let keys = [];
|
|
6350
6482
|
for (const key in obj) {
|
|
6351
6483
|
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
|
|
6352
|
-
const
|
|
6484
|
+
const path18 = prefix ? `${prefix}.${key}` : key;
|
|
6353
6485
|
if (typeof obj[key] === "object" && obj[key] !== null && !Array.isArray(obj[key])) {
|
|
6354
|
-
keys = keys.concat(_getAllKeys(obj[key],
|
|
6486
|
+
keys = keys.concat(_getAllKeys(obj[key], path18));
|
|
6355
6487
|
} else {
|
|
6356
|
-
keys.push(
|
|
6488
|
+
keys.push(path18);
|
|
6357
6489
|
}
|
|
6358
6490
|
}
|
|
6359
6491
|
return keys;
|
|
@@ -6866,19 +6998,19 @@ function createJsonDictionaryLoader() {
|
|
|
6866
6998
|
);
|
|
6867
6999
|
return input2;
|
|
6868
7000
|
}
|
|
6869
|
-
function walk(obj, dataNode,
|
|
7001
|
+
function walk(obj, dataNode, path18 = []) {
|
|
6870
7002
|
if (Array.isArray(obj) && Array.isArray(dataNode)) {
|
|
6871
7003
|
obj.forEach(
|
|
6872
|
-
(item, idx) => walk(item, dataNode[idx], [...
|
|
7004
|
+
(item, idx) => walk(item, dataNode[idx], [...path18, String(idx)])
|
|
6873
7005
|
);
|
|
6874
7006
|
} else if (obj && typeof obj === "object" && dataNode && typeof dataNode === "object" && !Array.isArray(dataNode)) {
|
|
6875
7007
|
for (const key of Object.keys(obj)) {
|
|
6876
7008
|
if (dataNode.hasOwnProperty(key)) {
|
|
6877
|
-
walk(obj[key], dataNode[key], [...
|
|
7009
|
+
walk(obj[key], dataNode[key], [...path18, key]);
|
|
6878
7010
|
}
|
|
6879
7011
|
}
|
|
6880
7012
|
} else if (obj && typeof obj === "object" && !Array.isArray(obj) && typeof dataNode === "string") {
|
|
6881
|
-
setNestedLocale(input2,
|
|
7013
|
+
setNestedLocale(input2, path18, locale, dataNode, originalLocale);
|
|
6882
7014
|
}
|
|
6883
7015
|
}
|
|
6884
7016
|
walk(input2, data);
|
|
@@ -6906,14 +7038,14 @@ function extractTranslatables(obj, locale) {
|
|
|
6906
7038
|
function isTranslatableObject(obj, locale) {
|
|
6907
7039
|
return obj && typeof obj === "object" && !Array.isArray(obj) && Object.prototype.hasOwnProperty.call(obj, locale);
|
|
6908
7040
|
}
|
|
6909
|
-
function setNestedLocale(obj,
|
|
7041
|
+
function setNestedLocale(obj, path18, locale, value, originalLocale) {
|
|
6910
7042
|
let curr = obj;
|
|
6911
|
-
for (let i = 0; i <
|
|
6912
|
-
const key =
|
|
7043
|
+
for (let i = 0; i < path18.length - 1; i++) {
|
|
7044
|
+
const key = path18[i];
|
|
6913
7045
|
if (!(key in curr)) curr[key] = {};
|
|
6914
7046
|
curr = curr[key];
|
|
6915
7047
|
}
|
|
6916
|
-
const last =
|
|
7048
|
+
const last = path18[path18.length - 1];
|
|
6917
7049
|
if (curr[last] && typeof curr[last] === "object") {
|
|
6918
7050
|
curr[last][locale] = value;
|
|
6919
7051
|
if (originalLocale && curr[last][originalLocale]) {
|
|
@@ -7483,7 +7615,11 @@ function trackEvent(distinctId, event, properties) {
|
|
|
7483
7615
|
properties: {
|
|
7484
7616
|
...properties,
|
|
7485
7617
|
$lib: "lingo.dev-cli",
|
|
7486
|
-
$lib_version: process.env.npm_package_version || "unknown"
|
|
7618
|
+
$lib_version: process.env.npm_package_version || "unknown",
|
|
7619
|
+
// Essential debugging context only
|
|
7620
|
+
node_version: process.version,
|
|
7621
|
+
is_ci: !!process.env.CI,
|
|
7622
|
+
debug_enabled: process.env.DEBUG === "true"
|
|
7487
7623
|
},
|
|
7488
7624
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
7489
7625
|
};
|
|
@@ -7683,7 +7819,21 @@ var i18n_default = new Command12().command("i18n").description("Run Localization
|
|
|
7683
7819
|
).action(async function(options) {
|
|
7684
7820
|
updateGitignore();
|
|
7685
7821
|
const ora = Ora7();
|
|
7686
|
-
|
|
7822
|
+
let flags;
|
|
7823
|
+
try {
|
|
7824
|
+
flags = parseFlags(options);
|
|
7825
|
+
} catch (parseError) {
|
|
7826
|
+
await trackEvent("unknown", "cmd.i18n.error", {
|
|
7827
|
+
errorType: "validation_error",
|
|
7828
|
+
errorName: parseError.name || "ValidationError",
|
|
7829
|
+
errorMessage: parseError.message || "Invalid command line options",
|
|
7830
|
+
errorStack: parseError.stack,
|
|
7831
|
+
fatal: true,
|
|
7832
|
+
errorCount: 1,
|
|
7833
|
+
stage: "flag_validation"
|
|
7834
|
+
});
|
|
7835
|
+
throw parseError;
|
|
7836
|
+
}
|
|
7687
7837
|
if (flags.debug) {
|
|
7688
7838
|
const { debug } = await inquirer2.prompt([
|
|
7689
7839
|
{
|
|
@@ -7695,6 +7845,7 @@ var i18n_default = new Command12().command("i18n").description("Run Localization
|
|
|
7695
7845
|
}
|
|
7696
7846
|
let hasErrors = false;
|
|
7697
7847
|
let authId = null;
|
|
7848
|
+
const errorDetails = [];
|
|
7698
7849
|
try {
|
|
7699
7850
|
ora.start("Loading configuration...");
|
|
7700
7851
|
const i18nConfig = getConfig();
|
|
@@ -7727,7 +7878,7 @@ var i18n_default = new Command12().command("i18n").description("Run Localization
|
|
|
7727
7878
|
if (flags.file?.length) {
|
|
7728
7879
|
buckets = buckets.map((bucket) => {
|
|
7729
7880
|
const paths = bucket.paths.filter(
|
|
7730
|
-
(
|
|
7881
|
+
(path18) => flags.file.find((file) => path18.pathPattern?.includes(file))
|
|
7731
7882
|
);
|
|
7732
7883
|
return { ...bucket, paths };
|
|
7733
7884
|
}).filter((bucket) => bucket.paths.length > 0);
|
|
@@ -7742,8 +7893,8 @@ var i18n_default = new Command12().command("i18n").description("Run Localization
|
|
|
7742
7893
|
ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
|
|
7743
7894
|
buckets.map((bucket) => {
|
|
7744
7895
|
ora.info(` ${bucket.type}:`);
|
|
7745
|
-
bucket.paths.forEach((
|
|
7746
|
-
ora.info(` - ${
|
|
7896
|
+
bucket.paths.forEach((path18) => {
|
|
7897
|
+
ora.info(` - ${path18.pathPattern}`);
|
|
7747
7898
|
});
|
|
7748
7899
|
});
|
|
7749
7900
|
}
|
|
@@ -7996,9 +8147,23 @@ var i18n_default = new Command12().command("i18n").description("Run Localization
|
|
|
7996
8147
|
);
|
|
7997
8148
|
}
|
|
7998
8149
|
} catch (_error) {
|
|
7999
|
-
const error = new
|
|
8000
|
-
`[${sourceLocale} -> ${targetLocale}] Localization failed: ${_error.message}
|
|
8150
|
+
const error = new LocalizationError(
|
|
8151
|
+
`[${sourceLocale} -> ${targetLocale}] Localization failed: ${_error.message}`,
|
|
8152
|
+
{
|
|
8153
|
+
bucket: bucket.type,
|
|
8154
|
+
sourceLocale,
|
|
8155
|
+
targetLocale,
|
|
8156
|
+
pathPattern: bucketPath.pathPattern
|
|
8157
|
+
}
|
|
8001
8158
|
);
|
|
8159
|
+
errorDetails.push({
|
|
8160
|
+
type: "locale_error",
|
|
8161
|
+
bucket: bucket.type,
|
|
8162
|
+
locale: `${sourceLocale} -> ${targetLocale}`,
|
|
8163
|
+
pathPattern: bucketPath.pathPattern,
|
|
8164
|
+
message: _error.message,
|
|
8165
|
+
stack: _error.stack
|
|
8166
|
+
});
|
|
8002
8167
|
if (flags.strict) {
|
|
8003
8168
|
throw error;
|
|
8004
8169
|
} else {
|
|
@@ -8014,9 +8179,16 @@ var i18n_default = new Command12().command("i18n").description("Run Localization
|
|
|
8014
8179
|
}
|
|
8015
8180
|
}
|
|
8016
8181
|
} catch (_error) {
|
|
8017
|
-
const error = new
|
|
8018
|
-
`Failed to process bucket ${bucket.type}: ${_error.message}
|
|
8182
|
+
const error = new BucketProcessingError(
|
|
8183
|
+
`Failed to process bucket ${bucket.type}: ${_error.message}`,
|
|
8184
|
+
bucket.type
|
|
8019
8185
|
);
|
|
8186
|
+
errorDetails.push({
|
|
8187
|
+
type: "bucket_error",
|
|
8188
|
+
bucket: bucket.type,
|
|
8189
|
+
message: _error.message,
|
|
8190
|
+
stack: _error.stack
|
|
8191
|
+
});
|
|
8020
8192
|
if (flags.strict) {
|
|
8021
8193
|
throw error;
|
|
8022
8194
|
} else {
|
|
@@ -8029,20 +8201,54 @@ var i18n_default = new Command12().command("i18n").description("Run Localization
|
|
|
8029
8201
|
if (!hasErrors) {
|
|
8030
8202
|
ora.succeed("Localization completed.");
|
|
8031
8203
|
await trackEvent(authId, "cmd.i18n.success", {
|
|
8032
|
-
i18nConfig
|
|
8033
|
-
|
|
8204
|
+
i18nConfig: {
|
|
8205
|
+
sourceLocale: i18nConfig.locale.source,
|
|
8206
|
+
targetLocales: i18nConfig.locale.targets,
|
|
8207
|
+
bucketTypes: Object.keys(i18nConfig.buckets)
|
|
8208
|
+
},
|
|
8209
|
+
flags,
|
|
8210
|
+
bucketCount: buckets.length,
|
|
8211
|
+
localeCount: targetLocales.length,
|
|
8212
|
+
processedSuccessfully: true
|
|
8034
8213
|
});
|
|
8035
8214
|
} else {
|
|
8036
8215
|
ora.warn("Localization completed with errors.");
|
|
8037
8216
|
await trackEvent(authId || "unknown", "cmd.i18n.error", {
|
|
8038
|
-
flags
|
|
8217
|
+
flags,
|
|
8218
|
+
...aggregateErrorAnalytics(
|
|
8219
|
+
errorDetails,
|
|
8220
|
+
buckets,
|
|
8221
|
+
targetLocales,
|
|
8222
|
+
i18nConfig
|
|
8223
|
+
)
|
|
8039
8224
|
});
|
|
8040
8225
|
}
|
|
8041
8226
|
} catch (error) {
|
|
8042
8227
|
ora.fail(error.message);
|
|
8228
|
+
const errorType = getCLIErrorType(error);
|
|
8229
|
+
let errorContext = {};
|
|
8230
|
+
if (isLocalizationError(error)) {
|
|
8231
|
+
errorContext = {
|
|
8232
|
+
bucket: error.bucket,
|
|
8233
|
+
sourceLocale: error.sourceLocale,
|
|
8234
|
+
targetLocale: error.targetLocale,
|
|
8235
|
+
pathPattern: error.pathPattern
|
|
8236
|
+
};
|
|
8237
|
+
} else if (isBucketProcessingError(error)) {
|
|
8238
|
+
errorContext = {
|
|
8239
|
+
bucket: error.bucket
|
|
8240
|
+
};
|
|
8241
|
+
}
|
|
8043
8242
|
await trackEvent(authId || "unknown", "cmd.i18n.error", {
|
|
8044
8243
|
flags,
|
|
8045
|
-
|
|
8244
|
+
errorType,
|
|
8245
|
+
errorName: error.name || "Error",
|
|
8246
|
+
errorMessage: error.message,
|
|
8247
|
+
errorStack: error.stack,
|
|
8248
|
+
errorContext,
|
|
8249
|
+
fatal: true,
|
|
8250
|
+
errorCount: errorDetails.length + 1,
|
|
8251
|
+
previousErrors: createPreviousErrorContext(errorDetails)
|
|
8046
8252
|
});
|
|
8047
8253
|
}
|
|
8048
8254
|
});
|
|
@@ -8063,7 +8269,7 @@ function parseFlags(options) {
|
|
|
8063
8269
|
}
|
|
8064
8270
|
async function validateAuth(settings) {
|
|
8065
8271
|
if (!settings.auth.apiKey) {
|
|
8066
|
-
throw new
|
|
8272
|
+
throw new AuthenticationError({
|
|
8067
8273
|
message: "Not authenticated. Please run `lingo.dev login` to authenticate.",
|
|
8068
8274
|
docUrl: "authError"
|
|
8069
8275
|
});
|
|
@@ -8074,7 +8280,7 @@ async function validateAuth(settings) {
|
|
|
8074
8280
|
});
|
|
8075
8281
|
const user = await authenticator.whoami();
|
|
8076
8282
|
if (!user) {
|
|
8077
|
-
throw new
|
|
8283
|
+
throw new AuthenticationError({
|
|
8078
8284
|
message: "Invalid API key. Please run `lingo.dev login` to authenticate.",
|
|
8079
8285
|
docUrl: "authError"
|
|
8080
8286
|
});
|
|
@@ -8083,24 +8289,24 @@ async function validateAuth(settings) {
|
|
|
8083
8289
|
}
|
|
8084
8290
|
function validateParams(i18nConfig, flags) {
|
|
8085
8291
|
if (!i18nConfig) {
|
|
8086
|
-
throw new
|
|
8292
|
+
throw new ConfigError({
|
|
8087
8293
|
message: "i18n.json not found. Please run `lingo.dev init` to initialize the project.",
|
|
8088
8294
|
docUrl: "i18nNotFound"
|
|
8089
8295
|
});
|
|
8090
8296
|
} else if (!i18nConfig.buckets || !Object.keys(i18nConfig.buckets).length) {
|
|
8091
|
-
throw new
|
|
8297
|
+
throw new ConfigError({
|
|
8092
8298
|
message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
|
|
8093
8299
|
docUrl: "bucketNotFound"
|
|
8094
8300
|
});
|
|
8095
8301
|
} else if (flags.locale?.some((locale) => !i18nConfig.locale.targets.includes(locale))) {
|
|
8096
|
-
throw new
|
|
8302
|
+
throw new ValidationError({
|
|
8097
8303
|
message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
|
|
8098
8304
|
docUrl: "localeTargetNotFound"
|
|
8099
8305
|
});
|
|
8100
8306
|
} else if (flags.bucket?.some(
|
|
8101
8307
|
(bucket) => !i18nConfig.buckets[bucket]
|
|
8102
8308
|
)) {
|
|
8103
|
-
throw new
|
|
8309
|
+
throw new ValidationError({
|
|
8104
8310
|
message: `One or more specified buckets do not exist in i18n.json. Please add them to the list and try again.`,
|
|
8105
8311
|
docUrl: "bucketNotFound"
|
|
8106
8312
|
});
|
|
@@ -8533,7 +8739,7 @@ import { execSync as execSync2 } from "child_process";
|
|
|
8533
8739
|
|
|
8534
8740
|
// src/cli/cmd/ci/flows/in-branch.ts
|
|
8535
8741
|
import { execSync } from "child_process";
|
|
8536
|
-
import
|
|
8742
|
+
import path17 from "path";
|
|
8537
8743
|
|
|
8538
8744
|
// src/cli/cmd/ci/flows/_base.ts
|
|
8539
8745
|
var IntegrationFlow = class {
|
|
@@ -8553,6 +8759,10 @@ function escapeShellArg(arg) {
|
|
|
8553
8759
|
|
|
8554
8760
|
// src/cli/cmd/run/index.ts
|
|
8555
8761
|
import { Command as Command16 } from "interactive-commander";
|
|
8762
|
+
import { exec } from "child_process";
|
|
8763
|
+
import path16 from "path";
|
|
8764
|
+
import { fileURLToPath } from "url";
|
|
8765
|
+
import os2 from "os";
|
|
8556
8766
|
|
|
8557
8767
|
// src/cli/cmd/run/setup.ts
|
|
8558
8768
|
import chalk10 from "chalk";
|
|
@@ -9296,14 +9506,14 @@ async function watch2(ctx) {
|
|
|
9296
9506
|
pollInterval: 100
|
|
9297
9507
|
}
|
|
9298
9508
|
});
|
|
9299
|
-
watcher.on("change", (
|
|
9300
|
-
handleFileChange(
|
|
9509
|
+
watcher.on("change", (path18) => {
|
|
9510
|
+
handleFileChange(path18, state, ctx);
|
|
9301
9511
|
});
|
|
9302
|
-
watcher.on("add", (
|
|
9303
|
-
handleFileChange(
|
|
9512
|
+
watcher.on("add", (path18) => {
|
|
9513
|
+
handleFileChange(path18, state, ctx);
|
|
9304
9514
|
});
|
|
9305
|
-
watcher.on("unlink", (
|
|
9306
|
-
handleFileChange(
|
|
9515
|
+
watcher.on("unlink", (path18) => {
|
|
9516
|
+
handleFileChange(path18, state, ctx);
|
|
9307
9517
|
});
|
|
9308
9518
|
watcher.on("error", (error) => {
|
|
9309
9519
|
console.error(
|
|
@@ -9414,8 +9624,9 @@ var flagsSchema2 = z2.object({
|
|
|
9414
9624
|
sourceLocale: z2.string().optional(),
|
|
9415
9625
|
targetLocale: z2.array(z2.string()).optional(),
|
|
9416
9626
|
watch: z2.boolean().default(false),
|
|
9417
|
-
debounce: z2.number().positive().default(5e3)
|
|
9627
|
+
debounce: z2.number().positive().default(5e3),
|
|
9418
9628
|
// 5 seconds default
|
|
9629
|
+
sound: z2.boolean().optional()
|
|
9419
9630
|
});
|
|
9420
9631
|
|
|
9421
9632
|
// src/cli/cmd/run/_utils.ts
|
|
@@ -9434,6 +9645,32 @@ async function determineAuthId(ctx) {
|
|
|
9434
9645
|
}
|
|
9435
9646
|
|
|
9436
9647
|
// src/cli/cmd/run/index.ts
|
|
9648
|
+
var __dirname = path16.dirname(fileURLToPath(import.meta.url));
|
|
9649
|
+
function playSound(type) {
|
|
9650
|
+
const platform = os2.platform();
|
|
9651
|
+
return new Promise((resolve) => {
|
|
9652
|
+
const assetDir = path16.join(__dirname, "../assets");
|
|
9653
|
+
const soundFiles = [path16.join(assetDir, `${type}.mp3`)];
|
|
9654
|
+
let command = "";
|
|
9655
|
+
if (platform === "linux") {
|
|
9656
|
+
command = soundFiles.map(
|
|
9657
|
+
(file) => `mpg123 -q "${file}" 2>/dev/null || aplay "${file}" 2>/dev/null`
|
|
9658
|
+
).join(" || ");
|
|
9659
|
+
} else if (platform === "darwin") {
|
|
9660
|
+
command = soundFiles.map((file) => `afplay "${file}"`).join(" || ");
|
|
9661
|
+
} else if (platform === "win32") {
|
|
9662
|
+
command = `powershell -c "try { (New-Object Media.SoundPlayer '${soundFiles[1]}').PlaySync() } catch { Start-Process -FilePath '${soundFiles[0]}' -WindowStyle Hidden -Wait }"`;
|
|
9663
|
+
} else {
|
|
9664
|
+
command = soundFiles.map(
|
|
9665
|
+
(file) => `aplay "${file}" 2>/dev/null || afplay "${file}" 2>/dev/null`
|
|
9666
|
+
).join(" || ");
|
|
9667
|
+
}
|
|
9668
|
+
exec(command, () => {
|
|
9669
|
+
resolve();
|
|
9670
|
+
});
|
|
9671
|
+
setTimeout(resolve, 3e3);
|
|
9672
|
+
});
|
|
9673
|
+
}
|
|
9437
9674
|
var run_default = new Command16().command("run").description("Run Lingo.dev localization engine").helpOption("-h, --help", "Show help").option(
|
|
9438
9675
|
"--source-locale <source-locale>",
|
|
9439
9676
|
"Locale to use as source locale. Defaults to i18n.json locale.source"
|
|
@@ -9473,6 +9710,9 @@ var run_default = new Command16().command("run").description("Run Lingo.dev loca
|
|
|
9473
9710
|
"--debounce <milliseconds>",
|
|
9474
9711
|
"Debounce delay in milliseconds for watch mode (default: 5000ms)",
|
|
9475
9712
|
(val) => parseInt(val)
|
|
9713
|
+
).option(
|
|
9714
|
+
"--sound",
|
|
9715
|
+
"Play sound on completion, partially completion and failed of the task"
|
|
9476
9716
|
).action(async (args) => {
|
|
9477
9717
|
let authId = null;
|
|
9478
9718
|
try {
|
|
@@ -9502,6 +9742,9 @@ var run_default = new Command16().command("run").description("Run Lingo.dev loca
|
|
|
9502
9742
|
await renderSpacer();
|
|
9503
9743
|
await renderSummary(ctx.results);
|
|
9504
9744
|
await renderSpacer();
|
|
9745
|
+
if (ctx.flags.sound) {
|
|
9746
|
+
await playSound("success");
|
|
9747
|
+
}
|
|
9505
9748
|
if (ctx.flags.watch) {
|
|
9506
9749
|
await watch2(ctx);
|
|
9507
9750
|
}
|
|
@@ -9511,6 +9754,9 @@ var run_default = new Command16().command("run").description("Run Lingo.dev loca
|
|
|
9511
9754
|
});
|
|
9512
9755
|
} catch (error) {
|
|
9513
9756
|
await trackEvent(authId || "unknown", "cmd.run.error", {});
|
|
9757
|
+
if (args.sound) {
|
|
9758
|
+
await playSound("failure");
|
|
9759
|
+
}
|
|
9514
9760
|
throw error;
|
|
9515
9761
|
}
|
|
9516
9762
|
});
|
|
@@ -9601,7 +9847,7 @@ var InBranchFlow = class extends IntegrationFlow {
|
|
|
9601
9847
|
return false;
|
|
9602
9848
|
}
|
|
9603
9849
|
}
|
|
9604
|
-
const workingDir =
|
|
9850
|
+
const workingDir = path17.resolve(
|
|
9605
9851
|
process.cwd(),
|
|
9606
9852
|
this.platformKit.config.workingDir
|
|
9607
9853
|
);
|
|
@@ -10340,8 +10586,8 @@ var status_default = new Command18().command("status").description("Show the sta
|
|
|
10340
10586
|
if (flags.file?.length) {
|
|
10341
10587
|
buckets = buckets.map((bucket) => {
|
|
10342
10588
|
const paths = bucket.paths.filter(
|
|
10343
|
-
(
|
|
10344
|
-
(file) =>
|
|
10589
|
+
(path18) => flags.file.find(
|
|
10590
|
+
(file) => path18.pathPattern?.includes(file) || path18.pathPattern?.match(file) || minimatch(path18.pathPattern, file)
|
|
10345
10591
|
)
|
|
10346
10592
|
);
|
|
10347
10593
|
return { ...bucket, paths };
|
|
@@ -10355,8 +10601,8 @@ var status_default = new Command18().command("status").description("Show the sta
|
|
|
10355
10601
|
ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
|
|
10356
10602
|
buckets.map((bucket) => {
|
|
10357
10603
|
ora.info(` ${bucket.type}:`);
|
|
10358
|
-
bucket.paths.forEach((
|
|
10359
|
-
ora.info(` - ${
|
|
10604
|
+
bucket.paths.forEach((path18) => {
|
|
10605
|
+
ora.info(` - ${path18.pathPattern}`);
|
|
10360
10606
|
});
|
|
10361
10607
|
});
|
|
10362
10608
|
}
|
|
@@ -10640,10 +10886,10 @@ var status_default = new Command18().command("status").description("Show the sta
|
|
|
10640
10886
|
if (flags.confirm && Object.keys(fileStats).length > 0) {
|
|
10641
10887
|
console.log(chalk14.bold(`
|
|
10642
10888
|
\u{1F4D1} BREAKDOWN BY FILE:`));
|
|
10643
|
-
Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([
|
|
10889
|
+
Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([path18, stats]) => {
|
|
10644
10890
|
if (stats.sourceKeys === 0) return;
|
|
10645
10891
|
console.log(chalk14.bold(`
|
|
10646
|
-
\u2022 ${
|
|
10892
|
+
\u2022 ${path18}:`));
|
|
10647
10893
|
console.log(
|
|
10648
10894
|
` ${stats.sourceKeys} source keys, ~${stats.wordCount.toLocaleString()} source words`
|
|
10649
10895
|
);
|
|
@@ -10863,7 +11109,7 @@ async function renderHero2() {
|
|
|
10863
11109
|
// package.json
|
|
10864
11110
|
var package_default = {
|
|
10865
11111
|
name: "lingo.dev",
|
|
10866
|
-
version: "0.111.
|
|
11112
|
+
version: "0.111.5",
|
|
10867
11113
|
description: "Lingo.dev CLI",
|
|
10868
11114
|
private: false,
|
|
10869
11115
|
publishConfig: {
|
|
@@ -10961,7 +11207,8 @@ var package_default = {
|
|
|
10961
11207
|
},
|
|
10962
11208
|
files: [
|
|
10963
11209
|
"bin",
|
|
10964
|
-
"build"
|
|
11210
|
+
"build",
|
|
11211
|
+
"assets"
|
|
10965
11212
|
],
|
|
10966
11213
|
scripts: {
|
|
10967
11214
|
"lingo.dev": "node --inspect=9229 ./bin/cli.mjs",
|