typedoc.plugin.mjs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // @ts-check
  2. import { dirname, resolve } from "node:path";
  3. import { cwd } from "node:process";
  4. import * as td from "typedoc-plugin-markdown";
  5. import { typedocPageIndexData } from "./docs/typedoc-data.mjs";
  6. // Extract the package directory name to be used as the part of the markdown links
  7. let dirs = cwd().split("/packages/");
  8. /** @param {td.MarkdownApplication} app */
  9. export function load(app) {
  10. // For multi-export packages, put each docs into a different directory
  11. if (!app.options.getValue("out").endsWith("/.docs")) {
  12. // console.warn("[app]", app.options.getValue("out"));
  13. dirs = app.options.getValue("out").split("/.docs/");
  14. }
  15. const apiDirName = dirs[dirs.length - 1];
  16. // Set Markdown frontmatter for each page
  17. app.renderer.on(td.MarkdownPageEvent.BEGIN, (page) => {
  18. page.frontmatter = {
  19. title: page.model.name,
  20. };
  21. // Slice in the index data (when desired)
  22. if (page.url == "index.mdx" && typedocPageIndexData[apiDirName]?.frontmatter) {
  23. page.frontmatter = {
  24. ...page.frontmatter,
  25. ...typedocPageIndexData[apiDirName].frontmatter,
  26. };
  27. }
  28. });
  29. // Rewrite all of the internal links
  30. // - root relative for compatibility with Next.js
  31. // - strip the .mdx extension
  32. app.renderer.on(td.MarkdownPageEvent.END, (page) => {
  33. if (!page.contents) return;
  34. // Slice in the index data (when desired)
  35. if (page.url == "index.mdx" && typedocPageIndexData[apiDirName]?.contents) {
  36. page.contents = insertAfterFrontmatter(page.contents, typedocPageIndexData[apiDirName].contents);
  37. }
  38. page.contents = page.contents.replace(/\(((?:[^\/\)]+\/)*[^\/\)]+)\.mdx\)/gm, (_, path) => {
  39. // Remove trailing /index routes
  40. if (path.endsWith("/index")) path = path.replace(/\/index$/gi, "");
  41. const rootRelativeUrl = resolve(`/api/${apiDirName}`, dirname(page.url), path);
  42. return `(${rootRelativeUrl})`;
  43. });
  44. });
  45. }
  46. function insertAfterFrontmatter(markdownText, textToInsert) {
  47. if (!markdownText.startsWith("---")) {
  48. return textToInsert + markdownText;
  49. }
  50. const secondDelimiter = markdownText.indexOf("\n---\n", 4);
  51. if (secondDelimiter === -1) {
  52. return textToInsert + markdownText;
  53. }
  54. const frontmatter = markdownText.substring(0, secondDelimiter + 5);
  55. const content = markdownText.substring(secondDelimiter + 5);
  56. return frontmatter + `\n${textToInsert}\n` + content;
  57. }