fumadocs-openapi 10.8.5 → 10.8.6
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/css/generated/shared.css +22 -1
- package/dist/generate-file.d.ts +1 -1
- package/dist/generate-file.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/node_modules/.pnpm/{@scalar_helpers@0.6.0 → @scalar_helpers@0.8.0}/node_modules/@scalar/helpers/dist/general/create-limiter.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_helpers@0.6.0 → @scalar_helpers@0.8.0}/node_modules/@scalar/helpers/dist/object/is-object.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_helpers@0.6.0 → @scalar_helpers@0.8.0}/node_modules/@scalar/helpers/dist/object/prevent-pollution.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_helpers@0.6.0 → @scalar_helpers@0.8.0}/node_modules/@scalar/helpers/dist/queue/queue.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_helpers@0.6.0 → @scalar_helpers@0.8.0}/node_modules/@scalar/helpers/dist/string/generate-hash.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/bundle/bundle.js +2 -2
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/bundle/plugins/fetch-urls/index.js +2 -2
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/bundle/plugins/read-files/index.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/bundle/value-generator.js +2 -2
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/convert-to-local-ref.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/escape-json-pointer.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/get-schemas.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/get-segments-from-path.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/get-value-by-path.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/is-file-path.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/is-http-url.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/is-json-object.js +2 -2
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/is-yaml.js +1 -1
- package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.14/node_modules/@scalar/json-magic/dist/helpers/normalize.js +33 -0
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/resolve-reference-path.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/set-value-at-path.js +2 -2
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/to-relative-path.js +1 -1
- package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/helpers/unescape-json-pointer.js +1 -1
- package/dist/playground/client.js +1 -1
- package/dist/server/index.d.ts +108 -3
- package/dist/server/index.js +181 -2
- package/dist/server/proxy.d.ts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/ui/base.d.ts +1 -1
- package/dist/ui/components/method-label.js +1 -4
- package/dist/ui/index.d.ts +1 -1
- package/dist/utils/document/process.js +4 -4
- package/dist/utils/pages/builder.d.ts +4 -3
- package/dist/utils/pages/builder.js +20 -1
- package/dist/utils/pages/to-text.d.ts +1 -1
- package/dist/utils/pages/to-text.js +23 -42
- package/package.json +7 -7
- package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.12/node_modules/@scalar/json-magic/dist/helpers/normalize.js +0 -26
- package/dist/server/create.d.ts +0 -40
- package/dist/server/create.js +0 -42
- package/dist/server/source-api.d.ts +0 -55
- package/dist/server/source-api.js +0 -149
- /package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/bundle/plugins/node.js +0 -0
- /package/dist/node_modules/.pnpm/{@scalar_json-magic@0.12.12 → @scalar_json-magic@0.12.14}/node_modules/@scalar/json-magic/dist/bundle/plugins/parse-yaml/index.js +0 -0
package/dist/server/index.js
CHANGED
|
@@ -1,3 +1,182 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { getPageProps } from "../utils/pages/builder.js";
|
|
2
|
+
import { toStaticData } from "../utils/pages/to-static-data.js";
|
|
3
|
+
import { MethodLabel } from "../ui/components/method-label.js";
|
|
4
|
+
import { createProxy } from "./proxy.js";
|
|
5
|
+
import { processDocument } from "../utils/document/process.js";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { PathUtils } from "fumadocs-core/source";
|
|
8
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
//#region src/server/index.tsx
|
|
11
|
+
function createOpenAPI(options = {}) {
|
|
12
|
+
const { input = [], disableCache = false } = options;
|
|
13
|
+
let schemas;
|
|
14
|
+
async function getSchemas() {
|
|
15
|
+
if (Array.isArray(input)) {
|
|
16
|
+
const entries = await Promise.all(input.map(async (item) => [item, await processDocument(item)]));
|
|
17
|
+
return Object.fromEntries(entries);
|
|
18
|
+
} else {
|
|
19
|
+
const entries = await Promise.all(Object.entries(await input()).map(async ([k, v]) => [k, await processDocument(v)]));
|
|
20
|
+
return Object.fromEntries(entries);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async function getVirtualFiles(server, options) {
|
|
24
|
+
const { baseDir = "", meta = false } = options;
|
|
25
|
+
const { createAutoPreset } = await import("../utils/pages/preset-auto.js");
|
|
26
|
+
const { fromServer } = await import("../utils/pages/builder.js");
|
|
27
|
+
const files = [];
|
|
28
|
+
const entries = await fromServer(server, createAutoPreset(options));
|
|
29
|
+
for (const [schemaId, list] of Object.entries(entries)) {
|
|
30
|
+
const processed = await server.getSchema(schemaId);
|
|
31
|
+
function onEntry(entry) {
|
|
32
|
+
const props = getPageProps(entry);
|
|
33
|
+
files.push({
|
|
34
|
+
type: "page",
|
|
35
|
+
path: `${baseDir}/${entry.path}`,
|
|
36
|
+
data: {
|
|
37
|
+
...entry.info,
|
|
38
|
+
getAPIPageProps() {
|
|
39
|
+
return props;
|
|
40
|
+
},
|
|
41
|
+
async getClientAPIPageProps() {
|
|
42
|
+
return {
|
|
43
|
+
payload: {
|
|
44
|
+
bundled: processed.bundled,
|
|
45
|
+
proxyUrl: server.options.proxyUrl
|
|
46
|
+
},
|
|
47
|
+
...props
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
getSchema() {
|
|
51
|
+
return {
|
|
52
|
+
id: schemaId,
|
|
53
|
+
...processed
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
...toStaticData(props, processed.dereferenced),
|
|
57
|
+
_openapi: {
|
|
58
|
+
method: entry.type === "operation" || entry.type === "webhook" ? entry.item.method : void 0,
|
|
59
|
+
webhook: entry.type === "webhook",
|
|
60
|
+
deprecated: entry.info.deprecated
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function onEntries(entries, parent) {
|
|
66
|
+
if (!meta) {
|
|
67
|
+
for (const entry of entries) if (entry.type === "group") onEntries(entry.entries, entry);
|
|
68
|
+
else onEntry(entry);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const { folderStyle = "folder" } = meta === true ? {} : meta;
|
|
72
|
+
const pages = [];
|
|
73
|
+
for (const entry of entries) {
|
|
74
|
+
const relativePath = PathUtils.slash(parent ? path.relative(parent.path, entry.path) : entry.path);
|
|
75
|
+
if (entry.type === "group") {
|
|
76
|
+
onEntries(entry.entries, entry);
|
|
77
|
+
if (folderStyle === "folder") pages.push(relativePath);
|
|
78
|
+
else pages.push(`---${entry.info.title}---`, `...${relativePath}`);
|
|
79
|
+
} else {
|
|
80
|
+
onEntry(entry);
|
|
81
|
+
pages.push(relativePath.slice(0, -path.extname(entry.path).length));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (pages.length === 0) return;
|
|
85
|
+
files.push({
|
|
86
|
+
type: "meta",
|
|
87
|
+
path: path.join(baseDir, parent?.path ?? "", "meta.json"),
|
|
88
|
+
data: {
|
|
89
|
+
title: parent?.info.title,
|
|
90
|
+
description: parent?.info.description,
|
|
91
|
+
pages
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
onEntries(list);
|
|
96
|
+
}
|
|
97
|
+
return files;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
options,
|
|
101
|
+
createProxy,
|
|
102
|
+
_getWatchPaths() {
|
|
103
|
+
return (Array.isArray(input) ? input : Object.keys(input)).filter((key) => !URL.canParse(key) && fs.existsSync(key));
|
|
104
|
+
},
|
|
105
|
+
async getSchema(document) {
|
|
106
|
+
const schemas = await this.getSchemas();
|
|
107
|
+
if (document in schemas) return schemas[document];
|
|
108
|
+
console.warn(`[Fumadocs OpenAPI] the document "${document}" is not listed in the input array, this may not be expected.`);
|
|
109
|
+
return processDocument(document);
|
|
110
|
+
},
|
|
111
|
+
async getSchemas() {
|
|
112
|
+
if (disableCache) return getSchemas();
|
|
113
|
+
return schemas ??= getSchemas();
|
|
114
|
+
},
|
|
115
|
+
async staticSource(options = {}) {
|
|
116
|
+
return { files: await getVirtualFiles(this, options) };
|
|
117
|
+
},
|
|
118
|
+
dynamicSource(options = {}) {
|
|
119
|
+
return { files: () => getVirtualFiles(this, options) };
|
|
120
|
+
},
|
|
121
|
+
loaderPlugin() {
|
|
122
|
+
return openapiPlugin();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* @deprecated
|
|
128
|
+
*/
|
|
129
|
+
function createCodeSample(options) {
|
|
130
|
+
return options;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Fumadocs Source API integration, pass this to `plugins` array in `loader()`.
|
|
134
|
+
*/
|
|
135
|
+
function openapiPlugin() {
|
|
136
|
+
return {
|
|
137
|
+
name: "fumadocs:openapi",
|
|
138
|
+
enforce: "pre",
|
|
139
|
+
transformPageTree: { file(node, filePath) {
|
|
140
|
+
if (!filePath) return node;
|
|
141
|
+
const file = this.storage.read(filePath);
|
|
142
|
+
if (!file || file.format !== "page") return node;
|
|
143
|
+
const openApiData = file.data._openapi;
|
|
144
|
+
if (!openApiData || typeof openApiData !== "object") return node;
|
|
145
|
+
if (openApiData.deprecated) node.name = /* @__PURE__ */ jsx("span", {
|
|
146
|
+
className: "fd-page-tree-item-name line-through",
|
|
147
|
+
children: node.name
|
|
148
|
+
});
|
|
149
|
+
if (openApiData.webhook) node.name = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
150
|
+
node.name,
|
|
151
|
+
" ",
|
|
152
|
+
/* @__PURE__ */ jsx("span", {
|
|
153
|
+
className: "ms-auto border border-current px-1 rounded-lg text-xs text-nowrap font-mono",
|
|
154
|
+
children: "Webhook"
|
|
155
|
+
})
|
|
156
|
+
] });
|
|
157
|
+
else if (openApiData.method) node.name = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
158
|
+
node.name,
|
|
159
|
+
" ",
|
|
160
|
+
/* @__PURE__ */ jsx(MethodLabel, {
|
|
161
|
+
className: "ms-auto text-xs text-nowrap",
|
|
162
|
+
children: openApiData.method
|
|
163
|
+
})
|
|
164
|
+
] });
|
|
165
|
+
return node;
|
|
166
|
+
} }
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Generate virtual pages for Fumadocs Source API
|
|
171
|
+
*/
|
|
172
|
+
async function openapiSource(server, options = {}) {
|
|
173
|
+
return server.staticSource(options);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* @deprecated use `openapiPlugin()`
|
|
177
|
+
*/
|
|
178
|
+
function transformerOpenAPI() {
|
|
179
|
+
return openapiPlugin().transformPageTree;
|
|
180
|
+
}
|
|
181
|
+
//#endregion
|
|
3
182
|
export { createCodeSample, createOpenAPI, openapiPlugin, openapiSource, transformerOpenAPI };
|
package/dist/server/proxy.d.ts
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { MediaAdapter } from "./requests/media/adapter.js";
|
|
|
2
2
|
import { InlineCodeUsageGenerator } from "./requests/generators/index.js";
|
|
3
3
|
import { boundary_d_exports } from "./ui/client/boundary.js";
|
|
4
4
|
import { OpenAPIV3, OpenAPIV3_2 } from "./_openapi/types.js";
|
|
5
|
-
import { OpenAPIOptions } from "./server/create.js";
|
|
6
5
|
import { CreateAPIPageOptions } from "./ui/base.js";
|
|
6
|
+
import { OpenAPIOptions } from "./server/index.js";
|
|
7
7
|
import { NoReference } from "./utils/schema/index.js";
|
|
8
8
|
import { DereferencedDocument } from "./utils/document/dereference.js";
|
|
9
9
|
import { HTMLAttributes, ReactNode } from "react";
|
package/dist/ui/base.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ import { CodeUsageGeneratorRegistry, InlineCodeUsageGenerator } from "../request
|
|
|
3
3
|
import { ExampleRequestItem } from "./operation/get-example-requests.js";
|
|
4
4
|
import { APIPageClientOptions } from "./client/index.js";
|
|
5
5
|
import { SchemaUIOptions } from "./schema/index.js";
|
|
6
|
-
import { OpenAPIServer } from "../server/create.js";
|
|
7
6
|
import { ApiPageProps, OperationItem, WebhookItem } from "./api-page.js";
|
|
8
7
|
import { ResponseTab } from "./operation/response-tabs.js";
|
|
9
8
|
import { RequestTabsRenderContext } from "./operation/request-tabs.js";
|
|
10
9
|
import { ClientCodeBlockProvider } from "./components/codeblock.js";
|
|
10
|
+
import { OpenAPIServer } from "../server/index.js";
|
|
11
11
|
import { Awaitable, MethodInformation, RenderContext } from "../types.js";
|
|
12
12
|
import { NoReference } from "../utils/schema/index.js";
|
|
13
13
|
import { DereferencedDocument } from "../utils/document/dereference.js";
|
|
@@ -20,10 +20,7 @@ function getMethodColor(method) {
|
|
|
20
20
|
}
|
|
21
21
|
function Badge({ className, color, ...props }) {
|
|
22
22
|
return /* @__PURE__ */ jsx("span", {
|
|
23
|
-
className: cn(badgeVariants({
|
|
24
|
-
color,
|
|
25
|
-
className
|
|
26
|
-
})),
|
|
23
|
+
className: cn(badgeVariants({ color }), className),
|
|
27
24
|
...props,
|
|
28
25
|
children: props.children
|
|
29
26
|
});
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { OpenAPIServer } from "../server/create.js";
|
|
2
1
|
import { ApiPageProps, OperationItem, WebhookItem } from "./api-page.js";
|
|
3
2
|
import { CreateAPIPageOptions as CreateAPIPageOptions$1, ServerApiPageProps } from "./base.js";
|
|
3
|
+
import { OpenAPIServer } from "../server/index.js";
|
|
4
4
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
5
5
|
|
|
6
6
|
//#region src/ui/index.d.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { bundle } from "../../node_modules/.pnpm/@scalar_json-magic@0.12.
|
|
1
|
+
import { bundle } from "../../node_modules/.pnpm/@scalar_json-magic@0.12.14/node_modules/@scalar/json-magic/dist/bundle/bundle.js";
|
|
2
2
|
import { upgrade } from "../../node_modules/.pnpm/@scalar_openapi-upgrader@0.2.7/node_modules/@scalar/openapi-upgrader/dist/upgrade.js";
|
|
3
|
-
import { fetchUrls } from "../../node_modules/.pnpm/@scalar_json-magic@0.12.
|
|
4
|
-
import { readFiles } from "../../node_modules/.pnpm/@scalar_json-magic@0.12.
|
|
5
|
-
import "../../node_modules/.pnpm/@scalar_json-magic@0.12.
|
|
3
|
+
import { fetchUrls } from "../../node_modules/.pnpm/@scalar_json-magic@0.12.14/node_modules/@scalar/json-magic/dist/bundle/plugins/fetch-urls/index.js";
|
|
4
|
+
import { readFiles } from "../../node_modules/.pnpm/@scalar_json-magic@0.12.14/node_modules/@scalar/json-magic/dist/bundle/plugins/read-files/index.js";
|
|
5
|
+
import "../../node_modules/.pnpm/@scalar_json-magic@0.12.14/node_modules/@scalar/json-magic/dist/bundle/plugins/node.js";
|
|
6
6
|
import { dereferenceDocument } from "./dereference.js";
|
|
7
7
|
//#region src/utils/document/process.ts
|
|
8
8
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ApiPageProps, OperationItem, WebhookItem } from "../../ui/api-page.js";
|
|
2
|
+
import { OpenAPIServer } from "../../server/index.js";
|
|
3
3
|
import { OperationObject, PathItemObject, TagObject } from "../../types.js";
|
|
4
4
|
import { NoReference } from "../schema/index.js";
|
|
5
5
|
import { DereferencedDocument } from "../document/dereference.js";
|
|
@@ -85,5 +85,6 @@ interface ExtractedInfo {
|
|
|
85
85
|
}
|
|
86
86
|
declare function fromServer(server: OpenAPIServer, config: PagesBuilderConfig): Promise<Record<string, OutputEntry[]>>;
|
|
87
87
|
declare function fromSchema(schemaId: string, processed: DereferencedDocument, config: PagesBuilderConfig): OutputEntry[];
|
|
88
|
+
declare function getPageProps(entry: PageOutput | OperationOutput | WebhookOutput): ApiPageProps;
|
|
88
89
|
//#endregion
|
|
89
|
-
export { OperationOutput, OutputEntry, OutputGroup, PageOutput, PagesBuilder, PagesBuilderConfig, WebhookOutput, fromSchema, fromServer };
|
|
90
|
+
export { OperationOutput, OutputEntry, OutputGroup, PageOutput, PagesBuilder, PagesBuilderConfig, WebhookOutput, fromSchema, fromServer, getPageProps };
|
|
@@ -97,5 +97,24 @@ function fromSchema(schemaId, processed, config) {
|
|
|
97
97
|
});
|
|
98
98
|
return files;
|
|
99
99
|
}
|
|
100
|
+
function getPageProps(entry) {
|
|
101
|
+
if (entry.type === "operation") return {
|
|
102
|
+
document: entry.schemaId,
|
|
103
|
+
operations: [entry.item],
|
|
104
|
+
showDescription: true
|
|
105
|
+
};
|
|
106
|
+
if (entry.type === "webhook") return {
|
|
107
|
+
document: entry.schemaId,
|
|
108
|
+
webhooks: [entry.item],
|
|
109
|
+
showDescription: true
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
showTitle: true,
|
|
113
|
+
showDescription: true,
|
|
114
|
+
document: entry.schemaId,
|
|
115
|
+
operations: entry.operations,
|
|
116
|
+
webhooks: entry.webhooks
|
|
117
|
+
};
|
|
118
|
+
}
|
|
100
119
|
//#endregion
|
|
101
|
-
export { fromSchema, fromServer };
|
|
120
|
+
export { fromSchema, fromServer, getPageProps };
|
|
@@ -17,7 +17,7 @@ interface PagesToTextOptions {
|
|
|
17
17
|
/**
|
|
18
18
|
* Add description to document body.
|
|
19
19
|
*
|
|
20
|
-
* We recommend
|
|
20
|
+
* We recommend to enable it, it is disabled by default because some OpenAPI schemas have invalid description that breaks Markdown syntax.
|
|
21
21
|
*
|
|
22
22
|
* @defaultValue false
|
|
23
23
|
*/
|
|
@@ -1,58 +1,24 @@
|
|
|
1
1
|
import { removeUndefined } from "../remove-undefined.js";
|
|
2
|
+
import { getPageProps } from "./builder.js";
|
|
2
3
|
import { toStaticData } from "./to-static-data.js";
|
|
3
4
|
import { doubleQuote } from "../../requests/string-utils.js";
|
|
4
5
|
import { dump } from "js-yaml";
|
|
5
6
|
//#region src/utils/pages/to-text.ts
|
|
6
7
|
function toText(entry, processed, options = {}) {
|
|
7
|
-
switch (entry.type) {
|
|
8
|
-
case "operation": return generatePage(entry.schemaId, processed, { operations: [entry.item] }, options, entry);
|
|
9
|
-
case "page": return generatePage(entry.schemaId, processed, {
|
|
10
|
-
operations: entry.operations,
|
|
11
|
-
webhooks: entry.webhooks,
|
|
12
|
-
showTitle: true
|
|
13
|
-
}, options, entry);
|
|
14
|
-
case "webhook": return generatePage(entry.schemaId, processed, { webhooks: [entry.item] }, options, entry);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
function generateDocument(frontmatter, content, options) {
|
|
18
|
-
const { addGeneratedComment = true, imports } = options;
|
|
19
|
-
const out = [];
|
|
20
|
-
const banner = dump(removeUndefined(frontmatter)).trimEnd();
|
|
21
|
-
if (banner.length > 0) out.push(`---\n${banner}\n---`);
|
|
22
|
-
if (addGeneratedComment) {
|
|
23
|
-
let commentContent = "This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again.";
|
|
24
|
-
if (typeof addGeneratedComment === "string") commentContent = addGeneratedComment;
|
|
25
|
-
commentContent = commentContent.replaceAll("/", "\\/");
|
|
26
|
-
out.push(`{/* ${commentContent} */}`);
|
|
27
|
-
}
|
|
28
|
-
if (imports) out.push(...imports.map((item) => `import { ${item.names.join(", ")} } from ${doubleQuote(item.from)};`).join("\n"));
|
|
29
|
-
out.push(content);
|
|
30
|
-
return out.join("\n\n");
|
|
31
|
-
}
|
|
32
|
-
function generatePage(schemaId, processed, pageProps, options, entry) {
|
|
33
8
|
const { frontmatter, includeDescription = false } = options;
|
|
34
9
|
const extend = frontmatter?.(entry.info.title, entry.info.description, entry.type === "page" ? entry.tag ? {
|
|
35
10
|
type: "tag",
|
|
36
11
|
tag: entry.tag
|
|
37
12
|
} : { type: "file" } : { type: "operation" });
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
document: schemaId
|
|
41
|
-
};
|
|
13
|
+
const pageProps = getPageProps(entry);
|
|
14
|
+
if (!includeDescription) pageProps.showDescription = false;
|
|
42
15
|
let meta;
|
|
43
|
-
if (
|
|
44
|
-
method:
|
|
16
|
+
if (entry.type === "operation" || entry.type === "webhook") meta = {
|
|
17
|
+
method: entry.item.method.toUpperCase(),
|
|
18
|
+
webhook: entry.type === "webhook",
|
|
45
19
|
deprecated: entry.info.deprecated
|
|
46
20
|
};
|
|
47
|
-
|
|
48
|
-
method: page.webhooks[0].method.toUpperCase(),
|
|
49
|
-
webhook: true,
|
|
50
|
-
deprecated: entry.info.deprecated
|
|
51
|
-
};
|
|
52
|
-
const data = toStaticData(page, processed.dereferenced);
|
|
53
|
-
const content = [];
|
|
54
|
-
if (entry.info.description && includeDescription) content.push(entry.info.description);
|
|
55
|
-
content.push(pageContent(page));
|
|
21
|
+
const data = toStaticData(pageProps, processed.dereferenced);
|
|
56
22
|
return generateDocument({
|
|
57
23
|
title: entry.info.title,
|
|
58
24
|
description: !includeDescription ? entry.info.description : void 0,
|
|
@@ -63,7 +29,22 @@ function generatePage(schemaId, processed, pageProps, options, entry) {
|
|
|
63
29
|
...data,
|
|
64
30
|
...extend?._openapi
|
|
65
31
|
}
|
|
66
|
-
},
|
|
32
|
+
}, pageContent(pageProps), options);
|
|
33
|
+
}
|
|
34
|
+
function generateDocument(frontmatter, content, options) {
|
|
35
|
+
const { addGeneratedComment = true, imports } = options;
|
|
36
|
+
const out = [];
|
|
37
|
+
const banner = dump(removeUndefined(frontmatter)).trimEnd();
|
|
38
|
+
if (banner.length > 0) out.push(`---\n${banner}\n---`);
|
|
39
|
+
if (addGeneratedComment) {
|
|
40
|
+
let commentContent = "This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again.";
|
|
41
|
+
if (typeof addGeneratedComment === "string") commentContent = addGeneratedComment;
|
|
42
|
+
commentContent = commentContent.replaceAll("/", "\\/");
|
|
43
|
+
out.push(`{/* ${commentContent} */}`);
|
|
44
|
+
}
|
|
45
|
+
if (imports) out.push(...imports.map((item) => `import { ${item.names.join(", ")} } from ${doubleQuote(item.from)};`).join("\n"));
|
|
46
|
+
out.push(content);
|
|
47
|
+
return out.join("\n\n");
|
|
67
48
|
}
|
|
68
49
|
function pageContent({ showTitle, showDescription, document, webhooks, operations }) {
|
|
69
50
|
const propStrs = [`document={${doubleQuote(document)}}`];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-openapi",
|
|
3
|
-
"version": "10.8.
|
|
3
|
+
"version": "10.8.6",
|
|
4
4
|
"description": "Generate MDX docs for your OpenAPI spec",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Docs",
|
|
@@ -60,11 +60,11 @@
|
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@fastify/deepmerge": "^3.2.1",
|
|
62
62
|
"@scalar/api-client-react": "2.0.1",
|
|
63
|
-
"@scalar/json-magic": "^0.12.
|
|
63
|
+
"@scalar/json-magic": "^0.12.14",
|
|
64
64
|
"@scalar/openapi-upgrader": "^0.2.7",
|
|
65
65
|
"@tailwindcss/oxide": "^4.3.0",
|
|
66
66
|
"@types/js-yaml": "^4.0.9",
|
|
67
|
-
"@types/node": "25.
|
|
67
|
+
"@types/node": "25.8.0",
|
|
68
68
|
"@types/react": "^19.2.14",
|
|
69
69
|
"ajv": "^8.20.0",
|
|
70
70
|
"fast-content-type-parse": "^3.0.0",
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
"tailwindcss": "^4.3.0",
|
|
73
73
|
"tsdown": "0.22.0",
|
|
74
74
|
"xml-js": "^1.6.11",
|
|
75
|
-
"fumadocs-core": "16.8.
|
|
76
|
-
"fumadocs-ui": "16.8.
|
|
75
|
+
"fumadocs-core": "16.8.12",
|
|
76
|
+
"fumadocs-ui": "16.8.12",
|
|
77
77
|
"tsconfig": "0.0.0"
|
|
78
78
|
},
|
|
79
79
|
"peerDependencies": {
|
|
@@ -98,8 +98,8 @@
|
|
|
98
98
|
},
|
|
99
99
|
"inlinedDependencies": {
|
|
100
100
|
"@fastify/deepmerge": "3.2.1",
|
|
101
|
-
"@scalar/helpers": "0.
|
|
102
|
-
"@scalar/json-magic": "0.12.
|
|
101
|
+
"@scalar/helpers": "0.8.0",
|
|
102
|
+
"@scalar/json-magic": "0.12.14",
|
|
103
103
|
"@scalar/openapi-upgrader": "0.2.7",
|
|
104
104
|
"ajv": "8.20.0",
|
|
105
105
|
"fast-content-type-parse": "3.0.0",
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { parse } from "../../../../../../yaml@2.9.0/node_modules/yaml/browser/dist/public-api.js";
|
|
2
|
-
import "../../../../../../yaml@2.9.0/node_modules/yaml/browser/index.js";
|
|
3
|
-
//#region ../../node_modules/.pnpm/@scalar+json-magic@0.12.12/node_modules/@scalar/json-magic/dist/helpers/normalize.js
|
|
4
|
-
/**
|
|
5
|
-
* Normalize a string (YAML, JSON, object) to a JavaScript datatype.
|
|
6
|
-
*/
|
|
7
|
-
function normalize(content) {
|
|
8
|
-
if (content === null) return;
|
|
9
|
-
if (typeof content === "string") {
|
|
10
|
-
if (content.trim() === "") return;
|
|
11
|
-
try {
|
|
12
|
-
return JSON.parse(content);
|
|
13
|
-
} catch (_error) {
|
|
14
|
-
const hasColon = /^[^:]+:/.test(content);
|
|
15
|
-
const isJson = content.slice(0, 50).trimStart().startsWith("{");
|
|
16
|
-
if (!hasColon || isJson) return;
|
|
17
|
-
return parse(content, {
|
|
18
|
-
maxAliasCount: 1e4,
|
|
19
|
-
merge: true
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return content;
|
|
24
|
-
}
|
|
25
|
-
//#endregion
|
|
26
|
-
export { normalize };
|
package/dist/server/create.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { InlineCodeUsageGenerator } from "../requests/generators/index.js";
|
|
2
|
-
import { createProxy } from "./proxy.js";
|
|
3
|
-
import { ProcessedDocument } from "../utils/document/process.js";
|
|
4
|
-
import { Document } from "../types.js";
|
|
5
|
-
|
|
6
|
-
//#region src/server/create.d.ts
|
|
7
|
-
/**
|
|
8
|
-
* schema id -> file path, URL, or downloaded schema object
|
|
9
|
-
*/
|
|
10
|
-
type SchemaMap = Record<string, string | Document>;
|
|
11
|
-
type ProcessedSchemaMap = Record<string, ProcessedDocument>;
|
|
12
|
-
interface OpenAPIOptions {
|
|
13
|
-
/**
|
|
14
|
-
* Schema files, can be:
|
|
15
|
-
* - URL
|
|
16
|
-
* - file path
|
|
17
|
-
* - a function returning records of downloaded schemas.
|
|
18
|
-
*/
|
|
19
|
-
input?: string[] | (() => SchemaMap | Promise<SchemaMap>);
|
|
20
|
-
disableCache?: boolean;
|
|
21
|
-
/**
|
|
22
|
-
* The url of proxy to avoid CORS issues
|
|
23
|
-
*/
|
|
24
|
-
proxyUrl?: string;
|
|
25
|
-
}
|
|
26
|
-
interface OpenAPIServer {
|
|
27
|
-
createProxy: typeof createProxy;
|
|
28
|
-
getSchemas: () => Promise<ProcessedSchemaMap>;
|
|
29
|
-
getSchema: (document: string) => Promise<ProcessedDocument>;
|
|
30
|
-
/** @private internal API */
|
|
31
|
-
_getWatchPaths: () => string[];
|
|
32
|
-
readonly options: OpenAPIOptions;
|
|
33
|
-
}
|
|
34
|
-
declare function createOpenAPI(options?: OpenAPIOptions): OpenAPIServer;
|
|
35
|
-
/**
|
|
36
|
-
* @deprecated
|
|
37
|
-
*/
|
|
38
|
-
declare function createCodeSample<T>(options: InlineCodeUsageGenerator<T>): InlineCodeUsageGenerator<T>;
|
|
39
|
-
//#endregion
|
|
40
|
-
export { OpenAPIOptions, OpenAPIServer, createCodeSample, createOpenAPI };
|
package/dist/server/create.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { createProxy } from "./proxy.js";
|
|
2
|
-
import { processDocument } from "../utils/document/process.js";
|
|
3
|
-
import fs from "node:fs";
|
|
4
|
-
//#region src/server/create.ts
|
|
5
|
-
function createOpenAPI(options = {}) {
|
|
6
|
-
const { input = [], disableCache = false } = options;
|
|
7
|
-
let schemas;
|
|
8
|
-
async function getSchemas() {
|
|
9
|
-
if (Array.isArray(input)) {
|
|
10
|
-
const entries = await Promise.all(input.map(async (item) => [item, await processDocument(item)]));
|
|
11
|
-
return Object.fromEntries(entries);
|
|
12
|
-
} else {
|
|
13
|
-
const entries = await Promise.all(Object.entries(await input()).map(async ([k, v]) => [k, await processDocument(v)]));
|
|
14
|
-
return Object.fromEntries(entries);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return {
|
|
18
|
-
options,
|
|
19
|
-
createProxy,
|
|
20
|
-
_getWatchPaths() {
|
|
21
|
-
return (Array.isArray(input) ? input : Object.keys(input)).filter((key) => !URL.canParse(key) && fs.existsSync(key));
|
|
22
|
-
},
|
|
23
|
-
async getSchema(document) {
|
|
24
|
-
const schemas = await this.getSchemas();
|
|
25
|
-
if (document in schemas) return schemas[document];
|
|
26
|
-
console.warn(`[Fumadocs OpenAPI] the document "${document}" is not listed in the input array, this may not be expected.`);
|
|
27
|
-
return processDocument(document);
|
|
28
|
-
},
|
|
29
|
-
async getSchemas() {
|
|
30
|
-
if (disableCache) return getSchemas();
|
|
31
|
-
return schemas ??= getSchemas();
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* @deprecated
|
|
37
|
-
*/
|
|
38
|
-
function createCodeSample(options) {
|
|
39
|
-
return options;
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
42
|
-
export { createCodeSample, createOpenAPI };
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { OpenAPIServer } from "./create.js";
|
|
2
|
-
import { ApiPageProps } from "../ui/api-page.js";
|
|
3
|
-
import { SchemaToPagesOptions } from "../utils/pages/preset-auto.js";
|
|
4
|
-
import { ClientApiPageProps } from "../ui/create-client.js";
|
|
5
|
-
import { DereferencedDocument } from "../utils/document/dereference.js";
|
|
6
|
-
import { LoaderPlugin, MetaData, PageData, PageTreeTransformer, Source } from "fumadocs-core/source";
|
|
7
|
-
import { StructuredData } from "fumadocs-core/mdx-plugins";
|
|
8
|
-
import { TOCItemType } from "fumadocs-core/toc";
|
|
9
|
-
|
|
10
|
-
//#region src/server/source-api.d.ts
|
|
11
|
-
declare module 'fumadocs-core/source' {
|
|
12
|
-
interface PageData {
|
|
13
|
-
/**
|
|
14
|
-
* Added by Fumadocs OpenAPI
|
|
15
|
-
*/
|
|
16
|
-
_openapi?: InternalOpenAPIMeta;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
interface InternalOpenAPIMeta {
|
|
20
|
-
method?: string;
|
|
21
|
-
webhook?: boolean;
|
|
22
|
-
deprecated?: boolean;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Fumadocs Source API integration, pass this to `plugins` array in `loader()`.
|
|
26
|
-
*/
|
|
27
|
-
declare function openapiPlugin(): LoaderPlugin;
|
|
28
|
-
interface OpenAPIPageData extends PageData {
|
|
29
|
-
getAPIPageProps: () => ApiPageProps;
|
|
30
|
-
getSchema: () => {
|
|
31
|
-
id: string;
|
|
32
|
-
} & DereferencedDocument;
|
|
33
|
-
getClientAPIPageProps: () => Promise<ClientApiPageProps>;
|
|
34
|
-
structuredData: StructuredData;
|
|
35
|
-
toc: TOCItemType[];
|
|
36
|
-
}
|
|
37
|
-
type OpenAPISourceOptions = SchemaToPagesOptions & {
|
|
38
|
-
baseDir?: string; /** Generate `meta.json` files */
|
|
39
|
-
meta?: boolean | {
|
|
40
|
-
folderStyle?: 'folder' | 'separator';
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
/**
|
|
44
|
-
* Generate virtual pages for Fumadocs Source API
|
|
45
|
-
*/
|
|
46
|
-
declare function openapiSource(server: OpenAPIServer, options?: OpenAPISourceOptions): Promise<Source<{
|
|
47
|
-
metaData: MetaData;
|
|
48
|
-
pageData: OpenAPIPageData;
|
|
49
|
-
}>>;
|
|
50
|
-
/**
|
|
51
|
-
* @deprecated use `openapiPlugin()`
|
|
52
|
-
*/
|
|
53
|
-
declare function transformerOpenAPI(): PageTreeTransformer;
|
|
54
|
-
//#endregion
|
|
55
|
-
export { InternalOpenAPIMeta, OpenAPIPageData, OpenAPISourceOptions, openapiPlugin, openapiSource, transformerOpenAPI };
|