fumadocs-openapi 9.7.2 → 10.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.
- package/dist/generate-file.d.ts +3 -4
- package/dist/generate-file.d.ts.map +1 -1
- package/dist/generate-file.js +4 -34
- package/dist/playground/client.d.ts +43 -22
- package/dist/playground/client.d.ts.map +1 -1
- package/dist/playground/client.js +68 -63
- package/dist/playground/{inputs.d.ts → components/inputs.d.ts} +1 -1
- package/dist/playground/components/inputs.d.ts.map +1 -0
- package/dist/playground/{inputs.js → components/inputs.js} +7 -7
- package/dist/playground/components/oauth-dialog.d.ts.map +1 -0
- package/dist/playground/components/server-select.d.ts.map +1 -0
- package/dist/{ui → playground/components}/server-select.js +6 -7
- package/dist/playground/index.d.ts +1 -4
- package/dist/playground/index.d.ts.map +1 -1
- package/dist/playground/index.js +5 -3
- package/dist/playground/lazy.d.ts +2 -0
- package/dist/playground/lazy.d.ts.map +1 -0
- package/dist/playground/lazy.js +3 -0
- package/dist/requests/generators/index.d.ts +2 -2
- package/dist/requests/generators/index.d.ts.map +1 -1
- package/dist/requests/generators/index.js +6 -0
- package/dist/requests/media/adapter.d.ts +0 -6
- package/dist/requests/media/adapter.d.ts.map +1 -1
- package/dist/scalar/index.d.ts +5 -0
- package/dist/scalar/index.d.ts.map +1 -1
- package/dist/scalar/index.js +14 -0
- package/dist/server/create.d.ts +11 -59
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/create.js +5 -14
- package/dist/server/source-api.d.ts +1 -1
- package/dist/server/source-api.d.ts.map +1 -1
- package/dist/server/source-api.js +1 -1
- package/dist/types.d.ts +12 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/api-page.d.ts +145 -0
- package/dist/ui/api-page.d.ts.map +1 -0
- package/dist/ui/api-page.js +120 -0
- package/dist/ui/client/index.d.ts +29 -0
- package/dist/ui/client/index.d.ts.map +1 -0
- package/dist/ui/client/index.js +4 -0
- package/dist/ui/client/storage-key.d.ts +9 -0
- package/dist/ui/client/storage-key.d.ts.map +1 -0
- package/dist/ui/client/storage-key.js +12 -0
- package/dist/ui/components/method-label.d.ts +1 -1
- package/dist/ui/contexts/api.d.ts +12 -10
- package/dist/ui/contexts/api.d.ts.map +1 -1
- package/dist/ui/contexts/api.js +53 -37
- package/dist/ui/contexts/api.lazy.d.ts +2 -0
- package/dist/ui/contexts/api.lazy.d.ts.map +1 -0
- package/dist/ui/contexts/api.lazy.js +3 -0
- package/dist/ui/contexts/operation.d.ts +20 -0
- package/dist/ui/contexts/operation.d.ts.map +1 -0
- package/dist/ui/contexts/operation.js +48 -0
- package/dist/ui/contexts/operation.lazy.d.ts +2 -0
- package/dist/ui/contexts/operation.lazy.d.ts.map +1 -0
- package/dist/ui/contexts/operation.lazy.js +3 -0
- package/dist/ui/index.d.ts +1 -8
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +1 -26
- package/dist/ui/{select-tabs.d.ts → operation/client.d.ts} +5 -2
- package/dist/ui/operation/client.d.ts.map +1 -0
- package/dist/ui/{client.js → operation/client.js} +18 -1
- package/dist/ui/operation/example-panel/client.d.ts +4 -0
- package/dist/ui/operation/example-panel/client.d.ts.map +1 -0
- package/dist/ui/operation/example-panel/client.js +50 -0
- package/dist/ui/operation/example-panel/index.d.ts +58 -0
- package/dist/ui/operation/example-panel/index.d.ts.map +1 -0
- package/dist/ui/operation/example-panel/index.js +140 -0
- package/dist/ui/operation/example-panel/lazy.d.ts +3 -0
- package/dist/ui/operation/example-panel/lazy.d.ts.map +1 -0
- package/dist/ui/operation/example-panel/lazy.js +4 -0
- package/dist/ui/operation/get-request-data.d.ts.map +1 -0
- package/dist/ui/operation/index.d.ts +11 -0
- package/dist/ui/operation/index.d.ts.map +1 -0
- package/dist/{render → ui}/operation/index.js +50 -24
- package/dist/ui/schema/client.d.ts +11 -0
- package/dist/ui/schema/client.d.ts.map +1 -0
- package/dist/{render → ui}/schema/client.js +22 -12
- package/dist/{render/schema/server.d.ts → ui/schema/index.d.ts} +5 -4
- package/dist/ui/schema/index.d.ts.map +1 -0
- package/dist/{render/schema/server.js → ui/schema/index.js} +11 -5
- package/dist/ui/schema/lazy.d.ts +2 -0
- package/dist/ui/schema/lazy.d.ts.map +1 -0
- package/dist/ui/schema/lazy.js +3 -0
- package/dist/utils/get-typescript-schema.d.ts +3 -2
- package/dist/utils/get-typescript-schema.d.ts.map +1 -1
- package/dist/utils/get-typescript-schema.js +12 -7
- package/dist/utils/lazy.d.ts +5 -0
- package/dist/utils/lazy.d.ts.map +1 -0
- package/dist/utils/lazy.js +12 -0
- package/dist/utils/pages/builder.d.ts +1 -1
- package/dist/utils/pages/builder.d.ts.map +1 -1
- package/dist/utils/pages/to-body.d.ts +2 -3
- package/dist/utils/pages/to-body.d.ts.map +1 -1
- package/dist/utils/pages/to-body.js +7 -7
- package/dist/utils/pages/to-text.d.ts.map +1 -1
- package/dist/utils/process-document.d.ts +1 -0
- package/dist/utils/process-document.d.ts.map +1 -1
- package/dist/utils/process-document.js +7 -2
- package/package.json +18 -14
- package/dist/playground/auth/oauth-dialog.d.ts.map +0 -1
- package/dist/playground/inputs.d.ts.map +0 -1
- package/dist/render/api-page.d.ts +0 -33
- package/dist/render/api-page.d.ts.map +0 -1
- package/dist/render/api-page.js +0 -59
- package/dist/render/codeblock.d.ts +0 -9
- package/dist/render/codeblock.d.ts.map +0 -1
- package/dist/render/codeblock.js +0 -14
- package/dist/render/heading.d.ts +0 -4
- package/dist/render/heading.d.ts.map +0 -1
- package/dist/render/heading.js +0 -6
- package/dist/render/markdown.d.ts +0 -5
- package/dist/render/markdown.d.ts.map +0 -1
- package/dist/render/markdown.js +0 -31
- package/dist/render/operation/api-example.d.ts +0 -30
- package/dist/render/operation/api-example.d.ts.map +0 -1
- package/dist/render/operation/api-example.js +0 -103
- package/dist/render/operation/get-request-data.d.ts.map +0 -1
- package/dist/render/operation/index.d.ts +0 -27
- package/dist/render/operation/index.d.ts.map +0 -1
- package/dist/render/renderer.d.ts +0 -79
- package/dist/render/renderer.d.ts.map +0 -1
- package/dist/render/renderer.js +0 -25
- package/dist/render/schema/client.d.ts +0 -18
- package/dist/render/schema/client.d.ts.map +0 -1
- package/dist/render/schema/index.d.ts +0 -7
- package/dist/render/schema/index.d.ts.map +0 -1
- package/dist/render/schema/index.js +0 -11
- package/dist/render/schema/server.d.ts.map +0 -1
- package/dist/render/schema/ui.d.ts +0 -16
- package/dist/render/schema/ui.d.ts.map +0 -1
- package/dist/render/schema/ui.js +0 -14
- package/dist/ui/client.d.ts +0 -4
- package/dist/ui/client.d.ts.map +0 -1
- package/dist/ui/contexts/code-example.d.ts +0 -24
- package/dist/ui/contexts/code-example.d.ts.map +0 -1
- package/dist/ui/contexts/code-example.js +0 -97
- package/dist/ui/lazy.d.ts +0 -16
- package/dist/ui/lazy.d.ts.map +0 -1
- package/dist/ui/lazy.js +0 -22
- package/dist/ui/select-tabs.d.ts.map +0 -1
- package/dist/ui/select-tabs.js +0 -20
- package/dist/ui/server-select.d.ts.map +0 -1
- /package/dist/playground/{auth → components}/oauth-dialog.d.ts +0 -0
- /package/dist/playground/{auth → components}/oauth-dialog.js +0 -0
- /package/dist/{ui → playground/components}/server-select.d.ts +0 -0
- /package/dist/{render → ui}/operation/get-request-data.d.ts +0 -0
- /package/dist/{render → ui}/operation/get-request-data.js +0 -0
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { type ReactNode } from 'react';
|
|
2
|
-
import type { RenderContext
|
|
1
|
+
import { type ReactNode, type RefObject } from 'react';
|
|
2
|
+
import type { RenderContext } from '../../types.js';
|
|
3
3
|
import { type MediaAdapter } from '../../requests/media/adapter.js';
|
|
4
|
-
|
|
5
|
-
export interface ApiProviderProps extends
|
|
4
|
+
type InheritFromContext = Pick<Required<RenderContext>, 'servers' | 'client'> & Pick<RenderContext, 'shikiOptions'>;
|
|
5
|
+
export interface ApiProviderProps extends InheritFromContext {
|
|
6
6
|
/**
|
|
7
7
|
* Base URL for API requests
|
|
8
8
|
*/
|
|
9
9
|
defaultBaseUrl?: string;
|
|
10
|
-
children?: ReactNode;
|
|
11
|
-
mediaAdapters?: Record<string, MediaAdapter>;
|
|
12
10
|
}
|
|
13
11
|
export interface SelectedServer {
|
|
14
12
|
url: string;
|
|
15
13
|
variables: Record<string, string>;
|
|
16
14
|
}
|
|
17
|
-
interface ApiContextType {
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
interface ApiContextType extends InheritFromContext {
|
|
16
|
+
/**
|
|
17
|
+
* ref to selected API server (to query)
|
|
18
|
+
*/
|
|
19
|
+
serverRef: RefObject<SelectedServer | null>;
|
|
20
20
|
mediaAdapters: Record<string, MediaAdapter>;
|
|
21
21
|
}
|
|
22
22
|
interface ServerSelectType {
|
|
@@ -26,6 +26,8 @@ interface ServerSelectType {
|
|
|
26
26
|
}
|
|
27
27
|
export declare function useApiContext(): ApiContextType;
|
|
28
28
|
export declare function useServerSelectContext(): ServerSelectType;
|
|
29
|
-
export declare function ApiProvider({ defaultBaseUrl, children, servers,
|
|
29
|
+
export declare function ApiProvider({ defaultBaseUrl, children, servers, shikiOptions, client, }: ApiProviderProps & {
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
30
32
|
export {};
|
|
31
33
|
//# sourceMappingURL=api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/ui/contexts/api.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/ui/contexts/api.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAI9E,KAAK,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC,GAC3E,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AAEtC,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB;IAC1D;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,UAAU,cAAe,SAAQ,kBAAkB;IACjD;;OAEG;IACH,SAAS,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAE5C,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC7C;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CAC7D;AAKD,wBAAgB,aAAa,IAAI,cAAc,CAK9C;AAED,wBAAgB,sBAAsB,IAAI,gBAAgB,CAKzD;AAED,wBAAgB,WAAW,CAAC,EAC1B,cAAc,EACd,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,MAAM,GACP,EAAE,gBAAgB,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAwB5C"}
|
package/dist/ui/contexts/api.js
CHANGED
|
@@ -1,26 +1,42 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { createContext,
|
|
3
|
+
import { createContext, use, useEffect, useMemo, useRef, useState, } from 'react';
|
|
4
4
|
import { defaultAdapters } from '../../requests/media/adapter.js';
|
|
5
|
+
import { useStorageKey } from '../client/storage-key.js';
|
|
5
6
|
const ApiContext = createContext(null);
|
|
6
7
|
const ServerSelectContext = createContext(null);
|
|
7
8
|
export function useApiContext() {
|
|
8
|
-
const ctx =
|
|
9
|
+
const ctx = use(ApiContext);
|
|
9
10
|
if (!ctx)
|
|
10
11
|
throw new Error('Component must be used under <ApiProvider />');
|
|
11
12
|
return ctx;
|
|
12
13
|
}
|
|
13
14
|
export function useServerSelectContext() {
|
|
14
|
-
const ctx =
|
|
15
|
+
const ctx = use(ServerSelectContext);
|
|
15
16
|
if (!ctx)
|
|
16
17
|
throw new Error('Component must be used under <ApiProvider />');
|
|
17
18
|
return ctx;
|
|
18
19
|
}
|
|
19
|
-
export function ApiProvider({ defaultBaseUrl, children, servers,
|
|
20
|
+
export function ApiProvider({ defaultBaseUrl, children, servers, shikiOptions, client, }) {
|
|
21
|
+
const serverRef = useRef(null);
|
|
22
|
+
return (_jsx(ApiContext, { value: useMemo(() => ({
|
|
23
|
+
serverRef,
|
|
24
|
+
shikiOptions,
|
|
25
|
+
client,
|
|
26
|
+
mediaAdapters: {
|
|
27
|
+
...defaultAdapters,
|
|
28
|
+
...client.mediaAdapters,
|
|
29
|
+
},
|
|
30
|
+
servers,
|
|
31
|
+
}), [servers, client, shikiOptions]), children: _jsx(ServerSelectProvider, { defaultBaseUrl: defaultBaseUrl, children: children }) }));
|
|
32
|
+
}
|
|
33
|
+
function ServerSelectProvider({ defaultBaseUrl, children, }) {
|
|
34
|
+
const { servers, serverRef } = useApiContext();
|
|
35
|
+
const storageKeys = useStorageKey();
|
|
20
36
|
const [server, setServer] = useState(() => {
|
|
21
37
|
const defaultItem = defaultBaseUrl
|
|
22
38
|
? servers.find((item) => item.url === defaultBaseUrl)
|
|
23
|
-
: servers
|
|
39
|
+
: servers[0];
|
|
24
40
|
return defaultItem
|
|
25
41
|
? {
|
|
26
42
|
url: defaultItem.url,
|
|
@@ -28,8 +44,9 @@ export function ApiProvider({ defaultBaseUrl, children, servers, mediaAdapters,
|
|
|
28
44
|
}
|
|
29
45
|
: null;
|
|
30
46
|
});
|
|
47
|
+
serverRef.current = server;
|
|
31
48
|
useEffect(() => {
|
|
32
|
-
const cached = localStorage.getItem('
|
|
49
|
+
const cached = localStorage.getItem(storageKeys.of('server-url'));
|
|
33
50
|
if (!cached)
|
|
34
51
|
return;
|
|
35
52
|
try {
|
|
@@ -41,38 +58,37 @@ export function ApiProvider({ defaultBaseUrl, children, servers, mediaAdapters,
|
|
|
41
58
|
catch {
|
|
42
59
|
// ignore
|
|
43
60
|
}
|
|
44
|
-
}, []);
|
|
45
|
-
return (_jsx(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
61
|
+
}, [storageKeys]);
|
|
62
|
+
return (_jsx(ServerSelectContext, { value: useMemo(() => ({
|
|
63
|
+
server,
|
|
64
|
+
setServerVariables(variables) {
|
|
65
|
+
setServer((prev) => {
|
|
66
|
+
if (!prev)
|
|
67
|
+
return null;
|
|
68
|
+
const updated = { ...prev, variables };
|
|
69
|
+
localStorage.setItem(storageKeys.of('server-url'), JSON.stringify(updated));
|
|
70
|
+
return updated;
|
|
71
|
+
});
|
|
50
72
|
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
setServer(value) {
|
|
64
|
-
const obj = servers.find((item) => item.url === value);
|
|
65
|
-
if (!obj)
|
|
66
|
-
return;
|
|
67
|
-
const result = {
|
|
68
|
-
url: value,
|
|
69
|
-
variables: getDefaultValues(obj),
|
|
70
|
-
};
|
|
71
|
-
localStorage.setItem('apiBaseUrl', JSON.stringify(result));
|
|
72
|
-
setServer(result);
|
|
73
|
-
},
|
|
74
|
-
}), [server, servers]), children: children }) }));
|
|
73
|
+
setServer(value) {
|
|
74
|
+
const obj = servers.find((item) => item.url === value);
|
|
75
|
+
if (!obj)
|
|
76
|
+
return;
|
|
77
|
+
const result = {
|
|
78
|
+
url: value,
|
|
79
|
+
variables: getDefaultValues(obj),
|
|
80
|
+
};
|
|
81
|
+
localStorage.setItem(storageKeys.of('server-url'), JSON.stringify(result));
|
|
82
|
+
setServer(result);
|
|
83
|
+
},
|
|
84
|
+
}), [server, servers, storageKeys]), children: children }));
|
|
75
85
|
}
|
|
76
86
|
function getDefaultValues(server) {
|
|
77
|
-
|
|
87
|
+
const out = {};
|
|
88
|
+
if (!server.variables)
|
|
89
|
+
return out;
|
|
90
|
+
for (const [k, v] of Object.entries(server.variables)) {
|
|
91
|
+
out[k] = v.default;
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
78
94
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.lazy.d.ts","sourceRoot":"","sources":["../../../src/ui/contexts/api.lazy.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,oCAE3B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { APIExampleItem } from '../../ui/operation/example-panel/index.js';
|
|
3
|
+
import type { RawRequestData, RequestData } from '../../requests/types.js';
|
|
4
|
+
export type ExampleUpdateListener = (data: RawRequestData, encoded: RequestData) => void;
|
|
5
|
+
export declare function OperationProvider({ route, examples, defaultExampleId, children, }: {
|
|
6
|
+
route: string;
|
|
7
|
+
examples: APIExampleItem[];
|
|
8
|
+
defaultExampleId?: string;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare function useOperationContext(): {
|
|
12
|
+
route: string;
|
|
13
|
+
examples: APIExampleItem[];
|
|
14
|
+
example: string | undefined;
|
|
15
|
+
setExample: (id: string) => void;
|
|
16
|
+
setExampleData: (data: RawRequestData, encoded: RequestData) => void;
|
|
17
|
+
addListener: (listener: ExampleUpdateListener) => void;
|
|
18
|
+
removeListener: (listener: ExampleUpdateListener) => void;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=operation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation.d.ts","sourceRoot":"","sources":["../../../src/ui/contexts/operation.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpE,MAAM,MAAM,qBAAqB,GAAG,CAClC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,WAAW,KACjB,IAAI,CAAC;AAaV,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,QAAQ,EACR,gBAAgB,EAChB,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB,2CAwDA;AAED,wBAAgB,mBAAmB;WA9E1B,MAAM;cACH,cAAc,EAAE;aACjB,MAAM,GAAG,SAAS;gBACf,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI;oBAChB,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,KAAK,IAAI;iBAEvD,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI;oBACtC,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI;EAyE1D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, use, useMemo, useRef, useState, } from 'react';
|
|
4
|
+
const OperationContext = createContext(null);
|
|
5
|
+
export function OperationProvider({ route, examples, defaultExampleId, children, }) {
|
|
6
|
+
const [example, setExample] = useState(() => defaultExampleId ?? examples.at(0)?.id);
|
|
7
|
+
const listeners = useRef([]);
|
|
8
|
+
return (_jsx(OperationContext, { value: useMemo(() => ({
|
|
9
|
+
example,
|
|
10
|
+
route,
|
|
11
|
+
setExample: (newKey) => {
|
|
12
|
+
const example = examples.find((example) => example.id === newKey);
|
|
13
|
+
if (!example)
|
|
14
|
+
return;
|
|
15
|
+
setExample(newKey);
|
|
16
|
+
for (const listener of listeners.current) {
|
|
17
|
+
listener(example.data, example.encoded);
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
examples,
|
|
21
|
+
setExampleData: (data, encoded) => {
|
|
22
|
+
for (const item of examples) {
|
|
23
|
+
if (item.id === example) {
|
|
24
|
+
// persistent changes
|
|
25
|
+
item.data = data;
|
|
26
|
+
item.encoded = encoded;
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
for (const listener of listeners.current) {
|
|
31
|
+
listener(data, encoded);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
removeListener: (listener) => {
|
|
35
|
+
listeners.current = listeners.current.filter((item) => item !== listener);
|
|
36
|
+
},
|
|
37
|
+
addListener: (listener) => {
|
|
38
|
+
// initial call to listeners to ensure their data is the latest
|
|
39
|
+
// this is necessary to avoid race conditions between `useEffect()`
|
|
40
|
+
const active = examples.find((item) => item.id === example);
|
|
41
|
+
listener(active.data, active.encoded);
|
|
42
|
+
listeners.current.push(listener);
|
|
43
|
+
},
|
|
44
|
+
}), [example, route, examples]), children: children }));
|
|
45
|
+
}
|
|
46
|
+
export function useOperationContext() {
|
|
47
|
+
return use(OperationContext);
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation.lazy.d.ts","sourceRoot":"","sources":["../../../src/ui/contexts/operation.lazy.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,gDAEjC,CAAC"}
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import type { RootProps } from '../render/renderer.js';
|
|
3
|
-
export declare function Root({ children, className, ctx, ...props }: RootProps & HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
4
|
-
export declare function APIInfo({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
export declare function API({ children, ...props }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
export declare function APIExample(props: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
export { Property, ObjectCollapsible } from '../render/schema/ui.js';
|
|
8
|
-
export { APIPage, type ApiPageProps } from '../render/api-page.js';
|
|
1
|
+
export * from '../ui/api-page.js';
|
|
9
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/ui/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.tsx"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.tsx"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
|
package/dist/ui/index.js
CHANGED
|
@@ -1,26 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { ApiProvider } from '../ui/lazy.js';
|
|
3
|
-
import { cn } from 'fumadocs-ui/utils/cn';
|
|
4
|
-
export function Root({ children, className, ctx, ...props }) {
|
|
5
|
-
const mediaAdapters = {};
|
|
6
|
-
for (const k in ctx.mediaAdapters) {
|
|
7
|
-
const adapter = ctx.mediaAdapters[k];
|
|
8
|
-
if (adapter.client)
|
|
9
|
-
mediaAdapters[k] = adapter.client;
|
|
10
|
-
}
|
|
11
|
-
return (_jsx("div", { className: cn('flex flex-col gap-24 text-sm', className), ...props, children: _jsx(ApiProvider, { mediaAdapters: mediaAdapters, servers: ctx.servers, shikiOptions: ctx.shikiOptions, children: children }) }));
|
|
12
|
-
}
|
|
13
|
-
export function APIInfo({ className, ...props }) {
|
|
14
|
-
return (_jsx("div", { className: cn('min-w-0 flex-1', className), ...props, children: props.children }));
|
|
15
|
-
}
|
|
16
|
-
export function API({ children, ...props }) {
|
|
17
|
-
return (_jsx("div", { ...props, className: cn('flex flex-col gap-x-6 gap-y-4 xl:flex-row xl:items-start', props.className), style: {
|
|
18
|
-
'--fd-api-info-top': 'calc(12px + var(--fd-nav-height) + var(--fd-banner-height) + var(--fd-tocnav-height, 0px))',
|
|
19
|
-
...props.style,
|
|
20
|
-
}, children: children }));
|
|
21
|
-
}
|
|
22
|
-
export function APIExample(props) {
|
|
23
|
-
return (_jsx("div", { ...props, className: cn('prose-no-margin md:sticky md:top-(--fd-api-info-top) xl:w-[400px]', props.className), children: props.children }));
|
|
24
|
-
}
|
|
25
|
-
export { Property, ObjectCollapsible } from '../render/schema/ui.js';
|
|
26
|
-
export { APIPage } from '../render/api-page.js';
|
|
1
|
+
export * from '../ui/api-page.js';
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { type ComponentProps, type ReactNode } from 'react';
|
|
2
|
-
import { SelectTrigger } from '
|
|
2
|
+
import { SelectTrigger } from '../../ui/components/select.js';
|
|
3
|
+
export declare function CopyResponseTypeScript({ code }: {
|
|
4
|
+
code: string;
|
|
5
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
3
6
|
export declare function SelectTabs({ defaultValue, children, }: {
|
|
4
7
|
defaultValue?: string;
|
|
5
8
|
children: ReactNode;
|
|
@@ -10,4 +13,4 @@ export declare function SelectTab({ value, ...props }: ComponentProps<'div'> & {
|
|
|
10
13
|
export declare function SelectTabTrigger({ items, ...props }: ComponentProps<typeof SelectTrigger> & {
|
|
11
14
|
items: string[];
|
|
12
15
|
}): import("react/jsx-runtime").JSX.Element;
|
|
13
|
-
//# sourceMappingURL=
|
|
16
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/ui/operation/client.tsx"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AACf,OAAO,EAIL,aAAa,EAEd,MAAM,wBAAwB,CAAC;AAEhC,wBAAgB,sBAAsB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,2CAgChE;AAOD,wBAAgB,UAAU,CAAC,EACzB,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,SAAS,CAAC;CACrB,2CAQA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;CACf,uDAKA;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,2CAoB5D"}
|
|
@@ -3,7 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useCopyButton } from 'fumadocs-ui/utils/use-copy-button';
|
|
4
4
|
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
|
|
5
5
|
import { cn } from 'fumadocs-ui/utils/cn';
|
|
6
|
-
import { Check, Copy } from '
|
|
6
|
+
import { Check, Copy } from '../../icons.js';
|
|
7
|
+
import { createContext, use, useMemo, useState, } from 'react';
|
|
8
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../ui/components/select.js';
|
|
7
9
|
export function CopyResponseTypeScript({ code }) {
|
|
8
10
|
const [isChecked, onCopy] = useCopyButton(() => {
|
|
9
11
|
void navigator.clipboard.writeText(code);
|
|
@@ -14,3 +16,18 @@ export function CopyResponseTypeScript({ code }) {
|
|
|
14
16
|
size: 'sm',
|
|
15
17
|
})), children: [isChecked ? (_jsx(Check, { className: "size-3.5" })) : (_jsx(Copy, { className: "size-3.5" })), "Copy"] })] }));
|
|
16
18
|
}
|
|
19
|
+
const Context = createContext(null);
|
|
20
|
+
export function SelectTabs({ defaultValue, children, }) {
|
|
21
|
+
const [type, setType] = useState(defaultValue ?? null);
|
|
22
|
+
return (_jsx(Context, { value: useMemo(() => ({ type, setType }), [type]), children: children }));
|
|
23
|
+
}
|
|
24
|
+
export function SelectTab({ value, ...props }) {
|
|
25
|
+
const ctx = use(Context);
|
|
26
|
+
if (value !== ctx?.type)
|
|
27
|
+
return;
|
|
28
|
+
return _jsx("div", { ...props, children: props.children });
|
|
29
|
+
}
|
|
30
|
+
export function SelectTabTrigger({ items, ...props }) {
|
|
31
|
+
const { type, setType } = use(Context);
|
|
32
|
+
return (_jsxs(Select, { value: type ?? '', onValueChange: setType, children: [_jsx(SelectTrigger, { ...props, className: cn('not-prose w-fit', props.className), children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: items.map((type) => (_jsx(SelectItem, { value: type, children: type }, type))) })] }));
|
|
33
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CodeUsageGenerator } from './index.js';
|
|
2
|
+
export declare function APIExampleSelector(): import("react/jsx-runtime").JSX.Element | null;
|
|
3
|
+
export declare function APIExampleUsageTab(sample: CodeUsageGenerator): import("react/jsx-runtime").JSX.Element | null;
|
|
4
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/ui/operation/example-panel/client.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAkB,kBAAkB,EAAE,MAAM,GAAG,CAAC;AAE5D,wBAAgB,kBAAkB,mDAkCjC;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,kDAkD5D"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useApiContext, useServerSelectContext } from '../../../ui/contexts/api.js';
|
|
4
|
+
import { useOperationContext, } from '../../../ui/contexts/operation.js';
|
|
5
|
+
import { joinURL, withBase, resolveServerUrl, resolveRequestData, } from '../../../utils/url.js';
|
|
6
|
+
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, } from '../../../ui/components/select.js';
|
|
7
|
+
import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
|
|
8
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
9
|
+
export function APIExampleSelector() {
|
|
10
|
+
const { example: key, setExample: setKey, examples } = useOperationContext();
|
|
11
|
+
const { APIExampleSelector: Override } = useApiContext().client.operation ?? {};
|
|
12
|
+
if (Override) {
|
|
13
|
+
return _jsx(Override, { items: examples, value: key, onValueChange: setKey });
|
|
14
|
+
}
|
|
15
|
+
function renderItem(item) {
|
|
16
|
+
return (_jsxs("div", { children: [_jsx("span", { className: "font-medium text-sm", children: item.name }), _jsx("span", { className: "text-fd-muted-foreground", children: item.description })] }));
|
|
17
|
+
}
|
|
18
|
+
if (examples.length === 1)
|
|
19
|
+
return null;
|
|
20
|
+
const selected = examples.find((item) => item.id === key);
|
|
21
|
+
return (_jsxs(Select, { value: key, onValueChange: setKey, children: [_jsx(SelectTrigger, { className: "not-prose mb-2", children: selected && _jsx(SelectValue, { asChild: true, children: renderItem(selected) }) }), _jsx(SelectContent, { children: examples.map((item) => (_jsx(SelectItem, { value: item.id, children: renderItem(item) }, item.id))) })] }));
|
|
22
|
+
}
|
|
23
|
+
export function APIExampleUsageTab(sample) {
|
|
24
|
+
const { shikiOptions, mediaAdapters } = useApiContext();
|
|
25
|
+
const { examples, example: selectedExampleId, route, addListener, removeListener, } = useOperationContext();
|
|
26
|
+
const { server } = useServerSelectContext();
|
|
27
|
+
const [data, setData] = useState(() => examples.find((example) => example.id === selectedExampleId)?.encoded);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const listener = (_, encoded) => setData(encoded);
|
|
30
|
+
addListener(listener);
|
|
31
|
+
return () => {
|
|
32
|
+
removeListener(listener);
|
|
33
|
+
};
|
|
34
|
+
}, [addListener, removeListener]);
|
|
35
|
+
const code = useMemo(() => {
|
|
36
|
+
if (!sample.source || !data)
|
|
37
|
+
return;
|
|
38
|
+
if (typeof sample.source === 'string')
|
|
39
|
+
return sample.source;
|
|
40
|
+
return sample.source(joinURL(withBase(server ? resolveServerUrl(server.url, server.variables) : '/', typeof window !== 'undefined'
|
|
41
|
+
? window.location.origin
|
|
42
|
+
: 'https://loading'), resolveRequestData(route, data)), data, {
|
|
43
|
+
server: sample.serverContext,
|
|
44
|
+
mediaAdapters,
|
|
45
|
+
});
|
|
46
|
+
}, [mediaAdapters, sample, server, route, data]);
|
|
47
|
+
if (!code || !sample)
|
|
48
|
+
return null;
|
|
49
|
+
return (_jsx(DynamicCodeBlock, { lang: sample.lang, code: code, options: shikiOptions }));
|
|
50
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { MethodInformation, RenderContext, ResponseObject } from '../../../types.js';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import { type NoReference } from '../../../utils/schema.js';
|
|
4
|
+
import type { RawRequestData, RequestData, SampleGenerator } from '../../../requests/types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate code example for given programming language
|
|
7
|
+
*/
|
|
8
|
+
export interface CodeUsageGenerator<T = unknown> {
|
|
9
|
+
id: string;
|
|
10
|
+
lang: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
/**
|
|
13
|
+
* either:
|
|
14
|
+
* - code
|
|
15
|
+
* - a function imported from a file with "use client" directive
|
|
16
|
+
* - false (disabled)
|
|
17
|
+
*/
|
|
18
|
+
source?: string | SampleGenerator<T> | false;
|
|
19
|
+
/**
|
|
20
|
+
* Pass extra context to client-side source generator
|
|
21
|
+
*/
|
|
22
|
+
serverContext?: T;
|
|
23
|
+
}
|
|
24
|
+
export interface APIExampleItem {
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
data: RawRequestData;
|
|
29
|
+
encoded: RequestData;
|
|
30
|
+
}
|
|
31
|
+
export interface ResponseTab {
|
|
32
|
+
/**
|
|
33
|
+
* HTTP response code
|
|
34
|
+
*/
|
|
35
|
+
code: string;
|
|
36
|
+
response: NoReference<ResponseObject>;
|
|
37
|
+
/**
|
|
38
|
+
* media type of response
|
|
39
|
+
*/
|
|
40
|
+
mediaType: string | null;
|
|
41
|
+
examples?: {
|
|
42
|
+
/**
|
|
43
|
+
* generated/defined example data
|
|
44
|
+
*/
|
|
45
|
+
sample: unknown;
|
|
46
|
+
label: string;
|
|
47
|
+
/**
|
|
48
|
+
* description (in Markdown)
|
|
49
|
+
*/
|
|
50
|
+
description?: string;
|
|
51
|
+
}[];
|
|
52
|
+
}
|
|
53
|
+
export declare function getAPIExamples(path: string, method: MethodInformation, ctx: RenderContext): APIExampleItem[];
|
|
54
|
+
export declare function APIExample({ method, ctx, }: {
|
|
55
|
+
method: MethodInformation;
|
|
56
|
+
ctx: RenderContext;
|
|
57
|
+
}): Promise<import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | (string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined)>;
|
|
58
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/operation/example-panel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGpE,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAmB1B;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,OAAO;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IAE7C;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb,QAAQ,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;IACtC;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzB,QAAQ,CAAC,EAAE;QACT;;WAEG;QACH,MAAM,EAAE,OAAO,CAAC;QAEhB,KAAK,EAAE,MAAM,CAAC;QAEd;;WAEG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,EAAE,CAAC;CACL;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,iBAAiB,EACzB,GAAG,EAAE,aAAa,GACjB,cAAc,EAAE,CA0ClB;AAED,wBAAsB,UAAU,CAAC,EAC/B,MAAM,EACN,GAAG,GACJ,EAAE;IACD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,GAAG,EAAE,aAAa,CAAC;CACpB,wUAmEA"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { getPreferredType } from '../../../utils/schema.js';
|
|
3
|
+
import { getRequestData } from '../../../ui/operation/get-request-data.js';
|
|
4
|
+
import { sample } from 'openapi-sampler';
|
|
5
|
+
import { defaultSamples } from '../../../requests/generators/index.js';
|
|
6
|
+
import { encodeRequestData } from '../../../requests/media/encode.js';
|
|
7
|
+
import { AccordionContent, AccordionHeader, AccordionItem, Accordions, AccordionTrigger, } from '../../../ui/components/accordion.js';
|
|
8
|
+
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
|
9
|
+
import { CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, } from 'fumadocs-ui/components/codeblock';
|
|
10
|
+
import { APIExampleSelectorLazy, APIExampleUsageTabLazy } from './lazy.js';
|
|
11
|
+
export function getAPIExamples(path, method, ctx) {
|
|
12
|
+
const media = method.requestBody
|
|
13
|
+
? getPreferredType(method.requestBody.content)
|
|
14
|
+
: null;
|
|
15
|
+
const bodyOfType = media ? method.requestBody?.content[media] : null;
|
|
16
|
+
if (bodyOfType?.examples) {
|
|
17
|
+
const result = [];
|
|
18
|
+
for (const [key, value] of Object.entries(bodyOfType.examples)) {
|
|
19
|
+
const data = getRequestData(path, method, key, ctx);
|
|
20
|
+
result.push({
|
|
21
|
+
id: key,
|
|
22
|
+
name: value.summary ?? key,
|
|
23
|
+
description: value.description,
|
|
24
|
+
data,
|
|
25
|
+
encoded: encodeRequestData(data, ctx.mediaAdapters, method.parameters ?? []),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (result.length > 0)
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
const data = getRequestData(path, method, null, ctx);
|
|
32
|
+
return [
|
|
33
|
+
{
|
|
34
|
+
id: '_default',
|
|
35
|
+
name: 'Default',
|
|
36
|
+
description: bodyOfType?.schema?.description,
|
|
37
|
+
data,
|
|
38
|
+
encoded: encodeRequestData(data, ctx.mediaAdapters, method.parameters ?? []),
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
export async function APIExample({ method, ctx, }) {
|
|
43
|
+
let { renderAPIExampleUsageTabs, renderAPIExampleLayout } = ctx.content ?? {};
|
|
44
|
+
renderAPIExampleLayout ?? (renderAPIExampleLayout = (slots) => {
|
|
45
|
+
return (_jsxs("div", { className: "prose-no-margin md:sticky md:top-(--fd-api-info-top) xl:w-[400px]", children: [slots.selector, slots.usageTabs, slots.responseTabs] }));
|
|
46
|
+
});
|
|
47
|
+
renderAPIExampleUsageTabs ?? (renderAPIExampleUsageTabs = (generators) => {
|
|
48
|
+
if (generators.length === 0)
|
|
49
|
+
return null;
|
|
50
|
+
return (_jsxs(CodeBlockTabs, { groupId: "fumadocs_openapi_requests", defaultValue: generators[0].id, children: [_jsx(CodeBlockTabsList, { children: generators.map((item) => (_jsx(CodeBlockTabsTrigger, { value: item.id, children: item.label ?? item.lang }, item.id))) }), generators.map((item) => (_jsx(CodeBlockTab, { value: item.id, children: _jsx(APIExampleUsageTabLazy, { ...item }) }, item.id)))] }));
|
|
51
|
+
});
|
|
52
|
+
let generators = [...defaultSamples];
|
|
53
|
+
if (ctx.generateCodeSamples) {
|
|
54
|
+
generators.push(...(await ctx.generateCodeSamples(method)));
|
|
55
|
+
}
|
|
56
|
+
if (method['x-codeSamples']) {
|
|
57
|
+
for (const sample of method['x-codeSamples']) {
|
|
58
|
+
generators.push('id' in sample && typeof sample.id === 'string'
|
|
59
|
+
? sample
|
|
60
|
+
: {
|
|
61
|
+
id: sample.lang,
|
|
62
|
+
...sample,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
generators = dedupe(generators);
|
|
67
|
+
return renderAPIExampleLayout({
|
|
68
|
+
selector: method['x-exclusiveCodeSample'] ? null : (_jsx(APIExampleSelectorLazy, {})),
|
|
69
|
+
usageTabs: await renderAPIExampleUsageTabs(generators, ctx),
|
|
70
|
+
responseTabs: _jsx(ResponseTabs, { operation: method, ctx: ctx }),
|
|
71
|
+
}, ctx);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Remove duplicated ids
|
|
75
|
+
*/
|
|
76
|
+
function dedupe(samples) {
|
|
77
|
+
const set = new Set();
|
|
78
|
+
const out = [];
|
|
79
|
+
for (let i = samples.length - 1; i >= 0; i--) {
|
|
80
|
+
const item = samples[i];
|
|
81
|
+
if (set.has(item.id))
|
|
82
|
+
continue;
|
|
83
|
+
set.add(item.id);
|
|
84
|
+
if (item.source !== false)
|
|
85
|
+
out.unshift(item);
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
function ResponseTabs({ operation, ctx, }) {
|
|
90
|
+
if (!operation.responses)
|
|
91
|
+
return null;
|
|
92
|
+
const tabs = [];
|
|
93
|
+
for (const [code, response] of Object.entries(operation.responses)) {
|
|
94
|
+
const media = response.content ? getPreferredType(response.content) : null;
|
|
95
|
+
const responseOfType = media ? response.content?.[media] : null;
|
|
96
|
+
const tab = {
|
|
97
|
+
code,
|
|
98
|
+
response,
|
|
99
|
+
mediaType: media,
|
|
100
|
+
};
|
|
101
|
+
if (responseOfType?.examples) {
|
|
102
|
+
tab.examples ?? (tab.examples = []);
|
|
103
|
+
for (const [key, sample] of Object.entries(responseOfType.examples)) {
|
|
104
|
+
const title = sample?.summary ?? `Example ${key}`;
|
|
105
|
+
tab.examples.push({
|
|
106
|
+
label: title,
|
|
107
|
+
sample: sample.value,
|
|
108
|
+
description: sample?.description,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else if (responseOfType?.example || responseOfType?.schema) {
|
|
113
|
+
tab.examples ?? (tab.examples = []);
|
|
114
|
+
tab.examples.push({
|
|
115
|
+
label: 'Example',
|
|
116
|
+
sample: responseOfType.example ?? sample(responseOfType.schema),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
tabs.push(tab);
|
|
120
|
+
}
|
|
121
|
+
const { renderResponseTabs = renderResponseTabsDefault } = ctx.content ?? {};
|
|
122
|
+
return renderResponseTabs(tabs, ctx);
|
|
123
|
+
}
|
|
124
|
+
function renderResponseTabsDefault(tabs, ctx) {
|
|
125
|
+
async function renderResponse(tab) {
|
|
126
|
+
const { examples = [] } = tab;
|
|
127
|
+
let slot = 'Empty';
|
|
128
|
+
if (examples.length > 1) {
|
|
129
|
+
slot = (_jsx(Accordions, { type: "single", className: "pt-2", defaultValue: examples[0].label, children: examples.map((example, i) => (_jsxs(AccordionItem, { value: example.label, children: [_jsx(AccordionHeader, { children: _jsx(AccordionTrigger, { children: example.label }) }), _jsxs(AccordionContent, { className: "prose-no-margin", children: [example.description && ctx.renderMarkdown(example.description), ctx.renderCodeBlock('json', JSON.stringify(example.sample, null, 2))] })] }, i))) }));
|
|
130
|
+
}
|
|
131
|
+
else if (examples.length === 1) {
|
|
132
|
+
const example = examples[0];
|
|
133
|
+
slot = (_jsxs(_Fragment, { children: [example.description && ctx.renderMarkdown(example.description), ctx.renderCodeBlock('json', JSON.stringify(example.sample, null, 2))] }));
|
|
134
|
+
}
|
|
135
|
+
return _jsx(Tab, { value: tab.code, children: slot });
|
|
136
|
+
}
|
|
137
|
+
if (tabs.length === 0)
|
|
138
|
+
return null;
|
|
139
|
+
return (_jsx(Tabs, { groupId: "fumadocs_openapi_responses", items: tabs.map((tab) => tab.code), children: tabs.map(renderResponse) }));
|
|
140
|
+
}
|