lingo.dev 0.86.0 → 0.87.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/cli.mjs CHANGED
@@ -991,10 +991,14 @@ var files_default = new Command4().command("files").description("Print out the l
991
991
  var show_default = new Command5().command("show").description("Prints out the current configuration").helpOption("-h, --help", "Show help").addCommand(config_default).addCommand(locale_default).addCommand(files_default);
992
992
 
993
993
  // src/cli/cmd/i18n.ts
994
- import { bucketTypeSchema, localeCodeSchema, resolveOverriddenLocale as resolveOverriddenLocale3 } from "@lingo.dev/_spec";
994
+ import {
995
+ bucketTypeSchema,
996
+ localeCodeSchema,
997
+ resolveOverriddenLocale as resolveOverriddenLocale3
998
+ } from "@lingo.dev/_spec";
995
999
  import { Command as Command6 } from "interactive-commander";
996
1000
  import Z3 from "zod";
997
- import _22 from "lodash";
1001
+ import _21 from "lodash";
998
1002
  import * as path15 from "path";
999
1003
  import Ora5 from "ora";
1000
1004
 
@@ -1214,7 +1218,7 @@ function createTextFileLoader(pathPattern) {
1214
1218
  const trimmedResult = result.trim();
1215
1219
  return trimmedResult;
1216
1220
  },
1217
- async push(locale, data, _25, originalLocale) {
1221
+ async push(locale, data, _24, originalLocale) {
1218
1222
  const draftPath = pathPattern.replaceAll("[locale]", locale);
1219
1223
  const finalPath = path10.resolve(draftPath);
1220
1224
  const dirPath = path10.dirname(finalPath);
@@ -1285,7 +1289,6 @@ function getStringType(yamlString) {
1285
1289
  const trimmedLine = line.trim();
1286
1290
  return (trimmedLine.startsWith('"') || trimmedLine.match(/:\s*"/)) && (trimmedLine.endsWith('"') || trimmedLine.endsWith('",'));
1287
1291
  });
1288
- console.log("hasDoubleQuotes", hasDoubleQuotes);
1289
1292
  if (hasDoubleQuotes) {
1290
1293
  return "QUOTE_DOUBLE";
1291
1294
  }
@@ -1637,96 +1640,6 @@ ${content}`;
1637
1640
  });
1638
1641
  }
1639
1642
 
1640
- // src/cli/loaders/mdx.ts
1641
- import _9 from "lodash";
1642
- import { unified } from "unified";
1643
- import remarkParse from "remark-parse";
1644
- import remarkFrontmatter from "remark-frontmatter";
1645
- import remarkGfm from "remark-gfm";
1646
- import remarkStringify from "remark-stringify";
1647
- import { VFile } from "vfile";
1648
- var parser = unified().use(remarkParse).use(remarkFrontmatter, ["yaml"]).use(remarkGfm);
1649
- var serializer = unified().use(remarkStringify).use(remarkFrontmatter, ["yaml"]).use(remarkGfm);
1650
- function createMdxFormatLoader() {
1651
- const skippedTypes = ["code", "inlineCode"];
1652
- return createLoader({
1653
- async pull(locale, input2) {
1654
- const file = new VFile(input2);
1655
- const ast = parser.parse(file);
1656
- const result = _9.cloneDeep(ast);
1657
- traverseMdast(result, (node) => {
1658
- if (skippedTypes.includes(node.type)) {
1659
- if ("value" in node) {
1660
- node.value = "";
1661
- }
1662
- }
1663
- });
1664
- return result;
1665
- },
1666
- async push(locale, data, originalInput, originalLocale, pullInput, pullOutput) {
1667
- const file = new VFile(originalInput);
1668
- const ast = parser.parse(file);
1669
- const result = _9.cloneDeep(ast);
1670
- traverseMdast(result, (node, indexPath) => {
1671
- if ("value" in node) {
1672
- const incomingValue = findNodeByIndexPath(data, indexPath);
1673
- if (incomingValue && "value" in incomingValue && !_9.isEmpty(incomingValue.value)) {
1674
- node.value = incomingValue.value;
1675
- }
1676
- }
1677
- });
1678
- return String(serializer.stringify(result));
1679
- }
1680
- });
1681
- }
1682
- function createDoubleSerializationLoader() {
1683
- return createLoader({
1684
- async pull(locale, input2) {
1685
- return input2;
1686
- },
1687
- async push(locale, data) {
1688
- const file = new VFile(data);
1689
- const ast = parser.parse(file);
1690
- const finalContent = String(serializer.stringify(ast));
1691
- return finalContent;
1692
- }
1693
- });
1694
- }
1695
- function createMdxStructureLoader() {
1696
- return createLoader({
1697
- async pull(locale, input2) {
1698
- const result = _9.chain(input2).pickBy((value, key) => key.endsWith("/value")).value();
1699
- return result;
1700
- },
1701
- async push(locale, data, originalInput) {
1702
- const result = _9.merge({}, originalInput, data);
1703
- return result;
1704
- }
1705
- });
1706
- }
1707
- function traverseMdast(ast, visitor, indexPath = []) {
1708
- visitor(ast, indexPath);
1709
- if ("children" in ast && Array.isArray(ast.children)) {
1710
- for (let i = 0; i < ast.children.length; i++) {
1711
- traverseMdast(ast.children[i], visitor, [...indexPath, i]);
1712
- }
1713
- }
1714
- }
1715
- function findNodeByIndexPath(ast, indexPath) {
1716
- let result = null;
1717
- const stringifiedIndexPath = indexPath.join(".");
1718
- traverseMdast(ast, (node, path18) => {
1719
- if (result) {
1720
- return;
1721
- }
1722
- const currentStringifiedPath = path18.join(".");
1723
- if (currentStringifiedPath === stringifiedIndexPath) {
1724
- result = node;
1725
- }
1726
- });
1727
- return result;
1728
- }
1729
-
1730
1643
  // src/cli/loaders/properties.ts
1731
1644
  function createPropertiesLoader() {
1732
1645
  return createLoader({
@@ -1746,7 +1659,7 @@ function createPropertiesLoader() {
1746
1659
  return result;
1747
1660
  },
1748
1661
  async push(locale, payload) {
1749
- const result = Object.entries(payload).filter(([_25, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1662
+ const result = Object.entries(payload).filter(([_24, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1750
1663
  return result;
1751
1664
  }
1752
1665
  });
@@ -1832,7 +1745,7 @@ function createXcodeStringsdictLoader() {
1832
1745
  }
1833
1746
 
1834
1747
  // src/cli/loaders/xcode-xcstrings.ts
1835
- import _10 from "lodash";
1748
+ import _9 from "lodash";
1836
1749
  function createXcodeXcstringsLoader(defaultLocale) {
1837
1750
  return createLoader({
1838
1751
  async pull(locale, input2, initCtx) {
@@ -1862,13 +1775,12 @@ function createXcodeXcstringsLoader(defaultLocale) {
1862
1775
  resultData[translationKey] = translationKey;
1863
1776
  }
1864
1777
  }
1865
- console.log(resultData);
1866
1778
  return resultData;
1867
1779
  },
1868
1780
  async push(locale, payload, originalInput) {
1869
1781
  const langDataToMerge = {};
1870
1782
  langDataToMerge.strings = {};
1871
- const input2 = _10.cloneDeep(originalInput) || { sourceLanguage: locale, strings: {} };
1783
+ const input2 = _9.cloneDeep(originalInput) || { sourceLanguage: locale, strings: {} };
1872
1784
  for (const [key, value] of Object.entries(payload)) {
1873
1785
  if (value === null || value === void 0) {
1874
1786
  continue;
@@ -1914,7 +1826,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
1914
1826
  }
1915
1827
  }
1916
1828
  }
1917
- const result = _10.merge({}, originalInput, langDataToMerge);
1829
+ const result = _9.merge({}, originalInput, langDataToMerge);
1918
1830
  return result;
1919
1831
  }
1920
1832
  });
@@ -1926,41 +1838,20 @@ import prettier from "prettier";
1926
1838
  function createPrettierLoader(options) {
1927
1839
  return createLoader({
1928
1840
  async pull(locale, data) {
1929
- return data;
1841
+ const draftPath = options.bucketPathPattern.replaceAll(
1842
+ "[locale]",
1843
+ locale
1844
+ );
1845
+ const finalPath = path11.resolve(draftPath);
1846
+ return await formatDataWithPrettier(data, finalPath, options);
1930
1847
  },
1931
1848
  async push(locale, data) {
1932
- const draftPath = options.bucketPathPattern.replaceAll("[locale]", locale);
1849
+ const draftPath = options.bucketPathPattern.replaceAll(
1850
+ "[locale]",
1851
+ locale
1852
+ );
1933
1853
  const finalPath = path11.resolve(draftPath);
1934
- const prettierConfig = await loadPrettierConfig(finalPath);
1935
- if (!prettierConfig) {
1936
- return data;
1937
- }
1938
- const config = {
1939
- ...prettierConfig || { printWidth: 2500, bracketSameLine: false },
1940
- parser: options.parser,
1941
- // For HTML parser, preserve comments and quotes
1942
- ...options.parser === "html" ? {
1943
- htmlWhitespaceSensitivity: "ignore",
1944
- singleQuote: false,
1945
- embeddedLanguageFormatting: "off"
1946
- } : {}
1947
- };
1948
- try {
1949
- const result = await prettier.format(data, config);
1950
- return result;
1951
- } catch (error) {
1952
- if (error instanceof Error && error.message.startsWith("Cannot find package")) {
1953
- console.log();
1954
- console.log("\u26A0\uFE0F Prettier plugins are not installed. Formatting without plugins.");
1955
- console.log("\u26A0\uFE0F To use prettier plugins install project dependencies before running Lingo.dev.");
1956
- config.plugins = [];
1957
- await prettier.clearConfigCache();
1958
- const result = await prettier.format(data, config);
1959
- return result;
1960
- } else {
1961
- throw error;
1962
- }
1963
- }
1854
+ return await formatDataWithPrettier(data, finalPath, options);
1964
1855
  }
1965
1856
  });
1966
1857
  }
@@ -1972,19 +1863,52 @@ async function loadPrettierConfig(filePath) {
1972
1863
  return {};
1973
1864
  }
1974
1865
  }
1866
+ async function formatDataWithPrettier(data, filePath, options) {
1867
+ const prettierConfig = await loadPrettierConfig(filePath);
1868
+ if (!prettierConfig && !options.alwaysFormat) {
1869
+ return data;
1870
+ }
1871
+ const config = {
1872
+ ...prettierConfig || { printWidth: 2500, bracketSameLine: false },
1873
+ parser: options.parser,
1874
+ // For HTML parser, preserve comments and quotes
1875
+ ...options.parser === "html" ? {
1876
+ htmlWhitespaceSensitivity: "ignore",
1877
+ singleQuote: false,
1878
+ embeddedLanguageFormatting: "off"
1879
+ } : {}
1880
+ };
1881
+ try {
1882
+ return await prettier.format(data, config);
1883
+ } catch (error) {
1884
+ if (error instanceof Error && error.message.startsWith("Cannot find package")) {
1885
+ console.log();
1886
+ console.log(
1887
+ "\u26A0\uFE0F Prettier plugins are not installed. Formatting without plugins."
1888
+ );
1889
+ console.log(
1890
+ "\u26A0\uFE0F To use prettier plugins install project dependencies before running Lingo.dev."
1891
+ );
1892
+ config.plugins = [];
1893
+ await prettier.clearConfigCache();
1894
+ return await prettier.format(data, config);
1895
+ }
1896
+ throw error;
1897
+ }
1898
+ }
1975
1899
 
1976
1900
  // src/cli/loaders/unlocalizable.ts
1977
- import _11 from "lodash";
1901
+ import _10 from "lodash";
1978
1902
  import _isUrl from "is-url";
1979
1903
  import { isValid, parseISO } from "date-fns";
1980
1904
  function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys = false) {
1981
1905
  const rules = {
1982
- isEmpty: (v) => _11.isEmpty(v),
1906
+ isEmpty: (v) => _10.isEmpty(v),
1983
1907
  isNumber: (v) => typeof v === "number" || /^[0-9]+$/.test(v),
1984
- isBoolean: (v) => _11.isBoolean(v),
1985
- isIsoDate: (v) => _11.isString(v) && _isIsoDate(v),
1986
- isSystemId: (v) => _11.isString(v) && _isSystemId(v),
1987
- isUrl: (v) => _11.isString(v) && _isUrl(v)
1908
+ isBoolean: (v) => _10.isBoolean(v),
1909
+ isIsoDate: (v) => _10.isString(v) && _isIsoDate(v),
1910
+ isSystemId: (v) => _10.isString(v) && _isSystemId(v),
1911
+ isUrl: (v) => _10.isString(v) && _isUrl(v)
1988
1912
  };
1989
1913
  return createLoader({
1990
1914
  async pull(locale, input2) {
@@ -1995,18 +1919,18 @@ function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys
1995
1919
  }
1996
1920
  }
1997
1921
  return false;
1998
- }).map(([key, _25]) => key);
1999
- const result = _11.omitBy(input2, (_25, key) => passthroughKeys.includes(key));
1922
+ }).map(([key, _24]) => key);
1923
+ const result = _10.omitBy(input2, (_24, key) => passthroughKeys.includes(key));
2000
1924
  if (returnUnlocalizedKeys) {
2001
- result.unlocalizable = _11.omitBy(input2, (_25, key) => !passthroughKeys.includes(key));
1925
+ result.unlocalizable = _10.omitBy(input2, (_24, key) => !passthroughKeys.includes(key));
2002
1926
  }
2003
1927
  return result;
2004
1928
  },
2005
1929
  async push(locale, data, originalInput) {
2006
1930
  if (isCacheRestore) {
2007
- return _11.merge({}, data);
1931
+ return _10.merge({}, data);
2008
1932
  }
2009
- const result = _11.merge({}, originalInput, data);
1933
+ const result = _10.merge({}, originalInput, data);
2010
1934
  return result;
2011
1935
  }
2012
1936
  });
@@ -2019,7 +1943,7 @@ function _isIsoDate(v) {
2019
1943
  }
2020
1944
 
2021
1945
  // src/cli/loaders/po/index.ts
2022
- import _12 from "lodash";
1946
+ import _11 from "lodash";
2023
1947
  import gettextParser from "gettext-parser";
2024
1948
  function createPoLoader(params = { multiline: false }) {
2025
1949
  return composeLoaders(createPoDataLoader(params), createPoContentLoader());
@@ -2032,7 +1956,7 @@ function createPoDataLoader(params) {
2032
1956
  const sections = input2.split("\n\n").filter(Boolean);
2033
1957
  for (const section of sections) {
2034
1958
  const sectionPo = gettextParser.po.parse(section);
2035
- const contextKey = _12.keys(sectionPo.translations)[0];
1959
+ const contextKey = _11.keys(sectionPo.translations)[0];
2036
1960
  const entries = sectionPo.translations[contextKey];
2037
1961
  Object.entries(entries).forEach(([msgid, entry]) => {
2038
1962
  if (msgid && entry.msgid) {
@@ -2051,13 +1975,13 @@ function createPoDataLoader(params) {
2051
1975
  const originalSections = originalInput?.split("\n\n").filter(Boolean) || [];
2052
1976
  const result = originalSections.map((section) => {
2053
1977
  const sectionPo = gettextParser.po.parse(section);
2054
- const contextKey = _12.keys(sectionPo.translations)[0];
1978
+ const contextKey = _11.keys(sectionPo.translations)[0];
2055
1979
  const entries = sectionPo.translations[contextKey];
2056
1980
  const msgid = Object.keys(entries).find((key) => entries[key].msgid);
2057
1981
  if (!msgid) {
2058
1982
  const currentSection = currentSections.find((cs) => {
2059
1983
  const csPo = gettextParser.po.parse(cs);
2060
- const csContextKey = _12.keys(csPo.translations)[0];
1984
+ const csContextKey = _11.keys(csPo.translations)[0];
2061
1985
  const csEntries = csPo.translations[csContextKey];
2062
1986
  const csMsgid = Object.keys(csEntries).find((key) => csEntries[key].msgid);
2063
1987
  return csMsgid === msgid;
@@ -2068,7 +1992,7 @@ function createPoDataLoader(params) {
2068
1992
  return section;
2069
1993
  }
2070
1994
  if (data[msgid]) {
2071
- const updatedPo = _12.merge({}, sectionPo, {
1995
+ const updatedPo = _11.merge({}, sectionPo, {
2072
1996
  translations: {
2073
1997
  [contextKey]: {
2074
1998
  [msgid]: {
@@ -2088,7 +2012,7 @@ function createPoDataLoader(params) {
2088
2012
  function createPoContentLoader() {
2089
2013
  return createLoader({
2090
2014
  async pull(locale, input2) {
2091
- const result = _12.chain(input2).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => [
2015
+ const result = _11.chain(input2).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => [
2092
2016
  entry.msgid,
2093
2017
  {
2094
2018
  singular: entry.msgstr[0] || entry.msgid,
@@ -2098,7 +2022,7 @@ function createPoContentLoader() {
2098
2022
  return result;
2099
2023
  },
2100
2024
  async push(locale, data, originalInput) {
2101
- const result = _12.chain(originalInput).entries().map(([, entry]) => [
2025
+ const result = _11.chain(originalInput).entries().map(([, entry]) => [
2102
2026
  entry.msgid,
2103
2027
  {
2104
2028
  ...entry,
@@ -2221,34 +2145,34 @@ var datoSettingsSchema = Z2.object({
2221
2145
  });
2222
2146
 
2223
2147
  // src/cli/loaders/dato/filter.ts
2224
- import _13 from "lodash";
2148
+ import _12 from "lodash";
2225
2149
  function createDatoFilterLoader() {
2226
2150
  return createLoader({
2227
2151
  async pull(locale, input2) {
2228
2152
  const result = {};
2229
- for (const [modelId, modelInfo] of _13.entries(input2)) {
2153
+ for (const [modelId, modelInfo] of _12.entries(input2)) {
2230
2154
  result[modelId] = {};
2231
2155
  for (const record of modelInfo.records) {
2232
- result[modelId][record.id] = _13.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _13.get(record, [field.api_key, locale])).value();
2156
+ result[modelId][record.id] = _12.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _12.get(record, [field.api_key, locale])).value();
2233
2157
  }
2234
2158
  }
2235
2159
  return result;
2236
2160
  },
2237
2161
  async push(locale, data, originalInput, originalLocale) {
2238
- const result = _13.cloneDeep(originalInput || {});
2239
- for (const [modelId, modelInfo] of _13.entries(result)) {
2162
+ const result = _12.cloneDeep(originalInput || {});
2163
+ for (const [modelId, modelInfo] of _12.entries(result)) {
2240
2164
  for (const record of modelInfo.records) {
2241
- for (const [fieldId, fieldValue] of _13.entries(record)) {
2165
+ for (const [fieldId, fieldValue] of _12.entries(record)) {
2242
2166
  const fieldInfo = modelInfo.fields.find((field) => field.api_key === fieldId);
2243
2167
  if (fieldInfo) {
2244
- const sourceFieldValue = _13.get(fieldValue, [originalLocale]);
2245
- const targetFieldValue = _13.get(data, [modelId, record.id, fieldId]);
2168
+ const sourceFieldValue = _12.get(fieldValue, [originalLocale]);
2169
+ const targetFieldValue = _12.get(data, [modelId, record.id, fieldId]);
2246
2170
  if (targetFieldValue) {
2247
- _13.set(record, [fieldId, locale], targetFieldValue);
2171
+ _12.set(record, [fieldId, locale], targetFieldValue);
2248
2172
  } else {
2249
- _13.set(record, [fieldId, locale], sourceFieldValue);
2173
+ _12.set(record, [fieldId, locale], sourceFieldValue);
2250
2174
  }
2251
- _13.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _13.isEmpty(_13.get(fieldValue, [loc]))).forEach((loc) => _13.set(record, [fieldId, loc], sourceFieldValue)).value();
2175
+ _12.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _12.isEmpty(_12.get(fieldValue, [loc]))).forEach((loc) => _12.set(record, [fieldId, loc], sourceFieldValue)).value();
2252
2176
  }
2253
2177
  }
2254
2178
  }
@@ -2259,10 +2183,10 @@ function createDatoFilterLoader() {
2259
2183
  }
2260
2184
 
2261
2185
  // src/cli/loaders/dato/api.ts
2262
- import _15 from "lodash";
2186
+ import _14 from "lodash";
2263
2187
 
2264
2188
  // src/cli/loaders/dato/_utils.ts
2265
- import _14 from "lodash";
2189
+ import _13 from "lodash";
2266
2190
  import { buildClient } from "@datocms/cma-client-node";
2267
2191
  function createDatoClient(params) {
2268
2192
  if (!params.apiKey) {
@@ -2437,7 +2361,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2437
2361
  const result = {
2438
2362
  models: {}
2439
2363
  };
2440
- const updatedConfig = _15.cloneDeep(config);
2364
+ const updatedConfig = _14.cloneDeep(config);
2441
2365
  console.log(`Initializing DatoCMS loader...`);
2442
2366
  const project = await dato.findProject();
2443
2367
  const modelChoices = await getModelChoices(dato, config);
@@ -2455,7 +2379,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2455
2379
  delete updatedConfig.models[modelId];
2456
2380
  }
2457
2381
  }
2458
- for (const modelId of _15.keys(updatedConfig.models)) {
2382
+ for (const modelId of _14.keys(updatedConfig.models)) {
2459
2383
  const { modelName, fields } = await getModelFields(dato, modelId);
2460
2384
  if (fields.length > 0) {
2461
2385
  result.models[modelId] = { fields: [], records: [] };
@@ -2466,7 +2390,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2466
2390
  const isLocalized = await updateFieldLocalization(dato, fieldInfo, selectedFields.includes(fieldInfo.id));
2467
2391
  if (isLocalized) {
2468
2392
  result.models[modelId].fields.push(fieldInfo);
2469
- updatedConfig.models[modelId].fields = _15.uniq([
2393
+ updatedConfig.models[modelId].fields = _14.uniq([
2470
2394
  ...updatedConfig.models[modelId].fields || [],
2471
2395
  fieldInfo.api_key
2472
2396
  ]);
@@ -2485,7 +2409,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2485
2409
  },
2486
2410
  async pull(locale, input2, initCtx) {
2487
2411
  const result = {};
2488
- for (const modelId of _15.keys(initCtx?.models || {})) {
2412
+ for (const modelId of _14.keys(initCtx?.models || {})) {
2489
2413
  let records = initCtx?.models[modelId].records || [];
2490
2414
  const recordIds = records.map((record) => record.id);
2491
2415
  records = await dato.findRecords(recordIds);
@@ -2500,7 +2424,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2500
2424
  return result;
2501
2425
  },
2502
2426
  async push(locale, data, originalInput) {
2503
- for (const modelId of _15.keys(data)) {
2427
+ for (const modelId of _14.keys(data)) {
2504
2428
  for (let i = 0; i < data[modelId].records.length; i++) {
2505
2429
  const record = data[modelId].records[i];
2506
2430
  console.log(`Updating record ${i + 1}/${data[modelId].records.length} for model ${modelId}...`);
@@ -2514,7 +2438,7 @@ async function getModelFields(dato, modelId) {
2514
2438
  const modelInfo = await dato.findModel(modelId);
2515
2439
  return {
2516
2440
  modelName: modelInfo.name,
2517
- fields: _15.filter(modelInfo.fields, (field) => field.type === "field")
2441
+ fields: _14.filter(modelInfo.fields, (field) => field.type === "field")
2518
2442
  };
2519
2443
  }
2520
2444
  async function getFieldDetails(dato, fields) {
@@ -2592,17 +2516,17 @@ async function promptModelSelection(choices) {
2592
2516
  }
2593
2517
 
2594
2518
  // src/cli/loaders/dato/extract.ts
2595
- import _16 from "lodash";
2519
+ import _15 from "lodash";
2596
2520
  function createDatoExtractLoader() {
2597
2521
  return createLoader({
2598
2522
  async pull(locale, input2) {
2599
2523
  const result = {};
2600
- for (const [modelId, modelInfo] of _16.entries(input2)) {
2601
- for (const [recordId, record] of _16.entries(modelInfo)) {
2602
- for (const [fieldName, fieldValue] of _16.entries(record)) {
2524
+ for (const [modelId, modelInfo] of _15.entries(input2)) {
2525
+ for (const [recordId, record] of _15.entries(modelInfo)) {
2526
+ for (const [fieldName, fieldValue] of _15.entries(record)) {
2603
2527
  const parsedValue = createParsedDatoValue(fieldValue);
2604
2528
  if (parsedValue) {
2605
- _16.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
2529
+ _15.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
2606
2530
  }
2607
2531
  }
2608
2532
  }
@@ -2610,14 +2534,14 @@ function createDatoExtractLoader() {
2610
2534
  return result;
2611
2535
  },
2612
2536
  async push(locale, data, originalInput) {
2613
- const result = _16.cloneDeep(originalInput || {});
2614
- for (const [modelId, modelInfo] of _16.entries(data)) {
2615
- for (const [virtualRecordId, record] of _16.entries(modelInfo)) {
2616
- for (const [fieldName, fieldValue] of _16.entries(record)) {
2537
+ const result = _15.cloneDeep(originalInput || {});
2538
+ for (const [modelId, modelInfo] of _15.entries(data)) {
2539
+ for (const [virtualRecordId, record] of _15.entries(modelInfo)) {
2540
+ for (const [fieldName, fieldValue] of _15.entries(record)) {
2617
2541
  const [, recordId] = virtualRecordId.split("_");
2618
- const originalFieldValue = _16.get(originalInput, [modelId, recordId, fieldName]);
2542
+ const originalFieldValue = _15.get(originalInput, [modelId, recordId, fieldName]);
2619
2543
  const rawValue = createRawDatoValue(fieldValue, originalFieldValue, true);
2620
- _16.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
2544
+ _15.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
2621
2545
  }
2622
2546
  }
2623
2547
  }
@@ -2626,25 +2550,25 @@ function createDatoExtractLoader() {
2626
2550
  });
2627
2551
  }
2628
2552
  function detectDatoFieldType(rawDatoValue) {
2629
- if (_16.has(rawDatoValue, "document") && _16.get(rawDatoValue, "schema") === "dast") {
2553
+ if (_15.has(rawDatoValue, "document") && _15.get(rawDatoValue, "schema") === "dast") {
2630
2554
  return "structured_text";
2631
- } else if (_16.has(rawDatoValue, "no_index") || _16.has(rawDatoValue, "twitter_card")) {
2555
+ } else if (_15.has(rawDatoValue, "no_index") || _15.has(rawDatoValue, "twitter_card")) {
2632
2556
  return "seo";
2633
- } else if (_16.get(rawDatoValue, "type") === "item") {
2557
+ } else if (_15.get(rawDatoValue, "type") === "item") {
2634
2558
  return "single_block";
2635
- } else if (_16.isArray(rawDatoValue) && _16.every(rawDatoValue, (item) => _16.get(item, "type") === "item")) {
2559
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.get(item, "type") === "item")) {
2636
2560
  return "rich_text";
2637
2561
  } else if (_isFile(rawDatoValue)) {
2638
2562
  return "file";
2639
- } else if (_16.isArray(rawDatoValue) && _16.every(rawDatoValue, (item) => _isFile(item))) {
2563
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _isFile(item))) {
2640
2564
  return "gallery";
2641
2565
  } else if (_isJson(rawDatoValue)) {
2642
2566
  return "json";
2643
- } else if (_16.isString(rawDatoValue)) {
2567
+ } else if (_15.isString(rawDatoValue)) {
2644
2568
  return "string";
2645
2569
  } else if (_isVideo(rawDatoValue)) {
2646
2570
  return "video";
2647
- } else if (_16.isArray(rawDatoValue) && _16.every(rawDatoValue, (item) => _16.isString(item))) {
2571
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.isString(item))) {
2648
2572
  return "ref_list";
2649
2573
  } else {
2650
2574
  return null;
@@ -2706,9 +2630,9 @@ function serializeStructuredText(rawStructuredText) {
2706
2630
  if ("document" in node) {
2707
2631
  return serializeStructuredTextNode(node.document, [...path18, "document"], acc);
2708
2632
  }
2709
- if (!_16.isNil(node.value)) {
2633
+ if (!_15.isNil(node.value)) {
2710
2634
  acc[[...path18, "value"].join(".")] = node.value;
2711
- } else if (_16.get(node, "type") === "block") {
2635
+ } else if (_15.get(node, "type") === "block") {
2712
2636
  acc[[...path18, "item"].join(".")] = serializeBlock(node.item);
2713
2637
  }
2714
2638
  if (node.children) {
@@ -2720,44 +2644,44 @@ function serializeStructuredText(rawStructuredText) {
2720
2644
  }
2721
2645
  }
2722
2646
  function serializeSeo(rawSeo) {
2723
- return _16.chain(rawSeo).pick(["title", "description"]).value();
2647
+ return _15.chain(rawSeo).pick(["title", "description"]).value();
2724
2648
  }
2725
2649
  function serializeBlock(rawBlock) {
2726
- if (_16.get(rawBlock, "type") === "item" && _16.has(rawBlock, "id")) {
2650
+ if (_15.get(rawBlock, "type") === "item" && _15.has(rawBlock, "id")) {
2727
2651
  return serializeBlock(rawBlock.attributes);
2728
2652
  }
2729
2653
  const result = {};
2730
- for (const [attributeName, attributeValue] of _16.entries(rawBlock)) {
2654
+ for (const [attributeName, attributeValue] of _15.entries(rawBlock)) {
2731
2655
  result[attributeName] = createParsedDatoValue(attributeValue);
2732
2656
  }
2733
2657
  return result;
2734
2658
  }
2735
2659
  function serializeBlockList(rawBlockList) {
2736
- return _16.chain(rawBlockList).map((block) => serializeBlock(block)).value();
2660
+ return _15.chain(rawBlockList).map((block) => serializeBlock(block)).value();
2737
2661
  }
2738
2662
  function serializeVideo(rawVideo) {
2739
- return _16.chain(rawVideo).pick(["title"]).value();
2663
+ return _15.chain(rawVideo).pick(["title"]).value();
2740
2664
  }
2741
2665
  function serializeFile(rawFile) {
2742
- return _16.chain(rawFile).pick(["alt", "title"]).value();
2666
+ return _15.chain(rawFile).pick(["alt", "title"]).value();
2743
2667
  }
2744
2668
  function serializeGallery(rawGallery) {
2745
- return _16.chain(rawGallery).map((item) => serializeFile(item)).value();
2669
+ return _15.chain(rawGallery).map((item) => serializeFile(item)).value();
2746
2670
  }
2747
2671
  function deserializeFile(parsedFile, originalRawFile) {
2748
- return _16.chain(parsedFile).defaults(originalRawFile).value();
2672
+ return _15.chain(parsedFile).defaults(originalRawFile).value();
2749
2673
  }
2750
2674
  function deserializeGallery(parsedGallery, originalRawGallery) {
2751
- return _16.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
2675
+ return _15.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
2752
2676
  }
2753
2677
  function deserializeVideo(parsedVideo, originalRawVideo) {
2754
- return _16.chain(parsedVideo).defaults(originalRawVideo).value();
2678
+ return _15.chain(parsedVideo).defaults(originalRawVideo).value();
2755
2679
  }
2756
2680
  function deserializeBlock(payload, rawNode, isClean = false) {
2757
- const result = _16.cloneDeep(rawNode);
2758
- for (const [attributeName, attributeValue] of _16.entries(rawNode.attributes)) {
2681
+ const result = _15.cloneDeep(rawNode);
2682
+ for (const [attributeName, attributeValue] of _15.entries(rawNode.attributes)) {
2759
2683
  const rawValue = createRawDatoValue(payload[attributeName], attributeValue, isClean);
2760
- _16.set(result, ["attributes", attributeName], rawValue);
2684
+ _15.set(result, ["attributes", attributeName], rawValue);
2761
2685
  }
2762
2686
  if (isClean) {
2763
2687
  delete result["id"];
@@ -2765,33 +2689,33 @@ function deserializeBlock(payload, rawNode, isClean = false) {
2765
2689
  return result;
2766
2690
  }
2767
2691
  function deserializeSeo(parsedSeo, originalRawSeo) {
2768
- return _16.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
2692
+ return _15.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
2769
2693
  }
2770
2694
  function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = false) {
2771
- return _16.chain(parsedBlockList).map((block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)).value();
2695
+ return _15.chain(parsedBlockList).map((block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)).value();
2772
2696
  }
2773
2697
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
2774
- const result = _16.cloneDeep(originalRawStructuredText);
2775
- for (const [path18, value] of _16.entries(parsedStructuredText)) {
2776
- const realPath = _16.chain(path18.split(".")).flatMap((s) => !_16.isNaN(_16.toNumber(s)) ? ["children", s] : s).value();
2777
- const deserializedValue = createRawDatoValue(value, _16.get(originalRawStructuredText, realPath), true);
2778
- _16.set(result, realPath, deserializedValue);
2698
+ const result = _15.cloneDeep(originalRawStructuredText);
2699
+ for (const [path18, value] of _15.entries(parsedStructuredText)) {
2700
+ const realPath = _15.chain(path18.split(".")).flatMap((s) => !_15.isNaN(_15.toNumber(s)) ? ["children", s] : s).value();
2701
+ const deserializedValue = createRawDatoValue(value, _15.get(originalRawStructuredText, realPath), true);
2702
+ _15.set(result, realPath, deserializedValue);
2779
2703
  }
2780
2704
  return result;
2781
2705
  }
2782
2706
  function _isJson(rawDatoValue) {
2783
2707
  try {
2784
- return _16.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
2708
+ return _15.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
2785
2709
  } catch (e) {
2786
2710
  return false;
2787
2711
  }
2788
2712
  }
2789
2713
  function _isFile(rawDatoValue) {
2790
- return _16.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every((key) => _16.has(rawDatoValue, key));
2714
+ return _15.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every((key) => _15.has(rawDatoValue, key));
2791
2715
  }
2792
2716
  function _isVideo(rawDatoValue) {
2793
- return _16.isObject(rawDatoValue) && ["url", "title", "width", "height", "provider", "provider_uid", "thumbnail_url"].every(
2794
- (key) => _16.has(rawDatoValue, key)
2717
+ return _15.isObject(rawDatoValue) && ["url", "title", "width", "height", "provider", "provider_uid", "thumbnail_url"].every(
2718
+ (key) => _15.has(rawDatoValue, key)
2795
2719
  );
2796
2720
  }
2797
2721
 
@@ -2852,7 +2776,7 @@ function createVttLoader() {
2852
2776
  }
2853
2777
 
2854
2778
  // src/cli/loaders/variable/index.ts
2855
- import _17 from "lodash";
2779
+ import _16 from "lodash";
2856
2780
  function createVariableLoader(params) {
2857
2781
  return composeLoaders(variableExtractLoader(params), variableContentLoader());
2858
2782
  }
@@ -2861,7 +2785,7 @@ function variableExtractLoader(params) {
2861
2785
  return createLoader({
2862
2786
  pull: async (locale, input2) => {
2863
2787
  const result = {};
2864
- const inputValues = _17.omitBy(input2, _17.isEmpty);
2788
+ const inputValues = _16.omitBy(input2, _16.isEmpty);
2865
2789
  for (const [key, value] of Object.entries(inputValues)) {
2866
2790
  const matches = value.match(specifierPattern) || [];
2867
2791
  result[key] = result[key] || {
@@ -2896,11 +2820,11 @@ function variableExtractLoader(params) {
2896
2820
  function variableContentLoader() {
2897
2821
  return createLoader({
2898
2822
  pull: async (locale, input2) => {
2899
- const result = _17.mapValues(input2, (payload) => payload.value);
2823
+ const result = _16.mapValues(input2, (payload) => payload.value);
2900
2824
  return result;
2901
2825
  },
2902
2826
  push: async (locale, data, originalInput) => {
2903
- const result = _17.cloneDeep(originalInput || {});
2827
+ const result = _16.cloneDeep(originalInput || {});
2904
2828
  for (const [key, originalValueObj] of Object.entries(result)) {
2905
2829
  result[key] = {
2906
2830
  ...originalValueObj,
@@ -2923,20 +2847,20 @@ function getFormatSpecifierPattern(type) {
2923
2847
  }
2924
2848
 
2925
2849
  // src/cli/loaders/sync.ts
2926
- import _18 from "lodash";
2850
+ import _17 from "lodash";
2927
2851
  function createSyncLoader() {
2928
2852
  return createLoader({
2929
2853
  async pull(locale, input2, originalInput) {
2930
2854
  if (!originalInput) {
2931
2855
  return input2;
2932
2856
  }
2933
- return _18.chain(originalInput).mapValues((value, key) => input2[key]).value();
2857
+ return _17.chain(originalInput).mapValues((value, key) => input2[key]).value();
2934
2858
  },
2935
2859
  async push(locale, data, originalInput) {
2936
2860
  if (!originalInput) {
2937
2861
  return data;
2938
2862
  }
2939
- return _18.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
2863
+ return _17.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
2940
2864
  }
2941
2865
  });
2942
2866
  }
@@ -3096,7 +3020,7 @@ function parseVueFile(input2) {
3096
3020
  }
3097
3021
 
3098
3022
  // src/cli/loaders/inject-locale.ts
3099
- import _19 from "lodash";
3023
+ import _18 from "lodash";
3100
3024
  function createInjectLocaleLoader(injectLocaleKeys) {
3101
3025
  return createLoader({
3102
3026
  async pull(locale, data) {
@@ -3104,19 +3028,19 @@ function createInjectLocaleLoader(injectLocaleKeys) {
3104
3028
  return data;
3105
3029
  }
3106
3030
  const omitKeys = injectLocaleKeys.filter((key) => {
3107
- return _19.get(data, key) === locale;
3031
+ return _18.get(data, key) === locale;
3108
3032
  });
3109
- const result = _19.omit(data, omitKeys);
3033
+ const result = _18.omit(data, omitKeys);
3110
3034
  return result;
3111
3035
  },
3112
3036
  async push(locale, data, originalInput, originalLocale) {
3113
3037
  if (!injectLocaleKeys) {
3114
3038
  return data;
3115
3039
  }
3116
- const mergedData = _19.merge({}, originalInput, data);
3040
+ const mergedData = _18.merge({}, originalInput, data);
3117
3041
  injectLocaleKeys.forEach((key) => {
3118
- if (_19.get(mergedData, key) === originalLocale) {
3119
- _19.set(mergedData, key, locale);
3042
+ if (_18.get(mergedData, key) === originalLocale) {
3043
+ _18.set(mergedData, key, locale);
3120
3044
  }
3121
3045
  });
3122
3046
  return mergedData;
@@ -3125,19 +3049,436 @@ function createInjectLocaleLoader(injectLocaleKeys) {
3125
3049
  }
3126
3050
 
3127
3051
  // src/cli/loaders/locked-keys.ts
3128
- import _20 from "lodash";
3052
+ import _19 from "lodash";
3129
3053
  function createLockedKeysLoader(lockedKeys, isCacheRestore = false) {
3130
3054
  return createLoader({
3131
- pull: async (locale, data) => _20.chain(data).pickBy((value, key) => !lockedKeys.some((lockedKey) => key.startsWith(lockedKey))).value(),
3055
+ pull: async (locale, data) => _19.chain(data).pickBy((value, key) => !lockedKeys.some((lockedKey) => key.startsWith(lockedKey))).value(),
3132
3056
  push: async (locale, data, originalInput) => {
3133
- const lockedSubObject = _20.chain(originalInput).pickBy((value, key) => lockedKeys.some((lockedKey) => key.startsWith(lockedKey))).value();
3057
+ const lockedSubObject = _19.chain(originalInput).pickBy((value, key) => lockedKeys.some((lockedKey) => key.startsWith(lockedKey))).value();
3134
3058
  if (isCacheRestore) {
3135
- return _20.merge({}, data, lockedSubObject);
3059
+ return _19.merge({}, data, lockedSubObject);
3136
3060
  } else {
3137
- return _20.merge({}, originalInput, data, lockedSubObject);
3061
+ return _19.merge({}, originalInput, data, lockedSubObject);
3062
+ }
3063
+ }
3064
+ });
3065
+ }
3066
+
3067
+ // src/cli/loaders/mdx2/frontmatter-split.ts
3068
+ import matter2 from "gray-matter";
3069
+ function createMdxFrontmatterSplitLoader() {
3070
+ return createLoader({
3071
+ async pull(locale, input2) {
3072
+ const source = input2 || "";
3073
+ const { data: frontmatter, content } = matter2(source);
3074
+ return {
3075
+ frontmatter,
3076
+ content
3077
+ };
3078
+ },
3079
+ async push(locale, data) {
3080
+ const { frontmatter = {}, content = "" } = data || {};
3081
+ const result = matter2.stringify(content, frontmatter).trim();
3082
+ return result;
3083
+ }
3084
+ });
3085
+ }
3086
+
3087
+ // src/cli/loaders/mdx2/_utils.ts
3088
+ function traverseMdast(ast, visitor) {
3089
+ visitor(ast);
3090
+ if ("children" in ast && Array.isArray(ast.children)) {
3091
+ for (const child of ast.children) {
3092
+ traverseMdast(child, visitor);
3093
+ }
3094
+ }
3095
+ }
3096
+
3097
+ // src/cli/utils/md5.ts
3098
+ import { MD5 } from "object-hash";
3099
+ function md5(input2) {
3100
+ return MD5(input2);
3101
+ }
3102
+
3103
+ // src/cli/loaders/mdx2/code-placeholder.ts
3104
+ import { unified } from "unified";
3105
+ import remarkParse from "remark-parse";
3106
+ import remarkGfm from "remark-gfm";
3107
+ import { VFile } from "vfile";
3108
+ import remarkMdx from "remark-mdx";
3109
+ function parseMdast(content) {
3110
+ const file = new VFile(content);
3111
+ const parser2 = unified().use(remarkParse).use(remarkGfm).use(remarkMdx);
3112
+ const result = parser2.parse(file);
3113
+ return result;
3114
+ }
3115
+ function extractCodePlaceholders(content) {
3116
+ const ast = parseMdast(content);
3117
+ const placeholderableElements = [
3118
+ "code",
3119
+ "inlineCode"
3120
+ ];
3121
+ let finalContent = content;
3122
+ const codePlaceholders = {};
3123
+ traverseMdast(ast, (_node) => {
3124
+ if (!placeholderableElements.includes(_node.type)) {
3125
+ return;
3126
+ }
3127
+ const node = _node;
3128
+ const nodeContent = node.value;
3129
+ const nodeContentHash = md5(nodeContent);
3130
+ const placeholderId = `__PLACEHOLDER_${nodeContentHash}__`;
3131
+ const nodeContentStart = node.position?.start.offset;
3132
+ const nodeContentEnd = node.position?.end.offset;
3133
+ if (!nodeContentStart || !nodeContentEnd) {
3134
+ return;
3135
+ }
3136
+ codePlaceholders[placeholderId] = nodeContent;
3137
+ finalContent = finalContent.split(nodeContent).join(placeholderId);
3138
+ });
3139
+ return {
3140
+ content: finalContent,
3141
+ codePlaceholders
3142
+ };
3143
+ }
3144
+ function createMdxCodePlaceholderLoader() {
3145
+ return createLoader({
3146
+ async pull(locale, input2) {
3147
+ const { frontmatter = {}, content = "" } = input2 || {
3148
+ frontmatter: {},
3149
+ content: ""
3150
+ };
3151
+ const { content: resultContent, codePlaceholders } = extractCodePlaceholders(content);
3152
+ return {
3153
+ frontmatter,
3154
+ content: resultContent,
3155
+ codePlaceholders
3156
+ };
3157
+ },
3158
+ async push(locale, data, originalInput) {
3159
+ const { codePlaceholders } = extractCodePlaceholders(
3160
+ originalInput?.content ?? ""
3161
+ );
3162
+ let finalContent = data.content;
3163
+ for (const [placeholder, original] of Object.entries(codePlaceholders)) {
3164
+ finalContent = finalContent.replaceAll(placeholder, () => original);
3165
+ }
3166
+ const result = {
3167
+ frontmatter: data.frontmatter,
3168
+ content: finalContent
3169
+ };
3170
+ return result;
3171
+ }
3172
+ });
3173
+ }
3174
+
3175
+ // src/cli/loaders/mdx2/section-split.ts
3176
+ import { unified as unified2 } from "unified";
3177
+ import remarkParse2 from "remark-parse";
3178
+ import remarkGfm2 from "remark-gfm";
3179
+ import remarkMdx2 from "remark-mdx";
3180
+ import { VFile as VFile2 } from "vfile";
3181
+ var parser = unified2().use(remarkParse2).use(remarkGfm2).use(remarkMdx2);
3182
+ var SPACING_MATRIX = [
3183
+ // HEADING as previous type
3184
+ ["\n\n", "\n\n", "\n\n", "\n\n", "\n\n", "\n\n"],
3185
+ // JSX_OPENING_TAG as previous type
3186
+ ["\n\n", "\n", "\n", "\n", "\n", "\n\n"],
3187
+ // JSX_CLOSING_TAG as previous type
3188
+ ["\n\n", "\n", "\n", "\n", "\n\n", "\n\n"],
3189
+ // JSX_SELF_CLOSING_TAG as previous type
3190
+ ["\n\n", "\n", "\n", "\n", "\n", "\n\n"],
3191
+ // CONTENT as previous type
3192
+ ["\n\n", "\n\n", "\n", "\n\n", "\n\n", "\n\n"],
3193
+ // UNKNOWN as previous type
3194
+ ["\n\n", "\n\n", "\n\n", "\n\n", "\n\n", "\n\n"]
3195
+ ];
3196
+ function createMdxSectionSplitLoader() {
3197
+ return createLoader({
3198
+ async pull(_locale, input2) {
3199
+ const {
3200
+ frontmatter = {},
3201
+ content = "",
3202
+ codePlaceholders = {}
3203
+ } = input2 || {
3204
+ frontmatter: {},
3205
+ content: "",
3206
+ codePlaceholders: {}
3207
+ };
3208
+ if (!content.trim()) {
3209
+ return {
3210
+ frontmatter,
3211
+ sections: {}
3212
+ };
3213
+ }
3214
+ const file = new VFile2(content);
3215
+ const ast = parser.parse(file);
3216
+ const boundaries = findSectionBoundaries(ast, content);
3217
+ const sections = createSectionsFromBoundaries(boundaries, content);
3218
+ return {
3219
+ frontmatter,
3220
+ sections
3221
+ };
3222
+ },
3223
+ async push(_locale, data, originalInput, _originalLocale) {
3224
+ const sectionsArray = Object.values(data.sections);
3225
+ if (sectionsArray.length === 0) {
3226
+ return {
3227
+ frontmatter: data.frontmatter,
3228
+ content: "",
3229
+ codePlaceholders: originalInput?.codePlaceholders ?? {}
3230
+ };
3231
+ }
3232
+ const resultParts = new Array(sectionsArray.length * 2 - 1);
3233
+ const sectionTypes = new Array(sectionsArray.length);
3234
+ for (let i = 0; i < sectionsArray.length; i++) {
3235
+ sectionTypes[i] = determineJsxSectionType(sectionsArray[i]);
3236
+ }
3237
+ resultParts[0] = sectionsArray[0];
3238
+ for (let i = 1, j = 1; i < sectionsArray.length; i++, j += 2) {
3239
+ const prevType = sectionTypes[i - 1];
3240
+ const currentType = sectionTypes[i];
3241
+ resultParts[j] = SPACING_MATRIX[prevType][currentType];
3242
+ resultParts[j + 1] = sectionsArray[i];
3243
+ }
3244
+ const content = resultParts.join("");
3245
+ return {
3246
+ frontmatter: data.frontmatter,
3247
+ content,
3248
+ codePlaceholders: originalInput?.codePlaceholders ?? {}
3249
+ };
3250
+ }
3251
+ });
3252
+ }
3253
+ function determineJsxSectionType(section) {
3254
+ section = section.trim();
3255
+ if (!section) return 5 /* UNKNOWN */;
3256
+ const firstChar = section.charAt(0);
3257
+ const lastChar = section.charAt(section.length - 1);
3258
+ if (firstChar === "#") {
3259
+ if (/^#{1,6}\s/.test(section)) {
3260
+ return 0 /* HEADING */;
3261
+ }
3262
+ }
3263
+ if (firstChar === "<") {
3264
+ if (section.endsWith("/>")) {
3265
+ return 3 /* JSX_SELF_CLOSING_TAG */;
3266
+ }
3267
+ if (section.startsWith("</")) {
3268
+ return 2 /* JSX_CLOSING_TAG */;
3269
+ }
3270
+ if (lastChar === ">") {
3271
+ return 1 /* JSX_OPENING_TAG */;
3272
+ }
3273
+ }
3274
+ return 4 /* CONTENT */;
3275
+ }
3276
+ function isJsxOrHtml(node) {
3277
+ return node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement" || node.type === "html";
3278
+ }
3279
+ function findOpeningTagEnd(text) {
3280
+ let depth = 0;
3281
+ let inQuotes = false;
3282
+ let quoteChar = "";
3283
+ for (let i = 0; i < text.length; i++) {
3284
+ const char = text[i];
3285
+ if ((char === '"' || char === "'") && (i === 0 || text[i - 1] !== "\\")) {
3286
+ if (!inQuotes) {
3287
+ inQuotes = true;
3288
+ quoteChar = char;
3289
+ } else if (char === quoteChar) {
3290
+ inQuotes = false;
3138
3291
  }
3139
3292
  }
3293
+ if (!inQuotes) {
3294
+ if (char === "<") depth++;
3295
+ if (char === ">") {
3296
+ depth--;
3297
+ if (depth === 0) return i + 1;
3298
+ }
3299
+ }
3300
+ }
3301
+ return -1;
3302
+ }
3303
+ function findClosingTagStart(text) {
3304
+ const openTagMatch = /<([^\s/>]+)/.exec(text);
3305
+ if (!openTagMatch) return -1;
3306
+ const tagName = openTagMatch[1];
3307
+ const closingTagRegex = new RegExp(`</${tagName}\\s*>`, "g");
3308
+ let lastMatch = null;
3309
+ let match;
3310
+ while ((match = closingTagRegex.exec(text)) !== null) {
3311
+ lastMatch = match;
3312
+ }
3313
+ return lastMatch ? lastMatch.index : -1;
3314
+ }
3315
+ function processJsxNode(node, content, boundaries) {
3316
+ if (!node.position || typeof node.position.start.offset !== "number" || typeof node.position.end.offset !== "number") {
3317
+ return;
3318
+ }
3319
+ const nodeStart = node.position.start.offset;
3320
+ const nodeEnd = node.position.end.offset;
3321
+ const nodeContent = content.slice(nodeStart, nodeEnd);
3322
+ if (node.type === "html") {
3323
+ extractHtmlTags(nodeStart, nodeContent, boundaries);
3324
+ return;
3325
+ }
3326
+ if (node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement") {
3327
+ const isSelfClosing = node.selfClosing === true;
3328
+ if (isSelfClosing) {
3329
+ boundaries.push({
3330
+ start: nodeStart,
3331
+ end: nodeEnd,
3332
+ isolateSelf: true
3333
+ });
3334
+ } else {
3335
+ extractJsxTags(node, nodeContent, boundaries);
3336
+ if (node.children) {
3337
+ for (const child of node.children) {
3338
+ if (isJsxOrHtml(child)) {
3339
+ processJsxNode(child, content, boundaries);
3340
+ }
3341
+ }
3342
+ }
3343
+ }
3344
+ }
3345
+ }
3346
+ function extractHtmlTags(nodeStart, nodeContent, boundaries) {
3347
+ const tagRegex = /<\/?[a-zA-Z][a-zA-Z0-9:._-]*(?:\s+[a-zA-Z:_][a-zA-Z0-9:._-]*(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s]+))?)*\s*\/?>/g;
3348
+ let match;
3349
+ while ((match = tagRegex.exec(nodeContent)) !== null) {
3350
+ const tagStart = nodeStart + match.index;
3351
+ const tagEnd = tagStart + match[0].length;
3352
+ boundaries.push({
3353
+ start: tagStart,
3354
+ end: tagEnd,
3355
+ isolateSelf: true
3356
+ });
3357
+ }
3358
+ }
3359
+ function extractJsxTags(node, nodeContent, boundaries) {
3360
+ const nodeStart = node.position.start.offset;
3361
+ const nodeEnd = node.position.end.offset;
3362
+ if (!nodeStart || !nodeEnd) {
3363
+ return;
3364
+ }
3365
+ const openingTagEnd = findOpeningTagEnd(nodeContent);
3366
+ if (openingTagEnd > 0) {
3367
+ boundaries.push({
3368
+ start: nodeStart,
3369
+ end: nodeStart + openingTagEnd,
3370
+ isolateSelf: true
3371
+ });
3372
+ }
3373
+ const closingTagStart = findClosingTagStart(nodeContent);
3374
+ if (closingTagStart > 0 && closingTagStart < nodeContent.length) {
3375
+ boundaries.push({
3376
+ start: nodeStart + closingTagStart,
3377
+ end: nodeEnd,
3378
+ isolateSelf: true
3379
+ });
3380
+ }
3381
+ }
3382
+ function findSectionBoundaries(ast, content) {
3383
+ const boundaries = [];
3384
+ const nodePositions = /* @__PURE__ */ new Map();
3385
+ traverseMdast(ast, (node) => {
3386
+ if (node.position && typeof node.position.start.offset === "number" && typeof node.position.end.offset === "number") {
3387
+ nodePositions.set(node, {
3388
+ start: node.position.start.offset,
3389
+ end: node.position.end.offset
3390
+ });
3391
+ }
3140
3392
  });
3393
+ for (const child of ast.children) {
3394
+ const position = nodePositions.get(child);
3395
+ if (!position) continue;
3396
+ if (child.type === "heading") {
3397
+ boundaries.push({
3398
+ start: position.start,
3399
+ end: position.end,
3400
+ isolateSelf: false
3401
+ });
3402
+ } else if (isJsxOrHtml(child)) {
3403
+ processJsxNode(child, content, boundaries);
3404
+ }
3405
+ }
3406
+ return boundaries.sort((a, b) => a.start - b.start);
3407
+ }
3408
+ function createSectionsFromBoundaries(boundaries, content) {
3409
+ const sections = {};
3410
+ if (!content.trim() || boundaries.length === 0) {
3411
+ const trimmed = content.trim();
3412
+ if (trimmed) {
3413
+ sections["0"] = trimmed;
3414
+ }
3415
+ return sections;
3416
+ }
3417
+ let idx = 0;
3418
+ let lastEnd = 0;
3419
+ const sectionsArray = [];
3420
+ for (let i = 0; i < boundaries.length; i++) {
3421
+ const { start, end, isolateSelf } = boundaries[i];
3422
+ if (start > lastEnd) {
3423
+ const segment = content.slice(lastEnd, start).trim();
3424
+ if (segment) {
3425
+ sectionsArray.push(segment);
3426
+ }
3427
+ }
3428
+ if (isolateSelf) {
3429
+ const segment = content.slice(start, end).trim();
3430
+ if (segment) {
3431
+ sectionsArray.push(segment);
3432
+ }
3433
+ lastEnd = end;
3434
+ } else {
3435
+ const nextStart = i + 1 < boundaries.length ? boundaries[i + 1].start : content.length;
3436
+ const segment = content.slice(start, nextStart).trim();
3437
+ if (segment) {
3438
+ sectionsArray.push(segment);
3439
+ }
3440
+ lastEnd = nextStart;
3441
+ }
3442
+ }
3443
+ if (lastEnd < content.length) {
3444
+ const segment = content.slice(lastEnd).trim();
3445
+ if (segment) {
3446
+ sectionsArray.push(segment);
3447
+ }
3448
+ }
3449
+ sectionsArray.forEach((section, index) => {
3450
+ sections[index.toString()] = section;
3451
+ });
3452
+ return sections;
3453
+ }
3454
+
3455
+ // src/cli/loaders/mdx2/localizable-document.ts
3456
+ function createLocalizableMdxDocumentLoader() {
3457
+ return createLoader({
3458
+ async pull(_locale, input2) {
3459
+ return {
3460
+ meta: input2.frontmatter,
3461
+ content: input2.sections
3462
+ };
3463
+ },
3464
+ async push(_locale, data, originalInput, _originalLocale, pullInput) {
3465
+ const result = {
3466
+ frontmatter: data.meta || {},
3467
+ sections: data.content || {}
3468
+ };
3469
+ return result;
3470
+ }
3471
+ });
3472
+ }
3473
+
3474
+ // src/cli/loaders/mdx2/index.ts
3475
+ function createMdxLoader() {
3476
+ return composeLoaders(
3477
+ createMdxFrontmatterSplitLoader(),
3478
+ createMdxCodePlaceholderLoader(),
3479
+ createMdxSectionSplitLoader(),
3480
+ createLocalizableMdxDocumentLoader()
3481
+ );
3141
3482
  }
3142
3483
 
3143
3484
  // src/cli/loaders/index.ts
@@ -3151,7 +3492,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3151
3492
  createAndroidLoader(),
3152
3493
  createFlatLoader(),
3153
3494
  createSyncLoader(),
3154
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3495
+ createUnlocalizableLoader(
3496
+ options.isCacheRestore,
3497
+ options.returnUnlocalizedKeys
3498
+ )
3155
3499
  );
3156
3500
  case "csv":
3157
3501
  return composeLoaders(
@@ -3159,7 +3503,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3159
3503
  createCsvLoader(),
3160
3504
  createFlatLoader(),
3161
3505
  createSyncLoader(),
3162
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3506
+ createUnlocalizableLoader(
3507
+ options.isCacheRestore,
3508
+ options.returnUnlocalizedKeys
3509
+ )
3163
3510
  );
3164
3511
  case "html":
3165
3512
  return composeLoaders(
@@ -3167,7 +3514,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3167
3514
  createPrettierLoader({ parser: "html", bucketPathPattern }),
3168
3515
  createHtmlLoader(),
3169
3516
  createSyncLoader(),
3170
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3517
+ createUnlocalizableLoader(
3518
+ options.isCacheRestore,
3519
+ options.returnUnlocalizedKeys
3520
+ )
3171
3521
  );
3172
3522
  case "json":
3173
3523
  return composeLoaders(
@@ -3178,7 +3528,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3178
3528
  createFlatLoader(),
3179
3529
  createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
3180
3530
  createSyncLoader(),
3181
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3531
+ createUnlocalizableLoader(
3532
+ options.isCacheRestore,
3533
+ options.returnUnlocalizedKeys
3534
+ )
3182
3535
  );
3183
3536
  case "markdown":
3184
3537
  return composeLoaders(
@@ -3186,18 +3539,22 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3186
3539
  createPrettierLoader({ parser: "markdown", bucketPathPattern }),
3187
3540
  createMarkdownLoader(),
3188
3541
  createSyncLoader(),
3189
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3542
+ createUnlocalizableLoader(
3543
+ options.isCacheRestore,
3544
+ options.returnUnlocalizedKeys
3545
+ )
3190
3546
  );
3191
3547
  case "mdx":
3192
3548
  return composeLoaders(
3193
3549
  createTextFileLoader(bucketPathPattern),
3194
- createDoubleSerializationLoader(),
3195
3550
  createPrettierLoader({ parser: "mdx", bucketPathPattern }),
3196
- createMdxFormatLoader(),
3551
+ createMdxLoader(),
3197
3552
  createFlatLoader(),
3198
- createMdxStructureLoader(),
3199
3553
  createSyncLoader(),
3200
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3554
+ createUnlocalizableLoader(
3555
+ options.isCacheRestore,
3556
+ options.returnUnlocalizedKeys
3557
+ )
3201
3558
  );
3202
3559
  case "po":
3203
3560
  return composeLoaders(
@@ -3206,21 +3563,30 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3206
3563
  createFlatLoader(),
3207
3564
  createSyncLoader(),
3208
3565
  createVariableLoader({ type: "python" }),
3209
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3566
+ createUnlocalizableLoader(
3567
+ options.isCacheRestore,
3568
+ options.returnUnlocalizedKeys
3569
+ )
3210
3570
  );
3211
3571
  case "properties":
3212
3572
  return composeLoaders(
3213
3573
  createTextFileLoader(bucketPathPattern),
3214
3574
  createPropertiesLoader(),
3215
3575
  createSyncLoader(),
3216
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3576
+ createUnlocalizableLoader(
3577
+ options.isCacheRestore,
3578
+ options.returnUnlocalizedKeys
3579
+ )
3217
3580
  );
3218
3581
  case "xcode-strings":
3219
3582
  return composeLoaders(
3220
3583
  createTextFileLoader(bucketPathPattern),
3221
3584
  createXcodeStringsLoader(),
3222
3585
  createSyncLoader(),
3223
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3586
+ createUnlocalizableLoader(
3587
+ options.isCacheRestore,
3588
+ options.returnUnlocalizedKeys
3589
+ )
3224
3590
  );
3225
3591
  case "xcode-stringsdict":
3226
3592
  return composeLoaders(
@@ -3228,7 +3594,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3228
3594
  createXcodeStringsdictLoader(),
3229
3595
  createFlatLoader(),
3230
3596
  createSyncLoader(),
3231
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3597
+ createUnlocalizableLoader(
3598
+ options.isCacheRestore,
3599
+ options.returnUnlocalizedKeys
3600
+ )
3232
3601
  );
3233
3602
  case "xcode-xcstrings":
3234
3603
  return composeLoaders(
@@ -3239,7 +3608,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3239
3608
  createFlatLoader(),
3240
3609
  createSyncLoader(),
3241
3610
  createVariableLoader({ type: "ieee" }),
3242
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3611
+ createUnlocalizableLoader(
3612
+ options.isCacheRestore,
3613
+ options.returnUnlocalizedKeys
3614
+ )
3243
3615
  );
3244
3616
  case "yaml":
3245
3617
  return composeLoaders(
@@ -3249,7 +3621,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3249
3621
  createFlatLoader(),
3250
3622
  createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
3251
3623
  createSyncLoader(),
3252
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3624
+ createUnlocalizableLoader(
3625
+ options.isCacheRestore,
3626
+ options.returnUnlocalizedKeys
3627
+ )
3253
3628
  );
3254
3629
  case "yaml-root-key":
3255
3630
  return composeLoaders(
@@ -3259,7 +3634,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3259
3634
  createRootKeyLoader(true),
3260
3635
  createFlatLoader(),
3261
3636
  createSyncLoader(),
3262
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3637
+ createUnlocalizableLoader(
3638
+ options.isCacheRestore,
3639
+ options.returnUnlocalizedKeys
3640
+ )
3263
3641
  );
3264
3642
  case "flutter":
3265
3643
  return composeLoaders(
@@ -3269,7 +3647,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3269
3647
  createFlutterLoader(),
3270
3648
  createFlatLoader(),
3271
3649
  createSyncLoader(),
3272
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3650
+ createUnlocalizableLoader(
3651
+ options.isCacheRestore,
3652
+ options.returnUnlocalizedKeys
3653
+ )
3273
3654
  );
3274
3655
  case "xliff":
3275
3656
  return composeLoaders(
@@ -3277,7 +3658,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3277
3658
  createXliffLoader(),
3278
3659
  createFlatLoader(),
3279
3660
  createSyncLoader(),
3280
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3661
+ createUnlocalizableLoader(
3662
+ options.isCacheRestore,
3663
+ options.returnUnlocalizedKeys
3664
+ )
3281
3665
  );
3282
3666
  case "xml":
3283
3667
  return composeLoaders(
@@ -3285,28 +3669,40 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3285
3669
  createXmlLoader(),
3286
3670
  createFlatLoader(),
3287
3671
  createSyncLoader(),
3288
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3672
+ createUnlocalizableLoader(
3673
+ options.isCacheRestore,
3674
+ options.returnUnlocalizedKeys
3675
+ )
3289
3676
  );
3290
3677
  case "srt":
3291
3678
  return composeLoaders(
3292
3679
  createTextFileLoader(bucketPathPattern),
3293
3680
  createSrtLoader(),
3294
3681
  createSyncLoader(),
3295
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3682
+ createUnlocalizableLoader(
3683
+ options.isCacheRestore,
3684
+ options.returnUnlocalizedKeys
3685
+ )
3296
3686
  );
3297
3687
  case "dato":
3298
3688
  return composeLoaders(
3299
3689
  createDatoLoader(bucketPathPattern),
3300
3690
  createSyncLoader(),
3301
3691
  createFlatLoader(),
3302
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3692
+ createUnlocalizableLoader(
3693
+ options.isCacheRestore,
3694
+ options.returnUnlocalizedKeys
3695
+ )
3303
3696
  );
3304
3697
  case "vtt":
3305
3698
  return composeLoaders(
3306
3699
  createTextFileLoader(bucketPathPattern),
3307
3700
  createVttLoader(),
3308
3701
  createSyncLoader(),
3309
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3702
+ createUnlocalizableLoader(
3703
+ options.isCacheRestore,
3704
+ options.returnUnlocalizedKeys
3705
+ )
3310
3706
  );
3311
3707
  case "php":
3312
3708
  return composeLoaders(
@@ -3314,7 +3710,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3314
3710
  createPhpLoader(),
3315
3711
  createSyncLoader(),
3316
3712
  createFlatLoader(),
3317
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3713
+ createUnlocalizableLoader(
3714
+ options.isCacheRestore,
3715
+ options.returnUnlocalizedKeys
3716
+ )
3318
3717
  );
3319
3718
  case "vue-json":
3320
3719
  return composeLoaders(
@@ -3322,7 +3721,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3322
3721
  createVueJsonLoader(),
3323
3722
  createSyncLoader(),
3324
3723
  createFlatLoader(),
3325
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3724
+ createUnlocalizableLoader(
3725
+ options.isCacheRestore,
3726
+ options.returnUnlocalizedKeys
3727
+ )
3326
3728
  );
3327
3729
  }
3328
3730
  }
@@ -3345,23 +3747,6 @@ var cacheChunk = (targetLocale, sourceChunk, processedChunk) => {
3345
3747
  }));
3346
3748
  _appendToCache(rows);
3347
3749
  };
3348
- function getNormalizedCache() {
3349
- const rows = _loadCache();
3350
- if (!rows.length) {
3351
- return null;
3352
- }
3353
- const normalized = {};
3354
- for (const row of rows) {
3355
- if (!normalized[row.targetLocale]) {
3356
- normalized[row.targetLocale] = {};
3357
- }
3358
- normalized[row.targetLocale][row.key] = {
3359
- source: row.source,
3360
- result: row.processed
3361
- };
3362
- }
3363
- return normalized;
3364
- }
3365
3750
  function deleteCache() {
3366
3751
  const cacheFilePath = _getCacheFilePath();
3367
3752
  try {
@@ -3369,15 +3754,6 @@ function deleteCache() {
3369
3754
  } catch (e) {
3370
3755
  }
3371
3756
  }
3372
- function _loadCache() {
3373
- const cacheFilePath = _getCacheFilePath();
3374
- if (!fs10.existsSync(cacheFilePath)) {
3375
- return [];
3376
- }
3377
- const content = fs10.readFileSync(cacheFilePath, "utf-8");
3378
- const result = _parseJSONLines(content);
3379
- return result;
3380
- }
3381
3757
  function _appendToCache(rows) {
3382
3758
  const cacheFilePath = _getCacheFilePath();
3383
3759
  const lines = _buildJSONLines(rows);
@@ -3389,16 +3765,6 @@ function _getCacheFilePath() {
3389
3765
  function _buildJSONLines(rows) {
3390
3766
  return rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
3391
3767
  }
3392
- function _parseJSONLines(lines) {
3393
- return lines.split("\n").map(_tryParseJSON).filter((line) => line !== null);
3394
- }
3395
- function _tryParseJSON(line) {
3396
- try {
3397
- return JSON.parse(line);
3398
- } catch (e) {
3399
- return null;
3400
- }
3401
- }
3402
3768
 
3403
3769
  // src/cli/processor/lingo.ts
3404
3770
  import { LingoDotDevEngine } from "@lingo.dev/_sdk";
@@ -3565,9 +3931,8 @@ async function trackEvent(distinctId, event, properties) {
3565
3931
  }
3566
3932
 
3567
3933
  // src/cli/utils/delta.ts
3568
- import _21 from "lodash";
3934
+ import _20 from "lodash";
3569
3935
  import z from "zod";
3570
- import { MD5 } from "object-hash";
3571
3936
 
3572
3937
  // src/cli/utils/fs.ts
3573
3938
  import * as fs11 from "fs";
@@ -3615,14 +3980,14 @@ function createDeltaProcessor(fileKey) {
3615
3980
  return checkIfFileExists(lockfilePath);
3616
3981
  },
3617
3982
  async calculateDelta(params) {
3618
- let added = _21.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
3619
- let removed = _21.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
3620
- const updated = _21.filter(Object.keys(params.sourceData), (key) => {
3621
- return MD5(params.sourceData[key]) !== params.checksums[key] && params.checksums[key];
3983
+ let added = _20.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
3984
+ let removed = _20.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
3985
+ const updated = _20.filter(Object.keys(params.sourceData), (key) => {
3986
+ return md5(params.sourceData[key]) !== params.checksums[key] && params.checksums[key];
3622
3987
  });
3623
3988
  const renamed = [];
3624
3989
  for (const addedKey of added) {
3625
- const addedHash = MD5(params.sourceData[addedKey]);
3990
+ const addedHash = md5(params.sourceData[addedKey]);
3626
3991
  for (const removedKey of removed) {
3627
3992
  if (params.checksums[removedKey] === addedHash) {
3628
3993
  renamed.push([removedKey, addedKey]);
@@ -3655,18 +4020,18 @@ function createDeltaProcessor(fileKey) {
3655
4020
  writeFile(lockfilePath, lockfileYaml);
3656
4021
  },
3657
4022
  async loadChecksums() {
3658
- const id = MD5(fileKey);
4023
+ const id = md5(fileKey);
3659
4024
  const lockfileData = await this.loadLock();
3660
4025
  return lockfileData.checksums[id] || {};
3661
4026
  },
3662
4027
  async saveChecksums(checksums) {
3663
- const id = MD5(fileKey);
4028
+ const id = md5(fileKey);
3664
4029
  const lockfileData = await this.loadLock();
3665
4030
  lockfileData.checksums[id] = checksums;
3666
4031
  await this.saveLock(lockfileData);
3667
4032
  },
3668
4033
  async createChecksums(sourceData) {
3669
- const checksums = _21.mapValues(sourceData, (value) => MD5(value));
4034
+ const checksums = _20.mapValues(sourceData, (value) => md5(value));
3670
4035
  return checksums;
3671
4036
  }
3672
4037
  };
@@ -3674,7 +4039,15 @@ function createDeltaProcessor(fileKey) {
3674
4039
 
3675
4040
  // src/cli/cmd/i18n.ts
3676
4041
  import { flatten as flatten2, unflatten as unflatten2 } from "flat";
3677
- var i18n_default = new Command6().command("i18n").description("Run Localization engine").helpOption("-h, --help", "Show help").option("--locale <locale>", "Locale to process", (val, prev) => prev ? [...prev, val] : [val]).option("--bucket <bucket>", "Bucket to process", (val, prev) => prev ? [...prev, val] : [val]).option(
4042
+ var i18n_default = new Command6().command("i18n").description("Run Localization engine").helpOption("-h, --help", "Show help").option(
4043
+ "--locale <locale>",
4044
+ "Locale to process",
4045
+ (val, prev) => prev ? [...prev, val] : [val]
4046
+ ).option(
4047
+ "--bucket <bucket>",
4048
+ "Bucket to process",
4049
+ (val, prev) => prev ? [...prev, val] : [val]
4050
+ ).option(
3678
4051
  "--key <key>",
3679
4052
  "Key to process. Process only a specific translation key, useful for debugging or updating a single entry"
3680
4053
  ).option(
@@ -3683,7 +4056,25 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3683
4056
  ).option(
3684
4057
  "--frozen",
3685
4058
  `Run in read-only mode - fails if any translations need updating, useful for CI/CD pipelines to detect missing translations`
3686
- ).option("--force", "Ignore lockfile and process all keys, useful for full re-translation").option("--verbose", "Show detailed output including intermediate processing data and API communication details").option("--interactive", "Enable interactive mode for reviewing and editing translations before they are applied").option("--api-key <api-key>", "Explicitly set the API key to use, override the default API key from settings").option("--debug", "Pause execution at start for debugging purposes, waits for user confirmation before proceeding").option("--strict", "Stop processing on first error instead of continuing with other locales/buckets").action(async function(options) {
4059
+ ).option(
4060
+ "--force",
4061
+ "Ignore lockfile and process all keys, useful for full re-translation"
4062
+ ).option(
4063
+ "--verbose",
4064
+ "Show detailed output including intermediate processing data and API communication details"
4065
+ ).option(
4066
+ "--interactive",
4067
+ "Enable interactive mode for reviewing and editing translations before they are applied"
4068
+ ).option(
4069
+ "--api-key <api-key>",
4070
+ "Explicitly set the API key to use, override the default API key from settings"
4071
+ ).option(
4072
+ "--debug",
4073
+ "Pause execution at start for debugging purposes, waits for user confirmation before proceeding"
4074
+ ).option(
4075
+ "--strict",
4076
+ "Stop processing on first error instead of continuing with other locales/buckets"
4077
+ ).action(async function(options) {
3687
4078
  updateGitignore();
3688
4079
  const ora = Ora5();
3689
4080
  const flags = parseFlags(options);
@@ -3716,7 +4107,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3716
4107
  });
3717
4108
  let buckets = getBuckets(i18nConfig);
3718
4109
  if (flags.bucket?.length) {
3719
- buckets = buckets.filter((bucket) => flags.bucket.includes(bucket.type));
4110
+ buckets = buckets.filter(
4111
+ (bucket) => flags.bucket.includes(bucket.type)
4112
+ );
3720
4113
  }
3721
4114
  ora.succeed("Buckets retrieved");
3722
4115
  if (flags.file?.length) {
@@ -3727,7 +4120,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3727
4120
  return { ...bucket, paths };
3728
4121
  }).filter((bucket) => bucket.paths.length > 0);
3729
4122
  if (buckets.length === 0) {
3730
- ora.fail("No buckets found. All buckets were filtered out by --file option.");
4123
+ ora.fail(
4124
+ "No buckets found. All buckets were filtered out by --file option."
4125
+ );
3731
4126
  process.exit(1);
3732
4127
  } else {
3733
4128
  ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
@@ -3747,7 +4142,10 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3747
4142
  ora.start("Creating i18n.lock...");
3748
4143
  for (const bucket of buckets) {
3749
4144
  for (const bucketPath of bucket.paths) {
3750
- const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
4145
+ const sourceLocale = resolveOverriddenLocale3(
4146
+ i18nConfig.locale.source,
4147
+ bucketPath.delimiter
4148
+ );
3751
4149
  const bucketLoader = createBucketLoader(
3752
4150
  bucket.type,
3753
4151
  bucketPath.pathPattern,
@@ -3760,7 +4158,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3760
4158
  );
3761
4159
  bucketLoader.setDefaultLocale(sourceLocale);
3762
4160
  await bucketLoader.init();
3763
- const sourceData = await bucketLoader.pull(i18nConfig.locale.source);
4161
+ const sourceData = await bucketLoader.pull(
4162
+ i18nConfig.locale.source
4163
+ );
3764
4164
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3765
4165
  const checksums = await deltaProcessor.createChecksums(sourceData);
3766
4166
  await deltaProcessor.saveChecksums(checksums);
@@ -3776,9 +4176,15 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3776
4176
  }
3777
4177
  ora.start("Validating localization state...");
3778
4178
  for (const bucketPath of bucket.paths) {
3779
- const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
4179
+ const sourceLocale = resolveOverriddenLocale3(
4180
+ i18nConfig.locale.source,
4181
+ bucketPath.delimiter
4182
+ );
3780
4183
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3781
- const sourcePath = path15.join(process.cwd(), bucketPath.pathPattern.replace("[locale]", sourceLocale));
4184
+ const sourcePath = path15.join(
4185
+ process.cwd(),
4186
+ bucketPath.pathPattern.replace("[locale]", sourceLocale)
4187
+ );
3782
4188
  const sourceContent = tryReadFile(sourcePath, null);
3783
4189
  const sourceData = JSON.parse(sourceContent || "{}");
3784
4190
  const sourceFlattenedData = flatten2(sourceData, {
@@ -3788,8 +4194,14 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3788
4194
  }
3789
4195
  });
3790
4196
  for (const _targetLocale of targetLocales) {
3791
- const targetLocale = resolveOverriddenLocale3(_targetLocale, bucketPath.delimiter);
3792
- const targetPath = path15.join(process.cwd(), bucketPath.pathPattern.replace("[locale]", targetLocale));
4197
+ const targetLocale = resolveOverriddenLocale3(
4198
+ _targetLocale,
4199
+ bucketPath.delimiter
4200
+ );
4201
+ const targetPath = path15.join(
4202
+ process.cwd(),
4203
+ bucketPath.pathPattern.replace("[locale]", targetLocale)
4204
+ );
3793
4205
  const targetContent = tryReadFile(targetPath, null);
3794
4206
  const targetData = JSON.parse(targetContent || "{}");
3795
4207
  const targetFlattenedData = flatten2(targetData, {
@@ -3817,68 +4229,23 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3817
4229
  return decodeURIComponent(key);
3818
4230
  }
3819
4231
  });
3820
- await writeFile(targetPath, JSON.stringify(updatedTargetData, null, 2));
3821
- }
3822
- }
3823
- ora.succeed("Localization state check completed");
3824
- }
3825
- const cache = getNormalizedCache();
3826
- if (cache) {
3827
- console.log();
3828
- ora.succeed(`Cache loaded. Attempting recovery...`);
3829
- const cacheOra = Ora5({ indent: 2 });
3830
- for (const bucket of buckets) {
3831
- cacheOra.info(`Processing bucket: ${bucket.type}`);
3832
- for (const bucketPath of bucket.paths) {
3833
- const bucketOra = Ora5({ indent: 4 });
3834
- bucketOra.info(`Processing path: ${bucketPath.pathPattern}`);
3835
- const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
3836
- const bucketLoader = createBucketLoader(
3837
- bucket.type,
3838
- bucketPath.pathPattern,
3839
- {
3840
- isCacheRestore: true,
3841
- defaultLocale: sourceLocale,
3842
- injectLocale: bucket.injectLocale
3843
- },
3844
- bucket.lockedKeys
4232
+ await writeFile(
4233
+ targetPath,
4234
+ JSON.stringify(updatedTargetData, null, 2)
3845
4235
  );
3846
- bucketLoader.setDefaultLocale(sourceLocale);
3847
- await bucketLoader.init();
3848
- const sourceData = await bucketLoader.pull(sourceLocale);
3849
- const cachedSourceData = {};
3850
- for (const targetLocale in cache) {
3851
- const targetData = await bucketLoader.pull(targetLocale);
3852
- for (const key in cache[targetLocale]) {
3853
- const { source, result } = cache[targetLocale][key];
3854
- if (sourceData[key] === source && targetData[key] !== result) {
3855
- targetData[key] = result;
3856
- cachedSourceData[key] = source;
3857
- }
3858
- }
3859
- await bucketLoader.push(targetLocale, targetData);
3860
- const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3861
- const checksums = await deltaProcessor.createChecksums(cachedSourceData);
3862
- await deltaProcessor.saveChecksums(checksums);
3863
- bucketOra.succeed(
3864
- `[${sourceLocale} -> ${targetLocale}] Recovered ${Object.keys(cachedSourceData).length} entries from cache`
3865
- );
3866
- }
3867
4236
  }
3868
4237
  }
3869
- deleteCache();
3870
- if (flags.verbose) {
3871
- cacheOra.info("Cache file deleted.");
3872
- }
3873
- } else if (flags.verbose) {
3874
- ora.info("Cache file not found. Skipping recovery.");
4238
+ ora.succeed("Localization state check completed");
3875
4239
  }
3876
4240
  if (flags.frozen) {
3877
4241
  ora.start("Checking for lockfile updates...");
3878
4242
  let requiresUpdate = null;
3879
4243
  bucketLoop: for (const bucket of buckets) {
3880
4244
  for (const bucketPath of bucket.paths) {
3881
- const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
4245
+ const sourceLocale = resolveOverriddenLocale3(
4246
+ i18nConfig.locale.source,
4247
+ bucketPath.delimiter
4248
+ );
3882
4249
  const bucketLoader = createBucketLoader(
3883
4250
  bucket.type,
3884
4251
  bucketPath.pathPattern,
@@ -3892,13 +4259,11 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3892
4259
  );
3893
4260
  bucketLoader.setDefaultLocale(sourceLocale);
3894
4261
  await bucketLoader.init();
3895
- const { unlocalizable: sourceUnlocalizable, ...sourceData } = await bucketLoader.pull(
3896
- i18nConfig.locale.source
3897
- );
4262
+ const { unlocalizable: sourceUnlocalizable, ...sourceData } = await bucketLoader.pull(i18nConfig.locale.source);
3898
4263
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3899
4264
  const sourceChecksums = await deltaProcessor.createChecksums(sourceData);
3900
4265
  const savedChecksums = await deltaProcessor.loadChecksums();
3901
- const updatedSourceData = _22.pickBy(
4266
+ const updatedSourceData = _21.pickBy(
3902
4267
  sourceData,
3903
4268
  (value, key) => sourceChecksums[key] !== savedChecksums[key]
3904
4269
  );
@@ -3907,11 +4272,23 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3907
4272
  break bucketLoop;
3908
4273
  }
3909
4274
  for (const _targetLocale of targetLocales) {
3910
- const targetLocale = resolveOverriddenLocale3(_targetLocale, bucketPath.delimiter);
4275
+ const targetLocale = resolveOverriddenLocale3(
4276
+ _targetLocale,
4277
+ bucketPath.delimiter
4278
+ );
3911
4279
  const { unlocalizable: targetUnlocalizable, ...targetData } = await bucketLoader.pull(targetLocale);
3912
- const missingKeys = _22.difference(Object.keys(sourceData), Object.keys(targetData));
3913
- const extraKeys = _22.difference(Object.keys(targetData), Object.keys(sourceData));
3914
- const unlocalizableDataDiff = !_22.isEqual(sourceUnlocalizable, targetUnlocalizable);
4280
+ const missingKeys = _21.difference(
4281
+ Object.keys(sourceData),
4282
+ Object.keys(targetData)
4283
+ );
4284
+ const extraKeys = _21.difference(
4285
+ Object.keys(targetData),
4286
+ Object.keys(sourceData)
4287
+ );
4288
+ const unlocalizableDataDiff = !_21.isEqual(
4289
+ sourceUnlocalizable,
4290
+ targetUnlocalizable
4291
+ );
3915
4292
  if (missingKeys.length > 0) {
3916
4293
  requiresUpdate = "missing";
3917
4294
  break bucketLoop;
@@ -3934,7 +4311,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3934
4311
  extra: "Target file has extra translations not present in the source file.",
3935
4312
  unlocalizable: "Unlocalizable data (such as booleans, dates, URLs, etc.) do not match."
3936
4313
  }[requiresUpdate];
3937
- ora.fail(`Localization data has changed; please update i18n.lock or run without --frozen.`);
4314
+ ora.fail(
4315
+ `Localization data has changed; please update i18n.lock or run without --frozen.`
4316
+ );
3938
4317
  ora.fail(` Details: ${message}`);
3939
4318
  process.exit(1);
3940
4319
  } else {
@@ -3946,8 +4325,13 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3946
4325
  console.log();
3947
4326
  ora.info(`Processing bucket: ${bucket.type}`);
3948
4327
  for (const bucketPath of bucket.paths) {
3949
- const bucketOra = Ora5({ indent: 2 }).info(`Processing path: ${bucketPath.pathPattern}`);
3950
- const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
4328
+ const bucketOra = Ora5({ indent: 2 }).info(
4329
+ `Processing path: ${bucketPath.pathPattern}`
4330
+ );
4331
+ const sourceLocale = resolveOverriddenLocale3(
4332
+ i18nConfig.locale.source,
4333
+ bucketPath.delimiter
4334
+ );
3951
4335
  const bucketLoader = createBucketLoader(
3952
4336
  bucket.type,
3953
4337
  bucketPath.pathPattern,
@@ -3962,21 +4346,33 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3962
4346
  await bucketLoader.init();
3963
4347
  let sourceData = await bucketLoader.pull(sourceLocale);
3964
4348
  for (const _targetLocale of targetLocales) {
3965
- const targetLocale = resolveOverriddenLocale3(_targetLocale, bucketPath.delimiter);
4349
+ const targetLocale = resolveOverriddenLocale3(
4350
+ _targetLocale,
4351
+ bucketPath.delimiter
4352
+ );
3966
4353
  try {
3967
- bucketOra.start(`[${sourceLocale} -> ${targetLocale}] (0%) Localization in progress...`);
4354
+ bucketOra.start(
4355
+ `[${sourceLocale} -> ${targetLocale}] (0%) Localization in progress...`
4356
+ );
3968
4357
  sourceData = await bucketLoader.pull(sourceLocale);
3969
4358
  const targetData = await bucketLoader.pull(targetLocale);
3970
- const deltaProcessor2 = createDeltaProcessor(bucketPath.pathPattern);
4359
+ const deltaProcessor2 = createDeltaProcessor(
4360
+ bucketPath.pathPattern
4361
+ );
3971
4362
  const checksums2 = await deltaProcessor2.loadChecksums();
3972
4363
  const delta = await deltaProcessor2.calculateDelta({
3973
4364
  sourceData,
3974
4365
  targetData,
3975
4366
  checksums: checksums2
3976
4367
  });
3977
- let processableData = _22.chain(sourceData).entries().filter(([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!flags.force).fromPairs().value();
4368
+ let processableData = _21.chain(sourceData).entries().filter(
4369
+ ([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!flags.force
4370
+ ).fromPairs().value();
3978
4371
  if (flags.key) {
3979
- processableData = _22.pickBy(processableData, (_25, key) => key === flags.key);
4372
+ processableData = _21.pickBy(
4373
+ processableData,
4374
+ (_24, key) => key === flags.key
4375
+ );
3980
4376
  }
3981
4377
  if (flags.verbose) {
3982
4378
  bucketOra.info(JSON.stringify(processableData, null, 2));
@@ -3988,7 +4384,11 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3988
4384
  apiKey: settings.auth.apiKey,
3989
4385
  apiUrl: settings.auth.apiUrl
3990
4386
  });
3991
- processPayload = withExponentialBackoff(processPayload, 3, 1e3);
4387
+ processPayload = withExponentialBackoff(
4388
+ processPayload,
4389
+ 3,
4390
+ 1e3
4391
+ );
3992
4392
  const processedTargetData = await processPayload(
3993
4393
  {
3994
4394
  sourceLocale,
@@ -4013,7 +4413,12 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4013
4413
  if (flags.verbose) {
4014
4414
  bucketOra.info(JSON.stringify(processedTargetData, null, 2));
4015
4415
  }
4016
- let finalTargetData = _22.merge({}, sourceData, targetData, processedTargetData);
4416
+ let finalTargetData = _21.merge(
4417
+ {},
4418
+ sourceData,
4419
+ targetData,
4420
+ processedTargetData
4421
+ );
4017
4422
  if (flags.interactive) {
4018
4423
  bucketOra.stop();
4019
4424
  const reviewedData = await reviewChanges({
@@ -4025,17 +4430,25 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4025
4430
  force: flags.force
4026
4431
  });
4027
4432
  finalTargetData = reviewedData;
4028
- bucketOra.start(`Applying changes to ${bucketPath} (${targetLocale})`);
4433
+ bucketOra.start(
4434
+ `Applying changes to ${bucketPath} (${targetLocale})`
4435
+ );
4029
4436
  }
4030
- const finalDiffSize = _22.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
4437
+ const finalDiffSize = _21.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
4031
4438
  await bucketLoader.push(targetLocale, finalTargetData);
4032
4439
  if (finalDiffSize > 0 || flags.force) {
4033
- bucketOra.succeed(`[${sourceLocale} -> ${targetLocale}] Localization completed`);
4440
+ bucketOra.succeed(
4441
+ `[${sourceLocale} -> ${targetLocale}] Localization completed`
4442
+ );
4034
4443
  } else {
4035
- bucketOra.succeed(`[${sourceLocale} -> ${targetLocale}] Localization completed (no changes).`);
4444
+ bucketOra.succeed(
4445
+ `[${sourceLocale} -> ${targetLocale}] Localization completed (no changes).`
4446
+ );
4036
4447
  }
4037
4448
  } catch (_error) {
4038
- const error = new Error(`[${sourceLocale} -> ${targetLocale}] Localization failed: ${_error.message}`);
4449
+ const error = new Error(
4450
+ `[${sourceLocale} -> ${targetLocale}] Localization failed: ${_error.message}`
4451
+ );
4039
4452
  if (flags.strict) {
4040
4453
  throw error;
4041
4454
  } else {
@@ -4049,7 +4462,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4049
4462
  await deltaProcessor.saveChecksums(checksums);
4050
4463
  }
4051
4464
  } catch (_error) {
4052
- const error = new Error(`Failed to process bucket ${bucket.type}: ${_error.message}`);
4465
+ const error = new Error(
4466
+ `Failed to process bucket ${bucket.type}: ${_error.message}`
4467
+ );
4053
4468
  if (flags.strict) {
4054
4469
  throw error;
4055
4470
  } else {
@@ -4132,7 +4547,9 @@ function validateParams(i18nConfig, flags) {
4132
4547
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
4133
4548
  docUrl: "localeTargetNotFound"
4134
4549
  });
4135
- } else if (flags.bucket?.some((bucket) => !i18nConfig.buckets[bucket])) {
4550
+ } else if (flags.bucket?.some(
4551
+ (bucket) => !i18nConfig.buckets[bucket]
4552
+ )) {
4136
4553
  throw new CLIError({
4137
4554
  message: `One or more specified buckets do not exist in i18n.json. Please add them to the list and try again.`,
4138
4555
  docUrl: "bucketNotFound"
@@ -4164,8 +4581,10 @@ ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targetLocale)}): ${chalk.gr
4164
4581
  if (line.startsWith("@")) return chalk.cyan(line);
4165
4582
  return line;
4166
4583
  }).join("\n");
4167
- console.log(`
4168
- Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targetLocale)}):`);
4584
+ console.log(
4585
+ `
4586
+ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targetLocale)}):`
4587
+ );
4169
4588
  console.log(coloredDiff);
4170
4589
  const { action } = await inquirer2.prompt([
4171
4590
  {
@@ -4187,7 +4606,7 @@ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targe
4187
4606
  return args.currentData;
4188
4607
  }
4189
4608
  const customData = { ...args.currentData };
4190
- const changes = _22.reduce(
4609
+ const changes = _21.reduce(
4191
4610
  args.proposedData,
4192
4611
  (result, value, key) => {
4193
4612
  if (args.currentData[key] !== value) {
@@ -4201,9 +4620,19 @@ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targe
4201
4620
  console.log(`
4202
4621
  Editing value for: ${chalk.cyan(key)}`);
4203
4622
  console.log(chalk.gray("Source text:"), chalk.blue(args.sourceData[key]));
4204
- console.log(chalk.gray("Current value:"), chalk.red(args.currentData[key] || "(empty)"));
4205
- console.log(chalk.gray("Suggested value:"), chalk.green(args.proposedData[key]));
4206
- console.log(chalk.gray("\nYour editor will open. Edit the text and save to continue."));
4623
+ console.log(
4624
+ chalk.gray("Current value:"),
4625
+ chalk.red(args.currentData[key] || "(empty)")
4626
+ );
4627
+ console.log(
4628
+ chalk.gray("Suggested value:"),
4629
+ chalk.green(args.proposedData[key])
4630
+ );
4631
+ console.log(
4632
+ chalk.gray(
4633
+ "\nYour editor will open. Edit the text and save to continue."
4634
+ )
4635
+ );
4207
4636
  console.log(chalk.gray("------------"));
4208
4637
  try {
4209
4638
  const editorContent = [
@@ -4224,11 +4653,15 @@ Editing value for: ${chalk.cyan(key)}`);
4224
4653
  if (customValue) {
4225
4654
  customData[key] = customValue;
4226
4655
  } else {
4227
- console.log(chalk.yellow("Empty value provided, keeping the current value."));
4656
+ console.log(
4657
+ chalk.yellow("Empty value provided, keeping the current value.")
4658
+ );
4228
4659
  customData[key] = args.currentData[key] || args.proposedData[key];
4229
4660
  }
4230
4661
  } catch (error) {
4231
- console.log(chalk.red("Error while editing, keeping the suggested value."));
4662
+ console.log(
4663
+ chalk.red("Error while editing, keeping the suggested value.")
4664
+ );
4232
4665
  customData[key] = args.proposedData[key];
4233
4666
  }
4234
4667
  }
@@ -4246,7 +4679,7 @@ import path16 from "path";
4246
4679
  import Z4 from "zod";
4247
4680
  import YAML4 from "yaml";
4248
4681
  import { MD5 as MD52 } from "object-hash";
4249
- import _23 from "lodash";
4682
+ import _22 from "lodash";
4250
4683
  function createLockfileHelper() {
4251
4684
  return {
4252
4685
  isLockfileExists: () => {
@@ -4256,23 +4689,23 @@ function createLockfileHelper() {
4256
4689
  registerSourceData: (pathPattern, sourceData) => {
4257
4690
  const lockfile = _loadLockfile();
4258
4691
  const sectionKey = MD52(pathPattern);
4259
- const sectionChecksums = _23.mapValues(sourceData, (value) => MD52(value));
4692
+ const sectionChecksums = _22.mapValues(sourceData, (value) => MD52(value));
4260
4693
  lockfile.checksums[sectionKey] = sectionChecksums;
4261
4694
  _saveLockfile(lockfile);
4262
4695
  },
4263
4696
  registerPartialSourceData: (pathPattern, partialSourceData) => {
4264
4697
  const lockfile = _loadLockfile();
4265
4698
  const sectionKey = MD52(pathPattern);
4266
- const sectionChecksums = _23.mapValues(partialSourceData, (value) => MD52(value));
4267
- lockfile.checksums[sectionKey] = _23.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
4699
+ const sectionChecksums = _22.mapValues(partialSourceData, (value) => MD52(value));
4700
+ lockfile.checksums[sectionKey] = _22.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
4268
4701
  _saveLockfile(lockfile);
4269
4702
  },
4270
4703
  extractUpdatedData: (pathPattern, sourceData) => {
4271
4704
  const lockfile = _loadLockfile();
4272
4705
  const sectionKey = MD52(pathPattern);
4273
- const currentChecksums = _23.mapValues(sourceData, (value) => MD52(value));
4706
+ const currentChecksums = _22.mapValues(sourceData, (value) => MD52(value));
4274
4707
  const savedChecksums = lockfile.checksums[sectionKey] || {};
4275
- const updatedData = _23.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4708
+ const updatedData = _22.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4276
4709
  return updatedData;
4277
4710
  }
4278
4711
  };
@@ -4342,7 +4775,7 @@ var flagsSchema = Z5.object({
4342
4775
  // src/cli/cmd/cleanup.ts
4343
4776
  import { resolveOverriddenLocale as resolveOverriddenLocale5 } from "@lingo.dev/_spec";
4344
4777
  import { Command as Command8 } from "interactive-commander";
4345
- import _24 from "lodash";
4778
+ import _23 from "lodash";
4346
4779
  import Ora7 from "ora";
4347
4780
  var cleanup_default = new Command8().command("cleanup").description("Remove keys from target files that do not exist in the source file").helpOption("-h, --help", "Show help").option("--locale <locale>", "Specific locale to cleanup").option("--bucket <bucket>", "Specific bucket to cleanup").option("--dry-run", "Show what would be removed without making changes").option(
4348
4781
  "--verbose",
@@ -4378,7 +4811,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
4378
4811
  try {
4379
4812
  const targetData = await bucketLoader.pull(targetLocale);
4380
4813
  const targetKeys = Object.keys(targetData);
4381
- const keysToRemove = _24.difference(targetKeys, sourceKeys);
4814
+ const keysToRemove = _23.difference(targetKeys, sourceKeys);
4382
4815
  if (keysToRemove.length === 0) {
4383
4816
  bucketOra.succeed(`[${targetLocale}] No keys to remove`);
4384
4817
  continue;
@@ -4387,7 +4820,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
4387
4820
  bucketOra.info(`[${targetLocale}] Keys to remove: ${JSON.stringify(keysToRemove, null, 2)}`);
4388
4821
  }
4389
4822
  if (!options.dryRun) {
4390
- const cleanedData = _24.pick(targetData, sourceKeys);
4823
+ const cleanedData = _23.pick(targetData, sourceKeys);
4391
4824
  await bucketLoader.push(targetLocale, cleanedData);
4392
4825
  bucketOra.succeed(`[${targetLocale}] Removed ${keysToRemove.length} keys`);
4393
4826
  } else {
@@ -4442,7 +4875,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
4442
4875
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4443
4876
  import Z6 from "zod";
4444
4877
  import { ReplexicaEngine } from "@lingo.dev/_sdk";
4445
- var mcp_default = new Command9().command("mcp").description("Use Lingo.dev model context provider with your AI agent").helpOption("-h, --help", "Show help").action(async (_25, program) => {
4878
+ var mcp_default = new Command9().command("mcp").description("Use Lingo.dev model context provider with your AI agent").helpOption("-h, --help", "Show help").action(async (_24, program) => {
4446
4879
  const apiKey = program.args[0];
4447
4880
  const settings = getSettings(apiKey);
4448
4881
  if (!settings.auth.apiKey) {
@@ -5523,7 +5956,7 @@ function validateParams2(i18nConfig, flags) {
5523
5956
  // package.json
5524
5957
  var package_default = {
5525
5958
  name: "lingo.dev",
5526
- version: "0.86.0",
5959
+ version: "0.87.0",
5527
5960
  description: "Lingo.dev CLI",
5528
5961
  private: false,
5529
5962
  publishConfig: {
@@ -5597,6 +6030,7 @@ var package_default = {
5597
6030
  "csv-parse": "^5.6.0",
5598
6031
  "csv-stringify": "^6.5.2",
5599
6032
  "date-fns": "^4.1.0",
6033
+ dedent: "^1.5.3",
5600
6034
  diff: "^7.0.0",
5601
6035
  dotenv: "^16.4.7",
5602
6036
  express: "^4.21.2",
@@ -5616,6 +6050,9 @@ var package_default = {
5616
6050
  jsonrepair: "^3.11.2",
5617
6051
  lodash: "^4.17.21",
5618
6052
  marked: "^15.0.6",
6053
+ "mdast-util-from-markdown": "^2.0.2",
6054
+ "mdast-util-gfm": "^3.1.0",
6055
+ "micromark-extension-gfm": "^3.0.0",
5619
6056
  "node-webvtt": "^1.9.4",
5620
6057
  "object-hash": "^3.0.0",
5621
6058
  octokit: "^4.0.2",
@@ -5626,14 +6063,18 @@ var package_default = {
5626
6063
  plist: "^3.1.0",
5627
6064
  "posthog-node": "^4.11.2",
5628
6065
  prettier: "^3.4.2",
6066
+ "rehype-stringify": "^10.0.1",
6067
+ "remark-disable-tokenizers": "^1.1.1",
5629
6068
  "remark-frontmatter": "^5.0.0",
5630
6069
  "remark-gfm": "^4.0.1",
5631
6070
  "remark-mdx": "^3.1.0",
5632
6071
  "remark-mdx-frontmatter": "^5.1.0",
5633
6072
  "remark-parse": "^11.0.0",
6073
+ "remark-rehype": "^11.1.2",
5634
6074
  "remark-stringify": "^11.0.0",
5635
6075
  "srt-parser-2": "^1.2.3",
5636
6076
  unified: "^11.0.5",
6077
+ "unist-util-visit": "^5.0.0",
5637
6078
  vfile: "^6.0.3",
5638
6079
  xliff: "^6.2.1",
5639
6080
  xml2js: "^0.6.2",