1{"version":3,"file":"XML.js","names":["writeXMLAsync","options","xml","format","fs","promises","mkdir","path","dirname","recursive","writeFile","readXMLAsync","contents","readFile","encoding","flag","parser","Parser","manifest","parseStringPromise","fallback","Array","isArray","resources","string","$","translatable","_","unescapeAndroidString","parseXMLAsync","stringTimesN","n","char","join","indentLevel","newline","EOL","xmlInput","toString","builder","Builder","headless","escapeAndroidString","buildObject","Error","indentString","formatted","regex","replace","pad","split","map","line","trim","forEach","indent","match","padding","value","m"],"sources":["../../src/utils/XML.ts"],"sourcesContent":["import fs from 'fs';\nimport { EOL } from 'os';\nimport path from 'path';\nimport { Builder, Parser } from 'xml2js';\n\nexport type XMLValue = boolean | number | string | null | XMLArray | XMLObject;\n\nexport interface XMLArray extends Array<XMLValue> {}\n\nexport interface XMLObject {\n  [key: string]: XMLValue | undefined;\n}\n\nexport async function writeXMLAsync(options: { path: string; xml: any }): Promise<void> {\n  const xml = format(options.xml);\n  await fs.promises.mkdir(path.dirname(options.path), { recursive: true });\n  await fs.promises.writeFile(options.path, xml);\n}\n\nexport async function readXMLAsync(options: {\n  path: string;\n  fallback?: string | null;\n}): Promise<XMLObject> {\n  let contents: string = '';\n  try {\n    contents = await fs.promises.readFile(options.path, { encoding: 'utf8', flag: 'r' });\n  } catch {\n    // catch and use fallback\n  }\n  const parser = new Parser();\n  const manifest = await parser.parseStringPromise(contents || options.fallback || '');\n\n  // For strings.xml\n  if (Array.isArray(manifest?.resources?.string)) {\n    for (const string of manifest?.resources?.string) {\n      if (string.$.translatable === 'false' || string.$.translatable === false) {\n        continue;\n      }\n      string._ = unescapeAndroidString(string._);\n    }\n  }\n\n  return manifest;\n}\n\nexport async function parseXMLAsync(contents: string): Promise<XMLObject> {\n  const xml = await new Parser().parseStringPromise(contents);\n  return xml;\n}\n\nconst stringTimesN = (n: number, char: string) => Array(n + 1).join(char);\n\nexport function format(manifest: any, { indentLevel = 2, newline = EOL } = {}): string {\n  let xmlInput: string;\n  if (typeof manifest === 'string') {\n    xmlInput = manifest;\n  } else if (manifest.toString) {\n    const builder = new Builder({\n      headless: true,\n    });\n\n    // For strings.xml\n    if (Array.isArray(manifest?.resources?.string)) {\n      for (const string of manifest?.resources?.string) {\n        if (string.$.translatable === 'false' || string.$.translatable === false) {\n          continue;\n        }\n        string._ = escapeAndroidString(string._);\n      }\n    }\n\n    xmlInput = builder.buildObject(manifest);\n\n    return xmlInput;\n  } else {\n    throw new Error(`Invalid XML value passed in: ${manifest}`);\n  }\n  const indentString = stringTimesN(indentLevel, ' ');\n\n  let formatted = '';\n  const regex = /(>)(<)(\\/*)/g;\n  const xml = xmlInput.replace(regex, `$1${newline}$2$3`);\n  let pad = 0;\n  xml\n    .split(/\\r?\\n/)\n    .map((line: string) => line.trim())\n    .forEach((line: string) => {\n      let indent = 0;\n      if (line.match(/.+<\\/\\w[^>]*>$/)) {\n        indent = 0;\n      } else if (line.match(/^<\\/\\w/)) {\n        if (pad !== 0) {\n          pad -= 1;\n        }\n      } else if (line.match(/^<\\w([^>]*[^/])?>.*$/)) {\n        indent = 1;\n      } else {\n        indent = 0;\n      }\n\n      const padding = stringTimesN(pad, indentString);\n      formatted += padding + line + newline;\n      pad += indent;\n    });\n\n  return formatted.trim();\n}\n\n/**\n * Escapes Android string literals, specifically characters `\"`, `'`, `\\`, `\\n`, `\\r`, `\\t`\n *\n * @param value unescaped Android XML string literal.\n */\nexport function escapeAndroidString(value: string): string {\n  value = value.replace(/[\\n\\r\\t'\"@]/g, (m) => {\n    switch (m) {\n      case '\"':\n      case \"'\":\n      case '@':\n        return '\\\\' + m;\n      case '\\n':\n        return '\\\\n';\n      case '\\r':\n        return '\\\\r';\n      case '\\t':\n        return '\\\\t';\n      default:\n        throw new Error(`Cannot escape unhandled XML character: ${m}`);\n    }\n  });\n  if (value.match(/(^\\s|\\s$)/)) {\n    value = '\"' + value + '\"';\n  }\n  return value;\n}\n\nexport function unescapeAndroidString(value: string): string {\n  return value.replace(/\\\\(.)/g, '$1');\n}\n"],"mappings":"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"}