fumadocs-typescript 5.0.0 → 5.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.
package/dist/index.js CHANGED
@@ -1,438 +1,322 @@
1
- import {
2
- __async,
3
- __objRest,
4
- __spreadProps,
5
- __spreadValues,
6
- parseTags,
7
- renderMarkdownToHast,
8
- renderTypeToHast
9
- } from "./chunk-H4DZJVYN.js";
10
-
11
- // src/lib/base.ts
12
- import {
13
- Project as Project2,
14
- ts as ts2
15
- } from "ts-morph";
1
+ import { n as markdownRenderer, t as parseTags } from "./parse-tags-B09hzgIX.js";
2
+ import * as ts$1 from "ts-morph";
3
+ import { Project, ts } from "ts-morph";
4
+ import * as fs$1 from "node:fs/promises";
5
+ import fs from "node:fs/promises";
6
+ import path, { join } from "node:path";
7
+ import { valueToEstree } from "estree-util-value-to-estree";
8
+ import { visit } from "unist-util-visit";
9
+ import { toEstree } from "hast-util-to-estree";
10
+ import { createHash } from "node:crypto";
16
11
 
17
- // src/create-project.ts
18
- import { Project } from "ts-morph";
12
+ //#region src/create-project.ts
19
13
  function createProject(options = {}) {
20
- var _a;
21
- return new Project({
22
- tsConfigFilePath: (_a = options.tsconfigPath) != null ? _a : "./tsconfig.json",
23
- skipAddingFilesFromTsConfig: true
24
- });
14
+ return new Project({
15
+ tsConfigFilePath: options.tsconfigPath ?? "./tsconfig.json",
16
+ skipAddingFilesFromTsConfig: true
17
+ });
25
18
  }
26
19
 
27
- // src/lib/base.ts
28
- import fs2 from "fs/promises";
29
-
30
- // src/lib/type-table.ts
31
- import * as fs from "fs/promises";
32
- import { join } from "path";
33
- function getTypeTableOutput(gen, _a, options) {
34
- return __async(this, null, function* () {
35
- var _b = _a, { name, type } = _b, props = __objRest(_b, ["name", "type"]);
36
- const file = props.path && (options == null ? void 0 : options.basePath) ? join(options.basePath, props.path) : props.path;
37
- let typeName = name;
38
- let content = "";
39
- if (file) {
40
- content = (yield fs.readFile(file)).toString();
41
- }
42
- if (type && type.split("\n").length > 1) {
43
- content += `
44
- ${type}`;
45
- } else if (type) {
46
- typeName != null ? typeName : typeName = "$Fumadocs";
47
- content += `
48
- export type ${typeName} = ${type}`;
49
- }
50
- const output = yield gen.generateDocumentation(
51
- { path: file != null ? file : "temp.ts", content },
52
- typeName,
53
- options
54
- );
55
- if (name && output.length === 0)
56
- throw new Error(`${name} in ${file != null ? file : "empty file"} doesn't exist`);
57
- return output;
58
- });
20
+ //#endregion
21
+ //#region src/lib/type-table.ts
22
+ async function getTypeTableOutput(gen, { name, type, ...props }, options) {
23
+ const file = props.path && options?.basePath ? join(options.basePath, props.path) : props.path;
24
+ let typeName = name;
25
+ let content = "";
26
+ if (file) content = (await fs$1.readFile(file)).toString();
27
+ if (type && type.split("\n").length > 1) content += `\n${type}`;
28
+ else if (type) {
29
+ typeName ??= "$Fumadocs";
30
+ content += `\nexport type ${typeName} = ${type}`;
31
+ }
32
+ const output = await gen.generateDocumentation({
33
+ path: file ?? "temp.ts",
34
+ content
35
+ }, typeName, options);
36
+ if (name && output.length === 0) throw new Error(`${name} in ${file ?? "empty file"} doesn't exist`);
37
+ return output;
59
38
  }
60
39
 
61
- // src/lib/base.ts
62
- import path from "path";
63
-
64
- // src/lib/get-simple-form.ts
65
- import * as ts from "ts-morph";
40
+ //#endregion
41
+ //#region src/lib/get-simple-form.ts
66
42
  function getSimpleForm(type, checker, noUndefined = false, location) {
67
- if (type.isUndefined() && noUndefined) return "";
68
- const alias = type.getAliasSymbol();
69
- if (alias) {
70
- const args = type.getAliasTypeArguments();
71
- if (args.length === 0) return alias.getName();
72
- return `${alias.getName()}<${args.map((arg) => getSimpleForm(arg, checker)).join(", ")}>`;
73
- }
74
- if (type.isUnion()) {
75
- const types = [];
76
- for (const t of type.getUnionTypes()) {
77
- const str = getSimpleForm(t, checker, noUndefined);
78
- if (str.length > 0 && str !== "never") types.unshift(str);
79
- }
80
- return types.length > 0 ? (
81
- // boolean | null will become true | false | null, need to ensure it's still returned as boolean
82
- dedupe(types).join(" | ").replace("true | false", "boolean")
83
- ) : "never";
84
- }
85
- if (type.isIntersection()) {
86
- const types = [];
87
- for (const t of type.getIntersectionTypes()) {
88
- const str = getSimpleForm(t, checker, noUndefined);
89
- if (str.length > 0 && str !== "never") types.unshift(str);
90
- }
91
- return dedupe(types).join(" & ");
92
- }
93
- if (type.isTuple()) {
94
- const elements = type.getTupleElements().map((t) => getSimpleForm(t, checker)).join(", ");
95
- return `[${elements}]`;
96
- }
97
- if (type.isArray() || type.isReadonlyArray()) {
98
- return "array";
99
- }
100
- if (type.getCallSignatures().length > 0) {
101
- return "function";
102
- }
103
- if (type.isClassOrInterface() || type.isObject()) {
104
- return "object";
105
- }
106
- return type.getText(
107
- location,
108
- ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope
109
- );
43
+ if (type.isUndefined() && noUndefined) return "";
44
+ const alias = type.getAliasSymbol();
45
+ if (alias) {
46
+ const args = type.getAliasTypeArguments();
47
+ if (args.length === 0) return alias.getName();
48
+ return `${alias.getName()}<${args.map((arg) => getSimpleForm(arg, checker)).join(", ")}>`;
49
+ }
50
+ if (type.isUnion()) {
51
+ const types = [];
52
+ for (const t of type.getUnionTypes()) {
53
+ const str = getSimpleForm(t, checker, noUndefined);
54
+ if (str.length > 0 && str !== "never") types.unshift(str);
55
+ }
56
+ return types.length > 0 ? dedupe(types).join(" | ").replace("true | false", "boolean") : "never";
57
+ }
58
+ if (type.isIntersection()) {
59
+ const types = [];
60
+ for (const t of type.getIntersectionTypes()) {
61
+ const str = getSimpleForm(t, checker, noUndefined);
62
+ if (str.length > 0 && str !== "never") types.unshift(str);
63
+ }
64
+ return dedupe(types).join(" & ");
65
+ }
66
+ if (type.isTuple()) return `[${type.getTupleElements().map((t) => getSimpleForm(t, checker)).join(", ")}]`;
67
+ if (type.isArray() || type.isReadonlyArray()) return "array";
68
+ if (type.getCallSignatures().length > 0) return "function";
69
+ if (type.isClassOrInterface() || type.isObject()) return "object";
70
+ return type.getText(location, ts$1.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope);
110
71
  }
111
72
  function dedupe(arr) {
112
- const dedupe2 = /* @__PURE__ */ new Set();
113
- const out = [];
114
- for (const item of arr) {
115
- if (!dedupe2.has(item)) {
116
- out.push(item);
117
- dedupe2.add(item);
118
- }
119
- }
120
- return out;
73
+ const dedupe$1 = /* @__PURE__ */ new Set();
74
+ const out = [];
75
+ for (const item of arr) if (!dedupe$1.has(item)) {
76
+ out.push(item);
77
+ dedupe$1.add(item);
78
+ }
79
+ return out;
121
80
  }
122
81
 
123
- // src/lib/base.ts
82
+ //#endregion
83
+ //#region src/lib/base.ts
124
84
  function createGenerator(config) {
125
- const options = config instanceof Project2 ? {
126
- project: config
127
- } : config;
128
- const cache = (options == null ? void 0 : options.cache) ? options.cache : null;
129
- let instance;
130
- function getProject() {
131
- var _a2;
132
- instance != null ? instance : instance = (_a2 = options == null ? void 0 : options.project) != null ? _a2 : createProject(options);
133
- return instance;
134
- }
135
- return {
136
- generateDocumentation(file, name, options2) {
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;
159
- });
160
- },
161
- generateTypeTable(props, options2) {
162
- return getTypeTableOutput(this, props, options2);
163
- }
164
- };
85
+ const options = config instanceof Project ? { project: config } : config;
86
+ const cache = options?.cache ? options.cache : null;
87
+ let instance;
88
+ function getProject() {
89
+ instance ??= options?.project ?? createProject(options);
90
+ return instance;
91
+ }
92
+ return {
93
+ async generateDocumentation(file, name, options$1) {
94
+ const content = file.content ?? (await fs.readFile(path.resolve(file.path))).toString();
95
+ const cacheKey = `${file.path}:${name}:${content}`;
96
+ if (cache) {
97
+ const cached = await cache.read(cacheKey);
98
+ if (cached) return cached;
99
+ }
100
+ const sourceFile = getProject().createSourceFile(file.path, content, { overwrite: true });
101
+ const out = [];
102
+ for (const [k, d] of sourceFile.getExportedDeclarations()) {
103
+ if (name && name !== k) continue;
104
+ if (d.length > 1) console.warn(`export ${k} should not have more than one type declaration.`);
105
+ out.push(generate(getProject(), k, d[0], options$1));
106
+ }
107
+ cache?.write(cacheKey, out);
108
+ return out;
109
+ },
110
+ generateTypeTable(props, options$1) {
111
+ return getTypeTableOutput(this, props, options$1);
112
+ }
113
+ };
165
114
  }
166
115
  function generate(program, name, declaration, { allowInternal = false, transform } = {}) {
167
- var _a;
168
- const entryContext = {
169
- transform,
170
- program,
171
- type: declaration.getType(),
172
- declaration
173
- };
174
- const comment = (_a = declaration.getSymbol()) == null ? void 0 : _a.compilerSymbol.getDocumentationComment(
175
- program.getTypeChecker().compilerObject
176
- );
177
- return {
178
- name,
179
- description: comment ? ts2.displayPartsToString(comment) : "",
180
- entries: declaration.getType().getProperties().map((prop) => getDocEntry(prop, entryContext)).filter(
181
- (entry) => entry && (allowInternal || !("internal" in entry.tags))
182
- )
183
- };
116
+ const entryContext = {
117
+ transform,
118
+ program,
119
+ type: declaration.getType(),
120
+ declaration
121
+ };
122
+ const comment = declaration.getSymbol()?.compilerSymbol.getDocumentationComment(program.getTypeChecker().compilerObject);
123
+ return {
124
+ name,
125
+ description: comment ? ts.displayPartsToString(comment) : "",
126
+ entries: declaration.getType().getProperties().map((prop) => getDocEntry(prop, entryContext)).filter((entry) => entry && (allowInternal || !("internal" in entry.tags)))
127
+ };
184
128
  }
185
129
  function getDocEntry(prop, context) {
186
- var _a, _b;
187
- const { transform, program } = context;
188
- if (context.type.isClass() && prop.getName().startsWith("#")) {
189
- return;
190
- }
191
- const subType = prop.getTypeAtLocation(context.declaration);
192
- const isOptional = prop.isOptional();
193
- const tags = prop.getJsDocTags().map(
194
- (tag) => ({
195
- name: tag.getName(),
196
- text: ts2.displayPartsToString(tag.getText())
197
- })
198
- );
199
- let type = subType.getText(
200
- context.declaration,
201
- ts2.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | ts2.TypeFormatFlags.NoTruncation
202
- );
203
- let simplifiedType = getSimpleForm(
204
- subType,
205
- program.getTypeChecker(),
206
- isOptional,
207
- context.declaration
208
- );
209
- for (const tag of tags) {
210
- if (tag.name === "fumadocsType") {
211
- const match = (_a = new RegExp("`(?<name>.+)`$").exec(tag.text)) == null ? void 0 : _a[1];
212
- if (match) type = match;
213
- continue;
214
- }
215
- if (tag.name === "remarks") {
216
- const match = (_b = new RegExp("^`(?<name>.+)`").exec(tag.text)) == null ? void 0 : _b[1];
217
- if (match) simplifiedType = match;
218
- }
219
- }
220
- const entry = {
221
- name: prop.getName(),
222
- description: ts2.displayPartsToString(
223
- prop.compilerSymbol.getDocumentationComment(
224
- program.getTypeChecker().compilerObject
225
- )
226
- ),
227
- tags,
228
- type,
229
- simplifiedType,
230
- required: !isOptional,
231
- deprecated: tags.some((tag) => tag.name === "deprecated")
232
- };
233
- transform == null ? void 0 : transform.call(context, entry, subType, prop);
234
- return entry;
130
+ const { transform, program } = context;
131
+ if (context.type.isClass() && prop.getName().startsWith("#")) return;
132
+ const subType = prop.getTypeAtLocation(context.declaration);
133
+ const isOptional = prop.isOptional();
134
+ const tags = prop.getJsDocTags().map((tag) => ({
135
+ name: tag.getName(),
136
+ text: ts.displayPartsToString(tag.getText())
137
+ }));
138
+ let type = subType.getText(context.declaration, ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | ts.TypeFormatFlags.NoTruncation);
139
+ let simplifiedType = getSimpleForm(subType, program.getTypeChecker(), isOptional, context.declaration);
140
+ for (const tag of tags) {
141
+ if (tag.name === "fumadocsType") {
142
+ const match = /`(?<name>.+)`$/.exec(tag.text)?.[1];
143
+ if (match) type = match;
144
+ continue;
145
+ }
146
+ if (tag.name === "remarks") {
147
+ const match = /^`(?<name>.+)`/.exec(tag.text)?.[1];
148
+ if (match) simplifiedType = match;
149
+ }
150
+ }
151
+ const entry = {
152
+ name: prop.getName(),
153
+ description: ts.displayPartsToString(prop.compilerSymbol.getDocumentationComment(program.getTypeChecker().compilerObject)),
154
+ tags,
155
+ type,
156
+ simplifiedType,
157
+ required: !isOptional,
158
+ deprecated: tags.some((tag) => tag.name === "deprecated")
159
+ };
160
+ transform?.call(context, entry, subType, prop);
161
+ return entry;
235
162
  }
236
163
 
237
- // src/lib/remark-auto-type-table.ts
238
- import { valueToEstree } from "estree-util-value-to-estree";
239
- import { visit } from "unist-util-visit";
240
- import { toEstree } from "hast-util-to-estree";
164
+ //#endregion
165
+ //#region src/lib/remark-auto-type-table.ts
241
166
  function objectBuilder() {
242
- const out = {
243
- type: "ObjectExpression",
244
- properties: []
245
- };
246
- return {
247
- addExpressionNode(key, expression) {
248
- out.properties.push({
249
- type: "Property",
250
- method: false,
251
- shorthand: false,
252
- computed: false,
253
- key: {
254
- type: "Identifier",
255
- name: key
256
- },
257
- kind: "init",
258
- value: expression
259
- });
260
- },
261
- addJsxProperty(key, hast) {
262
- const estree = toEstree(hast, {
263
- elementAttributeNameCase: "react"
264
- }).body[0];
265
- this.addExpressionNode(key, estree.expression);
266
- },
267
- build() {
268
- return out;
269
- }
270
- };
167
+ const out = {
168
+ type: "ObjectExpression",
169
+ properties: []
170
+ };
171
+ return {
172
+ addExpressionNode(key, expression) {
173
+ out.properties.push({
174
+ type: "Property",
175
+ method: false,
176
+ shorthand: false,
177
+ computed: false,
178
+ key: {
179
+ type: "Identifier",
180
+ name: key
181
+ },
182
+ kind: "init",
183
+ value: expression
184
+ });
185
+ },
186
+ addJsxProperty(key, hast) {
187
+ const estree = toEstree(hast, { elementAttributeNameCase: "react" }).body[0];
188
+ this.addExpressionNode(key, estree.expression);
189
+ },
190
+ build() {
191
+ return out;
192
+ }
193
+ };
271
194
  }
272
- function buildTypeProp(_0, _1) {
273
- return __async(this, arguments, function* (entries, {
274
- renderMarkdown = renderMarkdownToHast,
275
- renderType = renderTypeToHast
276
- }) {
277
- function onItem(entry) {
278
- return __async(this, null, function* () {
279
- const node = objectBuilder();
280
- const tags = parseTags(entry.tags);
281
- node.addJsxProperty("type", yield renderType(entry.simplifiedType));
282
- node.addJsxProperty("typeDescription", yield renderType(entry.type));
283
- node.addExpressionNode("required", valueToEstree(entry.required));
284
- if (tags.default)
285
- node.addJsxProperty("default", yield renderType(tags.default));
286
- if (tags.returns)
287
- node.addJsxProperty("returns", yield renderMarkdown(tags.returns));
288
- if (tags.params) {
289
- node.addExpressionNode("parameters", {
290
- type: "ArrayExpression",
291
- elements: yield Promise.all(tags.params.map(onParam))
292
- });
293
- }
294
- if (entry.description) {
295
- node.addJsxProperty(
296
- "description",
297
- yield renderMarkdown(entry.description)
298
- );
299
- }
300
- return node.build();
301
- });
302
- }
303
- function onParam(param) {
304
- return __async(this, null, function* () {
305
- const node = objectBuilder();
306
- node.addExpressionNode("name", valueToEstree(param.name));
307
- if (param.description)
308
- node.addJsxProperty(
309
- "description",
310
- yield renderMarkdown(param.description)
311
- );
312
- return node.build();
313
- });
314
- }
315
- const prop = objectBuilder();
316
- const output = yield Promise.all(
317
- entries.map((entry) => __async(null, null, function* () {
318
- return {
319
- name: entry.name,
320
- node: yield onItem(entry)
321
- };
322
- }))
323
- );
324
- for (const node of output) {
325
- prop.addExpressionNode(node.name, node.node);
326
- }
327
- return prop.build();
328
- });
195
+ async function buildTypeProp(entries, renderer) {
196
+ async function onItem(entry) {
197
+ const node = objectBuilder();
198
+ const tags = parseTags(entry.tags);
199
+ node.addJsxProperty("type", await renderer.renderTypeToHast(entry.simplifiedType));
200
+ node.addJsxProperty("typeDescription", await renderer.renderTypeToHast(entry.type));
201
+ node.addExpressionNode("required", valueToEstree(entry.required));
202
+ if (tags.default) node.addJsxProperty("default", await renderer.renderTypeToHast(tags.default));
203
+ if (tags.returns) node.addJsxProperty("returns", await renderer.renderMarkdownToHast(tags.returns));
204
+ if (tags.params) node.addExpressionNode("parameters", {
205
+ type: "ArrayExpression",
206
+ elements: await Promise.all(tags.params.map(onParam))
207
+ });
208
+ if (entry.description) node.addJsxProperty("description", await renderer.renderMarkdownToHast(entry.description));
209
+ return node.build();
210
+ }
211
+ async function onParam(param) {
212
+ const node = objectBuilder();
213
+ node.addExpressionNode("name", valueToEstree(param.name));
214
+ if (param.description) node.addJsxProperty("description", await renderer.renderMarkdownToHast(param.description));
215
+ return node.build();
216
+ }
217
+ const prop = objectBuilder();
218
+ const output = await Promise.all(entries.map(async (entry) => ({
219
+ name: entry.name,
220
+ node: await onItem(entry)
221
+ })));
222
+ for (const node of output) prop.addExpressionNode(node.name, node.node);
223
+ return prop.build();
329
224
  }
225
+ /**
226
+ * Compile `auto-type-table` into Fumadocs UI compatible TypeTable
227
+ *
228
+ * MDX is required to use this plugin.
229
+ */
330
230
  function remarkAutoTypeTable(config = {}) {
331
- const {
332
- name = "auto-type-table",
333
- outputName = "TypeTable",
334
- options: generateOptions = {},
335
- remarkStringify = true,
336
- generator = createGenerator()
337
- } = config;
338
- return (tree, file) => __async(null, null, function* () {
339
- const queue = [];
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
- }
385
- visit(tree, "mdxJsxFlowElement", (node) => {
386
- if (node.name !== name) return;
387
- const props = {};
388
- for (const attr of node.attributes) {
389
- if (attr.type !== "mdxJsxAttribute" || typeof attr.value !== "string" && attr.value !== null)
390
- throw new Error(
391
- "`auto-type-table` only support string & boolean attributes"
392
- );
393
- props[attr.name] = attr.value;
394
- }
395
- queue.push(run(node, props));
396
- return "skip";
397
- });
398
- yield Promise.all(queue);
399
- });
231
+ const { name = "auto-type-table", outputName = "TypeTable", options: generateOptions = {}, remarkStringify = true, generator = createGenerator(), renderMarkdown, renderType, shiki } = config;
232
+ let renderer;
233
+ if (renderMarkdown && renderType) renderer = {
234
+ renderMarkdownToHast: renderMarkdown,
235
+ renderTypeToHast: renderType
236
+ };
237
+ else {
238
+ renderer = markdownRenderer(shiki);
239
+ if (renderMarkdown) renderer.renderMarkdownToHast = renderMarkdown;
240
+ if (renderType) renderer.renderTypeToHast = renderType;
241
+ }
242
+ return async (tree, file) => {
243
+ const queue = [];
244
+ async function run(node, props) {
245
+ let basePath = props.cwd ? file.cwd : generateOptions.basePath;
246
+ if (file.dirname) basePath ??= file.dirname;
247
+ const rendered = (await generator.generateTypeTable(props, {
248
+ ...generateOptions,
249
+ basePath
250
+ })).map(async (doc) => {
251
+ return {
252
+ type: "mdxJsxFlowElement",
253
+ name: outputName,
254
+ attributes: [{
255
+ type: "mdxJsxAttribute",
256
+ name: "type",
257
+ value: {
258
+ type: "mdxJsxAttributeValueExpression",
259
+ value: remarkStringify ? JSON.stringify(doc, null, 2) : "",
260
+ data: { estree: {
261
+ type: "Program",
262
+ sourceType: "module",
263
+ body: [{
264
+ type: "ExpressionStatement",
265
+ expression: await buildTypeProp(doc.entries, renderer)
266
+ }]
267
+ } }
268
+ }
269
+ }],
270
+ children: []
271
+ };
272
+ });
273
+ Object.assign(node, {
274
+ type: "root",
275
+ attributes: [],
276
+ children: await Promise.all(rendered)
277
+ });
278
+ }
279
+ visit(tree, "mdxJsxFlowElement", (node) => {
280
+ if (node.name !== name) return;
281
+ const props = {};
282
+ const onError = (message, cause) => {
283
+ const location = node.position ? `${file.path}:${node.position.start.line}:${node.position.start.column}` : file.path;
284
+ throw new Error(`${location} from <auto-type-table>: ${message}`, { cause });
285
+ };
286
+ for (const attr of node.attributes) if (attr.type !== "mdxJsxAttribute") onError("only named attributes are allowed.");
287
+ else if (typeof attr.value === "string") props[attr.name] = attr.value;
288
+ else if (attr.value === null) props[attr.name] = true;
289
+ else onError("only string & boolean attributes are allowed.");
290
+ queue.push(run(node, props).catch((err) => {
291
+ onError("failed to generate type table", err);
292
+ }));
293
+ return "skip";
294
+ });
295
+ await Promise.all(queue);
296
+ };
400
297
  }
401
298
 
402
- // src/cache/fs-cache.ts
403
- import fs3 from "fs/promises";
404
- import { createHash } from "crypto";
405
- import path2 from "path";
299
+ //#endregion
300
+ //#region src/cache/fs-cache.ts
406
301
  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
- };
302
+ dir = path.resolve(dir);
303
+ const initDirPromise = fs.mkdir(dir, { recursive: true }).catch(() => {});
304
+ return {
305
+ async write(input, data) {
306
+ const hash = createHash("SHA256").update(input).digest("hex").slice(0, 12);
307
+ await initDirPromise;
308
+ await fs.writeFile(path.join(dir, `${hash}.json`), JSON.stringify(data));
309
+ },
310
+ async read(input) {
311
+ const hash = createHash("SHA256").update(input).digest("hex").slice(0, 12);
312
+ try {
313
+ return JSON.parse((await fs.readFile(path.join(dir, `${hash}.json`))).toString());
314
+ } catch {
315
+ return;
316
+ }
317
+ }
318
+ };
431
319
  }
432
- export {
433
- createFileSystemGeneratorCache,
434
- createGenerator,
435
- createProject,
436
- remarkAutoTypeTable,
437
- renderMarkdownToHast
438
- };
320
+
321
+ //#endregion
322
+ export { createFileSystemGeneratorCache, createGenerator, createProject, remarkAutoTypeTable };