import type { AstroConfig, AstroIntegration } from "astro"; import AutoImport from "astro-auto-import"; import remarkDirective from "remark-directive"; import createEmbedPlugin from "./remark-plugin.ts"; const importNamespace = "AuToImPoRtEdAstroCusToMEmbed"; /** * Embeds can be triggered by a single URL or a directive. */ export type EmbedsOption = { componentName: string; /** * path to import component from (default is 'src/components/embeds') */ importPath?: string; /** * for matching single urls on a single line * function that should return a string with the argument to pass to the component or undefined if it doesn't match * * @param url * @returns */ urlMatcher?: (url: string) => string | undefined | null; /** * what argument to pass the url as to the component (default is 'href') */ urlArgument?: string; /** * for matching a directive, name of the directive, can also be an array of names * * @param directive * @returns */ directiveName?: string | string[]; }; /** * Astro embed MDX integration. */ export default function customEmbeds({ embeds = [], }: { embeds?: EmbedsOption[]; } = {}) { const AstroCustomEmbeds: AstroIntegration = { name: "astro-custom-embeds", hooks: { "astro:config:setup": ({ config, updateConfig }) => { checkIntegrationsOrder(config); updateConfig({ markdown: { remarkPlugins: [ remarkDirective, createEmbedPlugin({ embeds, importNamespace }), ], }, }); }, }, }; const imports: Record = {}; for (const embed of embeds) { let importPath = embed.importPath ?? "src/components/embeds"; if (!imports[importPath]) { imports[importPath] = []; } imports[importPath].push([ embed.componentName, importNamespace + "_" + embed.componentName, ]); } return [ AutoImport({ imports: [imports], }), AstroCustomEmbeds, ]; } function checkIntegrationsOrder({ integrations }: AstroConfig) { const indexOf = (name: string) => integrations.findIndex((i) => i.name === name); const mdxIndex = indexOf("@astrojs/mdx"); const embedIndex = indexOf("astro-custom-embeds"); if (mdxIndex > -1 && mdxIndex < embedIndex) { throw new Error( "MDX integration configured before astro-custom-embeds.\n" + "Please move `mdx()` after `customEmbeds()` in the `integrations` array in astro.config.ts.", ); } }