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