1082815dcSEvan Bacon"use strict"; 2082815dcSEvan Bacon 3082815dcSEvan BaconObject.defineProperty(exports, "__esModule", { 4082815dcSEvan Bacon value: true 5082815dcSEvan Bacon}); 6*ed3bd27bSEvan Baconexports._processAndroidXML = _processAndroidXML; 7082815dcSEvan Baconexports.escapeAndroidString = escapeAndroidString; 8082815dcSEvan Baconexports.format = format; 9082815dcSEvan Baconexports.parseXMLAsync = parseXMLAsync; 10082815dcSEvan Baconexports.readXMLAsync = readXMLAsync; 11082815dcSEvan Baconexports.unescapeAndroidString = unescapeAndroidString; 12082815dcSEvan Baconexports.writeXMLAsync = writeXMLAsync; 13082815dcSEvan Baconfunction _fs() { 14082815dcSEvan Bacon const data = _interopRequireDefault(require("fs")); 15082815dcSEvan Bacon _fs = function () { 16082815dcSEvan Bacon return data; 17082815dcSEvan Bacon }; 18082815dcSEvan Bacon return data; 19082815dcSEvan Bacon} 20082815dcSEvan Baconfunction _os() { 21082815dcSEvan Bacon const data = require("os"); 22082815dcSEvan Bacon _os = function () { 23082815dcSEvan Bacon return data; 24082815dcSEvan Bacon }; 25082815dcSEvan Bacon return data; 26082815dcSEvan Bacon} 27082815dcSEvan Baconfunction _path() { 28082815dcSEvan Bacon const data = _interopRequireDefault(require("path")); 29082815dcSEvan Bacon _path = function () { 30082815dcSEvan Bacon return data; 31082815dcSEvan Bacon }; 32082815dcSEvan Bacon return data; 33082815dcSEvan Bacon} 34082815dcSEvan Baconfunction _xml2js() { 35082815dcSEvan Bacon const data = require("xml2js"); 36082815dcSEvan Bacon _xml2js = function () { 37082815dcSEvan Bacon return data; 38082815dcSEvan Bacon }; 39082815dcSEvan Bacon return data; 40082815dcSEvan Bacon} 41082815dcSEvan Baconfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 42082815dcSEvan Baconasync function writeXMLAsync(options) { 43082815dcSEvan Bacon const xml = format(options.xml); 44082815dcSEvan Bacon await _fs().default.promises.mkdir(_path().default.dirname(options.path), { 45082815dcSEvan Bacon recursive: true 46082815dcSEvan Bacon }); 47082815dcSEvan Bacon await _fs().default.promises.writeFile(options.path, xml); 48082815dcSEvan Bacon} 49082815dcSEvan Baconasync function readXMLAsync(options) { 50082815dcSEvan Bacon let contents = ''; 51082815dcSEvan Bacon try { 52082815dcSEvan Bacon contents = await _fs().default.promises.readFile(options.path, { 53082815dcSEvan Bacon encoding: 'utf8', 54082815dcSEvan Bacon flag: 'r' 55082815dcSEvan Bacon }); 56ee216927STomasz Sapeta } catch { 57ee216927STomasz Sapeta // catch and use fallback 58082815dcSEvan Bacon } 59082815dcSEvan Bacon const parser = new (_xml2js().Parser)(); 60ee216927STomasz Sapeta const manifest = await parser.parseStringPromise(contents || options.fallback || ''); 61*ed3bd27bSEvan Bacon return _processAndroidXML(manifest); 62*ed3bd27bSEvan Bacon} 63*ed3bd27bSEvan Baconfunction _processAndroidXML(manifest) { 64*ed3bd27bSEvan Bacon var _manifest$resources; 65ee216927STomasz Sapeta // For strings.xml 66082815dcSEvan Bacon if (Array.isArray(manifest === null || manifest === void 0 ? void 0 : (_manifest$resources = manifest.resources) === null || _manifest$resources === void 0 ? void 0 : _manifest$resources.string)) { 67082815dcSEvan Bacon for (const string of manifest === null || manifest === void 0 ? void 0 : (_manifest$resources2 = manifest.resources) === null || _manifest$resources2 === void 0 ? void 0 : _manifest$resources2.string) { 68082815dcSEvan Bacon var _manifest$resources2; 69082815dcSEvan Bacon if (string.$.translatable === 'false' || string.$.translatable === false) { 70082815dcSEvan Bacon continue; 71082815dcSEvan Bacon } 72082815dcSEvan Bacon string._ = unescapeAndroidString(string._); 73082815dcSEvan Bacon } 74082815dcSEvan Bacon } 75082815dcSEvan Bacon return manifest; 76082815dcSEvan Bacon} 77082815dcSEvan Baconasync function parseXMLAsync(contents) { 78082815dcSEvan Bacon const xml = await new (_xml2js().Parser)().parseStringPromise(contents); 79082815dcSEvan Bacon return xml; 80082815dcSEvan Bacon} 81082815dcSEvan Baconconst stringTimesN = (n, char) => Array(n + 1).join(char); 82082815dcSEvan Baconfunction format(manifest, { 83082815dcSEvan Bacon indentLevel = 2, 84082815dcSEvan Bacon newline = _os().EOL 85082815dcSEvan Bacon} = {}) { 86082815dcSEvan Bacon let xmlInput; 87082815dcSEvan Bacon if (typeof manifest === 'string') { 88082815dcSEvan Bacon xmlInput = manifest; 89082815dcSEvan Bacon } else if (manifest.toString) { 90082815dcSEvan Bacon var _manifest$resources3; 91082815dcSEvan Bacon const builder = new (_xml2js().Builder)({ 92082815dcSEvan Bacon headless: true 93ee216927STomasz Sapeta }); 94082815dcSEvan Bacon 95ee216927STomasz Sapeta // For strings.xml 96082815dcSEvan Bacon if (Array.isArray(manifest === null || manifest === void 0 ? void 0 : (_manifest$resources3 = manifest.resources) === null || _manifest$resources3 === void 0 ? void 0 : _manifest$resources3.string)) { 97082815dcSEvan Bacon for (const string of manifest === null || manifest === void 0 ? void 0 : (_manifest$resources4 = manifest.resources) === null || _manifest$resources4 === void 0 ? void 0 : _manifest$resources4.string) { 98082815dcSEvan Bacon var _manifest$resources4; 99082815dcSEvan Bacon if (string.$.translatable === 'false' || string.$.translatable === false) { 100082815dcSEvan Bacon continue; 101082815dcSEvan Bacon } 102082815dcSEvan Bacon string._ = escapeAndroidString(string._); 103082815dcSEvan Bacon } 104082815dcSEvan Bacon } 105082815dcSEvan Bacon xmlInput = builder.buildObject(manifest); 106082815dcSEvan Bacon return xmlInput; 107082815dcSEvan Bacon } else { 108082815dcSEvan Bacon throw new Error(`Invalid XML value passed in: ${manifest}`); 109082815dcSEvan Bacon } 110082815dcSEvan Bacon const indentString = stringTimesN(indentLevel, ' '); 111082815dcSEvan Bacon let formatted = ''; 112082815dcSEvan Bacon const regex = /(>)(<)(\/*)/g; 113082815dcSEvan Bacon const xml = xmlInput.replace(regex, `$1${newline}$2$3`); 114082815dcSEvan Bacon let pad = 0; 115082815dcSEvan Bacon xml.split(/\r?\n/).map(line => line.trim()).forEach(line => { 116082815dcSEvan Bacon let indent = 0; 117082815dcSEvan Bacon if (line.match(/.+<\/\w[^>]*>$/)) { 118082815dcSEvan Bacon indent = 0; 119082815dcSEvan Bacon } else if (line.match(/^<\/\w/)) { 120082815dcSEvan Bacon if (pad !== 0) { 121082815dcSEvan Bacon pad -= 1; 122082815dcSEvan Bacon } 123082815dcSEvan Bacon } else if (line.match(/^<\w([^>]*[^/])?>.*$/)) { 124082815dcSEvan Bacon indent = 1; 125082815dcSEvan Bacon } else { 126082815dcSEvan Bacon indent = 0; 127082815dcSEvan Bacon } 128082815dcSEvan Bacon const padding = stringTimesN(pad, indentString); 129082815dcSEvan Bacon formatted += padding + line + newline; 130082815dcSEvan Bacon pad += indent; 131082815dcSEvan Bacon }); 132082815dcSEvan Bacon return formatted.trim(); 133082815dcSEvan Bacon} 134ee216927STomasz Sapeta 135082815dcSEvan Bacon/** 136082815dcSEvan Bacon * Escapes Android string literals, specifically characters `"`, `'`, `\`, `\n`, `\r`, `\t` 137082815dcSEvan Bacon * 138082815dcSEvan Bacon * @param value unescaped Android XML string literal. 139082815dcSEvan Bacon */ 140082815dcSEvan Baconfunction escapeAndroidString(value) { 141082815dcSEvan Bacon value = value.replace(/[\n\r\t'"@]/g, m => { 142082815dcSEvan Bacon switch (m) { 143082815dcSEvan Bacon case '"': 144082815dcSEvan Bacon case "'": 145082815dcSEvan Bacon case '@': 146082815dcSEvan Bacon return '\\' + m; 147082815dcSEvan Bacon case '\n': 148082815dcSEvan Bacon return '\\n'; 149082815dcSEvan Bacon case '\r': 150082815dcSEvan Bacon return '\\r'; 151082815dcSEvan Bacon case '\t': 152082815dcSEvan Bacon return '\\t'; 153082815dcSEvan Bacon default: 154082815dcSEvan Bacon throw new Error(`Cannot escape unhandled XML character: ${m}`); 155082815dcSEvan Bacon } 156082815dcSEvan Bacon }); 157082815dcSEvan Bacon if (value.match(/(^\s|\s$)/)) { 158082815dcSEvan Bacon value = '"' + value + '"'; 159082815dcSEvan Bacon } 160082815dcSEvan Bacon return value; 161082815dcSEvan Bacon} 162082815dcSEvan Baconfunction unescapeAndroidString(value) { 163082815dcSEvan Bacon return value.replace(/\\(.)/g, '$1'); 164082815dcSEvan Bacon} 165082815dcSEvan Bacon//# sourceMappingURL=XML.js.map