fumadocs-typescript 4.0.14 → 5.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.
@@ -47,6 +47,11 @@ interface GenerateTypeTableOptions extends GenerateOptions {
47
47
  basePath?: string;
48
48
  }
49
49
 
50
+ interface Cache {
51
+ read: (key: string) => unknown | undefined | Promise<unknown | undefined>;
52
+ write: (key: string, value: unknown) => void | Promise<void>;
53
+ }
54
+
50
55
  interface GeneratedDoc {
51
56
  name: string;
52
57
  description: string;
@@ -89,29 +94,17 @@ interface GeneratorOptions extends TypescriptConfig {
89
94
  /**
90
95
  * cache results, note that some options are not marked as dependency.
91
96
  *
92
- * @defaultValue fs
97
+ * @defaultValue false
93
98
  */
94
- cache?: 'fs' | false;
99
+ cache?: Cache | false;
95
100
  project?: Project;
96
101
  }
97
102
  declare function createGenerator(config?: GeneratorOptions | Project): {
98
103
  generateDocumentation(file: {
99
104
  path: string;
100
105
  content?: string;
101
- }, name: string | undefined, options?: GenerateOptions): GeneratedDoc[];
106
+ }, name: string | undefined, options?: GenerateOptions): Promise<GeneratedDoc[]>;
102
107
  generateTypeTable(props: BaseTypeTableProps, options?: GenerateTypeTableOptions): Promise<GeneratedDoc[]>;
103
108
  };
104
- /**
105
- * Generate documentation for properties in an exported type/interface
106
- *
107
- * @deprecated use `createGenerator` instead
108
- */
109
- declare function generateDocumentation(file: string, name: string | undefined, content: string, options?: GenerateOptions & {
110
- /**
111
- * Typescript configurations
112
- */
113
- config?: TypescriptConfig;
114
- project?: Project;
115
- }): GeneratedDoc[];
116
109
 
117
- export { type BaseTypeTableProps as B, type DocEntry as D, type GenerateOptions as G, type RawTag as R, type GeneratedDoc as a, type Generator as b, type GenerateTypeTableOptions as c, createProject as d, type GeneratorOptions as e, createGenerator as f, generateDocumentation as g };
110
+ export { type BaseTypeTableProps as B, type Cache as C, type DocEntry as D, type GenerateTypeTableOptions as G, type RawTag as R, type Generator as a, type GeneratedDoc as b, createProject as c, type GenerateOptions as d, type GeneratorOptions as e, createGenerator as f };
@@ -57,9 +57,13 @@ import {
57
57
  rehypeCode
58
58
  } from "fumadocs-core/mdx-plugins/rehype-code";
59
59
  import remarkRehype from "remark-rehype";
60
- import { highlightHast } from "fumadocs-core/highlight";
60
+ import { getHighlighter } from "fumadocs-core/highlight";
61
61
  var shikiOptions = {
62
62
  lazy: true,
63
+ langs: ["ts", "tsx"],
64
+ // disable default transformers & meta parser
65
+ transformers: [],
66
+ parseMetaString: void 0,
63
67
  themes: {
64
68
  light: "github-light",
65
69
  dark: "github-dark"
@@ -68,10 +72,16 @@ var shikiOptions = {
68
72
  var processor = remark().use(remarkGfm).use(remarkRehype).use(rehypeCode, shikiOptions);
69
73
  function renderTypeToHast(type) {
70
74
  return __async(this, null, function* () {
71
- const nodes = yield highlightHast(type, __spreadProps(__spreadValues({}, shikiOptions), {
75
+ const highlighter = yield getHighlighter("js", {
76
+ langs: ["ts"],
77
+ themes: Object.values(shikiOptions.themes)
78
+ });
79
+ const nodes = highlighter.codeToHast(type, {
72
80
  lang: "ts",
73
- structure: "inline"
74
- }));
81
+ structure: "inline",
82
+ themes: shikiOptions.themes,
83
+ defaultColor: false
84
+ });
75
85
  return {
76
86
  type: "element",
77
87
  tagName: "span",
package/dist/index.d.ts CHANGED
@@ -1,39 +1,10 @@
1
- import { G as GenerateOptions, a as GeneratedDoc, D as DocEntry, b as Generator, c as GenerateTypeTableOptions } from './base-Q18nCvFH.js';
2
- export { e as GeneratorOptions, R as RawTag, f as createGenerator, d as createProject, g as generateDocumentation } from './base-Q18nCvFH.js';
3
- import { GlobOptions } from 'tinyglobby';
1
+ import { G as GenerateTypeTableOptions, a as Generator, B as BaseTypeTableProps, C as Cache } from './base-C72MF-7Q.js';
2
+ export { D as DocEntry, d as GenerateOptions, b as GeneratedDoc, e as GeneratorOptions, R as RawTag, f as createGenerator, c as createProject } from './base-C72MF-7Q.js';
4
3
  import { Nodes } from 'hast';
5
4
  import { Root } from 'mdast';
6
5
  import { Transformer } from 'unified';
7
6
  import 'ts-morph';
8
7
 
9
- interface Templates {
10
- block: (doc: GeneratedDoc, children: string) => string;
11
- property: (entry: DocEntry) => string;
12
- }
13
- interface GenerateMDXOptions extends GenerateOptions {
14
- /**
15
- * a root directory to resolve relative file paths
16
- */
17
- basePath?: string;
18
- templates?: Partial<Templates>;
19
- }
20
- declare function generateMDX(generator: Generator, source: string, { basePath, templates: overrides, ...rest }?: GenerateMDXOptions): string;
21
-
22
- interface GenerateFilesOptions {
23
- input: string | string[];
24
- /**
25
- * Output directory, or a function that returns the output path
26
- */
27
- output: string | ((inputPath: string) => string);
28
- globOptions?: GlobOptions;
29
- options?: GenerateMDXOptions;
30
- /**
31
- * @returns New content
32
- */
33
- transformOutput?: (path: string, content: string) => string;
34
- }
35
- declare function generateFiles(generator: Generator, options: GenerateFilesOptions): Promise<void>;
36
-
37
8
  declare function renderTypeToHast(type: string): Promise<Nodes>;
38
9
  declare function renderMarkdownToHast(md: string): Promise<Nodes>;
39
10
 
@@ -58,6 +29,9 @@ interface RemarkAutoTypeTableOptions {
58
29
  remarkStringify?: boolean;
59
30
  generator?: Generator;
60
31
  }
32
+ interface TypeTableProps extends BaseTypeTableProps {
33
+ cwd?: true;
34
+ }
61
35
  /**
62
36
  * Compile `auto-type-table` into Fumadocs UI compatible TypeTable
63
37
  *
@@ -65,4 +39,6 @@ interface RemarkAutoTypeTableOptions {
65
39
  */
66
40
  declare function remarkAutoTypeTable(config?: RemarkAutoTypeTableOptions): Transformer<Root, Root>;
67
41
 
68
- export { DocEntry, type GenerateFilesOptions, type GenerateMDXOptions, GenerateOptions, GeneratedDoc, Generator, type RemarkAutoTypeTableOptions, generateFiles, generateMDX, remarkAutoTypeTable, renderMarkdownToHast };
42
+ declare function createFileSystemGeneratorCache(dir: string): Cache;
43
+
44
+ export { Cache, Generator, type RemarkAutoTypeTableOptions, type TypeTableProps, createFileSystemGeneratorCache, remarkAutoTypeTable, renderMarkdownToHast };
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  parseTags,
7
7
  renderMarkdownToHast,
8
8
  renderTypeToHast
9
- } from "./chunk-REUDVA2G.js";
9
+ } from "./chunk-H4DZJVYN.js";
10
10
 
11
11
  // src/lib/base.ts
12
12
  import {
@@ -25,7 +25,7 @@ function createProject(options = {}) {
25
25
  }
26
26
 
27
27
  // src/lib/base.ts
28
- import fs3 from "fs";
28
+ import fs2 from "fs/promises";
29
29
 
30
30
  // src/lib/type-table.ts
31
31
  import * as fs from "fs/promises";
@@ -47,7 +47,7 @@ ${type}`;
47
47
  content += `
48
48
  export type ${typeName} = ${type}`;
49
49
  }
50
- const output = gen.generateDocumentation(
50
+ const output = yield gen.generateDocumentation(
51
51
  { path: file != null ? file : "temp.ts", content },
52
52
  typeName,
53
53
  options
@@ -58,36 +58,8 @@ export type ${typeName} = ${type}`;
58
58
  });
59
59
  }
60
60
 
61
- // src/lib/cache.ts
62
- import fs2 from "fs";
63
- import { createHash } from "crypto";
64
- import path from "path";
65
- function createCache() {
66
- const dir = path.join(process.cwd(), ".next/fumadocs-typescript");
67
- try {
68
- fs2.mkdirSync(dir, { recursive: true });
69
- } catch (e) {
70
- }
71
- return {
72
- write(input, data) {
73
- const hash = createHash("SHA256").update(input).digest("hex").slice(0, 12);
74
- fs2.writeFileSync(path.join(dir, `${hash}.json`), JSON.stringify(data));
75
- },
76
- read(input) {
77
- const hash = createHash("SHA256").update(input).digest("hex").slice(0, 12);
78
- try {
79
- return JSON.parse(
80
- fs2.readFileSync(path.join(dir, `${hash}.json`)).toString()
81
- );
82
- } catch (e) {
83
- return;
84
- }
85
- }
86
- };
87
- }
88
-
89
61
  // src/lib/base.ts
90
- import path2 from "path";
62
+ import path from "path";
91
63
 
92
64
  // src/lib/get-simple-form.ts
93
65
  import * as ts from "ts-morph";
@@ -150,12 +122,10 @@ function dedupe(arr) {
150
122
 
151
123
  // src/lib/base.ts
152
124
  function createGenerator(config) {
153
- var _a;
154
125
  const options = config instanceof Project2 ? {
155
126
  project: config
156
127
  } : config;
157
- const cacheType = (_a = options == null ? void 0 : options.cache) != null ? _a : process.env.NODE_ENV !== "development" ? "fs" : false;
158
- const cache = cacheType === "fs" ? createCache() : null;
128
+ const cache = (options == null ? void 0 : options.cache) ? options.cache : null;
159
129
  let instance;
160
130
  function getProject() {
161
131
  var _a2;
@@ -164,38 +134,35 @@ function createGenerator(config) {
164
134
  }
165
135
  return {
166
136
  generateDocumentation(file, name, options2) {
167
- var _a2;
168
- const content = (_a2 = file.content) != null ? _a2 : fs3.readFileSync(path2.resolve(file.path)).toString();
169
- const cacheKey = `${file.path}:${name}:${content}`;
170
- if (cache) {
171
- const cached = cache.read(cacheKey);
172
- if (cached) return cached;
173
- }
174
- const sourceFile = getProject().createSourceFile(file.path, content, {
175
- overwrite: true
137
+ return __async(this, null, function* () {
138
+ var _a2;
139
+ const content = (_a2 = file.content) != null ? _a2 : (yield fs2.readFile(path.resolve(file.path))).toString();
140
+ const cacheKey = `${file.path}:${name}:${content}`;
141
+ if (cache) {
142
+ const cached = yield cache.read(cacheKey);
143
+ if (cached) return cached;
144
+ }
145
+ const sourceFile = getProject().createSourceFile(file.path, content, {
146
+ overwrite: true
147
+ });
148
+ const out = [];
149
+ for (const [k, d] of sourceFile.getExportedDeclarations()) {
150
+ if (name && name !== k) continue;
151
+ if (d.length > 1)
152
+ console.warn(
153
+ `export ${k} should not have more than one type declaration.`
154
+ );
155
+ out.push(generate(getProject(), k, d[0], options2));
156
+ }
157
+ void (cache == null ? void 0 : cache.write(cacheKey, out));
158
+ return out;
176
159
  });
177
- const out = [];
178
- for (const [k, d] of sourceFile.getExportedDeclarations()) {
179
- if (name && name !== k) continue;
180
- if (d.length > 1)
181
- console.warn(
182
- `export ${k} should not have more than one type declaration.`
183
- );
184
- out.push(generate(getProject(), k, d[0], options2));
185
- }
186
- cache == null ? void 0 : cache.write(cacheKey, out);
187
- return out;
188
160
  },
189
161
  generateTypeTable(props, options2) {
190
162
  return getTypeTableOutput(this, props, options2);
191
163
  }
192
164
  };
193
165
  }
194
- function generateDocumentation(file, name, content, options = {}) {
195
- var _a;
196
- const gen = createGenerator((_a = options.project) != null ? _a : options.config);
197
- return gen.generateDocumentation({ path: file, content }, name, options);
198
- }
199
166
  function generate(program, name, declaration, { allowInternal = false, transform } = {}) {
200
167
  var _a;
201
168
  const entryContext = {
@@ -267,89 +234,10 @@ function getDocEntry(prop, context) {
267
234
  return entry;
268
235
  }
269
236
 
270
- // src/lib/mdx.ts
271
- import * as path3 from "path";
272
- var regex = new RegExp("^---type-table---\\r?\\n(?<file>.+?)(?:#(?<name>.+))?\\r?\\n---end---$", "gm");
273
- var defaultTemplates = {
274
- block: (doc, c) => `### ${doc.name}
275
-
276
- ${doc.description}
277
-
278
- <div className='*:border-b [&>*:last-child]:border-b-0'>${c}</div>`,
279
- property: (c) => `<div className='text-sm text-fd-muted-foreground py-4'>
280
-
281
- <div className="flex flex-row items-center gap-4">
282
- <code className="text-sm">${c.name}</code>
283
- <code className="text-fd-muted-foreground">{${JSON.stringify(c.simplifiedType)}}</code>
284
- </div>
285
-
286
- Full Type: <code className="text-fd-muted-foreground">{${JSON.stringify(c.type)}}</code>
287
-
288
- ${c.description || "No Description"}
289
-
290
- ${c.tags.map((tag) => `- ${tag.name}:
291
- ${replaceJsDocLinks(tag.text)}`).join("\n")}
292
-
293
- </div>`
294
- };
295
- function generateMDX(generator, source, _a = {}) {
296
- var _b = _a, { basePath = "./", templates: overrides } = _b, rest = __objRest(_b, ["basePath", "templates"]);
297
- const templates = __spreadValues(__spreadValues({}, defaultTemplates), overrides);
298
- return source.replace(regex, (...args) => {
299
- const groups = args[args.length - 1];
300
- const file = path3.resolve(basePath, groups.file);
301
- const docs = generator.generateDocumentation(
302
- { path: file },
303
- groups.name,
304
- rest
305
- );
306
- return docs.map(
307
- (doc) => templates.block(doc, doc.entries.map(templates.property).join("\n"))
308
- ).join("\n\n");
309
- });
310
- }
311
- function replaceJsDocLinks(md) {
312
- return md.replace(new RegExp("{@link (?<link>[^}]*)}", "g"), "$1");
313
- }
314
-
315
- // src/lib/file.ts
316
- import * as path4 from "path";
317
- import { mkdir, writeFile, readFile as readFile2 } from "fs/promises";
318
- import { glob } from "tinyglobby";
319
- function generateFiles(generator, options) {
320
- return __async(this, null, function* () {
321
- const files = yield glob(options.input, options.globOptions);
322
- const produce = files.map((file) => __async(null, null, function* () {
323
- const absolutePath = path4.resolve(file);
324
- const outputPath = typeof options.output === "function" ? options.output(file) : path4.resolve(
325
- options.output,
326
- `${path4.basename(file, path4.extname(file))}.mdx`
327
- );
328
- const content = (yield readFile2(absolutePath)).toString();
329
- let result = generateMDX(generator, content, __spreadValues({
330
- basePath: path4.dirname(absolutePath)
331
- }, options.options));
332
- if (options.transformOutput) {
333
- result = options.transformOutput(outputPath, result);
334
- }
335
- yield write(outputPath, result);
336
- console.log(`Generated: ${outputPath}`);
337
- }));
338
- yield Promise.all(produce);
339
- });
340
- }
341
- function write(file, content) {
342
- return __async(this, null, function* () {
343
- yield mkdir(path4.dirname(file), { recursive: true });
344
- yield writeFile(file, content);
345
- });
346
- }
347
-
348
237
  // src/lib/remark-auto-type-table.ts
349
238
  import { valueToEstree } from "estree-util-value-to-estree";
350
239
  import { visit } from "unist-util-visit";
351
240
  import { toEstree } from "hast-util-to-estree";
352
- import { dirname as dirname2 } from "path";
353
241
  function objectBuilder() {
354
242
  const out = {
355
243
  type: "ObjectExpression",
@@ -389,10 +277,10 @@ function buildTypeProp(_0, _1) {
389
277
  function onItem(entry) {
390
278
  return __async(this, null, function* () {
391
279
  const node = objectBuilder();
280
+ const tags = parseTags(entry.tags);
392
281
  node.addJsxProperty("type", yield renderType(entry.simplifiedType));
393
282
  node.addJsxProperty("typeDescription", yield renderType(entry.type));
394
283
  node.addExpressionNode("required", valueToEstree(entry.required));
395
- const tags = parseTags(entry.tags);
396
284
  if (tags.default)
397
285
  node.addJsxProperty("default", yield renderType(tags.default));
398
286
  if (tags.returns)
@@ -449,74 +337,102 @@ function remarkAutoTypeTable(config = {}) {
449
337
  } = config;
450
338
  return (tree, file) => __async(null, null, function* () {
451
339
  const queue = [];
452
- const defaultBasePath = file.path ? dirname2(file.path) : void 0;
340
+ function run(node, props) {
341
+ return __async(this, null, function* () {
342
+ let basePath = props.cwd ? file.cwd : generateOptions.basePath;
343
+ if (file.dirname) {
344
+ basePath != null ? basePath : basePath = file.dirname;
345
+ }
346
+ const output = yield generator.generateTypeTable(props, __spreadProps(__spreadValues({}, generateOptions), {
347
+ basePath
348
+ }));
349
+ const rendered = output.map((doc) => __async(null, null, function* () {
350
+ return {
351
+ type: "mdxJsxFlowElement",
352
+ name: outputName,
353
+ attributes: [
354
+ {
355
+ type: "mdxJsxAttribute",
356
+ name: "type",
357
+ value: {
358
+ type: "mdxJsxAttributeValueExpression",
359
+ value: remarkStringify ? JSON.stringify(doc, null, 2) : "",
360
+ data: {
361
+ estree: {
362
+ type: "Program",
363
+ sourceType: "module",
364
+ body: [
365
+ {
366
+ type: "ExpressionStatement",
367
+ expression: yield buildTypeProp(doc.entries, config)
368
+ }
369
+ ]
370
+ }
371
+ }
372
+ }
373
+ }
374
+ ],
375
+ children: []
376
+ };
377
+ }));
378
+ Object.assign(node, {
379
+ type: "root",
380
+ attributes: [],
381
+ children: yield Promise.all(rendered)
382
+ });
383
+ });
384
+ }
453
385
  visit(tree, "mdxJsxFlowElement", (node) => {
454
386
  if (node.name !== name) return;
455
387
  const props = {};
456
388
  for (const attr of node.attributes) {
457
- if (attr.type !== "mdxJsxAttribute" || typeof attr.value !== "string")
389
+ if (attr.type !== "mdxJsxAttribute" || typeof attr.value !== "string" && attr.value !== null)
458
390
  throw new Error(
459
- "`auto-type-table` does not support non-string attributes"
391
+ "`auto-type-table` only support string & boolean attributes"
460
392
  );
461
393
  props[attr.name] = attr.value;
462
394
  }
463
- function run() {
464
- return __async(this, null, function* () {
465
- var _a;
466
- const output = yield generator.generateTypeTable(
467
- props,
468
- __spreadProps(__spreadValues({}, generateOptions), {
469
- basePath: (_a = generateOptions.basePath) != null ? _a : defaultBasePath
470
- })
471
- );
472
- const rendered = output.map((doc) => __async(null, null, function* () {
473
- return {
474
- type: "mdxJsxFlowElement",
475
- name: outputName,
476
- attributes: [
477
- {
478
- type: "mdxJsxAttribute",
479
- name: "type",
480
- value: {
481
- type: "mdxJsxAttributeValueExpression",
482
- value: remarkStringify ? JSON.stringify(doc, null, 2) : "",
483
- data: {
484
- estree: {
485
- type: "Program",
486
- sourceType: "module",
487
- body: [
488
- {
489
- type: "ExpressionStatement",
490
- expression: yield buildTypeProp(doc.entries, config)
491
- }
492
- ]
493
- }
494
- }
495
- }
496
- }
497
- ],
498
- children: []
499
- };
500
- }));
501
- Object.assign(node, {
502
- type: "root",
503
- attributes: [],
504
- children: yield Promise.all(rendered)
505
- });
506
- });
507
- }
508
- queue.push(run());
395
+ queue.push(run(node, props));
509
396
  return "skip";
510
397
  });
511
398
  yield Promise.all(queue);
512
399
  });
513
400
  }
401
+
402
+ // src/cache/fs-cache.ts
403
+ import fs3 from "fs/promises";
404
+ import { createHash } from "crypto";
405
+ import path2 from "path";
406
+ function createFileSystemGeneratorCache(dir) {
407
+ dir = path2.resolve(dir);
408
+ const initDirPromise = fs3.mkdir(dir, { recursive: true }).catch(() => {
409
+ });
410
+ return {
411
+ write(input, data) {
412
+ return __async(this, null, function* () {
413
+ const hash = createHash("SHA256").update(input).digest("hex").slice(0, 12);
414
+ yield initDirPromise;
415
+ yield fs3.writeFile(path2.join(dir, `${hash}.json`), JSON.stringify(data));
416
+ });
417
+ },
418
+ read(input) {
419
+ return __async(this, null, function* () {
420
+ const hash = createHash("SHA256").update(input).digest("hex").slice(0, 12);
421
+ try {
422
+ return JSON.parse(
423
+ (yield fs3.readFile(path2.join(dir, `${hash}.json`))).toString()
424
+ );
425
+ } catch (e) {
426
+ return;
427
+ }
428
+ });
429
+ }
430
+ };
431
+ }
514
432
  export {
433
+ createFileSystemGeneratorCache,
515
434
  createGenerator,
516
435
  createProject,
517
- generateDocumentation,
518
- generateFiles,
519
- generateMDX,
520
436
  remarkAutoTypeTable,
521
437
  renderMarkdownToHast
522
438
  };
@@ -1,6 +1,6 @@
1
1
  import * as runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { B as BaseTypeTableProps, b as Generator, c as GenerateTypeTableOptions } from '../base-Q18nCvFH.js';
3
+ import { B as BaseTypeTableProps, a as Generator, G as GenerateTypeTableOptions } from '../base-C72MF-7Q.js';
4
4
  import 'ts-morph';
5
5
 
6
6
  type AutoTypeTableProps = BaseTypeTableProps;
package/dist/ui/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  parseTags,
7
7
  renderMarkdownToHast,
8
8
  renderTypeToHast
9
- } from "../chunk-REUDVA2G.js";
9
+ } from "../chunk-H4DZJVYN.js";
10
10
 
11
11
  // src/ui/auto-type-table.tsx
12
12
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-typescript",
3
- "version": "4.0.14",
3
+ "version": "5.0.0",
4
4
  "description": "Typescript Integration for Fumadocs",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -48,8 +48,8 @@
48
48
  "typescript": "^5.9.3",
49
49
  "unified": "^11.0.5",
50
50
  "eslint-config-custom": "0.0.0",
51
- "fumadocs-core": "16.2.4",
52
- "fumadocs-ui": "16.2.4",
51
+ "fumadocs-core": "16.3.2",
52
+ "fumadocs-ui": "16.3.2",
53
53
  "tsconfig": "0.0.0"
54
54
  },
55
55
  "peerDependencies": {