lingo.dev 0.111.16 → 0.112.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.cjs CHANGED
@@ -1539,148 +1539,11 @@ var files_default = new (0, _interactivecommander.Command)().command("files").de
1539
1539
  }
1540
1540
  });
1541
1541
 
1542
- // src/cli/cmd/show/index.ts
1543
- var show_default = new (0, _interactivecommander.Command)().command("show").description("Display configuration, locales, and file paths").helpOption("-h, --help", "Show help").addCommand(config_default).addCommand(locale_default).addCommand(files_default);
1544
-
1545
- // src/cli/cmd/config/index.ts
1546
-
1547
-
1548
- // src/cli/cmd/config/set.ts
1549
-
1550
-
1551
- var _dedent = require('dedent'); var _dedent2 = _interopRequireDefault(_dedent);
1552
-
1553
- var set_default = new (0, _interactivecommander.Command)().name("set").description("Set or update a CLI setting in ~/.lingodotdevrc").addHelpText("afterAll", `
1554
- Available keys:
1555
- ${SETTINGS_KEYS.join("\n ")}`).argument(
1556
- "<key>",
1557
- "Configuration key to set (dot notation, e.g., auth.apiKey)"
1558
- ).argument("<value>", "The configuration value to set").helpOption("-h, --help", "Show help").action(async (key, value) => {
1559
- if (!SETTINGS_KEYS.includes(key)) {
1560
- console.error(
1561
- _dedent2.default`
1562
- ${_chalk2.default.red("\u2716")} Unknown configuration key: ${_chalk2.default.bold(key)}
1563
- Run ${_chalk2.default.dim("lingo.dev config set --help")} to see available keys.
1564
- `
1565
- );
1566
- process.exitCode = 1;
1567
- return;
1568
- }
1569
- const current = loadSystemSettings();
1570
- const updated = _lodash2.default.cloneDeep(current);
1571
- _lodash2.default.set(updated, key, value);
1572
- try {
1573
- saveSettings(updated);
1574
- console.log(`${_chalk2.default.green("\u2714")} Set ${_chalk2.default.bold(key)}`);
1575
- } catch (err) {
1576
- console.error(
1577
- _chalk2.default.red(
1578
- `\u2716 Failed to save configuration: ${_chalk2.default.dim(
1579
- err instanceof Error ? err.message : String(err)
1580
- )}`
1581
- )
1582
- );
1583
- process.exitCode = 1;
1584
- }
1585
- });
1586
-
1587
- // src/cli/cmd/config/unset.ts
1588
-
1589
-
1590
-
1591
-
1592
- var unset_default = new (0, _interactivecommander.Command)().name("unset").description("Remove a CLI setting from ~/.lingodotdevrc").addHelpText("afterAll", `
1593
- Available keys:
1594
- ${SETTINGS_KEYS.join("\n ")}`).argument(
1595
- "<key>",
1596
- "Configuration key to remove (must match one of the available keys listed below)"
1597
- ).helpOption("-h, --help", "Show help").action(async (key) => {
1598
- if (!SETTINGS_KEYS.includes(key)) {
1599
- console.error(
1600
- _dedent2.default`
1601
- ${_chalk2.default.red("\u2716")} Unknown configuration key: ${_chalk2.default.bold(key)}
1602
- Run ${_chalk2.default.dim(
1603
- "lingo.dev config unset --help"
1604
- )} to see available keys.
1605
- `
1606
- );
1607
- process.exitCode = 1;
1608
- return;
1609
- }
1610
- const settings = loadSystemSettings();
1611
- const currentValue = _lodash2.default.get(settings, key);
1612
- if (!_lodash2.default.trim(String(currentValue || ""))) {
1613
- console.log(`${_chalk2.default.cyan("\u2139")} ${_chalk2.default.bold(key)} is not set.`);
1614
- return;
1615
- } else {
1616
- const updated = _lodash2.default.cloneDeep(settings);
1617
- _lodash2.default.unset(updated, key);
1618
- try {
1619
- saveSettings(updated);
1620
- console.log(
1621
- `${_chalk2.default.green("\u2714")} Removed configuration key ${_chalk2.default.bold(key)}`
1622
- );
1623
- } catch (err) {
1624
- console.error(
1625
- _chalk2.default.red(
1626
- `\u2716 Failed to save configuration: ${_chalk2.default.dim(
1627
- err instanceof Error ? err.message : String(err)
1628
- )}`
1629
- )
1630
- );
1631
- process.exitCode = 1;
1632
- }
1633
- }
1634
- });
1635
-
1636
- // src/cli/cmd/config/get.ts
1637
-
1638
-
1639
-
1640
-
1641
- var get_default = new (0, _interactivecommander.Command)().name("get").description("Display the value of a CLI setting from ~/.lingodotdevrc").addHelpText("afterAll", `
1642
- Available keys:
1643
- ${SETTINGS_KEYS.join("\n ")}`).argument(
1644
- "<key>",
1645
- "Configuration key to read (choose from the available keys listed below)"
1646
- ).helpOption("-h, --help", "Show help").action(async (key) => {
1647
- if (!SETTINGS_KEYS.includes(key)) {
1648
- console.error(
1649
- _dedent2.default`
1650
- ${_chalk2.default.red("\u2716")} Unknown configuration key: ${_chalk2.default.bold(key)}
1651
- Run ${_chalk2.default.dim("lingo.dev config get --help")} to see available keys.
1652
- `
1653
- );
1654
- process.exitCode = 1;
1655
- return;
1656
- }
1657
- const settings = loadSystemSettings();
1658
- const value = _lodash2.default.get(settings, key);
1659
- if (!value) {
1660
- console.log(`${_chalk2.default.cyan("\u2139")} ${_chalk2.default.bold(key)} is not set.`);
1661
- return;
1662
- }
1663
- if (typeof value === "object") {
1664
- console.log(JSON.stringify(value, null, 2));
1665
- } else {
1666
- console.log(value);
1667
- }
1668
- });
1669
-
1670
- // src/cli/cmd/config/index.ts
1671
- var config_default2 = new (0, _interactivecommander.Command)().command("config").description(
1672
- "Manage CLI settings (authentication, API keys) stored in ~/.lingodotdevrc"
1673
- ).helpOption("-h, --help", "Show help").addCommand(set_default).addCommand(unset_default).addCommand(get_default);
1674
-
1675
- // src/cli/cmd/i18n.ts
1676
-
1677
-
1678
-
1679
-
1680
-
1542
+ // src/cli/cmd/show/locked-keys.ts
1681
1543
 
1682
1544
 
1683
1545
 
1546
+ // src/cli/cmd/show/_shared-key-command.ts
1684
1547
 
1685
1548
 
1686
1549
  // src/cli/loaders/_utils.ts
@@ -2713,6 +2576,133 @@ ${content}`;
2713
2576
  });
2714
2577
  }
2715
2578
 
2579
+ // src/cli/loaders/markdoc.ts
2580
+ var _markdoc = require('@markdoc/markdoc'); var _markdoc2 = _interopRequireDefault(_markdoc);
2581
+
2582
+ var FM_ATTR_PREFIX2 = "fm-attr-";
2583
+ function createMarkdocLoader() {
2584
+ return createLoader({
2585
+ async pull(locale, input2) {
2586
+ const ast = _markdoc2.default.parse(input2);
2587
+ const result = {};
2588
+ const counters = {};
2589
+ traverseAndExtract(ast, "", result, counters);
2590
+ if (_optionalChain([ast, 'access', _130 => _130.attributes, 'optionalAccess', _131 => _131.frontmatter])) {
2591
+ const frontmatter = _yaml2.default.parse(ast.attributes.frontmatter);
2592
+ Object.entries(frontmatter).forEach(([key, value]) => {
2593
+ if (typeof value === "string") {
2594
+ result[`${FM_ATTR_PREFIX2}${key}`] = value;
2595
+ }
2596
+ });
2597
+ }
2598
+ return result;
2599
+ },
2600
+ async push(locale, data, originalInput) {
2601
+ if (!originalInput) {
2602
+ throw new Error("Original input is required for push");
2603
+ }
2604
+ const ast = _markdoc2.default.parse(originalInput);
2605
+ const counters = {};
2606
+ const pathMap = {};
2607
+ buildPathMap(ast, "", counters, pathMap);
2608
+ const frontmatterEntries = Object.entries(data).filter(([key]) => key.startsWith(FM_ATTR_PREFIX2)).map(([key, value]) => [key.replace(FM_ATTR_PREFIX2, ""), value]);
2609
+ if (frontmatterEntries.length > 0 && ast.attributes) {
2610
+ const frontmatter = Object.fromEntries(frontmatterEntries);
2611
+ ast.attributes.frontmatter = _yaml2.default.stringify(frontmatter, {
2612
+ defaultStringType: "PLAIN"
2613
+ }).trim();
2614
+ }
2615
+ const contentData = Object.fromEntries(
2616
+ Object.entries(data).filter(([key]) => !key.startsWith(FM_ATTR_PREFIX2))
2617
+ );
2618
+ applyTranslations(ast, "", contentData, pathMap);
2619
+ return _markdoc2.default.format(ast);
2620
+ }
2621
+ });
2622
+ }
2623
+ function getSemanticNodeType(node) {
2624
+ if (node.type === "tag") return node.tag || "tag";
2625
+ return node.type;
2626
+ }
2627
+ function traverseAndExtract(node, path19, result, counters, parentType) {
2628
+ if (!node || typeof node !== "object") {
2629
+ return;
2630
+ }
2631
+ let semanticType = parentType;
2632
+ const nodeSemanticType = getSemanticNodeType(node);
2633
+ if (nodeSemanticType && !["text", "strong", "em", "inline", "link"].includes(nodeSemanticType)) {
2634
+ semanticType = nodeSemanticType;
2635
+ }
2636
+ if (node.type === "text" && _optionalChain([node, 'access', _132 => _132.attributes, 'optionalAccess', _133 => _133.content])) {
2637
+ const content = node.attributes.content;
2638
+ if (typeof content === "string" && content.trim()) {
2639
+ if (semanticType) {
2640
+ const index = counters[semanticType] || 0;
2641
+ counters[semanticType] = index + 1;
2642
+ const semanticKey = `${semanticType}-${index}`;
2643
+ result[semanticKey] = content;
2644
+ }
2645
+ }
2646
+ }
2647
+ if (Array.isArray(node.children)) {
2648
+ node.children.forEach((child, index) => {
2649
+ const childPath = path19 ? `${path19}/children/${index}` : `children/${index}`;
2650
+ traverseAndExtract(child, childPath, result, counters, semanticType);
2651
+ });
2652
+ }
2653
+ }
2654
+ function buildPathMap(node, path19, counters, pathMap, parentType) {
2655
+ if (!node || typeof node !== "object") {
2656
+ return;
2657
+ }
2658
+ let semanticType = parentType;
2659
+ const nodeSemanticType = getSemanticNodeType(node);
2660
+ if (nodeSemanticType && !["text", "strong", "em", "inline", "link"].includes(nodeSemanticType)) {
2661
+ semanticType = nodeSemanticType;
2662
+ }
2663
+ if (node.type === "text" && _optionalChain([node, 'access', _134 => _134.attributes, 'optionalAccess', _135 => _135.content])) {
2664
+ const content = node.attributes.content;
2665
+ if (typeof content === "string" && content.trim()) {
2666
+ if (semanticType) {
2667
+ const index = counters[semanticType] || 0;
2668
+ counters[semanticType] = index + 1;
2669
+ const semanticKey = `${semanticType}-${index}`;
2670
+ const contentPath = path19 ? `${path19}/attributes/content` : "attributes/content";
2671
+ pathMap[semanticKey] = contentPath;
2672
+ }
2673
+ }
2674
+ }
2675
+ if (Array.isArray(node.children)) {
2676
+ node.children.forEach((child, index) => {
2677
+ const childPath = path19 ? `${path19}/children/${index}` : `children/${index}`;
2678
+ buildPathMap(child, childPath, counters, pathMap, semanticType);
2679
+ });
2680
+ }
2681
+ }
2682
+ function applyTranslations(node, path19, data, pathMap) {
2683
+ if (!node || typeof node !== "object") {
2684
+ return;
2685
+ }
2686
+ if (node.type === "text" && _optionalChain([node, 'access', _136 => _136.attributes, 'optionalAccess', _137 => _137.content])) {
2687
+ const content = node.attributes.content;
2688
+ if (typeof content === "string") {
2689
+ const contentPath = path19 ? `${path19}/attributes/content` : "attributes/content";
2690
+ const semanticKey = Object.keys(pathMap).find(
2691
+ (key) => pathMap[key] === contentPath
2692
+ );
2693
+ if (semanticKey && data[semanticKey] !== void 0) {
2694
+ node.attributes.content = data[semanticKey];
2695
+ }
2696
+ }
2697
+ }
2698
+ if (Array.isArray(node.children)) {
2699
+ node.children.forEach((child, index) => {
2700
+ const childPath = path19 ? `${path19}/children/${index}` : `children/${index}`;
2701
+ applyTranslations(child, childPath, data, pathMap);
2702
+ });
2703
+ }
2704
+ }
2705
+
2716
2706
  // src/cli/loaders/properties.ts
2717
2707
  function createPropertiesLoader() {
2718
2708
  return createLoader({
@@ -2743,7 +2733,7 @@ function isSkippableLine(line) {
2743
2733
  function parsePropertyLine(line) {
2744
2734
  const [key, ...valueParts] = line.split("=");
2745
2735
  return {
2746
- key: _optionalChain([key, 'optionalAccess', _130 => _130.trim, 'call', _131 => _131()]) || "",
2736
+ key: _optionalChain([key, 'optionalAccess', _138 => _138.trim, 'call', _139 => _139()]) || "",
2747
2737
  value: valueParts.join("=").trim()
2748
2738
  };
2749
2739
  }
@@ -2831,7 +2821,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2831
2821
  if (rootTranslationEntity.shouldTranslate === false) {
2832
2822
  continue;
2833
2823
  }
2834
- const langTranslationEntity = _optionalChain([rootTranslationEntity, 'optionalAccess', _132 => _132.localizations, 'optionalAccess', _133 => _133[locale]]);
2824
+ const langTranslationEntity = _optionalChain([rootTranslationEntity, 'optionalAccess', _140 => _140.localizations, 'optionalAccess', _141 => _141[locale]]);
2835
2825
  if (langTranslationEntity) {
2836
2826
  if ("stringUnit" in langTranslationEntity) {
2837
2827
  resultData[translationKey] = langTranslationEntity.stringUnit.value;
@@ -2840,7 +2830,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2840
2830
  resultData[translationKey] = {};
2841
2831
  const pluralForms = langTranslationEntity.variations.plural;
2842
2832
  for (const form in pluralForms) {
2843
- if (_optionalChain([pluralForms, 'access', _134 => _134[form], 'optionalAccess', _135 => _135.stringUnit, 'optionalAccess', _136 => _136.value])) {
2833
+ if (_optionalChain([pluralForms, 'access', _142 => _142[form], 'optionalAccess', _143 => _143.stringUnit, 'optionalAccess', _144 => _144.value])) {
2844
2834
  resultData[translationKey][form] = pluralForms[form].stringUnit.value;
2845
2835
  }
2846
2836
  }
@@ -2866,7 +2856,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2866
2856
  const hasDoNotTranslateFlag = originalInput && originalInput.strings && originalInput.strings[key] && originalInput.strings[key].shouldTranslate === false;
2867
2857
  if (typeof value === "string") {
2868
2858
  langDataToMerge.strings[key] = {
2869
- extractionState: _optionalChain([originalInput, 'optionalAccess', _137 => _137.strings, 'optionalAccess', _138 => _138[key], 'optionalAccess', _139 => _139.extractionState]),
2859
+ extractionState: _optionalChain([originalInput, 'optionalAccess', _145 => _145.strings, 'optionalAccess', _146 => _146[key], 'optionalAccess', _147 => _147.extractionState]),
2870
2860
  localizations: {
2871
2861
  [locale]: {
2872
2862
  stringUnit: {
@@ -2924,7 +2914,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2924
2914
  for (const [locale, localization] of Object.entries(
2925
2915
  entity.localizations
2926
2916
  )) {
2927
- if (_optionalChain([localization, 'access', _140 => _140.variations, 'optionalAccess', _141 => _141.plural])) {
2917
+ if (_optionalChain([localization, 'access', _148 => _148.variations, 'optionalAccess', _149 => _149.plural])) {
2928
2918
  const pluralForms = localization.variations.plural;
2929
2919
  for (const form in pluralForms) {
2930
2920
  const pluralKey = `${translationKey}/${form}`;
@@ -2944,7 +2934,7 @@ function _removeLocale(input2, locale) {
2944
2934
  const { strings } = input2;
2945
2935
  const newStrings = _lodash2.default.cloneDeep(strings);
2946
2936
  for (const [key, value] of Object.entries(newStrings)) {
2947
- if (_optionalChain([value, 'access', _142 => _142.localizations, 'optionalAccess', _143 => _143[locale]])) {
2937
+ if (_optionalChain([value, 'access', _150 => _150.localizations, 'optionalAccess', _151 => _151[locale]])) {
2948
2938
  delete value.localizations[locale];
2949
2939
  }
2950
2940
  }
@@ -3147,8 +3137,8 @@ async function formatDataWithBiome(data, filePath, options) {
3147
3137
  });
3148
3138
  return formatted.content;
3149
3139
  } catch (error) {
3150
- const errorMessage = error instanceof Error ? error.message || _optionalChain([error, 'access', _144 => _144.stackTrace, 'optionalAccess', _145 => _145.toString, 'call', _146 => _146(), 'access', _147 => _147.split, 'call', _148 => _148("\n"), 'access', _149 => _149[0]]) : "";
3151
- if (_optionalChain([errorMessage, 'optionalAccess', _150 => _150.includes, 'call', _151 => _151("does not exist in the workspace")])) {
3140
+ const errorMessage = error instanceof Error ? error.message || _optionalChain([error, 'access', _152 => _152.stackTrace, 'optionalAccess', _153 => _153.toString, 'call', _154 => _154(), 'access', _155 => _155.split, 'call', _156 => _156("\n"), 'access', _157 => _157[0]]) : "";
3141
+ if (_optionalChain([errorMessage, 'optionalAccess', _158 => _158.includes, 'call', _159 => _159("does not exist in the workspace")])) {
3152
3142
  } else {
3153
3143
  console.log(`\u26A0\uFE0F Biome skipped ${path14.default.basename(filePath)}`);
3154
3144
  if (errorMessage) {
@@ -3195,7 +3185,7 @@ function createPoDataLoader(params) {
3195
3185
  Object.entries(entries).forEach(([msgid, entry]) => {
3196
3186
  if (msgid && entry.msgid) {
3197
3187
  const context = entry.msgctxt || "";
3198
- const fullEntry = _optionalChain([parsedPo, 'access', _152 => _152.translations, 'access', _153 => _153[context], 'optionalAccess', _154 => _154[msgid]]);
3188
+ const fullEntry = _optionalChain([parsedPo, 'access', _160 => _160.translations, 'access', _161 => _161[context], 'optionalAccess', _162 => _162[msgid]]);
3199
3189
  if (fullEntry) {
3200
3190
  result[msgid] = fullEntry;
3201
3191
  }
@@ -3205,8 +3195,8 @@ function createPoDataLoader(params) {
3205
3195
  return result;
3206
3196
  },
3207
3197
  async push(locale, data, originalInput, originalLocale, pullInput) {
3208
- const currentSections = _optionalChain([pullInput, 'optionalAccess', _155 => _155.split, 'call', _156 => _156("\n\n"), 'access', _157 => _157.filter, 'call', _158 => _158(Boolean)]) || [];
3209
- const originalSections = _optionalChain([originalInput, 'optionalAccess', _159 => _159.split, 'call', _160 => _160("\n\n"), 'access', _161 => _161.filter, 'call', _162 => _162(Boolean)]) || [];
3198
+ const currentSections = _optionalChain([pullInput, 'optionalAccess', _163 => _163.split, 'call', _164 => _164("\n\n"), 'access', _165 => _165.filter, 'call', _166 => _166(Boolean)]) || [];
3199
+ const originalSections = _optionalChain([originalInput, 'optionalAccess', _167 => _167.split, 'call', _168 => _168("\n\n"), 'access', _169 => _169.filter, 'call', _170 => _170(Boolean)]) || [];
3210
3200
  const result = originalSections.map((section) => {
3211
3201
  const sectionPo = _gettextparser2.default.po.parse(section);
3212
3202
  if (Object.keys(sectionPo.translations).length === 0) {
@@ -3275,8 +3265,8 @@ function createPoContentLoader() {
3275
3265
  {
3276
3266
  ...entry,
3277
3267
  msgstr: [
3278
- _optionalChain([data, 'access', _163 => _163[entry.msgid], 'optionalAccess', _164 => _164.singular]),
3279
- _optionalChain([data, 'access', _165 => _165[entry.msgid], 'optionalAccess', _166 => _166.plural]) || null
3268
+ _optionalChain([data, 'access', _171 => _171[entry.msgid], 'optionalAccess', _172 => _172.singular]),
3269
+ _optionalChain([data, 'access', _173 => _173[entry.msgid], 'optionalAccess', _174 => _174.plural]) || null
3280
3270
  ].filter(Boolean)
3281
3271
  }
3282
3272
  ]).fromPairs().value();
@@ -3398,7 +3388,7 @@ function pullV1(xliffElement, locale, originalLocale) {
3398
3388
  let key = getTransUnitKey(unit);
3399
3389
  if (!key) return;
3400
3390
  if (seenKeys.has(key)) {
3401
- const id = _optionalChain([unit, 'access', _167 => _167.getAttribute, 'call', _168 => _168("id"), 'optionalAccess', _169 => _169.trim, 'call', _170 => _170()]);
3391
+ const id = _optionalChain([unit, 'access', _175 => _175.getAttribute, 'call', _176 => _176("id"), 'optionalAccess', _177 => _177.trim, 'call', _178 => _178()]);
3402
3392
  if (id) {
3403
3393
  key = `${key}#${id}`;
3404
3394
  } else {
@@ -3446,7 +3436,7 @@ function pushV1(dom, xliffElement, locale, translations, originalLocale, origina
3446
3436
  let key = getTransUnitKey(unit);
3447
3437
  if (!key) return;
3448
3438
  if (seenKeys.has(key)) {
3449
- const id = _optionalChain([unit, 'access', _171 => _171.getAttribute, 'call', _172 => _172("id"), 'optionalAccess', _173 => _173.trim, 'call', _174 => _174()]);
3439
+ const id = _optionalChain([unit, 'access', _179 => _179.getAttribute, 'call', _180 => _180("id"), 'optionalAccess', _181 => _181.trim, 'call', _182 => _182()]);
3450
3440
  if (id) {
3451
3441
  key = `${key}#${id}`;
3452
3442
  } else {
@@ -3488,7 +3478,7 @@ function pushV1(dom, xliffElement, locale, translations, originalLocale, origina
3488
3478
  const translationKeys = new Set(Object.keys(translations));
3489
3479
  existingUnits.forEach((unit, key) => {
3490
3480
  if (!translationKeys.has(key)) {
3491
- _optionalChain([unit, 'access', _175 => _175.parentNode, 'optionalAccess', _176 => _176.removeChild, 'call', _177 => _177(unit)]);
3481
+ _optionalChain([unit, 'access', _183 => _183.parentNode, 'optionalAccess', _184 => _184.removeChild, 'call', _185 => _185(unit)]);
3492
3482
  }
3493
3483
  });
3494
3484
  return serializeWithDeclaration(
@@ -3531,18 +3521,18 @@ function traverseUnitsV2(container, fileId, currentPath, result) {
3531
3521
  Array.from(container.children).forEach((child) => {
3532
3522
  const tagName = child.tagName;
3533
3523
  if (tagName === "unit") {
3534
- const unitId = _optionalChain([child, 'access', _178 => _178.getAttribute, 'call', _179 => _179("id"), 'optionalAccess', _180 => _180.trim, 'call', _181 => _181()]);
3524
+ const unitId = _optionalChain([child, 'access', _186 => _186.getAttribute, 'call', _187 => _187("id"), 'optionalAccess', _188 => _188.trim, 'call', _189 => _189()]);
3535
3525
  if (!unitId) return;
3536
3526
  const key = `resources/${fileId}/${currentPath}${unitId}/source`;
3537
3527
  const segment = child.querySelector("segment");
3538
- const source = _optionalChain([segment, 'optionalAccess', _182 => _182.querySelector, 'call', _183 => _183("source")]);
3528
+ const source = _optionalChain([segment, 'optionalAccess', _190 => _190.querySelector, 'call', _191 => _191("source")]);
3539
3529
  if (source) {
3540
3530
  result[key] = extractTextContent(source);
3541
3531
  } else {
3542
3532
  result[key] = unitId;
3543
3533
  }
3544
3534
  } else if (tagName === "group") {
3545
- const groupId = _optionalChain([child, 'access', _184 => _184.getAttribute, 'call', _185 => _185("id"), 'optionalAccess', _186 => _186.trim, 'call', _187 => _187()]);
3535
+ const groupId = _optionalChain([child, 'access', _192 => _192.getAttribute, 'call', _193 => _193("id"), 'optionalAccess', _194 => _194.trim, 'call', _195 => _195()]);
3546
3536
  const newPath = groupId ? `${currentPath}${groupId}/groupUnits/` : currentPath;
3547
3537
  traverseUnitsV2(child, fileId, newPath, result);
3548
3538
  }
@@ -3578,12 +3568,12 @@ function indexUnitsV2(container, fileId, currentPath, index) {
3578
3568
  Array.from(container.children).forEach((child) => {
3579
3569
  const tagName = child.tagName;
3580
3570
  if (tagName === "unit") {
3581
- const unitId = _optionalChain([child, 'access', _188 => _188.getAttribute, 'call', _189 => _189("id"), 'optionalAccess', _190 => _190.trim, 'call', _191 => _191()]);
3571
+ const unitId = _optionalChain([child, 'access', _196 => _196.getAttribute, 'call', _197 => _197("id"), 'optionalAccess', _198 => _198.trim, 'call', _199 => _199()]);
3582
3572
  if (!unitId) return;
3583
3573
  const key = `resources/${fileId}/${currentPath}${unitId}/source`;
3584
3574
  index.set(key, child);
3585
3575
  } else if (tagName === "group") {
3586
- const groupId = _optionalChain([child, 'access', _192 => _192.getAttribute, 'call', _193 => _193("id"), 'optionalAccess', _194 => _194.trim, 'call', _195 => _195()]);
3576
+ const groupId = _optionalChain([child, 'access', _200 => _200.getAttribute, 'call', _201 => _201("id"), 'optionalAccess', _202 => _202.trim, 'call', _203 => _203()]);
3587
3577
  const newPath = groupId ? `${currentPath}${groupId}/groupUnits/` : currentPath;
3588
3578
  indexUnitsV2(child, fileId, newPath, index);
3589
3579
  }
@@ -3604,9 +3594,9 @@ function updateUnitV2(unit, value) {
3604
3594
  setTextContent(source, value);
3605
3595
  }
3606
3596
  function getTransUnitKey(transUnit) {
3607
- const resname = _optionalChain([transUnit, 'access', _196 => _196.getAttribute, 'call', _197 => _197("resname"), 'optionalAccess', _198 => _198.trim, 'call', _199 => _199()]);
3597
+ const resname = _optionalChain([transUnit, 'access', _204 => _204.getAttribute, 'call', _205 => _205("resname"), 'optionalAccess', _206 => _206.trim, 'call', _207 => _207()]);
3608
3598
  if (resname) return resname;
3609
- const id = _optionalChain([transUnit, 'access', _200 => _200.getAttribute, 'call', _201 => _201("id"), 'optionalAccess', _202 => _202.trim, 'call', _203 => _203()]);
3599
+ const id = _optionalChain([transUnit, 'access', _208 => _208.getAttribute, 'call', _209 => _209("id"), 'optionalAccess', _210 => _210.trim, 'call', _211 => _211()]);
3610
3600
  if (id) return id;
3611
3601
  const sourceElement = transUnit.querySelector("source");
3612
3602
  if (sourceElement) {
@@ -3663,7 +3653,7 @@ function formatXml(xml) {
3663
3653
  if (cdataNode) {
3664
3654
  return `${indent2}${openTag}<![CDATA[${cdataNode.nodeValue}]]></${tagName}>`;
3665
3655
  }
3666
- const textContent = _optionalChain([element, 'access', _204 => _204.textContent, 'optionalAccess', _205 => _205.trim, 'call', _206 => _206()]) || "";
3656
+ const textContent = _optionalChain([element, 'access', _212 => _212.textContent, 'optionalAccess', _213 => _213.trim, 'call', _214 => _214()]) || "";
3667
3657
  const hasOnlyText = element.childNodes.length === 1 && element.childNodes[0].nodeType === 3;
3668
3658
  if (hasOnlyText && textContent) {
3669
3659
  return `${indent2}${openTag}${textContent}</${tagName}>`;
@@ -3956,7 +3946,7 @@ function createDatoClient(params) {
3956
3946
  ids: !records.length ? void 0 : records.join(",")
3957
3947
  }
3958
3948
  }).catch(
3959
- (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _207 => _207.response, 'optionalAccess', _208 => _208.body, 'optionalAccess', _209 => _209.data, 'optionalAccess', _210 => _210[0]]) || error)
3949
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _215 => _215.response, 'optionalAccess', _216 => _216.body, 'optionalAccess', _217 => _217.data, 'optionalAccess', _218 => _218[0]]) || error)
3960
3950
  );
3961
3951
  },
3962
3952
  findRecordsForModel: async (modelId, records) => {
@@ -3967,10 +3957,10 @@ function createDatoClient(params) {
3967
3957
  filter: {
3968
3958
  type: modelId,
3969
3959
  only_valid: "true",
3970
- ids: !_optionalChain([records, 'optionalAccess', _211 => _211.length]) ? void 0 : records.join(",")
3960
+ ids: !_optionalChain([records, 'optionalAccess', _219 => _219.length]) ? void 0 : records.join(",")
3971
3961
  }
3972
3962
  }).catch(
3973
- (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _212 => _212.response, 'optionalAccess', _213 => _213.body, 'optionalAccess', _214 => _214.data, 'optionalAccess', _215 => _215[0]]) || error)
3963
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _220 => _220.response, 'optionalAccess', _221 => _221.body, 'optionalAccess', _222 => _222.data, 'optionalAccess', _223 => _223[0]]) || error)
3974
3964
  );
3975
3965
  return result;
3976
3966
  } catch (_error) {
@@ -3986,10 +3976,10 @@ function createDatoClient(params) {
3986
3976
  updateRecord: async (id, payload) => {
3987
3977
  try {
3988
3978
  await dato.items.update(id, payload).catch(
3989
- (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _216 => _216.response, 'optionalAccess', _217 => _217.body, 'optionalAccess', _218 => _218.data, 'optionalAccess', _219 => _219[0]]) || error)
3979
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _224 => _224.response, 'optionalAccess', _225 => _225.body, 'optionalAccess', _226 => _226.data, 'optionalAccess', _227 => _227[0]]) || error)
3990
3980
  );
3991
3981
  } catch (_error) {
3992
- if (_optionalChain([_error, 'optionalAccess', _220 => _220.attributes, 'optionalAccess', _221 => _221.details, 'optionalAccess', _222 => _222.message])) {
3982
+ if (_optionalChain([_error, 'optionalAccess', _228 => _228.attributes, 'optionalAccess', _229 => _229.details, 'optionalAccess', _230 => _230.message])) {
3993
3983
  throw new Error(
3994
3984
  [
3995
3985
  `${_error.attributes.details.message}`,
@@ -4011,10 +4001,10 @@ function createDatoClient(params) {
4011
4001
  enableFieldLocalization: async (args) => {
4012
4002
  try {
4013
4003
  await dato.fields.update(`${args.modelId}::${args.fieldId}`, { localized: true }).catch(
4014
- (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _223 => _223.response, 'optionalAccess', _224 => _224.body, 'optionalAccess', _225 => _225.data, 'optionalAccess', _226 => _226[0]]) || error)
4004
+ (error) => Promise.reject(_optionalChain([error, 'optionalAccess', _231 => _231.response, 'optionalAccess', _232 => _232.body, 'optionalAccess', _233 => _233.data, 'optionalAccess', _234 => _234[0]]) || error)
4015
4005
  );
4016
4006
  } catch (_error) {
4017
- if (_optionalChain([_error, 'optionalAccess', _227 => _227.attributes, 'optionalAccess', _228 => _228.code]) === "NOT_FOUND") {
4007
+ if (_optionalChain([_error, 'optionalAccess', _235 => _235.attributes, 'optionalAccess', _236 => _236.code]) === "NOT_FOUND") {
4018
4008
  throw new Error(
4019
4009
  [
4020
4010
  `Field "${args.fieldId}" not found in model "${args.modelId}".`,
@@ -4022,7 +4012,7 @@ function createDatoClient(params) {
4022
4012
  ].join("\n\n")
4023
4013
  );
4024
4014
  }
4025
- if (_optionalChain([_error, 'optionalAccess', _229 => _229.attributes, 'optionalAccess', _230 => _230.details, 'optionalAccess', _231 => _231.message])) {
4015
+ if (_optionalChain([_error, 'optionalAccess', _237 => _237.attributes, 'optionalAccess', _238 => _238.details, 'optionalAccess', _239 => _239.message])) {
4026
4016
  throw new Error(
4027
4017
  [
4028
4018
  `${_error.attributes.details.message}`,
@@ -4100,7 +4090,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4100
4090
  const records = await dato.findRecordsForModel(modelId);
4101
4091
  const recordChoices = createRecordChoices(
4102
4092
  records,
4103
- _optionalChain([config, 'access', _232 => _232.models, 'access', _233 => _233[modelId], 'optionalAccess', _234 => _234.records]) || [],
4093
+ _optionalChain([config, 'access', _240 => _240.models, 'access', _241 => _241[modelId], 'optionalAccess', _242 => _242.records]) || [],
4104
4094
  project
4105
4095
  );
4106
4096
  const selectedRecords = await promptRecordSelection(
@@ -4119,14 +4109,14 @@ function createDatoApiLoader(config, onConfigUpdate) {
4119
4109
  },
4120
4110
  async pull(locale, input2, initCtx) {
4121
4111
  const result = {};
4122
- for (const modelId of _lodash2.default.keys(_optionalChain([initCtx, 'optionalAccess', _235 => _235.models]) || {})) {
4123
- let records = _optionalChain([initCtx, 'optionalAccess', _236 => _236.models, 'access', _237 => _237[modelId], 'access', _238 => _238.records]) || [];
4112
+ for (const modelId of _lodash2.default.keys(_optionalChain([initCtx, 'optionalAccess', _243 => _243.models]) || {})) {
4113
+ let records = _optionalChain([initCtx, 'optionalAccess', _244 => _244.models, 'access', _245 => _245[modelId], 'access', _246 => _246.records]) || [];
4124
4114
  const recordIds = records.map((record) => record.id);
4125
4115
  records = await dato.findRecords(recordIds);
4126
4116
  console.log(`Fetched ${records.length} records for model ${modelId}`);
4127
4117
  if (records.length > 0) {
4128
4118
  result[modelId] = {
4129
- fields: _optionalChain([initCtx, 'optionalAccess', _239 => _239.models, 'optionalAccess', _240 => _240[modelId], 'optionalAccess', _241 => _241.fields]) || [],
4119
+ fields: _optionalChain([initCtx, 'optionalAccess', _247 => _247.models, 'optionalAccess', _248 => _248[modelId], 'optionalAccess', _249 => _249.fields]) || [],
4130
4120
  records
4131
4121
  };
4132
4122
  }
@@ -4189,7 +4179,7 @@ function createRecordChoices(records, selectedIds = [], project) {
4189
4179
  return records.map((record) => ({
4190
4180
  name: `${record.id} - https://${project.internal_domain}/editor/item_types/${record.item_type.id}/items/${record.id}`,
4191
4181
  value: record.id,
4192
- checked: _optionalChain([selectedIds, 'optionalAccess', _242 => _242.includes, 'call', _243 => _243(record.id)])
4182
+ checked: _optionalChain([selectedIds, 'optionalAccess', _250 => _250.includes, 'call', _251 => _251(record.id)])
4193
4183
  }));
4194
4184
  }
4195
4185
  async function promptRecordSelection(modelName, choices) {
@@ -4508,7 +4498,7 @@ function createVttLoader() {
4508
4498
  if (!input2) {
4509
4499
  return "";
4510
4500
  }
4511
- const vtt = _optionalChain([_nodewebvtt2.default, 'access', _244 => _244.parse, 'call', _245 => _245(input2), 'optionalAccess', _246 => _246.cues]);
4501
+ const vtt = _optionalChain([_nodewebvtt2.default, 'access', _252 => _252.parse, 'call', _253 => _253(input2), 'optionalAccess', _254 => _254.cues]);
4512
4502
  if (Object.keys(vtt).length === 0) {
4513
4503
  return {};
4514
4504
  } else {
@@ -4562,7 +4552,7 @@ function variableExtractLoader(params) {
4562
4552
  for (let i = 0; i < matches.length; i++) {
4563
4553
  const match2 = matches[i];
4564
4554
  const currentValue = result[key].value;
4565
- const newValue = _optionalChain([currentValue, 'optionalAccess', _247 => _247.replace, 'call', _248 => _248(match2, `{variable:${i}}`)]);
4555
+ const newValue = _optionalChain([currentValue, 'optionalAccess', _255 => _255.replace, 'call', _256 => _256(match2, `{variable:${i}}`)]);
4566
4556
  result[key].value = newValue;
4567
4557
  result[key].variables[i] = match2;
4568
4558
  }
@@ -4576,7 +4566,7 @@ function variableExtractLoader(params) {
4576
4566
  for (let i = 0; i < valueObj.variables.length; i++) {
4577
4567
  const variable = valueObj.variables[i];
4578
4568
  const currentValue = result[key];
4579
- const newValue = _optionalChain([currentValue, 'optionalAccess', _249 => _249.replace, 'call', _250 => _250(`{variable:${i}}`, variable)]);
4569
+ const newValue = _optionalChain([currentValue, 'optionalAccess', _257 => _257.replace, 'call', _258 => _258(`{variable:${i}}`, variable)]);
4580
4570
  result[key] = newValue;
4581
4571
  }
4582
4572
  }
@@ -4776,7 +4766,7 @@ function createVueJsonLoader() {
4776
4766
  return createLoader({
4777
4767
  pull: async (locale, input2, ctx) => {
4778
4768
  const parsed = parseVueFile(input2);
4779
- return _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _251 => _251.i18n, 'optionalAccess', _252 => _252[locale]]), () => ( {}));
4769
+ return _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _259 => _259.i18n, 'optionalAccess', _260 => _260[locale]]), () => ( {}));
4780
4770
  },
4781
4771
  push: async (locale, data, originalInput) => {
4782
4772
  const parsed = parseVueFile(_nullishCoalesce(originalInput, () => ( "")));
@@ -4961,7 +4951,7 @@ function updateStringsInObjectExpression(objectExpression, data) {
4961
4951
  objectExpression.properties.forEach((prop) => {
4962
4952
  if (!t.isObjectProperty(prop)) return;
4963
4953
  const key = getPropertyKey(prop);
4964
- const incomingVal = _optionalChain([data, 'optionalAccess', _253 => _253[key]]);
4954
+ const incomingVal = _optionalChain([data, 'optionalAccess', _261 => _261[key]]);
4965
4955
  if (incomingVal === void 0) {
4966
4956
  return;
4967
4957
  }
@@ -4997,7 +4987,7 @@ function updateStringsInArrayExpression(arrayExpression, incoming) {
4997
4987
  let modified = false;
4998
4988
  arrayExpression.elements.forEach((element, index) => {
4999
4989
  if (!element) return;
5000
- const incomingVal = _optionalChain([incoming, 'optionalAccess', _254 => _254[index]]);
4990
+ const incomingVal = _optionalChain([incoming, 'optionalAccess', _262 => _262[index]]);
5001
4991
  if (incomingVal === void 0) return;
5002
4992
  if (t.isStringLiteral(element) && typeof incomingVal === "string") {
5003
4993
  if (element.value !== incomingVal) {
@@ -5488,7 +5478,7 @@ var AST = class _AST {
5488
5478
  const ret = this.type === null ? this.#parts.slice().map((p) => typeof p === "string" ? p : p.toJSON()) : [this.type, ...this.#parts.map((p) => p.toJSON())];
5489
5479
  if (this.isStart() && !this.type)
5490
5480
  ret.unshift([]);
5491
- if (this.isEnd() && (this === this.#root || this.#root.#filledNegs && _optionalChain([this, 'access', _255 => _255.#parent, 'optionalAccess', _256 => _256.type]) === "!")) {
5481
+ if (this.isEnd() && (this === this.#root || this.#root.#filledNegs && _optionalChain([this, 'access', _263 => _263.#parent, 'optionalAccess', _264 => _264.type]) === "!")) {
5492
5482
  ret.push({});
5493
5483
  }
5494
5484
  return ret;
@@ -5496,7 +5486,7 @@ var AST = class _AST {
5496
5486
  isStart() {
5497
5487
  if (this.#root === this)
5498
5488
  return true;
5499
- if (!_optionalChain([this, 'access', _257 => _257.#parent, 'optionalAccess', _258 => _258.isStart, 'call', _259 => _259()]))
5489
+ if (!_optionalChain([this, 'access', _265 => _265.#parent, 'optionalAccess', _266 => _266.isStart, 'call', _267 => _267()]))
5500
5490
  return false;
5501
5491
  if (this.#parentIndex === 0)
5502
5492
  return true;
@@ -5512,12 +5502,12 @@ var AST = class _AST {
5512
5502
  isEnd() {
5513
5503
  if (this.#root === this)
5514
5504
  return true;
5515
- if (_optionalChain([this, 'access', _260 => _260.#parent, 'optionalAccess', _261 => _261.type]) === "!")
5505
+ if (_optionalChain([this, 'access', _268 => _268.#parent, 'optionalAccess', _269 => _269.type]) === "!")
5516
5506
  return true;
5517
- if (!_optionalChain([this, 'access', _262 => _262.#parent, 'optionalAccess', _263 => _263.isEnd, 'call', _264 => _264()]))
5507
+ if (!_optionalChain([this, 'access', _270 => _270.#parent, 'optionalAccess', _271 => _271.isEnd, 'call', _272 => _272()]))
5518
5508
  return false;
5519
5509
  if (!this.type)
5520
- return _optionalChain([this, 'access', _265 => _265.#parent, 'optionalAccess', _266 => _266.isEnd, 'call', _267 => _267()]);
5510
+ return _optionalChain([this, 'access', _273 => _273.#parent, 'optionalAccess', _274 => _274.isEnd, 'call', _275 => _275()]);
5521
5511
  const pl = this.#parent ? this.#parent.#parts.length : 0;
5522
5512
  return this.#parentIndex === pl - 1;
5523
5513
  }
@@ -5762,7 +5752,7 @@ var AST = class _AST {
5762
5752
  }
5763
5753
  }
5764
5754
  let end = "";
5765
- if (this.isEnd() && this.#root.#filledNegs && _optionalChain([this, 'access', _268 => _268.#parent, 'optionalAccess', _269 => _269.type]) === "!") {
5755
+ if (this.isEnd() && this.#root.#filledNegs && _optionalChain([this, 'access', _276 => _276.#parent, 'optionalAccess', _277 => _277.type]) === "!") {
5766
5756
  end = "(?:$|\\/)";
5767
5757
  }
5768
5758
  const final2 = start2 + src + end;
@@ -6637,22 +6627,35 @@ function _getAllKeys(obj, prefix = "") {
6637
6627
 
6638
6628
  // src/cli/loaders/locked-keys.ts
6639
6629
 
6630
+
6631
+ // src/cli/utils/key-matching.ts
6632
+ function matchesKeyPattern(key, patterns) {
6633
+ return patterns.some(
6634
+ (pattern) => key.startsWith(pattern) || minimatch(key, pattern)
6635
+ );
6636
+ }
6637
+ function formatDisplayValue(value, maxLength = 50) {
6638
+ if (typeof value === "string") {
6639
+ return value.length > maxLength ? `${value.substring(0, maxLength)}...` : value;
6640
+ }
6641
+ return JSON.stringify(value);
6642
+ }
6643
+
6644
+ // src/cli/loaders/locked-keys.ts
6640
6645
  function createLockedKeysLoader(lockedKeys) {
6641
6646
  return createLoader({
6642
6647
  pull: async (locale, data) => {
6643
- return _lodash2.default.pickBy(data, (value, key) => !_isLockedKey(key, lockedKeys));
6648
+ return _lodash2.default.pickBy(
6649
+ data,
6650
+ (value, key) => !matchesKeyPattern(key, lockedKeys)
6651
+ );
6644
6652
  },
6645
6653
  push: async (locale, data, originalInput) => {
6646
- const lockedSubObject = _lodash2.default.chain(originalInput).pickBy((value, key) => _isLockedKey(key, lockedKeys)).value();
6654
+ const lockedSubObject = _lodash2.default.chain(originalInput).pickBy((value, key) => matchesKeyPattern(key, lockedKeys)).value();
6647
6655
  return _lodash2.default.merge({}, data, lockedSubObject);
6648
6656
  }
6649
6657
  });
6650
6658
  }
6651
- function _isLockedKey(key, lockedKeys) {
6652
- return lockedKeys.some(
6653
- (lockedKey) => key.startsWith(lockedKey) || minimatch(key, lockedKey)
6654
- );
6655
- }
6656
6659
 
6657
6660
  // src/cli/loaders/mdx2/frontmatter-split.ts
6658
6661
 
@@ -6839,7 +6842,7 @@ function createMdxSectionsSplit2Loader() {
6839
6842
  const content = _lodash2.default.chain(data.sections).values().join("\n\n").value();
6840
6843
  const result = {
6841
6844
  frontmatter: data.frontmatter,
6842
- codePlaceholders: _optionalChain([pullInput, 'optionalAccess', _270 => _270.codePlaceholders]) || {},
6845
+ codePlaceholders: _optionalChain([pullInput, 'optionalAccess', _278 => _278.codePlaceholders]) || {},
6843
6846
  content
6844
6847
  };
6845
6848
  return result;
@@ -6908,25 +6911,20 @@ function createIgnoredKeysLoader(ignoredKeys) {
6908
6911
  pull: async (locale, data) => {
6909
6912
  const result = _lodash2.default.omitBy(
6910
6913
  data,
6911
- (value, key) => _isIgnoredKey(key, ignoredKeys)
6914
+ (value, key) => matchesKeyPattern(key, ignoredKeys)
6912
6915
  );
6913
6916
  return result;
6914
6917
  },
6915
6918
  push: async (locale, data, originalInput, originalLocale, pullInput) => {
6916
6919
  const ignoredSubObject = _lodash2.default.pickBy(
6917
6920
  pullInput,
6918
- (value, key) => _isIgnoredKey(key, ignoredKeys)
6921
+ (value, key) => matchesKeyPattern(key, ignoredKeys)
6919
6922
  );
6920
6923
  const result = _lodash2.default.merge({}, data, ignoredSubObject);
6921
6924
  return result;
6922
6925
  }
6923
6926
  });
6924
6927
  }
6925
- function _isIgnoredKey(key, ignoredKeys) {
6926
- return ignoredKeys.some(
6927
- (ignoredKey) => key.startsWith(ignoredKey) || minimatch(key, ignoredKey)
6928
- );
6929
- }
6930
6928
 
6931
6929
  // src/cli/loaders/ejs.ts
6932
6930
  function parseEjsForTranslation(input2) {
@@ -7286,6 +7284,15 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7286
7284
  createSyncLoader(),
7287
7285
  createUnlocalizableLoader(options.returnUnlocalizedKeys)
7288
7286
  );
7287
+ case "markdoc":
7288
+ return composeLoaders(
7289
+ createTextFileLoader(bucketPathPattern),
7290
+ createMarkdocLoader(),
7291
+ createFlatLoader(),
7292
+ createEnsureKeyOrderLoader(),
7293
+ createSyncLoader(),
7294
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
7295
+ );
7289
7296
  case "mdx":
7290
7297
  return composeLoaders(
7291
7298
  createTextFileLoader(bucketPathPattern),
@@ -7477,8 +7484,277 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
7477
7484
  }
7478
7485
  }
7479
7486
 
7487
+ // src/cli/cmd/show/_shared-key-command.ts
7488
+ async function executeKeyCommand(i18nConfig, buckets, options, config) {
7489
+ let hasAnyKeys = false;
7490
+ for (const bucket of buckets) {
7491
+ if (options.bucket && bucket.type !== options.bucket) {
7492
+ continue;
7493
+ }
7494
+ const keyPatterns = bucket[config.filterType];
7495
+ if (!keyPatterns || keyPatterns.length === 0) {
7496
+ continue;
7497
+ }
7498
+ hasAnyKeys = true;
7499
+ console.log(`
7500
+ Bucket: ${bucket.type}`);
7501
+ console.log(
7502
+ `${capitalize(config.displayName)} key patterns: ${keyPatterns.join(", ")}`
7503
+ );
7504
+ for (const bucketConfig of bucket.paths) {
7505
+ const sourceLocale = __spec.resolveOverriddenLocale.call(void 0,
7506
+ i18nConfig.locale.source,
7507
+ bucketConfig.delimiter
7508
+ );
7509
+ const sourcePath = bucketConfig.pathPattern.replace(
7510
+ /\[locale\]/g,
7511
+ sourceLocale
7512
+ );
7513
+ try {
7514
+ const loader = createBucketLoader(
7515
+ bucket.type,
7516
+ bucketConfig.pathPattern,
7517
+ {
7518
+ defaultLocale: sourceLocale,
7519
+ injectLocale: bucket.injectLocale
7520
+ },
7521
+ [],
7522
+ // Don't apply any filtering when reading
7523
+ [],
7524
+ []
7525
+ );
7526
+ loader.setDefaultLocale(sourceLocale);
7527
+ const data = await loader.pull(sourceLocale);
7528
+ if (!data || Object.keys(data).length === 0) {
7529
+ continue;
7530
+ }
7531
+ const matchedEntries = Object.entries(data).filter(
7532
+ ([key]) => matchesKeyPattern(key, keyPatterns)
7533
+ );
7534
+ if (matchedEntries.length > 0) {
7535
+ console.log(`
7536
+ Matches in ${sourcePath}:`);
7537
+ for (const [key, value] of matchedEntries) {
7538
+ const displayValue = formatDisplayValue(value);
7539
+ console.log(` - ${key}: ${displayValue}`);
7540
+ }
7541
+ console.log(
7542
+ `Total: ${matchedEntries.length} ${config.displayName} key(s)`
7543
+ );
7544
+ }
7545
+ } catch (error) {
7546
+ console.error(` Error reading ${sourcePath}: ${error.message}`);
7547
+ }
7548
+ }
7549
+ }
7550
+ if (!hasAnyKeys) {
7551
+ if (options.bucket) {
7552
+ console.log(
7553
+ `No ${config.displayName} keys configured for bucket: ${options.bucket}`
7554
+ );
7555
+ } else {
7556
+ console.log(`No ${config.displayName} keys configured in any bucket.`);
7557
+ }
7558
+ }
7559
+ }
7560
+ function capitalize(str) {
7561
+ return str.charAt(0).toUpperCase() + str.slice(1);
7562
+ }
7563
+
7564
+ // src/cli/cmd/show/locked-keys.ts
7565
+ var locked_keys_default = new (0, _interactivecommander.Command)().command("locked-keys").description(
7566
+ "Show which key-value pairs in source files match lockedKeys patterns"
7567
+ ).option("--bucket <name>", "Only show locked keys for a specific bucket").helpOption("-h, --help", "Show help").action(async (options) => {
7568
+ const ora = _ora2.default.call(void 0, );
7569
+ try {
7570
+ const i18nConfig = await getConfig();
7571
+ if (!i18nConfig) {
7572
+ throw new CLIError({
7573
+ message: "i18n.json not found. Please run `lingo.dev init` to initialize the project.",
7574
+ docUrl: "i18nNotFound"
7575
+ });
7576
+ }
7577
+ const buckets = getBuckets(i18nConfig);
7578
+ await executeKeyCommand(i18nConfig, buckets, options, {
7579
+ filterType: "lockedKeys",
7580
+ displayName: "locked"
7581
+ });
7582
+ } catch (error) {
7583
+ ora.fail(error.message);
7584
+ process.exit(1);
7585
+ }
7586
+ });
7587
+
7588
+ // src/cli/cmd/show/ignored-keys.ts
7589
+
7590
+
7591
+ var ignored_keys_default = new (0, _interactivecommander.Command)().command("ignored-keys").description(
7592
+ "Show which key-value pairs in source files match ignoredKeys patterns"
7593
+ ).option("--bucket <name>", "Only show ignored keys for a specific bucket").helpOption("-h, --help", "Show help").action(async (options) => {
7594
+ const ora = _ora2.default.call(void 0, );
7595
+ try {
7596
+ const i18nConfig = await getConfig();
7597
+ if (!i18nConfig) {
7598
+ throw new CLIError({
7599
+ message: "i18n.json not found. Please run `lingo.dev init` to initialize the project.",
7600
+ docUrl: "i18nNotFound"
7601
+ });
7602
+ }
7603
+ const buckets = getBuckets(i18nConfig);
7604
+ await executeKeyCommand(i18nConfig, buckets, options, {
7605
+ filterType: "ignoredKeys",
7606
+ displayName: "ignored"
7607
+ });
7608
+ } catch (error) {
7609
+ ora.fail(error.message);
7610
+ process.exit(1);
7611
+ }
7612
+ });
7613
+
7614
+ // src/cli/cmd/show/index.ts
7615
+ var show_default = new (0, _interactivecommander.Command)().command("show").description("Display configuration, locales, and file paths").helpOption("-h, --help", "Show help").addCommand(config_default).addCommand(locale_default).addCommand(files_default).addCommand(locked_keys_default).addCommand(ignored_keys_default);
7616
+
7617
+ // src/cli/cmd/config/index.ts
7618
+
7619
+
7620
+ // src/cli/cmd/config/set.ts
7621
+
7622
+
7623
+ var _dedent = require('dedent'); var _dedent2 = _interopRequireDefault(_dedent);
7624
+
7625
+ var set_default = new (0, _interactivecommander.Command)().name("set").description("Set or update a CLI setting in ~/.lingodotdevrc").addHelpText("afterAll", `
7626
+ Available keys:
7627
+ ${SETTINGS_KEYS.join("\n ")}`).argument(
7628
+ "<key>",
7629
+ "Configuration key to set (dot notation, e.g., auth.apiKey)"
7630
+ ).argument("<value>", "The configuration value to set").helpOption("-h, --help", "Show help").action(async (key, value) => {
7631
+ if (!SETTINGS_KEYS.includes(key)) {
7632
+ console.error(
7633
+ _dedent2.default`
7634
+ ${_chalk2.default.red("\u2716")} Unknown configuration key: ${_chalk2.default.bold(key)}
7635
+ Run ${_chalk2.default.dim("lingo.dev config set --help")} to see available keys.
7636
+ `
7637
+ );
7638
+ process.exitCode = 1;
7639
+ return;
7640
+ }
7641
+ const current = loadSystemSettings();
7642
+ const updated = _lodash2.default.cloneDeep(current);
7643
+ _lodash2.default.set(updated, key, value);
7644
+ try {
7645
+ saveSettings(updated);
7646
+ console.log(`${_chalk2.default.green("\u2714")} Set ${_chalk2.default.bold(key)}`);
7647
+ } catch (err) {
7648
+ console.error(
7649
+ _chalk2.default.red(
7650
+ `\u2716 Failed to save configuration: ${_chalk2.default.dim(
7651
+ err instanceof Error ? err.message : String(err)
7652
+ )}`
7653
+ )
7654
+ );
7655
+ process.exitCode = 1;
7656
+ }
7657
+ });
7658
+
7659
+ // src/cli/cmd/config/unset.ts
7660
+
7661
+
7662
+
7663
+
7664
+ var unset_default = new (0, _interactivecommander.Command)().name("unset").description("Remove a CLI setting from ~/.lingodotdevrc").addHelpText("afterAll", `
7665
+ Available keys:
7666
+ ${SETTINGS_KEYS.join("\n ")}`).argument(
7667
+ "<key>",
7668
+ "Configuration key to remove (must match one of the available keys listed below)"
7669
+ ).helpOption("-h, --help", "Show help").action(async (key) => {
7670
+ if (!SETTINGS_KEYS.includes(key)) {
7671
+ console.error(
7672
+ _dedent2.default`
7673
+ ${_chalk2.default.red("\u2716")} Unknown configuration key: ${_chalk2.default.bold(key)}
7674
+ Run ${_chalk2.default.dim(
7675
+ "lingo.dev config unset --help"
7676
+ )} to see available keys.
7677
+ `
7678
+ );
7679
+ process.exitCode = 1;
7680
+ return;
7681
+ }
7682
+ const settings = loadSystemSettings();
7683
+ const currentValue = _lodash2.default.get(settings, key);
7684
+ if (!_lodash2.default.trim(String(currentValue || ""))) {
7685
+ console.log(`${_chalk2.default.cyan("\u2139")} ${_chalk2.default.bold(key)} is not set.`);
7686
+ return;
7687
+ } else {
7688
+ const updated = _lodash2.default.cloneDeep(settings);
7689
+ _lodash2.default.unset(updated, key);
7690
+ try {
7691
+ saveSettings(updated);
7692
+ console.log(
7693
+ `${_chalk2.default.green("\u2714")} Removed configuration key ${_chalk2.default.bold(key)}`
7694
+ );
7695
+ } catch (err) {
7696
+ console.error(
7697
+ _chalk2.default.red(
7698
+ `\u2716 Failed to save configuration: ${_chalk2.default.dim(
7699
+ err instanceof Error ? err.message : String(err)
7700
+ )}`
7701
+ )
7702
+ );
7703
+ process.exitCode = 1;
7704
+ }
7705
+ }
7706
+ });
7707
+
7708
+ // src/cli/cmd/config/get.ts
7709
+
7710
+
7711
+
7712
+
7713
+ var get_default = new (0, _interactivecommander.Command)().name("get").description("Display the value of a CLI setting from ~/.lingodotdevrc").addHelpText("afterAll", `
7714
+ Available keys:
7715
+ ${SETTINGS_KEYS.join("\n ")}`).argument(
7716
+ "<key>",
7717
+ "Configuration key to read (choose from the available keys listed below)"
7718
+ ).helpOption("-h, --help", "Show help").action(async (key) => {
7719
+ if (!SETTINGS_KEYS.includes(key)) {
7720
+ console.error(
7721
+ _dedent2.default`
7722
+ ${_chalk2.default.red("\u2716")} Unknown configuration key: ${_chalk2.default.bold(key)}
7723
+ Run ${_chalk2.default.dim("lingo.dev config get --help")} to see available keys.
7724
+ `
7725
+ );
7726
+ process.exitCode = 1;
7727
+ return;
7728
+ }
7729
+ const settings = loadSystemSettings();
7730
+ const value = _lodash2.default.get(settings, key);
7731
+ if (!value) {
7732
+ console.log(`${_chalk2.default.cyan("\u2139")} ${_chalk2.default.bold(key)} is not set.`);
7733
+ return;
7734
+ }
7735
+ if (typeof value === "object") {
7736
+ console.log(JSON.stringify(value, null, 2));
7737
+ } else {
7738
+ console.log(value);
7739
+ }
7740
+ });
7741
+
7742
+ // src/cli/cmd/config/index.ts
7743
+ var config_default2 = new (0, _interactivecommander.Command)().command("config").description(
7744
+ "Manage CLI settings (authentication, API keys) stored in ~/.lingodotdevrc"
7745
+ ).helpOption("-h, --help", "Show help").addCommand(set_default).addCommand(unset_default).addCommand(get_default);
7746
+
7480
7747
  // src/cli/cmd/i18n.ts
7481
7748
 
7749
+
7750
+
7751
+
7752
+
7753
+
7754
+
7755
+
7756
+
7757
+
7482
7758
  var _diff = require('diff');
7483
7759
 
7484
7760
  var _externaleditor = require('external-editor'); var _externaleditor2 = _interopRequireDefault(_externaleditor);
@@ -7517,7 +7793,7 @@ function createLingoLocalizer(params) {
7517
7793
  // src/cli/processor/basic.ts
7518
7794
  var _ai = require('ai');
7519
7795
 
7520
- function createBasicTranslator(model, systemPrompt) {
7796
+ function createBasicTranslator(model, systemPrompt, settings = {}) {
7521
7797
  return async (input2, onProgress) => {
7522
7798
  const chunks = extractPayloadChunks(input2.processableData);
7523
7799
  const subResults = [];
@@ -7539,6 +7815,7 @@ function createBasicTranslator(model, systemPrompt) {
7539
7815
  }
7540
7816
  const response = await _ai.generateText.call(void 0, {
7541
7817
  model,
7818
+ ...settings,
7542
7819
  messages: [
7543
7820
  {
7544
7821
  role: "system",
@@ -7578,7 +7855,7 @@ function createBasicTranslator(model, systemPrompt) {
7578
7855
  ]
7579
7856
  });
7580
7857
  const result = JSON.parse(response.text);
7581
- return _optionalChain([result, 'optionalAccess', _271 => _271.data]) || {};
7858
+ return _optionalChain([result, 'optionalAccess', _279 => _279.data]) || {};
7582
7859
  }
7583
7860
  }
7584
7861
  function extractPayloadChunks(payload) {
@@ -7629,7 +7906,8 @@ function createProcessor(provider, params) {
7629
7906
  return result;
7630
7907
  } else {
7631
7908
  const model = getPureModelProvider(provider);
7632
- const result = createBasicTranslator(model, provider.prompt);
7909
+ const settings = provider.settings || {};
7910
+ const result = createBasicTranslator(model, provider.prompt, settings);
7633
7911
  return result;
7634
7912
  }
7635
7913
  }
@@ -7660,7 +7938,7 @@ function getPureModelProvider(provider) {
7660
7938
 
7661
7939
  ${_chalk2.default.hex(colors.blue)("Docs: https://lingo.dev/go/docs")}
7662
7940
  `;
7663
- switch (_optionalChain([provider, 'optionalAccess', _272 => _272.id])) {
7941
+ switch (_optionalChain([provider, 'optionalAccess', _280 => _280.id])) {
7664
7942
  case "openai": {
7665
7943
  if (!process.env.OPENAI_API_KEY) {
7666
7944
  throw new Error(
@@ -7718,7 +7996,7 @@ function getPureModelProvider(provider) {
7718
7996
  })(provider.model);
7719
7997
  }
7720
7998
  default: {
7721
- throw new Error(createUnsupportedProviderErrorMessage(_optionalChain([provider, 'optionalAccess', _273 => _273.id])));
7999
+ throw new Error(createUnsupportedProviderErrorMessage(_optionalChain([provider, 'optionalAccess', _281 => _281.id])));
7722
8000
  }
7723
8001
  }
7724
8002
  }
@@ -8003,7 +8281,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
8003
8281
  validateParams(i18nConfig, flags);
8004
8282
  ora.succeed("Localization configuration is valid");
8005
8283
  ora.start("Connecting to Lingo.dev Localization Engine...");
8006
- const isByokMode = !!_optionalChain([i18nConfig, 'optionalAccess', _274 => _274.provider]);
8284
+ const isByokMode = !!_optionalChain([i18nConfig, 'optionalAccess', _282 => _282.provider]);
8007
8285
  if (isByokMode) {
8008
8286
  authId = null;
8009
8287
  ora.succeed("Using external provider (BYOK mode)");
@@ -8017,16 +8295,16 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
8017
8295
  flags
8018
8296
  });
8019
8297
  let buckets = getBuckets(i18nConfig);
8020
- if (_optionalChain([flags, 'access', _275 => _275.bucket, 'optionalAccess', _276 => _276.length])) {
8298
+ if (_optionalChain([flags, 'access', _283 => _283.bucket, 'optionalAccess', _284 => _284.length])) {
8021
8299
  buckets = buckets.filter(
8022
8300
  (bucket) => flags.bucket.includes(bucket.type)
8023
8301
  );
8024
8302
  }
8025
8303
  ora.succeed("Buckets retrieved");
8026
- if (_optionalChain([flags, 'access', _277 => _277.file, 'optionalAccess', _278 => _278.length])) {
8304
+ if (_optionalChain([flags, 'access', _285 => _285.file, 'optionalAccess', _286 => _286.length])) {
8027
8305
  buckets = buckets.map((bucket) => {
8028
8306
  const paths = bucket.paths.filter(
8029
- (path19) => flags.file.find((file) => _optionalChain([path19, 'access', _279 => _279.pathPattern, 'optionalAccess', _280 => _280.includes, 'call', _281 => _281(file)]))
8307
+ (path19) => flags.file.find((file) => _optionalChain([path19, 'access', _287 => _287.pathPattern, 'optionalAccess', _288 => _288.includes, 'call', _289 => _289(file)]))
8030
8308
  );
8031
8309
  return { ...bucket, paths };
8032
8310
  }).filter((bucket) => bucket.paths.length > 0);
@@ -8047,7 +8325,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
8047
8325
  });
8048
8326
  }
8049
8327
  }
8050
- const targetLocales = _optionalChain([flags, 'access', _282 => _282.locale, 'optionalAccess', _283 => _283.length]) ? flags.locale : i18nConfig.locale.targets;
8328
+ const targetLocales = _optionalChain([flags, 'access', _290 => _290.locale, 'optionalAccess', _291 => _291.length]) ? flags.locale : i18nConfig.locale.targets;
8051
8329
  ora.start("Setting up localization cache...");
8052
8330
  const checkLockfileProcessor = createDeltaProcessor("");
8053
8331
  const lockfileExists = await checkLockfileProcessor.checkIfLockExists();
@@ -8324,7 +8602,7 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
8324
8602
  }
8325
8603
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
8326
8604
  const checksums = await deltaProcessor.createChecksums(sourceData);
8327
- if (!_optionalChain([flags, 'access', _284 => _284.locale, 'optionalAccess', _285 => _285.length])) {
8605
+ if (!_optionalChain([flags, 'access', _292 => _292.locale, 'optionalAccess', _293 => _293.length])) {
8328
8606
  await deltaProcessor.saveChecksums(checksums);
8329
8607
  }
8330
8608
  }
@@ -8448,12 +8726,12 @@ function validateParams(i18nConfig, flags) {
8448
8726
  message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
8449
8727
  docUrl: "bucketNotFound"
8450
8728
  });
8451
- } else if (_optionalChain([flags, 'access', _286 => _286.locale, 'optionalAccess', _287 => _287.some, 'call', _288 => _288((locale) => !i18nConfig.locale.targets.includes(locale))])) {
8729
+ } else if (_optionalChain([flags, 'access', _294 => _294.locale, 'optionalAccess', _295 => _295.some, 'call', _296 => _296((locale) => !i18nConfig.locale.targets.includes(locale))])) {
8452
8730
  throw new ValidationError({
8453
8731
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
8454
8732
  docUrl: "localeTargetNotFound"
8455
8733
  });
8456
- } else if (_optionalChain([flags, 'access', _289 => _289.bucket, 'optionalAccess', _290 => _290.some, 'call', _291 => _291(
8734
+ } else if (_optionalChain([flags, 'access', _297 => _297.bucket, 'optionalAccess', _298 => _298.some, 'call', _299 => _299(
8457
8735
  (bucket) => !i18nConfig.buckets[bucket]
8458
8736
  )])) {
8459
8737
  throw new ValidationError({
@@ -8979,10 +9257,11 @@ function createLingoDotDevLocalizer(explicitApiKey) {
8979
9257
  const response = await engine.whoami();
8980
9258
  return {
8981
9259
  authenticated: !!response,
8982
- username: _optionalChain([response, 'optionalAccess', _292 => _292.email])
9260
+ username: _optionalChain([response, 'optionalAccess', _300 => _300.email])
8983
9261
  };
8984
- } catch (e3) {
8985
- return { authenticated: false };
9262
+ } catch (error) {
9263
+ const errorMessage = error instanceof Error ? error.message : String(error);
9264
+ return { authenticated: false, error: errorMessage };
8986
9265
  }
8987
9266
  },
8988
9267
  localize: async (input2, onProgress) => {
@@ -9019,6 +9298,7 @@ function createLingoDotDevLocalizer(explicitApiKey) {
9019
9298
 
9020
9299
 
9021
9300
  function createExplicitLocalizer(provider) {
9301
+ const settings = provider.settings || {};
9022
9302
  switch (provider.id) {
9023
9303
  default:
9024
9304
  throw new Error(
@@ -9042,7 +9322,8 @@ function createExplicitLocalizer(provider) {
9042
9322
  id: provider.id,
9043
9323
  prompt: provider.prompt,
9044
9324
  apiKeyName: "OPENAI_API_KEY",
9045
- baseUrl: provider.baseUrl
9325
+ baseUrl: provider.baseUrl,
9326
+ settings
9046
9327
  });
9047
9328
  case "anthropic":
9048
9329
  return createAiSdkLocalizer({
@@ -9050,7 +9331,8 @@ function createExplicitLocalizer(provider) {
9050
9331
  id: provider.id,
9051
9332
  prompt: provider.prompt,
9052
9333
  apiKeyName: "ANTHROPIC_API_KEY",
9053
- baseUrl: provider.baseUrl
9334
+ baseUrl: provider.baseUrl,
9335
+ settings
9054
9336
  });
9055
9337
  case "google":
9056
9338
  return createAiSdkLocalizer({
@@ -9058,7 +9340,8 @@ function createExplicitLocalizer(provider) {
9058
9340
  id: provider.id,
9059
9341
  prompt: provider.prompt,
9060
9342
  apiKeyName: "GOOGLE_API_KEY",
9061
- baseUrl: provider.baseUrl
9343
+ baseUrl: provider.baseUrl,
9344
+ settings
9062
9345
  });
9063
9346
  case "openrouter":
9064
9347
  return createAiSdkLocalizer({
@@ -9066,14 +9349,16 @@ function createExplicitLocalizer(provider) {
9066
9349
  id: provider.id,
9067
9350
  prompt: provider.prompt,
9068
9351
  apiKeyName: "OPENROUTER_API_KEY",
9069
- baseUrl: provider.baseUrl
9352
+ baseUrl: provider.baseUrl,
9353
+ settings
9070
9354
  });
9071
9355
  case "ollama":
9072
9356
  return createAiSdkLocalizer({
9073
9357
  factory: (_params) => _ollamaaiprovider.createOllama.call(void 0, ).languageModel(provider.model),
9074
9358
  id: provider.id,
9075
9359
  prompt: provider.prompt,
9076
- skipAuth: true
9360
+ skipAuth: true,
9361
+ settings
9077
9362
  });
9078
9363
  case "mistral":
9079
9364
  return createAiSdkLocalizer({
@@ -9081,13 +9366,14 @@ function createExplicitLocalizer(provider) {
9081
9366
  id: provider.id,
9082
9367
  prompt: provider.prompt,
9083
9368
  apiKeyName: "MISTRAL_API_KEY",
9084
- baseUrl: provider.baseUrl
9369
+ baseUrl: provider.baseUrl,
9370
+ settings
9085
9371
  });
9086
9372
  }
9087
9373
  }
9088
9374
  function createAiSdkLocalizer(params) {
9089
9375
  const skipAuth = params.skipAuth === true;
9090
- const apiKey = process.env[_nullishCoalesce(_optionalChain([params, 'optionalAccess', _293 => _293.apiKeyName]), () => ( ""))];
9376
+ const apiKey = process.env[_nullishCoalesce(_optionalChain([params, 'optionalAccess', _301 => _301.apiKeyName]), () => ( ""))];
9091
9377
  if (!skipAuth && !apiKey || !params.apiKeyName) {
9092
9378
  throw new Error(
9093
9379
  _dedent2.default`
@@ -9115,9 +9401,13 @@ function createAiSdkLocalizer(params) {
9115
9401
  return {
9116
9402
  id: params.id,
9117
9403
  checkAuth: async () => {
9404
+ return { authenticated: true, username: "anonymous" };
9405
+ },
9406
+ validateSettings: async () => {
9118
9407
  try {
9119
9408
  await _ai.generateText.call(void 0, {
9120
9409
  model,
9410
+ ...params.settings,
9121
9411
  messages: [
9122
9412
  { role: "system", content: "You are an echo server" },
9123
9413
  { role: "user", content: "OK" },
@@ -9125,9 +9415,10 @@ function createAiSdkLocalizer(params) {
9125
9415
  { role: "user", content: "OK" }
9126
9416
  ]
9127
9417
  });
9128
- return { authenticated: true, username: "anonymous" };
9418
+ return { valid: true };
9129
9419
  } catch (error) {
9130
- return { authenticated: false };
9420
+ const errorMessage = error instanceof Error ? error.message : String(error);
9421
+ return { valid: false, error: errorMessage };
9131
9422
  }
9132
9423
  },
9133
9424
  localize: async (input2) => {
@@ -9157,6 +9448,7 @@ function createAiSdkLocalizer(params) {
9157
9448
  };
9158
9449
  const response = await _ai.generateText.call(void 0, {
9159
9450
  model,
9451
+ ...params.settings,
9160
9452
  messages: [
9161
9453
  { role: "system", content: systemPrompt },
9162
9454
  { role: "user", content: "OK" },
@@ -9170,6 +9462,9 @@ function createAiSdkLocalizer(params) {
9170
9462
  ]
9171
9463
  });
9172
9464
  const result = JSON.parse(response.text);
9465
+ if (typeof result.data === "object" && result.data !== null) {
9466
+ return result.data;
9467
+ }
9173
9468
  const index = result.data.indexOf("{");
9174
9469
  const lastIndex = result.data.lastIndexOf("}");
9175
9470
  const trimmed = result.data.slice(index, lastIndex + 1);
@@ -9212,8 +9507,8 @@ async function setup(input2) {
9212
9507
  throw new Error(
9213
9508
  "No buckets found in i18n.json. Please add at least one bucket containing i18n content."
9214
9509
  );
9215
- } else if (_optionalChain([ctx, 'access', _294 => _294.flags, 'access', _295 => _295.bucket, 'optionalAccess', _296 => _296.some, 'call', _297 => _297(
9216
- (bucket) => !_optionalChain([ctx, 'access', _298 => _298.config, 'optionalAccess', _299 => _299.buckets, 'access', _300 => _300[bucket]])
9510
+ } else if (_optionalChain([ctx, 'access', _302 => _302.flags, 'access', _303 => _303.bucket, 'optionalAccess', _304 => _304.some, 'call', _305 => _305(
9511
+ (bucket) => !_optionalChain([ctx, 'access', _306 => _306.config, 'optionalAccess', _307 => _307.buckets, 'access', _308 => _308[bucket]])
9217
9512
  )])) {
9218
9513
  throw new Error(
9219
9514
  `One or more specified buckets do not exist in i18n.json. Please add them to the list first and try again.`
@@ -9226,7 +9521,7 @@ async function setup(input2) {
9226
9521
  title: "Selecting localization provider",
9227
9522
  task: async (ctx, task) => {
9228
9523
  ctx.localizer = createLocalizer(
9229
- _optionalChain([ctx, 'access', _301 => _301.config, 'optionalAccess', _302 => _302.provider]),
9524
+ _optionalChain([ctx, 'access', _309 => _309.config, 'optionalAccess', _310 => _310.provider]),
9230
9525
  ctx.flags.apiKey
9231
9526
  );
9232
9527
  if (!ctx.localizer) {
@@ -9239,20 +9534,30 @@ async function setup(input2) {
9239
9534
  },
9240
9535
  {
9241
9536
  title: "Checking authentication",
9537
+ enabled: (ctx) => _optionalChain([ctx, 'access', _311 => _311.localizer, 'optionalAccess', _312 => _312.id]) === "Lingo.dev",
9242
9538
  task: async (ctx, task) => {
9243
9539
  const authStatus = await ctx.localizer.checkAuth();
9244
9540
  if (!authStatus.authenticated) {
9245
- throw new Error(
9246
- `Failed to authenticate with ${_chalk2.default.hex(colors.yellow)(
9247
- ctx.localizer.id
9248
- )} provider. Please check your API key and try again.`
9249
- );
9541
+ throw new Error(authStatus.error || "Authentication failed");
9250
9542
  }
9251
9543
  task.title = `Authenticated as ${_chalk2.default.hex(colors.yellow)(
9252
9544
  authStatus.username
9253
9545
  )}`;
9254
9546
  }
9255
9547
  },
9548
+ {
9549
+ title: "Validating configuration",
9550
+ enabled: (ctx) => _optionalChain([ctx, 'access', _313 => _313.localizer, 'optionalAccess', _314 => _314.id]) !== "Lingo.dev",
9551
+ task: async (ctx, task) => {
9552
+ const validationStatus = await ctx.localizer.validateSettings();
9553
+ if (!validationStatus.valid) {
9554
+ throw new Error(
9555
+ validationStatus.error || "Configuration validation failed"
9556
+ );
9557
+ }
9558
+ task.title = `Configuration validated`;
9559
+ }
9560
+ },
9256
9561
  {
9257
9562
  title: "Initializing localization provider",
9258
9563
  async task(ctx, task) {
@@ -9557,7 +9862,7 @@ function createWorkerTask(args) {
9557
9862
  const processableData = _lodash2.default.chain(sourceData).entries().filter(
9558
9863
  ([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!args.ctx.flags.force
9559
9864
  ).filter(
9560
- ([key]) => !assignedTask.onlyKeys.length || _optionalChain([assignedTask, 'access', _303 => _303.onlyKeys, 'optionalAccess', _304 => _304.some, 'call', _305 => _305(
9865
+ ([key]) => !assignedTask.onlyKeys.length || _optionalChain([assignedTask, 'access', _315 => _315.onlyKeys, 'optionalAccess', _316 => _316.some, 'call', _317 => _317(
9561
9866
  (pattern) => minimatch(key, pattern)
9562
9867
  )])
9563
9868
  ).fromPairs().value();
@@ -9625,7 +9930,7 @@ function createWorkerTask(args) {
9625
9930
  finalRenamedTargetData
9626
9931
  );
9627
9932
  const checksums = await deltaProcessor.createChecksums(sourceData);
9628
- if (!_optionalChain([args, 'access', _306 => _306.ctx, 'access', _307 => _307.flags, 'access', _308 => _308.targetLocale, 'optionalAccess', _309 => _309.length])) {
9933
+ if (!_optionalChain([args, 'access', _318 => _318.ctx, 'access', _319 => _319.flags, 'access', _320 => _320.targetLocale, 'optionalAccess', _321 => _321.length])) {
9629
9934
  await deltaProcessor.saveChecksums(checksums);
9630
9935
  }
9631
9936
  });
@@ -9824,14 +10129,14 @@ var flagsSchema2 = _zod.z.object({
9824
10129
 
9825
10130
  // src/cli/cmd/run/_utils.ts
9826
10131
  async function determineAuthId(ctx) {
9827
- const isByokMode = !!_optionalChain([ctx, 'access', _310 => _310.config, 'optionalAccess', _311 => _311.provider]);
10132
+ const isByokMode = !!_optionalChain([ctx, 'access', _322 => _322.config, 'optionalAccess', _323 => _323.provider]);
9828
10133
  if (isByokMode) {
9829
10134
  return null;
9830
10135
  } else {
9831
10136
  try {
9832
- const authStatus = await _optionalChain([ctx, 'access', _312 => _312.localizer, 'optionalAccess', _313 => _313.checkAuth, 'call', _314 => _314()]);
9833
- return _optionalChain([authStatus, 'optionalAccess', _315 => _315.username]) || null;
9834
- } catch (e4) {
10137
+ const authStatus = await _optionalChain([ctx, 'access', _324 => _324.localizer, 'optionalAccess', _325 => _325.checkAuth, 'call', _326 => _326()]);
10138
+ return _optionalChain([authStatus, 'optionalAccess', _327 => _327.username]) || null;
10139
+ } catch (e3) {
9835
10140
  return null;
9836
10141
  }
9837
10142
  }
@@ -10022,7 +10327,7 @@ var InBranchFlow = class extends IntegrationFlow {
10022
10327
  _child_process.execSync.call(void 0, `git config --global safe.directory ${process.cwd()}`);
10023
10328
  _child_process.execSync.call(void 0, `git config user.name "${gitConfig.userName}"`);
10024
10329
  _child_process.execSync.call(void 0, `git config user.email "${gitConfig.userEmail}"`);
10025
- _optionalChain([this, 'access', _316 => _316.platformKit, 'optionalAccess', _317 => _317.gitConfig, 'call', _318 => _318()]);
10330
+ _optionalChain([this, 'access', _328 => _328.platformKit, 'optionalAccess', _329 => _329.gitConfig, 'call', _330 => _330()]);
10026
10331
  _child_process.execSync.call(void 0, `git fetch origin ${baseBranchName}`, { stdio: "inherit" });
10027
10332
  _child_process.execSync.call(void 0, `git checkout ${baseBranchName} --`, { stdio: "inherit" });
10028
10333
  if (!processOwnCommits) {
@@ -10054,7 +10359,7 @@ var InBranchFlow = class extends IntegrationFlow {
10054
10359
  // src/cli/cmd/ci/flows/pull-request.ts
10055
10360
  var PullRequestFlow = class extends InBranchFlow {
10056
10361
  async preRun() {
10057
- const canContinue = await _optionalChain([super.preRun.bind(this), 'optionalCall', _319 => _319()]);
10362
+ const canContinue = await _optionalChain([super.preRun.bind(this), 'optionalCall', _331 => _331()]);
10058
10363
  if (!canContinue) {
10059
10364
  return false;
10060
10365
  }
@@ -10317,10 +10622,10 @@ var BitbucketPlatformKit = class extends PlatformKit {
10317
10622
  repo_slug: this.platformConfig.repositoryName,
10318
10623
  state: "OPEN"
10319
10624
  }).then(({ data: { values } }) => {
10320
- return _optionalChain([values, 'optionalAccess', _320 => _320.find, 'call', _321 => _321(
10321
- ({ source, destination }) => _optionalChain([source, 'optionalAccess', _322 => _322.branch, 'optionalAccess', _323 => _323.name]) === branch && _optionalChain([destination, 'optionalAccess', _324 => _324.branch, 'optionalAccess', _325 => _325.name]) === this.platformConfig.baseBranchName
10625
+ return _optionalChain([values, 'optionalAccess', _332 => _332.find, 'call', _333 => _333(
10626
+ ({ source, destination }) => _optionalChain([source, 'optionalAccess', _334 => _334.branch, 'optionalAccess', _335 => _335.name]) === branch && _optionalChain([destination, 'optionalAccess', _336 => _336.branch, 'optionalAccess', _337 => _337.name]) === this.platformConfig.baseBranchName
10322
10627
  )]);
10323
- }).then((pr) => _optionalChain([pr, 'optionalAccess', _326 => _326.id]));
10628
+ }).then((pr) => _optionalChain([pr, 'optionalAccess', _338 => _338.id]));
10324
10629
  }
10325
10630
  async closePullRequest({ pullRequestNumber }) {
10326
10631
  await this.bb.repositories.declinePullRequest({
@@ -10416,7 +10721,7 @@ var GitHubPlatformKit = class extends PlatformKit {
10416
10721
  repo: this.platformConfig.repositoryName,
10417
10722
  base: this.platformConfig.baseBranchName,
10418
10723
  state: "open"
10419
- }).then(({ data }) => data[0]).then((pr) => _optionalChain([pr, 'optionalAccess', _327 => _327.number]));
10724
+ }).then(({ data }) => data[0]).then((pr) => _optionalChain([pr, 'optionalAccess', _339 => _339.number]));
10420
10725
  }
10421
10726
  async closePullRequest({ pullRequestNumber }) {
10422
10727
  await this.octokit.rest.pulls.update({
@@ -10531,7 +10836,7 @@ var GitlabPlatformKit = class extends PlatformKit {
10531
10836
  branch
10532
10837
  );
10533
10838
  return true;
10534
- } catch (e5) {
10839
+ } catch (e4) {
10535
10840
  return false;
10536
10841
  }
10537
10842
  }
@@ -10543,7 +10848,7 @@ var GitlabPlatformKit = class extends PlatformKit {
10543
10848
  sourceBranch: branch,
10544
10849
  state: "opened"
10545
10850
  });
10546
- return _optionalChain([mergeRequests, 'access', _328 => _328[0], 'optionalAccess', _329 => _329.iid]);
10851
+ return _optionalChain([mergeRequests, 'access', _340 => _340[0], 'optionalAccess', _341 => _341.iid]);
10547
10852
  }
10548
10853
  async closePullRequest({
10549
10854
  pullRequestNumber
@@ -10649,7 +10954,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
10649
10954
  }
10650
10955
  const env = {
10651
10956
  LINGODOTDEV_API_KEY: settings.auth.apiKey,
10652
- LINGODOTDEV_PULL_REQUEST: _optionalChain([options, 'access', _330 => _330.pullRequest, 'optionalAccess', _331 => _331.toString, 'call', _332 => _332()]) || "false",
10957
+ LINGODOTDEV_PULL_REQUEST: _optionalChain([options, 'access', _342 => _342.pullRequest, 'optionalAccess', _343 => _343.toString, 'call', _344 => _344()]) || "false",
10653
10958
  ...options.commitMessage && {
10654
10959
  LINGODOTDEV_COMMIT_MESSAGE: options.commitMessage
10655
10960
  },
@@ -10669,7 +10974,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
10669
10974
  const { isPullRequestMode } = platformKit.config;
10670
10975
  ora.info(`Pull request mode: ${isPullRequestMode ? "on" : "off"}`);
10671
10976
  const flow = isPullRequestMode ? new PullRequestFlow(ora, platformKit) : new InBranchFlow(ora, platformKit);
10672
- const canRun = await _optionalChain([flow, 'access', _333 => _333.preRun, 'optionalCall', _334 => _334()]);
10977
+ const canRun = await _optionalChain([flow, 'access', _345 => _345.preRun, 'optionalCall', _346 => _346()]);
10673
10978
  if (canRun === false) {
10674
10979
  return;
10675
10980
  }
@@ -10679,7 +10984,7 @@ var ci_default = new (0, _interactivecommander.Command)().command("ci").descript
10679
10984
  if (!hasChanges) {
10680
10985
  return;
10681
10986
  }
10682
- await _optionalChain([flow, 'access', _335 => _335.postRun, 'optionalCall', _336 => _336()]);
10987
+ await _optionalChain([flow, 'access', _347 => _347.postRun, 'optionalCall', _348 => _348()]);
10683
10988
  });
10684
10989
  function parseBooleanArg(val) {
10685
10990
  if (val === true) return true;
@@ -10716,8 +11021,8 @@ function exitGracefully(elapsedMs = 0) {
10716
11021
  }
10717
11022
  }
10718
11023
  function checkForPendingOperations() {
10719
- const activeHandles = _optionalChain([process, 'access', _337 => _337._getActiveHandles, 'optionalCall', _338 => _338()]) || [];
10720
- const activeRequests = _optionalChain([process, 'access', _339 => _339._getActiveRequests, 'optionalCall', _340 => _340()]) || [];
11024
+ const activeHandles = _optionalChain([process, 'access', _349 => _349._getActiveHandles, 'optionalCall', _350 => _350()]) || [];
11025
+ const activeRequests = _optionalChain([process, 'access', _351 => _351._getActiveRequests, 'optionalCall', _352 => _352()]) || [];
10721
11026
  const nonStandardHandles = activeHandles.filter((handle) => {
10722
11027
  if (handle === process.stdin || handle === process.stdout || handle === process.stderr) {
10723
11028
  return false;
@@ -10786,17 +11091,17 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
10786
11091
  flags
10787
11092
  });
10788
11093
  let buckets = getBuckets(i18nConfig);
10789
- if (_optionalChain([flags, 'access', _341 => _341.bucket, 'optionalAccess', _342 => _342.length])) {
11094
+ if (_optionalChain([flags, 'access', _353 => _353.bucket, 'optionalAccess', _354 => _354.length])) {
10790
11095
  buckets = buckets.filter(
10791
11096
  (bucket) => flags.bucket.includes(bucket.type)
10792
11097
  );
10793
11098
  }
10794
11099
  ora.succeed("Buckets retrieved");
10795
- if (_optionalChain([flags, 'access', _343 => _343.file, 'optionalAccess', _344 => _344.length])) {
11100
+ if (_optionalChain([flags, 'access', _355 => _355.file, 'optionalAccess', _356 => _356.length])) {
10796
11101
  buckets = buckets.map((bucket) => {
10797
11102
  const paths = bucket.paths.filter(
10798
11103
  (path19) => flags.file.find(
10799
- (file) => _optionalChain([path19, 'access', _345 => _345.pathPattern, 'optionalAccess', _346 => _346.includes, 'call', _347 => _347(file)]) || _optionalChain([path19, 'access', _348 => _348.pathPattern, 'optionalAccess', _349 => _349.match, 'call', _350 => _350(file)]) || minimatch(path19.pathPattern, file)
11104
+ (file) => _optionalChain([path19, 'access', _357 => _357.pathPattern, 'optionalAccess', _358 => _358.includes, 'call', _359 => _359(file)]) || _optionalChain([path19, 'access', _360 => _360.pathPattern, 'optionalAccess', _361 => _361.match, 'call', _362 => _362(file)]) || minimatch(path19.pathPattern, file)
10800
11105
  )
10801
11106
  );
10802
11107
  return { ...bucket, paths };
@@ -10816,7 +11121,7 @@ var status_default = new (0, _interactivecommander.Command)().command("status").
10816
11121
  });
10817
11122
  }
10818
11123
  }
10819
- const targetLocales = _optionalChain([flags, 'access', _351 => _351.locale, 'optionalAccess', _352 => _352.length]) ? flags.locale : i18nConfig.locale.targets;
11124
+ const targetLocales = _optionalChain([flags, 'access', _363 => _363.locale, 'optionalAccess', _364 => _364.length]) ? flags.locale : i18nConfig.locale.targets;
10820
11125
  let totalSourceKeyCount = 0;
10821
11126
  let uniqueKeysToTranslate = 0;
10822
11127
  let totalExistingTranslations = 0;
@@ -11222,12 +11527,12 @@ function validateParams2(i18nConfig, flags) {
11222
11527
  message: "No buckets found in i18n.json. Please add at least one bucket containing i18n content.",
11223
11528
  docUrl: "bucketNotFound"
11224
11529
  });
11225
- } else if (_optionalChain([flags, 'access', _353 => _353.locale, 'optionalAccess', _354 => _354.some, 'call', _355 => _355((locale) => !i18nConfig.locale.targets.includes(locale))])) {
11530
+ } else if (_optionalChain([flags, 'access', _365 => _365.locale, 'optionalAccess', _366 => _366.some, 'call', _367 => _367((locale) => !i18nConfig.locale.targets.includes(locale))])) {
11226
11531
  throw new CLIError({
11227
11532
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
11228
11533
  docUrl: "localeTargetNotFound"
11229
11534
  });
11230
- } else if (_optionalChain([flags, 'access', _356 => _356.bucket, 'optionalAccess', _357 => _357.some, 'call', _358 => _358(
11535
+ } else if (_optionalChain([flags, 'access', _368 => _368.bucket, 'optionalAccess', _369 => _369.some, 'call', _370 => _370(
11231
11536
  (bucket) => !i18nConfig.buckets[bucket]
11232
11537
  )])) {
11233
11538
  throw new CLIError({
@@ -11319,7 +11624,7 @@ async function renderHero2() {
11319
11624
  // package.json
11320
11625
  var package_default = {
11321
11626
  name: "lingo.dev",
11322
- version: "0.111.16",
11627
+ version: "0.112.1",
11323
11628
  description: "Lingo.dev CLI",
11324
11629
  private: false,
11325
11630
  publishConfig: {
@@ -11460,6 +11765,7 @@ var package_default = {
11460
11765
  "@lingo.dev/_react": "workspace:*",
11461
11766
  "@lingo.dev/_sdk": "workspace:*",
11462
11767
  "@lingo.dev/_spec": "workspace:*",
11768
+ "@markdoc/markdoc": "^0.5.4",
11463
11769
  "@modelcontextprotocol/sdk": "^1.5.0",
11464
11770
  "@openrouter/ai-sdk-provider": "^0.7.1",
11465
11771
  "@paralleldrive/cuid2": "^2.2.2",
@@ -11608,7 +11914,7 @@ var purge_default = new (0, _interactivecommander.Command)().command("purge").de
11608
11914
  if (options.file && options.file.length) {
11609
11915
  buckets = buckets.map((bucket) => {
11610
11916
  const paths = bucket.paths.filter(
11611
- (bucketPath) => _optionalChain([options, 'access', _359 => _359.file, 'optionalAccess', _360 => _360.some, 'call', _361 => _361((f) => bucketPath.pathPattern.includes(f))])
11917
+ (bucketPath) => _optionalChain([options, 'access', _371 => _371.file, 'optionalAccess', _372 => _372.some, 'call', _373 => _373((f) => bucketPath.pathPattern.includes(f))])
11612
11918
  );
11613
11919
  return { ...bucket, paths };
11614
11920
  }).filter((bucket) => bucket.paths.length > 0);