bijlobke/vendor/integration/index.ts
2024-10-26 11:51:26 +02:00

117 lines
3.9 KiB
TypeScript

import fs from 'node:fs';
import os from 'node:os';
import type { AstroConfig, AstroIntegration } from 'astro';
import configBuilder, { type Config } from './utils/configBuilder';
import loadConfig from './utils/loadConfig';
export default ({ config: _themeConfig = 'src/config.yaml' } = {}): AstroIntegration => {
let cfg: AstroConfig;
return {
name: 'astrowind-integration',
hooks: {
'astro:config:setup': async ({
// command,
config,
// injectRoute,
// isRestart,
logger,
updateConfig,
addWatchFile,
}) => {
const buildLogger = logger.fork('astrowind');
const virtualModuleId = 'astrowind:config';
const resolvedVirtualModuleId = '\0' + virtualModuleId;
const rawJsonConfig = (await loadConfig(_themeConfig)) as Config;
const { SITE, I18N, METADATA, APP_BLOG, UI, ANALYTICS } = configBuilder(rawJsonConfig);
updateConfig({
site: SITE.site,
base: SITE.base,
trailingSlash: SITE.trailingSlash ? 'always' : 'never',
vite: {
plugins: [
{
name: 'vite-plugin-astrowind-config',
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId;
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `
export const SITE = ${JSON.stringify(SITE)};
export const I18N = ${JSON.stringify(I18N)};
export const METADATA = ${JSON.stringify(METADATA)};
export const APP_BLOG = ${JSON.stringify(APP_BLOG)};
export const UI = ${JSON.stringify(UI)};
export const ANALYTICS = ${JSON.stringify(ANALYTICS)};
`;
}
},
},
],
},
});
if (typeof _themeConfig === 'string') {
addWatchFile(new URL(_themeConfig, config.root));
buildLogger.info(`Astrowind \`${_themeConfig}\` has been loaded.`);
} else {
buildLogger.info(`Astrowind config has been loaded.`);
}
},
'astro:config:done': async ({ config }) => {
cfg = config;
},
'astro:build:done': async ({ logger }) => {
const buildLogger = logger.fork('astrowind');
buildLogger.info('Updating `robots.txt` with `sitemap-index.xml` ...');
try {
const outDir = cfg.outDir;
const publicDir = cfg.publicDir;
const sitemapName = 'sitemap-index.xml';
const sitemapFile = new URL(sitemapName, outDir);
const robotsTxtFile = new URL('robots.txt', publicDir);
const robotsTxtFileInOut = new URL('robots.txt', outDir);
const hasIntegration =
Array.isArray(cfg?.integrations) &&
cfg.integrations?.find((e) => e?.name === '@astrojs/sitemap') !== undefined;
const sitemapExists = fs.existsSync(sitemapFile);
if (hasIntegration && sitemapExists) {
const robotsTxt = fs.readFileSync(robotsTxtFile, { encoding: 'utf8', flag: 'a+' });
const sitemapUrl = new URL(sitemapName, String(new URL(cfg.base, cfg.site)));
const pattern = /^Sitemap:(.*)$/m;
if (!pattern.test(robotsTxt)) {
fs.writeFileSync(robotsTxtFileInOut, `${robotsTxt}${os.EOL}${os.EOL}Sitemap: ${sitemapUrl}`, {
encoding: 'utf8',
flag: 'w',
});
} else {
fs.writeFileSync(robotsTxtFileInOut, robotsTxt.replace(pattern, `Sitemap: ${sitemapUrl}`), {
encoding: 'utf8',
flag: 'w',
});
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
/* empty */
}
},
},
};
};