@rspress/plugin-llms 2.0.0-beta.17 → 2.0.0-beta.19

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.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,18 @@
1
1
  import type { PageIndexInfo } from '@rspress/shared';
2
2
  import type { RspressPlugin } from '@rspress/shared';
3
3
 
4
+ declare interface LlmsFullTxt {
5
+ /**
6
+ * @default "llms-full.txt"
7
+ */
8
+ name: string;
9
+ }
10
+
4
11
  export declare interface LlmsTxt {
12
+ /**
13
+ * @default "llms.txt"
14
+ */
15
+ name: string;
5
16
  onTitleGenerate?: (context: {
6
17
  title: string | undefined;
7
18
  description: string | undefined;
@@ -10,22 +21,26 @@ export declare interface LlmsTxt {
10
21
  onAfterLlmsTxtGenerate?: (llmsTxtContent: string) => string;
11
22
  }
12
23
 
24
+ declare interface MdFiles {
25
+ /**
26
+ * @default true
27
+ */
28
+ mdxToMd: boolean;
29
+ }
30
+
13
31
  export declare interface Options {
14
32
  /**
15
33
  * Whether to generate llms.txt.
16
- * @default true
17
34
  */
18
- llmsTxt?: boolean | LlmsTxt;
35
+ llmsTxt?: false | LlmsTxt;
19
36
  /**
20
37
  * Whether to generate llms.txt related md files for each route.
21
- * @default true
22
38
  */
23
- mdFiles?: boolean;
39
+ mdFiles?: false | MdFiles;
24
40
  /**
25
41
  * Whether to generate llms-full.txt.
26
- * @default true
27
42
  */
28
- llmsFullTxt?: boolean;
43
+ llmsFullTxt?: false | LlmsFullTxt;
29
44
  /**
30
45
  * Whether to include some routes from llms.txt.
31
46
  * @param context
@@ -47,6 +62,8 @@ export declare interface Options {
47
62
  /**
48
63
  * A plugin for rspress to generate llms.txt, llms-full.txt, md files to let llm understand your website.
49
64
  */
50
- export declare function pluginLlms(options?: Options): RspressPlugin;
65
+ export declare function pluginLlms(options?: RspressPluginLlmsOptions): RspressPlugin;
66
+
67
+ declare type RspressPluginLlmsOptions = Options | Options[];
51
68
 
52
69
  export { }
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*! For license information please see index.js.LICENSE.txt */
2
2
  import node_path from "node:path";
3
- import { getSidebarDataGroup, normalizeHref, removeBase } from "@rspress/shared";
3
+ import { getSidebarDataGroup, normalizeHref, withBase } from "@rspress/shared";
4
4
  import { logger } from "@rspress/shared/logger";
5
5
  import { remarkPluginNormalizeLink } from "@rspress/core";
6
6
  import remark_mdx from "remark-mdx";
@@ -116,15 +116,15 @@ new Set([
116
116
  308
117
117
  ]);
118
118
  Symbol("deferred");
119
- function routePathToMdPath(routePath) {
119
+ function routePathToMdPath(routePath, base) {
120
120
  let url = routePath;
121
121
  url = normalizeHref(url, false);
122
122
  url = url.replace(/\.html$/, '.md');
123
- return url;
123
+ return withBase(url, base);
124
124
  }
125
- function generateLlmsTxt(pageDataArray, navList, others, llmsTxtOptions, title, description) {
125
+ function generateLlmsTxt(pageDataArray, navList, others, llmsTxtOptions, title, description, base) {
126
126
  const lines = [];
127
- const { onAfterLlmsTxtGenerate, onLineGenerate, onTitleGenerate } = 'boolean' == typeof llmsTxtOptions ? {} : llmsTxtOptions;
127
+ const { onAfterLlmsTxtGenerate, onLineGenerate, onTitleGenerate } = llmsTxtOptions;
128
128
  const summary = onTitleGenerate ? onTitleGenerate({
129
129
  title,
130
130
  description
@@ -139,7 +139,7 @@ function generateLlmsTxt(pageDataArray, navList, others, llmsTxtOptions, title,
139
139
  for (const page of pages){
140
140
  const { routePath, lang, title, frontmatter } = page;
141
141
  if ('/' === routePath || routePath === `/${lang}/`) continue;
142
- const line = onLineGenerate ? onLineGenerate(page) : `- [${title}](${routePathToMdPath(routePath)})${frontmatter.description ? `: ${frontmatter.description}` : ''}`;
142
+ const line = onLineGenerate ? onLineGenerate(page) : `- [${title}](${routePathToMdPath(routePath, base)})${frontmatter.description ? `: ${frontmatter.description}` : ''}`;
143
143
  lines.push(line);
144
144
  }
145
145
  }
@@ -149,7 +149,7 @@ function generateLlmsTxt(pageDataArray, navList, others, llmsTxtOptions, title,
149
149
  for (const page of others){
150
150
  const { routePath, lang, title, frontmatter } = page;
151
151
  if ('/' === routePath || routePath === `/${lang}/`) continue;
152
- const line = onLineGenerate ? onLineGenerate(page) : `- [${title}](${routePathToMdPath(routePath)})${frontmatter.description ? `: ${frontmatter.description}` : ''}`;
152
+ const line = onLineGenerate ? onLineGenerate(page) : `- [${title}](${routePathToMdPath(routePath, base)})${frontmatter.description ? `: ${frontmatter.description}` : ''}`;
153
153
  otherLines.push(line);
154
154
  hasOthers = true;
155
155
  }
@@ -157,13 +157,13 @@ function generateLlmsTxt(pageDataArray, navList, others, llmsTxtOptions, title,
157
157
  const llmsTxt = `${summary}\n${lines.join('\n')}`;
158
158
  return onAfterLlmsTxtGenerate ? onAfterLlmsTxtGenerate(llmsTxt) : llmsTxt;
159
159
  }
160
- function generateLlmsFullTxt(pageDataArray, navList, others) {
160
+ function generateLlmsFullTxt(pageDataArray, navList, others, base) {
161
161
  const lines = [];
162
162
  for(let i = 0; i < navList.length; i++){
163
163
  const pages = pageDataArray[i];
164
164
  if (0 !== pages.length) for (const page of pages){
165
165
  lines.push(`---
166
- url: ${routePathToMdPath(page.routePath)}
166
+ url: ${routePathToMdPath(page.routePath, base)}
167
167
  ---
168
168
  `);
169
169
  lines.push(page.mdContent ?? page._flattenContent ?? page.content);
@@ -172,7 +172,7 @@ url: ${routePathToMdPath(page.routePath)}
172
172
  }
173
173
  for (const page of others){
174
174
  lines.push(`---
175
- url: ${routePathToMdPath(page.routePath)}
175
+ url: ${routePathToMdPath(page.routePath, base)}
176
176
  ---
177
177
  `);
178
178
  lines.push(page.mdContent ?? page._flattenContent ?? page.content);
@@ -200,23 +200,27 @@ const mdxToMdPlugin = ()=>(tree)=>{
200
200
  }
201
201
  });
202
202
  };
203
- function mdxToMd(content, filepath, docDirectory, routeService) {
203
+ function mdxToMd(content, filepath, routeService, base) {
204
204
  return unified().use(remark_parse).use(remark_mdx).use(mdxToMdPlugin).use(remarkPluginNormalizeLink, {
205
205
  cleanUrls: '.md',
206
- root: docDirectory,
207
- routeService
206
+ routeService,
207
+ __base: base
208
208
  }).use(remark_stringify).process({
209
209
  value: content,
210
210
  path: filepath
211
211
  });
212
212
  }
213
- const rsbuildPluginLlms = ({ disableSSGRef, pageDataList, routes, titleRef, descriptionRef, langRef, sidebar, baseRef, docDirectoryRef, routeServiceRef, nav, rspressPluginOptions })=>({
214
- name: 'rsbuild-plugin-llms',
213
+ const rsbuildPluginLlms = ({ disableSSGRef, baseRef, pageDataList, routes, titleRef, descriptionRef, langRef, sidebar, routeServiceRef, nav, rspressPluginOptions, index = 0 })=>({
214
+ name: `rsbuild-plugin-llms-${index}`,
215
215
  async setup (api) {
216
- const { llmsTxt = true, mdFiles = true, llmsFullTxt = true, include, exclude } = rspressPluginOptions;
216
+ const { llmsTxt = {
217
+ name: 'llms.txt'
218
+ }, mdFiles = {
219
+ mdxToMd: true
220
+ }, llmsFullTxt = {
221
+ name: 'llms-full.txt'
222
+ }, include, exclude } = rspressPluginOptions;
217
223
  api.onBeforeBuild(async ()=>{
218
- const base = baseRef.current;
219
- const docDirectory = docDirectoryRef.current;
220
224
  const disableSSG = disableSSGRef.current;
221
225
  const newPageDataList = mergeRouteMetaWithPageData(routes, pageDataList, langRef.current, include, exclude);
222
226
  const navList = Array.isArray(nav) ? nav.map((i)=>{
@@ -234,13 +238,14 @@ const rsbuildPluginLlms = ({ disableSSGRef, pageDataList, routes, titleRef, desc
234
238
  for(let i = 0; i < pageArray.length; i++){
235
239
  const pageArrayItem = pageArray[i];
236
240
  const navItem = navList[i];
237
- if (lang === navItem.lang && new RegExp(navItem.activeMatch ?? navItem.link).test(removeBase(routePath, base))) return void pageArrayItem.push(pageData);
241
+ if (lang === navItem.lang && new RegExp(navItem.activeMatch ?? navItem.link).test(routePath)) return void pageArrayItem.push(pageData);
238
242
  }
239
243
  others.push(pageData);
240
244
  });
241
- for (const array of pageArray)organizeBySidebar(sidebar, array, base);
245
+ for (const array of pageArray)organizeBySidebar(sidebar, array);
242
246
  if (llmsTxt) {
243
- const llmsTxtContent = generateLlmsTxt(pageArray, navList, others, rspressPluginOptions.llmsTxt ?? {}, titleRef.current, descriptionRef.current);
247
+ const { name } = llmsTxt;
248
+ const llmsTxtContent = generateLlmsTxt(pageArray, navList, others, llmsTxt, titleRef.current, descriptionRef.current, baseRef.current);
244
249
  api.processAssets({
245
250
  targets: disableSSG ? [
246
251
  'web'
@@ -250,7 +255,7 @@ const rsbuildPluginLlms = ({ disableSSGRef, pageDataList, routes, titleRef, desc
250
255
  stage: 'additional'
251
256
  }, async ({ compilation, sources })=>{
252
257
  const source = new sources.RawSource(llmsTxtContent);
253
- compilation.emitAsset('llms.txt', source);
258
+ compilation.emitAsset(name, source);
254
259
  });
255
260
  }
256
261
  const mdContents = {};
@@ -261,9 +266,9 @@ const rsbuildPluginLlms = ({ disableSSGRef, pageDataList, routes, titleRef, desc
261
266
  const filepath = pageData._filepath;
262
267
  const isMD = 'mdx' !== node_path.extname(filepath).slice(1);
263
268
  let mdContent;
264
- if (isMD) mdContent = content;
269
+ if (isMD || mdFiles && false === mdFiles.mdxToMd) mdContent = content;
265
270
  else try {
266
- mdContent = (await mdxToMd(content, filepath, docDirectory, routeServiceRef.current)).toString();
271
+ mdContent = (await mdxToMd(content, filepath, routeServiceRef.current, baseRef.current)).toString();
267
272
  } catch (e) {
268
273
  logger.debug(e);
269
274
  mdContent = content;
@@ -287,7 +292,8 @@ const rsbuildPluginLlms = ({ disableSSGRef, pageDataList, routes, titleRef, desc
287
292
  });
288
293
  });
289
294
  if (llmsFullTxt) {
290
- const llmsFullTxtContent = generateLlmsFullTxt(pageArray, navList, others);
295
+ const { name } = llmsFullTxt;
296
+ const llmsFullTxtContent = generateLlmsFullTxt(pageArray, navList, others, baseRef.current);
291
297
  api.processAssets({
292
298
  targets: disableSSG ? [
293
299
  'web'
@@ -297,7 +303,7 @@ const rsbuildPluginLlms = ({ disableSSGRef, pageDataList, routes, titleRef, desc
297
303
  stage: 'additional'
298
304
  }, async ({ compilation, sources })=>{
299
305
  const source = new sources.RawSource(llmsFullTxtContent);
300
- compilation.emitAsset('llms-full.txt', source);
306
+ compilation.emitAsset(name, source);
301
307
  });
302
308
  }
303
309
  });
@@ -337,10 +343,10 @@ function flatSidebar(sidebar) {
337
343
  if ('items' in i && Array.isArray(i.items)) return flatSidebar(i.items);
338
344
  }).filter(Boolean);
339
345
  }
340
- function organizeBySidebar(sidebar, pages, base) {
346
+ function organizeBySidebar(sidebar, pages) {
341
347
  if (0 === pages.length) return;
342
348
  const pageItem = pages[0];
343
- const currSidebar = getSidebarDataGroup(sidebar, pageItem.routePath, base);
349
+ const currSidebar = getSidebarDataGroup(sidebar, pageItem.routePath);
344
350
  if (0 === currSidebar.length) return;
345
351
  const orderList = flatSidebar(currSidebar);
346
352
  pages.sort((a, b)=>{
@@ -416,15 +422,26 @@ function pluginLlms(options = {}) {
416
422
  },
417
423
  builderConfig: {
418
424
  plugins: [
419
- rsbuildPluginLlms({
420
- ...options,
425
+ Array.isArray(options) ? options.map((item, index)=>rsbuildPluginLlms({
426
+ pageDataList,
427
+ routes,
428
+ titleRef,
429
+ descriptionRef,
430
+ langRef,
431
+ sidebar,
432
+ routeServiceRef,
433
+ nav,
434
+ baseRef,
435
+ disableSSGRef,
436
+ rspressPluginOptions: item,
437
+ index
438
+ })) : rsbuildPluginLlms({
421
439
  pageDataList,
422
440
  routes,
423
441
  titleRef,
424
442
  descriptionRef,
425
443
  langRef,
426
444
  sidebar,
427
- docDirectoryRef,
428
445
  routeServiceRef,
429
446
  nav,
430
447
  baseRef,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspress/plugin-llms",
3
- "version": "2.0.0-beta.17",
3
+ "version": "2.0.0-beta.19",
4
4
  "description": "A plugin for rspress to generate llms.txt, llms-full.txt, md files to let llm understand your website.",
5
5
  "bugs": "https://github.com/web-infra-dev/rspress/issues",
6
6
  "repository": {
@@ -24,21 +24,21 @@
24
24
  "unified": "^11.0.5",
25
25
  "unist-util-visit": "^5.0.0",
26
26
  "unist-util-visit-children": "^3.0.0",
27
- "@rspress/shared": "2.0.0-beta.17"
27
+ "@rspress/shared": "2.0.0-beta.19"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@microsoft/api-extractor": "^7.52.8",
31
- "@rsbuild/core": "~1.4.0-rc.0",
32
- "@rslib/core": "0.10.2",
31
+ "@rsbuild/core": "~1.4.2",
32
+ "@rslib/core": "0.10.4",
33
33
  "@types/hast": "^3.0.4",
34
34
  "@types/node": "^22.8.1",
35
35
  "typescript": "^5.8.2",
36
36
  "vfile": "^6.0.3",
37
- "@rspress/runtime": "2.0.0-beta.17",
38
- "@rspress/config": "1.0.0"
37
+ "@rspress/config": "1.0.0",
38
+ "@rspress/runtime": "2.0.0-beta.19"
39
39
  },
40
40
  "peerDependencies": {
41
- "@rspress/core": "^2.0.0-beta.17"
41
+ "@rspress/core": "^2.0.0-beta.19"
42
42
  },
43
43
  "engines": {
44
44
  "node": ">=18.0.0"