mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
120 lines
3.4 KiB
TypeScript
120 lines
3.4 KiB
TypeScript
import { getCollection } from 'astro:content';
|
|
|
|
import { BLOG_PAGE_SIZE } from '@/consts';
|
|
import { SUPPORTED_FRAMEWORKS, type SupportedFramework } from '@/types/docs';
|
|
import { filterSidebar, getAllGuideSlugs } from '@/utils/docs/sidebar';
|
|
import { getDocTitle } from '@/utils/docs/title';
|
|
import { normalizeSitePath } from '@/utils/og/normalize-site-path';
|
|
|
|
const STATIC_PAGES: { path: string; title: string }[] = [
|
|
{ path: 'index', title: 'The open source player for the web' },
|
|
{ path: 'support', title: 'Support' },
|
|
{ path: 'privacy', title: 'Privacy' },
|
|
{ path: 'blog', title: 'Blog' },
|
|
];
|
|
|
|
export type OgTitleEntryKind = 'static' | 'blog' | 'blog-index' | 'author' | 'docs';
|
|
export type OgTitleSource = 'static' | 'title' | 'ogTitle' | 'frameworkTitle' | 'name';
|
|
|
|
export interface OgTitleEntry {
|
|
kind: OgTitleEntryKind;
|
|
path: string;
|
|
title: string;
|
|
source: OgTitleSource;
|
|
collectionId?: string;
|
|
framework?: SupportedFramework;
|
|
}
|
|
|
|
export async function listOgTitleEntries(): Promise<OgTitleEntry[]> {
|
|
const entries: OgTitleEntry[] = [];
|
|
|
|
for (const { path, title } of STATIC_PAGES) {
|
|
entries.push({
|
|
kind: path === 'blog' ? 'blog-index' : 'static',
|
|
path,
|
|
title,
|
|
source: 'static',
|
|
});
|
|
}
|
|
|
|
const blogPosts = (await getCollection('blog')).filter((post) => !post.data.devOnly || import.meta.env.DEV);
|
|
|
|
for (const post of blogPosts) {
|
|
entries.push({
|
|
kind: 'blog',
|
|
path: `blog/${post.id}`,
|
|
title: post.data.ogTitle ?? post.data.title,
|
|
source: post.data.ogTitle ? 'ogTitle' : 'title',
|
|
collectionId: post.id,
|
|
});
|
|
}
|
|
|
|
const totalBlogPages = Math.ceil(blogPosts.length / BLOG_PAGE_SIZE);
|
|
|
|
for (let page = 2; page <= totalBlogPages; page += 1) {
|
|
entries.push({
|
|
kind: 'blog-index',
|
|
path: `blog/${page}`,
|
|
title: 'Blog',
|
|
source: 'static',
|
|
});
|
|
}
|
|
|
|
const authors = await getCollection('authors');
|
|
|
|
for (const author of authors) {
|
|
entries.push({
|
|
kind: 'author',
|
|
path: `blog/authors/${author.id}`,
|
|
title: author.data.name,
|
|
source: 'name',
|
|
collectionId: author.id,
|
|
});
|
|
}
|
|
|
|
const docsCollection = await getCollection('docs');
|
|
|
|
for (const framework of SUPPORTED_FRAMEWORKS) {
|
|
const allowedSlugs = new Set(getAllGuideSlugs(filterSidebar(framework)));
|
|
|
|
for (const doc of docsCollection) {
|
|
if (!allowedSlugs.has(doc.id)) {
|
|
continue;
|
|
}
|
|
|
|
const frameworkTitle = doc.data.frameworkTitle?.[framework];
|
|
|
|
entries.push({
|
|
kind: 'docs',
|
|
path: `docs/framework/${framework}/${doc.id}`,
|
|
title: doc.data.ogTitle ?? getDocTitle(doc, framework),
|
|
source: doc.data.ogTitle ? 'ogTitle' : frameworkTitle ? 'frameworkTitle' : 'title',
|
|
collectionId: doc.id,
|
|
framework,
|
|
});
|
|
}
|
|
}
|
|
|
|
return entries;
|
|
}
|
|
|
|
export async function buildOgTitleMap(): Promise<Map<string, string>> {
|
|
const titleMap = new Map<string, string>();
|
|
|
|
for (const entry of await listOgTitleEntries()) {
|
|
const normalizedPath = normalizeSitePath(entry.path);
|
|
const existingTitle = titleMap.get(normalizedPath);
|
|
|
|
if (existingTitle && existingTitle !== entry.title) {
|
|
throw new Error(
|
|
`Duplicate OG image path "${normalizedPath}" maps to multiple titles: ` +
|
|
`"${existingTitle}" and "${entry.title}".`
|
|
);
|
|
}
|
|
|
|
titleMap.set(normalizedPath, entry.title);
|
|
}
|
|
|
|
return titleMap;
|
|
}
|