Skip to content

Commit

Permalink
검색 인덱스를 API 라우트를 통해 생성
Browse files Browse the repository at this point in the history
  • Loading branch information
XiNiHa committed Mar 15, 2024
1 parent 1d4bd2f commit 01c747f
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 150 deletions.
3 changes: 0 additions & 3 deletions astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,13 @@ import { transformerMetaHighlight } from "@shikijs/transformers";
import { defineConfig } from "astro/config";
import unocss from "unocss/astro";

import contentIndex from "./src/content-index";

// https://astro.build/config
export default defineConfig({
site: "https://developers.portone.io/",
integrations: [
preact({ compat: true }),
mdx(),
unocss({ injectReset: true }),
contentIndex,
sitemap({
customPages: ["/api/rest-v1/", "/api/rest-v2/"].map(
(url) => `https://developers.portone.io${url}`,
Expand Down
147 changes: 0 additions & 147 deletions src/content-index.ts

This file was deleted.

84 changes: 84 additions & 0 deletions src/pages/content-index/[fileName].json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type { APIRoute, GetStaticPaths } from "astro";
import * as yaml from "js-yaml";

import { toPlainText } from "~/misc/mdx";

export const prerender = true;

const indexFilesMapping = {
blog: "blog/",
"docs-en": "docs/en/",
"docs-ko": "docs/ko/",
"release-notes": "release-notes/",
} as const satisfies Record<string, string>;
type IndexFileName = keyof typeof indexFilesMapping;
const isIndexFileName = (value: string): value is IndexFileName =>
value in indexFilesMapping;

export const getStaticPaths: GetStaticPaths = () =>
Object.keys(indexFilesMapping).map((fileName) => ({
params: { fileName },
}));

export const GET: APIRoute = async ({ params }) => {
const { fileName } = params;
const slug =
fileName && isIndexFileName(fileName) && indexFilesMapping[fileName];
if (!slug) return new Response(null, { status: 404 });
const entryMap = import.meta.glob("../../content/**/*.mdx", {
query: "?raw",
});
const mdxTable = Object.fromEntries(
(
await Promise.all(
Object.entries(entryMap).map(async ([path, importEntry]) => {
const match = path.match(/\/content\/(.+)\.mdx$/);
if (!match || !match[1]?.startsWith(slug)) return;
const entry = await importEntry();
if (
!entry ||
typeof entry !== "object" ||
!("default" in entry) ||
typeof entry.default !== "string"
)
return;

const { frontmatter, md } = cutFrontmatter(entry.default);
if (!frontmatter || typeof frontmatter !== "object") return;
const entrySlug = String(
"slug" in frontmatter ? frontmatter.slug : match[1],
);
return [entrySlug, { ...frontmatter, slug, md }] as const;
}),
)
).filter(Boolean),
);
const indexes = Object.values(mdxTable).map((mdx) => ({
...mdx,
text: toPlainText(mdx.md),
}));
return new Response(JSON.stringify(indexes), {
headers: {
"Content-Type": "application/json",
},
});
};

interface CutFrontmatterResult {
frontmatter: unknown;
md: string;
}
function cutFrontmatter(md: string): CutFrontmatterResult {
const match = md.match(
/^---\r?\n((?:.|\r|\n)*?)\r?\n---\r?\n((?:.|\r|\n)*)$/,
);
if (!match) return { frontmatter: {}, md };
try {
const fm = match[1] || "";
const md = match[2] || "";
const frontmatter = yaml.load(fm);
return { frontmatter, md };
} catch {
return { frontmatter: {}, md };
}
}

0 comments on commit 01c747f

Please sign in to comment.