lingo.dev 0.89.6 → 0.90.1
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 +1 -1
- package/build/cli.cjs +189 -84
- package/build/cli.cjs.map +1 -1
- package/build/cli.mjs +183 -78
- package/build/cli.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -164,11 +164,11 @@ Want to contribute? Create a pull request!
|
|
|
164
164
|
- [English](https://github.com/lingodotdev/lingo.dev)
|
|
165
165
|
- [Chinese](/readme/zh-Hans.md)
|
|
166
166
|
- [Japanese](/readme/ja.md)
|
|
167
|
+
- [Korean](/readme/ko.md)
|
|
167
168
|
- [Spanish](/readme/es.md)
|
|
168
169
|
- [French](/readme/fr.md)
|
|
169
170
|
- [Russian](/readme/ru.md)
|
|
170
171
|
- [German](/readme/de.md)
|
|
171
|
-
- [Korean](/readme/ko.md)
|
|
172
172
|
- [Italian](/readme/it.md)
|
|
173
173
|
- [Arabic](/readme/ar.md)
|
|
174
174
|
- [Hindi](/readme/hi.md)
|
package/build/cli.cjs
CHANGED
|
@@ -1342,42 +1342,105 @@ function createAndroidLoader() {
|
|
|
1342
1342
|
return createLoader({
|
|
1343
1343
|
async pull(locale, input2) {
|
|
1344
1344
|
try {
|
|
1345
|
+
if (!input2) {
|
|
1346
|
+
return {};
|
|
1347
|
+
}
|
|
1345
1348
|
const result = {};
|
|
1346
|
-
const
|
|
1349
|
+
const stringRegex = /<string\s+name="([^"]+)"(?:\s+translatable="([^"]+)")?[^>]*>([\s\S]*?)<\/string>/gi;
|
|
1350
|
+
let stringMatch;
|
|
1351
|
+
while ((stringMatch = stringRegex.exec(input2)) !== null) {
|
|
1352
|
+
const name = stringMatch[1];
|
|
1353
|
+
const translatable = stringMatch[2];
|
|
1354
|
+
let value = stringMatch[3];
|
|
1355
|
+
if (translatable === "false") {
|
|
1356
|
+
continue;
|
|
1357
|
+
}
|
|
1358
|
+
const cdataRegex = /<!\[CDATA\[([\s\S]*?)\]\]>/g;
|
|
1359
|
+
value = value.replace(cdataRegex, (match, content) => content);
|
|
1360
|
+
value = value.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'");
|
|
1361
|
+
if (value.startsWith('"') && value.endsWith('"') && value.length >= 2) {
|
|
1362
|
+
value = value.substring(1, value.length - 1);
|
|
1363
|
+
} else {
|
|
1364
|
+
value = value === "" || /^\s+$/.test(value) ? value : value.trim();
|
|
1365
|
+
}
|
|
1366
|
+
result[name] = value;
|
|
1367
|
+
}
|
|
1368
|
+
const parsed = await _xml2js.parseStringPromise.call(void 0, input2, {
|
|
1369
|
+
explicitArray: true,
|
|
1370
|
+
mergeAttrs: false,
|
|
1371
|
+
normalize: true,
|
|
1372
|
+
normalizeTags: false,
|
|
1373
|
+
trim: true,
|
|
1374
|
+
attrkey: "$",
|
|
1375
|
+
charkey: "_"
|
|
1376
|
+
});
|
|
1347
1377
|
if (!parsed || !parsed.resources) {
|
|
1348
|
-
console.warn("No resources found in the Android resource file");
|
|
1349
1378
|
return result;
|
|
1350
1379
|
}
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1380
|
+
if (parsed.resources["string-array"]) {
|
|
1381
|
+
parsed.resources["string-array"].forEach((arrayItem) => {
|
|
1382
|
+
if (arrayItem.$ && arrayItem.$.translatable === "false") {
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1385
|
+
const name = arrayItem.$.name;
|
|
1386
|
+
const items = [];
|
|
1387
|
+
if (arrayItem.item) {
|
|
1388
|
+
arrayItem.item.forEach((item) => {
|
|
1389
|
+
let itemValue = "";
|
|
1390
|
+
if (typeof item === "string") {
|
|
1391
|
+
itemValue = item;
|
|
1392
|
+
} else if (item._) {
|
|
1393
|
+
itemValue = item._;
|
|
1394
|
+
} else if (item._ === "") {
|
|
1395
|
+
itemValue = "";
|
|
1396
|
+
}
|
|
1397
|
+
items.push(itemValue === "" || /^\s+$/.test(itemValue) ? itemValue : itemValue.trim());
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
result[name] = items;
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
if (parsed.resources.plurals) {
|
|
1404
|
+
parsed.resources.plurals.forEach((pluralItem) => {
|
|
1405
|
+
if (pluralItem.$ && pluralItem.$.translatable === "false") {
|
|
1406
|
+
return;
|
|
1407
|
+
}
|
|
1408
|
+
const name = pluralItem.$.name;
|
|
1409
|
+
const pluralObj = {};
|
|
1410
|
+
if (pluralItem.item) {
|
|
1411
|
+
pluralItem.item.forEach((item) => {
|
|
1412
|
+
if (item.$ && item.$.quantity) {
|
|
1413
|
+
let value = "";
|
|
1414
|
+
if (item._) {
|
|
1415
|
+
value = item._;
|
|
1416
|
+
} else if (item._ === "") {
|
|
1417
|
+
value = "";
|
|
1369
1418
|
}
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
} else if (resourceType === "bool") {
|
|
1374
|
-
result[item.$.name] = item._ === "true";
|
|
1375
|
-
} else if (resourceType === "integer") {
|
|
1376
|
-
result[item.$.name] = parseInt(item._ || "0", 10);
|
|
1419
|
+
pluralObj[item.$.quantity] = value === "" || /^\s+$/.test(value) ? value : value.trim();
|
|
1420
|
+
}
|
|
1421
|
+
});
|
|
1377
1422
|
}
|
|
1423
|
+
result[name] = pluralObj;
|
|
1378
1424
|
});
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1425
|
+
}
|
|
1426
|
+
if (parsed.resources.bool) {
|
|
1427
|
+
parsed.resources.bool.forEach((boolItem) => {
|
|
1428
|
+
if (boolItem.$ && boolItem.$.translatable === "false") {
|
|
1429
|
+
return;
|
|
1430
|
+
}
|
|
1431
|
+
const name = boolItem.$.name;
|
|
1432
|
+
result[name] = boolItem._ === "true";
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
1435
|
+
if (parsed.resources.integer) {
|
|
1436
|
+
parsed.resources.integer.forEach((intItem) => {
|
|
1437
|
+
if (intItem.$ && intItem.$.translatable === "false") {
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1440
|
+
const name = intItem.$.name;
|
|
1441
|
+
result[name] = parseInt(intItem._ || "0", 10);
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1381
1444
|
return result;
|
|
1382
1445
|
} catch (error) {
|
|
1383
1446
|
console.error("Error parsing Android resource file:", error);
|
|
@@ -1388,43 +1451,69 @@ function createAndroidLoader() {
|
|
|
1388
1451
|
}
|
|
1389
1452
|
},
|
|
1390
1453
|
async push(locale, payload) {
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1454
|
+
try {
|
|
1455
|
+
const xmlObj = {
|
|
1456
|
+
resources: {
|
|
1457
|
+
string: [],
|
|
1458
|
+
"string-array": [],
|
|
1459
|
+
plurals: [],
|
|
1460
|
+
bool: [],
|
|
1461
|
+
integer: []
|
|
1462
|
+
}
|
|
1463
|
+
};
|
|
1464
|
+
const processHtmlContent = (str) => {
|
|
1465
|
+
if (typeof str !== "string") return { _: String(str) };
|
|
1466
|
+
const containsHtml = /<[a-z][\s\S]*>/i.test(str);
|
|
1467
|
+
const containsSpecialChars = /[<>&]/.test(str);
|
|
1468
|
+
return { _: str };
|
|
1469
|
+
};
|
|
1470
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
1471
|
+
if (typeof value === "string") {
|
|
1472
|
+
xmlObj.resources.string.push({
|
|
1473
|
+
$: { name: key },
|
|
1474
|
+
...processHtmlContent(value)
|
|
1475
|
+
});
|
|
1476
|
+
} else if (Array.isArray(value)) {
|
|
1477
|
+
xmlObj.resources["string-array"].push({
|
|
1478
|
+
$: { name: key },
|
|
1479
|
+
item: value.map((item) => processHtmlContent(item))
|
|
1480
|
+
});
|
|
1481
|
+
} else if (typeof value === "object") {
|
|
1482
|
+
xmlObj.resources.plurals.push({
|
|
1483
|
+
$: { name: key },
|
|
1484
|
+
item: Object.entries(value).map(([quantity, text]) => ({
|
|
1485
|
+
$: { quantity },
|
|
1486
|
+
...processHtmlContent(text)
|
|
1487
|
+
}))
|
|
1488
|
+
});
|
|
1489
|
+
} else if (typeof value === "boolean") {
|
|
1490
|
+
xmlObj.resources.bool.push({
|
|
1491
|
+
$: { name: key },
|
|
1492
|
+
_: value.toString()
|
|
1493
|
+
});
|
|
1494
|
+
} else if (typeof value === "number") {
|
|
1495
|
+
xmlObj.resources.integer.push({
|
|
1496
|
+
$: { name: key },
|
|
1497
|
+
_: value.toString()
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1424
1500
|
}
|
|
1501
|
+
const builder = new (0, _xml2js.Builder)({
|
|
1502
|
+
headless: true,
|
|
1503
|
+
renderOpts: {
|
|
1504
|
+
pretty: true,
|
|
1505
|
+
indent: " ",
|
|
1506
|
+
newline: "\n"
|
|
1507
|
+
}
|
|
1508
|
+
});
|
|
1509
|
+
return builder.buildObject(xmlObj);
|
|
1510
|
+
} catch (error) {
|
|
1511
|
+
console.error("Error generating Android resource file:", error);
|
|
1512
|
+
throw new CLIError({
|
|
1513
|
+
message: "Failed to generate Android resource file",
|
|
1514
|
+
docUrl: "androidResouceError"
|
|
1515
|
+
});
|
|
1425
1516
|
}
|
|
1426
|
-
const result = builder.buildObject(xmlObj);
|
|
1427
|
-
return result;
|
|
1428
1517
|
}
|
|
1429
1518
|
});
|
|
1430
1519
|
}
|
|
@@ -3732,7 +3821,6 @@ async function trackEvent(distinctId, event, properties) {
|
|
|
3732
3821
|
}
|
|
3733
3822
|
try {
|
|
3734
3823
|
const { PostHog } = await Promise.resolve().then(() => _interopRequireWildcard(require("posthog-node")));
|
|
3735
|
-
console.log("--- ---");
|
|
3736
3824
|
const safeProperties = properties ? JSON.parse(
|
|
3737
3825
|
JSON.stringify(properties, (key, value) => {
|
|
3738
3826
|
if (value instanceof Error) {
|
|
@@ -3753,7 +3841,6 @@ async function trackEvent(distinctId, event, properties) {
|
|
|
3753
3841
|
flushInterval: 0
|
|
3754
3842
|
}
|
|
3755
3843
|
);
|
|
3756
|
-
console.log("--- ---");
|
|
3757
3844
|
await posthog.capture({
|
|
3758
3845
|
distinctId,
|
|
3759
3846
|
event,
|
|
@@ -3765,9 +3852,7 @@ async function trackEvent(distinctId, event, properties) {
|
|
|
3765
3852
|
}
|
|
3766
3853
|
}
|
|
3767
3854
|
});
|
|
3768
|
-
console.log("--- ---");
|
|
3769
3855
|
await posthog.shutdown();
|
|
3770
|
-
console.log("--- ---");
|
|
3771
3856
|
} catch (error) {
|
|
3772
3857
|
if (process.env.DEBUG) {
|
|
3773
3858
|
console.error(error);
|
|
@@ -4881,6 +4966,22 @@ var InBranchFlow = class extends IntegrationFlow {
|
|
|
4881
4966
|
}
|
|
4882
4967
|
return true;
|
|
4883
4968
|
}
|
|
4969
|
+
async returnToOriginalBranch() {
|
|
4970
|
+
const originalBranch = this.platformKit.platformConfig.baseBranchName;
|
|
4971
|
+
if (originalBranch) {
|
|
4972
|
+
this.ora.start(`Returning to original branch: ${originalBranch}`);
|
|
4973
|
+
try {
|
|
4974
|
+
_child_process.execSync.call(void 0, `git checkout ${originalBranch}`, {
|
|
4975
|
+
stdio: "inherit",
|
|
4976
|
+
encoding: "utf8"
|
|
4977
|
+
});
|
|
4978
|
+
this.ora.succeed(`Returned to original branch: ${originalBranch}`);
|
|
4979
|
+
} catch (error) {
|
|
4980
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
4981
|
+
this.ora.fail(`Failed to return to original branch: ${errorMessage}`);
|
|
4982
|
+
}
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4884
4985
|
};
|
|
4885
4986
|
|
|
4886
4987
|
// src/cli/cmd/ci/flows/pull-request.ts
|
|
@@ -5465,15 +5566,19 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
|
|
|
5465
5566
|
const { isPullRequestMode } = platformKit.config;
|
|
5466
5567
|
ora.info(`Pull request mode: ${isPullRequestMode ? "on" : "off"}`);
|
|
5467
5568
|
const flow = isPullRequestMode ? new PullRequestFlow(ora, platformKit) : new InBranchFlow(ora, platformKit);
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5569
|
+
try {
|
|
5570
|
+
const canRun = await _optionalChain([flow, 'access', _181 => _181.preRun, 'optionalCall', _182 => _182()]);
|
|
5571
|
+
if (canRun === false) {
|
|
5572
|
+
return;
|
|
5573
|
+
}
|
|
5574
|
+
const hasChanges = await flow.run();
|
|
5575
|
+
if (!hasChanges) {
|
|
5576
|
+
return;
|
|
5577
|
+
}
|
|
5578
|
+
await _optionalChain([flow, 'access', _183 => _183.postRun, 'optionalCall', _184 => _184()]);
|
|
5579
|
+
} finally {
|
|
5580
|
+
await _optionalChain([flow, 'access', _185 => _185.returnToOriginalBranch, 'optionalCall', _186 => _186()]);
|
|
5475
5581
|
}
|
|
5476
|
-
await _optionalChain([flow, 'access', _183 => _183.postRun, 'optionalCall', _184 => _184()]);
|
|
5477
5582
|
});
|
|
5478
5583
|
|
|
5479
5584
|
// src/cli/cmd/status.ts
|
|
@@ -5517,13 +5622,13 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
|
|
|
5517
5622
|
flags
|
|
5518
5623
|
});
|
|
5519
5624
|
let buckets = getBuckets(i18nConfig);
|
|
5520
|
-
if (_optionalChain([flags, 'access',
|
|
5625
|
+
if (_optionalChain([flags, 'access', _187 => _187.bucket, 'optionalAccess', _188 => _188.length])) {
|
|
5521
5626
|
buckets = buckets.filter((bucket) => flags.bucket.includes(bucket.type));
|
|
5522
5627
|
}
|
|
5523
5628
|
ora.succeed("Buckets retrieved");
|
|
5524
|
-
if (_optionalChain([flags, 'access',
|
|
5629
|
+
if (_optionalChain([flags, 'access', _189 => _189.file, 'optionalAccess', _190 => _190.length])) {
|
|
5525
5630
|
buckets = buckets.map((bucket) => {
|
|
5526
|
-
const paths = bucket.paths.filter((path17) => flags.file.find((file) => _optionalChain([path17, 'access',
|
|
5631
|
+
const paths = bucket.paths.filter((path17) => flags.file.find((file) => _optionalChain([path17, 'access', _191 => _191.pathPattern, 'optionalAccess', _192 => _192.match, 'call', _193 => _193(file)])));
|
|
5527
5632
|
return { ...bucket, paths };
|
|
5528
5633
|
}).filter((bucket) => bucket.paths.length > 0);
|
|
5529
5634
|
if (buckets.length === 0) {
|
|
@@ -5539,7 +5644,7 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
|
|
|
5539
5644
|
});
|
|
5540
5645
|
}
|
|
5541
5646
|
}
|
|
5542
|
-
const targetLocales = _optionalChain([flags, 'access',
|
|
5647
|
+
const targetLocales = _optionalChain([flags, 'access', _194 => _194.locale, 'optionalAccess', _195 => _195.length]) ? flags.locale : i18nConfig.locale.targets;
|
|
5543
5648
|
let totalSourceKeyCount = 0;
|
|
5544
5649
|
let uniqueKeysToTranslate = 0;
|
|
5545
5650
|
let totalExistingTranslations = 0;
|
|
@@ -5880,12 +5985,12 @@ function validateParams2(i18nConfig, flags) {
|
|
|
5880
5985
|
message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
|
|
5881
5986
|
docUrl: "bucketNotFound"
|
|
5882
5987
|
});
|
|
5883
|
-
} else if (_optionalChain([flags, 'access',
|
|
5988
|
+
} else if (_optionalChain([flags, 'access', _196 => _196.locale, 'optionalAccess', _197 => _197.some, 'call', _198 => _198((locale) => !i18nConfig.locale.targets.includes(locale))])) {
|
|
5884
5989
|
throw new CLIError({
|
|
5885
5990
|
message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
|
|
5886
5991
|
docUrl: "localeTargetNotFound"
|
|
5887
5992
|
});
|
|
5888
|
-
} else if (_optionalChain([flags, 'access',
|
|
5993
|
+
} else if (_optionalChain([flags, 'access', _199 => _199.bucket, 'optionalAccess', _200 => _200.some, 'call', _201 => _201((bucket) => !i18nConfig.buckets[bucket])])) {
|
|
5889
5994
|
throw new CLIError({
|
|
5890
5995
|
message: `One or more specified buckets do not exist in i18n.json. Please add them to the list and try again.`,
|
|
5891
5996
|
docUrl: "bucketNotFound"
|
|
@@ -5896,7 +6001,7 @@ function validateParams2(i18nConfig, flags) {
|
|
|
5896
6001
|
// package.json
|
|
5897
6002
|
var package_default = {
|
|
5898
6003
|
name: "lingo.dev",
|
|
5899
|
-
version: "0.
|
|
6004
|
+
version: "0.90.1",
|
|
5900
6005
|
description: "Lingo.dev CLI",
|
|
5901
6006
|
private: false,
|
|
5902
6007
|
publishConfig: {
|
|
@@ -5955,7 +6060,7 @@ var package_default = {
|
|
|
5955
6060
|
dependencies: {
|
|
5956
6061
|
"@ai-sdk/anthropic": "^1.2.6",
|
|
5957
6062
|
"@ai-sdk/openai": "^1.3.7",
|
|
5958
|
-
"@datocms/cma-client-node": "^
|
|
6063
|
+
"@datocms/cma-client-node": "^4.0.1",
|
|
5959
6064
|
"@gitbeaker/rest": "^39.34.3",
|
|
5960
6065
|
"@inquirer/prompts": "^7.4.1",
|
|
5961
6066
|
"@lingo.dev/_sdk": "workspace:*",
|