fumadocs-openapi 10.2.5 → 10.2.7
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 +1 -2
- package/dist/generate-file.js +1 -2
- package/dist/playground/client.d.ts +1 -2
- package/dist/playground/client.js +1 -2
- package/dist/playground/components/inputs.js +34 -54
- package/dist/playground/components/oauth-dialog.js +1 -2
- package/dist/playground/components/server-select.js +1 -2
- package/dist/playground/fetcher.d.ts +1 -2
- package/dist/playground/fetcher.js +1 -2
- package/dist/playground/get-default-values.js +1 -2
- package/dist/playground/index.d.ts +1 -2
- package/dist/playground/index.js +1 -2
- package/dist/playground/lazy.js +1 -2
- package/dist/playground/schema.d.ts +1 -2
- package/dist/playground/schema.js +1 -2
- package/dist/playground/status-info.js +1 -2
- package/dist/requests/generators/csharp.js +1 -2
- package/dist/requests/generators/curl.js +1 -2
- package/dist/requests/generators/go.js +1 -2
- package/dist/requests/generators/index.js +1 -2
- package/dist/requests/generators/java.js +1 -2
- package/dist/requests/generators/javascript.js +1 -2
- package/dist/requests/generators/python.js +1 -2
- package/dist/requests/media/adapter.d.ts +1 -2
- package/dist/requests/media/adapter.js +1 -2
- package/dist/requests/media/encode.d.ts +1 -2
- package/dist/requests/media/encode.js +1 -2
- package/dist/requests/media/resolve-adapter.js +1 -2
- package/dist/requests/string-utils.js +1 -2
- package/dist/requests/to-python-object.js +1 -2
- package/dist/requests/types.d.ts +1 -2
- package/dist/scalar/client.js +1 -2
- package/dist/scalar/index.d.ts +1 -2
- package/dist/scalar/index.js +1 -2
- package/dist/server/create.d.ts +1 -2
- package/dist/server/create.js +2 -3
- package/dist/server/proxy.d.ts +1 -2
- package/dist/server/proxy.js +1 -2
- package/dist/server/source-api.d.ts +1 -2
- package/dist/server/source-api.js +1 -2
- package/dist/types.d.ts +1 -2
- package/dist/ui/api-page.d.ts +1 -2
- package/dist/ui/api-page.js +1 -2
- package/dist/ui/client/index.d.ts +1 -2
- package/dist/ui/client/index.js +1 -2
- package/dist/ui/client/storage-key.js +1 -2
- package/dist/ui/components/accordion.js +1 -2
- package/dist/ui/components/dialog.js +1 -2
- package/dist/ui/components/input.js +1 -2
- package/dist/ui/components/method-label.js +1 -2
- package/dist/ui/components/select.js +1 -2
- package/dist/ui/contexts/api.js +1 -2
- package/dist/ui/contexts/api.lazy.js +1 -2
- package/dist/ui/operation/client.js +1 -2
- package/dist/ui/operation/index.js +1 -2
- package/dist/ui/operation/request-tabs.d.ts +1 -2
- package/dist/ui/operation/request-tabs.js +1 -2
- package/dist/ui/operation/response-tabs.d.ts +1 -2
- package/dist/ui/operation/response-tabs.js +1 -2
- package/dist/ui/operation/usage-tabs/client.js +1 -2
- package/dist/ui/operation/usage-tabs/index.d.ts +1 -2
- package/dist/ui/operation/usage-tabs/index.js +1 -2
- package/dist/ui/operation/usage-tabs/lazy.js +1 -2
- package/dist/ui/schema/client.d.ts +1 -2
- package/dist/ui/schema/client.js +34 -3
- package/dist/ui/schema/index.d.ts +6 -3
- package/dist/ui/schema/index.js +42 -25
- package/dist/ui/schema/lazy.js +1 -2
- package/dist/utils/deep-equal.js +1 -2
- package/dist/utils/get-typescript-schema.js +1 -2
- package/dist/utils/id-to-title.js +1 -2
- package/dist/utils/lazy.js +1 -2
- package/dist/utils/merge-schema.js +1 -2
- package/dist/utils/pages/builder.d.ts +1 -2
- package/dist/utils/pages/builder.js +1 -2
- package/dist/utils/pages/preset-auto.d.ts +1 -2
- package/dist/utils/pages/preset-auto.js +1 -2
- package/dist/utils/pages/to-body.js +1 -2
- package/dist/utils/pages/to-static-data.js +1 -2
- package/dist/utils/pages/to-text.d.ts +1 -2
- package/dist/utils/pages/to-text.js +1 -2
- package/dist/utils/process-document.d.ts +1 -2
- package/dist/utils/process-document.js +1 -2
- package/dist/utils/remove-undefined.js +1 -2
- package/dist/utils/schema-to-string.js +1 -2
- package/dist/utils/schema.d.ts +1 -2
- package/dist/utils/schema.js +1 -2
- package/dist/utils/url.js +1 -2
- package/dist/utils/use-query.js +1 -2
- package/package.json +12 -12
- package/dist/generate-file.d.ts.map +0 -1
- package/dist/generate-file.js.map +0 -1
- package/dist/playground/client.d.ts.map +0 -1
- package/dist/playground/client.js.map +0 -1
- package/dist/playground/components/inputs.js.map +0 -1
- package/dist/playground/components/oauth-dialog.js.map +0 -1
- package/dist/playground/components/server-select.js.map +0 -1
- package/dist/playground/fetcher.d.ts.map +0 -1
- package/dist/playground/fetcher.js.map +0 -1
- package/dist/playground/get-default-values.js.map +0 -1
- package/dist/playground/index.d.ts.map +0 -1
- package/dist/playground/index.js.map +0 -1
- package/dist/playground/lazy.js.map +0 -1
- package/dist/playground/schema.d.ts.map +0 -1
- package/dist/playground/schema.js.map +0 -1
- package/dist/playground/status-info.js.map +0 -1
- package/dist/requests/generators/csharp.js.map +0 -1
- package/dist/requests/generators/curl.js.map +0 -1
- package/dist/requests/generators/go.js.map +0 -1
- package/dist/requests/generators/index.js.map +0 -1
- package/dist/requests/generators/java.js.map +0 -1
- package/dist/requests/generators/javascript.js.map +0 -1
- package/dist/requests/generators/python.js.map +0 -1
- package/dist/requests/media/adapter.d.ts.map +0 -1
- package/dist/requests/media/adapter.js.map +0 -1
- package/dist/requests/media/encode.d.ts.map +0 -1
- package/dist/requests/media/encode.js.map +0 -1
- package/dist/requests/media/resolve-adapter.js.map +0 -1
- package/dist/requests/string-utils.js.map +0 -1
- package/dist/requests/to-python-object.js.map +0 -1
- package/dist/requests/types.d.ts.map +0 -1
- package/dist/scalar/client.js.map +0 -1
- package/dist/scalar/index.d.ts.map +0 -1
- package/dist/scalar/index.js.map +0 -1
- package/dist/server/create.d.ts.map +0 -1
- package/dist/server/create.js.map +0 -1
- package/dist/server/proxy.d.ts.map +0 -1
- package/dist/server/proxy.js.map +0 -1
- package/dist/server/source-api.d.ts.map +0 -1
- package/dist/server/source-api.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/ui/api-page.d.ts.map +0 -1
- package/dist/ui/api-page.js.map +0 -1
- package/dist/ui/client/index.d.ts.map +0 -1
- package/dist/ui/client/index.js.map +0 -1
- package/dist/ui/client/storage-key.js.map +0 -1
- package/dist/ui/components/accordion.js.map +0 -1
- package/dist/ui/components/dialog.js.map +0 -1
- package/dist/ui/components/input.js.map +0 -1
- package/dist/ui/components/method-label.js.map +0 -1
- package/dist/ui/components/select.js.map +0 -1
- package/dist/ui/contexts/api.js.map +0 -1
- package/dist/ui/contexts/api.lazy.js.map +0 -1
- package/dist/ui/operation/client.js.map +0 -1
- package/dist/ui/operation/index.js.map +0 -1
- package/dist/ui/operation/request-tabs.d.ts.map +0 -1
- package/dist/ui/operation/request-tabs.js.map +0 -1
- package/dist/ui/operation/response-tabs.d.ts.map +0 -1
- package/dist/ui/operation/response-tabs.js.map +0 -1
- package/dist/ui/operation/usage-tabs/client.js.map +0 -1
- package/dist/ui/operation/usage-tabs/index.d.ts.map +0 -1
- package/dist/ui/operation/usage-tabs/index.js.map +0 -1
- package/dist/ui/operation/usage-tabs/lazy.js.map +0 -1
- package/dist/ui/schema/client.d.ts.map +0 -1
- package/dist/ui/schema/client.js.map +0 -1
- package/dist/ui/schema/index.d.ts.map +0 -1
- package/dist/ui/schema/index.js.map +0 -1
- package/dist/ui/schema/lazy.js.map +0 -1
- package/dist/utils/deep-equal.js.map +0 -1
- package/dist/utils/get-typescript-schema.js.map +0 -1
- package/dist/utils/id-to-title.js.map +0 -1
- package/dist/utils/lazy.js.map +0 -1
- package/dist/utils/merge-schema.js.map +0 -1
- package/dist/utils/pages/builder.d.ts.map +0 -1
- package/dist/utils/pages/builder.js.map +0 -1
- package/dist/utils/pages/preset-auto.d.ts.map +0 -1
- package/dist/utils/pages/preset-auto.js.map +0 -1
- package/dist/utils/pages/to-body.js.map +0 -1
- package/dist/utils/pages/to-static-data.js.map +0 -1
- package/dist/utils/pages/to-text.d.ts.map +0 -1
- package/dist/utils/pages/to-text.js.map +0 -1
- package/dist/utils/process-document.d.ts.map +0 -1
- package/dist/utils/process-document.js.map +0 -1
- package/dist/utils/remove-undefined.js.map +0 -1
- package/dist/utils/schema-to-string.js.map +0 -1
- package/dist/utils/schema.d.ts.map +0 -1
- package/dist/utils/schema.js.map +0 -1
- package/dist/utils/url.js.map +0 -1
- package/dist/utils/use-query.js.map +0 -1
|
@@ -8,5 +8,4 @@ const UsageTabLazy = wrapLazy(() => import("./client.js").then((mod) => ({ defau
|
|
|
8
8
|
const UsageTabsProviderLazy = wrapLazy(() => import("./client.js").then((mod) => ({ default: mod.UsageTabsProvider })));
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
|
-
export { UsageTabLazy, UsageTabsProviderLazy, UsageTabsSelectorLazy };
|
|
12
|
-
//# sourceMappingURL=lazy.js.map
|
|
11
|
+
export { UsageTabLazy, UsageTabsProviderLazy, UsageTabsSelectorLazy };
|
package/dist/ui/schema/client.js
CHANGED
|
@@ -92,7 +92,7 @@ function SchemaUIProperty({ name, $type, variant = "default", overrides }) {
|
|
|
92
92
|
}
|
|
93
93
|
const child = /* @__PURE__ */ jsxs(Fragment$1, { children: [schema.description, schema.infoTags && schema.infoTags.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
94
94
|
className: "flex flex-row gap-2 flex-wrap my-2 not-prose empty:hidden",
|
|
95
|
-
children: schema.infoTags.map((tag
|
|
95
|
+
children: schema.infoTags.map((tag) => /* @__PURE__ */ jsx(InfoTag, { tag }, tag.label))
|
|
96
96
|
})] });
|
|
97
97
|
if (variant === "expand") return child;
|
|
98
98
|
return /* @__PURE__ */ jsx(Property, {
|
|
@@ -103,6 +103,38 @@ function SchemaUIProperty({ name, $type, variant = "default", overrides }) {
|
|
|
103
103
|
children: child
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
|
+
function InfoTag({ tag }) {
|
|
107
|
+
const ref = useRef(null);
|
|
108
|
+
const [isTruncated, setTruncated] = useState(false);
|
|
109
|
+
const [open, setOpen] = useState(false);
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
const element = ref.current;
|
|
112
|
+
if (!element) return;
|
|
113
|
+
setTruncated(element.scrollWidth !== element.offsetWidth);
|
|
114
|
+
}, []);
|
|
115
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
116
|
+
className: "flex flex-row items-start gap-2 bg-fd-secondary border rounded-lg text-xs p-1.5 shadow-md max-w-full",
|
|
117
|
+
children: [
|
|
118
|
+
/* @__PURE__ */ jsx("span", {
|
|
119
|
+
className: "font-medium",
|
|
120
|
+
children: tag.label
|
|
121
|
+
}),
|
|
122
|
+
/* @__PURE__ */ jsx("code", {
|
|
123
|
+
ref,
|
|
124
|
+
className: cn("min-w-0 flex-1 text-fd-muted-foreground", open ? "wrap-break-word" : "truncate"),
|
|
125
|
+
children: tag.value
|
|
126
|
+
}),
|
|
127
|
+
isTruncated && /* @__PURE__ */ jsx("button", {
|
|
128
|
+
className: cn(buttonVariants({
|
|
129
|
+
size: "icon-xs",
|
|
130
|
+
variant: "ghost"
|
|
131
|
+
})),
|
|
132
|
+
onClick: () => setOpen((prev) => !prev),
|
|
133
|
+
children: /* @__PURE__ */ jsx(ChevronDown, {})
|
|
134
|
+
})
|
|
135
|
+
]
|
|
136
|
+
});
|
|
137
|
+
}
|
|
106
138
|
function SchemaUIPopover({ initialPath }) {
|
|
107
139
|
const [path, setPath] = useState(initialPath);
|
|
108
140
|
const ref = useRef(null);
|
|
@@ -233,5 +265,4 @@ function Property({ name, type, required, deprecated, nested = false, className,
|
|
|
233
265
|
}
|
|
234
266
|
|
|
235
267
|
//#endregion
|
|
236
|
-
export { SchemaUI };
|
|
237
|
-
//# sourceMappingURL=client.js.map
|
|
268
|
+
export { SchemaUI };
|
|
@@ -7,11 +7,15 @@ import "react/jsx-runtime";
|
|
|
7
7
|
//#region src/ui/schema/index.d.ts
|
|
8
8
|
interface FieldBase {
|
|
9
9
|
description?: ReactNode;
|
|
10
|
-
infoTags?:
|
|
10
|
+
infoTags?: InfoTag[];
|
|
11
11
|
typeName: string;
|
|
12
12
|
aliasName: string;
|
|
13
13
|
deprecated?: boolean;
|
|
14
14
|
}
|
|
15
|
+
interface InfoTag {
|
|
16
|
+
label: string;
|
|
17
|
+
value: string;
|
|
18
|
+
}
|
|
15
19
|
type SchemaData = FieldBase & ({
|
|
16
20
|
type: 'primitive';
|
|
17
21
|
} | {
|
|
@@ -56,5 +60,4 @@ interface SchemaUIGeneratedData {
|
|
|
56
60
|
refs: Record<string, SchemaData>;
|
|
57
61
|
}
|
|
58
62
|
//#endregion
|
|
59
|
-
export { SchemaUIGeneratedData, SchemaUIOptions };
|
|
60
|
-
//# sourceMappingURL=index.d.ts.map
|
|
63
|
+
export { SchemaUIGeneratedData, SchemaUIOptions };
|
package/dist/ui/schema/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mergeAllOf } from "../../utils/merge-schema.js";
|
|
2
2
|
import { FormatFlags, schemaToString } from "../../utils/schema-to-string.js";
|
|
3
3
|
import { SchemaUILazy } from "./lazy.js";
|
|
4
|
-
import { jsx
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
|
|
6
6
|
//#region src/ui/schema/index.tsx
|
|
7
7
|
function Schema({ ctx, ...options }) {
|
|
@@ -16,32 +16,50 @@ function generateSchemaUI({ root, readOnly, writeOnly }, ctx) {
|
|
|
16
16
|
const { showExample = false } = ctx.schemaUI ?? {};
|
|
17
17
|
function generateInfoTags(schema) {
|
|
18
18
|
const fields = [];
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
if (schema.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
19
|
+
if (schema.default !== void 0) fields.push({
|
|
20
|
+
label: "Default",
|
|
21
|
+
value: JSON.stringify(schema.default)
|
|
22
|
+
});
|
|
23
|
+
if (schema.pattern) fields.push({
|
|
24
|
+
label: "Match",
|
|
25
|
+
value: schema.pattern
|
|
26
|
+
});
|
|
27
|
+
if (schema.format) fields.push({
|
|
28
|
+
label: "Format",
|
|
29
|
+
value: schema.format
|
|
30
|
+
});
|
|
31
|
+
if (schema.multipleOf) fields.push({
|
|
32
|
+
label: "Multiple Of",
|
|
33
|
+
value: schema.multipleOf.toString()
|
|
34
|
+
});
|
|
35
35
|
let range = formatRange("value", schema.minimum, schema.exclusiveMinimum, schema.maximum, schema.exclusiveMaximum);
|
|
36
|
-
if (range) fields.push(
|
|
36
|
+
if (range) fields.push({
|
|
37
|
+
label: "Range",
|
|
38
|
+
value: range
|
|
39
|
+
});
|
|
37
40
|
range = formatRange("length", schema.minLength, void 0, schema.maxLength, void 0);
|
|
38
|
-
if (range) fields.push(
|
|
41
|
+
if (range) fields.push({
|
|
42
|
+
label: "Length",
|
|
43
|
+
value: range
|
|
44
|
+
});
|
|
39
45
|
range = formatRange("properties", schema.minProperties, void 0, schema.maxProperties, void 0);
|
|
40
|
-
if (range) fields.push(
|
|
46
|
+
if (range) fields.push({
|
|
47
|
+
label: "Properties",
|
|
48
|
+
value: range
|
|
49
|
+
});
|
|
41
50
|
range = formatRange("items", schema.minItems, void 0, schema.maxItems, void 0);
|
|
42
|
-
if (range) fields.push(
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
if (range) fields.push({
|
|
52
|
+
label: "Items",
|
|
53
|
+
value: range
|
|
54
|
+
});
|
|
55
|
+
if (schema.enum) fields.push({
|
|
56
|
+
label: "Value in",
|
|
57
|
+
value: schema.enum.map((value) => JSON.stringify(value)).join(" | ")
|
|
58
|
+
});
|
|
59
|
+
if (showExample && schema.examples) for (const example of schema.examples) fields.push({
|
|
60
|
+
label: "Example",
|
|
61
|
+
value: JSON.stringify(example, null, 2)
|
|
62
|
+
});
|
|
45
63
|
return fields;
|
|
46
64
|
}
|
|
47
65
|
let _counter = 0;
|
|
@@ -225,5 +243,4 @@ function formatRange(value, min, exclusiveMin, max, exclusiveMax) {
|
|
|
225
243
|
}
|
|
226
244
|
|
|
227
245
|
//#endregion
|
|
228
|
-
export { Schema };
|
|
229
|
-
//# sourceMappingURL=index.js.map
|
|
246
|
+
export { Schema };
|
package/dist/ui/schema/lazy.js
CHANGED
package/dist/utils/deep-equal.js
CHANGED
package/dist/utils/lazy.js
CHANGED
|
@@ -87,5 +87,4 @@ interface ExtractedInfo {
|
|
|
87
87
|
declare function fromServer(server: OpenAPIServer, config: PagesBuilderConfig): Promise<Record<string, OutputEntry[]>>;
|
|
88
88
|
declare function fromSchema(schemaId: string, processed: ProcessedDocument, config: PagesBuilderConfig): OutputEntry[];
|
|
89
89
|
//#endregion
|
|
90
|
-
export { OperationOutput, OutputEntry, OutputGroup, PagesBuilder, PagesBuilderConfig, TagOutput, WebhookOutput, fromSchema, fromServer };
|
|
91
|
-
//# sourceMappingURL=builder.d.ts.map
|
|
90
|
+
export { OperationOutput, OutputEntry, OutputGroup, PagesBuilder, PagesBuilderConfig, TagOutput, WebhookOutput, fromSchema, fromServer };
|
|
@@ -67,5 +67,4 @@ interface BaseConfig {
|
|
|
67
67
|
}
|
|
68
68
|
declare function createAutoPreset(options: SchemaToPagesOptions): PagesBuilderConfig;
|
|
69
69
|
//#endregion
|
|
70
|
-
export { SchemaToPagesOptions, createAutoPreset };
|
|
71
|
-
//# sourceMappingURL=preset-auto.d.ts.map
|
|
70
|
+
export { SchemaToPagesOptions, createAutoPreset };
|
package/dist/utils/schema.d.ts
CHANGED
|
@@ -10,5 +10,4 @@ type NoReferenceJSONSchema<T> = T extends (infer I)[] ? NoReference<I>[] : T ext
|
|
|
10
10
|
type ParsedSchema = JSONSchema;
|
|
11
11
|
type ResolvedSchema = NoReferenceJSONSchema<ParsedSchema>;
|
|
12
12
|
//#endregion
|
|
13
|
-
export { NoReference, ParsedSchema, ResolvedSchema };
|
|
14
|
-
//# sourceMappingURL=schema.d.ts.map
|
|
13
|
+
export { NoReference, ParsedSchema, ResolvedSchema };
|
package/dist/utils/schema.js
CHANGED
|
@@ -45,5 +45,4 @@ function pickExample(value) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
//#endregion
|
|
48
|
-
export { createMethod, getPreferredType, getTagDisplayName, methodKeys, pickExample };
|
|
49
|
-
//# sourceMappingURL=schema.js.map
|
|
48
|
+
export { createMethod, getPreferredType, getTagDisplayName, methodKeys, pickExample };
|
package/dist/utils/url.js
CHANGED
|
@@ -37,5 +37,4 @@ function resolveRequestData(pathname, { path, query }) {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
//#endregion
|
|
40
|
-
export { isUrl, joinURL, resolveRequestData, resolveServerUrl, withBase };
|
|
41
|
-
//# sourceMappingURL=url.js.map
|
|
40
|
+
export { isUrl, joinURL, resolveRequestData, resolveServerUrl, withBase };
|
package/dist/utils/use-query.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-openapi",
|
|
3
|
-
"version": "10.2.
|
|
3
|
+
"version": "10.2.7",
|
|
4
4
|
"description": "Generate MDX docs for your OpenAPI spec",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Docs",
|
|
@@ -57,17 +57,17 @@
|
|
|
57
57
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
58
58
|
"@radix-ui/react-select": "^2.2.6",
|
|
59
59
|
"@radix-ui/react-slot": "^1.2.4",
|
|
60
|
-
"@scalar/json-magic": "^0.
|
|
61
|
-
"@scalar/openapi-parser": "0.
|
|
60
|
+
"@scalar/json-magic": "^0.9.4",
|
|
61
|
+
"@scalar/openapi-parser": "0.24.5",
|
|
62
62
|
"ajv": "^8.17.1",
|
|
63
63
|
"class-variance-authority": "^0.7.1",
|
|
64
64
|
"github-slugger": "^2.0.0",
|
|
65
65
|
"hast-util-to-jsx-runtime": "^2.3.6",
|
|
66
66
|
"js-yaml": "^4.1.1",
|
|
67
|
-
"lucide-react": "^0.
|
|
67
|
+
"lucide-react": "^0.563.0",
|
|
68
68
|
"next-themes": "^0.4.6",
|
|
69
69
|
"openapi-sampler": "^1.6.2",
|
|
70
|
-
"react-hook-form": "^7.
|
|
70
|
+
"react-hook-form": "^7.71.1",
|
|
71
71
|
"remark": "^15.0.1",
|
|
72
72
|
"remark-rehype": "^11.1.2",
|
|
73
73
|
"tailwind-merge": "^3.4.0",
|
|
@@ -75,19 +75,19 @@
|
|
|
75
75
|
"@fumari/stf": "^0.0.1"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@scalar/api-client-react": "^1.3.
|
|
78
|
+
"@scalar/api-client-react": "^1.3.82",
|
|
79
79
|
"@types/js-yaml": "^4.0.9",
|
|
80
|
-
"@types/node": "25.0
|
|
80
|
+
"@types/node": "25.1.0",
|
|
81
81
|
"@types/openapi-sampler": "^1.0.3",
|
|
82
|
-
"@types/react": "^19.2.
|
|
82
|
+
"@types/react": "^19.2.10",
|
|
83
83
|
"json-schema-typed": "^8.0.2",
|
|
84
84
|
"openapi-types": "^12.1.3",
|
|
85
85
|
"tailwindcss": "^4.1.18",
|
|
86
86
|
"tsdown": "^0.19.0",
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"fumadocs-
|
|
90
|
-
"
|
|
87
|
+
"eslint-config-custom": "0.0.0",
|
|
88
|
+
"fumadocs-core": "16.4.10",
|
|
89
|
+
"fumadocs-ui": "16.4.10",
|
|
90
|
+
"tsconfig": "0.0.0"
|
|
91
91
|
},
|
|
92
92
|
"peerDependencies": {
|
|
93
93
|
"@scalar/api-client-react": "*",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-file.d.ts","names":[],"sources":["../src/generate-file.ts"],"sourcesContent":[],"mappings":";;;;;;;;UASiB,UAAA;;;AAAjB;AAGC,UAES,WAAA,CAAW;EACZ,KAAA,EAAA,SAAA,EAAA,GAAA,CAAA,CAAA,GAAA,EAAqB,kBAArB,EAAA,GAA4C,SAA5C,EAAA,CAAA;EAAqB;;;EAgBpB,GAAA,EAAA,CAAA,CAAA,QAAS,EAAA,MAAA,EAAA,GAAA,MAAA,CAAA,GAAA;IAaT,OAAA,EAAA,MAAA;IAID;;;IAeyC,UAAA,EAAA,MAAA;EAAwB,CAAA;;UAhChE,SAAA,CAa8C;EAsB5C,IAAA,EAAA,MAAM;EAER,KAAA,CAAA,EAAA,MAAA;EAC2B,WAAA,CAAA,EAAA,MAAA;EAAf;;;;;EAEM,IAAA,CAAA,EAAA,MAAA,EAAA;AAG5B;AAeA,UA7CU,mBAAA,SAA4B,kBA6CC,CAAA;EAC5B;;;EACA,KAAA,EA3CF,aA2CE;EAAR;;;;;;;UAjCO;;;;uBAKa,2BAA2B,wBAAwB;;KAG9D,MAAA,GAAS,uBAAuB;UAElC,kBAAA;sBACY,eAAe;6BACR,eAAe;sBACtB,eAAe;;iBAGf,aAAA,UAAuB,SAAS;iBAehC,iBAAA,UACX,uBAAuB,KAAK,iCACpC,QAAQ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-file.js","names":["entries","path"],"sources":["../src/generate-file.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { generateDocument, type PagesToTextOptions, toText } from './utils/pages/to-text';\nimport type { ProcessedDocument } from '@/utils/process-document';\nimport type { OpenAPIServer } from '@/server';\nimport { createGetUrl, getSlugs } from 'fumadocs-core/source';\nimport { createAutoPreset, type SchemaToPagesOptions } from '@/utils/pages/preset-auto';\nimport { fromSchema, type OutputEntry } from '@/utils/pages/builder';\n\nexport interface OutputFile {\n path: string;\n content: string;\n}\n\ninterface IndexConfig {\n items: IndexItem[] | ((ctx: BeforeWriteContext) => IndexItem[]);\n\n /**\n * Generate URLs for cards\n */\n url:\n | ((filePath: string) => string)\n | {\n baseUrl: string;\n /**\n * Base content directory\n */\n contentDir: string;\n };\n}\n\ninterface IndexItem {\n path: string;\n title?: string;\n description?: string;\n\n /**\n * Specify linked pages:\n * - items in `inputs` to include all generated pages of a specific schema.\n * - specific Markdown/MDX files.\n */\n only?: string[];\n}\n\ninterface GenerateFilesConfig extends PagesToTextOptions {\n /**\n * the OpenAPI server object\n */\n input: OpenAPIServer;\n\n /**\n * Output directory\n */\n output: string;\n\n /**\n * Generate index files with cards linking to generated pages.\n */\n index?: IndexConfig;\n\n /**\n * Can add/change/remove output files before writing to file system\n **/\n beforeWrite?: (this: BeforeWriteContext, files: OutputFile[]) => void | Promise<void>;\n}\n\nexport type Config = SchemaToPagesOptions & GenerateFilesConfig;\n\ninterface BeforeWriteContext {\n readonly generated: Record<string, OutputFile[]>;\n readonly generatedEntries: Record<string, OutputEntry[]>;\n readonly documents: Record<string, ProcessedDocument>;\n}\n\nexport async function generateFiles(options: Config): Promise<void> {\n const files = await generateFilesOnly(options);\n const { output } = options;\n\n await Promise.all(\n files.map(async (file) => {\n const filePath = path.join(output, file.path);\n\n await mkdir(path.dirname(filePath), { recursive: true });\n await writeFile(filePath, file.content);\n console.log(`Generated: ${filePath}`);\n }),\n );\n}\n\nexport async function generateFilesOnly(\n options: SchemaToPagesOptions & Omit<GenerateFilesConfig, 'output'>,\n): Promise<OutputFile[]> {\n const schemas = await options.input.getSchemas();\n\n const files: OutputFile[] = [];\n const generated: Record<string, OutputFile[]> = {};\n const generatedEntries: Record<string, OutputEntry[]> = {};\n\n const entries = Object.entries(schemas);\n if (entries.length === 0) {\n throw new Error('No input files found.');\n }\n const preset = createAutoPreset(options);\n for (const [id, schema] of entries) {\n const entries = fromSchema(id, schema, preset);\n const schemaFiles = (generated[id] ??= []);\n\n generatedEntries[id] = entries;\n for (const entry of entries) {\n const file: OutputFile = {\n path: entry.path,\n content: toText(entry, schema, options),\n };\n\n schemaFiles.push(file);\n files.push(file);\n }\n }\n\n const context: BeforeWriteContext = {\n generated,\n generatedEntries,\n documents: schemas,\n };\n\n if (options.index) {\n writeIndexFiles(files, context, options);\n }\n\n await options.beforeWrite?.call(context, files);\n return files;\n}\n\nfunction writeIndexFiles(\n files: OutputFile[],\n context: BeforeWriteContext,\n options: SchemaToPagesOptions & Omit<GenerateFilesConfig, 'output'>,\n) {\n const { generatedEntries } = context;\n const { items, url } = options.index!;\n\n let urlFn: (path: string) => string;\n if (typeof url === 'object') {\n const getUrl = createGetUrl(url.baseUrl);\n\n urlFn = (file) => getUrl(getSlugs(path.relative(url.contentDir, file)));\n } else {\n urlFn = url;\n }\n\n function findEntryByPath(path: string) {\n for (const entries of Object.values(generatedEntries)) {\n const match = entries.find((entry) => entry.path === path);\n\n if (match) return match;\n }\n }\n\n function fileContent(index: IndexItem): string {\n const content: string[] = [];\n content.push('<Cards>');\n const pathToEntry = new Map<string, OutputEntry>();\n const only = index.only ?? Object.keys(context.generated);\n\n for (const item of only) {\n if (generatedEntries[item]) {\n for (const entry of generatedEntries[item]) {\n pathToEntry.set(entry.path, entry);\n }\n } else {\n const match = findEntryByPath(item);\n if (!match) {\n throw new Error(\n `${item} does not exist on \"input\", available: ${Object.keys(generatedEntries).join(', ')}.`,\n );\n }\n\n pathToEntry.set(match.path, match);\n }\n }\n\n for (const file of pathToEntry.values()) {\n const descriptionAttr = file.info.description\n ? `description=${JSON.stringify(file.info.description)} `\n : '';\n content.push(\n `<Card href=\"${urlFn(file.path)}\" title=${JSON.stringify(file.info.title)} ${descriptionAttr}/>`,\n );\n }\n\n content.push('</Cards>');\n return generateDocument(\n {\n title: index.title ?? 'Overview',\n description: index.description,\n },\n content.join('\\n'),\n options,\n );\n }\n\n for (const item of typeof items === 'function' ? items(context) : items) {\n files.push({\n path: path.extname(item.path).length === 0 ? `${item.path}.mdx` : item.path,\n content: fileContent(item),\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","names":[],"sources":["../../src/playground/client.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;UAsDiB,UAAA,SAAmB;QAC5B;SACC;EAFQ,MAAA,EAGP,MAHkB,CAAA,MAAA,EAAA,OAAA,CAAA;EACpB,MAAA,EAGE,MAHF,CAAA,MAAA,EAAA,OAAA,CAAA;EACC,IAAA,EAAA,OAAA;;AAEC,UAIO,qBAAA,SAA8B,cAJrC,CAAA,MAAA,CAAA,EAI6D,WAJ7D,CAAA;EAJ0B,KAAA,EAAA,MAAA;EAAM,MAAA,EAAA,MAAA;EAQzB,UAAA,CAAA,EAGF,cAHwB,EAAA;EAGxB,UAAA,EACD,aADC,EAAA,EAAA;EACD,IAAA,CAAA,EAAA;IAEF,MAAA,EAAA,YAAA;IAMiB,SAAA,EAAA,MAAA;EAAf,CAAA;EAZiC;;;EAgB9B,UAAA,EAJH,MAIG,CAAA,MAAA,EAJY,YAIW,CAAA;EAIP,QAAA,CAAA,EAAA,MAAA;;AAQH,UAZb,uBAAA,CAYa;EAAX;;;EAWmC,mBAAA,CAAA,EAAA,CAAA,MAAA,EAnBrB,SAmBqB,EAAA,EAAA,GAnBL,SAmBK,EAAA;EAAmB;;;EAazD,cAAA,CAAA,EAAA,MAAA;EAcQ,UAAA,CAAA,EAvCT,OAuCyB,CAAA;IACtC,aAAA,EAvCiB,EAuCjB,CAAA;MACA,IAAA,EAxC4B,WAwC5B;IACA,CAAA,CAAA;EACA,CAAA,CAAA;EACA;;;;;;;;EA0Ue,oBAAS,CAAA,EAAA,CAAA,SAAA,EA1WW,QA0WX,EAAA,KAAA,EA1W4B,cA0W5B,EAAA,GA1W+C,SA0W/C;EACb;;;;AAiRb;;YAlnBc;;QAGP;;iBAciB,gBAAA;;;;;;;;;;;GAWrB,wBAAqB,kBAAA,CAAA,GAAA,CAAA;UAoUP,SAAA;aACJ;;aAGA;YACD;;;cA6QC;2BAEE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":[],"sources":["../../src/playground/client.tsx"],"sourcesContent":["'use client';\nimport {\n type FC,\n Fragment,\n lazy,\n type ReactNode,\n useEffect,\n useMemo,\n useState,\n type ComponentProps,\n useRef,\n} from 'react';\nimport { useApiContext } from '@/ui/contexts/api';\nimport type { FetchResult } from '@/playground/fetcher';\nimport type { ParameterField, SecurityEntry } from '@/playground/index';\nimport { getStatusInfo } from './status-info';\nimport { joinURL, resolveRequestData, resolveServerUrl, withBase } from '@/utils/url';\nimport { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';\nimport { MethodLabel } from '@/ui/components/method-label';\nimport { useQuery } from '@/utils/use-query';\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from 'fumadocs-ui/components/ui/collapsible';\nimport { X, ChevronDown, LoaderCircle } from 'lucide-react';\nimport { encodeRequestData } from '@/requests/media/encode';\nimport { buttonVariants } from 'fumadocs-ui/components/ui/button';\nimport { cn } from '@/utils/cn';\nimport { SchemaProvider, SchemaScope, useResolvedSchema } from '@/playground/schema';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/ui/components/select';\nimport { labelVariants } from '@/ui/components/input';\nimport type { ParsedSchema } from '@/utils/schema';\nimport ServerSelect from './components/server-select';\nimport { useStorageKey } from '@/ui/client/storage-key';\nimport { useExampleRequests } from '@/ui/operation/usage-tabs/client';\nimport {\n FieldKey,\n Stf,\n StfProvider,\n useDataEngine,\n useFieldValue,\n useListener,\n useStf,\n} from '@fumari/stf';\nimport { objectGet, objectSet, stringifyFieldKey } from '@fumari/stf/lib/utils';\nimport { FieldInput, FieldSet, JsonInput, ObjectInput } from './components/inputs';\n\nexport interface FormValues extends Record<string, unknown> {\n path: Record<string, unknown>;\n query: Record<string, unknown>;\n header: Record<string, unknown>;\n cookie: Record<string, unknown>;\n body: unknown;\n}\n\nexport interface PlaygroundClientProps extends ComponentProps<'form'>, SchemaScope {\n route: string;\n method: string;\n parameters?: ParameterField[];\n securities: SecurityEntry[][];\n body?: {\n schema: ParsedSchema;\n mediaType: string;\n };\n /**\n * Resolver for $ref schemas you've passed\n */\n references: Record<string, ParsedSchema>;\n proxyUrl?: string;\n}\n\nexport interface PlaygroundClientOptions {\n /**\n * transform fields for auth-specific parameters (e.g. header)\n */\n transformAuthInputs?: (fields: AuthField[]) => AuthField[];\n\n /**\n * Request timeout in seconds (default: 10s)\n */\n requestTimeout?: number;\n\n components?: Partial<{\n ResultDisplay: FC<{ data: FetchResult }>;\n }>;\n\n /**\n * render the paremeter inputs of API endpoint.\n *\n * for updating values, use:\n * - the `Custom.useController()` from `fumadocs-openapi/playground/client`.\n *\n * Recommended types packages: `json-schema-typed`, `openapi-types`.\n */\n renderParameterField?: (fieldName: FieldKey, param: ParameterField) => ReactNode;\n\n /**\n * render the input for API endpoint body.\n *\n * @see renderParameterField for customisation tips\n */\n renderBodyField?: (\n fieldName: 'body',\n info: {\n schema: ParsedSchema;\n mediaType: string;\n },\n ) => ReactNode;\n}\n\nconst OauthDialog = lazy(() =>\n import('./components/oauth-dialog').then((mod) => ({\n default: mod.OauthDialog,\n })),\n);\nconst OauthDialogTrigger = lazy(() =>\n import('./components/oauth-dialog').then((mod) => ({\n default: mod.OauthDialogTrigger,\n })),\n);\n\nexport default function PlaygroundClient({\n route,\n method = 'GET',\n securities,\n parameters = [],\n body,\n references,\n proxyUrl,\n writeOnly,\n readOnly,\n ...rest\n}: PlaygroundClientProps) {\n const { example: exampleId, examples, setExampleData } = useExampleRequests();\n const storageKeys = useStorageKey();\n const {\n mediaAdapters,\n serverRef,\n client: {\n playground: {\n components: { ResultDisplay = DefaultResultDisplay } = {},\n requestTimeout = 10,\n transformAuthInputs,\n } = {},\n },\n } = useApiContext();\n const [securityId, setSecurityId] = useState(0);\n const { inputs, mapInputs, initAuthValues } = useAuthInputs(\n securities[securityId],\n transformAuthInputs,\n );\n\n const defaultValues: FormValues = useMemo(() => {\n const requestData = examples.find((example) => example.id === exampleId)?.data;\n\n return {\n path: requestData?.path ?? {},\n query: requestData?.query ?? {},\n header: requestData?.header ?? {},\n body: requestData?.body ?? {},\n cookie: requestData?.cookie ?? {},\n };\n }, [examples, exampleId]);\n\n const stf = useStf({\n // it is fine to modify `defaultValues` in place\n // because we already try to persist the form values via `setExampleData`.\n defaultValues,\n });\n\n const testQuery = useQuery(async (input: FormValues) => {\n const targetServer = serverRef.current;\n const fetcher = await import('./fetcher').then((mod) =>\n mod.createBrowserFetcher(mediaAdapters, requestTimeout),\n );\n const encoded = encodeRequestData(\n { ...mapInputs(input), method, bodyMediaType: body?.mediaType },\n mediaAdapters,\n parameters,\n );\n return fetcher.fetch(\n joinURL(\n withBase(\n targetServer ? resolveServerUrl(targetServer.url, targetServer.variables) : '/',\n window.location.origin,\n ),\n resolveRequestData(route, encoded),\n ),\n {\n proxyUrl,\n ...encoded,\n },\n );\n });\n\n const timerRef = useRef<number | null>(null);\n useListener({\n stf,\n onUpdate() {\n if (timerRef.current) window.clearTimeout(timerRef.current);\n timerRef.current = window.setTimeout(\n () => {\n const values = stf.dataEngine.getData() as FormValues;\n for (const item of inputs) {\n const value = stf.dataEngine.get(item.fieldName);\n\n if (value) {\n localStorage.setItem(storageKeys.AuthField(item), JSON.stringify(value));\n }\n }\n\n const data = {\n ...mapInputs(values),\n method,\n bodyMediaType: body?.mediaType,\n };\n setExampleData(data, encodeRequestData(data, mediaAdapters, parameters));\n },\n timerRef.current ? 400 : 0,\n );\n },\n });\n\n useEffect(() => {\n return () => {\n stf.dataEngine.reset(defaultValues);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- ignore other parts\n }, [defaultValues]);\n\n useEffect(() => {\n return initAuthValues(stf);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- ignore other parts\n }, [defaultValues, inputs]);\n\n return (\n <StfProvider value={stf}>\n <SchemaProvider references={references} writeOnly={writeOnly} readOnly={readOnly}>\n <form\n {...rest}\n className={cn(\n 'not-prose flex flex-col rounded-xl border shadow-md overflow-hidden bg-fd-card text-fd-card-foreground',\n rest.className,\n )}\n onSubmit={(e) => {\n testQuery.start(mapInputs(stf.dataEngine.getData() as FormValues));\n e.preventDefault();\n }}\n >\n <ServerSelect />\n <div className=\"flex flex-row items-center gap-2 text-sm p-3 not-last:pb-0\">\n <MethodLabel>{method}</MethodLabel>\n <Route route={route} className=\"flex-1\" />\n <button\n type=\"submit\"\n className={cn(buttonVariants({ color: 'primary', size: 'sm' }), 'w-14 py-1.5')}\n disabled={testQuery.isLoading}\n >\n {testQuery.isLoading ? <LoaderCircle className=\"size-4 animate-spin\" /> : 'Send'}\n </button>\n </div>\n\n {securities.length > 0 && (\n <SecurityTabs\n securities={securities}\n securityId={securityId}\n setSecurityId={setSecurityId}\n >\n {inputs.map((input) => (\n <Fragment key={stringifyFieldKey(input.fieldName)}>{input.children}</Fragment>\n ))}\n </SecurityTabs>\n )}\n <FormBody body={body} parameters={parameters} />\n {testQuery.data ? <ResultDisplay data={testQuery.data} reset={testQuery.reset} /> : null}\n </form>\n </SchemaProvider>\n </StfProvider>\n );\n}\n\nfunction SecurityTabs({\n securities,\n setSecurityId,\n securityId,\n children,\n}: {\n securities: SecurityEntry[][];\n securityId: number;\n setSecurityId: (value: number) => void;\n children: ReactNode;\n}) {\n const [open, setOpen] = useState(false);\n const engine = useDataEngine();\n\n const result = (\n <CollapsiblePanel title=\"Authorization\">\n <Select value={securityId.toString()} onValueChange={(v) => setSecurityId(Number(v))}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {securities.map((security, i) => (\n <SelectItem key={i} value={i.toString()}>\n {security.map((item) => (\n <div key={item.id} className=\"max-w-[600px]\">\n <p className=\"font-mono font-medium\">{item.id}</p>\n <p className=\"text-fd-muted-foreground whitespace-pre-wrap\">{item.description}</p>\n </div>\n ))}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {children}\n </CollapsiblePanel>\n );\n\n for (let i = 0; i < securities.length; i++) {\n const security = securities[i];\n\n for (const item of security) {\n if (item.type === 'oauth2') {\n return (\n <OauthDialog\n scheme={item}\n scopes={item.scopes}\n open={open}\n setOpen={(v) => {\n setOpen(v);\n if (v) {\n setSecurityId(i);\n }\n }}\n setToken={(token) => engine.update(['header', 'Authorization'], token)}\n >\n {result}\n </OauthDialog>\n );\n }\n }\n }\n\n return result;\n}\n\nconst ParamTypes = ['path', 'header', 'cookie', 'query'] as const;\n\nfunction FormBody({ parameters = [], body }: Pick<PlaygroundClientProps, 'parameters' | 'body'>) {\n const { renderParameterField, renderBodyField } = useApiContext().client.playground ?? {};\n const panels = useMemo(() => {\n return ParamTypes.map((type) => {\n const items = parameters.filter((v) => v.in === type);\n if (items.length === 0) return;\n\n return (\n <CollapsiblePanel\n key={type}\n title={\n {\n header: 'Header',\n cookie: 'Cookies',\n query: 'Query',\n path: 'Path',\n }[type]\n }\n >\n {items.map((field) => {\n const fieldName: FieldKey = [type, field.name];\n if (renderParameterField) {\n return renderParameterField(fieldName, field);\n }\n\n const contentTypes = field.content && Object.keys(field.content);\n const schema = (\n field.content && contentTypes && contentTypes.length > 0\n ? field.content[contentTypes[0]].schema\n : field.schema\n ) as ParsedSchema;\n\n return (\n <FieldSet\n key={stringifyFieldKey(fieldName)}\n name={field.name}\n fieldName={fieldName}\n field={schema}\n />\n );\n })}\n </CollapsiblePanel>\n );\n });\n }, [parameters, renderParameterField]);\n\n return (\n <>\n {panels}\n {body && (\n <CollapsiblePanel title=\"Body\">\n {renderBodyField ? renderBodyField('body', body) : <BodyInput field={body.schema} />}\n </CollapsiblePanel>\n )}\n </>\n );\n}\n\nfunction BodyInput({ field: _field }: { field: ParsedSchema }) {\n const field = useResolvedSchema(_field);\n const [isJson, setIsJson] = useState(false);\n\n if (field.format === 'binary') return <FieldSet field={field} fieldName={['body']} />;\n\n if (isJson)\n return (\n <>\n <button\n className={cn(\n buttonVariants({\n color: 'secondary',\n size: 'sm',\n className: 'w-fit font-mono p-2',\n }),\n )}\n onClick={() => setIsJson(false)}\n type=\"button\"\n >\n Close JSON Editor\n </button>\n <JsonInput fieldName={['body']} />\n </>\n );\n\n return (\n <FieldSet\n field={field}\n fieldName={['body']}\n collapsible={false}\n name={\n <button\n type=\"button\"\n className={cn(\n buttonVariants({\n color: 'secondary',\n size: 'sm',\n className: 'p-2',\n }),\n )}\n onClick={() => setIsJson(true)}\n >\n Open JSON Editor\n </button>\n }\n />\n );\n}\n\nexport interface AuthField {\n fieldName: FieldKey;\n defaultValue: unknown;\n\n original?: SecurityEntry;\n children: ReactNode;\n\n mapOutput?: (values: unknown) => unknown;\n}\n\nfunction useAuthInputs(\n securities?: SecurityEntry[],\n transform?: (fields: AuthField[]) => AuthField[],\n) {\n const storageKeys = useStorageKey();\n const inputs = useMemo(() => {\n const result: AuthField[] = [];\n if (!securities) return result;\n\n for (const security of securities) {\n if (security.type === 'http' && security.scheme === 'basic') {\n const fieldName: FieldKey = ['header', 'Authorization'];\n\n result.push({\n fieldName,\n original: security,\n defaultValue: {\n username: '',\n password: '',\n },\n mapOutput(out) {\n if (out && typeof out === 'object') {\n return `Basic ${btoa(`${'username' in out ? out.username : ''}:${'password' in out ? out.password : ''}`)}`;\n }\n\n return out;\n },\n children: (\n <ObjectInput\n field={{\n type: 'object',\n properties: {\n username: {\n type: 'string',\n },\n password: {\n type: 'string',\n },\n },\n required: ['username', 'password'],\n }}\n fieldName={fieldName}\n />\n ),\n });\n } else if (security.type === 'oauth2') {\n const fieldName: FieldKey = ['header', 'Authorization'];\n\n result.push({\n fieldName,\n original: security,\n defaultValue: 'Bearer ',\n children: (\n <fieldset className=\"flex flex-col gap-2\">\n <label htmlFor={stringifyFieldKey(fieldName)} className={cn(labelVariants())}>\n Access Token\n </label>\n <div className=\"flex gap-2\">\n <FieldInput\n fieldName={fieldName}\n isRequired\n field={{\n type: 'string',\n }}\n className=\"flex-1\"\n />\n\n <OauthDialogTrigger\n type=\"button\"\n className={cn(\n buttonVariants({\n size: 'sm',\n color: 'secondary',\n }),\n )}\n >\n Authorize\n </OauthDialogTrigger>\n </div>\n </fieldset>\n ),\n });\n } else if (security.type === 'http') {\n const fieldName: FieldKey = ['header', 'Authorization'];\n\n result.push({\n fieldName,\n original: security,\n defaultValue: 'Bearer ',\n children: (\n <FieldSet\n name=\"Authorization (header)\"\n fieldName={fieldName}\n isRequired\n field={{\n type: 'string',\n }}\n />\n ),\n });\n } else if (security.type === 'apiKey') {\n const fieldName: FieldKey = [security.in, security.name];\n\n result.push({\n fieldName,\n defaultValue: '',\n original: security,\n children: (\n <FieldSet\n fieldName={fieldName}\n name={`${security.name} (${security.in})`}\n isRequired\n field={{\n type: 'string',\n }}\n />\n ),\n });\n } else {\n const fieldName: FieldKey = ['header', 'Authorization'];\n\n result.push({\n fieldName,\n defaultValue: '',\n original: security,\n children: (\n <>\n <FieldSet\n name=\"Authorization (header)\"\n isRequired\n fieldName={fieldName}\n field={{\n type: 'string',\n }}\n />\n <p className=\"text-fd-muted-foreground text-xs\">\n OpenID Connect is not supported at the moment, you can still set an access token\n here.\n </p>\n </>\n ),\n });\n }\n }\n\n return transform ? transform(result) : result;\n }, [securities, transform]);\n\n const mapInputs = (values: FormValues) => {\n const cloned = structuredClone(values);\n\n for (const item of inputs) {\n if (!item.mapOutput) continue;\n objectSet(cloned, item.fieldName, item.mapOutput(objectGet(cloned, item.fieldName)));\n }\n\n return cloned;\n };\n\n const initAuthValues = (stf: Stf) => {\n const { dataEngine } = stf;\n for (const item of inputs) {\n const stored = localStorage.getItem(storageKeys.AuthField(item));\n\n if (stored) {\n const parsed = JSON.parse(stored);\n if (typeof parsed === typeof item.defaultValue) {\n dataEngine.init(item.fieldName, parsed);\n continue;\n }\n }\n\n dataEngine.init(item.fieldName, item.defaultValue);\n }\n\n // reset\n return () => {\n for (const item of inputs) {\n stf.dataEngine.delete(item.fieldName);\n }\n };\n };\n\n return { inputs, mapInputs, initAuthValues };\n}\n\nfunction Route({ route, ...props }: ComponentProps<'div'> & { route: string }) {\n return (\n <div\n {...props}\n className={cn(\n 'flex flex-row items-center gap-0.5 overflow-auto text-nowrap',\n props.className,\n )}\n >\n {route.split('/').map((part, index) => (\n <Fragment key={index}>\n {index > 0 && <span className=\"text-fd-muted-foreground\">/</span>}\n {part.startsWith('{') && part.endsWith('}') ? (\n <code className=\"bg-fd-primary/10 text-fd-primary\">{part}</code>\n ) : (\n <code className=\"text-fd-foreground\">{part}</code>\n )}\n </Fragment>\n ))}\n </div>\n );\n}\n\nfunction DefaultResultDisplay({ data, reset }: { data: FetchResult; reset: () => void }) {\n const statusInfo = useMemo(() => getStatusInfo(data.status), [data.status]);\n const { shikiOptions } = useApiContext();\n\n return (\n <div className=\"flex flex-col gap-3 p-3\">\n <div className=\"flex justify-between items-center\">\n <div className=\"inline-flex items-center gap-1.5 text-sm font-medium text-fd-foreground\">\n <statusInfo.icon className={cn('size-4', statusInfo.color)} />\n {statusInfo.description}\n </div>\n <button\n type=\"button\"\n className={cn(\n buttonVariants({ size: 'icon-xs' }),\n 'p-0 text-fd-muted-foreground hover:text-fd-accent-foreground [&_svg]:size-3.5',\n )}\n onClick={() => reset()}\n aria-label=\"Dismiss response\"\n >\n <X />\n </button>\n </div>\n <p className=\"text-sm text-fd-muted-foreground\">{data.status}</p>\n {data.data !== undefined && (\n <DynamicCodeBlock\n lang={typeof data.data === 'string' && data.data.length > 50000 ? 'text' : data.type}\n code={typeof data.data === 'string' ? data.data : JSON.stringify(data.data, null, 2)}\n options={shikiOptions}\n />\n )}\n </div>\n );\n}\n\nfunction CollapsiblePanel({\n title,\n children,\n ...props\n}: Omit<ComponentProps<'div'>, 'title'> & {\n title: ReactNode;\n}) {\n return (\n <Collapsible {...props} className=\"border-b last:border-b-0\">\n <CollapsibleTrigger className=\"group w-full flex items-center gap-2 p-3 text-sm font-medium\">\n {title}\n <ChevronDown className=\"ms-auto size-3.5 text-fd-muted-foreground group-data-[state=open]:rotate-180\" />\n </CollapsibleTrigger>\n <CollapsibleContent>\n <div className=\"flex flex-col gap-3 p-3 pt-1\">{children}</div>\n </CollapsibleContent>\n </Collapsible>\n );\n}\n\nexport const Custom = {\n useController(\n fieldName: FieldKey,\n options?: {\n defaultValue?: unknown;\n },\n ) {\n const [value, setValue] = useFieldValue(fieldName, options);\n return {\n value,\n setValue,\n };\n },\n};\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inputs.js","names":["value"],"sources":["../../../src/playground/components/inputs.tsx"],"sourcesContent":["'use client';\nimport { type ComponentProps, type HTMLAttributes, type ReactNode, useState } from 'react';\nimport { ChevronRight, Plus, Trash2, X } from 'lucide-react';\nimport { FieldKey, useArray, useDataEngine, useFieldValue, useObject } from '@fumari/stf';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/ui/components/select';\nimport { Input, labelVariants } from '@/ui/components/input';\nimport { getDefaultValue } from '../get-default-values';\nimport { cn } from '@/utils/cn';\nimport { buttonVariants } from 'fumadocs-ui/components/ui/button';\nimport { FormatFlags, schemaToString } from '@/utils/schema-to-string';\nimport { anyFields, useFieldInfo, useResolvedSchema, useSchemaScope } from '@/playground/schema';\nimport type { ParsedSchema } from '@/utils/schema';\nimport { stringifyFieldKey } from '@fumari/stf/lib/utils';\n\nfunction FieldLabel(props: ComponentProps<'label'>) {\n return (\n <label {...props} className={cn('w-full inline-flex items-center gap-0.5', props.className)}>\n {props.children}\n </label>\n );\n}\n\nfunction FieldLabelName({\n required = false,\n ...props\n}: ComponentProps<'span'> & { required?: boolean }) {\n return (\n <span {...props} className={cn(labelVariants(), 'font-mono me-auto', props.className)}>\n {props.children}\n {required && <span className=\"text-red-400/80 mx-1\">*</span>}\n </span>\n );\n}\n\nfunction FieldLabelType(props: ComponentProps<'code'>) {\n return (\n <code {...props} className={cn('text-xs text-fd-muted-foreground', props.className)}>\n {props.children}\n </code>\n );\n}\n\nexport function ObjectInput({\n field: _field,\n fieldName,\n ...props\n}: {\n field: Exclude<ParsedSchema, boolean>;\n fieldName: FieldKey;\n} & ComponentProps<'div'>) {\n const field = useResolvedSchema(_field);\n const [nextName, setNextName] = useState('');\n const { properties, onAppend, onDelete } = useObject(fieldName, {\n defaultValue: () => getDefaultValue(field) as object,\n properties: field.properties ?? {},\n fallback: field.additionalProperties,\n patternProperties: field.patternProperties,\n });\n\n const isDynamic = field.patternProperties ?? field.additionalProperties;\n return (\n <div {...props} className={cn('grid grid-cols-1 gap-4 @md:grid-cols-2', props.className)}>\n {properties.map((child) => {\n let toolbar: ReactNode = null;\n if (child.kind === 'pattern' || child.kind === 'fallback') {\n toolbar = (\n <button\n type=\"button\"\n aria-label=\"Remove Item\"\n className={cn(\n buttonVariants({\n color: 'outline',\n size: 'icon-xs',\n }),\n )}\n onClick={() => {\n onDelete(child.key);\n }}\n >\n <Trash2 />\n </button>\n );\n }\n\n return (\n <FieldSet\n key={child.key}\n name={child.key}\n field={child.info}\n fieldName={child.field}\n isRequired={field.required?.includes(child.key)}\n toolbar={toolbar}\n />\n );\n })}\n {isDynamic && (\n <div className=\"flex gap-2 col-span-full\">\n <Input\n value={nextName}\n placeholder=\"Enter Property Name\"\n onChange={(e) => setNextName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n setNextName('');\n onAppend(nextName);\n e.preventDefault();\n }\n }}\n />\n <button\n type=\"button\"\n className={cn(buttonVariants({ color: 'secondary', size: 'sm' }), 'px-4')}\n onClick={() => {\n onAppend(nextName);\n setNextName('');\n }}\n >\n New\n </button>\n </div>\n )}\n </div>\n );\n}\n\nexport function JsonInput({ fieldName }: { fieldName: FieldKey }) {\n const engine = useDataEngine();\n const [error, setError] = useState<string | null>(null);\n const [value, setValue] = useState(() => JSON.stringify(engine.init(fieldName, {}), null, 2));\n\n return (\n <div className=\"flex flex-col bg-fd-secondary text-fd-secondary-foreground overflow-hidden border rounded-lg\">\n <textarea\n value={value}\n className=\"p-2 h-[240px] text-sm font-mono resize-none focus-visible:outline-none\"\n onChange={(v) => {\n setValue(v.target.value);\n try {\n engine.update(fieldName, JSON.parse(v.target.value));\n setError(null);\n } catch (e) {\n if (e instanceof Error) setError(e.message);\n }\n }}\n />\n <p className=\"p-2 text-xs font-mono border-t text-red-400 empty:hidden\">{error}</p>\n </div>\n );\n}\n\nexport function FieldInput({\n field,\n fieldName,\n isRequired,\n ...props\n}: HTMLAttributes<HTMLElement> & {\n field: Exclude<ParsedSchema, boolean>;\n isRequired?: boolean;\n fieldName: FieldKey;\n}) {\n const engine = useDataEngine();\n const [value, setValue] = useFieldValue(fieldName);\n const id = stringifyFieldKey(fieldName);\n if (field.type === 'null') return;\n\n function renderUnset(children: ReactNode) {\n return (\n <div {...props} className={cn('flex flex-row gap-2', props.className)}>\n {children}\n {value !== undefined && !isRequired && (\n <button\n type=\"button\"\n onClick={() => engine.delete(fieldName)}\n className=\"text-fd-muted-foreground\"\n >\n <X className=\"size-4\" />\n </button>\n )}\n </div>\n );\n }\n\n if (field.type === 'string' && field.format === 'binary') {\n return renderUnset(\n <>\n <label\n htmlFor={id}\n className={cn(\n buttonVariants({\n color: 'secondary',\n className: 'w-full h-9 gap-2 truncate',\n }),\n )}\n >\n {value instanceof File ? (\n <>\n <span className=\"text-fd-muted-foreground text-xs\">Selected</span>\n <span className=\"truncate w-0 flex-1 text-end\">{value.name}</span>\n </>\n ) : (\n <span className=\"text-fd-muted-foreground\">Upload</span>\n )}\n </label>\n <input\n id={id}\n type=\"file\"\n multiple={false}\n onChange={(e) => {\n if (!e.target.files || e.target.files.length === 0) return;\n setValue(e.target.files.item(0));\n }}\n hidden\n />\n </>,\n );\n }\n\n if (field.enum && field.enum.length > 0) {\n const idx = field.enum.indexOf(value);\n\n return (\n <Select value={String(idx)} onValueChange={(v) => setValue(field.enum![Number(v)])}>\n <SelectTrigger id={id} {...props}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {field.enum.map((item, i) => (\n <SelectItem key={i} value={String(i)}>\n {typeof item === 'string' ? item : JSON.stringify(item, null, 2)}\n </SelectItem>\n ))}\n {!isRequired && <SelectItem value=\"-1\">Unset</SelectItem>}\n </SelectContent>\n </Select>\n );\n }\n\n if (field.type === 'boolean') {\n return (\n <Select\n value={String(value)}\n onValueChange={(value) => setValue(value === 'undefined' ? undefined : value === 'true')}\n >\n <SelectTrigger id={id} {...props}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"true\">True</SelectItem>\n <SelectItem value=\"false\">False</SelectItem>\n {!isRequired && <SelectItem value=\"undefined\">Unset</SelectItem>}\n </SelectContent>\n </Select>\n );\n }\n\n const isNumber = field.type === 'integer' || field.type === 'number';\n return renderUnset(\n <Input\n id={id}\n placeholder=\"Enter value\"\n type={isNumber ? 'number' : 'text'}\n step={field.type === 'integer' ? 1 : undefined}\n value={String(value ?? '')}\n onChange={(e) => {\n if (isNumber) {\n setValue(Number.isNaN(e.target.valueAsNumber) ? undefined : e.target.valueAsNumber);\n } else if (!isNumber) {\n setValue(e.target.value);\n }\n }}\n />,\n );\n}\n\nexport function FieldSet({\n field: _field,\n fieldName,\n toolbar,\n name,\n isRequired,\n depth = 0,\n slotType,\n collapsible = true,\n ...props\n}: HTMLAttributes<HTMLElement> & {\n isRequired?: boolean;\n name?: ReactNode;\n field: ParsedSchema;\n fieldName: FieldKey;\n depth?: number;\n\n slotType?: ReactNode;\n toolbar?: ReactNode;\n collapsible?: boolean;\n}) {\n const { readOnly, writeOnly } = useSchemaScope();\n const field = useResolvedSchema(_field);\n const [show, setShow] = useState(!collapsible);\n const { info, updateInfo } = useFieldInfo(fieldName, field);\n const id = stringifyFieldKey(fieldName);\n const dataEngine = useDataEngine();\n\n if (_field === false) return;\n if (field.readOnly && !readOnly) return;\n if (field.writeOnly && !writeOnly) return;\n\n if (info.unionField && field[info.unionField]) {\n const union = field[info.unionField]!;\n const showSelect = union.length > 1;\n\n return (\n <FieldSet\n {...props}\n name={name}\n fieldName={fieldName}\n isRequired={isRequired}\n field={union[info.oneOf]}\n depth={depth + 1}\n slotType={showSelect ? false : slotType}\n toolbar={\n <>\n {showSelect && (\n <select\n className=\"text-xs font-mono\"\n value={info.oneOf}\n onChange={(e) => {\n updateInfo({\n oneOf: Number(e.target.value),\n });\n }}\n >\n {union.map((item, i) => (\n <option key={i} value={i} className=\"bg-fd-popover text-fd-popover-foreground\">\n {schemaToString(item, undefined, FormatFlags.UseAlias)}\n </option>\n ))}\n </select>\n )}\n {toolbar}\n </>\n }\n />\n );\n }\n\n if (Array.isArray(field.type)) {\n const showSelect = field.type.length > 1;\n\n return (\n <FieldSet\n {...props}\n name={name}\n fieldName={fieldName}\n isRequired={isRequired}\n field={{\n ...field,\n type: info.selectedType,\n }}\n depth={depth + 1}\n slotType={showSelect ? false : slotType}\n toolbar={\n <>\n {showSelect && (\n <select\n className=\"text-xs font-mono\"\n value={info.selectedType}\n onChange={(e) => {\n updateInfo({\n selectedType: e.target.value,\n });\n }}\n >\n {field.type.map((item) => (\n <option\n key={item}\n value={item}\n className=\"bg-fd-popover text-fd-popover-foreground\"\n >\n {item}\n </option>\n ))}\n </select>\n )}\n {toolbar}\n </>\n }\n />\n );\n }\n\n if (field.type === 'object' || info.intersection) {\n const schema = info.intersection?.merged ?? field;\n return (\n <fieldset\n {...props}\n className={cn('flex flex-col gap-1.5 col-span-full @container', props.className)}\n >\n <FieldLabel htmlFor={id}>\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => {\n dataEngine.init(fieldName, getDefaultValue(schema));\n setShow((prev) => !prev);\n }}\n className={cn(\n buttonVariants({\n size: 'icon-xs',\n color: 'ghost',\n className: 'text-fd-muted-foreground -ms-1',\n }),\n )}\n >\n <ChevronRight className={cn(show && 'rotate-90')} />\n </button>\n )}\n <FieldLabelName required={isRequired}>{name}</FieldLabelName>\n {slotType ?? <FieldLabelType>{schemaToString(field)}</FieldLabelType>}\n {toolbar}\n </FieldLabel>\n {show && (\n <ObjectInput\n field={schema}\n fieldName={fieldName}\n {...props}\n className={cn(\n 'rounded-lg border border-fd-primary/20 bg-fd-background/50 p-2 shadow-sm',\n props.className,\n )}\n />\n )}\n </fieldset>\n );\n }\n\n if (field.type === 'array') {\n return (\n <fieldset {...props} className={cn('flex flex-col gap-1.5 col-span-full', props.className)}>\n <FieldLabel htmlFor={id}>\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => {\n dataEngine.init(fieldName, getDefaultValue(field));\n setShow((prev) => !prev);\n }}\n className={cn(\n buttonVariants({\n size: 'icon-xs',\n color: 'ghost',\n className: 'text-fd-muted-foreground -ms-1',\n }),\n )}\n >\n <ChevronRight className={cn(show && 'rotate-90')} />\n </button>\n )}\n <FieldLabelName required={isRequired}>{name}</FieldLabelName>\n {slotType ?? <FieldLabelType>{schemaToString(field)}</FieldLabelType>}\n {toolbar}\n </FieldLabel>\n {show && (\n <ArrayInput\n fieldName={fieldName}\n items={field.items ?? anyFields}\n {...props}\n className={cn(\n 'rounded-lg border border-fd-primary/20 bg-fd-background/50 p-2 shadow-sm',\n props.className,\n )}\n />\n )}\n </fieldset>\n );\n }\n return (\n <fieldset {...props} className={cn('flex flex-col gap-1.5', props.className)}>\n <FieldLabel htmlFor={id}>\n <FieldLabelName required={isRequired}>{name}</FieldLabelName>\n {slotType ?? <FieldLabelType>{schemaToString(field)}</FieldLabelType>}\n {toolbar}\n </FieldLabel>\n <FieldInput field={field} fieldName={fieldName} isRequired={isRequired} />\n </fieldset>\n );\n}\n\nfunction ArrayInput({\n fieldName,\n items: itemSchema,\n ...props\n}: {\n fieldName: FieldKey;\n items: ParsedSchema;\n} & ComponentProps<'div'>) {\n const name = fieldName.at(-1) ?? '';\n const { items, insertItem, removeItem } = useArray(fieldName, {\n defaultValue: [],\n });\n\n return (\n <div {...props} className={cn('flex flex-col gap-2', props.className)}>\n {items.map((item) => (\n <FieldSet\n key={item.index}\n name={\n <span className=\"text-fd-muted-foreground\">\n {name}[{item.index}]\n </span>\n }\n field={itemSchema}\n isRequired\n fieldName={item.field}\n toolbar={\n <button\n type=\"button\"\n aria-label=\"Remove Item\"\n className={cn(\n buttonVariants({\n color: 'outline',\n size: 'icon-xs',\n }),\n )}\n onClick={() => removeItem(item.index)}\n >\n <Trash2 />\n </button>\n }\n />\n ))}\n <button\n type=\"button\"\n className={cn(\n buttonVariants({\n color: 'secondary',\n className: 'gap-1.5 py-2',\n size: 'sm',\n }),\n )}\n onClick={() => {\n insertItem(getDefaultValue(itemSchema));\n }}\n >\n <Plus className=\"size-4\" />\n New Item\n </button>\n </div>\n );\n}\n"],"mappings":"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"}
|