@rspress/plugin-llms 2.0.0-alpha.8 → 2.0.0-beta.1
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 +33 -22
- package/dist/index.js +146 -36
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
@@ -228,6 +228,15 @@ declare interface Hero {
|
|
228
228
|
}[];
|
229
229
|
}
|
230
230
|
|
231
|
+
export declare interface LlmsTxt {
|
232
|
+
onTitleGenerate?: (context: {
|
233
|
+
title: string | undefined;
|
234
|
+
description: string | undefined;
|
235
|
+
}) => string;
|
236
|
+
onLineGenerate?: (page: PageIndexInfo) => string;
|
237
|
+
onAfterLlmsTxtGenerate?: (llmsTxtContent: string) => string;
|
238
|
+
}
|
239
|
+
|
231
240
|
declare interface Locale {
|
232
241
|
lang: string;
|
233
242
|
label: string;
|
@@ -302,21 +311,6 @@ declare interface MarkdownOptions {
|
|
302
311
|
* Register prism languages
|
303
312
|
*/
|
304
313
|
highlightLanguages?: (string | [string, string])[];
|
305
|
-
/**
|
306
|
-
* Whether to enable mdx-rs, default is true
|
307
|
-
*/
|
308
|
-
mdxRs?: boolean | MdxRsOptions;
|
309
|
-
/**
|
310
|
-
* @deprecated, use `mdxRs` instead
|
311
|
-
*/
|
312
|
-
experimentalMdxRs?: boolean;
|
313
|
-
}
|
314
|
-
|
315
|
-
declare interface MdxRsOptions {
|
316
|
-
/**
|
317
|
-
* Determine whether the file use mdxRs compiler
|
318
|
-
*/
|
319
|
-
include?: (filepath: string) => boolean;
|
320
314
|
}
|
321
315
|
|
322
316
|
declare type Nav = NavItem[] | {
|
@@ -349,12 +343,29 @@ declare interface NavItemWithLinkAndChildren {
|
|
349
343
|
position?: 'left' | 'right';
|
350
344
|
}
|
351
345
|
|
352
|
-
declare interface Options {
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
346
|
+
export declare interface Options {
|
347
|
+
/**
|
348
|
+
* Whether to generate llms.txt.
|
349
|
+
* @default true
|
350
|
+
*/
|
351
|
+
llmsTxt?: boolean | LlmsTxt;
|
352
|
+
/**
|
353
|
+
* Whether to generate llms.txt related md files for each route.
|
354
|
+
* @default true
|
355
|
+
*/
|
356
|
+
mdFiles?: boolean;
|
357
|
+
/**
|
358
|
+
* Whether to generate llms.full.txt.
|
359
|
+
* @default true
|
360
|
+
*/
|
361
|
+
llmsFullTxt?: boolean;
|
362
|
+
/**
|
363
|
+
* Whether to exclude some routes from llms.txt.
|
364
|
+
* @default undefined
|
365
|
+
*/
|
366
|
+
exclude?: (context: {
|
367
|
+
page: PageIndexInfo;
|
368
|
+
}) => boolean;
|
358
369
|
}
|
359
370
|
|
360
371
|
/**
|
@@ -368,7 +379,7 @@ declare interface PageIndexInfo {
|
|
368
379
|
routePath: string;
|
369
380
|
toc: Header[];
|
370
381
|
content: string;
|
371
|
-
|
382
|
+
_flattenContent?: string;
|
372
383
|
_html: string;
|
373
384
|
frontmatter: FrontMatterMeta;
|
374
385
|
lang: string;
|
package/dist/index.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
|
2
|
+
import * as __WEBPACK_EXTERNAL_MODULE__rspress_runtime_server_673c713a__ from "@rspress/runtime/server";
|
2
3
|
import * as __WEBPACK_EXTERNAL_MODULE__rspress_core_1b2e46ce__ from "@rspress/core";
|
3
4
|
import * as __WEBPACK_EXTERNAL_MODULE_unist_util_visit_555e002a__ from "unist-util-visit";
|
4
5
|
import * as __WEBPACK_EXTERNAL_MODULE_unified__ from "unified";
|
@@ -5831,11 +5832,33 @@ function normalizeSlash(url) {
|
|
5831
5832
|
function isExternalUrl(url = '') {
|
5832
5833
|
return url.startsWith('http://') || url.startsWith('https://') || url.startsWith('mailto:') || url.startsWith('tel:');
|
5833
5834
|
}
|
5835
|
+
const parseUrl = (url)=>{
|
5836
|
+
const [withoutHash, hash = ''] = url.split('#');
|
5837
|
+
return {
|
5838
|
+
url: withoutHash,
|
5839
|
+
hash
|
5840
|
+
};
|
5841
|
+
};
|
5842
|
+
function normalizeHref(url, cleanUrls = false) {
|
5843
|
+
if (!url) return '/';
|
5844
|
+
if (isExternalUrl(url)) return url;
|
5845
|
+
if (url.startsWith('#')) return url;
|
5846
|
+
let { url: cleanUrl, hash } = parseUrl(decodeURIComponent(url));
|
5847
|
+
if (cleanUrls) {
|
5848
|
+
if (cleanUrl.endsWith('.html')) cleanUrl = cleanUrl.replace(/\.html$/, '');
|
5849
|
+
if (cleanUrls && cleanUrl.endsWith('/index')) cleanUrl = cleanUrl.replace(/\/index$/, '/');
|
5850
|
+
} else if (!cleanUrl.endsWith('.html')) if (cleanUrl.endsWith('/')) cleanUrl += 'index.html';
|
5851
|
+
else cleanUrl += '.html';
|
5852
|
+
return addLeadingSlash(hash ? `${cleanUrl}#${hash}` : cleanUrl);
|
5853
|
+
}
|
5834
5854
|
function withBase(url, base) {
|
5835
5855
|
const normalizedUrl = addLeadingSlash(url);
|
5836
5856
|
const normalizedBase = normalizeSlash(base);
|
5837
5857
|
return normalizedUrl.startsWith(normalizedBase) ? normalizedUrl : `${normalizedBase}${normalizedUrl}`;
|
5838
5858
|
}
|
5859
|
+
function removeBase(url, base) {
|
5860
|
+
return addLeadingSlash(url).replace(new RegExp(`^${normalizeSlash(base)}`), '');
|
5861
|
+
}
|
5839
5862
|
const matchSidebar = (pattern, currentPathname, base)=>{
|
5840
5863
|
const prefix = withBase(pattern, base);
|
5841
5864
|
if (prefix === currentPathname) return true;
|
@@ -5844,23 +5867,56 @@ const matchSidebar = (pattern, currentPathname, base)=>{
|
|
5844
5867
|
const prefixWithDot = `${prefix}.`;
|
5845
5868
|
return currentPathname.startsWith(prefixWithDot);
|
5846
5869
|
};
|
5847
|
-
|
5870
|
+
const getSidebarDataGroup = (sidebar, currentPathname, base)=>{
|
5871
|
+
const navRoutes = Object.keys(sidebar).sort((a, b)=>b.length - a.length);
|
5872
|
+
for (const name of navRoutes)if (matchSidebar(name, currentPathname, base)) {
|
5873
|
+
const sidebarGroup = sidebar[name];
|
5874
|
+
return sidebarGroup;
|
5875
|
+
}
|
5876
|
+
return [];
|
5877
|
+
};
|
5878
|
+
function routePathToMdPath(routePath) {
|
5879
|
+
let url = routePath;
|
5880
|
+
url = normalizeHref(url, false);
|
5881
|
+
url = url.replace(/\.html$/, '.md');
|
5882
|
+
return url;
|
5883
|
+
}
|
5884
|
+
function generateLlmsTxt(pageDataArray, navList, others, llmsTxtOptions, title, description) {
|
5848
5885
|
const lines = [];
|
5886
|
+
const { onAfterLlmsTxtGenerate, onLineGenerate, onTitleGenerate } = 'boolean' == typeof llmsTxtOptions ? {} : llmsTxtOptions;
|
5887
|
+
const summary = onTitleGenerate ? onTitleGenerate({
|
5888
|
+
title,
|
5889
|
+
description
|
5890
|
+
}) : `# ${title}${description ? `\n\n> ${description}` : ''}`;
|
5849
5891
|
for(let i = 0; i < navList.length; i++){
|
5850
5892
|
const nav = navList[i];
|
5851
5893
|
const pages = pageDataArray[i];
|
5852
5894
|
const { text } = nav;
|
5853
5895
|
if (0 === pages.length) continue;
|
5854
5896
|
const title = text;
|
5855
|
-
lines.push(
|
5897
|
+
lines.push(`\n## ${title}\n`);
|
5856
5898
|
for (const page of pages){
|
5857
|
-
|
5858
|
-
|
5859
|
-
|
5860
|
-
|
5861
|
-
|
5862
|
-
}
|
5863
|
-
|
5899
|
+
const { routePath, lang, title, frontmatter } = page;
|
5900
|
+
if ('/' === routePath || routePath === `/${lang}/`) continue;
|
5901
|
+
const line = onLineGenerate ? onLineGenerate(page) : `- [${title}](${routePathToMdPath(routePath)})${frontmatter.description ? `: ${frontmatter.description}` : ''}`;
|
5902
|
+
lines.push(line);
|
5903
|
+
}
|
5904
|
+
}
|
5905
|
+
let hasOthers = false;
|
5906
|
+
const otherLines = [];
|
5907
|
+
otherLines.push('\n## Others\n');
|
5908
|
+
for (const page of others){
|
5909
|
+
const { routePath, lang, title, frontmatter } = page;
|
5910
|
+
if ('/' === routePath || routePath === `/${lang}/`) continue;
|
5911
|
+
const line = onLineGenerate ? onLineGenerate(page) : `- [${title}](${routePathToMdPath(routePath)})${frontmatter.description ? `: ${frontmatter.description}` : ''}`;
|
5912
|
+
otherLines.push(line);
|
5913
|
+
hasOthers = true;
|
5914
|
+
}
|
5915
|
+
if (hasOthers) lines.push(...otherLines);
|
5916
|
+
const llmsTxt = `${summary}\n${lines.join('\n')}`;
|
5917
|
+
return onAfterLlmsTxtGenerate ? onAfterLlmsTxtGenerate(llmsTxt) : llmsTxt;
|
5918
|
+
}
|
5919
|
+
function generateLlmsFullTxt(pageDataArray, navList, others) {
|
5864
5920
|
const lines = [];
|
5865
5921
|
for(let i = 0; i < navList.length; i++){
|
5866
5922
|
const nav = navList[i];
|
@@ -5869,10 +5925,15 @@ function generateLlmsFullTxt(pageDataArray, navList) {
|
|
5869
5925
|
const title = nav.text;
|
5870
5926
|
lines.push(`# ${title}\n`);
|
5871
5927
|
for (const page of pages){
|
5872
|
-
lines.push(page.mdContent ?? page.
|
5928
|
+
lines.push(page.mdContent ?? page._flattenContent ?? page.content);
|
5873
5929
|
lines.push('\n');
|
5874
5930
|
}
|
5875
5931
|
}
|
5932
|
+
lines.push('# Others\n');
|
5933
|
+
for (const page of others){
|
5934
|
+
lines.push(page.mdContent ?? page._flattenContent ?? page.content);
|
5935
|
+
lines.push('\n');
|
5936
|
+
}
|
5876
5937
|
return lines.join('\n');
|
5877
5938
|
}
|
5878
5939
|
function default_ok() {}
|
@@ -20842,25 +20903,36 @@ function mdxToMd(content, filepath, docDirectory, routeService) {
|
|
20842
20903
|
path: filepath
|
20843
20904
|
});
|
20844
20905
|
}
|
20845
|
-
const rsbuildPluginLlms = ({ pageDataList, routes, baseRef, docDirectoryRef, routeServiceRef, nav,
|
20906
|
+
const rsbuildPluginLlms = ({ pageDataList, routes, titleRef, descriptionRef, sidebar, baseRef, docDirectoryRef, routeServiceRef, nav, rspressPluginOptions })=>({
|
20846
20907
|
name: 'rsbuild-plugin-llms',
|
20847
20908
|
async setup (api) {
|
20848
|
-
const { llmsTxt, mdFiles, llmsFullTxt } =
|
20909
|
+
const { llmsTxt = true, mdFiles = true, llmsFullTxt = true, exclude } = rspressPluginOptions;
|
20849
20910
|
api.onBeforeBuild(async ()=>{
|
20850
20911
|
const base = baseRef.current;
|
20851
20912
|
const docDirectory = docDirectoryRef.current;
|
20852
|
-
const newPageDataList = mergeRouteMetaWithPageData(routes, pageDataList);
|
20853
|
-
const navList = Array.isArray(nav) ? nav.map((i)=>
|
20854
|
-
|
20913
|
+
const newPageDataList = mergeRouteMetaWithPageData(routes, pageDataList, exclude);
|
20914
|
+
const navList = Array.isArray(nav) ? nav.map((i)=>{
|
20915
|
+
const nav = i.nav.default;
|
20916
|
+
const lang = i.lang;
|
20917
|
+
return nav.map((i)=>({
|
20918
|
+
...i,
|
20919
|
+
lang
|
20920
|
+
}));
|
20921
|
+
}).flat().filter((i)=>i.activeMatch || i.link) : [];
|
20922
|
+
const others = [];
|
20923
|
+
const pageArray = new Array(navList.length).fill(0).map(()=>[]);
|
20855
20924
|
newPageDataList.forEach((pageData)=>{
|
20856
|
-
const { routePath } = pageData;
|
20857
|
-
pageArray.
|
20858
|
-
const
|
20859
|
-
|
20860
|
-
|
20925
|
+
const { routePath, lang } = pageData;
|
20926
|
+
for(let i = 0; i < pageArray.length; i++){
|
20927
|
+
const pageArrayItem = pageArray[i];
|
20928
|
+
const navItem = navList[i];
|
20929
|
+
if (lang === navItem.lang && new RegExp(navItem.activeMatch ?? navItem.link).test(removeBase(routePath, base))) return void pageArrayItem.push(pageData);
|
20930
|
+
}
|
20931
|
+
others.push(pageData);
|
20861
20932
|
});
|
20933
|
+
for (const array of pageArray)organizeBySidebar(sidebar, array, base);
|
20862
20934
|
if (llmsTxt) {
|
20863
|
-
const llmsTxtContent = generateLlmsTxt(pageArray, navList);
|
20935
|
+
const llmsTxtContent = generateLlmsTxt(pageArray, navList, others, rspressPluginOptions.llmsTxt ?? {}, titleRef.current, descriptionRef.current);
|
20864
20936
|
api.processAssets({
|
20865
20937
|
targets: [
|
20866
20938
|
'node'
|
@@ -20875,7 +20947,7 @@ const rsbuildPluginLlms = ({ pageDataList, routes, baseRef, docDirectoryRef, rou
|
|
20875
20947
|
await Promise.all([
|
20876
20948
|
...newPageDataList.values()
|
20877
20949
|
].map(async (pageData)=>{
|
20878
|
-
const content = pageData.
|
20950
|
+
const content = pageData._flattenContent ?? pageData.content;
|
20879
20951
|
const filepath = pageData._filepath;
|
20880
20952
|
const isMD = 'md' === __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].extname(filepath).slice(1);
|
20881
20953
|
let mdContent;
|
@@ -20903,7 +20975,7 @@ const rsbuildPluginLlms = ({ pageDataList, routes, baseRef, docDirectoryRef, rou
|
|
20903
20975
|
});
|
20904
20976
|
});
|
20905
20977
|
if (llmsFullTxt) {
|
20906
|
-
const llmsFullTxtContent = generateLlmsFullTxt(pageArray, navList);
|
20978
|
+
const llmsFullTxtContent = generateLlmsFullTxt(pageArray, navList, others);
|
20907
20979
|
api.processAssets({
|
20908
20980
|
targets: [
|
20909
20981
|
'node'
|
@@ -20917,8 +20989,13 @@ const rsbuildPluginLlms = ({ pageDataList, routes, baseRef, docDirectoryRef, rou
|
|
20917
20989
|
});
|
20918
20990
|
}
|
20919
20991
|
});
|
20920
|
-
function mergeRouteMetaWithPageData(routeMetaList, pageDataList) {
|
20921
|
-
const m = new Map(pageDataList.
|
20992
|
+
function mergeRouteMetaWithPageData(routeMetaList, pageDataList, exclude) {
|
20993
|
+
const m = new Map(pageDataList.filter((pageData)=>{
|
20994
|
+
if (exclude) return !exclude?.({
|
20995
|
+
page: pageData
|
20996
|
+
});
|
20997
|
+
return true;
|
20998
|
+
}).map((pageData)=>[
|
20922
20999
|
pageData.routePath,
|
20923
21000
|
pageData
|
20924
21001
|
]));
|
@@ -20929,16 +21006,42 @@ function mergeRouteMetaWithPageData(routeMetaList, pageDataList) {
|
|
20929
21006
|
});
|
20930
21007
|
return mergedPageDataList;
|
20931
21008
|
}
|
20932
|
-
function
|
20933
|
-
|
20934
|
-
|
20935
|
-
|
21009
|
+
function flatSidebar(sidebar) {
|
21010
|
+
if (!sidebar) return [];
|
21011
|
+
return sidebar.flatMap((i)=>{
|
21012
|
+
if ('string' == typeof i) return i;
|
21013
|
+
if ('link' in i && 'string' == typeof i.link) return [
|
21014
|
+
i.link,
|
21015
|
+
...flatSidebar(i?.items ?? [])
|
21016
|
+
];
|
21017
|
+
if ('items' in i && Array.isArray(i.items)) return flatSidebar(i.items);
|
21018
|
+
}).filter(Boolean);
|
21019
|
+
}
|
21020
|
+
function organizeBySidebar(sidebar, pages, base) {
|
21021
|
+
if (0 === pages.length) return;
|
21022
|
+
const pageItem = pages[0];
|
21023
|
+
const currSidebar = getSidebarDataGroup(sidebar, pageItem.routePath, base);
|
21024
|
+
if (0 === currSidebar.length) return;
|
21025
|
+
const orderList = flatSidebar(currSidebar);
|
21026
|
+
pages.sort((a, b)=>{
|
21027
|
+
const aIndex = orderList.findIndex((order)=>(0, __WEBPACK_EXTERNAL_MODULE__rspress_runtime_server_673c713a__.matchPath)(order, a.routePath));
|
21028
|
+
const bIndex = orderList.findIndex((order)=>(0, __WEBPACK_EXTERNAL_MODULE__rspress_runtime_server_673c713a__.matchPath)(order, b.routePath));
|
21029
|
+
return aIndex - bIndex;
|
21030
|
+
});
|
21031
|
+
}
|
21032
|
+
function pluginLlms(options = {}) {
|
20936
21033
|
const baseRef = {
|
20937
21034
|
current: ''
|
20938
21035
|
};
|
20939
21036
|
const docDirectoryRef = {
|
20940
21037
|
current: ''
|
20941
21038
|
};
|
21039
|
+
const titleRef = {
|
21040
|
+
current: ''
|
21041
|
+
};
|
21042
|
+
const descriptionRef = {
|
21043
|
+
current: ''
|
21044
|
+
};
|
20942
21045
|
const pageDataList = [];
|
20943
21046
|
const routes = [];
|
20944
21047
|
const sidebar = {};
|
@@ -20958,9 +21061,18 @@ function pluginLlms(options = {
|
|
20958
21061
|
if (isProd) routes.push(..._routes);
|
20959
21062
|
},
|
20960
21063
|
beforeBuild (config) {
|
20961
|
-
|
20962
|
-
|
21064
|
+
const configSidebar = config?.themeConfig?.locales?.map((i)=>i.sidebar).reduce((prev, curr)=>{
|
21065
|
+
Object.assign(prev, curr);
|
21066
|
+
return prev;
|
21067
|
+
}, {});
|
21068
|
+
Object.assign(sidebar, configSidebar);
|
21069
|
+
const configNav = config.themeConfig?.locales?.filter((i)=>Boolean(i.nav))?.map((i)=>({
|
21070
|
+
nav: i.nav,
|
21071
|
+
lang: i.lang
|
21072
|
+
}));
|
20963
21073
|
nav.push(...configNav);
|
21074
|
+
titleRef.current = config.title;
|
21075
|
+
descriptionRef.current = config.description;
|
20964
21076
|
baseRef.current = config.base ?? '/';
|
20965
21077
|
docDirectoryRef.current = config.root ?? 'docs';
|
20966
21078
|
},
|
@@ -20970,16 +21082,14 @@ function pluginLlms(options = {
|
|
20970
21082
|
...options,
|
20971
21083
|
pageDataList,
|
20972
21084
|
routes,
|
21085
|
+
titleRef,
|
21086
|
+
descriptionRef,
|
20973
21087
|
sidebar,
|
20974
21088
|
docDirectoryRef,
|
20975
21089
|
routeServiceRef,
|
20976
21090
|
nav,
|
20977
21091
|
baseRef,
|
20978
|
-
|
20979
|
-
llmsFullTxt,
|
20980
|
-
llmsTxt,
|
20981
|
-
mdFiles
|
20982
|
-
}
|
21092
|
+
rspressPluginOptions: options
|
20983
21093
|
})
|
20984
21094
|
]
|
20985
21095
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@rspress/plugin-llms",
|
3
|
-
"version": "2.0.0-
|
3
|
+
"version": "2.0.0-beta.1",
|
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": {
|
@@ -23,9 +23,9 @@
|
|
23
23
|
"unist-util-visit-children": "^3.0.0"
|
24
24
|
},
|
25
25
|
"devDependencies": {
|
26
|
-
"@microsoft/api-extractor": "^7.52.
|
26
|
+
"@microsoft/api-extractor": "^7.52.4",
|
27
27
|
"@rsbuild/core": "1.3.0",
|
28
|
-
"@rslib/core": "0.6.
|
28
|
+
"@rslib/core": "0.6.5",
|
29
29
|
"@types/hast": "^3.0.4",
|
30
30
|
"@types/node": "^18.11.17",
|
31
31
|
"remark-mdx": "^3.1.0",
|
@@ -34,14 +34,14 @@
|
|
34
34
|
"typescript": "^5.8.2",
|
35
35
|
"vfile": "^6.0.3",
|
36
36
|
"@rspress/config": "1.0.0",
|
37
|
-
"@rspress/shared": "2.0.0-
|
37
|
+
"@rspress/shared": "2.0.0-beta.1"
|
38
38
|
},
|
39
39
|
"peerDependencies": {
|
40
|
-
"@rspress/core": "^2.0.0-
|
41
|
-
"@rspress/runtime": "^2.0.0-
|
40
|
+
"@rspress/core": "^2.0.0-beta.1",
|
41
|
+
"@rspress/runtime": "^2.0.0-beta.1"
|
42
42
|
},
|
43
43
|
"engines": {
|
44
|
-
"node": ">=
|
44
|
+
"node": ">=18.0.0"
|
45
45
|
},
|
46
46
|
"publishConfig": {
|
47
47
|
"access": "public",
|