47 lines
1.6 KiB
TypeScript
47 lines
1.6 KiB
TypeScript
import { ARTICLES, PAGES, RELEASES, TAGS } from '../constants/collections'
|
|
import { createDiagnostics } from '../diagnostics'
|
|
import type { Diagnostics } from '../diagnostics/types'
|
|
import { createContentReader } from './reader'
|
|
import type { ArticleEntry, Content, PageEntry, ReleaseEntry, TagEntry } from './types'
|
|
|
|
interface CollectionReader<T> {
|
|
list(): Promise<string[]>
|
|
read(id: string): Promise<T | null>
|
|
}
|
|
|
|
function reason(error: unknown): string {
|
|
const [first, ...rest] = (error instanceof Error ? error.message : String(error)).split('\n')
|
|
return first.endsWith(':') && rest.length ? rest.join('; ') : first
|
|
}
|
|
|
|
async function readAll<T>(
|
|
reader: CollectionReader<T>,
|
|
collection: string,
|
|
problems: Diagnostics,
|
|
): Promise<Map<string, T>> {
|
|
const entries = new Map<string, T>()
|
|
await Promise.all(
|
|
(await reader.list()).map(async (id) => {
|
|
try {
|
|
const entry = await reader.read(id)
|
|
if (entry) entries.set(id, entry)
|
|
} catch (error) {
|
|
problems.error(collection, id, reason(error))
|
|
}
|
|
}),
|
|
)
|
|
return entries
|
|
}
|
|
|
|
export async function loadContent(): Promise<Content> {
|
|
const { collections } = createContentReader()
|
|
const problems = createDiagnostics()
|
|
const [articles, pages, tags, releases] = await Promise.all([
|
|
readAll<ArticleEntry>(collections.articles, ARTICLES, problems),
|
|
readAll<PageEntry>(collections.pages, PAGES, problems),
|
|
readAll<TagEntry>(collections.tags, TAGS, problems),
|
|
readAll<ReleaseEntry>(collections.releases, RELEASES, problems),
|
|
])
|
|
return { articles, pages, tags, releases, diagnostics: problems.list }
|
|
}
|