fumadocs-typescript 2.1.0 → 3.0.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.
- package/dist/{base-CqMIWAcs.d.ts → base-BltLCalB.d.ts} +11 -17
- package/dist/chunk-XZ3O77SF.js +200 -0
- package/dist/index.d.ts +7 -8
- package/dist/index.js +21 -29
- package/dist/ui/index.d.ts +40 -8
- package/dist/ui/index.js +76 -28
- package/package.json +11 -15
- package/dist/chunk-HGR3BUTN.js +0 -162
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Project, ExportedDeclarations, Type, Symbol } from 'ts-morph';
|
|
2
2
|
|
|
3
3
|
interface TypescriptConfig {
|
|
4
4
|
files?: string[];
|
|
5
5
|
tsconfigPath?: string;
|
|
6
6
|
/** A root directory to resolve relative path entries in the config file to. e.g. outDir */
|
|
7
7
|
basePath?: string;
|
|
8
|
-
/**
|
|
9
|
-
* Default lib directory, use `./node_modules/typescript/lib` if not specified
|
|
10
|
-
*/
|
|
11
|
-
getDefaultLibLocation?: (() => string) | 'default';
|
|
12
8
|
}
|
|
13
|
-
declare function
|
|
9
|
+
declare function getProject(options?: TypescriptConfig): Project;
|
|
14
10
|
|
|
15
11
|
interface GeneratedDoc {
|
|
16
12
|
name: string;
|
|
@@ -24,13 +20,12 @@ interface DocEntry {
|
|
|
24
20
|
tags: Record<string, string>;
|
|
25
21
|
}
|
|
26
22
|
interface EntryContext {
|
|
27
|
-
program:
|
|
28
|
-
checker: ts.TypeChecker;
|
|
23
|
+
program: Project;
|
|
29
24
|
transform?: Transformer;
|
|
30
|
-
type:
|
|
31
|
-
|
|
25
|
+
type: Type;
|
|
26
|
+
declaration: ExportedDeclarations;
|
|
32
27
|
}
|
|
33
|
-
type Transformer = (this: EntryContext, entry: DocEntry, propertyType:
|
|
28
|
+
type Transformer = (this: EntryContext, entry: DocEntry, propertyType: Type, propertySymbol: Symbol) => void;
|
|
34
29
|
interface GenerateOptions {
|
|
35
30
|
/**
|
|
36
31
|
* Allow fields with `@internal` tag
|
|
@@ -47,14 +42,13 @@ interface GenerateDocumentationOptions extends GenerateOptions {
|
|
|
47
42
|
/**
|
|
48
43
|
* Typescript configurations
|
|
49
44
|
*/
|
|
50
|
-
config?: TypescriptConfig
|
|
51
|
-
|
|
52
|
-
};
|
|
45
|
+
config?: TypescriptConfig;
|
|
46
|
+
project?: Project;
|
|
53
47
|
}
|
|
54
48
|
/**
|
|
55
49
|
* Generate documentation for properties in an exported type/interface
|
|
56
50
|
*/
|
|
57
|
-
declare function generateDocumentation(file: string, name: string, options?: GenerateDocumentationOptions): GeneratedDoc
|
|
58
|
-
declare function generate(program:
|
|
51
|
+
declare function generateDocumentation(file: string, name: string | undefined, content: string, options?: GenerateDocumentationOptions): GeneratedDoc[];
|
|
52
|
+
declare function generate(program: Project, name: string, declaration: ExportedDeclarations, { allowInternal, transform }: GenerateOptions): GeneratedDoc;
|
|
59
53
|
|
|
60
|
-
export { type DocEntry as D, type
|
|
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 };
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __objRest = (source, exclude) => {
|
|
21
|
+
var target = {};
|
|
22
|
+
for (var prop in source)
|
|
23
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
24
|
+
target[prop] = source[prop];
|
|
25
|
+
if (source != null && __getOwnPropSymbols)
|
|
26
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
27
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
}
|
|
30
|
+
return target;
|
|
31
|
+
};
|
|
32
|
+
var __async = (__this, __arguments, generator) => {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
var fulfilled = (value) => {
|
|
35
|
+
try {
|
|
36
|
+
step(generator.next(value));
|
|
37
|
+
} catch (e) {
|
|
38
|
+
reject(e);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
var rejected = (value) => {
|
|
42
|
+
try {
|
|
43
|
+
step(generator.throw(value));
|
|
44
|
+
} catch (e) {
|
|
45
|
+
reject(e);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
49
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// src/get-project.ts
|
|
54
|
+
import { Project } from "ts-morph";
|
|
55
|
+
function getProject(options = {}) {
|
|
56
|
+
var _a;
|
|
57
|
+
return new Project({
|
|
58
|
+
tsConfigFilePath: (_a = options.tsconfigPath) != null ? _a : "./tsconfig.json",
|
|
59
|
+
skipAddingFilesFromTsConfig: true
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/generate/base.ts
|
|
64
|
+
import {
|
|
65
|
+
ts
|
|
66
|
+
} from "ts-morph";
|
|
67
|
+
function generateDocumentation(file, name, content, options = {}) {
|
|
68
|
+
var _a;
|
|
69
|
+
const project = (_a = options.project) != null ? _a : getProject(options.config);
|
|
70
|
+
const sourceFile = project.createSourceFile(file, content, {
|
|
71
|
+
overwrite: true
|
|
72
|
+
});
|
|
73
|
+
const out = [];
|
|
74
|
+
for (const [k, d] of sourceFile.getExportedDeclarations()) {
|
|
75
|
+
if (name && name !== k) continue;
|
|
76
|
+
if (d.length > 1)
|
|
77
|
+
console.warn(
|
|
78
|
+
`export ${k} should not have more than one type declaration.`
|
|
79
|
+
);
|
|
80
|
+
out.push(generate(project, k, d[0], options));
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
function generate(program, name, declaration, { allowInternal = false, transform }) {
|
|
85
|
+
var _a;
|
|
86
|
+
const entryContext = {
|
|
87
|
+
transform,
|
|
88
|
+
program,
|
|
89
|
+
type: declaration.getType(),
|
|
90
|
+
declaration
|
|
91
|
+
};
|
|
92
|
+
const comment = (_a = declaration.getSymbol()) == null ? void 0 : _a.compilerSymbol.getDocumentationComment(
|
|
93
|
+
program.getTypeChecker().compilerObject
|
|
94
|
+
);
|
|
95
|
+
return {
|
|
96
|
+
name,
|
|
97
|
+
description: comment ? ts.displayPartsToString(comment) : "",
|
|
98
|
+
entries: declaration.getType().getProperties().map((prop) => getDocEntry(prop, entryContext)).filter((entry) => allowInternal || !("internal" in entry.tags))
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function getDocEntry(prop, context) {
|
|
102
|
+
var _a, _b, _c, _d;
|
|
103
|
+
const { transform, program } = context;
|
|
104
|
+
const subType = program.getTypeChecker().getTypeOfSymbolAtLocation(prop, context.declaration);
|
|
105
|
+
const tags = Object.fromEntries(
|
|
106
|
+
prop.getJsDocTags().map((tag) => [tag.getName(), ts.displayPartsToString(tag.getText())])
|
|
107
|
+
);
|
|
108
|
+
let typeName = subType.getNonNullableType().getText(void 0, ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope);
|
|
109
|
+
if (subType.getAliasSymbol() && subType.getAliasTypeArguments().length === 0) {
|
|
110
|
+
typeName = (_b = (_a = subType.getAliasSymbol()) == null ? void 0 : _a.getEscapedName()) != null ? _b : typeName;
|
|
111
|
+
}
|
|
112
|
+
if ("remarks" in tags) {
|
|
113
|
+
typeName = (_d = (_c = new RegExp("^`(?<name>.+)`").exec(tags.remarks)) == null ? void 0 : _c[1]) != null ? _d : typeName;
|
|
114
|
+
}
|
|
115
|
+
const entry = {
|
|
116
|
+
name: prop.getName(),
|
|
117
|
+
description: ts.displayPartsToString(
|
|
118
|
+
prop.compilerSymbol.getDocumentationComment(
|
|
119
|
+
program.getTypeChecker().compilerObject
|
|
120
|
+
)
|
|
121
|
+
),
|
|
122
|
+
tags,
|
|
123
|
+
type: typeName
|
|
124
|
+
};
|
|
125
|
+
transform == null ? void 0 : transform.call(context, entry, subType, prop);
|
|
126
|
+
return entry;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/markdown.ts
|
|
130
|
+
import { fromMarkdown } from "mdast-util-from-markdown";
|
|
131
|
+
import { gfmFromMarkdown } from "mdast-util-gfm";
|
|
132
|
+
import { toHast } from "mdast-util-to-hast";
|
|
133
|
+
import { getSingletonHighlighter } from "shiki";
|
|
134
|
+
function renderMarkdownToHast(md) {
|
|
135
|
+
return __async(this, null, function* () {
|
|
136
|
+
const mdast = fromMarkdown(
|
|
137
|
+
md.replace(new RegExp("{@link (?<link>[^}]*)}", "g"), "$1"),
|
|
138
|
+
// replace jsdoc links
|
|
139
|
+
{ mdastExtensions: [gfmFromMarkdown()] }
|
|
140
|
+
);
|
|
141
|
+
const highlighter = yield getSingletonHighlighter({
|
|
142
|
+
themes: ["vitesse-light", "vitesse-dark"]
|
|
143
|
+
});
|
|
144
|
+
function preload(contents) {
|
|
145
|
+
return __async(this, null, function* () {
|
|
146
|
+
yield Promise.all(
|
|
147
|
+
contents.map((c) => __async(this, null, function* () {
|
|
148
|
+
if ("children" in c) yield preload(c.children);
|
|
149
|
+
if (c.type === "code" && c.lang) {
|
|
150
|
+
yield highlighter.loadLanguage(
|
|
151
|
+
c.lang
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}))
|
|
155
|
+
);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
yield preload(mdast.children);
|
|
159
|
+
return toHast(mdast, {
|
|
160
|
+
handlers: {
|
|
161
|
+
// @ts-expect-error hast with mdx
|
|
162
|
+
code(_, node) {
|
|
163
|
+
var _a;
|
|
164
|
+
const lang = (_a = node.lang) != null ? _a : "plaintext";
|
|
165
|
+
return highlighter.codeToHast(node.value, {
|
|
166
|
+
lang,
|
|
167
|
+
themes: {
|
|
168
|
+
light: "vitesse-light",
|
|
169
|
+
dark: "vitesse-dark"
|
|
170
|
+
},
|
|
171
|
+
defaultColor: false,
|
|
172
|
+
transformers: [
|
|
173
|
+
{
|
|
174
|
+
name: "rehype-code:pre-process",
|
|
175
|
+
line(hast) {
|
|
176
|
+
if (hast.children.length > 0) return;
|
|
177
|
+
hast.children.push({
|
|
178
|
+
type: "text",
|
|
179
|
+
value: " "
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
}).children;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export {
|
|
192
|
+
__spreadValues,
|
|
193
|
+
__spreadProps,
|
|
194
|
+
__objRest,
|
|
195
|
+
__async,
|
|
196
|
+
getProject,
|
|
197
|
+
generateDocumentation,
|
|
198
|
+
generate,
|
|
199
|
+
renderMarkdownToHast
|
|
200
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
import { G as
|
|
2
|
-
export { b as
|
|
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';
|
|
3
3
|
import fg from 'fast-glob';
|
|
4
4
|
import { Nodes } from 'hast';
|
|
5
|
-
import '
|
|
5
|
+
import 'ts-morph';
|
|
6
6
|
|
|
7
7
|
interface Templates {
|
|
8
8
|
block: (doc: GeneratedDoc, children: string) => string;
|
|
9
9
|
property: (entry: DocEntry) => string;
|
|
10
10
|
}
|
|
11
|
-
interface GenerateMDXOptions extends
|
|
11
|
+
interface GenerateMDXOptions extends GenerateDocumentationOptions {
|
|
12
12
|
/**
|
|
13
13
|
* a root directory to resolve relative file paths
|
|
14
14
|
*/
|
|
15
15
|
basePath?: string;
|
|
16
16
|
templates?: Partial<Templates>;
|
|
17
|
-
config?: TypescriptConfig;
|
|
18
17
|
}
|
|
19
|
-
declare function generateMDX(source: string, { basePath, templates: overrides,
|
|
18
|
+
declare function generateMDX(source: string, { basePath, templates: overrides, ...rest }?: GenerateMDXOptions): string;
|
|
20
19
|
|
|
21
20
|
interface GenerateFilesOptions {
|
|
22
21
|
input: string | string[];
|
|
@@ -33,6 +32,6 @@ interface GenerateFilesOptions {
|
|
|
33
32
|
}
|
|
34
33
|
declare function generateFiles(options: GenerateFilesOptions): Promise<void>;
|
|
35
34
|
|
|
36
|
-
declare function renderMarkdownToHast(md: string): Nodes
|
|
35
|
+
declare function renderMarkdownToHast(md: string): Promise<Nodes>;
|
|
37
36
|
|
|
38
|
-
export { DocEntry, type GenerateFilesOptions, type GenerateMDXOptions,
|
|
37
|
+
export { DocEntry, GenerateDocumentationOptions, type GenerateFilesOptions, type GenerateMDXOptions, GeneratedDoc, generateFiles, generateMDX, renderMarkdownToHast };
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__async,
|
|
3
3
|
__objRest,
|
|
4
|
+
__spreadProps,
|
|
4
5
|
__spreadValues,
|
|
5
6
|
generate,
|
|
6
7
|
generateDocumentation,
|
|
7
|
-
|
|
8
|
-
getProgram,
|
|
8
|
+
getProject,
|
|
9
9
|
renderMarkdownToHast
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-XZ3O77SF.js";
|
|
11
11
|
|
|
12
12
|
// src/generate/mdx.ts
|
|
13
|
-
import * as path from "path";
|
|
13
|
+
import * as path from "node:path";
|
|
14
|
+
import fs from "node:fs";
|
|
14
15
|
var regex = new RegExp("^---type-table---\\r?\\n(?<file>.+?)(?:#(?<name>.+))?\\r?\\n---end---$", "gm");
|
|
15
16
|
var defaultTemplates = {
|
|
16
17
|
block: (doc, c) => `### ${doc.name}
|
|
@@ -33,30 +34,17 @@ ${replaceJsDocLinks(value)}`).join("\n")}
|
|
|
33
34
|
</div>`
|
|
34
35
|
};
|
|
35
36
|
function generateMDX(source, _a = {}) {
|
|
36
|
-
var _b = _a, {
|
|
37
|
-
|
|
38
|
-
templates: overrides,
|
|
39
|
-
config: options
|
|
40
|
-
} = _b, rest = __objRest(_b, [
|
|
41
|
-
"basePath",
|
|
42
|
-
"templates",
|
|
43
|
-
"config"
|
|
44
|
-
]);
|
|
37
|
+
var _b = _a, { basePath = "./", templates: overrides } = _b, rest = __objRest(_b, ["basePath", "templates"]);
|
|
38
|
+
var _a2;
|
|
45
39
|
const templates = __spreadValues(__spreadValues({}, defaultTemplates), overrides);
|
|
46
|
-
const
|
|
40
|
+
const project = (_a2 = rest.project) != null ? _a2 : getProject(rest.config);
|
|
47
41
|
return source.replace(regex, (...args) => {
|
|
48
42
|
const groups = args[args.length - 1];
|
|
49
43
|
const file = path.resolve(basePath, groups.file);
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
docs = program.getTypeChecker().getExportsOfModule(fileSymbol).map((symbol) => generate(program, symbol, rest));
|
|
55
|
-
} else {
|
|
56
|
-
const symbol = program.getTypeChecker().getExportsOfModule(fileSymbol).find((s) => s.getEscapedName().toString() === groups.name);
|
|
57
|
-
if (!symbol) throw new Error(`Type ${groups.name} doesn't exist`);
|
|
58
|
-
docs = [generate(program, symbol, rest)];
|
|
59
|
-
}
|
|
44
|
+
const content = fs.readFileSync(file);
|
|
45
|
+
const docs = generateDocumentation(file, groups.name, content.toString(), __spreadProps(__spreadValues({}, rest), {
|
|
46
|
+
project
|
|
47
|
+
}));
|
|
60
48
|
return docs.map(
|
|
61
49
|
(doc) => templates.block(doc, doc.entries.map(templates.property).join("\n"))
|
|
62
50
|
).join("\n\n");
|
|
@@ -67,12 +55,14 @@ function replaceJsDocLinks(md) {
|
|
|
67
55
|
}
|
|
68
56
|
|
|
69
57
|
// src/generate/file.ts
|
|
70
|
-
import * as path2 from "path";
|
|
71
|
-
import { mkdir, writeFile, readFile } from "fs/promises";
|
|
58
|
+
import * as path2 from "node:path";
|
|
59
|
+
import { mkdir, writeFile, readFile } from "node:fs/promises";
|
|
72
60
|
import fg from "fast-glob";
|
|
73
61
|
function generateFiles(options) {
|
|
74
62
|
return __async(this, null, function* () {
|
|
63
|
+
var _a, _b, _c;
|
|
75
64
|
const files = yield fg(options.input, options.globOptions);
|
|
65
|
+
const project = (_c = (_a = options.options) == null ? void 0 : _a.project) != null ? _c : getProject((_b = options.options) == null ? void 0 : _b.config);
|
|
76
66
|
const produce = files.map((file) => __async(this, null, function* () {
|
|
77
67
|
const absolutePath = path2.resolve(file);
|
|
78
68
|
const outputPath = typeof options.output === "function" ? options.output(file) : path2.resolve(
|
|
@@ -80,9 +70,11 @@ function generateFiles(options) {
|
|
|
80
70
|
`${path2.basename(file, path2.extname(file))}.mdx`
|
|
81
71
|
);
|
|
82
72
|
const content = (yield readFile(absolutePath)).toString();
|
|
83
|
-
let result = generateMDX(content, __spreadValues({
|
|
73
|
+
let result = generateMDX(content, __spreadProps(__spreadValues({
|
|
84
74
|
basePath: path2.dirname(absolutePath)
|
|
85
|
-
}, options.options)
|
|
75
|
+
}, options.options), {
|
|
76
|
+
project
|
|
77
|
+
}));
|
|
86
78
|
if (options.transformOutput) {
|
|
87
79
|
result = options.transformOutput(outputPath, result);
|
|
88
80
|
}
|
|
@@ -103,6 +95,6 @@ export {
|
|
|
103
95
|
generateDocumentation,
|
|
104
96
|
generateFiles,
|
|
105
97
|
generateMDX,
|
|
106
|
-
|
|
98
|
+
getProject,
|
|
107
99
|
renderMarkdownToHast
|
|
108
100
|
};
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -1,15 +1,47 @@
|
|
|
1
|
-
import { G as
|
|
2
|
-
import '
|
|
1
|
+
import { G as GenerateDocumentationOptions } from '../base-BltLCalB.js';
|
|
2
|
+
import 'ts-morph';
|
|
3
3
|
|
|
4
|
+
interface AutoTypeTableProps {
|
|
5
|
+
/**
|
|
6
|
+
* The path to source TypeScript file.
|
|
7
|
+
*/
|
|
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;
|
|
36
|
+
}
|
|
37
|
+
declare function createTypeTable(options?: GenerateDocumentationOptions): {
|
|
38
|
+
AutoTypeTable: (props: Omit<AutoTypeTableProps, 'options'>) => React.ReactNode;
|
|
39
|
+
};
|
|
4
40
|
/**
|
|
5
41
|
* **Server Component Only**
|
|
6
42
|
*
|
|
7
43
|
* Display properties in an exported interface via Type Table
|
|
8
44
|
*/
|
|
9
|
-
declare function AutoTypeTable({ path, name, options, }:
|
|
10
|
-
path: string;
|
|
11
|
-
name: string;
|
|
12
|
-
options?: GenerateOptions;
|
|
13
|
-
}): React.ReactElement;
|
|
45
|
+
declare function AutoTypeTable({ path, name, type, options, }: AutoTypeTableProps): Promise<React.ReactElement>;
|
|
14
46
|
|
|
15
|
-
export { AutoTypeTable };
|
|
47
|
+
export { AutoTypeTable, type AutoTypeTableProps, createTypeTable };
|
package/dist/ui/index.js
CHANGED
|
@@ -1,44 +1,92 @@
|
|
|
1
1
|
import {
|
|
2
|
+
__async,
|
|
3
|
+
__spreadProps,
|
|
4
|
+
__spreadValues,
|
|
2
5
|
generateDocumentation,
|
|
6
|
+
getProject,
|
|
3
7
|
renderMarkdownToHast
|
|
4
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-XZ3O77SF.js";
|
|
5
9
|
|
|
6
10
|
// src/ui/auto-type-table.tsx
|
|
11
|
+
import fs from "node:fs/promises";
|
|
7
12
|
import { TypeTable } from "fumadocs-ui/components/type-table";
|
|
8
13
|
import { toJsxRuntime } from "hast-util-to-jsx-runtime";
|
|
9
14
|
import * as runtime from "react/jsx-runtime";
|
|
15
|
+
import defaultMdxComponents from "fumadocs-ui/mdx";
|
|
10
16
|
import "server-only";
|
|
11
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (!output) throw new Error(`${name} in ${path} doesn't exist`);
|
|
19
|
-
return /* @__PURE__ */ jsx2(
|
|
20
|
-
TypeTable,
|
|
21
|
-
{
|
|
22
|
-
type: Object.fromEntries(
|
|
23
|
-
output.entries.map((entry) => [
|
|
24
|
-
entry.name,
|
|
25
|
-
{
|
|
26
|
-
type: entry.type,
|
|
27
|
-
description: renderMarkdown(entry.description),
|
|
28
|
-
default: entry.tags.default || entry.tags.defaultValue
|
|
29
|
-
}
|
|
30
|
-
])
|
|
31
|
-
)
|
|
17
|
+
import { Fragment as Fragment2, jsx as jsx2 } from "react/jsx-runtime";
|
|
18
|
+
function createTypeTable(options = {}) {
|
|
19
|
+
var _a;
|
|
20
|
+
const project = (_a = options.project) != null ? _a : getProject(options.config);
|
|
21
|
+
return {
|
|
22
|
+
AutoTypeTable(props) {
|
|
23
|
+
return /* @__PURE__ */ jsx2(AutoTypeTable, __spreadProps(__spreadValues({}, props), { options: __spreadProps(__spreadValues({}, options), { project }) }));
|
|
32
24
|
}
|
|
33
|
-
|
|
25
|
+
};
|
|
26
|
+
}
|
|
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* () {
|
|
56
|
+
const entries = item.entries.map(
|
|
57
|
+
(entry) => __async(this, null, function* () {
|
|
58
|
+
return [
|
|
59
|
+
entry.name,
|
|
60
|
+
{
|
|
61
|
+
type: entry.type,
|
|
62
|
+
description: yield renderMarkdown(entry.description),
|
|
63
|
+
default: entry.tags.default || entry.tags.defaultValue
|
|
64
|
+
}
|
|
65
|
+
];
|
|
66
|
+
})
|
|
67
|
+
);
|
|
68
|
+
return /* @__PURE__ */ jsx2(
|
|
69
|
+
TypeTable,
|
|
70
|
+
{
|
|
71
|
+
type: Object.fromEntries(yield Promise.all(entries))
|
|
72
|
+
},
|
|
73
|
+
item.name
|
|
74
|
+
);
|
|
75
|
+
})) });
|
|
76
|
+
});
|
|
34
77
|
}
|
|
35
78
|
function renderMarkdown(md) {
|
|
36
|
-
return
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
79
|
+
return __async(this, null, function* () {
|
|
80
|
+
return toJsxRuntime(yield renderMarkdownToHast(md), {
|
|
81
|
+
Fragment: runtime.Fragment,
|
|
82
|
+
jsx: runtime.jsx,
|
|
83
|
+
jsxs: runtime.jsxs,
|
|
84
|
+
// @ts-expect-error -- mdx components
|
|
85
|
+
components: __spreadProps(__spreadValues({}, defaultMdxComponents), { img: void 0 })
|
|
86
|
+
});
|
|
40
87
|
});
|
|
41
88
|
}
|
|
42
89
|
export {
|
|
43
|
-
AutoTypeTable
|
|
90
|
+
AutoTypeTable,
|
|
91
|
+
createTypeTable
|
|
44
92
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-typescript",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Typescript Integration for Fumadocs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NextJs",
|
|
@@ -24,32 +24,28 @@
|
|
|
24
24
|
},
|
|
25
25
|
"main": "./dist/index.js",
|
|
26
26
|
"types": "./dist/index.d.ts",
|
|
27
|
-
"typesVersions": {
|
|
28
|
-
"*": {
|
|
29
|
-
"ui": [
|
|
30
|
-
"./dist/ui/index.d.ts"
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
27
|
"files": [
|
|
35
28
|
"dist/*"
|
|
36
29
|
],
|
|
37
30
|
"dependencies": {
|
|
31
|
+
"@types/node": "22.7.7",
|
|
38
32
|
"fast-glob": "^3.3.1",
|
|
39
|
-
"hast-util-to-jsx-runtime": "^2.3.
|
|
33
|
+
"hast-util-to-jsx-runtime": "^2.3.2",
|
|
40
34
|
"mdast-util-from-markdown": "^2.0.1",
|
|
41
35
|
"mdast-util-gfm": "^3.0.0",
|
|
42
|
-
"mdast-util-to-hast": "^13.2.0"
|
|
36
|
+
"mdast-util-to-hast": "^13.2.0",
|
|
37
|
+
"shiki": "^1.22.0",
|
|
38
|
+
"ts-morph": "^24.0.0"
|
|
43
39
|
},
|
|
44
40
|
"devDependencies": {
|
|
45
|
-
"@types/estree": "^1.0.
|
|
41
|
+
"@types/estree": "^1.0.6",
|
|
46
42
|
"@types/hast": "^3.0.4",
|
|
47
43
|
"@types/mdast": "^4.0.3",
|
|
48
|
-
"@types/react": "18.3.
|
|
49
|
-
"@types/react-dom": "18.3.
|
|
50
|
-
"typescript": "^5.
|
|
44
|
+
"@types/react": "18.3.11",
|
|
45
|
+
"@types/react-dom": "18.3.1",
|
|
46
|
+
"typescript": "^5.6.3",
|
|
51
47
|
"eslint-config-custom": "0.0.0",
|
|
52
|
-
"fumadocs-ui": "
|
|
48
|
+
"fumadocs-ui": "14.0.0",
|
|
53
49
|
"tsconfig": "0.0.0"
|
|
54
50
|
},
|
|
55
51
|
"peerDependencies": {
|
package/dist/chunk-HGR3BUTN.js
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
-
var __spreadValues = (a, b) => {
|
|
7
|
-
for (var prop in b || (b = {}))
|
|
8
|
-
if (__hasOwnProp.call(b, prop))
|
|
9
|
-
__defNormalProp(a, prop, b[prop]);
|
|
10
|
-
if (__getOwnPropSymbols)
|
|
11
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
-
if (__propIsEnum.call(b, prop))
|
|
13
|
-
__defNormalProp(a, prop, b[prop]);
|
|
14
|
-
}
|
|
15
|
-
return a;
|
|
16
|
-
};
|
|
17
|
-
var __objRest = (source, exclude) => {
|
|
18
|
-
var target = {};
|
|
19
|
-
for (var prop in source)
|
|
20
|
-
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
21
|
-
target[prop] = source[prop];
|
|
22
|
-
if (source != null && __getOwnPropSymbols)
|
|
23
|
-
for (var prop of __getOwnPropSymbols(source)) {
|
|
24
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
25
|
-
target[prop] = source[prop];
|
|
26
|
-
}
|
|
27
|
-
return target;
|
|
28
|
-
};
|
|
29
|
-
var __async = (__this, __arguments, generator) => {
|
|
30
|
-
return new Promise((resolve2, reject) => {
|
|
31
|
-
var fulfilled = (value) => {
|
|
32
|
-
try {
|
|
33
|
-
step(generator.next(value));
|
|
34
|
-
} catch (e) {
|
|
35
|
-
reject(e);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var rejected = (value) => {
|
|
39
|
-
try {
|
|
40
|
-
step(generator.throw(value));
|
|
41
|
-
} catch (e) {
|
|
42
|
-
reject(e);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
var step = (x) => x.done ? resolve2(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
46
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
47
|
-
});
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// src/program.ts
|
|
51
|
-
import * as path from "path";
|
|
52
|
-
import ts from "typescript";
|
|
53
|
-
function getFileSymbol(file, program) {
|
|
54
|
-
const checker = program.getTypeChecker();
|
|
55
|
-
const sourceFile = program.getSourceFile(file);
|
|
56
|
-
if (!sourceFile) return;
|
|
57
|
-
return checker.getSymbolAtLocation(sourceFile);
|
|
58
|
-
}
|
|
59
|
-
function getProgram(options = {}) {
|
|
60
|
-
var _a, _b, _c, _d;
|
|
61
|
-
const configFile = ts.readJsonConfigFile(
|
|
62
|
-
(_a = options.tsconfigPath) != null ? _a : "./tsconfig.json",
|
|
63
|
-
(p) => ts.sys.readFile(p)
|
|
64
|
-
);
|
|
65
|
-
const parsed = ts.parseJsonSourceFileConfigFileContent(
|
|
66
|
-
configFile,
|
|
67
|
-
ts.sys,
|
|
68
|
-
(_b = options.basePath) != null ? _b : "./"
|
|
69
|
-
);
|
|
70
|
-
parsed.options.incremental = false;
|
|
71
|
-
const host = ts.createCompilerHost(parsed.options);
|
|
72
|
-
if (options.getDefaultLibLocation !== "default") {
|
|
73
|
-
host.getDefaultLibLocation = (_c = options.getDefaultLibLocation) != null ? _c : () => path.resolve("./node_modules/typescript/lib");
|
|
74
|
-
}
|
|
75
|
-
return ts.createProgram({
|
|
76
|
-
rootNames: (_d = options.files) != null ? _d : parsed.fileNames,
|
|
77
|
-
host,
|
|
78
|
-
options: parsed.options,
|
|
79
|
-
configFileParsingDiagnostics: parsed.errors,
|
|
80
|
-
projectReferences: parsed.projectReferences
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// src/generate/base.ts
|
|
85
|
-
import ts2 from "typescript";
|
|
86
|
-
function generateDocumentation(file, name, options = {}) {
|
|
87
|
-
const program = options.config && "program" in options.config ? options.config.program : getProgram(options.config);
|
|
88
|
-
const fileSymbol = getFileSymbol(file, program);
|
|
89
|
-
if (!fileSymbol) return;
|
|
90
|
-
const symbol = program.getTypeChecker().getExportsOfModule(fileSymbol).find((e) => e.getEscapedName().toString() === name);
|
|
91
|
-
if (!symbol) return;
|
|
92
|
-
return generate(program, symbol, options);
|
|
93
|
-
}
|
|
94
|
-
function generate(program, symbol, { allowInternal = false, transform }) {
|
|
95
|
-
const checker = program.getTypeChecker();
|
|
96
|
-
const type = checker.getDeclaredTypeOfSymbol(symbol);
|
|
97
|
-
const entryContext = {
|
|
98
|
-
checker,
|
|
99
|
-
transform,
|
|
100
|
-
program,
|
|
101
|
-
type,
|
|
102
|
-
symbol
|
|
103
|
-
};
|
|
104
|
-
return {
|
|
105
|
-
name: symbol.getEscapedName().toString(),
|
|
106
|
-
description: ts2.displayPartsToString(
|
|
107
|
-
symbol.getDocumentationComment(checker)
|
|
108
|
-
),
|
|
109
|
-
entries: type.getProperties().map((prop) => getDocEntry(prop, entryContext)).filter((entry) => allowInternal || !("internal" in entry.tags))
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
function getDocEntry(prop, context) {
|
|
113
|
-
var _a, _b;
|
|
114
|
-
const { checker, transform } = context;
|
|
115
|
-
const subType = checker.getTypeOfSymbol(prop);
|
|
116
|
-
const tags = Object.fromEntries(
|
|
117
|
-
prop.getJsDocTags().map((tag) => [tag.name, ts2.displayPartsToString(tag.text)])
|
|
118
|
-
);
|
|
119
|
-
let typeName = checker.typeToString(
|
|
120
|
-
subType.getNonNullableType(),
|
|
121
|
-
void 0,
|
|
122
|
-
ts2.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope
|
|
123
|
-
);
|
|
124
|
-
if (subType.aliasSymbol && !subType.aliasTypeArguments) {
|
|
125
|
-
typeName = subType.aliasSymbol.escapedName.toString();
|
|
126
|
-
}
|
|
127
|
-
if (tags.remarks) {
|
|
128
|
-
typeName = (_b = (_a = new RegExp("^`(?<name>.+)`").exec(tags.remarks)) == null ? void 0 : _a[1]) != null ? _b : typeName;
|
|
129
|
-
}
|
|
130
|
-
const entry = {
|
|
131
|
-
name: prop.getName(),
|
|
132
|
-
description: ts2.displayPartsToString(prop.getDocumentationComment(checker)),
|
|
133
|
-
tags,
|
|
134
|
-
type: typeName
|
|
135
|
-
};
|
|
136
|
-
transform == null ? void 0 : transform.call(context, entry, subType, prop);
|
|
137
|
-
return entry;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// src/markdown.ts
|
|
141
|
-
import { fromMarkdown } from "mdast-util-from-markdown";
|
|
142
|
-
import { gfmFromMarkdown } from "mdast-util-gfm";
|
|
143
|
-
import { toHast } from "mdast-util-to-hast";
|
|
144
|
-
function renderMarkdownToHast(md) {
|
|
145
|
-
const mdast = fromMarkdown(
|
|
146
|
-
md.replace(new RegExp("{@link (?<link>[^}]*)}", "g"), "$1"),
|
|
147
|
-
// replace jsdoc links
|
|
148
|
-
{ mdastExtensions: [gfmFromMarkdown()] }
|
|
149
|
-
);
|
|
150
|
-
return toHast(mdast);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export {
|
|
154
|
-
__spreadValues,
|
|
155
|
-
__objRest,
|
|
156
|
-
__async,
|
|
157
|
-
getFileSymbol,
|
|
158
|
-
getProgram,
|
|
159
|
-
generateDocumentation,
|
|
160
|
-
generate,
|
|
161
|
-
renderMarkdownToHast
|
|
162
|
-
};
|