mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
OpenAPI: Support integration with Fumadocs Source API
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-openapi': minor
|
||||
---
|
||||
|
||||
Support integration with Fumadocs Source API
|
||||
@@ -56,7 +56,36 @@ node ./scripts/generate-docs.mjs
|
||||
|
||||
Fumadocs OpenAPI generates MDX content directly, you can use a formatter (e.g. Prettier) to format the output files.
|
||||
|
||||
### Features
|
||||
### Generate Page Tree
|
||||
|
||||
You can add the `attachFile` to decorate the page tree with Source API.
|
||||
|
||||
It adds a badge to each page item.
|
||||
|
||||
```ts title="source.ts"
|
||||
import { createMDXSource, defaultSchemas } from 'fumadocs-mdx';
|
||||
import { z } from 'zod';
|
||||
import { loader } from 'fumadocs-core/source';
|
||||
import { attachFile } from 'fumadocs-openapi/source';
|
||||
|
||||
const frontmatter = defaultSchemas.frontmatter.extend({
|
||||
method: z.string().optional(),
|
||||
});
|
||||
|
||||
export const utils = loader({
|
||||
source: createMDXSource(map, {
|
||||
schema: {
|
||||
frontmatter,
|
||||
},
|
||||
}),
|
||||
pageTree: {
|
||||
attachFile,
|
||||
},
|
||||
// other props
|
||||
});
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
The official OpenAPI integration supports:
|
||||
|
||||
@@ -86,10 +115,32 @@ Path to the output directory.
|
||||
|
||||
Customise how the page is generated, default to `file`.
|
||||
|
||||
| mode | description |
|
||||
| ---- | ------------------------------- |
|
||||
| tag | Generate a page for each tag |
|
||||
| file | Generate a page for each schema |
|
||||
| mode | Generate a page for |
|
||||
| --------- | ----------------------------------- |
|
||||
| tag | each tag |
|
||||
| file | each schema |
|
||||
| operation | each operation (method of endpoint) |
|
||||
|
||||
```ts
|
||||
import { generateFiles } from 'fumadocs-openapi';
|
||||
|
||||
void generateFiles({
|
||||
per: 'tag',
|
||||
});
|
||||
```
|
||||
|
||||
### Group By Folder
|
||||
|
||||
In `operation` mode, you can group operations with folders.
|
||||
|
||||
```ts
|
||||
import { generateFiles } from 'fumadocs-openapi';
|
||||
|
||||
void generateFiles({
|
||||
per: 'operation',
|
||||
groupByFolder: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Name
|
||||
|
||||
@@ -99,8 +150,9 @@ A function that controls the output path of files.
|
||||
import { generateFiles } from 'fumadocs-openapi';
|
||||
|
||||
void generateFiles({
|
||||
input: ['./petstore.yaml'],
|
||||
output: './content/docs',
|
||||
name: (type, file) => {
|
||||
return; // filename
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
@@ -127,7 +179,16 @@ void generateFiles({
|
||||
### Frontmatter
|
||||
|
||||
Customise the frontmatter of MDX files.
|
||||
By default, it includes a `full: true` property for Fumadocs UI.
|
||||
|
||||
By default, it includes:
|
||||
|
||||
| property | description |
|
||||
| ------------- | ------------------------------------------------ |
|
||||
| `title` | Page title |
|
||||
| `description` | Page description |
|
||||
| `full` | Always true, added for Fumadocs UI |
|
||||
| `method` | Available method of operation (`operation` mode) |
|
||||
| `route` | Route of operation (`operation` mode) |
|
||||
|
||||
```ts
|
||||
import { generateFiles } from 'fumadocs-openapi';
|
||||
|
||||
@@ -3,9 +3,9 @@ import { z } from 'zod';
|
||||
import type { InferMetaType, InferPageType } from 'fumadocs-core/source';
|
||||
import { loader } from 'fumadocs-core/source';
|
||||
import { icons } from 'lucide-react';
|
||||
import { attachFile } from 'fumadocs-openapi/source';
|
||||
import { map } from '@/.map';
|
||||
import { create } from '@/components/ui/icon';
|
||||
import { ApiIndicator } from '@/components/ui/api-indicator';
|
||||
|
||||
const frontmatter = defaultSchemas.frontmatter.extend({
|
||||
preview: z.string().optional(),
|
||||
@@ -29,18 +29,7 @@ export const utils = loader({
|
||||
},
|
||||
}),
|
||||
pageTree: {
|
||||
attachFile(node, file) {
|
||||
if (!file) return node;
|
||||
const data = file.data.data as z.output<typeof frontmatter>;
|
||||
if (!data.full) return node;
|
||||
|
||||
node.name = [
|
||||
node.name,
|
||||
' ',
|
||||
ApiIndicator({ method: data.method ?? 'API' }),
|
||||
];
|
||||
return node;
|
||||
},
|
||||
attachFile,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
"./ui": {
|
||||
"import": "./dist/ui/index.js",
|
||||
"types": "./dist/ui/index.d.ts"
|
||||
},
|
||||
"./source": {
|
||||
"import": "./dist/source/index.js",
|
||||
"types": "./dist/source/index.d.ts"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
@@ -30,6 +34,9 @@
|
||||
],
|
||||
"ui": [
|
||||
"./dist/ui/index.d.ts"
|
||||
],
|
||||
"source": [
|
||||
"./dist/source/index.d.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import React from 'react';
|
||||
import type { BuildPageTreeOptions } from 'fumadocs-core/source';
|
||||
import { type ReactNode } from 'react';
|
||||
import { cva } from 'class-variance-authority';
|
||||
import { getBadgeColor } from '@/ui/shared';
|
||||
|
||||
/**
|
||||
* Source API Integration
|
||||
*
|
||||
* Add this to page tree builder options
|
||||
*/
|
||||
export const attachFile: BuildPageTreeOptions['attachFile'] = (node, file) => {
|
||||
if (!file) return node;
|
||||
const data = file.data.data as object;
|
||||
|
||||
if ('method' in data && typeof data.method === 'string') {
|
||||
node.name = [node.name, ' ', ApiIndicator({ method: data.method })];
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
const badgeVariants = cva('rounded-full border px-1.5 text-xs font-medium', {
|
||||
variants: {
|
||||
color: {
|
||||
green: 'bg-green-400/20 text-green-600 dark:text-green-400',
|
||||
yellow: 'bg-yellow-400/20 text-yellow-600 dark:text-yellow-400',
|
||||
red: 'bg-red-400/20 text-red-600 dark:text-red-400',
|
||||
blue: 'bg-blue-400/20 text-blue-600 dark:text-blue-400',
|
||||
orange: 'bg-orange-400/20 text-orange-600 dark:text-orange-400',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
function ApiIndicator({ method }: { method: string }): ReactNode {
|
||||
const color = getBadgeColor(method);
|
||||
|
||||
return React.createElement(
|
||||
'span',
|
||||
{
|
||||
className: badgeVariants({ className: 'ms-auto', color }),
|
||||
},
|
||||
method,
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['./src/index.ts', './src/ui/index.ts'],
|
||||
entry: ['./src/index.ts', './src/ui/index.ts', './src/source/index.ts'],
|
||||
format: 'esm',
|
||||
dts: true,
|
||||
target: 'es2022',
|
||||
|
||||
Reference in New Issue
Block a user