{
  "version": 3,
  "sources": ["../../src/file/json2xml.ts"],
  "sourcesContent": ["/**\n * Character map for XML escaping to prevent XML injection attacks.\n */\nconst XML_ESCAPE_MAP: Record<string, string> = {\n  '&': '&amp;',\n  '<': '&lt;',\n  '>': '&gt;',\n  '\"': '&quot;',\n  \"'\": '&apos;',\n}\n\n/**\n * Escapes special XML characters to prevent injection attacks.\n */\nfunction escapeXml(str: string): string {\n  return str.replace(/[&<>\"']/g, (char) => XML_ESCAPE_MAP[char] ?? char)\n}\n\n/**\n * This function converts an object to XML.\n * Values are automatically escaped to prevent XML injection attacks.\n */\nexport function json2xml(\n  data: Record<string, any>,\n  options: {\n    indent?: string\n    format?: boolean\n    xmlDeclaration?: boolean\n  } = {},\n) {\n  const { indent = '  ', format = true, xmlDeclaration = true } = options\n\n  const toXml = (value: any, key: string, currentIndent: string): string => {\n    let xml = ''\n\n    if (Array.isArray(value)) {\n      for (let i = 0, n = value.length; i < n; i++) {\n        xml += toXml(value[i], key, currentIndent)\n      }\n    } else if (typeof value === 'object' && value !== null) {\n      let hasChild = false\n      let attributes = ''\n      let children = ''\n\n      // Handle attributes (keys starting with @)\n      for (const attr in value) {\n        if (attr.charAt(0) === '@') {\n          attributes += ' ' + attr.substr(1) + '=\"' + escapeXml(value[attr].toString()) + '\"'\n        }\n      }\n\n      // Handle children and special content\n      for (const child in value) {\n        if (child === '#text') {\n          children += escapeXml(value[child]?.toString() ?? '')\n        } else if (child === '#cdata') {\n          // Escape ]]> sequences to prevent CDATA injection\n          const cdataContent = value[child]?.toString() ?? ''\n          children += '<![CDATA[' + cdataContent.replace(/]]>/g, ']]]]><![CDATA[>') + ']]>'\n        } else if (child.charAt(0) !== '@') {\n          hasChild = true\n          children += toXml(value[child], child, currentIndent + indent)\n        }\n      }\n\n      if (hasChild || children) {\n        xml += currentIndent + '<' + key + attributes + '>\\n'\n        xml += children\n        xml += currentIndent + '</' + key + '>\\n'\n      } else {\n        xml += currentIndent + '<' + key + attributes + '/>\\n'\n      }\n    } else {\n      xml += currentIndent + '<' + key + '>' + escapeXml(value?.toString() || '') + '</' + key + '>\\n'\n    }\n\n    return xml\n  }\n\n  let xml = ''\n\n  // Add XML declaration if requested\n  if (xmlDeclaration) {\n    xml += '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'\n    if (format) {\n      xml += '\\n'\n    }\n  }\n\n  // Convert data to XML\n  for (const key in data) {\n    if (Object.hasOwn(data, key)) {\n      xml += toXml(data[key], key, '')\n    }\n  }\n\n  // Format or compact the output\n  if (format) {\n    return xml.trim()\n  }\n\n  // Remove all newlines and extra spaces, but keep the XML declaration clean\n  return xml.replace(/\\n/g, '').replace(/>\\s+</g, '><').trim()\n}\n"],
  "mappings": "AAGA,MAAM,iBAAyC;AAAA,EAC7C,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAKA,SAAS,UAAU,KAAqB;AACtC,SAAO,IAAI,QAAQ,YAAY,CAAC,SAAS,eAAe,IAAI,KAAK,IAAI;AACvE;AAMO,SAAS,SACd,MACA,UAII,CAAC,GACL;AACA,QAAM,EAAE,SAAS,MAAM,SAAS,MAAM,iBAAiB,KAAK,IAAI;AAEhE,QAAM,QAAQ,CAAC,OAAY,KAAa,kBAAkC;AACxE,QAAIA,OAAM;AAEV,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,IAAI,GAAG,KAAK;AAC5C,QAAAA,QAAO,MAAM,MAAM,CAAC,GAAG,KAAK,aAAa;AAAA,MAC3C;AAAA,IACF,WAAW,OAAO,UAAU,YAAY,UAAU,MAAM;AACtD,UAAI,WAAW;AACf,UAAI,aAAa;AACjB,UAAI,WAAW;AAGf,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,OAAO,CAAC,MAAM,KAAK;AAC1B,wBAAc,MAAM,KAAK,OAAO,CAAC,IAAI,OAAO,UAAU,MAAM,IAAI,EAAE,SAAS,CAAC,IAAI;AAAA,QAClF;AAAA,MACF;AAGA,iBAAW,SAAS,OAAO;AACzB,YAAI,UAAU,SAAS;AACrB,sBAAY,UAAU,MAAM,KAAK,GAAG,SAAS,KAAK,EAAE;AAAA,QACtD,WAAW,UAAU,UAAU;AAE7B,gBAAM,eAAe,MAAM,KAAK,GAAG,SAAS,KAAK;AACjD,sBAAY,cAAc,aAAa,QAAQ,QAAQ,iBAAiB,IAAI;AAAA,QAC9E,WAAW,MAAM,OAAO,CAAC,MAAM,KAAK;AAClC,qBAAW;AACX,sBAAY,MAAM,MAAM,KAAK,GAAG,OAAO,gBAAgB,MAAM;AAAA,QAC/D;AAAA,MACF;AAEA,UAAI,YAAY,UAAU;AACxB,QAAAA,QAAO,gBAAgB,MAAM,MAAM,aAAa;AAChD,QAAAA,QAAO;AACP,QAAAA,QAAO,gBAAgB,OAAO,MAAM;AAAA,MACtC,OAAO;AACL,QAAAA,QAAO,gBAAgB,MAAM,MAAM,aAAa;AAAA,MAClD;AAAA,IACF,OAAO;AACL,MAAAA,QAAO,gBAAgB,MAAM,MAAM,MAAM,UAAU,OAAO,SAAS,KAAK,EAAE,IAAI,OAAO,MAAM;AAAA,IAC7F;AAEA,WAAOA;AAAA,EACT;AAEA,MAAI,MAAM;AAGV,MAAI,gBAAgB;AAClB,WAAO;AACP,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAGA,aAAW,OAAO,MAAM;AACtB,QAAI,OAAO,OAAO,MAAM,GAAG,GAAG;AAC5B,aAAO,MAAM,KAAK,GAAG,GAAG,KAAK,EAAE;AAAA,IACjC;AAAA,EACF;AAGA,MAAI,QAAQ;AACV,WAAO,IAAI,KAAK;AAAA,EAClB;AAGA,SAAO,IAAI,QAAQ,OAAO,EAAE,EAAE,QAAQ,UAAU,IAAI,EAAE,KAAK;AAC7D;",
  "names": ["xml"]
}
