@clarify-labs/renderer 0.9.1 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/output/{ClarifyShell-291_IXxJ.js → ClarifyShell-BQ29N8P5.js} +223 -161
  2. package/output/ClarifyShell-BQ29N8P5.js.map +1 -0
  3. package/output/{ClarifyShell-DJ4fOVOd.cjs → ClarifyShell-Dm--LZco.cjs} +224 -162
  4. package/output/ClarifyShell-Dm--LZco.cjs.map +1 -0
  5. package/output/{OpenApiOperation-E8lSLsSK.js → OpenApiOperation-C9xyRo5a.js} +597 -292
  6. package/output/OpenApiOperation-C9xyRo5a.js.map +1 -0
  7. package/output/{OpenApiOperation-3DUVruIO.cjs → OpenApiOperation-DIWGdw29.cjs} +595 -290
  8. package/output/OpenApiOperation-DIWGdw29.cjs.map +1 -0
  9. package/output/{PageActions-DaXQgMYP.js → PageActions-B_tSec1f.js} +282 -197
  10. package/output/PageActions-B_tSec1f.js.map +1 -0
  11. package/output/{PageActions-GI1t-JrR.cjs → PageActions-DEuFHgyB.cjs} +280 -201
  12. package/output/PageActions-DEuFHgyB.cjs.map +1 -0
  13. package/output/app/SectionProvider.d.ts +1 -1
  14. package/output/client.cjs +3 -3
  15. package/output/client.js +3 -3
  16. package/output/components/Tabs.d.ts +16 -0
  17. package/output/components/index.d.ts +1 -0
  18. package/output/core/i18n.d.ts +1 -1
  19. package/output/core/types.d.ts +1 -0
  20. package/output/index.cjs +4 -4
  21. package/output/index.js +4 -4
  22. package/output/openapi/components/CodeDisplay.d.ts +25 -0
  23. package/output/openapi/components/EndpointSections.d.ts +6 -0
  24. package/output/openapi/components/ExamplePanels.d.ts +10 -17
  25. package/output/openapi/components/OpenApiOperation.d.ts +6 -0
  26. package/output/openapi/components/OpenApiOperation.state.d.ts +43 -0
  27. package/output/openapi/components/SchemaProperties.d.ts +2 -0
  28. package/output/openapi/components/SelectControl.d.ts +15 -0
  29. package/output/openapi/components/helpers.d.ts +22 -0
  30. package/output/preview.cjs +114 -67
  31. package/output/preview.cjs.map +1 -1
  32. package/output/preview.js +114 -67
  33. package/output/preview.js.map +1 -1
  34. package/output/{render-r9DclX3Y.cjs → render-BCGK1WpS.cjs} +2 -2
  35. package/output/{render-r9DclX3Y.cjs.map → render-BCGK1WpS.cjs.map} +1 -1
  36. package/output/{render-yBo2SUlA.js → render-CEWLJSmt.js} +2 -2
  37. package/output/{render-yBo2SUlA.js.map → render-CEWLJSmt.js.map} +1 -1
  38. package/output/renderer.css +207 -104
  39. package/output/server.cjs +2 -2
  40. package/output/server.js +2 -2
  41. package/output/shell/Header.d.ts +2 -0
  42. package/package.json +1 -1
  43. package/output/ClarifyShell-291_IXxJ.js.map +0 -1
  44. package/output/ClarifyShell-DJ4fOVOd.cjs.map +0 -1
  45. package/output/OpenApiOperation-3DUVruIO.cjs.map +0 -1
  46. package/output/OpenApiOperation-E8lSLsSK.js.map +0 -1
  47. package/output/PageActions-DaXQgMYP.js.map +0 -1
  48. package/output/PageActions-GI1t-JrR.cjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-DakpK96I.cjs");
2
- const require_PageActions = require("./PageActions-GI1t-JrR.cjs");
2
+ const require_PageActions = require("./PageActions-DEuFHgyB.cjs");
3
3
  const require_remark = require("./remark-Dv3owbSH.cjs");
4
4
  let clsx = require("clsx");
5
5
  clsx = require_chunk.__toESM(clsx, 1);
@@ -906,6 +906,44 @@ function Prose(arg0) {
906
906
  });
907
907
  }
908
908
  //#endregion
909
+ //#region source/components/Tabs.tsx
910
+ function Tabs(arg0) {
911
+ const { items, selectedIndex, onChange, className, listClassName, panelsClassName } = arg0;
912
+ const [internalIndex, setInternalIndex] = (0, react.useState)(0);
913
+ const resolvedIndex = typeof selectedIndex === "number" ? selectedIndex : internalIndex;
914
+ const indicatorLayoutId = (0, react.useId)();
915
+ const handleChange = (index) => {
916
+ if (typeof selectedIndex !== "number") setInternalIndex(index);
917
+ onChange?.(index);
918
+ };
919
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_headlessui_react.TabGroup, {
920
+ selectedIndex: resolvedIndex,
921
+ onChange: handleChange,
922
+ className,
923
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TabList, {
924
+ className: (0, clsx.default)("flex flex-wrap items-center gap-6 border-b border-(--clarify-theme-tokens-colors-border) pb-0", listClassName),
925
+ children: items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.Tab, {
926
+ className: ({ selected }) => (0, clsx.default)("clarify-ui-tab relative inline-flex h-10 shrink-0 items-center px-0 py-0 text-sm font-medium transition focus:outline-none", selected && "clarify-ui-tab-active"),
927
+ children: ({ selected }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: item.label }), selected ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(framer_motion.motion.span, {
928
+ layoutId: indicatorLayoutId,
929
+ className: "absolute inset-x-0 bottom-0 h-0.5 rounded-full bg-(--clarify-theme-tokens-colors-foreground)",
930
+ transition: {
931
+ type: "tween",
932
+ duration: .16,
933
+ ease: "easeOut"
934
+ }
935
+ }) : null] })
936
+ }, item.id))
937
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TabPanels, {
938
+ className: (0, clsx.default)("mt-4", panelsClassName),
939
+ children: items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_headlessui_react.TabPanel, {
940
+ className: "focus:outline-none",
941
+ children: item.panel
942
+ }, item.id))
943
+ })]
944
+ });
945
+ }
946
+ //#endregion
909
947
  //#region source/components/WebFrame.tsx
910
948
  function WebFrame(arg0) {
911
949
  const { src, title = "Embedded content", children, showWindow = true, className, iframeClassName, height = 420, style, ...props } = arg0;
@@ -1725,7 +1763,7 @@ function buildRequestCodeExamples(input) {
1725
1763
  }));
1726
1764
  }
1727
1765
  //#endregion
1728
- //#region source/openapi/components/ExamplePanels.tsx
1766
+ //#region source/openapi/components/SelectControl.tsx
1729
1767
  function SelectControl(arg0) {
1730
1768
  const { label, value, options, onChange, icon, compact = false } = arg0;
1731
1769
  const normalizedOptions = options.map((option) => typeof option === "string" ? {
@@ -1772,69 +1810,8 @@ function SelectControl(arg0) {
1772
1810
  })
1773
1811
  });
1774
1812
  }
1775
- function getExampleLabel(example, t) {
1776
- return example.generated && example.title === "schema" ? t("openapi.schemaExample") : example.title;
1777
- }
1778
- function getLanguageOptions(codeOptions) {
1779
- const languages = /* @__PURE__ */ new Map();
1780
- for (const option of codeOptions ?? []) languages.set(option.languageKey, option.title);
1781
- return Array.from(languages, ([value, label]) => ({
1782
- value,
1783
- label
1784
- }));
1785
- }
1786
- function getClientOptions(codeOptions, languageKey) {
1787
- return (codeOptions ?? []).filter((option) => option.languageKey === languageKey).map((option) => ({
1788
- value: option.clientKey,
1789
- label: option.clientTitle
1790
- }));
1791
- }
1792
- function getServers(spec, operation, path) {
1793
- const operationServers = operation.servers;
1794
- const pathServers = path ? getPathItem(spec, path)?.servers : void 0;
1795
- const servers = Array.isArray(operationServers) ? operationServers : Array.isArray(pathServers) ? pathServers : spec.servers;
1796
- if (!Array.isArray(servers)) return [{ url: "https://api.example.com" }];
1797
- const validServers = servers.filter((server) => isRecord(server) && typeof server.url === "string");
1798
- return validServers.length > 0 ? validServers : [{ url: "https://api.example.com" }];
1799
- }
1800
- function getServerKey(server, index) {
1801
- return `${index}:${server.url ?? ""}`;
1802
- }
1803
- function getServerLabel(server, index) {
1804
- return server.url ?? `Server ${index + 1}`;
1805
- }
1806
- function defaultServerVariables(server) {
1807
- return Object.fromEntries(Object.entries(server?.variables ?? {}).map(([name, variable]) => [name, variable.default ?? variable.enum?.[0] ?? ""]));
1808
- }
1809
- function getSecuritySchemes(spec) {
1810
- const schemes = spec.components;
1811
- if (!isRecord(schemes) || !isRecord(schemes.securitySchemes)) return {};
1812
- return Object.fromEntries(Object.entries(schemes.securitySchemes).filter((entry) => isRecord(entry[1])));
1813
- }
1814
- function getSecurityRequirements(spec, operation) {
1815
- const operationSecurity = operation.security;
1816
- if (Array.isArray(operationSecurity)) return operationSecurity.filter(isRecord);
1817
- const specSecurity = spec.security;
1818
- return Array.isArray(specSecurity) ? specSecurity.filter(isRecord) : [];
1819
- }
1820
- function getAuthOptions(spec, operation) {
1821
- const schemes = getSecuritySchemes(spec);
1822
- const requirements = getSecurityRequirements(spec, operation);
1823
- const names = new Set(requirements.flatMap((requirement) => Object.keys(requirement)));
1824
- return Array.from(names).map((name) => ({
1825
- name,
1826
- scheme: schemes[name]
1827
- })).filter((option) => Boolean(option.scheme));
1828
- }
1829
- function authPlaceholder(auth) {
1830
- if (!auth) return "";
1831
- if (auth.scheme.type === "apiKey") return "{api_key}";
1832
- if (auth.scheme.type === "http" && auth.scheme.scheme?.toLowerCase() === "basic") return "{base64_credentials}";
1833
- return "{token}";
1834
- }
1835
- function authLabel(name, scheme) {
1836
- return `${name}${scheme.type === "apiKey" && scheme.in && scheme.name ? ` · ${scheme.in}: ${scheme.name}` : ""}`;
1837
- }
1813
+ //#endregion
1814
+ //#region source/openapi/components/CodeDisplay.tsx
1838
1815
  function CopyCodeButton(arg0) {
1839
1816
  const { code } = arg0;
1840
1817
  const t = require_PageActions.useBuiltInText();
@@ -1900,6 +1877,73 @@ function CodeToolbar(arg0) {
1900
1877
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyCodeButton, { code })]
1901
1878
  });
1902
1879
  }
1880
+ //#endregion
1881
+ //#region source/openapi/components/helpers.ts
1882
+ function getServers(spec, operation, path) {
1883
+ const operationServers = operation.servers;
1884
+ const pathServers = path ? getPathItem(spec, path)?.servers : void 0;
1885
+ const servers = Array.isArray(operationServers) ? operationServers : Array.isArray(pathServers) ? pathServers : spec.servers;
1886
+ if (!Array.isArray(servers)) return [{ url: "https://api.example.com" }];
1887
+ const validServers = servers.filter((server) => isRecord(server) && typeof server.url === "string");
1888
+ return validServers.length > 0 ? validServers : [{ url: "https://api.example.com" }];
1889
+ }
1890
+ function getServerKey(server, index) {
1891
+ return `${index}:${server.url ?? ""}`;
1892
+ }
1893
+ function getServerLabel(server, index) {
1894
+ return server.url ?? `Server ${index + 1}`;
1895
+ }
1896
+ function defaultServerVariables(server) {
1897
+ return Object.fromEntries(Object.entries(server?.variables ?? {}).map(([name, variable]) => [name, variable.default ?? variable.enum?.[0] ?? ""]));
1898
+ }
1899
+ function getSecuritySchemes(spec) {
1900
+ const schemes = spec.components;
1901
+ if (!isRecord(schemes) || !isRecord(schemes.securitySchemes)) return {};
1902
+ return Object.fromEntries(Object.entries(schemes.securitySchemes).filter((entry) => isRecord(entry[1])));
1903
+ }
1904
+ function getSecurityRequirements(spec, operation) {
1905
+ const operationSecurity = operation.security;
1906
+ if (Array.isArray(operationSecurity)) return operationSecurity.filter(isRecord);
1907
+ const specSecurity = spec.security;
1908
+ return Array.isArray(specSecurity) ? specSecurity.filter(isRecord) : [];
1909
+ }
1910
+ function getAuthOptions(spec, operation) {
1911
+ const schemes = getSecuritySchemes(spec);
1912
+ const requirements = getSecurityRequirements(spec, operation);
1913
+ const names = new Set(requirements.flatMap((requirement) => Object.keys(requirement)));
1914
+ return Array.from(names).map((name) => ({
1915
+ name,
1916
+ scheme: schemes[name]
1917
+ })).filter((option) => Boolean(option.scheme));
1918
+ }
1919
+ function authPlaceholder(auth) {
1920
+ if (!auth) return "";
1921
+ if (auth.scheme.type === "apiKey") return "{api_key}";
1922
+ if (auth.scheme.type === "http" && auth.scheme.scheme?.toLowerCase() === "basic") return "{base64_credentials}";
1923
+ return "{token}";
1924
+ }
1925
+ function authLabel(name, scheme) {
1926
+ return `${name}${scheme.type === "apiKey" && scheme.in && scheme.name ? ` · ${scheme.in}: ${scheme.name}` : ""}`;
1927
+ }
1928
+ function getExampleLabel(example, t) {
1929
+ return example.generated && example.title === "schema" ? t("openapi.schemaExample") : example.title;
1930
+ }
1931
+ function getLanguageOptions(codeOptions) {
1932
+ const languages = /* @__PURE__ */ new Map();
1933
+ for (const option of codeOptions ?? []) languages.set(option.languageKey, option.title);
1934
+ return Array.from(languages, ([value, label]) => ({
1935
+ value,
1936
+ label
1937
+ }));
1938
+ }
1939
+ function getClientOptions(codeOptions, languageKey) {
1940
+ return (codeOptions ?? []).filter((option) => option.languageKey === languageKey).map((option) => ({
1941
+ value: option.clientKey,
1942
+ label: option.clientTitle
1943
+ }));
1944
+ }
1945
+ //#endregion
1946
+ //#region source/openapi/components/ExamplePanels.tsx
1903
1947
  function ApiExampleCodeGroup(arg0) {
1904
1948
  const { title, tag, tagOptions, onSelectTag, label, labelOptions, onSelectLabel, comfortableMeta = false, code, language, mediaTypes, selectedMediaType, onSelectMediaType, examples, selectedExampleKey, onSelectExample, languageOptions, selectedLanguageKey, onSelectLanguage, clientOptions, selectedClientKey, onSelectClient } = arg0;
1905
1949
  const t = require_PageActions.useBuiltInText();
@@ -1976,15 +2020,18 @@ function ApiExampleCodeGroup(arg0) {
1976
2020
  })
1977
2021
  });
1978
2022
  }
1979
- function RequestExamplesPanel(arg0) {
1980
- const { spec, path, method, parameters, requestContents, selectedMediaType, onSelectMediaType, selectedServer, serverVariables, auth } = arg0;
1981
- const t = require_PageActions.useBuiltInText();
2023
+ function firstExampleKeyForMediaType(requestContents, mediaType) {
2024
+ return getExampleEntries(requestContents.find((content) => content.mediaType === mediaType)?.value)[0]?.key ?? "";
2025
+ }
2026
+ function useRequestExamplesState(arg0) {
2027
+ const { spec, path, method, parameters, requestContents, selectedMediaType, onSelectMediaType, selectedServer, serverVariables, auth, sharedExampleKey, onSelectExampleKey } = arg0;
1982
2028
  const selectedContent = requestContents.find((content) => content.mediaType === selectedMediaType) ?? requestContents[0];
1983
2029
  const examples = getExampleEntries(selectedContent?.value);
1984
2030
  const [selectedExampleKey, setSelectedExampleKey] = (0, react.useState)(examples[0]?.key ?? "");
1985
2031
  const [selectedLanguageKey, setSelectedLanguageKey] = (0, react.useState)("shell");
1986
2032
  const [selectedClientKey, setSelectedClientKey] = (0, react.useState)("curl");
1987
- const selectedExample = examples.find((example) => example.key === selectedExampleKey) ?? examples[0];
2033
+ const currentExampleKey = (sharedExampleKey && examples.some((example) => example.key === sharedExampleKey) ? sharedExampleKey : void 0) ?? selectedExampleKey;
2034
+ const selectedExample = examples.find((example) => example.key === currentExampleKey) ?? examples[0];
1988
2035
  const codeOptions = buildRequestCodeExamples({
1989
2036
  spec,
1990
2037
  path,
@@ -2004,71 +2051,159 @@ function RequestExamplesPanel(arg0) {
2004
2051
  });
2005
2052
  const selectedLanguage = codeOptions.find((option) => option.languageKey === selectedLanguageKey) ?? codeOptions[0];
2006
2053
  const selectedCode = codeOptions.find((option) => option.languageKey === selectedLanguage.languageKey && option.clientKey === selectedClientKey) ?? selectedLanguage;
2007
- const languageOptions = getLanguageOptions(codeOptions);
2008
- const clientOptions = getClientOptions(codeOptions, selectedCode.languageKey);
2009
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ApiExampleCodeGroup, {
2010
- title: t("openapi.request"),
2011
- tag: method,
2012
- label: path,
2013
- code: selectedCode.code,
2014
- language: selectedCode.language,
2015
- mediaTypes: requestContents.map((content) => content.mediaType),
2016
- selectedMediaType: selectedContent?.mediaType,
2054
+ return {
2055
+ selectedContent,
2056
+ selectedExample,
2057
+ selectedCode,
2058
+ languageOptions: getLanguageOptions(codeOptions),
2059
+ clientOptions: getClientOptions(codeOptions, selectedCode.languageKey),
2060
+ examples,
2017
2061
  onSelectMediaType: (value) => {
2018
2062
  onSelectMediaType(value);
2019
- setSelectedExampleKey(getExampleEntries(requestContents.find((content) => content.mediaType === value)?.value)[0]?.key ?? "");
2063
+ setSelectedExampleKey(firstExampleKeyForMediaType(requestContents, value));
2064
+ },
2065
+ onSelectExample: (value) => {
2066
+ setSelectedExampleKey(value);
2067
+ onSelectExampleKey?.(value);
2020
2068
  },
2021
- examples,
2022
- selectedExampleKey: selectedExample?.key,
2023
- onSelectExample: setSelectedExampleKey,
2024
- languageOptions,
2025
- selectedLanguageKey: selectedCode.languageKey,
2026
2069
  onSelectLanguage: (value) => {
2027
2070
  const nextCode = codeOptions.find((option) => option.languageKey === value);
2028
2071
  setSelectedLanguageKey(nextCode?.languageKey ?? value);
2029
2072
  setSelectedClientKey(nextCode?.clientKey ?? "");
2030
2073
  },
2031
- clientOptions,
2032
- selectedClientKey: selectedCode.clientKey,
2033
2074
  onSelectClient: setSelectedClientKey
2034
- });
2075
+ };
2035
2076
  }
2036
- function ResponseExamplesPanel(arg0) {
2037
- const { operation, spec } = arg0;
2077
+ function RequestExamplesPanel(arg0) {
2078
+ const { spec, path, method, parameters, requestContents, selectedMediaType, onSelectMediaType, selectedServer, serverVariables, auth, sharedExampleKey, onSelectExampleKey } = arg0;
2038
2079
  const t = require_PageActions.useBuiltInText();
2039
- const responses = getResponseEntries(operation, spec).filter(({ response }) => getMediaTypeEntries(response.content, spec).length > 0);
2040
- const [selectedStatus, setSelectedStatus] = (0, react.useState)(responses.find(({ status }) => status.startsWith("2"))?.status ?? responses[0]?.status ?? "");
2041
- const selectedResponse = responses.find(({ status }) => status === selectedStatus) ?? responses[0];
2080
+ const state = useRequestExamplesState({
2081
+ spec,
2082
+ path,
2083
+ method,
2084
+ parameters,
2085
+ requestContents,
2086
+ selectedMediaType,
2087
+ onSelectMediaType,
2088
+ selectedServer,
2089
+ serverVariables,
2090
+ auth,
2091
+ sharedExampleKey,
2092
+ onSelectExampleKey
2093
+ });
2094
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ApiExampleCodeGroup, {
2095
+ title: t("openapi.request"),
2096
+ tag: method,
2097
+ label: path,
2098
+ code: state.selectedCode.code,
2099
+ language: state.selectedCode.language,
2100
+ mediaTypes: requestContents.map((content) => content.mediaType),
2101
+ selectedMediaType: state.selectedContent?.mediaType,
2102
+ onSelectMediaType: state.onSelectMediaType,
2103
+ examples: state.examples,
2104
+ selectedExampleKey: state.selectedExample?.key,
2105
+ onSelectExample: state.onSelectExample,
2106
+ languageOptions: state.languageOptions,
2107
+ selectedLanguageKey: state.selectedCode.languageKey,
2108
+ onSelectLanguage: state.onSelectLanguage,
2109
+ clientOptions: state.clientOptions,
2110
+ selectedClientKey: state.selectedCode.clientKey,
2111
+ onSelectClient: state.onSelectClient
2112
+ });
2113
+ }
2114
+ function firstExampleKeyForResponseContent(content) {
2115
+ return getExampleEntries(content?.value)[0]?.key ?? "";
2116
+ }
2117
+ function useResponseExamplesState(arg0) {
2118
+ const { operation, spec, sharedExampleKey, onSelectExampleKey, selectedStatus, onSelectStatus } = arg0;
2119
+ const orderedResponses = [...getResponseEntries(operation, spec).filter(({ response }) => getMediaTypeEntries(response.content, spec).length > 0)].sort((left, right) => {
2120
+ if (left.status === "default") return -1;
2121
+ if (right.status === "default") return 1;
2122
+ const leftCode = Number(left.status);
2123
+ const rightCode = Number(right.status);
2124
+ if (!Number.isNaN(leftCode) && !Number.isNaN(rightCode)) return leftCode - rightCode;
2125
+ return left.status.localeCompare(right.status);
2126
+ });
2127
+ const [internalSelectedStatus, setInternalSelectedStatus] = (0, react.useState)(orderedResponses.find(({ status }) => status === "default")?.status ?? orderedResponses.find(({ status }) => status.startsWith("2"))?.status ?? orderedResponses[0]?.status ?? "");
2128
+ const activeStatus = selectedStatus ?? internalSelectedStatus;
2129
+ const selectedResponse = orderedResponses.find(({ status }) => status === activeStatus) ?? orderedResponses[0];
2042
2130
  const responseContents = getMediaTypeEntries(selectedResponse?.response.content, spec);
2043
- const [selectedMediaType, setSelectedMediaType] = (0, react.useState)(responseContents[0]?.mediaType ?? "");
2044
- const selectedContent = responseContents.find((content) => content.mediaType === selectedMediaType) ?? responseContents[0];
2131
+ const [selection, setSelection] = (0, react.useState)(() => ({
2132
+ status: activeStatus,
2133
+ mediaType: responseContents[0]?.mediaType ?? "",
2134
+ exampleKey: firstExampleKeyForResponseContent(responseContents[0])
2135
+ }));
2136
+ const resolvedSelection = selection.status === activeStatus ? selection : {
2137
+ status: activeStatus,
2138
+ mediaType: responseContents[0]?.mediaType ?? "",
2139
+ exampleKey: firstExampleKeyForResponseContent(responseContents[0])
2140
+ };
2141
+ const selectedContent = responseContents.find((content) => content.mediaType === resolvedSelection.mediaType) ?? responseContents[0];
2045
2142
  const examples = getExampleEntries(selectedContent?.value);
2046
- const [selectedExampleKey, setSelectedExampleKey] = (0, react.useState)(examples[0]?.key ?? "");
2047
- const selectedExample = examples.find((example) => example.key === selectedExampleKey) ?? examples[0];
2048
- const responseCode = stringifyExample(selectedExample?.value);
2049
- if (!selectedResponse || !selectedContent || !responseCode) return null;
2050
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ApiExampleCodeGroup, {
2051
- title: t("openapi.response"),
2052
- tag: selectedResponse.status,
2053
- tagOptions: responses.map(({ status }) => status),
2054
- onSelectTag: (value) => {
2055
- const nextContents = getMediaTypeEntries(responses.find(({ status }) => status === value)?.response.content, spec);
2056
- setSelectedStatus(value);
2057
- setSelectedMediaType(nextContents[0]?.mediaType ?? "");
2058
- setSelectedExampleKey(getExampleEntries(nextContents[0]?.value)[0]?.key ?? "");
2143
+ const selectedExampleKey = examples.some((example) => example.key === resolvedSelection.exampleKey) ? resolvedSelection.exampleKey : examples[0]?.key ?? "";
2144
+ const currentExampleKey = (sharedExampleKey && examples.some((example) => example.key === sharedExampleKey) ? sharedExampleKey : void 0) ?? selectedExampleKey;
2145
+ const selectedExample = examples.find((example) => example.key === currentExampleKey) ?? examples[0];
2146
+ return {
2147
+ responses: orderedResponses,
2148
+ selectedResponse,
2149
+ responseContents,
2150
+ selectedContent,
2151
+ examples,
2152
+ selectedExample,
2153
+ responseCode: stringifyExample(selectedExample?.value),
2154
+ onSelectStatus: (value) => {
2155
+ const nextContents = getMediaTypeEntries(orderedResponses.find(({ status }) => status === value)?.response.content, spec);
2156
+ if (typeof selectedStatus === "undefined") setInternalSelectedStatus(value);
2157
+ onSelectStatus?.(value);
2158
+ setSelection({
2159
+ status: value,
2160
+ mediaType: nextContents[0]?.mediaType ?? "",
2161
+ exampleKey: firstExampleKeyForResponseContent(nextContents[0])
2162
+ });
2059
2163
  },
2060
- label: selectedContent.mediaType,
2061
- labelOptions: responseContents.map((content) => content.mediaType),
2062
- onSelectLabel: (value) => {
2063
- setSelectedMediaType(value);
2064
- setSelectedExampleKey(getExampleEntries(responseContents.find((content) => content.mediaType === value)?.value)[0]?.key ?? "");
2164
+ onSelectMediaType: (value) => {
2165
+ const nextContent = responseContents.find((content) => content.mediaType === value);
2166
+ setSelection((current) => ({
2167
+ ...current,
2168
+ mediaType: value,
2169
+ exampleKey: firstExampleKeyForResponseContent(nextContent)
2170
+ }));
2065
2171
  },
2172
+ onSelectExample: (value) => {
2173
+ setSelection((current) => ({
2174
+ ...current,
2175
+ exampleKey: value
2176
+ }));
2177
+ onSelectExampleKey?.(value);
2178
+ }
2179
+ };
2180
+ }
2181
+ function ResponseExamplesPanel(arg0) {
2182
+ const { operation, spec, sharedExampleKey, onSelectExampleKey, selectedStatus, onSelectStatus } = arg0;
2183
+ const t = require_PageActions.useBuiltInText();
2184
+ const state = useResponseExamplesState({
2185
+ operation,
2186
+ spec,
2187
+ sharedExampleKey,
2188
+ onSelectExampleKey,
2189
+ selectedStatus,
2190
+ onSelectStatus
2191
+ });
2192
+ if (!state.selectedResponse || !state.selectedContent || !state.responseCode) return null;
2193
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ApiExampleCodeGroup, {
2194
+ title: t("openapi.response"),
2195
+ tag: state.selectedResponse.status,
2196
+ tagOptions: state.responses.map(({ status }) => status),
2197
+ onSelectTag: state.onSelectStatus,
2198
+ label: state.selectedContent.mediaType,
2199
+ labelOptions: state.responseContents.map((content) => content.mediaType),
2200
+ onSelectLabel: state.onSelectMediaType,
2066
2201
  comfortableMeta: true,
2067
- code: responseCode,
2068
- language: codeLanguageForMediaType(selectedContent.mediaType),
2069
- examples,
2070
- selectedExampleKey: selectedExample?.key,
2071
- onSelectExample: setSelectedExampleKey
2202
+ code: state.responseCode,
2203
+ language: codeLanguageForMediaType(state.selectedContent.mediaType),
2204
+ examples: state.examples,
2205
+ selectedExampleKey: state.selectedExample?.key,
2206
+ onSelectExample: state.onSelectExample
2072
2207
  });
2073
2208
  }
2074
2209
  //#endregion
@@ -2302,111 +2437,292 @@ function SchemaProperties(arg0) {
2302
2437
  function ParameterList(arg0) {
2303
2438
  const { title, parameters } = arg0;
2304
2439
  const t = require_PageActions.useBuiltInText();
2305
- if (parameters.length === 0) return null;
2306
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: title }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Properties, { children: parameters.map((parameter) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Property, {
2440
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: title }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Properties, { children: parameters.length > 0 ? parameters.map((parameter) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Property, {
2307
2441
  name: parameter.name ?? t("openapi.parameter"),
2308
2442
  type: [schemaToType(parameter.schema), parameter.required ? t("openapi.requiredBadge") : void 0].filter(Boolean).join(", ") || void 0,
2309
2443
  children: parameter.description ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Markdown, {
2310
2444
  className: "*:first:mt-0 *:last:mb-0",
2311
2445
  children: parameter.description
2312
2446
  }) : t("openapi.operationParameter")
2313
- }, `${parameter.in}-${parameter.name}`)) })] });
2447
+ }, `${parameter.in}-${parameter.name}`)) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2448
+ className: "text-sm/5 text-(--clarify-ui-text-soft)",
2449
+ children: t("openapi.none")
2450
+ }) })] });
2314
2451
  }
2315
2452
  function ResponseList(arg0) {
2316
- const { operation, spec } = arg0;
2453
+ const { operation, spec, selectedStatus, onSelectStatus } = arg0;
2317
2454
  const t = require_PageActions.useBuiltInText();
2318
- const responses = getResponseEntries(operation, spec);
2319
- if (responses.length === 0) return null;
2320
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("openapi.responses") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Properties, { children: responses.map(({ status, response }) => {
2321
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Property, {
2322
- name: status,
2323
- type: schemaToType(getJsonLikeContent(response.content, spec)?.value.schema),
2324
- children: response.description ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Markdown, {
2325
- className: "*:first:mt-0 *:last:mb-0",
2326
- children: response.description
2327
- }) : `${t("openapi.response")}.`
2328
- }, status);
2329
- }) })] });
2455
+ const orderedResponses = [...getResponseEntries(operation, spec)].sort((left, right) => {
2456
+ if (left.status === "default") return -1;
2457
+ if (right.status === "default") return 1;
2458
+ const leftCode = Number(left.status);
2459
+ const rightCode = Number(right.status);
2460
+ if (!Number.isNaN(leftCode) && !Number.isNaN(rightCode)) return leftCode - rightCode;
2461
+ return left.status.localeCompare(right.status);
2462
+ });
2463
+ const activeStatus = selectedStatus ?? orderedResponses.find(({ status }) => status === "default")?.status ?? orderedResponses.find(({ status }) => status.startsWith("2"))?.status ?? orderedResponses[0]?.status ?? "";
2464
+ const selectedIndex = Math.max(0, orderedResponses.findIndex(({ status }) => status === activeStatus));
2465
+ if (orderedResponses.length === 0) return null;
2466
+ const renderResponsePanel = ({ status, response }) => {
2467
+ const responseSchema = getJsonLikeContent(response.content, spec)?.value.schema;
2468
+ const type = schemaToType(responseSchema);
2469
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2470
+ className: "rounded-(--clarify-theme-tokens-radius-xl) p-0",
2471
+ children: [
2472
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2473
+ className: "flex flex-wrap items-center gap-2",
2474
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2475
+ className: "text-sm/5 font-semibold text-(--clarify-theme-tokens-colors-foreground)",
2476
+ children: status
2477
+ }), type ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2478
+ className: "text-xs text-(--clarify-theme-tokens-colors-muted)",
2479
+ children: type
2480
+ }) : null]
2481
+ }),
2482
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2483
+ className: "mt-3 text-sm/6 text-(--clarify-ui-text-soft) *:first:mt-0 *:last:mb-0",
2484
+ children: response.description ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Markdown, {
2485
+ className: "*:first:mt-0 *:last:mb-0",
2486
+ children: response.description
2487
+ }) : `${t("openapi.response")}.`
2488
+ }),
2489
+ responseSchema && spec ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2490
+ className: "mt-4",
2491
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SchemaProperties, {
2492
+ title: t("openapi.responseBodyProperties"),
2493
+ schema: responseSchema,
2494
+ spec
2495
+ })
2496
+ }) : null
2497
+ ]
2498
+ });
2499
+ };
2500
+ if (orderedResponses.length === 1) {
2501
+ const [{ status, response }] = orderedResponses;
2502
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("openapi.responses") }), renderResponsePanel({
2503
+ status,
2504
+ response
2505
+ })] });
2506
+ }
2507
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("openapi.responses") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tabs, {
2508
+ selectedIndex,
2509
+ onChange: (index) => {
2510
+ onSelectStatus?.(orderedResponses[index]?.status ?? "");
2511
+ },
2512
+ items: orderedResponses.map(({ status, response }) => ({
2513
+ id: status,
2514
+ label: status,
2515
+ panel: renderResponsePanel({
2516
+ status,
2517
+ response
2518
+ })
2519
+ })),
2520
+ panelsClassName: "mt-4"
2521
+ })] });
2330
2522
  }
2331
2523
  //#endregion
2332
2524
  //#region source/openapi/components/EndpointSections.tsx
2333
2525
  function EndpointRequest(arg0) {
2334
- const { spec, path, method, description, groupedParameters, parameters, requestBody, requestContents, requestSchema, selectedRequestMediaType, onSelectRequestMediaType, selectedServer, serverVariables, auth } = arg0;
2526
+ const { spec, path, method, description, groupedParameters, parameters, requestBody, requestContents, requestSchema, selectedRequestMediaType, onSelectRequestMediaType, selectedServer, serverVariables, auth, sharedExampleKey, onSelectExampleKey } = arg0;
2335
2527
  const t = require_PageActions.useBuiltInText();
2336
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
2528
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [description ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Markdown, { children: description }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
2337
2529
  className: "relative mt-6",
2338
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Col, { children: [
2339
- description ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Markdown, { children: description }) : null,
2340
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ParameterList, {
2341
- title: t("openapi.pathParameters"),
2342
- parameters: groupedParameters.path
2343
- }),
2344
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ParameterList, {
2345
- title: t("openapi.queryParameters"),
2346
- parameters: groupedParameters.query
2347
- }),
2348
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ParameterList, {
2349
- title: t("openapi.headers"),
2350
- parameters: groupedParameters.header
2351
- }),
2352
- requestBody && requestContents.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
2353
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("openapi.requestBody") }),
2354
- typeof requestBody.description === "string" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Markdown, { children: requestBody.description }) : null,
2355
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SchemaProperties, {
2356
- title: t("openapi.bodyProperties"),
2357
- schema: requestSchema,
2358
- spec
2359
- })
2360
- ] }) : null
2361
- ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Col, {
2530
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Col, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2531
+ className: "w-full",
2532
+ children: [
2533
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ParameterList, {
2534
+ title: t("openapi.pathParameters"),
2535
+ parameters: groupedParameters.path
2536
+ }),
2537
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ParameterList, {
2538
+ title: t("openapi.queryParameters"),
2539
+ parameters: groupedParameters.query
2540
+ }),
2541
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ParameterList, {
2542
+ title: t("openapi.headers"),
2543
+ parameters: groupedParameters.header
2544
+ }),
2545
+ requestBody && requestContents.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
2546
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("openapi.requestBody") }),
2547
+ typeof requestBody.description === "string" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Markdown, { children: requestBody.description }) : null,
2548
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SchemaProperties, {
2549
+ title: t("openapi.bodyProperties"),
2550
+ schema: requestSchema,
2551
+ spec
2552
+ })
2553
+ ] }) : null
2554
+ ]
2555
+ }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Col, {
2362
2556
  sticky: true,
2363
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RequestExamplesPanel, {
2364
- spec,
2365
- path,
2366
- method,
2367
- parameters,
2368
- requestContents,
2369
- selectedMediaType: selectedRequestMediaType,
2370
- onSelectMediaType: onSelectRequestMediaType,
2371
- selectedServer,
2372
- serverVariables,
2373
- auth
2557
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2558
+ className: "w-full",
2559
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RequestExamplesPanel, {
2560
+ spec,
2561
+ path,
2562
+ method,
2563
+ parameters,
2564
+ requestContents,
2565
+ selectedMediaType: selectedRequestMediaType,
2566
+ onSelectMediaType: onSelectRequestMediaType,
2567
+ selectedServer,
2568
+ serverVariables,
2569
+ auth,
2570
+ sharedExampleKey,
2571
+ onSelectExampleKey
2572
+ })
2374
2573
  })
2375
2574
  })]
2376
- });
2575
+ })] });
2377
2576
  }
2378
2577
  function EndpointResponse(arg0) {
2379
- const { spec, operation } = arg0;
2380
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
2381
- className: "relative mt-6",
2382
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Col, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponseList, {
2383
- operation,
2384
- spec
2385
- }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Col, {
2386
- sticky: true,
2387
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponseExamplesPanel, {
2388
- operation,
2389
- spec
2390
- })
2391
- })]
2578
+ const { spec, operation, sharedExampleKey, onSelectExampleKey, selectedStatus, onSelectStatus } = arg0;
2579
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2580
+ className: "mt-6",
2581
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Row, {
2582
+ className: "relative",
2583
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Col, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2584
+ className: "w-full",
2585
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponseList, {
2586
+ operation,
2587
+ spec,
2588
+ selectedStatus,
2589
+ onSelectStatus
2590
+ })
2591
+ }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Col, {
2592
+ sticky: true,
2593
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2594
+ className: "w-full",
2595
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponseExamplesPanel, {
2596
+ operation,
2597
+ spec,
2598
+ sharedExampleKey,
2599
+ onSelectExampleKey,
2600
+ selectedStatus,
2601
+ onSelectStatus
2602
+ })
2603
+ })
2604
+ })]
2605
+ })
2392
2606
  });
2393
2607
  }
2394
2608
  //#endregion
2609
+ //#region source/openapi/components/OpenApiOperation.state.ts
2610
+ function useOperationRequestState(spec, path, operation) {
2611
+ const parameters = getOperationParameters(spec, path, operation);
2612
+ const requestBody = getRequestBody$1(spec, operation);
2613
+ const requestContents = getMediaTypeEntries(requestBody?.content, spec);
2614
+ const [selectedRequestMediaType, setSelectedRequestMediaType] = (0, react.useState)(requestContents[0]?.mediaType ?? "");
2615
+ const selectedRequestContent = requestContents.find((content) => content.mediaType === selectedRequestMediaType) ?? requestContents[0];
2616
+ const requestSchema = selectedRequestContent?.value.schema;
2617
+ const groupedParameters = {
2618
+ path: parameters.filter((parameter) => parameter.in === "path"),
2619
+ query: parameters.filter((parameter) => parameter.in === "query"),
2620
+ header: parameters.filter((parameter) => parameter.in === "header")
2621
+ };
2622
+ return {
2623
+ parameters,
2624
+ requestBody,
2625
+ requestContents,
2626
+ selectedRequestMediaType: selectedRequestContent?.mediaType ?? "",
2627
+ setSelectedRequestMediaType,
2628
+ requestSchema,
2629
+ groupedParameters
2630
+ };
2631
+ }
2632
+ function useOperationServerState(spec, operation, path) {
2633
+ const servers = getServers(spec, operation, path);
2634
+ const [selectedServerKey, setSelectedServerKey] = (0, react.useState)(getServerKey(servers[0], 0));
2635
+ const selectedServer = servers.find((server, index) => getServerKey(server, index) === selectedServerKey) ?? servers[0];
2636
+ const [serverVariables, setServerVariables] = (0, react.useState)(defaultServerVariables(selectedServer));
2637
+ const [serverOpen, setServerOpen] = (0, react.useState)(false);
2638
+ return {
2639
+ servers,
2640
+ selectedServerKey,
2641
+ selectedServer,
2642
+ serverVariables,
2643
+ serverOpen,
2644
+ onSelectServer: (value) => {
2645
+ const nextServer = servers.find((server, index) => getServerKey(server, index) === value) ?? servers[0];
2646
+ setSelectedServerKey(value);
2647
+ setServerVariables(defaultServerVariables(nextServer));
2648
+ },
2649
+ onChangeServerVariable: (name, value) => setServerVariables((current) => ({
2650
+ ...current,
2651
+ [name]: value
2652
+ })),
2653
+ onToggleServer: () => setServerOpen((current) => !current),
2654
+ closeServer: () => setServerOpen(false)
2655
+ };
2656
+ }
2657
+ function useOperationAuthState(spec, operation) {
2658
+ const authOptions = getAuthOptions(spec, operation);
2659
+ const [selectedAuthName, setSelectedAuthName] = (0, react.useState)(authOptions[0]?.name ?? "");
2660
+ const selectedAuth = authOptions.find((option) => option.name === selectedAuthName);
2661
+ const [authValues, setAuthValues] = (0, react.useState)({});
2662
+ const [authOpen, setAuthOpen] = (0, react.useState)(false);
2663
+ return {
2664
+ authOptions,
2665
+ selectedAuthName,
2666
+ selectedAuth,
2667
+ authValues,
2668
+ authOpen,
2669
+ authInput: selectedAuth ? {
2670
+ name: selectedAuth.name,
2671
+ scheme: selectedAuth.scheme,
2672
+ value: authValues[selectedAuth.name] ?? authPlaceholder(selectedAuth)
2673
+ } : void 0,
2674
+ onSelectAuth: setSelectedAuthName,
2675
+ onChangeAuthValue: (name, value) => setAuthValues((current) => ({
2676
+ ...current,
2677
+ [name]: value
2678
+ })),
2679
+ onToggleAuth: () => setAuthOpen((current) => !current),
2680
+ closeAuth: () => setAuthOpen(false)
2681
+ };
2682
+ }
2683
+ //#endregion
2395
2684
  //#region source/openapi/components/OpenApiOperation.tsx
2396
- var endpointMethodStyles = {
2397
- GET: "bg-emerald-400/15 text-emerald-600 dark:bg-emerald-400/20 dark:text-emerald-300",
2398
- POST: "bg-sky-400/15 text-sky-600 dark:bg-sky-400/20 dark:text-sky-300",
2399
- PUT: "bg-amber-400/15 text-amber-600 dark:bg-amber-400/20 dark:text-amber-300",
2400
- PATCH: "bg-amber-400/15 text-amber-600 dark:bg-amber-400/20 dark:text-amber-300",
2401
- DELETE: "bg-rose-400/15 text-rose-600 dark:bg-rose-400/20 dark:text-rose-300"
2685
+ var endpointMethodStyleVars = {
2686
+ GET: "bg-(--clarify-http-method-get-background) text-(--clarify-http-method-get-text)",
2687
+ POST: "bg-(--clarify-http-method-post-background) text-(--clarify-http-method-post-text)",
2688
+ PUT: "bg-(--clarify-http-method-put-background) text-(--clarify-http-method-put-text)",
2689
+ PATCH: "bg-(--clarify-http-method-patch-background) text-(--clarify-http-method-patch-text)",
2690
+ DELETE: "bg-(--clarify-http-method-delete-background) text-(--clarify-http-method-delete-text)"
2402
2691
  };
2403
2692
  function EndpointMethodBadge(arg0) {
2404
2693
  const { method } = arg0;
2405
2694
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2406
- className: (0, clsx.default)("rounded-(--clarify-theme-tokens-radius-md) px-2.5 py-0.5 text-xs/6 font-black tracking-wide", endpointMethodStyles[method] ?? "bg-zinc-400/15 text-zinc-700 dark:bg-zinc-400/20 dark:text-zinc-200"),
2695
+ className: (0, clsx.default)("rounded-(--clarify-theme-tokens-radius-md) px-2.5 py-0.5 text-xs/6 font-black tracking-wide", endpointMethodStyleVars[method] ?? "bg-(--clarify-http-method-default-background) text-(--clarify-http-method-default-text)"),
2407
2696
  children: method
2408
2697
  });
2409
2698
  }
2699
+ function EndpointPath(arg0) {
2700
+ const { path, copied = false, onCopy } = arg0;
2701
+ const t = require_PageActions.useBuiltInText();
2702
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2703
+ className: "flex min-w-0 flex-1 items-center gap-2 overflow-hidden",
2704
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2705
+ className: "min-w-0 flex-1 overflow-x-auto text-sm font-bold leading-6 whitespace-nowrap",
2706
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2707
+ className: "select-text font-mono text-(--clarify-theme-tokens-colors-foreground)",
2708
+ children: path || "/"
2709
+ })
2710
+ }), onCopy ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2711
+ type: "button",
2712
+ "aria-label": copied ? t("actions.copied") : t("actions.copy"),
2713
+ title: copied ? t("actions.copied") : t("actions.copy"),
2714
+ onClick: onCopy,
2715
+ className: (0, clsx.default)("flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface) text-(--clarify-ui-text-soft) transition hover:border-(--clarify-ui-text-faint) hover:bg-(--clarify-ui-hover-background) hover:text-(--clarify-theme-tokens-colors-foreground)", copied && "border-emerald-400/70 bg-emerald-50 text-emerald-700 dark:bg-emerald-400/10 dark:text-emerald-200"),
2716
+ children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CheckIcon, {
2717
+ className: "h-3.5 w-3.5",
2718
+ "aria-hidden": "true"
2719
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CopyIcon, {
2720
+ className: "h-3.5 w-3.5",
2721
+ "aria-hidden": "true"
2722
+ })
2723
+ }) : null]
2724
+ });
2725
+ }
2410
2726
  function InlineListbox(arg0) {
2411
2727
  const { label, value, options, onChange, compact = false } = arg0;
2412
2728
  const selected = options.find((option) => option.value === value) ?? options[0];
@@ -2452,6 +2768,22 @@ function InlineListbox(arg0) {
2452
2768
  function getServerPreviewUrl(server, variables) {
2453
2769
  return (server.url ?? "").replace(/\{([^}]+)\}/g, (_, name) => variables[name] ?? server.variables?.[name]?.default ?? `{${name}}`);
2454
2770
  }
2771
+ function getFullEndpointUrl(server, variables, path) {
2772
+ const base = getServerPreviewUrl(server, variables);
2773
+ if (!base) return path;
2774
+ return `${base.endsWith("/") ? base.slice(0, -1) : base}${path.startsWith("/") ? path : `/${path}`}`;
2775
+ }
2776
+ function getDefaultResponseStatus(operation, spec) {
2777
+ const orderedResponses = [...getResponseEntries(operation, spec).filter(({ response }) => getMediaTypeEntries(response.content, spec).length > 0)].sort((left, right) => {
2778
+ if (left.status === "default") return -1;
2779
+ if (right.status === "default") return 1;
2780
+ const leftCode = Number(left.status);
2781
+ const rightCode = Number(right.status);
2782
+ if (!Number.isNaN(leftCode) && !Number.isNaN(rightCode)) return leftCode - rightCode;
2783
+ return left.status.localeCompare(right.status);
2784
+ });
2785
+ return orderedResponses.find(({ status }) => status === "default")?.status ?? orderedResponses.find(({ status }) => status.startsWith("2"))?.status ?? orderedResponses[0]?.status ?? "";
2786
+ }
2455
2787
  function ServerUrlValue(arg0) {
2456
2788
  const { server, variables, open, interactive, onToggle } = arg0;
2457
2789
  const url = getServerPreviewUrl(server, variables);
@@ -2522,7 +2854,7 @@ function ServerPanel(arg0) {
2522
2854
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2523
2855
  className: "border-t border-(--clarify-theme-tokens-colors-border) bg-(--clarify-ui-subtle-background) p-3",
2524
2856
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2525
- className: "grid gap-3 sm:grid-cols-(--clarify-openapi-control-grid)",
2857
+ className: "flex flex-col gap-3",
2526
2858
  children: [servers.length > 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2527
2859
  className: "flex min-w-0 flex-col gap-1.5",
2528
2860
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -2538,18 +2870,21 @@ function ServerPanel(arg0) {
2538
2870
  })),
2539
2871
  onChange: onSelectServer
2540
2872
  })]
2541
- }) : null, variableEntries.map(([name, variable]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2542
- className: "flex min-w-0 flex-col gap-1.5",
2543
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2544
- className: "text-2xs font-semibold text-(--clarify-ui-text-soft)",
2545
- children: name
2546
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ServerVariableControl, {
2547
- name,
2548
- variable,
2549
- value: variables[name] ?? variable.default ?? "",
2550
- onChange: (value) => onChangeVariable(name, value)
2551
- })]
2552
- }, name))]
2873
+ }) : null, variableEntries.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2874
+ className: "grid gap-3 sm:grid-cols-(--clarify-openapi-variable-grid)",
2875
+ children: variableEntries.map(([name, variable]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2876
+ className: "flex min-w-0 flex-col gap-1.5",
2877
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2878
+ className: "text-2xs font-semibold text-(--clarify-ui-text-soft)",
2879
+ children: name
2880
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ServerVariableControl, {
2881
+ name,
2882
+ variable,
2883
+ value: variables[name] ?? variable.default ?? "",
2884
+ onChange: (value) => onChangeVariable(name, value)
2885
+ })]
2886
+ }, name))
2887
+ }) : null]
2553
2888
  })
2554
2889
  });
2555
2890
  }
@@ -2597,8 +2932,17 @@ function AuthPanel(arg0) {
2597
2932
  }
2598
2933
  function EndpointIdentity(arg0) {
2599
2934
  const { method, path, servers, selectedServerKey, selectedServer, serverVariables, serverOpen, authOptions, selectedAuthName, selectedAuth, authValues, authOpen, onSelectServer, onChangeServerVariable, onToggleServer, onToggleAuth, onSelectAuth, onChangeAuthValue } = arg0;
2600
- const segments = path.split("/").filter(Boolean);
2601
2935
  const serverInteractive = servers.length > 1 || Object.keys(selectedServer.variables ?? {}).length > 0;
2936
+ const [copiedUrl, setCopiedUrl] = (0, react.useState)(false);
2937
+ const fullUrl = getFullEndpointUrl(selectedServer, serverVariables, path);
2938
+ (0, react.useEffect)(() => {
2939
+ if (!copiedUrl) return void 0;
2940
+ const timeout = window.setTimeout(() => setCopiedUrl(false), 1200);
2941
+ return () => window.clearTimeout(timeout);
2942
+ }, [copiedUrl]);
2943
+ async function handleCopyUrl() {
2944
+ if (await require_PageActions.copyTextToClipboard(fullUrl)) setCopiedUrl(true);
2945
+ }
2602
2946
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2603
2947
  className: "not-prose flex w-full flex-col overflow-hidden rounded-xl border border-(--clarify-theme-tokens-colors-border) bg-(--clarify-theme-tokens-colors-surface) shadow-xs",
2604
2948
  children: [
@@ -2613,24 +2957,10 @@ function EndpointIdentity(arg0) {
2613
2957
  interactive: serverInteractive,
2614
2958
  onToggle: onToggleServer
2615
2959
  }),
2616
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2617
- className: "flex min-w-0 flex-1 items-center overflow-x-auto text-sm font-bold leading-6 whitespace-nowrap",
2618
- children: segments.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2619
- className: "text-(--clarify-ui-text-faint)",
2620
- children: "/"
2621
- }), segments.map((segment, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2622
- className: "flex items-center",
2623
- children: [index > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2624
- className: "text-(--clarify-ui-text-faint)",
2625
- children: "/"
2626
- }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2627
- className: "font-bold text-(--clarify-theme-tokens-colors-foreground)",
2628
- children: segment
2629
- })]
2630
- }, `${segment}-${index}`))] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2631
- className: "font-bold text-(--clarify-theme-tokens-colors-foreground)",
2632
- children: "/"
2633
- })
2960
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EndpointPath, {
2961
+ path,
2962
+ copied: copiedUrl,
2963
+ onCopy: handleCopyUrl
2634
2964
  }),
2635
2965
  authOptions.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2636
2966
  type: "button",
@@ -2672,32 +3002,11 @@ function OpenApiOperation(arg0) {
2672
3002
  const id = (0, github_slugger.slug)(`${method.toLowerCase()} ${path}`);
2673
3003
  const summary = operation.summary ?? `${method} ${path}`;
2674
3004
  const description = operation.description;
2675
- const parameters = getOperationParameters(spec, path, operation);
2676
- const requestBody = getRequestBody$1(spec, operation);
2677
- const requestContents = getMediaTypeEntries(requestBody?.content, spec);
2678
- const [selectedRequestMediaType, setSelectedRequestMediaType] = (0, react.useState)(requestContents[0]?.mediaType ?? "");
2679
- const selectedRequestContent = requestContents.find((content) => content.mediaType === selectedRequestMediaType) ?? requestContents[0];
2680
- const requestSchema = selectedRequestContent?.value.schema;
2681
- const servers = getServers(spec, operation, path);
2682
- const [selectedServerKey, setSelectedServerKey] = (0, react.useState)(getServerKey(servers[0], 0));
2683
- const selectedServer = servers.find((server, index) => getServerKey(server, index) === selectedServerKey) ?? servers[0];
2684
- const [serverVariables, setServerVariables] = (0, react.useState)(defaultServerVariables(selectedServer));
2685
- const [serverOpen, setServerOpen] = (0, react.useState)(false);
2686
- const authOptions = getAuthOptions(spec, operation);
2687
- const [selectedAuthName, setSelectedAuthName] = (0, react.useState)(authOptions[0]?.name ?? "");
2688
- const selectedAuth = authOptions.find((option) => option.name === selectedAuthName);
2689
- const [authValues, setAuthValues] = (0, react.useState)({});
2690
- const [authOpen, setAuthOpen] = (0, react.useState)(false);
2691
- const authInput = selectedAuth ? {
2692
- name: selectedAuth.name,
2693
- scheme: selectedAuth.scheme,
2694
- value: authValues[selectedAuth.name] ?? authPlaceholder(selectedAuth)
2695
- } : void 0;
2696
- const groupedParameters = {
2697
- path: parameters.filter((parameter) => parameter.in === "path"),
2698
- query: parameters.filter((parameter) => parameter.in === "query"),
2699
- header: parameters.filter((parameter) => parameter.in === "header")
2700
- };
3005
+ const requestState = useOperationRequestState(spec, path, operation);
3006
+ const serverState = useOperationServerState(spec, operation, path);
3007
+ const authState = useOperationAuthState(spec, operation);
3008
+ const [linkedExampleKey, setLinkedExampleKey] = (0, react.useState)("");
3009
+ const [selectedResponseStatus, setSelectedResponseStatus] = (0, react.useState)(() => getDefaultResponseStatus(operation, spec));
2701
3010
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2702
3011
  className: "clarify-api-endpoint scroll-mt-24 pb-16 first:pt-0 last:pb-0",
2703
3012
  "aria-labelledby": id,
@@ -2709,58 +3018,54 @@ function OpenApiOperation(arg0) {
2709
3018
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EndpointIdentity, {
2710
3019
  method,
2711
3020
  path,
2712
- servers,
2713
- selectedServerKey,
2714
- selectedServer,
2715
- serverVariables,
2716
- serverOpen,
2717
- authOptions,
2718
- selectedAuthName,
2719
- selectedAuth,
2720
- authValues,
2721
- authOpen,
2722
- onSelectServer: (value) => {
2723
- const nextServer = servers.find((server, index) => getServerKey(server, index) === value) ?? servers[0];
2724
- setSelectedServerKey(value);
2725
- setServerVariables(defaultServerVariables(nextServer));
2726
- },
2727
- onChangeServerVariable: (name, value) => setServerVariables((current) => ({
2728
- ...current,
2729
- [name]: value
2730
- })),
3021
+ servers: serverState.servers,
3022
+ selectedServerKey: serverState.selectedServerKey,
3023
+ selectedServer: serverState.selectedServer,
3024
+ serverVariables: serverState.serverVariables,
3025
+ serverOpen: serverState.serverOpen,
3026
+ authOptions: authState.authOptions,
3027
+ selectedAuthName: authState.selectedAuthName,
3028
+ selectedAuth: authState.selectedAuth,
3029
+ authValues: authState.authValues,
3030
+ authOpen: authState.authOpen,
3031
+ onSelectServer: serverState.onSelectServer,
3032
+ onChangeServerVariable: serverState.onChangeServerVariable,
2731
3033
  onToggleServer: () => {
2732
- setServerOpen((current) => !current);
2733
- setAuthOpen(false);
3034
+ serverState.onToggleServer();
3035
+ authState.closeAuth();
2734
3036
  },
2735
3037
  onToggleAuth: () => {
2736
- setAuthOpen((current) => !current);
2737
- setServerOpen(false);
3038
+ authState.onToggleAuth();
3039
+ serverState.closeServer();
2738
3040
  },
2739
- onSelectAuth: setSelectedAuthName,
2740
- onChangeAuthValue: (name, value) => setAuthValues((current) => ({
2741
- ...current,
2742
- [name]: value
2743
- }))
3041
+ onSelectAuth: authState.onSelectAuth,
3042
+ onChangeAuthValue: authState.onChangeAuthValue
2744
3043
  }),
2745
3044
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EndpointRequest, {
2746
3045
  spec,
2747
3046
  path,
2748
3047
  method,
2749
3048
  description,
2750
- groupedParameters,
2751
- parameters,
2752
- requestBody,
2753
- requestContents,
2754
- requestSchema,
2755
- selectedRequestMediaType: selectedRequestContent?.mediaType ?? "",
2756
- onSelectRequestMediaType: setSelectedRequestMediaType,
2757
- selectedServer,
2758
- serverVariables,
2759
- auth: authInput
3049
+ groupedParameters: requestState.groupedParameters,
3050
+ parameters: requestState.parameters,
3051
+ requestBody: requestState.requestBody,
3052
+ requestContents: requestState.requestContents,
3053
+ requestSchema: requestState.requestSchema,
3054
+ selectedRequestMediaType: requestState.selectedRequestMediaType,
3055
+ onSelectRequestMediaType: requestState.setSelectedRequestMediaType,
3056
+ selectedServer: serverState.selectedServer,
3057
+ serverVariables: serverState.serverVariables,
3058
+ auth: authState.authInput,
3059
+ sharedExampleKey: linkedExampleKey,
3060
+ onSelectExampleKey: setLinkedExampleKey
2760
3061
  }),
2761
3062
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EndpointResponse, {
2762
3063
  spec,
2763
- operation
3064
+ operation,
3065
+ sharedExampleKey: linkedExampleKey,
3066
+ onSelectExampleKey: setLinkedExampleKey,
3067
+ selectedStatus: selectedResponseStatus,
3068
+ onSelectStatus: setSelectedResponseStatus
2764
3069
  })
2765
3070
  ]
2766
3071
  });
@@ -2947,4 +3252,4 @@ Object.defineProperty(exports, "primitives_exports", {
2947
3252
  }
2948
3253
  });
2949
3254
 
2950
- //# sourceMappingURL=OpenApiOperation-3DUVruIO.cjs.map
3255
+ //# sourceMappingURL=OpenApiOperation-DIWGdw29.cjs.map