@djangocfg/ui-tools 2.1.318 → 2.1.319
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/{DocsLayout-ESVQZO3V.mjs → DocsLayout-CTJINVBM.mjs} +235 -267
- package/dist/DocsLayout-CTJINVBM.mjs.map +1 -0
- package/dist/{DocsLayout-KUPDWJ3G.cjs → DocsLayout-XLDB6CJ2.cjs} +273 -305
- package/dist/DocsLayout-XLDB6CJ2.cjs.map +1 -0
- package/dist/{chunk-GBLQTHWT.mjs → chunk-62Y65TGK.mjs} +5 -4
- package/dist/chunk-62Y65TGK.mjs.map +1 -0
- package/dist/{chunk-S44PW6NK.cjs → chunk-TKSFZHCG.cjs} +5 -4
- package/dist/chunk-TKSFZHCG.cjs.map +1 -0
- package/dist/index.cjs +10 -10
- package/dist/index.mjs +4 -4
- package/package.json +6 -6
- package/src/tools/OpenapiViewer/OpenapiViewer.story.tsx +30 -0
- package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/Header/MetaActions.tsx +35 -50
- package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/Header/index.tsx +49 -22
- package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/Section/index.tsx +1 -1
- package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/store/index.ts +10 -11
- package/src/tools/OpenapiViewer/components/DocsLayout/SchemaCopyMenu.tsx +25 -5
- package/src/tools/OpenapiViewer/components/DocsLayout/Sidebar/BrandHeader.tsx +18 -33
- package/src/tools/OpenapiViewer/components/DocsLayout/Sidebar/Toolbar.tsx +40 -24
- package/src/tools/OpenapiViewer/components/DocsLayout/Sidebar/index.tsx +8 -14
- package/src/tools/OpenapiViewer/components/DocsLayout/sidebarLabel.ts +1 -4
- package/src/tools/OpenapiViewer/utils/operationToHar.ts +2 -1
- package/src/tools/OpenapiViewer/utils/url.ts +9 -2
- package/dist/DocsLayout-ESVQZO3V.mjs.map +0 -1
- package/dist/DocsLayout-KUPDWJ3G.cjs.map +0 -1
- package/dist/chunk-GBLQTHWT.mjs.map +0 -1
- package/dist/chunk-S44PW6NK.cjs.map +0 -1
- package/src/tools/OpenapiViewer/components/DocsLayout/Sidebar/MethodChips.tsx +0 -43
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { deduplicateEndpoints, dereferenceSchema, resolveBaseUrl, usePlaygroundContext, toMarkdown, toCompactJson, toRawJson, formatBytes, MarkdownMessage, CODE_SAMPLE_TARGETS, buildHarRequest, resolveAbsolute, renderSnippet, PrettyCode_default,
|
|
1
|
+
import { deduplicateEndpoints, dereferenceSchema, resolveBaseUrl, usePlaygroundContext, relativePath, toMarkdown, toCompactJson, toRawJson, formatBytes, MarkdownMessage, CODE_SAMPLE_TARGETS, buildHarRequest, resolveAbsolute, renderSnippet, PrettyCode_default, endpointToMarkdown, isValidJson, findApiKeyById, parseRequestHeaders, UrlBuilder, sampleSchemaJson, joinUrl } from './chunk-62Y65TGK.mjs';
|
|
2
2
|
import { JsonTree_default } from './chunk-LFWQ36LJ.mjs';
|
|
3
3
|
import './chunk-SSUOENAZ.mjs';
|
|
4
4
|
import { __name } from './chunk-CGILA3WO.mjs';
|
|
5
5
|
import React12, { useRef, useEffect, createContext, useCallback, useMemo, useState, useContext } from 'react';
|
|
6
6
|
import { groupBy, orderBy, partition, sortBy, keyBy } from 'lodash-es';
|
|
7
|
-
import { Tooltip, TooltipTrigger, TooltipContent, DropdownMenu, DropdownMenuTrigger, Button, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuItem, Input,
|
|
7
|
+
import { Tooltip, TooltipTrigger, TooltipContent, DropdownMenu, DropdownMenuTrigger, Button, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuItem, Input, SafeTooltipProvider, CopyButton, Switch, Combobox, Textarea, SidePanel, ResponsiveSheet, ResponsiveSheetContent, ResponsiveSheetHeader, ResponsiveSheetTitle, Skeleton, TooltipProvider } from '@djangocfg/ui-core/components';
|
|
8
8
|
import { toast, useMediaQuery } from '@djangocfg/ui-core/hooks';
|
|
9
9
|
import consola from 'consola';
|
|
10
|
-
import { ChevronRight, Sparkles, ChevronDown, Check, Search, X,
|
|
10
|
+
import { ChevronRight, Sparkles, ChevronDown, Check, Search, X, Play, Link2, Minus, Plus, RotateCcw, Send, Key, Terminal, Info, ShieldCheck, Loader2, WifiOff, AlertCircle, ChevronsDownUp, ChevronsUpDown } from 'lucide-react';
|
|
11
11
|
import { cn } from '@djangocfg/ui-core/lib';
|
|
12
12
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
13
13
|
import { create } from 'zustand';
|
|
@@ -590,142 +590,20 @@ function CollapsibleSection({
|
|
|
590
590
|
] });
|
|
591
591
|
}
|
|
592
592
|
__name(CollapsibleSection, "CollapsibleSection");
|
|
593
|
-
|
|
594
|
-
markdown: {
|
|
595
|
-
title: "Markdown for LLM",
|
|
596
|
-
hint: "Endpoints + params as prose. Smallest."
|
|
597
|
-
},
|
|
598
|
-
compact: {
|
|
599
|
-
title: "Compact JSON",
|
|
600
|
-
hint: "Dereferenced, no examples, minified."
|
|
601
|
-
},
|
|
602
|
-
raw: {
|
|
603
|
-
title: "Raw JSON",
|
|
604
|
-
hint: "Full OpenAPI document with $refs."
|
|
605
|
-
}
|
|
606
|
-
};
|
|
607
|
-
function SchemaCopyMenu({ schema, endpoints, baseUrl, variant = "button" }) {
|
|
608
|
-
const [sizeCache, setSizeCache] = useState({});
|
|
609
|
-
const [justCopied, setJustCopied] = useState(null);
|
|
610
|
-
const [open, setOpen] = useState(false);
|
|
611
|
-
const isReady = schema !== null && endpoints.length > 0;
|
|
612
|
-
const build = useCallback(
|
|
613
|
-
(flavour) => {
|
|
614
|
-
if (!schema) return "";
|
|
615
|
-
if (flavour === "markdown") return toMarkdown(schema, endpoints, baseUrl);
|
|
616
|
-
if (flavour === "compact") return toCompactJson(schema, baseUrl);
|
|
617
|
-
return toRawJson(schema, baseUrl);
|
|
618
|
-
},
|
|
619
|
-
[schema, endpoints, baseUrl]
|
|
620
|
-
);
|
|
621
|
-
const handleCopy = useCallback(
|
|
622
|
-
async (flavour) => {
|
|
623
|
-
if (!isReady) return;
|
|
624
|
-
const text = build(flavour);
|
|
625
|
-
const label = FLAVOUR_LABELS[flavour].title;
|
|
626
|
-
try {
|
|
627
|
-
await navigator.clipboard.writeText(text);
|
|
628
|
-
const size = formatBytes(text);
|
|
629
|
-
setSizeCache((prev) => ({ ...prev, [flavour]: size }));
|
|
630
|
-
setJustCopied(flavour);
|
|
631
|
-
setTimeout(() => setJustCopied(null), 1500);
|
|
632
|
-
setOpen(false);
|
|
633
|
-
toast.success(`Copied ${label}`, { description: size });
|
|
634
|
-
} catch (err) {
|
|
635
|
-
const message = err instanceof Error ? err.message : "Clipboard permission denied";
|
|
636
|
-
toast.error("Copy failed", { description: message });
|
|
637
|
-
}
|
|
638
|
-
},
|
|
639
|
-
[build, isReady]
|
|
640
|
-
);
|
|
641
|
-
const flavours = useMemo(() => ["markdown", "compact", "raw"], []);
|
|
642
|
-
return /* @__PURE__ */ jsxs(DropdownMenu, { open, onOpenChange: setOpen, children: [
|
|
643
|
-
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: variant === "icon" ? /* @__PURE__ */ jsx(
|
|
644
|
-
Button,
|
|
645
|
-
{
|
|
646
|
-
variant: "ghost",
|
|
647
|
-
size: "icon",
|
|
648
|
-
className: "h-7 w-7 shrink-0",
|
|
649
|
-
disabled: !isReady,
|
|
650
|
-
title: "Copy schema for AI",
|
|
651
|
-
"aria-label": "Copy schema for AI",
|
|
652
|
-
children: /* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5" })
|
|
653
|
-
}
|
|
654
|
-
) : /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs", disabled: !isReady, children: [
|
|
655
|
-
/* @__PURE__ */ jsx(Sparkles, { className: "h-3 w-3" }),
|
|
656
|
-
"Copy for AI",
|
|
657
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 opacity-60" })
|
|
658
|
-
] }) }),
|
|
659
|
-
/* @__PURE__ */ jsxs(
|
|
660
|
-
DropdownMenuContent,
|
|
661
|
-
{
|
|
662
|
-
side: "right",
|
|
663
|
-
align: "start",
|
|
664
|
-
sideOffset: 6,
|
|
665
|
-
collisionPadding: 8,
|
|
666
|
-
className: "w-60 max-w-[calc(100vw-16px)]",
|
|
667
|
-
children: [
|
|
668
|
-
/* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-[10px] uppercase tracking-wider text-muted-foreground/70", children: "Copy schema" }),
|
|
669
|
-
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
670
|
-
flavours.map((f) => {
|
|
671
|
-
const label = FLAVOUR_LABELS[f];
|
|
672
|
-
const size = sizeCache[f];
|
|
673
|
-
const isDone = justCopied === f;
|
|
674
|
-
return /* @__PURE__ */ jsxs(
|
|
675
|
-
DropdownMenuItem,
|
|
676
|
-
{
|
|
677
|
-
onClick: (e) => {
|
|
678
|
-
e.preventDefault();
|
|
679
|
-
void handleCopy(f);
|
|
680
|
-
},
|
|
681
|
-
className: "flex flex-col items-start gap-0.5 py-2 cursor-pointer",
|
|
682
|
-
children: [
|
|
683
|
-
/* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-2", children: [
|
|
684
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium flex-1", children: label.title }),
|
|
685
|
-
isDone ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-[10px] text-emerald-500", children: [
|
|
686
|
-
/* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }),
|
|
687
|
-
" Copied"
|
|
688
|
-
] }) : size ? /* @__PURE__ */ jsx("span", { className: "text-[10px] font-mono text-muted-foreground/70 tabular-nums", children: size }) : null
|
|
689
|
-
] }),
|
|
690
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground/70 leading-snug line-clamp-1", children: label.hint })
|
|
691
|
-
]
|
|
692
|
-
},
|
|
693
|
-
f
|
|
694
|
-
);
|
|
695
|
-
})
|
|
696
|
-
]
|
|
697
|
-
}
|
|
698
|
-
)
|
|
699
|
-
] });
|
|
700
|
-
}
|
|
701
|
-
__name(SchemaCopyMenu, "SchemaCopyMenu");
|
|
702
|
-
function BrandHeader({ info, endpoints, rawSchema, resolvedBaseUrl }) {
|
|
593
|
+
function BrandHeader({ info }) {
|
|
703
594
|
const apiTitle = info?.title ?? "API Reference";
|
|
704
|
-
const
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
{
|
|
710
|
-
className: "text-[13px] font-semibold text-foreground leading-tight truncate",
|
|
711
|
-
title: apiTitle,
|
|
712
|
-
children: apiTitle
|
|
713
|
-
}
|
|
714
|
-
),
|
|
715
|
-
info?.version && /* @__PURE__ */ jsxs("div", { className: "font-mono text-[10px] text-muted-foreground/60 leading-tight mt-0.5", children: [
|
|
716
|
-
"v",
|
|
717
|
-
info.version
|
|
718
|
-
] })
|
|
719
|
-
] }),
|
|
720
|
-
copyReady && /* @__PURE__ */ jsx(
|
|
721
|
-
SchemaCopyMenu,
|
|
595
|
+
const versionLabel = info?.version ? `v${info.version}` : null;
|
|
596
|
+
const versionNode = versionLabel ? /* @__PURE__ */ jsx("div", { className: "font-mono text-[10px] text-muted-foreground/60 leading-tight mt-0.5", children: versionLabel }) : null;
|
|
597
|
+
return /* @__PURE__ */ jsxs("div", { className: "shrink-0 border-b px-3 py-2.5", children: [
|
|
598
|
+
/* @__PURE__ */ jsx(
|
|
599
|
+
"div",
|
|
722
600
|
{
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
variant: "icon"
|
|
601
|
+
className: "text-[13px] font-semibold text-foreground leading-tight truncate",
|
|
602
|
+
title: apiTitle,
|
|
603
|
+
children: apiTitle
|
|
727
604
|
}
|
|
728
|
-
)
|
|
605
|
+
),
|
|
606
|
+
versionNode
|
|
729
607
|
] });
|
|
730
608
|
}
|
|
731
609
|
__name(BrandHeader, "BrandHeader");
|
|
@@ -755,19 +633,11 @@ function sidebarLabel(ep, groupCommonPrefix) {
|
|
|
755
633
|
const tail = ep.path.slice(groupCommonPrefix.length) || "/";
|
|
756
634
|
return tail;
|
|
757
635
|
}
|
|
758
|
-
return
|
|
636
|
+
return relativePath(ep.path);
|
|
759
637
|
}
|
|
760
638
|
__name(sidebarLabel, "sidebarLabel");
|
|
761
|
-
function relativePath2(full) {
|
|
762
|
-
try {
|
|
763
|
-
return new URL(full).pathname;
|
|
764
|
-
} catch {
|
|
765
|
-
return full;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
__name(relativePath2, "relativePath");
|
|
769
639
|
function sidebarTooltip(ep) {
|
|
770
|
-
return `${ep.method} ${
|
|
640
|
+
return `${ep.method} ${relativePath(ep.path)}`;
|
|
771
641
|
}
|
|
772
642
|
__name(sidebarTooltip, "sidebarTooltip");
|
|
773
643
|
|
|
@@ -951,29 +821,130 @@ function SidebarBody({ body, onNavigate }) {
|
|
|
951
821
|
return /* @__PURE__ */ jsx("nav", { className: "py-1.5", children: body.sections.map((section) => /* @__PURE__ */ jsx(SchemaSection, { section, onNavigate }, section.sourceId)) });
|
|
952
822
|
}
|
|
953
823
|
__name(SidebarBody, "SidebarBody");
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
824
|
+
var FLAVOUR_LABELS = {
|
|
825
|
+
markdown: {
|
|
826
|
+
title: "Markdown for LLM",
|
|
827
|
+
hint: "Endpoints + params as prose. Smallest."
|
|
828
|
+
},
|
|
829
|
+
compact: {
|
|
830
|
+
title: "Compact JSON",
|
|
831
|
+
hint: "Dereferenced, no examples, minified."
|
|
832
|
+
},
|
|
833
|
+
raw: {
|
|
834
|
+
title: "Raw JSON",
|
|
835
|
+
hint: "Full OpenAPI document with $refs."
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
function SchemaCopyMenu({ schema, endpoints, baseUrl, variant = "button", side }) {
|
|
839
|
+
const [sizeCache, setSizeCache] = useState({});
|
|
840
|
+
const [justCopied, setJustCopied] = useState(null);
|
|
841
|
+
const [open, setOpen] = useState(false);
|
|
842
|
+
const isReady = schema !== null && endpoints.length > 0;
|
|
843
|
+
const build = useCallback(
|
|
844
|
+
(flavour) => {
|
|
845
|
+
if (!schema) return "";
|
|
846
|
+
if (flavour === "markdown") return toMarkdown(schema, endpoints, baseUrl);
|
|
847
|
+
if (flavour === "compact") return toCompactJson(schema, baseUrl);
|
|
848
|
+
return toRawJson(schema, baseUrl);
|
|
849
|
+
},
|
|
850
|
+
[schema, endpoints, baseUrl]
|
|
851
|
+
);
|
|
852
|
+
const handleCopy = useCallback(
|
|
853
|
+
async (flavour) => {
|
|
854
|
+
if (!isReady) return;
|
|
855
|
+
const text = build(flavour);
|
|
856
|
+
const label = FLAVOUR_LABELS[flavour].title;
|
|
857
|
+
try {
|
|
858
|
+
await navigator.clipboard.writeText(text);
|
|
859
|
+
const size = formatBytes(text);
|
|
860
|
+
setSizeCache((prev) => ({ ...prev, [flavour]: size }));
|
|
861
|
+
setJustCopied(flavour);
|
|
862
|
+
setTimeout(() => setJustCopied(null), 1500);
|
|
863
|
+
setOpen(false);
|
|
864
|
+
toast.success(`Copied ${label}`, { description: size });
|
|
865
|
+
} catch (err) {
|
|
866
|
+
const message = err instanceof Error ? err.message : "Clipboard permission denied";
|
|
867
|
+
toast.error("Copy failed", { description: message });
|
|
868
|
+
}
|
|
869
|
+
},
|
|
870
|
+
[build, isReady]
|
|
871
|
+
);
|
|
872
|
+
const flavours = useMemo(() => ["markdown", "compact", "raw"], []);
|
|
873
|
+
const resolvedSide = side ?? (variant === "footer" ? "top" : "right");
|
|
874
|
+
const resolvedAlign = variant === "footer" ? "center" : "start";
|
|
875
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { open, onOpenChange: setOpen, children: [
|
|
876
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: variant === "icon" ? /* @__PURE__ */ jsx(
|
|
877
|
+
Button,
|
|
962
878
|
{
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
"
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
)
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
879
|
+
variant: "ghost",
|
|
880
|
+
size: "icon",
|
|
881
|
+
className: "h-7 w-7 shrink-0",
|
|
882
|
+
disabled: !isReady,
|
|
883
|
+
title: "Copy schema for AI",
|
|
884
|
+
"aria-label": "Copy schema for AI",
|
|
885
|
+
children: /* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5" })
|
|
886
|
+
}
|
|
887
|
+
) : variant === "footer" ? /* @__PURE__ */ jsxs(
|
|
888
|
+
Button,
|
|
889
|
+
{
|
|
890
|
+
variant: "secondary",
|
|
891
|
+
size: "sm",
|
|
892
|
+
className: "w-full justify-center gap-1.5 text-xs",
|
|
893
|
+
disabled: !isReady,
|
|
894
|
+
children: [
|
|
895
|
+
/* @__PURE__ */ jsx(Sparkles, { className: "h-3 w-3" }),
|
|
896
|
+
"Copy schema for AI",
|
|
897
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 opacity-60" })
|
|
898
|
+
]
|
|
899
|
+
}
|
|
900
|
+
) : /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs", disabled: !isReady, children: [
|
|
901
|
+
/* @__PURE__ */ jsx(Sparkles, { className: "h-3 w-3" }),
|
|
902
|
+
"Copy for AI",
|
|
903
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 opacity-60" })
|
|
904
|
+
] }) }),
|
|
905
|
+
/* @__PURE__ */ jsxs(
|
|
906
|
+
DropdownMenuContent,
|
|
907
|
+
{
|
|
908
|
+
side: resolvedSide,
|
|
909
|
+
align: resolvedAlign,
|
|
910
|
+
sideOffset: 6,
|
|
911
|
+
collisionPadding: 8,
|
|
912
|
+
className: "w-60 max-w-[calc(100vw-16px)]",
|
|
913
|
+
children: [
|
|
914
|
+
/* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-[10px] uppercase tracking-wider text-muted-foreground/70", children: "Copy schema" }),
|
|
915
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
916
|
+
flavours.map((f) => {
|
|
917
|
+
const label = FLAVOUR_LABELS[f];
|
|
918
|
+
const size = sizeCache[f];
|
|
919
|
+
const isDone = justCopied === f;
|
|
920
|
+
return /* @__PURE__ */ jsxs(
|
|
921
|
+
DropdownMenuItem,
|
|
922
|
+
{
|
|
923
|
+
onClick: (e) => {
|
|
924
|
+
e.preventDefault();
|
|
925
|
+
void handleCopy(f);
|
|
926
|
+
},
|
|
927
|
+
className: "flex flex-col items-start gap-0.5 py-2 cursor-pointer",
|
|
928
|
+
children: [
|
|
929
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-2", children: [
|
|
930
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium flex-1", children: label.title }),
|
|
931
|
+
isDone ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-[10px] text-emerald-500", children: [
|
|
932
|
+
/* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }),
|
|
933
|
+
" Copied"
|
|
934
|
+
] }) : size ? /* @__PURE__ */ jsx("span", { className: "text-[10px] font-mono text-muted-foreground/70 tabular-nums", children: size }) : null
|
|
935
|
+
] }),
|
|
936
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground/70 leading-snug line-clamp-1", children: label.hint })
|
|
937
|
+
]
|
|
938
|
+
},
|
|
939
|
+
f
|
|
940
|
+
);
|
|
941
|
+
})
|
|
942
|
+
]
|
|
943
|
+
}
|
|
944
|
+
)
|
|
945
|
+
] });
|
|
975
946
|
}
|
|
976
|
-
__name(
|
|
947
|
+
__name(SchemaCopyMenu, "SchemaCopyMenu");
|
|
977
948
|
function SearchInput({ value, onChange, placeholder }) {
|
|
978
949
|
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
979
950
|
/* @__PURE__ */ jsx(Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/50 pointer-events-none" }),
|
|
@@ -1010,28 +981,41 @@ function Toolbar({
|
|
|
1010
981
|
showSchemaSelector,
|
|
1011
982
|
search,
|
|
1012
983
|
onSearchChange,
|
|
1013
|
-
|
|
1014
|
-
|
|
984
|
+
endpoints,
|
|
985
|
+
rawSchema,
|
|
986
|
+
resolvedBaseUrl
|
|
1015
987
|
}) {
|
|
1016
988
|
const schemaOptions = React12.useMemo(
|
|
1017
989
|
() => schemas.map((s) => ({ value: s.id, label: s.name })),
|
|
1018
990
|
[schemas]
|
|
1019
991
|
);
|
|
992
|
+
const copyReady = rawSchema !== null && rawSchema !== void 0 && endpoints.length > 0;
|
|
993
|
+
const schemaSelectorNode = showSchemaSelector ? /* @__PURE__ */ jsx(
|
|
994
|
+
Combobox,
|
|
995
|
+
{
|
|
996
|
+
options: schemaOptions,
|
|
997
|
+
value: currentSchemaId ?? "",
|
|
998
|
+
onValueChange: (id) => id && onSchemaChange(id),
|
|
999
|
+
placeholder: "Select API",
|
|
1000
|
+
searchPlaceholder: "Search APIs\u2026",
|
|
1001
|
+
emptyText: "No APIs found",
|
|
1002
|
+
className: "w-full h-8 text-xs"
|
|
1003
|
+
}
|
|
1004
|
+
) : null;
|
|
1005
|
+
const copyMenuNode = copyReady ? /* @__PURE__ */ jsx(
|
|
1006
|
+
SchemaCopyMenu,
|
|
1007
|
+
{
|
|
1008
|
+
schema: rawSchema ?? null,
|
|
1009
|
+
endpoints,
|
|
1010
|
+
baseUrl: resolvedBaseUrl,
|
|
1011
|
+
variant: "footer",
|
|
1012
|
+
side: "bottom"
|
|
1013
|
+
}
|
|
1014
|
+
) : null;
|
|
1020
1015
|
return /* @__PURE__ */ jsxs("div", { className: "shrink-0 border-b px-3 py-2.5 space-y-2", children: [
|
|
1021
|
-
|
|
1022
|
-
Combobox,
|
|
1023
|
-
{
|
|
1024
|
-
options: schemaOptions,
|
|
1025
|
-
value: currentSchemaId ?? "",
|
|
1026
|
-
onValueChange: (id) => id && onSchemaChange(id),
|
|
1027
|
-
placeholder: "Select API",
|
|
1028
|
-
searchPlaceholder: "Search APIs\u2026",
|
|
1029
|
-
emptyText: "No APIs found",
|
|
1030
|
-
className: "w-full h-8 text-xs"
|
|
1031
|
-
}
|
|
1032
|
-
),
|
|
1016
|
+
schemaSelectorNode,
|
|
1033
1017
|
/* @__PURE__ */ jsx(SearchInput, { value: search, onChange: onSearchChange }),
|
|
1034
|
-
|
|
1018
|
+
copyMenuNode
|
|
1035
1019
|
] });
|
|
1036
1020
|
}
|
|
1037
1021
|
__name(Toolbar, "Toolbar");
|
|
@@ -1059,7 +1043,6 @@ function DocsSidebar({
|
|
|
1059
1043
|
resolvedBaseUrl
|
|
1060
1044
|
}) {
|
|
1061
1045
|
const [search, setSearch] = useState("");
|
|
1062
|
-
const [methodFilter, setMethodFilter] = useState("ALL");
|
|
1063
1046
|
const debouncedSearch = useDebouncedValue(search);
|
|
1064
1047
|
const body = useMemo(() => {
|
|
1065
1048
|
if (grouping === "sections") {
|
|
@@ -1068,7 +1051,7 @@ function DocsSidebar({
|
|
|
1068
1051
|
endpointsBySchema ?? {},
|
|
1069
1052
|
selectedVersion,
|
|
1070
1053
|
debouncedSearch,
|
|
1071
|
-
|
|
1054
|
+
"ALL",
|
|
1072
1055
|
activeEndpointId
|
|
1073
1056
|
);
|
|
1074
1057
|
}
|
|
@@ -1076,7 +1059,7 @@ function DocsSidebar({
|
|
|
1076
1059
|
endpoints,
|
|
1077
1060
|
selectedVersion,
|
|
1078
1061
|
debouncedSearch,
|
|
1079
|
-
|
|
1062
|
+
"ALL",
|
|
1080
1063
|
activeEndpointId
|
|
1081
1064
|
);
|
|
1082
1065
|
}, [
|
|
@@ -1086,21 +1069,12 @@ function DocsSidebar({
|
|
|
1086
1069
|
endpoints,
|
|
1087
1070
|
selectedVersion,
|
|
1088
1071
|
debouncedSearch,
|
|
1089
|
-
methodFilter,
|
|
1090
1072
|
activeEndpointId
|
|
1091
1073
|
]);
|
|
1092
1074
|
const hasMultipleSchemas = schemas.length > 1;
|
|
1093
1075
|
const showSchemaSelector = grouping === "selector" && hasMultipleSchemas;
|
|
1094
1076
|
return /* @__PURE__ */ jsxs("aside", { className: "flex flex-col h-full min-h-0 border-r bg-muted/10", children: [
|
|
1095
|
-
/* @__PURE__ */ jsx(
|
|
1096
|
-
BrandHeader,
|
|
1097
|
-
{
|
|
1098
|
-
info,
|
|
1099
|
-
endpoints,
|
|
1100
|
-
rawSchema,
|
|
1101
|
-
resolvedBaseUrl
|
|
1102
|
-
}
|
|
1103
|
-
),
|
|
1077
|
+
/* @__PURE__ */ jsx(BrandHeader, { info }),
|
|
1104
1078
|
/* @__PURE__ */ jsx(
|
|
1105
1079
|
Toolbar,
|
|
1106
1080
|
{
|
|
@@ -1110,8 +1084,9 @@ function DocsSidebar({
|
|
|
1110
1084
|
showSchemaSelector,
|
|
1111
1085
|
search,
|
|
1112
1086
|
onSearchChange: setSearch,
|
|
1113
|
-
|
|
1114
|
-
|
|
1087
|
+
endpoints,
|
|
1088
|
+
rawSchema,
|
|
1089
|
+
resolvedBaseUrl
|
|
1115
1090
|
}
|
|
1116
1091
|
),
|
|
1117
1092
|
/* @__PURE__ */ jsx(ScrollArea, { children: /* @__PURE__ */ jsx(SidebarBody, { body, onNavigate }) })
|
|
@@ -1210,21 +1185,14 @@ var useEndpointDocStore = create()(
|
|
|
1210
1185
|
persist(
|
|
1211
1186
|
(set) => ({
|
|
1212
1187
|
...initialState,
|
|
1213
|
-
toggleSection: /* @__PURE__ */ __name((endpointId, sectionId) => set((state) => {
|
|
1188
|
+
toggleSection: /* @__PURE__ */ __name((endpointId, sectionId, defaultOpen) => set((state) => {
|
|
1214
1189
|
const key = sectionKey(endpointId, sectionId);
|
|
1215
1190
|
const current = state.openSections[key];
|
|
1191
|
+
const visible = current === void 0 ? defaultOpen : current;
|
|
1216
1192
|
return {
|
|
1217
1193
|
openSections: {
|
|
1218
1194
|
...state.openSections,
|
|
1219
|
-
|
|
1220
|
-
// first click means "flip from the default". We
|
|
1221
|
-
// assume the default was ``true`` for the most
|
|
1222
|
-
// common case (bodies/responses) and ``false``
|
|
1223
|
-
// otherwise; the Section component tracks this
|
|
1224
|
-
// via its ``defaultOpen`` prop and never calls
|
|
1225
|
-
// toggle on sections whose defaults match the
|
|
1226
|
-
// next state.
|
|
1227
|
-
[key]: current === void 0 ? false : !current
|
|
1195
|
+
[key]: !visible
|
|
1228
1196
|
}
|
|
1229
1197
|
};
|
|
1230
1198
|
}), "toggleSection"),
|
|
@@ -1383,15 +1351,15 @@ function IconButton({ label, onClick, children, active }) {
|
|
|
1383
1351
|
] });
|
|
1384
1352
|
}
|
|
1385
1353
|
__name(IconButton, "IconButton");
|
|
1386
|
-
function MetaActions({ anchor,
|
|
1354
|
+
function MetaActions({ anchor, presentSections }) {
|
|
1387
1355
|
const { endpointId } = useEndpointDocContext();
|
|
1388
1356
|
const expandAll = useEndpointDocStore((s) => s.expandAll);
|
|
1389
1357
|
const collapseAll = useEndpointDocStore((s) => s.collapseAll);
|
|
1390
1358
|
const openSections = useEndpointDocStore((s) => s.openSections);
|
|
1391
|
-
const [
|
|
1392
|
-
const
|
|
1393
|
-
|
|
1394
|
-
setTimeout(() =>
|
|
1359
|
+
const [linkCopied, setLinkCopied] = useState(false);
|
|
1360
|
+
const flashLink = useCallback(() => {
|
|
1361
|
+
setLinkCopied(true);
|
|
1362
|
+
setTimeout(() => setLinkCopied(false), 1200);
|
|
1395
1363
|
}, []);
|
|
1396
1364
|
const mostlyOpen = useMemo(() => {
|
|
1397
1365
|
if (presentSections.length === 0) return false;
|
|
@@ -1404,43 +1372,21 @@ function MetaActions({ anchor, endpointMarkdown, presentSections }) {
|
|
|
1404
1372
|
const copyLink = useCallback(() => {
|
|
1405
1373
|
if (typeof window === "undefined") return;
|
|
1406
1374
|
const url = `${window.location.origin}${window.location.pathname}#${anchor}`;
|
|
1407
|
-
void navigator.clipboard?.writeText(url).then(
|
|
1408
|
-
}, [anchor,
|
|
1409
|
-
const copyMarkdown = useCallback(() => {
|
|
1410
|
-
if (typeof window === "undefined") return;
|
|
1411
|
-
void navigator.clipboard?.writeText(endpointMarkdown).then(() => flash("md"));
|
|
1412
|
-
}, [endpointMarkdown, flash]);
|
|
1375
|
+
void navigator.clipboard?.writeText(url).then(flashLink);
|
|
1376
|
+
}, [anchor, flashLink]);
|
|
1413
1377
|
const toggleAll = useCallback(() => {
|
|
1414
1378
|
if (mostlyOpen) collapseAll(endpointId, presentSections);
|
|
1415
1379
|
else expandAll(endpointId, presentSections);
|
|
1416
1380
|
}, [mostlyOpen, collapseAll, expandAll, endpointId, presentSections]);
|
|
1381
|
+
const linkLabel = linkCopied ? "Copied!" : "Copy link to endpoint";
|
|
1382
|
+
const linkIcon = linkCopied ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(Link2, { className: "h-3.5 w-3.5" });
|
|
1383
|
+
const showToggleAll = presentSections.length >= 2;
|
|
1384
|
+
const toggleAllLabel = mostlyOpen ? "Collapse all sections" : "Expand all sections";
|
|
1385
|
+
const toggleAllIcon = mostlyOpen ? /* @__PURE__ */ jsx(ChevronsDownUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronsUpDown, { className: "h-3.5 w-3.5" });
|
|
1386
|
+
const toggleAllNode = showToggleAll ? /* @__PURE__ */ jsx(IconButton, { label: toggleAllLabel, onClick: toggleAll, children: toggleAllIcon }) : null;
|
|
1417
1387
|
return /* @__PURE__ */ jsx(SafeTooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
1418
|
-
/* @__PURE__ */ jsx(
|
|
1419
|
-
|
|
1420
|
-
{
|
|
1421
|
-
label: justCopied === "link" ? "Copied!" : "Copy link to endpoint",
|
|
1422
|
-
onClick: copyLink,
|
|
1423
|
-
active: justCopied === "link",
|
|
1424
|
-
children: justCopied === "link" ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(Link2, { className: "h-3.5 w-3.5" })
|
|
1425
|
-
}
|
|
1426
|
-
),
|
|
1427
|
-
/* @__PURE__ */ jsx(
|
|
1428
|
-
IconButton,
|
|
1429
|
-
{
|
|
1430
|
-
label: justCopied === "md" ? "Copied!" : "Copy as Markdown (for AI)",
|
|
1431
|
-
onClick: copyMarkdown,
|
|
1432
|
-
active: justCopied === "md",
|
|
1433
|
-
children: justCopied === "md" ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(FileCode2, { className: "h-3.5 w-3.5" })
|
|
1434
|
-
}
|
|
1435
|
-
),
|
|
1436
|
-
presentSections.length >= 2 && /* @__PURE__ */ jsx(
|
|
1437
|
-
IconButton,
|
|
1438
|
-
{
|
|
1439
|
-
label: mostlyOpen ? "Collapse all sections" : "Expand all sections",
|
|
1440
|
-
onClick: toggleAll,
|
|
1441
|
-
children: mostlyOpen ? /* @__PURE__ */ jsx(ChevronsDownUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronsUpDown, { className: "h-3.5 w-3.5" })
|
|
1442
|
-
}
|
|
1443
|
-
)
|
|
1388
|
+
/* @__PURE__ */ jsx(IconButton, { label: linkLabel, onClick: copyLink, active: linkCopied, children: linkIcon }),
|
|
1389
|
+
toggleAllNode
|
|
1444
1390
|
] }) });
|
|
1445
1391
|
}
|
|
1446
1392
|
__name(MetaActions, "MetaActions");
|
|
@@ -1463,35 +1409,57 @@ function EndpointHeader({
|
|
|
1463
1409
|
presentSections
|
|
1464
1410
|
}) {
|
|
1465
1411
|
const endpointMd = useMemo(() => endpointToMarkdown(endpoint), [endpoint]);
|
|
1412
|
+
const [aiCopied, setAiCopied] = useState(false);
|
|
1413
|
+
const onAiCopy = useCallback(() => {
|
|
1414
|
+
if (typeof window === "undefined") return;
|
|
1415
|
+
void navigator.clipboard?.writeText(endpointMd).then(() => {
|
|
1416
|
+
setAiCopied(true);
|
|
1417
|
+
setTimeout(() => setAiCopied(false), 1200);
|
|
1418
|
+
});
|
|
1419
|
+
}, [endpointMd]);
|
|
1420
|
+
const tryItLabel = isLoadedInPlayground ? "Loaded" : "Try it";
|
|
1421
|
+
const aiCopyIcon = aiCopied ? /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(Sparkles, { className: "h-3 w-3" });
|
|
1422
|
+
const aiCopyLabel = aiCopied ? "Copied" : "AI Copy";
|
|
1423
|
+
const descriptionNode = endpoint.description ? /* @__PURE__ */ jsx("div", { className: "text-muted-foreground text-sm", children: /* @__PURE__ */ jsx(MarkdownMessage, { content: endpoint.description }) }) : null;
|
|
1466
1424
|
return /* @__PURE__ */ jsxs("header", { className: "space-y-3", children: [
|
|
1467
1425
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-wrap", children: [
|
|
1468
1426
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
1469
1427
|
/* @__PURE__ */ jsx(MethodBadge, { method: endpoint.method }),
|
|
1470
|
-
/* @__PURE__ */ jsx(
|
|
1471
|
-
|
|
1428
|
+
/* @__PURE__ */ jsx(MetaActions, { anchor, presentSections })
|
|
1429
|
+
] }),
|
|
1430
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
|
|
1431
|
+
/* @__PURE__ */ jsxs(
|
|
1432
|
+
Button,
|
|
1472
1433
|
{
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1434
|
+
size: "sm",
|
|
1435
|
+
variant: "secondary",
|
|
1436
|
+
onClick: onAiCopy,
|
|
1437
|
+
title: "Copy endpoint as Markdown for AI",
|
|
1438
|
+
"aria-label": "Copy endpoint as Markdown for AI",
|
|
1439
|
+
className: "h-7 text-xs gap-1.5 px-2.5",
|
|
1440
|
+
children: [
|
|
1441
|
+
aiCopyIcon,
|
|
1442
|
+
aiCopyLabel
|
|
1443
|
+
]
|
|
1444
|
+
}
|
|
1445
|
+
),
|
|
1446
|
+
/* @__PURE__ */ jsxs(
|
|
1447
|
+
Button,
|
|
1448
|
+
{
|
|
1449
|
+
size: "sm",
|
|
1450
|
+
variant: isLoadedInPlayground ? "secondary" : "default",
|
|
1451
|
+
onClick: onTryIt,
|
|
1452
|
+
className: "h-7 text-xs gap-1.5 px-2.5",
|
|
1453
|
+
children: [
|
|
1454
|
+
/* @__PURE__ */ jsx(Play, { className: "h-3 w-3" }),
|
|
1455
|
+
tryItLabel
|
|
1456
|
+
]
|
|
1476
1457
|
}
|
|
1477
1458
|
)
|
|
1478
|
-
] })
|
|
1479
|
-
/* @__PURE__ */ jsxs(
|
|
1480
|
-
Button,
|
|
1481
|
-
{
|
|
1482
|
-
size: "sm",
|
|
1483
|
-
variant: isLoadedInPlayground ? "secondary" : "default",
|
|
1484
|
-
onClick: onTryIt,
|
|
1485
|
-
className: "ml-auto h-7 text-xs gap-1.5 px-2.5",
|
|
1486
|
-
children: [
|
|
1487
|
-
/* @__PURE__ */ jsx(Play, { className: "h-3 w-3" }),
|
|
1488
|
-
isLoadedInPlayground ? "Loaded" : "Try it"
|
|
1489
|
-
]
|
|
1490
|
-
}
|
|
1491
|
-
)
|
|
1459
|
+
] })
|
|
1492
1460
|
] }),
|
|
1493
1461
|
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx(PathDisplay, { path: endpoint.path }) }),
|
|
1494
|
-
|
|
1462
|
+
descriptionNode
|
|
1495
1463
|
] });
|
|
1496
1464
|
}
|
|
1497
1465
|
__name(EndpointHeader, "EndpointHeader");
|
|
@@ -1924,7 +1892,7 @@ function Section({ id, title, badge, children }) {
|
|
|
1924
1892
|
title,
|
|
1925
1893
|
badge,
|
|
1926
1894
|
open,
|
|
1927
|
-
onToggle: () => toggleSection(endpointId, id)
|
|
1895
|
+
onToggle: () => toggleSection(endpointId, id, defaultOpen)
|
|
1928
1896
|
}
|
|
1929
1897
|
),
|
|
1930
1898
|
open && /* @__PURE__ */ jsx("div", { children })
|
|
@@ -3459,5 +3427,5 @@ var DocsLayout = /* @__PURE__ */ __name(() => {
|
|
|
3459
3427
|
}, "DocsLayout");
|
|
3460
3428
|
|
|
3461
3429
|
export { DocsLayout };
|
|
3462
|
-
//# sourceMappingURL=DocsLayout-
|
|
3463
|
-
//# sourceMappingURL=DocsLayout-
|
|
3430
|
+
//# sourceMappingURL=DocsLayout-CTJINVBM.mjs.map
|
|
3431
|
+
//# sourceMappingURL=DocsLayout-CTJINVBM.mjs.map
|