lingo.dev 0.85.7 → 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,58 +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 remarkMdx from "remark-mdx";
1645
- import remarkFrontmatter from "remark-frontmatter";
1646
- import remarkGfm from "remark-gfm";
1647
- import remarkStringify from "remark-stringify";
1648
- import remarkMdxFrontmatter from "remark-mdx-frontmatter";
1649
- import { VFile } from "vfile";
1650
- var parser = unified().use(remarkParse).use(remarkMdx).use(remarkFrontmatter, ["yaml"]).use(remarkMdxFrontmatter).use(remarkGfm);
1651
- var serializer = unified().use(remarkStringify).use(remarkMdx).use(remarkFrontmatter, ["yaml"]).use(remarkMdxFrontmatter).use(remarkGfm);
1652
- function createMdxFormatLoader() {
1653
- return createLoader({
1654
- async pull(locale, input2) {
1655
- const file = new VFile(input2);
1656
- const ast = parser.parse(file);
1657
- return JSON.parse(JSON.stringify(ast));
1658
- },
1659
- async push(locale, data) {
1660
- const ast = data;
1661
- const content = String(serializer.stringify(ast));
1662
- return content;
1663
- }
1664
- });
1665
- }
1666
- function createDoubleSerializationLoader() {
1667
- return createLoader({
1668
- async pull(locale, input2) {
1669
- return input2;
1670
- },
1671
- async push(locale, data) {
1672
- const file = new VFile(data);
1673
- const ast = parser.parse(file);
1674
- const finalContent = String(serializer.stringify(ast));
1675
- return finalContent;
1676
- }
1677
- });
1678
- }
1679
- function createMdxStructureLoader() {
1680
- return createLoader({
1681
- async pull(locale, input2) {
1682
- const result = _9.chain(input2).pickBy((value, key) => key.endsWith("/value")).value();
1683
- return result;
1684
- },
1685
- async push(locale, data, originalInput) {
1686
- const result = _9.merge({}, originalInput, data);
1687
- return result;
1688
- }
1689
- });
1690
- }
1691
-
1692
1643
  // src/cli/loaders/properties.ts
1693
1644
  function createPropertiesLoader() {
1694
1645
  return createLoader({
@@ -1708,7 +1659,7 @@ function createPropertiesLoader() {
1708
1659
  return result;
1709
1660
  },
1710
1661
  async push(locale, payload) {
1711
- 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");
1712
1663
  return result;
1713
1664
  }
1714
1665
  });
@@ -1794,7 +1745,7 @@ function createXcodeStringsdictLoader() {
1794
1745
  }
1795
1746
 
1796
1747
  // src/cli/loaders/xcode-xcstrings.ts
1797
- import _10 from "lodash";
1748
+ import _9 from "lodash";
1798
1749
  function createXcodeXcstringsLoader(defaultLocale) {
1799
1750
  return createLoader({
1800
1751
  async pull(locale, input2, initCtx) {
@@ -1824,13 +1775,12 @@ function createXcodeXcstringsLoader(defaultLocale) {
1824
1775
  resultData[translationKey] = translationKey;
1825
1776
  }
1826
1777
  }
1827
- console.log(resultData);
1828
1778
  return resultData;
1829
1779
  },
1830
1780
  async push(locale, payload, originalInput) {
1831
1781
  const langDataToMerge = {};
1832
1782
  langDataToMerge.strings = {};
1833
- const input2 = _10.cloneDeep(originalInput) || { sourceLanguage: locale, strings: {} };
1783
+ const input2 = _9.cloneDeep(originalInput) || { sourceLanguage: locale, strings: {} };
1834
1784
  for (const [key, value] of Object.entries(payload)) {
1835
1785
  if (value === null || value === void 0) {
1836
1786
  continue;
@@ -1876,7 +1826,7 @@ function createXcodeXcstringsLoader(defaultLocale) {
1876
1826
  }
1877
1827
  }
1878
1828
  }
1879
- const result = _10.merge({}, originalInput, langDataToMerge);
1829
+ const result = _9.merge({}, originalInput, langDataToMerge);
1880
1830
  return result;
1881
1831
  }
1882
1832
  });
@@ -1888,41 +1838,20 @@ import prettier from "prettier";
1888
1838
  function createPrettierLoader(options) {
1889
1839
  return createLoader({
1890
1840
  async pull(locale, data) {
1891
- 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);
1892
1847
  },
1893
1848
  async push(locale, data) {
1894
- const draftPath = options.bucketPathPattern.replaceAll("[locale]", locale);
1849
+ const draftPath = options.bucketPathPattern.replaceAll(
1850
+ "[locale]",
1851
+ locale
1852
+ );
1895
1853
  const finalPath = path11.resolve(draftPath);
1896
- const prettierConfig = await loadPrettierConfig(finalPath);
1897
- if (!prettierConfig) {
1898
- return data;
1899
- }
1900
- const config = {
1901
- ...prettierConfig || { printWidth: 2500, bracketSameLine: false },
1902
- parser: options.parser,
1903
- // For HTML parser, preserve comments and quotes
1904
- ...options.parser === "html" ? {
1905
- htmlWhitespaceSensitivity: "ignore",
1906
- singleQuote: false,
1907
- embeddedLanguageFormatting: "off"
1908
- } : {}
1909
- };
1910
- try {
1911
- const result = await prettier.format(data, config);
1912
- return result;
1913
- } catch (error) {
1914
- if (error instanceof Error && error.message.startsWith("Cannot find package")) {
1915
- console.log();
1916
- console.log("\u26A0\uFE0F Prettier plugins are not installed. Formatting without plugins.");
1917
- console.log("\u26A0\uFE0F To use prettier plugins install project dependencies before running Lingo.dev.");
1918
- config.plugins = [];
1919
- await prettier.clearConfigCache();
1920
- const result = await prettier.format(data, config);
1921
- return result;
1922
- } else {
1923
- throw error;
1924
- }
1925
- }
1854
+ return await formatDataWithPrettier(data, finalPath, options);
1926
1855
  }
1927
1856
  });
1928
1857
  }
@@ -1934,19 +1863,52 @@ async function loadPrettierConfig(filePath) {
1934
1863
  return {};
1935
1864
  }
1936
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
+ }
1937
1899
 
1938
1900
  // src/cli/loaders/unlocalizable.ts
1939
- import _11 from "lodash";
1901
+ import _10 from "lodash";
1940
1902
  import _isUrl from "is-url";
1941
1903
  import { isValid, parseISO } from "date-fns";
1942
1904
  function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys = false) {
1943
1905
  const rules = {
1944
- isEmpty: (v) => _11.isEmpty(v),
1906
+ isEmpty: (v) => _10.isEmpty(v),
1945
1907
  isNumber: (v) => typeof v === "number" || /^[0-9]+$/.test(v),
1946
- isBoolean: (v) => _11.isBoolean(v),
1947
- isIsoDate: (v) => _11.isString(v) && _isIsoDate(v),
1948
- isSystemId: (v) => _11.isString(v) && _isSystemId(v),
1949
- 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)
1950
1912
  };
1951
1913
  return createLoader({
1952
1914
  async pull(locale, input2) {
@@ -1957,18 +1919,18 @@ function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys
1957
1919
  }
1958
1920
  }
1959
1921
  return false;
1960
- }).map(([key, _25]) => key);
1961
- 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));
1962
1924
  if (returnUnlocalizedKeys) {
1963
- result.unlocalizable = _11.omitBy(input2, (_25, key) => !passthroughKeys.includes(key));
1925
+ result.unlocalizable = _10.omitBy(input2, (_24, key) => !passthroughKeys.includes(key));
1964
1926
  }
1965
1927
  return result;
1966
1928
  },
1967
1929
  async push(locale, data, originalInput) {
1968
1930
  if (isCacheRestore) {
1969
- return _11.merge({}, data);
1931
+ return _10.merge({}, data);
1970
1932
  }
1971
- const result = _11.merge({}, originalInput, data);
1933
+ const result = _10.merge({}, originalInput, data);
1972
1934
  return result;
1973
1935
  }
1974
1936
  });
@@ -1981,7 +1943,7 @@ function _isIsoDate(v) {
1981
1943
  }
1982
1944
 
1983
1945
  // src/cli/loaders/po/index.ts
1984
- import _12 from "lodash";
1946
+ import _11 from "lodash";
1985
1947
  import gettextParser from "gettext-parser";
1986
1948
  function createPoLoader(params = { multiline: false }) {
1987
1949
  return composeLoaders(createPoDataLoader(params), createPoContentLoader());
@@ -1994,7 +1956,7 @@ function createPoDataLoader(params) {
1994
1956
  const sections = input2.split("\n\n").filter(Boolean);
1995
1957
  for (const section of sections) {
1996
1958
  const sectionPo = gettextParser.po.parse(section);
1997
- const contextKey = _12.keys(sectionPo.translations)[0];
1959
+ const contextKey = _11.keys(sectionPo.translations)[0];
1998
1960
  const entries = sectionPo.translations[contextKey];
1999
1961
  Object.entries(entries).forEach(([msgid, entry]) => {
2000
1962
  if (msgid && entry.msgid) {
@@ -2013,13 +1975,13 @@ function createPoDataLoader(params) {
2013
1975
  const originalSections = originalInput?.split("\n\n").filter(Boolean) || [];
2014
1976
  const result = originalSections.map((section) => {
2015
1977
  const sectionPo = gettextParser.po.parse(section);
2016
- const contextKey = _12.keys(sectionPo.translations)[0];
1978
+ const contextKey = _11.keys(sectionPo.translations)[0];
2017
1979
  const entries = sectionPo.translations[contextKey];
2018
1980
  const msgid = Object.keys(entries).find((key) => entries[key].msgid);
2019
1981
  if (!msgid) {
2020
1982
  const currentSection = currentSections.find((cs) => {
2021
1983
  const csPo = gettextParser.po.parse(cs);
2022
- const csContextKey = _12.keys(csPo.translations)[0];
1984
+ const csContextKey = _11.keys(csPo.translations)[0];
2023
1985
  const csEntries = csPo.translations[csContextKey];
2024
1986
  const csMsgid = Object.keys(csEntries).find((key) => csEntries[key].msgid);
2025
1987
  return csMsgid === msgid;
@@ -2030,7 +1992,7 @@ function createPoDataLoader(params) {
2030
1992
  return section;
2031
1993
  }
2032
1994
  if (data[msgid]) {
2033
- const updatedPo = _12.merge({}, sectionPo, {
1995
+ const updatedPo = _11.merge({}, sectionPo, {
2034
1996
  translations: {
2035
1997
  [contextKey]: {
2036
1998
  [msgid]: {
@@ -2050,7 +2012,7 @@ function createPoDataLoader(params) {
2050
2012
  function createPoContentLoader() {
2051
2013
  return createLoader({
2052
2014
  async pull(locale, input2) {
2053
- 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]) => [
2054
2016
  entry.msgid,
2055
2017
  {
2056
2018
  singular: entry.msgstr[0] || entry.msgid,
@@ -2060,7 +2022,7 @@ function createPoContentLoader() {
2060
2022
  return result;
2061
2023
  },
2062
2024
  async push(locale, data, originalInput) {
2063
- const result = _12.chain(originalInput).entries().map(([, entry]) => [
2025
+ const result = _11.chain(originalInput).entries().map(([, entry]) => [
2064
2026
  entry.msgid,
2065
2027
  {
2066
2028
  ...entry,
@@ -2183,34 +2145,34 @@ var datoSettingsSchema = Z2.object({
2183
2145
  });
2184
2146
 
2185
2147
  // src/cli/loaders/dato/filter.ts
2186
- import _13 from "lodash";
2148
+ import _12 from "lodash";
2187
2149
  function createDatoFilterLoader() {
2188
2150
  return createLoader({
2189
2151
  async pull(locale, input2) {
2190
2152
  const result = {};
2191
- for (const [modelId, modelInfo] of _13.entries(input2)) {
2153
+ for (const [modelId, modelInfo] of _12.entries(input2)) {
2192
2154
  result[modelId] = {};
2193
2155
  for (const record of modelInfo.records) {
2194
- 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();
2195
2157
  }
2196
2158
  }
2197
2159
  return result;
2198
2160
  },
2199
2161
  async push(locale, data, originalInput, originalLocale) {
2200
- const result = _13.cloneDeep(originalInput || {});
2201
- for (const [modelId, modelInfo] of _13.entries(result)) {
2162
+ const result = _12.cloneDeep(originalInput || {});
2163
+ for (const [modelId, modelInfo] of _12.entries(result)) {
2202
2164
  for (const record of modelInfo.records) {
2203
- for (const [fieldId, fieldValue] of _13.entries(record)) {
2165
+ for (const [fieldId, fieldValue] of _12.entries(record)) {
2204
2166
  const fieldInfo = modelInfo.fields.find((field) => field.api_key === fieldId);
2205
2167
  if (fieldInfo) {
2206
- const sourceFieldValue = _13.get(fieldValue, [originalLocale]);
2207
- 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]);
2208
2170
  if (targetFieldValue) {
2209
- _13.set(record, [fieldId, locale], targetFieldValue);
2171
+ _12.set(record, [fieldId, locale], targetFieldValue);
2210
2172
  } else {
2211
- _13.set(record, [fieldId, locale], sourceFieldValue);
2173
+ _12.set(record, [fieldId, locale], sourceFieldValue);
2212
2174
  }
2213
- _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();
2214
2176
  }
2215
2177
  }
2216
2178
  }
@@ -2221,10 +2183,10 @@ function createDatoFilterLoader() {
2221
2183
  }
2222
2184
 
2223
2185
  // src/cli/loaders/dato/api.ts
2224
- import _15 from "lodash";
2186
+ import _14 from "lodash";
2225
2187
 
2226
2188
  // src/cli/loaders/dato/_utils.ts
2227
- import _14 from "lodash";
2189
+ import _13 from "lodash";
2228
2190
  import { buildClient } from "@datocms/cma-client-node";
2229
2191
  function createDatoClient(params) {
2230
2192
  if (!params.apiKey) {
@@ -2399,7 +2361,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2399
2361
  const result = {
2400
2362
  models: {}
2401
2363
  };
2402
- const updatedConfig = _15.cloneDeep(config);
2364
+ const updatedConfig = _14.cloneDeep(config);
2403
2365
  console.log(`Initializing DatoCMS loader...`);
2404
2366
  const project = await dato.findProject();
2405
2367
  const modelChoices = await getModelChoices(dato, config);
@@ -2417,7 +2379,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2417
2379
  delete updatedConfig.models[modelId];
2418
2380
  }
2419
2381
  }
2420
- for (const modelId of _15.keys(updatedConfig.models)) {
2382
+ for (const modelId of _14.keys(updatedConfig.models)) {
2421
2383
  const { modelName, fields } = await getModelFields(dato, modelId);
2422
2384
  if (fields.length > 0) {
2423
2385
  result.models[modelId] = { fields: [], records: [] };
@@ -2428,7 +2390,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2428
2390
  const isLocalized = await updateFieldLocalization(dato, fieldInfo, selectedFields.includes(fieldInfo.id));
2429
2391
  if (isLocalized) {
2430
2392
  result.models[modelId].fields.push(fieldInfo);
2431
- updatedConfig.models[modelId].fields = _15.uniq([
2393
+ updatedConfig.models[modelId].fields = _14.uniq([
2432
2394
  ...updatedConfig.models[modelId].fields || [],
2433
2395
  fieldInfo.api_key
2434
2396
  ]);
@@ -2447,7 +2409,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2447
2409
  },
2448
2410
  async pull(locale, input2, initCtx) {
2449
2411
  const result = {};
2450
- for (const modelId of _15.keys(initCtx?.models || {})) {
2412
+ for (const modelId of _14.keys(initCtx?.models || {})) {
2451
2413
  let records = initCtx?.models[modelId].records || [];
2452
2414
  const recordIds = records.map((record) => record.id);
2453
2415
  records = await dato.findRecords(recordIds);
@@ -2462,7 +2424,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
2462
2424
  return result;
2463
2425
  },
2464
2426
  async push(locale, data, originalInput) {
2465
- for (const modelId of _15.keys(data)) {
2427
+ for (const modelId of _14.keys(data)) {
2466
2428
  for (let i = 0; i < data[modelId].records.length; i++) {
2467
2429
  const record = data[modelId].records[i];
2468
2430
  console.log(`Updating record ${i + 1}/${data[modelId].records.length} for model ${modelId}...`);
@@ -2476,7 +2438,7 @@ async function getModelFields(dato, modelId) {
2476
2438
  const modelInfo = await dato.findModel(modelId);
2477
2439
  return {
2478
2440
  modelName: modelInfo.name,
2479
- fields: _15.filter(modelInfo.fields, (field) => field.type === "field")
2441
+ fields: _14.filter(modelInfo.fields, (field) => field.type === "field")
2480
2442
  };
2481
2443
  }
2482
2444
  async function getFieldDetails(dato, fields) {
@@ -2554,17 +2516,17 @@ async function promptModelSelection(choices) {
2554
2516
  }
2555
2517
 
2556
2518
  // src/cli/loaders/dato/extract.ts
2557
- import _16 from "lodash";
2519
+ import _15 from "lodash";
2558
2520
  function createDatoExtractLoader() {
2559
2521
  return createLoader({
2560
2522
  async pull(locale, input2) {
2561
2523
  const result = {};
2562
- for (const [modelId, modelInfo] of _16.entries(input2)) {
2563
- for (const [recordId, record] of _16.entries(modelInfo)) {
2564
- 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)) {
2565
2527
  const parsedValue = createParsedDatoValue(fieldValue);
2566
2528
  if (parsedValue) {
2567
- _16.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
2529
+ _15.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
2568
2530
  }
2569
2531
  }
2570
2532
  }
@@ -2572,14 +2534,14 @@ function createDatoExtractLoader() {
2572
2534
  return result;
2573
2535
  },
2574
2536
  async push(locale, data, originalInput) {
2575
- const result = _16.cloneDeep(originalInput || {});
2576
- for (const [modelId, modelInfo] of _16.entries(data)) {
2577
- for (const [virtualRecordId, record] of _16.entries(modelInfo)) {
2578
- 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)) {
2579
2541
  const [, recordId] = virtualRecordId.split("_");
2580
- const originalFieldValue = _16.get(originalInput, [modelId, recordId, fieldName]);
2542
+ const originalFieldValue = _15.get(originalInput, [modelId, recordId, fieldName]);
2581
2543
  const rawValue = createRawDatoValue(fieldValue, originalFieldValue, true);
2582
- _16.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
2544
+ _15.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
2583
2545
  }
2584
2546
  }
2585
2547
  }
@@ -2588,25 +2550,25 @@ function createDatoExtractLoader() {
2588
2550
  });
2589
2551
  }
2590
2552
  function detectDatoFieldType(rawDatoValue) {
2591
- if (_16.has(rawDatoValue, "document") && _16.get(rawDatoValue, "schema") === "dast") {
2553
+ if (_15.has(rawDatoValue, "document") && _15.get(rawDatoValue, "schema") === "dast") {
2592
2554
  return "structured_text";
2593
- } 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")) {
2594
2556
  return "seo";
2595
- } else if (_16.get(rawDatoValue, "type") === "item") {
2557
+ } else if (_15.get(rawDatoValue, "type") === "item") {
2596
2558
  return "single_block";
2597
- } 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")) {
2598
2560
  return "rich_text";
2599
2561
  } else if (_isFile(rawDatoValue)) {
2600
2562
  return "file";
2601
- } else if (_16.isArray(rawDatoValue) && _16.every(rawDatoValue, (item) => _isFile(item))) {
2563
+ } else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _isFile(item))) {
2602
2564
  return "gallery";
2603
2565
  } else if (_isJson(rawDatoValue)) {
2604
2566
  return "json";
2605
- } else if (_16.isString(rawDatoValue)) {
2567
+ } else if (_15.isString(rawDatoValue)) {
2606
2568
  return "string";
2607
2569
  } else if (_isVideo(rawDatoValue)) {
2608
2570
  return "video";
2609
- } 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))) {
2610
2572
  return "ref_list";
2611
2573
  } else {
2612
2574
  return null;
@@ -2668,9 +2630,9 @@ function serializeStructuredText(rawStructuredText) {
2668
2630
  if ("document" in node) {
2669
2631
  return serializeStructuredTextNode(node.document, [...path18, "document"], acc);
2670
2632
  }
2671
- if (!_16.isNil(node.value)) {
2633
+ if (!_15.isNil(node.value)) {
2672
2634
  acc[[...path18, "value"].join(".")] = node.value;
2673
- } else if (_16.get(node, "type") === "block") {
2635
+ } else if (_15.get(node, "type") === "block") {
2674
2636
  acc[[...path18, "item"].join(".")] = serializeBlock(node.item);
2675
2637
  }
2676
2638
  if (node.children) {
@@ -2682,44 +2644,44 @@ function serializeStructuredText(rawStructuredText) {
2682
2644
  }
2683
2645
  }
2684
2646
  function serializeSeo(rawSeo) {
2685
- return _16.chain(rawSeo).pick(["title", "description"]).value();
2647
+ return _15.chain(rawSeo).pick(["title", "description"]).value();
2686
2648
  }
2687
2649
  function serializeBlock(rawBlock) {
2688
- if (_16.get(rawBlock, "type") === "item" && _16.has(rawBlock, "id")) {
2650
+ if (_15.get(rawBlock, "type") === "item" && _15.has(rawBlock, "id")) {
2689
2651
  return serializeBlock(rawBlock.attributes);
2690
2652
  }
2691
2653
  const result = {};
2692
- for (const [attributeName, attributeValue] of _16.entries(rawBlock)) {
2654
+ for (const [attributeName, attributeValue] of _15.entries(rawBlock)) {
2693
2655
  result[attributeName] = createParsedDatoValue(attributeValue);
2694
2656
  }
2695
2657
  return result;
2696
2658
  }
2697
2659
  function serializeBlockList(rawBlockList) {
2698
- return _16.chain(rawBlockList).map((block) => serializeBlock(block)).value();
2660
+ return _15.chain(rawBlockList).map((block) => serializeBlock(block)).value();
2699
2661
  }
2700
2662
  function serializeVideo(rawVideo) {
2701
- return _16.chain(rawVideo).pick(["title"]).value();
2663
+ return _15.chain(rawVideo).pick(["title"]).value();
2702
2664
  }
2703
2665
  function serializeFile(rawFile) {
2704
- return _16.chain(rawFile).pick(["alt", "title"]).value();
2666
+ return _15.chain(rawFile).pick(["alt", "title"]).value();
2705
2667
  }
2706
2668
  function serializeGallery(rawGallery) {
2707
- return _16.chain(rawGallery).map((item) => serializeFile(item)).value();
2669
+ return _15.chain(rawGallery).map((item) => serializeFile(item)).value();
2708
2670
  }
2709
2671
  function deserializeFile(parsedFile, originalRawFile) {
2710
- return _16.chain(parsedFile).defaults(originalRawFile).value();
2672
+ return _15.chain(parsedFile).defaults(originalRawFile).value();
2711
2673
  }
2712
2674
  function deserializeGallery(parsedGallery, originalRawGallery) {
2713
- 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();
2714
2676
  }
2715
2677
  function deserializeVideo(parsedVideo, originalRawVideo) {
2716
- return _16.chain(parsedVideo).defaults(originalRawVideo).value();
2678
+ return _15.chain(parsedVideo).defaults(originalRawVideo).value();
2717
2679
  }
2718
2680
  function deserializeBlock(payload, rawNode, isClean = false) {
2719
- const result = _16.cloneDeep(rawNode);
2720
- 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)) {
2721
2683
  const rawValue = createRawDatoValue(payload[attributeName], attributeValue, isClean);
2722
- _16.set(result, ["attributes", attributeName], rawValue);
2684
+ _15.set(result, ["attributes", attributeName], rawValue);
2723
2685
  }
2724
2686
  if (isClean) {
2725
2687
  delete result["id"];
@@ -2727,33 +2689,33 @@ function deserializeBlock(payload, rawNode, isClean = false) {
2727
2689
  return result;
2728
2690
  }
2729
2691
  function deserializeSeo(parsedSeo, originalRawSeo) {
2730
- return _16.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
2692
+ return _15.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
2731
2693
  }
2732
2694
  function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = false) {
2733
- 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();
2734
2696
  }
2735
2697
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
2736
- const result = _16.cloneDeep(originalRawStructuredText);
2737
- for (const [path18, value] of _16.entries(parsedStructuredText)) {
2738
- const realPath = _16.chain(path18.split(".")).flatMap((s) => !_16.isNaN(_16.toNumber(s)) ? ["children", s] : s).value();
2739
- const deserializedValue = createRawDatoValue(value, _16.get(originalRawStructuredText, realPath), true);
2740
- _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);
2741
2703
  }
2742
2704
  return result;
2743
2705
  }
2744
2706
  function _isJson(rawDatoValue) {
2745
2707
  try {
2746
- return _16.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
2708
+ return _15.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
2747
2709
  } catch (e) {
2748
2710
  return false;
2749
2711
  }
2750
2712
  }
2751
2713
  function _isFile(rawDatoValue) {
2752
- 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));
2753
2715
  }
2754
2716
  function _isVideo(rawDatoValue) {
2755
- return _16.isObject(rawDatoValue) && ["url", "title", "width", "height", "provider", "provider_uid", "thumbnail_url"].every(
2756
- (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)
2757
2719
  );
2758
2720
  }
2759
2721
 
@@ -2814,7 +2776,7 @@ function createVttLoader() {
2814
2776
  }
2815
2777
 
2816
2778
  // src/cli/loaders/variable/index.ts
2817
- import _17 from "lodash";
2779
+ import _16 from "lodash";
2818
2780
  function createVariableLoader(params) {
2819
2781
  return composeLoaders(variableExtractLoader(params), variableContentLoader());
2820
2782
  }
@@ -2823,7 +2785,7 @@ function variableExtractLoader(params) {
2823
2785
  return createLoader({
2824
2786
  pull: async (locale, input2) => {
2825
2787
  const result = {};
2826
- const inputValues = _17.omitBy(input2, _17.isEmpty);
2788
+ const inputValues = _16.omitBy(input2, _16.isEmpty);
2827
2789
  for (const [key, value] of Object.entries(inputValues)) {
2828
2790
  const matches = value.match(specifierPattern) || [];
2829
2791
  result[key] = result[key] || {
@@ -2858,11 +2820,11 @@ function variableExtractLoader(params) {
2858
2820
  function variableContentLoader() {
2859
2821
  return createLoader({
2860
2822
  pull: async (locale, input2) => {
2861
- const result = _17.mapValues(input2, (payload) => payload.value);
2823
+ const result = _16.mapValues(input2, (payload) => payload.value);
2862
2824
  return result;
2863
2825
  },
2864
2826
  push: async (locale, data, originalInput) => {
2865
- const result = _17.cloneDeep(originalInput || {});
2827
+ const result = _16.cloneDeep(originalInput || {});
2866
2828
  for (const [key, originalValueObj] of Object.entries(result)) {
2867
2829
  result[key] = {
2868
2830
  ...originalValueObj,
@@ -2885,20 +2847,20 @@ function getFormatSpecifierPattern(type) {
2885
2847
  }
2886
2848
 
2887
2849
  // src/cli/loaders/sync.ts
2888
- import _18 from "lodash";
2850
+ import _17 from "lodash";
2889
2851
  function createSyncLoader() {
2890
2852
  return createLoader({
2891
2853
  async pull(locale, input2, originalInput) {
2892
2854
  if (!originalInput) {
2893
2855
  return input2;
2894
2856
  }
2895
- return _18.chain(originalInput).mapValues((value, key) => input2[key]).value();
2857
+ return _17.chain(originalInput).mapValues((value, key) => input2[key]).value();
2896
2858
  },
2897
2859
  async push(locale, data, originalInput) {
2898
2860
  if (!originalInput) {
2899
2861
  return data;
2900
2862
  }
2901
- return _18.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
2863
+ return _17.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
2902
2864
  }
2903
2865
  });
2904
2866
  }
@@ -3058,7 +3020,7 @@ function parseVueFile(input2) {
3058
3020
  }
3059
3021
 
3060
3022
  // src/cli/loaders/inject-locale.ts
3061
- import _19 from "lodash";
3023
+ import _18 from "lodash";
3062
3024
  function createInjectLocaleLoader(injectLocaleKeys) {
3063
3025
  return createLoader({
3064
3026
  async pull(locale, data) {
@@ -3066,19 +3028,19 @@ function createInjectLocaleLoader(injectLocaleKeys) {
3066
3028
  return data;
3067
3029
  }
3068
3030
  const omitKeys = injectLocaleKeys.filter((key) => {
3069
- return _19.get(data, key) === locale;
3031
+ return _18.get(data, key) === locale;
3070
3032
  });
3071
- const result = _19.omit(data, omitKeys);
3033
+ const result = _18.omit(data, omitKeys);
3072
3034
  return result;
3073
3035
  },
3074
3036
  async push(locale, data, originalInput, originalLocale) {
3075
3037
  if (!injectLocaleKeys) {
3076
3038
  return data;
3077
3039
  }
3078
- const mergedData = _19.merge({}, originalInput, data);
3040
+ const mergedData = _18.merge({}, originalInput, data);
3079
3041
  injectLocaleKeys.forEach((key) => {
3080
- if (_19.get(mergedData, key) === originalLocale) {
3081
- _19.set(mergedData, key, locale);
3042
+ if (_18.get(mergedData, key) === originalLocale) {
3043
+ _18.set(mergedData, key, locale);
3082
3044
  }
3083
3045
  });
3084
3046
  return mergedData;
@@ -3087,21 +3049,438 @@ function createInjectLocaleLoader(injectLocaleKeys) {
3087
3049
  }
3088
3050
 
3089
3051
  // src/cli/loaders/locked-keys.ts
3090
- import _20 from "lodash";
3052
+ import _19 from "lodash";
3091
3053
  function createLockedKeysLoader(lockedKeys, isCacheRestore = false) {
3092
3054
  return createLoader({
3093
- 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(),
3094
3056
  push: async (locale, data, originalInput) => {
3095
- 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();
3096
3058
  if (isCacheRestore) {
3097
- return _20.merge({}, data, lockedSubObject);
3059
+ return _19.merge({}, data, lockedSubObject);
3098
3060
  } else {
3099
- 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;
3291
+ }
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
+ }
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);
3100
3426
  }
3101
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
+ }
3102
3471
  });
3103
3472
  }
3104
3473
 
3474
+ // src/cli/loaders/mdx2/index.ts
3475
+ function createMdxLoader() {
3476
+ return composeLoaders(
3477
+ createMdxFrontmatterSplitLoader(),
3478
+ createMdxCodePlaceholderLoader(),
3479
+ createMdxSectionSplitLoader(),
3480
+ createLocalizableMdxDocumentLoader()
3481
+ );
3482
+ }
3483
+
3105
3484
  // src/cli/loaders/index.ts
3106
3485
  function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys) {
3107
3486
  switch (bucketType) {
@@ -3113,7 +3492,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3113
3492
  createAndroidLoader(),
3114
3493
  createFlatLoader(),
3115
3494
  createSyncLoader(),
3116
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3495
+ createUnlocalizableLoader(
3496
+ options.isCacheRestore,
3497
+ options.returnUnlocalizedKeys
3498
+ )
3117
3499
  );
3118
3500
  case "csv":
3119
3501
  return composeLoaders(
@@ -3121,7 +3503,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3121
3503
  createCsvLoader(),
3122
3504
  createFlatLoader(),
3123
3505
  createSyncLoader(),
3124
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3506
+ createUnlocalizableLoader(
3507
+ options.isCacheRestore,
3508
+ options.returnUnlocalizedKeys
3509
+ )
3125
3510
  );
3126
3511
  case "html":
3127
3512
  return composeLoaders(
@@ -3129,7 +3514,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3129
3514
  createPrettierLoader({ parser: "html", bucketPathPattern }),
3130
3515
  createHtmlLoader(),
3131
3516
  createSyncLoader(),
3132
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3517
+ createUnlocalizableLoader(
3518
+ options.isCacheRestore,
3519
+ options.returnUnlocalizedKeys
3520
+ )
3133
3521
  );
3134
3522
  case "json":
3135
3523
  return composeLoaders(
@@ -3140,7 +3528,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3140
3528
  createFlatLoader(),
3141
3529
  createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
3142
3530
  createSyncLoader(),
3143
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3531
+ createUnlocalizableLoader(
3532
+ options.isCacheRestore,
3533
+ options.returnUnlocalizedKeys
3534
+ )
3144
3535
  );
3145
3536
  case "markdown":
3146
3537
  return composeLoaders(
@@ -3148,18 +3539,22 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3148
3539
  createPrettierLoader({ parser: "markdown", bucketPathPattern }),
3149
3540
  createMarkdownLoader(),
3150
3541
  createSyncLoader(),
3151
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3542
+ createUnlocalizableLoader(
3543
+ options.isCacheRestore,
3544
+ options.returnUnlocalizedKeys
3545
+ )
3152
3546
  );
3153
3547
  case "mdx":
3154
3548
  return composeLoaders(
3155
3549
  createTextFileLoader(bucketPathPattern),
3156
- createDoubleSerializationLoader(),
3157
3550
  createPrettierLoader({ parser: "mdx", bucketPathPattern }),
3158
- createMdxFormatLoader(),
3551
+ createMdxLoader(),
3159
3552
  createFlatLoader(),
3160
- createMdxStructureLoader(),
3161
3553
  createSyncLoader(),
3162
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3554
+ createUnlocalizableLoader(
3555
+ options.isCacheRestore,
3556
+ options.returnUnlocalizedKeys
3557
+ )
3163
3558
  );
3164
3559
  case "po":
3165
3560
  return composeLoaders(
@@ -3168,21 +3563,30 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3168
3563
  createFlatLoader(),
3169
3564
  createSyncLoader(),
3170
3565
  createVariableLoader({ type: "python" }),
3171
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3566
+ createUnlocalizableLoader(
3567
+ options.isCacheRestore,
3568
+ options.returnUnlocalizedKeys
3569
+ )
3172
3570
  );
3173
3571
  case "properties":
3174
3572
  return composeLoaders(
3175
3573
  createTextFileLoader(bucketPathPattern),
3176
3574
  createPropertiesLoader(),
3177
3575
  createSyncLoader(),
3178
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3576
+ createUnlocalizableLoader(
3577
+ options.isCacheRestore,
3578
+ options.returnUnlocalizedKeys
3579
+ )
3179
3580
  );
3180
3581
  case "xcode-strings":
3181
3582
  return composeLoaders(
3182
3583
  createTextFileLoader(bucketPathPattern),
3183
3584
  createXcodeStringsLoader(),
3184
3585
  createSyncLoader(),
3185
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3586
+ createUnlocalizableLoader(
3587
+ options.isCacheRestore,
3588
+ options.returnUnlocalizedKeys
3589
+ )
3186
3590
  );
3187
3591
  case "xcode-stringsdict":
3188
3592
  return composeLoaders(
@@ -3190,7 +3594,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3190
3594
  createXcodeStringsdictLoader(),
3191
3595
  createFlatLoader(),
3192
3596
  createSyncLoader(),
3193
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3597
+ createUnlocalizableLoader(
3598
+ options.isCacheRestore,
3599
+ options.returnUnlocalizedKeys
3600
+ )
3194
3601
  );
3195
3602
  case "xcode-xcstrings":
3196
3603
  return composeLoaders(
@@ -3201,7 +3608,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3201
3608
  createFlatLoader(),
3202
3609
  createSyncLoader(),
3203
3610
  createVariableLoader({ type: "ieee" }),
3204
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3611
+ createUnlocalizableLoader(
3612
+ options.isCacheRestore,
3613
+ options.returnUnlocalizedKeys
3614
+ )
3205
3615
  );
3206
3616
  case "yaml":
3207
3617
  return composeLoaders(
@@ -3211,7 +3621,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3211
3621
  createFlatLoader(),
3212
3622
  createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
3213
3623
  createSyncLoader(),
3214
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3624
+ createUnlocalizableLoader(
3625
+ options.isCacheRestore,
3626
+ options.returnUnlocalizedKeys
3627
+ )
3215
3628
  );
3216
3629
  case "yaml-root-key":
3217
3630
  return composeLoaders(
@@ -3221,7 +3634,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3221
3634
  createRootKeyLoader(true),
3222
3635
  createFlatLoader(),
3223
3636
  createSyncLoader(),
3224
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3637
+ createUnlocalizableLoader(
3638
+ options.isCacheRestore,
3639
+ options.returnUnlocalizedKeys
3640
+ )
3225
3641
  );
3226
3642
  case "flutter":
3227
3643
  return composeLoaders(
@@ -3231,7 +3647,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3231
3647
  createFlutterLoader(),
3232
3648
  createFlatLoader(),
3233
3649
  createSyncLoader(),
3234
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3650
+ createUnlocalizableLoader(
3651
+ options.isCacheRestore,
3652
+ options.returnUnlocalizedKeys
3653
+ )
3235
3654
  );
3236
3655
  case "xliff":
3237
3656
  return composeLoaders(
@@ -3239,7 +3658,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3239
3658
  createXliffLoader(),
3240
3659
  createFlatLoader(),
3241
3660
  createSyncLoader(),
3242
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3661
+ createUnlocalizableLoader(
3662
+ options.isCacheRestore,
3663
+ options.returnUnlocalizedKeys
3664
+ )
3243
3665
  );
3244
3666
  case "xml":
3245
3667
  return composeLoaders(
@@ -3247,28 +3669,40 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3247
3669
  createXmlLoader(),
3248
3670
  createFlatLoader(),
3249
3671
  createSyncLoader(),
3250
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3672
+ createUnlocalizableLoader(
3673
+ options.isCacheRestore,
3674
+ options.returnUnlocalizedKeys
3675
+ )
3251
3676
  );
3252
3677
  case "srt":
3253
3678
  return composeLoaders(
3254
3679
  createTextFileLoader(bucketPathPattern),
3255
3680
  createSrtLoader(),
3256
3681
  createSyncLoader(),
3257
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3682
+ createUnlocalizableLoader(
3683
+ options.isCacheRestore,
3684
+ options.returnUnlocalizedKeys
3685
+ )
3258
3686
  );
3259
3687
  case "dato":
3260
3688
  return composeLoaders(
3261
3689
  createDatoLoader(bucketPathPattern),
3262
3690
  createSyncLoader(),
3263
3691
  createFlatLoader(),
3264
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3692
+ createUnlocalizableLoader(
3693
+ options.isCacheRestore,
3694
+ options.returnUnlocalizedKeys
3695
+ )
3265
3696
  );
3266
3697
  case "vtt":
3267
3698
  return composeLoaders(
3268
3699
  createTextFileLoader(bucketPathPattern),
3269
3700
  createVttLoader(),
3270
3701
  createSyncLoader(),
3271
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3702
+ createUnlocalizableLoader(
3703
+ options.isCacheRestore,
3704
+ options.returnUnlocalizedKeys
3705
+ )
3272
3706
  );
3273
3707
  case "php":
3274
3708
  return composeLoaders(
@@ -3276,7 +3710,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3276
3710
  createPhpLoader(),
3277
3711
  createSyncLoader(),
3278
3712
  createFlatLoader(),
3279
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3713
+ createUnlocalizableLoader(
3714
+ options.isCacheRestore,
3715
+ options.returnUnlocalizedKeys
3716
+ )
3280
3717
  );
3281
3718
  case "vue-json":
3282
3719
  return composeLoaders(
@@ -3284,7 +3721,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
3284
3721
  createVueJsonLoader(),
3285
3722
  createSyncLoader(),
3286
3723
  createFlatLoader(),
3287
- createUnlocalizableLoader(options.isCacheRestore, options.returnUnlocalizedKeys)
3724
+ createUnlocalizableLoader(
3725
+ options.isCacheRestore,
3726
+ options.returnUnlocalizedKeys
3727
+ )
3288
3728
  );
3289
3729
  }
3290
3730
  }
@@ -3307,23 +3747,6 @@ var cacheChunk = (targetLocale, sourceChunk, processedChunk) => {
3307
3747
  }));
3308
3748
  _appendToCache(rows);
3309
3749
  };
3310
- function getNormalizedCache() {
3311
- const rows = _loadCache();
3312
- if (!rows.length) {
3313
- return null;
3314
- }
3315
- const normalized = {};
3316
- for (const row of rows) {
3317
- if (!normalized[row.targetLocale]) {
3318
- normalized[row.targetLocale] = {};
3319
- }
3320
- normalized[row.targetLocale][row.key] = {
3321
- source: row.source,
3322
- result: row.processed
3323
- };
3324
- }
3325
- return normalized;
3326
- }
3327
3750
  function deleteCache() {
3328
3751
  const cacheFilePath = _getCacheFilePath();
3329
3752
  try {
@@ -3331,15 +3754,6 @@ function deleteCache() {
3331
3754
  } catch (e) {
3332
3755
  }
3333
3756
  }
3334
- function _loadCache() {
3335
- const cacheFilePath = _getCacheFilePath();
3336
- if (!fs10.existsSync(cacheFilePath)) {
3337
- return [];
3338
- }
3339
- const content = fs10.readFileSync(cacheFilePath, "utf-8");
3340
- const result = _parseJSONLines(content);
3341
- return result;
3342
- }
3343
3757
  function _appendToCache(rows) {
3344
3758
  const cacheFilePath = _getCacheFilePath();
3345
3759
  const lines = _buildJSONLines(rows);
@@ -3351,16 +3765,6 @@ function _getCacheFilePath() {
3351
3765
  function _buildJSONLines(rows) {
3352
3766
  return rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
3353
3767
  }
3354
- function _parseJSONLines(lines) {
3355
- return lines.split("\n").map(_tryParseJSON).filter((line) => line !== null);
3356
- }
3357
- function _tryParseJSON(line) {
3358
- try {
3359
- return JSON.parse(line);
3360
- } catch (e) {
3361
- return null;
3362
- }
3363
- }
3364
3768
 
3365
3769
  // src/cli/processor/lingo.ts
3366
3770
  import { LingoDotDevEngine } from "@lingo.dev/_sdk";
@@ -3527,9 +3931,8 @@ async function trackEvent(distinctId, event, properties) {
3527
3931
  }
3528
3932
 
3529
3933
  // src/cli/utils/delta.ts
3530
- import _21 from "lodash";
3934
+ import _20 from "lodash";
3531
3935
  import z from "zod";
3532
- import { MD5 } from "object-hash";
3533
3936
 
3534
3937
  // src/cli/utils/fs.ts
3535
3938
  import * as fs11 from "fs";
@@ -3577,14 +3980,14 @@ function createDeltaProcessor(fileKey) {
3577
3980
  return checkIfFileExists(lockfilePath);
3578
3981
  },
3579
3982
  async calculateDelta(params) {
3580
- let added = _21.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
3581
- let removed = _21.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
3582
- const updated = _21.filter(Object.keys(params.sourceData), (key) => {
3583
- 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];
3584
3987
  });
3585
3988
  const renamed = [];
3586
3989
  for (const addedKey of added) {
3587
- const addedHash = MD5(params.sourceData[addedKey]);
3990
+ const addedHash = md5(params.sourceData[addedKey]);
3588
3991
  for (const removedKey of removed) {
3589
3992
  if (params.checksums[removedKey] === addedHash) {
3590
3993
  renamed.push([removedKey, addedKey]);
@@ -3617,18 +4020,18 @@ function createDeltaProcessor(fileKey) {
3617
4020
  writeFile(lockfilePath, lockfileYaml);
3618
4021
  },
3619
4022
  async loadChecksums() {
3620
- const id = MD5(fileKey);
4023
+ const id = md5(fileKey);
3621
4024
  const lockfileData = await this.loadLock();
3622
4025
  return lockfileData.checksums[id] || {};
3623
4026
  },
3624
4027
  async saveChecksums(checksums) {
3625
- const id = MD5(fileKey);
4028
+ const id = md5(fileKey);
3626
4029
  const lockfileData = await this.loadLock();
3627
4030
  lockfileData.checksums[id] = checksums;
3628
4031
  await this.saveLock(lockfileData);
3629
4032
  },
3630
4033
  async createChecksums(sourceData) {
3631
- const checksums = _21.mapValues(sourceData, (value) => MD5(value));
4034
+ const checksums = _20.mapValues(sourceData, (value) => md5(value));
3632
4035
  return checksums;
3633
4036
  }
3634
4037
  };
@@ -3636,7 +4039,15 @@ function createDeltaProcessor(fileKey) {
3636
4039
 
3637
4040
  // src/cli/cmd/i18n.ts
3638
4041
  import { flatten as flatten2, unflatten as unflatten2 } from "flat";
3639
- 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(
3640
4051
  "--key <key>",
3641
4052
  "Key to process. Process only a specific translation key, useful for debugging or updating a single entry"
3642
4053
  ).option(
@@ -3645,7 +4056,25 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3645
4056
  ).option(
3646
4057
  "--frozen",
3647
4058
  `Run in read-only mode - fails if any translations need updating, useful for CI/CD pipelines to detect missing translations`
3648
- ).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) {
3649
4078
  updateGitignore();
3650
4079
  const ora = Ora5();
3651
4080
  const flags = parseFlags(options);
@@ -3678,7 +4107,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3678
4107
  });
3679
4108
  let buckets = getBuckets(i18nConfig);
3680
4109
  if (flags.bucket?.length) {
3681
- buckets = buckets.filter((bucket) => flags.bucket.includes(bucket.type));
4110
+ buckets = buckets.filter(
4111
+ (bucket) => flags.bucket.includes(bucket.type)
4112
+ );
3682
4113
  }
3683
4114
  ora.succeed("Buckets retrieved");
3684
4115
  if (flags.file?.length) {
@@ -3689,7 +4120,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3689
4120
  return { ...bucket, paths };
3690
4121
  }).filter((bucket) => bucket.paths.length > 0);
3691
4122
  if (buckets.length === 0) {
3692
- 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
+ );
3693
4126
  process.exit(1);
3694
4127
  } else {
3695
4128
  ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
@@ -3709,7 +4142,10 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3709
4142
  ora.start("Creating i18n.lock...");
3710
4143
  for (const bucket of buckets) {
3711
4144
  for (const bucketPath of bucket.paths) {
3712
- const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
4145
+ const sourceLocale = resolveOverriddenLocale3(
4146
+ i18nConfig.locale.source,
4147
+ bucketPath.delimiter
4148
+ );
3713
4149
  const bucketLoader = createBucketLoader(
3714
4150
  bucket.type,
3715
4151
  bucketPath.pathPattern,
@@ -3722,7 +4158,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3722
4158
  );
3723
4159
  bucketLoader.setDefaultLocale(sourceLocale);
3724
4160
  await bucketLoader.init();
3725
- const sourceData = await bucketLoader.pull(i18nConfig.locale.source);
4161
+ const sourceData = await bucketLoader.pull(
4162
+ i18nConfig.locale.source
4163
+ );
3726
4164
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3727
4165
  const checksums = await deltaProcessor.createChecksums(sourceData);
3728
4166
  await deltaProcessor.saveChecksums(checksums);
@@ -3738,9 +4176,15 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3738
4176
  }
3739
4177
  ora.start("Validating localization state...");
3740
4178
  for (const bucketPath of bucket.paths) {
3741
- const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
4179
+ const sourceLocale = resolveOverriddenLocale3(
4180
+ i18nConfig.locale.source,
4181
+ bucketPath.delimiter
4182
+ );
3742
4183
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3743
- 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
+ );
3744
4188
  const sourceContent = tryReadFile(sourcePath, null);
3745
4189
  const sourceData = JSON.parse(sourceContent || "{}");
3746
4190
  const sourceFlattenedData = flatten2(sourceData, {
@@ -3750,8 +4194,14 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3750
4194
  }
3751
4195
  });
3752
4196
  for (const _targetLocale of targetLocales) {
3753
- const targetLocale = resolveOverriddenLocale3(_targetLocale, bucketPath.delimiter);
3754
- 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
+ );
3755
4205
  const targetContent = tryReadFile(targetPath, null);
3756
4206
  const targetData = JSON.parse(targetContent || "{}");
3757
4207
  const targetFlattenedData = flatten2(targetData, {
@@ -3779,68 +4229,23 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3779
4229
  return decodeURIComponent(key);
3780
4230
  }
3781
4231
  });
3782
- await writeFile(targetPath, JSON.stringify(updatedTargetData, null, 2));
3783
- }
3784
- }
3785
- ora.succeed("Localization state check completed");
3786
- }
3787
- const cache = getNormalizedCache();
3788
- if (cache) {
3789
- console.log();
3790
- ora.succeed(`Cache loaded. Attempting recovery...`);
3791
- const cacheOra = Ora5({ indent: 2 });
3792
- for (const bucket of buckets) {
3793
- cacheOra.info(`Processing bucket: ${bucket.type}`);
3794
- for (const bucketPath of bucket.paths) {
3795
- const bucketOra = Ora5({ indent: 4 });
3796
- bucketOra.info(`Processing path: ${bucketPath.pathPattern}`);
3797
- const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
3798
- const bucketLoader = createBucketLoader(
3799
- bucket.type,
3800
- bucketPath.pathPattern,
3801
- {
3802
- isCacheRestore: true,
3803
- defaultLocale: sourceLocale,
3804
- injectLocale: bucket.injectLocale
3805
- },
3806
- bucket.lockedKeys
4232
+ await writeFile(
4233
+ targetPath,
4234
+ JSON.stringify(updatedTargetData, null, 2)
3807
4235
  );
3808
- bucketLoader.setDefaultLocale(sourceLocale);
3809
- await bucketLoader.init();
3810
- const sourceData = await bucketLoader.pull(sourceLocale);
3811
- const cachedSourceData = {};
3812
- for (const targetLocale in cache) {
3813
- const targetData = await bucketLoader.pull(targetLocale);
3814
- for (const key in cache[targetLocale]) {
3815
- const { source, result } = cache[targetLocale][key];
3816
- if (sourceData[key] === source && targetData[key] !== result) {
3817
- targetData[key] = result;
3818
- cachedSourceData[key] = source;
3819
- }
3820
- }
3821
- await bucketLoader.push(targetLocale, targetData);
3822
- const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3823
- const checksums = await deltaProcessor.createChecksums(cachedSourceData);
3824
- await deltaProcessor.saveChecksums(checksums);
3825
- bucketOra.succeed(
3826
- `[${sourceLocale} -> ${targetLocale}] Recovered ${Object.keys(cachedSourceData).length} entries from cache`
3827
- );
3828
- }
3829
4236
  }
3830
4237
  }
3831
- deleteCache();
3832
- if (flags.verbose) {
3833
- cacheOra.info("Cache file deleted.");
3834
- }
3835
- } else if (flags.verbose) {
3836
- ora.info("Cache file not found. Skipping recovery.");
4238
+ ora.succeed("Localization state check completed");
3837
4239
  }
3838
4240
  if (flags.frozen) {
3839
4241
  ora.start("Checking for lockfile updates...");
3840
4242
  let requiresUpdate = null;
3841
4243
  bucketLoop: for (const bucket of buckets) {
3842
4244
  for (const bucketPath of bucket.paths) {
3843
- const sourceLocale = resolveOverriddenLocale3(i18nConfig.locale.source, bucketPath.delimiter);
4245
+ const sourceLocale = resolveOverriddenLocale3(
4246
+ i18nConfig.locale.source,
4247
+ bucketPath.delimiter
4248
+ );
3844
4249
  const bucketLoader = createBucketLoader(
3845
4250
  bucket.type,
3846
4251
  bucketPath.pathPattern,
@@ -3854,13 +4259,11 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3854
4259
  );
3855
4260
  bucketLoader.setDefaultLocale(sourceLocale);
3856
4261
  await bucketLoader.init();
3857
- const { unlocalizable: sourceUnlocalizable, ...sourceData } = await bucketLoader.pull(
3858
- i18nConfig.locale.source
3859
- );
4262
+ const { unlocalizable: sourceUnlocalizable, ...sourceData } = await bucketLoader.pull(i18nConfig.locale.source);
3860
4263
  const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
3861
4264
  const sourceChecksums = await deltaProcessor.createChecksums(sourceData);
3862
4265
  const savedChecksums = await deltaProcessor.loadChecksums();
3863
- const updatedSourceData = _22.pickBy(
4266
+ const updatedSourceData = _21.pickBy(
3864
4267
  sourceData,
3865
4268
  (value, key) => sourceChecksums[key] !== savedChecksums[key]
3866
4269
  );
@@ -3869,11 +4272,23 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3869
4272
  break bucketLoop;
3870
4273
  }
3871
4274
  for (const _targetLocale of targetLocales) {
3872
- const targetLocale = resolveOverriddenLocale3(_targetLocale, bucketPath.delimiter);
4275
+ const targetLocale = resolveOverriddenLocale3(
4276
+ _targetLocale,
4277
+ bucketPath.delimiter
4278
+ );
3873
4279
  const { unlocalizable: targetUnlocalizable, ...targetData } = await bucketLoader.pull(targetLocale);
3874
- const missingKeys = _22.difference(Object.keys(sourceData), Object.keys(targetData));
3875
- const extraKeys = _22.difference(Object.keys(targetData), Object.keys(sourceData));
3876
- 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
+ );
3877
4292
  if (missingKeys.length > 0) {
3878
4293
  requiresUpdate = "missing";
3879
4294
  break bucketLoop;
@@ -3896,7 +4311,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3896
4311
  extra: "Target file has extra translations not present in the source file.",
3897
4312
  unlocalizable: "Unlocalizable data (such as booleans, dates, URLs, etc.) do not match."
3898
4313
  }[requiresUpdate];
3899
- 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
+ );
3900
4317
  ora.fail(` Details: ${message}`);
3901
4318
  process.exit(1);
3902
4319
  } else {
@@ -3908,8 +4325,13 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3908
4325
  console.log();
3909
4326
  ora.info(`Processing bucket: ${bucket.type}`);
3910
4327
  for (const bucketPath of bucket.paths) {
3911
- const bucketOra = Ora5({ indent: 2 }).info(`Processing path: ${bucketPath.pathPattern}`);
3912
- 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
+ );
3913
4335
  const bucketLoader = createBucketLoader(
3914
4336
  bucket.type,
3915
4337
  bucketPath.pathPattern,
@@ -3924,21 +4346,33 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3924
4346
  await bucketLoader.init();
3925
4347
  let sourceData = await bucketLoader.pull(sourceLocale);
3926
4348
  for (const _targetLocale of targetLocales) {
3927
- const targetLocale = resolveOverriddenLocale3(_targetLocale, bucketPath.delimiter);
4349
+ const targetLocale = resolveOverriddenLocale3(
4350
+ _targetLocale,
4351
+ bucketPath.delimiter
4352
+ );
3928
4353
  try {
3929
- bucketOra.start(`[${sourceLocale} -> ${targetLocale}] (0%) Localization in progress...`);
4354
+ bucketOra.start(
4355
+ `[${sourceLocale} -> ${targetLocale}] (0%) Localization in progress...`
4356
+ );
3930
4357
  sourceData = await bucketLoader.pull(sourceLocale);
3931
4358
  const targetData = await bucketLoader.pull(targetLocale);
3932
- const deltaProcessor2 = createDeltaProcessor(bucketPath.pathPattern);
4359
+ const deltaProcessor2 = createDeltaProcessor(
4360
+ bucketPath.pathPattern
4361
+ );
3933
4362
  const checksums2 = await deltaProcessor2.loadChecksums();
3934
4363
  const delta = await deltaProcessor2.calculateDelta({
3935
4364
  sourceData,
3936
4365
  targetData,
3937
4366
  checksums: checksums2
3938
4367
  });
3939
- 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();
3940
4371
  if (flags.key) {
3941
- processableData = _22.pickBy(processableData, (_25, key) => key === flags.key);
4372
+ processableData = _21.pickBy(
4373
+ processableData,
4374
+ (_24, key) => key === flags.key
4375
+ );
3942
4376
  }
3943
4377
  if (flags.verbose) {
3944
4378
  bucketOra.info(JSON.stringify(processableData, null, 2));
@@ -3950,7 +4384,11 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3950
4384
  apiKey: settings.auth.apiKey,
3951
4385
  apiUrl: settings.auth.apiUrl
3952
4386
  });
3953
- processPayload = withExponentialBackoff(processPayload, 3, 1e3);
4387
+ processPayload = withExponentialBackoff(
4388
+ processPayload,
4389
+ 3,
4390
+ 1e3
4391
+ );
3954
4392
  const processedTargetData = await processPayload(
3955
4393
  {
3956
4394
  sourceLocale,
@@ -3975,7 +4413,12 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3975
4413
  if (flags.verbose) {
3976
4414
  bucketOra.info(JSON.stringify(processedTargetData, null, 2));
3977
4415
  }
3978
- let finalTargetData = _22.merge({}, sourceData, targetData, processedTargetData);
4416
+ let finalTargetData = _21.merge(
4417
+ {},
4418
+ sourceData,
4419
+ targetData,
4420
+ processedTargetData
4421
+ );
3979
4422
  if (flags.interactive) {
3980
4423
  bucketOra.stop();
3981
4424
  const reviewedData = await reviewChanges({
@@ -3987,17 +4430,25 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
3987
4430
  force: flags.force
3988
4431
  });
3989
4432
  finalTargetData = reviewedData;
3990
- bucketOra.start(`Applying changes to ${bucketPath} (${targetLocale})`);
4433
+ bucketOra.start(
4434
+ `Applying changes to ${bucketPath} (${targetLocale})`
4435
+ );
3991
4436
  }
3992
- 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();
3993
4438
  await bucketLoader.push(targetLocale, finalTargetData);
3994
4439
  if (finalDiffSize > 0 || flags.force) {
3995
- bucketOra.succeed(`[${sourceLocale} -> ${targetLocale}] Localization completed`);
4440
+ bucketOra.succeed(
4441
+ `[${sourceLocale} -> ${targetLocale}] Localization completed`
4442
+ );
3996
4443
  } else {
3997
- bucketOra.succeed(`[${sourceLocale} -> ${targetLocale}] Localization completed (no changes).`);
4444
+ bucketOra.succeed(
4445
+ `[${sourceLocale} -> ${targetLocale}] Localization completed (no changes).`
4446
+ );
3998
4447
  }
3999
4448
  } catch (_error) {
4000
- const error = new Error(`[${sourceLocale} -> ${targetLocale}] Localization failed: ${_error.message}`);
4449
+ const error = new Error(
4450
+ `[${sourceLocale} -> ${targetLocale}] Localization failed: ${_error.message}`
4451
+ );
4001
4452
  if (flags.strict) {
4002
4453
  throw error;
4003
4454
  } else {
@@ -4011,7 +4462,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
4011
4462
  await deltaProcessor.saveChecksums(checksums);
4012
4463
  }
4013
4464
  } catch (_error) {
4014
- 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
+ );
4015
4468
  if (flags.strict) {
4016
4469
  throw error;
4017
4470
  } else {
@@ -4094,7 +4547,9 @@ function validateParams(i18nConfig, flags) {
4094
4547
  message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
4095
4548
  docUrl: "localeTargetNotFound"
4096
4549
  });
4097
- } else if (flags.bucket?.some((bucket) => !i18nConfig.buckets[bucket])) {
4550
+ } else if (flags.bucket?.some(
4551
+ (bucket) => !i18nConfig.buckets[bucket]
4552
+ )) {
4098
4553
  throw new CLIError({
4099
4554
  message: `One or more specified buckets do not exist in i18n.json. Please add them to the list and try again.`,
4100
4555
  docUrl: "bucketNotFound"
@@ -4126,8 +4581,10 @@ ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targetLocale)}): ${chalk.gr
4126
4581
  if (line.startsWith("@")) return chalk.cyan(line);
4127
4582
  return line;
4128
4583
  }).join("\n");
4129
- console.log(`
4130
- 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
+ );
4131
4588
  console.log(coloredDiff);
4132
4589
  const { action } = await inquirer2.prompt([
4133
4590
  {
@@ -4149,7 +4606,7 @@ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targe
4149
4606
  return args.currentData;
4150
4607
  }
4151
4608
  const customData = { ...args.currentData };
4152
- const changes = _22.reduce(
4609
+ const changes = _21.reduce(
4153
4610
  args.proposedData,
4154
4611
  (result, value, key) => {
4155
4612
  if (args.currentData[key] !== value) {
@@ -4163,9 +4620,19 @@ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targe
4163
4620
  console.log(`
4164
4621
  Editing value for: ${chalk.cyan(key)}`);
4165
4622
  console.log(chalk.gray("Source text:"), chalk.blue(args.sourceData[key]));
4166
- console.log(chalk.gray("Current value:"), chalk.red(args.currentData[key] || "(empty)"));
4167
- console.log(chalk.gray("Suggested value:"), chalk.green(args.proposedData[key]));
4168
- 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
+ );
4169
4636
  console.log(chalk.gray("------------"));
4170
4637
  try {
4171
4638
  const editorContent = [
@@ -4186,11 +4653,15 @@ Editing value for: ${chalk.cyan(key)}`);
4186
4653
  if (customValue) {
4187
4654
  customData[key] = customValue;
4188
4655
  } else {
4189
- 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
+ );
4190
4659
  customData[key] = args.currentData[key] || args.proposedData[key];
4191
4660
  }
4192
4661
  } catch (error) {
4193
- 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
+ );
4194
4665
  customData[key] = args.proposedData[key];
4195
4666
  }
4196
4667
  }
@@ -4208,7 +4679,7 @@ import path16 from "path";
4208
4679
  import Z4 from "zod";
4209
4680
  import YAML4 from "yaml";
4210
4681
  import { MD5 as MD52 } from "object-hash";
4211
- import _23 from "lodash";
4682
+ import _22 from "lodash";
4212
4683
  function createLockfileHelper() {
4213
4684
  return {
4214
4685
  isLockfileExists: () => {
@@ -4218,23 +4689,23 @@ function createLockfileHelper() {
4218
4689
  registerSourceData: (pathPattern, sourceData) => {
4219
4690
  const lockfile = _loadLockfile();
4220
4691
  const sectionKey = MD52(pathPattern);
4221
- const sectionChecksums = _23.mapValues(sourceData, (value) => MD52(value));
4692
+ const sectionChecksums = _22.mapValues(sourceData, (value) => MD52(value));
4222
4693
  lockfile.checksums[sectionKey] = sectionChecksums;
4223
4694
  _saveLockfile(lockfile);
4224
4695
  },
4225
4696
  registerPartialSourceData: (pathPattern, partialSourceData) => {
4226
4697
  const lockfile = _loadLockfile();
4227
4698
  const sectionKey = MD52(pathPattern);
4228
- const sectionChecksums = _23.mapValues(partialSourceData, (value) => MD52(value));
4229
- 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);
4230
4701
  _saveLockfile(lockfile);
4231
4702
  },
4232
4703
  extractUpdatedData: (pathPattern, sourceData) => {
4233
4704
  const lockfile = _loadLockfile();
4234
4705
  const sectionKey = MD52(pathPattern);
4235
- const currentChecksums = _23.mapValues(sourceData, (value) => MD52(value));
4706
+ const currentChecksums = _22.mapValues(sourceData, (value) => MD52(value));
4236
4707
  const savedChecksums = lockfile.checksums[sectionKey] || {};
4237
- const updatedData = _23.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4708
+ const updatedData = _22.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
4238
4709
  return updatedData;
4239
4710
  }
4240
4711
  };
@@ -4304,7 +4775,7 @@ var flagsSchema = Z5.object({
4304
4775
  // src/cli/cmd/cleanup.ts
4305
4776
  import { resolveOverriddenLocale as resolveOverriddenLocale5 } from "@lingo.dev/_spec";
4306
4777
  import { Command as Command8 } from "interactive-commander";
4307
- import _24 from "lodash";
4778
+ import _23 from "lodash";
4308
4779
  import Ora7 from "ora";
4309
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(
4310
4781
  "--verbose",
@@ -4340,7 +4811,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
4340
4811
  try {
4341
4812
  const targetData = await bucketLoader.pull(targetLocale);
4342
4813
  const targetKeys = Object.keys(targetData);
4343
- const keysToRemove = _24.difference(targetKeys, sourceKeys);
4814
+ const keysToRemove = _23.difference(targetKeys, sourceKeys);
4344
4815
  if (keysToRemove.length === 0) {
4345
4816
  bucketOra.succeed(`[${targetLocale}] No keys to remove`);
4346
4817
  continue;
@@ -4349,7 +4820,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
4349
4820
  bucketOra.info(`[${targetLocale}] Keys to remove: ${JSON.stringify(keysToRemove, null, 2)}`);
4350
4821
  }
4351
4822
  if (!options.dryRun) {
4352
- const cleanedData = _24.pick(targetData, sourceKeys);
4823
+ const cleanedData = _23.pick(targetData, sourceKeys);
4353
4824
  await bucketLoader.push(targetLocale, cleanedData);
4354
4825
  bucketOra.succeed(`[${targetLocale}] Removed ${keysToRemove.length} keys`);
4355
4826
  } else {
@@ -4404,7 +4875,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
4404
4875
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4405
4876
  import Z6 from "zod";
4406
4877
  import { ReplexicaEngine } from "@lingo.dev/_sdk";
4407
- 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) => {
4408
4879
  const apiKey = program.args[0];
4409
4880
  const settings = getSettings(apiKey);
4410
4881
  if (!settings.auth.apiKey) {
@@ -5485,7 +5956,7 @@ function validateParams2(i18nConfig, flags) {
5485
5956
  // package.json
5486
5957
  var package_default = {
5487
5958
  name: "lingo.dev",
5488
- version: "0.85.7",
5959
+ version: "0.87.0",
5489
5960
  description: "Lingo.dev CLI",
5490
5961
  private: false,
5491
5962
  publishConfig: {
@@ -5559,6 +6030,7 @@ var package_default = {
5559
6030
  "csv-parse": "^5.6.0",
5560
6031
  "csv-stringify": "^6.5.2",
5561
6032
  "date-fns": "^4.1.0",
6033
+ dedent: "^1.5.3",
5562
6034
  diff: "^7.0.0",
5563
6035
  dotenv: "^16.4.7",
5564
6036
  express: "^4.21.2",
@@ -5578,6 +6050,9 @@ var package_default = {
5578
6050
  jsonrepair: "^3.11.2",
5579
6051
  lodash: "^4.17.21",
5580
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",
5581
6056
  "node-webvtt": "^1.9.4",
5582
6057
  "object-hash": "^3.0.0",
5583
6058
  octokit: "^4.0.2",
@@ -5588,14 +6063,18 @@ var package_default = {
5588
6063
  plist: "^3.1.0",
5589
6064
  "posthog-node": "^4.11.2",
5590
6065
  prettier: "^3.4.2",
6066
+ "rehype-stringify": "^10.0.1",
6067
+ "remark-disable-tokenizers": "^1.1.1",
5591
6068
  "remark-frontmatter": "^5.0.0",
5592
6069
  "remark-gfm": "^4.0.1",
5593
6070
  "remark-mdx": "^3.1.0",
5594
6071
  "remark-mdx-frontmatter": "^5.1.0",
5595
6072
  "remark-parse": "^11.0.0",
6073
+ "remark-rehype": "^11.1.2",
5596
6074
  "remark-stringify": "^11.0.0",
5597
6075
  "srt-parser-2": "^1.2.3",
5598
6076
  unified: "^11.0.5",
6077
+ "unist-util-visit": "^5.0.0",
5599
6078
  vfile: "^6.0.3",
5600
6079
  xliff: "^6.2.1",
5601
6080
  xml2js: "^0.6.2",