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