auto-generate.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // @ts-ignore
  2. import * as path from 'path';
  3. // @ts-ignore
  4. import * as fs from 'fs/promises'; // 使用 fs.promises 处理异步操作
  5. import { load } from 'typedoc-plugin-markdown';
  6. import { Application, TSConfigReader, ProjectReflection } from 'typedoc';
  7. import { patchGeneratedApiDocs } from './patch';
  8. import { docLabelMap, overviewMetaJson } from './constants';
  9. async function generateDocs() {
  10. // @ts-ignore
  11. const projectRoot = path.resolve(__dirname, '../../../'); // Rush 项目根目录
  12. // @ts-ignore
  13. const packagesDir = path.join(projectRoot, 'packages'); // packages 目录
  14. // @ts-ignore
  15. const outputDir = path.join(__dirname, '../src/zh/auto-docs'); // 输出目录
  16. const packages: string[] = [];
  17. // 读取 packages 目录
  18. const firstLevelFiles = await fs.readdir(packagesDir); // 使用 fs.promises 读取目录
  19. for (const firstLevel of firstLevelFiles) {
  20. const firstLevelPath = path.resolve(packagesDir, firstLevel);
  21. const packageNames = await fs.readdir(firstLevelPath); // 异步读取包目录
  22. for (const packageName of packageNames) {
  23. const packagePath = path.join(firstLevelPath, packageName);
  24. const packageJsonPath = path.join(packagePath, 'package.json');
  25. const tsconfigPath = path.join(packagePath, 'tsconfig.json');
  26. // 检查是否是有效的包
  27. if (!(await fileExists(packageJsonPath)) || !(await fileExists(tsconfigPath))) {
  28. // console.log(`Skipping ${packagePath}: Missing package.json or tsconfig.json`);
  29. } else {
  30. packages.push(packageName);
  31. console.log(`Generating docs for package: ${packageName}`);
  32. // 输出目录为 auto-docs/{packageName}
  33. const packageOutputDir = path.join(outputDir, packageName);
  34. // 创建 Typedoc 应用实例
  35. const app = new Application();
  36. app.options.addReader(new TSConfigReader());
  37. load(app);
  38. // 配置 Typedoc
  39. app.bootstrap({
  40. entryPoints: [path.join(packagePath, 'src')],
  41. tsconfig: tsconfigPath,
  42. out: packageOutputDir,
  43. plugin: ['typedoc-plugin-markdown'], // 使用 Markdown 插件
  44. theme: 'markdown', // Markdown 模式不依赖 HTML 主题
  45. exclude: ['**/__tests__/**', 'vitest.config.ts', 'vitest.setup.ts'],
  46. basePath: packagePath,
  47. excludePrivate: true,
  48. excludeProtected: true,
  49. disableSources: true,
  50. readme: 'none',
  51. githubPages: true,
  52. hideGenerator: true,
  53. skipErrorChecking: true,
  54. requiredToBeDocumented: ['Class', 'Function', 'Interface'],
  55. // @ts-expect-error MarkdownTheme has no export
  56. hideBreadcrumbs: true,
  57. hideMembersSymbol: true,
  58. allReflectionsHaveOwnDocument: true,
  59. });
  60. // 生成文档
  61. const project: ProjectReflection | undefined = app.convert();
  62. if (project) {
  63. await app.generateDocs(project, packageOutputDir);
  64. await patchGeneratedApiDocs(packageOutputDir);
  65. const files = await fs.readdir(packageOutputDir);
  66. const packageMetaJson: Record<string, string>[] = [];
  67. for (const file of files) {
  68. if (!['.nojekyll', 'README.md'].includes(file)) {
  69. packageMetaJson.push({
  70. type: 'dir',
  71. name: file,
  72. label: docLabelMap[file] || file,
  73. });
  74. }
  75. }
  76. await fs.writeFile(
  77. path.join(packageOutputDir, '_meta.json'),
  78. JSON.stringify(packageMetaJson),
  79. 'utf-8'
  80. );
  81. await fs.unlink(path.join(packageOutputDir, 'README.md')); // 删除 README.md 文件
  82. console.log(`Docs generated for ${packageName} at ${packageOutputDir}`);
  83. } else {
  84. console.error(`Failed to generate docs for ${packageName}: Conversion failed`);
  85. // @ts-ignore
  86. process.exit();
  87. }
  88. }
  89. }
  90. }
  91. // 写入 index.md 和 _meta.json
  92. await fs.writeFile(
  93. // @ts-ignore
  94. path.resolve(__dirname, '../src/zh/auto-docs/index.md'),
  95. overviewMetaJson,
  96. 'utf-8'
  97. );
  98. const metaJson: (string | Record<string, string>)[] = [];
  99. metaJson.push('index');
  100. packages.forEach((packageName) => {
  101. metaJson.push({
  102. type: 'dir',
  103. label: `@flowgram.ai/${packageName}`,
  104. name: packageName,
  105. });
  106. });
  107. await fs.writeFile(
  108. // @ts-ignore
  109. path.resolve(__dirname, '../src/zh/auto-docs/_meta.json'),
  110. JSON.stringify(metaJson),
  111. 'utf-8'
  112. );
  113. }
  114. // 检查文件是否存在
  115. async function fileExists(path: string): Promise<boolean> {
  116. try {
  117. await fs.access(path);
  118. return true;
  119. } catch {
  120. return false;
  121. }
  122. }
  123. generateDocs().catch((error) => {
  124. console.error('Error generating docs:', error);
  125. });