fumadocs-typescript 3.0.3 → 3.1.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.
@@ -60,7 +60,7 @@ function getProject(options = {}) {
60
60
  });
61
61
  }
62
62
 
63
- // src/generate/base.ts
63
+ // src/lib/base.ts
64
64
  import {
65
65
  ts
66
66
  } from "ts-morph";
@@ -125,71 +125,77 @@ function getDocEntry(prop, context) {
125
125
  )
126
126
  ),
127
127
  tags,
128
- type: typeName
128
+ type: typeName,
129
+ required: !prop.isOptional()
129
130
  };
130
131
  transform == null ? void 0 : transform.call(context, entry, subType, prop);
131
132
  return entry;
132
133
  }
133
134
 
134
135
  // src/markdown.ts
135
- import { fromMarkdown } from "mdast-util-from-markdown";
136
- import { gfmFromMarkdown } from "mdast-util-gfm";
137
- import { toHast } from "mdast-util-to-hast";
138
- import { getSingletonHighlighter } from "shiki";
136
+ import { remark } from "remark";
137
+ import {
138
+ remarkGfm,
139
+ rehypeCode
140
+ } from "fumadocs-core/mdx-plugins";
141
+ import remarkRehype from "remark-rehype";
142
+ var processor = remark().use(remarkGfm).use(remarkRehype).use(rehypeCode, {
143
+ lazy: true,
144
+ themes: {
145
+ light: "github-light",
146
+ dark: "github-dark"
147
+ }
148
+ }).use(() => {
149
+ return (tree, file) => {
150
+ file.data.tree = tree;
151
+ return "";
152
+ };
153
+ });
139
154
  function renderMarkdownToHast(md) {
140
155
  return __async(this, null, function* () {
141
- const mdast = fromMarkdown(
142
- md.replace(new RegExp("{@link (?<link>[^}]*)}", "g"), "$1"),
143
- // replace jsdoc links
144
- { mdastExtensions: [gfmFromMarkdown()] }
145
- );
146
- const highlighter = yield getSingletonHighlighter({
147
- themes: ["vitesse-light", "vitesse-dark"]
148
- });
149
- function preload(contents) {
150
- return __async(this, null, function* () {
151
- yield Promise.all(
152
- contents.map((c) => __async(this, null, function* () {
153
- if ("children" in c) yield preload(c.children);
154
- if (c.type === "code" && c.lang) {
155
- yield highlighter.loadLanguage(
156
- c.lang
157
- );
158
- }
159
- }))
160
- );
161
- });
156
+ md = md.replace(new RegExp("{@link (?<link>[^}]*)}", "g"), "$1");
157
+ const out = yield processor.process(md);
158
+ return out.data.tree;
159
+ });
160
+ }
161
+
162
+ // src/utils/type-table.ts
163
+ import * as fs from "node:fs/promises";
164
+ import { join } from "node:path";
165
+ function getTypeTableOutput(_a) {
166
+ return __async(this, null, function* () {
167
+ var _b = _a, {
168
+ name,
169
+ type,
170
+ options
171
+ } = _b, props = __objRest(_b, [
172
+ "name",
173
+ "type",
174
+ "options"
175
+ ]);
176
+ const file = props.path && (options == null ? void 0 : options.basePath) ? join(options.basePath, props.path) : props.path;
177
+ let typeName = name;
178
+ let content = "";
179
+ if (file) {
180
+ content = (yield fs.readFile(file)).toString();
162
181
  }
163
- yield preload(mdast.children);
164
- return toHast(mdast, {
165
- handlers: {
166
- // @ts-expect-error hast with mdx
167
- code(_, node) {
168
- var _a;
169
- const lang = (_a = node.lang) != null ? _a : "plaintext";
170
- return highlighter.codeToHast(node.value, {
171
- lang,
172
- themes: {
173
- light: "vitesse-light",
174
- dark: "vitesse-dark"
175
- },
176
- defaultColor: false,
177
- transformers: [
178
- {
179
- name: "rehype-code:pre-process",
180
- line(hast) {
181
- if (hast.children.length > 0) return;
182
- hast.children.push({
183
- type: "text",
184
- value: " "
185
- });
186
- }
187
- }
188
- ]
189
- }).children;
190
- }
191
- }
192
- });
182
+ if (type && type.split("\n").length > 1) {
183
+ content += `
184
+ ${type}`;
185
+ } else if (type) {
186
+ typeName != null ? typeName : typeName = "$Fumadocs";
187
+ content += `
188
+ export type ${typeName} = ${type}`;
189
+ }
190
+ const output = generateDocumentation(
191
+ file != null ? file : "temp.ts",
192
+ typeName,
193
+ content,
194
+ options
195
+ );
196
+ if (name && output.length === 0)
197
+ throw new Error(`${name} in ${file != null ? file : "empty file"} doesn't exist`);
198
+ return output;
193
199
  });
194
200
  }
195
201
 
@@ -201,5 +207,6 @@ export {
201
207
  getProject,
202
208
  generateDocumentation,
203
209
  generate,
204
- renderMarkdownToHast
210
+ renderMarkdownToHast,
211
+ getTypeTableOutput
205
212
  };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
- import { G as GenerateDocumentationOptions, a as GeneratedDoc, D as DocEntry } from './base-BltLCalB.js';
2
- export { b as GenerateOptions, d as generate, c as generateDocumentation, g as getProject } from './base-BltLCalB.js';
1
+ import { G as GenerateDocumentationOptions, a as GeneratedDoc, D as DocEntry, B as BaseTypeTableProps } from './type-table-DyymKQK8.js';
2
+ export { b as GenerateOptions, d as generate, c as generateDocumentation, g as getProject } from './type-table-DyymKQK8.js';
3
3
  import fg from 'fast-glob';
4
4
  import { Nodes } from 'hast';
5
+ import { Root } from 'mdast';
6
+ import { Transformer } from 'unified';
5
7
  import 'ts-morph';
6
8
 
7
9
  interface Templates {
@@ -34,4 +36,26 @@ declare function generateFiles(options: GenerateFilesOptions): Promise<void>;
34
36
 
35
37
  declare function renderMarkdownToHast(md: string): Promise<Nodes>;
36
38
 
37
- export { DocEntry, GenerateDocumentationOptions, type GenerateFilesOptions, type GenerateMDXOptions, GeneratedDoc, generateFiles, generateMDX, renderMarkdownToHast };
39
+ interface RemarkAutoTypeTableOptions {
40
+ /**
41
+ * @defaultValue 'auto-type-table'
42
+ */
43
+ name?: string;
44
+ /**
45
+ * @defaultValue 'TypeTable'
46
+ */
47
+ outputName?: string;
48
+ renderMarkdown?: typeof renderMarkdownToHast;
49
+ /**
50
+ * Override some type table props
51
+ */
52
+ options?: BaseTypeTableProps['options'];
53
+ }
54
+ /**
55
+ * Compile `auto-type-table` into Fumadocs UI compatible TypeTable
56
+ *
57
+ * MDX is required to use this plugin.
58
+ */
59
+ declare function remarkAutoTypeTable({ name, outputName, renderMarkdown, options, }?: RemarkAutoTypeTableOptions): Transformer<Root, Root>;
60
+
61
+ export { DocEntry, GenerateDocumentationOptions, type GenerateFilesOptions, type GenerateMDXOptions, GeneratedDoc, type RemarkAutoTypeTableOptions, generateFiles, generateMDX, remarkAutoTypeTable, renderMarkdownToHast };
package/dist/index.js CHANGED
@@ -6,10 +6,11 @@ import {
6
6
  generate,
7
7
  generateDocumentation,
8
8
  getProject,
9
+ getTypeTableOutput,
9
10
  renderMarkdownToHast
10
- } from "./chunk-2L4CMRDQ.js";
11
+ } from "./chunk-LRCT2FYJ.js";
11
12
 
12
- // src/generate/mdx.ts
13
+ // src/lib/mdx.ts
13
14
  import * as path from "node:path";
14
15
  import fs from "node:fs";
15
16
  var regex = new RegExp("^---type-table---\\r?\\n(?<file>.+?)(?:#(?<name>.+))?\\r?\\n---end---$", "gm");
@@ -54,7 +55,7 @@ function replaceJsDocLinks(md) {
54
55
  return md.replace(new RegExp("{@link (?<link>[^}]*)}", "g"), "$1");
55
56
  }
56
57
 
57
- // src/generate/file.ts
58
+ // src/lib/file.ts
58
59
  import * as path2 from "node:path";
59
60
  import { mkdir, writeFile, readFile } from "node:fs/promises";
60
61
  import fg from "fast-glob";
@@ -90,11 +91,145 @@ function write(file, content) {
90
91
  yield writeFile(file, content);
91
92
  });
92
93
  }
94
+
95
+ // src/lib/remark-auto-type-table.tsx
96
+ import { valueToEstree } from "estree-util-value-to-estree";
97
+ import { visit } from "unist-util-visit";
98
+ import { toEstree } from "hast-util-to-estree";
99
+ import { dirname as dirname2 } from "node:path";
100
+ function expressionToAttribute(key, value) {
101
+ return {
102
+ type: "mdxJsxAttribute",
103
+ name: key,
104
+ value: {
105
+ type: "mdxJsxAttributeValueExpression",
106
+ data: {
107
+ estree: {
108
+ type: "Program",
109
+ body: [
110
+ {
111
+ type: "ExpressionStatement",
112
+ expression: value
113
+ }
114
+ ]
115
+ }
116
+ }
117
+ }
118
+ };
119
+ }
120
+ function mapProperty(entry, renderMarkdown) {
121
+ return __async(this, null, function* () {
122
+ const value = valueToEstree({
123
+ type: entry.type,
124
+ default: entry.tags.default || entry.tags.defaultValue
125
+ });
126
+ if (entry.description) {
127
+ const hast = toEstree(yield renderMarkdown(entry.description), {
128
+ elementAttributeNameCase: "react"
129
+ }).body[0];
130
+ value.properties.push({
131
+ type: "Property",
132
+ method: false,
133
+ shorthand: false,
134
+ computed: false,
135
+ key: {
136
+ type: "Identifier",
137
+ name: "description"
138
+ },
139
+ kind: "init",
140
+ value: hast.expression
141
+ });
142
+ }
143
+ return {
144
+ type: "Property",
145
+ method: false,
146
+ shorthand: false,
147
+ computed: false,
148
+ key: {
149
+ type: "Identifier",
150
+ name: entry.name
151
+ },
152
+ kind: "init",
153
+ value
154
+ };
155
+ });
156
+ }
157
+ function remarkAutoTypeTable({
158
+ name = "auto-type-table",
159
+ outputName = "TypeTable",
160
+ renderMarkdown = renderMarkdownToHast,
161
+ options = {}
162
+ } = {}) {
163
+ var _a;
164
+ const project = (_a = options.project) != null ? _a : getProject(options.config);
165
+ return (tree, file) => __async(this, null, function* () {
166
+ const queue = [];
167
+ let basePath = options == null ? void 0 : options.basePath;
168
+ if (!basePath && file.path) basePath = dirname2(file.path);
169
+ visit(tree, "mdxJsxFlowElement", (node) => {
170
+ if (node.name !== name) return;
171
+ const props = {};
172
+ for (const attr of node.attributes) {
173
+ if (attr.type !== "mdxJsxAttribute" || typeof attr.value !== "string")
174
+ throw new Error(
175
+ "`auto-type-table` does not support non-string attributes"
176
+ );
177
+ props[attr.name] = attr.value;
178
+ }
179
+ function run() {
180
+ return __async(this, null, function* () {
181
+ const output = yield getTypeTableOutput(__spreadProps(__spreadValues({}, props), {
182
+ options: __spreadProps(__spreadValues({}, options), {
183
+ project,
184
+ basePath
185
+ })
186
+ }));
187
+ const rendered = output.map((doc) => __async(this, null, function* () {
188
+ const properties = yield Promise.all(
189
+ doc.entries.map((entry) => mapProperty(entry, renderMarkdown))
190
+ );
191
+ return {
192
+ type: "mdxJsxFlowElement",
193
+ name: outputName,
194
+ attributes: [
195
+ expressionToAttribute("type", {
196
+ type: "ObjectExpression",
197
+ properties
198
+ })
199
+ ],
200
+ data: {
201
+ // for Fumadocs `remarkStructure`
202
+ _string: [
203
+ doc.name,
204
+ doc.description,
205
+ ...doc.entries.flatMap((entry) => [
206
+ `${entry.name}: ${entry.type}`,
207
+ entry.description
208
+ ])
209
+ ]
210
+ },
211
+ children: []
212
+ };
213
+ }));
214
+ Object.assign(node, {
215
+ type: "root",
216
+ attributes: [],
217
+ children: yield Promise.all(rendered)
218
+ });
219
+ });
220
+ }
221
+ queue.push(run());
222
+ return "skip";
223
+ });
224
+ yield Promise.all(queue);
225
+ });
226
+ }
93
227
  export {
94
228
  generate,
95
229
  generateDocumentation,
96
230
  generateFiles,
97
231
  generateMDX,
98
232
  getProject,
233
+ remarkAutoTypeTable,
99
234
  renderMarkdownToHast
100
235
  };
@@ -1,4 +1,4 @@
1
- import { Project, ExportedDeclarations, Type, Symbol } from 'ts-morph';
1
+ import { Project, Type, ExportedDeclarations, Symbol } from 'ts-morph';
2
2
 
3
3
  interface TypescriptConfig {
4
4
  files?: string[];
@@ -18,6 +18,7 @@ interface DocEntry {
18
18
  description: string;
19
19
  type: string;
20
20
  tags: Record<string, string>;
21
+ required: boolean;
21
22
  }
22
23
  interface EntryContext {
23
24
  program: Project;
@@ -51,4 +52,43 @@ interface GenerateDocumentationOptions extends GenerateOptions {
51
52
  declare function generateDocumentation(file: string, name: string | undefined, content: string, options?: GenerateDocumentationOptions): GeneratedDoc[];
52
53
  declare function generate(program: Project, name: string, declaration: ExportedDeclarations, { allowInternal, transform }: GenerateOptions): GeneratedDoc;
53
54
 
54
- export { type DocEntry as D, type GenerateDocumentationOptions as G, type GeneratedDoc as a, type GenerateOptions as b, generateDocumentation as c, generate as d, getProject as g };
55
+ interface BaseTypeTableProps {
56
+ /**
57
+ * The path to source TypeScript file.
58
+ */
59
+ path?: string;
60
+ /**
61
+ * Exported type name to generate from.
62
+ */
63
+ name?: string;
64
+ /**
65
+ * Set the type to generate from.
66
+ *
67
+ * When used with `name`, it generates the type with `name` as export name.
68
+ *
69
+ * ```ts
70
+ * export const myName = MyType;
71
+ * ```
72
+ *
73
+ * When `type` contains multiple lines, `export const` is not added.
74
+ * You need to export it manually, and specify the type name with `name`.
75
+ *
76
+ * ```tsx
77
+ * <AutoTypeTable
78
+ * path="./file.ts"
79
+ * type={`import { ReactNode } from "react"
80
+ * export const MyName = ReactNode`}
81
+ * name="MyName"
82
+ * />
83
+ * ```
84
+ */
85
+ type?: string;
86
+ options?: GenerateDocumentationOptions & {
87
+ /**
88
+ * base path to resolve `path` prop
89
+ */
90
+ basePath?: string;
91
+ };
92
+ }
93
+
94
+ export { type BaseTypeTableProps as B, type DocEntry as D, type GenerateDocumentationOptions as G, type GeneratedDoc as a, type GenerateOptions as b, generateDocumentation as c, generate as d, getProject as g };
@@ -1,47 +1,22 @@
1
- import { G as GenerateDocumentationOptions } from '../base-BltLCalB.js';
1
+ import { B as BaseTypeTableProps, G as GenerateDocumentationOptions } from '../type-table-DyymKQK8.js';
2
+ import { ReactNode } from 'react';
2
3
  import 'ts-morph';
3
4
 
4
- interface AutoTypeTableProps {
5
+ interface AutoTypeTableProps extends BaseTypeTableProps {
5
6
  /**
6
- * The path to source TypeScript file.
7
+ * Override the function to render markdown into JSX nodes
7
8
  */
8
- path?: string;
9
- /**
10
- * Exported type name to generate from.
11
- */
12
- name?: string;
13
- /**
14
- * Set the type to generate from.
15
- *
16
- * When used with `name`, it generates the type with `name` as export name.
17
- *
18
- * ```ts
19
- * export const myName = MyType;
20
- * ```
21
- *
22
- * When `type` contains multiple lines, `export const` is not added.
23
- * You need to export it manually, and specify the type name with `name`.
24
- *
25
- * ```tsx
26
- * <AutoTypeTable
27
- * path="./file.ts"
28
- * type={`import { ReactNode } from "react"
29
- * export const MyName = ReactNode`}
30
- * name="MyName"
31
- * />
32
- * ```
33
- */
34
- type?: string;
35
- options?: GenerateDocumentationOptions;
9
+ renderMarkdown?: typeof renderMarkdownDefault;
36
10
  }
37
11
  declare function createTypeTable(options?: GenerateDocumentationOptions): {
38
- AutoTypeTable: (props: Omit<AutoTypeTableProps, 'options'>) => React.ReactNode;
12
+ AutoTypeTable: (props: Omit<AutoTypeTableProps, 'options'>) => ReactNode;
39
13
  };
40
14
  /**
41
15
  * **Server Component Only**
42
16
  *
43
17
  * Display properties in an exported interface via Type Table
44
18
  */
45
- declare function AutoTypeTable({ path, name, type, options, }: AutoTypeTableProps): Promise<React.ReactElement>;
19
+ declare function AutoTypeTable({ renderMarkdown, ...props }: AutoTypeTableProps): Promise<ReactNode>;
20
+ declare function renderMarkdownDefault(md: string): Promise<ReactNode>;
46
21
 
47
22
  export { AutoTypeTable, type AutoTypeTableProps, createTypeTable };
package/dist/ui/index.js CHANGED
@@ -1,58 +1,40 @@
1
1
  import {
2
2
  __async,
3
+ __objRest,
3
4
  __spreadProps,
4
5
  __spreadValues,
5
- generateDocumentation,
6
6
  getProject,
7
+ getTypeTableOutput,
7
8
  renderMarkdownToHast
8
- } from "../chunk-2L4CMRDQ.js";
9
+ } from "../chunk-LRCT2FYJ.js";
9
10
 
10
11
  // src/ui/auto-type-table.tsx
11
- import fs from "node:fs/promises";
12
12
  import { TypeTable } from "fumadocs-ui/components/type-table";
13
13
  import { toJsxRuntime } from "hast-util-to-jsx-runtime";
14
14
  import * as runtime from "react/jsx-runtime";
15
15
  import defaultMdxComponents from "fumadocs-ui/mdx";
16
16
  import "server-only";
17
- import { Fragment as Fragment2, jsx as jsx2 } from "react/jsx-runtime";
17
+ import { jsx as jsx2 } from "react/jsx-runtime";
18
18
  function createTypeTable(options = {}) {
19
19
  var _a;
20
- const project = (_a = options.project) != null ? _a : getProject(options.config);
20
+ const overrideOptions = __spreadProps(__spreadValues({}, options), {
21
+ project: (_a = options.project) != null ? _a : getProject(options.config)
22
+ });
21
23
  return {
22
24
  AutoTypeTable(props) {
23
- return /* @__PURE__ */ jsx2(AutoTypeTable, __spreadProps(__spreadValues({}, props), { options: __spreadProps(__spreadValues({}, options), { project }) }));
25
+ return /* @__PURE__ */ jsx2(AutoTypeTable, __spreadProps(__spreadValues({}, props), { options: overrideOptions }));
24
26
  }
25
27
  };
26
28
  }
27
- function AutoTypeTable(_0) {
28
- return __async(this, arguments, function* ({
29
- path,
30
- name,
31
- type,
32
- options = {}
33
- }) {
34
- let typeName = name;
35
- let content = "";
36
- if (path) {
37
- content = yield fs.readFile(path).then((res) => res.toString());
38
- }
39
- if (type && type.split("\n").length > 1) {
40
- content += `
41
- ${type}`;
42
- } else if (type) {
43
- typeName != null ? typeName : typeName = "$Fumadocs";
44
- content += `
45
- export type ${typeName} = ${type}`;
46
- }
47
- const output = generateDocumentation(
48
- path != null ? path : "temp.ts",
49
- typeName,
50
- content,
51
- options
52
- );
53
- if (name && output.length === 0)
54
- throw new Error(`${name} in ${path != null ? path : "empty file"} doesn't exist`);
55
- return /* @__PURE__ */ jsx2(Fragment2, { children: output.map((item) => __async(this, null, function* () {
29
+ function AutoTypeTable(_a) {
30
+ return __async(this, null, function* () {
31
+ var _b = _a, {
32
+ renderMarkdown = renderMarkdownDefault
33
+ } = _b, props = __objRest(_b, [
34
+ "renderMarkdown"
35
+ ]);
36
+ const output = yield getTypeTableOutput(props);
37
+ return output.map((item) => __async(this, null, function* () {
56
38
  const entries = item.entries.map(
57
39
  (entry) => __async(this, null, function* () {
58
40
  return [
@@ -60,7 +42,8 @@ export type ${typeName} = ${type}`;
60
42
  {
61
43
  type: entry.type,
62
44
  description: yield renderMarkdown(entry.description),
63
- default: entry.tags.default || entry.tags.defaultValue
45
+ default: entry.tags.default || entry.tags.defaultValue,
46
+ required: entry.required
64
47
  }
65
48
  ];
66
49
  })
@@ -72,10 +55,10 @@ export type ${typeName} = ${type}`;
72
55
  },
73
56
  item.name
74
57
  );
75
- })) });
58
+ }));
76
59
  });
77
60
  }
78
- function renderMarkdown(md) {
61
+ function renderMarkdownDefault(md) {
79
62
  return __async(this, null, function* () {
80
63
  return toJsxRuntime(yield renderMarkdownToHast(md), {
81
64
  Fragment: runtime.Fragment,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-typescript",
3
- "version": "3.0.3",
3
+ "version": "3.1.0",
4
4
  "description": "Typescript Integration for Fumadocs",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -28,24 +28,29 @@
28
28
  "dist/*"
29
29
  ],
30
30
  "dependencies": {
31
+ "estree-util-value-to-estree": "^3.3.2",
31
32
  "fast-glob": "^3.3.3",
32
- "hast-util-to-jsx-runtime": "^2.3.2",
33
- "mdast-util-from-markdown": "^2.0.2",
34
- "mdast-util-gfm": "^3.0.0",
35
- "mdast-util-to-hast": "^13.2.0",
36
- "shiki": "^2.0.3",
37
- "ts-morph": "^25.0.0"
33
+ "hast-util-to-estree": "^3.1.2",
34
+ "hast-util-to-jsx-runtime": "^2.3.5",
35
+ "remark": "^15.0.1",
36
+ "remark-rehype": "^11.1.1",
37
+ "shiki": "^3.1.0",
38
+ "ts-morph": "^25.0.1",
39
+ "unist-util-visit": "^5.0.0"
38
40
  },
39
41
  "devDependencies": {
42
+ "@mdx-js/mdx": "^3.1.0",
40
43
  "@types/estree": "^1.0.6",
41
44
  "@types/hast": "^3.0.4",
42
45
  "@types/mdast": "^4.0.3",
43
- "@types/node": "22.10.7",
44
- "@types/react": "19.0.7",
45
- "@types/react-dom": "19.0.3",
46
- "typescript": "^5.7.3",
46
+ "@types/node": "22.13.8",
47
+ "@types/react": "19.0.10",
48
+ "@types/react-dom": "19.0.4",
49
+ "typescript": "^5.8.2",
50
+ "unified": "^11.0.5",
47
51
  "eslint-config-custom": "0.0.0",
48
- "fumadocs-ui": "14.7.6",
52
+ "fumadocs-core": "15.0.14",
53
+ "fumadocs-ui": "15.0.14",
49
54
  "tsconfig": "0.0.0"
50
55
  },
51
56
  "peerDependencies": {