fumadocs-openapi 10.5.0 → 10.6.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/css/generated/shared.css +33 -21
- package/dist/generate-file.d.ts +10 -2
- package/dist/generate-file.d.ts.map +1 -1
- package/dist/generate-file.js +15 -3
- package/dist/generate-file.js.map +1 -1
- package/dist/playground/client.d.ts +32 -10
- package/dist/playground/client.d.ts.map +1 -1
- package/dist/playground/client.js +70 -60
- package/dist/playground/client.js.map +1 -1
- package/dist/playground/components/inputs.js +1 -1
- package/dist/playground/components/inputs.js.map +1 -1
- package/dist/playground/components/server-select.js +3 -4
- package/dist/playground/components/server-select.js.map +1 -1
- package/dist/playground/fetcher.d.ts +20 -1
- package/dist/playground/fetcher.d.ts.map +1 -1
- package/dist/playground/fetcher.js +28 -24
- package/dist/playground/fetcher.js.map +1 -1
- package/dist/playground/index.d.ts +3 -3
- package/dist/playground/index.d.ts.map +1 -1
- package/dist/playground/index.js +2 -2
- package/dist/playground/index.js.map +1 -1
- package/dist/playground/schema.d.ts +1 -0
- package/dist/playground/schema.d.ts.map +1 -1
- package/dist/playground/schema.js +10 -12
- package/dist/playground/schema.js.map +1 -1
- package/dist/requests/generators/python.d.ts +2 -1
- package/dist/requests/generators/python.d.ts.map +1 -1
- package/dist/requests/generators/python.js +13 -2
- package/dist/requests/generators/python.js.map +1 -1
- package/dist/scalar/index.d.ts +2 -1
- package/dist/scalar/index.d.ts.map +1 -1
- package/dist/server/create.d.ts +2 -0
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/create.js +11 -8
- package/dist/server/create.js.map +1 -1
- package/dist/server/proxy.d.ts +5 -2
- package/dist/server/proxy.d.ts.map +1 -1
- package/dist/server/proxy.js +41 -31
- package/dist/server/proxy.js.map +1 -1
- package/dist/server/source-api.d.ts +2 -0
- package/dist/server/source-api.d.ts.map +1 -1
- package/dist/server/source-api.js +10 -1
- package/dist/server/source-api.js.map +1 -1
- package/dist/types.d.ts +2 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/api-page.d.ts +1 -3
- package/dist/ui/api-page.d.ts.map +1 -1
- package/dist/ui/api-page.js +4 -6
- package/dist/ui/api-page.js.map +1 -1
- package/dist/ui/base.d.ts +20 -16
- package/dist/ui/base.d.ts.map +1 -1
- package/dist/ui/base.js +18 -9
- package/dist/ui/base.js.map +1 -1
- package/dist/ui/{full.client.js → client/full.js} +3 -3
- package/dist/ui/client/full.js.map +1 -0
- package/dist/ui/client/index.d.ts +1 -1
- package/dist/ui/client/index.js.map +1 -1
- package/dist/ui/client/storage-key.js.map +1 -1
- package/dist/ui/components/codeblock.d.ts +2 -2
- package/dist/ui/components/codeblock.d.ts.map +1 -1
- package/dist/ui/components/server-tab.js +43 -0
- package/dist/ui/components/server-tab.js.map +1 -0
- package/dist/ui/contexts/api.js +18 -35
- package/dist/ui/contexts/api.js.map +1 -1
- package/dist/ui/create-client.d.ts +26 -0
- package/dist/ui/create-client.d.ts.map +1 -0
- package/dist/ui/create-client.js +132 -0
- package/dist/ui/create-client.js.map +1 -0
- package/dist/ui/index.d.ts +10 -2
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +21 -1
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/operation/client.js +44 -36
- package/dist/ui/operation/client.js.map +1 -1
- package/dist/ui/operation/{request-tabs.d.ts → get-example-requests.d.ts} +2 -4
- package/dist/ui/operation/get-example-requests.d.ts.map +1 -0
- package/dist/ui/operation/get-example-requests.js +83 -0
- package/dist/ui/operation/get-example-requests.js.map +1 -0
- package/dist/ui/operation/index.js +101 -63
- package/dist/ui/operation/index.js.map +1 -1
- package/dist/ui/operation/request-tabs.js +3 -81
- package/dist/ui/operation/request-tabs.js.map +1 -1
- package/dist/ui/operation/response-tabs.d.ts +1 -1
- package/dist/ui/operation/response-tabs.js +57 -54
- package/dist/ui/operation/response-tabs.js.map +1 -1
- package/dist/ui/operation/usage-tabs/client.js +7 -48
- package/dist/ui/operation/usage-tabs/client.js.map +1 -1
- package/dist/ui/operation/usage-tabs/index.js +14 -10
- package/dist/ui/operation/usage-tabs/index.js.map +1 -1
- package/dist/ui/operation/usage-tabs/lazy.js +1 -2
- package/dist/ui/operation/usage-tabs/lazy.js.map +1 -1
- package/dist/ui/schema/client.d.ts +0 -1
- package/dist/ui/schema/client.d.ts.map +1 -1
- package/dist/ui/schema/index.d.ts +1 -2
- package/dist/ui/schema/index.d.ts.map +1 -1
- package/dist/ui/schema/index.js +4 -2
- package/dist/ui/schema/index.js.map +1 -1
- package/dist/utils/pages/builder.d.ts +1 -1
- package/dist/utils/pages/builder.js +1 -1
- package/dist/utils/process-document.d.ts +1 -1
- package/dist/utils/process-document.js +1 -32
- package/dist/utils/process-document.js.map +1 -1
- package/dist/utils/schema/dereference.js +37 -0
- package/dist/utils/schema/dereference.js.map +1 -0
- package/dist/utils/{schema.d.ts → schema/index.d.ts} +3 -3
- package/dist/utils/schema/index.d.ts.map +1 -0
- package/dist/utils/{schema.js → schema/index.js} +3 -3
- package/dist/utils/schema/index.js.map +1 -0
- package/dist/utils/schema/resolve-ref.js +21 -0
- package/dist/utils/schema/resolve-ref.js.map +1 -0
- package/dist/utils/{schema-to-string.js → schema/to-string.js} +2 -2
- package/dist/utils/schema/to-string.js.map +1 -0
- package/package.json +10 -10
- package/dist/requests/to-python-object.js +0 -17
- package/dist/requests/to-python-object.js.map +0 -1
- package/dist/ui/full.client.js.map +0 -1
- package/dist/ui/full.d.ts +0 -11
- package/dist/ui/full.d.ts.map +0 -1
- package/dist/ui/full.js +0 -36
- package/dist/ui/full.js.map +0 -1
- package/dist/ui/operation/request-tabs.d.ts.map +0 -1
- package/dist/utils/schema-to-string.js.map +0 -1
- package/dist/utils/schema.d.ts.map +0 -1
- package/dist/utils/schema.js.map +0 -1
- /package/dist/utils/{schema-to-string.d.ts → schema/to-string.d.ts} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { OpenAPIServer } from "./create.js";
|
|
2
2
|
import { ApiPageProps } from "../ui/api-page.js";
|
|
3
3
|
import { SchemaToPagesOptions } from "../utils/pages/preset-auto.js";
|
|
4
|
+
import { ClientApiPageProps } from "../ui/create-client.js";
|
|
4
5
|
import { ProcessedDocument } from "../utils/process-document.js";
|
|
5
6
|
import { LoaderPlugin, MetaData, PageData, PageTreeTransformer, Source } from "fumadocs-core/source";
|
|
6
7
|
import { StructuredData } from "fumadocs-core/mdx-plugins";
|
|
@@ -28,6 +29,7 @@ interface OpenAPIPageData extends PageData {
|
|
|
28
29
|
getSchema: () => {
|
|
29
30
|
id: string;
|
|
30
31
|
} & ProcessedDocument;
|
|
32
|
+
getClientAPIPageProps: () => Promise<ClientApiPageProps>;
|
|
31
33
|
structuredData: StructuredData;
|
|
32
34
|
toc: TOCItemType[];
|
|
33
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-api.d.ts","names":[],"sources":["../../src/server/source-api.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-api.d.ts","names":[],"sources":["../../src/server/source-api.tsx"],"mappings":";;;;;;;;;;;YA2BmB,QAAA;IAJ0C;;;IAQzD,QAAA,GAAW,mBAAA;EAAA;AAAA;AAAA,UAIE,mBAAA;EACf,MAAA;EACA,OAAA;AAAA;AAFF;;;AAAA,iBAQgB,aAAA,CAAA,GAAiB,YAAA;AAAA,UAuCvB,eAAA,SAAwB,QAAA;EAChC,eAAA,QAAuB,YAAA;EACvB,SAAA;IAAmB,EAAA;EAAA,IAAe,iBAAA;EAClC,qBAAA,QAA6B,OAAA,CAAQ,kBAAA;EACrC,cAAA,EAAgB,cAAA;EAChB,GAAA,EAAK,WAAA;AAAA;AAAA,UAGG,WAAA;EACR,WAAA;AAAA;;;;iBAMoB,aAAA,CACpB,MAAA,EAAQ,aAAA,EACR,OAAA,GAAS,oBAAA;EACP,OAAA,WAlBsC;EAoBtC,IAAA,aAAiB,WAAA;AAAA,IAElB,OAAA,CACD,MAAA;EACE,QAAA,EAAU,QAAA;EACV,QAAA,EAAU,eAAA;AAAA;;;;iBAqIE,kBAAA,CAAA,GAAsB,mBAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { toStaticData } from "../utils/pages/to-static-data.js";
|
|
1
2
|
import { MethodLabel } from "../ui/components/method-label.js";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { PathUtils } from "fumadocs-core/source";
|
|
@@ -43,7 +44,6 @@ async function openapiSource(server, options = {}) {
|
|
|
43
44
|
const { baseDir = "", meta = false } = options;
|
|
44
45
|
const { createAutoPreset } = await import("../utils/pages/preset-auto.js");
|
|
45
46
|
const { fromServer } = await import("../utils/pages/builder.js");
|
|
46
|
-
const { toStaticData } = await import("../utils/pages/to-static-data.js");
|
|
47
47
|
const files = [];
|
|
48
48
|
const entries = await fromServer(server, createAutoPreset(options));
|
|
49
49
|
for (const [schemaId, list] of Object.entries(entries)) {
|
|
@@ -58,6 +58,15 @@ async function openapiSource(server, options = {}) {
|
|
|
58
58
|
getAPIPageProps() {
|
|
59
59
|
return props;
|
|
60
60
|
},
|
|
61
|
+
async getClientAPIPageProps() {
|
|
62
|
+
return {
|
|
63
|
+
payload: {
|
|
64
|
+
bundled: processed.bundled,
|
|
65
|
+
proxyUrl: server.options.proxyUrl
|
|
66
|
+
},
|
|
67
|
+
...props
|
|
68
|
+
};
|
|
69
|
+
},
|
|
61
70
|
getSchema() {
|
|
62
71
|
return {
|
|
63
72
|
id: schemaId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-api.js","names":[],"sources":["../../src/server/source-api.tsx"],"sourcesContent":["import { MethodLabel } from '@/ui/components/method-label';\nimport {\n PathUtils,\n type LoaderPlugin,\n type MetaData,\n type PageData,\n type PageTreeTransformer,\n type Source,\n type VirtualFile,\n} from 'fumadocs-core/source';\nimport type { OpenAPIServer } from '@/server/create';\nimport type { SchemaToPagesOptions } from '@/utils/pages/preset-auto';\nimport type { ApiPageProps } from '@/ui/api-page';\nimport type { StructuredData } from 'fumadocs-core/mdx-plugins';\nimport type { TOCItemType } from 'fumadocs-core/toc';\nimport type { ProcessedDocument } from '@/utils/process-document';\nimport type {\n OperationOutput,\n OutputEntry,\n PageOutput,\n WebhookOutput,\n} from '@/utils/pages/builder';\nimport path from 'node:path';\n\ndeclare module 'fumadocs-core/source' {\n export interface PageData {\n /**\n * Added by Fumadocs OpenAPI\n */\n _openapi?: InternalOpenAPIMeta;\n }\n}\n\nexport interface InternalOpenAPIMeta {\n method?: string;\n webhook?: boolean;\n}\n\n/**\n * Fumadocs Source API integration, pass this to `plugins` array in `loader()`.\n */\nexport function openapiPlugin(): LoaderPlugin {\n return {\n name: 'fumadocs:openapi',\n enforce: 'pre',\n transformPageTree: {\n file(node, filePath) {\n if (!filePath) return node;\n const file = this.storage.read(filePath);\n if (!file || file.format !== 'page') return node;\n\n const openApiData = file.data._openapi;\n if (!openApiData || typeof openApiData !== 'object') return node;\n\n if (openApiData.webhook) {\n node.name = (\n <>\n {node.name}{' '}\n <span className=\"ms-auto border border-current px-1 rounded-lg text-xs text-nowrap font-mono\">\n Webhook\n </span>\n </>\n );\n } else if (openApiData.method) {\n node.name = (\n <>\n {node.name}{' '}\n <MethodLabel className=\"ms-auto text-xs text-nowrap\">\n {openApiData.method}\n </MethodLabel>\n </>\n );\n }\n\n return node;\n },\n },\n };\n}\n\ninterface OpenAPIPageData extends PageData {\n getAPIPageProps: () => ApiPageProps;\n getSchema: () => { id: string } & ProcessedDocument;\n structuredData: StructuredData;\n toc: TOCItemType[];\n}\n\ninterface MetaOptions {\n folderStyle?: 'folder' | 'separator';\n}\n\n/**\n * Generate virtual pages for Fumadocs Source API\n */\nexport async function openapiSource(\n server: OpenAPIServer,\n options: SchemaToPagesOptions & {\n baseDir?: string;\n /** Generate `meta.json` files */\n meta?: boolean | MetaOptions;\n } = {},\n): Promise<\n Source<{\n metaData: MetaData;\n pageData: OpenAPIPageData;\n }>\n> {\n const { baseDir = '', meta = false } = options;\n const { createAutoPreset } = await import('@/utils/pages/preset-auto');\n const { fromServer } = await import('@/utils/pages/builder');\n const
|
|
1
|
+
{"version":3,"file":"source-api.js","names":[],"sources":["../../src/server/source-api.tsx"],"sourcesContent":["import { MethodLabel } from '@/ui/components/method-label';\nimport {\n PathUtils,\n type LoaderPlugin,\n type MetaData,\n type PageData,\n type PageTreeTransformer,\n type Source,\n type VirtualFile,\n} from 'fumadocs-core/source';\nimport type { OpenAPIServer } from '@/server/create';\nimport type { SchemaToPagesOptions } from '@/utils/pages/preset-auto';\nimport type { ApiPageProps } from '@/ui/api-page';\nimport type { StructuredData } from 'fumadocs-core/mdx-plugins';\nimport type { TOCItemType } from 'fumadocs-core/toc';\nimport type { ProcessedDocument } from '@/utils/process-document';\nimport type {\n OperationOutput,\n OutputEntry,\n PageOutput,\n WebhookOutput,\n} from '@/utils/pages/builder';\nimport path from 'node:path';\nimport type { ClientApiPageProps } from '@/ui/create-client';\nimport { toStaticData } from '@/utils/pages/to-static-data';\n\ndeclare module 'fumadocs-core/source' {\n export interface PageData {\n /**\n * Added by Fumadocs OpenAPI\n */\n _openapi?: InternalOpenAPIMeta;\n }\n}\n\nexport interface InternalOpenAPIMeta {\n method?: string;\n webhook?: boolean;\n}\n\n/**\n * Fumadocs Source API integration, pass this to `plugins` array in `loader()`.\n */\nexport function openapiPlugin(): LoaderPlugin {\n return {\n name: 'fumadocs:openapi',\n enforce: 'pre',\n transformPageTree: {\n file(node, filePath) {\n if (!filePath) return node;\n const file = this.storage.read(filePath);\n if (!file || file.format !== 'page') return node;\n\n const openApiData = file.data._openapi;\n if (!openApiData || typeof openApiData !== 'object') return node;\n\n if (openApiData.webhook) {\n node.name = (\n <>\n {node.name}{' '}\n <span className=\"ms-auto border border-current px-1 rounded-lg text-xs text-nowrap font-mono\">\n Webhook\n </span>\n </>\n );\n } else if (openApiData.method) {\n node.name = (\n <>\n {node.name}{' '}\n <MethodLabel className=\"ms-auto text-xs text-nowrap\">\n {openApiData.method}\n </MethodLabel>\n </>\n );\n }\n\n return node;\n },\n },\n };\n}\n\ninterface OpenAPIPageData extends PageData {\n getAPIPageProps: () => ApiPageProps;\n getSchema: () => { id: string } & ProcessedDocument;\n getClientAPIPageProps: () => Promise<ClientApiPageProps>;\n structuredData: StructuredData;\n toc: TOCItemType[];\n}\n\ninterface MetaOptions {\n folderStyle?: 'folder' | 'separator';\n}\n\n/**\n * Generate virtual pages for Fumadocs Source API\n */\nexport async function openapiSource(\n server: OpenAPIServer,\n options: SchemaToPagesOptions & {\n baseDir?: string;\n /** Generate `meta.json` files */\n meta?: boolean | MetaOptions;\n } = {},\n): Promise<\n Source<{\n metaData: MetaData;\n pageData: OpenAPIPageData;\n }>\n> {\n const { baseDir = '', meta = false } = options;\n const { createAutoPreset } = await import('@/utils/pages/preset-auto');\n const { fromServer } = await import('@/utils/pages/builder');\n const files: VirtualFile<{\n pageData: OpenAPIPageData;\n metaData: MetaData;\n }>[] = [];\n\n const entries = await fromServer(server, createAutoPreset(options));\n for (const [schemaId, list] of Object.entries(entries)) {\n const processed = await server.getSchema(schemaId);\n\n function onEntry(entry: PageOutput | OperationOutput | WebhookOutput) {\n const props = getProps(entry);\n\n files.push({\n type: 'page',\n path: `${baseDir}/${entry.path}`,\n data: {\n ...entry.info,\n getAPIPageProps() {\n return props;\n },\n async getClientAPIPageProps() {\n return {\n payload: {\n bundled: processed.bundled,\n proxyUrl: server.options.proxyUrl,\n },\n ...props,\n };\n },\n getSchema() {\n return {\n id: schemaId,\n ...processed,\n };\n },\n ...toStaticData(props, processed.dereferenced),\n _openapi: {\n method:\n entry.type === 'operation' || entry.type === 'webhook'\n ? entry.item.method\n : undefined,\n webhook: entry.type === 'webhook',\n },\n },\n });\n }\n\n function onEntries(entries: OutputEntry[], parent?: OutputEntry) {\n if (!meta) {\n for (const entry of entries) {\n if (entry.type === 'group') {\n onEntries(entry.entries, entry);\n } else {\n onEntry(entry);\n }\n }\n\n return;\n }\n\n const { folderStyle = 'folder' } = meta === true ? {} : meta;\n const pages: string[] = [];\n\n for (const entry of entries) {\n const relativePath = PathUtils.slash(\n parent ? path.relative(parent.path, entry.path) : entry.path,\n );\n\n if (entry.type === 'group') {\n onEntries(entry.entries, entry);\n if (folderStyle === 'folder') {\n pages.push(relativePath);\n } else {\n pages.push(`---${entry.info.title}---`, `...${relativePath}`);\n }\n } else {\n onEntry(entry);\n pages.push(relativePath.slice(0, -path.extname(entry.path).length));\n }\n }\n\n if (pages.length === 0) return;\n files.push({\n type: 'meta',\n path: path.join(baseDir, parent?.path ?? '', 'meta.json'),\n data: {\n title: parent?.info.title,\n description: parent?.info.description,\n pages,\n },\n });\n }\n\n onEntries(list);\n }\n\n return {\n files,\n };\n}\n\nfunction getProps(entry: PageOutput | OperationOutput | WebhookOutput): ApiPageProps {\n if (entry.type === 'operation')\n return {\n document: entry.schemaId,\n operations: [entry.item],\n showDescription: true,\n };\n if (entry.type === 'webhook')\n return {\n document: entry.schemaId,\n webhooks: [entry.item],\n showDescription: true,\n };\n\n return {\n showTitle: true,\n showDescription: true,\n document: entry.schemaId,\n operations: entry.operations,\n webhooks: entry.webhooks,\n };\n}\n\n/**\n * @deprecated use `openapiPlugin()`\n */\nexport function transformerOpenAPI(): PageTreeTransformer {\n return openapiPlugin().transformPageTree!;\n}\n"],"mappings":";;;;;;;;;AA2CA,SAAgB,gBAA8B;AAC5C,QAAO;EACL,MAAM;EACN,SAAS;EACT,mBAAmB,EACjB,KAAK,MAAM,UAAU;AACnB,OAAI,CAAC,SAAU,QAAO;GACtB,MAAM,OAAO,KAAK,QAAQ,KAAK,SAAS;AACxC,OAAI,CAAC,QAAQ,KAAK,WAAW,OAAQ,QAAO;GAE5C,MAAM,cAAc,KAAK,KAAK;AAC9B,OAAI,CAAC,eAAe,OAAO,gBAAgB,SAAU,QAAO;AAE5D,OAAI,YAAY,QACd,MAAK,OACH,qBAAA,UAAA,EAAA,UAAA;IACG,KAAK;IAAM;IACZ,oBAAC,QAAD;KAAM,WAAU;eAA8E;KAEvF,CAAA;IACN,EAAA,CAAA;YAEI,YAAY,OACrB,MAAK,OACH,qBAAA,UAAA,EAAA,UAAA;IACG,KAAK;IAAM;IACZ,oBAAC,aAAD;KAAa,WAAU;eACpB,YAAY;KACD,CAAA;IACb,EAAA,CAAA;AAIP,UAAO;KAEV;EACF;;;;;AAkBH,eAAsB,cACpB,QACA,UAII,EAAE,EAMN;CACA,MAAM,EAAE,UAAU,IAAI,OAAO,UAAU;CACvC,MAAM,EAAE,qBAAqB,MAAM,OAAO;CAC1C,MAAM,EAAE,eAAe,MAAM,OAAO;CACpC,MAAM,QAGC,EAAE;CAET,MAAM,UAAU,MAAM,WAAW,QAAQ,iBAAiB,QAAQ,CAAC;AACnE,MAAK,MAAM,CAAC,UAAU,SAAS,OAAO,QAAQ,QAAQ,EAAE;EACtD,MAAM,YAAY,MAAM,OAAO,UAAU,SAAS;EAElD,SAAS,QAAQ,OAAqD;GACpE,MAAM,QAAQ,SAAS,MAAM;AAE7B,SAAM,KAAK;IACT,MAAM;IACN,MAAM,GAAG,QAAQ,GAAG,MAAM;IAC1B,MAAM;KACJ,GAAG,MAAM;KACT,kBAAkB;AAChB,aAAO;;KAET,MAAM,wBAAwB;AAC5B,aAAO;OACL,SAAS;QACP,SAAS,UAAU;QACnB,UAAU,OAAO,QAAQ;QAC1B;OACD,GAAG;OACJ;;KAEH,YAAY;AACV,aAAO;OACL,IAAI;OACJ,GAAG;OACJ;;KAEH,GAAG,aAAa,OAAO,UAAU,aAAa;KAC9C,UAAU;MACR,QACE,MAAM,SAAS,eAAe,MAAM,SAAS,YACzC,MAAM,KAAK,SACX,KAAA;MACN,SAAS,MAAM,SAAS;MACzB;KACF;IACF,CAAC;;EAGJ,SAAS,UAAU,SAAwB,QAAsB;AAC/D,OAAI,CAAC,MAAM;AACT,SAAK,MAAM,SAAS,QAClB,KAAI,MAAM,SAAS,QACjB,WAAU,MAAM,SAAS,MAAM;QAE/B,SAAQ,MAAM;AAIlB;;GAGF,MAAM,EAAE,cAAc,aAAa,SAAS,OAAO,EAAE,GAAG;GACxD,MAAM,QAAkB,EAAE;AAE1B,QAAK,MAAM,SAAS,SAAS;IAC3B,MAAM,eAAe,UAAU,MAC7B,SAAS,KAAK,SAAS,OAAO,MAAM,MAAM,KAAK,GAAG,MAAM,KACzD;AAED,QAAI,MAAM,SAAS,SAAS;AAC1B,eAAU,MAAM,SAAS,MAAM;AAC/B,SAAI,gBAAgB,SAClB,OAAM,KAAK,aAAa;SAExB,OAAM,KAAK,MAAM,MAAM,KAAK,MAAM,MAAM,MAAM,eAAe;WAE1D;AACL,aAAQ,MAAM;AACd,WAAM,KAAK,aAAa,MAAM,GAAG,CAAC,KAAK,QAAQ,MAAM,KAAK,CAAC,OAAO,CAAC;;;AAIvE,OAAI,MAAM,WAAW,EAAG;AACxB,SAAM,KAAK;IACT,MAAM;IACN,MAAM,KAAK,KAAK,SAAS,QAAQ,QAAQ,IAAI,YAAY;IACzD,MAAM;KACJ,OAAO,QAAQ,KAAK;KACpB,aAAa,QAAQ,KAAK;KAC1B;KACD;IACF,CAAC;;AAGJ,YAAU,KAAK;;AAGjB,QAAO,EACL,OACD;;AAGH,SAAS,SAAS,OAAmE;AACnF,KAAI,MAAM,SAAS,YACjB,QAAO;EACL,UAAU,MAAM;EAChB,YAAY,CAAC,MAAM,KAAK;EACxB,iBAAiB;EAClB;AACH,KAAI,MAAM,SAAS,UACjB,QAAO;EACL,UAAU,MAAM;EAChB,UAAU,CAAC,MAAM,KAAK;EACtB,iBAAiB;EAClB;AAEH,QAAO;EACL,WAAW;EACX,iBAAiB;EACjB,UAAU,MAAM;EAChB,YAAY,MAAM;EAClB,UAAU,MAAM;EACjB;;;;;AAMH,SAAgB,qBAA0C;AACxD,QAAO,eAAe,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { OpenAPIV3, OpenAPIV3_2 } from "./_openapi/types.js";
|
|
2
|
-
import { NoReference } from "./utils/schema.js";
|
|
2
|
+
import { NoReference } from "./utils/schema/index.js";
|
|
3
3
|
import { MediaAdapter } from "./requests/media/adapter.js";
|
|
4
4
|
import { InlineCodeUsageGenerator } from "./requests/generators/index.js";
|
|
5
5
|
import { OpenAPIOptions } from "./server/create.js";
|
|
6
6
|
import { CreateAPIPageOptions } from "./ui/base.js";
|
|
7
7
|
import { ProcessedDocument } from "./utils/process-document.js";
|
|
8
|
-
import Slugger from "github-slugger";
|
|
9
8
|
import { HTMLAttributes, ReactNode } from "react";
|
|
10
9
|
|
|
11
10
|
//#region src/types.d.ts
|
|
@@ -32,8 +31,7 @@ type MethodInformation = NoReference<OperationObject> & {
|
|
|
32
31
|
'x-exclusiveCodeSample'?: string;
|
|
33
32
|
};
|
|
34
33
|
type RequireKeys<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
|
|
35
|
-
interface RenderContext extends Pick<OpenAPIOptions, 'proxyUrl'>, Omit<RequireKeys<CreateAPIPageOptions, '
|
|
36
|
-
slugger: Slugger;
|
|
34
|
+
interface RenderContext extends Pick<OpenAPIOptions, 'proxyUrl'>, Omit<RequireKeys<CreateAPIPageOptions, 'renderMarkdown' | 'generateTypeScriptDefinitions'>, 'renderCodeBlock' | 'renderHeading' | 'generateTypeScriptSchema'> {
|
|
37
35
|
/**
|
|
38
36
|
* dereferenced schema
|
|
39
37
|
*/
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;;;;;KASY,QAAA,GAAW,WAAA,CAAY,QAAA;AAAA,KACvB,eAAA,GAAkB,WAAA,CAAY,eAAA;AAAA,KAC9B,eAAA,GAAkB,WAAA,CAAY,eAAA;AAAA,KAC9B,oBAAA,GAAuB,WAAA,CAAY,oBAAA;AAAA,KACnC,eAAA,GAAkB,WAAA,CAAY,eAAA;AAAA,KAC9B,cAAA,GAAiB,WAAA,CAAY,cAAA;AAAA,KAC7B,SAAA,GAAY,WAAA,CAAY,SAAA;AAAA,KACxB,YAAA,GAAe,WAAA,CAAY,YAAA;AAAA,KAC3B,cAAA,GAAiB,WAAA,CAAY,cAAA;AAAA,KAC7B,oBAAA,GAAuB,SAAA,CAAU,oBAAA;AAAA,KACjC,cAAA,GAAiB,WAAA,CAAY,cAAA;AAAA,KAC7B,oBAAA,GAAuB,WAAA,CAAY,oBAAA;AAAA,KACnC,WAAA,GAAc,WAAA,CAAY,WAAA;AAAA,KAC1B,aAAA,GAAgB,WAAA,CAAY,aAAA;AAAA,KAC5B,eAAA,GAAkB,WAAA,CAAY,eAAA;AAAA,KAC9B,iBAAA,GAAoB,WAAA,CAAY,iBAAA;AAAA,KAEhC,iBAAA,GAAoB,WAAA,CAAY,eAAA;EAC1C,MAAA;EACA,eAAA,GAAkB,wBAAA;EAClB,sBAAA;EACA,uBAAA;AAAA;AAAA,KAGG,WAAA,oBAA+B,CAAA,IAAK,IAAA,CAAK,CAAA,EAAG,CAAA,IAAK,QAAA,CAAS,IAAA,CAAK,CAAA,EAAG,CAAA;AAAA,UAEtD,aAAA,SAEb,IAAA,CAAK,cAAA,eACL,IAAA,CACE,WAAA,CAAY,oBAAA;EA1BS;;;EAgCzB,MAAA,EAAQ,iBAAA;EAER,aAAA,EAAe,MAAA,SAAe,YAAA;EAE9B,aAAA,GACE,KAAA,UACA,IAAA,WAAe,SAAA,EACf,KAAA,GAAQ,cAAA,CAAe,kBAAA;IAAwB,EAAA;EAAA,MAC5C,SAAA;EACL,eAAA,GAAkB,IAAA,UAAc,IAAA,aAAiB,SAAA;AAAA;AAAA,KAGvC,gBAAA,cAA8B,WAAA,IAAe,CAAA,mBAAoB,IAAA,CAAK,CAAA,EAAG,CAAA;AAAA,KACzE,SAAA,MAAe,CAAA,GAAI,OAAA,CAAQ,CAAA"}
|
package/dist/ui/api-page.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { HttpMethods } from "../types.js";
|
|
2
|
-
import { ProcessedDocument } from "../utils/process-document.js";
|
|
3
|
-
|
|
4
2
|
//#region src/ui/api-page.d.ts
|
|
5
3
|
interface ApiPageProps {
|
|
6
|
-
document:
|
|
4
|
+
document: string;
|
|
7
5
|
showTitle?: boolean;
|
|
8
6
|
showDescription?: boolean;
|
|
9
7
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-page.d.ts","names":[],"sources":["../../src/ui/api-page.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"api-page.d.ts","names":[],"sources":["../../src/ui/api-page.tsx"],"mappings":";;UAKiB,YAAA;EACf,QAAA;EACA,SAAA;EACA,eAAA;EAH2B;;;EAQ3B,UAAA,GAAa,aAAA;EAEb,QAAA,GAAW,WAAA;AAAA;AAAA,UAGI,WAAA;EALF;;;EASb,IAAA;EACA,MAAA,EAAQ,WAAA;AAAA;AAAA,UAGO,aAAA;;;;EAIf,IAAA;EAPQ;;;EAWR,MAAA,EAAQ,WAAA;AAAA"}
|
package/dist/ui/api-page.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { createMethod } from "../utils/schema.js";
|
|
1
|
+
import { createMethod } from "../utils/schema/index.js";
|
|
2
2
|
import { ApiProviderLazy, ServerProviderLazy } from "./contexts/api.lazy.js";
|
|
3
3
|
import { Operation } from "./operation/index.js";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
//#region src/ui/api-page.tsx
|
|
6
|
-
|
|
6
|
+
function APIPage({ showTitle: hasHead = false, showDescription, operations, webhooks, ctx }) {
|
|
7
7
|
const { dereferenced } = ctx.schema;
|
|
8
8
|
let { renderPageLayout } = ctx.content ?? {};
|
|
9
9
|
renderPageLayout ??= (slots) => /* @__PURE__ */ jsxs("div", {
|
|
10
10
|
className: "flex flex-col gap-24 text-sm @container",
|
|
11
11
|
children: [slots.operations?.map((op) => op.children), slots.webhooks?.map((op) => op.children)]
|
|
12
12
|
});
|
|
13
|
-
const content =
|
|
13
|
+
const content = renderPageLayout({
|
|
14
14
|
operations: operations?.map((item) => {
|
|
15
15
|
const pathItem = dereferenced.paths?.[item.path];
|
|
16
16
|
if (!pathItem) throw new Error(`[Fumadocs OpenAPI] Path not found in OpenAPI schema: ${item.path}`);
|
|
@@ -45,13 +45,11 @@ async function APIPage({ showTitle: hasHead = false, showDescription, operations
|
|
|
45
45
|
};
|
|
46
46
|
})
|
|
47
47
|
}, ctx);
|
|
48
|
-
let servers = ctx.schema.dereferenced.servers;
|
|
49
|
-
if (!servers || servers.length === 0) servers = [{ url: "/" }];
|
|
50
48
|
return /* @__PURE__ */ jsx(ApiProviderLazy, {
|
|
51
49
|
shikiOptions: ctx.shikiOptions,
|
|
52
50
|
client: ctx.client ?? {},
|
|
53
51
|
children: /* @__PURE__ */ jsx(ServerProviderLazy, {
|
|
54
|
-
servers,
|
|
52
|
+
servers: dereferenced.servers,
|
|
55
53
|
children: content
|
|
56
54
|
})
|
|
57
55
|
});
|
package/dist/ui/api-page.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-page.js","names":[],"sources":["../../src/ui/api-page.tsx"],"sourcesContent":["import { Operation } from '@/ui/operation';\nimport type { HttpMethods, RenderContext } from '@/types';\nimport { createMethod } from '@/utils/schema';\nimport
|
|
1
|
+
{"version":3,"file":"api-page.js","names":[],"sources":["../../src/ui/api-page.tsx"],"sourcesContent":["import { Operation } from '@/ui/operation';\nimport type { HttpMethods, RenderContext, ServerObject } from '@/types';\nimport { createMethod } from '@/utils/schema';\nimport { ApiProviderLazy, ServerProviderLazy } from './contexts/api.lazy';\n\nexport interface ApiPageProps {\n document: string;\n showTitle?: boolean;\n showDescription?: boolean;\n\n /**\n * An array of operations\n */\n operations?: OperationItem[];\n\n webhooks?: WebhookItem[];\n}\n\nexport interface WebhookItem {\n /**\n * webhook name in `webhooks`\n */\n name: string;\n method: HttpMethods;\n}\n\nexport interface OperationItem {\n /**\n * the path of operation in `paths`\n */\n path: string;\n /**\n * the HTTP method of operation\n */\n method: HttpMethods;\n}\n\nexport function APIPage({\n showTitle: hasHead = false,\n showDescription,\n operations,\n webhooks,\n ctx,\n}: Omit<ApiPageProps, 'document'> & {\n ctx: RenderContext;\n}) {\n const { dereferenced } = ctx.schema;\n let { renderPageLayout } = ctx.content ?? {};\n renderPageLayout ??= (slots) => (\n <div className=\"flex flex-col gap-24 text-sm @container\">\n {slots.operations?.map((op) => op.children)}\n {slots.webhooks?.map((op) => op.children)}\n </div>\n );\n\n const content = renderPageLayout(\n {\n operations: operations?.map((item) => {\n const pathItem = dereferenced.paths?.[item.path];\n if (!pathItem)\n throw new Error(`[Fumadocs OpenAPI] Path not found in OpenAPI schema: ${item.path}`);\n\n const operation = pathItem[item.method];\n if (!operation)\n throw new Error(\n `[Fumadocs OpenAPI] Method ${item.method} not found in operation: ${item.path}`,\n );\n\n const method = createMethod(item.method, pathItem, operation);\n\n return {\n item,\n children: (\n <Operation\n key={`${item.path}:${item.method}`}\n method={method}\n path={item.path}\n ctx={ctx}\n showTitle={hasHead}\n showDescription={showDescription}\n />\n ),\n };\n }),\n webhooks: webhooks?.map((item) => {\n const webhook = dereferenced.webhooks?.[item.name];\n if (!webhook)\n throw new Error(`[Fumadocs OpenAPI] Webhook not found in OpenAPI schema: ${item.name}`);\n\n const hook = webhook[item.method];\n if (!hook)\n throw new Error(\n `[Fumadocs OpenAPI] Method ${item.method} not found in webhook: ${item.name}`,\n );\n\n return {\n item,\n children: (\n <Operation\n type=\"webhook\"\n key={`${item.name}:${item.method}`}\n method={createMethod(item.method, webhook, hook)}\n ctx={ctx}\n path={`/${item.name}`}\n showTitle={hasHead}\n showDescription={showDescription}\n />\n ),\n };\n }),\n },\n ctx,\n );\n\n return (\n <ApiProviderLazy shikiOptions={ctx.shikiOptions} client={ctx.client ?? {}}>\n <ServerProviderLazy servers={dereferenced.servers as ServerObject[]}>\n {content}\n </ServerProviderLazy>\n </ApiProviderLazy>\n );\n}\n"],"mappings":";;;;;AAqCA,SAAgB,QAAQ,EACtB,WAAW,UAAU,OACrB,iBACA,YACA,UACA,OAGC;CACD,MAAM,EAAE,iBAAiB,IAAI;CAC7B,IAAI,EAAE,qBAAqB,IAAI,WAAW,EAAE;AAC5C,uBAAsB,UACpB,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,MAAM,YAAY,KAAK,OAAO,GAAG,SAAS,EAC1C,MAAM,UAAU,KAAK,OAAO,GAAG,SAAS,CACrC;;CAGR,MAAM,UAAU,iBACd;EACE,YAAY,YAAY,KAAK,SAAS;GACpC,MAAM,WAAW,aAAa,QAAQ,KAAK;AAC3C,OAAI,CAAC,SACH,OAAM,IAAI,MAAM,wDAAwD,KAAK,OAAO;GAEtF,MAAM,YAAY,SAAS,KAAK;AAChC,OAAI,CAAC,UACH,OAAM,IAAI,MACR,6BAA6B,KAAK,OAAO,2BAA2B,KAAK,OAC1E;AAIH,UAAO;IACL;IACA,UACE,oBAAC,WAAD;KAEE,QAPS,aAAa,KAAK,QAAQ,UAAU,UAAU;KAQvD,MAAM,KAAK;KACN;KACL,WAAW;KACM;KACjB,EANK,GAAG,KAAK,KAAK,GAAG,KAAK,SAM1B;IAEL;IACD;EACF,UAAU,UAAU,KAAK,SAAS;GAChC,MAAM,UAAU,aAAa,WAAW,KAAK;AAC7C,OAAI,CAAC,QACH,OAAM,IAAI,MAAM,2DAA2D,KAAK,OAAO;GAEzF,MAAM,OAAO,QAAQ,KAAK;AAC1B,OAAI,CAAC,KACH,OAAM,IAAI,MACR,6BAA6B,KAAK,OAAO,yBAAyB,KAAK,OACxE;AAEH,UAAO;IACL;IACA,UACE,oBAAC,WAAD;KACE,MAAK;KAEL,QAAQ,aAAa,KAAK,QAAQ,SAAS,KAAK;KAC3C;KACL,MAAM,IAAI,KAAK;KACf,WAAW;KACM;KACjB,EANK,GAAG,KAAK,KAAK,GAAG,KAAK,SAM1B;IAEL;IACD;EACH,EACD,IACD;AAED,QACE,oBAAC,iBAAD;EAAiB,cAAc,IAAI;EAAc,QAAQ,IAAI,UAAU,EAAE;YACvE,oBAAC,oBAAD;GAAoB,SAAS,aAAa;aACvC;GACkB,CAAA;EACL,CAAA"}
|
package/dist/ui/base.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { NoReference } from "../utils/schema.js";
|
|
1
|
+
import { NoReference } from "../utils/schema/index.js";
|
|
2
2
|
import { MediaAdapter } from "../requests/media/adapter.js";
|
|
3
3
|
import { CodeUsageGeneratorRegistry, InlineCodeUsageGenerator } from "../requests/generators/index.js";
|
|
4
4
|
import { OpenAPIServer } from "../server/create.js";
|
|
5
5
|
import { ApiPageProps, OperationItem, WebhookItem } from "./api-page.js";
|
|
6
|
-
import { ExampleRequestItem } from "./operation/
|
|
6
|
+
import { ExampleRequestItem } from "./operation/get-example-requests.js";
|
|
7
7
|
import { APIPageClientOptions } from "./client/index.js";
|
|
8
8
|
import { SchemaUIOptions } from "./schema/index.js";
|
|
9
9
|
import { ResponseTab } from "./operation/response-tabs.js";
|
|
10
10
|
import { ClientCodeBlockProvider } from "./components/codeblock.js";
|
|
11
11
|
import { Awaitable, MethodInformation, RenderContext } from "../types.js";
|
|
12
|
+
import { ProcessedDocument } from "../utils/process-document.js";
|
|
12
13
|
import { FC, HTMLAttributes, ReactNode } from "react";
|
|
13
14
|
import { ShikiFactory } from "fumadocs-core/highlight/shiki";
|
|
14
15
|
import { JSONSchema } from "json-schema-typed";
|
|
@@ -41,7 +42,7 @@ interface CreateAPIPageOptions {
|
|
|
41
42
|
*
|
|
42
43
|
* Pass `false` to disable it.
|
|
43
44
|
*/
|
|
44
|
-
generateTypeScriptDefinitions?: (schema: JSONSchema, ctx: GenerateTypeScriptDefinitionsContext) => Awaitable<string | undefined
|
|
45
|
+
generateTypeScriptDefinitions?: ((schema: JSONSchema, ctx: GenerateTypeScriptDefinitionsContext) => Awaitable<string | undefined>) | false;
|
|
45
46
|
/**
|
|
46
47
|
* Generate example code usage for all endpoints.
|
|
47
48
|
*/
|
|
@@ -49,7 +50,7 @@ interface CreateAPIPageOptions {
|
|
|
49
50
|
/**
|
|
50
51
|
* Generate example code usage for each endpoint.
|
|
51
52
|
*/
|
|
52
|
-
generateCodeSamples?: (method: MethodInformation) =>
|
|
53
|
+
generateCodeSamples?: (method: MethodInformation) => InlineCodeUsageGenerator[];
|
|
53
54
|
shiki: ShikiFactory;
|
|
54
55
|
renderMarkdown?: (md: string) => ReactNode;
|
|
55
56
|
shikiOptions: Omit<CodeToHastOptionsCommon, 'lang'> & CodeOptionsThemes<BundledTheme>;
|
|
@@ -67,20 +68,20 @@ interface CreateAPIPageOptions {
|
|
|
67
68
|
* Customise page content
|
|
68
69
|
*/
|
|
69
70
|
content?: {
|
|
70
|
-
renderResponseTabs?: (tabs: ResponseTab[], ctx: RenderContext) =>
|
|
71
|
+
renderResponseTabs?: (tabs: ResponseTab[], ctx: RenderContext) => ReactNode;
|
|
71
72
|
renderRequestTabs?: (items: ExampleRequestItem[], ctx: RenderContext & {
|
|
72
73
|
route: string;
|
|
73
74
|
operation: NoReference<MethodInformation>;
|
|
74
|
-
}) =>
|
|
75
|
+
}) => ReactNode;
|
|
75
76
|
renderAPIExampleLayout?: (slots: {
|
|
76
77
|
selector: ReactNode;
|
|
77
78
|
usageTabs: ReactNode;
|
|
78
79
|
responseTabs: ReactNode;
|
|
79
|
-
}, ctx: RenderContext) =>
|
|
80
|
+
}, ctx: RenderContext) => ReactNode;
|
|
80
81
|
/**
|
|
81
82
|
* @param generators - codegens for API example usages
|
|
82
83
|
*/
|
|
83
|
-
renderAPIExampleUsageTabs?: (generators: CodeUsageGeneratorRegistry, ctx: RenderContext) =>
|
|
84
|
+
renderAPIExampleUsageTabs?: (generators: CodeUsageGeneratorRegistry, ctx: RenderContext) => ReactNode;
|
|
84
85
|
/**
|
|
85
86
|
* renderer of the entire page's layout (containing all operations & webhooks UI)
|
|
86
87
|
*/
|
|
@@ -93,7 +94,7 @@ interface CreateAPIPageOptions {
|
|
|
93
94
|
item: WebhookItem;
|
|
94
95
|
children: ReactNode;
|
|
95
96
|
}[];
|
|
96
|
-
}, ctx: RenderContext) =>
|
|
97
|
+
}, ctx: RenderContext) => ReactNode;
|
|
97
98
|
renderOperationLayout?: (slots: {
|
|
98
99
|
header: ReactNode;
|
|
99
100
|
description: ReactNode;
|
|
@@ -104,7 +105,7 @@ interface CreateAPIPageOptions {
|
|
|
104
105
|
body: ReactNode;
|
|
105
106
|
responses: ReactNode;
|
|
106
107
|
callbacks: ReactNode;
|
|
107
|
-
}, ctx: RenderContext, method: NoReference<MethodInformation>) =>
|
|
108
|
+
}, ctx: RenderContext, method: NoReference<MethodInformation>) => ReactNode;
|
|
108
109
|
renderWebhookLayout?: (slots: {
|
|
109
110
|
header: ReactNode;
|
|
110
111
|
description: ReactNode;
|
|
@@ -114,13 +115,13 @@ interface CreateAPIPageOptions {
|
|
|
114
115
|
requests: ReactNode;
|
|
115
116
|
responses: ReactNode;
|
|
116
117
|
callbacks: ReactNode;
|
|
117
|
-
}) =>
|
|
118
|
+
}) => ReactNode;
|
|
118
119
|
};
|
|
119
120
|
/**
|
|
120
121
|
* Info UI for JSON schemas
|
|
121
122
|
*/
|
|
122
123
|
schemaUI?: {
|
|
123
|
-
render?: (options: SchemaUIOptions, ctx: RenderContext) =>
|
|
124
|
+
render?: (options: SchemaUIOptions, ctx: RenderContext) => ReactNode;
|
|
124
125
|
/**
|
|
125
126
|
* Show examples under the generated content of JSON schemas.
|
|
126
127
|
*
|
|
@@ -145,14 +146,17 @@ interface CreateAPIPageOptions {
|
|
|
145
146
|
ctx: RenderContext;
|
|
146
147
|
}) => Awaitable<ReactNode>;
|
|
147
148
|
};
|
|
148
|
-
renderHeading?: (props: HTMLAttributes<HTMLHeadingElement>, depth: number) =>
|
|
149
|
+
renderHeading?: (props: HTMLAttributes<HTMLHeadingElement>, depth: number) => ReactNode;
|
|
149
150
|
renderCodeBlock?: (props: {
|
|
150
151
|
lang: string;
|
|
151
152
|
code: string;
|
|
152
|
-
}) =>
|
|
153
|
+
}) => ReactNode;
|
|
153
154
|
client?: APIPageClientOptions;
|
|
154
155
|
}
|
|
155
|
-
|
|
156
|
+
interface ServerApiPageProps extends Omit<ApiPageProps, 'document'> {
|
|
157
|
+
document: string | ProcessedDocument;
|
|
158
|
+
}
|
|
159
|
+
declare function createAPIPage(server: OpenAPIServer, options: CreateAPIPageOptions): FC<ServerApiPageProps>;
|
|
156
160
|
//#endregion
|
|
157
|
-
export { ClientCodeBlockProvider, CreateAPIPageOptions, GenerateTypeScriptDefinitionsContext, createAPIPage };
|
|
161
|
+
export { ClientCodeBlockProvider, CreateAPIPageOptions, GenerateTypeScriptDefinitionsContext, ServerApiPageProps, createAPIPage };
|
|
158
162
|
//# sourceMappingURL=base.d.ts.map
|
package/dist/ui/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","names":[],"sources":["../../src/ui/base.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"base.d.ts","names":[],"sources":["../../src/ui/base.tsx"],"mappings":"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"}
|
package/dist/ui/base.js
CHANGED
|
@@ -13,6 +13,7 @@ import remarkRehype from "remark-rehype";
|
|
|
13
13
|
import { toJsxRuntime } from "hast-util-to-jsx-runtime";
|
|
14
14
|
import { CodeBlock, Pre } from "fumadocs-ui/components/codeblock";
|
|
15
15
|
import { highlightHast } from "fumadocs-core/highlight/shiki";
|
|
16
|
+
import { compile } from "@fumari/json-schema-ts";
|
|
16
17
|
//#region src/ui/base.tsx
|
|
17
18
|
function createAPIPage(server, options) {
|
|
18
19
|
let processor;
|
|
@@ -37,7 +38,7 @@ function createAPIPage(server, options) {
|
|
|
37
38
|
return async function APIPageWrapper({ document, ...props }) {
|
|
38
39
|
let processed;
|
|
39
40
|
if (typeof document === "string") processed = await server.getSchema(document);
|
|
40
|
-
else processed =
|
|
41
|
+
else processed = document;
|
|
41
42
|
const slugger = new Slugger();
|
|
42
43
|
const ctx = {
|
|
43
44
|
schema: processed,
|
|
@@ -47,8 +48,7 @@ function createAPIPage(server, options) {
|
|
|
47
48
|
...defaultAdapters,
|
|
48
49
|
...options.mediaAdapters
|
|
49
50
|
},
|
|
50
|
-
|
|
51
|
-
async renderHeading(depth, text, props) {
|
|
51
|
+
renderHeading(depth, text, props) {
|
|
52
52
|
const id = typeof text === "string" ? slugger.slug(text) : props?.id;
|
|
53
53
|
if (!id) throw new Error("missing 'id' for non-string children");
|
|
54
54
|
if (options.renderHeading) return options.renderHeading({
|
|
@@ -63,14 +63,23 @@ function createAPIPage(server, options) {
|
|
|
63
63
|
children: text
|
|
64
64
|
}, id);
|
|
65
65
|
},
|
|
66
|
-
generateTypeScriptDefinitions(schema, ctx) {
|
|
67
|
-
|
|
68
|
-
if (generateTypeScriptSchema && ctx._internal_legacy) {
|
|
66
|
+
generateTypeScriptDefinitions: options.generateTypeScriptDefinitions ?? ((schema, ctx) => {
|
|
67
|
+
if (options.generateTypeScriptSchema && ctx._internal_legacy) {
|
|
69
68
|
const { statusCode, contentType } = ctx._internal_legacy;
|
|
70
|
-
return generateTypeScriptSchema(ctx.operation, statusCode, contentType, ctx);
|
|
69
|
+
return options.generateTypeScriptSchema(ctx.operation, statusCode, contentType, ctx);
|
|
71
70
|
}
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
if (typeof schema !== "object") return;
|
|
72
|
+
try {
|
|
73
|
+
return compile(schema, {
|
|
74
|
+
name: "Response",
|
|
75
|
+
readOnly: ctx.readOnly,
|
|
76
|
+
writeOnly: ctx.writeOnly,
|
|
77
|
+
getSchemaId: ctx.schema.getRawRef
|
|
78
|
+
});
|
|
79
|
+
} catch (e) {
|
|
80
|
+
console.warn("Failed to generate typescript schema:", e);
|
|
81
|
+
}
|
|
82
|
+
}),
|
|
74
83
|
async renderMarkdown(text) {
|
|
75
84
|
if (options.renderMarkdown) return options.renderMarkdown(text);
|
|
76
85
|
processor ??= createMarkdownProcessor();
|
package/dist/ui/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":[],"sources":["../../src/ui/base.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any -- rehype-react without types */\nimport Slugger from 'github-slugger';\nimport type { Awaitable, MethodInformation, RenderContext } from '@/types';\nimport type { NoReference } from '@/utils/schema';\nimport type { ProcessedDocument } from '@/utils/process-document';\nimport { defaultAdapters, MediaAdapter } from '@/requests/media/adapter';\nimport type { FC, HTMLAttributes, ReactNode } from 'react';\nimport type { OpenAPIServer } from '@/server';\nimport type { APIPageClientOptions } from './client';\nimport { Heading } from 'fumadocs-ui/components/heading';\nimport { createRehypeCode } from 'fumadocs-core/mdx-plugins/rehype-code.core';\nimport { remarkGfm } from 'fumadocs-core/mdx-plugins/remark-gfm';\nimport defaultMdxComponents from 'fumadocs-ui/mdx';\nimport { remark } from 'remark';\nimport remarkRehype from 'remark-rehype';\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime';\nimport * as JsxRuntime from 'react/jsx-runtime';\nimport { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';\nimport type { SchemaUIOptions } from './schema';\nimport type { ResponseTab } from './operation/response-tabs';\nimport type { ExampleRequestItem } from './operation/request-tabs';\nimport { APIPage, type ApiPageProps, type OperationItem, type WebhookItem } from './api-page';\nimport type { CodeUsageGeneratorRegistry, InlineCodeUsageGenerator } from '@/requests/generators';\nimport type { JSONSchema } from 'json-schema-typed';\nimport type { BundledTheme, CodeOptionsThemes, CodeToHastOptionsCommon } from 'shiki';\nimport { highlightHast, type ShikiFactory } from 'fumadocs-core/highlight/shiki';\n\nexport interface GenerateTypeScriptDefinitionsContext extends RenderContext {\n operation: NoReference<MethodInformation>;\n readOnly: boolean;\n writeOnly: boolean;\n /** @deprecated */\n _internal_legacy?: {\n statusCode: string;\n contentType: string;\n };\n}\n\nexport interface CreateAPIPageOptions {\n /**\n * Generate TypeScript definitions from response schema.\n *\n * Pass `false` to disable it.\n *\n * @param method - the operation object\n * @param statusCode - status code\n * @deprecated use `generateTypeScriptDefinitions` instead.\n */\n generateTypeScriptSchema?:\n | ((\n method: NoReference<MethodInformation>,\n statusCode: string,\n contentType: string,\n ctx: RenderContext,\n ) => Awaitable<string | undefined>)\n | false;\n\n /**\n * Generate TypeScript definitions from JSON schema.\n *\n * Pass `false` to disable it.\n */\n generateTypeScriptDefinitions?: (\n schema: JSONSchema,\n ctx: GenerateTypeScriptDefinitionsContext,\n ) => Awaitable<string | undefined>;\n\n /**\n * Generate example code usage for all endpoints.\n */\n codeUsages?: CodeUsageGeneratorRegistry;\n\n /**\n * Generate example code usage for each endpoint.\n */\n generateCodeSamples?: (method: MethodInformation) => Awaitable<InlineCodeUsageGenerator[]>;\n\n shiki: ShikiFactory;\n renderMarkdown?: (md: string) => ReactNode;\n shikiOptions: Omit<CodeToHastOptionsCommon, 'lang'> & CodeOptionsThemes<BundledTheme>;\n\n /**\n * Show full response schema instead of only example response & Typescript definitions.\n *\n * @default true\n */\n showResponseSchema?: boolean;\n\n /**\n * Support other media types (for server-side generation).\n */\n mediaAdapters?: Record<string, MediaAdapter>;\n\n /**\n * Customise page content\n */\n content?: {\n renderResponseTabs?: (tabs: ResponseTab[], ctx: RenderContext) => Awaitable<ReactNode>;\n\n renderRequestTabs?: (\n items: ExampleRequestItem[],\n ctx: RenderContext & {\n route: string;\n operation: NoReference<MethodInformation>;\n },\n ) => Awaitable<ReactNode>;\n\n renderAPIExampleLayout?: (\n slots: {\n selector: ReactNode;\n usageTabs: ReactNode;\n responseTabs: ReactNode;\n },\n ctx: RenderContext,\n ) => Awaitable<ReactNode>;\n\n /**\n * @param generators - codegens for API example usages\n */\n renderAPIExampleUsageTabs?: (\n generators: CodeUsageGeneratorRegistry,\n ctx: RenderContext,\n ) => Awaitable<ReactNode>;\n\n /**\n * renderer of the entire page's layout (containing all operations & webhooks UI)\n */\n renderPageLayout?: (\n slots: {\n operations?: {\n item: OperationItem;\n children: ReactNode;\n }[];\n webhooks?: {\n item: WebhookItem;\n children: ReactNode;\n }[];\n },\n ctx: RenderContext,\n ) => Awaitable<ReactNode>;\n\n renderOperationLayout?: (\n slots: {\n header: ReactNode;\n description: ReactNode;\n apiExample: ReactNode;\n apiPlayground: ReactNode;\n\n authSchemes: ReactNode;\n parameters: ReactNode;\n body: ReactNode;\n responses: ReactNode;\n callbacks: ReactNode;\n },\n ctx: RenderContext,\n method: NoReference<MethodInformation>,\n ) => Awaitable<ReactNode>;\n\n renderWebhookLayout?: (slots: {\n header: ReactNode;\n description: ReactNode;\n authSchemes: ReactNode;\n parameters: ReactNode;\n body: ReactNode;\n requests: ReactNode;\n responses: ReactNode;\n callbacks: ReactNode;\n }) => Awaitable<ReactNode>;\n };\n\n /**\n * Info UI for JSON schemas\n */\n schemaUI?: {\n render?: (options: SchemaUIOptions, ctx: RenderContext) => Awaitable<ReactNode>;\n\n /**\n * Show examples under the generated content of JSON schemas.\n *\n * @defaultValue false\n */\n showExample?: boolean;\n };\n\n /**\n * Customise API playground\n */\n playground?: {\n /**\n * @defaultValue true\n */\n enabled?: boolean;\n /**\n * replace the server-side renderer\n */\n render?: (props: {\n path: string;\n method: MethodInformation;\n ctx: RenderContext;\n }) => Awaitable<ReactNode>;\n };\n\n renderHeading?: (\n props: HTMLAttributes<HTMLHeadingElement>,\n depth: number,\n ) => Awaitable<ReactNode>;\n renderCodeBlock?: (props: { lang: string; code: string }) => Awaitable<ReactNode>;\n\n client?: APIPageClientOptions;\n}\n\nexport function createAPIPage(\n server: OpenAPIServer,\n options: CreateAPIPageOptions,\n): FC<ApiPageProps> {\n let processor: ReturnType<typeof createMarkdownProcessor>;\n\n function createMarkdownProcessor() {\n function rehypeReact(this: any) {\n this.compiler = (tree: any, file: any) => {\n return toJsxRuntime(tree, {\n development: false,\n filePath: file.path,\n ...JsxRuntime,\n components: defaultMdxComponents,\n });\n };\n }\n\n return remark()\n .use(remarkGfm)\n .use(remarkRehype)\n .use(createRehypeCode(options.shiki), {\n langs: [],\n lazy: true,\n defaultColor: false,\n ...options.shikiOptions,\n })\n .use(rehypeReact);\n }\n\n return async function APIPageWrapper({ document, ...props }) {\n let processed: ProcessedDocument;\n if (typeof document === 'string') {\n processed = await server.getSchema(document);\n } else {\n processed = await document;\n }\n\n const slugger = new Slugger();\n\n const ctx: RenderContext = {\n schema: processed,\n proxyUrl: server.options.proxyUrl,\n ...options,\n mediaAdapters: {\n ...defaultAdapters,\n ...options.mediaAdapters,\n },\n slugger,\n async renderHeading(depth, text, props) {\n const id = typeof text === 'string' ? slugger.slug(text) : props?.id;\n if (!id) throw new Error(\"missing 'id' for non-string children\");\n\n if (options.renderHeading) {\n return options.renderHeading({ id, children: text, ...props }, depth);\n }\n\n return (\n <Heading id={id} key={id} as={`h${depth}` as `h1`} {...props}>\n {text}\n </Heading>\n );\n },\n generateTypeScriptDefinitions(schema, ctx) {\n const { generateTypeScriptSchema, generateTypeScriptDefinitions } = options;\n if (generateTypeScriptSchema && ctx._internal_legacy) {\n const { statusCode, contentType } = ctx._internal_legacy;\n return generateTypeScriptSchema(ctx.operation, statusCode, contentType, ctx);\n }\n\n return generateTypeScriptDefinitions?.(schema, ctx);\n },\n async renderMarkdown(text) {\n if (options.renderMarkdown) return options.renderMarkdown(text);\n processor ??= createMarkdownProcessor();\n\n const out = await processor.process({\n value: text,\n });\n\n return out.result as ReactNode;\n },\n async renderCodeBlock(lang, code) {\n if (options.renderCodeBlock) {\n return options.renderCodeBlock({ lang, code });\n }\n\n const hast = await highlightHast(await options.shiki.getOrInit(), code, {\n lang,\n defaultColor: false,\n ...options.shikiOptions,\n });\n const rendered = toJsxRuntime(hast, {\n ...JsxRuntime,\n components: {\n pre: Pre,\n },\n });\n\n return <CodeBlock className=\"my-0\">{rendered}</CodeBlock>;\n },\n };\n\n return <APIPage {...props} ctx={ctx} />;\n };\n}\n\nexport { ClientCodeBlockProvider } from './components/codeblock';\n"],"mappings":";;;;;;;;;;;;;;;;AAmNA,SAAgB,cACd,QACA,SACkB;CAClB,IAAI;CAEJ,SAAS,0BAA0B;EACjC,SAAS,cAAuB;AAC9B,QAAK,YAAY,MAAW,SAAc;AACxC,WAAO,aAAa,MAAM;KACxB,aAAa;KACb,UAAU,KAAK;KACf,GAAG;KACH,YAAY;KACb,CAAC;;;AAIN,SAAO,QAAQ,CACZ,IAAI,UAAU,CACd,IAAI,aAAa,CACjB,IAAI,iBAAiB,QAAQ,MAAM,EAAE;GACpC,OAAO,EAAE;GACT,MAAM;GACN,cAAc;GACd,GAAG,QAAQ;GACZ,CAAC,CACD,IAAI,YAAY;;AAGrB,QAAO,eAAe,eAAe,EAAE,UAAU,GAAG,SAAS;EAC3D,IAAI;AACJ,MAAI,OAAO,aAAa,SACtB,aAAY,MAAM,OAAO,UAAU,SAAS;MAE5C,aAAY,MAAM;EAGpB,MAAM,UAAU,IAAI,SAAS;EAE7B,MAAM,MAAqB;GACzB,QAAQ;GACR,UAAU,OAAO,QAAQ;GACzB,GAAG;GACH,eAAe;IACb,GAAG;IACH,GAAG,QAAQ;IACZ;GACD;GACA,MAAM,cAAc,OAAO,MAAM,OAAO;IACtC,MAAM,KAAK,OAAO,SAAS,WAAW,QAAQ,KAAK,KAAK,GAAG,OAAO;AAClE,QAAI,CAAC,GAAI,OAAM,IAAI,MAAM,uCAAuC;AAEhE,QAAI,QAAQ,cACV,QAAO,QAAQ,cAAc;KAAE;KAAI,UAAU;KAAM,GAAG;KAAO,EAAE,MAAM;AAGvE,WACE,oBAAC,SAAD;KAAa;KAAa,IAAI,IAAI;KAAiB,GAAI;eACpD;KACO,EAFY,GAEZ;;GAGd,8BAA8B,QAAQ,KAAK;IACzC,MAAM,EAAE,0BAA0B,kCAAkC;AACpE,QAAI,4BAA4B,IAAI,kBAAkB;KACpD,MAAM,EAAE,YAAY,gBAAgB,IAAI;AACxC,YAAO,yBAAyB,IAAI,WAAW,YAAY,aAAa,IAAI;;AAG9E,WAAO,gCAAgC,QAAQ,IAAI;;GAErD,MAAM,eAAe,MAAM;AACzB,QAAI,QAAQ,eAAgB,QAAO,QAAQ,eAAe,KAAK;AAC/D,kBAAc,yBAAyB;AAMvC,YAJY,MAAM,UAAU,QAAQ,EAClC,OAAO,MACR,CAAC,EAES;;GAEb,MAAM,gBAAgB,MAAM,MAAM;AAChC,QAAI,QAAQ,gBACV,QAAO,QAAQ,gBAAgB;KAAE;KAAM;KAAM,CAAC;AAehD,WAAO,oBAAC,WAAD;KAAW,WAAU;eAPX,aALJ,MAAM,cAAc,MAAM,QAAQ,MAAM,WAAW,EAAE,MAAM;MACtE;MACA,cAAc;MACd,GAAG,QAAQ;MACZ,CAAC,EACkC;MAClC,GAAG;MACH,YAAY,EACV,KAAK,KACN;MACF,CAAC;KAEuD,CAAA;;GAE5D;AAED,SAAO,oBAAC,SAAD;GAAS,GAAI;GAAY;GAAO,CAAA"}
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"sources":["../../src/ui/base.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any -- rehype-react without types */\nimport Slugger from 'github-slugger';\nimport type { Awaitable, MethodInformation, RenderContext } from '@/types';\nimport type { NoReference } from '@/utils/schema';\nimport type { ProcessedDocument } from '@/utils/process-document';\nimport { defaultAdapters, MediaAdapter } from '@/requests/media/adapter';\nimport type { FC, HTMLAttributes, ReactNode } from 'react';\nimport type { OpenAPIServer } from '@/server';\nimport type { APIPageClientOptions } from './client';\nimport { Heading } from 'fumadocs-ui/components/heading';\nimport { createRehypeCode } from 'fumadocs-core/mdx-plugins/rehype-code.core';\nimport { remarkGfm } from 'fumadocs-core/mdx-plugins/remark-gfm';\nimport defaultMdxComponents from 'fumadocs-ui/mdx';\nimport { remark } from 'remark';\nimport remarkRehype from 'remark-rehype';\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime';\nimport * as JsxRuntime from 'react/jsx-runtime';\nimport { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';\nimport type { SchemaUIOptions } from './schema';\nimport type { ResponseTab } from './operation/response-tabs';\nimport { APIPage, type ApiPageProps, type OperationItem, type WebhookItem } from './api-page';\nimport type { CodeUsageGeneratorRegistry, InlineCodeUsageGenerator } from '@/requests/generators';\nimport type { JSONSchema } from 'json-schema-typed';\nimport type { BundledTheme, CodeOptionsThemes, CodeToHastOptionsCommon } from 'shiki';\nimport { highlightHast, type ShikiFactory } from 'fumadocs-core/highlight/shiki';\nimport type { ExampleRequestItem } from './operation/get-example-requests';\nimport { compile } from '@fumari/json-schema-ts';\n\nexport interface GenerateTypeScriptDefinitionsContext extends RenderContext {\n operation: NoReference<MethodInformation>;\n readOnly: boolean;\n writeOnly: boolean;\n /** @deprecated */\n _internal_legacy?: {\n statusCode: string;\n contentType: string;\n };\n}\n\nexport interface CreateAPIPageOptions {\n /**\n * Generate TypeScript definitions from response schema.\n *\n * Pass `false` to disable it.\n *\n * @param method - the operation object\n * @param statusCode - status code\n * @deprecated use `generateTypeScriptDefinitions` instead.\n */\n generateTypeScriptSchema?:\n | ((\n method: NoReference<MethodInformation>,\n statusCode: string,\n contentType: string,\n ctx: RenderContext,\n ) => Awaitable<string | undefined>)\n | false;\n\n /**\n * Generate TypeScript definitions from JSON schema.\n *\n * Pass `false` to disable it.\n */\n generateTypeScriptDefinitions?:\n | ((\n schema: JSONSchema,\n ctx: GenerateTypeScriptDefinitionsContext,\n ) => Awaitable<string | undefined>)\n | false;\n\n /**\n * Generate example code usage for all endpoints.\n */\n codeUsages?: CodeUsageGeneratorRegistry;\n\n /**\n * Generate example code usage for each endpoint.\n */\n generateCodeSamples?: (method: MethodInformation) => InlineCodeUsageGenerator[];\n\n shiki: ShikiFactory;\n renderMarkdown?: (md: string) => ReactNode;\n shikiOptions: Omit<CodeToHastOptionsCommon, 'lang'> & CodeOptionsThemes<BundledTheme>;\n\n /**\n * Show full response schema instead of only example response & Typescript definitions.\n *\n * @default true\n */\n showResponseSchema?: boolean;\n\n /**\n * Support other media types (for server-side generation).\n */\n mediaAdapters?: Record<string, MediaAdapter>;\n\n /**\n * Customise page content\n */\n content?: {\n renderResponseTabs?: (tabs: ResponseTab[], ctx: RenderContext) => ReactNode;\n\n renderRequestTabs?: (\n items: ExampleRequestItem[],\n ctx: RenderContext & {\n route: string;\n operation: NoReference<MethodInformation>;\n },\n ) => ReactNode;\n\n renderAPIExampleLayout?: (\n slots: {\n selector: ReactNode;\n usageTabs: ReactNode;\n responseTabs: ReactNode;\n },\n ctx: RenderContext,\n ) => ReactNode;\n\n /**\n * @param generators - codegens for API example usages\n */\n renderAPIExampleUsageTabs?: (\n generators: CodeUsageGeneratorRegistry,\n ctx: RenderContext,\n ) => ReactNode;\n\n /**\n * renderer of the entire page's layout (containing all operations & webhooks UI)\n */\n renderPageLayout?: (\n slots: {\n operations?: {\n item: OperationItem;\n children: ReactNode;\n }[];\n webhooks?: {\n item: WebhookItem;\n children: ReactNode;\n }[];\n },\n ctx: RenderContext,\n ) => ReactNode;\n\n renderOperationLayout?: (\n slots: {\n header: ReactNode;\n description: ReactNode;\n apiExample: ReactNode;\n apiPlayground: ReactNode;\n\n authSchemes: ReactNode;\n parameters: ReactNode;\n body: ReactNode;\n responses: ReactNode;\n callbacks: ReactNode;\n },\n ctx: RenderContext,\n method: NoReference<MethodInformation>,\n ) => ReactNode;\n\n renderWebhookLayout?: (slots: {\n header: ReactNode;\n description: ReactNode;\n authSchemes: ReactNode;\n parameters: ReactNode;\n body: ReactNode;\n requests: ReactNode;\n responses: ReactNode;\n callbacks: ReactNode;\n }) => ReactNode;\n };\n\n /**\n * Info UI for JSON schemas\n */\n schemaUI?: {\n render?: (options: SchemaUIOptions, ctx: RenderContext) => ReactNode;\n\n /**\n * Show examples under the generated content of JSON schemas.\n *\n * @defaultValue false\n */\n showExample?: boolean;\n };\n\n /**\n * Customise API playground\n */\n playground?: {\n /**\n * @defaultValue true\n */\n enabled?: boolean;\n /**\n * replace the server-side renderer\n */\n render?: (props: {\n path: string;\n method: MethodInformation;\n ctx: RenderContext;\n }) => Awaitable<ReactNode>;\n };\n\n renderHeading?: (props: HTMLAttributes<HTMLHeadingElement>, depth: number) => ReactNode;\n renderCodeBlock?: (props: { lang: string; code: string }) => ReactNode;\n\n client?: APIPageClientOptions;\n}\n\nexport interface ServerApiPageProps extends Omit<ApiPageProps, 'document'> {\n document: string | ProcessedDocument;\n}\n\nexport function createAPIPage(\n server: OpenAPIServer,\n options: CreateAPIPageOptions,\n): FC<ServerApiPageProps> {\n let processor: ReturnType<typeof createMarkdownProcessor>;\n\n function createMarkdownProcessor() {\n function rehypeReact(this: any) {\n this.compiler = (tree: any, file: any) => {\n return toJsxRuntime(tree, {\n development: false,\n filePath: file.path,\n ...JsxRuntime,\n components: defaultMdxComponents,\n });\n };\n }\n\n return remark()\n .use(remarkGfm)\n .use(remarkRehype)\n .use(createRehypeCode(options.shiki), {\n langs: [],\n lazy: true,\n defaultColor: false,\n ...options.shikiOptions,\n })\n .use(rehypeReact);\n }\n\n return async function APIPageWrapper({ document, ...props }) {\n let processed: ProcessedDocument;\n if (typeof document === 'string') {\n processed = await server.getSchema(document);\n } else {\n processed = document;\n }\n\n const slugger = new Slugger();\n\n const ctx: RenderContext = {\n schema: processed,\n proxyUrl: server.options.proxyUrl,\n ...options,\n mediaAdapters: {\n ...defaultAdapters,\n ...options.mediaAdapters,\n },\n renderHeading(depth, text, props) {\n const id = typeof text === 'string' ? slugger.slug(text) : props?.id;\n if (!id) throw new Error(\"missing 'id' for non-string children\");\n\n if (options.renderHeading) {\n return options.renderHeading({ id, children: text, ...props }, depth);\n }\n\n return (\n <Heading id={id} key={id} as={`h${depth}` as `h1`} {...props}>\n {text}\n </Heading>\n );\n },\n generateTypeScriptDefinitions:\n options.generateTypeScriptDefinitions ??\n ((schema, ctx) => {\n if (options.generateTypeScriptSchema && ctx._internal_legacy) {\n const { statusCode, contentType } = ctx._internal_legacy;\n return options.generateTypeScriptSchema(ctx.operation, statusCode, contentType, ctx);\n }\n\n if (typeof schema !== 'object') return;\n try {\n return compile(schema, {\n name: 'Response',\n readOnly: ctx.readOnly,\n writeOnly: ctx.writeOnly,\n getSchemaId: ctx.schema.getRawRef,\n });\n } catch (e) {\n console.warn('Failed to generate typescript schema:', e);\n }\n }),\n async renderMarkdown(text) {\n if (options.renderMarkdown) return options.renderMarkdown(text);\n processor ??= createMarkdownProcessor();\n\n const out = await processor.process({\n value: text,\n });\n\n return out.result as ReactNode;\n },\n async renderCodeBlock(lang, code) {\n if (options.renderCodeBlock) {\n return options.renderCodeBlock({ lang, code });\n }\n\n const hast = await highlightHast(await options.shiki.getOrInit(), code, {\n lang,\n defaultColor: false,\n ...options.shikiOptions,\n });\n const rendered = toJsxRuntime(hast, {\n ...JsxRuntime,\n components: {\n pre: Pre,\n },\n });\n\n return <CodeBlock className=\"my-0\">{rendered}</CodeBlock>;\n },\n };\n\n return <APIPage {...props} ctx={ctx} />;\n };\n}\n\nexport { ClientCodeBlockProvider } from './components/codeblock';\n"],"mappings":";;;;;;;;;;;;;;;;;AAuNA,SAAgB,cACd,QACA,SACwB;CACxB,IAAI;CAEJ,SAAS,0BAA0B;EACjC,SAAS,cAAuB;AAC9B,QAAK,YAAY,MAAW,SAAc;AACxC,WAAO,aAAa,MAAM;KACxB,aAAa;KACb,UAAU,KAAK;KACf,GAAG;KACH,YAAY;KACb,CAAC;;;AAIN,SAAO,QAAQ,CACZ,IAAI,UAAU,CACd,IAAI,aAAa,CACjB,IAAI,iBAAiB,QAAQ,MAAM,EAAE;GACpC,OAAO,EAAE;GACT,MAAM;GACN,cAAc;GACd,GAAG,QAAQ;GACZ,CAAC,CACD,IAAI,YAAY;;AAGrB,QAAO,eAAe,eAAe,EAAE,UAAU,GAAG,SAAS;EAC3D,IAAI;AACJ,MAAI,OAAO,aAAa,SACtB,aAAY,MAAM,OAAO,UAAU,SAAS;MAE5C,aAAY;EAGd,MAAM,UAAU,IAAI,SAAS;EAE7B,MAAM,MAAqB;GACzB,QAAQ;GACR,UAAU,OAAO,QAAQ;GACzB,GAAG;GACH,eAAe;IACb,GAAG;IACH,GAAG,QAAQ;IACZ;GACD,cAAc,OAAO,MAAM,OAAO;IAChC,MAAM,KAAK,OAAO,SAAS,WAAW,QAAQ,KAAK,KAAK,GAAG,OAAO;AAClE,QAAI,CAAC,GAAI,OAAM,IAAI,MAAM,uCAAuC;AAEhE,QAAI,QAAQ,cACV,QAAO,QAAQ,cAAc;KAAE;KAAI,UAAU;KAAM,GAAG;KAAO,EAAE,MAAM;AAGvE,WACE,oBAAC,SAAD;KAAa;KAAa,IAAI,IAAI;KAAiB,GAAI;eACpD;KACO,EAFY,GAEZ;;GAGd,+BACE,QAAQ,mCACN,QAAQ,QAAQ;AAChB,QAAI,QAAQ,4BAA4B,IAAI,kBAAkB;KAC5D,MAAM,EAAE,YAAY,gBAAgB,IAAI;AACxC,YAAO,QAAQ,yBAAyB,IAAI,WAAW,YAAY,aAAa,IAAI;;AAGtF,QAAI,OAAO,WAAW,SAAU;AAChC,QAAI;AACF,YAAO,QAAQ,QAAQ;MACrB,MAAM;MACN,UAAU,IAAI;MACd,WAAW,IAAI;MACf,aAAa,IAAI,OAAO;MACzB,CAAC;aACK,GAAG;AACV,aAAQ,KAAK,yCAAyC,EAAE;;;GAG9D,MAAM,eAAe,MAAM;AACzB,QAAI,QAAQ,eAAgB,QAAO,QAAQ,eAAe,KAAK;AAC/D,kBAAc,yBAAyB;AAMvC,YAJY,MAAM,UAAU,QAAQ,EAClC,OAAO,MACR,CAAC,EAES;;GAEb,MAAM,gBAAgB,MAAM,MAAM;AAChC,QAAI,QAAQ,gBACV,QAAO,QAAQ,gBAAgB;KAAE;KAAM;KAAM,CAAC;AAehD,WAAO,oBAAC,WAAD;KAAW,WAAU;eAPX,aALJ,MAAM,cAAc,MAAM,QAAQ,MAAM,WAAW,EAAE,MAAM;MACtE;MACA,cAAc;MACd,GAAG,QAAQ;MACZ,CAAC,EACkC;MAClC,GAAG;MACH,YAAY,EACV,KAAK,KACN;MACF,CAAC;KAEuD,CAAA;;GAE5D;AAED,SAAO,oBAAC,SAAD;GAAS,GAAI;GAAY;GAAO,CAAA"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { ClientCodeBlockProvider } from "
|
|
2
|
+
import { ClientCodeBlockProvider } from "../components/codeblock.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { defaultShikiFactory } from "fumadocs-core/highlight/shiki/full";
|
|
5
|
-
//#region src/ui/full.
|
|
5
|
+
//#region src/ui/client/full.tsx
|
|
6
6
|
function FullProvider({ children }) {
|
|
7
7
|
return /* @__PURE__ */ jsx(ClientCodeBlockProvider, {
|
|
8
8
|
factory: defaultShikiFactory,
|
|
@@ -12,4 +12,4 @@ function FullProvider({ children }) {
|
|
|
12
12
|
//#endregion
|
|
13
13
|
export { FullProvider };
|
|
14
14
|
|
|
15
|
-
//# sourceMappingURL=full.
|
|
15
|
+
//# sourceMappingURL=full.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full.js","names":[],"sources":["../../../src/ui/client/full.tsx"],"sourcesContent":["'use client';\nimport type { ReactNode } from 'react';\nimport { ClientCodeBlockProvider } from '../components/codeblock';\nimport { defaultShikiFactory } from 'fumadocs-core/highlight/shiki/full';\n\nexport function FullProvider({ children }: { children: ReactNode }) {\n return (\n <ClientCodeBlockProvider factory={defaultShikiFactory}>{children}</ClientCodeBlockProvider>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,aAAa,EAAE,YAAqC;AAClE,QACE,oBAAC,yBAAD;EAAyB,SAAS;EAAsB;EAAmC,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MediaAdapter } from "../../requests/media/adapter.js";
|
|
2
2
|
import { CodeUsageGeneratorRegistry } from "../../requests/generators/index.js";
|
|
3
3
|
import { PlaygroundClientOptions } from "../../playground/client.js";
|
|
4
|
-
import { ExampleRequestItem } from "../operation/
|
|
4
|
+
import { ExampleRequestItem } from "../operation/get-example-requests.js";
|
|
5
5
|
import { FC } from "react";
|
|
6
6
|
|
|
7
7
|
//#region src/ui/client/index.d.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/ui/client/index.tsx"],"sourcesContent":["'use client';\nimport type { PlaygroundClientOptions } from '@/playground/client';\nimport type { MediaAdapter } from '@/requests/media/adapter';\nimport type { FC } from 'react';\nimport type {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/ui/client/index.tsx"],"sourcesContent":["'use client';\nimport type { PlaygroundClientOptions } from '@/playground/client';\nimport type { MediaAdapter } from '@/requests/media/adapter';\nimport type { FC } from 'react';\nimport type { CodeUsageGeneratorRegistry } from '@/requests/generators';\nimport type { ExampleRequestItem } from '../operation/get-example-requests';\n\nexport interface APIPageClientOptions {\n playground?: PlaygroundClientOptions;\n operation?: OperationClientOptions;\n\n /**\n * Set a prefix for `localStorage` keys.\n *\n * Useful when using multiple OpenAPI instances to prevent state conflicts.\n *\n * @defaultValue `fumadocs-openapi-`\n */\n storageKeyPrefix?: string;\n\n /**\n * Support other media types (for client-side serialization)\n */\n mediaAdapters?: Record<string, MediaAdapter>;\n\n /**\n * generate code usage examples\n */\n codeUsages?: CodeUsageGeneratorRegistry;\n}\n\nexport interface OperationClientOptions {\n APIExampleSelector?: FC<{\n items: ExampleRequestItem[];\n\n value: string | undefined;\n onValueChange: (id: string) => void;\n }>;\n}\n\nexport function defineClientConfig(options: APIPageClientOptions = {}): APIPageClientOptions {\n return options;\n}\n"],"mappings":";;AAwCA,SAAgB,mBAAmB,UAAgC,EAAE,EAAwB;AAC3F,QAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-key.js","names":[],"sources":["../../../src/ui/client/storage-key.ts"],"sourcesContent":["import type { AuthField } from '@/playground/client';\nimport { useApiContext } from '../contexts/api';\nimport { useMemo } from 'react';\n\ntype KeyName = 'server-url' | `auth-${string}`;\n\nexport function useStorageKey() {\n const { storageKeyPrefix } = useApiContext().client;\n\n return useMemo(\n () => ({\n of: (name: KeyName) => getStorageKey(storageKeyPrefix, name),\n AuthField: (field: AuthField) =>\n getStorageKey(storageKeyPrefix, `auth-${field.original?.id ?? field.fieldName}`),\n }),\n [storageKeyPrefix],\n );\n}\n\
|
|
1
|
+
{"version":3,"file":"storage-key.js","names":[],"sources":["../../../src/ui/client/storage-key.ts"],"sourcesContent":["import type { AuthField } from '@/playground/client';\nimport { useApiContext } from '../contexts/api';\nimport { useMemo } from 'react';\n\ntype KeyName = 'server-url' | `auth-${string}`;\n\nexport function useStorageKey() {\n const { storageKeyPrefix } = useApiContext().client;\n\n return useMemo(\n () => ({\n of: (name: KeyName) => getStorageKey(storageKeyPrefix, name),\n AuthField: (field: AuthField) =>\n getStorageKey(storageKeyPrefix, `auth-${field.original?.id ?? field.fieldName}`),\n }),\n [storageKeyPrefix],\n );\n}\n\nfunction getStorageKey(prefix = 'fumadocs-openapi-', name: KeyName) {\n return prefix + name;\n}\n"],"mappings":";;;AAMA,SAAgB,gBAAgB;CAC9B,MAAM,EAAE,qBAAqB,eAAe,CAAC;AAE7C,QAAO,eACE;EACL,KAAK,SAAkB,cAAc,kBAAkB,KAAK;EAC5D,YAAY,UACV,cAAc,kBAAkB,QAAQ,MAAM,UAAU,MAAM,MAAM,YAAY;EACnF,GACD,CAAC,iBAAiB,CACnB;;AAGH,SAAS,cAAc,SAAS,qBAAqB,MAAe;AAClE,QAAO,SAAS"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
3
|
import { ShikiFactory } from "fumadocs-core/highlight/shiki";
|
|
4
4
|
|
|
5
5
|
//#region src/ui/components/codeblock.d.ts
|
|
@@ -9,7 +9,7 @@ declare function ClientCodeBlockProvider({
|
|
|
9
9
|
}: {
|
|
10
10
|
factory: ShikiFactory;
|
|
11
11
|
children: ReactNode;
|
|
12
|
-
}): react_jsx_runtime0.JSX.Element;
|
|
12
|
+
}): _$react_jsx_runtime0.JSX.Element;
|
|
13
13
|
//#endregion
|
|
14
14
|
export { ClientCodeBlockProvider };
|
|
15
15
|
//# sourceMappingURL=codeblock.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codeblock.d.ts","names":[],"sources":["../../../src/ui/components/codeblock.tsx"],"mappings":";;;;;iBAsBgB,uBAAA,CAAA;EACd,OAAA;EACA;AAAA;EAEA,OAAA,EAAS,YAAA;EACT,QAAA,EAAU,SAAA;AAAA,IACX,
|
|
1
|
+
{"version":3,"file":"codeblock.d.ts","names":[],"sources":["../../../src/ui/components/codeblock.tsx"],"mappings":";;;;;iBAsBgB,uBAAA,CAAA;EACd,OAAA;EACA;AAAA;EAEA,OAAA,EAAS,YAAA;EACT,QAAA,EAAU,SAAA;AAAA,IACX,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select.js";
|
|
4
|
+
import { createContext, use, useMemo, useState } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/ui/components/server-tab.tsx
|
|
7
|
+
const Context = createContext(null);
|
|
8
|
+
function SelectTabs({ defaultValue, children }) {
|
|
9
|
+
const [type, setType] = useState(defaultValue ?? null);
|
|
10
|
+
return /* @__PURE__ */ jsx(Context, {
|
|
11
|
+
value: useMemo(() => ({
|
|
12
|
+
type,
|
|
13
|
+
setType
|
|
14
|
+
}), [type]),
|
|
15
|
+
children
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function SelectTab({ value, ...props }) {
|
|
19
|
+
if (value !== use(Context)?.type) return;
|
|
20
|
+
return /* @__PURE__ */ jsx("div", {
|
|
21
|
+
...props,
|
|
22
|
+
children: props.children
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function SelectTabTrigger({ items, className, ...props }) {
|
|
26
|
+
const { type, setType } = use(Context);
|
|
27
|
+
return /* @__PURE__ */ jsxs(Select, {
|
|
28
|
+
value: type ?? "",
|
|
29
|
+
onValueChange: setType,
|
|
30
|
+
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
31
|
+
className: cn("not-prose w-fit min-w-0 *:min-w-0", className),
|
|
32
|
+
...props,
|
|
33
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
34
|
+
}), /* @__PURE__ */ jsx(SelectContent, { children: items.map(({ label, value }) => /* @__PURE__ */ jsx(SelectItem, {
|
|
35
|
+
value,
|
|
36
|
+
children: label
|
|
37
|
+
}, value)) })]
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { SelectTab, SelectTabTrigger, SelectTabs };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=server-tab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-tab.js","names":[],"sources":["../../../src/ui/components/server-tab.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@/utils/cn';\nimport { SelectTrigger, Select, SelectValue, SelectContent, SelectItem } from './select';\nimport { type ReactNode, useState, useMemo, type ComponentProps, createContext, use } from 'react';\n\nconst Context = createContext<{\n type: string | null;\n setType: (type: string) => void;\n} | null>(null);\n\nexport function SelectTabs({\n defaultValue,\n children,\n}: {\n defaultValue?: string;\n children: ReactNode;\n}) {\n const [type, setType] = useState<string | null>(defaultValue ?? null);\n\n return <Context value={useMemo(() => ({ type, setType }), [type])}>{children}</Context>;\n}\n\nexport function SelectTab({\n value,\n ...props\n}: ComponentProps<'div'> & {\n value: string;\n}) {\n const ctx = use(Context);\n if (value !== ctx?.type) return;\n\n return <div {...props}>{props.children}</div>;\n}\n\nexport function SelectTabTrigger({\n items,\n className,\n ...props\n}: ComponentProps<typeof SelectTrigger> & {\n items: {\n label: ReactNode;\n value: string;\n }[];\n}) {\n const { type, setType } = use(Context)!;\n\n return (\n <Select value={type ?? ''} onValueChange={setType}>\n <SelectTrigger className={cn('not-prose w-fit min-w-0 *:min-w-0', className)} {...props}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {items.map(({ label, value }) => (\n <SelectItem key={value} value={value}>\n {label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":";;;;;;AAMA,MAAM,UAAU,cAGN,KAAK;AAEf,SAAgB,WAAW,EACzB,cACA,YAIC;CACD,MAAM,CAAC,MAAM,WAAW,SAAwB,gBAAgB,KAAK;AAErE,QAAO,oBAAC,SAAD;EAAS,OAAO,eAAe;GAAE;GAAM;GAAS,GAAG,CAAC,KAAK,CAAC;EAAG;EAAmB,CAAA;;AAGzF,SAAgB,UAAU,EACxB,OACA,GAAG,SAGF;AAED,KAAI,UADQ,IAAI,QAAQ,EACL,KAAM;AAEzB,QAAO,oBAAC,OAAD;EAAK,GAAI;YAAQ,MAAM;EAAe,CAAA;;AAG/C,SAAgB,iBAAiB,EAC/B,OACA,WACA,GAAG,SAMF;CACD,MAAM,EAAE,MAAM,YAAY,IAAI,QAAQ;AAEtC,QACE,qBAAC,QAAD;EAAQ,OAAO,QAAQ;EAAI,eAAe;YAA1C,CACE,oBAAC,eAAD;GAAe,WAAW,GAAG,qCAAqC,UAAU;GAAE,GAAI;aAChF,oBAAC,aAAD,EAAe,CAAA;GACD,CAAA,EAChB,oBAAC,eAAD,EAAA,UACG,MAAM,KAAK,EAAE,OAAO,YACnB,oBAAC,YAAD;GAA+B;aAC5B;GACU,EAFI,MAEJ,CACb,EACY,CAAA,CACT"}
|