fumadocs-openapi 9.4.1 → 9.5.1
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/generate-file.d.ts +22 -82
- package/dist/generate-file.d.ts.map +1 -1
- package/dist/generate-file.js +18 -139
- package/dist/render/api-page.js +1 -1
- package/dist/render/operation/index.d.ts.map +1 -1
- package/dist/render/operation/index.js +1 -1
- package/dist/server/source-api.d.ts +27 -1
- package/dist/server/source-api.d.ts.map +1 -1
- package/dist/server/source-api.js +31 -2
- package/dist/utils/pages/to-body.d.ts +5 -0
- package/dist/utils/pages/to-body.d.ts.map +1 -0
- package/dist/utils/pages/to-body.js +20 -0
- package/dist/utils/pages/to-text.d.ts +46 -0
- package/dist/utils/pages/to-text.d.ts.map +1 -0
- package/dist/{generate.js → utils/pages/to-text.js} +35 -84
- package/dist/utils/schema-to-pages.d.ts +97 -0
- package/dist/utils/schema-to-pages.d.ts.map +1 -0
- package/dist/utils/schema-to-pages.js +167 -0
- package/dist/utils/schema.d.ts +6 -1
- package/dist/utils/schema.d.ts.map +1 -1
- package/dist/utils/schema.js +18 -0
- package/package.json +7 -7
- package/dist/generate.d.ts +0 -69
- package/dist/generate.d.ts.map +0 -1
- package/dist/server/create-method.d.ts +0 -7
- package/dist/server/create-method.d.ts.map +0 -1
- package/dist/server/create-method.js +0 -12
package/dist/generate-file.d.ts
CHANGED
|
@@ -1,67 +1,23 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PagesToTextOptions } from './utils/pages/to-text.js';
|
|
2
2
|
import { type ProcessedDocument } from './utils/process-document.js';
|
|
3
3
|
import type { OpenAPIServer } from './server/index.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The original schema file path/url from `input`
|
|
7
|
-
*/
|
|
8
|
-
pathOrUrl: string;
|
|
9
|
-
content: string;
|
|
10
|
-
}
|
|
4
|
+
import { type SchemaToPagesOptions } from './utils/schema-to-pages.js';
|
|
11
5
|
export interface OutputFile {
|
|
12
6
|
path: string;
|
|
13
7
|
content: string;
|
|
14
8
|
}
|
|
15
|
-
interface
|
|
16
|
-
|
|
17
|
-
* Generate a page for each API endpoint/operation (default).
|
|
18
|
-
*/
|
|
19
|
-
per?: 'operation';
|
|
20
|
-
/**
|
|
21
|
-
* Group output using folders (Only works on `operation` mode)
|
|
22
|
-
* - tag: `{tag}/{file}`
|
|
23
|
-
* - route: `{endpoint}/{method}` (it will ignore the `name` option)
|
|
24
|
-
* - none: `{file}` (default)
|
|
25
|
-
*
|
|
26
|
-
* @defaultValue 'none'
|
|
27
|
-
*/
|
|
28
|
-
groupBy?: 'tag' | 'route' | 'none';
|
|
29
|
-
/**
|
|
30
|
-
* Specify name for output file
|
|
31
|
-
*/
|
|
32
|
-
name?: ((output: GeneratePageOutput, document: ProcessedDocument['dereferenced']) => string) | BaseName;
|
|
33
|
-
}
|
|
34
|
-
interface TagConfig extends BaseConfig {
|
|
35
|
-
/**
|
|
36
|
-
* Generate a page for each tag.
|
|
37
|
-
*/
|
|
38
|
-
per: 'tag';
|
|
39
|
-
/**
|
|
40
|
-
* Specify name for output file
|
|
41
|
-
*/
|
|
42
|
-
name?: ((output: GenerateTagOutput, document: ProcessedDocument['dereferenced']) => string) | BaseName;
|
|
43
|
-
}
|
|
44
|
-
interface FileConfig extends BaseConfig {
|
|
45
|
-
/**
|
|
46
|
-
* Generate a page for each schema file.
|
|
47
|
-
*/
|
|
48
|
-
per: 'file';
|
|
9
|
+
interface IndexConfig {
|
|
10
|
+
items: IndexItem[] | ((ctx: HookContext) => IndexItem[]);
|
|
49
11
|
/**
|
|
50
|
-
*
|
|
12
|
+
* Generate URLs for cards
|
|
51
13
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
* v1: Fumadocs OpenAPI v8
|
|
60
|
-
* v2: Fumadocs OpenAPI v9
|
|
61
|
-
*
|
|
62
|
-
* @defaultValue v2
|
|
63
|
-
*/
|
|
64
|
-
algorithm?: 'v2' | 'v1';
|
|
14
|
+
url: ((filePath: string) => string) | {
|
|
15
|
+
baseUrl: string;
|
|
16
|
+
/**
|
|
17
|
+
* Base content directory
|
|
18
|
+
*/
|
|
19
|
+
contentDir: string;
|
|
20
|
+
};
|
|
65
21
|
}
|
|
66
22
|
interface IndexItem {
|
|
67
23
|
path: string;
|
|
@@ -74,12 +30,8 @@ interface IndexItem {
|
|
|
74
30
|
*/
|
|
75
31
|
only?: (string | OutputFile)[];
|
|
76
32
|
}
|
|
77
|
-
interface
|
|
78
|
-
|
|
79
|
-
readonly generated: Record<string, OutputFile[]>;
|
|
80
|
-
readonly documents: Record<string, ProcessedDocument>;
|
|
81
|
-
}
|
|
82
|
-
interface BaseConfig extends GenerateOptions {
|
|
33
|
+
interface GenerateFilesConfig extends PagesToTextOptions {
|
|
34
|
+
cwd?: string;
|
|
83
35
|
/**
|
|
84
36
|
* Schema files, or the OpenAPI server object
|
|
85
37
|
*/
|
|
@@ -88,34 +40,22 @@ interface BaseConfig extends GenerateOptions {
|
|
|
88
40
|
* Output directory
|
|
89
41
|
*/
|
|
90
42
|
output: string;
|
|
91
|
-
/**
|
|
92
|
-
* Custom function to convert names into file names.
|
|
93
|
-
*
|
|
94
|
-
* By default, it only escapes whitespaces and upper case (English) characters
|
|
95
|
-
*/
|
|
96
|
-
slugify?: (name: string) => string;
|
|
97
43
|
/**
|
|
98
44
|
* Generate index files with cards linking to generated pages.
|
|
99
45
|
*/
|
|
100
|
-
index?:
|
|
101
|
-
items: IndexItem[] | ((ctx: HookContext) => IndexItem[]);
|
|
102
|
-
/**
|
|
103
|
-
* Generate URLs for cards
|
|
104
|
-
*/
|
|
105
|
-
url: ((filePath: string) => string) | {
|
|
106
|
-
baseUrl: string;
|
|
107
|
-
/**
|
|
108
|
-
* Base content directory
|
|
109
|
-
*/
|
|
110
|
-
contentDir: string;
|
|
111
|
-
};
|
|
112
|
-
};
|
|
46
|
+
index?: IndexConfig;
|
|
113
47
|
/**
|
|
114
48
|
* Can add/change/remove output files before writing to file system
|
|
115
49
|
**/
|
|
116
50
|
beforeWrite?: (this: HookContext, files: OutputFile[]) => void | Promise<void>;
|
|
117
51
|
}
|
|
52
|
+
export type Config = SchemaToPagesOptions & GenerateFilesConfig;
|
|
53
|
+
interface HookContext {
|
|
54
|
+
files: OutputFile[];
|
|
55
|
+
readonly generated: Record<string, OutputFile[]>;
|
|
56
|
+
readonly documents: Record<string, ProcessedDocument>;
|
|
57
|
+
}
|
|
118
58
|
export declare function generateFiles(options: Config): Promise<void>;
|
|
119
|
-
export declare function generateFilesOnly(options:
|
|
59
|
+
export declare function generateFilesOnly(options: SchemaToPagesOptions & Omit<GenerateFilesConfig, 'output'>): Promise<OutputFile[]>;
|
|
120
60
|
export {};
|
|
121
61
|
//# sourceMappingURL=generate-file.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-file.d.ts","sourceRoot":"","sources":["../src/generate-file.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"generate-file.d.ts","sourceRoot":"","sources":["../src/generate-file.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,WAAW;IACnB,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,WAAW,KAAK,SAAS,EAAE,CAAC,CAAC;IAEzD;;OAEG;IACH,GAAG,EACC,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,GAC9B;QACE,OAAO,EAAE,MAAM,CAAC;QAChB;;WAEG;QACH,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACP;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC;CAChC;AAED,UAAU,mBAAoB,SAAQ,kBAAkB;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,aAAa,CAAC;IAEzC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,KAAK,CAAC,EAAE,WAAW,CAAC;IAEpB;;QAEI;IACJ,WAAW,CAAC,EAAE,CACZ,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,UAAU,EAAE,KAChB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,MAAM,MAAM,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;AAEhE,UAAU,WAAW;IACnB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CACvD;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAclE;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,GAClE,OAAO,CAAC,UAAU,EAAE,CAAC,CAkEvB"}
|
package/dist/generate-file.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { glob } from 'tinyglobby';
|
|
4
|
-
import {
|
|
4
|
+
import { generateDocument, toText, } from './utils/pages/to-text.js';
|
|
5
5
|
import { processDocumentCached, } from './utils/process-document.js';
|
|
6
6
|
import { createGetUrl, getSlugs } from 'fumadocs-core/source';
|
|
7
7
|
import matter from 'gray-matter';
|
|
8
|
+
import { isUrl, schemaToPages, } from './utils/schema-to-pages.js';
|
|
8
9
|
export async function generateFiles(options) {
|
|
9
10
|
const files = await generateFilesOnly(options);
|
|
11
|
+
const { output, cwd = process.cwd() } = options;
|
|
12
|
+
const baseDir = path.join(cwd, output);
|
|
10
13
|
await Promise.all(files.map(async (file) => {
|
|
11
|
-
|
|
12
|
-
await
|
|
13
|
-
|
|
14
|
+
const filePath = path.join(baseDir, file.path);
|
|
15
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
16
|
+
await writeFile(filePath, file.content);
|
|
17
|
+
console.log(`Generated: ${filePath}`);
|
|
14
18
|
}));
|
|
15
19
|
}
|
|
16
20
|
export async function generateFilesOnly(options) {
|
|
@@ -49,7 +53,10 @@ export async function generateFilesOnly(options) {
|
|
|
49
53
|
throw new Error('No input files found.');
|
|
50
54
|
}
|
|
51
55
|
for (const [id, schema] of entries) {
|
|
52
|
-
const result =
|
|
56
|
+
const result = schemaToPages(id, schema, options).map((page) => ({
|
|
57
|
+
path: page.path,
|
|
58
|
+
content: toText(page, schema, options),
|
|
59
|
+
}));
|
|
53
60
|
files.push(...result);
|
|
54
61
|
generated[id] = result;
|
|
55
62
|
}
|
|
@@ -59,140 +66,17 @@ export async function generateFilesOnly(options) {
|
|
|
59
66
|
documents: schemas,
|
|
60
67
|
};
|
|
61
68
|
if (options.index) {
|
|
62
|
-
writeIndexFiles(context, options);
|
|
69
|
+
writeIndexFiles(context, options.index, options);
|
|
63
70
|
}
|
|
64
71
|
await beforeWrite?.call(context, context.files);
|
|
65
72
|
return context.files;
|
|
66
73
|
}
|
|
67
|
-
function
|
|
68
|
-
const
|
|
69
|
-
const { dereferenced } = processed;
|
|
70
|
-
const { output, cwd = process.cwd(), slugify = defaultSlugify } = options;
|
|
71
|
-
const outputDir = path.join(cwd, output);
|
|
72
|
-
let nameFn;
|
|
73
|
-
if (!options.name || typeof options.name !== 'function') {
|
|
74
|
-
const algorithm = options.name?.algorithm;
|
|
75
|
-
nameFn = (out, doc) => defaultNameFn(schemaId, out, doc, options, algorithm);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
nameFn = options.name;
|
|
79
|
-
}
|
|
80
|
-
function getOutputPaths(groupBy = 'none', result) {
|
|
81
|
-
if (groupBy === 'route') {
|
|
82
|
-
return [
|
|
83
|
-
path.join(getOutputPathFromRoute(result.type === 'operation' ? result.item.path : result.item.name), `${result.item.method.toLowerCase()}.mdx`),
|
|
84
|
-
];
|
|
85
|
-
}
|
|
86
|
-
const file = nameFn(result, dereferenced);
|
|
87
|
-
if (groupBy === 'tag') {
|
|
88
|
-
let tags = result.type === 'operation'
|
|
89
|
-
? dereferenced.paths[result.item.path][result.item.method].tags
|
|
90
|
-
: dereferenced.webhooks[result.item.name][result.item.method].tags;
|
|
91
|
-
if (!tags || tags.length === 0) {
|
|
92
|
-
console.warn('When `groupBy` is set to `tag`, make sure a `tags` is defined for every operation schema.');
|
|
93
|
-
tags = ['unknown'];
|
|
94
|
-
}
|
|
95
|
-
return tags.map((tag) => path.join(slugify(tag), `${file}.mdx`));
|
|
96
|
-
}
|
|
97
|
-
return [`${file}.mdx`];
|
|
98
|
-
}
|
|
99
|
-
if (options.per === 'file') {
|
|
100
|
-
const result = generateAll(schemaId, processed, options);
|
|
101
|
-
const filename = nameFn({
|
|
102
|
-
pathOrUrl: schemaId,
|
|
103
|
-
content: result,
|
|
104
|
-
}, dereferenced);
|
|
105
|
-
files.push({
|
|
106
|
-
path: path.join(outputDir, `${filename}.mdx`),
|
|
107
|
-
content: result,
|
|
108
|
-
});
|
|
109
|
-
return files;
|
|
110
|
-
}
|
|
111
|
-
if (options.per === 'tag') {
|
|
112
|
-
const results = generateTags(schemaId, processed, options);
|
|
113
|
-
for (const result of results) {
|
|
114
|
-
const filename = nameFn(result, dereferenced);
|
|
115
|
-
files.push({
|
|
116
|
-
path: path.join(outputDir, `${filename}.mdx`),
|
|
117
|
-
content: result.content,
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
return files;
|
|
121
|
-
}
|
|
122
|
-
const results = generatePages(schemaId, processed, options);
|
|
123
|
-
const mapping = new Map();
|
|
124
|
-
for (const result of results) {
|
|
125
|
-
for (const outputPath of getOutputPaths(options.groupBy, result)) {
|
|
126
|
-
mapping.set(outputPath, result);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
for (const [key, output] of mapping.entries()) {
|
|
130
|
-
let outputPath = key;
|
|
131
|
-
// v1 will remove nested directories
|
|
132
|
-
if (typeof options.name === 'object' && options.name.algorithm === 'v1') {
|
|
133
|
-
const isSharedDir = Array.from(mapping.keys()).some((item) => item !== outputPath &&
|
|
134
|
-
path.dirname(item) === path.dirname(outputPath));
|
|
135
|
-
if (!isSharedDir && path.dirname(outputPath) !== '.') {
|
|
136
|
-
outputPath = path.join(path.dirname(outputPath) + '.mdx');
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
files.push({
|
|
140
|
-
path: path.join(outputDir, outputPath),
|
|
141
|
-
content: output.content,
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
return files;
|
|
145
|
-
}
|
|
146
|
-
function defaultNameFn(schemaId, output, document, options, algorithm = 'v2') {
|
|
147
|
-
const { slugify = defaultSlugify } = options;
|
|
148
|
-
if (options.per === 'tag') {
|
|
149
|
-
const result = output;
|
|
150
|
-
return slugify(result.tag);
|
|
151
|
-
}
|
|
152
|
-
if (options.per === 'file') {
|
|
153
|
-
return isUrl(schemaId)
|
|
154
|
-
? 'index'
|
|
155
|
-
: path.basename(schemaId, path.extname(schemaId));
|
|
156
|
-
}
|
|
157
|
-
const result = output;
|
|
158
|
-
if (result.type === 'operation') {
|
|
159
|
-
const operation = document.paths[result.item.path][result.item.method];
|
|
160
|
-
if (algorithm === 'v2' && operation.operationId) {
|
|
161
|
-
return operation.operationId;
|
|
162
|
-
}
|
|
163
|
-
return path.join(getOutputPathFromRoute(result.item.path), result.item.method.toLowerCase());
|
|
164
|
-
}
|
|
165
|
-
const hook = document.webhooks[result.item.name][result.item.method];
|
|
166
|
-
if (algorithm === 'v2' && hook.operationId) {
|
|
167
|
-
return hook.operationId;
|
|
168
|
-
}
|
|
169
|
-
return slugify(result.item.name);
|
|
170
|
-
}
|
|
171
|
-
function isUrl(input) {
|
|
172
|
-
return input.startsWith('https://') || input.startsWith('http://');
|
|
173
|
-
}
|
|
174
|
-
function getOutputPathFromRoute(path) {
|
|
175
|
-
return (path
|
|
176
|
-
.toLowerCase()
|
|
177
|
-
.replaceAll('.', '-')
|
|
178
|
-
.split('/')
|
|
179
|
-
.map((v) => {
|
|
180
|
-
if (v.startsWith('{') && v.endsWith('}'))
|
|
181
|
-
return v.slice(1, -1);
|
|
182
|
-
return v;
|
|
183
|
-
})
|
|
184
|
-
.join('/') ?? '');
|
|
185
|
-
}
|
|
186
|
-
function writeIndexFiles(context, options) {
|
|
187
|
-
const { index, output, cwd = process.cwd() } = options;
|
|
188
|
-
if (!index)
|
|
189
|
-
return;
|
|
190
|
-
const { items, url } = index;
|
|
74
|
+
function writeIndexFiles(context, options, generateOptions) {
|
|
75
|
+
const { items, url } = options;
|
|
191
76
|
let urlFn;
|
|
192
77
|
if (typeof url === 'object') {
|
|
193
78
|
const getUrl = createGetUrl(url.baseUrl);
|
|
194
|
-
|
|
195
|
-
urlFn = (file) => getUrl(getSlugs(path.relative(contentDir, file)));
|
|
79
|
+
urlFn = (file) => getUrl(getSlugs(path.relative(url.contentDir, file)));
|
|
196
80
|
}
|
|
197
81
|
else {
|
|
198
82
|
urlFn = url;
|
|
@@ -231,17 +115,12 @@ function writeIndexFiles(context, options) {
|
|
|
231
115
|
return generateDocument({
|
|
232
116
|
title: index.title ?? 'Overview',
|
|
233
117
|
description: index.description,
|
|
234
|
-
}, content.join('\n'),
|
|
118
|
+
}, content.join('\n'), generateOptions);
|
|
235
119
|
}
|
|
236
|
-
const outputDir = path.join(cwd, output);
|
|
237
120
|
for (const item of typeof items === 'function' ? items(context) : items) {
|
|
238
|
-
const outPath = path.join(outputDir, path.extname(item.path).length === 0 ? `${item.path}.mdx` : item.path);
|
|
239
121
|
context.files.push({
|
|
240
|
-
path:
|
|
122
|
+
path: path.extname(item.path).length === 0 ? `${item.path}.mdx` : item.path,
|
|
241
123
|
content: fileContent(item),
|
|
242
124
|
});
|
|
243
125
|
}
|
|
244
126
|
}
|
|
245
|
-
function defaultSlugify(s) {
|
|
246
|
-
return s.replace(/\s+/g, '-').toLowerCase();
|
|
247
|
-
}
|
package/dist/render/api-page.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import Slugger from 'github-slugger';
|
|
3
3
|
import { Operation } from '../render/operation/index.js';
|
|
4
|
-
import { createMethod } from '../
|
|
4
|
+
import { createMethod } from '../utils/schema.js';
|
|
5
5
|
import { createRenders } from '../render/renderer.js';
|
|
6
6
|
import { processDocumentCached, } from '../utils/process-document.js';
|
|
7
7
|
import { defaultAdapters } from '../media/adapter.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/render/operation/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,YAAY,EAAkB,MAAM,OAAO,CAAC;AACpE,OAAO,KAAK,EAEV,iBAAiB,EACjB,aAAa,EAEd,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/render/operation/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,YAAY,EAAkB,MAAM,OAAO,CAAC;AACpE,OAAO,KAAK,EAEV,iBAAiB,EACjB,aAAa,EAEd,MAAM,SAAS,CAAC;AAajB,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAY1D,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,OAAO;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IAE7C;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,CAAC;CACnB;AASD,wBAAgB,SAAS,CAAC,EACxB,IAAkB,EAClB,IAAI,EACJ,MAAM,EACN,GAAG,EACH,OAAO,EACP,YAAgB,GACjB,EAAE;IACD,IAAI,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,GAAG,EAAE,aAAa,CAAC;IAEnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,YAAY,CAiNf"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment } from 'react';
|
|
3
|
+
import { createMethod } from '../../utils/schema.js';
|
|
3
4
|
import { idToTitle } from '../../utils/id-to-title.js';
|
|
4
5
|
import { Markdown } from '../markdown.js';
|
|
5
6
|
import { heading } from '../heading.js';
|
|
6
7
|
import { Schema } from '../schema.js';
|
|
7
|
-
import { createMethod } from '../../server/create-method.js';
|
|
8
8
|
import { methodKeys } from '../../build-routes.js';
|
|
9
9
|
import { APIExample, APIExampleProvider, getAPIExamples, } from '../../render/operation/api-example.js';
|
|
10
10
|
import { MethodLabel } from '../../ui/components/method-label.js';
|
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
import type * as PageTree from 'fumadocs-core/page-tree';
|
|
2
|
-
import
|
|
2
|
+
import { LoaderPlugin, MetaData, PageData, PageFile, PageTreeTransformer, Source } from 'fumadocs-core/source';
|
|
3
|
+
import type { OpenAPIServer } from '../server/create.js';
|
|
4
|
+
import type { SchemaToPagesOptions } from '../utils/schema-to-pages.js';
|
|
5
|
+
import { ApiPageProps } from '../render/api-page.js';
|
|
6
|
+
declare module 'fumadocs-core/source' {
|
|
7
|
+
interface PageData {
|
|
8
|
+
/**
|
|
9
|
+
* Added by Fumadocs OpenAPI
|
|
10
|
+
*/
|
|
11
|
+
_openapi?: {
|
|
12
|
+
method?: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
3
16
|
/**
|
|
4
17
|
* Fumadocs Source API integration, pass this to `plugins` array in `loader()`.
|
|
5
18
|
*/
|
|
6
19
|
export declare function openapiPlugin(): LoaderPlugin;
|
|
20
|
+
interface OpenAPIPageData extends PageData {
|
|
21
|
+
getAPIPageProps: () => ApiPageProps;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Generate virtual pages for Fumadocs Source API
|
|
25
|
+
*/
|
|
26
|
+
export declare function openapiSource(from: OpenAPIServer, options?: SchemaToPagesOptions & {
|
|
27
|
+
baseDir?: string;
|
|
28
|
+
}): Promise<Source<{
|
|
29
|
+
metaData: MetaData;
|
|
30
|
+
pageData: OpenAPIPageData;
|
|
31
|
+
}>>;
|
|
7
32
|
/**
|
|
8
33
|
* Source API Integration, add this to page tree builder options.
|
|
9
34
|
*
|
|
@@ -14,4 +39,5 @@ export declare const attachFile: (node: PageTree.Item, file: PageFile | undefine
|
|
|
14
39
|
* @deprecated use `openapiPlugin()`
|
|
15
40
|
*/
|
|
16
41
|
export declare function transformerOpenAPI(): PageTreeTransformer;
|
|
42
|
+
export {};
|
|
17
43
|
//# sourceMappingURL=source-api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-api.d.ts","sourceRoot":"","sources":["../../src/server/source-api.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"source-api.d.ts","sourceRoot":"","sources":["../../src/server/source-api.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,MAAM,EAEP,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,QAAQ,sBAAsB,CAAC;IACpC,UAAiB,QAAQ;QACvB;;WAEG;QACH,QAAQ,CAAC,EAAE;YACT,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC;KACH;CACF;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,YAAY,CAgC5C;AAED,UAAU,eAAgB,SAAQ,QAAQ;IACxC,eAAe,EAAE,MAAM,YAAY,CAAC;CACrC;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,oBAAoB,GAAG;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CACb,GACL,OAAO,CACR,MAAM,CAAC;IACL,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,eAAe,CAAC;CAC3B,CAAC,CACH,CA8BA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,QAAQ,CAAC,IAAI,EACnB,MAAM,QAAQ,GAAG,SAAS,KACzB,QAAQ,CAAC,IA4BX,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,mBAAmB,CAExD"}
|
|
@@ -5,6 +5,8 @@ import { MethodLabel } from '../ui/components/method-label.js';
|
|
|
5
5
|
*/
|
|
6
6
|
export function openapiPlugin() {
|
|
7
7
|
return {
|
|
8
|
+
name: 'fumadocs:openapi',
|
|
9
|
+
enforce: 'pre',
|
|
8
10
|
transformPageTree: {
|
|
9
11
|
file(node, filePath) {
|
|
10
12
|
if (!filePath)
|
|
@@ -15,8 +17,7 @@ export function openapiPlugin() {
|
|
|
15
17
|
const data = file.data;
|
|
16
18
|
let method;
|
|
17
19
|
if ('_openapi' in data && typeof data._openapi === 'object') {
|
|
18
|
-
|
|
19
|
-
method = meta.method;
|
|
20
|
+
method = data._openapi.method;
|
|
20
21
|
}
|
|
21
22
|
if (method) {
|
|
22
23
|
node.name = (_jsxs(_Fragment, { children: [node.name, ' ', _jsx(MethodLabel, { className: "ms-auto text-xs text-nowrap", children: method })] }));
|
|
@@ -26,6 +27,34 @@ export function openapiPlugin() {
|
|
|
26
27
|
},
|
|
27
28
|
};
|
|
28
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Generate virtual pages for Fumadocs Source API
|
|
32
|
+
*/
|
|
33
|
+
export async function openapiSource(from, options = {}) {
|
|
34
|
+
const { baseDir = '' } = options;
|
|
35
|
+
const { serverToPages } = await import('../utils/schema-to-pages.js');
|
|
36
|
+
const { toBody } = await import('../utils/pages/to-body.js');
|
|
37
|
+
const files = [];
|
|
38
|
+
const entries = await serverToPages(from, options);
|
|
39
|
+
for (const entry of Object.values(entries).flat()) {
|
|
40
|
+
files.push({
|
|
41
|
+
type: 'page',
|
|
42
|
+
path: `${baseDir}/${entry.path}`,
|
|
43
|
+
data: {
|
|
44
|
+
...entry.info,
|
|
45
|
+
getAPIPageProps: () => toBody(from, entry),
|
|
46
|
+
_openapi: {
|
|
47
|
+
method: entry.type === 'operation' || entry.type === 'webhook'
|
|
48
|
+
? entry.item.method
|
|
49
|
+
: undefined,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
files,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
29
58
|
/**
|
|
30
59
|
* Source API Integration, add this to page tree builder options.
|
|
31
60
|
*
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { OutputEntry } from '../../utils/schema-to-pages.js';
|
|
2
|
+
import type { ApiPageProps } from '../../render/api-page.js';
|
|
3
|
+
import type { OpenAPIServer } from '../../server/index.js';
|
|
4
|
+
export declare function toBody(server: OpenAPIServer, entry: OutputEntry): ApiPageProps;
|
|
5
|
+
//# sourceMappingURL=to-body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"to-body.d.ts","sourceRoot":"","sources":["../../../src/utils/pages/to-body.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,MAAM,CACpB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,WAAW,GACjB,YAAY,CAoBd"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function toBody(server, entry) {
|
|
2
|
+
if (entry.type === 'operation')
|
|
3
|
+
return server.getAPIPageProps({
|
|
4
|
+
hasHead: false,
|
|
5
|
+
document: entry.schemaId,
|
|
6
|
+
operations: [entry.item],
|
|
7
|
+
});
|
|
8
|
+
if (entry.type === 'webhook')
|
|
9
|
+
return server.getAPIPageProps({
|
|
10
|
+
hasHead: false,
|
|
11
|
+
document: entry.schemaId,
|
|
12
|
+
webhooks: [entry.item],
|
|
13
|
+
});
|
|
14
|
+
return server.getAPIPageProps({
|
|
15
|
+
hasHead: true,
|
|
16
|
+
document: entry.schemaId,
|
|
17
|
+
operations: entry.operations,
|
|
18
|
+
webhooks: entry.webhooks,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ProcessedDocument } from '../../utils/process-document.js';
|
|
2
|
+
import type { TagObject } from '../../types.js';
|
|
3
|
+
import type { OutputEntry } from '../../utils/schema-to-pages.js';
|
|
4
|
+
export interface PagesToTextOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Additional imports of your MDX components.
|
|
7
|
+
*/
|
|
8
|
+
imports?: {
|
|
9
|
+
names: string[];
|
|
10
|
+
from: string;
|
|
11
|
+
}[];
|
|
12
|
+
/**
|
|
13
|
+
* Customise frontmatter.
|
|
14
|
+
*
|
|
15
|
+
* A `full: true` property will be added by default.
|
|
16
|
+
*/
|
|
17
|
+
frontmatter?: (title: string, description: string | undefined, context: DocumentContext) => Record<string, unknown>;
|
|
18
|
+
/**
|
|
19
|
+
* Add description to document body.
|
|
20
|
+
*
|
|
21
|
+
* We recommend but don't enable it by default because some OpenAPI schemas have invalid description that breaks MDX syntax.
|
|
22
|
+
*
|
|
23
|
+
* @defaultValue false
|
|
24
|
+
*/
|
|
25
|
+
includeDescription?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Add a comment to the top of generated files indicating they are auto-generated.
|
|
28
|
+
* - `true`: Adds a standardized comment
|
|
29
|
+
* - `false`: No comment is added
|
|
30
|
+
* - `string`: Adds the provided custom comment
|
|
31
|
+
*
|
|
32
|
+
* @defaultValue true
|
|
33
|
+
*/
|
|
34
|
+
addGeneratedComment?: boolean | string;
|
|
35
|
+
}
|
|
36
|
+
export declare function toText(entry: OutputEntry, processed: ProcessedDocument, options?: PagesToTextOptions): string;
|
|
37
|
+
export declare function generateDocument(frontmatter: unknown, content: string, options: PagesToTextOptions): string;
|
|
38
|
+
export type DocumentContext = {
|
|
39
|
+
type: 'tag';
|
|
40
|
+
tag: TagObject | undefined;
|
|
41
|
+
} | {
|
|
42
|
+
type: 'operation';
|
|
43
|
+
} | {
|
|
44
|
+
type: 'file';
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=to-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"to-text.d.ts","sourceRoot":"","sources":["../../../src/utils/pages/to-text.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,KAAK,EAAY,SAAS,EAAE,MAAM,SAAS,CAAC;AAKnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;KACd,EAAE,CAAC;IAEJ;;;;OAIG;IACH,WAAW,CAAC,EAAE,CACZ,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,eAAe,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE7B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACxC;AAED,wBAAgB,MAAM,CACpB,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,GAAE,kBAAuB,UAuEjC;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,OAAO,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,kBAAkB,GAC1B,MAAM,CA+BR;AAOD,MAAM,MAAM,eAAe,GACvB;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,SAAS,GAAG,SAAS,CAAC;CAC5B,GACD;IACE,IAAI,EAAE,WAAW,CAAC;CACnB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC"}
|
|
@@ -1,102 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { idToTitle } from './utils/id-to-title.js';
|
|
1
|
+
import { idToTitle } from '../../utils/id-to-title.js';
|
|
3
2
|
import { dump } from 'js-yaml';
|
|
4
3
|
import Slugger from 'github-slugger';
|
|
5
|
-
import { removeUndefined } from '
|
|
6
|
-
export function
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
webhooks: items.webhooks,
|
|
12
|
-
hasHead: true,
|
|
13
|
-
}, {
|
|
14
|
-
...options,
|
|
15
|
-
title: dereferenced.info.title,
|
|
16
|
-
description: dereferenced.info.description,
|
|
17
|
-
}, {
|
|
18
|
-
type: 'file',
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
export function generatePages(schemaId, processed, options = {}) {
|
|
22
|
-
const { dereferenced } = processed;
|
|
23
|
-
const items = getAPIPageItems(dereferenced);
|
|
24
|
-
const result = [];
|
|
25
|
-
for (const item of items.operations) {
|
|
26
|
-
const pathItem = dereferenced.paths?.[item.path];
|
|
27
|
-
if (!pathItem)
|
|
28
|
-
continue;
|
|
29
|
-
const operation = pathItem[item.method];
|
|
30
|
-
if (!operation)
|
|
31
|
-
continue;
|
|
32
|
-
result.push({
|
|
33
|
-
type: 'operation',
|
|
34
|
-
item,
|
|
35
|
-
content: generatePage(schemaId, processed, {
|
|
36
|
-
operations: [item],
|
|
4
|
+
import { removeUndefined } from '../../utils/remove-undefined.js';
|
|
5
|
+
export function toText(entry, processed, options = {}) {
|
|
6
|
+
switch (entry.type) {
|
|
7
|
+
case 'operation':
|
|
8
|
+
return generatePage(entry.schemaId, processed, {
|
|
9
|
+
operations: [entry.item],
|
|
37
10
|
hasHead: false,
|
|
38
11
|
}, {
|
|
39
12
|
...options,
|
|
40
|
-
|
|
41
|
-
pathItem.summary ??
|
|
42
|
-
idToTitle(operation.operationId ?? 'unknown'),
|
|
43
|
-
description: operation.description ?? pathItem.description,
|
|
13
|
+
...entry.info,
|
|
44
14
|
}, {
|
|
45
15
|
type: 'operation',
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
continue;
|
|
53
|
-
const operation = pathItem[item.method];
|
|
54
|
-
if (!operation)
|
|
55
|
-
continue;
|
|
56
|
-
result.push({
|
|
57
|
-
type: 'webhook',
|
|
58
|
-
item,
|
|
59
|
-
content: generatePage(schemaId, processed, {
|
|
60
|
-
webhooks: [item],
|
|
61
|
-
hasHead: false,
|
|
16
|
+
});
|
|
17
|
+
case 'schema':
|
|
18
|
+
return generatePage(entry.schemaId, processed, {
|
|
19
|
+
operations: entry.operations,
|
|
20
|
+
webhooks: entry.webhooks,
|
|
21
|
+
hasHead: true,
|
|
62
22
|
}, {
|
|
63
23
|
...options,
|
|
64
|
-
|
|
65
|
-
description: operation.description ?? pathItem.description,
|
|
24
|
+
...entry.info,
|
|
66
25
|
}, {
|
|
67
|
-
type: '
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
export function generateTags(schemaId, processed, options = {}) {
|
|
74
|
-
const { dereferenced } = processed;
|
|
75
|
-
if (!dereferenced.tags)
|
|
76
|
-
return [];
|
|
77
|
-
const items = getAPIPageItems(dereferenced);
|
|
78
|
-
return dereferenced.tags.map((tag) => {
|
|
79
|
-
const webhooks = items.webhooks.filter((v) => v.tags && v.tags.includes(tag.name));
|
|
80
|
-
const operations = items.operations.filter((v) => v.tags && v.tags.includes(tag.name));
|
|
81
|
-
const displayName = tag && 'x-displayName' in tag && typeof tag['x-displayName'] === 'string'
|
|
82
|
-
? tag['x-displayName']
|
|
83
|
-
: idToTitle(tag.name);
|
|
84
|
-
return {
|
|
85
|
-
tag: tag.name,
|
|
86
|
-
content: generatePage(schemaId, processed, {
|
|
87
|
-
operations,
|
|
88
|
-
webhooks,
|
|
26
|
+
type: 'file',
|
|
27
|
+
});
|
|
28
|
+
case 'tag':
|
|
29
|
+
return generatePage(entry.schemaId, processed, {
|
|
30
|
+
operations: entry.operations,
|
|
31
|
+
webhooks: entry.webhooks,
|
|
89
32
|
hasHead: true,
|
|
90
33
|
}, {
|
|
91
34
|
...options,
|
|
92
|
-
|
|
93
|
-
description: tag?.description,
|
|
35
|
+
...entry.info,
|
|
94
36
|
}, {
|
|
95
37
|
type: 'tag',
|
|
96
|
-
tag,
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
|
|
38
|
+
tag: entry.rawTag,
|
|
39
|
+
});
|
|
40
|
+
case 'webhook':
|
|
41
|
+
return generatePage(entry.schemaId, processed, {
|
|
42
|
+
webhooks: [entry.item],
|
|
43
|
+
hasHead: false,
|
|
44
|
+
}, {
|
|
45
|
+
...options,
|
|
46
|
+
...entry.info,
|
|
47
|
+
}, {
|
|
48
|
+
type: 'operation',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
100
51
|
}
|
|
101
52
|
export function generateDocument(frontmatter, content, options) {
|
|
102
53
|
const { addGeneratedComment = true, imports } = options;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type ProcessedDocument } from '../utils/process-document.js';
|
|
2
|
+
import type { OpenAPIServer } from '../server/index.js';
|
|
3
|
+
import type { OperationItem, WebhookItem } from '../render/api-page.js';
|
|
4
|
+
import type { TagObject } from '../types.js';
|
|
5
|
+
interface BaseEntry {
|
|
6
|
+
path: string;
|
|
7
|
+
schemaId: string;
|
|
8
|
+
info: {
|
|
9
|
+
title: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export interface OutputOperationEntry extends BaseEntry {
|
|
14
|
+
type: 'operation';
|
|
15
|
+
item: OperationItem;
|
|
16
|
+
}
|
|
17
|
+
export interface OutputWebhookEntry extends BaseEntry {
|
|
18
|
+
type: 'webhook';
|
|
19
|
+
item: WebhookItem;
|
|
20
|
+
}
|
|
21
|
+
export interface OutputTagEntry extends BaseEntry {
|
|
22
|
+
type: 'tag';
|
|
23
|
+
tag: string;
|
|
24
|
+
rawTag: TagObject;
|
|
25
|
+
operations: OperationItem[];
|
|
26
|
+
webhooks: WebhookItem[];
|
|
27
|
+
}
|
|
28
|
+
export interface OutputSchemaEntry extends BaseEntry {
|
|
29
|
+
type: 'schema';
|
|
30
|
+
operations: OperationItem[];
|
|
31
|
+
webhooks: WebhookItem[];
|
|
32
|
+
}
|
|
33
|
+
export type OutputEntry = OutputTagEntry | OutputOperationEntry | OutputWebhookEntry | OutputSchemaEntry;
|
|
34
|
+
interface OperationConfig extends BaseConfig {
|
|
35
|
+
/**
|
|
36
|
+
* Generate a page for each API endpoint/operation (default).
|
|
37
|
+
*/
|
|
38
|
+
per?: 'operation';
|
|
39
|
+
/**
|
|
40
|
+
* Group output using folders (Only works on `operation` mode)
|
|
41
|
+
* - tag: `{tag}/{file}`
|
|
42
|
+
* - route: `{endpoint}/{method}` (it will ignore the `name` option)
|
|
43
|
+
* - none: `{file}` (default)
|
|
44
|
+
*
|
|
45
|
+
* @defaultValue 'none'
|
|
46
|
+
*/
|
|
47
|
+
groupBy?: 'tag' | 'route' | 'none';
|
|
48
|
+
/**
|
|
49
|
+
* Specify name for output file
|
|
50
|
+
*/
|
|
51
|
+
name?: NameFn<OutputOperationEntry | OutputWebhookEntry>;
|
|
52
|
+
}
|
|
53
|
+
interface TagConfig extends BaseConfig {
|
|
54
|
+
/**
|
|
55
|
+
* Generate a page for each tag.
|
|
56
|
+
*/
|
|
57
|
+
per: 'tag';
|
|
58
|
+
/**
|
|
59
|
+
* Specify name for output file
|
|
60
|
+
*/
|
|
61
|
+
name?: NameFn<OutputTagEntry>;
|
|
62
|
+
}
|
|
63
|
+
interface SchemaConfig extends BaseConfig {
|
|
64
|
+
/**
|
|
65
|
+
* Generate a page for each schema file.
|
|
66
|
+
*/
|
|
67
|
+
per: 'file';
|
|
68
|
+
/**
|
|
69
|
+
* Specify name for output file
|
|
70
|
+
*/
|
|
71
|
+
name?: NameFn<OutputSchemaEntry>;
|
|
72
|
+
}
|
|
73
|
+
export type SchemaToPagesOptions = SchemaConfig | TagConfig | OperationConfig;
|
|
74
|
+
type NameFn<Entry> = ((output: Entry, document: ProcessedDocument['dereferenced']) => string) | {
|
|
75
|
+
/**
|
|
76
|
+
* The version of algorithm used to generate file paths.
|
|
77
|
+
*
|
|
78
|
+
* v1: Fumadocs OpenAPI v8
|
|
79
|
+
* v2: Fumadocs OpenAPI v9
|
|
80
|
+
*
|
|
81
|
+
* @defaultValue v2
|
|
82
|
+
*/
|
|
83
|
+
algorithm?: 'v2' | 'v1';
|
|
84
|
+
};
|
|
85
|
+
interface BaseConfig {
|
|
86
|
+
/**
|
|
87
|
+
* Custom function to convert names into file names.
|
|
88
|
+
*
|
|
89
|
+
* By default, it only escapes whitespaces and upper case (English) characters
|
|
90
|
+
*/
|
|
91
|
+
slugify?: (name: string) => string;
|
|
92
|
+
}
|
|
93
|
+
export declare function serverToPages(server: OpenAPIServer, options: SchemaToPagesOptions): Promise<Record<string, OutputEntry[]>>;
|
|
94
|
+
export declare function schemaToPages(schemaId: string, processed: ProcessedDocument, options: SchemaToPagesOptions): OutputEntry[];
|
|
95
|
+
export declare function isUrl(schemaId: string): boolean;
|
|
96
|
+
export {};
|
|
97
|
+
//# sourceMappingURL=schema-to-pages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-to-pages.d.ts","sourceRoot":"","sources":["../../src/utils/schema-to-pages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGzC,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,oBAAqB,SAAQ,SAAS;IACrD,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,CAAC;IAClB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,MAAM,WAAW,GACnB,cAAc,GACd,oBAAoB,GACpB,kBAAkB,GAClB,iBAAiB,CAAC;AAEtB,UAAU,eAAgB,SAAQ,UAAU;IAC1C;;OAEG;IACH,GAAG,CAAC,EAAE,WAAW,CAAC;IAElB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;IAEnC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,oBAAoB,GAAG,kBAAkB,CAAC,CAAC;CAC1D;AAED,UAAU,SAAU,SAAQ,UAAU;IACpC;;OAEG;IACH,GAAG,EAAE,KAAK,CAAC;IAEX;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;CAC/B;AAED,UAAU,YAAa,SAAQ,UAAU;IACvC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;CAClC;AAED,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,SAAS,GAAG,eAAe,CAAC;AAE9E,KAAK,MAAM,CAAC,KAAK,IACb,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,iBAAiB,CAAC,cAAc,CAAC,KAAK,MAAM,CAAC,GACxE;IACE;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB,CAAC;AAEN,UAAU,UAAU;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAcxC;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,oBAAoB,GAC5B,WAAW,EAAE,CAoJf;AA2CD,wBAAgB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE/C"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import { idToTitle } from '../utils/id-to-title.js';
|
|
3
|
+
import { getAPIPageItems } from '../build-routes.js';
|
|
4
|
+
import { getTagDisplayName } from '../utils/schema.js';
|
|
5
|
+
export async function serverToPages(server, options) {
|
|
6
|
+
const schemas = await server.getSchemas();
|
|
7
|
+
const generated = {};
|
|
8
|
+
const entries = Object.entries(schemas);
|
|
9
|
+
if (entries.length === 0) {
|
|
10
|
+
throw new Error('No input files found.');
|
|
11
|
+
}
|
|
12
|
+
for (const [id, schema] of entries) {
|
|
13
|
+
generated[id] = schemaToPages(id, schema, options);
|
|
14
|
+
}
|
|
15
|
+
return generated;
|
|
16
|
+
}
|
|
17
|
+
export function schemaToPages(schemaId, processed, options) {
|
|
18
|
+
const files = [];
|
|
19
|
+
const { dereferenced } = processed;
|
|
20
|
+
const { slugify = defaultSlugify } = options;
|
|
21
|
+
let nameFn;
|
|
22
|
+
if (!options.name || typeof options.name !== 'function') {
|
|
23
|
+
const algorithm = options.name?.algorithm;
|
|
24
|
+
nameFn = (out, doc) => defaultNameFn(schemaId, out, doc, options, algorithm);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
nameFn = options.name;
|
|
28
|
+
}
|
|
29
|
+
function getOutputPaths(groupBy = 'none', entry) {
|
|
30
|
+
if (groupBy === 'route') {
|
|
31
|
+
return [
|
|
32
|
+
path.join(getOutputPathFromRoute(entry.type === 'operation' ? entry.item.path : entry.item.name), `${entry.item.method.toLowerCase()}.mdx`),
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
const file = nameFn(entry, dereferenced);
|
|
36
|
+
if (groupBy === 'tag') {
|
|
37
|
+
let tags = entry.type === 'operation'
|
|
38
|
+
? dereferenced.paths[entry.item.path][entry.item.method].tags
|
|
39
|
+
: dereferenced.webhooks[entry.item.name][entry.item.method].tags;
|
|
40
|
+
if (!tags || tags.length === 0) {
|
|
41
|
+
console.warn('When `groupBy` is set to `tag`, make sure a `tags` is defined for every operation schema.');
|
|
42
|
+
tags = ['unknown'];
|
|
43
|
+
}
|
|
44
|
+
return tags.map((tag) => path.join(slugify(tag), `${file}.mdx`));
|
|
45
|
+
}
|
|
46
|
+
return [`${file}.mdx`];
|
|
47
|
+
}
|
|
48
|
+
if (options.per === 'file') {
|
|
49
|
+
const items = getAPIPageItems(dereferenced);
|
|
50
|
+
const entry = {
|
|
51
|
+
type: 'schema',
|
|
52
|
+
schemaId,
|
|
53
|
+
path: '',
|
|
54
|
+
info: {
|
|
55
|
+
title: dereferenced.info.title,
|
|
56
|
+
description: dereferenced.info.description,
|
|
57
|
+
},
|
|
58
|
+
...items,
|
|
59
|
+
};
|
|
60
|
+
entry.path = nameFn(entry, dereferenced) + '.mdx';
|
|
61
|
+
files.push(entry);
|
|
62
|
+
return files;
|
|
63
|
+
}
|
|
64
|
+
if (options.per === 'tag') {
|
|
65
|
+
const items = getAPIPageItems(dereferenced);
|
|
66
|
+
const tags = dereferenced.tags ?? [];
|
|
67
|
+
for (const tag of tags) {
|
|
68
|
+
const entry = {
|
|
69
|
+
type: 'tag',
|
|
70
|
+
path: '',
|
|
71
|
+
schemaId,
|
|
72
|
+
info: {
|
|
73
|
+
title: getTagDisplayName(tag),
|
|
74
|
+
description: tag.description,
|
|
75
|
+
},
|
|
76
|
+
webhooks: items.webhooks.filter((webhook) => webhook.tags?.includes(tag.name)),
|
|
77
|
+
operations: items.operations.filter((op) => op.tags?.includes(tag.name)),
|
|
78
|
+
tag: tag.name,
|
|
79
|
+
rawTag: tag,
|
|
80
|
+
};
|
|
81
|
+
entry.path = nameFn(entry, dereferenced) + '.mdx';
|
|
82
|
+
files.push(entry);
|
|
83
|
+
}
|
|
84
|
+
return files;
|
|
85
|
+
}
|
|
86
|
+
const results = getAPIPageItems(dereferenced);
|
|
87
|
+
for (const op of results.operations) {
|
|
88
|
+
const pathItem = dereferenced.paths[op.path];
|
|
89
|
+
const operation = pathItem[op.method];
|
|
90
|
+
const entry = {
|
|
91
|
+
type: 'operation',
|
|
92
|
+
schemaId,
|
|
93
|
+
item: op,
|
|
94
|
+
path: '',
|
|
95
|
+
info: {
|
|
96
|
+
title: operation.summary ??
|
|
97
|
+
pathItem.summary ??
|
|
98
|
+
idToTitle(operation.operationId ?? 'unknown'),
|
|
99
|
+
description: operation.description ?? pathItem.description,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
for (const outputPath of getOutputPaths(options.groupBy, entry)) {
|
|
103
|
+
files.push({ ...entry, path: outputPath });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
for (const webhook of results.webhooks) {
|
|
107
|
+
const pathItem = dereferenced.webhooks[webhook.name];
|
|
108
|
+
const operation = pathItem[webhook.method];
|
|
109
|
+
const entry = {
|
|
110
|
+
type: 'webhook',
|
|
111
|
+
schemaId,
|
|
112
|
+
info: {
|
|
113
|
+
title: operation.summary ?? pathItem.summary ?? idToTitle(webhook.name),
|
|
114
|
+
description: operation.description ?? pathItem.description,
|
|
115
|
+
},
|
|
116
|
+
item: webhook,
|
|
117
|
+
path: '',
|
|
118
|
+
};
|
|
119
|
+
for (const outputPath of getOutputPaths(options.groupBy, entry)) {
|
|
120
|
+
files.push({ ...entry, path: outputPath });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return files;
|
|
124
|
+
}
|
|
125
|
+
function defaultNameFn(schemaId, result, document, options, algorithm = 'v2') {
|
|
126
|
+
const { slugify = defaultSlugify } = options;
|
|
127
|
+
if (result.type === 'tag') {
|
|
128
|
+
return slugify(result.tag);
|
|
129
|
+
}
|
|
130
|
+
if (result.type === 'schema') {
|
|
131
|
+
return isUrl(schemaId)
|
|
132
|
+
? 'index'
|
|
133
|
+
: path.basename(schemaId, path.extname(schemaId));
|
|
134
|
+
}
|
|
135
|
+
if (result.type === 'operation') {
|
|
136
|
+
const operation = document.paths[result.item.path][result.item.method];
|
|
137
|
+
if (algorithm === 'v2' && operation.operationId) {
|
|
138
|
+
return operation.operationId;
|
|
139
|
+
}
|
|
140
|
+
return path.join(getOutputPathFromRoute(result.item.path), result.item.method.toLowerCase());
|
|
141
|
+
}
|
|
142
|
+
const hook = document.webhooks[result.item.name][result.item.method];
|
|
143
|
+
if (algorithm === 'v2' && hook.operationId) {
|
|
144
|
+
return hook.operationId;
|
|
145
|
+
}
|
|
146
|
+
return slugify(result.item.name);
|
|
147
|
+
}
|
|
148
|
+
export function isUrl(schemaId) {
|
|
149
|
+
return schemaId.startsWith('https://') || schemaId.startsWith('http://');
|
|
150
|
+
}
|
|
151
|
+
function getOutputPathFromRoute(path) {
|
|
152
|
+
return path
|
|
153
|
+
.toLowerCase()
|
|
154
|
+
.replaceAll('.', '-')
|
|
155
|
+
.split('/')
|
|
156
|
+
.flatMap((v) => {
|
|
157
|
+
if (v.startsWith('{') && v.endsWith('}'))
|
|
158
|
+
return v.slice(1, -1);
|
|
159
|
+
if (v.length === 0)
|
|
160
|
+
return [];
|
|
161
|
+
return v;
|
|
162
|
+
})
|
|
163
|
+
.join('/');
|
|
164
|
+
}
|
|
165
|
+
function defaultSlugify(s) {
|
|
166
|
+
return s.replace(/\s+/g, '-').toLowerCase();
|
|
167
|
+
}
|
package/dist/utils/schema.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { JSONSchema } from 'json-schema-typed/draft-2020-12';
|
|
2
|
-
import type { ReferenceObject } from '../types.js';
|
|
2
|
+
import type { MethodInformation, OperationObject, PathItemObject, ReferenceObject, TagObject } from '../types.js';
|
|
3
3
|
export type NoReference<T> = T extends (infer I)[] ? NoReference<I>[] : T extends ReferenceObject ? Exclude<T, ReferenceObject> : T extends object ? {
|
|
4
4
|
[K in keyof T]: NoReference<T[K]>;
|
|
5
5
|
} : T;
|
|
@@ -9,5 +9,10 @@ type NoReferenceJSONSchema<T> = T extends (infer I)[] ? NoReference<I>[] : T ext
|
|
|
9
9
|
export type ParsedSchema = JSONSchema;
|
|
10
10
|
export type ResolvedSchema = NoReferenceJSONSchema<ParsedSchema>;
|
|
11
11
|
export declare function getPreferredType<B extends Record<string, unknown>>(body: B): keyof B | undefined;
|
|
12
|
+
export declare function getTagDisplayName(tag: TagObject): string;
|
|
13
|
+
/**
|
|
14
|
+
* Summarize method endpoint information
|
|
15
|
+
*/
|
|
16
|
+
export declare function createMethod(method: string, path: NoReference<PathItemObject>, operation: NoReference<OperationObject>): MethodInformation;
|
|
12
17
|
export {};
|
|
13
18
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/utils/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/utils/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,eAAe,EACf,SAAS,EACV,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAC9C,WAAW,CAAC,CAAC,CAAC,EAAE,GAChB,CAAC,SAAS,eAAe,GACvB,OAAO,CAAC,CAAC,EAAE,eAAe,CAAC,GAC3B,CAAC,SAAS,MAAM,GACd;KACG,CAAC,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAClC,GACD,CAAC,CAAC;AAEV,KAAK,qBAAqB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACjD,WAAW,CAAC,CAAC,CAAC,EAAE,GAChB,CAAC,SAAS;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACzB,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,GACf,CAAC,CAAC;AAER,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC;AACtC,MAAM,MAAM,cAAc,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;AAEjE,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,IAAI,EAAE,CAAC,GACN,MAAM,CAAC,GAAG,SAAS,CAIrB;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAIxD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,CAAC,cAAc,CAAC,EACjC,SAAS,EAAE,WAAW,CAAC,eAAe,CAAC,GACtC,iBAAiB,CAQnB"}
|
package/dist/utils/schema.js
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
|
+
import { idToTitle } from '../utils/id-to-title.js';
|
|
1
2
|
export function getPreferredType(body) {
|
|
2
3
|
if ('application/json' in body)
|
|
3
4
|
return 'application/json';
|
|
4
5
|
return Object.keys(body)[0];
|
|
5
6
|
}
|
|
7
|
+
export function getTagDisplayName(tag) {
|
|
8
|
+
return 'x-displayName' in tag && typeof tag['x-displayName'] === 'string'
|
|
9
|
+
? tag['x-displayName']
|
|
10
|
+
: idToTitle(tag.name);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Summarize method endpoint information
|
|
14
|
+
*/
|
|
15
|
+
export function createMethod(method, path, operation) {
|
|
16
|
+
return {
|
|
17
|
+
description: path.description,
|
|
18
|
+
summary: path.summary,
|
|
19
|
+
...operation,
|
|
20
|
+
parameters: [...(operation.parameters ?? []), ...(path.parameters ?? [])],
|
|
21
|
+
method: method.toUpperCase(),
|
|
22
|
+
};
|
|
23
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-openapi",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.5.1",
|
|
4
4
|
"description": "Generate MDX docs for your OpenAPI spec",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NextJs",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
51
51
|
"@radix-ui/react-select": "^2.2.6",
|
|
52
52
|
"@radix-ui/react-slot": "^1.2.3",
|
|
53
|
-
"@scalar/json-magic": "^0.
|
|
54
|
-
"@scalar/openapi-parser": "0.
|
|
53
|
+
"@scalar/json-magic": "^0.6.0",
|
|
54
|
+
"@scalar/openapi-parser": "0.22.1",
|
|
55
55
|
"ajv": "^8.17.1",
|
|
56
56
|
"class-variance-authority": "^0.7.1",
|
|
57
57
|
"github-slugger": "^2.0.0",
|
|
@@ -60,16 +60,16 @@
|
|
|
60
60
|
"js-yaml": "^4.1.0",
|
|
61
61
|
"next-themes": "^0.4.6",
|
|
62
62
|
"openapi-sampler": "^1.6.1",
|
|
63
|
-
"react-hook-form": "^7.
|
|
63
|
+
"react-hook-form": "^7.64.0",
|
|
64
64
|
"remark": "^15.0.1",
|
|
65
65
|
"remark-rehype": "^11.1.2",
|
|
66
66
|
"tinyglobby": "^0.2.15",
|
|
67
67
|
"xml-js": "^1.6.11",
|
|
68
|
-
"fumadocs-
|
|
69
|
-
"fumadocs-
|
|
68
|
+
"fumadocs-ui": "15.8.5",
|
|
69
|
+
"fumadocs-core": "15.8.5"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@scalar/api-client-react": "^1.3.
|
|
72
|
+
"@scalar/api-client-react": "^1.3.44",
|
|
73
73
|
"@types/js-yaml": "^4.0.9",
|
|
74
74
|
"@types/node": "24.6.2",
|
|
75
75
|
"@types/openapi-sampler": "^1.0.3",
|
package/dist/generate.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import type { OperationItem, WebhookItem } from './render/api-page.js';
|
|
2
|
-
import type { ProcessedDocument } from './utils/process-document.js';
|
|
3
|
-
import type { TagObject } from './types.js';
|
|
4
|
-
export interface GenerateOptions {
|
|
5
|
-
/**
|
|
6
|
-
* Additional imports of your MDX components.
|
|
7
|
-
*/
|
|
8
|
-
imports?: {
|
|
9
|
-
names: string[];
|
|
10
|
-
from: string;
|
|
11
|
-
}[];
|
|
12
|
-
/**
|
|
13
|
-
* Customise frontmatter.
|
|
14
|
-
*
|
|
15
|
-
* A `full: true` property will be added by default.
|
|
16
|
-
*/
|
|
17
|
-
frontmatter?: (title: string, description: string | undefined, context: DocumentContext) => Record<string, unknown>;
|
|
18
|
-
/**
|
|
19
|
-
* Add description to document body.
|
|
20
|
-
*
|
|
21
|
-
* We recommend but don't enable it by default because some OpenAPI schemas have invalid description that breaks MDX syntax.
|
|
22
|
-
*
|
|
23
|
-
* @defaultValue false
|
|
24
|
-
*/
|
|
25
|
-
includeDescription?: boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Add a comment to the top of generated files indicating they are auto-generated.
|
|
28
|
-
* - `true`: Adds a standardized comment
|
|
29
|
-
* - `false`: No comment is added
|
|
30
|
-
* - `string`: Adds the provided custom comment
|
|
31
|
-
*
|
|
32
|
-
* @defaultValue true
|
|
33
|
-
*/
|
|
34
|
-
addGeneratedComment?: boolean | string;
|
|
35
|
-
cwd?: string;
|
|
36
|
-
/**
|
|
37
|
-
* Inline the entire OpenAPI document into the MDX file.
|
|
38
|
-
*
|
|
39
|
-
* @deprecated Use the new `input` API on `createOpenAPI()` instead.
|
|
40
|
-
* @defaultValue false
|
|
41
|
-
*/
|
|
42
|
-
inlineDocument?: boolean;
|
|
43
|
-
}
|
|
44
|
-
export interface GenerateTagOutput {
|
|
45
|
-
tag: string;
|
|
46
|
-
content: string;
|
|
47
|
-
}
|
|
48
|
-
export type GeneratePageOutput = {
|
|
49
|
-
type: 'operation';
|
|
50
|
-
item: OperationItem;
|
|
51
|
-
content: string;
|
|
52
|
-
} | {
|
|
53
|
-
type: 'webhook';
|
|
54
|
-
item: WebhookItem;
|
|
55
|
-
content: string;
|
|
56
|
-
};
|
|
57
|
-
export declare function generateAll(schemaId: string, processed: ProcessedDocument, options?: GenerateOptions): string;
|
|
58
|
-
export declare function generatePages(schemaId: string, processed: ProcessedDocument, options?: GenerateOptions): GeneratePageOutput[];
|
|
59
|
-
export declare function generateTags(schemaId: string, processed: ProcessedDocument, options?: GenerateOptions): GenerateTagOutput[];
|
|
60
|
-
export declare function generateDocument(frontmatter: unknown, content: string, options: Pick<GenerateOptions, 'addGeneratedComment' | 'imports'>): string;
|
|
61
|
-
export type DocumentContext = {
|
|
62
|
-
type: 'tag';
|
|
63
|
-
tag: TagObject | undefined;
|
|
64
|
-
} | {
|
|
65
|
-
type: 'operation';
|
|
66
|
-
} | {
|
|
67
|
-
type: 'file';
|
|
68
|
-
};
|
|
69
|
-
//# sourceMappingURL=generate.d.ts.map
|
package/dist/generate.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,aAAa,EACb,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,KAAK,EAAY,SAAS,EAAE,MAAM,SAAS,CAAC;AAMnD,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;KACd,EAAE,CAAC;IAEJ;;;;OAIG;IACH,WAAW,CAAC,EAAE,CACZ,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,eAAe,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE7B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAEvC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,kBAAkB,GAC1B;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEN,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAqBR;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,GAAE,eAAoB,GAC5B,kBAAkB,EAAE,CAiEtB;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,GAAE,eAAoB,GAC5B,iBAAiB,EAAE,CAwCrB;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,OAAO,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,qBAAqB,GAAG,SAAS,CAAC,GAChE,MAAM,CA+BR;AAOD,MAAM,MAAM,eAAe,GACvB;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,SAAS,GAAG,SAAS,CAAC;CAC5B,GACD;IACE,IAAI,EAAE,WAAW,CAAC;CACnB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { MethodInformation, OperationObject, PathItemObject } from '../types.js';
|
|
2
|
-
import type { NoReference } from '../utils/schema.js';
|
|
3
|
-
/**
|
|
4
|
-
* Summarize method endpoint information
|
|
5
|
-
*/
|
|
6
|
-
export declare function createMethod(method: string, path: NoReference<PathItemObject>, operation: NoReference<OperationObject>): MethodInformation;
|
|
7
|
-
//# sourceMappingURL=create-method.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-method.d.ts","sourceRoot":"","sources":["../../src/server/create-method.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,cAAc,EACf,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,CAAC,cAAc,CAAC,EACjC,SAAS,EAAE,WAAW,CAAC,eAAe,CAAC,GACtC,iBAAiB,CAQnB"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Summarize method endpoint information
|
|
3
|
-
*/
|
|
4
|
-
export function createMethod(method, path, operation) {
|
|
5
|
-
return {
|
|
6
|
-
description: path.description,
|
|
7
|
-
summary: path.summary,
|
|
8
|
-
...operation,
|
|
9
|
-
parameters: [...(operation.parameters ?? []), ...(path.parameters ?? [])],
|
|
10
|
-
method: method.toUpperCase(),
|
|
11
|
-
};
|
|
12
|
-
}
|