fumadocs-openapi 10.0.11 → 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.
- package/dist/generate-file.d.ts +6 -5
- package/dist/generate-file.d.ts.map +1 -1
- package/dist/generate-file.js +44 -37
- package/dist/playground/client.d.ts +9 -7
- package/dist/playground/client.d.ts.map +1 -1
- package/dist/playground/client.js +7 -7
- package/dist/playground/components/inputs.d.ts +6 -6
- package/dist/playground/components/inputs.d.ts.map +1 -1
- package/dist/playground/components/inputs.js +13 -12
- package/dist/playground/get-default-values.d.ts +2 -2
- package/dist/playground/get-default-values.d.ts.map +1 -1
- package/dist/playground/index.d.ts +1 -2
- package/dist/playground/index.d.ts.map +1 -1
- package/dist/playground/index.js +2 -0
- package/dist/playground/schema.d.ts +22 -8
- package/dist/playground/schema.d.ts.map +1 -1
- package/dist/playground/schema.js +29 -34
- package/dist/requests/generators/index.d.ts +1 -1
- package/dist/requests/generators/index.d.ts.map +1 -1
- package/dist/server/create.d.ts +1 -1
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/source-api.d.ts +5 -3
- package/dist/server/source-api.d.ts.map +1 -1
- package/dist/server/source-api.js +13 -7
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/api-page.d.ts +16 -8
- package/dist/ui/api-page.d.ts.map +1 -1
- package/dist/ui/api-page.js +7 -7
- package/dist/ui/client/index.d.ts +2 -2
- package/dist/ui/client/index.d.ts.map +1 -1
- package/dist/ui/operation/index.d.ts +4 -3
- package/dist/ui/operation/index.d.ts.map +1 -1
- package/dist/ui/operation/index.js +37 -20
- package/dist/ui/operation/request-tabs.d.ts +18 -0
- package/dist/ui/operation/request-tabs.d.ts.map +1 -0
- package/dist/ui/operation/request-tabs.js +143 -0
- package/dist/ui/operation/response-tabs.d.ts +32 -0
- package/dist/ui/operation/response-tabs.d.ts.map +1 -0
- package/dist/ui/operation/response-tabs.js +59 -0
- package/dist/ui/operation/usage-tabs/client.d.ts +23 -0
- package/dist/ui/operation/usage-tabs/client.d.ts.map +1 -0
- package/dist/ui/operation/{example-panel → usage-tabs}/client.js +50 -6
- package/dist/ui/operation/usage-tabs/index.d.ts +26 -0
- package/dist/ui/operation/usage-tabs/index.d.ts.map +1 -0
- package/dist/ui/operation/usage-tabs/index.js +52 -0
- package/dist/ui/operation/usage-tabs/lazy.d.ts +4 -0
- package/dist/ui/operation/usage-tabs/lazy.d.ts.map +1 -0
- package/dist/ui/operation/usage-tabs/lazy.js +5 -0
- package/dist/ui/schema/client.d.ts +1 -3
- package/dist/ui/schema/client.d.ts.map +1 -1
- package/dist/ui/schema/client.js +13 -17
- package/dist/ui/schema/index.d.ts +19 -5
- package/dist/ui/schema/index.d.ts.map +1 -1
- package/dist/ui/schema/index.js +69 -29
- package/dist/utils/deep-equal.d.ts +2 -0
- package/dist/utils/deep-equal.d.ts.map +1 -0
- package/dist/utils/deep-equal.js +27 -0
- package/dist/utils/merge-schema.d.ts +7 -0
- package/dist/utils/merge-schema.d.ts.map +1 -0
- package/dist/utils/merge-schema.js +179 -0
- package/dist/utils/pages/to-body.d.ts.map +1 -1
- package/dist/utils/pages/to-body.js +2 -3
- package/dist/utils/pages/to-text.d.ts.map +1 -1
- package/dist/utils/pages/to-text.js +31 -16
- package/dist/utils/schema-to-string.d.ts.map +1 -1
- package/dist/utils/schema-to-string.js +8 -5
- package/dist/utils/use-query.d.ts +1 -0
- package/dist/utils/use-query.d.ts.map +1 -1
- package/dist/utils/use-query.js +5 -0
- package/package.json +8 -8
- package/dist/ui/contexts/operation.d.ts +0 -20
- package/dist/ui/contexts/operation.d.ts.map +0 -1
- package/dist/ui/contexts/operation.js +0 -48
- package/dist/ui/contexts/operation.lazy.d.ts +0 -2
- package/dist/ui/contexts/operation.lazy.d.ts.map +0 -1
- package/dist/ui/contexts/operation.lazy.js +0 -3
- package/dist/ui/operation/example-panel/client.d.ts +0 -4
- package/dist/ui/operation/example-panel/client.d.ts.map +0 -1
- package/dist/ui/operation/example-panel/index.d.ts +0 -58
- package/dist/ui/operation/example-panel/index.d.ts.map +0 -1
- package/dist/ui/operation/example-panel/index.js +0 -140
- package/dist/ui/operation/example-panel/lazy.d.ts +0 -3
- package/dist/ui/operation/example-panel/lazy.d.ts.map +0 -1
- package/dist/ui/operation/example-panel/lazy.js +0 -4
- package/dist/ui/operation/get-request-data.d.ts +0 -4
- package/dist/ui/operation/get-request-data.d.ts.map +0 -1
- package/dist/ui/operation/get-request-data.js +0 -70
- package/dist/utils/combine-schema.d.ts +0 -6
- package/dist/utils/combine-schema.d.ts.map +0 -1
- package/dist/utils/combine-schema.js +0 -51
|
@@ -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
|
-
|
|
10
|
-
|
|
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
|
|
67
|
+
export function UsageTab(sample) {
|
|
24
68
|
const { shikiOptions, mediaAdapters } = useApiContext();
|
|
25
|
-
const { examples, example: selectedExampleId, route, addListener, removeListener, } =
|
|
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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { wrapLazy } from '../../../utils/lazy.js';
|
|
3
|
+
export const UsageTabsSelectorLazy = wrapLazy(() => import('./client.js').then((mod) => ({ default: mod.UsageTabsSelector })));
|
|
4
|
+
export const UsageTabLazy = wrapLazy(() => import('./client.js').then((mod) => ({ default: mod.UsageTab })));
|
|
5
|
+
export const UsageTabsProviderLazy = wrapLazy(() => import('./client.js').then((mod) => ({ default: mod.UsageTabsProvider })));
|
|
@@ -3,9 +3,7 @@ export interface SchemaUIProps {
|
|
|
3
3
|
name: string;
|
|
4
4
|
required?: boolean;
|
|
5
5
|
as?: 'property' | 'body';
|
|
6
|
-
readOnly?: boolean;
|
|
7
|
-
writeOnly?: boolean;
|
|
8
6
|
generated: SchemaUIGeneratedData;
|
|
9
7
|
}
|
|
10
|
-
export declare function SchemaUI({ name, required, as, generated,
|
|
8
|
+
export declare function SchemaUI({ name, required, as, generated, }: SchemaUIProps): import("react/jsx-runtime").JSX.Element;
|
|
11
9
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/ui/schema/client.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAc,qBAAqB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/ui/schema/client.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAc,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAuDrE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAEzB,SAAS,EAAE,qBAAqB,CAAC;CAClC;AAED,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,QAAgB,EAChB,EAAe,EACf,SAAS,GACV,EAAE,aAAa,2CAoBf"}
|
package/dist/ui/schema/client.js
CHANGED
|
@@ -26,23 +26,17 @@ function useData() {
|
|
|
26
26
|
function useProperty() {
|
|
27
27
|
return use(PropertyContext);
|
|
28
28
|
}
|
|
29
|
-
export function SchemaUI({ name, required = false, as = 'property', generated,
|
|
29
|
+
export function SchemaUI({ name, required = false, as = 'property', generated, }) {
|
|
30
30
|
const schema = generated.refs[generated.$root];
|
|
31
|
-
const context = useMemo(() =>
|
|
32
|
-
...generated,
|
|
33
|
-
readOnly,
|
|
34
|
-
writeOnly,
|
|
35
|
-
}), [generated, readOnly, writeOnly]);
|
|
31
|
+
const context = useMemo(() => generated, [generated]);
|
|
36
32
|
const isProperty = as === 'property' || !isExpandable(schema);
|
|
37
33
|
return (_jsx(DataContext, { value: context, children: isProperty ? (_jsx(SchemaUIProperty, { name: name, "$type": generated.$root, overrides: {
|
|
38
34
|
required,
|
|
39
35
|
} })) : (_jsx(SchemaUIContent, { "$type": generated.$root })) }));
|
|
40
36
|
}
|
|
41
37
|
function SchemaUIContent({ $type }) {
|
|
42
|
-
const { refs
|
|
38
|
+
const { refs } = useData();
|
|
43
39
|
const schema = refs[$type];
|
|
44
|
-
if ((schema.readOnly && !readOnly) || (schema.writeOnly && !writeOnly))
|
|
45
|
-
return;
|
|
46
40
|
let child = null;
|
|
47
41
|
if (schema.type === 'or' && schema.items.length > 0) {
|
|
48
42
|
child = (_jsxs(_Fragment, { children: [child, _jsxs(Tabs, { defaultValue: schema.items[0].$type, children: [_jsx(TabsList, { children: schema.items.map((item) => (_jsx(TabsTrigger, { value: item.$type, children: item.name }, item.$type))) }), schema.items.map((item) => (_jsx(TabsContent, { value: item.$type, forceMount: undefined, className: "py-0", children: _jsx(SchemaUIContent, { ...item }) }, item.$type)))] })] }));
|
|
@@ -51,16 +45,14 @@ function SchemaUIContent({ $type }) {
|
|
|
51
45
|
child = (_jsxs(_Fragment, { children: [child, schema.props.map((prop) => (_jsx(SchemaUIProperty, { name: prop.name, "$type": prop.$type, overrides: { required: prop.required } }, prop.name)))] }));
|
|
52
46
|
}
|
|
53
47
|
if (schema.type === 'array') {
|
|
54
|
-
child = (_jsxs(_Fragment, { children: [child,
|
|
48
|
+
child = (_jsxs(_Fragment, { children: [child, _jsxs(Collapsible, { className: "my-2", children: [_jsxs(CollapsibleTrigger, { className: cn(buttonVariants({ color: 'secondary', size: 'sm' }), 'group px-3 py-2 data-[state=open]:rounded-b-none'), children: ["Array Item", _jsx(ChevronDown, { className: "size-4 text-fd-muted-foreground group-data-[state=open]:rotate-180" })] }), _jsx(CollapsibleContent, { className: "-mt-px bg-fd-card px-3 rounded-lg rounded-tl-none border shadow-sm", children: _jsx(SchemaUIContent, { "$type": schema.item.$type }) })] })] }));
|
|
55
49
|
}
|
|
56
50
|
return child;
|
|
57
51
|
}
|
|
58
52
|
function SchemaUIProperty({ name, $type, overrides, }) {
|
|
59
53
|
const { renderRef } = useProperty();
|
|
60
|
-
const { refs
|
|
54
|
+
const { refs } = useData();
|
|
61
55
|
const schema = refs[$type];
|
|
62
|
-
if ((schema.readOnly && !readOnly) || (schema.writeOnly && !writeOnly))
|
|
63
|
-
return;
|
|
64
56
|
let type = schema.typeName;
|
|
65
57
|
if (schema.type === 'or' && schema.items.length > 0) {
|
|
66
58
|
type = (_jsx("span", { className: cn(typeVariants(), 'flex flex-row gap-2 items-center'), children: schema.items.map((item, i) => (_jsxs(Fragment, { children: [i > 0 && _jsx("span", { children: "|" }), renderRef({
|
|
@@ -69,6 +61,13 @@ function SchemaUIProperty({ name, $type, overrides, }) {
|
|
|
69
61
|
$ref: item.$type,
|
|
70
62
|
})] }, item.$type))) }));
|
|
71
63
|
}
|
|
64
|
+
if (schema.type === 'and' && schema.items.length > 0) {
|
|
65
|
+
type = (_jsx("span", { className: cn(typeVariants(), 'flex flex-row gap-2 items-center'), children: schema.items.map((item, i) => (_jsxs(Fragment, { children: [i > 0 && _jsx("span", { children: "&" }), renderRef({
|
|
66
|
+
pathName: name,
|
|
67
|
+
text: item.name,
|
|
68
|
+
$ref: item.$type,
|
|
69
|
+
})] }, item.$type))) }));
|
|
70
|
+
}
|
|
72
71
|
if (schema.type === 'object' && schema.props.length > 0) {
|
|
73
72
|
type = renderRef({
|
|
74
73
|
text: schema.aliasName,
|
|
@@ -136,13 +135,10 @@ function LinkRef({ $ref, pathName, onInsert, text, }) {
|
|
|
136
135
|
onInsert(pathName, $ref);
|
|
137
136
|
}, children: text }));
|
|
138
137
|
}
|
|
139
|
-
function ObjectCollapsible(props) {
|
|
140
|
-
return (_jsxs(Collapsible, { className: "my-2", ...props, children: [_jsxs(CollapsibleTrigger, { className: cn(buttonVariants({ color: 'secondary', size: 'sm' }), 'group px-3 py-2 data-[state=open]:rounded-b-none'), children: [props.name, _jsx(ChevronDown, { className: "size-4 text-fd-muted-foreground group-data-[state=open]:rotate-180" })] }), _jsx(CollapsibleContent, { className: "-mt-px *:bg-fd-card", children: props.children })] }));
|
|
141
|
-
}
|
|
142
138
|
function Property({ name, type, required, deprecated, nested = false, ...props }) {
|
|
143
139
|
return (_jsxs("div", { className: cn('text-sm border-t', nested
|
|
144
140
|
? 'p-3 border-x bg-fd-card last:rounded-b-xl first:rounded-tr-xl last:border-b'
|
|
145
|
-
: 'py-4 first:border-t-0', props.className), children: [_jsxs("div", { className: "flex flex-wrap items-center gap-3 not-prose", children: [_jsxs("span", { className: "font-medium font-mono text-fd-primary", children: [name, required
|
|
141
|
+
: 'py-4 first:border-t-0', props.className), children: [_jsxs("div", { className: "flex flex-wrap items-center gap-3 not-prose", children: [_jsxs("span", { className: "font-medium font-mono text-fd-primary", children: [name, required ? (_jsx("span", { className: "text-red-400", children: "*" })) : (_jsx("span", { className: "text-fd-muted-foreground", children: "?" }))] }), typeof type === 'string' ? (_jsx("span", { className: "text-sm font-mono text-fd-muted-foreground", children: type })) : (type), deprecated && (_jsx(Badge, { color: "yellow", className: "ms-auto text-xs", children: "Deprecated" }))] }), _jsx("div", { className: "prose-no-margin pt-2.5 empty:hidden", children: props.children })] }));
|
|
146
142
|
}
|
|
147
143
|
function isExpandable(schema) {
|
|
148
144
|
return schema.type !== 'primitive';
|
|
@@ -8,8 +8,6 @@ export interface FieldBase {
|
|
|
8
8
|
typeName: string;
|
|
9
9
|
aliasName: string;
|
|
10
10
|
deprecated?: boolean;
|
|
11
|
-
writeOnly?: boolean;
|
|
12
|
-
readOnly?: boolean;
|
|
13
11
|
}
|
|
14
12
|
export type SchemaData = FieldBase & ({
|
|
15
13
|
type: 'primitive';
|
|
@@ -31,15 +29,31 @@ export type SchemaData = FieldBase & ({
|
|
|
31
29
|
name: string;
|
|
32
30
|
$type: string;
|
|
33
31
|
}[];
|
|
32
|
+
} | {
|
|
33
|
+
type: 'and';
|
|
34
|
+
items: {
|
|
35
|
+
name: string;
|
|
36
|
+
$type: string;
|
|
37
|
+
}[];
|
|
34
38
|
});
|
|
35
39
|
export interface SchemaUIOptions {
|
|
36
40
|
root: ResolvedSchema;
|
|
37
|
-
|
|
41
|
+
client: Omit<SchemaUIProps, 'generated'>;
|
|
42
|
+
/**
|
|
43
|
+
* include read only props
|
|
44
|
+
*/
|
|
45
|
+
readOnly?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* include write only props
|
|
48
|
+
*/
|
|
49
|
+
writeOnly?: boolean;
|
|
38
50
|
}
|
|
39
51
|
export interface SchemaUIGeneratedData {
|
|
40
52
|
$root: string;
|
|
41
53
|
refs: Record<string, SchemaData>;
|
|
42
54
|
}
|
|
43
|
-
export declare function Schema({ ctx,
|
|
44
|
-
|
|
55
|
+
export declare function Schema({ ctx, ...options }: SchemaUIOptions & {
|
|
56
|
+
ctx: RenderContext;
|
|
57
|
+
}): string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<ReactNode> | Promise<ReactNode> | null | undefined;
|
|
58
|
+
export declare function generateSchemaUI({ root, readOnly, writeOnly }: SchemaUIOptions, ctx: RenderContext): SchemaUIGeneratedData;
|
|
45
59
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/schema/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,MAAM,WAAW,SAAS;IACxB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;IAEvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAElB,UAAU,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/schema/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,MAAM,WAAW,SAAS;IACxB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;IAEvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAElB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAChC,CACI;IACE,IAAI,EAAE,WAAW,CAAC;CACnB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,OAAO,CAAC;KACnB,EAAE,CAAC;CACL,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH,GACD;IACE,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;CACL,GACD;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;CACL,CACJ,CAAC;AAEJ,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IAEzC;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAClC;AAED,wBAAgB,MAAM,CAAC,EACrB,GAAG,EACH,GAAG,OAAO,EACX,EAAE,eAAe,GAAG;IACnB,GAAG,EAAE,aAAa,CAAC;CACpB,8IAWA;AAED,wBAAgB,gBAAgB,CAC9B,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,eAAe,EAC9C,GAAG,EAAE,aAAa,GACjB,qBAAqB,CAuSvB"}
|