main
 1import type { CollectionEntry } from "astro:content";
 2import type { AstroComponentFactory } from "astro/runtime/server/index.js";
 3
 4import { DEFAULT_LOCALE } from "@/config.ts";
 5
 6const contents = import.meta.glob<{ default: AstroComponentFactory }>(
 7  "/src/contents/**/*.typ",
 8);
 9
10/**
11 * Load content from `contents/<name>.<locale>.typ` or `contents/<name>/<locale>.typ`
12 */
13export async function loadLocaleContent(
14  name: string,
15  locale: string = DEFAULT_LOCALE,
16) {
17  const hasFlatFile = Boolean(contents[`/src/contents/${name}.${locale}.typ`]);
18  const hasNestFile = Boolean(contents[`/src/contents/${name}/${locale}.typ`]);
19
20  const resolvedLocale = hasFlatFile || hasNestFile ? locale : DEFAULT_LOCALE;
21
22  const loadedFile =
23    contents[`/src/contents/${name}.${resolvedLocale}.typ`] ||
24    contents[`/src/contents/${name}/${resolvedLocale}.typ`];
25  if (!loadedFile) {
26    throw new Error(`Missing content: /src/contents/${name}.${locale}.typ`);
27  }
28
29  return { Content: (await loadedFile()).default, locale: resolvedLocale };
30}
31
32export function getPostsLocaleMap(posts: CollectionEntry<"posts">[]) {
33  const postsLocaleMap: Record<
34    string,
35    Record<string, CollectionEntry<"posts">>
36  > = posts.reduce(
37    (
38      acc: Record<string, Record<string, CollectionEntry<"posts">>>,
39      curr: CollectionEntry<"posts">,
40    ) => {
41      const [locale, slug] = curr.id.split("/");
42      acc[slug] = { ...acc[slug], [locale]: curr };
43      return acc;
44    },
45    {},
46  );
47  return postsLocaleMap;
48}
49
50export function getLocalePosts(
51  posts: CollectionEntry<"posts">[],
52  locale: string = DEFAULT_LOCALE,
53) {
54  const postsLocaleMap = getPostsLocaleMap(posts);
55  return Object.values(postsLocaleMap).map(
56    (locales) => locales[locale] || locales[DEFAULT_LOCALE],
57  );
58}
59
60export function getPostLocaleSlug(post: CollectionEntry<"posts">) {
61  return {
62    locale: post.id.split("/")[0],
63    slug: `/posts/${post.id.split("/").at(-1)}`,
64  };
65}