| 15268 | } |
| 15269 | |
| 15270 | function recur(tagName: string, node: StringTree, depth: number, originalNameForMeta?: string): void { |
| 15271 | const { attrs, safe } = xml.tagInfo(tagName, originalNameForMeta) |
| 15272 | |
| 15273 | if (node === undefined) { |
| 15274 | push(depth, `<${safe}${attrs}/>`) |
| 15275 | } else if (typeof node === "string") { |
| 15276 | push(depth, `<${safe}${attrs}>${xml.escapeText(node)}</${safe}>`) |
| 15277 | } else if (typeof node !== "object" || node === null) { |
| 15278 | push(depth, `<${safe}${attrs}>${xml.escapeText(format(node))}</${safe}>`) |
| 15279 | } else { |
| 15280 | if (seen.has(node)) throw new globalThis.Error("Cycle detected while serializing to XML.", { cause: node }) |
| 15281 | seen.add(node) |
| 15282 | try { |
| 15283 | if (globalThis.globalThis.Array.isArray(node)) { |
| 15284 | if (node.length === 0) { |
| 15285 | push(depth, `<${safe}${attrs}/>`) |
| 15286 | return |
| 15287 | } |
| 15288 | push(depth, `<${safe}${attrs}>`) |
| 15289 | for (const item of node) recur(arrayItemName, item, depth + 1) |
| 15290 | push(depth, `</${safe}>`) |
| 15291 | return |
| 15292 | } |
| 15293 | |
| 15294 | const obj = node as Record<string, StringTree> |
| 15295 | const keys = Object.keys(obj) |
| 15296 | if (sortKeys) keys.sort() |
| 15297 | |
| 15298 | if (keys.length === 0) { |
| 15299 | push(depth, `<${safe}${attrs}/>`) |
| 15300 | return |
| 15301 | } |
| 15302 | |
| 15303 | push(depth, `<${safe}${attrs}>`) |
| 15304 | for (const k of keys) { |
| 15305 | recur(xml.parseTagName(k).safe, obj[k], depth + 1, k) |
| 15306 | } |
| 15307 | push(depth, `</${safe}>`) |
| 15308 | } finally { |
| 15309 | seen.delete(node) |
| 15310 | } |
| 15311 | } |
| 15312 | } |
| 15313 | } |
| 15314 | |
| 15315 | const xml = { |