fumadocs-openapi 10.6.5 → 10.6.6
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/css/generated/shared.css +32 -5
- package/dist/generate-file.js +3 -2
- package/dist/i18n.d.ts +1 -0
- package/dist/i18n.js +1 -0
- package/dist/playground/auth.js +92 -0
- package/dist/playground/client.d.ts +2 -1
- package/dist/playground/client.js +254 -180
- package/dist/playground/components/oauth-dialog.js +125 -162
- package/dist/playground/components/spinner.js +14 -0
- package/dist/requests/generators/csharp.js +2 -1
- package/dist/requests/generators/curl.js +5 -5
- package/dist/requests/generators/go.js +5 -5
- package/dist/requests/generators/java.js +4 -4
- package/dist/requests/generators/javascript.js +3 -3
- package/dist/requests/generators/python.js +5 -4
- package/dist/requests/media/adapter.js +7 -7
- package/dist/requests/string-utils.js +25 -4
- package/dist/requests/types.d.ts +3 -2
- package/dist/ui/api-page.js +3 -1
- package/dist/ui/base.d.ts +8 -4
- package/dist/ui/base.js +5 -0
- package/dist/ui/client/boundary.lazy.js +2 -1
- package/dist/ui/client/storage-key.js +1 -1
- package/dist/ui/contexts/api.d.ts +6 -3
- package/dist/ui/contexts/api.js +7 -2
- package/dist/ui/create-client.js +5 -0
- package/dist/ui/operation/request-tabs.d.ts +10 -0
- package/dist/ui/operation/request-tabs.js +43 -37
- package/dist/utils/pages/to-text.js +5 -4
- package/dist/utils/schema/index.d.ts +3 -4
- package/dist/utils/schema/index.js +4 -9
- package/dist/utils/use-query.js +2 -1
- package/package.json +2 -2
|
@@ -17,14 +17,17 @@ import ServerSelect from "./components/server-select.js";
|
|
|
17
17
|
import { FieldInput, FieldSet, JsonInput, ObjectInput } from "./components/inputs.js";
|
|
18
18
|
import { ClientCodeBlock } from "../ui/components/codeblock.js";
|
|
19
19
|
import { useOperationContext } from "../ui/operation/client.js";
|
|
20
|
-
import {
|
|
20
|
+
import { useAuth } from "./auth.js";
|
|
21
|
+
import { OAuthDialog, OAuthDialogContent, OAuthDialogTrigger } from "./components/oauth-dialog.js";
|
|
22
|
+
import { Spinner } from "./components/spinner.js";
|
|
21
23
|
import { Fragment, useEffect, useMemo, useRef, useState } from "react";
|
|
22
24
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
23
25
|
import { ChevronDown, LoaderCircle } from "lucide-react";
|
|
24
26
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "fumadocs-ui/components/ui/collapsible";
|
|
25
27
|
import { buttonVariants } from "fumadocs-ui/components/ui/button";
|
|
26
28
|
import { StfProvider, useDataEngine, useFieldValue, useListener, useStf } from "@fumari/stf";
|
|
27
|
-
import { objectGet, objectSet, stringifyFieldKey } from "@fumari/stf/lib/utils";
|
|
29
|
+
import { arrayStartsWith, objectGet, objectSet, stringifyFieldKey } from "@fumari/stf/lib/utils";
|
|
30
|
+
import { useOnChange } from "fumadocs-core/utils/use-on-change";
|
|
28
31
|
//#region src/playground/client.tsx
|
|
29
32
|
function PlaygroundClient({ route, method, securities, doc, proxyUrl, writeOnly, readOnly, ...rest }) {
|
|
30
33
|
const t = useTranslations();
|
|
@@ -51,13 +54,7 @@ function PlaygroundClient({ route, method, securities, doc, proxyUrl, writeOnly,
|
|
|
51
54
|
]);
|
|
52
55
|
const { example: exampleId, examples, setExampleData } = useOperationContext();
|
|
53
56
|
const { server } = useServerContext();
|
|
54
|
-
const
|
|
55
|
-
const { mediaAdapters, client: { playground: { components: { ResultDisplay = DefaultResultDisplay, CollapsiblePanel = DefaultCollapsiblePanel } = {}, requestTimeout, fetchOptions = { requestTimeout }, transformAuthInputs, renderBodyField } = {} } } = useApiContext();
|
|
56
|
-
const [securityId, setSecurityId] = useState(() => {
|
|
57
|
-
const idx = securities.findIndex((s) => s.every((entry) => !entry.deprecated));
|
|
58
|
-
return idx === -1 ? 0 : idx;
|
|
59
|
-
});
|
|
60
|
-
const { inputs, mapInputs, initAuthValues } = useAuthInputs(securities[securityId], transformAuthInputs);
|
|
57
|
+
const { mediaAdapters, client: { playground: { components: { ResultDisplay = DefaultResultDisplay, CollapsiblePanel = DefaultCollapsiblePanel } = {}, requestTimeout, fetchOptions = { requestTimeout }, renderBodyField } = {} } } = useApiContext();
|
|
61
58
|
const defaultValues = useMemo(() => {
|
|
62
59
|
const requestData = examples.find((example) => example.id === exampleId)?.data;
|
|
63
60
|
return {
|
|
@@ -69,6 +66,7 @@ function PlaygroundClient({ route, method, securities, doc, proxyUrl, writeOnly,
|
|
|
69
66
|
};
|
|
70
67
|
}, [examples, exampleId]);
|
|
71
68
|
const stf = useStf({ defaultValues });
|
|
69
|
+
const { inputs, requirementId, setRequirementId, mapInputs, initAuthInputs } = useAuthInputs(stf.dataEngine, securities);
|
|
72
70
|
const testQuery = useQuery(async (input) => {
|
|
73
71
|
const fetcher = await import("./fetcher.js").then((mod) => mod.createBrowserFetcher(mediaAdapters, {
|
|
74
72
|
proxyUrl,
|
|
@@ -82,23 +80,21 @@ function PlaygroundClient({ route, method, securities, doc, proxyUrl, writeOnly,
|
|
|
82
80
|
return fetcher.fetch(joinURL(withBase(server ? resolveServerUrl(server.url, server.variables) : "/", window.location.origin), resolveRequestData(route, encoded)), encoded);
|
|
83
81
|
});
|
|
84
82
|
const timerRef = useRef(null);
|
|
83
|
+
const stfSync = useRef(false);
|
|
84
|
+
function triggerExampleUpdate() {
|
|
85
|
+
const data = {
|
|
86
|
+
...mapInputs(stf.dataEngine.getData()),
|
|
87
|
+
method,
|
|
88
|
+
bodyMediaType: body?.mediaType
|
|
89
|
+
};
|
|
90
|
+
setExampleData(data, encodeRequestData(data, mediaAdapters, parameters));
|
|
91
|
+
}
|
|
85
92
|
useListener({
|
|
86
93
|
stf,
|
|
87
94
|
onUpdate() {
|
|
95
|
+
if (!stfSync.current) return;
|
|
88
96
|
if (timerRef.current) window.clearTimeout(timerRef.current);
|
|
89
|
-
timerRef.current = window.setTimeout(
|
|
90
|
-
const values = stf.dataEngine.getData();
|
|
91
|
-
for (const item of inputs) {
|
|
92
|
-
const value = stf.dataEngine.get(item.fieldName);
|
|
93
|
-
if (value) localStorage.setItem(storageKeys.AuthField(item), JSON.stringify(value));
|
|
94
|
-
}
|
|
95
|
-
const data = {
|
|
96
|
-
...mapInputs(values),
|
|
97
|
-
method,
|
|
98
|
-
bodyMediaType: body?.mediaType
|
|
99
|
-
};
|
|
100
|
-
setExampleData(data, encodeRequestData(data, mediaAdapters, parameters));
|
|
101
|
-
}, timerRef.current ? 400 : 0);
|
|
97
|
+
timerRef.current = window.setTimeout(triggerExampleUpdate, 400);
|
|
102
98
|
}
|
|
103
99
|
});
|
|
104
100
|
useEffect(() => {
|
|
@@ -106,7 +102,13 @@ function PlaygroundClient({ route, method, securities, doc, proxyUrl, writeOnly,
|
|
|
106
102
|
stf.dataEngine.reset(defaultValues);
|
|
107
103
|
}, [defaultValues]);
|
|
108
104
|
useEffect(() => {
|
|
109
|
-
|
|
105
|
+
const reset = initAuthInputs();
|
|
106
|
+
triggerExampleUpdate();
|
|
107
|
+
stfSync.current = true;
|
|
108
|
+
return () => {
|
|
109
|
+
stfSync.current = false;
|
|
110
|
+
reset();
|
|
111
|
+
};
|
|
110
112
|
}, [defaultValues, inputs]);
|
|
111
113
|
return /* @__PURE__ */ jsx(StfProvider, {
|
|
112
114
|
value: stf,
|
|
@@ -118,7 +120,7 @@ function PlaygroundClient({ route, method, securities, doc, proxyUrl, writeOnly,
|
|
|
118
120
|
...rest,
|
|
119
121
|
className: cn("not-prose flex flex-col rounded-xl border shadow-md overflow-hidden bg-fd-card text-fd-card-foreground", rest.className),
|
|
120
122
|
onSubmit: (e) => {
|
|
121
|
-
testQuery.start(
|
|
123
|
+
testQuery.start(stf.dataEngine.getData());
|
|
122
124
|
e.preventDefault();
|
|
123
125
|
},
|
|
124
126
|
children: [
|
|
@@ -146,10 +148,10 @@ function PlaygroundClient({ route, method, securities, doc, proxyUrl, writeOnly,
|
|
|
146
148
|
data: testQuery.data,
|
|
147
149
|
reset: testQuery.reset
|
|
148
150
|
}) : null,
|
|
149
|
-
securities.length > 0 && /* @__PURE__ */ jsx(
|
|
151
|
+
securities.length > 0 && /* @__PURE__ */ jsx(SecurityRequirements, {
|
|
150
152
|
securities,
|
|
151
|
-
securityId,
|
|
152
|
-
setSecurityId,
|
|
153
|
+
securityId: requirementId,
|
|
154
|
+
setSecurityId: setRequirementId,
|
|
153
155
|
children: inputs.map((input) => /* @__PURE__ */ jsx(Fragment, { children: input.children }, stringifyFieldKey(input.fieldName)))
|
|
154
156
|
}),
|
|
155
157
|
/* @__PURE__ */ jsx(ParametersForm, { parameters }),
|
|
@@ -163,50 +165,62 @@ function PlaygroundClient({ route, method, securities, doc, proxyUrl, writeOnly,
|
|
|
163
165
|
})
|
|
164
166
|
});
|
|
165
167
|
}
|
|
166
|
-
function
|
|
167
|
-
return /* @__PURE__ */ jsx("div", {
|
|
168
|
-
className: "flex flex-col gap-2 max-w-[600px]",
|
|
169
|
-
children: security.map((item) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", {
|
|
170
|
-
className: cn("font-mono font-medium", item.deprecated && "text-fd-muted-foreground line-through"),
|
|
171
|
-
children: item.id
|
|
172
|
-
}), /* @__PURE__ */ jsx("p", {
|
|
173
|
-
className: "text-fd-muted-foreground whitespace-pre-wrap",
|
|
174
|
-
children: item.description
|
|
175
|
-
})] }, item.id))
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
function SecurityTabs({ securities, setSecurityId, securityId, children }) {
|
|
179
|
-
const [open, setOpen] = useState(false);
|
|
180
|
-
const engine = useDataEngine();
|
|
168
|
+
function SecurityRequirements({ securities, setSecurityId, securityId, children }) {
|
|
181
169
|
const t = useTranslations();
|
|
170
|
+
const { isLoading, error } = useAuth();
|
|
171
|
+
const defaultOpen = isLoading || error != null;
|
|
172
|
+
const [open, setOpen] = useState(defaultOpen);
|
|
182
173
|
const { CollapsiblePanel = DefaultCollapsiblePanel } = useApiContext().client.playground?.components ?? {};
|
|
183
|
-
|
|
184
|
-
|
|
174
|
+
useOnChange(defaultOpen, () => {
|
|
175
|
+
if (defaultOpen) setOpen(true);
|
|
176
|
+
});
|
|
177
|
+
return /* @__PURE__ */ jsxs(CollapsiblePanel, {
|
|
178
|
+
title: /* @__PURE__ */ jsxs(Fragment$1, { children: [t.authorization, isLoading && /* @__PURE__ */ jsxs("span", {
|
|
179
|
+
className: "border-s ps-2 inline-flex items-center gap-1.5 text-fd-muted-foreground text-xs font-mono",
|
|
180
|
+
children: [
|
|
181
|
+
/* @__PURE__ */ jsx(Spinner, {}),
|
|
182
|
+
" ",
|
|
183
|
+
t.fetchingToken
|
|
184
|
+
]
|
|
185
|
+
})] }),
|
|
185
186
|
"data-type": "authorization",
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
children: /* @__PURE__ */ jsx(
|
|
192
|
-
|
|
193
|
-
|
|
187
|
+
open,
|
|
188
|
+
onOpenChange: setOpen,
|
|
189
|
+
children: [
|
|
190
|
+
error != null && /* @__PURE__ */ jsxs("div", {
|
|
191
|
+
className: "p-2 border rounded-lg bg-fd-secondary",
|
|
192
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
193
|
+
className: "text-fd-muted-foreground font-medium mb-1",
|
|
194
|
+
children: t.fetchTokenError
|
|
195
|
+
}), /* @__PURE__ */ jsx("p", { children: String(error) })]
|
|
196
|
+
}),
|
|
197
|
+
/* @__PURE__ */ jsxs(Select, {
|
|
198
|
+
value: securityId.toString(),
|
|
199
|
+
onValueChange: (v) => setSecurityId(Number(v)),
|
|
200
|
+
children: [/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { children: /* @__PURE__ */ jsx(SecurityRequirement, { requirement: securities[securityId] }) }) }), /* @__PURE__ */ jsx(SelectContent, { children: securities.map((security, i) => /* @__PURE__ */ jsx(SelectItem, {
|
|
201
|
+
value: i.toString(),
|
|
202
|
+
children: /* @__PURE__ */ jsx(SecurityRequirement, { requirement: security })
|
|
203
|
+
}, i)) })]
|
|
204
|
+
}),
|
|
205
|
+
children
|
|
206
|
+
]
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
function SecurityRequirement({ requirement }) {
|
|
210
|
+
const { schemes } = useApiContext();
|
|
211
|
+
return /* @__PURE__ */ jsx("div", {
|
|
212
|
+
className: "flex flex-col gap-2 max-w-[600px]",
|
|
213
|
+
children: requirement.map((item) => {
|
|
214
|
+
const scheme = schemes[item.id];
|
|
215
|
+
return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", {
|
|
216
|
+
className: cn("font-mono font-medium", scheme.deprecated && "text-fd-muted-foreground line-through"),
|
|
217
|
+
children: item.id
|
|
218
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
219
|
+
className: "text-fd-muted-foreground whitespace-pre-wrap",
|
|
220
|
+
children: scheme.description
|
|
221
|
+
})] }, item.id);
|
|
222
|
+
})
|
|
194
223
|
});
|
|
195
|
-
for (let i = 0; i < securities.length; i++) {
|
|
196
|
-
const security = securities[i];
|
|
197
|
-
for (const item of security) if (item.type === "oauth2") return /* @__PURE__ */ jsx(OauthDialog, {
|
|
198
|
-
scheme: item,
|
|
199
|
-
scopes: item.scopes,
|
|
200
|
-
open,
|
|
201
|
-
setOpen: (v) => {
|
|
202
|
-
setOpen(v);
|
|
203
|
-
if (v) setSecurityId(i);
|
|
204
|
-
},
|
|
205
|
-
setToken: (token) => engine.update(["header", "Authorization"], token),
|
|
206
|
-
children: result
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
return result;
|
|
210
224
|
}
|
|
211
225
|
const ParamTypes = [
|
|
212
226
|
"path",
|
|
@@ -287,98 +301,97 @@ function BodyInput({ field: _field }) {
|
|
|
287
301
|
})
|
|
288
302
|
});
|
|
289
303
|
}
|
|
290
|
-
function useAuthInputs(
|
|
304
|
+
function useAuthInputs(engine, requirements) {
|
|
305
|
+
const authCtx = useAuth();
|
|
291
306
|
const storageKeys = useStorageKey();
|
|
292
307
|
const t = useTranslations();
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
if (
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
308
|
+
const { schemes, client: { playground: { transformAuthInputs } = {} } } = useApiContext();
|
|
309
|
+
const [requirementId, setRequirementId] = useState(() => {
|
|
310
|
+
if (requirements.length === 0) return -1;
|
|
311
|
+
const idx = requirements.findIndex((s) => s.every((item) => !schemes[item.id].deprecated));
|
|
312
|
+
return idx !== -1 ? idx : 0;
|
|
313
|
+
});
|
|
314
|
+
const requirement = requirementId === -1 ? null : requirements[requirementId];
|
|
315
|
+
let inputs = useMemo(() => {
|
|
316
|
+
if (!requirement) return [];
|
|
317
|
+
return requirement.map((item) => {
|
|
318
|
+
const scheme = schemes[item.id];
|
|
319
|
+
if (scheme.type === "http" && scheme.scheme === "basic") {
|
|
320
|
+
const fieldName = ["header", "Authorization"];
|
|
321
|
+
return {
|
|
322
|
+
fieldName,
|
|
323
|
+
schemeId: item.id,
|
|
324
|
+
storageKey: storageKeys.AuthField(item.id),
|
|
325
|
+
defaultValue: {
|
|
326
|
+
username: "",
|
|
327
|
+
password: ""
|
|
328
|
+
},
|
|
329
|
+
mapOutput(out) {
|
|
330
|
+
if (out && typeof out === "object") {
|
|
331
|
+
const obj = out;
|
|
332
|
+
return `Basic ${btoa(`${obj.username ?? ""}:${obj.password ?? ""}`)}`;
|
|
318
333
|
}
|
|
334
|
+
return out;
|
|
319
335
|
},
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
336
|
-
className: "flex gap-2",
|
|
337
|
-
children: [/* @__PURE__ */ jsx(FieldInput, {
|
|
338
|
-
fieldName,
|
|
339
|
-
field: { type: "string" },
|
|
340
|
-
className: "flex-1"
|
|
341
|
-
}), /* @__PURE__ */ jsx(OauthDialogTrigger, {
|
|
342
|
-
type: "button",
|
|
343
|
-
className: cn(buttonVariants({
|
|
344
|
-
size: "sm",
|
|
345
|
-
color: "secondary"
|
|
346
|
-
})),
|
|
347
|
-
children: t.authorize
|
|
348
|
-
})]
|
|
349
|
-
})]
|
|
350
|
-
})
|
|
351
|
-
});
|
|
352
|
-
} else if (security.type === "http") {
|
|
353
|
-
const fieldName = ["header", "Authorization"];
|
|
354
|
-
result.push({
|
|
355
|
-
fieldName,
|
|
356
|
-
original: security,
|
|
357
|
-
defaultValue: "Bearer ",
|
|
358
|
-
children: /* @__PURE__ */ jsx(FieldSet, {
|
|
359
|
-
name: `${t.authorization} (${t.header})`,
|
|
336
|
+
children: /* @__PURE__ */ jsx(ObjectInput, {
|
|
337
|
+
field: {
|
|
338
|
+
type: "object",
|
|
339
|
+
properties: {
|
|
340
|
+
username: { type: "string" },
|
|
341
|
+
password: { type: "string" }
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
fieldName
|
|
345
|
+
})
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
if (scheme.type === "oauth2") {
|
|
349
|
+
const fieldName = ["header", "Authorization"];
|
|
350
|
+
return {
|
|
360
351
|
fieldName,
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
352
|
+
schemeId: item.id,
|
|
353
|
+
storageKey: storageKeys.AuthField(item.id),
|
|
354
|
+
defaultValue: "Bearer ",
|
|
355
|
+
children: /* @__PURE__ */ jsx(OAuth2Input, {
|
|
356
|
+
fieldName,
|
|
357
|
+
security: item
|
|
358
|
+
})
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
if (scheme.type === "http") {
|
|
362
|
+
const fieldName = ["header", "Authorization"];
|
|
363
|
+
return {
|
|
371
364
|
fieldName,
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
365
|
+
schemeId: item.id,
|
|
366
|
+
storageKey: storageKeys.AuthField(item.id),
|
|
367
|
+
defaultValue: "Bearer ",
|
|
368
|
+
children: /* @__PURE__ */ jsx(FieldSet, {
|
|
369
|
+
name: `${t.authorization} (${t.header})`,
|
|
370
|
+
fieldName,
|
|
371
|
+
field: { type: "string" }
|
|
372
|
+
})
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
if (scheme.type === "apiKey") {
|
|
376
|
+
const fieldName = [scheme.in, scheme.name];
|
|
377
|
+
return {
|
|
378
|
+
fieldName,
|
|
379
|
+
schemeId: item.id,
|
|
380
|
+
defaultValue: "",
|
|
381
|
+
storageKey: storageKeys.AuthField(item.id),
|
|
382
|
+
children: /* @__PURE__ */ jsx(FieldSet, {
|
|
383
|
+
fieldName,
|
|
384
|
+
name: `${scheme.name} (${scheme.in})`,
|
|
385
|
+
field: { type: "string" }
|
|
386
|
+
})
|
|
387
|
+
};
|
|
388
|
+
}
|
|
377
389
|
const fieldName = ["header", "Authorization"];
|
|
378
|
-
|
|
390
|
+
return {
|
|
379
391
|
fieldName,
|
|
392
|
+
schemeId: item.id,
|
|
380
393
|
defaultValue: "",
|
|
381
|
-
|
|
394
|
+
storageKey: storageKeys.AuthField(item.id),
|
|
382
395
|
children: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(FieldSet, {
|
|
383
396
|
name: `${t.authorization} (${t.header})`,
|
|
384
397
|
fieldName,
|
|
@@ -387,45 +400,106 @@ function useAuthInputs(securities, transform) {
|
|
|
387
400
|
className: "text-fd-muted-foreground text-xs",
|
|
388
401
|
children: t.openIdUnsupported
|
|
389
402
|
})] })
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
return transform ? transform(result) : result;
|
|
403
|
+
};
|
|
404
|
+
});
|
|
393
405
|
}, [
|
|
394
|
-
|
|
395
|
-
|
|
406
|
+
requirement,
|
|
407
|
+
storageKeys,
|
|
408
|
+
schemes,
|
|
396
409
|
t
|
|
397
410
|
]);
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
const initAuthValues = (stf) => {
|
|
407
|
-
const { dataEngine } = stf;
|
|
408
|
-
for (const item of inputs) {
|
|
409
|
-
const stored = localStorage.getItem(storageKeys.AuthField(item));
|
|
410
|
-
if (stored) {
|
|
411
|
-
const parsed = JSON.parse(stored);
|
|
412
|
-
if (typeof parsed === typeof item.defaultValue) {
|
|
413
|
-
dataEngine.init(item.fieldName, parsed);
|
|
414
|
-
continue;
|
|
415
|
-
}
|
|
411
|
+
if (transformAuthInputs) inputs = transformAuthInputs(inputs);
|
|
412
|
+
useListener({
|
|
413
|
+
stf: engine,
|
|
414
|
+
onUpdate(key) {
|
|
415
|
+
for (const item of inputs) {
|
|
416
|
+
if (!arrayStartsWith(item.fieldName, key)) continue;
|
|
417
|
+
const value = engine.get(item.fieldName);
|
|
418
|
+
if (value != null) localStorage.setItem(item.storageKey, JSON.stringify(value));
|
|
416
419
|
}
|
|
417
|
-
dataEngine.init(item.fieldName, item.defaultValue);
|
|
418
420
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
};
|
|
422
|
-
|
|
421
|
+
});
|
|
422
|
+
useOnChange(authCtx.updatedSchemeId, () => {
|
|
423
|
+
const { updatedSchemeId } = authCtx;
|
|
424
|
+
if (!updatedSchemeId) return;
|
|
425
|
+
const { token } = authCtx.store[updatedSchemeId];
|
|
426
|
+
const input = inputs.find((input) => input.schemeId === updatedSchemeId);
|
|
427
|
+
if (input) {
|
|
428
|
+
engine.update(input.fieldName, token);
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
const idx = requirements.findIndex((requirement) => requirement.some((item) => item.id === updatedSchemeId));
|
|
432
|
+
if (idx !== -1) {
|
|
433
|
+
localStorage.setItem(storageKeys.AuthField(updatedSchemeId), JSON.stringify(token));
|
|
434
|
+
setRequirementId(idx);
|
|
435
|
+
}
|
|
436
|
+
});
|
|
423
437
|
return {
|
|
424
438
|
inputs,
|
|
425
|
-
|
|
426
|
-
|
|
439
|
+
requirementId,
|
|
440
|
+
setRequirementId,
|
|
441
|
+
mapInputs(values) {
|
|
442
|
+
const cloned = structuredClone(values);
|
|
443
|
+
for (const item of inputs) {
|
|
444
|
+
if (!item.mapOutput) continue;
|
|
445
|
+
objectSet(cloned, item.fieldName, item.mapOutput(objectGet(cloned, item.fieldName)));
|
|
446
|
+
}
|
|
447
|
+
return cloned;
|
|
448
|
+
},
|
|
449
|
+
initAuthInputs() {
|
|
450
|
+
for (const item of inputs) {
|
|
451
|
+
const stored = localStorage.getItem(item.storageKey);
|
|
452
|
+
if (stored) {
|
|
453
|
+
const parsed = JSON.parse(stored);
|
|
454
|
+
if (typeof parsed === typeof item.defaultValue) {
|
|
455
|
+
engine.init(item.fieldName, parsed);
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
engine.init(item.fieldName, item.defaultValue);
|
|
460
|
+
}
|
|
461
|
+
return () => {
|
|
462
|
+
for (const item of inputs) engine.delete(item.fieldName);
|
|
463
|
+
};
|
|
464
|
+
}
|
|
427
465
|
};
|
|
428
466
|
}
|
|
467
|
+
function OAuth2Input({ fieldName, security }) {
|
|
468
|
+
const [open, setOpen] = useState(false);
|
|
469
|
+
const engine = useDataEngine();
|
|
470
|
+
const t = useTranslations();
|
|
471
|
+
return /* @__PURE__ */ jsxs("fieldset", {
|
|
472
|
+
className: "flex flex-col gap-2",
|
|
473
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
474
|
+
htmlFor: stringifyFieldKey(fieldName),
|
|
475
|
+
className: cn(labelVariants()),
|
|
476
|
+
children: t.accessToken
|
|
477
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
478
|
+
className: "flex gap-2",
|
|
479
|
+
children: [/* @__PURE__ */ jsx(FieldInput, {
|
|
480
|
+
fieldName,
|
|
481
|
+
field: { type: "string" },
|
|
482
|
+
className: "flex-1"
|
|
483
|
+
}), /* @__PURE__ */ jsxs(OAuthDialog, {
|
|
484
|
+
open,
|
|
485
|
+
onOpenChange: setOpen,
|
|
486
|
+
children: [/* @__PURE__ */ jsx(OAuthDialogTrigger, {
|
|
487
|
+
type: "button",
|
|
488
|
+
className: cn(buttonVariants({
|
|
489
|
+
size: "sm",
|
|
490
|
+
color: "secondary"
|
|
491
|
+
})),
|
|
492
|
+
children: t.authorize
|
|
493
|
+
}), /* @__PURE__ */ jsx(OAuthDialogContent, {
|
|
494
|
+
setOpen,
|
|
495
|
+
schemeId: security.id,
|
|
496
|
+
scopes: security.scopes,
|
|
497
|
+
setToken: (token) => engine.update(["header", "Authorization"], token)
|
|
498
|
+
})]
|
|
499
|
+
})]
|
|
500
|
+
})]
|
|
501
|
+
});
|
|
502
|
+
}
|
|
429
503
|
function Route({ route, ...props }) {
|
|
430
504
|
return /* @__PURE__ */ jsx("div", {
|
|
431
505
|
...props,
|