[READ-ONLY] Mirror of https://github.com/flo-bit/tiny-docs. quick setup, simple, minimalistic docs for your github project
flo-bit.dev/tiny-docs/
2.6 kB
103 lines
1import type { AstroConfig, AstroIntegration } from "astro";
2import AutoImport from "astro-auto-import";
3import remarkDirective from "remark-directive";
4
5import createEmbedPlugin from "./remark-plugin.ts";
6
7const importNamespace = "AuToImPoRtEdAstroCusToMEmbed";
8
9/**
10 * Embeds can be triggered by a single URL or a directive.
11 */
12export type EmbedsOption = {
13 componentName: string;
14
15 /**
16 * path to import component from (default is 'src/components/embeds')
17 */
18 importPath?: string;
19
20 /**
21 * for matching single urls on a single line
22 * function that should return a string with the argument to pass to the component or undefined if it doesn't match
23 *
24 * @param url
25 * @returns
26 */
27 urlMatcher?: (url: string) => string | undefined | null;
28
29 /**
30 * what argument to pass the url as to the component (default is 'href')
31 */
32 urlArgument?: string;
33
34 /**
35 * for matching a directive, name of the directive, can also be an array of names
36 *
37 * @param directive
38 * @returns
39 */
40 directiveName?: string | string[];
41};
42
43/**
44 * Astro embed MDX integration.
45 */
46export default function customEmbeds({
47 embeds = [],
48}: {
49 embeds?: EmbedsOption[];
50} = {}) {
51 const AstroCustomEmbeds: AstroIntegration = {
52 name: "astro-custom-embeds",
53 hooks: {
54 "astro:config:setup": ({ config, updateConfig }) => {
55 checkIntegrationsOrder(config);
56 updateConfig({
57 markdown: {
58 remarkPlugins: [
59 remarkDirective,
60 createEmbedPlugin({ embeds, importNamespace }),
61 ],
62 },
63 });
64 },
65 },
66 };
67
68 const imports: Record<string, [string, string][]> = {};
69
70 for (const embed of embeds) {
71 let importPath = embed.importPath ?? "src/components/embeds";
72
73 if (!imports[importPath]) {
74 imports[importPath] = [];
75 }
76
77 imports[importPath].push([
78 embed.componentName,
79 importNamespace + "_" + embed.componentName,
80 ]);
81 }
82
83 return [
84 AutoImport({
85 imports: [imports],
86 }),
87 AstroCustomEmbeds,
88 ];
89}
90
91function checkIntegrationsOrder({ integrations }: AstroConfig) {
92 const indexOf = (name: string) =>
93 integrations.findIndex((i) => i.name === name);
94 const mdxIndex = indexOf("@astrojs/mdx");
95 const embedIndex = indexOf("astro-custom-embeds");
96
97 if (mdxIndex > -1 && mdxIndex < embedIndex) {
98 throw new Error(
99 "MDX integration configured before astro-custom-embeds.\n" +
100 "Please move `mdx()` after `customEmbeds()` in the `integrations` array in astro.config.ts.",
101 );
102 }
103}