zudoku 0.33.1 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/dist/config/validators/common.d.ts +572 -354
  2. package/dist/config/validators/common.js +26 -8
  3. package/dist/config/validators/common.js.map +1 -1
  4. package/dist/config/validators/validate.d.ts +254 -167
  5. package/dist/lib/authentication/hook.d.ts +1 -0
  6. package/dist/lib/authentication/hook.js +11 -1
  7. package/dist/lib/authentication/hook.js.map +1 -1
  8. package/dist/lib/authentication/providers/clerk.js +6 -6
  9. package/dist/lib/authentication/providers/clerk.js.map +1 -1
  10. package/dist/lib/components/AnchorLink.d.ts +2 -2
  11. package/dist/lib/components/AnchorLink.js +4 -4
  12. package/dist/lib/components/AnchorLink.js.map +1 -1
  13. package/dist/lib/components/Banner.js +1 -1
  14. package/dist/lib/components/Banner.js.map +1 -1
  15. package/dist/lib/components/Heading.d.ts +2 -2
  16. package/dist/lib/components/Layout.js +1 -1
  17. package/dist/lib/components/Layout.js.map +1 -1
  18. package/dist/lib/components/context/ZudokuContext.d.ts +1 -1
  19. package/dist/lib/components/index.d.ts +1 -0
  20. package/dist/lib/components/navigation/SidebarItem.js +6 -5
  21. package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
  22. package/dist/lib/core/RouteGuard.js +2 -1
  23. package/dist/lib/core/RouteGuard.js.map +1 -1
  24. package/dist/lib/core/ZudokuContext.d.ts +4 -0
  25. package/dist/lib/core/ZudokuContext.js.map +1 -1
  26. package/dist/lib/plugins/api-catalog/Catalog.d.ts +3 -1
  27. package/dist/lib/plugins/api-catalog/Catalog.js +7 -4
  28. package/dist/lib/plugins/api-catalog/Catalog.js.map +1 -1
  29. package/dist/lib/plugins/api-catalog/index.js +1 -1
  30. package/dist/lib/plugins/api-catalog/index.js.map +1 -1
  31. package/dist/lib/plugins/markdown/MdxPage.js +1 -1
  32. package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
  33. package/dist/lib/plugins/openapi/OperationList.d.ts +1 -1
  34. package/dist/lib/plugins/openapi/OperationList.js +5 -1
  35. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  36. package/dist/lib/plugins/openapi/OperationListItem.d.ts +1 -1
  37. package/dist/lib/plugins/openapi/OperationListItem.js +6 -3
  38. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  39. package/dist/lib/plugins/openapi/ParameterList.d.ts +2 -1
  40. package/dist/lib/plugins/openapi/ParameterList.js +3 -2
  41. package/dist/lib/plugins/openapi/ParameterList.js.map +1 -1
  42. package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js +3 -1
  43. package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js.map +1 -1
  44. package/dist/lib/plugins/openapi/Sidecar.js +1 -1
  45. package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
  46. package/dist/lib/plugins/openapi/graphql/gql.d.ts +1 -1
  47. package/dist/lib/plugins/openapi/graphql/gql.js +1 -1
  48. package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
  49. package/dist/lib/plugins/openapi/graphql/graphql.d.ts +1 -0
  50. package/dist/lib/plugins/openapi/graphql/graphql.js +2 -0
  51. package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
  52. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.d.ts +2 -2
  53. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js +1 -5
  54. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js.map +1 -1
  55. package/dist/lib/plugins/openapi/playground/Headers.js +1 -1
  56. package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
  57. package/dist/lib/plugins/openapi/playground/IdentityDialog.d.ts +11 -0
  58. package/dist/lib/plugins/openapi/playground/IdentityDialog.js +14 -0
  59. package/dist/lib/plugins/openapi/playground/IdentityDialog.js.map +1 -0
  60. package/dist/lib/plugins/openapi/playground/IdentitySelector.d.ts +7 -0
  61. package/dist/lib/plugins/openapi/playground/IdentitySelector.js +10 -0
  62. package/dist/lib/plugins/openapi/playground/IdentitySelector.js.map +1 -0
  63. package/dist/lib/plugins/openapi/playground/PathParams.d.ts +3 -2
  64. package/dist/lib/plugins/openapi/playground/PathParams.js +3 -2
  65. package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -1
  66. package/dist/lib/plugins/openapi/playground/Playground.d.ts +13 -2
  67. package/dist/lib/plugins/openapi/playground/Playground.js +80 -26
  68. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  69. package/dist/lib/plugins/openapi/playground/QueryParams.js +1 -1
  70. package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
  71. package/dist/lib/plugins/openapi/playground/RequestLoginDialog.d.ts +7 -0
  72. package/dist/lib/plugins/openapi/playground/RequestLoginDialog.js +8 -0
  73. package/dist/lib/plugins/openapi/playground/RequestLoginDialog.js.map +1 -0
  74. package/dist/lib/plugins/openapi/playground/rememberedIdentity.d.ts +17 -0
  75. package/dist/lib/plugins/openapi/playground/rememberedIdentity.js +11 -0
  76. package/dist/lib/plugins/openapi/playground/rememberedIdentity.js.map +1 -0
  77. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +19 -13
  78. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js.map +1 -1
  79. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.d.ts +6 -4
  80. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js +4 -3
  81. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js.map +1 -1
  82. package/dist/lib/plugins/search-pagefind/PagefindSearch.d.ts +6 -0
  83. package/dist/lib/plugins/search-pagefind/PagefindSearch.js +66 -0
  84. package/dist/lib/plugins/search-pagefind/PagefindSearch.js.map +1 -0
  85. package/dist/lib/plugins/search-pagefind/ResultList.d.ts +8 -0
  86. package/dist/lib/plugins/search-pagefind/ResultList.js +31 -0
  87. package/dist/lib/plugins/search-pagefind/ResultList.js.map +1 -0
  88. package/dist/lib/plugins/search-pagefind/get-results.d.ts +3 -0
  89. package/dist/lib/plugins/search-pagefind/get-results.js +37 -0
  90. package/dist/lib/plugins/search-pagefind/get-results.js.map +1 -0
  91. package/dist/lib/plugins/search-pagefind/index.d.ts +8 -0
  92. package/dist/lib/plugins/search-pagefind/index.js +9 -0
  93. package/dist/lib/plugins/search-pagefind/index.js.map +1 -0
  94. package/dist/lib/plugins/search-pagefind/types.d.ts +85 -0
  95. package/dist/lib/plugins/search-pagefind/types.js +2 -0
  96. package/dist/lib/plugins/search-pagefind/types.js.map +1 -0
  97. package/dist/lib/ui/Checkbox.d.ts +2 -8
  98. package/dist/lib/ui/Checkbox.js +1 -13
  99. package/dist/lib/ui/Checkbox.js.map +1 -1
  100. package/dist/lib/ui/Command.d.ts +13 -7
  101. package/dist/lib/ui/Command.js +2 -2
  102. package/dist/lib/ui/Command.js.map +1 -1
  103. package/dist/lib/ui/Select.js +1 -1
  104. package/dist/lib/ui/Select.js.map +1 -1
  105. package/dist/lib/ui/SyntaxHighlight.d.ts +2 -1
  106. package/dist/lib/ui/SyntaxHighlight.js +19 -15
  107. package/dist/lib/ui/SyntaxHighlight.js.map +1 -1
  108. package/dist/lib/util/MdxComponents.d.ts +1 -1
  109. package/dist/lib/util/MdxComponents.js +2 -2
  110. package/dist/lib/util/MdxComponents.js.map +1 -1
  111. package/dist/lib/util/useScrollToAnchor.js +6 -8
  112. package/dist/lib/util/useScrollToAnchor.js.map +1 -1
  113. package/dist/vite/build.js +4 -0
  114. package/dist/vite/build.js.map +1 -1
  115. package/dist/vite/config.js +7 -2
  116. package/dist/vite/config.js.map +1 -1
  117. package/dist/vite/dev-server.js +8 -0
  118. package/dist/vite/dev-server.js.map +1 -1
  119. package/dist/vite/pagefind.d.ts +4 -0
  120. package/dist/vite/pagefind.js +15 -0
  121. package/dist/vite/pagefind.js.map +1 -0
  122. package/dist/vite/plugin-component.js +4 -0
  123. package/dist/vite/plugin-component.js.map +1 -1
  124. package/dist/vite/plugin-search.js +4 -0
  125. package/dist/vite/plugin-search.js.map +1 -1
  126. package/dist/vite/prerender/prerender.js +1 -1
  127. package/dist/vite/prerender/prerender.js.map +1 -1
  128. package/dist/vite/sitemap.js +2 -1
  129. package/dist/vite/sitemap.js.map +1 -1
  130. package/lib/{AuthenticationPlugin-CiO1FM6Q.js → AuthenticationPlugin-4ip08maU.js} +3 -3
  131. package/lib/{AuthenticationPlugin-CiO1FM6Q.js.map → AuthenticationPlugin-4ip08maU.js.map} +1 -1
  132. package/lib/Callout-B_sEhkYd.js +211 -0
  133. package/lib/Callout-B_sEhkYd.js.map +1 -0
  134. package/lib/{Dialog-DIKGQxQc.js → Dialog-sbgekbjb.js} +47 -32
  135. package/lib/{Dialog-DIKGQxQc.js.map → Dialog-sbgekbjb.js.map} +1 -1
  136. package/lib/{Markdown-DePfm7oQ.js → Markdown-DZXjQjpH.js} +4099 -3848
  137. package/lib/Markdown-DZXjQjpH.js.map +1 -0
  138. package/lib/MdxPage-52vRwa_7.js +200 -0
  139. package/lib/MdxPage-52vRwa_7.js.map +1 -0
  140. package/lib/{OasProvider-SzD9mHJc.js → OasProvider-CR2nG1Eg.js} +4 -4
  141. package/lib/{OasProvider-SzD9mHJc.js.map → OasProvider-CR2nG1Eg.js.map} +1 -1
  142. package/lib/{OperationList-DDs9NblY.js → OperationList-DndcCJUG.js} +2069 -1983
  143. package/lib/OperationList-DndcCJUG.js.map +1 -0
  144. package/lib/{Select-Dqtcn53H.js → Select-FAYHOYTy.js} +4 -4
  145. package/lib/{Select-Dqtcn53H.js.map → Select-FAYHOYTy.js.map} +1 -1
  146. package/lib/{SlotletProvider-DdtIOUi6.js → SlotletProvider-TydSHROc.js} +4 -4
  147. package/lib/{SlotletProvider-DdtIOUi6.js.map → SlotletProvider-TydSHROc.js.map} +1 -1
  148. package/lib/{chunk-IR6S3I6Y-D_3UmFIn.js → chunk-HA7DTUK3-ZGg2W6yV.js} +277 -277
  149. package/lib/chunk-HA7DTUK3-ZGg2W6yV.js.map +1 -0
  150. package/lib/hook-CfCFKZ-2.js +350 -0
  151. package/lib/hook-CfCFKZ-2.js.map +1 -0
  152. package/lib/index-DK7IuUyR.js +2201 -0
  153. package/lib/index-DK7IuUyR.js.map +1 -0
  154. package/lib/{index.esm-CQHE3GEU.js → index.esm-CltAN0Tf.js} +259 -239
  155. package/lib/index.esm-CltAN0Tf.js.map +1 -0
  156. package/lib/{mutation-EclmI0is.js → mutation-B81DztCT.js} +2 -2
  157. package/lib/{mutation-EclmI0is.js.map → mutation-B81DztCT.js.map} +1 -1
  158. package/lib/objectEntries-BS7aAgOm.js +12 -0
  159. package/lib/objectEntries-BS7aAgOm.js.map +1 -0
  160. package/lib/ui/Checkbox.js +15 -25
  161. package/lib/ui/Checkbox.js.map +1 -1
  162. package/lib/ui/Command.js +96 -70
  163. package/lib/ui/Command.js.map +1 -1
  164. package/lib/ui/Select.js +1 -1
  165. package/lib/ui/Select.js.map +1 -1
  166. package/lib/ui/SyntaxHighlight.js +483 -502
  167. package/lib/ui/SyntaxHighlight.js.map +1 -1
  168. package/lib/{useExposedProps-RIvey2Oy.js → useExposedProps-BslIn-FE.js} +2 -2
  169. package/lib/{useExposedProps-RIvey2Oy.js.map → useExposedProps-BslIn-FE.js.map} +1 -1
  170. package/lib/useQuery-CQUwWR9i.js +1137 -0
  171. package/lib/useQuery-CQUwWR9i.js.map +1 -0
  172. package/lib/zudoku.auth-auth0.js +1 -1
  173. package/lib/zudoku.auth-clerk.js +29 -29
  174. package/lib/zudoku.auth-clerk.js.map +1 -1
  175. package/lib/zudoku.auth-openid.js +3 -3
  176. package/lib/zudoku.components.js +146 -149
  177. package/lib/zudoku.components.js.map +1 -1
  178. package/lib/zudoku.hooks.js +1 -1
  179. package/lib/zudoku.plugin-api-catalog.js +87 -71
  180. package/lib/zudoku.plugin-api-catalog.js.map +1 -1
  181. package/lib/zudoku.plugin-api-keys.js +16 -15
  182. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  183. package/lib/zudoku.plugin-custom-pages.js +2 -2
  184. package/lib/zudoku.plugin-markdown.js +1 -1
  185. package/lib/zudoku.plugin-openapi.js +3 -3
  186. package/lib/zudoku.plugin-redirect.js +1 -1
  187. package/lib/zudoku.plugin-search-pagefind.js +204 -0
  188. package/lib/zudoku.plugin-search-pagefind.js.map +1 -0
  189. package/package.json +10 -5
  190. package/src/lib/authentication/hook.ts +12 -1
  191. package/src/lib/authentication/providers/clerk.tsx +10 -6
  192. package/src/lib/components/AnchorLink.tsx +7 -7
  193. package/src/lib/components/Banner.tsx +1 -0
  194. package/src/lib/components/Heading.tsx +1 -1
  195. package/src/lib/components/Layout.tsx +1 -0
  196. package/src/lib/components/navigation/SidebarItem.tsx +8 -23
  197. package/src/lib/core/RouteGuard.tsx +2 -1
  198. package/src/lib/core/ZudokuContext.ts +4 -0
  199. package/src/lib/plugins/api-catalog/Catalog.tsx +23 -7
  200. package/src/lib/plugins/api-catalog/index.tsx +1 -0
  201. package/src/lib/plugins/markdown/MdxPage.tsx +5 -1
  202. package/src/lib/plugins/openapi/OperationList.tsx +83 -31
  203. package/src/lib/plugins/openapi/OperationListItem.tsx +107 -86
  204. package/src/lib/plugins/openapi/ParameterList.tsx +4 -0
  205. package/src/lib/plugins/openapi/PlaygroundDialogWrapper.tsx +7 -0
  206. package/src/lib/plugins/openapi/Sidecar.tsx +1 -0
  207. package/src/lib/plugins/openapi/graphql/gql.ts +3 -3
  208. package/src/lib/plugins/openapi/graphql/graphql.ts +3 -0
  209. package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +30 -32
  210. package/src/lib/plugins/openapi/playground/Headers.tsx +0 -1
  211. package/src/lib/plugins/openapi/playground/IdentityDialog.tsx +74 -0
  212. package/src/lib/plugins/openapi/playground/IdentitySelector.tsx +54 -0
  213. package/src/lib/plugins/openapi/playground/PathParams.tsx +8 -2
  214. package/src/lib/plugins/openapi/playground/Playground.tsx +175 -88
  215. package/src/lib/plugins/openapi/playground/QueryParams.tsx +0 -1
  216. package/src/lib/plugins/openapi/playground/RequestLoginDialog.tsx +51 -0
  217. package/src/lib/plugins/openapi/playground/rememberedIdentity.ts +26 -0
  218. package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +24 -4
  219. package/src/lib/plugins/openapi/playground/result-panel/ResultPanel.tsx +66 -45
  220. package/src/lib/plugins/search-pagefind/PagefindSearch.tsx +135 -0
  221. package/src/lib/plugins/search-pagefind/ResultList.tsx +104 -0
  222. package/src/lib/plugins/search-pagefind/get-results.tsx +54 -0
  223. package/src/lib/plugins/search-pagefind/index.tsx +21 -0
  224. package/src/lib/plugins/search-pagefind/types.ts +118 -0
  225. package/src/lib/ui/Checkbox.tsx +8 -24
  226. package/src/lib/ui/Command.tsx +25 -3
  227. package/src/lib/ui/Select.tsx +1 -1
  228. package/src/lib/ui/SyntaxHighlight.tsx +94 -96
  229. package/src/lib/util/MdxComponents.tsx +2 -2
  230. package/src/lib/util/useScrollToAnchor.ts +8 -8
  231. package/lib/Markdown-DePfm7oQ.js.map +0 -1
  232. package/lib/MdxPage-DZTt9ld7.js +0 -193
  233. package/lib/MdxPage-DZTt9ld7.js.map +0 -1
  234. package/lib/OperationList-DDs9NblY.js.map +0 -1
  235. package/lib/chunk-IR6S3I6Y-D_3UmFIn.js.map +0 -1
  236. package/lib/hook-CN__aZIt.js +0 -1464
  237. package/lib/hook-CN__aZIt.js.map +0 -1
  238. package/lib/index-CibzSNks.js +0 -2100
  239. package/lib/index-CibzSNks.js.map +0 -1
  240. package/lib/index.esm-CQHE3GEU.js.map +0 -1
  241. package/lib/objectEntries-yMIkr2mI.js +0 -5
  242. package/lib/objectEntries-yMIkr2mI.js.map +0 -1
  243. package/lib/useScrollToAnchor-C7ilRSts.js +0 -290
  244. package/lib/useScrollToAnchor-C7ilRSts.js.map +0 -1
@@ -1,7 +1,13 @@
1
- import { ResultOf } from "@graphql-typed-document-node/core";
1
+ import { type ResultOf } from "@graphql-typed-document-node/core";
2
2
  import { useSuspenseQuery } from "@tanstack/react-query";
3
3
  import { Helmet } from "@zudoku/react-helmet-async";
4
+ import { ChevronsDownUpIcon, ChevronsUpDownIcon } from "lucide-react";
4
5
  import { useNavigate } from "react-router";
6
+ import {
7
+ Collapsible,
8
+ CollapsibleContent,
9
+ CollapsibleTrigger,
10
+ } from "zudoku/ui/Collapsible.js";
5
11
  import {
6
12
  Select,
7
13
  SelectContent,
@@ -31,6 +37,7 @@ export const OperationsFragment = graphql(/* GraphQL */ `
31
37
  operationId
32
38
  contentTypes
33
39
  path
40
+ deprecated
34
41
  parameters {
35
42
  name
36
43
  in
@@ -152,45 +159,90 @@ export const OperationList = ({
152
159
  ? sanitizeMarkdownForMetatag(description)
153
160
  : undefined;
154
161
 
162
+ const showVersions = Object.entries(versions).length > 1;
163
+
155
164
  return (
156
- <div className="pt-[--padding-content-top]">
165
+ <div
166
+ className="pt-[--padding-content-top]"
167
+ data-pagefind-filter="section:openapi"
168
+ data-pagefind-meta="section:openapi"
169
+ >
157
170
  <Helmet>
158
171
  <title>{title}</title>
159
172
  {metaDescription && (
160
173
  <meta name="description" content={metaDescription} />
161
174
  )}
162
175
  </Helmet>
163
- <div
164
- className={cn(ProseClasses, "mb-16 max-w-full prose-img:max-w-prose")}
165
- >
166
- <div className="flex">
167
- <div className="flex-1">
168
- <CategoryHeading>Overview</CategoryHeading>
169
- <Heading level={1} id="description" registerSidebarAnchor>
170
- {title}
171
- </Heading>
172
- </div>
173
- <div>
174
- {Object.entries(versions).length > 1 && (
175
- <Select
176
- onValueChange={(version) => navigate(versions[version]!)}
177
- defaultValue={version}
176
+ <div className="mb-8">
177
+ <Collapsible className="w-full">
178
+ <div className="flex flex-col gap-y-4 sm:flex-row justify-around items-start sm:items-end">
179
+ <div className="flex-1">
180
+ <CategoryHeading>{title}</CategoryHeading>
181
+ <Heading
182
+ level={1}
183
+ id="description"
184
+ registerSidebarAnchor
185
+ className="mb-0"
178
186
  >
179
- <SelectTrigger className="w-[180px]">
180
- <SelectValue placeholder="Select version" />
181
- </SelectTrigger>
182
- <SelectContent>
183
- {Object.entries(versions).map(([version]) => (
184
- <SelectItem key={version} value={version}>
185
- {version}
186
- </SelectItem>
187
- ))}
188
- </SelectContent>
189
- </Select>
190
- )}
187
+ {tag}
188
+ {showVersions && (
189
+ <span className="text-xl text-muted-foreground ml-1.5">
190
+ {" "}
191
+ ({version})
192
+ </span>
193
+ )}
194
+ </Heading>
195
+ </div>
196
+ <div className="flex flex-col gap-4 sm:items-end">
197
+ {showVersions && (
198
+ <Select
199
+ onValueChange={(version) => navigate(versions[version]!)}
200
+ defaultValue={version}
201
+ >
202
+ <SelectTrigger className="w-[180px]">
203
+ <SelectValue placeholder="Select version" />
204
+ </SelectTrigger>
205
+ <SelectContent>
206
+ {Object.entries(versions).map(([version]) => (
207
+ <SelectItem key={version} value={version}>
208
+ {version}
209
+ </SelectItem>
210
+ ))}
211
+ </SelectContent>
212
+ </Select>
213
+ )}
214
+ {schema.description && (
215
+ <CollapsibleTrigger className="flex items-center gap-1 text-sm font-medium text-muted-foreground group">
216
+ <span>Schema description</span>
217
+
218
+ <ChevronsUpDownIcon
219
+ className="group-data-[state=open]:hidden translate-y-px"
220
+ size={14}
221
+ />
222
+ <ChevronsDownUpIcon
223
+ className="group-data-[state=closed]:hidden translate-y-px"
224
+ size={13}
225
+ />
226
+ </CollapsibleTrigger>
227
+ )}
228
+ </div>
191
229
  </div>
192
- </div>
193
- <Markdown content={schema.description ?? ""} />
230
+ {schema.description && (
231
+ <CollapsibleContent className="CollapsibleContent">
232
+ <div
233
+ className={cn(
234
+ ProseClasses,
235
+ "pt-4 max-w-full prose-img:max-w-prose",
236
+ )}
237
+ >
238
+ <Markdown
239
+ className="border rounded bg-muted/25 border-border px-2.5 md:px-4"
240
+ content={schema.description}
241
+ />
242
+ </div>
243
+ </CollapsibleContent>
244
+ )}
245
+ </Collapsible>
194
246
  </div>
195
247
  <hr />
196
248
  <div className="my-4 flex items-center justify-end gap-4">
@@ -1,13 +1,16 @@
1
+ import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
1
2
  import { useRef, useState } from "react";
3
+ import { Badge } from "zudoku/ui/Badge.js";
2
4
  import { Heading } from "../../components/Heading.js";
3
5
  import { Markdown, ProseClasses } from "../../components/Markdown.js";
4
6
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/Tabs.js";
7
+ import { cn } from "../../util/cn.js";
5
8
  import { groupBy } from "../../util/groupBy.js";
6
9
  import { renderIf } from "../../util/renderIf.js";
7
10
  import { OperationsFragment } from "./OperationList.js";
8
11
  import { ParameterList } from "./ParameterList.js";
9
12
  import { Sidecar } from "./Sidecar.js";
10
- import { FragmentType, useFragment } from "./graphql/index.js";
13
+ import { type FragmentType, useFragment } from "./graphql/index.js";
11
14
  import { SchemaView } from "./schema/SchemaView.js";
12
15
  import { methodForColor } from "./util/methodToColor.js";
13
16
 
@@ -32,11 +35,19 @@ export const OperationListItem = ({
32
35
  const [selectedResponse, setSelectedResponse] = useState(first?.statusCode);
33
36
 
34
37
  return (
35
- <div
36
- key={operation.operationId}
37
- className="grid grid-cols-1 lg:grid-cols-[minmax(0,4fr)_minmax(0,3fr)] gap-8 items-start border-b-2 mb-16 pb-16"
38
- >
39
- <div className="flex flex-col gap-4">
38
+ <div className="border-b-2 mb-16 pb-16">
39
+ {operation.deprecated && (
40
+ <Badge variant="muted" className="text-xs mb-4">
41
+ deprecated
42
+ </Badge>
43
+ )}
44
+ <div
45
+ key={operation.operationId}
46
+ className={cn(
47
+ "grid grid-cols-1 lg:grid-cols-[minmax(0,4fr)_minmax(0,3fr)] gap-x-8 gap-y-4 items-start",
48
+ operation.deprecated && "opacity-50 transition hover:opacity-100",
49
+ )}
50
+ >
40
51
  <Heading
41
52
  level={2}
42
53
  id={operation.slug}
@@ -45,7 +56,7 @@ export const OperationListItem = ({
45
56
  >
46
57
  {operation.summary}
47
58
  </Heading>
48
- <div className="text-sm flex gap-2 font-mono">
59
+ <div className="text-sm flex gap-2 font-mono col-span-full">
49
60
  <span className={methodForColor(operation.method)}>
50
61
  {operation.method.toUpperCase()}
51
62
  </span>
@@ -72,91 +83,101 @@ export const OperationListItem = ({
72
83
  </div>
73
84
  </div>
74
85
  </div>
75
- {operation.description && (
76
- <Markdown
77
- className={`${ProseClasses} max-w-full prose-img:max-w-prose`}
78
- content={operation.description}
79
- />
80
- )}
81
- {operation.parameters && operation.parameters.length > 0 && (
82
- <>
83
- {PARAM_GROUPS.flatMap((group) =>
84
- groupedParameters[group]?.length ? (
85
- <ParameterList
86
- key={group}
87
- id={operation.slug}
88
- parameters={groupedParameters[group]}
89
- group={group}
90
- />
91
- ) : (
92
- []
93
- ),
94
- )}
95
- </>
96
- )}
97
- {renderIf(operation.requestBody?.content?.at(0)?.schema, (schema) => (
98
- <div className="mt-4 flex flex-col gap-4">
99
- <Heading
100
- level={3}
101
- className="capitalize"
102
- id={`${operation.slug}/request-body`}
103
- >
104
- Request Body
105
- </Heading>
106
- <SchemaView schema={schema} />
107
- </div>
108
- ))}
109
- {operation.responses.length > 0 && (
110
- <>
111
- <Heading
112
- level={3}
113
- className="capitalize mt-8 pt-8 border-t"
114
- id={`${operation.slug}/responses`}
115
- >
116
- Responses
117
- </Heading>
118
- <Tabs
119
- onValueChange={(value) => setSelectedResponse(value)}
120
- value={selectedResponse}
121
- >
122
- {operation.responses.length > 1 && (
123
- <TabsList>
86
+
87
+ <div className="flex flex-col gap-4">
88
+ {operation.description && (
89
+ <Markdown
90
+ className={`${ProseClasses} max-w-full prose-img:max-w-prose`}
91
+ content={operation.description}
92
+ />
93
+ )}
94
+ {operation.parameters && operation.parameters.length > 0 && (
95
+ <>
96
+ {PARAM_GROUPS.flatMap((group) =>
97
+ groupedParameters[group]?.length ? (
98
+ <ParameterList
99
+ key={group}
100
+ summary={operation.summary ?? undefined}
101
+ id={operation.slug}
102
+ parameters={groupedParameters[group]}
103
+ group={group}
104
+ />
105
+ ) : (
106
+ []
107
+ ),
108
+ )}
109
+ </>
110
+ )}
111
+ {renderIf(operation.requestBody?.content?.at(0)?.schema, (schema) => (
112
+ <div className="mt-4 flex flex-col gap-4">
113
+ <Heading
114
+ level={3}
115
+ className="capitalize"
116
+ id={`${operation.slug}/request-body`}
117
+ >
118
+ {operation.summary && (
119
+ <VisuallyHidden>{operation.summary} &rsaquo; </VisuallyHidden>
120
+ )}
121
+ Request Body
122
+ </Heading>
123
+ <SchemaView schema={schema} />
124
+ </div>
125
+ ))}
126
+ {operation.responses.length > 0 && (
127
+ <>
128
+ <Heading
129
+ level={3}
130
+ className="capitalize mt-8 pt-8 border-t"
131
+ id={`${operation.slug}/responses`}
132
+ >
133
+ {operation.summary && (
134
+ <VisuallyHidden>{operation.summary} &rsaquo; </VisuallyHidden>
135
+ )}
136
+ Responses
137
+ </Heading>
138
+ <Tabs
139
+ onValueChange={(value) => setSelectedResponse(value)}
140
+ value={selectedResponse}
141
+ >
142
+ {operation.responses.length > 1 && (
143
+ <TabsList>
144
+ {operation.responses.map((response) => (
145
+ <TabsTrigger
146
+ value={response.statusCode}
147
+ key={response.statusCode}
148
+ title={response.description ?? undefined}
149
+ >
150
+ {response.statusCode}
151
+ </TabsTrigger>
152
+ ))}
153
+ </TabsList>
154
+ )}
155
+ <ul className="list-none m-0 px-0">
124
156
  {operation.responses.map((response) => (
125
- <TabsTrigger
157
+ <TabsContent
126
158
  value={response.statusCode}
127
159
  key={response.statusCode}
128
- title={response.description ?? undefined}
129
160
  >
130
- {response.statusCode}
131
- </TabsTrigger>
161
+ <SchemaView
162
+ schema={
163
+ response.content?.find((content) => content.schema)
164
+ ?.schema
165
+ }
166
+ />
167
+ </TabsContent>
132
168
  ))}
133
- </TabsList>
134
- )}
135
- <ul className="list-none m-0 px-0">
136
- {operation.responses.map((response) => (
137
- <TabsContent
138
- value={response.statusCode}
139
- key={response.statusCode}
140
- >
141
- <SchemaView
142
- schema={
143
- response.content?.find((content) => content.schema)
144
- ?.schema
145
- }
146
- />
147
- </TabsContent>
148
- ))}
149
- </ul>
150
- </Tabs>
151
- </>
152
- )}
153
- </div>
169
+ </ul>
170
+ </Tabs>
171
+ </>
172
+ )}
173
+ </div>
154
174
 
155
- <Sidecar
156
- selectedResponse={selectedResponse}
157
- onSelectResponse={setSelectedResponse}
158
- operation={operation}
159
- />
175
+ <Sidecar
176
+ selectedResponse={selectedResponse}
177
+ onSelectResponse={setSelectedResponse}
178
+ operation={operation}
179
+ />
180
+ </div>
160
181
  </div>
161
182
  );
162
183
  };
@@ -1,3 +1,4 @@
1
+ import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
1
2
  import { Heading } from "../../components/Heading.js";
2
3
  import { Card } from "../../ui/Card.js";
3
4
  import type { ParameterGroup } from "./OperationListItem.js";
@@ -7,16 +8,19 @@ import {
7
8
  } from "./ParameterListItem.js";
8
9
 
9
10
  export const ParameterList = ({
11
+ summary,
10
12
  group,
11
13
  parameters,
12
14
  id,
13
15
  }: {
16
+ summary?: string;
14
17
  group: ParameterGroup;
15
18
  parameters: ParameterListItemResult[];
16
19
  id: string;
17
20
  }) => (
18
21
  <>
19
22
  <Heading level={3} id={`${id}/${group}-parameters`} className="capitalize">
23
+ {summary && <VisuallyHidden>{summary} &rsaquo; </VisuallyHidden>}
20
24
  {group === "header" ? "Headers" : `${group} Parameters`}
21
25
  </Heading>
22
26
  <Card>
@@ -1,3 +1,4 @@
1
+ import { useAuth } from "zudoku/components";
1
2
  import type { OperationListItemResult } from "./OperationList.js";
2
3
  import { PlaygroundDialog } from "./playground/PlaygroundDialog.js";
3
4
  import { Content } from "./SidecarExamples.js";
@@ -13,6 +14,9 @@ export const PlaygroundDialogWrapper = ({
13
14
  operation: OperationListItemResult;
14
15
  examples?: Content;
15
16
  }) => {
17
+ const { isAuthEnabled, login, signup, isPending, isAuthenticated } =
18
+ useAuth();
19
+
16
20
  const headers = operation.parameters
17
21
  ?.filter((p) => p.in === "header")
18
22
  .sort((a, b) => (a.required && !b.required ? -1 : 1))
@@ -49,6 +53,9 @@ export const PlaygroundDialogWrapper = ({
49
53
  queryParams={queryParams}
50
54
  pathParams={pathParams}
51
55
  examples={examples}
56
+ requiresLogin={isAuthEnabled && !isAuthenticated && !isPending}
57
+ onLogin={() => login()}
58
+ onSignUp={() => signup()}
52
59
  />
53
60
  );
54
61
  };
@@ -175,6 +175,7 @@ export const Sidecar = ({
175
175
  <aside
176
176
  ref={ref}
177
177
  className="flex flex-col overflow-hidden sticky top-[--scroll-padding] gap-4"
178
+ data-pagefind-ignore="all"
178
179
  >
179
180
  <SidecarBox.Root>
180
181
  <SidecarBox.Head className="flex justify-between items-center flex-nowrap py-2.5 gap-2 text-xs">
@@ -14,7 +14,7 @@ import * as types from "./graphql.js";
14
14
  */
15
15
  type Documents = {
16
16
  "\n query ServersQuery($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n servers {\n url\n }\n }\n }\n": typeof types.ServersQueryDocument;
17
- "\n fragment OperationsFragment on OperationItem {\n slug\n summary\n method\n description\n operationId\n contentTypes\n path\n parameters {\n name\n in\n description\n required\n schema\n style\n examples {\n name\n description\n externalValue\n value\n summary\n }\n }\n requestBody {\n content {\n mediaType\n encoding {\n name\n }\n examples {\n name\n description\n externalValue\n value\n summary\n }\n schema\n }\n description\n required\n }\n responses {\n statusCode\n links\n description\n content {\n examples {\n name\n description\n externalValue\n value\n summary\n }\n mediaType\n encoding {\n name\n }\n schema\n }\n }\n }\n": typeof types.OperationsFragmentFragmentDoc;
17
+ "\n fragment OperationsFragment on OperationItem {\n slug\n summary\n method\n description\n operationId\n contentTypes\n path\n deprecated\n parameters {\n name\n in\n description\n required\n schema\n style\n examples {\n name\n description\n externalValue\n value\n summary\n }\n }\n requestBody {\n content {\n mediaType\n encoding {\n name\n }\n examples {\n name\n description\n externalValue\n value\n summary\n }\n schema\n }\n description\n required\n }\n responses {\n statusCode\n links\n description\n content {\n examples {\n name\n description\n externalValue\n value\n summary\n }\n mediaType\n encoding {\n name\n }\n schema\n }\n }\n }\n": typeof types.OperationsFragmentFragmentDoc;
18
18
  "\n query AllOperations(\n $input: JSON!\n $type: SchemaType!\n $tag: String\n $untagged: Boolean\n ) {\n schema(input: $input, type: $type) {\n servers {\n url\n }\n description\n summary\n title\n url\n version\n tags(name: $tag) {\n name\n description\n }\n operations(tag: $tag, untagged: $untagged) {\n slug\n ...OperationsFragment\n }\n }\n }\n": typeof types.AllOperationsDocument;
19
19
  "\n query getServerQuery($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n servers {\n url\n }\n }\n }\n": typeof types.GetServerQueryDocument;
20
20
  "\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n tags {\n name\n }\n }\n }\n": typeof types.GetCategoriesDocument;
@@ -23,7 +23,7 @@ type Documents = {
23
23
  const documents: Documents = {
24
24
  "\n query ServersQuery($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n servers {\n url\n }\n }\n }\n":
25
25
  types.ServersQueryDocument,
26
- "\n fragment OperationsFragment on OperationItem {\n slug\n summary\n method\n description\n operationId\n contentTypes\n path\n parameters {\n name\n in\n description\n required\n schema\n style\n examples {\n name\n description\n externalValue\n value\n summary\n }\n }\n requestBody {\n content {\n mediaType\n encoding {\n name\n }\n examples {\n name\n description\n externalValue\n value\n summary\n }\n schema\n }\n description\n required\n }\n responses {\n statusCode\n links\n description\n content {\n examples {\n name\n description\n externalValue\n value\n summary\n }\n mediaType\n encoding {\n name\n }\n schema\n }\n }\n }\n":
26
+ "\n fragment OperationsFragment on OperationItem {\n slug\n summary\n method\n description\n operationId\n contentTypes\n path\n deprecated\n parameters {\n name\n in\n description\n required\n schema\n style\n examples {\n name\n description\n externalValue\n value\n summary\n }\n }\n requestBody {\n content {\n mediaType\n encoding {\n name\n }\n examples {\n name\n description\n externalValue\n value\n summary\n }\n schema\n }\n description\n required\n }\n responses {\n statusCode\n links\n description\n content {\n examples {\n name\n description\n externalValue\n value\n summary\n }\n mediaType\n encoding {\n name\n }\n schema\n }\n }\n }\n":
27
27
  types.OperationsFragmentFragmentDoc,
28
28
  "\n query AllOperations(\n $input: JSON!\n $type: SchemaType!\n $tag: String\n $untagged: Boolean\n ) {\n schema(input: $input, type: $type) {\n servers {\n url\n }\n description\n summary\n title\n url\n version\n tags(name: $tag) {\n name\n description\n }\n operations(tag: $tag, untagged: $untagged) {\n slug\n ...OperationsFragment\n }\n }\n }\n":
29
29
  types.AllOperationsDocument,
@@ -45,7 +45,7 @@ export function graphql(
45
45
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
46
46
  */
47
47
  export function graphql(
48
- source: "\n fragment OperationsFragment on OperationItem {\n slug\n summary\n method\n description\n operationId\n contentTypes\n path\n parameters {\n name\n in\n description\n required\n schema\n style\n examples {\n name\n description\n externalValue\n value\n summary\n }\n }\n requestBody {\n content {\n mediaType\n encoding {\n name\n }\n examples {\n name\n description\n externalValue\n value\n summary\n }\n schema\n }\n description\n required\n }\n responses {\n statusCode\n links\n description\n content {\n examples {\n name\n description\n externalValue\n value\n summary\n }\n mediaType\n encoding {\n name\n }\n schema\n }\n }\n }\n",
48
+ source: "\n fragment OperationsFragment on OperationItem {\n slug\n summary\n method\n description\n operationId\n contentTypes\n path\n deprecated\n parameters {\n name\n in\n description\n required\n schema\n style\n examples {\n name\n description\n externalValue\n value\n summary\n }\n }\n requestBody {\n content {\n mediaType\n encoding {\n name\n }\n examples {\n name\n description\n externalValue\n value\n summary\n }\n schema\n }\n description\n required\n }\n responses {\n statusCode\n links\n description\n content {\n examples {\n name\n description\n externalValue\n value\n summary\n }\n mediaType\n encoding {\n name\n }\n schema\n }\n }\n }\n",
49
49
  ): typeof import("./graphql.js").OperationsFragmentFragmentDoc;
50
50
  /**
51
51
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
@@ -197,6 +197,7 @@ export type OperationsFragmentFragment = {
197
197
  operationId?: string | null;
198
198
  contentTypes: Array<string>;
199
199
  path: string;
200
+ deprecated?: boolean | null;
200
201
  parameters?: Array<{
201
202
  __typename?: "ParameterItem";
202
203
  name: string;
@@ -374,6 +375,7 @@ export const OperationsFragmentFragmentDoc = new TypedDocumentString(
374
375
  operationId
375
376
  contentTypes
376
377
  path
378
+ deprecated
377
379
  parameters {
378
380
  name
379
381
  in
@@ -472,6 +474,7 @@ export const AllOperationsDocument = new TypedDocumentString(`
472
474
  operationId
473
475
  contentTypes
474
476
  path
477
+ deprecated
475
478
  parameters {
476
479
  name
477
480
  in
@@ -8,46 +8,44 @@ import {
8
8
  DropdownMenuSeparator,
9
9
  DropdownMenuTrigger,
10
10
  } from "zudoku/ui/DropdownMenu.js";
11
- import { Content, Example } from "../SidecarExamples.js";
11
+ import type { Content, Example } from "../SidecarExamples.js";
12
12
 
13
13
  const ExamplesDropdown = ({
14
14
  examples,
15
15
  onSelect,
16
16
  }: {
17
17
  examples: Content;
18
- onSelect: (example: Example) => void;
18
+ onSelect: (example: Example, mediaType: string) => void;
19
19
  }) => {
20
20
  return (
21
- <div className="flex flex-col gap-2 mt-2 items-end">
22
- <DropdownMenu>
23
- <DropdownMenuTrigger asChild>
24
- <Button variant="outline">Use Example</Button>
25
- </DropdownMenuTrigger>
26
- <DropdownMenuContent className="w-56">
27
- {examples.map((example) => {
28
- return (
29
- <div key={example.mediaType}>
30
- <DropdownMenuLabel>{example.mediaType}</DropdownMenuLabel>
31
- <DropdownMenuSeparator />
32
- <DropdownMenuGroup>
33
- {example.examples?.map((example) => {
34
- return (
35
- <DropdownMenuItem
36
- key={example.name}
37
- onSelect={() => onSelect(example)}
38
- className="line-clamp-1"
39
- >
40
- {example.summary ?? example.name}
41
- </DropdownMenuItem>
42
- );
43
- })}
44
- </DropdownMenuGroup>
45
- </div>
46
- );
47
- })}
48
- </DropdownMenuContent>
49
- </DropdownMenu>
50
- </div>
21
+ <DropdownMenu>
22
+ <DropdownMenuTrigger asChild>
23
+ <Button variant="outline">Use Example</Button>
24
+ </DropdownMenuTrigger>
25
+ <DropdownMenuContent className="max-w-72">
26
+ {examples.map((mediaTypeObject) => (
27
+ <div key={mediaTypeObject.mediaType}>
28
+ <DropdownMenuLabel>{mediaTypeObject.mediaType}</DropdownMenuLabel>
29
+ <DropdownMenuSeparator />
30
+ <DropdownMenuGroup>
31
+ {mediaTypeObject.examples?.map((example) => (
32
+ <DropdownMenuItem
33
+ key={example.name}
34
+ onSelect={() => onSelect(example, mediaTypeObject.mediaType)}
35
+ >
36
+ <span
37
+ className="line-clamp-1"
38
+ title={example.summary ?? example.name}
39
+ >
40
+ {example.summary ?? example.name}
41
+ </span>
42
+ </DropdownMenuItem>
43
+ ))}
44
+ </DropdownMenuGroup>
45
+ </div>
46
+ ))}
47
+ </DropdownMenuContent>
48
+ </DropdownMenu>
51
49
  );
52
50
  };
53
51
 
@@ -98,7 +98,6 @@ export const Headers = ({
98
98
  name={`headers.${i}.active`}
99
99
  render={({ field }) => (
100
100
  <Checkbox
101
- variant="outline"
102
101
  id={`headers.${i}.active`}
103
102
  checked={field.value}
104
103
  onCheckedChange={(checked) => {
@@ -0,0 +1,74 @@
1
+ import { useState } from "react";
2
+ import { Button } from "zudoku/ui/Button.js";
3
+ import { Checkbox } from "zudoku/ui/Checkbox.js";
4
+ import {
5
+ Dialog,
6
+ DialogContent,
7
+ DialogDescription,
8
+ DialogFooter,
9
+ DialogTitle,
10
+ } from "zudoku/ui/Dialog.js";
11
+ import { Label } from "zudoku/ui/Label.js";
12
+ import { type ApiIdentity } from "../../../core/ZudokuContext.js";
13
+ import IdentitySelector from "./IdentitySelector.js";
14
+
15
+ const IdentityDialog = ({
16
+ onSubmit,
17
+ identities,
18
+ open,
19
+ onOpenChange,
20
+ }: {
21
+ open: boolean;
22
+ onOpenChange: (open: boolean) => void;
23
+ onSubmit: ({
24
+ rememberedIdentity,
25
+ identity,
26
+ }: {
27
+ rememberedIdentity: boolean;
28
+ identity?: string;
29
+ }) => void;
30
+ identities: ApiIdentity[];
31
+ }) => {
32
+ const [identity, setIdentity] = useState<string | undefined>(undefined);
33
+ const [rememberedIdentity, setRememberedIdentity] = useState<boolean>(false);
34
+
35
+ return (
36
+ <Dialog open={open} onOpenChange={onOpenChange}>
37
+ <DialogContent>
38
+ <DialogTitle>Select an auth identity</DialogTitle>
39
+ <DialogDescription>
40
+ Please select an identity for this request.
41
+ </DialogDescription>
42
+ <div className="max-h-80 overflow-auto">
43
+ <IdentitySelector
44
+ identities={identities}
45
+ setValue={setIdentity}
46
+ value={identity}
47
+ />
48
+ </div>
49
+ <DialogFooter className="flex flex-col gap-2">
50
+ <div className="flex items-center gap-2">
51
+ <Checkbox
52
+ id="remember"
53
+ checked={rememberedIdentity}
54
+ onCheckedChange={(checked) =>
55
+ setRememberedIdentity(
56
+ checked === "indeterminate" ? false : !!checked,
57
+ )
58
+ }
59
+ />
60
+ <Label htmlFor="remember">Remember my choice</Label>
61
+ </div>
62
+
63
+ <Button
64
+ onClick={() => onSubmit({ identity: identity, rememberedIdentity })}
65
+ >
66
+ Send
67
+ </Button>
68
+ </DialogFooter>
69
+ </DialogContent>
70
+ </Dialog>
71
+ );
72
+ };
73
+
74
+ export { IdentityDialog };