fix: transform /rssapi response shape to match /news static page

The /news page template uses item.link, item.feedId, item.sourceUrl,
and feedsRes.feeds — but the blogroll API returns item.url, item.blog.id,
item.blog.siteUrl, and {items:[...]} respectively.

Add a response-transformer middleware to the /rssapi alias router that:
- maps url -> link on each item
- maps blog.id -> feedId, blog.siteUrl -> sourceUrl on each item
- renames items -> feeds for the /api/feeds endpoint

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Sven
2026-03-13 19:16:56 +01:00
parent c4299b73b1
commit 4cde4a28ba

View File

@@ -40,13 +40,42 @@ const patchSpecs = [
Indiekit.addEndpoint(this);
// rssapi dual-mount alias: register the same public routes at /rssapi
// so the /news static page (which hardcodes /rssapi/api/*) also works
// alongside the /blogroll page (which hardcodes /blogrollapi/api/*).
// with a response-shape transformer so the /news static page works.
// The /news page expects: item.link (not .url), item.feedId (not .blog.id),
// item.sourceUrl (not .blog.siteUrl), and feedsRes.feeds (not .items).
const { Router } = require("express");
const rssapiRouter = Router();
rssapiRouter.use((req, res, next) => {
const originalJson = res.json.bind(res);
res.json = function (data) {
if (data && Array.isArray(data.items)) {
if (req.path.startsWith("/api/items")) {
// Map url->link, blog.id->feedId, blog.siteUrl->sourceUrl
data = {
...data,
items: data.items.map((item) => ({
...item,
link: item.url,
feedId: item.blog?.id ?? null,
sourceUrl: item.blog?.siteUrl ?? null,
})),
};
} else if (req.path === "/api/feeds") {
// Rename items->feeds so feedsRes.feeds resolves correctly
const { items, ...rest } = data;
data = { ...rest, feeds: items };
}
}
return originalJson(data);
};
next();
});
rssapiRouter.use(publicRouter);
Indiekit.addEndpoint({
name: "Blogroll /rssapi alias",
mountPath: "/rssapi",
get routesPublic() {
return publicRouter;
return rssapiRouter;
},
});`,
},