app-template/packages/seo-geo/src/sitemap.ts

45 lines
1.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { SitemapStream, streamToPromise } from "sitemap";
import { absoluteUrl, normalizeSiteUrl } from "./url.js";
import type { SitemapEntry, SiteSeoConfig } from "./types.js";
/**
* 生成 sitemap.xml 字符串(走官方 `sitemap` 包流式序列化)。
* 异步:stream 需 `streamToPromise` 冲刷。
*/
export async function buildSitemapXml(
site: Pick<SiteSeoConfig, "siteUrl">,
entries: SitemapEntry[],
): Promise<string> {
const stream = new SitemapStream({
hostname: normalizeSiteUrl(site.siteUrl),
});
const done = streamToPromise(stream);
for (const e of entries) {
stream.write({
url: absoluteUrl(site.siteUrl, e.url),
...(e.lastmod ? { lastmod: e.lastmod } : {}),
...(e.changefreq ? { changefreq: e.changefreq } : {}),
...(e.priority !== undefined ? { priority: Math.min(1, Math.max(0, e.priority)) } : {}),
...(e.alternates?.length
? {
links: e.alternates.map((alt) => ({
url: absoluteUrl(site.siteUrl, alt.href),
lang: alt.hreflang,
})),
}
: {}),
});
}
stream.end();
const xml = await done;
return String(xml);
}
/** 常用:从路径列表生成 entry(默认 priority/changefreq 可覆盖)。 */
export function pathsToEntries(paths: string[], defaults?: Partial<SitemapEntry>): SitemapEntry[] {
return paths.map((p) => {
const { url: _u, ...rest } = defaults ?? {};
return { ...rest, url: p };
});
}