@bliztek/feed-generator
Version:
A simple and lightweight Node.js library for generating RSS 2.0, Atom, and JSON Feed formats.
106 lines (105 loc) • 5.72 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateRSSFeed = void 0;
const generateRSSFeed = (feedData) => {
const { title, link, description, language, image, copyright, lastBuildDate, generator = "Bliztek RSS Generator", docs, managingEditor, webMaster, category, cloud, ttl, skipHours, skipDays, items = [], feedLinks, } = feedData;
// Validate required fields
if (!title || !description || !link) {
throw new Error("Invalid feed data: title, description, and link are required.");
}
// Helper to generate optional tags
const generateOptionalTag = (tag, value) => value ? `\t\t<${tag}>${value}</${tag}>` : "";
// Generate <image> if provided
const generateImage = (image, channelTitle) => image
? `\t\t<image>
\t\t<url>${image.url}</url>
\t\t\t<title>${channelTitle}</title>
\t\t\t<link>${image.link || ""}</link>
${image.width ? `\t\t\t<width>${image.width}</width>` : ""}
${image.height ? `\t\t\t<height>${image.height}</height>` : ""}
${image.description
? `\t\t\t<description>${image.description}</description>`
: ""}
\t\t</image>`
: "";
// Generate categories
const generateCategories = (categories) => {
if (!categories || categories.length === 0)
return "";
return categories
.map((cat) => `\t\t<category${cat.domain ? ` domain="${cat.domain}"` : ""}>${cat.value}</category>`)
.join("");
};
// Generate items
const generateItems = (items) => items
.map((item) => {
var _a, _b, _c, _d, _e, _f;
const itemParts = [
`\t\t<item>`,
`\t<title>${((_a = item.title) === null || _a === void 0 ? void 0 : _a.trim()) || "Untitled"}</title>`,
`\t<link>${((_b = item.link) === null || _b === void 0 ? void 0 : _b.trim()) || ""}</link>`,
`\t<guid isPermaLink="${item.link ? "true" : "false"}">${((_d = (_c = item.guid) === null || _c === void 0 ? void 0 : _c.value) === null || _d === void 0 ? void 0 : _d.trim()) || ((_e = item.link) === null || _e === void 0 ? void 0 : _e.trim()) || ""}</guid>`,
`\t${generateOptionalTag("description", item.description
? `<![CDATA[${item.description.trim()}]]>`
: undefined)}`,
item.enclosure
? `\t<enclosure url="${item.enclosure.url.trim()}" type="${item.enclosure.type.trim()}" length="${item.enclosure.length}" />`
: "",
`\t<pubDate>${new Date(item.pubDate || lastBuildDate || new Date()).toUTCString()}</pubDate>`,
`\t${generateOptionalTag("comments", (_f = item.comments) === null || _f === void 0 ? void 0 : _f.trim())}`,
item.author ? `\t<author>${item.author.trim()}</author>` : "",
`\t${generateCategories(item.category)}`,
`</item>`,
];
// Filter empty parts and join
return itemParts.filter((part) => part.trim()).join("\n\t\t");
})
.join("\t\n");
const selfLink = (feedLinks === null || feedLinks === void 0 ? void 0 : feedLinks.atom) || `${link}/atom.xml`;
const atomLink = `\t\t<atom:link href="${selfLink}" rel="self" type="application/atom+xml" />`;
// Assembling the feed dynamically
const feedParts = [
`<?xml version="1.0" encoding="UTF-8"?>`,
`<rss version="2.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/">`,
`\t<channel>`,
`\t\t<title>${title.trim()}</title>`,
`\t\t<link>${link.trim()}</link>`,
`\t\t<description>${description.trim()}</description>`,
generateOptionalTag("language", language === null || language === void 0 ? void 0 : language.trim()),
generateImage(image, title),
generateOptionalTag("copyright", copyright === null || copyright === void 0 ? void 0 : copyright.trim()),
generateOptionalTag("lastBuildDate", lastBuildDate === null || lastBuildDate === void 0 ? void 0 : lastBuildDate.trim()),
generateOptionalTag("generator", generator === null || generator === void 0 ? void 0 : generator.trim()),
generateOptionalTag("docs", docs === null || docs === void 0 ? void 0 : docs.trim()),
generateOptionalTag("managingEditor", managingEditor === null || managingEditor === void 0 ? void 0 : managingEditor.trim()),
generateOptionalTag("webMaster", webMaster === null || webMaster === void 0 ? void 0 : webMaster.trim()),
generateCategories(category || []),
generateOptionalTag("ttl", ttl ? ttl.toString().trim() : undefined),
cloud
? `\t\t<cloud domain="${cloud.domain.trim()}" port="${cloud.port}" path="${cloud.path.trim()}" registerProcedure="${cloud.registerProcedure.trim()}" protocol="${cloud.protocol.trim()}" />`
: "",
(skipHours === null || skipHours === void 0 ? void 0 : skipHours.length)
? `\t\t<skipHours>${skipHours
.map((hour) => `<hour>${hour}</hour>`)
.join("")}</skipHours>`
: "",
(skipDays === null || skipDays === void 0 ? void 0 : skipDays.length)
? `\t\t<skipDays>${skipDays
.map((day) => `<day>${day}</day>`)
.join("")}</skipDays>`
: "",
atomLink,
generateItems(items),
`\t</channel>`,
`</rss>`,
];
// Join non-empty parts, ensuring no extra lines
return feedParts
.filter((part) => part.trim())
.join("\n")
.trim();
};
exports.generateRSSFeed = generateRSSFeed;