@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 +24 -7
- package/dist/index.js +48 -31
- package/package.json +7 -7
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?:
|
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?:
|
39
|
+
mdFiles?: false | MdFiles;
|
24
40
|
/**
|
25
41
|
* Whether to generate llms-full.txt.
|
26
|
-
* @default true
|
27
42
|
*/
|
28
|
-
llmsFullTxt?:
|
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?:
|
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,
|
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 } =
|
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,
|
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
|
-
|
207
|
-
|
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,
|
214
|
-
name:
|
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 =
|
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(
|
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
|
245
|
+
for (const array of pageArray)organizeBySidebar(sidebar, array);
|
242
246
|
if (llmsTxt) {
|
243
|
-
const
|
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(
|
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,
|
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
|
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(
|
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
|
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
|
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
|
-
|
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.
|
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.
|
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.
|
32
|
-
"@rslib/core": "0.10.
|
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/
|
38
|
-
"@rspress/
|
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.
|
41
|
+
"@rspress/core": "^2.0.0-beta.19"
|
42
42
|
},
|
43
43
|
"engines": {
|
44
44
|
"node": ">=18.0.0"
|