@hagicode/hagilight-starlight 0.2.2-dev.19.1.ce103b7 → 0.2.3-dev.22.1.69e2b54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.mjs +30 -4
  2. package/package.json +4 -2
  3. package/rss.xml.ts +25 -0
package/index.mjs CHANGED
@@ -87,7 +87,7 @@ function getRssFeedUrl(config) {
87
87
  return rssLink?.attrs.href;
88
88
  }
89
89
 
90
- function createConfiguredIntegration(instanceId, serializedOptions, componentIds, getConfiguredRssFeed) {
90
+ function createConfiguredIntegration(instanceId, serializedOptions, componentIds, getConfiguredRssFeed, generateRss) {
91
91
  const optionsId = `virtual:hagilight-starlight/${instanceId}/options`;
92
92
  const headerPath = componentIds.header
93
93
  ? fileURLToPath(new URL('./Header.astro', import.meta.url))
@@ -185,7 +185,14 @@ const isNotFound = /(?:^|\\/)404(?:\\.html)?\\/?$/u.test(Astro.url.pathname);
185
185
  return {
186
186
  name: `@hagicode/hagilight-starlight:${instanceId}`,
187
187
  hooks: {
188
- 'astro:config:setup'({ updateConfig }) {
188
+ 'astro:config:setup'({ injectRoute, updateConfig }) {
189
+ if (generateRss) {
190
+ injectRoute({
191
+ pattern: '/rss.xml',
192
+ entrypoint: fileURLToPath(new URL('./rss.xml.ts', import.meta.url)),
193
+ prerender: true,
194
+ });
195
+ }
189
196
  updateConfig({ vite: { plugins: [vitePlugin] } });
190
197
  },
191
198
  },
@@ -210,6 +217,13 @@ export default function hagilight(options = {}) {
210
217
  if (options.notFoundPage?.enabled !== undefined && typeof options.notFoundPage.enabled !== 'boolean') {
211
218
  throw new TypeError('Hagilight notFoundPage enabled option must be a boolean.');
212
219
  }
220
+ if (options.rss !== undefined
221
+ && (!options.rss || typeof options.rss !== 'object' || Array.isArray(options.rss))) {
222
+ throw new TypeError('Hagilight rss options must be an object.');
223
+ }
224
+ if (options.rss?.enabled !== undefined && typeof options.rss.enabled !== 'boolean') {
225
+ throw new TypeError('Hagilight rss enabled option must be a boolean.');
226
+ }
213
227
  if (options.analytics !== undefined
214
228
  && (!options.analytics || typeof options.analytics !== 'object' || Array.isArray(options.analytics))) {
215
229
  throw new TypeError('Hagilight analytics options must be an object.');
@@ -271,7 +285,7 @@ export default function hagilight(options = {}) {
271
285
  return {
272
286
  name: '@hagicode/hagilight-starlight',
273
287
  hooks: {
274
- 'config:setup'({ config, updateConfig, addIntegration }) {
288
+ 'config:setup'({ astroConfig, config, updateConfig, addIntegration }) {
275
289
  if (headerEnabled && config.components?.Header) {
276
290
  throw new Error('Hagilight cannot replace an existing Starlight Header override. Set header: { enabled: false } to keep it, or compose @hagicode/hagilight-starlight/Header directly.');
277
291
  }
@@ -291,17 +305,29 @@ export default function hagilight(options = {}) {
291
305
  throw new Error('Hagilight Google Analytics cannot replace an existing Starlight Head override. Compose @hagicode/hagilight/GoogleAnalytics in your Head instead.');
292
306
  }
293
307
 
308
+ const generateRss = options.rss?.enabled !== false && !getRssFeedUrl(config);
309
+ if (generateRss && !astroConfig.site) {
310
+ throw new Error('Hagilight RSS requires the Astro site option. Set site or disable RSS with rss: { enabled: false }.');
311
+ }
312
+ const rssFeedUrl = generateRss
313
+ ? new URL('rss.xml', new URL((astroConfig.base ?? '/').replace(/\/?$/u, '/'), astroConfig.site)).toString()
314
+ : undefined;
294
315
  addIntegration(createConfiguredIntegration(
295
316
  instanceId,
296
317
  serializedOptions,
297
318
  componentIds,
298
- () => getRssFeedUrl(config),
319
+ () => getRssFeedUrl(config) ?? rssFeedUrl,
320
+ generateRss,
299
321
  ));
300
322
  updateConfig({
301
323
  ...(config.logo === undefined ? { logo: { src: defaultLogo, alt: 'HagiCode' } } : {}),
302
324
  customCss: [...(config.customCss ?? []), contentWidthCssPath],
303
325
  head: [
304
326
  ...(config.head ?? []),
327
+ ...(rssFeedUrl ? [{
328
+ tag: 'link',
329
+ attrs: { rel: 'alternate', type: 'application/rss+xml', href: rssFeedUrl },
330
+ }] : []),
305
331
  { tag: 'script', content: contentWidthHeadScript },
306
332
  ],
307
333
  components: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hagicode/hagilight-starlight",
3
- "version": "0.2.2-dev.19.1.ce103b7",
3
+ "version": "0.2.3-dev.22.1.69e2b54",
4
4
  "type": "module",
5
5
  "description": "Starlight customizations for HagiCode documentation",
6
6
  "repository": {
@@ -30,11 +30,13 @@
30
30
  "index.mjs",
31
31
  "*.css",
32
32
  "*.mjs",
33
+ "rss.xml.ts",
33
34
  "*.astro",
34
35
  "assets/*.png"
35
36
  ],
36
37
  "dependencies": {
37
- "@hagicode/hagilight": "0.2.2-dev.19.1.ce103b7"
38
+ "@astrojs/rss": "^4.0.19",
39
+ "@hagicode/hagilight": "0.2.3-dev.22.1.69e2b54"
38
40
  },
39
41
  "peerDependencies": {
40
42
  "@astrojs/starlight": "^0.42.4",
package/rss.xml.ts ADDED
@@ -0,0 +1,25 @@
1
+ import rss from '@astrojs/rss';
2
+ import { getCollection } from 'astro:content';
3
+ import type { APIRoute } from 'astro';
4
+
5
+ export const GET: APIRoute = async ({ site }) => {
6
+ if (!site) throw new Error('Hagilight RSS requires the Astro site option.');
7
+
8
+ const pages = await getCollection('docs', ({ data }) => !data.draft);
9
+ const base = new URL(import.meta.env.BASE_URL, site);
10
+ return rss({
11
+ title: 'Documentation',
12
+ description: 'Recently updated documentation pages',
13
+ site: base,
14
+ items: pages
15
+ .sort((a, b) =>
16
+ (b.data.lastUpdated instanceof Date ? b.data.lastUpdated.getTime() : 0)
17
+ - (a.data.lastUpdated instanceof Date ? a.data.lastUpdated.getTime() : 0))
18
+ .map(({ id, data }) => ({
19
+ title: data.title,
20
+ description: data.description,
21
+ ...(data.lastUpdated instanceof Date ? { pubDate: data.lastUpdated } : {}),
22
+ link: new URL(`${id.replace(/(?:^|\/)index$/u, '')}/`, base).toString(),
23
+ })),
24
+ });
25
+ };