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/build/cli.mjs 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 parsed = !input2 ? { resources: {} } : await parseStringPromise(input2, { explicitArray: true });
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(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&").replace(/&quot;/g, '"').replace(/&apos;/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 parseStringPromise(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
- const processResource = (resourceType) => {
1352
- const resources = parsed.resources[resourceType];
1353
- if (!resources) return;
1354
- resources.forEach((item) => {
1355
- if (item.$ && item.$.translatable === "false") return;
1356
- if (resourceType === "string") {
1357
- result[item.$.name] = item._ || "";
1358
- } else if (resourceType === "string-array") {
1359
- result[item.$.name] = (item.item || []).map((subItem) => {
1360
- if (typeof subItem === "string") return subItem;
1361
- return subItem._ || "";
1362
- }).filter(Boolean);
1363
- } else if (resourceType === "plurals") {
1364
- const pluralObj = {};
1365
- if (Array.isArray(item.item)) {
1366
- item.item.forEach((subItem) => {
1367
- if (subItem.$ && subItem.$.quantity) {
1368
- pluralObj[subItem.$.quantity] = subItem._ || "";
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
- result[item.$.name] = pluralObj;
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
- ["string", "string-array", "plurals", "bool", "integer"].forEach(processResource);
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
- const builder = new Builder({ headless: true });
1392
- const xmlObj = { resources: {} };
1393
- const escapeSingleQuotes = (str) => {
1394
- return str.replace(/(?<!\\)'/g, "\\'");
1395
- };
1396
- for (const [key, value] of Object.entries(payload)) {
1397
- if (typeof value === "string") {
1398
- if (!xmlObj.resources.string) xmlObj.resources.string = [];
1399
- xmlObj.resources.string.push({ $: { name: key }, _: escapeSingleQuotes(value) });
1400
- } else if (Array.isArray(value)) {
1401
- if (!xmlObj.resources["string-array"]) xmlObj.resources["string-array"] = [];
1402
- xmlObj.resources["string-array"].push({
1403
- $: { name: key },
1404
- item: value.map((item) => ({ _: escapeSingleQuotes(item) }))
1405
- });
1406
- } else if (typeof value === "object") {
1407
- if (!xmlObj.resources.plurals) xmlObj.resources.plurals = [];
1408
- xmlObj.resources.plurals.push({
1409
- $: { name: key },
1410
- item: Object.entries(value).map(([quantity, text]) => ({
1411
- $: { quantity },
1412
- _: escapeSingleQuotes(text)
1413
- }))
1414
- });
1415
- } else if (typeof value === "boolean") {
1416
- if (!xmlObj.resources.bool) xmlObj.resources.bool = [];
1417
- xmlObj.resources.bool.push({ $: { name: key }, _: value.toString() });
1418
- } else if (typeof value === "number") {
1419
- if (!xmlObj.resources.integer) xmlObj.resources.integer = [];
1420
- xmlObj.resources.integer.push({
1421
- $: { name: key },
1422
- _: value.toString()
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 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 import("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
+ execSync(`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 Command10().command("ci").description("Run Lingo.dev CI/CD
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
- const canRun = await flow.preRun?.();
5469
- if (canRun === false) {
5470
- return;
5471
- }
5472
- const hasChanges = await flow.run();
5473
- if (!hasChanges) {
5474
- return;
5569
+ try {
5570
+ const canRun = await flow.preRun?.();
5571
+ if (canRun === false) {
5572
+ return;
5573
+ }
5574
+ const hasChanges = await flow.run();
5575
+ if (!hasChanges) {
5576
+ return;
5577
+ }
5578
+ await flow.postRun?.();
5579
+ } finally {
5580
+ await flow.returnToOriginalBranch?.();
5475
5581
  }
5476
- await flow.postRun?.();
5477
5582
  });
5478
5583
 
5479
5584
  // src/cli/cmd/status.ts
@@ -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.89.6",
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": "^3.4.0",
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:*",