UNPKG

studiocms

Version:

Astro Native CMS for AstroDB. Built from the ground up by the Astro community.

103 lines (91 loc) 3.15 kB
import { convertToSafeString } from '@withstudiocms/internal_helpers/utils'; import type { AstroIntegration } from 'astro'; import { addVirtualImports, createResolver } from 'astro-integration-kit'; /** * Options for configuring the dynamic sitemap. */ interface DynamicSitemapOptions { /** * An array of sitemap configurations. */ sitemaps: { /** * The name of the plugin that generates the sitemap. */ pluginName: string; /** * The endpoint path or URL where the sitemap XML can be accessed. */ sitemapXMLEndpointPath: string | URL; }[]; } /** * Converts a given string to a safe string format by removing leading and trailing underscores, * and replacing the prefix 'studiocms_' if present. * * @param str - The input string to be converted. * @returns The converted safe string. */ export function safeString(str: string) { return convertToSafeString(str).replace(/^_+/, '').replace(/_+$/, '').replace('studiocms_', ''); } /** * Generates a dynamic sitemap integration for Astro. * * @param {DynamicSitemapOptions} options - Configuration options for the dynamic sitemap. * @returns {AstroIntegration} The Astro integration object. * * The integration adds virtual imports for sitemaps and injects routes for the sitemap index and individual sitemaps. * * The `options` parameter should include: * - `sitemaps`: An array of objects, each containing: * - `pluginName`: The name of the plugin. * - `sitemapXMLEndpointPath`: The entry point path for the sitemap XML. * * The function performs the following steps: * 1. Creates a resolver using the current module URL. * 2. Adds virtual imports for the sitemaps. * 3. Injects a route for the sitemap index. * 4. Iterates over the provided sitemaps and injects routes for each sitemap. * * If multiple sitemaps have the same pattern, a unique pattern is generated by appending an index. */ export function dynamicSitemap(options: DynamicSitemapOptions): AstroIntegration { const { resolve } = createResolver(import.meta.url); return { name: 'studiocms/dynamic-sitemap', hooks: { /* v8 ignore start */ 'astro:config:setup': (params) => { const { injectRoute } = params; const { sitemaps } = options; addVirtualImports(params, { name: 'studiocms/dynamic-sitemap', imports: { 'virtual:studiocms/sitemaps': ` export const sitemaps = ${JSON.stringify([...sitemaps.map(({ pluginName }) => `./sitemap-${safeString(pluginName)}.xml`)])}; `, }, }); injectRoute({ entrypoint: resolve('./sitemap-index.xml.js'), pattern: '/sitemap-index.xml', prerender: false, }); const existingSitemaps: string[] = []; for (const { pluginName, sitemapXMLEndpointPath: entrypoint } of sitemaps) { let pattern = `/sitemap-${safeString(pluginName)}.xml`; if (existingSitemaps.includes(pattern)) { pattern = `/sitemap-${safeString(pluginName)}-${existingSitemaps.length}.xml`; } injectRoute({ entrypoint, pattern, prerender: false, }); } }, /* v8 ignore stop */ }, }; }