mirror of
https://github.com/sern-handler/website
synced 2026-06-23 08:12:22 +00:00
78 lines
2.5 KiB
TypeScript
78 lines
2.5 KiB
TypeScript
import type { AstroConfig, ViteUserConfig } from 'astro';
|
|
import { resolve } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import type { StarlightConfig } from '../utils/user-config';
|
|
|
|
function resolveVirtualModuleId<T extends string>(id: T): `\0${T}` {
|
|
return `\0${id}`;
|
|
}
|
|
|
|
/** Vite plugin that exposes Starlight user config and project context via virtual modules. */
|
|
export function vitePluginStarlightUserConfig(
|
|
opts: StarlightConfig,
|
|
{
|
|
build,
|
|
root,
|
|
srcDir,
|
|
trailingSlash,
|
|
}: Pick<AstroConfig, 'root' | 'srcDir' | 'trailingSlash'> & {
|
|
build: Pick<AstroConfig['build'], 'format'>;
|
|
}
|
|
): NonNullable<ViteUserConfig['plugins']>[number] {
|
|
const resolveId = (id: string) =>
|
|
JSON.stringify(id.startsWith('.') ? resolve(fileURLToPath(root), id) : id);
|
|
|
|
const virtualComponentModules = Object.fromEntries(
|
|
Object.entries(opts.components).map(([name, path]) => [
|
|
`virtual:starlight/components/${name}`,
|
|
`export { default } from ${resolveId(path)};`,
|
|
])
|
|
);
|
|
|
|
/** Map of virtual module names to their code contents as strings. */
|
|
const modules = {
|
|
'virtual:starlight/user-config': `export default ${JSON.stringify(opts)}`,
|
|
'virtual:starlight/project-context': `export default ${JSON.stringify({
|
|
build: { format: build.format },
|
|
root,
|
|
srcDir,
|
|
trailingSlash,
|
|
})}`,
|
|
'virtual:starlight/user-css': opts.customCss.map((id) => `import ${resolveId(id)};`).join(''),
|
|
'virtual:starlight/user-images': opts.logo
|
|
? 'src' in opts.logo
|
|
? `import src from ${resolveId(
|
|
opts.logo.src
|
|
)}; export const logos = { dark: src, light: src };`
|
|
: `import dark from ${resolveId(opts.logo.dark)}; import light from ${resolveId(
|
|
opts.logo.light
|
|
)}; export const logos = { dark, light };`
|
|
: 'export const logos = {};',
|
|
'virtual:starlight/collection-config': `let userCollections;
|
|
try {
|
|
userCollections = (await import('/src/content/config.ts')).collections;
|
|
} catch {}
|
|
export const collections = userCollections;`,
|
|
...virtualComponentModules,
|
|
} satisfies Record<string, string>;
|
|
|
|
/** Mapping names prefixed with `\0` to their original form. */
|
|
const resolutionMap = Object.fromEntries(
|
|
(Object.keys(modules) as (keyof typeof modules)[]).map((key) => [
|
|
resolveVirtualModuleId(key),
|
|
key,
|
|
])
|
|
);
|
|
|
|
return {
|
|
name: 'vite-plugin-starlight-user-config',
|
|
resolveId(id): string | void {
|
|
if (id in modules) return resolveVirtualModuleId(id);
|
|
},
|
|
load(id): string | void {
|
|
const resolution = resolutionMap[id];
|
|
if (resolution) return modules[resolution];
|
|
},
|
|
};
|
|
}
|