@rspress/plugin-typedoc 1.23.1 → 1.25.0

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.
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["path"],"ignoreList":[],"sources":["../../src/index.ts","../../src/constants.ts","../../src/sidebar.ts","../../src/utils.ts"],"sourcesContent":["import path from 'path';\nimport { Application, TSConfigReader } from 'typedoc';\nimport type { RspressPlugin } from '@rspress/shared';\nimport { load } from 'typedoc-plugin-markdown';\nimport { API_DIR } from './constants';\nimport {\n resolveSidebarForMultiEntry,\n resolveSidebarForSingleEntry,\n} from './sidebar';\n\nexport interface PluginTypeDocOptions {\n /**\n * The entry points of modules.\n * @default []\n */\n entryPoints: string[];\n /**\n * The output directory.\n * @default 'api'\n */\n outDir?: string;\n}\n\nexport function pluginTypeDoc(options: PluginTypeDocOptions): RspressPlugin {\n let docRoot: string | undefined;\n const { entryPoints = [], outDir = API_DIR } = options;\n return {\n name: '@rspress/plugin-typedoc',\n async addPages() {\n return [\n {\n routePath: `${outDir.replace(/\\/$/, '')}/`,\n filepath: path.join(docRoot!, outDir, 'README.md'),\n },\n ];\n },\n async config(config) {\n const app = new Application();\n docRoot = config.root;\n app.options.addReader(new TSConfigReader());\n load(app);\n app.bootstrap({\n name: config.title,\n entryPoints,\n theme: 'markdown',\n disableSources: true,\n readme: 'none',\n githubPages: false,\n requiredToBeDocumented: ['Class', 'Function', 'Interface'],\n plugin: ['typedoc-plugin-markdown'],\n // @ts-expect-error MarkdownTheme has no export\n hideBreadcrumbs: true,\n hideMembersSymbol: true,\n allReflectionsHaveOwnDocument: true,\n });\n const project = app.convert();\n\n if (project) {\n // 1. Generate module doc by typedoc\n const absoluteOutputdir = path.join(docRoot!, outDir);\n await app.generateDocs(project, absoluteOutputdir);\n const jsonDir = path.join(absoluteOutputdir, 'documentation.json');\n await app.generateJson(project, jsonDir);\n // 2. Generate sidebar\n config.themeConfig = config.themeConfig || {};\n config.themeConfig.nav = config.themeConfig.nav || [];\n const apiIndexLink = `/${outDir.replace(/(^\\/)|(\\/$)/, '')}/`;\n const { nav } = config.themeConfig;\n // Note: TypeDoc does not support i18n\n if (Array.isArray(nav)) {\n nav.push({\n text: 'API',\n link: apiIndexLink,\n });\n } else if ('default' in nav) {\n nav.default.push({\n text: 'API',\n link: apiIndexLink,\n });\n }\n\n config.themeConfig.sidebar = config.themeConfig.sidebar || {};\n config.themeConfig.sidebar[apiIndexLink] =\n entryPoints.length > 1\n ? await resolveSidebarForMultiEntry(jsonDir)\n : await resolveSidebarForSingleEntry(jsonDir);\n config.themeConfig.sidebar[apiIndexLink].unshift({\n text: 'Overview',\n link: `${apiIndexLink}README`,\n });\n }\n config.route = config.route || {};\n config.route.exclude = config.route.exclude || [];\n return config;\n },\n };\n}\n","export const API_DIR = 'api';\nexport const ROUTE_PREFIX = `/${API_DIR}`;\n","import path from 'path';\nimport fs from '@rspress/shared/fs-extra';\nimport type { SidebarGroup } from '@rspress/shared';\nimport { transformModuleName } from './utils';\nimport { ROUTE_PREFIX } from './constants';\n\ninterface ModuleItem {\n id: number;\n name: string;\n children: {\n id: number;\n name: string;\n }[];\n groups: {\n title: string;\n children: number[];\n }[];\n}\n\nasync function patchLinks(outputDir: string) {\n // Patch links in markdown files\n // Scan all the markdown files in the output directory\n // replace [foo](bar) -> [foo](./bar)\n const normlizeLinksInFile = async (filePath: string) => {\n const content = await fs.readFile(filePath, 'utf-8');\n // replace: [foo](bar) -> [foo](./bar)\n const newContent = content.replace(\n /\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n (_match, p1, p2) => {\n return `[${p1}](./${p2})`;\n },\n );\n await fs.writeFile(filePath, newContent);\n };\n\n const traverse = async (dir: string) => {\n const files = await fs.readdir(dir);\n for (const file of files) {\n const filePath = path.join(dir, file);\n const stat = await fs.stat(filePath);\n if (stat.isDirectory()) {\n await traverse(filePath);\n } else if (stat.isFile() && /\\.mdx?/.test(file)) {\n await normlizeLinksInFile(filePath);\n }\n }\n };\n await traverse(outputDir);\n}\n\nexport async function resolveSidebarForSingleEntry(\n jsonFile: string,\n): Promise<SidebarGroup[]> {\n const result: SidebarGroup[] = [];\n const data = JSON.parse(await fs.readFile(jsonFile, 'utf-8'));\n if (!data.children || data.children.length <= 0) {\n return [];\n }\n const symbolMap = new Map<string, number>();\n data.groups.forEach((group: { title: string; children: number[] }) => {\n const groupItem: SidebarGroup = {\n text: group.title,\n items: [],\n };\n group.children.forEach((id: number) => {\n const dataItem = data.children.find((item: ModuleItem) => item.id === id);\n if (dataItem) {\n // Note: we should handle the case that classes and interfaces have the same name\n // Such as class `Env` and variable `env`\n // The final output file name should be `classes/Env.md` and `variables/env-1.md`\n let fileName = dataItem.name;\n if (symbolMap.has(dataItem.name)) {\n const count = symbolMap.get(dataItem.name)! + 1;\n symbolMap.set(dataItem.name, count);\n fileName = `${dataItem.name}-${count}`;\n } else {\n symbolMap.set(dataItem.name.toLocaleLowerCase(), 0);\n }\n groupItem.items.push({\n text: dataItem.name,\n link: `${ROUTE_PREFIX}/${group.title.toLocaleLowerCase()}/${fileName}`,\n });\n }\n });\n result.push(groupItem);\n });\n\n await patchLinks(path.dirname(jsonFile));\n\n return result;\n}\n\nexport async function resolveSidebarForMultiEntry(\n jsonFile: string,\n): Promise<SidebarGroup[]> {\n const result: SidebarGroup[] = [];\n const data = JSON.parse(await fs.readFile(jsonFile, 'utf-8'));\n if (!data.children || data.children.length <= 0) {\n return result;\n }\n\n function getModulePath(name: string) {\n return path\n .join(`${ROUTE_PREFIX}/modules`, `${transformModuleName(name)}`)\n .replace(/\\\\/g, '/');\n }\n\n function getClassPath(moduleName: string, className: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/classes`,\n `${transformModuleName(moduleName)}.${className}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n function getInterfacePath(moduleName: string, interfaceName: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/interfaces`,\n `${transformModuleName(moduleName)}.${interfaceName}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n function getFunctionPath(moduleName: string, functionName: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/functions`,\n `${transformModuleName(moduleName)}.${functionName}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n data.children.forEach((module: ModuleItem) => {\n const moduleNames = module.name.split('/');\n const name = moduleNames[moduleNames.length - 1];\n const moduleConfig = {\n text: `Module:${name}`,\n items: [{ text: 'Overview', link: getModulePath(module.name) }],\n };\n if (!module.children || module.children.length <= 0) {\n return;\n }\n module.children.forEach(sub => {\n const kindString = module.groups\n .find(item => item.children.includes(sub.id))\n ?.title.slice(0, -1);\n if (!kindString) {\n return;\n }\n switch (kindString) {\n case 'Class':\n moduleConfig.items.push({\n text: `Class:${sub.name}`,\n link: getClassPath(module.name, sub.name),\n });\n break;\n case 'Interface':\n moduleConfig.items.push({\n text: `Interface:${sub.name}`,\n link: getInterfacePath(module.name, sub.name),\n });\n break;\n case 'Function':\n moduleConfig.items.push({\n text: `Function:${sub.name}`,\n link: getFunctionPath(module.name, sub.name),\n });\n break;\n default:\n break;\n }\n });\n result.push(moduleConfig);\n });\n await patchLinks(path.dirname(jsonFile));\n return result;\n}\n","export function transformModuleName(name: string) {\n return name.replace(/\\//g, '_').replace(/-/g, '_');\n}\n"]}
1
+ {"version":3,"mappings":"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","names":["path"],"ignoreList":[],"sources":["../../src/index.ts","../../src/constants.ts","../../src/sidebar.ts","../../src/utils.ts"],"sourcesContent":["import path from 'node:path';\nimport { Application, TSConfigReader } from 'typedoc';\nimport type { RspressPlugin } from '@rspress/shared';\nimport { load } from 'typedoc-plugin-markdown';\nimport { API_DIR } from './constants';\nimport {\n resolveSidebarForMultiEntry,\n resolveSidebarForSingleEntry,\n} from './sidebar';\n\nexport interface PluginTypeDocOptions {\n /**\n * The entry points of modules.\n * @default []\n */\n entryPoints: string[];\n /**\n * The output directory.\n * @default 'api'\n */\n outDir?: string;\n}\n\nexport function pluginTypeDoc(options: PluginTypeDocOptions): RspressPlugin {\n let docRoot: string | undefined;\n const { entryPoints = [], outDir = API_DIR } = options;\n return {\n name: '@rspress/plugin-typedoc',\n async addPages() {\n return [\n {\n routePath: `${outDir.replace(/\\/$/, '')}/`,\n filepath: path.join(docRoot!, outDir, 'README.md'),\n },\n ];\n },\n async config(config) {\n const app = new Application();\n docRoot = config.root;\n app.options.addReader(new TSConfigReader());\n load(app);\n app.bootstrap({\n name: config.title,\n entryPoints,\n theme: 'markdown',\n disableSources: true,\n readme: 'none',\n githubPages: false,\n requiredToBeDocumented: ['Class', 'Function', 'Interface'],\n plugin: ['typedoc-plugin-markdown'],\n // @ts-expect-error MarkdownTheme has no export\n hideBreadcrumbs: true,\n hideMembersSymbol: true,\n allReflectionsHaveOwnDocument: true,\n });\n const project = app.convert();\n\n if (project) {\n // 1. Generate module doc by typedoc\n const absoluteOutputdir = path.join(docRoot!, outDir);\n await app.generateDocs(project, absoluteOutputdir);\n const jsonDir = path.join(absoluteOutputdir, 'documentation.json');\n await app.generateJson(project, jsonDir);\n // 2. Generate sidebar\n config.themeConfig = config.themeConfig || {};\n config.themeConfig.nav = config.themeConfig.nav || [];\n const apiIndexLink = `/${outDir.replace(/(^\\/)|(\\/$)/, '')}/`;\n const { nav } = config.themeConfig;\n // Note: TypeDoc does not support i18n\n if (Array.isArray(nav)) {\n nav.push({\n text: 'API',\n link: apiIndexLink,\n });\n } else if ('default' in nav) {\n nav.default.push({\n text: 'API',\n link: apiIndexLink,\n });\n }\n\n config.themeConfig.sidebar = config.themeConfig.sidebar || {};\n config.themeConfig.sidebar[apiIndexLink] =\n entryPoints.length > 1\n ? await resolveSidebarForMultiEntry(jsonDir)\n : await resolveSidebarForSingleEntry(jsonDir);\n config.themeConfig.sidebar[apiIndexLink].unshift({\n text: 'Overview',\n link: `${apiIndexLink}README`,\n });\n }\n config.route = config.route || {};\n config.route.exclude = config.route.exclude || [];\n return config;\n },\n };\n}\n","export const API_DIR = 'api';\nexport const ROUTE_PREFIX = `/${API_DIR}`;\n","import path from 'node:path';\nimport fs from '@rspress/shared/fs-extra';\nimport type { SidebarGroup } from '@rspress/shared';\nimport { transformModuleName } from './utils';\nimport { ROUTE_PREFIX } from './constants';\n\ninterface ModuleItem {\n id: number;\n name: string;\n children: {\n id: number;\n name: string;\n }[];\n groups: {\n title: string;\n children: number[];\n }[];\n}\n\nasync function patchLinks(outputDir: string) {\n // Patch links in markdown files\n // Scan all the markdown files in the output directory\n // replace [foo](bar) -> [foo](./bar)\n const normlizeLinksInFile = async (filePath: string) => {\n const content = await fs.readFile(filePath, 'utf-8');\n // replace: [foo](bar) -> [foo](./bar)\n const newContent = content.replace(\n /\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n (_match, p1, p2) => {\n return `[${p1}](./${p2})`;\n },\n );\n await fs.writeFile(filePath, newContent);\n };\n\n const traverse = async (dir: string) => {\n const files = await fs.readdir(dir);\n for (const file of files) {\n const filePath = path.join(dir, file);\n const stat = await fs.stat(filePath);\n if (stat.isDirectory()) {\n await traverse(filePath);\n } else if (stat.isFile() && /\\.mdx?/.test(file)) {\n await normlizeLinksInFile(filePath);\n }\n }\n };\n await traverse(outputDir);\n}\n\nexport async function resolveSidebarForSingleEntry(\n jsonFile: string,\n): Promise<SidebarGroup[]> {\n const result: SidebarGroup[] = [];\n const data = JSON.parse(await fs.readFile(jsonFile, 'utf-8'));\n if (!data.children || data.children.length <= 0) {\n return [];\n }\n const symbolMap = new Map<string, number>();\n data.groups.forEach((group: { title: string; children: number[] }) => {\n const groupItem: SidebarGroup = {\n text: group.title,\n items: [],\n };\n group.children.forEach((id: number) => {\n const dataItem = data.children.find((item: ModuleItem) => item.id === id);\n if (dataItem) {\n // Note: we should handle the case that classes and interfaces have the same name\n // Such as class `Env` and variable `env`\n // The final output file name should be `classes/Env.md` and `variables/env-1.md`\n let fileName = dataItem.name;\n if (symbolMap.has(dataItem.name)) {\n const count = symbolMap.get(dataItem.name)! + 1;\n symbolMap.set(dataItem.name, count);\n fileName = `${dataItem.name}-${count}`;\n } else {\n symbolMap.set(dataItem.name.toLocaleLowerCase(), 0);\n }\n groupItem.items.push({\n text: dataItem.name,\n link: `${ROUTE_PREFIX}/${group.title.toLocaleLowerCase()}/${fileName}`,\n });\n }\n });\n result.push(groupItem);\n });\n\n await patchLinks(path.dirname(jsonFile));\n\n return result;\n}\n\nexport async function resolveSidebarForMultiEntry(\n jsonFile: string,\n): Promise<SidebarGroup[]> {\n const result: SidebarGroup[] = [];\n const data = JSON.parse(await fs.readFile(jsonFile, 'utf-8'));\n if (!data.children || data.children.length <= 0) {\n return result;\n }\n\n function getModulePath(name: string) {\n return path\n .join(`${ROUTE_PREFIX}/modules`, `${transformModuleName(name)}`)\n .replace(/\\\\/g, '/');\n }\n\n function getClassPath(moduleName: string, className: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/classes`,\n `${transformModuleName(moduleName)}.${className}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n function getInterfacePath(moduleName: string, interfaceName: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/interfaces`,\n `${transformModuleName(moduleName)}.${interfaceName}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n function getFunctionPath(moduleName: string, functionName: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/functions`,\n `${transformModuleName(moduleName)}.${functionName}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n data.children.forEach((module: ModuleItem) => {\n const moduleNames = module.name.split('/');\n const name = moduleNames[moduleNames.length - 1];\n const moduleConfig = {\n text: `Module:${name}`,\n items: [{ text: 'Overview', link: getModulePath(module.name) }],\n };\n if (!module.children || module.children.length <= 0) {\n return;\n }\n module.children.forEach(sub => {\n const kindString = module.groups\n .find(item => item.children.includes(sub.id))\n ?.title.slice(0, -1);\n if (!kindString) {\n return;\n }\n switch (kindString) {\n case 'Class':\n moduleConfig.items.push({\n text: `Class:${sub.name}`,\n link: getClassPath(module.name, sub.name),\n });\n break;\n case 'Interface':\n moduleConfig.items.push({\n text: `Interface:${sub.name}`,\n link: getInterfacePath(module.name, sub.name),\n });\n break;\n case 'Function':\n moduleConfig.items.push({\n text: `Function:${sub.name}`,\n link: getFunctionPath(module.name, sub.name),\n });\n break;\n default:\n break;\n }\n });\n result.push(moduleConfig);\n });\n await patchLinks(path.dirname(jsonFile));\n return result;\n}\n","export function transformModuleName(name: string) {\n return name.replace(/\\//g, '_').replace(/-/g, '_');\n}\n"]}
package/dist/lib/index.js CHANGED
@@ -53,7 +53,7 @@ __export(src_exports, {
53
53
  pluginTypeDoc: () => pluginTypeDoc
54
54
  });
55
55
  module.exports = __toCommonJS(src_exports);
56
- var import_path2 = __toESM(require("path"));
56
+ var import_node_path2 = __toESM(require("path"));
57
57
  var import_typedoc = require("typedoc");
58
58
  var import_typedoc_plugin_markdown = require("typedoc-plugin-markdown");
59
59
 
@@ -62,7 +62,7 @@ var API_DIR = "api";
62
62
  var ROUTE_PREFIX = `/${API_DIR}`;
63
63
 
64
64
  // src/sidebar.ts
65
- var import_path = __toESM(require("path"));
65
+ var import_node_path = __toESM(require("path"));
66
66
  var import_fs_extra = __toESM(require("@rspress/shared/fs-extra"));
67
67
 
68
68
  // src/utils.ts
@@ -86,7 +86,7 @@ function patchLinks(outputDir) {
86
86
  const traverse = (dir) => __async(this, null, function* () {
87
87
  const files = yield import_fs_extra.default.readdir(dir);
88
88
  for (const file of files) {
89
- const filePath = import_path.default.join(dir, file);
89
+ const filePath = import_node_path.default.join(dir, file);
90
90
  const stat = yield import_fs_extra.default.stat(filePath);
91
91
  if (stat.isDirectory()) {
92
92
  yield traverse(filePath);
@@ -130,7 +130,7 @@ function resolveSidebarForSingleEntry(jsonFile) {
130
130
  });
131
131
  result.push(groupItem);
132
132
  });
133
- yield patchLinks(import_path.default.dirname(jsonFile));
133
+ yield patchLinks(import_node_path.default.dirname(jsonFile));
134
134
  return result;
135
135
  });
136
136
  }
@@ -142,22 +142,22 @@ function resolveSidebarForMultiEntry(jsonFile) {
142
142
  return result;
143
143
  }
144
144
  function getModulePath(name) {
145
- return import_path.default.join(`${ROUTE_PREFIX}/modules`, `${transformModuleName(name)}`).replace(/\\/g, "/");
145
+ return import_node_path.default.join(`${ROUTE_PREFIX}/modules`, `${transformModuleName(name)}`).replace(/\\/g, "/");
146
146
  }
147
147
  function getClassPath(moduleName, className) {
148
- return import_path.default.join(
148
+ return import_node_path.default.join(
149
149
  `${ROUTE_PREFIX}/classes`,
150
150
  `${transformModuleName(moduleName)}.${className}`
151
151
  ).replace(/\\/g, "/");
152
152
  }
153
153
  function getInterfacePath(moduleName, interfaceName) {
154
- return import_path.default.join(
154
+ return import_node_path.default.join(
155
155
  `${ROUTE_PREFIX}/interfaces`,
156
156
  `${transformModuleName(moduleName)}.${interfaceName}`
157
157
  ).replace(/\\/g, "/");
158
158
  }
159
159
  function getFunctionPath(moduleName, functionName) {
160
- return import_path.default.join(
160
+ return import_node_path.default.join(
161
161
  `${ROUTE_PREFIX}/functions`,
162
162
  `${transformModuleName(moduleName)}.${functionName}`
163
163
  ).replace(/\\/g, "/");
@@ -203,7 +203,7 @@ function resolveSidebarForMultiEntry(jsonFile) {
203
203
  });
204
204
  result.push(moduleConfig);
205
205
  });
206
- yield patchLinks(import_path.default.dirname(jsonFile));
206
+ yield patchLinks(import_node_path.default.dirname(jsonFile));
207
207
  return result;
208
208
  });
209
209
  }
@@ -219,7 +219,7 @@ function pluginTypeDoc(options) {
219
219
  return [
220
220
  {
221
221
  routePath: `${outDir.replace(/\/$/, "")}/`,
222
- filepath: import_path2.default.join(docRoot, outDir, "README.md")
222
+ filepath: import_node_path2.default.join(docRoot, outDir, "README.md")
223
223
  }
224
224
  ];
225
225
  });
@@ -246,9 +246,9 @@ function pluginTypeDoc(options) {
246
246
  });
247
247
  const project = app.convert();
248
248
  if (project) {
249
- const absoluteOutputdir = import_path2.default.join(docRoot, outDir);
249
+ const absoluteOutputdir = import_node_path2.default.join(docRoot, outDir);
250
250
  yield app.generateDocs(project, absoluteOutputdir);
251
- const jsonDir = import_path2.default.join(absoluteOutputdir, "documentation.json");
251
+ const jsonDir = import_node_path2.default.join(absoluteOutputdir, "documentation.json");
252
252
  yield app.generateJson(project, jsonDir);
253
253
  config.themeConfig = config.themeConfig || {};
254
254
  config.themeConfig.nav = config.themeConfig.nav || [];
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["import_path","fs","path","module"],"ignoreList":[],"sources":["../../src/index.ts","../../src/constants.ts","../../src/sidebar.ts","../../src/utils.ts"],"sourcesContent":["import path from 'path';\nimport { Application, TSConfigReader } from 'typedoc';\nimport type { RspressPlugin } from '@rspress/shared';\nimport { load } from 'typedoc-plugin-markdown';\nimport { API_DIR } from './constants';\nimport {\n resolveSidebarForMultiEntry,\n resolveSidebarForSingleEntry,\n} from './sidebar';\n\nexport interface PluginTypeDocOptions {\n /**\n * The entry points of modules.\n * @default []\n */\n entryPoints: string[];\n /**\n * The output directory.\n * @default 'api'\n */\n outDir?: string;\n}\n\nexport function pluginTypeDoc(options: PluginTypeDocOptions): RspressPlugin {\n let docRoot: string | undefined;\n const { entryPoints = [], outDir = API_DIR } = options;\n return {\n name: '@rspress/plugin-typedoc',\n async addPages() {\n return [\n {\n routePath: `${outDir.replace(/\\/$/, '')}/`,\n filepath: path.join(docRoot!, outDir, 'README.md'),\n },\n ];\n },\n async config(config) {\n const app = new Application();\n docRoot = config.root;\n app.options.addReader(new TSConfigReader());\n load(app);\n app.bootstrap({\n name: config.title,\n entryPoints,\n theme: 'markdown',\n disableSources: true,\n readme: 'none',\n githubPages: false,\n requiredToBeDocumented: ['Class', 'Function', 'Interface'],\n plugin: ['typedoc-plugin-markdown'],\n // @ts-expect-error MarkdownTheme has no export\n hideBreadcrumbs: true,\n hideMembersSymbol: true,\n allReflectionsHaveOwnDocument: true,\n });\n const project = app.convert();\n\n if (project) {\n // 1. Generate module doc by typedoc\n const absoluteOutputdir = path.join(docRoot!, outDir);\n await app.generateDocs(project, absoluteOutputdir);\n const jsonDir = path.join(absoluteOutputdir, 'documentation.json');\n await app.generateJson(project, jsonDir);\n // 2. Generate sidebar\n config.themeConfig = config.themeConfig || {};\n config.themeConfig.nav = config.themeConfig.nav || [];\n const apiIndexLink = `/${outDir.replace(/(^\\/)|(\\/$)/, '')}/`;\n const { nav } = config.themeConfig;\n // Note: TypeDoc does not support i18n\n if (Array.isArray(nav)) {\n nav.push({\n text: 'API',\n link: apiIndexLink,\n });\n } else if ('default' in nav) {\n nav.default.push({\n text: 'API',\n link: apiIndexLink,\n });\n }\n\n config.themeConfig.sidebar = config.themeConfig.sidebar || {};\n config.themeConfig.sidebar[apiIndexLink] =\n entryPoints.length > 1\n ? await resolveSidebarForMultiEntry(jsonDir)\n : await resolveSidebarForSingleEntry(jsonDir);\n config.themeConfig.sidebar[apiIndexLink].unshift({\n text: 'Overview',\n link: `${apiIndexLink}README`,\n });\n }\n config.route = config.route || {};\n config.route.exclude = config.route.exclude || [];\n return config;\n },\n };\n}\n","export const API_DIR = 'api';\nexport const ROUTE_PREFIX = `/${API_DIR}`;\n","import path from 'path';\nimport fs from '@rspress/shared/fs-extra';\nimport type { SidebarGroup } from '@rspress/shared';\nimport { transformModuleName } from './utils';\nimport { ROUTE_PREFIX } from './constants';\n\ninterface ModuleItem {\n id: number;\n name: string;\n children: {\n id: number;\n name: string;\n }[];\n groups: {\n title: string;\n children: number[];\n }[];\n}\n\nasync function patchLinks(outputDir: string) {\n // Patch links in markdown files\n // Scan all the markdown files in the output directory\n // replace [foo](bar) -> [foo](./bar)\n const normlizeLinksInFile = async (filePath: string) => {\n const content = await fs.readFile(filePath, 'utf-8');\n // replace: [foo](bar) -> [foo](./bar)\n const newContent = content.replace(\n /\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n (_match, p1, p2) => {\n return `[${p1}](./${p2})`;\n },\n );\n await fs.writeFile(filePath, newContent);\n };\n\n const traverse = async (dir: string) => {\n const files = await fs.readdir(dir);\n for (const file of files) {\n const filePath = path.join(dir, file);\n const stat = await fs.stat(filePath);\n if (stat.isDirectory()) {\n await traverse(filePath);\n } else if (stat.isFile() && /\\.mdx?/.test(file)) {\n await normlizeLinksInFile(filePath);\n }\n }\n };\n await traverse(outputDir);\n}\n\nexport async function resolveSidebarForSingleEntry(\n jsonFile: string,\n): Promise<SidebarGroup[]> {\n const result: SidebarGroup[] = [];\n const data = JSON.parse(await fs.readFile(jsonFile, 'utf-8'));\n if (!data.children || data.children.length <= 0) {\n return [];\n }\n const symbolMap = new Map<string, number>();\n data.groups.forEach((group: { title: string; children: number[] }) => {\n const groupItem: SidebarGroup = {\n text: group.title,\n items: [],\n };\n group.children.forEach((id: number) => {\n const dataItem = data.children.find((item: ModuleItem) => item.id === id);\n if (dataItem) {\n // Note: we should handle the case that classes and interfaces have the same name\n // Such as class `Env` and variable `env`\n // The final output file name should be `classes/Env.md` and `variables/env-1.md`\n let fileName = dataItem.name;\n if (symbolMap.has(dataItem.name)) {\n const count = symbolMap.get(dataItem.name)! + 1;\n symbolMap.set(dataItem.name, count);\n fileName = `${dataItem.name}-${count}`;\n } else {\n symbolMap.set(dataItem.name.toLocaleLowerCase(), 0);\n }\n groupItem.items.push({\n text: dataItem.name,\n link: `${ROUTE_PREFIX}/${group.title.toLocaleLowerCase()}/${fileName}`,\n });\n }\n });\n result.push(groupItem);\n });\n\n await patchLinks(path.dirname(jsonFile));\n\n return result;\n}\n\nexport async function resolveSidebarForMultiEntry(\n jsonFile: string,\n): Promise<SidebarGroup[]> {\n const result: SidebarGroup[] = [];\n const data = JSON.parse(await fs.readFile(jsonFile, 'utf-8'));\n if (!data.children || data.children.length <= 0) {\n return result;\n }\n\n function getModulePath(name: string) {\n return path\n .join(`${ROUTE_PREFIX}/modules`, `${transformModuleName(name)}`)\n .replace(/\\\\/g, '/');\n }\n\n function getClassPath(moduleName: string, className: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/classes`,\n `${transformModuleName(moduleName)}.${className}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n function getInterfacePath(moduleName: string, interfaceName: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/interfaces`,\n `${transformModuleName(moduleName)}.${interfaceName}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n function getFunctionPath(moduleName: string, functionName: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/functions`,\n `${transformModuleName(moduleName)}.${functionName}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n data.children.forEach((module: ModuleItem) => {\n const moduleNames = module.name.split('/');\n const name = moduleNames[moduleNames.length - 1];\n const moduleConfig = {\n text: `Module:${name}`,\n items: [{ text: 'Overview', link: getModulePath(module.name) }],\n };\n if (!module.children || module.children.length <= 0) {\n return;\n }\n module.children.forEach(sub => {\n const kindString = module.groups\n .find(item => item.children.includes(sub.id))\n ?.title.slice(0, -1);\n if (!kindString) {\n return;\n }\n switch (kindString) {\n case 'Class':\n moduleConfig.items.push({\n text: `Class:${sub.name}`,\n link: getClassPath(module.name, sub.name),\n });\n break;\n case 'Interface':\n moduleConfig.items.push({\n text: `Interface:${sub.name}`,\n link: getInterfacePath(module.name, sub.name),\n });\n break;\n case 'Function':\n moduleConfig.items.push({\n text: `Function:${sub.name}`,\n link: getFunctionPath(module.name, sub.name),\n });\n break;\n default:\n break;\n }\n });\n result.push(moduleConfig);\n });\n await patchLinks(path.dirname(jsonFile));\n return result;\n}\n","export function transformModuleName(name: string) {\n return name.replace(/\\//g, '_').replace(/-/g, '_');\n}\n"]}
1
+ {"version":3,"mappings":"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","names":["import_node_path","fs","path","module"],"ignoreList":[],"sources":["../../src/index.ts","../../src/constants.ts","../../src/sidebar.ts","../../src/utils.ts"],"sourcesContent":["import path from 'node:path';\nimport { Application, TSConfigReader } from 'typedoc';\nimport type { RspressPlugin } from '@rspress/shared';\nimport { load } from 'typedoc-plugin-markdown';\nimport { API_DIR } from './constants';\nimport {\n resolveSidebarForMultiEntry,\n resolveSidebarForSingleEntry,\n} from './sidebar';\n\nexport interface PluginTypeDocOptions {\n /**\n * The entry points of modules.\n * @default []\n */\n entryPoints: string[];\n /**\n * The output directory.\n * @default 'api'\n */\n outDir?: string;\n}\n\nexport function pluginTypeDoc(options: PluginTypeDocOptions): RspressPlugin {\n let docRoot: string | undefined;\n const { entryPoints = [], outDir = API_DIR } = options;\n return {\n name: '@rspress/plugin-typedoc',\n async addPages() {\n return [\n {\n routePath: `${outDir.replace(/\\/$/, '')}/`,\n filepath: path.join(docRoot!, outDir, 'README.md'),\n },\n ];\n },\n async config(config) {\n const app = new Application();\n docRoot = config.root;\n app.options.addReader(new TSConfigReader());\n load(app);\n app.bootstrap({\n name: config.title,\n entryPoints,\n theme: 'markdown',\n disableSources: true,\n readme: 'none',\n githubPages: false,\n requiredToBeDocumented: ['Class', 'Function', 'Interface'],\n plugin: ['typedoc-plugin-markdown'],\n // @ts-expect-error MarkdownTheme has no export\n hideBreadcrumbs: true,\n hideMembersSymbol: true,\n allReflectionsHaveOwnDocument: true,\n });\n const project = app.convert();\n\n if (project) {\n // 1. Generate module doc by typedoc\n const absoluteOutputdir = path.join(docRoot!, outDir);\n await app.generateDocs(project, absoluteOutputdir);\n const jsonDir = path.join(absoluteOutputdir, 'documentation.json');\n await app.generateJson(project, jsonDir);\n // 2. Generate sidebar\n config.themeConfig = config.themeConfig || {};\n config.themeConfig.nav = config.themeConfig.nav || [];\n const apiIndexLink = `/${outDir.replace(/(^\\/)|(\\/$)/, '')}/`;\n const { nav } = config.themeConfig;\n // Note: TypeDoc does not support i18n\n if (Array.isArray(nav)) {\n nav.push({\n text: 'API',\n link: apiIndexLink,\n });\n } else if ('default' in nav) {\n nav.default.push({\n text: 'API',\n link: apiIndexLink,\n });\n }\n\n config.themeConfig.sidebar = config.themeConfig.sidebar || {};\n config.themeConfig.sidebar[apiIndexLink] =\n entryPoints.length > 1\n ? await resolveSidebarForMultiEntry(jsonDir)\n : await resolveSidebarForSingleEntry(jsonDir);\n config.themeConfig.sidebar[apiIndexLink].unshift({\n text: 'Overview',\n link: `${apiIndexLink}README`,\n });\n }\n config.route = config.route || {};\n config.route.exclude = config.route.exclude || [];\n return config;\n },\n };\n}\n","export const API_DIR = 'api';\nexport const ROUTE_PREFIX = `/${API_DIR}`;\n","import path from 'node:path';\nimport fs from '@rspress/shared/fs-extra';\nimport type { SidebarGroup } from '@rspress/shared';\nimport { transformModuleName } from './utils';\nimport { ROUTE_PREFIX } from './constants';\n\ninterface ModuleItem {\n id: number;\n name: string;\n children: {\n id: number;\n name: string;\n }[];\n groups: {\n title: string;\n children: number[];\n }[];\n}\n\nasync function patchLinks(outputDir: string) {\n // Patch links in markdown files\n // Scan all the markdown files in the output directory\n // replace [foo](bar) -> [foo](./bar)\n const normlizeLinksInFile = async (filePath: string) => {\n const content = await fs.readFile(filePath, 'utf-8');\n // replace: [foo](bar) -> [foo](./bar)\n const newContent = content.replace(\n /\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n (_match, p1, p2) => {\n return `[${p1}](./${p2})`;\n },\n );\n await fs.writeFile(filePath, newContent);\n };\n\n const traverse = async (dir: string) => {\n const files = await fs.readdir(dir);\n for (const file of files) {\n const filePath = path.join(dir, file);\n const stat = await fs.stat(filePath);\n if (stat.isDirectory()) {\n await traverse(filePath);\n } else if (stat.isFile() && /\\.mdx?/.test(file)) {\n await normlizeLinksInFile(filePath);\n }\n }\n };\n await traverse(outputDir);\n}\n\nexport async function resolveSidebarForSingleEntry(\n jsonFile: string,\n): Promise<SidebarGroup[]> {\n const result: SidebarGroup[] = [];\n const data = JSON.parse(await fs.readFile(jsonFile, 'utf-8'));\n if (!data.children || data.children.length <= 0) {\n return [];\n }\n const symbolMap = new Map<string, number>();\n data.groups.forEach((group: { title: string; children: number[] }) => {\n const groupItem: SidebarGroup = {\n text: group.title,\n items: [],\n };\n group.children.forEach((id: number) => {\n const dataItem = data.children.find((item: ModuleItem) => item.id === id);\n if (dataItem) {\n // Note: we should handle the case that classes and interfaces have the same name\n // Such as class `Env` and variable `env`\n // The final output file name should be `classes/Env.md` and `variables/env-1.md`\n let fileName = dataItem.name;\n if (symbolMap.has(dataItem.name)) {\n const count = symbolMap.get(dataItem.name)! + 1;\n symbolMap.set(dataItem.name, count);\n fileName = `${dataItem.name}-${count}`;\n } else {\n symbolMap.set(dataItem.name.toLocaleLowerCase(), 0);\n }\n groupItem.items.push({\n text: dataItem.name,\n link: `${ROUTE_PREFIX}/${group.title.toLocaleLowerCase()}/${fileName}`,\n });\n }\n });\n result.push(groupItem);\n });\n\n await patchLinks(path.dirname(jsonFile));\n\n return result;\n}\n\nexport async function resolveSidebarForMultiEntry(\n jsonFile: string,\n): Promise<SidebarGroup[]> {\n const result: SidebarGroup[] = [];\n const data = JSON.parse(await fs.readFile(jsonFile, 'utf-8'));\n if (!data.children || data.children.length <= 0) {\n return result;\n }\n\n function getModulePath(name: string) {\n return path\n .join(`${ROUTE_PREFIX}/modules`, `${transformModuleName(name)}`)\n .replace(/\\\\/g, '/');\n }\n\n function getClassPath(moduleName: string, className: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/classes`,\n `${transformModuleName(moduleName)}.${className}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n function getInterfacePath(moduleName: string, interfaceName: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/interfaces`,\n `${transformModuleName(moduleName)}.${interfaceName}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n function getFunctionPath(moduleName: string, functionName: string) {\n return path\n .join(\n `${ROUTE_PREFIX}/functions`,\n `${transformModuleName(moduleName)}.${functionName}`,\n )\n .replace(/\\\\/g, '/');\n }\n\n data.children.forEach((module: ModuleItem) => {\n const moduleNames = module.name.split('/');\n const name = moduleNames[moduleNames.length - 1];\n const moduleConfig = {\n text: `Module:${name}`,\n items: [{ text: 'Overview', link: getModulePath(module.name) }],\n };\n if (!module.children || module.children.length <= 0) {\n return;\n }\n module.children.forEach(sub => {\n const kindString = module.groups\n .find(item => item.children.includes(sub.id))\n ?.title.slice(0, -1);\n if (!kindString) {\n return;\n }\n switch (kindString) {\n case 'Class':\n moduleConfig.items.push({\n text: `Class:${sub.name}`,\n link: getClassPath(module.name, sub.name),\n });\n break;\n case 'Interface':\n moduleConfig.items.push({\n text: `Interface:${sub.name}`,\n link: getInterfacePath(module.name, sub.name),\n });\n break;\n case 'Function':\n moduleConfig.items.push({\n text: `Function:${sub.name}`,\n link: getFunctionPath(module.name, sub.name),\n });\n break;\n default:\n break;\n }\n });\n result.push(moduleConfig);\n });\n await patchLinks(path.dirname(jsonFile));\n return result;\n}\n","export function transformModuleName(name: string) {\n return name.replace(/\\//g, '_').replace(/-/g, '_');\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspress/plugin-typedoc",
3
- "version": "1.23.1",
3
+ "version": "1.25.0",
4
4
  "description": "A plugin for rspress to integrate typedoc",
5
5
  "bugs": "https://github.com/web-infra-dev/rspress/issues",
6
6
  "repository": {
@@ -17,7 +17,7 @@
17
17
  "node": ">=14.17.6"
18
18
  },
19
19
  "devDependencies": {
20
- "@modern-js/tsconfig": "2.51.0",
20
+ "@modern-js/tsconfig": "2.53.0",
21
21
  "@types/node": "^18.11.17",
22
22
  "@types/react": "^18",
23
23
  "@types/react-dom": "^18",
@@ -46,7 +46,7 @@
46
46
  "dependencies": {
47
47
  "typedoc": "0.24.8",
48
48
  "typedoc-plugin-markdown": "3.17.1",
49
- "@rspress/shared": "1.23.1"
49
+ "@rspress/shared": "1.25.0"
50
50
  },
51
51
  "scripts": {
52
52
  "dev": "modern build -w",
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import path from 'path';
1
+ import path from 'node:path';
2
2
  import { Application, TSConfigReader } from 'typedoc';
3
3
  import type { RspressPlugin } from '@rspress/shared';
4
4
  import { load } from 'typedoc-plugin-markdown';
package/src/sidebar.ts CHANGED
@@ -1,4 +1,4 @@
1
- import path from 'path';
1
+ import path from 'node:path';
2
2
  import fs from '@rspress/shared/fs-extra';
3
3
  import type { SidebarGroup } from '@rspress/shared';
4
4
  import { transformModuleName } from './utils';