Files
JiboViteDocs/node_modules/@lando/vitepress-theme-default-plus/node/generate-feeds.js

95 lines
2.9 KiB
JavaScript
Raw Normal View History

2026-05-03 12:12:57 -04:00
import {writeFileSync} from 'node:fs';
import {join} from 'node:path';
import {default as createContentLoader} from '../utils/create-content-loader.js';
import Debug from 'debug';
import {Feed} from 'feed';
const normalizeUrl = url => url.replace(/([^:]\/)\/+/g, '$1');
// helper to normalize things
const normalizeConfig = (config = {}, feed = 'feed') => {
// pluralize
if (!config.patterns && config.pattern) {
config.patterns = config.pattern;
delete config.pattern;
}
// arrayize
if (typeof config.patterns === 'string') config.patterns = [config.patterns];
// set filename if it isnt set
if (!config.file) config.file = `/${feed}.rss`;
// add the feed name just for the hell of it?
config.name = feed;
return config;
};
const sort = items => items.sort((a, b) => a.timestamp < b.timestamp ? 1 : -1);
export default async function(siteConfig, {debug = Debug('@lando/generate-feeds')} = {}) { // eslint-disable-line
const {userConfig, site, outDir} = siteConfig;
// get config from priority sources
const config = userConfig.feeds
|| userConfig?.themeConfig?.feeds
|| userConfig.feed
|| userConfig?.themeConfig?.feed;
// if feeds is false or undefined then just end it all right here
if (!config) return;
// if feeds has only one top level feed then bump it down
const feeds = (config.patterns || config.pattern) ? {feed: config} : config;
// loop through and generate feedzzz
await Promise.all(Object.entries(feeds).map(async ([name, config]) => {
config = normalizeConfig(config, name);
const {href} = new URL(site.base ?? '/', config.baseUrl ?? userConfig.baseUrl);
const feed = new Feed({
title: config.title ?? site.title ?? '',
description: config.description ?? config.description ?? '',
id: normalizeUrl(config.id ?? href),
link: normalizeUrl(config.link ?? href),
language: config.language ?? 'en',
image: config.image ?? '',
favicon: normalizeUrl(config.favicon ?? `${href}/favicon.ico`),
copyright: config.copyright ?? '',
});
// get items
const items = await createContentLoader(config.patterns, {excerpt: true, render: true, siteConfig}, {debug}).load();
// and loop theough them to add
for (const item of sort(items)) {
const {authors, timestamp, excerpt, html, summary, title, url} = item;
// initial payload
const data = {
title,
id: normalizeUrl(`${href}${url}`),
link: normalizeUrl(`${href}${url}`),
description: excerpt !== '' ? excerpt : summary,
content: html,
date: new Date(timestamp),
};
// add authors if we have them
if (authors && Array.isArray(authors)) data.authors = authors.map(({name, link}) => ({name, link}));
// SHE ALWAYS NEEDS TO FEED
feed.addItem(data);
}
// write feed
const dest = join(outDir, config.file);
writeFileSync(dest, feed.rss2());
debug('generated rss feed %o', dest);
}));
}