lingo.dev 0.74.12 → 0.74.13

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
@@ -580,7 +580,7 @@ import { bucketTypeSchema, localeCodeSchema, resolveOverridenLocale as resolveOv
580
580
  import { ReplexicaEngine } from "@lingo.dev/_sdk";
581
581
  import { Command as Command6 } from "interactive-commander";
582
582
  import Z4 from "zod";
583
- import _17 from "lodash";
583
+ import _18 from "lodash";
584
584
  import Ora5 from "ora";
585
585
 
586
586
  // src/cli/loaders/_utils.ts
@@ -682,26 +682,87 @@ function createJsonLoader() {
682
682
 
683
683
  // src/cli/loaders/flat.ts
684
684
  import { flatten, unflatten } from "flat";
685
+ import _5 from "lodash";
686
+ var OBJECT_NUMERIC_KEY_PREFIX = "__lingodotdev__obj__";
685
687
  function createFlatLoader() {
688
+ let denormalizedKeysMap = {};
686
689
  return createLoader({
687
690
  pull: async (locale, input) => {
688
- return flatten(input || {}, {
691
+ const denormalized = denormalizeObjectKeys(input || {});
692
+ const flattened = flatten(denormalized, {
689
693
  delimiter: "/",
690
694
  transformKey(key) {
691
695
  return encodeURIComponent(String(key));
692
696
  }
693
697
  });
698
+ denormalizedKeysMap = { ...denormalizedKeysMap, ...buildDenormalizedKeysMap(flattened) };
699
+ const normalized = normalizeObjectKeys(flattened);
700
+ return normalized;
694
701
  },
695
702
  push: async (locale, data) => {
696
- return unflatten(data || {}, {
703
+ const denormalized = mapDenormalizedKeys(data, denormalizedKeysMap);
704
+ const unflattened = unflatten(denormalized || {}, {
697
705
  delimiter: "/",
698
706
  transformKey(key) {
699
707
  return decodeURIComponent(String(key));
700
708
  }
701
709
  });
710
+ const normalized = normalizeObjectKeys(unflattened);
711
+ return normalized;
702
712
  }
703
713
  });
704
714
  }
715
+ function buildDenormalizedKeysMap(obj) {
716
+ if (!obj) return {};
717
+ return Object.keys(obj).reduce(
718
+ (acc, key) => {
719
+ if (key) {
720
+ const normalizedKey = `${key}`.replace(OBJECT_NUMERIC_KEY_PREFIX, "");
721
+ acc[normalizedKey] = key;
722
+ }
723
+ return acc;
724
+ },
725
+ {}
726
+ );
727
+ }
728
+ function mapDenormalizedKeys(obj, denormalizedKeysMap) {
729
+ return Object.keys(obj).reduce(
730
+ (acc, key) => {
731
+ const denormalizedKey = denormalizedKeysMap[key];
732
+ acc[denormalizedKey] = obj[key];
733
+ return acc;
734
+ },
735
+ {}
736
+ );
737
+ }
738
+ function denormalizeObjectKeys(obj) {
739
+ if (_5.isObject(obj) && !_5.isArray(obj)) {
740
+ return _5.transform(
741
+ obj,
742
+ (result, value, key) => {
743
+ const newKey = !isNaN(Number(key)) ? `${OBJECT_NUMERIC_KEY_PREFIX}${key}` : key;
744
+ result[newKey] = _5.isObject(value) ? denormalizeObjectKeys(value) : value;
745
+ },
746
+ {}
747
+ );
748
+ } else {
749
+ return obj;
750
+ }
751
+ }
752
+ function normalizeObjectKeys(obj) {
753
+ if (_5.isObject(obj) && !_5.isArray(obj)) {
754
+ return _5.transform(
755
+ obj,
756
+ (result, value, key) => {
757
+ const newKey = `${key}`.replace(OBJECT_NUMERIC_KEY_PREFIX, "");
758
+ result[newKey] = _5.isObject(value) ? normalizeObjectKeys(value) : value;
759
+ },
760
+ {}
761
+ );
762
+ } else {
763
+ return obj;
764
+ }
765
+ }
705
766
 
706
767
  // src/cli/loaders/text-file.ts
707
768
  import fs5 from "fs/promises";
@@ -713,7 +774,7 @@ function createTextFileLoader(pathPattern) {
713
774
  const trimmedResult = result.trim();
714
775
  return trimmedResult;
715
776
  },
716
- async push(locale, data, _19, originalLocale) {
777
+ async push(locale, data, _20, originalLocale) {
717
778
  const draftPath = pathPattern.replace("[locale]", locale);
718
779
  const finalPath = path6.resolve(draftPath);
719
780
  const dirPath = path6.dirname(finalPath);
@@ -782,15 +843,15 @@ function createRootKeyLoader(replaceAll = false) {
782
843
  }
783
844
 
784
845
  // src/cli/loaders/flutter.ts
785
- import _5 from "lodash";
846
+ import _6 from "lodash";
786
847
  function createFlutterLoader() {
787
848
  return createLoader({
788
849
  async pull(locale, input) {
789
- const result = _5.pickBy(input, (value, key) => !key.startsWith("@"));
850
+ const result = _6.pickBy(input, (value, key) => !key.startsWith("@"));
790
851
  return result;
791
852
  },
792
853
  async push(locale, data, originalInput) {
793
- const result = _5.merge({}, originalInput, { "@@locale": locale }, data);
854
+ const result = _6.merge({}, originalInput, { "@@locale": locale }, data);
794
855
  return result;
795
856
  }
796
857
  });
@@ -892,7 +953,7 @@ function createAndroidLoader() {
892
953
  // src/cli/loaders/csv.ts
893
954
  import { parse } from "csv-parse/sync";
894
955
  import { stringify } from "csv-stringify/sync";
895
- import _6 from "lodash";
956
+ import _7 from "lodash";
896
957
  function createCsvLoader() {
897
958
  return createLoader({
898
959
  async pull(locale, _input) {
@@ -900,7 +961,7 @@ function createCsvLoader() {
900
961
  columns: true
901
962
  });
902
963
  const result = {};
903
- _6.forEach(input, (row) => {
964
+ _7.forEach(input, (row) => {
904
965
  const key = row.id;
905
966
  if (key && row[locale]) {
906
967
  result[key] = row[locale];
@@ -1118,7 +1179,7 @@ function createPropertiesLoader() {
1118
1179
  return result;
1119
1180
  },
1120
1181
  async push(locale, payload) {
1121
- const result = Object.entries(payload).filter(([_19, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1182
+ const result = Object.entries(payload).filter(([_20, value]) => value != null).map(([key, value]) => `${key}=${value}`).join("\n");
1122
1183
  return result;
1123
1184
  }
1124
1185
  });
@@ -1204,7 +1265,7 @@ function createXcodeStringsdictLoader() {
1204
1265
  }
1205
1266
 
1206
1267
  // src/cli/loaders/xcode-xcstrings.ts
1207
- import _7 from "lodash";
1268
+ import _8 from "lodash";
1208
1269
  function createXcodeXcstringsLoader() {
1209
1270
  return createLoader({
1210
1271
  async pull(locale, input) {
@@ -1268,7 +1329,7 @@ function createXcodeXcstringsLoader() {
1268
1329
  };
1269
1330
  }
1270
1331
  }
1271
- const result = _7.merge({}, originalInput, langDataToMerge);
1332
+ const result = _8.merge({}, originalInput, langDataToMerge);
1272
1333
  return result;
1273
1334
  }
1274
1335
  });
@@ -1310,17 +1371,17 @@ async function loadPrettierConfig() {
1310
1371
  }
1311
1372
 
1312
1373
  // src/cli/loaders/unlocalizable.ts
1313
- import _8 from "lodash";
1374
+ import _9 from "lodash";
1314
1375
  import _isUrl from "is-url";
1315
1376
  import { isValid, parseISO } from "date-fns";
1316
1377
  function createUnlocalizableLoader() {
1317
1378
  const rules = {
1318
- isEmpty: (v) => _8.isEmpty(v),
1319
- isNumber: (v) => !_8.isNaN(_8.toNumber(v)),
1320
- isBoolean: (v) => _8.isBoolean(v),
1321
- isIsoDate: (v) => _8.isString(v) && _isIsoDate(v),
1322
- isSystemId: (v) => _8.isString(v) && _isSystemId(v),
1323
- isUrl: (v) => _8.isString(v) && _isUrl(v)
1379
+ isEmpty: (v) => _9.isEmpty(v),
1380
+ isNumber: (v) => !_9.isNaN(_9.toNumber(v)),
1381
+ isBoolean: (v) => _9.isBoolean(v),
1382
+ isIsoDate: (v) => _9.isString(v) && _isIsoDate(v),
1383
+ isSystemId: (v) => _9.isString(v) && _isSystemId(v),
1384
+ isUrl: (v) => _9.isString(v) && _isUrl(v)
1324
1385
  };
1325
1386
  return createLoader({
1326
1387
  async pull(locale, input) {
@@ -1331,12 +1392,12 @@ function createUnlocalizableLoader() {
1331
1392
  }
1332
1393
  }
1333
1394
  return false;
1334
- }).map(([key, _19]) => key);
1335
- const result = _8.omitBy(input, (_19, key) => passthroughKeys.includes(key));
1395
+ }).map(([key, _20]) => key);
1396
+ const result = _9.omitBy(input, (_20, key) => passthroughKeys.includes(key));
1336
1397
  return result;
1337
1398
  },
1338
1399
  async push(locale, data, originalInput) {
1339
- const result = _8.merge({}, originalInput, data);
1400
+ const result = _9.merge({}, originalInput, data);
1340
1401
  return result;
1341
1402
  }
1342
1403
  });
@@ -1349,7 +1410,7 @@ function _isIsoDate(v) {
1349
1410
  }
1350
1411
 
1351
1412
  // src/cli/loaders/po/index.ts
1352
- import _9 from "lodash";
1413
+ import _10 from "lodash";
1353
1414
  import gettextParser from "gettext-parser";
1354
1415
  function createPoLoader(params = { multiline: false }) {
1355
1416
  return composeLoaders(createPoDataLoader(params), createPoContentLoader());
@@ -1362,7 +1423,7 @@ function createPoDataLoader(params) {
1362
1423
  const sections = input.split("\n\n").filter(Boolean);
1363
1424
  for (const section of sections) {
1364
1425
  const sectionPo = gettextParser.po.parse(section);
1365
- const contextKey = _9.keys(sectionPo.translations)[0];
1426
+ const contextKey = _10.keys(sectionPo.translations)[0];
1366
1427
  const entries = sectionPo.translations[contextKey];
1367
1428
  Object.entries(entries).forEach(([msgid, entry]) => {
1368
1429
  if (msgid && entry.msgid) {
@@ -1380,12 +1441,12 @@ function createPoDataLoader(params) {
1380
1441
  const sections = originalInput?.split("\n\n").filter(Boolean) || [];
1381
1442
  const result = sections.map((section) => {
1382
1443
  const sectionPo = gettextParser.po.parse(section);
1383
- const contextKey = _9.keys(sectionPo.translations)[0];
1444
+ const contextKey = _10.keys(sectionPo.translations)[0];
1384
1445
  const entries = sectionPo.translations[contextKey];
1385
1446
  const msgid = Object.keys(entries).find((key) => entries[key].msgid);
1386
1447
  if (!msgid) return section;
1387
1448
  if (data[msgid]) {
1388
- const updatedPo = _9.merge({}, sectionPo, {
1449
+ const updatedPo = _10.merge({}, sectionPo, {
1389
1450
  translations: {
1390
1451
  [contextKey]: {
1391
1452
  [msgid]: {
@@ -1405,7 +1466,7 @@ function createPoDataLoader(params) {
1405
1466
  function createPoContentLoader() {
1406
1467
  return createLoader({
1407
1468
  async pull(locale, input) {
1408
- const result = _9.chain(input).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => [
1469
+ const result = _10.chain(input).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => [
1409
1470
  entry.msgid,
1410
1471
  {
1411
1472
  singular: entry.msgstr[0] || entry.msgid,
@@ -1415,7 +1476,7 @@ function createPoContentLoader() {
1415
1476
  return result;
1416
1477
  },
1417
1478
  async push(locale, data, originalInput) {
1418
- const result = _9.chain(originalInput).entries().map(([, entry]) => [
1479
+ const result = _10.chain(originalInput).entries().map(([, entry]) => [
1419
1480
  entry.msgid,
1420
1481
  {
1421
1482
  ...entry,
@@ -1538,34 +1599,34 @@ var datoSettingsSchema = Z2.object({
1538
1599
  });
1539
1600
 
1540
1601
  // src/cli/loaders/dato/filter.ts
1541
- import _10 from "lodash";
1602
+ import _11 from "lodash";
1542
1603
  function createDatoFilterLoader() {
1543
1604
  return createLoader({
1544
1605
  async pull(locale, input) {
1545
1606
  const result = {};
1546
- for (const [modelId, modelInfo] of _10.entries(input)) {
1607
+ for (const [modelId, modelInfo] of _11.entries(input)) {
1547
1608
  result[modelId] = {};
1548
1609
  for (const record of modelInfo.records) {
1549
- result[modelId][record.id] = _10.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _10.get(record, [field.api_key, locale])).value();
1610
+ result[modelId][record.id] = _11.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _11.get(record, [field.api_key, locale])).value();
1550
1611
  }
1551
1612
  }
1552
1613
  return result;
1553
1614
  },
1554
1615
  async push(locale, data, originalInput, originalLocale) {
1555
- const result = _10.cloneDeep(originalInput || {});
1556
- for (const [modelId, modelInfo] of _10.entries(result)) {
1616
+ const result = _11.cloneDeep(originalInput || {});
1617
+ for (const [modelId, modelInfo] of _11.entries(result)) {
1557
1618
  for (const record of modelInfo.records) {
1558
- for (const [fieldId, fieldValue] of _10.entries(record)) {
1619
+ for (const [fieldId, fieldValue] of _11.entries(record)) {
1559
1620
  const fieldInfo = modelInfo.fields.find((field) => field.api_key === fieldId);
1560
1621
  if (fieldInfo) {
1561
- const sourceFieldValue = _10.get(fieldValue, [originalLocale]);
1562
- const targetFieldValue = _10.get(data, [modelId, record.id, fieldId]);
1622
+ const sourceFieldValue = _11.get(fieldValue, [originalLocale]);
1623
+ const targetFieldValue = _11.get(data, [modelId, record.id, fieldId]);
1563
1624
  if (targetFieldValue) {
1564
- _10.set(record, [fieldId, locale], targetFieldValue);
1625
+ _11.set(record, [fieldId, locale], targetFieldValue);
1565
1626
  } else {
1566
- _10.set(record, [fieldId, locale], sourceFieldValue);
1627
+ _11.set(record, [fieldId, locale], sourceFieldValue);
1567
1628
  }
1568
- _10.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _10.isEmpty(_10.get(fieldValue, [loc]))).forEach((loc) => _10.set(record, [fieldId, loc], sourceFieldValue)).value();
1629
+ _11.chain(fieldValue).keys().reject((loc) => loc === locale || loc === originalLocale).filter((loc) => _11.isEmpty(_11.get(fieldValue, [loc]))).forEach((loc) => _11.set(record, [fieldId, loc], sourceFieldValue)).value();
1569
1630
  }
1570
1631
  }
1571
1632
  }
@@ -1576,10 +1637,10 @@ function createDatoFilterLoader() {
1576
1637
  }
1577
1638
 
1578
1639
  // src/cli/loaders/dato/api.ts
1579
- import _12 from "lodash";
1640
+ import _13 from "lodash";
1580
1641
 
1581
1642
  // src/cli/loaders/dato/_utils.ts
1582
- import _11 from "lodash";
1643
+ import _12 from "lodash";
1583
1644
  import { buildClient } from "@datocms/cma-client-node";
1584
1645
  function createDatoClient(params) {
1585
1646
  if (!params.apiKey) {
@@ -1754,7 +1815,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
1754
1815
  const result = {
1755
1816
  models: {}
1756
1817
  };
1757
- const updatedConfig = _12.cloneDeep(config);
1818
+ const updatedConfig = _13.cloneDeep(config);
1758
1819
  console.log(`Initializing DatoCMS loader...`);
1759
1820
  const project = await dato.findProject();
1760
1821
  const modelChoices = await getModelChoices(dato, config);
@@ -1772,7 +1833,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
1772
1833
  delete updatedConfig.models[modelId];
1773
1834
  }
1774
1835
  }
1775
- for (const modelId of _12.keys(updatedConfig.models)) {
1836
+ for (const modelId of _13.keys(updatedConfig.models)) {
1776
1837
  const { modelName, fields } = await getModelFields(dato, modelId);
1777
1838
  if (fields.length > 0) {
1778
1839
  result.models[modelId] = { fields: [], records: [] };
@@ -1783,7 +1844,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
1783
1844
  const isLocalized = await updateFieldLocalization(dato, fieldInfo, selectedFields.includes(fieldInfo.id));
1784
1845
  if (isLocalized) {
1785
1846
  result.models[modelId].fields.push(fieldInfo);
1786
- updatedConfig.models[modelId].fields = _12.uniq([
1847
+ updatedConfig.models[modelId].fields = _13.uniq([
1787
1848
  ...updatedConfig.models[modelId].fields || [],
1788
1849
  fieldInfo.api_key
1789
1850
  ]);
@@ -1802,7 +1863,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
1802
1863
  },
1803
1864
  async pull(locale, input, initCtx) {
1804
1865
  const result = {};
1805
- for (const modelId of _12.keys(initCtx?.models || {})) {
1866
+ for (const modelId of _13.keys(initCtx?.models || {})) {
1806
1867
  let records = initCtx?.models[modelId].records || [];
1807
1868
  const recordIds = records.map((record) => record.id);
1808
1869
  records = await dato.findRecords(recordIds);
@@ -1817,7 +1878,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
1817
1878
  return result;
1818
1879
  },
1819
1880
  async push(locale, data, originalInput) {
1820
- for (const modelId of _12.keys(data)) {
1881
+ for (const modelId of _13.keys(data)) {
1821
1882
  for (let i = 0; i < data[modelId].records.length; i++) {
1822
1883
  const record = data[modelId].records[i];
1823
1884
  console.log(`Updating record ${i + 1}/${data[modelId].records.length} for model ${modelId}...`);
@@ -1831,7 +1892,7 @@ async function getModelFields(dato, modelId) {
1831
1892
  const modelInfo = await dato.findModel(modelId);
1832
1893
  return {
1833
1894
  modelName: modelInfo.name,
1834
- fields: _12.filter(modelInfo.fields, (field) => field.type === "field")
1895
+ fields: _13.filter(modelInfo.fields, (field) => field.type === "field")
1835
1896
  };
1836
1897
  }
1837
1898
  async function getFieldDetails(dato, fields) {
@@ -1909,17 +1970,17 @@ async function promptModelSelection(choices) {
1909
1970
  }
1910
1971
 
1911
1972
  // src/cli/loaders/dato/extract.ts
1912
- import _13 from "lodash";
1973
+ import _14 from "lodash";
1913
1974
  function createDatoExtractLoader() {
1914
1975
  return createLoader({
1915
1976
  async pull(locale, input) {
1916
1977
  const result = {};
1917
- for (const [modelId, modelInfo] of _13.entries(input)) {
1918
- for (const [recordId, record] of _13.entries(modelInfo)) {
1919
- for (const [fieldName, fieldValue] of _13.entries(record)) {
1978
+ for (const [modelId, modelInfo] of _14.entries(input)) {
1979
+ for (const [recordId, record] of _14.entries(modelInfo)) {
1980
+ for (const [fieldName, fieldValue] of _14.entries(record)) {
1920
1981
  const parsedValue = createParsedDatoValue(fieldValue);
1921
1982
  if (parsedValue) {
1922
- _13.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
1983
+ _14.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
1923
1984
  }
1924
1985
  }
1925
1986
  }
@@ -1927,14 +1988,14 @@ function createDatoExtractLoader() {
1927
1988
  return result;
1928
1989
  },
1929
1990
  async push(locale, data, originalInput) {
1930
- const result = _13.cloneDeep(originalInput || {});
1931
- for (const [modelId, modelInfo] of _13.entries(data)) {
1932
- for (const [virtualRecordId, record] of _13.entries(modelInfo)) {
1933
- for (const [fieldName, fieldValue] of _13.entries(record)) {
1991
+ const result = _14.cloneDeep(originalInput || {});
1992
+ for (const [modelId, modelInfo] of _14.entries(data)) {
1993
+ for (const [virtualRecordId, record] of _14.entries(modelInfo)) {
1994
+ for (const [fieldName, fieldValue] of _14.entries(record)) {
1934
1995
  const [, recordId] = virtualRecordId.split("_");
1935
- const originalFieldValue = _13.get(originalInput, [modelId, recordId, fieldName]);
1996
+ const originalFieldValue = _14.get(originalInput, [modelId, recordId, fieldName]);
1936
1997
  const rawValue = createRawDatoValue(fieldValue, originalFieldValue, true);
1937
- _13.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
1998
+ _14.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
1938
1999
  }
1939
2000
  }
1940
2001
  }
@@ -1943,25 +2004,25 @@ function createDatoExtractLoader() {
1943
2004
  });
1944
2005
  }
1945
2006
  function detectDatoFieldType(rawDatoValue) {
1946
- if (_13.has(rawDatoValue, "document") && _13.get(rawDatoValue, "schema") === "dast") {
2007
+ if (_14.has(rawDatoValue, "document") && _14.get(rawDatoValue, "schema") === "dast") {
1947
2008
  return "structured_text";
1948
- } else if (_13.has(rawDatoValue, "no_index") || _13.has(rawDatoValue, "twitter_card")) {
2009
+ } else if (_14.has(rawDatoValue, "no_index") || _14.has(rawDatoValue, "twitter_card")) {
1949
2010
  return "seo";
1950
- } else if (_13.get(rawDatoValue, "type") === "item") {
2011
+ } else if (_14.get(rawDatoValue, "type") === "item") {
1951
2012
  return "single_block";
1952
- } else if (_13.isArray(rawDatoValue) && _13.every(rawDatoValue, (item) => _13.get(item, "type") === "item")) {
2013
+ } else if (_14.isArray(rawDatoValue) && _14.every(rawDatoValue, (item) => _14.get(item, "type") === "item")) {
1953
2014
  return "rich_text";
1954
2015
  } else if (_isFile(rawDatoValue)) {
1955
2016
  return "file";
1956
- } else if (_13.isArray(rawDatoValue) && _13.every(rawDatoValue, (item) => _isFile(item))) {
2017
+ } else if (_14.isArray(rawDatoValue) && _14.every(rawDatoValue, (item) => _isFile(item))) {
1957
2018
  return "gallery";
1958
2019
  } else if (_isJson(rawDatoValue)) {
1959
2020
  return "json";
1960
- } else if (_13.isString(rawDatoValue)) {
2021
+ } else if (_14.isString(rawDatoValue)) {
1961
2022
  return "string";
1962
2023
  } else if (_isVideo(rawDatoValue)) {
1963
2024
  return "video";
1964
- } else if (_13.isArray(rawDatoValue) && _13.every(rawDatoValue, (item) => _13.isString(item))) {
2025
+ } else if (_14.isArray(rawDatoValue) && _14.every(rawDatoValue, (item) => _14.isString(item))) {
1965
2026
  return "ref_list";
1966
2027
  } else {
1967
2028
  return null;
@@ -2023,9 +2084,9 @@ function serializeStructuredText(rawStructuredText) {
2023
2084
  if ("document" in node) {
2024
2085
  return serializeStructuredTextNode(node.document, [...path9, "document"], acc);
2025
2086
  }
2026
- if (!_13.isNil(node.value)) {
2087
+ if (!_14.isNil(node.value)) {
2027
2088
  acc[[...path9, "value"].join(".")] = node.value;
2028
- } else if (_13.get(node, "type") === "block") {
2089
+ } else if (_14.get(node, "type") === "block") {
2029
2090
  acc[[...path9, "item"].join(".")] = serializeBlock(node.item);
2030
2091
  }
2031
2092
  if (node.children) {
@@ -2037,44 +2098,44 @@ function serializeStructuredText(rawStructuredText) {
2037
2098
  }
2038
2099
  }
2039
2100
  function serializeSeo(rawSeo) {
2040
- return _13.chain(rawSeo).pick(["title", "description"]).value();
2101
+ return _14.chain(rawSeo).pick(["title", "description"]).value();
2041
2102
  }
2042
2103
  function serializeBlock(rawBlock) {
2043
- if (_13.get(rawBlock, "type") === "item" && _13.has(rawBlock, "id")) {
2104
+ if (_14.get(rawBlock, "type") === "item" && _14.has(rawBlock, "id")) {
2044
2105
  return serializeBlock(rawBlock.attributes);
2045
2106
  }
2046
2107
  const result = {};
2047
- for (const [attributeName, attributeValue] of _13.entries(rawBlock)) {
2108
+ for (const [attributeName, attributeValue] of _14.entries(rawBlock)) {
2048
2109
  result[attributeName] = createParsedDatoValue(attributeValue);
2049
2110
  }
2050
2111
  return result;
2051
2112
  }
2052
2113
  function serializeBlockList(rawBlockList) {
2053
- return _13.chain(rawBlockList).map((block) => serializeBlock(block)).value();
2114
+ return _14.chain(rawBlockList).map((block) => serializeBlock(block)).value();
2054
2115
  }
2055
2116
  function serializeVideo(rawVideo) {
2056
- return _13.chain(rawVideo).pick(["title"]).value();
2117
+ return _14.chain(rawVideo).pick(["title"]).value();
2057
2118
  }
2058
2119
  function serializeFile(rawFile) {
2059
- return _13.chain(rawFile).pick(["alt", "title"]).value();
2120
+ return _14.chain(rawFile).pick(["alt", "title"]).value();
2060
2121
  }
2061
2122
  function serializeGallery(rawGallery) {
2062
- return _13.chain(rawGallery).map((item) => serializeFile(item)).value();
2123
+ return _14.chain(rawGallery).map((item) => serializeFile(item)).value();
2063
2124
  }
2064
2125
  function deserializeFile(parsedFile, originalRawFile) {
2065
- return _13.chain(parsedFile).defaults(originalRawFile).value();
2126
+ return _14.chain(parsedFile).defaults(originalRawFile).value();
2066
2127
  }
2067
2128
  function deserializeGallery(parsedGallery, originalRawGallery) {
2068
- return _13.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
2129
+ return _14.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
2069
2130
  }
2070
2131
  function deserializeVideo(parsedVideo, originalRawVideo) {
2071
- return _13.chain(parsedVideo).defaults(originalRawVideo).value();
2132
+ return _14.chain(parsedVideo).defaults(originalRawVideo).value();
2072
2133
  }
2073
2134
  function deserializeBlock(payload, rawNode, isClean = false) {
2074
- const result = _13.cloneDeep(rawNode);
2075
- for (const [attributeName, attributeValue] of _13.entries(rawNode.attributes)) {
2135
+ const result = _14.cloneDeep(rawNode);
2136
+ for (const [attributeName, attributeValue] of _14.entries(rawNode.attributes)) {
2076
2137
  const rawValue = createRawDatoValue(payload[attributeName], attributeValue, isClean);
2077
- _13.set(result, ["attributes", attributeName], rawValue);
2138
+ _14.set(result, ["attributes", attributeName], rawValue);
2078
2139
  }
2079
2140
  if (isClean) {
2080
2141
  delete result["id"];
@@ -2082,33 +2143,33 @@ function deserializeBlock(payload, rawNode, isClean = false) {
2082
2143
  return result;
2083
2144
  }
2084
2145
  function deserializeSeo(parsedSeo, originalRawSeo) {
2085
- return _13.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
2146
+ return _14.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
2086
2147
  }
2087
2148
  function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = false) {
2088
- return _13.chain(parsedBlockList).map((block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)).value();
2149
+ return _14.chain(parsedBlockList).map((block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)).value();
2089
2150
  }
2090
2151
  function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
2091
- const result = _13.cloneDeep(originalRawStructuredText);
2092
- for (const [path9, value] of _13.entries(parsedStructuredText)) {
2093
- const realPath = _13.chain(path9.split(".")).flatMap((s) => !_13.isNaN(_13.toNumber(s)) ? ["children", s] : s).value();
2094
- const deserializedValue = createRawDatoValue(value, _13.get(originalRawStructuredText, realPath), true);
2095
- _13.set(result, realPath, deserializedValue);
2152
+ const result = _14.cloneDeep(originalRawStructuredText);
2153
+ for (const [path9, value] of _14.entries(parsedStructuredText)) {
2154
+ const realPath = _14.chain(path9.split(".")).flatMap((s) => !_14.isNaN(_14.toNumber(s)) ? ["children", s] : s).value();
2155
+ const deserializedValue = createRawDatoValue(value, _14.get(originalRawStructuredText, realPath), true);
2156
+ _14.set(result, realPath, deserializedValue);
2096
2157
  }
2097
2158
  return result;
2098
2159
  }
2099
2160
  function _isJson(rawDatoValue) {
2100
2161
  try {
2101
- return _13.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
2162
+ return _14.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
2102
2163
  } catch (e) {
2103
2164
  return false;
2104
2165
  }
2105
2166
  }
2106
2167
  function _isFile(rawDatoValue) {
2107
- return _13.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every((key) => _13.has(rawDatoValue, key));
2168
+ return _14.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every((key) => _14.has(rawDatoValue, key));
2108
2169
  }
2109
2170
  function _isVideo(rawDatoValue) {
2110
- return _13.isObject(rawDatoValue) && ["url", "title", "width", "height", "provider", "provider_uid", "thumbnail_url"].every(
2111
- (key) => _13.has(rawDatoValue, key)
2171
+ return _14.isObject(rawDatoValue) && ["url", "title", "width", "height", "provider", "provider_uid", "thumbnail_url"].every(
2172
+ (key) => _14.has(rawDatoValue, key)
2112
2173
  );
2113
2174
  }
2114
2175
 
@@ -2169,7 +2230,7 @@ function createVttLoader() {
2169
2230
  }
2170
2231
 
2171
2232
  // src/cli/loaders/variable/index.ts
2172
- import _14 from "lodash";
2233
+ import _15 from "lodash";
2173
2234
  function createVariableLoader(params) {
2174
2235
  return composeLoaders(variableExtractLoader(params), variableContentLoader());
2175
2236
  }
@@ -2212,11 +2273,11 @@ function variableExtractLoader(params) {
2212
2273
  function variableContentLoader() {
2213
2274
  return createLoader({
2214
2275
  pull: async (locale, input) => {
2215
- const result = _14.mapValues(input, (payload) => payload.value);
2276
+ const result = _15.mapValues(input, (payload) => payload.value);
2216
2277
  return result;
2217
2278
  },
2218
2279
  push: async (locale, data, originalInput) => {
2219
- const result = _14.cloneDeep(originalInput || {});
2280
+ const result = _15.cloneDeep(originalInput || {});
2220
2281
  for (const [key, originalValueObj] of Object.entries(result)) {
2221
2282
  result[key] = {
2222
2283
  ...originalValueObj,
@@ -2239,20 +2300,20 @@ function getFormatSpecifierPattern(type) {
2239
2300
  }
2240
2301
 
2241
2302
  // src/cli/loaders/sync.ts
2242
- import _15 from "lodash";
2303
+ import _16 from "lodash";
2243
2304
  function createSyncLoader() {
2244
2305
  return createLoader({
2245
2306
  async pull(locale, input, originalInput) {
2246
2307
  if (!originalInput) {
2247
2308
  return input;
2248
2309
  }
2249
- return _15.chain(originalInput).mapValues((value, key) => input[key]).value();
2310
+ return _16.chain(originalInput).mapValues((value, key) => input[key]).value();
2250
2311
  },
2251
2312
  async push(locale, data, originalInput) {
2252
2313
  if (!originalInput) {
2253
2314
  return data;
2254
2315
  }
2255
- return _15.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
2316
+ return _16.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
2256
2317
  }
2257
2318
  });
2258
2319
  }
@@ -2479,7 +2540,7 @@ import path7 from "path";
2479
2540
  import Z3 from "zod";
2480
2541
  import YAML3 from "yaml";
2481
2542
  import { MD5 } from "object-hash";
2482
- import _16 from "lodash";
2543
+ import _17 from "lodash";
2483
2544
  function createLockfileHelper() {
2484
2545
  return {
2485
2546
  isLockfileExists: () => {
@@ -2489,23 +2550,23 @@ function createLockfileHelper() {
2489
2550
  registerSourceData: (pathPattern, sourceData) => {
2490
2551
  const lockfile = _loadLockfile();
2491
2552
  const sectionKey = MD5(pathPattern);
2492
- const sectionChecksums = _16.mapValues(sourceData, (value) => MD5(value));
2553
+ const sectionChecksums = _17.mapValues(sourceData, (value) => MD5(value));
2493
2554
  lockfile.checksums[sectionKey] = sectionChecksums;
2494
2555
  _saveLockfile(lockfile);
2495
2556
  },
2496
2557
  registerPartialSourceData: (pathPattern, partialSourceData) => {
2497
2558
  const lockfile = _loadLockfile();
2498
2559
  const sectionKey = MD5(pathPattern);
2499
- const sectionChecksums = _16.mapValues(partialSourceData, (value) => MD5(value));
2500
- lockfile.checksums[sectionKey] = _16.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
2560
+ const sectionChecksums = _17.mapValues(partialSourceData, (value) => MD5(value));
2561
+ lockfile.checksums[sectionKey] = _17.merge({}, lockfile.checksums[sectionKey] ?? {}, sectionChecksums);
2501
2562
  _saveLockfile(lockfile);
2502
2563
  },
2503
2564
  extractUpdatedData: (pathPattern, sourceData) => {
2504
2565
  const lockfile = _loadLockfile();
2505
2566
  const sectionKey = MD5(pathPattern);
2506
- const currentChecksums = _16.mapValues(sourceData, (value) => MD5(value));
2567
+ const currentChecksums = _17.mapValues(sourceData, (value) => MD5(value));
2507
2568
  const savedChecksums = lockfile.checksums[sectionKey] || {};
2508
- const updatedData = _16.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
2569
+ const updatedData = _17.pickBy(sourceData, (value, key) => savedChecksums[key] !== currentChecksums[key]);
2509
2570
  return updatedData;
2510
2571
  }
2511
2572
  };
@@ -2753,7 +2814,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
2753
2814
  targetData
2754
2815
  });
2755
2816
  if (flags.key) {
2756
- processableData = _17.pickBy(processableData, (_19, key) => key === flags.key);
2817
+ processableData = _18.pickBy(processableData, (_20, key) => key === flags.key);
2757
2818
  }
2758
2819
  if (flags.verbose) {
2759
2820
  bucketOra.info(JSON.stringify(processableData, null, 2));
@@ -2789,7 +2850,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
2789
2850
  if (flags.verbose) {
2790
2851
  bucketOra.info(JSON.stringify(processedTargetData, null, 2));
2791
2852
  }
2792
- let finalTargetData = _17.merge({}, sourceData, targetData, processedTargetData);
2853
+ let finalTargetData = _18.merge({}, sourceData, targetData, processedTargetData);
2793
2854
  if (flags.interactive) {
2794
2855
  bucketOra.stop();
2795
2856
  const reviewedData = await reviewChanges({
@@ -2803,7 +2864,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
2803
2864
  finalTargetData = reviewedData;
2804
2865
  bucketOra.start(`Applying changes to ${bucketConfig} (${targetLocale})`);
2805
2866
  }
2806
- const finalDiffSize = _17.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
2867
+ const finalDiffSize = _18.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
2807
2868
  if (finalDiffSize > 0 || flags.force) {
2808
2869
  await bucketLoader.push(targetLocale, finalTargetData);
2809
2870
  bucketOra.succeed(`[${sourceLocale} -> ${targetLocale}] Localization completed`);
@@ -2848,9 +2909,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
2848
2909
  }
2849
2910
  });
2850
2911
  function calculateDataDelta(args) {
2851
- const newKeys = _17.difference(Object.keys(args.sourceData), Object.keys(args.targetData));
2912
+ const newKeys = _18.difference(Object.keys(args.sourceData), Object.keys(args.targetData));
2852
2913
  const updatedKeys = Object.keys(args.updatedSourceData);
2853
- const result = _17.chain(args.sourceData).pickBy((value, key) => newKeys.includes(key) || updatedKeys.includes(key)).value();
2914
+ const result = _18.chain(args.sourceData).pickBy((value, key) => newKeys.includes(key) || updatedKeys.includes(key)).value();
2854
2915
  return result;
2855
2916
  }
2856
2917
  async function retryWithExponentialBackoff(operation, maxAttempts, baseDelay = 1e3) {
@@ -2991,7 +3052,7 @@ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targe
2991
3052
  return args.currentData;
2992
3053
  }
2993
3054
  const customData = { ...args.currentData };
2994
- const changes = _17.reduce(
3055
+ const changes = _18.reduce(
2995
3056
  args.proposedData,
2996
3057
  (result, value, key) => {
2997
3058
  if (args.currentData[key] !== value) {
@@ -3072,7 +3133,7 @@ var flagsSchema = Z5.object({
3072
3133
  // src/cli/cmd/cleanup.ts
3073
3134
  import { resolveOverridenLocale as resolveOverridenLocale5 } from "@lingo.dev/_spec";
3074
3135
  import { Command as Command8 } from "interactive-commander";
3075
- import _18 from "lodash";
3136
+ import _19 from "lodash";
3076
3137
  import Ora7 from "ora";
3077
3138
  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("--verbose", "Show verbose output").action(async function(options) {
3078
3139
  const ora = Ora7();
@@ -3102,7 +3163,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
3102
3163
  try {
3103
3164
  const targetData = await bucketLoader.pull(targetLocale);
3104
3165
  const targetKeys = Object.keys(targetData);
3105
- const keysToRemove = _18.difference(targetKeys, sourceKeys);
3166
+ const keysToRemove = _19.difference(targetKeys, sourceKeys);
3106
3167
  if (keysToRemove.length === 0) {
3107
3168
  bucketOra.succeed(`[${targetLocale}] No keys to remove`);
3108
3169
  continue;
@@ -3111,7 +3172,7 @@ var cleanup_default = new Command8().command("cleanup").description("Remove keys
3111
3172
  bucketOra.info(`[${targetLocale}] Keys to remove: ${JSON.stringify(keysToRemove, null, 2)}`);
3112
3173
  }
3113
3174
  if (!options.dryRun) {
3114
- const cleanedData = _18.pick(targetData, sourceKeys);
3175
+ const cleanedData = _19.pick(targetData, sourceKeys);
3115
3176
  await bucketLoader.push(targetLocale, cleanedData);
3116
3177
  bucketOra.succeed(`[${targetLocale}] Removed ${keysToRemove.length} keys`);
3117
3178
  } else {
@@ -3163,7 +3224,7 @@ function displaySummary(results) {
3163
3224
  // package.json
3164
3225
  var package_default = {
3165
3226
  name: "lingo.dev",
3166
- version: "0.74.12",
3227
+ version: "0.74.13",
3167
3228
  description: "Lingo.dev CLI",
3168
3229
  private: false,
3169
3230
  publishConfig: {
@@ -3200,6 +3261,7 @@ var package_default = {
3200
3261
  dev: "tsup --watch",
3201
3262
  build: "tsc --noEmit && tsup",
3202
3263
  test: "vitest run",
3264
+ "test:watch": "vitest",
3203
3265
  clean: "rm -rf build"
3204
3266
  },
3205
3267
  keywords: [],