lingui-po-translate 1.0.0 → 1.0.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/dist/core/core-definitions.js +21 -0
- package/dist/core/core-util.js +65 -0
- package/dist/core/invoke-translation-service.js +82 -0
- package/dist/core/translate-cli.js +113 -0
- package/dist/core/translate-core.js +230 -0
- package/dist/core/tset-ops.js +110 -0
- package/dist/file-formats/common/format-cache.js +72 -0
- package/dist/file-formats/common/managed-json.js +37 -0
- package/dist/file-formats/common/managed-utf8.js +69 -0
- package/dist/file-formats/common/parse-utils.js +14 -0
- package/dist/file-formats/csv/csv.js +64 -0
- package/dist/file-formats/file-format-definitions.js +43 -0
- package/dist/file-formats/flat-json/flat-json.js +29 -0
- package/dist/file-formats/flutter-arb/flutter-arb.js +62 -0
- package/dist/file-formats/ios-strings/ios-read.js +72 -0
- package/dist/file-formats/ios-strings/ios-strings.js +22 -0
- package/dist/file-formats/ios-strings/ios-write.js +37 -0
- package/dist/file-formats/nested-json/nested-json.js +66 -0
- package/dist/file-formats/po/comment-parser.js +68 -0
- package/dist/file-formats/po/po-files.js +78 -0
- package/dist/file-formats/po/po-ops.js +111 -0
- package/dist/file-formats/xml/xml-generic.js +81 -0
- package/dist/file-formats/xml/xml-read.js +66 -0
- package/dist/file-formats/xml/xml-traverse.js +160 -0
- package/dist/file-formats/xml/xml-write.js +62 -0
- package/dist/file-formats/yaml/yaml-generic.js +113 -0
- package/dist/file-formats/yaml/yaml-manipulation.js +132 -0
- package/dist/file-formats/yaml/yaml-parse.js +38 -0
- package/dist/index.js +66 -0
- package/dist/matchers/i18next.js +11 -0
- package/dist/matchers/icu.js +23 -0
- package/dist/matchers/matcher-definitions.js +46 -0
- package/dist/matchers/sprintf.js +11 -0
- package/dist/services/azure-translator.js +52 -0
- package/dist/services/google-translate.js +55 -0
- package/dist/services/key-as-translation.js +18 -0
- package/dist/services/manual.js +29 -0
- package/dist/services/openai-translate.js +91 -0
- package/dist/services/service-definitions.js +57 -0
- package/dist/services/sync-without-translate.js +18 -0
- package/dist/services/typechat.js +214 -0
- package/dist/util/extract-version.js +20 -0
- package/dist/util/flatten.js +40 -0
- package/dist/util/util.js +87 -0
- package/package.json +2 -2
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PoFile = exports.getParsedComments = exports.potCache = void 0;
|
|
4
|
+
const gettext_parser_1 = require("gettext-parser");
|
|
5
|
+
const format_cache_1 = require("../common/format-cache");
|
|
6
|
+
const managed_utf8_1 = require("../common/managed-utf8");
|
|
7
|
+
const po_ops_1 = require("./po-ops");
|
|
8
|
+
exports.potCache = new format_cache_1.FormatCache();
|
|
9
|
+
/**
|
|
10
|
+
* Get parsed comments for all keys in a file
|
|
11
|
+
*/
|
|
12
|
+
function getParsedComments(path) {
|
|
13
|
+
const result = new Map();
|
|
14
|
+
const fileCache = exports.potCache.lookupFileCache(path);
|
|
15
|
+
if (fileCache) {
|
|
16
|
+
fileCache.entries.forEach((entry, key) => {
|
|
17
|
+
result.set(key, entry.parsedComment);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
exports.getParsedComments = getParsedComments;
|
|
23
|
+
class PoFile {
|
|
24
|
+
readTFile(args) {
|
|
25
|
+
const rawFile = (0, managed_utf8_1.readManagedUtf8)(args.path);
|
|
26
|
+
if (!rawFile) {
|
|
27
|
+
return Promise.resolve(new Map());
|
|
28
|
+
}
|
|
29
|
+
const potFile = (0, po_ops_1.parsePotFile)(args, rawFile);
|
|
30
|
+
exports.potCache.insertFileCache({
|
|
31
|
+
path: args.path,
|
|
32
|
+
entries: new Map(),
|
|
33
|
+
auxData: { potFile, rawFile },
|
|
34
|
+
});
|
|
35
|
+
const tSet = (0, po_ops_1.extractPotTranslations)(args, potFile);
|
|
36
|
+
return Promise.resolve(tSet);
|
|
37
|
+
}
|
|
38
|
+
writeTFile(args) {
|
|
39
|
+
var _a;
|
|
40
|
+
const sourcePot = (_a = exports.potCache.getOldestAuxdata()) === null || _a === void 0 ? void 0 : _a.potFile;
|
|
41
|
+
let output;
|
|
42
|
+
if (!sourcePot) {
|
|
43
|
+
output = createUncachedPot(args);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
output = createCachedPot(args, sourcePot);
|
|
47
|
+
}
|
|
48
|
+
(0, managed_utf8_1.writeManagedUtf8)({ path: args.path, utf8: output });
|
|
49
|
+
exports.potCache.purge();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.PoFile = PoFile;
|
|
53
|
+
const compileOptions = {
|
|
54
|
+
foldLength: 100,
|
|
55
|
+
sort: false,
|
|
56
|
+
};
|
|
57
|
+
function createCachedPot(args, sourcePot) {
|
|
58
|
+
(0, po_ops_1.updatePotTranslations)(args, sourcePot);
|
|
59
|
+
const buffer = gettext_parser_1.po.compile(sourcePot, compileOptions);
|
|
60
|
+
return buffer.toString("utf-8");
|
|
61
|
+
}
|
|
62
|
+
function createUncachedPot(args) {
|
|
63
|
+
const potFile = {
|
|
64
|
+
charset: "utf-8",
|
|
65
|
+
headers: {},
|
|
66
|
+
translations: {},
|
|
67
|
+
};
|
|
68
|
+
args.tSet.forEach((value, key) => {
|
|
69
|
+
potFile.translations[key] = {
|
|
70
|
+
key: {
|
|
71
|
+
msgid: key,
|
|
72
|
+
msgstr: [value !== null && value !== void 0 ? value : ""],
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
const buffer = gettext_parser_1.po.compile(potFile, compileOptions);
|
|
77
|
+
return buffer.toString("utf-8") + "\n";
|
|
78
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parsePotFile = exports.updatePotTranslations = exports.extractPotTranslations = void 0;
|
|
4
|
+
const gettext_parser_1 = require("gettext-parser");
|
|
5
|
+
const parse_utils_1 = require("../common/parse-utils");
|
|
6
|
+
const po_files_1 = require("./po-files");
|
|
7
|
+
const comment_parser_1 = require("./comment-parser");
|
|
8
|
+
function mergePotComments(args) {
|
|
9
|
+
if (!args.source) {
|
|
10
|
+
return args.oldTarget;
|
|
11
|
+
}
|
|
12
|
+
const source = args.source;
|
|
13
|
+
const oldTarget = args.oldTarget;
|
|
14
|
+
for (const key of Object.keys(source)) {
|
|
15
|
+
const sourceValue = source[key];
|
|
16
|
+
if (!oldTarget[key]) {
|
|
17
|
+
oldTarget[key] = sourceValue;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return args.oldTarget;
|
|
21
|
+
}
|
|
22
|
+
function extractPotTranslations(args, potFile) {
|
|
23
|
+
const tSet = new Map();
|
|
24
|
+
traversePot(potFile, (getText) => {
|
|
25
|
+
const key = getText.msgid;
|
|
26
|
+
const value = getText.msgstr.join();
|
|
27
|
+
if (key) {
|
|
28
|
+
tSet.set(key, value);
|
|
29
|
+
}
|
|
30
|
+
const comments = getText.comments;
|
|
31
|
+
if (typeof key === "string") {
|
|
32
|
+
const parsedComment = (0, comment_parser_1.parseExtractedComment)(comments === null || comments === void 0 ? void 0 : comments.extracted);
|
|
33
|
+
po_files_1.potCache.insert({
|
|
34
|
+
path: args.path,
|
|
35
|
+
key,
|
|
36
|
+
entry: {
|
|
37
|
+
comments: comments !== null && comments !== void 0 ? comments : {},
|
|
38
|
+
parsedComment,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return tSet;
|
|
44
|
+
}
|
|
45
|
+
exports.extractPotTranslations = extractPotTranslations;
|
|
46
|
+
function updatePotTranslations(args, potFile) {
|
|
47
|
+
const oldTarget = po_files_1.potCache.lookupSameFileAuxdata({ path: args.path });
|
|
48
|
+
if (oldTarget) {
|
|
49
|
+
potFile.headers = oldTarget.potFile.headers;
|
|
50
|
+
}
|
|
51
|
+
traversePot(potFile, (getText) => {
|
|
52
|
+
var _a, _b;
|
|
53
|
+
const key = getText.msgid;
|
|
54
|
+
const value = args.tSet.get(key);
|
|
55
|
+
if (value !== undefined) {
|
|
56
|
+
getText.msgstr = [value !== null && value !== void 0 ? value : ""];
|
|
57
|
+
}
|
|
58
|
+
const oldTargetComments = (_a = po_files_1.potCache.lookup({
|
|
59
|
+
path: args.path,
|
|
60
|
+
key,
|
|
61
|
+
})) === null || _a === void 0 ? void 0 : _a.comments;
|
|
62
|
+
if (typeof key === "string" && oldTargetComments) {
|
|
63
|
+
getText.comments = mergePotComments({
|
|
64
|
+
source: (_b = getText.comments) !== null && _b !== void 0 ? _b : null,
|
|
65
|
+
oldTarget: oldTargetComments,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (args.changeSet.added.has(key)) {
|
|
69
|
+
// add a special marking for newly-added PO-entries
|
|
70
|
+
const newPoMarker = "NEEDS WORK";
|
|
71
|
+
if (getText.comments) {
|
|
72
|
+
if (typeof getText.comments.reference === "string") {
|
|
73
|
+
getText.comments.reference += (" " + newPoMarker);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
getText.comments.reference = newPoMarker;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
getText.comments = {
|
|
81
|
+
reference: newPoMarker
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
exports.updatePotTranslations = updatePotTranslations;
|
|
88
|
+
function parsePotFile(args, rawFile) {
|
|
89
|
+
try {
|
|
90
|
+
const potFile = gettext_parser_1.po.parse(rawFile);
|
|
91
|
+
if (!potFile.headers) {
|
|
92
|
+
potFile.headers = {};
|
|
93
|
+
}
|
|
94
|
+
potFile.headers["X-Generator"] = "lingui-po-translate";
|
|
95
|
+
return potFile;
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
console.error(e);
|
|
99
|
+
(0, parse_utils_1.logParseError)("GetText parsing error", args);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.parsePotFile = parsePotFile;
|
|
103
|
+
function traversePot(potFile, operation) {
|
|
104
|
+
for (const outerKey of Object.keys(potFile.translations)) {
|
|
105
|
+
const potEntry = potFile.translations[outerKey];
|
|
106
|
+
for (const innerKey of Object.keys(potEntry)) {
|
|
107
|
+
const getText = potEntry[innerKey];
|
|
108
|
+
operation(getText);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.XmlGeneric = exports.DEFAULT_XML_HEADER = exports.DEFAULT_XML_INDENT = exports.sharedXmlOptions = exports.defaultExcludedContentKey = exports.defaultKeyAttribute = void 0;
|
|
4
|
+
const xml_read_1 = require("./xml-read");
|
|
5
|
+
const format_cache_1 = require("../common/format-cache");
|
|
6
|
+
const xml_write_1 = require("./xml-write");
|
|
7
|
+
const managed_utf8_1 = require("../common/managed-utf8");
|
|
8
|
+
const xmlCache = new format_cache_1.FormatCache();
|
|
9
|
+
exports.defaultKeyAttribute = "name";
|
|
10
|
+
exports.defaultExcludedContentKey = "string";
|
|
11
|
+
exports.sharedXmlOptions = {
|
|
12
|
+
attrkey: "attributesObj",
|
|
13
|
+
charkey: "characterContent",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Android Studio seems to auto-format XML-files with 4 spaces indentation.
|
|
17
|
+
*/
|
|
18
|
+
exports.DEFAULT_XML_INDENT = 4;
|
|
19
|
+
exports.DEFAULT_XML_HEADER = '<?xml version="1.0" encoding="utf-8"?>';
|
|
20
|
+
class XmlGeneric {
|
|
21
|
+
async readTFile(args) {
|
|
22
|
+
const xmlString = (0, managed_utf8_1.readManagedUtf8)(args.path);
|
|
23
|
+
const xmlFile = await (0, xml_read_1.parseRawXML)(xmlString, args);
|
|
24
|
+
if (!xmlFile) {
|
|
25
|
+
return new Map();
|
|
26
|
+
}
|
|
27
|
+
const firstLine = (0, xml_read_1.extractFirstLine)(xmlString);
|
|
28
|
+
const fileCache = {
|
|
29
|
+
path: args.path,
|
|
30
|
+
auxData: {
|
|
31
|
+
xmlHeader: firstLine.includes("<?") ? firstLine : null,
|
|
32
|
+
xmlFile,
|
|
33
|
+
detectedIntent: (0, xml_read_1.detectSpaceIndent)(xmlString),
|
|
34
|
+
},
|
|
35
|
+
entries: new Map(),
|
|
36
|
+
};
|
|
37
|
+
xmlCache.insertFileCache(fileCache);
|
|
38
|
+
return (0, xml_read_1.extractXmlContent)({ args, xmlFile });
|
|
39
|
+
}
|
|
40
|
+
writeTFile(args) {
|
|
41
|
+
var _a;
|
|
42
|
+
const sourceXml = (_a = xmlCache.getOldestAuxdata()) === null || _a === void 0 ? void 0 : _a.xmlFile;
|
|
43
|
+
let resultXml;
|
|
44
|
+
if (sourceXml) {
|
|
45
|
+
resultXml = this.extractCachedXml(args, sourceXml);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
resultXml = this.createUncachedXml(args);
|
|
49
|
+
}
|
|
50
|
+
(0, xml_write_1.writeXmlResourceFile)(resultXml, args, xmlCache.lookupAuxdata({ path: args.path }));
|
|
51
|
+
xmlCache.purge();
|
|
52
|
+
}
|
|
53
|
+
extractCachedXml(args, sourceXml) {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
const oldTargetXml = (_b = (_a = xmlCache.lookupSameFileAuxdata({
|
|
56
|
+
path: args.path,
|
|
57
|
+
})) === null || _a === void 0 ? void 0 : _a.xmlFile) !== null && _b !== void 0 ? _b : null;
|
|
58
|
+
(0, xml_write_1.updateXmlContent)({ args, sourceXml, oldTargetXml });
|
|
59
|
+
return sourceXml;
|
|
60
|
+
}
|
|
61
|
+
createUncachedXml(args) {
|
|
62
|
+
const tagArray = [];
|
|
63
|
+
args.tSet.forEach((value, key) => {
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
65
|
+
// @ts-ignore
|
|
66
|
+
tagArray.push({
|
|
67
|
+
characterContent: value !== null && value !== void 0 ? value : "",
|
|
68
|
+
attributesObj: { name: key },
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
const rootTag = {
|
|
74
|
+
string: tagArray,
|
|
75
|
+
};
|
|
76
|
+
return {
|
|
77
|
+
resources: rootTag,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.XmlGeneric = XmlGeneric;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractFirstLine = exports.detectSpaceIndent = exports.extractXmlContent = exports.parseRawXML = void 0;
|
|
4
|
+
const xml_generic_1 = require("./xml-generic");
|
|
5
|
+
const parse_utils_1 = require("../common/parse-utils");
|
|
6
|
+
const xml_traverse_1 = require("./xml-traverse");
|
|
7
|
+
async function parseRawXML(xmlString, args) {
|
|
8
|
+
try {
|
|
9
|
+
const options = {
|
|
10
|
+
...xml_generic_1.sharedXmlOptions,
|
|
11
|
+
strict: true,
|
|
12
|
+
async: false,
|
|
13
|
+
//explicitChildren: true, // if true, then the resulting object will be entirely different
|
|
14
|
+
preserveChildrenOrder: true,
|
|
15
|
+
headless: true,
|
|
16
|
+
//emptyTag: " ",
|
|
17
|
+
includeWhiteChars: true,
|
|
18
|
+
trim: false,
|
|
19
|
+
normalize: false,
|
|
20
|
+
normalizeTags: false,
|
|
21
|
+
};
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
23
|
+
const xml2js = require("xml2js");
|
|
24
|
+
const result = await xml2js.parseStringPromise(xmlString, options);
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
console.error(e);
|
|
29
|
+
(0, parse_utils_1.logParseError)("XML parsing error", args);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.parseRawXML = parseRawXML;
|
|
33
|
+
function extractXmlContent(args) {
|
|
34
|
+
const tSet = new Map();
|
|
35
|
+
(0, xml_traverse_1.traverseXml)({
|
|
36
|
+
xml: args.xmlFile,
|
|
37
|
+
oldTargetXml: null,
|
|
38
|
+
operation: (context, xmlTag) => {
|
|
39
|
+
var _a;
|
|
40
|
+
const key = (0, xml_traverse_1.constructJsonKey)(context);
|
|
41
|
+
if (tSet.has(key)) {
|
|
42
|
+
(0, parse_utils_1.logParseError)(`duplicate key '${key}' -> Currently, the usage of duplicate translation-keys is discouraged.`, args.args);
|
|
43
|
+
}
|
|
44
|
+
if (typeof xmlTag === "string") {
|
|
45
|
+
tSet.set(key, xmlTag);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
tSet.set(key, (_a = xmlTag.characterContent) !== null && _a !== void 0 ? _a : "");
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
return tSet;
|
|
54
|
+
}
|
|
55
|
+
exports.extractXmlContent = extractXmlContent;
|
|
56
|
+
function detectSpaceIndent(xmlString) {
|
|
57
|
+
var _a;
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
59
|
+
const detectModule = require("detect-indent");
|
|
60
|
+
return (_a = detectModule(xmlString).amount) !== null && _a !== void 0 ? _a : xml_generic_1.DEFAULT_XML_INDENT;
|
|
61
|
+
}
|
|
62
|
+
exports.detectSpaceIndent = detectSpaceIndent;
|
|
63
|
+
function extractFirstLine(str) {
|
|
64
|
+
return str.split("\n", 1)[0];
|
|
65
|
+
}
|
|
66
|
+
exports.extractFirstLine = extractFirstLine;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.traverseXml = exports.constructJsonKey = void 0;
|
|
4
|
+
const xml_generic_1 = require("./xml-generic");
|
|
5
|
+
const flatten_1 = require("../../util/flatten");
|
|
6
|
+
function constructJsonKey(context) {
|
|
7
|
+
return context.keyFragments.join(flatten_1.NESTED_JSON_SEPARATOR);
|
|
8
|
+
}
|
|
9
|
+
exports.constructJsonKey = constructJsonKey;
|
|
10
|
+
function traverseXml(args) {
|
|
11
|
+
var _a;
|
|
12
|
+
const context = {
|
|
13
|
+
keyFragments: [],
|
|
14
|
+
operation: args.operation,
|
|
15
|
+
};
|
|
16
|
+
for (const contentKey of Object.keys(args.xml)) {
|
|
17
|
+
const xmlContent = args.xml[contentKey];
|
|
18
|
+
const oldTargetTag = args.oldTargetXml
|
|
19
|
+
? (_a = args.oldTargetXml[contentKey]) !== null && _a !== void 0 ? _a : null
|
|
20
|
+
: null;
|
|
21
|
+
if (typeof xmlContent === "object") {
|
|
22
|
+
traverseRecursive({
|
|
23
|
+
context,
|
|
24
|
+
tag: xmlContent,
|
|
25
|
+
oldTargetTag,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.traverseXml = traverseXml;
|
|
31
|
+
function traverseRecursive(args) {
|
|
32
|
+
if (typeof args.tag !== "object") {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (typeof args.oldTargetTag !== typeof args.tag) {
|
|
36
|
+
args.oldTargetTag = null;
|
|
37
|
+
}
|
|
38
|
+
else if (args.oldTargetTag && typeof args.oldTargetTag === "object") {
|
|
39
|
+
if (typeof args.oldTargetTag.attributesObj === "object") {
|
|
40
|
+
args.tag.attributesObj = {
|
|
41
|
+
...args.tag.attributesObj,
|
|
42
|
+
...args.oldTargetTag.attributesObj,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (isNonEmptyArray(args.oldTargetTag.comments)) {
|
|
46
|
+
args.tag.comments = args.oldTargetTag.comments;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
let hasChildTags = false;
|
|
50
|
+
for (const contentKey of Object.keys(args.tag)) {
|
|
51
|
+
const xmlContent = args.tag[contentKey];
|
|
52
|
+
if (contentKey !== "comments" && isNonEmptyArray(xmlContent)) {
|
|
53
|
+
hasChildTags = true;
|
|
54
|
+
const oldTargetChilds = extractOldTargetChilds(args.oldTargetTag, contentKey);
|
|
55
|
+
xmlContent.forEach((sourceChild, index) => {
|
|
56
|
+
const newKeyFragments = constructKeyFragments({
|
|
57
|
+
tag: sourceChild,
|
|
58
|
+
contentKey,
|
|
59
|
+
index,
|
|
60
|
+
});
|
|
61
|
+
const newContext = {
|
|
62
|
+
keyFragments: [...args.context.keyFragments, ...newKeyFragments],
|
|
63
|
+
operation: args.context.operation,
|
|
64
|
+
};
|
|
65
|
+
if (typeof sourceChild === "string") {
|
|
66
|
+
const newContent = args.context.operation(newContext, sourceChild);
|
|
67
|
+
if (newContent !== null) {
|
|
68
|
+
xmlContent[index] = newContent;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
traverseRecursive({
|
|
73
|
+
context: newContext,
|
|
74
|
+
tag: sourceChild,
|
|
75
|
+
oldTargetTag: matchOldTargetChild({
|
|
76
|
+
oldTargetChilds,
|
|
77
|
+
sourceChild,
|
|
78
|
+
index,
|
|
79
|
+
}),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (!hasChildTags) {
|
|
86
|
+
const newContent = args.context.operation(args.context, args.tag);
|
|
87
|
+
if (newContent !== null) {
|
|
88
|
+
args.tag.characterContent = newContent;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function extractAttributeKey(tag) {
|
|
93
|
+
var _a;
|
|
94
|
+
if (typeof tag !== "object") {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const attributes = tag.attributesObj;
|
|
98
|
+
if (!attributes || typeof attributes !== "object") {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
return (_a = attributes[xml_generic_1.defaultKeyAttribute]) !== null && _a !== void 0 ? _a : null;
|
|
102
|
+
}
|
|
103
|
+
function constructKeyFragments(args) {
|
|
104
|
+
const keyFragments = [];
|
|
105
|
+
const attributeKey = extractAttributeKey(args.tag);
|
|
106
|
+
if (attributeKey) {
|
|
107
|
+
if (args.contentKey !== xml_generic_1.defaultExcludedContentKey) {
|
|
108
|
+
keyFragments.push(args.contentKey);
|
|
109
|
+
}
|
|
110
|
+
keyFragments.push(attributeKey);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
keyFragments.push(args.contentKey + "_" + args.index);
|
|
114
|
+
}
|
|
115
|
+
return keyFragments;
|
|
116
|
+
}
|
|
117
|
+
function extractOldTargetChilds(oldTargetXml, contentKey) {
|
|
118
|
+
if (!oldTargetXml) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
if (typeof oldTargetXml !== "object") {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
const xmlContent = oldTargetXml[contentKey];
|
|
125
|
+
if (xmlContent && typeof xmlContent === "object") {
|
|
126
|
+
return xmlContent;
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
function matchOldTargetChild(args) {
|
|
131
|
+
var _a;
|
|
132
|
+
if (!isNonEmptyArray(args.oldTargetChilds)) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
const sourceAttributeKey = extractAttributeKey(args.sourceChild);
|
|
136
|
+
if (sourceAttributeKey) {
|
|
137
|
+
return ((_a = args.oldTargetChilds.find((oldTargetChild) => {
|
|
138
|
+
const oldTargetAttributeKey = extractAttributeKey(oldTargetChild);
|
|
139
|
+
return (oldTargetAttributeKey && oldTargetAttributeKey === sourceAttributeKey);
|
|
140
|
+
})) !== null && _a !== void 0 ? _a : null);
|
|
141
|
+
}
|
|
142
|
+
else if (args.oldTargetChilds.length > args.index) {
|
|
143
|
+
return args.oldTargetChilds[args.index];
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function isNonEmptyArray(obj) {
|
|
150
|
+
if (!obj) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
if (!Array.isArray(obj)) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
if (!obj.length) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.writeXmlResourceFile = exports.updateXmlContent = void 0;
|
|
4
|
+
const xml_generic_1 = require("./xml-generic");
|
|
5
|
+
const xml_traverse_1 = require("./xml-traverse");
|
|
6
|
+
const managed_utf8_1 = require("../common/managed-utf8");
|
|
7
|
+
function updateXmlContent(args) {
|
|
8
|
+
(0, xml_traverse_1.traverseXml)({
|
|
9
|
+
xml: args.sourceXml,
|
|
10
|
+
oldTargetXml: args.oldTargetXml,
|
|
11
|
+
operation: (context, xmlTag) => {
|
|
12
|
+
const key = (0, xml_traverse_1.constructJsonKey)(context);
|
|
13
|
+
const value = args.args.tSet.get(key);
|
|
14
|
+
if (value !== undefined) {
|
|
15
|
+
return value !== null && value !== void 0 ? value : "";
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
exports.updateXmlContent = updateXmlContent;
|
|
22
|
+
function writeXmlResourceFile(xmlFile, args, auxData) {
|
|
23
|
+
var _a;
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
25
|
+
const xml2js = require("xml2js");
|
|
26
|
+
const stringIndent = " ".repeat((_a = auxData === null || auxData === void 0 ? void 0 : auxData.detectedIntent) !== null && _a !== void 0 ? _a : xml_generic_1.DEFAULT_XML_INDENT);
|
|
27
|
+
const options = {
|
|
28
|
+
...xml_generic_1.sharedXmlOptions,
|
|
29
|
+
headless: true,
|
|
30
|
+
renderOpts: {
|
|
31
|
+
pretty: true,
|
|
32
|
+
indent: stringIndent,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
// See https://github.com/oozcitak/xmlbuilder-js/wiki/Builder-Options for available xmlBuilderOptions
|
|
36
|
+
const xmlBuilderOptions = {
|
|
37
|
+
noValidation: false,
|
|
38
|
+
noDoubleEncoding: true,
|
|
39
|
+
};
|
|
40
|
+
const mergedOptions = { ...options, xmlBuilderOptions };
|
|
41
|
+
const builder = new xml2js.Builder(mergedOptions);
|
|
42
|
+
const rawXmlString = builder.buildObject(xmlFile);
|
|
43
|
+
let xmlHeader = xml_generic_1.DEFAULT_XML_HEADER + "\n";
|
|
44
|
+
if (auxData) {
|
|
45
|
+
if (auxData.xmlHeader) {
|
|
46
|
+
xmlHeader = auxData.xmlHeader + "\n";
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
xmlHeader = "";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const xmlString = `${xmlHeader}${removeBlankLines(rawXmlString)}\n`;
|
|
53
|
+
(0, managed_utf8_1.writeManagedUtf8)({ path: args.path, utf8: xmlString });
|
|
54
|
+
}
|
|
55
|
+
exports.writeXmlResourceFile = writeXmlResourceFile;
|
|
56
|
+
function removeBlankLines(str) {
|
|
57
|
+
const lines = str.split("\n");
|
|
58
|
+
const filteredLines = lines.filter((line) => {
|
|
59
|
+
return line.trim().length >= 1;
|
|
60
|
+
});
|
|
61
|
+
return filteredLines.join("\n");
|
|
62
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.YamlGeneric = exports.isScalar = exports.isPair = exports.isCollection = exports.isSequence = void 0;
|
|
4
|
+
const yaml_1 = require("yaml");
|
|
5
|
+
const format_cache_1 = require("../common/format-cache");
|
|
6
|
+
const flatten_1 = require("../../util/flatten");
|
|
7
|
+
const types_1 = require("yaml/types");
|
|
8
|
+
const yaml_manipulation_1 = require("./yaml-manipulation");
|
|
9
|
+
const util_1 = require("yaml/util");
|
|
10
|
+
const yaml_parse_1 = require("./yaml-parse");
|
|
11
|
+
const managed_utf8_1 = require("../common/managed-utf8");
|
|
12
|
+
function isSequence(node) {
|
|
13
|
+
if (!node.type) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return [util_1.Type.SEQ, util_1.Type.FLOW_SEQ].includes(node.type);
|
|
17
|
+
}
|
|
18
|
+
exports.isSequence = isSequence;
|
|
19
|
+
function isCollection(node) {
|
|
20
|
+
if (!node) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
if (!node.type) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return [
|
|
27
|
+
util_1.Type.MAP,
|
|
28
|
+
util_1.Type.FLOW_MAP,
|
|
29
|
+
util_1.Type.SEQ,
|
|
30
|
+
util_1.Type.FLOW_SEQ,
|
|
31
|
+
util_1.Type.DOCUMENT,
|
|
32
|
+
].includes(node.type);
|
|
33
|
+
}
|
|
34
|
+
exports.isCollection = isCollection;
|
|
35
|
+
function isPair(node) {
|
|
36
|
+
if (!node) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (!node.type) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return [types_1.Pair.Type.PAIR, types_1.Pair.Type.MERGE_PAIR].includes(node.type);
|
|
43
|
+
}
|
|
44
|
+
exports.isPair = isPair;
|
|
45
|
+
function isScalar(node) {
|
|
46
|
+
if (!node.type) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return [
|
|
50
|
+
util_1.Type.BLOCK_FOLDED,
|
|
51
|
+
util_1.Type.BLOCK_LITERAL,
|
|
52
|
+
util_1.Type.PLAIN,
|
|
53
|
+
util_1.Type.QUOTE_DOUBLE,
|
|
54
|
+
util_1.Type.QUOTE_SINGLE,
|
|
55
|
+
].includes(node.type);
|
|
56
|
+
}
|
|
57
|
+
exports.isScalar = isScalar;
|
|
58
|
+
const documentCache = new format_cache_1.FormatCache();
|
|
59
|
+
class YamlGeneric {
|
|
60
|
+
constructor() {
|
|
61
|
+
// Do not mess with user's line breaks; preserve everything as is!
|
|
62
|
+
yaml_1.scalarOptions.str.fold = { lineWidth: 0, minContentWidth: 0 };
|
|
63
|
+
yaml_1.scalarOptions.str.doubleQuoted = {
|
|
64
|
+
minMultiLineLength: 1000,
|
|
65
|
+
jsonEncoding: false,
|
|
66
|
+
};
|
|
67
|
+
yaml_1.scalarOptions.null.nullStr = "";
|
|
68
|
+
}
|
|
69
|
+
readTFile(args) {
|
|
70
|
+
const document = (0, yaml_parse_1.parseYaml)(args);
|
|
71
|
+
if (!document) {
|
|
72
|
+
return Promise.resolve(new Map());
|
|
73
|
+
}
|
|
74
|
+
documentCache.insertFileCache({
|
|
75
|
+
path: args.path,
|
|
76
|
+
entries: new Map(),
|
|
77
|
+
auxData: document,
|
|
78
|
+
});
|
|
79
|
+
const tSet = (0, yaml_manipulation_1.extractYmlNodes)(args, document);
|
|
80
|
+
return Promise.resolve(tSet);
|
|
81
|
+
}
|
|
82
|
+
writeTFile(args) {
|
|
83
|
+
const sourceYml = documentCache.getOldestAuxdata();
|
|
84
|
+
let ymlString;
|
|
85
|
+
if (sourceYml) {
|
|
86
|
+
ymlString = this.createCachedYml(args, sourceYml);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
ymlString = this.createUncachedYml(args);
|
|
90
|
+
}
|
|
91
|
+
(0, managed_utf8_1.writeManagedUtf8)({ path: args.path, utf8: ymlString });
|
|
92
|
+
documentCache.purge();
|
|
93
|
+
}
|
|
94
|
+
createCachedYml(args, sourceYml) {
|
|
95
|
+
const oldTargetYml = documentCache.lookupSameFileAuxdata({
|
|
96
|
+
path: args.path,
|
|
97
|
+
});
|
|
98
|
+
(0, yaml_manipulation_1.updateYmlNodes)({ args, sourceYml, oldTargetYml });
|
|
99
|
+
return sourceYml.toString();
|
|
100
|
+
}
|
|
101
|
+
createUncachedYml(args) {
|
|
102
|
+
const flatJson = {};
|
|
103
|
+
args.tSet.forEach((value, key) => {
|
|
104
|
+
flatJson[key] = value;
|
|
105
|
+
});
|
|
106
|
+
const nestedJson = (0, flatten_1.unflatten)(flatJson);
|
|
107
|
+
const options = {
|
|
108
|
+
mapAsMap: false,
|
|
109
|
+
};
|
|
110
|
+
return (0, yaml_1.stringify)(nestedJson, options);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.YamlGeneric = YamlGeneric;
|