lingo.dev 0.86.0 → 0.87.1
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 +540 -428
- package/build/cli.cjs.map +1 -1
- package/build/cli.mjs +577 -465
- package/build/cli.mjs.map +1 -1
- package/package.json +11 -3
package/build/cli.mjs
CHANGED
|
@@ -621,9 +621,9 @@ function makeGitlabInitializer(spinner) {
|
|
|
621
621
|
|
|
622
622
|
// src/cli/cmd/init.ts
|
|
623
623
|
import open2 from "open";
|
|
624
|
-
var openUrl = (
|
|
624
|
+
var openUrl = (path17) => {
|
|
625
625
|
const settings = getSettings(void 0);
|
|
626
|
-
open2(`${settings.auth.webUrl}${
|
|
626
|
+
open2(`${settings.auth.webUrl}${path17}`, { wait: false });
|
|
627
627
|
};
|
|
628
628
|
var throwHelpError = (option, value) => {
|
|
629
629
|
if (value === "help") {
|
|
@@ -970,8 +970,8 @@ var files_default = new Command4().command("files").description("Print out the l
|
|
|
970
970
|
} else if (type.target) {
|
|
971
971
|
result.push(...targetPaths);
|
|
972
972
|
}
|
|
973
|
-
result.forEach((
|
|
974
|
-
console.log(
|
|
973
|
+
result.forEach((path17) => {
|
|
974
|
+
console.log(path17);
|
|
975
975
|
});
|
|
976
976
|
}
|
|
977
977
|
}
|
|
@@ -991,11 +991,15 @@ 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
1001
|
import _22 from "lodash";
|
|
998
|
-
import * as
|
|
1002
|
+
import * as path14 from "path";
|
|
999
1003
|
import Ora5 from "ora";
|
|
1000
1004
|
|
|
1001
1005
|
// src/cli/loaders/_utils.ts
|
|
@@ -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
|
}
|
|
@@ -1551,9 +1554,9 @@ function createHtmlLoader() {
|
|
|
1551
1554
|
const bDepth = b.split("/").length;
|
|
1552
1555
|
return aDepth - bDepth;
|
|
1553
1556
|
});
|
|
1554
|
-
paths.forEach((
|
|
1555
|
-
const value = data[
|
|
1556
|
-
const [nodePath, attribute] =
|
|
1557
|
+
paths.forEach((path17) => {
|
|
1558
|
+
const value = data[path17];
|
|
1559
|
+
const [nodePath, attribute] = path17.split("#");
|
|
1557
1560
|
const [rootTag, ...indices] = nodePath.split("/");
|
|
1558
1561
|
let parent = rootTag === "head" ? document.head : document.body;
|
|
1559
1562
|
let current = parent;
|
|
@@ -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({
|
|
@@ -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
|
});
|
|
@@ -1924,43 +1836,29 @@ function createXcodeXcstringsLoader(defaultLocale) {
|
|
|
1924
1836
|
import path11 from "path";
|
|
1925
1837
|
import prettier from "prettier";
|
|
1926
1838
|
function createPrettierLoader(options) {
|
|
1839
|
+
const stage = options.stage || "both";
|
|
1927
1840
|
return createLoader({
|
|
1928
1841
|
async pull(locale, data) {
|
|
1929
|
-
|
|
1842
|
+
if (!["pull", "both"].includes(stage)) {
|
|
1843
|
+
return data;
|
|
1844
|
+
}
|
|
1845
|
+
const draftPath = options.bucketPathPattern.replaceAll(
|
|
1846
|
+
"[locale]",
|
|
1847
|
+
locale
|
|
1848
|
+
);
|
|
1849
|
+
const finalPath = path11.resolve(draftPath);
|
|
1850
|
+
return await formatDataWithPrettier(data, finalPath, options);
|
|
1930
1851
|
},
|
|
1931
1852
|
async push(locale, data) {
|
|
1932
|
-
|
|
1933
|
-
const finalPath = path11.resolve(draftPath);
|
|
1934
|
-
const prettierConfig = await loadPrettierConfig(finalPath);
|
|
1935
|
-
if (!prettierConfig) {
|
|
1853
|
+
if (!["push", "both"].includes(stage)) {
|
|
1936
1854
|
return data;
|
|
1937
1855
|
}
|
|
1938
|
-
const
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
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
|
-
}
|
|
1856
|
+
const draftPath = options.bucketPathPattern.replaceAll(
|
|
1857
|
+
"[locale]",
|
|
1858
|
+
locale
|
|
1859
|
+
);
|
|
1860
|
+
const finalPath = path11.resolve(draftPath);
|
|
1861
|
+
return await formatDataWithPrettier(data, finalPath, options);
|
|
1964
1862
|
}
|
|
1965
1863
|
});
|
|
1966
1864
|
}
|
|
@@ -1972,19 +1870,52 @@ async function loadPrettierConfig(filePath) {
|
|
|
1972
1870
|
return {};
|
|
1973
1871
|
}
|
|
1974
1872
|
}
|
|
1873
|
+
async function formatDataWithPrettier(data, filePath, options) {
|
|
1874
|
+
const prettierConfig = await loadPrettierConfig(filePath);
|
|
1875
|
+
if (!prettierConfig && !options.alwaysFormat) {
|
|
1876
|
+
return data;
|
|
1877
|
+
}
|
|
1878
|
+
const config = {
|
|
1879
|
+
...prettierConfig || { printWidth: 2500, bracketSameLine: false },
|
|
1880
|
+
parser: options.parser,
|
|
1881
|
+
// For HTML parser, preserve comments and quotes
|
|
1882
|
+
...options.parser === "html" ? {
|
|
1883
|
+
htmlWhitespaceSensitivity: "ignore",
|
|
1884
|
+
singleQuote: false,
|
|
1885
|
+
embeddedLanguageFormatting: "off"
|
|
1886
|
+
} : {}
|
|
1887
|
+
};
|
|
1888
|
+
try {
|
|
1889
|
+
return await prettier.format(data, config);
|
|
1890
|
+
} catch (error) {
|
|
1891
|
+
if (error instanceof Error && error.message.startsWith("Cannot find package")) {
|
|
1892
|
+
console.log();
|
|
1893
|
+
console.log(
|
|
1894
|
+
"\u26A0\uFE0F Prettier plugins are not installed. Formatting without plugins."
|
|
1895
|
+
);
|
|
1896
|
+
console.log(
|
|
1897
|
+
"\u26A0\uFE0F To use prettier plugins install project dependencies before running Lingo.dev."
|
|
1898
|
+
);
|
|
1899
|
+
config.plugins = [];
|
|
1900
|
+
await prettier.clearConfigCache();
|
|
1901
|
+
return await prettier.format(data, config);
|
|
1902
|
+
}
|
|
1903
|
+
throw error;
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1975
1906
|
|
|
1976
1907
|
// src/cli/loaders/unlocalizable.ts
|
|
1977
|
-
import
|
|
1908
|
+
import _10 from "lodash";
|
|
1978
1909
|
import _isUrl from "is-url";
|
|
1979
1910
|
import { isValid, parseISO } from "date-fns";
|
|
1980
1911
|
function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys = false) {
|
|
1981
1912
|
const rules = {
|
|
1982
|
-
isEmpty: (v) =>
|
|
1913
|
+
isEmpty: (v) => _10.isEmpty(v),
|
|
1983
1914
|
isNumber: (v) => typeof v === "number" || /^[0-9]+$/.test(v),
|
|
1984
|
-
isBoolean: (v) =>
|
|
1985
|
-
isIsoDate: (v) =>
|
|
1986
|
-
isSystemId: (v) =>
|
|
1987
|
-
isUrl: (v) =>
|
|
1915
|
+
isBoolean: (v) => _10.isBoolean(v),
|
|
1916
|
+
isIsoDate: (v) => _10.isString(v) && _isIsoDate(v),
|
|
1917
|
+
isSystemId: (v) => _10.isString(v) && _isSystemId(v),
|
|
1918
|
+
isUrl: (v) => _10.isString(v) && _isUrl(v)
|
|
1988
1919
|
};
|
|
1989
1920
|
return createLoader({
|
|
1990
1921
|
async pull(locale, input2) {
|
|
@@ -1996,17 +1927,17 @@ function createUnlocalizableLoader(isCacheRestore = false, returnUnlocalizedKeys
|
|
|
1996
1927
|
}
|
|
1997
1928
|
return false;
|
|
1998
1929
|
}).map(([key, _25]) => key);
|
|
1999
|
-
const result =
|
|
1930
|
+
const result = _10.omitBy(input2, (_25, key) => passthroughKeys.includes(key));
|
|
2000
1931
|
if (returnUnlocalizedKeys) {
|
|
2001
|
-
result.unlocalizable =
|
|
1932
|
+
result.unlocalizable = _10.omitBy(input2, (_25, key) => !passthroughKeys.includes(key));
|
|
2002
1933
|
}
|
|
2003
1934
|
return result;
|
|
2004
1935
|
},
|
|
2005
1936
|
async push(locale, data, originalInput) {
|
|
2006
1937
|
if (isCacheRestore) {
|
|
2007
|
-
return
|
|
1938
|
+
return _10.merge({}, data);
|
|
2008
1939
|
}
|
|
2009
|
-
const result =
|
|
1940
|
+
const result = _10.merge({}, originalInput, data);
|
|
2010
1941
|
return result;
|
|
2011
1942
|
}
|
|
2012
1943
|
});
|
|
@@ -2019,7 +1950,7 @@ function _isIsoDate(v) {
|
|
|
2019
1950
|
}
|
|
2020
1951
|
|
|
2021
1952
|
// src/cli/loaders/po/index.ts
|
|
2022
|
-
import
|
|
1953
|
+
import _11 from "lodash";
|
|
2023
1954
|
import gettextParser from "gettext-parser";
|
|
2024
1955
|
function createPoLoader(params = { multiline: false }) {
|
|
2025
1956
|
return composeLoaders(createPoDataLoader(params), createPoContentLoader());
|
|
@@ -2032,7 +1963,7 @@ function createPoDataLoader(params) {
|
|
|
2032
1963
|
const sections = input2.split("\n\n").filter(Boolean);
|
|
2033
1964
|
for (const section of sections) {
|
|
2034
1965
|
const sectionPo = gettextParser.po.parse(section);
|
|
2035
|
-
const contextKey =
|
|
1966
|
+
const contextKey = _11.keys(sectionPo.translations)[0];
|
|
2036
1967
|
const entries = sectionPo.translations[contextKey];
|
|
2037
1968
|
Object.entries(entries).forEach(([msgid, entry]) => {
|
|
2038
1969
|
if (msgid && entry.msgid) {
|
|
@@ -2051,13 +1982,13 @@ function createPoDataLoader(params) {
|
|
|
2051
1982
|
const originalSections = originalInput?.split("\n\n").filter(Boolean) || [];
|
|
2052
1983
|
const result = originalSections.map((section) => {
|
|
2053
1984
|
const sectionPo = gettextParser.po.parse(section);
|
|
2054
|
-
const contextKey =
|
|
1985
|
+
const contextKey = _11.keys(sectionPo.translations)[0];
|
|
2055
1986
|
const entries = sectionPo.translations[contextKey];
|
|
2056
1987
|
const msgid = Object.keys(entries).find((key) => entries[key].msgid);
|
|
2057
1988
|
if (!msgid) {
|
|
2058
1989
|
const currentSection = currentSections.find((cs) => {
|
|
2059
1990
|
const csPo = gettextParser.po.parse(cs);
|
|
2060
|
-
const csContextKey =
|
|
1991
|
+
const csContextKey = _11.keys(csPo.translations)[0];
|
|
2061
1992
|
const csEntries = csPo.translations[csContextKey];
|
|
2062
1993
|
const csMsgid = Object.keys(csEntries).find((key) => csEntries[key].msgid);
|
|
2063
1994
|
return csMsgid === msgid;
|
|
@@ -2068,7 +1999,7 @@ function createPoDataLoader(params) {
|
|
|
2068
1999
|
return section;
|
|
2069
2000
|
}
|
|
2070
2001
|
if (data[msgid]) {
|
|
2071
|
-
const updatedPo =
|
|
2002
|
+
const updatedPo = _11.merge({}, sectionPo, {
|
|
2072
2003
|
translations: {
|
|
2073
2004
|
[contextKey]: {
|
|
2074
2005
|
[msgid]: {
|
|
@@ -2088,7 +2019,7 @@ function createPoDataLoader(params) {
|
|
|
2088
2019
|
function createPoContentLoader() {
|
|
2089
2020
|
return createLoader({
|
|
2090
2021
|
async pull(locale, input2) {
|
|
2091
|
-
const result =
|
|
2022
|
+
const result = _11.chain(input2).entries().filter(([, entry]) => !!entry.msgid).map(([, entry]) => [
|
|
2092
2023
|
entry.msgid,
|
|
2093
2024
|
{
|
|
2094
2025
|
singular: entry.msgstr[0] || entry.msgid,
|
|
@@ -2098,7 +2029,7 @@ function createPoContentLoader() {
|
|
|
2098
2029
|
return result;
|
|
2099
2030
|
},
|
|
2100
2031
|
async push(locale, data, originalInput) {
|
|
2101
|
-
const result =
|
|
2032
|
+
const result = _11.chain(originalInput).entries().map(([, entry]) => [
|
|
2102
2033
|
entry.msgid,
|
|
2103
2034
|
{
|
|
2104
2035
|
...entry,
|
|
@@ -2168,10 +2099,10 @@ function createXmlLoader() {
|
|
|
2168
2099
|
// src/cli/loaders/srt.ts
|
|
2169
2100
|
import srtParser from "srt-parser-2";
|
|
2170
2101
|
function createSrtLoader() {
|
|
2171
|
-
const
|
|
2102
|
+
const parser = new srtParser();
|
|
2172
2103
|
return createLoader({
|
|
2173
2104
|
async pull(locale, input2) {
|
|
2174
|
-
const parsed =
|
|
2105
|
+
const parsed = parser.fromSrt(input2) || [];
|
|
2175
2106
|
const result = {};
|
|
2176
2107
|
parsed.forEach((entry) => {
|
|
2177
2108
|
const key = `${entry.id}#${entry.startTime}-${entry.endTime}`;
|
|
@@ -2192,7 +2123,7 @@ function createSrtLoader() {
|
|
|
2192
2123
|
text
|
|
2193
2124
|
};
|
|
2194
2125
|
});
|
|
2195
|
-
const srtContent =
|
|
2126
|
+
const srtContent = parser.toSrt(output).trim().replace(/\r?\n/g, "\n");
|
|
2196
2127
|
return srtContent;
|
|
2197
2128
|
}
|
|
2198
2129
|
});
|
|
@@ -2221,34 +2152,34 @@ var datoSettingsSchema = Z2.object({
|
|
|
2221
2152
|
});
|
|
2222
2153
|
|
|
2223
2154
|
// src/cli/loaders/dato/filter.ts
|
|
2224
|
-
import
|
|
2155
|
+
import _12 from "lodash";
|
|
2225
2156
|
function createDatoFilterLoader() {
|
|
2226
2157
|
return createLoader({
|
|
2227
2158
|
async pull(locale, input2) {
|
|
2228
2159
|
const result = {};
|
|
2229
|
-
for (const [modelId, modelInfo] of
|
|
2160
|
+
for (const [modelId, modelInfo] of _12.entries(input2)) {
|
|
2230
2161
|
result[modelId] = {};
|
|
2231
2162
|
for (const record of modelInfo.records) {
|
|
2232
|
-
result[modelId][record.id] =
|
|
2163
|
+
result[modelId][record.id] = _12.chain(modelInfo.fields).mapKeys((field) => field.api_key).mapValues((field) => _12.get(record, [field.api_key, locale])).value();
|
|
2233
2164
|
}
|
|
2234
2165
|
}
|
|
2235
2166
|
return result;
|
|
2236
2167
|
},
|
|
2237
2168
|
async push(locale, data, originalInput, originalLocale) {
|
|
2238
|
-
const result =
|
|
2239
|
-
for (const [modelId, modelInfo] of
|
|
2169
|
+
const result = _12.cloneDeep(originalInput || {});
|
|
2170
|
+
for (const [modelId, modelInfo] of _12.entries(result)) {
|
|
2240
2171
|
for (const record of modelInfo.records) {
|
|
2241
|
-
for (const [fieldId, fieldValue] of
|
|
2172
|
+
for (const [fieldId, fieldValue] of _12.entries(record)) {
|
|
2242
2173
|
const fieldInfo = modelInfo.fields.find((field) => field.api_key === fieldId);
|
|
2243
2174
|
if (fieldInfo) {
|
|
2244
|
-
const sourceFieldValue =
|
|
2245
|
-
const targetFieldValue =
|
|
2175
|
+
const sourceFieldValue = _12.get(fieldValue, [originalLocale]);
|
|
2176
|
+
const targetFieldValue = _12.get(data, [modelId, record.id, fieldId]);
|
|
2246
2177
|
if (targetFieldValue) {
|
|
2247
|
-
|
|
2178
|
+
_12.set(record, [fieldId, locale], targetFieldValue);
|
|
2248
2179
|
} else {
|
|
2249
|
-
|
|
2180
|
+
_12.set(record, [fieldId, locale], sourceFieldValue);
|
|
2250
2181
|
}
|
|
2251
|
-
|
|
2182
|
+
_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
2183
|
}
|
|
2253
2184
|
}
|
|
2254
2185
|
}
|
|
@@ -2259,10 +2190,10 @@ function createDatoFilterLoader() {
|
|
|
2259
2190
|
}
|
|
2260
2191
|
|
|
2261
2192
|
// src/cli/loaders/dato/api.ts
|
|
2262
|
-
import
|
|
2193
|
+
import _14 from "lodash";
|
|
2263
2194
|
|
|
2264
2195
|
// src/cli/loaders/dato/_utils.ts
|
|
2265
|
-
import
|
|
2196
|
+
import _13 from "lodash";
|
|
2266
2197
|
import { buildClient } from "@datocms/cma-client-node";
|
|
2267
2198
|
function createDatoClient(params) {
|
|
2268
2199
|
if (!params.apiKey) {
|
|
@@ -2437,7 +2368,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
2437
2368
|
const result = {
|
|
2438
2369
|
models: {}
|
|
2439
2370
|
};
|
|
2440
|
-
const updatedConfig =
|
|
2371
|
+
const updatedConfig = _14.cloneDeep(config);
|
|
2441
2372
|
console.log(`Initializing DatoCMS loader...`);
|
|
2442
2373
|
const project = await dato.findProject();
|
|
2443
2374
|
const modelChoices = await getModelChoices(dato, config);
|
|
@@ -2455,7 +2386,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
2455
2386
|
delete updatedConfig.models[modelId];
|
|
2456
2387
|
}
|
|
2457
2388
|
}
|
|
2458
|
-
for (const modelId of
|
|
2389
|
+
for (const modelId of _14.keys(updatedConfig.models)) {
|
|
2459
2390
|
const { modelName, fields } = await getModelFields(dato, modelId);
|
|
2460
2391
|
if (fields.length > 0) {
|
|
2461
2392
|
result.models[modelId] = { fields: [], records: [] };
|
|
@@ -2466,7 +2397,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
2466
2397
|
const isLocalized = await updateFieldLocalization(dato, fieldInfo, selectedFields.includes(fieldInfo.id));
|
|
2467
2398
|
if (isLocalized) {
|
|
2468
2399
|
result.models[modelId].fields.push(fieldInfo);
|
|
2469
|
-
updatedConfig.models[modelId].fields =
|
|
2400
|
+
updatedConfig.models[modelId].fields = _14.uniq([
|
|
2470
2401
|
...updatedConfig.models[modelId].fields || [],
|
|
2471
2402
|
fieldInfo.api_key
|
|
2472
2403
|
]);
|
|
@@ -2485,7 +2416,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
2485
2416
|
},
|
|
2486
2417
|
async pull(locale, input2, initCtx) {
|
|
2487
2418
|
const result = {};
|
|
2488
|
-
for (const modelId of
|
|
2419
|
+
for (const modelId of _14.keys(initCtx?.models || {})) {
|
|
2489
2420
|
let records = initCtx?.models[modelId].records || [];
|
|
2490
2421
|
const recordIds = records.map((record) => record.id);
|
|
2491
2422
|
records = await dato.findRecords(recordIds);
|
|
@@ -2500,7 +2431,7 @@ function createDatoApiLoader(config, onConfigUpdate) {
|
|
|
2500
2431
|
return result;
|
|
2501
2432
|
},
|
|
2502
2433
|
async push(locale, data, originalInput) {
|
|
2503
|
-
for (const modelId of
|
|
2434
|
+
for (const modelId of _14.keys(data)) {
|
|
2504
2435
|
for (let i = 0; i < data[modelId].records.length; i++) {
|
|
2505
2436
|
const record = data[modelId].records[i];
|
|
2506
2437
|
console.log(`Updating record ${i + 1}/${data[modelId].records.length} for model ${modelId}...`);
|
|
@@ -2514,7 +2445,7 @@ async function getModelFields(dato, modelId) {
|
|
|
2514
2445
|
const modelInfo = await dato.findModel(modelId);
|
|
2515
2446
|
return {
|
|
2516
2447
|
modelName: modelInfo.name,
|
|
2517
|
-
fields:
|
|
2448
|
+
fields: _14.filter(modelInfo.fields, (field) => field.type === "field")
|
|
2518
2449
|
};
|
|
2519
2450
|
}
|
|
2520
2451
|
async function getFieldDetails(dato, fields) {
|
|
@@ -2592,17 +2523,17 @@ async function promptModelSelection(choices) {
|
|
|
2592
2523
|
}
|
|
2593
2524
|
|
|
2594
2525
|
// src/cli/loaders/dato/extract.ts
|
|
2595
|
-
import
|
|
2526
|
+
import _15 from "lodash";
|
|
2596
2527
|
function createDatoExtractLoader() {
|
|
2597
2528
|
return createLoader({
|
|
2598
2529
|
async pull(locale, input2) {
|
|
2599
2530
|
const result = {};
|
|
2600
|
-
for (const [modelId, modelInfo] of
|
|
2601
|
-
for (const [recordId, record] of
|
|
2602
|
-
for (const [fieldName, fieldValue] of
|
|
2531
|
+
for (const [modelId, modelInfo] of _15.entries(input2)) {
|
|
2532
|
+
for (const [recordId, record] of _15.entries(modelInfo)) {
|
|
2533
|
+
for (const [fieldName, fieldValue] of _15.entries(record)) {
|
|
2603
2534
|
const parsedValue = createParsedDatoValue(fieldValue);
|
|
2604
2535
|
if (parsedValue) {
|
|
2605
|
-
|
|
2536
|
+
_15.set(result, [modelId, `_${recordId}`, fieldName], parsedValue);
|
|
2606
2537
|
}
|
|
2607
2538
|
}
|
|
2608
2539
|
}
|
|
@@ -2610,14 +2541,14 @@ function createDatoExtractLoader() {
|
|
|
2610
2541
|
return result;
|
|
2611
2542
|
},
|
|
2612
2543
|
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
|
|
2544
|
+
const result = _15.cloneDeep(originalInput || {});
|
|
2545
|
+
for (const [modelId, modelInfo] of _15.entries(data)) {
|
|
2546
|
+
for (const [virtualRecordId, record] of _15.entries(modelInfo)) {
|
|
2547
|
+
for (const [fieldName, fieldValue] of _15.entries(record)) {
|
|
2617
2548
|
const [, recordId] = virtualRecordId.split("_");
|
|
2618
|
-
const originalFieldValue =
|
|
2549
|
+
const originalFieldValue = _15.get(originalInput, [modelId, recordId, fieldName]);
|
|
2619
2550
|
const rawValue = createRawDatoValue(fieldValue, originalFieldValue, true);
|
|
2620
|
-
|
|
2551
|
+
_15.set(result, [modelId, recordId, fieldName], rawValue || originalFieldValue);
|
|
2621
2552
|
}
|
|
2622
2553
|
}
|
|
2623
2554
|
}
|
|
@@ -2626,25 +2557,25 @@ function createDatoExtractLoader() {
|
|
|
2626
2557
|
});
|
|
2627
2558
|
}
|
|
2628
2559
|
function detectDatoFieldType(rawDatoValue) {
|
|
2629
|
-
if (
|
|
2560
|
+
if (_15.has(rawDatoValue, "document") && _15.get(rawDatoValue, "schema") === "dast") {
|
|
2630
2561
|
return "structured_text";
|
|
2631
|
-
} else if (
|
|
2562
|
+
} else if (_15.has(rawDatoValue, "no_index") || _15.has(rawDatoValue, "twitter_card")) {
|
|
2632
2563
|
return "seo";
|
|
2633
|
-
} else if (
|
|
2564
|
+
} else if (_15.get(rawDatoValue, "type") === "item") {
|
|
2634
2565
|
return "single_block";
|
|
2635
|
-
} else if (
|
|
2566
|
+
} else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.get(item, "type") === "item")) {
|
|
2636
2567
|
return "rich_text";
|
|
2637
2568
|
} else if (_isFile(rawDatoValue)) {
|
|
2638
2569
|
return "file";
|
|
2639
|
-
} else if (
|
|
2570
|
+
} else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _isFile(item))) {
|
|
2640
2571
|
return "gallery";
|
|
2641
2572
|
} else if (_isJson(rawDatoValue)) {
|
|
2642
2573
|
return "json";
|
|
2643
|
-
} else if (
|
|
2574
|
+
} else if (_15.isString(rawDatoValue)) {
|
|
2644
2575
|
return "string";
|
|
2645
2576
|
} else if (_isVideo(rawDatoValue)) {
|
|
2646
2577
|
return "video";
|
|
2647
|
-
} else if (
|
|
2578
|
+
} else if (_15.isArray(rawDatoValue) && _15.every(rawDatoValue, (item) => _15.isString(item))) {
|
|
2648
2579
|
return "ref_list";
|
|
2649
2580
|
} else {
|
|
2650
2581
|
return null;
|
|
@@ -2702,62 +2633,62 @@ function createRawDatoValue(parsedDatoValue, originalRawDatoValue, isClean = fal
|
|
|
2702
2633
|
}
|
|
2703
2634
|
function serializeStructuredText(rawStructuredText) {
|
|
2704
2635
|
return serializeStructuredTextNode(rawStructuredText);
|
|
2705
|
-
function serializeStructuredTextNode(node,
|
|
2636
|
+
function serializeStructuredTextNode(node, path17 = [], acc = {}) {
|
|
2706
2637
|
if ("document" in node) {
|
|
2707
|
-
return serializeStructuredTextNode(node.document, [...
|
|
2638
|
+
return serializeStructuredTextNode(node.document, [...path17, "document"], acc);
|
|
2708
2639
|
}
|
|
2709
|
-
if (!
|
|
2710
|
-
acc[[...
|
|
2711
|
-
} else if (
|
|
2712
|
-
acc[[...
|
|
2640
|
+
if (!_15.isNil(node.value)) {
|
|
2641
|
+
acc[[...path17, "value"].join(".")] = node.value;
|
|
2642
|
+
} else if (_15.get(node, "type") === "block") {
|
|
2643
|
+
acc[[...path17, "item"].join(".")] = serializeBlock(node.item);
|
|
2713
2644
|
}
|
|
2714
2645
|
if (node.children) {
|
|
2715
2646
|
for (let i = 0; i < node.children.length; i++) {
|
|
2716
|
-
serializeStructuredTextNode(node.children[i], [...
|
|
2647
|
+
serializeStructuredTextNode(node.children[i], [...path17, i.toString()], acc);
|
|
2717
2648
|
}
|
|
2718
2649
|
}
|
|
2719
2650
|
return acc;
|
|
2720
2651
|
}
|
|
2721
2652
|
}
|
|
2722
2653
|
function serializeSeo(rawSeo) {
|
|
2723
|
-
return
|
|
2654
|
+
return _15.chain(rawSeo).pick(["title", "description"]).value();
|
|
2724
2655
|
}
|
|
2725
2656
|
function serializeBlock(rawBlock) {
|
|
2726
|
-
if (
|
|
2657
|
+
if (_15.get(rawBlock, "type") === "item" && _15.has(rawBlock, "id")) {
|
|
2727
2658
|
return serializeBlock(rawBlock.attributes);
|
|
2728
2659
|
}
|
|
2729
2660
|
const result = {};
|
|
2730
|
-
for (const [attributeName, attributeValue] of
|
|
2661
|
+
for (const [attributeName, attributeValue] of _15.entries(rawBlock)) {
|
|
2731
2662
|
result[attributeName] = createParsedDatoValue(attributeValue);
|
|
2732
2663
|
}
|
|
2733
2664
|
return result;
|
|
2734
2665
|
}
|
|
2735
2666
|
function serializeBlockList(rawBlockList) {
|
|
2736
|
-
return
|
|
2667
|
+
return _15.chain(rawBlockList).map((block) => serializeBlock(block)).value();
|
|
2737
2668
|
}
|
|
2738
2669
|
function serializeVideo(rawVideo) {
|
|
2739
|
-
return
|
|
2670
|
+
return _15.chain(rawVideo).pick(["title"]).value();
|
|
2740
2671
|
}
|
|
2741
2672
|
function serializeFile(rawFile) {
|
|
2742
|
-
return
|
|
2673
|
+
return _15.chain(rawFile).pick(["alt", "title"]).value();
|
|
2743
2674
|
}
|
|
2744
2675
|
function serializeGallery(rawGallery) {
|
|
2745
|
-
return
|
|
2676
|
+
return _15.chain(rawGallery).map((item) => serializeFile(item)).value();
|
|
2746
2677
|
}
|
|
2747
2678
|
function deserializeFile(parsedFile, originalRawFile) {
|
|
2748
|
-
return
|
|
2679
|
+
return _15.chain(parsedFile).defaults(originalRawFile).value();
|
|
2749
2680
|
}
|
|
2750
2681
|
function deserializeGallery(parsedGallery, originalRawGallery) {
|
|
2751
|
-
return
|
|
2682
|
+
return _15.chain(parsedGallery).map((item, i) => deserializeFile(item, originalRawGallery[i])).value();
|
|
2752
2683
|
}
|
|
2753
2684
|
function deserializeVideo(parsedVideo, originalRawVideo) {
|
|
2754
|
-
return
|
|
2685
|
+
return _15.chain(parsedVideo).defaults(originalRawVideo).value();
|
|
2755
2686
|
}
|
|
2756
2687
|
function deserializeBlock(payload, rawNode, isClean = false) {
|
|
2757
|
-
const result =
|
|
2758
|
-
for (const [attributeName, attributeValue] of
|
|
2688
|
+
const result = _15.cloneDeep(rawNode);
|
|
2689
|
+
for (const [attributeName, attributeValue] of _15.entries(rawNode.attributes)) {
|
|
2759
2690
|
const rawValue = createRawDatoValue(payload[attributeName], attributeValue, isClean);
|
|
2760
|
-
|
|
2691
|
+
_15.set(result, ["attributes", attributeName], rawValue);
|
|
2761
2692
|
}
|
|
2762
2693
|
if (isClean) {
|
|
2763
2694
|
delete result["id"];
|
|
@@ -2765,33 +2696,33 @@ function deserializeBlock(payload, rawNode, isClean = false) {
|
|
|
2765
2696
|
return result;
|
|
2766
2697
|
}
|
|
2767
2698
|
function deserializeSeo(parsedSeo, originalRawSeo) {
|
|
2768
|
-
return
|
|
2699
|
+
return _15.chain(parsedSeo).pick(["title", "description"]).defaults(originalRawSeo).value();
|
|
2769
2700
|
}
|
|
2770
2701
|
function deserializeBlockList(parsedBlockList, originalRawBlockList, isClean = false) {
|
|
2771
|
-
return
|
|
2702
|
+
return _15.chain(parsedBlockList).map((block, i) => deserializeBlock(block, originalRawBlockList[i], isClean)).value();
|
|
2772
2703
|
}
|
|
2773
2704
|
function deserializeStructuredText(parsedStructuredText, originalRawStructuredText) {
|
|
2774
|
-
const result =
|
|
2775
|
-
for (const [
|
|
2776
|
-
const realPath =
|
|
2777
|
-
const deserializedValue = createRawDatoValue(value,
|
|
2778
|
-
|
|
2705
|
+
const result = _15.cloneDeep(originalRawStructuredText);
|
|
2706
|
+
for (const [path17, value] of _15.entries(parsedStructuredText)) {
|
|
2707
|
+
const realPath = _15.chain(path17.split(".")).flatMap((s) => !_15.isNaN(_15.toNumber(s)) ? ["children", s] : s).value();
|
|
2708
|
+
const deserializedValue = createRawDatoValue(value, _15.get(originalRawStructuredText, realPath), true);
|
|
2709
|
+
_15.set(result, realPath, deserializedValue);
|
|
2779
2710
|
}
|
|
2780
2711
|
return result;
|
|
2781
2712
|
}
|
|
2782
2713
|
function _isJson(rawDatoValue) {
|
|
2783
2714
|
try {
|
|
2784
|
-
return
|
|
2715
|
+
return _15.isString(rawDatoValue) && rawDatoValue.startsWith("{") && rawDatoValue.endsWith("}") && !!JSON.parse(rawDatoValue);
|
|
2785
2716
|
} catch (e) {
|
|
2786
2717
|
return false;
|
|
2787
2718
|
}
|
|
2788
2719
|
}
|
|
2789
2720
|
function _isFile(rawDatoValue) {
|
|
2790
|
-
return
|
|
2721
|
+
return _15.isObject(rawDatoValue) && ["alt", "title", "custom_data", "focal_point", "upload_id"].every((key) => _15.has(rawDatoValue, key));
|
|
2791
2722
|
}
|
|
2792
2723
|
function _isVideo(rawDatoValue) {
|
|
2793
|
-
return
|
|
2794
|
-
(key) =>
|
|
2724
|
+
return _15.isObject(rawDatoValue) && ["url", "title", "width", "height", "provider", "provider_uid", "thumbnail_url"].every(
|
|
2725
|
+
(key) => _15.has(rawDatoValue, key)
|
|
2795
2726
|
);
|
|
2796
2727
|
}
|
|
2797
2728
|
|
|
@@ -2852,7 +2783,7 @@ function createVttLoader() {
|
|
|
2852
2783
|
}
|
|
2853
2784
|
|
|
2854
2785
|
// src/cli/loaders/variable/index.ts
|
|
2855
|
-
import
|
|
2786
|
+
import _16 from "lodash";
|
|
2856
2787
|
function createVariableLoader(params) {
|
|
2857
2788
|
return composeLoaders(variableExtractLoader(params), variableContentLoader());
|
|
2858
2789
|
}
|
|
@@ -2861,7 +2792,7 @@ function variableExtractLoader(params) {
|
|
|
2861
2792
|
return createLoader({
|
|
2862
2793
|
pull: async (locale, input2) => {
|
|
2863
2794
|
const result = {};
|
|
2864
|
-
const inputValues =
|
|
2795
|
+
const inputValues = _16.omitBy(input2, _16.isEmpty);
|
|
2865
2796
|
for (const [key, value] of Object.entries(inputValues)) {
|
|
2866
2797
|
const matches = value.match(specifierPattern) || [];
|
|
2867
2798
|
result[key] = result[key] || {
|
|
@@ -2896,11 +2827,11 @@ function variableExtractLoader(params) {
|
|
|
2896
2827
|
function variableContentLoader() {
|
|
2897
2828
|
return createLoader({
|
|
2898
2829
|
pull: async (locale, input2) => {
|
|
2899
|
-
const result =
|
|
2830
|
+
const result = _16.mapValues(input2, (payload) => payload.value);
|
|
2900
2831
|
return result;
|
|
2901
2832
|
},
|
|
2902
2833
|
push: async (locale, data, originalInput) => {
|
|
2903
|
-
const result =
|
|
2834
|
+
const result = _16.cloneDeep(originalInput || {});
|
|
2904
2835
|
for (const [key, originalValueObj] of Object.entries(result)) {
|
|
2905
2836
|
result[key] = {
|
|
2906
2837
|
...originalValueObj,
|
|
@@ -2923,20 +2854,20 @@ function getFormatSpecifierPattern(type) {
|
|
|
2923
2854
|
}
|
|
2924
2855
|
|
|
2925
2856
|
// src/cli/loaders/sync.ts
|
|
2926
|
-
import
|
|
2857
|
+
import _17 from "lodash";
|
|
2927
2858
|
function createSyncLoader() {
|
|
2928
2859
|
return createLoader({
|
|
2929
2860
|
async pull(locale, input2, originalInput) {
|
|
2930
2861
|
if (!originalInput) {
|
|
2931
2862
|
return input2;
|
|
2932
2863
|
}
|
|
2933
|
-
return
|
|
2864
|
+
return _17.chain(originalInput).mapValues((value, key) => input2[key]).value();
|
|
2934
2865
|
},
|
|
2935
2866
|
async push(locale, data, originalInput) {
|
|
2936
2867
|
if (!originalInput) {
|
|
2937
2868
|
return data;
|
|
2938
2869
|
}
|
|
2939
|
-
return
|
|
2870
|
+
return _17.chain(originalInput || {}).mapValues((value, key) => data[key]).value();
|
|
2940
2871
|
}
|
|
2941
2872
|
});
|
|
2942
2873
|
}
|
|
@@ -3096,7 +3027,7 @@ function parseVueFile(input2) {
|
|
|
3096
3027
|
}
|
|
3097
3028
|
|
|
3098
3029
|
// src/cli/loaders/inject-locale.ts
|
|
3099
|
-
import
|
|
3030
|
+
import _18 from "lodash";
|
|
3100
3031
|
function createInjectLocaleLoader(injectLocaleKeys) {
|
|
3101
3032
|
return createLoader({
|
|
3102
3033
|
async pull(locale, data) {
|
|
@@ -3104,19 +3035,19 @@ function createInjectLocaleLoader(injectLocaleKeys) {
|
|
|
3104
3035
|
return data;
|
|
3105
3036
|
}
|
|
3106
3037
|
const omitKeys = injectLocaleKeys.filter((key) => {
|
|
3107
|
-
return
|
|
3038
|
+
return _18.get(data, key) === locale;
|
|
3108
3039
|
});
|
|
3109
|
-
const result =
|
|
3040
|
+
const result = _18.omit(data, omitKeys);
|
|
3110
3041
|
return result;
|
|
3111
3042
|
},
|
|
3112
3043
|
async push(locale, data, originalInput, originalLocale) {
|
|
3113
3044
|
if (!injectLocaleKeys) {
|
|
3114
3045
|
return data;
|
|
3115
3046
|
}
|
|
3116
|
-
const mergedData =
|
|
3047
|
+
const mergedData = _18.merge({}, originalInput, data);
|
|
3117
3048
|
injectLocaleKeys.forEach((key) => {
|
|
3118
|
-
if (
|
|
3119
|
-
|
|
3049
|
+
if (_18.get(mergedData, key) === originalLocale) {
|
|
3050
|
+
_18.set(mergedData, key, locale);
|
|
3120
3051
|
}
|
|
3121
3052
|
});
|
|
3122
3053
|
return mergedData;
|
|
@@ -3125,17 +3056,128 @@ function createInjectLocaleLoader(injectLocaleKeys) {
|
|
|
3125
3056
|
}
|
|
3126
3057
|
|
|
3127
3058
|
// src/cli/loaders/locked-keys.ts
|
|
3128
|
-
import
|
|
3059
|
+
import _19 from "lodash";
|
|
3129
3060
|
function createLockedKeysLoader(lockedKeys, isCacheRestore = false) {
|
|
3130
3061
|
return createLoader({
|
|
3131
|
-
pull: async (locale, data) =>
|
|
3062
|
+
pull: async (locale, data) => _19.chain(data).pickBy((value, key) => !lockedKeys.some((lockedKey) => key.startsWith(lockedKey))).value(),
|
|
3132
3063
|
push: async (locale, data, originalInput) => {
|
|
3133
|
-
const lockedSubObject =
|
|
3064
|
+
const lockedSubObject = _19.chain(originalInput).pickBy((value, key) => lockedKeys.some((lockedKey) => key.startsWith(lockedKey))).value();
|
|
3134
3065
|
if (isCacheRestore) {
|
|
3135
|
-
return
|
|
3066
|
+
return _19.merge({}, data, lockedSubObject);
|
|
3136
3067
|
} else {
|
|
3137
|
-
return
|
|
3068
|
+
return _19.merge({}, originalInput, data, lockedSubObject);
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
});
|
|
3072
|
+
}
|
|
3073
|
+
|
|
3074
|
+
// src/cli/loaders/mdx2/frontmatter-split.ts
|
|
3075
|
+
import matter2 from "gray-matter";
|
|
3076
|
+
function createMdxFrontmatterSplitLoader() {
|
|
3077
|
+
return createLoader({
|
|
3078
|
+
async pull(locale, input2) {
|
|
3079
|
+
const source = input2 || "";
|
|
3080
|
+
const { data: frontmatter, content } = matter2(source);
|
|
3081
|
+
return {
|
|
3082
|
+
frontmatter,
|
|
3083
|
+
content
|
|
3084
|
+
};
|
|
3085
|
+
},
|
|
3086
|
+
async push(locale, data) {
|
|
3087
|
+
const { frontmatter = {}, content = "" } = data || {};
|
|
3088
|
+
const result = matter2.stringify(content, frontmatter).trim();
|
|
3089
|
+
return result;
|
|
3090
|
+
}
|
|
3091
|
+
});
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
// src/cli/utils/md5.ts
|
|
3095
|
+
import { MD5 } from "object-hash";
|
|
3096
|
+
function md5(input2) {
|
|
3097
|
+
return MD5(input2);
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
// src/cli/loaders/mdx2/code-placeholder.ts
|
|
3101
|
+
import { unified } from "unified";
|
|
3102
|
+
import remarkParse from "remark-parse";
|
|
3103
|
+
import remarkGfm from "remark-gfm";
|
|
3104
|
+
import { VFile } from "vfile";
|
|
3105
|
+
import remarkMdx from "remark-mdx";
|
|
3106
|
+
function extractCodePlaceholders(content) {
|
|
3107
|
+
let finalContent = content;
|
|
3108
|
+
const codePlaceholders = {};
|
|
3109
|
+
const codeBlockRegex = /^```.*\n([\s\S]*?)^```$/gm;
|
|
3110
|
+
const codeBlockMatches = finalContent.matchAll(codeBlockRegex);
|
|
3111
|
+
for (const match of codeBlockMatches) {
|
|
3112
|
+
const codeBlock = match[0];
|
|
3113
|
+
const codeBlockHash = md5(codeBlock);
|
|
3114
|
+
const placeholderId = `---CODE_PLACEHOLDER_${codeBlockHash}---`;
|
|
3115
|
+
codePlaceholders[placeholderId] = codeBlock;
|
|
3116
|
+
finalContent = finalContent.replace(codeBlock, placeholderId);
|
|
3117
|
+
}
|
|
3118
|
+
return {
|
|
3119
|
+
content: finalContent,
|
|
3120
|
+
codePlaceholders
|
|
3121
|
+
};
|
|
3122
|
+
}
|
|
3123
|
+
function createMdxCodePlaceholderLoader() {
|
|
3124
|
+
return createLoader({
|
|
3125
|
+
async pull(locale, input2) {
|
|
3126
|
+
const response = extractCodePlaceholders(input2);
|
|
3127
|
+
return response.content;
|
|
3128
|
+
},
|
|
3129
|
+
async push(locale, data, originalInput) {
|
|
3130
|
+
const response = extractCodePlaceholders(originalInput ?? "");
|
|
3131
|
+
let result = data;
|
|
3132
|
+
for (const [placeholder, original] of Object.entries(
|
|
3133
|
+
response.codePlaceholders
|
|
3134
|
+
)) {
|
|
3135
|
+
result = result.replaceAll(placeholder, original);
|
|
3138
3136
|
}
|
|
3137
|
+
return result;
|
|
3138
|
+
}
|
|
3139
|
+
});
|
|
3140
|
+
}
|
|
3141
|
+
|
|
3142
|
+
// src/cli/loaders/mdx2/localizable-document.ts
|
|
3143
|
+
function createLocalizableMdxDocumentLoader() {
|
|
3144
|
+
return createLoader({
|
|
3145
|
+
async pull(_locale, input2) {
|
|
3146
|
+
return {
|
|
3147
|
+
meta: input2.frontmatter,
|
|
3148
|
+
content: input2.sections
|
|
3149
|
+
};
|
|
3150
|
+
},
|
|
3151
|
+
async push(_locale, data, originalInput, _originalLocale, pullInput) {
|
|
3152
|
+
const result = {
|
|
3153
|
+
frontmatter: data.meta || {},
|
|
3154
|
+
sections: data.content || {}
|
|
3155
|
+
};
|
|
3156
|
+
return result;
|
|
3157
|
+
}
|
|
3158
|
+
});
|
|
3159
|
+
}
|
|
3160
|
+
|
|
3161
|
+
// src/cli/loaders/mdx2/sections-split-2.ts
|
|
3162
|
+
import _20 from "lodash";
|
|
3163
|
+
function createMdxSectionsSplit2Loader() {
|
|
3164
|
+
return createLoader({
|
|
3165
|
+
async pull(locale, input2) {
|
|
3166
|
+
const sections = _20.chain(input2.content).split("\n\n").filter(Boolean).map((section, index) => [index, section]).fromPairs().value();
|
|
3167
|
+
const result = {
|
|
3168
|
+
frontmatter: input2.frontmatter,
|
|
3169
|
+
sections
|
|
3170
|
+
};
|
|
3171
|
+
return result;
|
|
3172
|
+
},
|
|
3173
|
+
async push(locale, data, originalInput, _originalLocale, pullInput) {
|
|
3174
|
+
const content = _20.chain(data.sections).values().join("\n\n").value();
|
|
3175
|
+
const result = {
|
|
3176
|
+
frontmatter: data.frontmatter,
|
|
3177
|
+
codePlaceholders: pullInput?.codePlaceholders || {},
|
|
3178
|
+
content
|
|
3179
|
+
};
|
|
3180
|
+
return result;
|
|
3139
3181
|
}
|
|
3140
3182
|
});
|
|
3141
3183
|
}
|
|
@@ -3151,7 +3193,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3151
3193
|
createAndroidLoader(),
|
|
3152
3194
|
createFlatLoader(),
|
|
3153
3195
|
createSyncLoader(),
|
|
3154
|
-
createUnlocalizableLoader(
|
|
3196
|
+
createUnlocalizableLoader(
|
|
3197
|
+
options.isCacheRestore,
|
|
3198
|
+
options.returnUnlocalizedKeys
|
|
3199
|
+
)
|
|
3155
3200
|
);
|
|
3156
3201
|
case "csv":
|
|
3157
3202
|
return composeLoaders(
|
|
@@ -3159,7 +3204,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3159
3204
|
createCsvLoader(),
|
|
3160
3205
|
createFlatLoader(),
|
|
3161
3206
|
createSyncLoader(),
|
|
3162
|
-
createUnlocalizableLoader(
|
|
3207
|
+
createUnlocalizableLoader(
|
|
3208
|
+
options.isCacheRestore,
|
|
3209
|
+
options.returnUnlocalizedKeys
|
|
3210
|
+
)
|
|
3163
3211
|
);
|
|
3164
3212
|
case "html":
|
|
3165
3213
|
return composeLoaders(
|
|
@@ -3167,7 +3215,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3167
3215
|
createPrettierLoader({ parser: "html", bucketPathPattern }),
|
|
3168
3216
|
createHtmlLoader(),
|
|
3169
3217
|
createSyncLoader(),
|
|
3170
|
-
createUnlocalizableLoader(
|
|
3218
|
+
createUnlocalizableLoader(
|
|
3219
|
+
options.isCacheRestore,
|
|
3220
|
+
options.returnUnlocalizedKeys
|
|
3221
|
+
)
|
|
3171
3222
|
);
|
|
3172
3223
|
case "json":
|
|
3173
3224
|
return composeLoaders(
|
|
@@ -3178,7 +3229,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3178
3229
|
createFlatLoader(),
|
|
3179
3230
|
createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
|
|
3180
3231
|
createSyncLoader(),
|
|
3181
|
-
createUnlocalizableLoader(
|
|
3232
|
+
createUnlocalizableLoader(
|
|
3233
|
+
options.isCacheRestore,
|
|
3234
|
+
options.returnUnlocalizedKeys
|
|
3235
|
+
)
|
|
3182
3236
|
);
|
|
3183
3237
|
case "markdown":
|
|
3184
3238
|
return composeLoaders(
|
|
@@ -3186,18 +3240,28 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3186
3240
|
createPrettierLoader({ parser: "markdown", bucketPathPattern }),
|
|
3187
3241
|
createMarkdownLoader(),
|
|
3188
3242
|
createSyncLoader(),
|
|
3189
|
-
createUnlocalizableLoader(
|
|
3243
|
+
createUnlocalizableLoader(
|
|
3244
|
+
options.isCacheRestore,
|
|
3245
|
+
options.returnUnlocalizedKeys
|
|
3246
|
+
)
|
|
3190
3247
|
);
|
|
3191
3248
|
case "mdx":
|
|
3192
3249
|
return composeLoaders(
|
|
3193
3250
|
createTextFileLoader(bucketPathPattern),
|
|
3194
|
-
|
|
3195
|
-
createPrettierLoader({
|
|
3196
|
-
|
|
3251
|
+
createMdxCodePlaceholderLoader(),
|
|
3252
|
+
createPrettierLoader({
|
|
3253
|
+
parser: "mdx",
|
|
3254
|
+
bucketPathPattern
|
|
3255
|
+
}),
|
|
3256
|
+
createMdxFrontmatterSplitLoader(),
|
|
3257
|
+
createMdxSectionsSplit2Loader(),
|
|
3258
|
+
createLocalizableMdxDocumentLoader(),
|
|
3197
3259
|
createFlatLoader(),
|
|
3198
|
-
createMdxStructureLoader(),
|
|
3199
3260
|
createSyncLoader(),
|
|
3200
|
-
createUnlocalizableLoader(
|
|
3261
|
+
createUnlocalizableLoader(
|
|
3262
|
+
options.isCacheRestore,
|
|
3263
|
+
options.returnUnlocalizedKeys
|
|
3264
|
+
)
|
|
3201
3265
|
);
|
|
3202
3266
|
case "po":
|
|
3203
3267
|
return composeLoaders(
|
|
@@ -3206,21 +3270,30 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3206
3270
|
createFlatLoader(),
|
|
3207
3271
|
createSyncLoader(),
|
|
3208
3272
|
createVariableLoader({ type: "python" }),
|
|
3209
|
-
createUnlocalizableLoader(
|
|
3273
|
+
createUnlocalizableLoader(
|
|
3274
|
+
options.isCacheRestore,
|
|
3275
|
+
options.returnUnlocalizedKeys
|
|
3276
|
+
)
|
|
3210
3277
|
);
|
|
3211
3278
|
case "properties":
|
|
3212
3279
|
return composeLoaders(
|
|
3213
3280
|
createTextFileLoader(bucketPathPattern),
|
|
3214
3281
|
createPropertiesLoader(),
|
|
3215
3282
|
createSyncLoader(),
|
|
3216
|
-
createUnlocalizableLoader(
|
|
3283
|
+
createUnlocalizableLoader(
|
|
3284
|
+
options.isCacheRestore,
|
|
3285
|
+
options.returnUnlocalizedKeys
|
|
3286
|
+
)
|
|
3217
3287
|
);
|
|
3218
3288
|
case "xcode-strings":
|
|
3219
3289
|
return composeLoaders(
|
|
3220
3290
|
createTextFileLoader(bucketPathPattern),
|
|
3221
3291
|
createXcodeStringsLoader(),
|
|
3222
3292
|
createSyncLoader(),
|
|
3223
|
-
createUnlocalizableLoader(
|
|
3293
|
+
createUnlocalizableLoader(
|
|
3294
|
+
options.isCacheRestore,
|
|
3295
|
+
options.returnUnlocalizedKeys
|
|
3296
|
+
)
|
|
3224
3297
|
);
|
|
3225
3298
|
case "xcode-stringsdict":
|
|
3226
3299
|
return composeLoaders(
|
|
@@ -3228,7 +3301,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3228
3301
|
createXcodeStringsdictLoader(),
|
|
3229
3302
|
createFlatLoader(),
|
|
3230
3303
|
createSyncLoader(),
|
|
3231
|
-
createUnlocalizableLoader(
|
|
3304
|
+
createUnlocalizableLoader(
|
|
3305
|
+
options.isCacheRestore,
|
|
3306
|
+
options.returnUnlocalizedKeys
|
|
3307
|
+
)
|
|
3232
3308
|
);
|
|
3233
3309
|
case "xcode-xcstrings":
|
|
3234
3310
|
return composeLoaders(
|
|
@@ -3239,7 +3315,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3239
3315
|
createFlatLoader(),
|
|
3240
3316
|
createSyncLoader(),
|
|
3241
3317
|
createVariableLoader({ type: "ieee" }),
|
|
3242
|
-
createUnlocalizableLoader(
|
|
3318
|
+
createUnlocalizableLoader(
|
|
3319
|
+
options.isCacheRestore,
|
|
3320
|
+
options.returnUnlocalizedKeys
|
|
3321
|
+
)
|
|
3243
3322
|
);
|
|
3244
3323
|
case "yaml":
|
|
3245
3324
|
return composeLoaders(
|
|
@@ -3249,7 +3328,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3249
3328
|
createFlatLoader(),
|
|
3250
3329
|
createLockedKeysLoader(lockedKeys || [], options.isCacheRestore),
|
|
3251
3330
|
createSyncLoader(),
|
|
3252
|
-
createUnlocalizableLoader(
|
|
3331
|
+
createUnlocalizableLoader(
|
|
3332
|
+
options.isCacheRestore,
|
|
3333
|
+
options.returnUnlocalizedKeys
|
|
3334
|
+
)
|
|
3253
3335
|
);
|
|
3254
3336
|
case "yaml-root-key":
|
|
3255
3337
|
return composeLoaders(
|
|
@@ -3259,7 +3341,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3259
3341
|
createRootKeyLoader(true),
|
|
3260
3342
|
createFlatLoader(),
|
|
3261
3343
|
createSyncLoader(),
|
|
3262
|
-
createUnlocalizableLoader(
|
|
3344
|
+
createUnlocalizableLoader(
|
|
3345
|
+
options.isCacheRestore,
|
|
3346
|
+
options.returnUnlocalizedKeys
|
|
3347
|
+
)
|
|
3263
3348
|
);
|
|
3264
3349
|
case "flutter":
|
|
3265
3350
|
return composeLoaders(
|
|
@@ -3269,7 +3354,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3269
3354
|
createFlutterLoader(),
|
|
3270
3355
|
createFlatLoader(),
|
|
3271
3356
|
createSyncLoader(),
|
|
3272
|
-
createUnlocalizableLoader(
|
|
3357
|
+
createUnlocalizableLoader(
|
|
3358
|
+
options.isCacheRestore,
|
|
3359
|
+
options.returnUnlocalizedKeys
|
|
3360
|
+
)
|
|
3273
3361
|
);
|
|
3274
3362
|
case "xliff":
|
|
3275
3363
|
return composeLoaders(
|
|
@@ -3277,7 +3365,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3277
3365
|
createXliffLoader(),
|
|
3278
3366
|
createFlatLoader(),
|
|
3279
3367
|
createSyncLoader(),
|
|
3280
|
-
createUnlocalizableLoader(
|
|
3368
|
+
createUnlocalizableLoader(
|
|
3369
|
+
options.isCacheRestore,
|
|
3370
|
+
options.returnUnlocalizedKeys
|
|
3371
|
+
)
|
|
3281
3372
|
);
|
|
3282
3373
|
case "xml":
|
|
3283
3374
|
return composeLoaders(
|
|
@@ -3285,28 +3376,40 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3285
3376
|
createXmlLoader(),
|
|
3286
3377
|
createFlatLoader(),
|
|
3287
3378
|
createSyncLoader(),
|
|
3288
|
-
createUnlocalizableLoader(
|
|
3379
|
+
createUnlocalizableLoader(
|
|
3380
|
+
options.isCacheRestore,
|
|
3381
|
+
options.returnUnlocalizedKeys
|
|
3382
|
+
)
|
|
3289
3383
|
);
|
|
3290
3384
|
case "srt":
|
|
3291
3385
|
return composeLoaders(
|
|
3292
3386
|
createTextFileLoader(bucketPathPattern),
|
|
3293
3387
|
createSrtLoader(),
|
|
3294
3388
|
createSyncLoader(),
|
|
3295
|
-
createUnlocalizableLoader(
|
|
3389
|
+
createUnlocalizableLoader(
|
|
3390
|
+
options.isCacheRestore,
|
|
3391
|
+
options.returnUnlocalizedKeys
|
|
3392
|
+
)
|
|
3296
3393
|
);
|
|
3297
3394
|
case "dato":
|
|
3298
3395
|
return composeLoaders(
|
|
3299
3396
|
createDatoLoader(bucketPathPattern),
|
|
3300
3397
|
createSyncLoader(),
|
|
3301
3398
|
createFlatLoader(),
|
|
3302
|
-
createUnlocalizableLoader(
|
|
3399
|
+
createUnlocalizableLoader(
|
|
3400
|
+
options.isCacheRestore,
|
|
3401
|
+
options.returnUnlocalizedKeys
|
|
3402
|
+
)
|
|
3303
3403
|
);
|
|
3304
3404
|
case "vtt":
|
|
3305
3405
|
return composeLoaders(
|
|
3306
3406
|
createTextFileLoader(bucketPathPattern),
|
|
3307
3407
|
createVttLoader(),
|
|
3308
3408
|
createSyncLoader(),
|
|
3309
|
-
createUnlocalizableLoader(
|
|
3409
|
+
createUnlocalizableLoader(
|
|
3410
|
+
options.isCacheRestore,
|
|
3411
|
+
options.returnUnlocalizedKeys
|
|
3412
|
+
)
|
|
3310
3413
|
);
|
|
3311
3414
|
case "php":
|
|
3312
3415
|
return composeLoaders(
|
|
@@ -3314,7 +3417,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3314
3417
|
createPhpLoader(),
|
|
3315
3418
|
createSyncLoader(),
|
|
3316
3419
|
createFlatLoader(),
|
|
3317
|
-
createUnlocalizableLoader(
|
|
3420
|
+
createUnlocalizableLoader(
|
|
3421
|
+
options.isCacheRestore,
|
|
3422
|
+
options.returnUnlocalizedKeys
|
|
3423
|
+
)
|
|
3318
3424
|
);
|
|
3319
3425
|
case "vue-json":
|
|
3320
3426
|
return composeLoaders(
|
|
@@ -3322,7 +3428,10 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys)
|
|
|
3322
3428
|
createVueJsonLoader(),
|
|
3323
3429
|
createSyncLoader(),
|
|
3324
3430
|
createFlatLoader(),
|
|
3325
|
-
createUnlocalizableLoader(
|
|
3431
|
+
createUnlocalizableLoader(
|
|
3432
|
+
options.isCacheRestore,
|
|
3433
|
+
options.returnUnlocalizedKeys
|
|
3434
|
+
)
|
|
3326
3435
|
);
|
|
3327
3436
|
}
|
|
3328
3437
|
}
|
|
@@ -3333,73 +3442,6 @@ import { createTwoFilesPatch } from "diff";
|
|
|
3333
3442
|
import inquirer2 from "inquirer";
|
|
3334
3443
|
import externalEditor from "external-editor";
|
|
3335
3444
|
|
|
3336
|
-
// src/cli/utils/cache.ts
|
|
3337
|
-
import path12 from "path";
|
|
3338
|
-
import fs10 from "fs";
|
|
3339
|
-
var cacheChunk = (targetLocale, sourceChunk, processedChunk) => {
|
|
3340
|
-
const rows = Object.entries(sourceChunk).map(([key, source]) => ({
|
|
3341
|
-
targetLocale,
|
|
3342
|
-
key,
|
|
3343
|
-
source,
|
|
3344
|
-
processed: processedChunk[key]
|
|
3345
|
-
}));
|
|
3346
|
-
_appendToCache(rows);
|
|
3347
|
-
};
|
|
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
|
-
function deleteCache() {
|
|
3366
|
-
const cacheFilePath = _getCacheFilePath();
|
|
3367
|
-
try {
|
|
3368
|
-
fs10.unlinkSync(cacheFilePath);
|
|
3369
|
-
} catch (e) {
|
|
3370
|
-
}
|
|
3371
|
-
}
|
|
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
|
-
function _appendToCache(rows) {
|
|
3382
|
-
const cacheFilePath = _getCacheFilePath();
|
|
3383
|
-
const lines = _buildJSONLines(rows);
|
|
3384
|
-
fs10.appendFileSync(cacheFilePath, lines);
|
|
3385
|
-
}
|
|
3386
|
-
function _getCacheFilePath() {
|
|
3387
|
-
return path12.join(process.cwd(), "i18n.cache");
|
|
3388
|
-
}
|
|
3389
|
-
function _buildJSONLines(rows) {
|
|
3390
|
-
return rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
|
|
3391
|
-
}
|
|
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
|
-
|
|
3403
3445
|
// src/cli/processor/lingo.ts
|
|
3404
3446
|
import { LingoDotDevEngine } from "@lingo.dev/_sdk";
|
|
3405
3447
|
function createLingoLocalizer(params) {
|
|
@@ -3567,32 +3609,31 @@ async function trackEvent(distinctId, event, properties) {
|
|
|
3567
3609
|
// src/cli/utils/delta.ts
|
|
3568
3610
|
import _21 from "lodash";
|
|
3569
3611
|
import z from "zod";
|
|
3570
|
-
import { MD5 } from "object-hash";
|
|
3571
3612
|
|
|
3572
3613
|
// src/cli/utils/fs.ts
|
|
3573
|
-
import * as
|
|
3574
|
-
import * as
|
|
3614
|
+
import * as fs10 from "fs";
|
|
3615
|
+
import * as path12 from "path";
|
|
3575
3616
|
function tryReadFile(filePath, defaultValue = null) {
|
|
3576
3617
|
try {
|
|
3577
|
-
const content =
|
|
3618
|
+
const content = fs10.readFileSync(filePath, "utf-8");
|
|
3578
3619
|
return content;
|
|
3579
3620
|
} catch (error) {
|
|
3580
3621
|
return defaultValue;
|
|
3581
3622
|
}
|
|
3582
3623
|
}
|
|
3583
3624
|
function writeFile(filePath, content) {
|
|
3584
|
-
const dir =
|
|
3585
|
-
if (!
|
|
3586
|
-
|
|
3625
|
+
const dir = path12.dirname(filePath);
|
|
3626
|
+
if (!fs10.existsSync(dir)) {
|
|
3627
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
3587
3628
|
}
|
|
3588
|
-
|
|
3629
|
+
fs10.writeFileSync(filePath, content);
|
|
3589
3630
|
}
|
|
3590
3631
|
function checkIfFileExists(filePath) {
|
|
3591
|
-
return
|
|
3632
|
+
return fs10.existsSync(filePath);
|
|
3592
3633
|
}
|
|
3593
3634
|
|
|
3594
3635
|
// src/cli/utils/delta.ts
|
|
3595
|
-
import * as
|
|
3636
|
+
import * as path13 from "path";
|
|
3596
3637
|
import YAML3 from "yaml";
|
|
3597
3638
|
var LockSchema = z.object({
|
|
3598
3639
|
version: z.literal(1).default(1),
|
|
@@ -3609,7 +3650,7 @@ var LockSchema = z.object({
|
|
|
3609
3650
|
).default({})
|
|
3610
3651
|
});
|
|
3611
3652
|
function createDeltaProcessor(fileKey) {
|
|
3612
|
-
const lockfilePath =
|
|
3653
|
+
const lockfilePath = path13.join(process.cwd(), "i18n.lock");
|
|
3613
3654
|
return {
|
|
3614
3655
|
async checkIfLockExists() {
|
|
3615
3656
|
return checkIfFileExists(lockfilePath);
|
|
@@ -3618,11 +3659,11 @@ function createDeltaProcessor(fileKey) {
|
|
|
3618
3659
|
let added = _21.difference(Object.keys(params.sourceData), Object.keys(params.targetData));
|
|
3619
3660
|
let removed = _21.difference(Object.keys(params.targetData), Object.keys(params.sourceData));
|
|
3620
3661
|
const updated = _21.filter(Object.keys(params.sourceData), (key) => {
|
|
3621
|
-
return
|
|
3662
|
+
return md5(params.sourceData[key]) !== params.checksums[key] && params.checksums[key];
|
|
3622
3663
|
});
|
|
3623
3664
|
const renamed = [];
|
|
3624
3665
|
for (const addedKey of added) {
|
|
3625
|
-
const addedHash =
|
|
3666
|
+
const addedHash = md5(params.sourceData[addedKey]);
|
|
3626
3667
|
for (const removedKey of removed) {
|
|
3627
3668
|
if (params.checksums[removedKey] === addedHash) {
|
|
3628
3669
|
renamed.push([removedKey, addedKey]);
|
|
@@ -3655,18 +3696,18 @@ function createDeltaProcessor(fileKey) {
|
|
|
3655
3696
|
writeFile(lockfilePath, lockfileYaml);
|
|
3656
3697
|
},
|
|
3657
3698
|
async loadChecksums() {
|
|
3658
|
-
const id =
|
|
3699
|
+
const id = md5(fileKey);
|
|
3659
3700
|
const lockfileData = await this.loadLock();
|
|
3660
3701
|
return lockfileData.checksums[id] || {};
|
|
3661
3702
|
},
|
|
3662
3703
|
async saveChecksums(checksums) {
|
|
3663
|
-
const id =
|
|
3704
|
+
const id = md5(fileKey);
|
|
3664
3705
|
const lockfileData = await this.loadLock();
|
|
3665
3706
|
lockfileData.checksums[id] = checksums;
|
|
3666
3707
|
await this.saveLock(lockfileData);
|
|
3667
3708
|
},
|
|
3668
3709
|
async createChecksums(sourceData) {
|
|
3669
|
-
const checksums = _21.mapValues(sourceData, (value) =>
|
|
3710
|
+
const checksums = _21.mapValues(sourceData, (value) => md5(value));
|
|
3670
3711
|
return checksums;
|
|
3671
3712
|
}
|
|
3672
3713
|
};
|
|
@@ -3674,7 +3715,15 @@ function createDeltaProcessor(fileKey) {
|
|
|
3674
3715
|
|
|
3675
3716
|
// src/cli/cmd/i18n.ts
|
|
3676
3717
|
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(
|
|
3718
|
+
var i18n_default = new Command6().command("i18n").description("Run Localization engine").helpOption("-h, --help", "Show help").option(
|
|
3719
|
+
"--locale <locale>",
|
|
3720
|
+
"Locale to process",
|
|
3721
|
+
(val, prev) => prev ? [...prev, val] : [val]
|
|
3722
|
+
).option(
|
|
3723
|
+
"--bucket <bucket>",
|
|
3724
|
+
"Bucket to process",
|
|
3725
|
+
(val, prev) => prev ? [...prev, val] : [val]
|
|
3726
|
+
).option(
|
|
3678
3727
|
"--key <key>",
|
|
3679
3728
|
"Key to process. Process only a specific translation key, useful for debugging or updating a single entry"
|
|
3680
3729
|
).option(
|
|
@@ -3683,7 +3732,25 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3683
3732
|
).option(
|
|
3684
3733
|
"--frozen",
|
|
3685
3734
|
`Run in read-only mode - fails if any translations need updating, useful for CI/CD pipelines to detect missing translations`
|
|
3686
|
-
).option(
|
|
3735
|
+
).option(
|
|
3736
|
+
"--force",
|
|
3737
|
+
"Ignore lockfile and process all keys, useful for full re-translation"
|
|
3738
|
+
).option(
|
|
3739
|
+
"--verbose",
|
|
3740
|
+
"Show detailed output including intermediate processing data and API communication details"
|
|
3741
|
+
).option(
|
|
3742
|
+
"--interactive",
|
|
3743
|
+
"Enable interactive mode for reviewing and editing translations before they are applied"
|
|
3744
|
+
).option(
|
|
3745
|
+
"--api-key <api-key>",
|
|
3746
|
+
"Explicitly set the API key to use, override the default API key from settings"
|
|
3747
|
+
).option(
|
|
3748
|
+
"--debug",
|
|
3749
|
+
"Pause execution at start for debugging purposes, waits for user confirmation before proceeding"
|
|
3750
|
+
).option(
|
|
3751
|
+
"--strict",
|
|
3752
|
+
"Stop processing on first error instead of continuing with other locales/buckets"
|
|
3753
|
+
).action(async function(options) {
|
|
3687
3754
|
updateGitignore();
|
|
3688
3755
|
const ora = Ora5();
|
|
3689
3756
|
const flags = parseFlags(options);
|
|
@@ -3716,25 +3783,29 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3716
3783
|
});
|
|
3717
3784
|
let buckets = getBuckets(i18nConfig);
|
|
3718
3785
|
if (flags.bucket?.length) {
|
|
3719
|
-
buckets = buckets.filter(
|
|
3786
|
+
buckets = buckets.filter(
|
|
3787
|
+
(bucket) => flags.bucket.includes(bucket.type)
|
|
3788
|
+
);
|
|
3720
3789
|
}
|
|
3721
3790
|
ora.succeed("Buckets retrieved");
|
|
3722
3791
|
if (flags.file?.length) {
|
|
3723
3792
|
buckets = buckets.map((bucket) => {
|
|
3724
3793
|
const paths = bucket.paths.filter(
|
|
3725
|
-
(
|
|
3794
|
+
(path17) => flags.file.find((file) => path17.pathPattern?.includes(file))
|
|
3726
3795
|
);
|
|
3727
3796
|
return { ...bucket, paths };
|
|
3728
3797
|
}).filter((bucket) => bucket.paths.length > 0);
|
|
3729
3798
|
if (buckets.length === 0) {
|
|
3730
|
-
ora.fail(
|
|
3799
|
+
ora.fail(
|
|
3800
|
+
"No buckets found. All buckets were filtered out by --file option."
|
|
3801
|
+
);
|
|
3731
3802
|
process.exit(1);
|
|
3732
3803
|
} else {
|
|
3733
3804
|
ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
|
|
3734
3805
|
buckets.map((bucket) => {
|
|
3735
3806
|
ora.info(` ${bucket.type}:`);
|
|
3736
|
-
bucket.paths.forEach((
|
|
3737
|
-
ora.info(` - ${
|
|
3807
|
+
bucket.paths.forEach((path17) => {
|
|
3808
|
+
ora.info(` - ${path17.pathPattern}`);
|
|
3738
3809
|
});
|
|
3739
3810
|
});
|
|
3740
3811
|
}
|
|
@@ -3747,7 +3818,10 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3747
3818
|
ora.start("Creating i18n.lock...");
|
|
3748
3819
|
for (const bucket of buckets) {
|
|
3749
3820
|
for (const bucketPath of bucket.paths) {
|
|
3750
|
-
const sourceLocale = resolveOverriddenLocale3(
|
|
3821
|
+
const sourceLocale = resolveOverriddenLocale3(
|
|
3822
|
+
i18nConfig.locale.source,
|
|
3823
|
+
bucketPath.delimiter
|
|
3824
|
+
);
|
|
3751
3825
|
const bucketLoader = createBucketLoader(
|
|
3752
3826
|
bucket.type,
|
|
3753
3827
|
bucketPath.pathPattern,
|
|
@@ -3760,7 +3834,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3760
3834
|
);
|
|
3761
3835
|
bucketLoader.setDefaultLocale(sourceLocale);
|
|
3762
3836
|
await bucketLoader.init();
|
|
3763
|
-
const sourceData = await bucketLoader.pull(
|
|
3837
|
+
const sourceData = await bucketLoader.pull(
|
|
3838
|
+
i18nConfig.locale.source
|
|
3839
|
+
);
|
|
3764
3840
|
const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
|
|
3765
3841
|
const checksums = await deltaProcessor.createChecksums(sourceData);
|
|
3766
3842
|
await deltaProcessor.saveChecksums(checksums);
|
|
@@ -3776,9 +3852,15 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3776
3852
|
}
|
|
3777
3853
|
ora.start("Validating localization state...");
|
|
3778
3854
|
for (const bucketPath of bucket.paths) {
|
|
3779
|
-
const sourceLocale = resolveOverriddenLocale3(
|
|
3855
|
+
const sourceLocale = resolveOverriddenLocale3(
|
|
3856
|
+
i18nConfig.locale.source,
|
|
3857
|
+
bucketPath.delimiter
|
|
3858
|
+
);
|
|
3780
3859
|
const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
|
|
3781
|
-
const sourcePath =
|
|
3860
|
+
const sourcePath = path14.join(
|
|
3861
|
+
process.cwd(),
|
|
3862
|
+
bucketPath.pathPattern.replace("[locale]", sourceLocale)
|
|
3863
|
+
);
|
|
3782
3864
|
const sourceContent = tryReadFile(sourcePath, null);
|
|
3783
3865
|
const sourceData = JSON.parse(sourceContent || "{}");
|
|
3784
3866
|
const sourceFlattenedData = flatten2(sourceData, {
|
|
@@ -3788,8 +3870,14 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3788
3870
|
}
|
|
3789
3871
|
});
|
|
3790
3872
|
for (const _targetLocale of targetLocales) {
|
|
3791
|
-
const targetLocale = resolveOverriddenLocale3(
|
|
3792
|
-
|
|
3873
|
+
const targetLocale = resolveOverriddenLocale3(
|
|
3874
|
+
_targetLocale,
|
|
3875
|
+
bucketPath.delimiter
|
|
3876
|
+
);
|
|
3877
|
+
const targetPath = path14.join(
|
|
3878
|
+
process.cwd(),
|
|
3879
|
+
bucketPath.pathPattern.replace("[locale]", targetLocale)
|
|
3880
|
+
);
|
|
3793
3881
|
const targetContent = tryReadFile(targetPath, null);
|
|
3794
3882
|
const targetData = JSON.parse(targetContent || "{}");
|
|
3795
3883
|
const targetFlattenedData = flatten2(targetData, {
|
|
@@ -3817,68 +3905,23 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3817
3905
|
return decodeURIComponent(key);
|
|
3818
3906
|
}
|
|
3819
3907
|
});
|
|
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
|
|
3908
|
+
await writeFile(
|
|
3909
|
+
targetPath,
|
|
3910
|
+
JSON.stringify(updatedTargetData, null, 2)
|
|
3845
3911
|
);
|
|
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
3912
|
}
|
|
3868
3913
|
}
|
|
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.");
|
|
3914
|
+
ora.succeed("Localization state check completed");
|
|
3875
3915
|
}
|
|
3876
3916
|
if (flags.frozen) {
|
|
3877
3917
|
ora.start("Checking for lockfile updates...");
|
|
3878
3918
|
let requiresUpdate = null;
|
|
3879
3919
|
bucketLoop: for (const bucket of buckets) {
|
|
3880
3920
|
for (const bucketPath of bucket.paths) {
|
|
3881
|
-
const sourceLocale = resolveOverriddenLocale3(
|
|
3921
|
+
const sourceLocale = resolveOverriddenLocale3(
|
|
3922
|
+
i18nConfig.locale.source,
|
|
3923
|
+
bucketPath.delimiter
|
|
3924
|
+
);
|
|
3882
3925
|
const bucketLoader = createBucketLoader(
|
|
3883
3926
|
bucket.type,
|
|
3884
3927
|
bucketPath.pathPattern,
|
|
@@ -3892,9 +3935,7 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3892
3935
|
);
|
|
3893
3936
|
bucketLoader.setDefaultLocale(sourceLocale);
|
|
3894
3937
|
await bucketLoader.init();
|
|
3895
|
-
const { unlocalizable: sourceUnlocalizable, ...sourceData } = await bucketLoader.pull(
|
|
3896
|
-
i18nConfig.locale.source
|
|
3897
|
-
);
|
|
3938
|
+
const { unlocalizable: sourceUnlocalizable, ...sourceData } = await bucketLoader.pull(i18nConfig.locale.source);
|
|
3898
3939
|
const deltaProcessor = createDeltaProcessor(bucketPath.pathPattern);
|
|
3899
3940
|
const sourceChecksums = await deltaProcessor.createChecksums(sourceData);
|
|
3900
3941
|
const savedChecksums = await deltaProcessor.loadChecksums();
|
|
@@ -3907,11 +3948,23 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3907
3948
|
break bucketLoop;
|
|
3908
3949
|
}
|
|
3909
3950
|
for (const _targetLocale of targetLocales) {
|
|
3910
|
-
const targetLocale = resolveOverriddenLocale3(
|
|
3951
|
+
const targetLocale = resolveOverriddenLocale3(
|
|
3952
|
+
_targetLocale,
|
|
3953
|
+
bucketPath.delimiter
|
|
3954
|
+
);
|
|
3911
3955
|
const { unlocalizable: targetUnlocalizable, ...targetData } = await bucketLoader.pull(targetLocale);
|
|
3912
|
-
const missingKeys = _22.difference(
|
|
3913
|
-
|
|
3914
|
-
|
|
3956
|
+
const missingKeys = _22.difference(
|
|
3957
|
+
Object.keys(sourceData),
|
|
3958
|
+
Object.keys(targetData)
|
|
3959
|
+
);
|
|
3960
|
+
const extraKeys = _22.difference(
|
|
3961
|
+
Object.keys(targetData),
|
|
3962
|
+
Object.keys(sourceData)
|
|
3963
|
+
);
|
|
3964
|
+
const unlocalizableDataDiff = !_22.isEqual(
|
|
3965
|
+
sourceUnlocalizable,
|
|
3966
|
+
targetUnlocalizable
|
|
3967
|
+
);
|
|
3915
3968
|
if (missingKeys.length > 0) {
|
|
3916
3969
|
requiresUpdate = "missing";
|
|
3917
3970
|
break bucketLoop;
|
|
@@ -3934,7 +3987,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3934
3987
|
extra: "Target file has extra translations not present in the source file.",
|
|
3935
3988
|
unlocalizable: "Unlocalizable data (such as booleans, dates, URLs, etc.) do not match."
|
|
3936
3989
|
}[requiresUpdate];
|
|
3937
|
-
ora.fail(
|
|
3990
|
+
ora.fail(
|
|
3991
|
+
`Localization data has changed; please update i18n.lock or run without --frozen.`
|
|
3992
|
+
);
|
|
3938
3993
|
ora.fail(` Details: ${message}`);
|
|
3939
3994
|
process.exit(1);
|
|
3940
3995
|
} else {
|
|
@@ -3946,8 +4001,13 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3946
4001
|
console.log();
|
|
3947
4002
|
ora.info(`Processing bucket: ${bucket.type}`);
|
|
3948
4003
|
for (const bucketPath of bucket.paths) {
|
|
3949
|
-
const bucketOra = Ora5({ indent: 2 }).info(
|
|
3950
|
-
|
|
4004
|
+
const bucketOra = Ora5({ indent: 2 }).info(
|
|
4005
|
+
`Processing path: ${bucketPath.pathPattern}`
|
|
4006
|
+
);
|
|
4007
|
+
const sourceLocale = resolveOverriddenLocale3(
|
|
4008
|
+
i18nConfig.locale.source,
|
|
4009
|
+
bucketPath.delimiter
|
|
4010
|
+
);
|
|
3951
4011
|
const bucketLoader = createBucketLoader(
|
|
3952
4012
|
bucket.type,
|
|
3953
4013
|
bucketPath.pathPattern,
|
|
@@ -3962,21 +4022,33 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3962
4022
|
await bucketLoader.init();
|
|
3963
4023
|
let sourceData = await bucketLoader.pull(sourceLocale);
|
|
3964
4024
|
for (const _targetLocale of targetLocales) {
|
|
3965
|
-
const targetLocale = resolveOverriddenLocale3(
|
|
4025
|
+
const targetLocale = resolveOverriddenLocale3(
|
|
4026
|
+
_targetLocale,
|
|
4027
|
+
bucketPath.delimiter
|
|
4028
|
+
);
|
|
3966
4029
|
try {
|
|
3967
|
-
bucketOra.start(
|
|
4030
|
+
bucketOra.start(
|
|
4031
|
+
`[${sourceLocale} -> ${targetLocale}] (0%) Localization in progress...`
|
|
4032
|
+
);
|
|
3968
4033
|
sourceData = await bucketLoader.pull(sourceLocale);
|
|
3969
4034
|
const targetData = await bucketLoader.pull(targetLocale);
|
|
3970
|
-
const deltaProcessor2 = createDeltaProcessor(
|
|
4035
|
+
const deltaProcessor2 = createDeltaProcessor(
|
|
4036
|
+
bucketPath.pathPattern
|
|
4037
|
+
);
|
|
3971
4038
|
const checksums2 = await deltaProcessor2.loadChecksums();
|
|
3972
4039
|
const delta = await deltaProcessor2.calculateDelta({
|
|
3973
4040
|
sourceData,
|
|
3974
4041
|
targetData,
|
|
3975
4042
|
checksums: checksums2
|
|
3976
4043
|
});
|
|
3977
|
-
let processableData = _22.chain(sourceData).entries().filter(
|
|
4044
|
+
let processableData = _22.chain(sourceData).entries().filter(
|
|
4045
|
+
([key, value]) => delta.added.includes(key) || delta.updated.includes(key) || !!flags.force
|
|
4046
|
+
).fromPairs().value();
|
|
3978
4047
|
if (flags.key) {
|
|
3979
|
-
processableData = _22.pickBy(
|
|
4048
|
+
processableData = _22.pickBy(
|
|
4049
|
+
processableData,
|
|
4050
|
+
(_25, key) => key === flags.key
|
|
4051
|
+
);
|
|
3980
4052
|
}
|
|
3981
4053
|
if (flags.verbose) {
|
|
3982
4054
|
bucketOra.info(JSON.stringify(processableData, null, 2));
|
|
@@ -3988,7 +4060,11 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3988
4060
|
apiKey: settings.auth.apiKey,
|
|
3989
4061
|
apiUrl: settings.auth.apiUrl
|
|
3990
4062
|
});
|
|
3991
|
-
processPayload = withExponentialBackoff(
|
|
4063
|
+
processPayload = withExponentialBackoff(
|
|
4064
|
+
processPayload,
|
|
4065
|
+
3,
|
|
4066
|
+
1e3
|
|
4067
|
+
);
|
|
3992
4068
|
const processedTargetData = await processPayload(
|
|
3993
4069
|
{
|
|
3994
4070
|
sourceLocale,
|
|
@@ -3998,7 +4074,6 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
3998
4074
|
targetData
|
|
3999
4075
|
},
|
|
4000
4076
|
(progress, sourceChunk, processedChunk) => {
|
|
4001
|
-
cacheChunk(targetLocale, sourceChunk, processedChunk);
|
|
4002
4077
|
const progressLog = `[${sourceLocale} -> ${targetLocale}] [${Object.keys(processableData).length} entries] (${progress}%) AI localization in progress...`;
|
|
4003
4078
|
if (flags.verbose) {
|
|
4004
4079
|
bucketOra.info(progressLog);
|
|
@@ -4013,7 +4088,12 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
4013
4088
|
if (flags.verbose) {
|
|
4014
4089
|
bucketOra.info(JSON.stringify(processedTargetData, null, 2));
|
|
4015
4090
|
}
|
|
4016
|
-
let finalTargetData = _22.merge(
|
|
4091
|
+
let finalTargetData = _22.merge(
|
|
4092
|
+
{},
|
|
4093
|
+
sourceData,
|
|
4094
|
+
targetData,
|
|
4095
|
+
processedTargetData
|
|
4096
|
+
);
|
|
4017
4097
|
if (flags.interactive) {
|
|
4018
4098
|
bucketOra.stop();
|
|
4019
4099
|
const reviewedData = await reviewChanges({
|
|
@@ -4025,17 +4105,25 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
4025
4105
|
force: flags.force
|
|
4026
4106
|
});
|
|
4027
4107
|
finalTargetData = reviewedData;
|
|
4028
|
-
bucketOra.start(
|
|
4108
|
+
bucketOra.start(
|
|
4109
|
+
`Applying changes to ${bucketPath} (${targetLocale})`
|
|
4110
|
+
);
|
|
4029
4111
|
}
|
|
4030
4112
|
const finalDiffSize = _22.chain(finalTargetData).omitBy((value, key) => value === targetData[key]).size().value();
|
|
4031
4113
|
await bucketLoader.push(targetLocale, finalTargetData);
|
|
4032
4114
|
if (finalDiffSize > 0 || flags.force) {
|
|
4033
|
-
bucketOra.succeed(
|
|
4115
|
+
bucketOra.succeed(
|
|
4116
|
+
`[${sourceLocale} -> ${targetLocale}] Localization completed`
|
|
4117
|
+
);
|
|
4034
4118
|
} else {
|
|
4035
|
-
bucketOra.succeed(
|
|
4119
|
+
bucketOra.succeed(
|
|
4120
|
+
`[${sourceLocale} -> ${targetLocale}] Localization completed (no changes).`
|
|
4121
|
+
);
|
|
4036
4122
|
}
|
|
4037
4123
|
} catch (_error) {
|
|
4038
|
-
const error = new Error(
|
|
4124
|
+
const error = new Error(
|
|
4125
|
+
`[${sourceLocale} -> ${targetLocale}] Localization failed: ${_error.message}`
|
|
4126
|
+
);
|
|
4039
4127
|
if (flags.strict) {
|
|
4040
4128
|
throw error;
|
|
4041
4129
|
} else {
|
|
@@ -4049,7 +4137,9 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
4049
4137
|
await deltaProcessor.saveChecksums(checksums);
|
|
4050
4138
|
}
|
|
4051
4139
|
} catch (_error) {
|
|
4052
|
-
const error = new Error(
|
|
4140
|
+
const error = new Error(
|
|
4141
|
+
`Failed to process bucket ${bucket.type}: ${_error.message}`
|
|
4142
|
+
);
|
|
4053
4143
|
if (flags.strict) {
|
|
4054
4144
|
throw error;
|
|
4055
4145
|
} else {
|
|
@@ -4061,10 +4151,6 @@ var i18n_default = new Command6().command("i18n").description("Run Localization
|
|
|
4061
4151
|
console.log();
|
|
4062
4152
|
if (!hasErrors) {
|
|
4063
4153
|
ora.succeed("Localization completed.");
|
|
4064
|
-
deleteCache();
|
|
4065
|
-
if (flags.verbose) {
|
|
4066
|
-
ora.info("Cache file deleted.");
|
|
4067
|
-
}
|
|
4068
4154
|
trackEvent(auth.id, "cmd.i18n.success", {
|
|
4069
4155
|
i18nConfig,
|
|
4070
4156
|
flags
|
|
@@ -4132,7 +4218,9 @@ function validateParams(i18nConfig, flags) {
|
|
|
4132
4218
|
message: `One or more specified locales do not exist in i18n.json locale.targets. Please add them to the list and try again.`,
|
|
4133
4219
|
docUrl: "localeTargetNotFound"
|
|
4134
4220
|
});
|
|
4135
|
-
} else if (flags.bucket?.some(
|
|
4221
|
+
} else if (flags.bucket?.some(
|
|
4222
|
+
(bucket) => !i18nConfig.buckets[bucket]
|
|
4223
|
+
)) {
|
|
4136
4224
|
throw new CLIError({
|
|
4137
4225
|
message: `One or more specified buckets do not exist in i18n.json. Please add them to the list and try again.`,
|
|
4138
4226
|
docUrl: "bucketNotFound"
|
|
@@ -4164,8 +4252,10 @@ ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targetLocale)}): ${chalk.gr
|
|
|
4164
4252
|
if (line.startsWith("@")) return chalk.cyan(line);
|
|
4165
4253
|
return line;
|
|
4166
4254
|
}).join("\n");
|
|
4167
|
-
console.log(
|
|
4168
|
-
|
|
4255
|
+
console.log(
|
|
4256
|
+
`
|
|
4257
|
+
Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targetLocale)}):`
|
|
4258
|
+
);
|
|
4169
4259
|
console.log(coloredDiff);
|
|
4170
4260
|
const { action } = await inquirer2.prompt([
|
|
4171
4261
|
{
|
|
@@ -4201,9 +4291,19 @@ Reviewing changes for ${chalk.blue(args.pathPattern)} (${chalk.yellow(args.targe
|
|
|
4201
4291
|
console.log(`
|
|
4202
4292
|
Editing value for: ${chalk.cyan(key)}`);
|
|
4203
4293
|
console.log(chalk.gray("Source text:"), chalk.blue(args.sourceData[key]));
|
|
4204
|
-
console.log(
|
|
4205
|
-
|
|
4206
|
-
|
|
4294
|
+
console.log(
|
|
4295
|
+
chalk.gray("Current value:"),
|
|
4296
|
+
chalk.red(args.currentData[key] || "(empty)")
|
|
4297
|
+
);
|
|
4298
|
+
console.log(
|
|
4299
|
+
chalk.gray("Suggested value:"),
|
|
4300
|
+
chalk.green(args.proposedData[key])
|
|
4301
|
+
);
|
|
4302
|
+
console.log(
|
|
4303
|
+
chalk.gray(
|
|
4304
|
+
"\nYour editor will open. Edit the text and save to continue."
|
|
4305
|
+
)
|
|
4306
|
+
);
|
|
4207
4307
|
console.log(chalk.gray("------------"));
|
|
4208
4308
|
try {
|
|
4209
4309
|
const editorContent = [
|
|
@@ -4224,11 +4324,15 @@ Editing value for: ${chalk.cyan(key)}`);
|
|
|
4224
4324
|
if (customValue) {
|
|
4225
4325
|
customData[key] = customValue;
|
|
4226
4326
|
} else {
|
|
4227
|
-
console.log(
|
|
4327
|
+
console.log(
|
|
4328
|
+
chalk.yellow("Empty value provided, keeping the current value.")
|
|
4329
|
+
);
|
|
4228
4330
|
customData[key] = args.currentData[key] || args.proposedData[key];
|
|
4229
4331
|
}
|
|
4230
4332
|
} catch (error) {
|
|
4231
|
-
console.log(
|
|
4333
|
+
console.log(
|
|
4334
|
+
chalk.red("Error while editing, keeping the suggested value.")
|
|
4335
|
+
);
|
|
4232
4336
|
customData[key] = args.proposedData[key];
|
|
4233
4337
|
}
|
|
4234
4338
|
}
|
|
@@ -4241,8 +4345,8 @@ import Z5 from "zod";
|
|
|
4241
4345
|
import Ora6 from "ora";
|
|
4242
4346
|
|
|
4243
4347
|
// src/cli/utils/lockfile.ts
|
|
4244
|
-
import
|
|
4245
|
-
import
|
|
4348
|
+
import fs11 from "fs";
|
|
4349
|
+
import path15 from "path";
|
|
4246
4350
|
import Z4 from "zod";
|
|
4247
4351
|
import YAML4 from "yaml";
|
|
4248
4352
|
import { MD5 as MD52 } from "object-hash";
|
|
@@ -4251,7 +4355,7 @@ function createLockfileHelper() {
|
|
|
4251
4355
|
return {
|
|
4252
4356
|
isLockfileExists: () => {
|
|
4253
4357
|
const lockfilePath = _getLockfilePath();
|
|
4254
|
-
return
|
|
4358
|
+
return fs11.existsSync(lockfilePath);
|
|
4255
4359
|
},
|
|
4256
4360
|
registerSourceData: (pathPattern, sourceData) => {
|
|
4257
4361
|
const lockfile = _loadLockfile();
|
|
@@ -4278,20 +4382,20 @@ function createLockfileHelper() {
|
|
|
4278
4382
|
};
|
|
4279
4383
|
function _loadLockfile() {
|
|
4280
4384
|
const lockfilePath = _getLockfilePath();
|
|
4281
|
-
if (!
|
|
4385
|
+
if (!fs11.existsSync(lockfilePath)) {
|
|
4282
4386
|
return LockfileSchema.parse({});
|
|
4283
4387
|
}
|
|
4284
|
-
const content =
|
|
4388
|
+
const content = fs11.readFileSync(lockfilePath, "utf-8");
|
|
4285
4389
|
const result = LockfileSchema.parse(YAML4.parse(content));
|
|
4286
4390
|
return result;
|
|
4287
4391
|
}
|
|
4288
4392
|
function _saveLockfile(lockfile) {
|
|
4289
4393
|
const lockfilePath = _getLockfilePath();
|
|
4290
4394
|
const content = YAML4.stringify(lockfile);
|
|
4291
|
-
|
|
4395
|
+
fs11.writeFileSync(lockfilePath, content);
|
|
4292
4396
|
}
|
|
4293
4397
|
function _getLockfilePath() {
|
|
4294
|
-
return
|
|
4398
|
+
return path15.join(process.cwd(), "i18n.lock");
|
|
4295
4399
|
}
|
|
4296
4400
|
}
|
|
4297
4401
|
var LockfileSchema = Z4.object({
|
|
@@ -4500,7 +4604,7 @@ import { execSync as execSync2 } from "child_process";
|
|
|
4500
4604
|
|
|
4501
4605
|
// ../../action/src/flows/in-branch.ts
|
|
4502
4606
|
import { execSync } from "child_process";
|
|
4503
|
-
import
|
|
4607
|
+
import path16 from "path";
|
|
4504
4608
|
|
|
4505
4609
|
// ../../action/src/flows/_base.ts
|
|
4506
4610
|
var IntegrationFlow = class {
|
|
@@ -4578,7 +4682,7 @@ var InBranchFlow = class extends IntegrationFlow {
|
|
|
4578
4682
|
return false;
|
|
4579
4683
|
}
|
|
4580
4684
|
}
|
|
4581
|
-
const workingDir =
|
|
4685
|
+
const workingDir = path16.resolve(process.cwd(), this.platformKit.config.workingDir);
|
|
4582
4686
|
if (workingDir !== process.cwd()) {
|
|
4583
4687
|
this.ora.info(`Changing to working directory: ${this.platformKit.config.workingDir}`);
|
|
4584
4688
|
process.chdir(workingDir);
|
|
@@ -5150,7 +5254,7 @@ var status_default = new Command11().command("status").description("Show the sta
|
|
|
5150
5254
|
ora.succeed("Buckets retrieved");
|
|
5151
5255
|
if (flags.file?.length) {
|
|
5152
5256
|
buckets = buckets.map((bucket) => {
|
|
5153
|
-
const paths = bucket.paths.filter((
|
|
5257
|
+
const paths = bucket.paths.filter((path17) => flags.file.find((file) => path17.pathPattern?.match(file)));
|
|
5154
5258
|
return { ...bucket, paths };
|
|
5155
5259
|
}).filter((bucket) => bucket.paths.length > 0);
|
|
5156
5260
|
if (buckets.length === 0) {
|
|
@@ -5160,8 +5264,8 @@ var status_default = new Command11().command("status").description("Show the sta
|
|
|
5160
5264
|
ora.info(`\x1B[36mProcessing only filtered buckets:\x1B[0m`);
|
|
5161
5265
|
buckets.map((bucket) => {
|
|
5162
5266
|
ora.info(` ${bucket.type}:`);
|
|
5163
|
-
bucket.paths.forEach((
|
|
5164
|
-
ora.info(` - ${
|
|
5267
|
+
bucket.paths.forEach((path17) => {
|
|
5268
|
+
ora.info(` - ${path17.pathPattern}`);
|
|
5165
5269
|
});
|
|
5166
5270
|
});
|
|
5167
5271
|
}
|
|
@@ -5390,10 +5494,10 @@ var status_default = new Command11().command("status").description("Show the sta
|
|
|
5390
5494
|
if (flags.confirm && Object.keys(fileStats).length > 0) {
|
|
5391
5495
|
console.log(chalk2.bold(`
|
|
5392
5496
|
\u{1F4D1} BREAKDOWN BY FILE:`));
|
|
5393
|
-
Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([
|
|
5497
|
+
Object.entries(fileStats).sort((a, b) => b[1].wordCount - a[1].wordCount).forEach(([path17, stats]) => {
|
|
5394
5498
|
if (stats.sourceKeys === 0) return;
|
|
5395
5499
|
console.log(chalk2.bold(`
|
|
5396
|
-
\u2022 ${
|
|
5500
|
+
\u2022 ${path17}:`));
|
|
5397
5501
|
console.log(` ${stats.sourceKeys} source keys, ~${stats.wordCount.toLocaleString()} source words`);
|
|
5398
5502
|
const fileTable = new Table({
|
|
5399
5503
|
head: ["Language", "Status", "Details"],
|
|
@@ -5523,7 +5627,7 @@ function validateParams2(i18nConfig, flags) {
|
|
|
5523
5627
|
// package.json
|
|
5524
5628
|
var package_default = {
|
|
5525
5629
|
name: "lingo.dev",
|
|
5526
|
-
version: "0.
|
|
5630
|
+
version: "0.87.1",
|
|
5527
5631
|
description: "Lingo.dev CLI",
|
|
5528
5632
|
private: false,
|
|
5529
5633
|
publishConfig: {
|
|
@@ -5597,6 +5701,7 @@ var package_default = {
|
|
|
5597
5701
|
"csv-parse": "^5.6.0",
|
|
5598
5702
|
"csv-stringify": "^6.5.2",
|
|
5599
5703
|
"date-fns": "^4.1.0",
|
|
5704
|
+
dedent: "^1.5.3",
|
|
5600
5705
|
diff: "^7.0.0",
|
|
5601
5706
|
dotenv: "^16.4.7",
|
|
5602
5707
|
express: "^4.21.2",
|
|
@@ -5616,6 +5721,9 @@ var package_default = {
|
|
|
5616
5721
|
jsonrepair: "^3.11.2",
|
|
5617
5722
|
lodash: "^4.17.21",
|
|
5618
5723
|
marked: "^15.0.6",
|
|
5724
|
+
"mdast-util-from-markdown": "^2.0.2",
|
|
5725
|
+
"mdast-util-gfm": "^3.1.0",
|
|
5726
|
+
"micromark-extension-gfm": "^3.0.0",
|
|
5619
5727
|
"node-webvtt": "^1.9.4",
|
|
5620
5728
|
"object-hash": "^3.0.0",
|
|
5621
5729
|
octokit: "^4.0.2",
|
|
@@ -5626,14 +5734,18 @@ var package_default = {
|
|
|
5626
5734
|
plist: "^3.1.0",
|
|
5627
5735
|
"posthog-node": "^4.11.2",
|
|
5628
5736
|
prettier: "^3.4.2",
|
|
5737
|
+
"rehype-stringify": "^10.0.1",
|
|
5738
|
+
"remark-disable-tokenizers": "^1.1.1",
|
|
5629
5739
|
"remark-frontmatter": "^5.0.0",
|
|
5630
5740
|
"remark-gfm": "^4.0.1",
|
|
5631
5741
|
"remark-mdx": "^3.1.0",
|
|
5632
5742
|
"remark-mdx-frontmatter": "^5.1.0",
|
|
5633
5743
|
"remark-parse": "^11.0.0",
|
|
5744
|
+
"remark-rehype": "^11.1.2",
|
|
5634
5745
|
"remark-stringify": "^11.0.0",
|
|
5635
5746
|
"srt-parser-2": "^1.2.3",
|
|
5636
5747
|
unified: "^11.0.5",
|
|
5748
|
+
"unist-util-visit": "^5.0.0",
|
|
5637
5749
|
vfile: "^6.0.3",
|
|
5638
5750
|
xliff: "^6.2.1",
|
|
5639
5751
|
xml2js: "^0.6.2",
|