fumadocs-openapi 4.4.2 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,91 @@
1
+ 'use client';
2
+ import { useContext, createContext, useState, useEffect } from 'react';
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { Check, Copy } from 'lucide-react';
5
+ import { cn, useCopyButton, buttonVariants } from 'fumadocs-ui/components/api';
6
+
7
+ const ApiContext = /*#__PURE__*/ createContext({
8
+ baseUrl: undefined,
9
+ setBaseUrl: ()=>undefined,
10
+ highlighter: null
11
+ });
12
+ function useApiContext() {
13
+ return useContext(ApiContext);
14
+ }
15
+ async function initHighlighter() {
16
+ const { createHighlighterCore } = await import('shiki/core');
17
+ const getWasm = await import('shiki/wasm');
18
+ return createHighlighterCore({
19
+ themes: [
20
+ import('shiki/themes/github-light.mjs'),
21
+ import('shiki/themes/github-dark.mjs')
22
+ ],
23
+ langs: [
24
+ import('shiki/langs/json.mjs')
25
+ ],
26
+ loadWasm: getWasm
27
+ });
28
+ }
29
+ function ApiProvider({ defaultBaseUrl, children }) {
30
+ const [highlighter, setHighlighter] = useState(null);
31
+ const [baseUrl, setBaseUrl] = useState(defaultBaseUrl);
32
+ useEffect(()=>{
33
+ setBaseUrl((prev)=>localStorage.getItem('apiBaseUrl') ?? prev);
34
+ void initHighlighter().then((res)=>{
35
+ setHighlighter(res);
36
+ });
37
+ }, []);
38
+ useEffect(()=>{
39
+ if (baseUrl) localStorage.setItem('apiBaseUrl', baseUrl);
40
+ }, [
41
+ baseUrl
42
+ ]);
43
+ return /*#__PURE__*/ jsx(ApiContext.Provider, {
44
+ value: {
45
+ baseUrl,
46
+ setBaseUrl,
47
+ highlighter
48
+ },
49
+ children: children
50
+ });
51
+ }
52
+
53
+ const SchemaContext = /*#__PURE__*/ createContext(undefined);
54
+ function useSchemaContext() {
55
+ const ctx = useContext(SchemaContext);
56
+ if (!ctx) throw new Error('Missing provider');
57
+ return ctx;
58
+ }
59
+
60
+ function Root({ children, baseUrl, className, ...props }) {
61
+ return /*#__PURE__*/ jsx("div", {
62
+ className: cn('flex flex-col gap-24 text-sm text-fd-muted-foreground', className),
63
+ ...props,
64
+ children: /*#__PURE__*/ jsx(ApiProvider, {
65
+ defaultBaseUrl: baseUrl,
66
+ children: children
67
+ })
68
+ });
69
+ }
70
+ function CopyRouteButton({ className, route, ...props }) {
71
+ const { baseUrl } = useApiContext();
72
+ const [checked, onCopy] = useCopyButton(()=>{
73
+ void navigator.clipboard.writeText(`${baseUrl ?? ''}${route}`);
74
+ });
75
+ return /*#__PURE__*/ jsx("button", {
76
+ type: "button",
77
+ className: cn(buttonVariants({
78
+ color: 'ghost',
79
+ className
80
+ })),
81
+ onClick: onCopy,
82
+ ...props,
83
+ children: checked ? /*#__PURE__*/ jsx(Check, {
84
+ className: "size-3"
85
+ }) : /*#__PURE__*/ jsx(Copy, {
86
+ className: "size-3"
87
+ })
88
+ });
89
+ }
90
+
91
+ export { CopyRouteButton as C, Root as R, SchemaContext as S, useApiContext as a, useSchemaContext as u };
@@ -1,8 +1,78 @@
1
1
  import * as react from 'react';
2
- import { ReactElement, HTMLAttributes, ReactNode, MutableRefObject } from 'react';
2
+ import { ReactNode, ReactElement, MutableRefObject, HTMLAttributes } from 'react';
3
3
  import { FieldPath, ControllerRenderProps, ControllerFieldState, UseFormStateReturn } from 'react-hook-form';
4
- import { R as RequestSchema, a as ReferenceSchema, A as APIPlaygroundProps, P as PrimitiveRequestField } from '../playground-vSsfCaVw.js';
5
- import { Tabs, Tab } from 'fumadocs-ui/components/tabs';
4
+
5
+ interface APIInfoProps {
6
+ method: string;
7
+ route: string;
8
+ children: ReactNode;
9
+ }
10
+ interface PropertyProps {
11
+ name: string;
12
+ type: string;
13
+ required?: boolean;
14
+ deprecated?: boolean;
15
+ children?: ReactNode;
16
+ }
17
+ interface RootProps {
18
+ baseUrl?: string;
19
+ children: ReactNode;
20
+ }
21
+
22
+ interface BaseRequestField {
23
+ name: string;
24
+ description?: string;
25
+ }
26
+ interface BaseSchema {
27
+ description?: string;
28
+ isRequired: boolean;
29
+ }
30
+ type PrimitiveRequestField = BaseRequestField & PrimitiveSchema;
31
+ interface PrimitiveSchema extends BaseSchema {
32
+ type: 'boolean' | 'string' | 'number';
33
+ defaultValue: string;
34
+ }
35
+ interface ReferenceSchema extends BaseSchema {
36
+ type: 'ref';
37
+ schema: string;
38
+ }
39
+ interface ArraySchema extends BaseSchema {
40
+ type: 'array';
41
+ /**
42
+ * Reference to item schema or the schema
43
+ */
44
+ items: string | RequestSchema;
45
+ }
46
+ interface FileSchema extends BaseSchema {
47
+ type: 'file';
48
+ }
49
+ interface ObjectSchema extends BaseSchema {
50
+ type: 'object';
51
+ properties: Record<string, ReferenceSchema>;
52
+ /**
53
+ * Reference to schema, or true if it's `any`
54
+ */
55
+ additionalProperties?: boolean | string;
56
+ }
57
+ interface SwitcherSchema extends BaseSchema {
58
+ type: 'switcher';
59
+ items: Record<string, ReferenceSchema | RequestSchema>;
60
+ }
61
+ interface NullSchema extends BaseSchema {
62
+ type: 'null';
63
+ }
64
+ type RequestSchema = PrimitiveSchema | ArraySchema | ObjectSchema | SwitcherSchema | NullSchema | FileSchema;
65
+ interface APIPlaygroundProps {
66
+ route: string;
67
+ method: string;
68
+ bodyType: 'json' | 'form-data';
69
+ authorization?: PrimitiveRequestField;
70
+ path?: PrimitiveRequestField[];
71
+ query?: PrimitiveRequestField[];
72
+ header?: PrimitiveRequestField[];
73
+ body?: RequestSchema;
74
+ schemas: Record<string, RequestSchema>;
75
+ }
6
76
 
7
77
  interface FormValues {
8
78
  authorization: string;
@@ -23,40 +93,6 @@ interface CustomField<TName extends FieldPath<FormValues>, Info> {
23
93
  }) => ReactElement;
24
94
  }
25
95
 
26
- interface RootProps extends HTMLAttributes<HTMLDivElement> {
27
- baseUrl?: string;
28
- }
29
- declare function Root({ children, baseUrl, className, ...props }: RootProps): React.ReactElement;
30
- declare function API({ className, children, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement;
31
- interface APIInfoProps extends HTMLAttributes<HTMLDivElement> {
32
- route: string;
33
- method?: string;
34
- badgeClassName?: string;
35
- }
36
- declare function APIInfo({ children, className, route, badgeClassName, method, ...props }: APIInfoProps): React.ReactElement;
37
- interface PropertyProps {
38
- name: string;
39
- type: string;
40
- required: boolean;
41
- deprecated: boolean;
42
- children: ReactNode;
43
- }
44
- declare function Property({ name, type, required, deprecated, children, }: PropertyProps): React.ReactElement;
45
- declare function APIExample({ children, className, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement;
46
- declare function ResponseTypes(props: {
47
- children: ReactNode;
48
- }): React.ReactElement;
49
- declare function ExampleResponse(props: {
50
- children: ReactNode;
51
- }): React.ReactElement;
52
- declare function TypeScriptResponse(props: {
53
- children: ReactNode;
54
- }): React.ReactElement;
55
- declare function ObjectCollapsible(props: {
56
- name: string;
57
- children: ReactNode;
58
- }): React.ReactElement;
59
-
60
96
  interface SchemaContextType {
61
97
  references: Record<string, RequestSchema>;
62
98
  dynamic: MutableRefObject<Map<string, DynamicField>>;
@@ -70,6 +106,8 @@ type DynamicField = {
70
106
  };
71
107
  declare function useSchemaContext(): SchemaContextType;
72
108
 
109
+ declare function Root({ children, baseUrl, className, ...props }: RootProps & HTMLAttributes<HTMLDivElement>): React.ReactElement;
110
+
73
111
  declare const APIPlayground: react.ComponentType<APIPlaygroundProps & {
74
112
  fields?: {
75
113
  auth?: CustomField<"authorization", PrimitiveRequestField>;
@@ -78,10 +116,16 @@ declare const APIPlayground: react.ComponentType<APIPlaygroundProps & {
78
116
  header?: CustomField<`header.${string}`, PrimitiveRequestField>;
79
117
  body?: CustomField<"body", RequestSchema>;
80
118
  };
81
- } & react.HTMLAttributes<HTMLFormElement>>;
82
- declare const Responses: typeof Tabs;
83
- declare const Response: typeof Tab;
84
- declare const Requests: typeof Tabs;
85
- declare const Request: typeof Tab;
119
+ } & HTMLAttributes<HTMLFormElement>>;
120
+ declare function APIInfo({ children, className, route, badgeClassname, method, ...props }: APIInfoProps & HTMLAttributes<HTMLDivElement> & {
121
+ badgeClassname?: string;
122
+ }): React.ReactElement;
123
+ declare function API({ className, children, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement;
124
+ declare function Property({ name, type, required, deprecated, children, }: PropertyProps): React.ReactElement;
125
+ declare function APIExample({ children, className, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement;
126
+ declare function ObjectCollapsible(props: {
127
+ name: string;
128
+ children: ReactNode;
129
+ }): React.ReactElement;
86
130
 
87
- export { API, APIExample, APIInfo, type APIInfoProps, APIPlayground, ExampleResponse, ObjectCollapsible, Property, Request, Requests, Response, ResponseTypes, Responses, Root, type RootProps, TypeScriptResponse, useSchemaContext };
131
+ export { API, APIExample, APIInfo, APIPlayground, ObjectCollapsible, Property, Root, useSchemaContext };
package/dist/ui/index.js CHANGED
@@ -1,201 +1,144 @@
1
- "use client";
2
- import {
3
- ApiProvider,
4
- useApiContext,
5
- useSchemaContext
6
- } from "../chunk-N4P4W4VJ.js";
7
- import {
8
- badgeVariants,
9
- getBadgeColor
10
- } from "../chunk-UG2WFM5D.js";
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import dynamic from 'next/dynamic';
3
+ import { cn } from 'fumadocs-ui/components/api';
4
+ import { Fragment } from 'react';
5
+ import { Accordions, Accordion } from 'fumadocs-ui/components/accordion';
6
+ import { cva } from 'class-variance-authority';
7
+ import { C as CopyRouteButton } from './client-client-CbQJObP6.js';
8
+ export { R as Root, u as useSchemaContext } from './client-client-CbQJObP6.js';
11
9
 
12
- // src/ui/index.ts
13
- import { Tab, Tabs } from "fumadocs-ui/components/tabs";
14
- import dynamic from "next/dynamic";
15
-
16
- // src/ui/components.tsx
17
- import {
18
- Fragment
19
- } from "react";
20
- import { Check, Copy } from "lucide-react";
21
- import { Accordion, Accordions } from "fumadocs-ui/components/accordion";
22
- import { cn, useCopyButton, buttonVariants } from "fumadocs-ui/components/api";
23
- import { jsx, jsxs } from "react/jsx-runtime";
24
- function Root({
25
- children,
26
- baseUrl,
27
- className,
28
- ...props
29
- }) {
30
- return /* @__PURE__ */ jsx(
31
- "div",
32
- {
33
- className: cn(
34
- "flex flex-col gap-24 text-sm text-fd-muted-foreground",
35
- className
36
- ),
37
- ...props,
38
- children: /* @__PURE__ */ jsx(ApiProvider, { defaultBaseUrl: baseUrl, children })
10
+ const badgeVariants = cva('rounded border px-1.5 py-1 text-xs font-medium leading-[12px]', {
11
+ variants: {
12
+ color: {
13
+ green: 'border-green-400/50 bg-green-400/20 text-green-600 dark:text-green-400',
14
+ yellow: 'border-yellow-400/50 bg-yellow-400/20 text-yellow-600 dark:text-yellow-400',
15
+ red: 'border-red-400/50 bg-red-400/20 text-red-600 dark:text-red-400',
16
+ blue: 'border-blue-400/50 bg-blue-400/20 text-blue-600 dark:text-blue-400',
17
+ orange: 'border-orange-400/50 bg-orange-400/20 text-orange-600 dark:text-orange-400'
18
+ }
39
19
  }
40
- );
41
- }
42
- function API({
43
- className,
44
- children,
45
- ...props
46
- }) {
47
- return /* @__PURE__ */ jsx(
48
- "div",
49
- {
50
- className: cn(
51
- "flex flex-col gap-x-6 gap-y-2 xl:flex-row xl:items-start",
52
- className
53
- ),
54
- ...props,
55
- children
20
+ });
21
+ function getBadgeColor(method) {
22
+ switch(method){
23
+ case 'PUT':
24
+ return 'yellow';
25
+ case 'PATCH':
26
+ return 'orange';
27
+ case 'POST':
28
+ return 'blue';
29
+ case 'DELETE':
30
+ return 'red';
31
+ default:
32
+ return 'green';
56
33
  }
57
- );
58
34
  }
35
+
36
+ const APIPlayground = dynamic(()=>import('./playground-client-W7yhm4ZD.js').then((mod)=>mod.APIPlayground));
59
37
  function Route({ route }) {
60
- const segments = route.split("/").filter((part) => part.length > 0);
61
- return /* @__PURE__ */ jsx("div", { className: "flex flex-row flex-wrap items-center gap-1 text-sm", children: segments.map((part, index) => /* @__PURE__ */ jsxs(Fragment, { children: [
62
- /* @__PURE__ */ jsx("span", { className: "text-fd-muted-foreground", children: "/" }),
63
- part.startsWith("{") && part.endsWith("}") ? /* @__PURE__ */ jsx("code", { className: "text-fd-primary", children: part }) : /* @__PURE__ */ jsx("span", { className: "text-fd-foreground", children: part })
64
- ] }, index)) });
38
+ const segments = route.split('/').filter((part)=>part.length > 0);
39
+ return /*#__PURE__*/ jsx("div", {
40
+ className: "flex flex-row flex-wrap items-center gap-1 text-sm",
41
+ children: segments.map((part, index)=>/*#__PURE__*/ jsxs(Fragment, {
42
+ children: [
43
+ /*#__PURE__*/ jsx("span", {
44
+ className: "text-fd-muted-foreground",
45
+ children: "/"
46
+ }),
47
+ part.startsWith('{') && part.endsWith('}') ? /*#__PURE__*/ jsx("code", {
48
+ className: "text-fd-primary",
49
+ children: part
50
+ }) : /*#__PURE__*/ jsx("span", {
51
+ className: "text-fd-foreground",
52
+ children: part
53
+ })
54
+ ]
55
+ }, index))
56
+ });
65
57
  }
66
- function APIInfo({
67
- children,
68
- className,
69
- route,
70
- badgeClassName,
71
- method = "GET",
72
- ...props
73
- }) {
74
- return /* @__PURE__ */ jsxs("div", { className: cn("min-w-0 flex-1", className), ...props, children: [
75
- /* @__PURE__ */ jsxs(
76
- "div",
77
- {
78
- className: cn(
79
- "sticky top-24 z-[2] mb-4 flex flex-row items-center gap-2 rounded-lg border bg-fd-card p-3 md:top-10"
80
- ),
58
+ function APIInfo({ children, className, route, badgeClassname, method = 'GET', ...props }) {
59
+ return /*#__PURE__*/ jsxs("div", {
60
+ className: cn('min-w-0 flex-1', className),
61
+ ...props,
81
62
  children: [
82
- /* @__PURE__ */ jsx(
83
- "span",
84
- {
85
- className: cn(
86
- badgeVariants({ color: getBadgeColor(method) }),
87
- badgeClassName
88
- ),
89
- children: method
90
- }
91
- ),
92
- /* @__PURE__ */ jsx(Route, { route }),
93
- /* @__PURE__ */ jsx(CopyRouteButton, { className: "ms-auto size-6 p-1", route })
63
+ /*#__PURE__*/ jsxs("div", {
64
+ className: cn('sticky top-24 z-[2] mb-4 flex flex-row items-center gap-2 rounded-lg border bg-fd-card p-3 md:top-10'),
65
+ children: [
66
+ /*#__PURE__*/ jsx("span", {
67
+ className: cn(badgeVariants({
68
+ color: getBadgeColor(method)
69
+ }), badgeClassname),
70
+ children: method
71
+ }),
72
+ /*#__PURE__*/ jsx(Route, {
73
+ route: route
74
+ }),
75
+ /*#__PURE__*/ jsx(CopyRouteButton, {
76
+ className: "ms-auto size-6 p-1",
77
+ route: route
78
+ })
79
+ ]
80
+ }),
81
+ /*#__PURE__*/ jsx("div", {
82
+ className: "prose-no-margin",
83
+ children: children
84
+ })
94
85
  ]
95
- }
96
- ),
97
- /* @__PURE__ */ jsx("div", { className: "prose-no-margin", children })
98
- ] });
86
+ });
99
87
  }
100
- function Property({
101
- name,
102
- type,
103
- required,
104
- deprecated,
105
- children
106
- }) {
107
- return /* @__PURE__ */ jsxs("div", { className: "mb-4 flex flex-col rounded-lg border bg-fd-card p-3 prose-no-margin", children: [
108
- /* @__PURE__ */ jsxs("h4", { className: "inline-flex items-center gap-4", children: [
109
- /* @__PURE__ */ jsx("code", { children: name }),
110
- required ? /* @__PURE__ */ jsx("div", { className: cn(badgeVariants({ color: "red" })), children: "Required" }) : null,
111
- deprecated ? /* @__PURE__ */ jsx("div", { className: cn(badgeVariants({ color: "yellow" })), children: "Deprecated" }) : null,
112
- /* @__PURE__ */ jsx("span", { className: "ms-auto font-mono text-[13px] text-fd-muted-foreground", children: type })
113
- ] }),
114
- children
115
- ] });
88
+ function API({ className, children, ...props }) {
89
+ return /*#__PURE__*/ jsx("div", {
90
+ className: cn('flex flex-col gap-x-6 gap-y-2 xl:flex-row xl:items-start', className),
91
+ ...props,
92
+ children: children
93
+ });
116
94
  }
117
- function APIExample({
118
- children,
119
- className,
120
- ...props
121
- }) {
122
- return /* @__PURE__ */ jsx(
123
- "div",
124
- {
125
- className: cn("sticky top-10 prose-no-margin xl:w-[400px]", className),
126
- ...props,
127
- children
128
- }
129
- );
130
- }
131
- function ResponseTypes(props) {
132
- return /* @__PURE__ */ jsx(
133
- Accordions,
134
- {
135
- type: "single",
136
- className: "!-m-4 border-none pt-2",
137
- defaultValue: "Response",
138
- children: props.children
139
- }
140
- );
141
- }
142
- function ExampleResponse(props) {
143
- return /* @__PURE__ */ jsx(Accordion, { title: "Response", children: props.children });
95
+ function Property({ name, type, required, deprecated, children }) {
96
+ return /*#__PURE__*/ jsxs("div", {
97
+ className: "mb-4 flex flex-col rounded-lg border bg-fd-card p-3 prose-no-margin",
98
+ children: [
99
+ /*#__PURE__*/ jsxs("h4", {
100
+ className: "inline-flex items-center gap-4",
101
+ children: [
102
+ /*#__PURE__*/ jsx("code", {
103
+ children: name
104
+ }),
105
+ required ? /*#__PURE__*/ jsx("div", {
106
+ className: cn(badgeVariants({
107
+ color: 'red'
108
+ })),
109
+ children: "Required"
110
+ }) : null,
111
+ deprecated ? /*#__PURE__*/ jsx("div", {
112
+ className: cn(badgeVariants({
113
+ color: 'yellow'
114
+ })),
115
+ children: "Deprecated"
116
+ }) : null,
117
+ /*#__PURE__*/ jsx("span", {
118
+ className: "ms-auto font-mono text-[13px] text-fd-muted-foreground",
119
+ children: type
120
+ })
121
+ ]
122
+ }),
123
+ children
124
+ ]
125
+ });
144
126
  }
145
- function TypeScriptResponse(props) {
146
- return /* @__PURE__ */ jsx(Accordion, { title: "Typescript", children: props.children });
127
+ function APIExample({ children, className, ...props }) {
128
+ return /*#__PURE__*/ jsx("div", {
129
+ className: cn('sticky top-10 prose-no-margin xl:w-[400px]', className),
130
+ ...props,
131
+ children: children
132
+ });
147
133
  }
148
134
  function ObjectCollapsible(props) {
149
- return /* @__PURE__ */ jsx(Accordions, { type: "single", children: /* @__PURE__ */ jsx(Accordion, { title: props.name, children: props.children }) });
150
- }
151
- function CopyRouteButton({
152
- className,
153
- route,
154
- ...props
155
- }) {
156
- const { baseUrl } = useApiContext();
157
- const [checked, onCopy] = useCopyButton(() => {
158
- void navigator.clipboard.writeText(`${baseUrl ?? ""}${route}`);
159
- });
160
- return /* @__PURE__ */ jsx(
161
- "button",
162
- {
163
- type: "button",
164
- className: cn(
165
- buttonVariants({
166
- color: "ghost",
167
- className
135
+ return /*#__PURE__*/ jsx(Accordions, {
136
+ type: "single",
137
+ children: /*#__PURE__*/ jsx(Accordion, {
138
+ title: props.name,
139
+ children: props.children
168
140
  })
169
- ),
170
- onClick: onCopy,
171
- ...props,
172
- children: checked ? /* @__PURE__ */ jsx(Check, { className: "size-3" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3" })
173
- }
174
- );
141
+ });
175
142
  }
176
143
 
177
- // src/ui/index.ts
178
- var APIPlayground = dynamic(
179
- () => import("../playground-GIGTWHCL.js").then((mod) => mod.APIPlayground)
180
- );
181
- var Responses = Tabs;
182
- var Response = Tab;
183
- var Requests = Tabs;
184
- var Request = Tab;
185
- export {
186
- API,
187
- APIExample,
188
- APIInfo,
189
- APIPlayground,
190
- ExampleResponse,
191
- ObjectCollapsible,
192
- Property,
193
- Request,
194
- Requests,
195
- Response,
196
- ResponseTypes,
197
- Responses,
198
- Root,
199
- TypeScriptResponse,
200
- useSchemaContext
201
- };
144
+ export { API, APIExample, APIInfo, APIPlayground, ObjectCollapsible, Property };