// @ts-check import { defineConfig } from "astro/config"; import sitemap from "@astrojs/sitemap"; import { parseFrontmatter } from "@astrojs/markdown-remark"; import remarkGfm from "remark-gfm"; import remarkSmartypants from "remark-smartypants"; import rehypeExternalLinks from "rehype-external-links"; import type { Root } from "mdast"; import type { VFile } from "vfile"; import type { Plugin } from "unified"; import type { Options } from "retext-smartypants"; import { visit } from "unist-util-visit"; import rehypeSanitize from "rehype-sanitize"; import remarkToc from "remark-toc"; import { get } from "./src/utils/anonymous.ts"; import { loadEnv } from "vite"; import process from "node:process"; // deno-lint-ignore no-non-null-assertion const { PUBLIC_SITE_URL } = loadEnv(process.env.NODE_ENV!, process.cwd(), ""); // https://astro.build/config export default defineConfig({ site: new URL(PUBLIC_SITE_URL).href, integrations: [sitemap({ serialize: async (item) => { const match = item.url.match(/\/blog\/read\/([^/]+)\/$/); if (match === null) { return item; } const slug = match[1]; let frontmatter; try { frontmatter = await Deno.readTextFile( `${Deno.cwd()}/public/blog/${slug}.md`, ).then(parseFrontmatter).then(get("frontmatter")); } catch { return item; } item.lastmod = (frontmatter.dateUpdated ?? frontmatter.dateCreated) .toISOString(); for await ( const { name, isFile } of Deno.readDir(`${Deno.cwd()}/public/blog/`) ) { if (!name.endsWith(".md") || !isFile || name === `${slug}.md`) { continue; } let frontmatter; try { frontmatter = await Deno.readTextFile( `${Deno.cwd()}/public/blog/${name}`, ).then(parseFrontmatter).then(get("frontmatter")); } catch { continue; } if (frontmatter.translationOf !== slug) { continue; } item.links ??= []; item.links.push({ url: `https://cravodeabril.pt/blog/${name}`, lang: frontmatter.lang, hreflang: frontmatter.lang, }); } return item; }, xslURL: "/sitemap.xsl", })], server: ({ command }) => ({ host: command === "dev", }), prefetch: true, markdown: { remarkPlugins: [ remarkGfm, remarkSmartypants as Plugin<[(Options | undefined)?], Root>, [remarkToc, { ordered: true }], () => (tree: Root, _file: VFile): void => { visit(tree, function (node) { if (node.type === "heading") { node.depth++; } }); }, ], rehypePlugins: [ [ rehypeExternalLinks, { target: "_blank", }, ], rehypeSanitize, ], remarkRehype: { clobberPrefix: "" }, }, });