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.mjs CHANGED
@@ -1277,7 +1277,7 @@ var init_default = new InteractiveCommand().command("init").description("Create
1277
1277
  });
1278
1278
 
1279
1279
  // src/cli/cmd/show/index.ts
1280
- import { Command as Command7 } from "interactive-commander";
1280
+ import { Command as Command9 } from "interactive-commander";
1281
1281
 
1282
1282
  // src/cli/cmd/show/config.ts
1283
1283
  import { Command as Command4 } from "interactive-commander";
@@ -1539,150 +1539,13 @@ var files_default = new Command6().command("files").description(
1539
1539
  }
1540
1540
  });
1541
1541
 
1542
- // src/cli/cmd/show/index.ts
1543
- var show_default = new Command7().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
- import { Command as Command11 } from "interactive-commander";
1547
-
1548
- // src/cli/cmd/config/set.ts
1549
- import { Command as Command8 } from "interactive-commander";
1550
- import chalk2 from "chalk";
1551
- import dedent from "dedent";
1552
- import _6 from "lodash";
1553
- var set_default = new Command8().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
- dedent`
1562
- ${chalk2.red("\u2716")} Unknown configuration key: ${chalk2.bold(key)}
1563
- Run ${chalk2.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 = _6.cloneDeep(current);
1571
- _6.set(updated, key, value);
1572
- try {
1573
- saveSettings(updated);
1574
- console.log(`${chalk2.green("\u2714")} Set ${chalk2.bold(key)}`);
1575
- } catch (err) {
1576
- console.error(
1577
- chalk2.red(
1578
- `\u2716 Failed to save configuration: ${chalk2.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
- import { Command as Command9 } from "interactive-commander";
1589
- import chalk3 from "chalk";
1590
- import dedent2 from "dedent";
1591
- import _7 from "lodash";
1592
- var unset_default = new Command9().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`
1601
- ${chalk3.red("\u2716")} Unknown configuration key: ${chalk3.bold(key)}
1602
- Run ${chalk3.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 = _7.get(settings, key);
1612
- if (!_7.trim(String(currentValue || ""))) {
1613
- console.log(`${chalk3.cyan("\u2139")} ${chalk3.bold(key)} is not set.`);
1614
- return;
1615
- } else {
1616
- const updated = _7.cloneDeep(settings);
1617
- _7.unset(updated, key);
1618
- try {
1619
- saveSettings(updated);
1620
- console.log(
1621
- `${chalk3.green("\u2714")} Removed configuration key ${chalk3.bold(key)}`
1622
- );
1623
- } catch (err) {
1624
- console.error(
1625
- chalk3.red(
1626
- `\u2716 Failed to save configuration: ${chalk3.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
- import { Command as Command10 } from "interactive-commander";
1638
- import chalk4 from "chalk";
1639
- import _8 from "lodash";
1640
- import dedent3 from "dedent";
1641
- var get_default = new Command10().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
- dedent3`
1650
- ${chalk4.red("\u2716")} Unknown configuration key: ${chalk4.bold(key)}
1651
- Run ${chalk4.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 = _8.get(settings, key);
1659
- if (!value) {
1660
- console.log(`${chalk4.cyan("\u2139")} ${chalk4.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 Command11().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
- import {
1677
- bucketTypeSchema,
1678
- localeCodeSchema,
1679
- resolveOverriddenLocale as resolveOverriddenLocale3
1680
- } from "@lingo.dev/_spec";
1681
- import { Command as Command12 } from "interactive-commander";
1682
- import Z3 from "zod";
1683
- import _31 from "lodash";
1542
+ // src/cli/cmd/show/locked-keys.ts
1543
+ import { Command as Command7 } from "interactive-commander";
1684
1544
  import Ora7 from "ora";
1685
1545
 
1546
+ // src/cli/cmd/show/_shared-key-command.ts
1547
+ import { resolveOverriddenLocale as resolveOverriddenLocale3 } from "@lingo.dev/_spec";
1548
+
1686
1549
  // src/cli/loaders/_utils.ts
1687
1550
  function composeLoaders(...loaders) {
1688
1551
  return {
@@ -2009,7 +1872,7 @@ function createJsoncLoader() {
2009
1872
 
2010
1873
  // src/cli/loaders/flat.ts
2011
1874
  import { flatten, unflatten } from "flat";
2012
- import _9 from "lodash";
1875
+ import _6 from "lodash";
2013
1876
  var OBJECT_NUMERIC_KEY_PREFIX = "__lingodotdev__obj__";
2014
1877
  function createFlatLoader() {
2015
1878
  const composedLoader = composeLoaders(
@@ -2088,12 +1951,12 @@ function mapDenormalizedKeys(obj, denormalizedKeysMap) {
2088
1951
  );
2089
1952
  }
2090
1953
  function denormalizeObjectKeys(obj) {
2091
- if (_9.isObject(obj) && !_9.isArray(obj)) {
2092
- return _9.transform(
1954
+ if (_6.isObject(obj) && !_6.isArray(obj)) {
1955
+ return _6.transform(
2093
1956
  obj,
2094
1957
  (result, value, key) => {
2095
1958
  const newKey = !isNaN(Number(key)) ? `${OBJECT_NUMERIC_KEY_PREFIX}${key}` : key;
2096
- result[newKey] = _9.isObject(value) && !_9.isDate(value) ? denormalizeObjectKeys(value) : value;
1959
+ result[newKey] = _6.isObject(value) && !_6.isDate(value) ? denormalizeObjectKeys(value) : value;
2097
1960
  },
2098
1961
  {}
2099
1962
  );
@@ -2102,12 +1965,12 @@ function denormalizeObjectKeys(obj) {
2102
1965
  }
2103
1966
  }
2104
1967
  function normalizeObjectKeys(obj) {
2105
- if (_9.isObject(obj) && !_9.isArray(obj)) {
2106
- return _9.transform(
1968
+ if (_6.isObject(obj) && !_6.isArray(obj)) {
1969
+ return _6.transform(
2107
1970
  obj,
2108
1971
  (result, value, key) => {
2109
1972
  const newKey = `${key}`.replace(OBJECT_NUMERIC_KEY_PREFIX, "");
2110
- result[newKey] = _9.isObject(value) && !_9.isDate(value) ? normalizeObjectKeys(value) : value;
1973
+ result[newKey] = _6.isObject(value) && !_6.isDate(value) ? normalizeObjectKeys(value) : value;
2111
1974
  },
2112
1975
  {}
2113
1976
  );
@@ -2118,14 +1981,14 @@ function normalizeObjectKeys(obj) {
2118
1981
  function flattenHints(obj, parentHints = [], parentPath = "") {
2119
1982
  const result = {};
2120
1983
  for (const [key, _value] of Object.entries(obj)) {
2121
- if (_9.isObject(_value) && !_9.isArray(_value)) {
1984
+ if (_6.isObject(_value) && !_6.isArray(_value)) {
2122
1985
  const value = _value;
2123
1986
  const currentHints = [...parentHints];
2124
1987
  const currentPath = parentPath ? `${parentPath}/${key}` : key;
2125
1988
  if (value.hint && typeof value.hint === "string") {
2126
1989
  currentHints.push(value.hint);
2127
1990
  }
2128
- const nestedObj = _9.omit(value, "hint");
1991
+ const nestedObj = _6.omit(value, "hint");
2129
1992
  if (Object.keys(nestedObj).length === 0) {
2130
1993
  if (currentHints.length > 0) {
2131
1994
  result[currentPath] = currentHints;
@@ -2253,19 +2116,19 @@ function createRootKeyLoader(replaceAll = false) {
2253
2116
  }
2254
2117
 
2255
2118
  // src/cli/loaders/flutter.ts
2256
- import _10 from "lodash";
2119
+ import _7 from "lodash";
2257
2120
  function createFlutterLoader() {
2258
2121
  return createLoader({
2259
2122
  async pull(locale, input2) {
2260
- const result = _10.pickBy(input2, (value, key) => !_isMetadataKey(key));
2123
+ const result = _7.pickBy(input2, (value, key) => !_isMetadataKey(key));
2261
2124
  return result;
2262
2125
  },
2263
2126
  async push(locale, data, originalInput) {
2264
- const metadata = _10.pickBy(
2127
+ const metadata = _7.pickBy(
2265
2128
  originalInput,
2266
2129
  (value, key) => _isMetadataKey(key)
2267
2130
  );
2268
- const result = _10.merge({}, metadata, { "@@locale": locale }, data);
2131
+ const result = _7.merge({}, metadata, { "@@locale": locale }, data);
2269
2132
  return result;
2270
2133
  }
2271
2134
  });
@@ -2455,7 +2318,7 @@ function createAndroidLoader() {
2455
2318
  // src/cli/loaders/csv.ts
2456
2319
  import { parse as parse2 } from "csv-parse/sync";
2457
2320
  import { stringify } from "csv-stringify/sync";
2458
- import _11 from "lodash";
2321
+ import _8 from "lodash";
2459
2322
  function detectKeyColumnName(csvString) {
2460
2323
  const row = parse2(csvString)[0];
2461
2324
  const firstColumn = row?.[0]?.trim();
@@ -2476,7 +2339,7 @@ function _createCsvLoader() {
2476
2339
  relax_column_count_less: true
2477
2340
  });
2478
2341
  const items = {};
2479
- _11.forEach(inputParsed, (row) => {
2342
+ _8.forEach(inputParsed, (row) => {
2480
2343
  const key = row[keyColumnName];
2481
2344
  if (key && row[locale] && row[locale].trim() !== "") {
2482
2345
  items[key] = row[locale];
@@ -2713,6 +2576,133 @@ ${content}`;
2713
2576
  });
2714
2577
  }
2715
2578
 
2579
+ // src/cli/loaders/markdoc.ts
2580
+ import Markdoc from "@markdoc/markdoc";
2581
+ import YAML3 from "yaml";
2582
+ var FM_ATTR_PREFIX2 = "fm-attr-";
2583
+ function createMarkdocLoader() {
2584
+ return createLoader({
2585
+ async pull(locale, input2) {
2586
+ const ast = Markdoc.parse(input2);
2587
+ const result = {};
2588
+ const counters = {};
2589
+ traverseAndExtract(ast, "", result, counters);
2590
+ if (ast.attributes?.frontmatter) {
2591
+ const frontmatter = YAML3.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 = Markdoc.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 = YAML3.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 Markdoc.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" && node.attributes?.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" && node.attributes?.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" && node.attributes?.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({
@@ -2818,7 +2808,7 @@ function createXcodeStringsdictLoader() {
2818
2808
  }
2819
2809
 
2820
2810
  // src/cli/loaders/xcode-xcstrings.ts
2821
- import _12 from "lodash";
2811
+ import _9 from "lodash";
2822
2812
  function createXcodeXcstringsLoader(defaultLocale) {
2823
2813
  return createLoader({
2824
2814
  async pull(locale, input2, initCtx) {
@@ -2855,7 +2845,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2855
2845
  async push(locale, payload, originalInput) {
2856
2846
  const langDataToMerge = {};
2857
2847
  langDataToMerge.strings = {};
2858
- const input2 = _12.cloneDeep(originalInput) || {
2848
+ const input2 = _9.cloneDeep(originalInput) || {
2859
2849
  sourceLanguage: locale,
2860
2850
  strings: {}
2861
2851
  };
@@ -2905,7 +2895,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2905
2895
  }
2906
2896
  }
2907
2897
  const originalInputWithoutLocale = originalInput ? _removeLocale(originalInput, locale) : {};
2908
- const result = _12.merge({}, originalInputWithoutLocale, langDataToMerge);
2898
+ const result = _9.merge({}, originalInputWithoutLocale, langDataToMerge);
2909
2899
  return result;
2910
2900
  },
2911
2901
  async pullHints(originalInput) {
@@ -2942,7 +2932,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
2942
2932
  }
2943
2933
  function _removeLocale(input2, locale) {
2944
2934
  const { strings } = input2;
2945
- const newStrings = _12.cloneDeep(strings);
2935
+ const newStrings = _9.cloneDeep(strings);
2946
2936
  for (const [key, value] of Object.entries(newStrings)) {
2947
2937
  if (value.localizations?.[locale]) {
2948
2938
  delete value.localizations[locale];
@@ -2952,19 +2942,19 @@ function _removeLocale(input2, locale) {
2952
2942
  }
2953
2943
 
2954
2944
  // src/cli/loaders/unlocalizable.ts
2955
- import _13 from "lodash";
2945
+ import _10 from "lodash";
2956
2946
  import _isUrl from "is-url";
2957
2947
  import { isValid, parseISO } from "date-fns";
2958
2948
  function createUnlocalizableLoader(returnUnlocalizedKeys = false) {
2959
2949
  return createLoader({
2960
2950
  async pull(locale, input2) {
2961
2951
  const unlocalizableKeys = _getUnlocalizableKeys(input2);
2962
- const result = _13.omitBy(
2952
+ const result = _10.omitBy(
2963
2953
  input2,
2964
2954
  (_35, key) => unlocalizableKeys.includes(key)
2965
2955
  );
2966
2956
  if (returnUnlocalizedKeys) {
2967
- result.unlocalizable = _13.omitBy(
2957
+ result.unlocalizable = _10.omitBy(
2968
2958
  input2,
2969
2959
  (_35, key) => !unlocalizableKeys.includes(key)
2970
2960
  );
@@ -2973,10 +2963,10 @@ function createUnlocalizableLoader(returnUnlocalizedKeys = false) {
2973
2963
  },
2974
2964
  async push(locale, data, originalInput) {
2975
2965
  const unlocalizableKeys = _getUnlocalizableKeys(originalInput);
2976
- const result = _13.merge(
2966
+ const result = _10.merge(
2977
2967
  {},
2978
2968
  data,
2979
- _13.omitBy(originalInput, (_35, key) => !unlocalizableKeys.includes(key))
2969
+ _10.omitBy(originalInput, (_35, key) => !unlocalizableKeys.includes(key))
2980
2970
  );
2981
2971
  return result;
2982
2972
  }
@@ -2990,12 +2980,12 @@ function _isIsoDate(v) {
2990
2980
  }
2991
2981
  function _getUnlocalizableKeys(input2) {
2992
2982
  const rules = {
2993
- isEmpty: (v) => _13.isEmpty(v),
2983
+ isEmpty: (v) => _10.isEmpty(v),
2994
2984
  isNumber: (v) => typeof v === "number" || /^[0-9]+$/.test(v),
2995
- isBoolean: (v) => _13.isBoolean(v),
2996
- isIsoDate: (v) => _13.isString(v) && _isIsoDate(v),
2997
- isSystemId: (v) => _13.isString(v) && _isSystemId(v),
2998
- isUrl: (v) => _13.isString(v) && _isUrl(v)
2985
+ isBoolean: (v) => _10.isBoolean(v),
2986
+ isIsoDate: (v) => _10.isString(v) && _isIsoDate(v),
2987
+ isSystemId: (v) => _10.isString(v) && _isSystemId(v),
2988
+ isUrl: (v) => _10.isString(v) && _isUrl(v)
2999
2989
  };
3000
2990
  if (!input2) {
3001
2991
  return [];
@@ -3174,7 +3164,7 @@ function createFormatterLoader(formatterType, parser, bucketPathPattern) {
3174
3164
  }
3175
3165
 
3176
3166
  // src/cli/loaders/po/index.ts
3177
- import _14 from "lodash";
3167
+ import _11 from "lodash";
3178
3168
  import gettextParser from "gettext-parser";
3179
3169
  function createPoLoader(params = { multiline: false }) {
3180
3170
  return composeLoaders(createPoDataLoader(params), createPoContentLoader());
@@ -3190,7 +3180,7 @@ function createPoDataLoader(params) {
3190
3180
  if (Object.keys(sectionPo.translations).length === 0) {
3191
3181
  continue;
3192
3182
  }
3193
- const contextKey = _14.keys(sectionPo.translations)[0];
3183
+ const contextKey = _11.keys(sectionPo.translations)[0];
3194
3184
  const entries = sectionPo.translations[contextKey];
3195
3185
  Object.entries(entries).forEach(([msgid, entry]) => {
3196
3186
  if (msgid && entry.msgid) {
@@ -3212,13 +3202,13 @@ function createPoDataLoader(params) {
3212
3202
  if (Object.keys(sectionPo.translations).length === 0) {
3213
3203
  return null;
3214
3204
  }
3215
- const contextKey = _14.keys(sectionPo.translations)[0];
3205
+ const contextKey = _11.keys(sectionPo.translations)[0];
3216
3206
  const entries = sectionPo.translations[contextKey];
3217
3207
  const msgid = Object.keys(entries).find((key) => entries[key].msgid);
3218
3208
  if (!msgid) {
3219
3209
  const currentSection = currentSections.find((cs) => {
3220
3210
  const csPo = gettextParser.po.parse(cs);
3221
- const csContextKey = _14.keys(csPo.translations)[0];
3211
+ const csContextKey = _11.keys(csPo.translations)[0];
3222
3212
  const csEntries = csPo.translations[csContextKey];
3223
3213
  const csMsgid = Object.keys(csEntries).find(
3224
3214
  (key) => csEntries[key].msgid
@@ -3231,7 +3221,7 @@ function createPoDataLoader(params) {
3231
3221
  return section;
3232
3222
  }
3233
3223
  if (data[msgid]) {
3234
- const updatedPo = _14.merge({}, sectionPo, {
3224
+ const updatedPo = _11.merge({}, sectionPo, {
3235
3225
  translations: {
3236
3226
  [contextKey]: {
3237
3227
  [msgid]: {
@@ -3255,7 +3245,7 @@ function createPoDataLoader(params) {
3255
3245
  function createPoContentLoader() {
3256
3246
  return createLoader({
3257
3247
  async pull(locale, input2, initCtx, originalLocale) {
3258
- const result = _14.chain(input2).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => {
3248
+ const result = _11.chain(input2).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => {
3259
3249
  const singularFallback = locale === originalLocale ? entry.msgid : null;
3260
3250
  const pluralFallback = locale === originalLocale ? entry.msgid_plural || entry.msgid : null;
3261
3251
  const hasPlural = entry.msgstr.length > 1;
@@ -3270,7 +3260,7 @@ function createPoContentLoader() {
3270
3260
  return result;
3271
3261
  },
3272
3262
  async push(locale, data, originalInput) {
3273
- const result = _14.chain(originalInput).entries().map(([, entry]) => [
3263
+ const result = _11.chain(originalInput).entries().map(([, entry]) => [
3274
3264
  entry.msgid,
3275
3265
  {
3276
3266
  ...entry,
@@ -3813,41 +3803,41 @@ var datoSettingsSchema = Z2.object({
3813
3803
  });
3814
3804
 
3815
3805
  // src/cli/loaders/dato/filter.ts
3816
- import _15 from "lodash";
3806
+ import _12 from "lodash";
3817
3807
  function createDatoFilterLoader() {
3818
3808
  return createLoader({
3819
3809
  async pull(locale, input2) {
3820
3810
  const result = {};
3821
- for (const [modelId, modelInfo] of _15.entries(input2)) {
3811
+ for (const [modelId, modelInfo] of _12.entries(input2)) {
3822
3812
  result[modelId] = {};
3823
3813
  for (const record of modelInfo.records) {
3824
- result[modelId][record.id] = _15.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _15.get(record, [field.api_key, locale])).value();
3814
+ result[modelId][record.id] = _12.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _12.get(record, [field.api_key, locale])).value();
3825
3815
  }
3826
3816
  }
3827
3817
  return result;
3828
3818
  },
3829
3819
  async push(locale, data, originalInput, originalLocale) {
3830
- const result = _15.cloneDeep(originalInput || {});
3831
- for (const [modelId, modelInfo] of _15.entries(result)) {
3820
+ const result = _12.cloneDeep(originalInput || {});
3821
+ for (const [modelId, modelInfo] of _12.entries(result)) {
3832
3822
  for (const record of modelInfo.records) {
3833
- for (const [fieldId, fieldValue] of _15.entries(record)) {
3823
+ for (const [fieldId, fieldValue] of _12.entries(record)) {
3834
3824
  const fieldInfo = modelInfo.fields.find(
3835
3825
  (field) => field.api_key === fieldId
3836
3826
  );
3837
3827
  if (fieldInfo) {
3838
- const sourceFieldValue = _15.get(fieldValue, [originalLocale]);
3839
- const targetFieldValue = _15.get(data, [
3828
+ const sourceFieldValue = _12.get(fieldValue, [originalLocale]);
3829
+ const targetFieldValue = _12.get(data, [
3840
3830
  modelId,
3841
3831
  record.id,
3842
3832
  fieldId
3843
3833
  ]);
3844
3834
  if (targetFieldValue) {
3845
- _15.set(record, [fieldId, locale], targetFieldValue);
3835
+ _12.set(record, [fieldId, locale], targetFieldValue);
3846
3836
  } else {
3847
- _15.set(record, [fieldId, locale], sourceFieldValue);
3837
+ _12.set(record, [fieldId, locale], sourceFieldValue);
3848
3838
  }
3849
- _15.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _15.isEmpty(_15.get(fieldValue, [loc]))).forEach(
3850
- (loc) => _15.set(record, [fieldId, loc], sourceFieldValue)
3839
+ _12.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _12.isEmpty(_12.get(fieldValue, [loc]))).forEach(
3840
+ (loc) => _12.set(record, [fieldId, loc], sourceFieldValue)
3851
3841
  ).value();
3852
3842
  }
3853
3843
  }
@@ -3859,10 +3849,10 @@ function createDatoFilterLoader() {
3859
3849
  }
3860
3850
 
3861
3851
  // src/cli/loaders/dato/api.ts
3862
- import _17 from "lodash";
3852
+ import _14 from "lodash";
3863
3853
 
3864
3854
  // src/cli/loaders/dato/_utils.ts
3865
- import _16 from "lodash";
3855
+ import _13 from "lodash";
3866
3856
  import { buildClient } from "@datocms/cma-client-node";
3867
3857
  function createDatoClient(params) {
3868
3858
  if (!params.apiKey) {
@@ -4055,7 +4045,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4055
4045
  const result = {
4056
4046
  models: {}
4057
4047
  };
4058
- const updatedConfig = _17.cloneDeep(config);
4048
+ const updatedConfig = _14.cloneDeep(config);
4059
4049
  console.log(`Initializing DatoCMS loader...`);
4060
4050
  const project = await dato.findProject();
4061
4051
  const modelChoices = await getModelChoices(dato, config);
@@ -4073,7 +4063,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4073
4063
  delete updatedConfig.models[modelId];
4074
4064
  }
4075
4065
  }
4076
- for (const modelId of _17.keys(updatedConfig.models)) {
4066
+ for (const modelId of _14.keys(updatedConfig.models)) {
4077
4067
  const { modelName, fields } = await getModelFields(dato, modelId);
4078
4068
  if (fields.length > 0) {
4079
4069
  result.models[modelId] = { fields: [], records: [] };
@@ -4091,7 +4081,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4091
4081
  );
4092
4082
  if (isLocalized) {
4093
4083
  result.models[modelId].fields.push(fieldInfo);
4094
- updatedConfig.models[modelId].fields = _17.uniq([
4084
+ updatedConfig.models[modelId].fields = _14.uniq([
4095
4085
  ...updatedConfig.models[modelId].fields || [],
4096
4086
  fieldInfo.api_key
4097
4087
  ]);
@@ -4119,7 +4109,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4119
4109
  },
4120
4110
  async pull(locale, input2, initCtx) {
4121
4111
  const result = {};
4122
- for (const modelId of _17.keys(initCtx?.models || {})) {
4112
+ for (const modelId of _14.keys(initCtx?.models || {})) {
4123
4113
  let records = initCtx?.models[modelId].records || [];
4124
4114
  const recordIds = records.map((record) => record.id);
4125
4115
  records = await dato.findRecords(recordIds);
@@ -4134,7 +4124,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
4134
4124
  return result;
4135
4125
  },
4136
4126
  async push(locale, data, originalInput) {
4137
- for (const modelId of _17.keys(data)) {
4127
+ for (const modelId of _14.keys(data)) {
4138
4128
  for (let i = 0; i < data[modelId].records.length; i++) {
4139
4129
  const record = data[modelId].records[i];
4140
4130
  console.log(
@@ -4150,7 +4140,7 @@ async function getModelFields(dato, modelId) {
4150
4140
  const modelInfo = await dato.findModel(modelId);
4151
4141
  return {
4152
4142
  modelName: modelInfo.name,
4153
- fields: _17.filter(modelInfo.fields, (field) => field.type === "field")
4143
+ fields: _14.filter(modelInfo.fields, (field) => field.type === "field")
4154
4144
  };
4155
4145
  }
4156
4146
  async function getFieldDetails(dato, fields) {
@@ -4230,17 +4220,17 @@ async function promptModelSelection(choices) {
4230
4220
  }
4231
4221
 
4232
4222
  // src/cli/loaders/dato/extract.ts
4233
- import _18 from "lodash";
4223
+ import _15 from "lodash";
4234
4224
  function createDatoExtractLoader() {
4235
4225
  return createLoader({
4236
4226
  async pull(locale, input2) {
4237
4227
  const result = {};
4238
- for (const [modelId, modelInfo] of _18.entries(input2)) {
4239
- for (const [recordId, record] of _18.entries(modelInfo)) {
4240
- for (const [fieldName, fieldValue] of _18.entries(record)) {
4228
+ for (const [modelId, modelInfo] of _15.entries(input2)) {
4229
+ for (const [recordId, record] of _15.entries(modelInfo)) {
4230
+ for (const [fieldName, fieldValue] of _15.entries(record)) {
4241
4231
  const parsedValue = createParsedDatoValue(fieldValue);
4242
4232
  if (parsedValue) {
4243
- _18.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
4233
+ _15.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
4244
4234
  }
4245
4235
  }
4246
4236
  }
@@ -4248,12 +4238,12 @@ function createDatoExtractLoader() {
4248
4238
  return result;
4249
4239
  },
4250
4240
  async push(locale, data, originalInput) {
4251
- const result = _18.cloneDeep(originalInput || {});
4252
- for (const [modelId, modelInfo] of _18.entries(data)) {
4253
- for (const [virtualRecordId, record] of _18.entries(modelInfo)) {
4254
- for (const [fieldName, fieldValue] of _18.entries(record)) {
4241
+ const result = _15.cloneDeep(originalInput || {});
4242
+ for (const [modelId, modelInfo] of _15.entries(data)) {
4243
+ for (const [virtualRecordId, record] of _15.entries(modelInfo)) {
4244
+ for (const [fieldName, fieldValue] of _15.entries(record)) {
4255
4245
  const [, recordId] = virtualRecordId.split("_");
4256
- const originalFieldValue = _18.get(originalInput, [
4246
+ const originalFieldValue = _15.get(originalInput, [
4257
4247
  modelId,
4258
4248
  recordId,
4259
4249
  fieldName
@@ -4263,7 +4253,7 @@ function createDatoExtractLoader() {
4263
4253
  originalFieldValue,
4264
4254
  true
4265
4255
  );
4266
- _18.set(
4256
+ _15.set(
4267
4257
  result,
4268
4258
  [modelId, recordId, fieldName],
4269
4259
  rawValue || originalFieldValue
@@ -4276,25 +4266,25 @@ function createDatoExtractLoader() {
4276
4266
  });
4277
4267
  }
4278
4268
  function detectDatoFieldType(rawDatoValue) {
4279
- if (_18.has(rawDatoValue, "document") && _18.get(rawDatoValue, "schema") === "dast") {
4269
+ if (_15.has(rawDatoValue, "document") && _15.get(rawDatoValue, "schema") === "dast") {
4280
4270
  return "structured_text";
4281
- } else if (_18.has(rawDatoValue, "no_index") || _18.has(rawDatoValue, "twitter_card")) {
4271
+ } else if (_15.has(rawDatoValue, "no_index") || _15.has(rawDatoValue, "twitter_card")) {
4282
4272
  return "seo";
4283
- } else if (_18.get(rawDatoValue, "type") === "item") {
4273
+ } else if (_15.get(rawDatoValue, "type") === "item") {
4284
4274
  return "single_block";
4285
- } else if (_18.isArray(rawDatoValue) && _18.every(rawDatoValue, (item) => _18.get(item, "type") === "item")) {
4275
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.get(item, "type") === "item")) {
4286
4276
  return "rich_text";
4287
4277
  } else if (_isFile(rawDatoValue)) {
4288
4278
  return "file";
4289
- } else if (_18.isArray(rawDatoValue) && _18.every(rawDatoValue, (item) => _isFile(item))) {
4279
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _isFile(item))) {
4290
4280
  return "gallery";
4291
4281
  } else if (_isJson(rawDatoValue)) {
4292
4282
  return "json";
4293
- } else if (_18.isString(rawDatoValue)) {
4283
+ } else if (_15.isString(rawDatoValue)) {
4294
4284
  return "string";
4295
4285
  } else if (_isVideo(rawDatoValue)) {
4296
4286
  return "video";
4297
- } else if (_18.isArray(rawDatoValue) && _18.every(rawDatoValue, (item) => _18.isString(item))) {
4287
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.isString(item))) {
4298
4288
  return "ref_list";
4299
4289
  } else {
4300
4290
  return null;
@@ -4364,9 +4354,9 @@ function serializeStructuredText(rawStructuredText) {
4364
4354
  acc
4365
4355
  );
4366
4356
  }
4367
- if (!_18.isNil(node.value)) {
4357
+ if (!_15.isNil(node.value)) {
4368
4358
  acc[[...path19, "value"].join(".")] = node.value;
4369
- } else if (_18.get(node, "type") === "block") {
4359
+ } else if (_15.get(node, "type") === "block") {
4370
4360
  acc[[...path19, "item"].join(".")] = serializeBlock(node.item);
4371
4361
  }
4372
4362
  if (node.children) {
@@ -4382,48 +4372,48 @@ function serializeStructuredText(rawStructuredText) {
4382
4372
  }
4383
4373
  }
4384
4374
  function serializeSeo(rawSeo) {
4385
- return _18.chain(rawSeo).pick(["title", "description"]).value();
4375
+ return _15.chain(rawSeo).pick(["title", "description"]).value();
4386
4376
  }
4387
4377
  function serializeBlock(rawBlock) {
4388
- if (_18.get(rawBlock, "type") === "item" && _18.has(rawBlock, "id")) {
4378
+ if (_15.get(rawBlock, "type") === "item" && _15.has(rawBlock, "id")) {
4389
4379
  return serializeBlock(rawBlock.attributes);
4390
4380
  }
4391
4381
  const result = {};
4392
- for (const [attributeName, attributeValue] of _18.entries(rawBlock)) {
4382
+ for (const [attributeName, attributeValue] of _15.entries(rawBlock)) {
4393
4383
  result[attributeName] = createParsedDatoValue(attributeValue);
4394
4384
  }
4395
4385
  return result;
4396
4386
  }
4397
4387
  function serializeBlockList(rawBlockList) {
4398
- return _18.chain(rawBlockList).map((block) => serializeBlock(block)).value();
4388
+ return _15.chain(rawBlockList).map((block) => serializeBlock(block)).value();
4399
4389
  }
4400
4390
  function serializeVideo(rawVideo) {
4401
- return _18.chain(rawVideo).pick(["title"]).value();
4391
+ return _15.chain(rawVideo).pick(["title"]).value();
4402
4392
  }
4403
4393
  function serializeFile(rawFile) {
4404
- return _18.chain(rawFile).pick(["alt", "title"]).value();
4394
+ return _15.chain(rawFile).pick(["alt", "title"]).value();
4405
4395
  }
4406
4396
  function serializeGallery(rawGallery) {
4407
- return _18.chain(rawGallery).map((item) => serializeFile(item)).value();
4397
+ return _15.chain(rawGallery).map((item) => serializeFile(item)).value();
4408
4398
  }
4409
4399
  function deserializeFile(parsedFile, originalRawFile) {
4410
- return _18.chain(parsedFile).defaults(originalRawFile).value();
4400
+ return _15.chain(parsedFile).defaults(originalRawFile).value();
4411
4401
  }
4412
4402
  function deserializeGallery(parsedGallery, originalRawGallery) {
4413
- return _18.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
4403
+ return _15.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
4414
4404
  }
4415
4405
  function deserializeVideo(parsedVideo, originalRawVideo) {
4416
- return _18.chain(parsedVideo).defaults(originalRawVideo).value();
4406
+ return _15.chain(parsedVideo).defaults(originalRawVideo).value();
4417
4407
  }
4418
4408
  function deserializeBlock(payload, rawNode, isClean = false) {
4419
- const result = _18.cloneDeep(rawNode);
4420
- for (const [attributeName, attributeValue] of _18.entries(rawNode.attributes)) {
4409
+ const result = _15.cloneDeep(rawNode);
4410
+ for (const [attributeName, attributeValue] of _15.entries(rawNode.attributes)) {
4421
4411
  const rawValue = createRawDatoValue(
4422
4412
  payload[attributeName],
4423
4413
  attributeValue,
4424
4414
  isClean
4425
4415
  );
4426
- _18.set(result, ["attributes", attributeName], rawValue);
4416
+ _15.set(result, ["attributes", attributeName], rawValue);
4427
4417
  }
4428
4418
  if (isClean) {
4429
4419
  delete result["id"];
@@ -4431,40 +4421,40 @@ function deserializeBlock(payload, rawNode, isClean = false) {
4431
4421
  return result;
4432
4422
  }
4433
4423
  function deserializeSeo(parsedSeo, originalRawSeo) {
4434
- return _18.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
4424
+ return _15.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
4435
4425
  }
4436
4426
  function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = false) {
4437
- return _18.chain(parsedBlockList).map(
4427
+ return _15.chain(parsedBlockList).map(
4438
4428
  (block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)
4439
4429
  ).value();
4440
4430
  }
4441
4431
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
4442
- const result = _18.cloneDeep(originalRawStructuredText);
4443
- for (const [path19, value] of _18.entries(parsedStructuredText)) {
4444
- const realPath = _18.chain(path19.split(".")).flatMap((s) => !_18.isNaN(_18.toNumber(s)) ? ["children", s] : s).value();
4432
+ const result = _15.cloneDeep(originalRawStructuredText);
4433
+ for (const [path19, value] of _15.entries(parsedStructuredText)) {
4434
+ const realPath = _15.chain(path19.split(".")).flatMap((s) => !_15.isNaN(_15.toNumber(s)) ? ["children", s] : s).value();
4445
4435
  const deserializedValue = createRawDatoValue(
4446
4436
  value,
4447
- _18.get(originalRawStructuredText, realPath),
4437
+ _15.get(originalRawStructuredText, realPath),
4448
4438
  true
4449
4439
  );
4450
- _18.set(result, realPath, deserializedValue);
4440
+ _15.set(result, realPath, deserializedValue);
4451
4441
  }
4452
4442
  return result;
4453
4443
  }
4454
4444
  function _isJson(rawDatoValue) {
4455
4445
  try {
4456
- return _18.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
4446
+ return _15.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
4457
4447
  } catch (e) {
4458
4448
  return false;
4459
4449
  }
4460
4450
  }
4461
4451
  function _isFile(rawDatoValue) {
4462
- return _18.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every(
4463
- (key) => _18.has(rawDatoValue, key)
4452
+ return _15.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every(
4453
+ (key) => _15.has(rawDatoValue, key)
4464
4454
  );
4465
4455
  }
4466
4456
  function _isVideo(rawDatoValue) {
4467
- return _18.isObject(rawDatoValue) && [
4457
+ return _15.isObject(rawDatoValue) && [
4468
4458
  "url",
4469
4459
  "title",
4470
4460
  "width",
@@ -4472,7 +4462,7 @@ function _isVideo(rawDatoValue) {
4472
4462
  "provider",
4473
4463
  "provider_uid",
4474
4464
  "thumbnail_url"
4475
- ].every((key) => _18.has(rawDatoValue, key));
4465
+ ].every((key) => _15.has(rawDatoValue, key));
4476
4466
  }
4477
4467
 
4478
4468
  // src/cli/loaders/dato/index.ts
@@ -4542,7 +4532,7 @@ function createVttLoader() {
4542
4532
  }
4543
4533
 
4544
4534
  // src/cli/loaders/variable/index.ts
4545
- import _19 from "lodash";
4535
+ import _16 from "lodash";
4546
4536
  function createVariableLoader(params) {
4547
4537
  return composeLoaders(variableExtractLoader(params), variableContentLoader());
4548
4538
  }
@@ -4551,7 +4541,7 @@ function variableExtractLoader(params) {
4551
4541
  return createLoader({
4552
4542
  pull: async (locale, input2, initXtx, originalLocale, originalInput) => {
4553
4543
  const result = {};
4554
- const inputValues = _19.omitBy(input2, _19.isEmpty);
4544
+ const inputValues = _16.omitBy(input2, _16.isEmpty);
4555
4545
  for (const [key, value] of Object.entries(inputValues)) {
4556
4546
  const originalValue = originalInput[key];
4557
4547
  const matches = originalValue.match(specifierPattern) || [];
@@ -4587,11 +4577,11 @@ function variableExtractLoader(params) {
4587
4577
  function variableContentLoader() {
4588
4578
  return createLoader({
4589
4579
  pull: async (locale, input2) => {
4590
- const result = _19.mapValues(input2, (payload) => payload.value);
4580
+ const result = _16.mapValues(input2, (payload) => payload.value);
4591
4581
  return result;
4592
4582
  },
4593
4583
  push: async (locale, data, originalInput, defaultLocale, pullInput) => {
4594
- const result = _19.cloneDeep(
4584
+ const result = _16.cloneDeep(
4595
4585
  originalInput || {}
4596
4586
  );
4597
4587
  for (const [key, originalValueObj] of Object.entries(result)) {
@@ -4616,20 +4606,20 @@ function getFormatSpecifierPattern(type) {
4616
4606
  }
4617
4607
 
4618
4608
  // src/cli/loaders/sync.ts
4619
- import _20 from "lodash";
4609
+ import _17 from "lodash";
4620
4610
  function createSyncLoader() {
4621
4611
  return createLoader({
4622
4612
  async pull(locale, input2, initCtx, originalLocale, originalInput) {
4623
4613
  if (!originalInput) {
4624
4614
  return input2;
4625
4615
  }
4626
- return _20.chain(originalInput).mapValues((value, key) => input2[key]).value();
4616
+ return _17.chain(originalInput).mapValues((value, key) => input2[key]).value();
4627
4617
  },
4628
4618
  async push(locale, data, originalInput) {
4629
4619
  if (!originalInput) {
4630
4620
  return data;
4631
4621
  }
4632
- return _20.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
4622
+ return _17.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
4633
4623
  }
4634
4624
  });
4635
4625
  }
@@ -4811,7 +4801,7 @@ function parseVueFile(input2) {
4811
4801
 
4812
4802
  // src/cli/loaders/typescript/index.ts
4813
4803
  import { parse as parse3 } from "@babel/parser";
4814
- import _21 from "lodash";
4804
+ import _18 from "lodash";
4815
4805
  import babelTraverseModule from "@babel/traverse";
4816
4806
  import * as t from "@babel/types";
4817
4807
  import babelGenerateModule from "@babel/generator";
@@ -4847,7 +4837,7 @@ function createTypescriptLoader() {
4847
4837
  },
4848
4838
  push: async (locale, data, originalInput, defaultLocale, pullInput, pullOutput) => {
4849
4839
  const ast = parseTypeScript(originalInput || "");
4850
- const finalData = _21.merge({}, pullOutput, data);
4840
+ const finalData = _18.merge({}, pullOutput, data);
4851
4841
  updateStringsInDefaultExport(ast, finalData);
4852
4842
  const { code } = generate(ast, {
4853
4843
  jsescOption: {
@@ -5048,7 +5038,7 @@ function getPropertyKey(prop) {
5048
5038
  }
5049
5039
 
5050
5040
  // src/cli/loaders/inject-locale.ts
5051
- import _22 from "lodash";
5041
+ import _19 from "lodash";
5052
5042
 
5053
5043
  // ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
5054
5044
  var balanced = (a, b, str) => {
@@ -6596,7 +6586,7 @@ function createInjectLocaleLoader(injectLocaleKeys) {
6596
6586
  return data;
6597
6587
  }
6598
6588
  const omitKeys = _getKeysWithLocales(data, injectLocaleKeys, locale);
6599
- const result = _22.omit(data, omitKeys);
6589
+ const result = _19.omit(data, omitKeys);
6600
6590
  return result;
6601
6591
  },
6602
6592
  async push(locale, data, originalInput, originalLocale) {
@@ -6609,7 +6599,7 @@ function createInjectLocaleLoader(injectLocaleKeys) {
6609
6599
  originalLocale
6610
6600
  );
6611
6601
  localeKeys.forEach((key) => {
6612
- _22.set(data, key, locale);
6602
+ _19.set(data, key, locale);
6613
6603
  });
6614
6604
  return data;
6615
6605
  }
@@ -6618,7 +6608,7 @@ function createInjectLocaleLoader(injectLocaleKeys) {
6618
6608
  function _getKeysWithLocales(data, injectLocaleKeys, locale) {
6619
6609
  const allKeys = _getAllKeys(data);
6620
6610
  return allKeys.filter((key) => {
6621
- return injectLocaleKeys.some((pattern) => minimatch(key, pattern)) && _22.get(data, key) === locale;
6611
+ return injectLocaleKeys.some((pattern) => minimatch(key, pattern)) && _19.get(data, key) === locale;
6622
6612
  });
6623
6613
  }
6624
6614
  function _getAllKeys(obj, prefix = "") {
@@ -6636,27 +6626,40 @@ function _getAllKeys(obj, prefix = "") {
6636
6626
  }
6637
6627
 
6638
6628
  // src/cli/loaders/locked-keys.ts
6639
- import _23 from "lodash";
6629
+ import _20 from "lodash";
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 _23.pickBy(data, (value, key) => !_isLockedKey(key, lockedKeys));
6648
+ return _20.pickBy(
6649
+ data,
6650
+ (value, key) => !matchesKeyPattern(key, lockedKeys)
6651
+ );
6644
6652
  },
6645
6653
  push: async (locale, data, originalInput) => {
6646
- const lockedSubObject = _23.chain(originalInput).pickBy((value, key) => _isLockedKey(key, lockedKeys)).value();
6647
- return _23.merge({}, data, lockedSubObject);
6654
+ const lockedSubObject = _20.chain(originalInput).pickBy((value, key) => matchesKeyPattern(key, lockedKeys)).value();
6655
+ return _20.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
  import matter2 from "gray-matter";
6659
- import YAML3 from "yaml";
6662
+ import YAML4 from "yaml";
6660
6663
  function createMdxFrontmatterSplitLoader() {
6661
6664
  const fmEngine = createFmEngine();
6662
6665
  return createLoader({
@@ -6677,8 +6680,8 @@ function createMdxFrontmatterSplitLoader() {
6677
6680
  }
6678
6681
  function createFmEngine() {
6679
6682
  const yamlEngine2 = {
6680
- parse: (str) => YAML3.parse(str),
6681
- stringify: (obj) => YAML3.stringify(obj, { defaultStringType: "PLAIN" })
6683
+ parse: (str) => YAML4.parse(str),
6684
+ stringify: (obj) => YAML4.stringify(obj, { defaultStringType: "PLAIN" })
6682
6685
  };
6683
6686
  return {
6684
6687
  parse: (input2) => matter2(input2, {
@@ -6701,7 +6704,7 @@ function md5(input2) {
6701
6704
  }
6702
6705
 
6703
6706
  // src/cli/loaders/mdx2/code-placeholder.ts
6704
- import _24 from "lodash";
6707
+ import _21 from "lodash";
6705
6708
  var fenceRegex = /([ \t]*)(^>\s*)?```([\s\S]*?)```/gm;
6706
6709
  var inlineCodeRegex = /(?<!`)`([^`\r\n]+?)`(?!`)/g;
6707
6710
  var imageRegex = /([ \t]*)(^>\s*)?!\[[^\]]*?\]\(([^()]*(\([^()]*\)[^()]*)*)\)/gm;
@@ -6724,7 +6727,7 @@ ${match2}
6724
6727
  found = true;
6725
6728
  }
6726
6729
  } while (found);
6727
- content = _24.chain(content).split("\n\n").map((section) => _24.trim(section, "\n")).filter(Boolean).join("\n\n").value();
6730
+ content = _21.chain(content).split("\n\n").map((section) => _21.trim(section, "\n")).filter(Boolean).join("\n\n").value();
6728
6731
  return content;
6729
6732
  }
6730
6733
  function ensureTrailingFenceNewline(_content) {
@@ -6746,7 +6749,7 @@ ${match2}
6746
6749
  found = true;
6747
6750
  }
6748
6751
  } while (found);
6749
- content = _24.chain(content).split("\n\n").map((section) => _24.trim(section, "\n")).filter(Boolean).join("\n\n").value();
6752
+ content = _21.chain(content).split("\n\n").map((section) => _21.trim(section, "\n")).filter(Boolean).join("\n\n").value();
6750
6753
  return content;
6751
6754
  }
6752
6755
  function extractCodePlaceholders(content) {
@@ -6788,7 +6791,7 @@ function createMdxCodePlaceholderLoader() {
6788
6791
  async push(locale, data, originalInput, originalLocale, pullInput) {
6789
6792
  const sourceInfo = extractCodePlaceholders(originalInput ?? "");
6790
6793
  const currentInfo = extractCodePlaceholders(pullInput ?? "");
6791
- const codePlaceholders = _24.merge(
6794
+ const codePlaceholders = _21.merge(
6792
6795
  sourceInfo.codePlaceholders,
6793
6796
  currentInfo.codePlaceholders,
6794
6797
  globalPlaceholderRegistry
@@ -6796,7 +6799,7 @@ function createMdxCodePlaceholderLoader() {
6796
6799
  );
6797
6800
  let result = data;
6798
6801
  for (const [placeholder, original] of Object.entries(codePlaceholders)) {
6799
- const replacement = original.startsWith(">") ? _24.trimStart(original, "> ") : original;
6802
+ const replacement = original.startsWith(">") ? _21.trimStart(original, "> ") : original;
6800
6803
  result = result.replaceAll(placeholder, replacement);
6801
6804
  }
6802
6805
  return result;
@@ -6824,11 +6827,11 @@ function createLocalizableMdxDocumentLoader() {
6824
6827
  }
6825
6828
 
6826
6829
  // src/cli/loaders/mdx2/sections-split-2.ts
6827
- import _25 from "lodash";
6830
+ import _22 from "lodash";
6828
6831
  function createMdxSectionsSplit2Loader() {
6829
6832
  return createLoader({
6830
6833
  async pull(locale, input2) {
6831
- const sections = _25.chain(input2.content).split("\n\n").filter(Boolean).map((section, index) => [index, section]).fromPairs().value();
6834
+ const sections = _22.chain(input2.content).split("\n\n").filter(Boolean).map((section, index) => [index, section]).fromPairs().value();
6832
6835
  const result = {
6833
6836
  frontmatter: input2.frontmatter,
6834
6837
  sections
@@ -6836,7 +6839,7 @@ function createMdxSectionsSplit2Loader() {
6836
6839
  return result;
6837
6840
  },
6838
6841
  async push(locale, data, originalInput, _originalLocale, pullInput) {
6839
- const content = _25.chain(data.sections).values().join("\n\n").value();
6842
+ const content = _22.chain(data.sections).values().join("\n\n").value();
6840
6843
  const result = {
6841
6844
  frontmatter: data.frontmatter,
6842
6845
  codePlaceholders: pullInput?.codePlaceholders || {},
@@ -6902,31 +6905,26 @@ function createMdxLockedPatternsLoader(defaultPatterns) {
6902
6905
  }
6903
6906
 
6904
6907
  // src/cli/loaders/ignored-keys.ts
6905
- import _26 from "lodash";
6908
+ import _23 from "lodash";
6906
6909
  function createIgnoredKeysLoader(ignoredKeys) {
6907
6910
  return createLoader({
6908
6911
  pull: async (locale, data) => {
6909
- const result = _26.omitBy(
6912
+ const result = _23.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
- const ignoredSubObject = _26.pickBy(
6919
+ const ignoredSubObject = _23.pickBy(
6917
6920
  pullInput,
6918
- (value, key) => _isIgnoredKey(key, ignoredKeys)
6921
+ (value, key) => matchesKeyPattern(key, ignoredKeys)
6919
6922
  );
6920
- const result = _26.merge({}, data, ignoredSubObject);
6923
+ const result = _23.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) {
@@ -7060,7 +7058,7 @@ function createEjsLoader() {
7060
7058
  }
7061
7059
 
7062
7060
  // src/cli/loaders/ensure-key-order.ts
7063
- import _27 from "lodash";
7061
+ import _24 from "lodash";
7064
7062
  function createEnsureKeyOrderLoader() {
7065
7063
  return createLoader({
7066
7064
  pull: async (_locale, input2) => {
@@ -7075,10 +7073,10 @@ function createEnsureKeyOrderLoader() {
7075
7073
  });
7076
7074
  }
7077
7075
  function reorderKeys(data, originalInput) {
7078
- if (_27.isArray(originalInput) && _27.isArray(data)) {
7076
+ if (_24.isArray(originalInput) && _24.isArray(data)) {
7079
7077
  return data.map((item, idx) => reorderKeys(item, originalInput[idx] ?? {}));
7080
7078
  }
7081
- if (!_27.isObject(data) || _27.isArray(data) || _27.isDate(data)) {
7079
+ if (!_24.isObject(data) || _24.isArray(data) || _24.isDate(data)) {
7082
7080
  return data;
7083
7081
  }
7084
7082
  const orderedData = {};
@@ -7116,7 +7114,7 @@ function createTxtLoader() {
7116
7114
  }
7117
7115
 
7118
7116
  // src/cli/loaders/json-dictionary.ts
7119
- import _28 from "lodash";
7117
+ import _25 from "lodash";
7120
7118
  var TOP_LEVEL_KEY = "--content--";
7121
7119
  function createJsonDictionaryLoader() {
7122
7120
  return createLoader({
@@ -7131,7 +7129,7 @@ function createJsonDictionaryLoader() {
7131
7129
  if (!originalInput) {
7132
7130
  throw new Error("Error while parsing json-dictionary bucket");
7133
7131
  }
7134
- const input2 = _28.cloneDeep(originalInput);
7132
+ const input2 = _25.cloneDeep(originalInput);
7135
7133
  if (Object.keys(data).length === 1 && Object.keys(data)[0] === TOP_LEVEL_KEY) {
7136
7134
  setNestedLocale(
7137
7135
  { [TOP_LEVEL_KEY]: 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,7 +7484,276 @@ 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 = resolveOverriddenLocale3(
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 Command7().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 = Ora7();
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
+ import { Command as Command8 } from "interactive-commander";
7590
+ import Ora8 from "ora";
7591
+ var ignored_keys_default = new Command8().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 = Ora8();
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 Command9().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
+ import { Command as Command13 } from "interactive-commander";
7619
+
7620
+ // src/cli/cmd/config/set.ts
7621
+ import { Command as Command10 } from "interactive-commander";
7622
+ import chalk2 from "chalk";
7623
+ import dedent from "dedent";
7624
+ import _26 from "lodash";
7625
+ var set_default = new Command10().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
+ dedent`
7634
+ ${chalk2.red("\u2716")} Unknown configuration key: ${chalk2.bold(key)}
7635
+ Run ${chalk2.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 = _26.cloneDeep(current);
7643
+ _26.set(updated, key, value);
7644
+ try {
7645
+ saveSettings(updated);
7646
+ console.log(`${chalk2.green("\u2714")} Set ${chalk2.bold(key)}`);
7647
+ } catch (err) {
7648
+ console.error(
7649
+ chalk2.red(
7650
+ `\u2716 Failed to save configuration: ${chalk2.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
+ import { Command as Command11 } from "interactive-commander";
7661
+ import chalk3 from "chalk";
7662
+ import dedent2 from "dedent";
7663
+ import _27 from "lodash";
7664
+ var unset_default = new Command11().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`
7673
+ ${chalk3.red("\u2716")} Unknown configuration key: ${chalk3.bold(key)}
7674
+ Run ${chalk3.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 = _27.get(settings, key);
7684
+ if (!_27.trim(String(currentValue || ""))) {
7685
+ console.log(`${chalk3.cyan("\u2139")} ${chalk3.bold(key)} is not set.`);
7686
+ return;
7687
+ } else {
7688
+ const updated = _27.cloneDeep(settings);
7689
+ _27.unset(updated, key);
7690
+ try {
7691
+ saveSettings(updated);
7692
+ console.log(
7693
+ `${chalk3.green("\u2714")} Removed configuration key ${chalk3.bold(key)}`
7694
+ );
7695
+ } catch (err) {
7696
+ console.error(
7697
+ chalk3.red(
7698
+ `\u2716 Failed to save configuration: ${chalk3.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
+ import { Command as Command12 } from "interactive-commander";
7710
+ import chalk4 from "chalk";
7711
+ import _28 from "lodash";
7712
+ import dedent3 from "dedent";
7713
+ var get_default = new Command12().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
+ dedent3`
7722
+ ${chalk4.red("\u2716")} Unknown configuration key: ${chalk4.bold(key)}
7723
+ Run ${chalk4.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 = _28.get(settings, key);
7731
+ if (!value) {
7732
+ console.log(`${chalk4.cyan("\u2139")} ${chalk4.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 Command13().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
7748
+ import {
7749
+ bucketTypeSchema,
7750
+ localeCodeSchema,
7751
+ resolveOverriddenLocale as resolveOverriddenLocale4
7752
+ } from "@lingo.dev/_spec";
7753
+ import { Command as Command14 } from "interactive-commander";
7754
+ import Z3 from "zod";
7755
+ import _31 from "lodash";
7756
+ import Ora9 from "ora";
7481
7757
  import chalk6 from "chalk";
7482
7758
  import { createTwoFilesPatch } from "diff";
7483
7759
  import inquirer2 from "inquirer";
@@ -7517,7 +7793,7 @@ function createLingoLocalizer(params) {
7517
7793
  // src/cli/processor/basic.ts
7518
7794
  import { generateText } from "ai";
7519
7795
  import _29 from "lodash";
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 generateText({
7541
7817
  model,
7818
+ ...settings,
7542
7819
  messages: [
7543
7820
  {
7544
7821
  role: "system",
@@ -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
  }
@@ -7832,7 +8110,7 @@ function checkIfFileExists(filePath) {
7832
8110
 
7833
8111
  // src/cli/utils/delta.ts
7834
8112
  import * as path15 from "path";
7835
- import YAML4 from "yaml";
8113
+ import YAML5 from "yaml";
7836
8114
  var LockSchema = z.object({
7837
8115
  version: z.literal(1).default(1),
7838
8116
  checksums: z.record(
@@ -7897,7 +8175,7 @@ function createDeltaProcessor(fileKey) {
7897
8175
  },
7898
8176
  async loadLock() {
7899
8177
  const lockfileContent = tryReadFile(lockfilePath, null);
7900
- const lockfileYaml = lockfileContent ? YAML4.parse(lockfileContent) : null;
8178
+ const lockfileYaml = lockfileContent ? YAML5.parse(lockfileContent) : null;
7901
8179
  const lockfileData = lockfileYaml ? LockSchema.parse(lockfileYaml) : {
7902
8180
  version: 1,
7903
8181
  checksums: {}
@@ -7905,7 +8183,7 @@ function createDeltaProcessor(fileKey) {
7905
8183
  return lockfileData;
7906
8184
  },
7907
8185
  async saveLock(lockData) {
7908
- const lockfileYaml = YAML4.stringify(lockData);
8186
+ const lockfileYaml = YAML5.stringify(lockData);
7909
8187
  writeFile(lockfilePath, lockfileYaml);
7910
8188
  },
7911
8189
  async loadChecksums() {
@@ -7927,7 +8205,7 @@ function createDeltaProcessor(fileKey) {
7927
8205
  }
7928
8206
 
7929
8207
  // src/cli/cmd/i18n.ts
7930
- var i18n_default = new Command12().command("i18n").description(
8208
+ var i18n_default = new Command14().command("i18n").description(
7931
8209
  "DEPRECATED: Run localization pipeline (prefer `run` command instead)"
7932
8210
  ).helpOption("-h, --help", "Show help").option(
7933
8211
  "--locale <locale>",
@@ -7966,7 +8244,7 @@ var i18n_default = new Command12().command("i18n").description(
7966
8244
  "Stop immediately on first error instead of continuing to process remaining buckets and locales (fail-fast mode)"
7967
8245
  ).action(async function(options) {
7968
8246
  updateGitignore();
7969
- const ora = Ora7();
8247
+ const ora = Ora9();
7970
8248
  let flags;
7971
8249
  try {
7972
8250
  flags = parseFlags(options);
@@ -8055,7 +8333,7 @@ var i18n_default = new Command12().command("i18n").description(
8055
8333
  ora.start("Creating i18n.lock...");
8056
8334
  for (const bucket of buckets) {
8057
8335
  for (const bucketPath of bucket.paths) {
8058
- const sourceLocale = resolveOverriddenLocale3(
8336
+ const sourceLocale = resolveOverriddenLocale4(
8059
8337
  i18nConfig.locale.source,
8060
8338
  bucketPath.delimiter
8061
8339
  );
@@ -8090,7 +8368,7 @@ var i18n_default = new Command12().command("i18n").description(
8090
8368
  let requiresUpdate = null;
8091
8369
  bucketLoop: for (const bucket of buckets) {
8092
8370
  for (const bucketPath of bucket.paths) {
8093
- const sourceLocale = resolveOverriddenLocale3(
8371
+ const sourceLocale = resolveOverriddenLocale4(
8094
8372
  i18nConfig.locale.source,
8095
8373
  bucketPath.delimiter
8096
8374
  );
@@ -8119,7 +8397,7 @@ var i18n_default = new Command12().command("i18n").description(
8119
8397
  break bucketLoop;
8120
8398
  }
8121
8399
  for (const _targetLocale of targetLocales) {
8122
- const targetLocale = resolveOverriddenLocale3(
8400
+ const targetLocale = resolveOverriddenLocale4(
8123
8401
  _targetLocale,
8124
8402
  bucketPath.delimiter
8125
8403
  );
@@ -8174,10 +8452,10 @@ var i18n_default = new Command12().command("i18n").description(
8174
8452
  console.log();
8175
8453
  ora.info(`Processing bucket: ${bucket.type}`);
8176
8454
  for (const bucketPath of bucket.paths) {
8177
- const bucketOra = Ora7({ indent: 2 }).info(
8455
+ const bucketOra = Ora9({ indent: 2 }).info(
8178
8456
  `Processing path: ${bucketPath.pathPattern}`
8179
8457
  );
8180
- const sourceLocale = resolveOverriddenLocale3(
8458
+ const sourceLocale = resolveOverriddenLocale4(
8181
8459
  i18nConfig.locale.source,
8182
8460
  bucketPath.delimiter
8183
8461
  );
@@ -8197,7 +8475,7 @@ var i18n_default = new Command12().command("i18n").description(
8197
8475
  await bucketLoader.init();
8198
8476
  let sourceData = await bucketLoader.pull(sourceLocale);
8199
8477
  for (const _targetLocale of targetLocales) {
8200
- const targetLocale = resolveOverriddenLocale3(
8478
+ const targetLocale = resolveOverriddenLocale4(
8201
8479
  _targetLocale,
8202
8480
  bucketPath.delimiter
8203
8481
  );
@@ -8579,15 +8857,15 @@ Editing value for: ${chalk6.cyan(key)}`);
8579
8857
  }
8580
8858
 
8581
8859
  // src/cli/cmd/lockfile.ts
8582
- import { Command as Command13 } from "interactive-commander";
8860
+ import { Command as Command15 } from "interactive-commander";
8583
8861
  import Z5 from "zod";
8584
- import Ora8 from "ora";
8862
+ import Ora10 from "ora";
8585
8863
 
8586
8864
  // src/cli/utils/lockfile.ts
8587
8865
  import fs12 from "fs";
8588
8866
  import path16 from "path";
8589
8867
  import Z4 from "zod";
8590
- import YAML5 from "yaml";
8868
+ import YAML6 from "yaml";
8591
8869
  import { MD5 as MD52 } from "object-hash";
8592
8870
  import _32 from "lodash";
8593
8871
  function createLockfileHelper() {
@@ -8635,12 +8913,12 @@ function createLockfileHelper() {
8635
8913
  return LockfileSchema.parse({});
8636
8914
  }
8637
8915
  const content = fs12.readFileSync(lockfilePath, "utf-8");
8638
- const result = LockfileSchema.parse(YAML5.parse(content));
8916
+ const result = LockfileSchema.parse(YAML6.parse(content));
8639
8917
  return result;
8640
8918
  }
8641
8919
  function _saveLockfile(lockfile) {
8642
8920
  const lockfilePath = _getLockfilePath();
8643
- const content = YAML5.stringify(lockfile);
8921
+ const content = YAML6.stringify(lockfile);
8644
8922
  fs12.writeFileSync(lockfilePath, content);
8645
8923
  }
8646
8924
  function _getLockfilePath() {
@@ -8663,15 +8941,15 @@ var LockfileSchema = Z4.object({
8663
8941
  });
8664
8942
 
8665
8943
  // src/cli/cmd/lockfile.ts
8666
- import { resolveOverriddenLocale as resolveOverriddenLocale4 } from "@lingo.dev/_spec";
8667
- var lockfile_default = new Command13().command("lockfile").description(
8944
+ import { resolveOverriddenLocale as resolveOverriddenLocale5 } from "@lingo.dev/_spec";
8945
+ var lockfile_default = new Command15().command("lockfile").description(
8668
8946
  "Generate or refresh i18n.lock based on the current source locale content"
8669
8947
  ).helpOption("-h, --help", "Show help").option(
8670
8948
  "-f, --force",
8671
8949
  "Overwrite existing lockfile to reset translation tracking"
8672
8950
  ).action(async (options) => {
8673
8951
  const flags = flagsSchema.parse(options);
8674
- const ora = Ora8();
8952
+ const ora = Ora10();
8675
8953
  const lockfileHelper = createLockfileHelper();
8676
8954
  if (lockfileHelper.isLockfileExists() && !flags.force) {
8677
8955
  ora.warn(
@@ -8682,7 +8960,7 @@ var lockfile_default = new Command13().command("lockfile").description(
8682
8960
  const buckets = getBuckets(i18nConfig);
8683
8961
  for (const bucket of buckets) {
8684
8962
  for (const bucketConfig of bucket.paths) {
8685
- const sourceLocale = resolveOverriddenLocale4(
8963
+ const sourceLocale = resolveOverriddenLocale5(
8686
8964
  i18nConfig.locale.source,
8687
8965
  bucketConfig.delimiter
8688
8966
  );
@@ -8710,11 +8988,11 @@ var flagsSchema = Z5.object({
8710
8988
  });
8711
8989
 
8712
8990
  // src/cli/cmd/cleanup.ts
8713
- import { resolveOverriddenLocale as resolveOverriddenLocale5 } from "@lingo.dev/_spec";
8714
- import { Command as Command14 } from "interactive-commander";
8991
+ import { resolveOverriddenLocale as resolveOverriddenLocale6 } from "@lingo.dev/_spec";
8992
+ import { Command as Command16 } from "interactive-commander";
8715
8993
  import _33 from "lodash";
8716
- import Ora9 from "ora";
8717
- var cleanup_default = new Command14().command("cleanup").description(
8994
+ import Ora11 from "ora";
8995
+ var cleanup_default = new Command16().command("cleanup").description(
8718
8996
  "Remove translation keys from target locales that no longer exist in the source locale"
8719
8997
  ).helpOption("-h, --help", "Show help").option(
8720
8998
  "--locale <locale>",
@@ -8729,7 +9007,7 @@ var cleanup_default = new Command14().command("cleanup").description(
8729
9007
  "--verbose",
8730
9008
  "Print detailed output showing the specific keys to be removed for each locale"
8731
9009
  ).action(async function(options) {
8732
- const ora = Ora9();
9010
+ const ora = Ora11();
8733
9011
  const results = [];
8734
9012
  try {
8735
9013
  ora.start("Loading configuration...");
@@ -8747,11 +9025,11 @@ var cleanup_default = new Command14().command("cleanup").description(
8747
9025
  console.log();
8748
9026
  ora.info(`Processing bucket: ${bucket.type}`);
8749
9027
  for (const bucketConfig of bucket.paths) {
8750
- const sourceLocale = resolveOverriddenLocale5(
9028
+ const sourceLocale = resolveOverriddenLocale6(
8751
9029
  i18nConfig.locale.source,
8752
9030
  bucketConfig.delimiter
8753
9031
  );
8754
- const bucketOra = Ora9({ indent: 2 }).info(
9032
+ const bucketOra = Ora11({ indent: 2 }).info(
8755
9033
  `Processing path: ${bucketConfig.pathPattern}`
8756
9034
  );
8757
9035
  const bucketLoader = createBucketLoader(
@@ -8766,7 +9044,7 @@ var cleanup_default = new Command14().command("cleanup").description(
8766
9044
  const sourceData = await bucketLoader.pull(sourceLocale);
8767
9045
  const sourceKeys = Object.keys(sourceData);
8768
9046
  for (const _targetLocale of targetLocales) {
8769
- const targetLocale = resolveOverriddenLocale5(
9047
+ const targetLocale = resolveOverriddenLocale6(
8770
9048
  _targetLocale,
8771
9049
  bucketConfig.delimiter
8772
9050
  );
@@ -8844,12 +9122,12 @@ function displaySummary(results) {
8844
9122
  }
8845
9123
 
8846
9124
  // src/cli/cmd/mcp.ts
8847
- import { Command as Command15 } from "interactive-commander";
9125
+ import { Command as Command17 } from "interactive-commander";
8848
9126
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8849
9127
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8850
9128
  import Z6 from "zod";
8851
9129
  import { ReplexicaEngine } from "@lingo.dev/_sdk";
8852
- var mcp_default = new Command15().command("mcp").description(
9130
+ var mcp_default = new Command17().command("mcp").description(
8853
9131
  "Start a Model Context Protocol (MCP) server for AI assistant integration"
8854
9132
  ).helpOption("-h, --help", "Show help").action(async (_35, program) => {
8855
9133
  const apiKey = program.args[0];
@@ -8899,7 +9177,7 @@ var mcp_default = new Command15().command("mcp").description(
8899
9177
  });
8900
9178
 
8901
9179
  // src/cli/cmd/ci/index.ts
8902
- import { Command as Command17 } from "interactive-commander";
9180
+ import { Command as Command19 } from "interactive-commander";
8903
9181
  import createOra from "ora";
8904
9182
 
8905
9183
  // src/cli/cmd/ci/flows/pull-request.ts
@@ -8926,7 +9204,7 @@ function escapeShellArg(arg) {
8926
9204
  }
8927
9205
 
8928
9206
  // src/cli/cmd/run/index.ts
8929
- import { Command as Command16 } from "interactive-commander";
9207
+ import { Command as Command18 } from "interactive-commander";
8930
9208
  import { exec } from "child_process";
8931
9209
  import path17 from "path";
8932
9210
  import { fileURLToPath } from "url";
@@ -8981,8 +9259,9 @@ function createLingoDotDevLocalizer(explicitApiKey) {
8981
9259
  authenticated: !!response,
8982
9260
  username: response?.email
8983
9261
  };
8984
- } catch {
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 @@ import { generateText as generateText2 } from "ai";
9019
9298
  import { jsonrepair as jsonrepair3 } from "jsonrepair";
9020
9299
  import { createOllama as createOllama2 } from "ollama-ai-provider";
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) => createOllama2().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,7 +9366,8 @@ 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
  }
@@ -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 generateText2({
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 generateText2({
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);
@@ -9239,20 +9534,30 @@ async function setup(input2) {
9239
9534
  },
9240
9535
  {
9241
9536
  title: "Checking authentication",
9537
+ enabled: (ctx) => ctx.localizer?.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 ${chalk10.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 ${chalk10.hex(colors.yellow)(
9252
9544
  authStatus.username
9253
9545
  )}`;
9254
9546
  }
9255
9547
  },
9548
+ {
9549
+ title: "Validating configuration",
9550
+ enabled: (ctx) => ctx.localizer?.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) {
@@ -9286,7 +9591,7 @@ async function setup(input2) {
9286
9591
  // src/cli/cmd/run/plan.ts
9287
9592
  import chalk11 from "chalk";
9288
9593
  import { Listr as Listr2 } from "listr2";
9289
- import { resolveOverriddenLocale as resolveOverriddenLocale6 } from "@lingo.dev/_spec";
9594
+ import { resolveOverriddenLocale as resolveOverriddenLocale7 } from "@lingo.dev/_spec";
9290
9595
  async function plan(input2) {
9291
9596
  console.log(chalk11.hex(colors.orange)("[Planning]"));
9292
9597
  let buckets = getBuckets(input2.config);
@@ -9367,12 +9672,12 @@ async function plan(input2) {
9367
9672
  continue;
9368
9673
  }
9369
9674
  }
9370
- const sourceLocale = resolveOverriddenLocale6(
9675
+ const sourceLocale = resolveOverriddenLocale7(
9371
9676
  _sourceLocale,
9372
9677
  bucketPath.delimiter
9373
9678
  );
9374
9679
  for (const _targetLocale of _targetLocales) {
9375
- const targetLocale = resolveOverriddenLocale6(
9680
+ const targetLocale = resolveOverriddenLocale7(
9376
9681
  _targetLocale,
9377
9682
  bucketPath.delimiter
9378
9683
  );
@@ -9864,7 +10169,7 @@ function playSound(type) {
9864
10169
  setTimeout(resolve, 3e3);
9865
10170
  });
9866
10171
  }
9867
- var run_default = new Command16().command("run").description("Run localization pipeline").helpOption("-h, --help", "Show help").option(
10172
+ var run_default = new Command18().command("run").description("Run localization pipeline").helpOption("-h, --help", "Show help").option(
9868
10173
  "--source-locale <source-locale>",
9869
10174
  "Override the source locale from i18n.json for this run"
9870
10175
  ).option(
@@ -10607,7 +10912,7 @@ var getPlatformKit = () => {
10607
10912
  };
10608
10913
 
10609
10914
  // src/cli/cmd/ci/index.ts
10610
- var ci_default = new Command17().command("ci").description("Run localization pipeline in CI/CD environment").helpOption("-h, --help", "Show help").option(
10915
+ var ci_default = new Command19().command("ci").description("Run localization pipeline in CI/CD environment").helpOption("-h, --help", "Show help").option(
10611
10916
  "--parallel [boolean]",
10612
10917
  "Process translations concurrently for faster execution. Defaults to false",
10613
10918
  parseBooleanArg
@@ -10693,11 +10998,11 @@ function parseBooleanArg(val) {
10693
10998
  import {
10694
10999
  bucketTypeSchema as bucketTypeSchema4,
10695
11000
  localeCodeSchema as localeCodeSchema3,
10696
- resolveOverriddenLocale as resolveOverriddenLocale7
11001
+ resolveOverriddenLocale as resolveOverriddenLocale8
10697
11002
  } from "@lingo.dev/_spec";
10698
- import { Command as Command18 } from "interactive-commander";
11003
+ import { Command as Command20 } from "interactive-commander";
10699
11004
  import Z11 from "zod";
10700
- import Ora10 from "ora";
11005
+ import Ora12 from "ora";
10701
11006
  import chalk14 from "chalk";
10702
11007
  import Table from "cli-table3";
10703
11008
 
@@ -10735,7 +11040,7 @@ function checkForPendingOperations() {
10735
11040
  }
10736
11041
 
10737
11042
  // src/cli/cmd/status.ts
10738
- var status_default = new Command18().command("status").description("Show the status of the localization process").helpOption("-h, --help", "Show help").option(
11043
+ var status_default = new Command20().command("status").description("Show the status of the localization process").helpOption("-h, --help", "Show help").option(
10739
11044
  "--locale <locale>",
10740
11045
  "Limit the report to specific target locales from i18n.json. Repeat the flag to include multiple locales. Defaults to all configured target locales",
10741
11046
  (val, prev) => prev ? [...prev, val] : [val]
@@ -10756,7 +11061,7 @@ var status_default = new Command18().command("status").description("Show the sta
10756
11061
  "--api-key <api-key>",
10757
11062
  "Override the API key from settings or environment variables for this run"
10758
11063
  ).action(async function(options) {
10759
- const ora = Ora10();
11064
+ const ora = Ora12();
10760
11065
  const flags = parseFlags2(options);
10761
11066
  let authId = null;
10762
11067
  try {
@@ -10837,10 +11142,10 @@ var status_default = new Command18().command("status").description("Show the sta
10837
11142
  console.log();
10838
11143
  ora.info(`Analyzing bucket: ${bucket.type}`);
10839
11144
  for (const bucketPath of bucket.paths) {
10840
- const bucketOra = Ora10({ indent: 2 }).info(
11145
+ const bucketOra = Ora12({ indent: 2 }).info(
10841
11146
  `Analyzing path: ${bucketPath.pathPattern}`
10842
11147
  );
10843
- const sourceLocale = resolveOverriddenLocale7(
11148
+ const sourceLocale = resolveOverriddenLocale8(
10844
11149
  i18nConfig.locale.source,
10845
11150
  bucketPath.delimiter
10846
11151
  );
@@ -10887,7 +11192,7 @@ var status_default = new Command18().command("status").description("Show the sta
10887
11192
  }
10888
11193
  fileStats[filePath].wordCount = sourceWordCount;
10889
11194
  for (const _targetLocale of targetLocales) {
10890
- const targetLocale = resolveOverriddenLocale7(
11195
+ const targetLocale = resolveOverriddenLocale8(
10891
11196
  _targetLocale,
10892
11197
  bucketPath.delimiter
10893
11198
  );
@@ -11238,7 +11543,7 @@ function validateParams2(i18nConfig, flags) {
11238
11543
  }
11239
11544
 
11240
11545
  // src/cli/cmd/may-the-fourth.ts
11241
- import { Command as Command19 } from "interactive-commander";
11546
+ import { Command as Command21 } from "interactive-commander";
11242
11547
  import * as cp from "node:child_process";
11243
11548
  import figlet2 from "figlet";
11244
11549
  import chalk15 from "chalk";
@@ -11251,7 +11556,7 @@ var colors2 = {
11251
11556
  grey: "#808080",
11252
11557
  red: "#ff0000"
11253
11558
  };
11254
- var may_the_fourth_default = new Command19().command("may-the-fourth").description("May the Fourth be with you").helpOption("-h, --help", "Show help").action(async () => {
11559
+ var may_the_fourth_default = new Command21().command("may-the-fourth").description("May the Fourth be with you").helpOption("-h, --help", "Show help").action(async () => {
11255
11560
  await renderClear2();
11256
11561
  await renderBanner2();
11257
11562
  await renderSpacer2();
@@ -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",
@@ -11567,11 +11873,11 @@ var package_default = {
11567
11873
  };
11568
11874
 
11569
11875
  // src/cli/cmd/purge.ts
11570
- import { Command as Command20 } from "interactive-commander";
11571
- import Ora11 from "ora";
11572
- import { resolveOverriddenLocale as resolveOverriddenLocale8 } from "@lingo.dev/_spec";
11876
+ import { Command as Command22 } from "interactive-commander";
11877
+ import Ora13 from "ora";
11878
+ import { resolveOverriddenLocale as resolveOverriddenLocale9 } from "@lingo.dev/_spec";
11573
11879
  import { confirm as confirm3 } from "@inquirer/prompts";
11574
- var purge_default = new Command20().command("purge").description(
11880
+ var purge_default = new Command22().command("purge").description(
11575
11881
  "WARNING: Permanently delete translation entries from bucket path patterns defined in i18n.json. This is a destructive operation that cannot be undone. Without any filters, ALL managed keys will be removed from EVERY target locale."
11576
11882
  ).helpOption("-h, --help", "Show help").option(
11577
11883
  "--bucket <bucket>",
@@ -11591,7 +11897,7 @@ var purge_default = new Command20().command("purge").description(
11591
11897
  "--yes-really",
11592
11898
  "Bypass safety confirmations for destructive operations. Use with extreme caution - this will delete translation keys without asking for confirmation. Intended for automated scripts and CI environments only."
11593
11899
  ).action(async function(options) {
11594
- const ora = Ora11();
11900
+ const ora = Ora13();
11595
11901
  try {
11596
11902
  ora.start("Loading configuration...");
11597
11903
  const i18nConfig = getConfig();
@@ -11625,11 +11931,11 @@ var purge_default = new Command20().command("purge").description(
11625
11931
  ora.info(`Processing bucket: ${bucket.type}`);
11626
11932
  for (const bucketPath of bucket.paths) {
11627
11933
  for (const _targetLocale of targetLocales) {
11628
- const targetLocale = resolveOverriddenLocale8(
11934
+ const targetLocale = resolveOverriddenLocale9(
11629
11935
  _targetLocale,
11630
11936
  bucketPath.delimiter
11631
11937
  );
11632
- const bucketOra = Ora11({ indent: 2 }).start(
11938
+ const bucketOra = Ora13({ indent: 2 }).start(
11633
11939
  `Processing path: ${bucketPath.pathPattern} [${targetLocale}]`
11634
11940
  );
11635
11941
  try {