lingo.dev 0.107.6 → 0.109.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/build/cli.cjs CHANGED
@@ -368,7 +368,8 @@ var colors = {
368
368
  blue: "#0090ff",
369
369
  yellow: "#ffcc00",
370
370
  grey: "#808080",
371
- red: "#ff0000"
371
+ red: "#ff0000",
372
+ white: "#ffffff"
372
373
  };
373
374
 
374
375
  // src/cli/utils/ui.ts
@@ -396,24 +397,24 @@ async function renderHero() {
396
397
  )} - open-source, AI-powered i18n CLI for web & mobile localization.`
397
398
  );
398
399
  console.log("");
399
- const label1 = "\u2B50 GitHub Repo:";
400
- const label2 = "\u{1F4DA} Docs:";
401
- const label3 = "\u{1F4AC} 24/7 Support:";
400
+ const label1 = "\u{1F4DA} Docs:";
401
+ const label2 = "\u2B50 Star the repo:";
402
+ const label3 = "\u{1F3AE} Join Discord:";
402
403
  const maxLabelWidth = 17;
403
404
  console.log(
404
- `${_chalk2.default.hex(colors.blue)(label1.padEnd(maxLabelWidth))} ${_chalk2.default.hex(
405
+ `${_chalk2.default.hex(colors.blue)(label1.padEnd(maxLabelWidth + 1))} ${_chalk2.default.hex(
405
406
  colors.blue
406
- )("https://lingo.dev/go/gh")}`
407
+ )("https://lingo.dev/go/docs")}`
407
408
  );
408
409
  console.log(
409
- `${_chalk2.default.hex(colors.blue)(label2.padEnd(maxLabelWidth + 1))} ${_chalk2.default.hex(
410
+ `${_chalk2.default.hex(colors.blue)(label2.padEnd(maxLabelWidth))} ${_chalk2.default.hex(
410
411
  colors.blue
411
- )("https://lingo.dev/go/docs")}`
412
+ )("https://lingo.dev/go/gh")}`
412
413
  );
413
414
  console.log(
414
415
  `${_chalk2.default.hex(colors.blue)(label3.padEnd(maxLabelWidth + 1))} ${_chalk2.default.hex(
415
416
  colors.blue
416
- )("hi@lingo.dev")}`
417
+ )("https://lingo.dev/go/discord")}`
417
418
  );
418
419
  }
419
420
  async function waitForUserPrompt(message) {
@@ -448,6 +449,17 @@ async function renderSummary(results) {
448
449
  (r) => r.status === "error"
449
450
  ).length;
450
451
  console.log(`\u2022 ${_chalk2.default.hex(colors.yellow)(failedTasksCount)} failed`);
452
+ if (failedTasksCount > 0) {
453
+ console.log(_chalk2.default.hex(colors.orange)("\n[Failed]"));
454
+ for (const result of Array.from(results.values()).filter(
455
+ (r) => r.status === "error"
456
+ )) {
457
+ console.log(
458
+ `\u274C ${_chalk2.default.hex(colors.white)(String(result.error.message))}
459
+ `
460
+ );
461
+ }
462
+ }
451
463
  }
452
464
 
453
465
  // src/cli/cmd/login.ts
@@ -1513,6 +1525,16 @@ function composeLoaders(...loaders) {
1513
1525
  result = await loaders[i].push(locale, result);
1514
1526
  }
1515
1527
  return result;
1528
+ },
1529
+ pullHints: async (originalInput) => {
1530
+ let result = originalInput;
1531
+ for (let i = 0; i < loaders.length; i++) {
1532
+ const subResult = await _optionalChain([loaders, 'access', _79 => _79[i], 'access', _80 => _80.pullHints, 'optionalCall', _81 => _81(result)]);
1533
+ if (subResult) {
1534
+ result = subResult;
1535
+ }
1536
+ }
1537
+ return result;
1516
1538
  }
1517
1539
  };
1518
1540
  }
@@ -1529,7 +1551,7 @@ function createLoader(lDefinition) {
1529
1551
  if (state.initCtx) {
1530
1552
  return state.initCtx;
1531
1553
  }
1532
- state.initCtx = await _optionalChain([lDefinition, 'access', _79 => _79.init, 'optionalCall', _80 => _80()]);
1554
+ state.initCtx = await _optionalChain([lDefinition, 'access', _82 => _82.init, 'optionalCall', _83 => _83()]);
1533
1555
  return state.initCtx;
1534
1556
  },
1535
1557
  setDefaultLocale(locale) {
@@ -1539,6 +1561,9 @@ function createLoader(lDefinition) {
1539
1561
  state.defaultLocale = locale;
1540
1562
  return this;
1541
1563
  },
1564
+ async pullHints() {
1565
+ return _optionalChain([lDefinition, 'access', _84 => _84.pullHints, 'optionalCall', _85 => _85(state.originalInput)]);
1566
+ },
1542
1567
  async pull(locale, input2) {
1543
1568
  if (!state.defaultLocale) {
1544
1569
  throw new Error("Default locale not set");
@@ -1601,12 +1626,220 @@ function createJsonLoader() {
1601
1626
  });
1602
1627
  }
1603
1628
 
1629
+ // src/cli/loaders/json5.ts
1630
+ var _json5 = require('json5'); var _json52 = _interopRequireDefault(_json5);
1631
+ function createJson5Loader() {
1632
+ return createLoader({
1633
+ pull: async (locale, input2) => {
1634
+ const json5String = input2 || "{}";
1635
+ return _json52.default.parse(json5String);
1636
+ },
1637
+ push: async (locale, data) => {
1638
+ const serializedData = _json52.default.stringify(data, null, 2);
1639
+ return serializedData;
1640
+ }
1641
+ });
1642
+ }
1643
+
1644
+ // src/cli/loaders/jsonc.ts
1645
+ var _jsoncparser = require('jsonc-parser');
1646
+ function extractCommentsFromJsonc(jsoncString) {
1647
+ const lines = jsoncString.split("\n");
1648
+ const comments = {};
1649
+ const errors = [];
1650
+ const result = _jsoncparser.parse.call(void 0, jsoncString, errors, {
1651
+ allowTrailingComma: true,
1652
+ disallowComments: false,
1653
+ allowEmptyContent: true
1654
+ });
1655
+ if (errors.length > 0) {
1656
+ return {};
1657
+ }
1658
+ const contextStack = [];
1659
+ for (let i = 0; i < lines.length; i++) {
1660
+ const line = lines[i];
1661
+ const trimmedLine = line.trim();
1662
+ if (!trimmedLine) continue;
1663
+ const commentData = extractCommentFromLine(line, lines, i);
1664
+ if (commentData.hint) {
1665
+ let keyInfo;
1666
+ if (commentData.isInline) {
1667
+ const keyMatch = line.match(/^\s*["']?([^"':,\s]+)["']?\s*:/);
1668
+ if (keyMatch) {
1669
+ const key = keyMatch[1];
1670
+ const path17 = contextStack.map((ctx) => ctx.key).filter(Boolean);
1671
+ keyInfo = { key, path: path17 };
1672
+ }
1673
+ } else {
1674
+ keyInfo = findAssociatedKey(lines, commentData.lineIndex, contextStack);
1675
+ }
1676
+ if (keyInfo && keyInfo.key) {
1677
+ setCommentAtPath(comments, keyInfo.path, keyInfo.key, commentData.hint);
1678
+ }
1679
+ i = commentData.endIndex;
1680
+ continue;
1681
+ }
1682
+ updateContext(contextStack, line, result);
1683
+ }
1684
+ return comments;
1685
+ }
1686
+ function extractCommentFromLine(line, lines, lineIndex) {
1687
+ const trimmed = line.trim();
1688
+ if (trimmed.startsWith("//")) {
1689
+ const hint = trimmed.replace(/^\/\/\s*/, "").trim();
1690
+ return { hint, lineIndex, endIndex: lineIndex, isInline: false };
1691
+ }
1692
+ if (trimmed.startsWith("/*")) {
1693
+ const blockResult = extractBlockComment(lines, lineIndex);
1694
+ return { ...blockResult, isInline: false };
1695
+ }
1696
+ const singleInlineMatch = line.match(/^(.+?)\s*\/\/\s*(.+)$/);
1697
+ if (singleInlineMatch && singleInlineMatch[1].includes(":")) {
1698
+ const hint = singleInlineMatch[2].trim();
1699
+ return { hint, lineIndex, endIndex: lineIndex, isInline: true };
1700
+ }
1701
+ const blockInlineMatch = line.match(/^(.+?)\s*\/\*\s*(.*?)\s*\*\/.*$/);
1702
+ if (blockInlineMatch && blockInlineMatch[1].includes(":")) {
1703
+ const hint = blockInlineMatch[2].trim();
1704
+ return { hint, lineIndex, endIndex: lineIndex, isInline: true };
1705
+ }
1706
+ return { hint: null, lineIndex, endIndex: lineIndex, isInline: false };
1707
+ }
1708
+ function extractBlockComment(lines, startIndex) {
1709
+ const startLine = lines[startIndex];
1710
+ const singleMatch = startLine.match(/\/\*\s*(.*?)\s*\*\//);
1711
+ if (singleMatch) {
1712
+ return {
1713
+ hint: singleMatch[1].trim(),
1714
+ lineIndex: startIndex,
1715
+ endIndex: startIndex
1716
+ };
1717
+ }
1718
+ const commentParts = [];
1719
+ let endIndex = startIndex;
1720
+ const firstContent = startLine.replace(/.*?\/\*\s*/, "").trim();
1721
+ if (firstContent && !firstContent.includes("*/")) {
1722
+ commentParts.push(firstContent);
1723
+ }
1724
+ for (let i = startIndex + 1; i < lines.length; i++) {
1725
+ const line = lines[i];
1726
+ endIndex = i;
1727
+ if (line.includes("*/")) {
1728
+ const lastContent = line.replace(/\*\/.*$/, "").replace(/^\s*\*?\s*/, "").trim();
1729
+ if (lastContent) {
1730
+ commentParts.push(lastContent);
1731
+ }
1732
+ break;
1733
+ } else {
1734
+ const content = line.replace(/^\s*\*?\s*/, "").trim();
1735
+ if (content) {
1736
+ commentParts.push(content);
1737
+ }
1738
+ }
1739
+ }
1740
+ return {
1741
+ hint: commentParts.join(" ").trim() || null,
1742
+ lineIndex: startIndex,
1743
+ endIndex
1744
+ };
1745
+ }
1746
+ function findAssociatedKey(lines, commentLineIndex, contextStack) {
1747
+ for (let i = commentLineIndex + 1; i < lines.length; i++) {
1748
+ const line = lines[i].trim();
1749
+ if (!line || line.startsWith("//") || line.startsWith("/*") || line === "{" || line === "}") {
1750
+ continue;
1751
+ }
1752
+ const keyMatch = line.match(/^\s*["']?([^"':,\s]+)["']?\s*:/);
1753
+ if (keyMatch) {
1754
+ const key = keyMatch[1];
1755
+ const path17 = contextStack.map((ctx) => ctx.key).filter(Boolean);
1756
+ return { key, path: path17 };
1757
+ }
1758
+ }
1759
+ return { key: null, path: [] };
1760
+ }
1761
+ function updateContext(contextStack, line, parsedJson) {
1762
+ const openBraces = (line.match(/\{/g) || []).length;
1763
+ const closeBraces = (line.match(/\}/g) || []).length;
1764
+ if (openBraces > closeBraces) {
1765
+ const keyMatch = line.match(/^\s*["']?([^"':,\s]+)["']?\s*:\s*\{/);
1766
+ if (keyMatch) {
1767
+ contextStack.push({ key: keyMatch[1], isArray: false });
1768
+ }
1769
+ } else if (closeBraces > openBraces) {
1770
+ for (let i = 0; i < closeBraces - openBraces; i++) {
1771
+ contextStack.pop();
1772
+ }
1773
+ }
1774
+ }
1775
+ function setCommentAtPath(comments, path17, key, hint) {
1776
+ let current = comments;
1777
+ for (const pathKey of path17) {
1778
+ if (!current[pathKey]) {
1779
+ current[pathKey] = {};
1780
+ }
1781
+ current = current[pathKey];
1782
+ }
1783
+ if (!current[key]) {
1784
+ current[key] = {};
1785
+ }
1786
+ if (typeof current[key] === "object" && current[key] !== null) {
1787
+ current[key].hint = hint;
1788
+ } else {
1789
+ current[key] = { hint };
1790
+ }
1791
+ }
1792
+ function createJsoncLoader() {
1793
+ return createLoader({
1794
+ pull: async (locale, input2) => {
1795
+ const jsoncString = input2 || "{}";
1796
+ const errors = [];
1797
+ const result = _jsoncparser.parse.call(void 0, jsoncString, errors, {
1798
+ allowTrailingComma: true,
1799
+ disallowComments: false,
1800
+ allowEmptyContent: true
1801
+ });
1802
+ if (errors.length > 0) {
1803
+ throw new Error(`Failed to parse JSONC: ${errors[0].error}`);
1804
+ }
1805
+ return result || {};
1806
+ },
1807
+ push: async (locale, data) => {
1808
+ const serializedData = JSON.stringify(data, null, 2);
1809
+ return serializedData;
1810
+ },
1811
+ pullHints: async (input2) => {
1812
+ if (!input2 || typeof input2 !== "string") {
1813
+ return {};
1814
+ }
1815
+ try {
1816
+ return extractCommentsFromJsonc(input2);
1817
+ } catch (error) {
1818
+ console.warn("Failed to extract comments from JSONC:", error);
1819
+ return {};
1820
+ }
1821
+ }
1822
+ });
1823
+ }
1824
+
1604
1825
  // src/cli/loaders/flat.ts
1605
1826
  var _flat = require('flat');
1606
1827
 
1607
1828
  var OBJECT_NUMERIC_KEY_PREFIX = "__lingodotdev__obj__";
1608
1829
  function createFlatLoader() {
1609
- return composeLoaders(createDenormalizeLoader(), createNormalizeLoader());
1830
+ const composedLoader = composeLoaders(
1831
+ createDenormalizeLoader(),
1832
+ createNormalizeLoader()
1833
+ );
1834
+ return {
1835
+ ...composedLoader,
1836
+ pullHints: async (input2) => {
1837
+ if (!input2 || typeof input2 !== "object") {
1838
+ return {};
1839
+ }
1840
+ return flattenHints(input2);
1841
+ }
1842
+ };
1610
1843
  }
1611
1844
  function createDenormalizeLoader() {
1612
1845
  return createLoader({
@@ -1634,7 +1867,7 @@ function createNormalizeLoader() {
1634
1867
  return normalized;
1635
1868
  },
1636
1869
  push: async (locale, data, originalInput) => {
1637
- const keysMap = _nullishCoalesce(_optionalChain([originalInput, 'optionalAccess', _81 => _81.keysMap]), () => ( {}));
1870
+ const keysMap = _nullishCoalesce(_optionalChain([originalInput, 'optionalAccess', _86 => _86.keysMap]), () => ( {}));
1638
1871
  const input2 = mapDenormalizedKeys(data, keysMap);
1639
1872
  const denormalized = _flat.unflatten.call(void 0, input2, {
1640
1873
  delimiter: "/",
@@ -1697,6 +1930,33 @@ function normalizeObjectKeys(obj) {
1697
1930
  return obj;
1698
1931
  }
1699
1932
  }
1933
+ function flattenHints(obj, parentHints = [], parentPath = "") {
1934
+ const result = {};
1935
+ for (const [key, _value] of Object.entries(obj)) {
1936
+ if (_lodash2.default.isObject(_value) && !_lodash2.default.isArray(_value)) {
1937
+ const value = _value;
1938
+ const currentHints = [...parentHints];
1939
+ const currentPath = parentPath ? `${parentPath}/${key}` : key;
1940
+ if (value.hint && typeof value.hint === "string") {
1941
+ currentHints.push(value.hint);
1942
+ }
1943
+ const nestedObj = _lodash2.default.omit(value, "hint");
1944
+ if (Object.keys(nestedObj).length === 0) {
1945
+ if (currentHints.length > 0) {
1946
+ result[currentPath] = currentHints;
1947
+ }
1948
+ } else {
1949
+ const nestedComments = flattenHints(
1950
+ nestedObj,
1951
+ currentHints,
1952
+ currentPath
1953
+ );
1954
+ Object.assign(result, nestedComments);
1955
+ }
1956
+ }
1957
+ }
1958
+ return result;
1959
+ }
1700
1960
 
1701
1961
  // src/cli/loaders/text-file.ts
1702
1962
  var _promises3 = require('fs/promises'); var _promises4 = _interopRequireDefault(_promises3);
@@ -1741,8 +2001,8 @@ async function getTrailingNewLine(pathPattern, locale, originalLocale) {
1741
2001
  if (!templateData) {
1742
2002
  templateData = await readFileForLocale(pathPattern, originalLocale);
1743
2003
  }
1744
- if (_optionalChain([templateData, 'optionalAccess', _82 => _82.match, 'call', _83 => _83(/[\r\n]$/)])) {
1745
- const ending = _optionalChain([templateData, 'optionalAccess', _84 => _84.includes, 'call', _85 => _85("\r\n")]) ? "\r\n" : _optionalChain([templateData, 'optionalAccess', _86 => _86.includes, 'call', _87 => _87("\r")]) ? "\r" : "\n";
2004
+ if (_optionalChain([templateData, 'optionalAccess', _87 => _87.match, 'call', _88 => _88(/[\r\n]$/)])) {
2005
+ const ending = _optionalChain([templateData, 'optionalAccess', _89 => _89.includes, 'call', _90 => _90("\r\n")]) ? "\r\n" : _optionalChain([templateData, 'optionalAccess', _91 => _91.includes, 'call', _92 => _92("\r")]) ? "\r" : "\n";
1746
2006
  return ending;
1747
2007
  }
1748
2008
  return "";
@@ -2013,7 +2273,7 @@ var _sync3 = require('csv-stringify/sync');
2013
2273
 
2014
2274
  function detectKeyColumnName(csvString) {
2015
2275
  const row = _sync.parse.call(void 0, csvString)[0];
2016
- const firstColumn = _optionalChain([row, 'optionalAccess', _88 => _88[0], 'optionalAccess', _89 => _89.trim, 'call', _90 => _90()]);
2276
+ const firstColumn = _optionalChain([row, 'optionalAccess', _93 => _93[0], 'optionalAccess', _94 => _94.trim, 'call', _95 => _95()]);
2017
2277
  return firstColumn || "KEY";
2018
2278
  }
2019
2279
  function createCsvLoader() {
@@ -2115,7 +2375,7 @@ function createHtmlLoader() {
2115
2375
  break;
2116
2376
  }
2117
2377
  const siblings = Array.from(parent.childNodes).filter(
2118
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _91 => _91.textContent, 'optionalAccess', _92 => _92.trim, 'call', _93 => _93()])
2378
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _96 => _96.textContent, 'optionalAccess', _97 => _97.trim, 'call', _98 => _98()])
2119
2379
  );
2120
2380
  const index = siblings.indexOf(current);
2121
2381
  if (index !== -1) {
@@ -2151,15 +2411,15 @@ function createHtmlLoader() {
2151
2411
  }
2152
2412
  });
2153
2413
  Array.from(element.childNodes).filter(
2154
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _94 => _94.textContent, 'optionalAccess', _95 => _95.trim, 'call', _96 => _96()])
2414
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _99 => _99.textContent, 'optionalAccess', _100 => _100.trim, 'call', _101 => _101()])
2155
2415
  ).forEach(processNode);
2156
2416
  }
2157
2417
  };
2158
2418
  Array.from(document.head.childNodes).filter(
2159
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _97 => _97.textContent, 'optionalAccess', _98 => _98.trim, 'call', _99 => _99()])
2419
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _102 => _102.textContent, 'optionalAccess', _103 => _103.trim, 'call', _104 => _104()])
2160
2420
  ).forEach(processNode);
2161
2421
  Array.from(document.body.childNodes).filter(
2162
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _100 => _100.textContent, 'optionalAccess', _101 => _101.trim, 'call', _102 => _102()])
2422
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _105 => _105.textContent, 'optionalAccess', _106 => _106.trim, 'call', _107 => _107()])
2163
2423
  ).forEach(processNode);
2164
2424
  return result;
2165
2425
  },
@@ -2184,7 +2444,7 @@ function createHtmlLoader() {
2184
2444
  for (let i = 0; i < indices.length; i++) {
2185
2445
  const index = parseInt(indices[i]);
2186
2446
  const siblings = Array.from(parent.childNodes).filter(
2187
- (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _103 => _103.textContent, 'optionalAccess', _104 => _104.trim, 'call', _105 => _105()])
2447
+ (n) => n.nodeType === 1 || n.nodeType === 3 && _optionalChain([n, 'access', _108 => _108.textContent, 'optionalAccess', _109 => _109.trim, 'call', _110 => _110()])
2188
2448
  );
2189
2449
  if (index >= siblings.length) {
2190
2450
  if (i === indices.length - 1) {
@@ -2235,7 +2495,7 @@ function createMarkdownLoader() {
2235
2495
  yaml: yamlEngine
2236
2496
  }
2237
2497
  });
2238
- const sections = content.split(SECTION_REGEX).map((section) => _nullishCoalesce(_optionalChain([section, 'optionalAccess', _106 => _106.trim, 'call', _107 => _107()]), () => ( ""))).filter(Boolean);
2498
+ const sections = content.split(SECTION_REGEX).map((section) => _nullishCoalesce(_optionalChain([section, 'optionalAccess', _111 => _111.trim, 'call', _112 => _112()]), () => ( ""))).filter(Boolean);
2239
2499
  return {
2240
2500
  ...Object.fromEntries(
2241
2501
  sections.map((section, index) => [`${MD_SECTION_PREFIX}${index}`, section]).filter(([, section]) => Boolean(section))
@@ -2254,7 +2514,7 @@ function createMarkdownLoader() {
2254
2514
  );
2255
2515
  let content = Object.entries(data).filter(([key]) => key.startsWith(MD_SECTION_PREFIX)).sort(
2256
2516
  ([a], [b]) => Number(a.split("-").pop()) - Number(b.split("-").pop())
2257
- ).map(([, value]) => _nullishCoalesce(_optionalChain([value, 'optionalAccess', _108 => _108.trim, 'call', _109 => _109()]), () => ( ""))).filter(Boolean).join("\n\n");
2517
+ ).map(([, value]) => _nullishCoalesce(_optionalChain([value, 'optionalAccess', _113 => _113.trim, 'call', _114 => _114()]), () => ( ""))).filter(Boolean).join("\n\n");
2258
2518
  if (Object.keys(frontmatter).length > 0) {
2259
2519
  content = `
2260
2520
  ${content}`;
@@ -2298,7 +2558,7 @@ function isSkippableLine(line) {
2298
2558
  function parsePropertyLine(line) {
2299
2559
  const [key, ...valueParts] = line.split("=");
2300
2560
  return {
2301
- key: _optionalChain([key, 'optionalAccess', _110 => _110.trim, 'call', _111 => _111()]) || "",
2561
+ key: _optionalChain([key, 'optionalAccess', _115 => _115.trim, 'call', _116 => _116()]) || "",
2302
2562
  value: valueParts.join("=").trim()
2303
2563
  };
2304
2564
  }
@@ -2386,7 +2646,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2386
2646
  if (rootTranslationEntity.shouldTranslate === false) {
2387
2647
  continue;
2388
2648
  }
2389
- const langTranslationEntity = _optionalChain([rootTranslationEntity, 'optionalAccess', _112 => _112.localizations, 'optionalAccess', _113 => _113[locale]]);
2649
+ const langTranslationEntity = _optionalChain([rootTranslationEntity, 'optionalAccess', _117 => _117.localizations, 'optionalAccess', _118 => _118[locale]]);
2390
2650
  if (langTranslationEntity) {
2391
2651
  if ("stringUnit" in langTranslationEntity) {
2392
2652
  resultData[translationKey] = langTranslationEntity.stringUnit.value;
@@ -2395,7 +2655,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2395
2655
  resultData[translationKey] = {};
2396
2656
  const pluralForms = langTranslationEntity.variations.plural;
2397
2657
  for (const form in pluralForms) {
2398
- if (_optionalChain([pluralForms, 'access', _114 => _114[form], 'optionalAccess', _115 => _115.stringUnit, 'optionalAccess', _116 => _116.value])) {
2658
+ if (_optionalChain([pluralForms, 'access', _119 => _119[form], 'optionalAccess', _120 => _120.stringUnit, 'optionalAccess', _121 => _121.value])) {
2399
2659
  resultData[translationKey][form] = pluralForms[form].stringUnit.value;
2400
2660
  }
2401
2661
  }
@@ -2421,7 +2681,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2421
2681
  const hasDoNotTranslateFlag = originalInput && originalInput.strings && originalInput.strings[key] && originalInput.strings[key].shouldTranslate === false;
2422
2682
  if (typeof value === "string") {
2423
2683
  langDataToMerge.strings[key] = {
2424
- extractionState: _optionalChain([originalInput, 'optionalAccess', _117 => _117.strings, 'optionalAccess', _118 => _118[key], 'optionalAccess', _119 => _119.extractionState]),
2684
+ extractionState: _optionalChain([originalInput, 'optionalAccess', _122 => _122.strings, 'optionalAccess', _123 => _123[key], 'optionalAccess', _124 => _124.extractionState]),
2425
2685
  localizations: {
2426
2686
  [locale]: {
2427
2687
  stringUnit: {
@@ -2462,6 +2722,36 @@ function createXcodeXcstringsLoader(defaultLocale) {
2462
2722
  const originalInputWithoutLocale = originalInput ? _removeLocale(originalInput, locale) : {};
2463
2723
  const result = _lodash2.default.merge({}, originalInputWithoutLocale, langDataToMerge);
2464
2724
  return result;
2725
+ },
2726
+ async pullHints(originalInput) {
2727
+ if (!originalInput || !originalInput.strings) {
2728
+ return {};
2729
+ }
2730
+ const hints = {};
2731
+ for (const [translationKey, translationEntity] of Object.entries(
2732
+ originalInput.strings
2733
+ )) {
2734
+ const entity = translationEntity;
2735
+ if (entity.comment && typeof entity.comment === "string") {
2736
+ hints[translationKey] = { hint: entity.comment };
2737
+ }
2738
+ if (entity.localizations) {
2739
+ for (const [locale, localization] of Object.entries(
2740
+ entity.localizations
2741
+ )) {
2742
+ if (_optionalChain([localization, 'access', _125 => _125.variations, 'optionalAccess', _126 => _126.plural])) {
2743
+ const pluralForms = localization.variations.plural;
2744
+ for (const form in pluralForms) {
2745
+ const pluralKey = `${translationKey}/${form}`;
2746
+ if (entity.comment && typeof entity.comment === "string") {
2747
+ hints[pluralKey] = { hint: entity.comment };
2748
+ }
2749
+ }
2750
+ }
2751
+ }
2752
+ }
2753
+ }
2754
+ return hints;
2465
2755
  }
2466
2756
  });
2467
2757
  }
@@ -2469,7 +2759,7 @@ function _removeLocale(input2, locale) {
2469
2759
  const { strings } = input2;
2470
2760
  const newStrings = _lodash2.default.cloneDeep(strings);
2471
2761
  for (const [key, value] of Object.entries(newStrings)) {
2472
- if (_optionalChain([value, 'access', _120 => _120.localizations, 'optionalAccess', _121 => _121[locale]])) {
2762
+ if (_optionalChain([value, 'access', _127 => _127.localizations, 'optionalAccess', _128 => _128[locale]])) {
2473
2763
  delete value.localizations[locale];
2474
2764
  }
2475
2765
  }
@@ -2629,7 +2919,7 @@ function createPoDataLoader(params) {
2629
2919
  Object.entries(entries).forEach(([msgid, entry]) => {
2630
2920
  if (msgid && entry.msgid) {
2631
2921
  const context = entry.msgctxt || "";
2632
- const fullEntry = _optionalChain([parsedPo, 'access', _122 => _122.translations, 'access', _123 => _123[context], 'optionalAccess', _124 => _124[msgid]]);
2922
+ const fullEntry = _optionalChain([parsedPo, 'access', _129 => _129.translations, 'access', _130 => _130[context], 'optionalAccess', _131 => _131[msgid]]);
2633
2923
  if (fullEntry) {
2634
2924
  result[msgid] = fullEntry;
2635
2925
  }
@@ -2639,8 +2929,8 @@ function createPoDataLoader(params) {
2639
2929
  return result;
2640
2930
  },
2641
2931
  async push(locale, data, originalInput, originalLocale, pullInput) {
2642
- const currentSections = _optionalChain([pullInput, 'optionalAccess', _125 => _125.split, 'call', _126 => _126("\n\n"), 'access', _127 => _127.filter, 'call', _128 => _128(Boolean)]) || [];
2643
- const originalSections = _optionalChain([originalInput, 'optionalAccess', _129 => _129.split, 'call', _130 => _130("\n\n"), 'access', _131 => _131.filter, 'call', _132 => _132(Boolean)]) || [];
2932
+ const currentSections = _optionalChain([pullInput, 'optionalAccess', _132 => _132.split, 'call', _133 => _133("\n\n"), 'access', _134 => _134.filter, 'call', _135 => _135(Boolean)]) || [];
2933
+ const originalSections = _optionalChain([originalInput, 'optionalAccess', _136 => _136.split, 'call', _137 => _137("\n\n"), 'access', _138 => _138.filter, 'call', _139 => _139(Boolean)]) || [];
2644
2934
  const result = originalSections.map((section) => {
2645
2935
  const sectionPo = _gettextparser2.default.po.parse(section);
2646
2936
  if (Object.keys(sectionPo.translations).length === 0) {
@@ -2709,8 +2999,8 @@ function createPoContentLoader() {
2709
2999
  {
2710
3000
  ...entry,
2711
3001
  msgstr: [
2712
- _optionalChain([data, 'access', _133 => _133[entry.msgid], 'optionalAccess', _134 => _134.singular]),
2713
- _optionalChain([data, 'access', _135 => _135[entry.msgid], 'optionalAccess', _136 => _136.plural]) || null
3002
+ _optionalChain([data, 'access', _140 => _140[entry.msgid], 'optionalAccess', _141 => _141.singular]),
3003
+ _optionalChain([data, 'access', _142 => _142[entry.msgid], 'optionalAccess', _143 => _143.plural]) || null
2714
3004
  ].filter(Boolean)
2715
3005
  }
2716
3006
  ]).fromPairs().value();
@@ -2832,7 +3122,7 @@ function pullV1(xliffElement, locale, originalLocale) {
2832
3122
  let key = getTransUnitKey(unit);
2833
3123
  if (!key) return;
2834
3124
  if (seenKeys.has(key)) {
2835
- const id = _optionalChain([unit, 'access', _137 => _137.getAttribute, 'call', _138 => _138("id"), 'optionalAccess', _139 => _139.trim, 'call', _140 => _140()]);
3125
+ const id = _optionalChain([unit, 'access', _144 => _144.getAttribute, 'call', _145 => _145("id"), 'optionalAccess', _146 => _146.trim, 'call', _147 => _147()]);
2836
3126
  if (id) {
2837
3127
  key = `${key}#${id}`;
2838
3128
  } else {
@@ -2880,7 +3170,7 @@ function pushV1(dom, xliffElement, locale, translations, originalLocale, origina
2880
3170
  let key = getTransUnitKey(unit);
2881
3171
  if (!key) return;
2882
3172
  if (seenKeys.has(key)) {
2883
- const id = _optionalChain([unit, 'access', _141 => _141.getAttribute, 'call', _142 => _142("id"), 'optionalAccess', _143 => _143.trim, 'call', _144 => _144()]);
3173
+ const id = _optionalChain([unit, 'access', _148 => _148.getAttribute, 'call', _149 => _149("id"), 'optionalAccess', _150 => _150.trim, 'call', _151 => _151()]);
2884
3174
  if (id) {
2885
3175
  key = `${key}#${id}`;
2886
3176
  } else {
@@ -2922,7 +3212,7 @@ function pushV1(dom, xliffElement, locale, translations, originalLocale, origina
2922
3212
  const translationKeys = new Set(Object.keys(translations));
2923
3213
  existingUnits.forEach((unit, key) => {
2924
3214
  if (!translationKeys.has(key)) {
2925
- _optionalChain([unit, 'access', _145 => _145.parentNode, 'optionalAccess', _146 => _146.removeChild, 'call', _147 => _147(unit)]);
3215
+ _optionalChain([unit, 'access', _152 => _152.parentNode, 'optionalAccess', _153 => _153.removeChild, 'call', _154 => _154(unit)]);
2926
3216
  }
2927
3217
  });
2928
3218
  return serializeWithDeclaration(
@@ -2965,18 +3255,18 @@ function traverseUnitsV2(container, fileId, currentPath, result) {
2965
3255
  Array.from(container.children).forEach((child) => {
2966
3256
  const tagName = child.tagName;
2967
3257
  if (tagName === "unit") {
2968
- const unitId = _optionalChain([child, 'access', _148 => _148.getAttribute, 'call', _149 => _149("id"), 'optionalAccess', _150 => _150.trim, 'call', _151 => _151()]);
3258
+ const unitId = _optionalChain([child, 'access', _155 => _155.getAttribute, 'call', _156 => _156("id"), 'optionalAccess', _157 => _157.trim, 'call', _158 => _158()]);
2969
3259
  if (!unitId) return;
2970
3260
  const key = `resources/${fileId}/${currentPath}${unitId}/source`;
2971
3261
  const segment = child.querySelector("segment");
2972
- const source = _optionalChain([segment, 'optionalAccess', _152 => _152.querySelector, 'call', _153 => _153("source")]);
3262
+ const source = _optionalChain([segment, 'optionalAccess', _159 => _159.querySelector, 'call', _160 => _160("source")]);
2973
3263
  if (source) {
2974
3264
  result[key] = extractTextContent(source);
2975
3265
  } else {
2976
3266
  result[key] = unitId;
2977
3267
  }
2978
3268
  } else if (tagName === "group") {
2979
- const groupId = _optionalChain([child, 'access', _154 => _154.getAttribute, 'call', _155 => _155("id"), 'optionalAccess', _156 => _156.trim, 'call', _157 => _157()]);
3269
+ const groupId = _optionalChain([child, 'access', _161 => _161.getAttribute, 'call', _162 => _162("id"), 'optionalAccess', _163 => _163.trim, 'call', _164 => _164()]);
2980
3270
  const newPath = groupId ? `${currentPath}${groupId}/groupUnits/` : currentPath;
2981
3271
  traverseUnitsV2(child, fileId, newPath, result);
2982
3272
  }
@@ -3012,12 +3302,12 @@ function indexUnitsV2(container, fileId, currentPath, index) {
3012
3302
  Array.from(container.children).forEach((child) => {
3013
3303
  const tagName = child.tagName;
3014
3304
  if (tagName === "unit") {
3015
- const unitId = _optionalChain([child, 'access', _158 => _158.getAttribute, 'call', _159 => _159("id"), 'optionalAccess', _160 => _160.trim, 'call', _161 => _161()]);
3305
+ const unitId = _optionalChain([child, 'access', _165 => _165.getAttribute, 'call', _166 => _166("id"), 'optionalAccess', _167 => _167.trim, 'call', _168 => _168()]);
3016
3306
  if (!unitId) return;
3017
3307
  const key = `resources/${fileId}/${currentPath}${unitId}/source`;
3018
3308
  index.set(key, child);
3019
3309
  } else if (tagName === "group") {
3020
- const groupId = _optionalChain([child, 'access', _162 => _162.getAttribute, 'call', _163 => _163("id"), 'optionalAccess', _164 => _164.trim, 'call', _165 => _165()]);
3310
+ const groupId = _optionalChain([child, 'access', _169 => _169.getAttribute, 'call', _170 => _170("id"), 'optionalAccess', _171 => _171.trim, 'call', _172 => _172()]);
3021
3311
  const newPath = groupId ? `${currentPath}${groupId}/groupUnits/` : currentPath;
3022
3312
  indexUnitsV2(child, fileId, newPath, index);
3023
3313
  }
@@ -3038,9 +3328,9 @@ function updateUnitV2(unit, value) {
3038
3328
  setTextContent(source, value);
3039
3329
  }
3040
3330
  function getTransUnitKey(transUnit) {
3041
- const resname = _optionalChain([transUnit, 'access', _166 => _166.getAttribute, 'call', _167 => _167("resname"), 'optionalAccess', _168 => _168.trim, 'call', _169 => _169()]);
3331
+ const resname = _optionalChain([transUnit, 'access', _173 => _173.getAttribute, 'call', _174 => _174("resname"), 'optionalAccess', _175 => _175.trim, 'call', _176 => _176()]);
3042
3332
  if (resname) return resname;
3043
- const id = _optionalChain([transUnit, 'access', _170 => _170.getAttribute, 'call', _171 => _171("id"), 'optionalAccess', _172 => _172.trim, 'call', _173 => _173()]);
3333
+ const id = _optionalChain([transUnit, 'access', _177 => _177.getAttribute, 'call', _178 => _178("id"), 'optionalAccess', _179 => _179.trim, 'call', _180 => _180()]);
3044
3334
  if (id) return id;
3045
3335
  const sourceElement = transUnit.querySelector("source");
3046
3336
  if (sourceElement) {
@@ -3097,7 +3387,7 @@ function formatXml(xml) {
3097
3387
  if (cdataNode) {
3098
3388
  return `${indent2}${openTag}<![CDATA[${cdataNode.nodeValue}]]></${tagName}>`;
3099
3389
  }
3100
- const textContent = _optionalChain([element, 'access', _174 => _174.textContent, 'optionalAccess', _175 => _175.trim, 'call', _176 => _176()]) || "";
3390
+ const textContent = _optionalChain([element, 'access', _181 => _181.textContent, 'optionalAccess', _182 => _182.trim, 'call', _183 => _183()]) || "";
3101
3391
  const hasOnlyText = element.childNodes.length === 1 && element.childNodes[0].nodeType === 3;
3102
3392
  if (hasOnlyText && textContent) {
3103
3393
  return `${indent2}${openTag}${textContent}</${tagName}>`;
@@ -3226,7 +3516,7 @@ function createSrtLoader() {
3226
3516
 
3227
3517
  // src/cli/loaders/dato/index.ts
3228
3518
 
3229
- var _json5 = require('json5'); var _json52 = _interopRequireDefault(_json5);
3519
+
3230
3520
 
3231
3521
  // src/cli/loaders/dato/_base.ts
3232
3522
 
@@ -3390,7 +3680,7 @@ function createDatoClient(params) {
3390
3680
  ids: !records.length ? void 0 : records.join(",")
3391
3681
  }
3392
3682
  }).catch(
3393
- (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _177 => _177.response, 'optionalAccess', _178 => _178.body, 'optionalAccess', _179 => _179.data, 'optionalAccess', _180 => _180[0]]) || error)
3683
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _184 => _184.response, 'optionalAccess', _185 => _185.body, 'optionalAccess', _186 => _186.data, 'optionalAccess', _187 => _187[0]]) || error)
3394
3684
  );
3395
3685
  },
3396
3686
  findRecordsForModel: async (modelId, records) => {
@@ -3401,10 +3691,10 @@ function createDatoClient(params) {
3401
3691
  filter: {
3402
3692
  type: modelId,
3403
3693
  only_valid: "true",
3404
- ids: !_optionalChain([records, 'optionalAccess', _181 => _181.length]) ? void 0 : records.join(",")
3694
+ ids: !_optionalChain([records, 'optionalAccess', _188 => _188.length]) ? void 0 : records.join(",")
3405
3695
  }
3406
3696
  }).catch(
3407
- (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _182 => _182.response, 'optionalAccess', _183 => _183.body, 'optionalAccess', _184 => _184.data, 'optionalAccess', _185 => _185[0]]) || error)
3697
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _189 => _189.response, 'optionalAccess', _190 => _190.body, 'optionalAccess', _191 => _191.data, 'optionalAccess', _192 => _192[0]]) || error)
3408
3698
  );
3409
3699
  return result;
3410
3700
  } catch (_error) {
@@ -3420,10 +3710,10 @@ function createDatoClient(params) {
3420
3710
  updateRecord: async (id, payload) => {
3421
3711
  try {
3422
3712
  await dato.items.update(id, payload).catch(
3423
- (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _186 => _186.response, 'optionalAccess', _187 => _187.body, 'optionalAccess', _188 => _188.data, 'optionalAccess', _189 => _189[0]]) || error)
3713
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _193 => _193.response, 'optionalAccess', _194 => _194.body, 'optionalAccess', _195 => _195.data, 'optionalAccess', _196 => _196[0]]) || error)
3424
3714
  );
3425
3715
  } catch (_error) {
3426
- if (_optionalChain([_error, 'optionalAccess', _190 => _190.attributes, 'optionalAccess', _191 => _191.details, 'optionalAccess', _192 => _192.message])) {
3716
+ if (_optionalChain([_error, 'optionalAccess', _197 => _197.attributes, 'optionalAccess', _198 => _198.details, 'optionalAccess', _199 => _199.message])) {
3427
3717
  throw new Error(
3428
3718
  [
3429
3719
  `${_error.attributes.details.message}`,
@@ -3445,10 +3735,10 @@ function createDatoClient(params) {
3445
3735
  enableFieldLocalization: async (args) => {
3446
3736
  try {
3447
3737
  await dato.fields.update(`${args.modelId}::${args.fieldId}`, { localized: true }).catch(
3448
- (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _193 => _193.response, 'optionalAccess', _194 => _194.body, 'optionalAccess', _195 => _195.data, 'optionalAccess', _196 => _196[0]]) || error)
3738
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _200 => _200.response, 'optionalAccess', _201 => _201.body, 'optionalAccess', _202 => _202.data, 'optionalAccess', _203 => _203[0]]) || error)
3449
3739
  );
3450
3740
  } catch (_error) {
3451
- if (_optionalChain([_error, 'optionalAccess', _197 => _197.attributes, 'optionalAccess', _198 => _198.code]) === "NOT_FOUND") {
3741
+ if (_optionalChain([_error, 'optionalAccess', _204 => _204.attributes, 'optionalAccess', _205 => _205.code]) === "NOT_FOUND") {
3452
3742
  throw new Error(
3453
3743
  [
3454
3744
  `Field "${args.fieldId}" not found in model "${args.modelId}".`,
@@ -3456,7 +3746,7 @@ function createDatoClient(params) {
3456
3746
  ].join("\n\n")
3457
3747
  );
3458
3748
  }
3459
- if (_optionalChain([_error, 'optionalAccess', _199 => _199.attributes, 'optionalAccess', _200 => _200.details, 'optionalAccess', _201 => _201.message])) {
3749
+ if (_optionalChain([_error, 'optionalAccess', _206 => _206.attributes, 'optionalAccess', _207 => _207.details, 'optionalAccess', _208 => _208.message])) {
3460
3750
  throw new Error(
3461
3751
  [
3462
3752
  `${_error.attributes.details.message}`,
@@ -3534,7 +3824,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
3534
3824
  const records = await dato.findRecordsForModel(modelId);
3535
3825
  const recordChoices = createRecordChoices(
3536
3826
  records,
3537
- _optionalChain([config, 'access', _202 => _202.models, 'access', _203 => _203[modelId], 'optionalAccess', _204 => _204.records]) || [],
3827
+ _optionalChain([config, 'access', _209 => _209.models, 'access', _210 => _210[modelId], 'optionalAccess', _211 => _211.records]) || [],
3538
3828
  project
3539
3829
  );
3540
3830
  const selectedRecords = await promptRecordSelection(
@@ -3553,14 +3843,14 @@ function createDatoApiLoader(config, onConfigUpdate) {
3553
3843
  },
3554
3844
  async pull(locale, input2, initCtx) {
3555
3845
  const result = {};
3556
- for (const modelId of _lodash2.default.keys(_optionalChain([initCtx, 'optionalAccess', _205 => _205.models]) || {})) {
3557
- let records = _optionalChain([initCtx, 'optionalAccess', _206 => _206.models, 'access', _207 => _207[modelId], 'access', _208 => _208.records]) || [];
3846
+ for (const modelId of _lodash2.default.keys(_optionalChain([initCtx, 'optionalAccess', _212 => _212.models]) || {})) {
3847
+ let records = _optionalChain([initCtx, 'optionalAccess', _213 => _213.models, 'access', _214 => _214[modelId], 'access', _215 => _215.records]) || [];
3558
3848
  const recordIds = records.map((record) => record.id);
3559
3849
  records = await dato.findRecords(recordIds);
3560
3850
  console.log(`Fetched ${records.length} records for model ${modelId}`);
3561
3851
  if (records.length > 0) {
3562
3852
  result[modelId] = {
3563
- fields: _optionalChain([initCtx, 'optionalAccess', _209 => _209.models, 'optionalAccess', _210 => _210[modelId], 'optionalAccess', _211 => _211.fields]) || [],
3853
+ fields: _optionalChain([initCtx, 'optionalAccess', _216 => _216.models, 'optionalAccess', _217 => _217[modelId], 'optionalAccess', _218 => _218.fields]) || [],
3564
3854
  records
3565
3855
  };
3566
3856
  }
@@ -3623,7 +3913,7 @@ function createRecordChoices(records, selectedIds = [], project) {
3623
3913
  return records.map((record) => ({
3624
3914
  name: `${record.id} - https://${project.internal_domain}/editor/item_types/${record.item_type.id}/items/${record.id}`,
3625
3915
  value: record.id,
3626
- checked: _optionalChain([selectedIds, 'optionalAccess', _212 => _212.includes, 'call', _213 => _213(record.id)])
3916
+ checked: _optionalChain([selectedIds, 'optionalAccess', _219 => _219.includes, 'call', _220 => _220(record.id)])
3627
3917
  }));
3628
3918
  }
3629
3919
  async function promptRecordSelection(modelName, choices) {
@@ -3942,7 +4232,7 @@ function createVttLoader() {
3942
4232
  if (!input2) {
3943
4233
  return "";
3944
4234
  }
3945
- const vtt = _optionalChain([_nodewebvtt2.default, 'access', _214 => _214.parse, 'call', _215 => _215(input2), 'optionalAccess', _216 => _216.cues]);
4235
+ const vtt = _optionalChain([_nodewebvtt2.default, 'access', _221 => _221.parse, 'call', _222 => _222(input2), 'optionalAccess', _223 => _223.cues]);
3946
4236
  if (Object.keys(vtt).length === 0) {
3947
4237
  return {};
3948
4238
  } else {
@@ -3996,7 +4286,7 @@ function variableExtractLoader(params) {
3996
4286
  for (let i = 0; i < matches.length; i++) {
3997
4287
  const match2 = matches[i];
3998
4288
  const currentValue = result[key].value;
3999
- const newValue = _optionalChain([currentValue, 'optionalAccess', _217 => _217.replace, 'call', _218 => _218(match2, `{variable:${i}}`)]);
4289
+ const newValue = _optionalChain([currentValue, 'optionalAccess', _224 => _224.replace, 'call', _225 => _225(match2, `{variable:${i}}`)]);
4000
4290
  result[key].value = newValue;
4001
4291
  result[key].variables[i] = match2;
4002
4292
  }
@@ -4010,7 +4300,7 @@ function variableExtractLoader(params) {
4010
4300
  for (let i = 0; i < valueObj.variables.length; i++) {
4011
4301
  const variable = valueObj.variables[i];
4012
4302
  const currentValue = result[key];
4013
- const newValue = _optionalChain([currentValue, 'optionalAccess', _219 => _219.replace, 'call', _220 => _220(`{variable:${i}}`, variable)]);
4303
+ const newValue = _optionalChain([currentValue, 'optionalAccess', _226 => _226.replace, 'call', _227 => _227(`{variable:${i}}`, variable)]);
4014
4304
  result[key] = newValue;
4015
4305
  }
4016
4306
  }
@@ -4210,7 +4500,7 @@ function createVueJsonLoader() {
4210
4500
  return createLoader({
4211
4501
  pull: async (locale, input2, ctx) => {
4212
4502
  const parsed = parseVueFile(input2);
4213
- return _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _221 => _221.i18n, 'optionalAccess', _222 => _222[locale]]), () => ( {}));
4503
+ return _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _228 => _228.i18n, 'optionalAccess', _229 => _229[locale]]), () => ( {}));
4214
4504
  },
4215
4505
  push: async (locale, data, originalInput) => {
4216
4506
  const parsed = parseVueFile(_nullishCoalesce(originalInput, () => ( "")));
@@ -4395,7 +4685,7 @@ function updateStringsInObjectExpression(objectExpression, data) {
4395
4685
  objectExpression.properties.forEach((prop) => {
4396
4686
  if (!t.isObjectProperty(prop)) return;
4397
4687
  const key = getPropertyKey(prop);
4398
- const incomingVal = _optionalChain([data, 'optionalAccess', _223 => _223[key]]);
4688
+ const incomingVal = _optionalChain([data, 'optionalAccess', _230 => _230[key]]);
4399
4689
  if (incomingVal === void 0) {
4400
4690
  return;
4401
4691
  }
@@ -4431,7 +4721,7 @@ function updateStringsInArrayExpression(arrayExpression, incoming) {
4431
4721
  let modified = false;
4432
4722
  arrayExpression.elements.forEach((element, index) => {
4433
4723
  if (!element) return;
4434
- const incomingVal = _optionalChain([incoming, 'optionalAccess', _224 => _224[index]]);
4724
+ const incomingVal = _optionalChain([incoming, 'optionalAccess', _231 => _231[index]]);
4435
4725
  if (incomingVal === void 0) return;
4436
4726
  if (t.isStringLiteral(element) && typeof incomingVal === "string") {
4437
4727
  if (element.value !== incomingVal) {
@@ -4922,7 +5212,7 @@ var AST = class _AST {
4922
5212
  const ret = this.type === null ? this.#parts.slice().map((p) => typeof p === "string" ? p : p.toJSON()) : [this.type, ...this.#parts.map((p) => p.toJSON())];
4923
5213
  if (this.isStart() && !this.type)
4924
5214
  ret.unshift([]);
4925
- if (this.isEnd() && (this === this.#root || this.#root.#filledNegs && _optionalChain([this, 'access', _225 => _225.#parent, 'optionalAccess', _226 => _226.type]) === "!")) {
5215
+ if (this.isEnd() && (this === this.#root || this.#root.#filledNegs && _optionalChain([this, 'access', _232 => _232.#parent, 'optionalAccess', _233 => _233.type]) === "!")) {
4926
5216
  ret.push({});
4927
5217
  }
4928
5218
  return ret;
@@ -4930,7 +5220,7 @@ var AST = class _AST {
4930
5220
  isStart() {
4931
5221
  if (this.#root === this)
4932
5222
  return true;
4933
- if (!_optionalChain([this, 'access', _227 => _227.#parent, 'optionalAccess', _228 => _228.isStart, 'call', _229 => _229()]))
5223
+ if (!_optionalChain([this, 'access', _234 => _234.#parent, 'optionalAccess', _235 => _235.isStart, 'call', _236 => _236()]))
4934
5224
  return false;
4935
5225
  if (this.#parentIndex === 0)
4936
5226
  return true;
@@ -4946,12 +5236,12 @@ var AST = class _AST {
4946
5236
  isEnd() {
4947
5237
  if (this.#root === this)
4948
5238
  return true;
4949
- if (_optionalChain([this, 'access', _230 => _230.#parent, 'optionalAccess', _231 => _231.type]) === "!")
5239
+ if (_optionalChain([this, 'access', _237 => _237.#parent, 'optionalAccess', _238 => _238.type]) === "!")
4950
5240
  return true;
4951
- if (!_optionalChain([this, 'access', _232 => _232.#parent, 'optionalAccess', _233 => _233.isEnd, 'call', _234 => _234()]))
5241
+ if (!_optionalChain([this, 'access', _239 => _239.#parent, 'optionalAccess', _240 => _240.isEnd, 'call', _241 => _241()]))
4952
5242
  return false;
4953
5243
  if (!this.type)
4954
- return _optionalChain([this, 'access', _235 => _235.#parent, 'optionalAccess', _236 => _236.isEnd, 'call', _237 => _237()]);
5244
+ return _optionalChain([this, 'access', _242 => _242.#parent, 'optionalAccess', _243 => _243.isEnd, 'call', _244 => _244()]);
4955
5245
  const pl = this.#parent ? this.#parent.#parts.length : 0;
4956
5246
  return this.#parentIndex === pl - 1;
4957
5247
  }
@@ -5196,7 +5486,7 @@ var AST = class _AST {
5196
5486
  }
5197
5487
  }
5198
5488
  let end = "";
5199
- if (this.isEnd() && this.#root.#filledNegs && _optionalChain([this, 'access', _238 => _238.#parent, 'optionalAccess', _239 => _239.type]) === "!") {
5489
+ if (this.isEnd() && this.#root.#filledNegs && _optionalChain([this, 'access', _245 => _245.#parent, 'optionalAccess', _246 => _246.type]) === "!") {
5200
5490
  end = "(?:$|\\/)";
5201
5491
  }
5202
5492
  const final2 = start2 + src + end;
@@ -6212,9 +6502,11 @@ function extractCodePlaceholders(content) {
6212
6502
  };
6213
6503
  }
6214
6504
  function createMdxCodePlaceholderLoader() {
6505
+ const globalPlaceholderRegistry = {};
6215
6506
  return createLoader({
6216
6507
  async pull(locale, input2) {
6217
6508
  const response = extractCodePlaceholders(input2);
6509
+ Object.assign(globalPlaceholderRegistry, response.codePlaceholders);
6218
6510
  return response.content;
6219
6511
  },
6220
6512
  async push(locale, data, originalInput, originalLocale, pullInput) {
@@ -6222,7 +6514,9 @@ function createMdxCodePlaceholderLoader() {
6222
6514
  const currentInfo = extractCodePlaceholders(_nullishCoalesce(pullInput, () => ( "")));
6223
6515
  const codePlaceholders = _lodash2.default.merge(
6224
6516
  sourceInfo.codePlaceholders,
6225
- currentInfo.codePlaceholders
6517
+ currentInfo.codePlaceholders,
6518
+ globalPlaceholderRegistry
6519
+ // Include ALL placeholders ever created
6226
6520
  );
6227
6521
  let result = data;
6228
6522
  for (const [placeholder, original] of Object.entries(codePlaceholders)) {
@@ -6269,7 +6563,7 @@ function createMdxSectionsSplit2Loader() {
6269
6563
  const content = _lodash2.default.chain(data.sections).values().join("\n\n").value();
6270
6564
  const result = {
6271
6565
  frontmatter: data.frontmatter,
6272
- codePlaceholders: _optionalChain([pullInput, 'optionalAccess', _240 => _240.codePlaceholders]) || {},
6566
+ codePlaceholders: _optionalChain([pullInput, 'optionalAccess', _247 => _247.codePlaceholders]) || {},
6273
6567
  content
6274
6568
  };
6275
6569
  return result;
@@ -6686,6 +6980,28 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
6686
6980
  createSyncLoader(),
6687
6981
  createUnlocalizableLoader(options.returnUnlocalizedKeys)
6688
6982
  );
6983
+ case "json5":
6984
+ return composeLoaders(
6985
+ createTextFileLoader(bucketPathPattern),
6986
+ createJson5Loader(),
6987
+ createEnsureKeyOrderLoader(),
6988
+ createFlatLoader(),
6989
+ createInjectLocaleLoader(options.injectLocale),
6990
+ createLockedKeysLoader(lockedKeys || []),
6991
+ createSyncLoader(),
6992
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
6993
+ );
6994
+ case "jsonc":
6995
+ return composeLoaders(
6996
+ createTextFileLoader(bucketPathPattern),
6997
+ createJsoncLoader(),
6998
+ createEnsureKeyOrderLoader(),
6999
+ createFlatLoader(),
7000
+ createInjectLocaleLoader(options.injectLocale),
7001
+ createLockedKeysLoader(lockedKeys || []),
7002
+ createSyncLoader(),
7003
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
7004
+ );
6689
7005
  case "markdown":
6690
7006
  return composeLoaders(
6691
7007
  createTextFileLoader(bucketPathPattern),
@@ -6984,7 +7300,7 @@ function createBasicTranslator(model, systemPrompt) {
6984
7300
  ]
6985
7301
  });
6986
7302
  const result = JSON.parse(response.text);
6987
- return _optionalChain([result, 'optionalAccess', _241 => _241.data]) || {};
7303
+ return _optionalChain([result, 'optionalAccess', _248 => _248.data]) || {};
6988
7304
  }
6989
7305
  }
6990
7306
  function extractPayloadChunks(payload) {
@@ -7066,7 +7382,7 @@ function getPureModelProvider(provider) {
7066
7382
 
7067
7383
  ${_chalk2.default.hex(colors.blue)("Docs: https://lingo.dev/go/docs")}
7068
7384
  `;
7069
- switch (_optionalChain([provider, 'optionalAccess', _242 => _242.id])) {
7385
+ switch (_optionalChain([provider, 'optionalAccess', _249 => _249.id])) {
7070
7386
  case "openai": {
7071
7387
  if (!process.env.OPENAI_API_KEY) {
7072
7388
  throw new Error(
@@ -7124,7 +7440,7 @@ function getPureModelProvider(provider) {
7124
7440
  })(provider.model);
7125
7441
  }
7126
7442
  default: {
7127
- throw new Error(createUnsupportedProviderErrorMessage(_optionalChain([provider, 'optionalAccess', _243 => _243.id])));
7443
+ throw new Error(createUnsupportedProviderErrorMessage(_optionalChain([provider, 'optionalAccess', _250 => _250.id])));
7128
7444
  }
7129
7445
  }
7130
7446
  }
@@ -7364,7 +7680,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
7364
7680
  validateParams(i18nConfig, flags);
7365
7681
  ora.succeed("Localization configuration is valid");
7366
7682
  ora.start("Connecting to Lingo.dev Localization Engine...");
7367
- const isByokMode = !!_optionalChain([i18nConfig, 'optionalAccess', _244 => _244.provider]);
7683
+ const isByokMode = !!_optionalChain([i18nConfig, 'optionalAccess', _251 => _251.provider]);
7368
7684
  if (isByokMode) {
7369
7685
  authId = null;
7370
7686
  ora.succeed("Using external provider (BYOK mode)");
@@ -7378,16 +7694,16 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
7378
7694
  flags
7379
7695
  });
7380
7696
  let buckets = getBuckets(i18nConfig);
7381
- if (_optionalChain([flags, 'access', _245 => _245.bucket, 'optionalAccess', _246 => _246.length])) {
7697
+ if (_optionalChain([flags, 'access', _252 => _252.bucket, 'optionalAccess', _253 => _253.length])) {
7382
7698
  buckets = buckets.filter(
7383
7699
  (bucket) => flags.bucket.includes(bucket.type)
7384
7700
  );
7385
7701
  }
7386
7702
  ora.succeed("Buckets retrieved");
7387
- if (_optionalChain([flags, 'access', _247 => _247.file, 'optionalAccess', _248 => _248.length])) {
7703
+ if (_optionalChain([flags, 'access', _254 => _254.file, 'optionalAccess', _255 => _255.length])) {
7388
7704
  buckets = buckets.map((bucket) => {
7389
7705
  const paths = bucket.paths.filter(
7390
- (path17) => flags.file.find((file) => _optionalChain([path17, 'access', _249 => _249.pathPattern, 'optionalAccess', _250 => _250.includes, 'call', _251 => _251(file)]))
7706
+ (path17) => flags.file.find((file) => _optionalChain([path17, 'access', _256 => _256.pathPattern, 'optionalAccess', _257 => _257.includes, 'call', _258 => _258(file)]))
7391
7707
  );
7392
7708
  return { ...bucket, paths };
7393
7709
  }).filter((bucket) => bucket.paths.length > 0);
@@ -7406,7 +7722,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
7406
7722
  });
7407
7723
  }
7408
7724
  }
7409
- const targetLocales = _optionalChain([flags, 'access', _252 => _252.locale, 'optionalAccess', _253 => _253.length]) ? flags.locale : i18nConfig.locale.targets;
7725
+ const targetLocales = _optionalChain([flags, 'access', _259 => _259.locale, 'optionalAccess', _260 => _260.length]) ? flags.locale : i18nConfig.locale.targets;
7410
7726
  ora.start("Setting up localization cache...");
7411
7727
  const checkLockfileProcessor = createDeltaProcessor("");
7412
7728
  const lockfileExists = await checkLockfileProcessor.checkIfLockExists();
@@ -7665,7 +7981,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
7665
7981
  }
7666
7982
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
7667
7983
  const checksums = await deltaProcessor.createChecksums(sourceData);
7668
- if (!_optionalChain([flags, 'access', _254 => _254.locale, 'optionalAccess', _255 => _255.length])) {
7984
+ if (!_optionalChain([flags, 'access', _261 => _261.locale, 'optionalAccess', _262 => _262.length])) {
7669
7985
  await deltaProcessor.saveChecksums(checksums);
7670
7986
  }
7671
7987
  }
@@ -7749,12 +8065,12 @@ function validateParams(i18nConfig, flags) {
7749
8065
  message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
7750
8066
  docUrl: "bucketNotFound"
7751
8067
  });
7752
- } else if (_optionalChain([flags, 'access', _256 => _256.locale, 'optionalAccess', _257 => _257.some, 'call', _258 => _258((locale) => !i18nConfig.locale.targets.includes(locale))])) {
8068
+ } else if (_optionalChain([flags, 'access', _263 => _263.locale, 'optionalAccess', _264 => _264.some, 'call', _265 => _265((locale) => !i18nConfig.locale.targets.includes(locale))])) {
7753
8069
  throw new CLIError({
7754
8070
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
7755
8071
  docUrl: "localeTargetNotFound"
7756
8072
  });
7757
- } else if (_optionalChain([flags, 'access', _259 => _259.bucket, 'optionalAccess', _260 => _260.some, 'call', _261 => _261(
8073
+ } else if (_optionalChain([flags, 'access', _266 => _266.bucket, 'optionalAccess', _267 => _267.some, 'call', _268 => _268(
7758
8074
  (bucket) => !i18nConfig.buckets[bucket]
7759
8075
  )])) {
7760
8076
  throw new CLIError({
@@ -8258,7 +8574,7 @@ function createLingoDotDevLocalizer(explicitApiKey) {
8258
8574
  const response = await engine.whoami();
8259
8575
  return {
8260
8576
  authenticated: !!response,
8261
- username: _optionalChain([response, 'optionalAccess', _262 => _262.email])
8577
+ username: _optionalChain([response, 'optionalAccess', _269 => _269.email])
8262
8578
  };
8263
8579
  } catch (e2) {
8264
8580
  return { authenticated: false };
@@ -8276,7 +8592,8 @@ function createLingoDotDevLocalizer(explicitApiKey) {
8276
8592
  reference: {
8277
8593
  [input2.sourceLocale]: input2.sourceData,
8278
8594
  [input2.targetLocale]: input2.targetData
8279
- }
8595
+ },
8596
+ hints: input2.hints
8280
8597
  },
8281
8598
  onProgress
8282
8599
  );
@@ -8365,7 +8682,7 @@ function createExplicitLocalizer(provider) {
8365
8682
  }
8366
8683
  function createAiSdkLocalizer(params) {
8367
8684
  const skipAuth = params.skipAuth === true;
8368
- const apiKey = process.env[_nullishCoalesce(_optionalChain([params, 'optionalAccess', _263 => _263.apiKeyName]), () => ( ""))];
8685
+ const apiKey = process.env[_nullishCoalesce(_optionalChain([params, 'optionalAccess', _270 => _270.apiKeyName]), () => ( ""))];
8369
8686
  if (!skipAuth && !apiKey || !params.apiKeyName) {
8370
8687
  throw new Error(
8371
8688
  _dedent2.default`
@@ -8490,8 +8807,8 @@ async function setup(input2) {
8490
8807
  throw new Error(
8491
8808
  "No buckets found in i18n.json. Please add at least one bucket containing i18n content."
8492
8809
  );
8493
- } else if (_optionalChain([ctx, 'access', _264 => _264.flags, 'access', _265 => _265.bucket, 'optionalAccess', _266 => _266.some, 'call', _267 => _267(
8494
- (bucket) => !_optionalChain([ctx, 'access', _268 => _268.config, 'optionalAccess', _269 => _269.buckets, 'access', _270 => _270[bucket]])
8810
+ } else if (_optionalChain([ctx, 'access', _271 => _271.flags, 'access', _272 => _272.bucket, 'optionalAccess', _273 => _273.some, 'call', _274 => _274(
8811
+ (bucket) => !_optionalChain([ctx, 'access', _275 => _275.config, 'optionalAccess', _276 => _276.buckets, 'access', _277 => _277[bucket]])
8495
8812
  )])) {
8496
8813
  throw new Error(
8497
8814
  `One or more specified buckets do not exist in i18n.json. Please add them to the list first and try again.`
@@ -8504,7 +8821,7 @@ async function setup(input2) {
8504
8821
  title: "Selecting localization provider",
8505
8822
  task: async (ctx, task) => {
8506
8823
  ctx.localizer = createLocalizer(
8507
- _optionalChain([ctx, 'access', _271 => _271.config, 'optionalAccess', _272 => _272.provider]),
8824
+ _optionalChain([ctx, 'access', _278 => _278.config, 'optionalAccess', _279 => _279.provider]),
8508
8825
  ctx.flags.apiKey
8509
8826
  );
8510
8827
  if (!ctx.localizer) {
@@ -8810,6 +9127,7 @@ function createWorkerTask(args) {
8810
9127
  const sourceData = await bucketLoader.pull(
8811
9128
  assignedTask.sourceLocale
8812
9129
  );
9130
+ const hints = await bucketLoader.pullHints();
8813
9131
  const targetData = await bucketLoader.pull(
8814
9132
  assignedTask.targetLocale
8815
9133
  );
@@ -8822,7 +9140,7 @@ function createWorkerTask(args) {
8822
9140
  const processableData = _lodash2.default.chain(sourceData).entries().filter(
8823
9141
  ([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!args.ctx.flags.force
8824
9142
  ).filter(
8825
- ([key]) => !assignedTask.onlyKeys.length || _optionalChain([assignedTask, 'access', _273 => _273.onlyKeys, 'optionalAccess', _274 => _274.some, 'call', _275 => _275(
9143
+ ([key]) => !assignedTask.onlyKeys.length || _optionalChain([assignedTask, 'access', _280 => _280.onlyKeys, 'optionalAccess', _281 => _281.some, 'call', _282 => _282(
8826
9144
  (pattern) => minimatch(key, pattern)
8827
9145
  )])
8828
9146
  ).fromPairs().value();
@@ -8832,13 +9150,15 @@ function createWorkerTask(args) {
8832
9150
  });
8833
9151
  return { status: "skipped" };
8834
9152
  }
9153
+ const relevantHints = _lodash2.default.pick(hints, Object.keys(processableData));
8835
9154
  const processedTargetData = await args.ctx.localizer.localize(
8836
9155
  {
8837
9156
  sourceLocale: assignedTask.sourceLocale,
8838
9157
  targetLocale: assignedTask.targetLocale,
8839
9158
  sourceData,
8840
9159
  targetData,
8841
- processableData
9160
+ processableData,
9161
+ hints: relevantHints
8842
9162
  },
8843
9163
  async (progress, _sourceChunk, processedChunk) => {
8844
9164
  await args.ioLimiter(async () => {
@@ -8883,7 +9203,7 @@ function createWorkerTask(args) {
8883
9203
  finalRenamedTargetData
8884
9204
  );
8885
9205
  const checksums2 = await deltaProcessor.createChecksums(sourceData);
8886
- if (!_optionalChain([args, 'access', _276 => _276.ctx, 'access', _277 => _277.flags, 'access', _278 => _278.targetLocale, 'optionalAccess', _279 => _279.length])) {
9206
+ if (!_optionalChain([args, 'access', _283 => _283.ctx, 'access', _284 => _284.flags, 'access', _285 => _285.targetLocale, 'optionalAccess', _286 => _286.length])) {
8887
9207
  await deltaProcessor.saveChecksums(checksums2);
8888
9208
  }
8889
9209
  });
@@ -9073,13 +9393,13 @@ var flagsSchema2 = _zod.z.object({
9073
9393
 
9074
9394
  // src/cli/cmd/run/_utils.ts
9075
9395
  async function determineAuthId(ctx) {
9076
- const isByokMode = !!_optionalChain([ctx, 'access', _280 => _280.config, 'optionalAccess', _281 => _281.provider]);
9396
+ const isByokMode = !!_optionalChain([ctx, 'access', _287 => _287.config, 'optionalAccess', _288 => _288.provider]);
9077
9397
  if (isByokMode) {
9078
9398
  return null;
9079
9399
  } else {
9080
9400
  try {
9081
- const authStatus = await _optionalChain([ctx, 'access', _282 => _282.localizer, 'optionalAccess', _283 => _283.checkAuth, 'call', _284 => _284()]);
9082
- return _optionalChain([authStatus, 'optionalAccess', _285 => _285.username]) || null;
9401
+ const authStatus = await _optionalChain([ctx, 'access', _289 => _289.localizer, 'optionalAccess', _290 => _290.checkAuth, 'call', _291 => _291()]);
9402
+ return _optionalChain([authStatus, 'optionalAccess', _292 => _292.username]) || null;
9083
9403
  } catch (e3) {
9084
9404
  return null;
9085
9405
  }
@@ -9239,7 +9559,7 @@ var InBranchFlow = class extends IntegrationFlow {
9239
9559
  _child_process.execSync.call(void 0, `git config --global safe.directory ${process.cwd()}`);
9240
9560
  _child_process.execSync.call(void 0, `git config user.name "${gitConfig.userName}"`);
9241
9561
  _child_process.execSync.call(void 0, `git config user.email "${gitConfig.userEmail}"`);
9242
- _optionalChain([this, 'access', _286 => _286.platformKit, 'optionalAccess', _287 => _287.gitConfig, 'call', _288 => _288()]);
9562
+ _optionalChain([this, 'access', _293 => _293.platformKit, 'optionalAccess', _294 => _294.gitConfig, 'call', _295 => _295()]);
9243
9563
  _child_process.execSync.call(void 0, `git fetch origin ${baseBranchName}`, { stdio: "inherit" });
9244
9564
  _child_process.execSync.call(void 0, `git checkout ${baseBranchName} --`, { stdio: "inherit" });
9245
9565
  if (!processOwnCommits) {
@@ -9271,7 +9591,7 @@ var InBranchFlow = class extends IntegrationFlow {
9271
9591
  // src/cli/cmd/ci/flows/pull-request.ts
9272
9592
  var PullRequestFlow = class extends InBranchFlow {
9273
9593
  async preRun() {
9274
- const canContinue = await _optionalChain([super.preRun.bind(this), 'optionalCall', _289 => _289()]);
9594
+ const canContinue = await _optionalChain([super.preRun.bind(this), 'optionalCall', _296 => _296()]);
9275
9595
  if (!canContinue) {
9276
9596
  return false;
9277
9597
  }
@@ -9534,10 +9854,10 @@ var BitbucketPlatformKit = class extends PlatformKit {
9534
9854
  repo_slug: this.platformConfig.repositoryName,
9535
9855
  state: "OPEN"
9536
9856
  }).then(({ data: { values } }) => {
9537
- return _optionalChain([values, 'optionalAccess', _290 => _290.find, 'call', _291 => _291(
9538
- ({ source, destination }) => _optionalChain([source, 'optionalAccess', _292 => _292.branch, 'optionalAccess', _293 => _293.name]) === branch && _optionalChain([destination, 'optionalAccess', _294 => _294.branch, 'optionalAccess', _295 => _295.name]) === this.platformConfig.baseBranchName
9857
+ return _optionalChain([values, 'optionalAccess', _297 => _297.find, 'call', _298 => _298(
9858
+ ({ source, destination }) => _optionalChain([source, 'optionalAccess', _299 => _299.branch, 'optionalAccess', _300 => _300.name]) === branch && _optionalChain([destination, 'optionalAccess', _301 => _301.branch, 'optionalAccess', _302 => _302.name]) === this.platformConfig.baseBranchName
9539
9859
  )]);
9540
- }).then((pr) => _optionalChain([pr, 'optionalAccess', _296 => _296.id]));
9860
+ }).then((pr) => _optionalChain([pr, 'optionalAccess', _303 => _303.id]));
9541
9861
  }
9542
9862
  async closePullRequest({ pullRequestNumber }) {
9543
9863
  await this.bb.repositories.declinePullRequest({
@@ -9633,7 +9953,7 @@ var GitHubPlatformKit = class extends PlatformKit {
9633
9953
  repo: this.platformConfig.repositoryName,
9634
9954
  base: this.platformConfig.baseBranchName,
9635
9955
  state: "open"
9636
- }).then(({ data }) => data[0]).then((pr) => _optionalChain([pr, 'optionalAccess', _297 => _297.number]));
9956
+ }).then(({ data }) => data[0]).then((pr) => _optionalChain([pr, 'optionalAccess', _304 => _304.number]));
9637
9957
  }
9638
9958
  async closePullRequest({ pullRequestNumber }) {
9639
9959
  await this.octokit.rest.pulls.update({
@@ -9760,7 +10080,7 @@ var GitlabPlatformKit = class extends PlatformKit {
9760
10080
  sourceBranch: branch,
9761
10081
  state: "opened"
9762
10082
  });
9763
- return _optionalChain([mergeRequests, 'access', _298 => _298[0], 'optionalAccess', _299 => _299.iid]);
10083
+ return _optionalChain([mergeRequests, 'access', _305 => _305[0], 'optionalAccess', _306 => _306.iid]);
9764
10084
  }
9765
10085
  async closePullRequest({
9766
10086
  pullRequestNumber
@@ -9850,7 +10170,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
9850
10170
  }
9851
10171
  const env = {
9852
10172
  LINGODOTDEV_API_KEY: settings.auth.apiKey,
9853
- LINGODOTDEV_PULL_REQUEST: _optionalChain([options, 'access', _300 => _300.pullRequest, 'optionalAccess', _301 => _301.toString, 'call', _302 => _302()]) || "false",
10173
+ LINGODOTDEV_PULL_REQUEST: _optionalChain([options, 'access', _307 => _307.pullRequest, 'optionalAccess', _308 => _308.toString, 'call', _309 => _309()]) || "false",
9854
10174
  ...options.commitMessage && {
9855
10175
  LINGODOTDEV_COMMIT_MESSAGE: options.commitMessage
9856
10176
  },
@@ -9870,7 +10190,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
9870
10190
  const { isPullRequestMode } = platformKit.config;
9871
10191
  ora.info(`Pull request mode: ${isPullRequestMode ? "on" : "off"}`);
9872
10192
  const flow = isPullRequestMode ? new PullRequestFlow(ora, platformKit) : new InBranchFlow(ora, platformKit);
9873
- const canRun = await _optionalChain([flow, 'access', _303 => _303.preRun, 'optionalCall', _304 => _304()]);
10193
+ const canRun = await _optionalChain([flow, 'access', _310 => _310.preRun, 'optionalCall', _311 => _311()]);
9874
10194
  if (canRun === false) {
9875
10195
  return;
9876
10196
  }
@@ -9880,7 +10200,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
9880
10200
  if (!hasChanges) {
9881
10201
  return;
9882
10202
  }
9883
- await _optionalChain([flow, 'access', _305 => _305.postRun, 'optionalCall', _306 => _306()]);
10203
+ await _optionalChain([flow, 'access', _312 => _312.postRun, 'optionalCall', _313 => _313()]);
9884
10204
  });
9885
10205
  function parseBooleanArg(val) {
9886
10206
  if (val === true) return true;
@@ -9949,17 +10269,17 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
9949
10269
  flags
9950
10270
  });
9951
10271
  let buckets = getBuckets(i18nConfig);
9952
- if (_optionalChain([flags, 'access', _307 => _307.bucket, 'optionalAccess', _308 => _308.length])) {
10272
+ if (_optionalChain([flags, 'access', _314 => _314.bucket, 'optionalAccess', _315 => _315.length])) {
9953
10273
  buckets = buckets.filter(
9954
10274
  (bucket) => flags.bucket.includes(bucket.type)
9955
10275
  );
9956
10276
  }
9957
10277
  ora.succeed("Buckets retrieved");
9958
- if (_optionalChain([flags, 'access', _309 => _309.file, 'optionalAccess', _310 => _310.length])) {
10278
+ if (_optionalChain([flags, 'access', _316 => _316.file, 'optionalAccess', _317 => _317.length])) {
9959
10279
  buckets = buckets.map((bucket) => {
9960
10280
  const paths = bucket.paths.filter(
9961
10281
  (path17) => flags.file.find(
9962
- (file) => _optionalChain([path17, 'access', _311 => _311.pathPattern, 'optionalAccess', _312 => _312.includes, 'call', _313 => _313(file)]) || _optionalChain([path17, 'access', _314 => _314.pathPattern, 'optionalAccess', _315 => _315.match, 'call', _316 => _316(file)]) || minimatch(path17.pathPattern, file)
10282
+ (file) => _optionalChain([path17, 'access', _318 => _318.pathPattern, 'optionalAccess', _319 => _319.includes, 'call', _320 => _320(file)]) || _optionalChain([path17, 'access', _321 => _321.pathPattern, 'optionalAccess', _322 => _322.match, 'call', _323 => _323(file)]) || minimatch(path17.pathPattern, file)
9963
10283
  )
9964
10284
  );
9965
10285
  return { ...bucket, paths };
@@ -9979,7 +10299,7 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
9979
10299
  });
9980
10300
  }
9981
10301
  }
9982
- const targetLocales = _optionalChain([flags, 'access', _317 => _317.locale, 'optionalAccess', _318 => _318.length]) ? flags.locale : i18nConfig.locale.targets;
10302
+ const targetLocales = _optionalChain([flags, 'access', _324 => _324.locale, 'optionalAccess', _325 => _325.length]) ? flags.locale : i18nConfig.locale.targets;
9983
10303
  let totalSourceKeyCount = 0;
9984
10304
  let uniqueKeysToTranslate = 0;
9985
10305
  let totalExistingTranslations = 0;
@@ -10383,12 +10703,12 @@ function validateParams2(i18nConfig, flags) {
10383
10703
  message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
10384
10704
  docUrl: "bucketNotFound"
10385
10705
  });
10386
- } else if (_optionalChain([flags, 'access', _319 => _319.locale, 'optionalAccess', _320 => _320.some, 'call', _321 => _321((locale) => !i18nConfig.locale.targets.includes(locale))])) {
10706
+ } else if (_optionalChain([flags, 'access', _326 => _326.locale, 'optionalAccess', _327 => _327.some, 'call', _328 => _328((locale) => !i18nConfig.locale.targets.includes(locale))])) {
10387
10707
  throw new CLIError({
10388
10708
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
10389
10709
  docUrl: "localeTargetNotFound"
10390
10710
  });
10391
- } else if (_optionalChain([flags, 'access', _322 => _322.bucket, 'optionalAccess', _323 => _323.some, 'call', _324 => _324(
10711
+ } else if (_optionalChain([flags, 'access', _329 => _329.bucket, 'optionalAccess', _330 => _330.some, 'call', _331 => _331(
10392
10712
  (bucket) => !i18nConfig.buckets[bucket]
10393
10713
  )])) {
10394
10714
  throw new CLIError({
@@ -10468,16 +10788,19 @@ async function renderHero2() {
10468
10788
  )} - open-source, AI-powered i18n CLI for web & mobile localization.`
10469
10789
  );
10470
10790
  console.log(" ");
10791
+ console.log(_chalk2.default.hex(colors2.blue)("\u{1F4DA} Docs: https://lingo.dev/go/docs"));
10792
+ console.log(
10793
+ _chalk2.default.hex(colors2.blue)("\u2B50 Star the repo: https://lingo.dev/go/gh")
10794
+ );
10471
10795
  console.log(
10472
- _chalk2.default.hex(colors2.blue)("\u2B50 GitHub Repo: https://lingo.dev/go/gh")
10796
+ _chalk2.default.hex(colors2.blue)("\u{1F3AE} Join Discord: https://lingo.dev/go/discord")
10473
10797
  );
10474
- console.log(_chalk2.default.hex(colors2.blue)("\u{1F4AC} 24/7 Support: hi@lingo.dev"));
10475
10798
  }
10476
10799
 
10477
10800
  // package.json
10478
10801
  var package_default = {
10479
10802
  name: "lingo.dev",
10480
- version: "0.107.6",
10803
+ version: "0.109.0",
10481
10804
  description: "Lingo.dev CLI",
10482
10805
  private: false,
10483
10806
  publishConfig: {
@@ -10580,7 +10903,8 @@ var package_default = {
10580
10903
  scripts: {
10581
10904
  "lingo.dev": "node --inspect=9229 ./bin/cli.mjs",
10582
10905
  dev: "tsup --watch",
10583
- build: "tsc --noEmit && tsup",
10906
+ build: "pnpm typecheck && tsup",
10907
+ typecheck: "tsc --noEmit",
10584
10908
  test: "vitest run",
10585
10909
  "test:watch": "vitest",
10586
10910
  clean: "rm -rf build"
@@ -10600,7 +10924,7 @@ var package_default = {
10600
10924
  "@datocms/cma-client-node": "^4.0.1",
10601
10925
  "@gitbeaker/rest": "^39.34.3",
10602
10926
  "@inkjs/ui": "^2.0.0",
10603
- "@inquirer/prompts": "^7.4.1",
10927
+ "@inquirer/prompts": "^7.7.0",
10604
10928
  "@lingo.dev/_compiler": "workspace:*",
10605
10929
  "@lingo.dev/_react": "workspace:*",
10606
10930
  "@lingo.dev/_sdk": "workspace:*",
@@ -10625,7 +10949,7 @@ var package_default = {
10625
10949
  ejs: "^3.1.10",
10626
10950
  express: "^5.1.0",
10627
10951
  "external-editor": "^3.1.0",
10628
- figlet: "^1.8.0",
10952
+ figlet: "^1.8.2",
10629
10953
  flat: "^6.0.1",
10630
10954
  "gettext-parser": "^8.0.0",
10631
10955
  glob: "<11.0.0",
@@ -10640,6 +10964,7 @@ var package_default = {
10640
10964
  "is-url": "^1.2.4",
10641
10965
  jsdom: "^25.0.1",
10642
10966
  json5: "^2.2.3",
10967
+ "jsonc-parser": "^3.3.1",
10643
10968
  jsonrepair: "^3.11.2",
10644
10969
  listr2: "^8.3.2",
10645
10970
  lodash: "^4.17.21",
@@ -10657,7 +10982,7 @@ var package_default = {
10657
10982
  "p-limit": "^6.2.0",
10658
10983
  "php-array-reader": "^2.1.2",
10659
10984
  plist: "^3.1.0",
10660
- "posthog-node": "^4.17.0",
10985
+ "posthog-node": "^5.5.1",
10661
10986
  prettier: "^3.4.2",
10662
10987
  react: "^18.3.1",
10663
10988
  "rehype-stringify": "^10.0.1",
@@ -10752,7 +11077,7 @@ var purge_default = new (0, _interactivecommander.Command)().command("purge").de
10752
11077
  if (options.file && options.file.length) {
10753
11078
  buckets = buckets.map((bucket) => {
10754
11079
  const paths = bucket.paths.filter(
10755
- (bucketPath) => _optionalChain([options, 'access', _325 => _325.file, 'optionalAccess', _326 => _326.some, 'call', _327 => _327((f) => bucketPath.pathPattern.includes(f))])
11080
+ (bucketPath) => _optionalChain([options, 'access', _332 => _332.file, 'optionalAccess', _333 => _333.some, 'call', _334 => _334((f) => bucketPath.pathPattern.includes(f))])
10756
11081
  );
10757
11082
  return { ...bucket, paths };
10758
11083
  }).filter((bucket) => bucket.paths.length > 0);