@bliztek/feed-generator
Version:
A simple and lightweight Node.js library for generating RSS 2.0, Atom, and JSON Feed formats.
61 lines (60 loc) • 2.36 kB
JavaScript
export const escapeXml = (str) => str
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
const renderAttributes = (attrs) => {
if (!attrs)
return "";
return Object.entries(attrs)
.filter(([, v]) => v !== undefined && v !== false)
.map(([k, v]) => ` ${k}="${escapeXml(String(v))}"`)
.join("");
};
export const renderXml = (xmlNodes, depth = 0, compact = false) => {
const ind = compact ? "" : " ".repeat(depth);
const nl = compact ? "" : "\n";
return xmlNodes
.map((node) => {
var _a;
if (typeof node === "string") {
return `${ind}${node}`;
}
const attrs = renderAttributes(node.attributes);
if (node.selfClosing) {
return `${ind}<${node.tag}${attrs} />`;
}
// Leaf node with text content (single string child)
if (((_a = node.children) === null || _a === void 0 ? void 0 : _a.length) === 1 &&
typeof node.children[0] === "string") {
const text = node.children[0];
if (node.cdata) {
// Escape ]]> sequences to prevent CDATA injection
const safe = text.replace(/\]\]>/g, "]]]]><![CDATA[>");
return `${ind}<${node.tag}${attrs}><![CDATA[${safe}]]></${node.tag}>`;
}
return `${ind}<${node.tag}${attrs}>${escapeXml(text)}</${node.tag}>`;
}
// No children
if (!node.children || node.children.length === 0) {
return `${ind}<${node.tag}${attrs}></${node.tag}>`;
}
// Nested children
const inner = renderXml(node.children, depth + 1, compact);
return `${ind}<${node.tag}${attrs}>${nl}${inner}${nl}${ind}</${node.tag}>`;
})
.join(nl);
};
export const xmlDeclaration = () => `<?xml version="1.0" encoding="UTF-8"?>`;
// Helper to create a simple text element
export const el = (tag, value, opts) => value !== undefined
? {
tag,
children: [value],
cdata: opts === null || opts === void 0 ? void 0 : opts.cdata,
attributes: opts === null || opts === void 0 ? void 0 : opts.attributes,
}
: null;
// Filter out nulls from a node list
export const nodes = (...items) => items.filter((n) => n != null);