zudoku 0.0.2-dev.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 (403) hide show
  1. package/cli.js +1 -0
  2. package/dist/app/DevPortal.d.ts +26 -0
  3. package/dist/app/DevPortal.js +41 -0
  4. package/dist/app/DevPortal.js.map +1 -0
  5. package/dist/app/Heading.d.ts +9 -0
  6. package/dist/app/Heading.js +27 -0
  7. package/dist/app/Heading.js.map +1 -0
  8. package/dist/app/app.d.ts +2 -0
  9. package/dist/app/app.js +69 -0
  10. package/dist/app/app.js.map +1 -0
  11. package/dist/app/authentication/authentication.d.ts +13 -0
  12. package/dist/app/authentication/authentication.js +2 -0
  13. package/dist/app/authentication/authentication.js.map +1 -0
  14. package/dist/app/authentication/clerk.d.ts +5 -0
  15. package/dist/app/authentication/clerk.js +36 -0
  16. package/dist/app/authentication/clerk.js.map +1 -0
  17. package/dist/app/authentication/openid.d.ts +11 -0
  18. package/dist/app/authentication/openid.js +118 -0
  19. package/dist/app/authentication/openid.js.map +1 -0
  20. package/dist/app/components/AnchorLink.d.ts +5 -0
  21. package/dist/app/components/AnchorLink.js +17 -0
  22. package/dist/app/components/AnchorLink.js.map +1 -0
  23. package/dist/app/components/CategoryHeading.d.ts +5 -0
  24. package/dist/app/components/CategoryHeading.js +6 -0
  25. package/dist/app/components/CategoryHeading.js.map +1 -0
  26. package/dist/app/components/DynamicIcon.d.ts +6 -0
  27. package/dist/app/components/DynamicIcon.js +6 -0
  28. package/dist/app/components/DynamicIcon.js.map +1 -0
  29. package/dist/app/components/Header.d.ts +2 -0
  30. package/dist/app/components/Header.js +15 -0
  31. package/dist/app/components/Header.js.map +1 -0
  32. package/dist/app/components/Layout.d.ts +4 -0
  33. package/dist/app/components/Layout.js +31 -0
  34. package/dist/app/components/Layout.js.map +1 -0
  35. package/dist/app/components/Markdown.d.ts +5 -0
  36. package/dist/app/components/Markdown.js +20 -0
  37. package/dist/app/components/Markdown.js.map +1 -0
  38. package/dist/app/components/SyntaxHighlight.d.ts +9 -0
  39. package/dist/app/components/SyntaxHighlight.js +31 -0
  40. package/dist/app/components/SyntaxHighlight.js.map +1 -0
  41. package/dist/app/components/TopNavigation.d.ts +1 -0
  42. package/dist/app/components/TopNavigation.js +11 -0
  43. package/dist/app/components/TopNavigation.js.map +1 -0
  44. package/dist/app/components/context/ComponentsContext.d.ts +10 -0
  45. package/dist/app/components/context/ComponentsContext.js +11 -0
  46. package/dist/app/components/context/ComponentsContext.js.map +1 -0
  47. package/dist/app/components/context/DevPortalProvider.d.ts +10 -0
  48. package/dist/app/components/context/DevPortalProvider.js +39 -0
  49. package/dist/app/components/context/DevPortalProvider.js.map +1 -0
  50. package/dist/app/components/context/PluginSystem.d.ts +1 -0
  51. package/dist/app/components/context/PluginSystem.js +2 -0
  52. package/dist/app/components/context/PluginSystem.js.map +1 -0
  53. package/dist/app/components/context/ThemeContext.d.ts +5 -0
  54. package/dist/app/components/context/ThemeContext.js +33 -0
  55. package/dist/app/components/context/ThemeContext.js.map +1 -0
  56. package/dist/app/components/context/ViewportAnchorContext.d.ts +15 -0
  57. package/dist/app/components/context/ViewportAnchorContext.js +89 -0
  58. package/dist/app/components/context/ViewportAnchorContext.js.map +1 -0
  59. package/dist/app/components/navigation/SideNavigation.d.ts +1 -0
  60. package/dist/app/components/navigation/SideNavigation.js +11 -0
  61. package/dist/app/components/navigation/SideNavigation.js.map +1 -0
  62. package/dist/app/components/navigation/SideNavigationCategory.d.ts +4 -0
  63. package/dist/app/components/navigation/SideNavigationCategory.js +26 -0
  64. package/dist/app/components/navigation/SideNavigationCategory.js.map +1 -0
  65. package/dist/app/components/navigation/SideNavigationItem.d.ts +12 -0
  66. package/dist/app/components/navigation/SideNavigationItem.js +38 -0
  67. package/dist/app/components/navigation/SideNavigationItem.js.map +1 -0
  68. package/dist/app/components/navigation/SideNavigationWrapper.d.ts +4 -0
  69. package/dist/app/components/navigation/SideNavigationWrapper.js +6 -0
  70. package/dist/app/components/navigation/SideNavigationWrapper.js.map +1 -0
  71. package/dist/app/components/navigation/useNavigationCollapsibleState.d.ts +7 -0
  72. package/dist/app/components/navigation/useNavigationCollapsibleState.js +16 -0
  73. package/dist/app/components/navigation/useNavigationCollapsibleState.js.map +1 -0
  74. package/dist/app/components/navigation/util.d.ts +8 -0
  75. package/dist/app/components/navigation/util.js +15 -0
  76. package/dist/app/components/navigation/util.js.map +1 -0
  77. package/dist/app/config.d.ts +3 -0
  78. package/dist/app/config.js +9 -0
  79. package/dist/app/config.js.map +1 -0
  80. package/dist/app/core/DevPortalContext.d.ts +80 -0
  81. package/dist/app/core/DevPortalContext.js +68 -0
  82. package/dist/app/core/DevPortalContext.js.map +1 -0
  83. package/dist/app/core/helmet.d.ts +4 -0
  84. package/dist/app/core/helmet.js +5 -0
  85. package/dist/app/core/helmet.js.map +1 -0
  86. package/dist/app/core/icons.d.ts +1 -0
  87. package/dist/app/core/icons.js +2 -0
  88. package/dist/app/core/icons.js.map +1 -0
  89. package/dist/app/core/plugins.d.ts +24 -0
  90. package/dist/app/core/plugins.js +4 -0
  91. package/dist/app/core/plugins.js.map +1 -0
  92. package/dist/app/core/router.d.ts +1 -0
  93. package/dist/app/core/router.js +2 -0
  94. package/dist/app/core/router.js.map +1 -0
  95. package/dist/app/core/types/combine.d.ts +4 -0
  96. package/dist/app/core/types/combine.js +2 -0
  97. package/dist/app/core/types/combine.js.map +1 -0
  98. package/dist/app/main.d.ts +1 -0
  99. package/dist/app/main.js +18 -0
  100. package/dist/app/main.js.map +1 -0
  101. package/dist/app/markdowns.d.ts +3 -0
  102. package/dist/app/markdowns.js +5 -0
  103. package/dist/app/markdowns.js.map +1 -0
  104. package/dist/app/oas/graphql/index.d.ts +12 -0
  105. package/dist/app/oas/graphql/index.js +290 -0
  106. package/dist/app/oas/graphql/index.js.map +1 -0
  107. package/dist/app/oas/graphql/server.d.ts +1 -0
  108. package/dist/app/oas/graphql/server.js +8 -0
  109. package/dist/app/oas/graphql/server.js.map +1 -0
  110. package/dist/app/oas/parser/dereference/index.d.ts +5 -0
  111. package/dist/app/oas/parser/dereference/index.js +43 -0
  112. package/dist/app/oas/parser/dereference/index.js.map +1 -0
  113. package/dist/app/oas/parser/dereference/resolveRef.d.ts +5 -0
  114. package/dist/app/oas/parser/dereference/resolveRef.js +26 -0
  115. package/dist/app/oas/parser/dereference/resolveRef.js.map +1 -0
  116. package/dist/app/oas/parser/index.d.ts +21 -0
  117. package/dist/app/oas/parser/index.js +58 -0
  118. package/dist/app/oas/parser/index.js.map +1 -0
  119. package/dist/app/oas/parser/schemas/v3.0.json +1489 -0
  120. package/dist/app/oas/parser/schemas/v3.1.json +1298 -0
  121. package/dist/app/oas/parser/upgrade/index.d.ts +9 -0
  122. package/dist/app/oas/parser/upgrade/index.js +90 -0
  123. package/dist/app/oas/parser/upgrade/index.js.map +1 -0
  124. package/dist/app/plugins/api-key/SettingsApiKeys.d.ts +4 -0
  125. package/dist/app/plugins/api-key/SettingsApiKeys.js +7 -0
  126. package/dist/app/plugins/api-key/SettingsApiKeys.js.map +1 -0
  127. package/dist/app/plugins/api-key/index.d.ts +32 -0
  128. package/dist/app/plugins/api-key/index.js +55 -0
  129. package/dist/app/plugins/api-key/index.js.map +1 -0
  130. package/dist/app/plugins/markdown/MdxPage.d.ts +3 -0
  131. package/dist/app/plugins/markdown/MdxPage.js +55 -0
  132. package/dist/app/plugins/markdown/MdxPage.js.map +1 -0
  133. package/dist/app/plugins/markdown/Toc.d.ts +4 -0
  134. package/dist/app/plugins/markdown/Toc.js +40 -0
  135. package/dist/app/plugins/markdown/Toc.js.map +1 -0
  136. package/dist/app/plugins/markdown/generateRoutes.d.ts +3 -0
  137. package/dist/app/plugins/markdown/generateRoutes.js +50 -0
  138. package/dist/app/plugins/markdown/generateRoutes.js.map +1 -0
  139. package/dist/app/plugins/markdown/index.d.ts +19 -0
  140. package/dist/app/plugins/markdown/index.js +9 -0
  141. package/dist/app/plugins/markdown/index.js.map +1 -0
  142. package/dist/app/plugins/openapi/ColorizedParam.d.ts +8 -0
  143. package/dist/app/plugins/openapi/ColorizedParam.js +40 -0
  144. package/dist/app/plugins/openapi/ColorizedParam.js.map +1 -0
  145. package/dist/app/plugins/openapi/MakeRequest.d.ts +4 -0
  146. package/dist/app/plugins/openapi/MakeRequest.js +11 -0
  147. package/dist/app/plugins/openapi/MakeRequest.js.map +1 -0
  148. package/dist/app/plugins/openapi/MethodBadge.d.ts +13 -0
  149. package/dist/app/plugins/openapi/MethodBadge.js +26 -0
  150. package/dist/app/plugins/openapi/MethodBadge.js.map +1 -0
  151. package/dist/app/plugins/openapi/OperationList.d.ts +47 -0
  152. package/dist/app/plugins/openapi/OperationList.js +82 -0
  153. package/dist/app/plugins/openapi/OperationList.js.map +1 -0
  154. package/dist/app/plugins/openapi/OperationListItem.d.ts +7 -0
  155. package/dist/app/plugins/openapi/OperationListItem.js +15 -0
  156. package/dist/app/plugins/openapi/OperationListItem.js.map +1 -0
  157. package/dist/app/plugins/openapi/ParameterList.d.ts +7 -0
  158. package/dist/app/plugins/openapi/ParameterList.js +5 -0
  159. package/dist/app/plugins/openapi/ParameterList.js.map +1 -0
  160. package/dist/app/plugins/openapi/ParameterListItem.d.ts +8 -0
  161. package/dist/app/plugins/openapi/ParameterListItem.js +13 -0
  162. package/dist/app/plugins/openapi/ParameterListItem.js.map +1 -0
  163. package/dist/app/plugins/openapi/RequestBodySidecarBox.d.ts +6 -0
  164. package/dist/app/plugins/openapi/RequestBodySidecarBox.js +19 -0
  165. package/dist/app/plugins/openapi/RequestBodySidecarBox.js.map +1 -0
  166. package/dist/app/plugins/openapi/ResponsesSidecarBox.d.ts +6 -0
  167. package/dist/app/plugins/openapi/ResponsesSidecarBox.js +15 -0
  168. package/dist/app/plugins/openapi/ResponsesSidecarBox.js.map +1 -0
  169. package/dist/app/plugins/openapi/Select.d.ts +9 -0
  170. package/dist/app/plugins/openapi/Select.js +5 -0
  171. package/dist/app/plugins/openapi/Select.js.map +1 -0
  172. package/dist/app/plugins/openapi/Sidecar.d.ts +4 -0
  173. package/dist/app/plugins/openapi/Sidecar.js +39 -0
  174. package/dist/app/plugins/openapi/Sidecar.js.map +1 -0
  175. package/dist/app/plugins/openapi/SidecarBox.d.ts +10 -0
  176. package/dist/app/plugins/openapi/SidecarBox.js +8 -0
  177. package/dist/app/plugins/openapi/SidecarBox.js.map +1 -0
  178. package/dist/app/plugins/openapi/graphql/index.d.ts +836 -0
  179. package/dist/app/plugins/openapi/graphql/index.js +4 -0
  180. package/dist/app/plugins/openapi/graphql/index.js.map +1 -0
  181. package/dist/app/plugins/openapi/index.d.ts +22 -0
  182. package/dist/app/plugins/openapi/index.js +91 -0
  183. package/dist/app/plugins/openapi/index.js.map +1 -0
  184. package/dist/app/plugins/openapi/util/generateSchemaExample.d.ts +3 -0
  185. package/dist/app/plugins/openapi/util/generateSchemaExample.js +52 -0
  186. package/dist/app/plugins/openapi/util/generateSchemaExample.js.map +1 -0
  187. package/dist/app/plugins/openapi/util/getCode.d.ts +2 -0
  188. package/dist/app/plugins/openapi/util/getCode.js +54 -0
  189. package/dist/app/plugins/openapi/util/getCode.js.map +1 -0
  190. package/dist/app/plugins/openapi/util/urql.d.ts +8 -0
  191. package/dist/app/plugins/openapi/util/urql.js +8 -0
  192. package/dist/app/plugins/openapi/util/urql.js.map +1 -0
  193. package/dist/app/plugins/openapi/worker/createSharedWorkerClient.d.ts +5 -0
  194. package/dist/app/plugins/openapi/worker/createSharedWorkerClient.js +47 -0
  195. package/dist/app/plugins/openapi/worker/createSharedWorkerClient.js.map +1 -0
  196. package/dist/app/plugins/openapi/worker/worker.d.ts +1 -0
  197. package/dist/app/plugins/openapi/worker/worker.js +20 -0
  198. package/dist/app/plugins/openapi/worker/worker.js.map +1 -0
  199. package/dist/app/plugins/redirect/index.d.ts +10 -0
  200. package/dist/app/plugins/redirect/index.js +11 -0
  201. package/dist/app/plugins/redirect/index.js.map +1 -0
  202. package/dist/app/tailwind.d.ts +3 -0
  203. package/dist/app/tailwind.js +69 -0
  204. package/dist/app/tailwind.js.map +1 -0
  205. package/dist/app/ui/Callout.d.ts +51 -0
  206. package/dist/app/ui/Callout.js +50 -0
  207. package/dist/app/ui/Callout.js.map +1 -0
  208. package/dist/app/ui/Card.d.ts +8 -0
  209. package/dist/app/ui/Card.js +17 -0
  210. package/dist/app/ui/Card.js.map +1 -0
  211. package/dist/app/ui/Note.d.ts +8 -0
  212. package/dist/app/ui/Note.js +23 -0
  213. package/dist/app/ui/Note.js.map +1 -0
  214. package/dist/app/util/MdxComponents.d.ts +27 -0
  215. package/dist/app/util/MdxComponents.js +40 -0
  216. package/dist/app/util/MdxComponents.js.map +1 -0
  217. package/dist/app/util/cn.d.ts +2 -0
  218. package/dist/app/util/cn.js +6 -0
  219. package/dist/app/util/cn.js.map +1 -0
  220. package/dist/app/util/createWaitForNotify.d.ts +1 -0
  221. package/dist/app/util/createWaitForNotify.js +15 -0
  222. package/dist/app/util/createWaitForNotify.js.map +1 -0
  223. package/dist/app/util/groupBy.d.ts +6 -0
  224. package/dist/app/util/groupBy.js +9 -0
  225. package/dist/app/util/groupBy.js.map +1 -0
  226. package/dist/app/util/joinPath.d.ts +1 -0
  227. package/dist/app/util/joinPath.js +8 -0
  228. package/dist/app/util/joinPath.js.map +1 -0
  229. package/dist/app/util/pastellize.d.ts +4 -0
  230. package/dist/app/util/pastellize.js +14 -0
  231. package/dist/app/util/pastellize.js.map +1 -0
  232. package/dist/app/util/slugify.d.ts +3 -0
  233. package/dist/app/util/slugify.js +3 -0
  234. package/dist/app/util/slugify.js.map +1 -0
  235. package/dist/app/util/traverseNavigation.d.ts +6 -0
  236. package/dist/app/util/traverseNavigation.js +30 -0
  237. package/dist/app/util/traverseNavigation.js.map +1 -0
  238. package/dist/app/util/useScrollToAnchor.d.ts +1 -0
  239. package/dist/app/util/useScrollToAnchor.js +33 -0
  240. package/dist/app/util/useScrollToAnchor.js.map +1 -0
  241. package/dist/app/util/useScrollToTop.d.ts +1 -0
  242. package/dist/app/util/useScrollToTop.js +13 -0
  243. package/dist/app/util/useScrollToTop.js.map +1 -0
  244. package/dist/auth.d.ts +2 -0
  245. package/dist/auth.js +3 -0
  246. package/dist/auth.js.map +1 -0
  247. package/dist/cli/build/handler.d.ts +4 -0
  248. package/dist/cli/build/handler.js +9 -0
  249. package/dist/cli/build/handler.js.map +1 -0
  250. package/dist/cli/cli.d.ts +1 -0
  251. package/dist/cli/cli.js +64 -0
  252. package/dist/cli/cli.js.map +1 -0
  253. package/dist/cli/cmds/build.d.ts +8 -0
  254. package/dist/cli/cmds/build.js +23 -0
  255. package/dist/cli/cmds/build.js.map +1 -0
  256. package/dist/cli/cmds/dev.d.ts +8 -0
  257. package/dist/cli/cmds/dev.js +29 -0
  258. package/dist/cli/cmds/dev.js.map +1 -0
  259. package/dist/cli/common/analytics/lib.d.ts +17 -0
  260. package/dist/cli/common/analytics/lib.js +53 -0
  261. package/dist/cli/common/analytics/lib.js.map +1 -0
  262. package/dist/cli/common/constants.d.ts +5 -0
  263. package/dist/cli/common/constants.js +9 -0
  264. package/dist/cli/common/constants.js.map +1 -0
  265. package/dist/cli/common/logger.d.ts +2 -0
  266. package/dist/cli/common/logger.js +14 -0
  267. package/dist/cli/common/logger.js.map +1 -0
  268. package/dist/cli/common/machine-id/lib.d.ts +1 -0
  269. package/dist/cli/common/machine-id/lib.js +74 -0
  270. package/dist/cli/common/machine-id/lib.js.map +1 -0
  271. package/dist/cli/common/outdated.d.ts +1 -0
  272. package/dist/cli/common/outdated.js +70 -0
  273. package/dist/cli/common/outdated.js.map +1 -0
  274. package/dist/cli/common/output.d.ts +9 -0
  275. package/dist/cli/common/output.js +65 -0
  276. package/dist/cli/common/output.js.map +1 -0
  277. package/dist/cli/common/utils/box.d.ts +33 -0
  278. package/dist/cli/common/utils/box.js +81 -0
  279. package/dist/cli/common/utils/box.js.map +1 -0
  280. package/dist/cli/common/utils/ports.d.ts +1 -0
  281. package/dist/cli/common/utils/ports.js +18 -0
  282. package/dist/cli/common/utils/ports.js.map +1 -0
  283. package/dist/cli/common/validators/lib.d.ts +20 -0
  284. package/dist/cli/common/validators/lib.js +31 -0
  285. package/dist/cli/common/validators/lib.js.map +1 -0
  286. package/dist/cli/common/xdg/lib.d.ts +6 -0
  287. package/dist/cli/common/xdg/lib.js +18 -0
  288. package/dist/cli/common/xdg/lib.js.map +1 -0
  289. package/dist/cli/dev/handler.d.ts +5 -0
  290. package/dist/cli/dev/handler.js +22 -0
  291. package/dist/cli/dev/handler.js.map +1 -0
  292. package/dist/config/config.d.ts +37 -0
  293. package/dist/config/config.js +2 -0
  294. package/dist/config/config.js.map +1 -0
  295. package/dist/index.d.ts +7 -0
  296. package/dist/index.js +6 -0
  297. package/dist/index.js.map +1 -0
  298. package/dist/plugins.d.ts +4 -0
  299. package/dist/plugins.js +6 -0
  300. package/dist/plugins.js.map +1 -0
  301. package/dist/vite/build.d.ts +3 -0
  302. package/dist/vite/build.js +29 -0
  303. package/dist/vite/build.js.map +1 -0
  304. package/dist/vite/config.d.ts +6 -0
  305. package/dist/vite/config.js +74 -0
  306. package/dist/vite/config.js.map +1 -0
  307. package/dist/vite/dev-server.d.ts +10 -0
  308. package/dist/vite/dev-server.js +53 -0
  309. package/dist/vite/dev-server.js.map +1 -0
  310. package/dist/vite/html.d.ts +5 -0
  311. package/dist/vite/html.js +32 -0
  312. package/dist/vite/html.js.map +1 -0
  313. package/dist/vite/import-auth-plugin.d.ts +3 -0
  314. package/dist/vite/import-auth-plugin.js +28 -0
  315. package/dist/vite/import-auth-plugin.js.map +1 -0
  316. package/dist/vite/plugin.d.ts +7 -0
  317. package/dist/vite/plugin.js +109 -0
  318. package/dist/vite/plugin.js.map +1 -0
  319. package/package.json +118 -0
  320. package/src/app/DevPortal.tsx +115 -0
  321. package/src/app/Heading.tsx +60 -0
  322. package/src/app/app.tsx +85 -0
  323. package/src/app/authentication/authentication.ts +18 -0
  324. package/src/app/authentication/clerk.ts +47 -0
  325. package/src/app/authentication/openid.ts +192 -0
  326. package/src/app/components/AnchorLink.tsx +19 -0
  327. package/src/app/components/CategoryHeading.tsx +16 -0
  328. package/src/app/components/DynamicIcon.tsx +60 -0
  329. package/src/app/components/Header.tsx +69 -0
  330. package/src/app/components/Layout.tsx +56 -0
  331. package/src/app/components/Markdown.tsx +37 -0
  332. package/src/app/components/SyntaxHighlight.tsx +92 -0
  333. package/src/app/components/TopNavigation.tsx +32 -0
  334. package/src/app/components/context/ComponentsContext.tsx +24 -0
  335. package/src/app/components/context/DevPortalProvider.ts +54 -0
  336. package/src/app/components/context/PluginSystem.ts +0 -0
  337. package/src/app/components/context/ThemeContext.tsx +46 -0
  338. package/src/app/components/context/ViewportAnchorContext.tsx +139 -0
  339. package/src/app/components/navigation/SideNavigation.tsx +18 -0
  340. package/src/app/components/navigation/SideNavigationCategory.tsx +74 -0
  341. package/src/app/components/navigation/SideNavigationItem.tsx +143 -0
  342. package/src/app/components/navigation/SideNavigationWrapper.tsx +15 -0
  343. package/src/app/components/navigation/useNavigationCollapsibleState.ts +27 -0
  344. package/src/app/components/navigation/util.ts +38 -0
  345. package/src/app/config.ts +20 -0
  346. package/src/app/core/DevPortalContext.ts +164 -0
  347. package/src/app/core/helmet.ts +5 -0
  348. package/src/app/core/icons.tsx +1 -0
  349. package/src/app/core/plugins.ts +43 -0
  350. package/src/app/core/router.tsx +1 -0
  351. package/src/app/core/types/combine.ts +16 -0
  352. package/src/app/main.css +137 -0
  353. package/src/app/main.tsx +22 -0
  354. package/src/app/markdowns.ts +7 -0
  355. package/src/app/oas/graphql/index.ts +422 -0
  356. package/src/app/oas/graphql/server.ts +10 -0
  357. package/src/app/oas/parser/dereference/index.ts +59 -0
  358. package/src/app/oas/parser/dereference/resolveRef.ts +32 -0
  359. package/src/app/oas/parser/index.ts +94 -0
  360. package/src/app/oas/parser/schemas/v3.0.json +1489 -0
  361. package/src/app/oas/parser/schemas/v3.1.json +1298 -0
  362. package/src/app/oas/parser/upgrade/index.ts +108 -0
  363. package/src/app/plugins/api-key/SettingsApiKeys.tsx +22 -0
  364. package/src/app/plugins/api-key/index.tsx +123 -0
  365. package/src/app/plugins/markdown/MdxPage.tsx +128 -0
  366. package/src/app/plugins/markdown/Toc.tsx +122 -0
  367. package/src/app/plugins/markdown/generateRoutes.tsx +72 -0
  368. package/src/app/plugins/markdown/index.tsx +31 -0
  369. package/src/app/plugins/openapi/ColorizedParam.tsx +73 -0
  370. package/src/app/plugins/openapi/MakeRequest.tsx +30 -0
  371. package/src/app/plugins/openapi/MethodBadge.tsx +36 -0
  372. package/src/app/plugins/openapi/OperationList.tsx +119 -0
  373. package/src/app/plugins/openapi/OperationListItem.tsx +55 -0
  374. package/src/app/plugins/openapi/ParameterList.tsx +32 -0
  375. package/src/app/plugins/openapi/ParameterListItem.tsx +60 -0
  376. package/src/app/plugins/openapi/RequestBodySidecarBox.tsx +48 -0
  377. package/src/app/plugins/openapi/ResponsesSidecarBox.tsx +60 -0
  378. package/src/app/plugins/openapi/Select.tsx +35 -0
  379. package/src/app/plugins/openapi/Sidecar.tsx +99 -0
  380. package/src/app/plugins/openapi/SidecarBox.tsx +35 -0
  381. package/src/app/plugins/openapi/graphql/env.d.ts +48 -0
  382. package/src/app/plugins/openapi/graphql/index.ts +13 -0
  383. package/src/app/plugins/openapi/index.tsx +142 -0
  384. package/src/app/plugins/openapi/util/generateSchemaExample.ts +59 -0
  385. package/src/app/plugins/openapi/util/getCode.tsx +69 -0
  386. package/src/app/plugins/openapi/util/urql.ts +8 -0
  387. package/src/app/plugins/openapi/worker/createSharedWorkerClient.ts +60 -0
  388. package/src/app/plugins/openapi/worker/worker.ts +30 -0
  389. package/src/app/plugins/redirect/index.tsx +20 -0
  390. package/src/app/tailwind.ts +72 -0
  391. package/src/app/ui/Callout.tsx +87 -0
  392. package/src/app/ui/Card.tsx +82 -0
  393. package/src/app/ui/Note.tsx +58 -0
  394. package/src/app/util/MdxComponents.tsx +70 -0
  395. package/src/app/util/cn.ts +6 -0
  396. package/src/app/util/createWaitForNotify.ts +18 -0
  397. package/src/app/util/groupBy.ts +24 -0
  398. package/src/app/util/joinPath.tsx +10 -0
  399. package/src/app/util/pastellize.ts +25 -0
  400. package/src/app/util/slugify.ts +3 -0
  401. package/src/app/util/traverseNavigation.ts +55 -0
  402. package/src/app/util/useScrollToAnchor.ts +38 -0
  403. package/src/app/util/useScrollToTop.ts +13 -0
@@ -0,0 +1,60 @@
1
+ import { type ReactNode } from "react";
2
+ import { useRegisterAnchorElement } from "./components/context/ViewportAnchorContext.js";
3
+ import { cn } from "./util/cn.js";
4
+
5
+ const getComponent = (level: number) => {
6
+ switch (level) {
7
+ case 1:
8
+ return "h1";
9
+ case 2:
10
+ return "h2";
11
+ case 3:
12
+ return "h3";
13
+ case 4:
14
+ return "h4";
15
+ case 5:
16
+ return "h5";
17
+ case 6:
18
+ return "h6";
19
+ default:
20
+ return "h1";
21
+ }
22
+ };
23
+
24
+ export type HeadingProps = {
25
+ children: ReactNode;
26
+ className?: string;
27
+ id?: string;
28
+ level?: 1 | 2 | 3 | 4 | 5 | 6;
29
+ registerSidebarAnchor?: boolean;
30
+ };
31
+
32
+ export const Heading = ({
33
+ level,
34
+ children,
35
+ id,
36
+ className,
37
+ registerSidebarAnchor,
38
+ }: HeadingProps) => {
39
+ const Component = getComponent(level ?? 1);
40
+ const { ref } = useRegisterAnchorElement();
41
+
42
+ return (
43
+ <Component
44
+ className={cn("group relative", className)}
45
+ ref={registerSidebarAnchor ? ref : undefined}
46
+ id={id}
47
+ >
48
+ {id && (
49
+ <a
50
+ href={`#${id}`}
51
+ className="no-underline absolute text-primary -left-[0.8em] pr-2.5 opacity-0 group-hover:opacity-50 hover:!opacity-100 transition-opacity duration-200"
52
+ aria-label={`Link to ${id}`}
53
+ >
54
+ #
55
+ </a>
56
+ )}
57
+ {children}
58
+ </Component>
59
+ );
60
+ };
@@ -0,0 +1,85 @@
1
+ import "./main.css";
2
+
3
+ import DevPortal from "./DevPortal.js";
4
+ import { markdownPlugin } from "./plugins/markdown/index.js";
5
+ import { openApiPlugin } from "./plugins/openapi/index.js";
6
+
7
+ import config from "./config.js";
8
+
9
+ // async function getAuthProvider(authConfig: AuthenticationConfig) {
10
+ // if (authConfig.type === "clerk") {
11
+ // const clerkProvider = await import("./authentication/clerk.js");
12
+ // return clerkProvider(authConfig);
13
+ // } else {
14
+ // throw new Error(
15
+ // `The authentication type "${authConfig.type}" is not supported.`,
16
+ // );
17
+ // }
18
+ // //openIdAuth({
19
+ // // clientId: oauth.client_id,
20
+ // // authorizationEndpoint: oauth.authorize_url,
21
+ // // tokenEndpoint: oauth.token_fetch_url,
22
+ // // })
23
+ // }
24
+
25
+ export default function App() {
26
+ return (
27
+ <DevPortal
28
+ meta={{
29
+ headerTitle: config?.ui?.headerTitle ?? "Developer Portal",
30
+ pageTitle: config?.ui?.pageTitle ?? "%s | Dev Portal",
31
+ logo: config?.ui?.logo ?? "https://cdn.zuplo.com/www/favicon.png",
32
+ favicon:
33
+ config?.ui?.metadata?.favicon ??
34
+ "https://cdn.zuplo.com/www/favicon.png",
35
+ }}
36
+ navigation={config.navigation ?? []}
37
+ // authentication={
38
+ // config.authentication
39
+ // ? getAuthProvider(config.authentication)
40
+ // : undefined
41
+ // }
42
+ plugins={[
43
+ ...(config.docs
44
+ ? Array.isArray(config.docs)
45
+ ? config.docs
46
+ : [config.docs]
47
+ : []
48
+ ).map((docs) =>
49
+ markdownPlugin({
50
+ markdownFiles: docs?.files ?? {},
51
+ }),
52
+ ),
53
+ ...(config.apis
54
+ ? Array.isArray(config.apis)
55
+ ? config.apis
56
+ : [config.apis]
57
+ : []
58
+ ).map((api) => openApiPlugin(api)),
59
+
60
+ // apiKeyPlugin({
61
+ // // consumerEndpoint:
62
+ // // "https://zudoku-customer-main-b36fa2f.d2.zuplo.dev/v1/developer/api-keys",
63
+ // getConsumers: async (ctx) => {
64
+ // const accessToken = await ctx.authentication?.getToken?.(ctx);
65
+
66
+ // if (!accessToken) {
67
+ // return;
68
+ // }
69
+
70
+ // const consumers = await fetch(
71
+ // "https://zudoku-customer-main-b36fa2f.d2.zuplo.dev/v1/developer/api-keys",
72
+ // {
73
+ // headers: {
74
+ // Authorization: `Bearer ${accessToken}`,
75
+ // },
76
+ // },
77
+ // );
78
+
79
+ // return { consumers: [await consumers.json()] };
80
+ // },
81
+ // }),
82
+ ]}
83
+ />
84
+ );
85
+ }
@@ -0,0 +1,18 @@
1
+ import { DevPortalContext } from "../core/DevPortalContext.js";
2
+
3
+ export interface AuthProvider {
4
+ initialize(context: DevPortalContext): Promise<unknown>;
5
+ login(context: DevPortalContext): Promise<unknown>;
6
+ getToken?: (context: DevPortalContext) => Promise<string | undefined>;
7
+ handleAuthenticationResponse?: (
8
+ path: Path,
9
+ context: DevPortalContext,
10
+ ) => Promise<unknown>;
11
+ signOut(context: DevPortalContext): void;
12
+ }
13
+
14
+ export type Path = {
15
+ pathname: string;
16
+ search: string;
17
+ hash: string;
18
+ };
@@ -0,0 +1,47 @@
1
+ import { Clerk } from "@clerk/clerk-js";
2
+ import { type AuthProvider } from "./authentication.js";
3
+
4
+ const clerkProvider = ({
5
+ clerkPubKey,
6
+ }: {
7
+ clerkPubKey: string;
8
+ }): AuthProvider => {
9
+ const clerkApi = new Clerk(clerkPubKey);
10
+
11
+ const clerkIsLoaded = clerkApi.load({});
12
+
13
+ return {
14
+ initialize: async (context) => {
15
+ await clerkIsLoaded;
16
+
17
+ if (clerkApi.session) {
18
+ await context.setUserProfile({
19
+ isLoggedIn: true,
20
+ name: clerkApi.session.user.fullName ?? undefined,
21
+ email:
22
+ clerkApi.session.user.emailAddresses.at(0)?.emailAddress ??
23
+ undefined,
24
+ });
25
+ } else {
26
+ await context.setUserProfile({
27
+ isLoggedIn: false,
28
+ });
29
+ }
30
+ },
31
+
32
+ getToken: async () => {
33
+ await clerkIsLoaded;
34
+ const token = await clerkApi.session?.getToken();
35
+ return token ?? undefined;
36
+ },
37
+
38
+ signOut() {
39
+ clerkApi.signOut();
40
+ },
41
+ login: async () => {
42
+ await clerkApi.redirectToSignIn();
43
+ },
44
+ };
45
+ };
46
+
47
+ export default clerkProvider;
@@ -0,0 +1,192 @@
1
+ import * as oauth from "oauth4webapi";
2
+ import { DevPortalContext } from "../core/DevPortalContext.js";
3
+ import { type AuthProvider } from "./authentication.js";
4
+ const algorithm = "oauth2";
5
+
6
+ const getAuthServerByIssuer = async (issuer: string) => {
7
+ const authorizationServer = await oauth
8
+ .discoveryRequest(new URL(issuer), { algorithm })
9
+ .then((response) =>
10
+ oauth.processDiscoveryResponse(new URL(issuer), response),
11
+ );
12
+
13
+ return authorizationServer;
14
+ };
15
+
16
+ export type AuthServerOption = {
17
+ issuer?: string;
18
+ authorizationEndpoint?: string;
19
+ tokenEndpoint?: string;
20
+ };
21
+
22
+ const getAuthServer = async ({
23
+ issuer,
24
+ authorizationEndpoint,
25
+ tokenEndpoint,
26
+ }: AuthServerOption) => {
27
+ return issuer
28
+ ? await getAuthServerByIssuer(issuer)
29
+ : ({
30
+ issuer: new URL(authorizationEndpoint!).origin,
31
+ authorization_endpoint: authorizationEndpoint,
32
+ token_endpoint: tokenEndpoint,
33
+ code_challenge_methods_supported: [],
34
+ } satisfies oauth.AuthorizationServer);
35
+ };
36
+
37
+ export const openIdAuth = ({
38
+ clientId,
39
+ clientSecret,
40
+ issuer,
41
+ authorizationEndpoint,
42
+ tokenEndpoint,
43
+ }: {
44
+ clientId: string;
45
+ clientSecret?: string;
46
+ audience?: string;
47
+ } & AuthServerOption): AuthProvider => {
48
+ const client: oauth.Client = {
49
+ client_id: clientId,
50
+ client_secret: clientSecret,
51
+ token_endpoint_auth_method: "none",
52
+ };
53
+
54
+ const redirect_uri = "http://localhost:5173/oauth/callback";
55
+
56
+ return {
57
+ initialize() {
58
+ return Promise.resolve();
59
+ },
60
+ signOut() {},
61
+ login: async (context: DevPortalContext) => {
62
+ const code_challenge_method = "S256";
63
+ const authorizationServer = await getAuthServer({
64
+ issuer,
65
+ authorizationEndpoint,
66
+ tokenEndpoint,
67
+ });
68
+
69
+ if (!authorizationServer.authorization_endpoint) {
70
+ throw new Error("No authorization endpoint");
71
+ }
72
+
73
+ /**
74
+ * The following MUST be generated for every redirect to the authorization_endpoint. You must store
75
+ * the codeVerifier and nonce in the end-user session such that it can be recovered as the user
76
+ * gets redirected from the authorization server back to your application.
77
+ */
78
+ const codeVerifier = oauth.generateRandomCodeVerifier();
79
+ const codeChallenge =
80
+ await oauth.calculatePKCECodeChallenge(codeVerifier);
81
+
82
+ await context.sessionStorage.set("codeVerifier", codeVerifier);
83
+
84
+ // redirect user to as.authorization_endpoint
85
+ const authorizationUrl = new URL(
86
+ authorizationServer.authorization_endpoint,
87
+ );
88
+ authorizationUrl.searchParams.set("client_id", client.client_id);
89
+ authorizationUrl.searchParams.set("redirect_uri", redirect_uri);
90
+ authorizationUrl.searchParams.set("response_type", "code");
91
+ // authorizationUrl.searchParams.set("scope", "api:read");
92
+ authorizationUrl.searchParams.set("code_challenge", codeChallenge);
93
+ authorizationUrl.searchParams.set(
94
+ "code_challenge_method",
95
+ code_challenge_method,
96
+ );
97
+
98
+ /**
99
+ * We cannot be sure the AS supports PKCE so we're going to use state too. Use of PKCE is
100
+ * backwards compatible even if the AS doesn't support it which is why we're using it regardless.
101
+ */
102
+ if (
103
+ authorizationServer.code_challenge_methods_supported?.includes(
104
+ "S256",
105
+ ) !== true
106
+ ) {
107
+ const state = oauth.generateRandomState();
108
+ authorizationUrl.searchParams.set("state", state);
109
+ }
110
+
111
+ // now redirect the user to authorizationUrl.href
112
+ location.href = authorizationUrl.href;
113
+ },
114
+
115
+ handleAuthenticationResponse: async ({ search }, { sessionStorage }) => {
116
+ const searchParams = new URLSearchParams(search);
117
+ const state = searchParams.get("state");
118
+ if (!state) {
119
+ return;
120
+ }
121
+
122
+ // one eternity later, the user lands back on the redirect_uri
123
+ // Authorization Code Grant Request & Response
124
+ const codeVerifier = await sessionStorage.get("codeVerifier");
125
+
126
+ if (!codeVerifier) {
127
+ return;
128
+ }
129
+
130
+ const as = await getAuthServer({
131
+ issuer,
132
+ authorizationEndpoint,
133
+ tokenEndpoint,
134
+ });
135
+
136
+ const params = oauth.validateAuthResponse(
137
+ as,
138
+ client,
139
+ searchParams,
140
+ state,
141
+ );
142
+ if (oauth.isOAuth2Error(params)) {
143
+ console.error("Error Response", params);
144
+ throw new Error(); // Handle OAuth 2.0 redirect error
145
+ }
146
+
147
+ const response = await oauth.authorizationCodeGrantRequest(
148
+ as,
149
+ client,
150
+ params,
151
+ redirect_uri,
152
+ codeVerifier,
153
+ );
154
+
155
+ // @todo do we need to do these
156
+ // const challenges = oauth.parseWwwAuthenticateChallenges(response);
157
+ // if (challenges) {
158
+ // for (const challenge of challenges) {
159
+ // console.error("WWW-Authenticate Challenge", challenge);
160
+ // }
161
+ // throw new Error(); // Handle WWW-Authenticate Challenges as needed
162
+ // }
163
+
164
+ const oauthResult = await oauth.processAuthorizationCodeOpenIDResponse(
165
+ as,
166
+ client,
167
+ response,
168
+ );
169
+ if (oauth.isOAuth2Error(oauthResult)) {
170
+ console.error("Error Response", oauthResult);
171
+ throw new Error(oauthResult.error);
172
+ }
173
+
174
+ const userInfoResponse = await oauth.userInfoRequest(
175
+ as,
176
+ client,
177
+ oauthResult.access_token,
178
+ );
179
+ const userInfo = await userInfoResponse.json();
180
+
181
+ // void storage.setProfile({
182
+ // sub: userInfo.sub,
183
+ // email: userInfo.email,
184
+ // name: userInfo.name,
185
+ // email_verified: userInfo.email_verified ?? false,
186
+ // picture: userInfo.picture,
187
+ // id_token: oauthResult.id_token,
188
+ // access_token: oauthResult.access_token,
189
+ // });
190
+ },
191
+ };
192
+ };
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import { Link, type LinkProps, useLocation } from "react-router-dom";
3
+
4
+ /**
5
+ * Link that scrolls to anchor even if the hash is already set in the URL.
6
+ */
7
+ export const AnchorLink = (props: LinkProps) => {
8
+ const location = useLocation();
9
+ const hash = typeof props.to === "string" ? props.to : props.to.hash;
10
+
11
+ const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
12
+ if (!hash?.startsWith("#") || hash !== location.hash) return;
13
+
14
+ event.preventDefault();
15
+ document.getElementById(hash.slice(1))?.scrollIntoView();
16
+ };
17
+
18
+ return <Link onClick={handleClick} {...props} />;
19
+ };
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from "react";
2
+ import { cx } from "class-variance-authority";
3
+
4
+ export const CategoryHeading = ({
5
+ children,
6
+ className,
7
+ }: {
8
+ children: ReactNode;
9
+ className?: string;
10
+ }) => {
11
+ return (
12
+ <div className={cx("text-sm font-semibold text-primary mb-2", className)}>
13
+ {children}
14
+ </div>
15
+ );
16
+ };
@@ -0,0 +1,60 @@
1
+ // import { type LucideProps } from "lucide-react";
2
+ // import dynamicIconImports from "lucide-react/dynamicIconImports.js";
3
+ // import { Suspense, lazy, memo } from "react";
4
+ // import { cn } from "../util/cn.js";
5
+
6
+ // export type IconName = keyof typeof dynamicIconImports;
7
+
8
+ // const IconNames = Object.keys(dynamicIconImports) as IconName[];
9
+
10
+ // export const isValidIcon = (name: unknown): name is IconName =>
11
+ // typeof name === "string" && IconNames.includes(name as IconName);
12
+
13
+ // type IconProps = Omit<LucideProps, "ref"> & {
14
+ // name: IconName;
15
+ // inline?: boolean;
16
+ // };
17
+
18
+ // const Fallback = ({
19
+ // inline,
20
+ // size,
21
+ // }: {
22
+ // inline?: boolean;
23
+ // size?: string | number;
24
+ // }) => (
25
+ // <span
26
+ // className={cn(inline ? "inline-block" : "block", "bg-background")}
27
+ // style={{ height: size, width: size }}
28
+ // role="presentation"
29
+ // />
30
+ // );
31
+
32
+ // export const DynamicIcon = memo(function ({
33
+ // name,
34
+ // inline,
35
+ // className,
36
+ // size = 16,
37
+ // ...props
38
+ // }: IconProps) {
39
+ // const LucideIcon = lazy(dynamicIconImports[name]);
40
+
41
+ // return (
42
+ // <Suspense fallback={<Fallback inline={inline} size={size} />}>
43
+ // <LucideIcon
44
+ // {...props}
45
+ // size={size}
46
+ // className={cn(inline && "inline-block align-[-0.125em]", className)}
47
+ // />
48
+ // </Suspense>
49
+ // );
50
+ // });
51
+
52
+ export type IconName = string;
53
+
54
+ export function isValidIcon(name: unknown): name is IconName {
55
+ return true;
56
+ }
57
+
58
+ export const DynamicIcon = (props: { name: string; size?: number }) => (
59
+ <div></div>
60
+ );
@@ -0,0 +1,69 @@
1
+ import { MoonStarIcon, SearchIcon, SunIcon } from "lucide-react";
2
+ import { memo } from "react";
3
+ import { useDevPortalState } from "../core/DevPortalContext.js";
4
+ import { TopNavigation } from "./TopNavigation.js";
5
+ import { useDevPortal } from "./context/DevPortalProvider.js";
6
+ import { useTheme } from "./context/ThemeContext.js";
7
+
8
+ export const Header = memo(() => {
9
+ const [isDark, toggleTheme] = useTheme();
10
+ const { isLoggedIn, email } = useDevPortalState();
11
+ const { login, logout, meta } = useDevPortal();
12
+
13
+ const ThemeIcon = isDark ? MoonStarIcon : SunIcon;
14
+
15
+ return (
16
+ <header className="fixed top-0 w-full z-10 bg-background/80 backdrop-blur">
17
+ <div className="max-w-screen-2xl mx-auto">
18
+ <div className="grid grid-cols-[calc(var(--side-nav-width))_1fr] lg:gap-12 items-center border-b border-border px-12 h-[--top-header-height]">
19
+ <div className="flex items-center gap-3.5">
20
+ {meta?.logo && (
21
+ <img src={meta.logo} alt="My Dev Portal" className="h-10" />
22
+ )}
23
+ <span className="font-bold text-2xl text-foreground/85 tracking-wide">
24
+ {meta?.headerTitle}
25
+ </span>
26
+ </div>
27
+ <div className="grid grid-cols-[--sidecar-grid-cols] items-center gap-8">
28
+ <div className="w-full max-w-prose mx-auto">
29
+ <button className="flex items-center border border-input hover:bg-accent hover:text-accent-foreground p-4 relative h-8 justify-start rounded-lg bg-background text-sm text-muted-foreground shadow-none w-40 sm:w-72">
30
+ <div className="flex items-center gap-2 flex-grow">
31
+ <SearchIcon size={14} />
32
+ Search
33
+ </div>
34
+ <kbd className="absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border border-border bg-muted px-1.5 font-mono text-[11px] font-medium opacity-100 sm:flex">
35
+ ⌘K
36
+ </kbd>
37
+ </button>
38
+ </div>
39
+ <div className="items-center justify-self-end text-sm hidden lg:flex">
40
+ {!isLoggedIn ? (
41
+ <button
42
+ className="cursor-pointer hover:bg-secondary p-1 px-2 mx-2 rounded"
43
+ onClick={logout}
44
+ >
45
+ Logout {email ? `(${email})` : null}
46
+ </button>
47
+ ) : (
48
+ <button
49
+ className="cursor-pointer hover:bg-secondary p-1 px-2 mx-2 rounded"
50
+ onClick={login}
51
+ >
52
+ Login
53
+ </button>
54
+ )}
55
+
56
+ <button
57
+ className="cursor-pointer hover:bg-secondary p-2.5 -m-2.5 rounded-full"
58
+ onClick={toggleTheme}
59
+ >
60
+ <ThemeIcon size={18} />
61
+ </button>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ <TopNavigation />
66
+ </div>
67
+ </header>
68
+ );
69
+ });
@@ -0,0 +1,56 @@
1
+ import { Suspense, useEffect, useRef, type ReactNode } from "react";
2
+ import { Outlet, useLocation } from "react-router-dom";
3
+ import { Helmet } from "../core/helmet.js";
4
+ import { useScrollToAnchor } from "../util/useScrollToAnchor.js";
5
+ import { useScrollToTop } from "../util/useScrollToTop.js";
6
+ import { Header } from "./Header.js";
7
+ import { useDevPortal } from "./context/DevPortalProvider.js";
8
+ import { useViewportAnchor } from "./context/ViewportAnchorContext.js";
9
+ import { SideNavigation } from "./navigation/SideNavigation.js";
10
+ import { SideNavigationWrapper } from "./navigation/SideNavigationWrapper.js";
11
+
12
+ export const Layout = ({ children }: { children?: ReactNode }) => {
13
+ const location = useLocation();
14
+ const { setActiveAnchor } = useViewportAnchor();
15
+ const { meta, handleAuthenticationResponse } = useDevPortal();
16
+
17
+ useEffect(() => {
18
+ void handleAuthenticationResponse(location);
19
+ }, [handleAuthenticationResponse, location]);
20
+
21
+ useScrollToAnchor();
22
+ useScrollToTop();
23
+
24
+ const previousLocationPath = useRef(location.pathname);
25
+
26
+ useEffect(() => {
27
+ // always reset on location change
28
+ if (location.pathname !== previousLocationPath.current) {
29
+ setActiveAnchor("");
30
+ }
31
+ previousLocationPath.current = location.pathname;
32
+ }, [location.pathname, setActiveAnchor]);
33
+
34
+ return (
35
+ <>
36
+ <Helmet titleTemplate={meta?.pageTitle}>
37
+ <title>Home</title>
38
+ {meta?.description && (
39
+ <meta name="description" content={meta.description} />
40
+ )}
41
+ {meta?.favicon && <link rel="icon" href={meta.favicon} />}
42
+ </Helmet>
43
+ <Header />
44
+ <div className="max-w-screen-2xl mx-auto pt-[--header-height] px-10 lg:px-12">
45
+ <Suspense
46
+ fallback={<SideNavigationWrapper>Loading...</SideNavigationWrapper>}
47
+ >
48
+ <SideNavigation />
49
+ </Suspense>
50
+ <main className="dark:border-white/10 lg:overflow-visible translate-x-0 lg:w-[calc(100%-var(--side-nav-width))] lg:translate-x-[--side-nav-width] pl-12">
51
+ {children ?? <Outlet />}
52
+ </main>
53
+ </div>
54
+ </>
55
+ );
56
+ };
@@ -0,0 +1,37 @@
1
+ import ReactMarkdown from "react-markdown";
2
+ import remarkGfm from "remark-gfm";
3
+ import { visit } from "unist-util-visit";
4
+ import { MdxComponents } from "../util/MdxComponents.js";
5
+
6
+ // same as in packages/dev-portal/framework/vite.ts
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ const rehypeCodeBlockPlugin = () => (tree: any) => {
9
+ visit(tree, "element", (node, _index, parent) => {
10
+ if (node.tagName === "code") {
11
+ node.properties.inline = parent?.tagName !== "pre";
12
+ }
13
+ });
14
+ };
15
+
16
+ const remarkPlugins = [remarkGfm];
17
+ const rehypePlugins = [rehypeCodeBlockPlugin];
18
+
19
+ // other styles are defined in main.css .prose
20
+ export const ProseClasses = "prose dark:prose-invert prose-neutral";
21
+
22
+ export const Markdown = ({
23
+ content,
24
+ className,
25
+ }: {
26
+ content: string;
27
+ className?: string;
28
+ }) => (
29
+ <ReactMarkdown
30
+ remarkPlugins={remarkPlugins}
31
+ rehypePlugins={rehypePlugins}
32
+ components={MdxComponents}
33
+ className={className}
34
+ >
35
+ {content}
36
+ </ReactMarkdown>
37
+ );