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