|
4 | 4 | * Licensed under the MIT License. See License.txt in the project root for license information. |
5 | 5 | *--------------------------------------------------------------------------------------------*/ |
6 | 6 | Object.defineProperty(exports, "__esModule", { value: true }); |
| 7 | +exports.prepareIslFiles = exports.prepareI18nPackFiles = exports.pullI18nPackFiles = exports.prepareI18nFiles = exports.pullSetupXlfFiles = exports.pullCoreAndExtensionsXlfFiles = exports.findObsoleteResources = exports.pushXlfFiles = exports.createXlfFilesForIsl = exports.createXlfFilesForExtensions = exports.createXlfFilesForCoreBundle = exports.getResource = exports.processNlsFiles = exports.Limiter = exports.XLF = exports.Line = exports.externalExtensionsWithTranslations = exports.extraLanguages = exports.defaultLanguages = void 0; |
7 | 8 | const path = require("path"); |
8 | 9 | const fs = require("fs"); |
9 | 10 | const event_stream_1 = require("event-stream"); |
@@ -100,155 +101,158 @@ class TextModel { |
100 | 101 | return this._lines; |
101 | 102 | } |
102 | 103 | } |
103 | | -class XLF { |
104 | | - constructor(project) { |
105 | | - this.project = project; |
106 | | - this.buffer = []; |
107 | | - this.files = Object.create(null); |
108 | | - this.numberOfMessages = 0; |
109 | | - } |
110 | | - toString() { |
111 | | - this.appendHeader(); |
112 | | - for (let file in this.files) { |
113 | | - this.appendNewLine(`<file original="${file}" source-language="en" datatype="plaintext"><body>`, 2); |
114 | | - for (let item of this.files[file]) { |
115 | | - this.addStringItem(item); |
116 | | - } |
117 | | - this.appendNewLine('</body></file>', 2); |
118 | | - } |
119 | | - this.appendFooter(); |
120 | | - return this.buffer.join('\r\n'); |
121 | | - } |
122 | | - addFile(original, keys, messages) { |
123 | | - if (keys.length === 0) { |
124 | | - console.log('No keys in ' + original); |
125 | | - return; |
| 104 | +let XLF = /** @class */ (() => { |
| 105 | + class XLF { |
| 106 | + constructor(project) { |
| 107 | + this.project = project; |
| 108 | + this.buffer = []; |
| 109 | + this.files = Object.create(null); |
| 110 | + this.numberOfMessages = 0; |
126 | 111 | } |
127 | | - if (keys.length !== messages.length) { |
128 | | - throw new Error(`Unmatching keys(${keys.length}) and messages(${messages.length}).`); |
| 112 | + toString() { |
| 113 | + this.appendHeader(); |
| 114 | + for (let file in this.files) { |
| 115 | + this.appendNewLine(`<file original="${file}" source-language="en" datatype="plaintext"><body>`, 2); |
| 116 | + for (let item of this.files[file]) { |
| 117 | + this.addStringItem(item); |
| 118 | + } |
| 119 | + this.appendNewLine('</body></file>', 2); |
| 120 | + } |
| 121 | + this.appendFooter(); |
| 122 | + return this.buffer.join('\r\n'); |
129 | 123 | } |
130 | | - this.numberOfMessages += keys.length; |
131 | | - this.files[original] = []; |
132 | | - let existingKeys = new Set(); |
133 | | - for (let i = 0; i < keys.length; i++) { |
134 | | - let key = keys[i]; |
135 | | - let realKey; |
136 | | - let comment; |
137 | | - if (Is.string(key)) { |
138 | | - realKey = key; |
139 | | - comment = undefined; |
| 124 | + addFile(original, keys, messages) { |
| 125 | + if (keys.length === 0) { |
| 126 | + console.log('No keys in ' + original); |
| 127 | + return; |
| 128 | + } |
| 129 | + if (keys.length !== messages.length) { |
| 130 | + throw new Error(`Unmatching keys(${keys.length}) and messages(${messages.length}).`); |
140 | 131 | } |
141 | | - else if (LocalizeInfo.is(key)) { |
142 | | - realKey = key.key; |
143 | | - if (key.comment && key.comment.length > 0) { |
144 | | - comment = key.comment.map(comment => encodeEntities(comment)).join('\r\n'); |
| 132 | + this.numberOfMessages += keys.length; |
| 133 | + this.files[original] = []; |
| 134 | + let existingKeys = new Set(); |
| 135 | + for (let i = 0; i < keys.length; i++) { |
| 136 | + let key = keys[i]; |
| 137 | + let realKey; |
| 138 | + let comment; |
| 139 | + if (Is.string(key)) { |
| 140 | + realKey = key; |
| 141 | + comment = undefined; |
| 142 | + } |
| 143 | + else if (LocalizeInfo.is(key)) { |
| 144 | + realKey = key.key; |
| 145 | + if (key.comment && key.comment.length > 0) { |
| 146 | + comment = key.comment.map(comment => encodeEntities(comment)).join('\r\n'); |
| 147 | + } |
| 148 | + } |
| 149 | + if (!realKey || existingKeys.has(realKey)) { |
| 150 | + continue; |
145 | 151 | } |
| 152 | + existingKeys.add(realKey); |
| 153 | + let message = encodeEntities(messages[i]); |
| 154 | + this.files[original].push({ id: realKey, message: message, comment: comment }); |
| 155 | + } |
| 156 | + } |
| 157 | + addStringItem(item) { |
| 158 | + if (!item.id || !item.message) { |
| 159 | + throw new Error(`No item ID or value specified: ${JSON.stringify(item)}`); |
146 | 160 | } |
147 | | - if (!realKey || existingKeys.has(realKey)) { |
148 | | - continue; |
| 161 | + this.appendNewLine(`<trans-unit id="${item.id}">`, 4); |
| 162 | + this.appendNewLine(`<source xml:lang="en">${item.message}</source>`, 6); |
| 163 | + if (item.comment) { |
| 164 | + this.appendNewLine(`<note>${item.comment}</note>`, 6); |
149 | 165 | } |
150 | | - existingKeys.add(realKey); |
151 | | - let message = encodeEntities(messages[i]); |
152 | | - this.files[original].push({ id: realKey, message: message, comment: comment }); |
| 166 | + this.appendNewLine('</trans-unit>', 4); |
153 | 167 | } |
154 | | - } |
155 | | - addStringItem(item) { |
156 | | - if (!item.id || !item.message) { |
157 | | - throw new Error(`No item ID or value specified: ${JSON.stringify(item)}`); |
| 168 | + appendHeader() { |
| 169 | + this.appendNewLine('<?xml version="1.0" encoding="utf-8"?>', 0); |
| 170 | + this.appendNewLine('<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">', 0); |
158 | 171 | } |
159 | | - this.appendNewLine(`<trans-unit id="${item.id}">`, 4); |
160 | | - this.appendNewLine(`<source xml:lang="en">${item.message}</source>`, 6); |
161 | | - if (item.comment) { |
162 | | - this.appendNewLine(`<note>${item.comment}</note>`, 6); |
| 172 | + appendFooter() { |
| 173 | + this.appendNewLine('</xliff>', 0); |
| 174 | + } |
| 175 | + appendNewLine(content, indent) { |
| 176 | + let line = new Line(indent); |
| 177 | + line.append(content); |
| 178 | + this.buffer.push(line.toString()); |
163 | 179 | } |
164 | | - this.appendNewLine('</trans-unit>', 4); |
165 | | - } |
166 | | - appendHeader() { |
167 | | - this.appendNewLine('<?xml version="1.0" encoding="utf-8"?>', 0); |
168 | | - this.appendNewLine('<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">', 0); |
169 | | - } |
170 | | - appendFooter() { |
171 | | - this.appendNewLine('</xliff>', 0); |
172 | | - } |
173 | | - appendNewLine(content, indent) { |
174 | | - let line = new Line(indent); |
175 | | - line.append(content); |
176 | | - this.buffer.push(line.toString()); |
177 | 180 | } |
178 | | -} |
179 | | -exports.XLF = XLF; |
180 | | -XLF.parsePseudo = function (xlfString) { |
181 | | - return new Promise((resolve) => { |
182 | | - let parser = new xml2js.Parser(); |
183 | | - let files = []; |
184 | | - parser.parseString(xlfString, function (_err, result) { |
185 | | - const fileNodes = result['xliff']['file']; |
186 | | - fileNodes.forEach(file => { |
187 | | - const originalFilePath = file.$.original; |
188 | | - const messages = {}; |
189 | | - const transUnits = file.body[0]['trans-unit']; |
190 | | - if (transUnits) { |
191 | | - transUnits.forEach((unit) => { |
192 | | - const key = unit.$.id; |
193 | | - const val = pseudify(unit.source[0]['_'].toString()); |
194 | | - if (key && val) { |
195 | | - messages[key] = decodeEntities(val); |
196 | | - } |
197 | | - }); |
198 | | - files.push({ messages: messages, originalFilePath: originalFilePath, language: 'ps' }); |
199 | | - } |
| 181 | + XLF.parsePseudo = function (xlfString) { |
| 182 | + return new Promise((resolve) => { |
| 183 | + let parser = new xml2js.Parser(); |
| 184 | + let files = []; |
| 185 | + parser.parseString(xlfString, function (_err, result) { |
| 186 | + const fileNodes = result['xliff']['file']; |
| 187 | + fileNodes.forEach(file => { |
| 188 | + const originalFilePath = file.$.original; |
| 189 | + const messages = {}; |
| 190 | + const transUnits = file.body[0]['trans-unit']; |
| 191 | + if (transUnits) { |
| 192 | + transUnits.forEach((unit) => { |
| 193 | + const key = unit.$.id; |
| 194 | + const val = pseudify(unit.source[0]['_'].toString()); |
| 195 | + if (key && val) { |
| 196 | + messages[key] = decodeEntities(val); |
| 197 | + } |
| 198 | + }); |
| 199 | + files.push({ messages: messages, originalFilePath: originalFilePath, language: 'ps' }); |
| 200 | + } |
| 201 | + }); |
| 202 | + resolve(files); |
200 | 203 | }); |
201 | | - resolve(files); |
202 | 204 | }); |
203 | | - }); |
204 | | -}; |
205 | | -XLF.parse = function (xlfString) { |
206 | | - return new Promise((resolve, reject) => { |
207 | | - let parser = new xml2js.Parser(); |
208 | | - let files = []; |
209 | | - parser.parseString(xlfString, function (err, result) { |
210 | | - if (err) { |
211 | | - reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`)); |
212 | | - } |
213 | | - const fileNodes = result['xliff']['file']; |
214 | | - if (!fileNodes) { |
215 | | - reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`)); |
216 | | - } |
217 | | - fileNodes.forEach((file) => { |
218 | | - const originalFilePath = file.$.original; |
219 | | - if (!originalFilePath) { |
220 | | - reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`)); |
| 205 | + }; |
| 206 | + XLF.parse = function (xlfString) { |
| 207 | + return new Promise((resolve, reject) => { |
| 208 | + let parser = new xml2js.Parser(); |
| 209 | + let files = []; |
| 210 | + parser.parseString(xlfString, function (err, result) { |
| 211 | + if (err) { |
| 212 | + reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`)); |
221 | 213 | } |
222 | | - let language = file.$['target-language']; |
223 | | - if (!language) { |
224 | | - reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`)); |
225 | | - } |
226 | | - const messages = {}; |
227 | | - const transUnits = file.body[0]['trans-unit']; |
228 | | - if (transUnits) { |
229 | | - transUnits.forEach((unit) => { |
230 | | - const key = unit.$.id; |
231 | | - if (!unit.target) { |
232 | | - return; // No translation available |
233 | | - } |
234 | | - let val = unit.target[0]; |
235 | | - if (typeof val !== 'string') { |
236 | | - val = val._; |
237 | | - } |
238 | | - if (key && val) { |
239 | | - messages[key] = decodeEntities(val); |
240 | | - } |
241 | | - else { |
242 | | - reject(new Error(`XLF parsing error: XLIFF file ${originalFilePath} does not contain full localization data. ID or target translation for one of the trans-unit nodes is not present.`)); |
243 | | - } |
244 | | - }); |
245 | | - files.push({ messages: messages, originalFilePath: originalFilePath, language: language.toLowerCase() }); |
| 214 | + const fileNodes = result['xliff']['file']; |
| 215 | + if (!fileNodes) { |
| 216 | + reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`)); |
246 | 217 | } |
| 218 | + fileNodes.forEach((file) => { |
| 219 | + const originalFilePath = file.$.original; |
| 220 | + if (!originalFilePath) { |
| 221 | + reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`)); |
| 222 | + } |
| 223 | + let language = file.$['target-language']; |
| 224 | + if (!language) { |
| 225 | + reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`)); |
| 226 | + } |
| 227 | + const messages = {}; |
| 228 | + const transUnits = file.body[0]['trans-unit']; |
| 229 | + if (transUnits) { |
| 230 | + transUnits.forEach((unit) => { |
| 231 | + const key = unit.$.id; |
| 232 | + if (!unit.target) { |
| 233 | + return; // No translation available |
| 234 | + } |
| 235 | + let val = unit.target[0]; |
| 236 | + if (typeof val !== 'string') { |
| 237 | + val = val._; |
| 238 | + } |
| 239 | + if (key && val) { |
| 240 | + messages[key] = decodeEntities(val); |
| 241 | + } |
| 242 | + else { |
| 243 | + reject(new Error(`XLF parsing error: XLIFF file ${originalFilePath} does not contain full localization data. ID or target translation for one of the trans-unit nodes is not present.`)); |
| 244 | + } |
| 245 | + }); |
| 246 | + files.push({ messages: messages, originalFilePath: originalFilePath, language: language.toLowerCase() }); |
| 247 | + } |
| 248 | + }); |
| 249 | + resolve(files); |
247 | 250 | }); |
248 | | - resolve(files); |
249 | 251 | }); |
250 | | - }); |
251 | | -}; |
| 252 | + }; |
| 253 | + return XLF; |
| 254 | +})(); |
| 255 | +exports.XLF = XLF; |
252 | 256 | class Limiter { |
253 | 257 | constructor(maxDegreeOfParalellism) { |
254 | 258 | this.maxDegreeOfParalellism = maxDegreeOfParalellism; |
|
0 commit comments