mirror of
https://github.com/svemagie/indiekit-endpoint-microsub.git
synced 2026-04-02 15:35:00 +02:00
Restores complete implementation from feat/endpoint-microsub branch: - Reader UI with views (reader.njk, channel.njk, feeds.njk, etc.) - Feed polling, parsing, and normalization - WebSub subscriber - SSE realtime updates - Redis caching - Search indexing - Media proxy - Webmention processing
62 lines
1.5 KiB
JavaScript
62 lines
1.5 KiB
JavaScript
/**
|
|
* Atom feed parser
|
|
* @module feeds/atom
|
|
*/
|
|
|
|
import { Readable } from "node:stream";
|
|
|
|
import FeedParser from "feedparser";
|
|
|
|
import { normalizeItem, normalizeFeedMeta } from "./normalizer.js";
|
|
|
|
/**
|
|
* Parse Atom feed content
|
|
* @param {string} content - Atom XML content
|
|
* @param {string} feedUrl - URL of the feed
|
|
* @returns {Promise<object>} Parsed feed with metadata and items
|
|
*/
|
|
export async function parseAtom(content, feedUrl) {
|
|
return new Promise((resolve, reject) => {
|
|
const feedparser = new FeedParser({ feedurl: feedUrl });
|
|
const items = [];
|
|
let meta;
|
|
|
|
feedparser.on("error", (error) => {
|
|
reject(new Error(`Atom parse error: ${error.message}`));
|
|
});
|
|
|
|
feedparser.on("meta", (feedMeta) => {
|
|
meta = feedMeta;
|
|
});
|
|
|
|
feedparser.on("readable", function () {
|
|
let item;
|
|
while ((item = this.read())) {
|
|
items.push(item);
|
|
}
|
|
});
|
|
|
|
feedparser.on("end", () => {
|
|
try {
|
|
const normalizedMeta = normalizeFeedMeta(meta, feedUrl);
|
|
const normalizedItems = items.map((item) =>
|
|
normalizeItem(item, feedUrl, "atom"),
|
|
);
|
|
|
|
resolve({
|
|
type: "feed",
|
|
url: feedUrl,
|
|
...normalizedMeta,
|
|
items: normalizedItems,
|
|
});
|
|
} catch (error) {
|
|
reject(error);
|
|
}
|
|
});
|
|
|
|
// Create readable stream from string and pipe to feedparser
|
|
const stream = Readable.from([content]);
|
|
stream.pipe(feedparser);
|
|
});
|
|
}
|