llm-txt-plugin.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. const path = require('path');
  2. const fs = require('fs');
  3. const DOCS_BASE_URL = process.env.DOCS_BASE_URL || 'https://docs.vendure.io';
  4. module.exports = function (context) {
  5. return {
  6. name: 'llms-txt-plugin',
  7. loadContent: async () => {
  8. const { siteDir } = context;
  9. const contentDir = siteDir;
  10. const allMdx = [];
  11. console.log('contentDir', contentDir);
  12. // recursive function to get all mdx files
  13. const getMdxFiles = async dir => {
  14. const entries = await fs.promises.readdir(dir, { withFileTypes: true });
  15. for (const entry of entries) {
  16. const fullPath = path.join(dir, entry.name);
  17. if (entry.isDirectory()) {
  18. await getMdxFiles(fullPath);
  19. } else if (entry.name.endsWith('.mdx') || entry.name.endsWith('.md')) {
  20. const content = await fs.promises.readFile(fullPath, 'utf8');
  21. allMdx.push(content);
  22. }
  23. }
  24. };
  25. await getMdxFiles(contentDir);
  26. return { allMdx };
  27. },
  28. postBuild: async ({ content, routes, outDir }) => {
  29. const { allMdx } = content;
  30. // Write concatenated MDX content
  31. const concatenatedPath = path.join(outDir, 'llms-full.txt');
  32. await fs.promises.writeFile(concatenatedPath, allMdx.join('\n\n---\n\n'));
  33. // we need to dig down several layers:
  34. // find PluginRouteConfig marked by plugin.name === "docusaurus-plugin-content-docs"
  35. const docsPluginRouteConfig = routes.filter(
  36. route => route.plugin.name === 'docusaurus-plugin-content-docs',
  37. )[0];
  38. // docsPluginRouteConfig has a routes property has a record with the path "/" that contains all docs routes.
  39. const allDocsRouteConfig = docsPluginRouteConfig.routes?.filter(route => route.path === '/')[0];
  40. // A little type checking first
  41. if (!allDocsRouteConfig?.props?.version) {
  42. return;
  43. }
  44. // this route config has a `props` property that contains the current documentation.
  45. const currentVersionDocsRoutes = allDocsRouteConfig.props.version.docs;
  46. // for every single docs route we now parse a path (which is the key) and a title
  47. const docsRecords = Object.entries(currentVersionDocsRoutes).map(([path, record]) => {
  48. return `- [${record.title}](${DOCS_BASE_URL}/${path}): ${record.description}`;
  49. });
  50. // Build up llms.txt file
  51. const llmsTxt = `# ${context.siteConfig.title}\n\n## Docs\n\n${docsRecords.join('\n')}`;
  52. // Write llms.txt file
  53. const llmsTxtPath = path.join(outDir, 'llms.txt');
  54. try {
  55. fs.writeFileSync(llmsTxtPath, llmsTxt);
  56. } catch (err) {
  57. throw err;
  58. }
  59. },
  60. };
  61. };