fumadocs-openapi 10.0.10 → 10.1.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.
Files changed (91) hide show
  1. package/dist/generate-file.d.ts +6 -5
  2. package/dist/generate-file.d.ts.map +1 -1
  3. package/dist/generate-file.js +44 -37
  4. package/dist/playground/client.d.ts +9 -7
  5. package/dist/playground/client.d.ts.map +1 -1
  6. package/dist/playground/client.js +7 -7
  7. package/dist/playground/components/inputs.d.ts +6 -6
  8. package/dist/playground/components/inputs.d.ts.map +1 -1
  9. package/dist/playground/components/inputs.js +13 -12
  10. package/dist/playground/get-default-values.d.ts +2 -2
  11. package/dist/playground/get-default-values.d.ts.map +1 -1
  12. package/dist/playground/index.d.ts +1 -2
  13. package/dist/playground/index.d.ts.map +1 -1
  14. package/dist/playground/index.js +2 -0
  15. package/dist/playground/schema.d.ts +22 -8
  16. package/dist/playground/schema.d.ts.map +1 -1
  17. package/dist/playground/schema.js +29 -34
  18. package/dist/requests/generators/index.d.ts +1 -1
  19. package/dist/requests/generators/index.d.ts.map +1 -1
  20. package/dist/server/create.d.ts +1 -1
  21. package/dist/server/create.d.ts.map +1 -1
  22. package/dist/server/source-api.d.ts +5 -3
  23. package/dist/server/source-api.d.ts.map +1 -1
  24. package/dist/server/source-api.js +13 -7
  25. package/dist/types.d.ts +3 -3
  26. package/dist/types.d.ts.map +1 -1
  27. package/dist/ui/api-page.d.ts +16 -8
  28. package/dist/ui/api-page.d.ts.map +1 -1
  29. package/dist/ui/api-page.js +7 -7
  30. package/dist/ui/client/index.d.ts +2 -2
  31. package/dist/ui/client/index.d.ts.map +1 -1
  32. package/dist/ui/operation/index.d.ts +4 -3
  33. package/dist/ui/operation/index.d.ts.map +1 -1
  34. package/dist/ui/operation/index.js +45 -24
  35. package/dist/ui/operation/request-tabs.d.ts +18 -0
  36. package/dist/ui/operation/request-tabs.d.ts.map +1 -0
  37. package/dist/ui/operation/request-tabs.js +143 -0
  38. package/dist/ui/operation/response-tabs.d.ts +32 -0
  39. package/dist/ui/operation/response-tabs.d.ts.map +1 -0
  40. package/dist/ui/operation/response-tabs.js +59 -0
  41. package/dist/ui/operation/usage-tabs/client.d.ts +23 -0
  42. package/dist/ui/operation/usage-tabs/client.d.ts.map +1 -0
  43. package/dist/ui/operation/{example-panel → usage-tabs}/client.js +50 -6
  44. package/dist/ui/operation/usage-tabs/index.d.ts +26 -0
  45. package/dist/ui/operation/usage-tabs/index.d.ts.map +1 -0
  46. package/dist/ui/operation/usage-tabs/index.js +52 -0
  47. package/dist/ui/operation/usage-tabs/lazy.d.ts +4 -0
  48. package/dist/ui/operation/usage-tabs/lazy.d.ts.map +1 -0
  49. package/dist/ui/operation/usage-tabs/lazy.js +5 -0
  50. package/dist/ui/schema/client.d.ts +1 -3
  51. package/dist/ui/schema/client.d.ts.map +1 -1
  52. package/dist/ui/schema/client.js +13 -17
  53. package/dist/ui/schema/index.d.ts +19 -5
  54. package/dist/ui/schema/index.d.ts.map +1 -1
  55. package/dist/ui/schema/index.js +69 -29
  56. package/dist/utils/deep-equal.d.ts +2 -0
  57. package/dist/utils/deep-equal.d.ts.map +1 -0
  58. package/dist/utils/deep-equal.js +27 -0
  59. package/dist/utils/merge-schema.d.ts +7 -0
  60. package/dist/utils/merge-schema.d.ts.map +1 -0
  61. package/dist/utils/merge-schema.js +179 -0
  62. package/dist/utils/pages/to-body.d.ts.map +1 -1
  63. package/dist/utils/pages/to-body.js +2 -3
  64. package/dist/utils/pages/to-text.d.ts.map +1 -1
  65. package/dist/utils/pages/to-text.js +31 -16
  66. package/dist/utils/schema-to-string.d.ts.map +1 -1
  67. package/dist/utils/schema-to-string.js +8 -5
  68. package/dist/utils/use-query.d.ts +1 -0
  69. package/dist/utils/use-query.d.ts.map +1 -1
  70. package/dist/utils/use-query.js +5 -0
  71. package/package.json +6 -6
  72. package/dist/ui/contexts/operation.d.ts +0 -20
  73. package/dist/ui/contexts/operation.d.ts.map +0 -1
  74. package/dist/ui/contexts/operation.js +0 -48
  75. package/dist/ui/contexts/operation.lazy.d.ts +0 -2
  76. package/dist/ui/contexts/operation.lazy.d.ts.map +0 -1
  77. package/dist/ui/contexts/operation.lazy.js +0 -3
  78. package/dist/ui/operation/example-panel/client.d.ts +0 -4
  79. package/dist/ui/operation/example-panel/client.d.ts.map +0 -1
  80. package/dist/ui/operation/example-panel/index.d.ts +0 -58
  81. package/dist/ui/operation/example-panel/index.d.ts.map +0 -1
  82. package/dist/ui/operation/example-panel/index.js +0 -140
  83. package/dist/ui/operation/example-panel/lazy.d.ts +0 -3
  84. package/dist/ui/operation/example-panel/lazy.d.ts.map +0 -1
  85. package/dist/ui/operation/example-panel/lazy.js +0 -4
  86. package/dist/ui/operation/get-request-data.d.ts +0 -4
  87. package/dist/ui/operation/get-request-data.d.ts.map +0 -1
  88. package/dist/ui/operation/get-request-data.js +0 -70
  89. package/dist/utils/combine-schema.d.ts +0 -6
  90. package/dist/utils/combine-schema.d.ts.map +0 -1
  91. package/dist/utils/combine-schema.js +0 -51
@@ -1,9 +1,9 @@
1
- import { Fragment as _Fragment, jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Fragment } from 'react';
3
3
  import { createMethod, methodKeys, } from '../../utils/schema.js';
4
4
  import { idToTitle } from '../../utils/id-to-title.js';
5
5
  import { Schema } from '../schema/index.js';
6
- import { APIExample, getAPIExamples } from '../../ui/operation/example-panel/index.js';
6
+ import { UsageTabs } from '../../ui/operation/usage-tabs/index.js';
7
7
  import { MethodLabel } from '../../ui/components/method-label.js';
8
8
  import { getTypescriptSchema } from '../../utils/get-typescript-schema.js';
9
9
  import { CopyResponseTypeScript, SelectTab, SelectTabs, SelectTabTrigger, } from './client.js';
@@ -11,57 +11,70 @@ import { AccordionContent, AccordionHeader, AccordionItem, Accordions, Accordion
11
11
  import { isMediaTypeSupported } from '../../requests/media/adapter.js';
12
12
  import { cn } from 'fumadocs-ui/utils/cn';
13
13
  import { APIPlayground } from '../../playground/index.js';
14
- import { OperationProviderLazy } from '../contexts/operation.lazy.js';
14
+ import { RequestTabs, getExampleRequests } from './request-tabs.js';
15
+ import { UsageTabsProviderLazy } from './usage-tabs/lazy.js';
15
16
  const ParamTypes = {
16
17
  path: 'Path Parameters',
17
18
  query: 'Query Parameters',
18
19
  header: 'Header Parameters',
19
20
  cookie: 'Cookie Parameters',
20
21
  };
21
- export async function Operation({ type = 'operation', path, method, ctx, hasHead, headingLevel = 2, }) {
22
+ export async function Operation({ type = 'operation', path, method, ctx, showTitle, showDescription, headingLevel = 2, }) {
22
23
  const { schema: { dereferenced }, } = ctx;
23
24
  const body = method.requestBody;
24
25
  let headNode = null;
26
+ const descriptionNode = showDescription &&
27
+ method.description &&
28
+ ctx.renderMarkdown(method.description);
25
29
  let bodyNode = null;
26
30
  let authNode = null;
27
31
  let responseNode = null;
28
32
  let callbacksNode = null;
29
- if (hasHead) {
33
+ if (showTitle) {
30
34
  const title = method.summary ??
31
35
  (method.operationId ? idToTitle(method.operationId) : path);
32
- headNode = (_jsxs(_Fragment, { children: [ctx.renderHeading(headingLevel, title), method.description && ctx.renderMarkdown(method.description)] }));
36
+ headNode = ctx.renderHeading(headingLevel, title);
33
37
  headingLevel++;
34
38
  }
35
39
  const contentTypes = body ? Object.entries(body.content) : null;
36
40
  if (body && contentTypes && contentTypes.length > 0) {
37
41
  const [defaultValue] = contentTypes[0];
38
- bodyNode = (_jsxs(SelectTabs, { defaultValue: defaultValue, children: [_jsxs("div", { className: "flex gap-2 items-end justify-between", children: [ctx.renderHeading(headingLevel, 'Request Body'), _jsx(SelectTabTrigger, { items: contentTypes.map(([key]) => key), className: "mb-4" })] }), body.description && ctx.renderMarkdown(body.description), contentTypes.map(([type, content]) => {
42
+ bodyNode = (_jsxs(SelectTabs, { defaultValue: defaultValue, children: [_jsxs("div", { className: "flex gap-2 items-end justify-between", children: [ctx.renderHeading(headingLevel, 'Request Body', {
43
+ className: 'my-0!',
44
+ }), contentTypes.length > 1 ? (_jsx(SelectTabTrigger, { items: contentTypes.map(([key]) => key) })) : (_jsx("p", { className: "text-sm text-fd-muted-foreground font-medium not-prose", children: defaultValue }))] }), body.description && ctx.renderMarkdown(body.description), contentTypes.map(([type, content]) => {
39
45
  if (!isMediaTypeSupported(type, ctx.mediaAdapters)) {
40
46
  throw new Error(`Media type ${type} is not supported (in ${path})`);
41
47
  }
42
- return (_jsx(SelectTab, { value: type, children: _jsx(Schema, { name: "body", as: "body", root: (content.schema ?? {}), required: body.required, readOnly: method.method === 'GET', writeOnly: method.method !== 'GET', ctx: ctx }) }, type));
48
+ return (_jsx(SelectTab, { value: type, children: _jsx(Schema, { client: {
49
+ name: 'body',
50
+ as: 'body',
51
+ required: body.required,
52
+ }, root: (content.schema ?? {}), readOnly: method.method === 'GET', writeOnly: method.method !== 'GET', ctx: ctx }) }, type));
43
53
  })] }));
44
54
  }
45
55
  if (method.responses && ctx.showResponseSchema !== false) {
46
56
  const statuses = Object.keys(method.responses);
47
- responseNode = (_jsxs(_Fragment, { children: [ctx.renderHeading(headingLevel, 'Response Body'), _jsx(Accordions, { type: "multiple", children: statuses.map((status) => (_jsx(AccordionItem, { value: status, children: _jsx(ResponseAccordion, { status: status, operation: method, ctx: ctx }) }, status))) })] }));
57
+ responseNode = (_jsxs(_Fragment, { children: [ctx.renderHeading(headingLevel, 'Response Body'), _jsx(Accordions, { type: "multiple", children: statuses.map((status) => (_jsx(ResponseAccordion, { status: status, operation: method, ctx: ctx }, status))) })] }));
48
58
  }
49
59
  const parameterNode = Object.entries(ParamTypes).map(([type, title]) => {
50
60
  const params = method.parameters?.filter((param) => param.in === type);
51
61
  if (!params || params.length === 0)
52
62
  return;
53
- return (_jsxs(Fragment, { children: [ctx.renderHeading(headingLevel, title), _jsx("div", { className: "flex flex-col", children: params.map((param) => (_jsx(Schema, { name: param.name, root: {
63
+ return (_jsxs(Fragment, { children: [ctx.renderHeading(headingLevel, title), _jsx("div", { className: "flex flex-col", children: params.map((param) => (_jsx(Schema, { client: {
64
+ name: param.name,
65
+ required: param.required,
66
+ }, root: {
54
67
  ...param.schema,
55
68
  description: param.description ?? param.schema?.description,
56
69
  deprecated: (param.deprecated ?? false) ||
57
70
  (param.schema?.deprecated ?? false),
58
- }, required: param.required, readOnly: method.method === 'GET', writeOnly: method.method !== 'GET', ctx: ctx }, param.name))) })] }, type));
71
+ }, readOnly: method.method === 'GET', writeOnly: method.method !== 'GET', ctx: ctx }, param.name))) })] }, type));
59
72
  });
60
73
  const securities = (method.security ?? dereferenced.security ?? []).filter((v) => Object.keys(v).length > 0);
61
74
  if (type === 'operation' && securities.length > 0) {
62
75
  const securitySchemes = dereferenced.components?.securitySchemes;
63
76
  const names = securities.map((security) => Object.keys(security).join(' & '));
64
- authNode = (_jsxs(SelectTabs, { defaultValue: names[0], children: [_jsxs("div", { className: "flex items-end justify-between gap-2", children: [ctx.renderHeading(headingLevel, 'Authorization'), _jsx(SelectTabTrigger, { items: names, className: "mb-4" })] }), securities.map((security, i) => (_jsx(SelectTab, { value: names[i], children: Object.entries(security).map(([key, scopes]) => {
77
+ authNode = (_jsxs(SelectTabs, { defaultValue: names[0], children: [_jsxs("div", { className: "flex items-end justify-between gap-2", children: [ctx.renderHeading(headingLevel, 'Authorization'), names.length > 1 ? (_jsx(SelectTabTrigger, { items: names, className: "mb-4" })) : (_jsx("p", { className: "text-sm text-fd-muted-foreground font-medium not-prose mb-7", children: names[0] }))] }), securities.map((security, i) => (_jsx(SelectTab, { value: names[i], children: Object.entries(security).map(([key, scopes]) => {
65
78
  const scheme = securitySchemes?.[key];
66
79
  if (!scheme)
67
80
  return;
@@ -71,37 +84,38 @@ export async function Operation({ type = 'operation', path, method, ctx, hasHead
71
84
  const callbacks = method.callbacks ? Object.entries(method.callbacks) : null;
72
85
  if (callbacks && callbacks.length > 0) {
73
86
  const [defaultValue] = callbacks[0];
74
- callbacksNode = (_jsxs(SelectTabs, { defaultValue: defaultValue, children: [_jsxs("div", { className: "flex justify-between gap-2 items-end", children: [ctx.renderHeading(headingLevel, 'Callbacks'), _jsx(SelectTabTrigger, { items: callbacks.map(([key]) => key), className: "mb-4" })] }), callbacks.map(([name, callback]) => (_jsx(SelectTab, { value: name, children: _jsx(WebhookCallback, { callback: callback, ctx: ctx, headingLevel: headingLevel }) }, name)))] }));
87
+ callbacksNode = (_jsxs(SelectTabs, { defaultValue: defaultValue, children: [_jsxs("div", { className: "flex justify-between gap-2 items-end", children: [ctx.renderHeading(headingLevel, 'Callbacks'), callbacks.length > 1 ? (_jsx(SelectTabTrigger, { items: callbacks.map(([key]) => key), className: "mb-4" })) : (_jsx("p", { className: "text-sm text-fd-muted-foreground font-medium not-prose mb-7", children: defaultValue }))] }), callbacks.map(([name, callback]) => (_jsx(SelectTab, { value: name, children: _jsx(WebhookCallback, { callback: callback, ctx: ctx, headingLevel: headingLevel }) }, name)))] }));
75
88
  }
76
89
  let { renderOperationLayout, renderWebhookLayout } = ctx.content ?? {};
77
90
  if (type === 'operation') {
78
91
  renderOperationLayout ?? (renderOperationLayout = (slots) => {
79
- return (_jsxs("div", { className: "flex flex-col gap-x-6 gap-y-4 xl:flex-row xl:items-start", style: {
80
- '--fd-api-info-top': 'calc(12px + var(--fd-nav-height) + var(--fd-banner-height) + var(--fd-tocnav-height, 0px))',
81
- }, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [slots.header, slots.apiPlayground, slots.authSchemes, slots.paremeters, slots.body, slots.responses, slots.callbacks] }), slots.apiExample] }));
92
+ return (_jsxs("div", { className: "flex flex-col gap-x-6 gap-y-4 @4xl:flex-row @4xl:items-start", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [slots.header, slots.apiPlayground, slots.description, slots.authSchemes, slots.paremeters, slots.body, slots.responses, slots.callbacks] }), _jsx("div", { className: "@4xl:sticky @4xl:top-[calc(var(--fd-docs-row-1,2rem)+1rem)] @4xl:w-[400px]", children: slots.apiExample })] }));
82
93
  });
83
94
  const playgroundEnabled = ctx.playground?.enabled ?? true;
84
95
  const content = await renderOperationLayout({
85
96
  header: headNode,
97
+ description: descriptionNode,
86
98
  authSchemes: authNode,
87
99
  body: bodyNode,
88
100
  callbacks: callbacksNode,
89
101
  paremeters: parameterNode,
90
102
  responses: responseNode,
91
103
  apiPlayground: playgroundEnabled ? (_jsx(APIPlayground, { path: path, method: method, ctx: ctx })) : (_jsxs("div", { className: "flex flex-row items-center gap-2.5 p-3 rounded-xl border bg-fd-card text-fd-card-foreground not-prose", children: [_jsx(MethodLabel, { className: "text-xs", children: method.method }), _jsx("code", { className: "flex-1 overflow-auto text-nowrap text-[0.8125rem] text-fd-muted-foreground", children: path })] })),
92
- apiExample: _jsx(APIExample, { method: method, ctx: ctx }),
104
+ apiExample: _jsx(UsageTabs, { method: method, ctx: ctx }),
93
105
  }, ctx, method);
94
- return (_jsx(OperationProviderLazy, { defaultExampleId: method['x-exclusiveCodeSample'] ?? method['x-selectedCodeSample'], route: path, examples: getAPIExamples(path, method, ctx), children: content }));
106
+ return (_jsx(UsageTabsProviderLazy, { defaultExampleId: method['x-exclusiveCodeSample'] ?? method['x-selectedCodeSample'], route: path, examples: getExampleRequests(path, method, ctx), children: content }));
95
107
  }
96
108
  else {
97
- renderWebhookLayout ?? (renderWebhookLayout = (slots) => (_jsxs("div", { children: [slots.header, slots.authSchemes, slots.paremeters, slots.body, slots.responses, slots.callbacks] })));
109
+ renderWebhookLayout ?? (renderWebhookLayout = (slots) => (_jsxs("div", { className: "flex flex-col-reverse gap-x-6 gap-y-4 @4xl:flex-row @4xl:items-start", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [slots.header, slots.description, slots.authSchemes, slots.paremeters, slots.body, slots.responses, slots.callbacks] }), _jsx("div", { className: "@4xl:sticky @4xl:top-[calc(var(--fd-docs-row-1,2rem)+1rem)] @4xl:w-[400px]", children: slots.requests })] })));
98
110
  return renderWebhookLayout({
99
111
  header: headNode,
112
+ description: descriptionNode,
100
113
  authSchemes: authNode,
101
114
  body: bodyNode,
102
115
  callbacks: callbacksNode,
103
116
  paremeters: parameterNode,
104
117
  responses: responseNode,
118
+ requests: _jsx(RequestTabs, { path: path, operation: method, ctx: ctx }),
105
119
  });
106
120
  }
107
121
  }
@@ -109,11 +123,15 @@ async function ResponseAccordion({ status, operation, ctx, }) {
109
123
  const response = operation.responses[status];
110
124
  const { generateTypeScriptSchema } = ctx;
111
125
  const contentTypes = response.content ? Object.entries(response.content) : [];
112
- if (contentTypes.length === 0) {
113
- return (response.description && (_jsx("div", { className: "prose-no-margin", children: ctx.renderMarkdown(response.description) })));
126
+ let wrapper = (children) => children;
127
+ let selectorNode = null;
128
+ if (contentTypes.length > 0) {
129
+ const [defaultValue] = contentTypes[0];
130
+ selectorNode =
131
+ contentTypes.length === 1 ? (_jsx("p", { className: "text-sm text-fd-muted-foreground", children: defaultValue })) : (_jsx(SelectTabTrigger, { items: contentTypes.map(([key]) => key) }));
132
+ wrapper = (children) => (_jsx(SelectTabs, { defaultValue: defaultValue, children: children }));
114
133
  }
115
- const [defaultValue] = contentTypes[0];
116
- return (_jsxs(SelectTabs, { defaultValue: defaultValue, children: [_jsxs(AccordionHeader, { children: [_jsx(AccordionTrigger, { className: "font-mono", children: status }), contentTypes.length > 1 ? (_jsx(SelectTabTrigger, { items: contentTypes.map(([key]) => key) })) : (_jsx("p", { className: "text-sm text-fd-muted-foreground", children: defaultValue }))] }), _jsxs(AccordionContent, { className: "ps-4.5", children: [response.description && (_jsx("div", { className: "prose-no-margin", children: ctx.renderMarkdown(response.description) })), contentTypes.map(async ([type, resType]) => {
134
+ return wrapper(_jsxs(AccordionItem, { value: status, children: [_jsxs(AccordionHeader, { children: [_jsx(AccordionTrigger, { className: "font-mono", children: status }), selectorNode] }), _jsxs(AccordionContent, { className: "ps-4.5", children: [response.description && (_jsx("div", { className: "prose-no-margin mb-2", children: ctx.renderMarkdown(response.description) })), contentTypes.map(async ([type, resType]) => {
117
135
  const schema = resType.schema;
118
136
  let ts;
119
137
  if (generateTypeScriptSchema) {
@@ -122,7 +140,10 @@ async function ResponseAccordion({ status, operation, ctx, }) {
122
140
  else if (generateTypeScriptSchema === undefined && schema) {
123
141
  ts = await getTypescriptSchema(schema, ctx);
124
142
  }
125
- return (_jsxs(SelectTab, { value: type, className: "my-2", children: [ts && _jsx(CopyResponseTypeScript, { code: ts }), schema && (_jsx("div", { className: "border px-3 py-2 rounded-lg", children: _jsx(Schema, { name: "response", root: schema, as: "body", readOnly: true, ctx: ctx }) }))] }, type));
143
+ return (_jsxs(SelectTab, { value: type, className: "mb-2", children: [ts && _jsx(CopyResponseTypeScript, { code: ts }), schema && (_jsx("div", { className: "border px-3 py-2 rounded-lg", children: _jsx(Schema, { client: {
144
+ name: 'response',
145
+ as: 'body',
146
+ }, root: schema, readOnly: true, ctx: ctx }) }))] }, type));
126
147
  })] })] }));
127
148
  }
128
149
  function WebhookCallback({ callback, ctx, headingLevel, }) {
@@ -0,0 +1,18 @@
1
+ import type { MethodInformation, RenderContext } from '../../types.js';
2
+ import { type NoReference } from '../../utils/schema.js';
3
+ import type { ReactNode } from 'react';
4
+ import type { RawRequestData, RequestData } from '../../requests/types.js';
5
+ export interface ExampleRequestItem {
6
+ id: string;
7
+ name: string;
8
+ description?: string;
9
+ data: RawRequestData;
10
+ encoded: RequestData;
11
+ }
12
+ export declare function getExampleRequests(path: string, operation: NoReference<MethodInformation>, ctx: RenderContext): ExampleRequestItem[];
13
+ export declare function RequestTabs({ path, operation, ctx, }: {
14
+ path: string;
15
+ operation: NoReference<MethodInformation>;
16
+ ctx: RenderContext;
17
+ }): Promise<string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<ReactNode> | null | undefined>;
18
+ //# sourceMappingURL=request-tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-tabs.d.ts","sourceRoot":"","sources":["../../../src/ui/operation/request-tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,KAAK,WAAW,EAAoB,MAAM,gBAAgB,CAAC;AASpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAWpE,MAAM,WAAW,kBAAkB;IACjC,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,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,WAAW,CAAC,iBAAiB,CAAC,EACzC,GAAG,EAAE,aAAa,GACjB,kBAAkB,EAAE,CA0CtB;AAkFD,wBAAsB,WAAW,CAAC,EAChC,IAAI,EACJ,SAAS,EACT,GAAG,GACJ,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAAC;IAC1C,GAAG,EAAE,aAAa,CAAC;CACpB,kIASA"}
@@ -0,0 +1,143 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { getPreferredType } from '../../utils/schema.js';
3
+ import { Accordions, AccordionItem, AccordionHeader, AccordionTrigger, AccordionContent, } from '../../ui/components/accordion.js';
4
+ import { sample } from 'openapi-sampler';
5
+ import { encodeRequestData } from '../../requests/media/encode.js';
6
+ import { Tabs, TabsContent, TabsList, TabsTrigger, } from 'fumadocs-ui/components/tabs';
7
+ import { resolveRequestData } from '../../utils/url.js';
8
+ import { MethodLabel } from '../components/method-label.js';
9
+ export function getExampleRequests(path, operation, ctx) {
10
+ const media = operation.requestBody
11
+ ? getPreferredType(operation.requestBody.content)
12
+ : null;
13
+ const bodyOfType = media ? operation.requestBody?.content[media] : null;
14
+ if (bodyOfType?.examples) {
15
+ const result = [];
16
+ for (const [key, value] of Object.entries(bodyOfType.examples)) {
17
+ const data = getRequestData(path, operation, key, ctx);
18
+ result.push({
19
+ id: key,
20
+ name: value.summary ?? key,
21
+ description: value.description,
22
+ data,
23
+ encoded: encodeRequestData(data, ctx.mediaAdapters, operation.parameters ?? []),
24
+ });
25
+ }
26
+ if (result.length > 0)
27
+ return result;
28
+ }
29
+ const data = getRequestData(path, operation, null, ctx);
30
+ return [
31
+ {
32
+ id: '_default',
33
+ name: 'Default',
34
+ description: bodyOfType?.schema?.description,
35
+ data,
36
+ encoded: encodeRequestData(data, ctx.mediaAdapters, operation.parameters ?? []),
37
+ },
38
+ ];
39
+ }
40
+ function getRequestData(path, method, sampleKey, _ctx) {
41
+ const result = {
42
+ path: {},
43
+ cookie: {},
44
+ header: {},
45
+ query: {},
46
+ method: method.method,
47
+ };
48
+ for (const param of method.parameters ?? []) {
49
+ let schema = param.schema;
50
+ let value;
51
+ if (!schema && param.content) {
52
+ const type = getPreferredType(param.content);
53
+ const content = type ? param.content[type] : undefined;
54
+ if (!content || !content.schema)
55
+ throw new Error(`Cannot find parameter schema for ${param.name} in ${path} ${method.method}`);
56
+ schema = content.schema;
57
+ value = content.example ?? param.example;
58
+ }
59
+ else {
60
+ value = param.example;
61
+ }
62
+ if (param.required) {
63
+ value ?? (value = sample(schema));
64
+ }
65
+ else if (value === undefined) {
66
+ continue;
67
+ }
68
+ switch (param.in) {
69
+ case 'cookie':
70
+ result.cookie[param.name] = value;
71
+ break;
72
+ case 'header':
73
+ result.header[param.name] = value;
74
+ break;
75
+ case 'query':
76
+ result.query[param.name] = value;
77
+ break;
78
+ default:
79
+ result.path[param.name] = value;
80
+ }
81
+ }
82
+ if (method.requestBody) {
83
+ const body = method.requestBody.content;
84
+ const type = getPreferredType(body);
85
+ if (!type)
86
+ throw new Error(`Cannot find body schema for ${path} ${method.method}: missing media type`);
87
+ result.bodyMediaType = type;
88
+ const bodyOfType = body[type];
89
+ if (bodyOfType.examples && sampleKey) {
90
+ result.body = bodyOfType.examples[sampleKey].value;
91
+ }
92
+ else if (bodyOfType.example) {
93
+ result.body = bodyOfType.example;
94
+ }
95
+ else {
96
+ result.body = sample((bodyOfType?.schema ?? {}), {
97
+ skipReadOnly: method.method !== 'GET',
98
+ skipWriteOnly: method.method === 'GET',
99
+ skipNonRequired: true,
100
+ });
101
+ }
102
+ }
103
+ return result;
104
+ }
105
+ export async function RequestTabs({ path, operation, ctx, }) {
106
+ if (!operation.requestBody)
107
+ return null;
108
+ const { renderRequestTabs = renderRequestTabsDefault } = ctx.content ?? {};
109
+ return renderRequestTabs(getExampleRequests(path, operation, ctx), {
110
+ ...ctx,
111
+ route: path,
112
+ operation,
113
+ });
114
+ }
115
+ function renderRequestTabsDefault(items, ctx) {
116
+ function renderItem(item) {
117
+ const requestData = item.data;
118
+ const displayNames = {
119
+ body: (_jsxs(_Fragment, { children: ["Body", _jsx("code", { className: "text-xs text-fd-muted-foreground ms-auto", children: requestData.bodyMediaType })] })),
120
+ cookie: 'Cookie',
121
+ header: 'Header',
122
+ query: 'Query Parameters',
123
+ path: 'Path Parameters',
124
+ };
125
+ return (_jsxs(_Fragment, { children: [item.description && ctx.renderMarkdown(item.description), _jsxs("div", { className: "flex flex-row gap-2 items-center justify-between", children: [_jsx(MethodLabel, { children: requestData.method }), _jsx("code", { children: resolveRequestData(ctx.route, item.encoded) })] }), _jsx(Accordions, { type: "multiple", className: "mt-2", children: Object.entries(displayNames).map(([k, v]) => {
126
+ const data = requestData[k];
127
+ if (!data || Object.keys(data).length === 0)
128
+ return;
129
+ return (_jsxs(AccordionItem, { value: k, children: [_jsx(AccordionHeader, { children: _jsx(AccordionTrigger, { children: v }) }), _jsx(AccordionContent, { className: "prose-no-margin", children: ctx.renderCodeBlock('json', JSON.stringify(data, null, 2)) })] }, k));
130
+ }) })] }));
131
+ }
132
+ let children;
133
+ if (items.length > 1) {
134
+ children = (_jsxs(Tabs, { defaultValue: items[0].id, children: [_jsx(TabsList, { children: items.map((item) => (_jsx(TabsTrigger, { value: item.id, children: item.name }, item.id))) }), items.map((item) => (_jsx(TabsContent, { value: item.id, children: renderItem(item) }, item.id)))] }));
135
+ }
136
+ else if (items.length === 1) {
137
+ children = renderItem(items[0]);
138
+ }
139
+ else {
140
+ children = _jsx("p", { className: "text-fd-muted-foreground text-xs", children: "Empty" });
141
+ }
142
+ return (_jsxs("div", { className: "p-3 rounded-xl border prose-no-margin bg-fd-card text-fd-card-foreground shadow-md", children: [_jsx("p", { className: "font-semibold border-b pb-2", children: "Example Requests" }), children] }));
143
+ }
@@ -0,0 +1,32 @@
1
+ import type { MethodInformation, RenderContext, ResponseObject } from '../../types.js';
2
+ import { type NoReference } from '../../utils/schema.js';
3
+ import type { ReactNode } from 'react';
4
+ export interface ResponseTab {
5
+ /**
6
+ * HTTP response code
7
+ */
8
+ code: string;
9
+ response: NoReference<ResponseObject>;
10
+ /**
11
+ * media type of response
12
+ */
13
+ mediaType: string | null;
14
+ examples?: ResponseExample[];
15
+ }
16
+ interface ResponseExample {
17
+ /**
18
+ * generated/defined example data
19
+ */
20
+ sample: unknown;
21
+ label: string;
22
+ /**
23
+ * description (in Markdown)
24
+ */
25
+ description?: string;
26
+ }
27
+ export declare function ResponseTabs({ operation, ctx, }: {
28
+ operation: NoReference<MethodInformation>;
29
+ ctx: RenderContext;
30
+ }): ReactNode | Promise<ReactNode>;
31
+ export {};
32
+ //# sourceMappingURL=response-tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-tabs.d.ts","sourceRoot":"","sources":["../../../src/ui/operation/response-tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,KAAK,WAAW,EAAoB,MAAM,gBAAgB,CAAC;AAUpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,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,eAAe,EAAE,CAAC;CAC9B;AAED,UAAU,eAAe;IACvB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,GAAG,GACJ,EAAE;IACD,SAAS,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAAC;IAC1C,GAAG,EAAE,aAAa,CAAC;CACpB,kCAwCA"}
@@ -0,0 +1,59 @@
1
+ import { Fragment as _Fragment, jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { getPreferredType } from '../../utils/schema.js';
3
+ import { Accordions, AccordionItem, AccordionHeader, AccordionTrigger, AccordionContent, } from '../../ui/components/accordion.js';
4
+ import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
5
+ import { sample } from 'openapi-sampler';
6
+ export function ResponseTabs({ operation, ctx, }) {
7
+ if (!operation.responses)
8
+ return null;
9
+ const tabs = [];
10
+ for (const [code, response] of Object.entries(operation.responses)) {
11
+ const media = response.content ? getPreferredType(response.content) : null;
12
+ const responseOfType = media ? response.content?.[media] : null;
13
+ const tab = {
14
+ code,
15
+ response,
16
+ mediaType: media,
17
+ };
18
+ if (responseOfType?.examples) {
19
+ tab.examples ?? (tab.examples = []);
20
+ for (const [key, sample] of Object.entries(responseOfType.examples)) {
21
+ const title = sample?.summary ?? `Example ${key}`;
22
+ tab.examples.push({
23
+ label: title,
24
+ sample: sample.value,
25
+ description: sample?.description,
26
+ });
27
+ }
28
+ }
29
+ else if (responseOfType?.example || responseOfType?.schema) {
30
+ tab.examples ?? (tab.examples = []);
31
+ tab.examples.push({
32
+ label: 'Example',
33
+ sample: responseOfType.example ?? sample(responseOfType.schema),
34
+ });
35
+ }
36
+ tabs.push(tab);
37
+ }
38
+ const { renderResponseTabs = renderResponseTabsDefault } = ctx.content ?? {};
39
+ return renderResponseTabs(tabs, ctx);
40
+ }
41
+ function renderResponseTabsDefault(tabs, ctx) {
42
+ function renderExampleContent(example) {
43
+ return (_jsxs(_Fragment, { children: [example.description && ctx.renderMarkdown(example.description), ctx.renderCodeBlock('json', JSON.stringify(example.sample, null, 2))] }));
44
+ }
45
+ async function renderResponse(tab) {
46
+ const { examples = [] } = tab;
47
+ let slot = 'Empty';
48
+ if (examples.length > 1) {
49
+ 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 }) }), _jsx(AccordionContent, { className: "prose-no-margin", children: renderExampleContent(example) })] }, i))) }));
50
+ }
51
+ else if (examples.length === 1) {
52
+ slot = renderExampleContent(examples[0]);
53
+ }
54
+ return _jsx(Tab, { value: tab.code, children: slot });
55
+ }
56
+ if (tabs.length === 0)
57
+ return null;
58
+ return (_jsx(Tabs, { groupId: "fumadocs_openapi_responses", items: tabs.map((tab) => tab.code), children: tabs.map(renderResponse) }));
59
+ }
@@ -0,0 +1,23 @@
1
+ import { ReactNode } from 'react';
2
+ import type { CodeUsageGenerator } from './index.js';
3
+ import type { ExampleRequestItem } from '../request-tabs.js';
4
+ import type { RawRequestData, RequestData } from '../../../requests/types.js';
5
+ export type ExampleUpdateListener = (data: RawRequestData, encoded: RequestData) => void;
6
+ export declare function UsageTabsProvider({ route, examples, defaultExampleId, children, }: {
7
+ route: string;
8
+ examples: ExampleRequestItem[];
9
+ defaultExampleId?: string;
10
+ children: ReactNode;
11
+ }): import("react/jsx-runtime").JSX.Element;
12
+ export declare function useExampleRequests(): {
13
+ route: string;
14
+ examples: ExampleRequestItem[];
15
+ example: string | undefined;
16
+ setExample: (id: string) => void;
17
+ setExampleData: (data: RawRequestData, encoded: RequestData) => void;
18
+ addListener: (listener: ExampleUpdateListener) => void;
19
+ removeListener: (listener: ExampleUpdateListener) => void;
20
+ };
21
+ export declare function UsageTabsSelector(): import("react/jsx-runtime").JSX.Element | null;
22
+ export declare function UsageTab(sample: CodeUsageGenerator): import("react/jsx-runtime").JSX.Element | null;
23
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/ui/operation/usage-tabs/client.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAKL,SAAS,EAGV,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,GAAG,CAAC;AAC5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,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,kBAAkB,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB,2CAwDA;AAED,wBAAgB,kBAAkB;WA9EzB,MAAM;cACH,kBAAkB,EAAE;aACrB,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;AAED,wBAAgB,iBAAiB,mDAkChC;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,kBAAkB,kDAkDlD"}
@@ -1,13 +1,57 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useApiContext, useServerSelectContext } from '../../../ui/contexts/api.js';
4
- import { useOperationContext, } from '../../../ui/contexts/operation.js';
5
4
  import { joinURL, withBase, resolveServerUrl, resolveRequestData, } from '../../../utils/url.js';
6
5
  import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, } from '../../../ui/components/select.js';
7
6
  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();
7
+ import { useState, useEffect, useMemo, createContext, useRef, use, } from 'react';
8
+ const Context = createContext(null);
9
+ export function UsageTabsProvider({ route, examples, defaultExampleId, children, }) {
10
+ const [example, setExample] = useState(() => defaultExampleId ?? examples.at(0)?.id);
11
+ const listeners = useRef([]);
12
+ return (_jsx(Context, { value: useMemo(() => ({
13
+ example,
14
+ route,
15
+ setExample: (newKey) => {
16
+ const example = examples.find((example) => example.id === newKey);
17
+ if (!example)
18
+ return;
19
+ setExample(newKey);
20
+ for (const listener of listeners.current) {
21
+ listener(example.data, example.encoded);
22
+ }
23
+ },
24
+ examples,
25
+ setExampleData(data, encoded) {
26
+ for (const item of examples) {
27
+ if (item.id === example) {
28
+ // persistent changes
29
+ item.data = data;
30
+ item.encoded = encoded;
31
+ break;
32
+ }
33
+ }
34
+ for (const listener of listeners.current) {
35
+ listener(data, encoded);
36
+ }
37
+ },
38
+ removeListener(listener) {
39
+ listeners.current = listeners.current.filter((item) => item !== listener);
40
+ },
41
+ addListener(listener) {
42
+ // initial call to listeners to ensure their data is the latest
43
+ // this is necessary to avoid race conditions between `useEffect()`
44
+ const active = examples.find((item) => item.id === example);
45
+ listener(active.data, active.encoded);
46
+ listeners.current.push(listener);
47
+ },
48
+ }), [example, route, examples]), children: children }));
49
+ }
50
+ export function useExampleRequests() {
51
+ return use(Context);
52
+ }
53
+ export function UsageTabsSelector() {
54
+ const { example: key, setExample: setKey, examples } = useExampleRequests();
11
55
  const { APIExampleSelector: Override } = useApiContext().client.operation ?? {};
12
56
  if (Override) {
13
57
  return _jsx(Override, { items: examples, value: key, onValueChange: setKey });
@@ -20,9 +64,9 @@ export function APIExampleSelector() {
20
64
  const selected = examples.find((item) => item.id === key);
21
65
  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
66
  }
23
- export function APIExampleUsageTab(sample) {
67
+ export function UsageTab(sample) {
24
68
  const { shikiOptions, mediaAdapters } = useApiContext();
25
- const { examples, example: selectedExampleId, route, addListener, removeListener, } = useOperationContext();
69
+ const { examples, example: selectedExampleId, route, addListener, removeListener, } = useExampleRequests();
26
70
  const { server } = useServerSelectContext();
27
71
  const [data, setData] = useState(() => examples.find((example) => example.id === selectedExampleId)?.encoded);
28
72
  useEffect(() => {
@@ -0,0 +1,26 @@
1
+ import type { MethodInformation, RenderContext } from '../../../types.js';
2
+ import type { SampleGenerator } from '../../../requests/types.js';
3
+ /**
4
+ * Generate code example for given programming language
5
+ */
6
+ export interface CodeUsageGenerator<T = unknown> {
7
+ id: string;
8
+ lang: string;
9
+ label?: string;
10
+ /**
11
+ * either:
12
+ * - code
13
+ * - a function imported from a file with "use client" directive
14
+ * - false (disabled)
15
+ */
16
+ source?: string | SampleGenerator<T> | false;
17
+ /**
18
+ * Pass extra context to client-side source generator
19
+ */
20
+ serverContext?: T;
21
+ }
22
+ export declare function UsageTabs({ method, ctx, }: {
23
+ method: MethodInformation;
24
+ ctx: RenderContext;
25
+ }): Promise<import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | (string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined)>;
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/operation/usage-tabs/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAWxD;;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,wBAAsB,SAAS,CAAC,EAC9B,MAAM,EACN,GAAG,GACJ,EAAE;IACD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,GAAG,EAAE,aAAa,CAAC;CACpB,wWAmEA"}
@@ -0,0 +1,52 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { defaultSamples } from '../../../requests/generators/index.js';
3
+ import { CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, } from 'fumadocs-ui/components/codeblock';
4
+ import { UsageTabsSelectorLazy, UsageTabLazy } from './lazy.js';
5
+ import { ResponseTabs } from '../response-tabs.js';
6
+ export async function UsageTabs({ method, ctx, }) {
7
+ let { renderAPIExampleUsageTabs, renderAPIExampleLayout } = ctx.content ?? {};
8
+ renderAPIExampleLayout ?? (renderAPIExampleLayout = (slots) => {
9
+ return (_jsxs("div", { className: "prose-no-margin", children: [slots.selector, slots.usageTabs, slots.responseTabs] }));
10
+ });
11
+ renderAPIExampleUsageTabs ?? (renderAPIExampleUsageTabs = (generators) => {
12
+ if (generators.length === 0)
13
+ return null;
14
+ 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(UsageTabLazy, { ...item }) }, item.id)))] }));
15
+ });
16
+ let generators = [...defaultSamples];
17
+ if (ctx.generateCodeSamples) {
18
+ generators.push(...(await ctx.generateCodeSamples(method)));
19
+ }
20
+ if (method['x-codeSamples']) {
21
+ for (const sample of method['x-codeSamples']) {
22
+ generators.push('id' in sample && typeof sample.id === 'string'
23
+ ? sample
24
+ : {
25
+ id: sample.lang,
26
+ ...sample,
27
+ });
28
+ }
29
+ }
30
+ generators = dedupe(generators);
31
+ return renderAPIExampleLayout({
32
+ selector: method['x-exclusiveCodeSample'] ? null : (_jsx(UsageTabsSelectorLazy, {})),
33
+ usageTabs: await renderAPIExampleUsageTabs(generators, ctx),
34
+ responseTabs: _jsx(ResponseTabs, { operation: method, ctx: ctx }),
35
+ }, ctx);
36
+ }
37
+ /**
38
+ * Remove duplicated ids
39
+ */
40
+ function dedupe(samples) {
41
+ const set = new Set();
42
+ const out = [];
43
+ for (let i = samples.length - 1; i >= 0; i--) {
44
+ const item = samples[i];
45
+ if (set.has(item.id))
46
+ continue;
47
+ set.add(item.id);
48
+ if (item.source !== false)
49
+ out.unshift(item);
50
+ }
51
+ return out;
52
+ }
@@ -0,0 +1,4 @@
1
+ export declare const UsageTabsSelectorLazy: typeof import("./client.js").UsageTabsSelector;
2
+ export declare const UsageTabLazy: typeof import("./client.js").UsageTab;
3
+ export declare const UsageTabsProviderLazy: typeof import("./client.js").UsageTabsProvider;
4
+ //# sourceMappingURL=lazy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../../../../src/ui/operation/usage-tabs/lazy.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,6CAEjC,CAAC;AAEF,eAAO,MAAM,YAAY,oCAExB,CAAC;AAEF,eAAO,MAAM,qBAAqB,6CAEjC,CAAC"}