zudoku 0.0.0-fix-firebase-export.2e421fda → 0.0.0-fix-circular-ref-false-positives.zbe02c6a6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/main.d.ts +6 -6
- package/dist/cli/common/version-check.js +12 -3
- package/dist/cli/common/version-check.js.map +1 -1
- package/dist/config/loader.js +3 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/config/validators/InputNavigationSchema.d.ts +77 -75
- package/dist/config/validators/InputNavigationSchema.js +1 -0
- package/dist/config/validators/InputNavigationSchema.js.map +1 -1
- package/dist/config/validators/NavigationSchema.js +6 -1
- package/dist/config/validators/NavigationSchema.js.map +1 -1
- package/dist/config/validators/validate.d.ts +59 -14
- package/dist/config/validators/validate.js +7 -5
- package/dist/config/validators/validate.js.map +1 -1
- package/dist/flat-config.d.ts +29 -27
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/auth/issuer.js +1 -1
- package/dist/lib/auth/issuer.js.map +1 -1
- package/dist/lib/authentication/authentication.d.ts +3 -2
- package/dist/lib/authentication/components/CallbackHandler.js +1 -1
- package/dist/lib/authentication/components/CallbackHandler.js.map +1 -1
- package/dist/lib/authentication/components/SignIn.js +4 -2
- package/dist/lib/authentication/components/SignIn.js.map +1 -1
- package/dist/lib/authentication/components/SignUp.js +4 -2
- package/dist/lib/authentication/components/SignUp.js.map +1 -1
- package/dist/lib/authentication/hook.d.ts +2 -0
- package/dist/lib/authentication/hook.js +10 -0
- package/dist/lib/authentication/hook.js.map +1 -1
- package/dist/lib/authentication/providers/auth0.js +11 -7
- package/dist/lib/authentication/providers/auth0.js.map +1 -1
- package/dist/lib/authentication/providers/clerk.js +0 -22
- package/dist/lib/authentication/providers/clerk.js.map +1 -1
- package/dist/lib/authentication/providers/firebase.js +67 -9
- package/dist/lib/authentication/providers/firebase.js.map +1 -1
- package/dist/lib/authentication/providers/supabase.js +6 -15
- package/dist/lib/authentication/providers/supabase.js.map +1 -1
- package/dist/lib/authentication/ui/EmailVerificationUi.d.ts +4 -0
- package/dist/lib/authentication/ui/EmailVerificationUi.js +34 -0
- package/dist/lib/authentication/ui/EmailVerificationUi.js.map +1 -0
- package/dist/lib/authentication/ui/ZudokuAuthUi.d.ts +7 -2
- package/dist/lib/authentication/ui/ZudokuAuthUi.js +48 -12
- package/dist/lib/authentication/ui/ZudokuAuthUi.js.map +1 -1
- package/dist/lib/authentication/utils/relativeRedirectUrl.d.ts +1 -0
- package/dist/lib/authentication/utils/relativeRedirectUrl.js +8 -0
- package/dist/lib/authentication/utils/relativeRedirectUrl.js.map +1 -0
- package/dist/lib/components/Pagination.js +2 -2
- package/dist/lib/components/Pagination.js.map +1 -1
- package/dist/lib/components/index.d.ts +5 -0
- package/dist/lib/components/index.js +4 -0
- package/dist/lib/components/index.js.map +1 -1
- package/dist/lib/components/navigation/NavigationItem.js +2 -2
- package/dist/lib/components/navigation/NavigationItem.js.map +1 -1
- package/dist/lib/core/RouteGuard.js +12 -7
- package/dist/lib/core/RouteGuard.js.map +1 -1
- package/dist/lib/core/plugins.d.ts +11 -1
- package/dist/lib/core/plugins.js +1 -0
- package/dist/lib/core/plugins.js.map +1 -1
- package/dist/lib/core/react-query.d.ts +1 -0
- package/dist/lib/core/react-query.js +2 -0
- package/dist/lib/core/react-query.js.map +1 -0
- package/dist/lib/core/transform-config.d.ts +2 -0
- package/dist/lib/core/transform-config.js +22 -0
- package/dist/lib/core/transform-config.js.map +1 -0
- package/dist/lib/errors/ErrorMessage.d.ts +3 -0
- package/dist/lib/errors/ErrorMessage.js +16 -0
- package/dist/lib/errors/ErrorMessage.js.map +1 -0
- package/dist/lib/hooks/index.d.ts +2 -0
- package/dist/lib/oas/graphql/circular.d.ts +2 -0
- package/dist/lib/oas/graphql/circular.js +21 -16
- package/dist/lib/oas/graphql/circular.js.map +1 -1
- package/dist/lib/oas/graphql/circular.test.d.ts +1 -0
- package/dist/lib/oas/graphql/circular.test.js +183 -0
- package/dist/lib/oas/graphql/circular.test.js.map +1 -0
- package/dist/lib/oas/graphql/index.js +7 -3
- package/dist/lib/oas/graphql/index.js.map +1 -1
- package/dist/lib/plugins/api-keys/SettingsApiKeys.js +9 -172
- package/dist/lib/plugins/api-keys/SettingsApiKeys.js.map +1 -1
- package/dist/lib/plugins/api-keys/index.d.ts +11 -4
- package/dist/lib/plugins/api-keys/index.js +36 -22
- package/dist/lib/plugins/api-keys/index.js.map +1 -1
- package/dist/lib/plugins/api-keys/settings/ApiKeyItem.d.ts +12 -0
- package/dist/lib/plugins/api-keys/settings/ApiKeyItem.js +133 -0
- package/dist/lib/plugins/api-keys/settings/ApiKeyItem.js.map +1 -0
- package/dist/lib/plugins/api-keys/settings/ApiKeyList.d.ts +4 -0
- package/dist/lib/plugins/api-keys/settings/ApiKeyList.js +33 -0
- package/dist/lib/plugins/api-keys/settings/ApiKeyList.js.map +1 -0
- package/dist/lib/plugins/api-keys/settings/RevealApiKey.d.ts +6 -0
- package/dist/lib/plugins/api-keys/settings/RevealApiKey.js +39 -0
- package/dist/lib/plugins/api-keys/settings/RevealApiKey.js.map +1 -0
- package/dist/lib/plugins/openapi/OasProvider.js +6 -2
- package/dist/lib/plugins/openapi/OasProvider.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationList.js +4 -4
- package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
- package/dist/lib/plugins/openapi/ParamInfos.js +1 -0
- package/dist/lib/plugins/openapi/ParamInfos.js.map +1 -1
- package/dist/lib/plugins/openapi/Sidecar.js +3 -2
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/interfaces.d.ts +3 -0
- package/dist/lib/plugins/openapi/schema/SchemaView.js +1 -1
- package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/utils.js +11 -3
- package/dist/lib/plugins/openapi/schema/utils.js.map +1 -1
- package/dist/lib/plugins/openapi/util/createHttpSnippet.js +24 -1
- package/dist/lib/plugins/openapi/util/createHttpSnippet.js.map +1 -1
- package/dist/lib/plugins/openapi/util/getRoutes.d.ts +3 -0
- package/dist/lib/plugins/openapi/util/getRoutes.js +2 -1
- package/dist/lib/plugins/openapi/util/getRoutes.js.map +1 -1
- package/dist/lib/ui/Button.js +1 -1
- package/dist/lib/ui/Button.js.map +1 -1
- package/dist/lib/ui/Command.d.ts +3 -3
- package/dist/lib/util/invariant.d.ts +1 -1
- package/dist/lib/util/invariant.js +2 -2
- package/dist/lib/util/invariant.js.map +1 -1
- package/dist/vite/api/SchemaManager.d.ts +12 -1
- package/dist/vite/api/SchemaManager.js +31 -14
- package/dist/vite/api/SchemaManager.js.map +1 -1
- package/dist/vite/api/SchemaManager.test.js +44 -0
- package/dist/vite/api/SchemaManager.test.js.map +1 -1
- package/dist/vite/config.js +10 -4
- package/dist/vite/config.js.map +1 -1
- package/dist/vite/error-handler.js +1 -5
- package/dist/vite/error-handler.js.map +1 -1
- package/dist/vite/mdx/remark-link-rewrite.js +1 -1
- package/dist/vite/plugin-api-keys.js +5 -1
- package/dist/vite/plugin-api-keys.js.map +1 -1
- package/dist/vite/plugin-api.js +5 -3
- package/dist/vite/plugin-api.js.map +1 -1
- package/dist/vite/plugin-markdown-export.js +1 -1
- package/dist/vite/plugin-markdown-export.js.map +1 -1
- package/dist/vite/prerender/utils.js +9 -3
- package/dist/vite/prerender/utils.js.map +1 -1
- package/dist/vite/prerender/worker.js +3 -0
- package/dist/vite/prerender/worker.js.map +1 -1
- package/dist/vite/zuplo.d.ts +13 -0
- package/dist/vite/zuplo.js +15 -0
- package/dist/vite/zuplo.js.map +1 -0
- package/lib/{ActionButton-DUgvSylL.js → ActionButton-B0CXL1Lq.js} +3 -3
- package/lib/{ActionButton-DUgvSylL.js.map → ActionButton-B0CXL1Lq.js.map} +1 -1
- package/lib/{Button-CynVW1JV.js → Button-GUVe7pmt.js} +8 -7
- package/lib/{Button-CynVW1JV.js.map → Button-GUVe7pmt.js.map} +1 -1
- package/lib/{Card-KFniaZn5.js → Card-DCdq37aA.js} +2 -2
- package/lib/{Card-KFniaZn5.js.map → Card-DCdq37aA.js.map} +1 -1
- package/lib/{ClaudeLogo-B4Xxt-x_.js → ClaudeLogo-DJ9bU-sO.js} +22 -22
- package/lib/ClaudeLogo-DJ9bU-sO.js.map +1 -0
- package/lib/{Command-BpT1iBE6.js → Command-N6VujV30.js} +3 -3
- package/lib/{Command-BpT1iBE6.js.map → Command-N6VujV30.js.map} +1 -1
- package/lib/{Dialog-BQciPiHN.js → Dialog-hlvmmQ_c.js} +2 -2
- package/lib/{Dialog-BQciPiHN.js.map → Dialog-hlvmmQ_c.js.map} +1 -1
- package/lib/{Drawer-Ci7XwhqT.js → Drawer-Ch7927PF.js} +7 -7
- package/lib/{Drawer-Ci7XwhqT.js.map → Drawer-Ch7927PF.js.map} +1 -1
- package/lib/{DropdownMenu-C8SX_-S_.js → DropdownMenu-DN0jNrjj.js} +2 -2
- package/lib/{DropdownMenu-C8SX_-S_.js.map → DropdownMenu-DN0jNrjj.js.map} +1 -1
- package/lib/Frame-DKlOmSkU.js +205 -0
- package/lib/Frame-DKlOmSkU.js.map +1 -0
- package/lib/HydrationBoundary-CNF2ZV3E.js +601 -0
- package/lib/HydrationBoundary-CNF2ZV3E.js.map +1 -0
- package/lib/{IndexingDialog-B5zCiUKr.js → IndexingDialog-D0YdGfbn.js} +3 -3
- package/lib/{IndexingDialog-B5zCiUKr.js.map → IndexingDialog-D0YdGfbn.js.map} +1 -1
- package/lib/Input-Cx-GeKoF.js +22 -0
- package/lib/Input-Cx-GeKoF.js.map +1 -0
- package/lib/{MdxPage-BagO2c-n.js → MdxPage-stpAoBtx.js} +11 -11
- package/lib/{MdxPage-BagO2c-n.js.map → MdxPage-stpAoBtx.js.map} +1 -1
- package/lib/{Mermaid-D_VSX7_Q.js → Mermaid-Koc3z8mU.js} +4 -4
- package/lib/{Mermaid-D_VSX7_Q.js.map → Mermaid-Koc3z8mU.js.map} +1 -1
- package/lib/{OAuthErrorPage-Fq54RLgt.js → OAuthErrorPage-DJ811Bn_.js} +15 -15
- package/lib/OAuthErrorPage-DJ811Bn_.js.map +1 -0
- package/lib/OasProvider-B2KxIBsI.js +48 -0
- package/lib/OasProvider-B2KxIBsI.js.map +1 -0
- package/lib/{OperationList-C0jiEaG5.js → OperationList-C2tAfThO.js} +1558 -1543
- package/lib/{OperationList-C0jiEaG5.js.map → OperationList-C2tAfThO.js.map} +1 -1
- package/lib/RouteGuard--A04ESy8.js +77 -0
- package/lib/RouteGuard--A04ESy8.js.map +1 -0
- package/lib/{SchemaList-BU0zCHn9.js → SchemaList-Ep8DleP_.js} +9 -9
- package/lib/{SchemaList-BU0zCHn9.js.map → SchemaList-Ep8DleP_.js.map} +1 -1
- package/lib/SchemaView-BpaEKRYx.js +438 -0
- package/lib/SchemaView-BpaEKRYx.js.map +1 -0
- package/lib/{Select-CkxXP5I7.js → Secret-BDBqq4p3.js} +122 -122
- package/lib/Secret-BDBqq4p3.js.map +1 -0
- package/lib/{Separator-CTPSeW1S.js → Separator-BXt1LYnm.js} +2 -2
- package/lib/{Separator-CTPSeW1S.js.map → Separator-BXt1LYnm.js.map} +1 -1
- package/lib/SignUp-DCBViNUi.js +50 -0
- package/lib/SignUp-DCBViNUi.js.map +1 -0
- package/lib/{SyntaxHighlight-Kdyskw3C.js → SyntaxHighlight-Dshjn3Zf.js} +1749 -1723
- package/lib/SyntaxHighlight-Dshjn3Zf.js.map +1 -0
- package/lib/{Toc-DJxFPfcS.js → Toc-Cgz6CPiE.js} +3 -3
- package/lib/{Toc-DJxFPfcS.js.map → Toc-Cgz6CPiE.js.map} +1 -1
- package/lib/ZudokuContext-BZB1TWdT.js +387 -0
- package/lib/ZudokuContext-BZB1TWdT.js.map +1 -0
- package/lib/{___vite-browser-external_commonjs-proxy-Cga3HsWk.js → ___vite-browser-external_commonjs-proxy-BttVsNON.js} +2 -2
- package/lib/___vite-browser-external_commonjs-proxy-BttVsNON.js.map +1 -0
- package/lib/chunk-EPOLDU6W-C6C8jAwd.js +8558 -0
- package/lib/chunk-EPOLDU6W-C6C8jAwd.js.map +1 -0
- package/lib/{circular-CzWF1hj5.js → circular-CG3e0_Uz.js} +1689 -1686
- package/lib/{circular-CzWF1hj5.js.map → circular-CG3e0_Uz.js.map} +1 -1
- package/lib/{cn-dYga0KKN.js → cn-5-Gd1Dss.js} +531 -498
- package/lib/cn-5-Gd1Dss.js.map +1 -0
- package/lib/{createServer-BIr2_tGn.js → createServer-CNeRqj98.js} +12 -12
- package/lib/{createServer-BIr2_tGn.js.map → createServer-CNeRqj98.js.map} +1 -1
- package/lib/createVariantComponent-Dc0vtOvr.js +18 -0
- package/lib/createVariantComponent-Dc0vtOvr.js.map +1 -0
- package/lib/{errors-Bs4duWDy.js → errors-b9I-fAOY.js} +3 -3
- package/lib/{errors-Bs4duWDy.js.map → errors-b9I-fAOY.js.map} +1 -1
- package/lib/{firebase-Cax7HPzn.js → firebase-BCXX7Qv5.js} +1579 -1325
- package/lib/firebase-BCXX7Qv5.js.map +1 -0
- package/lib/hook-BGlHBdET.js +52 -0
- package/lib/hook-BGlHBdET.js.map +1 -0
- package/lib/{ErrorAlert-DrOR8w3f.js → index-CL8eDnQW.js} +5473 -4433
- package/lib/index-CL8eDnQW.js.map +1 -0
- package/lib/index-CrcNWbel.js.map +1 -1
- package/lib/{index-Css56y3F.js → index-DBjOT2H1.js} +4 -4
- package/lib/{index-Css56y3F.js.map → index-DBjOT2H1.js.map} +1 -1
- package/lib/{index-0oT9beQN.js → index-I3kmZ7tG.js} +152 -148
- package/lib/{index-0oT9beQN.js.map → index-I3kmZ7tG.js.map} +1 -1
- package/lib/{index-Bh-MffiL.js → index-UOLtazB8.js} +2 -2
- package/lib/{index-Bh-MffiL.js.map → index-UOLtazB8.js.map} +1 -1
- package/lib/index.esm-BYObtETB.js.map +1 -1
- package/lib/{index.esm-DtzT_KoE.js → index.esm-B_0dvNjB.js} +2 -2
- package/lib/{index.esm-DtzT_KoE.js.map → index.esm-B_0dvNjB.js.map} +1 -1
- package/lib/{index.esm-DDENMN4y.js → index.esm-C5CBsVzN.js} +16 -14
- package/lib/index.esm-C5CBsVzN.js.map +1 -0
- package/lib/{invariant-CGOLuIIz.js → invariant-BJAl77rw.js} +4 -4
- package/lib/invariant-BJAl77rw.js.map +1 -0
- package/lib/jsx-runtime-BzflLqGi.js.map +1 -1
- package/lib/{mutation-BoVlx8yA.js → mutation-BISOc7OM.js} +70 -44
- package/lib/mutation-BISOc7OM.js.map +1 -0
- package/lib/ui/Accordion.js +1 -1
- package/lib/ui/ActionButton.js +2 -2
- package/lib/ui/Alert.js +1 -1
- package/lib/ui/AlertDialog.js +1 -1
- package/lib/ui/Badge.js +1 -1
- package/lib/ui/Breadcrumb.js +1 -1
- package/lib/ui/Button.js +7 -6
- package/lib/ui/Button.js.map +1 -1
- package/lib/ui/ButtonGroup.js +1 -1
- package/lib/ui/Callout.js +1 -1
- package/lib/ui/Card.js +1 -1
- package/lib/ui/Carousel.js +1 -1
- package/lib/ui/Carousel.js.map +1 -1
- package/lib/ui/Checkbox.js +1 -1
- package/lib/ui/CodeBlock.js +1 -1
- package/lib/ui/Command.js +2 -2
- package/lib/ui/Dialog.js +1 -1
- package/lib/ui/Drawer.js +3 -3
- package/lib/ui/DropdownMenu.js +1 -1
- package/lib/ui/EmbeddedCodeBlock.js +1 -1
- package/lib/ui/Form.js +1 -1
- package/lib/ui/Frame.js +1 -1
- package/lib/ui/HoverCard.js +1 -1
- package/lib/ui/Input.js +1 -1
- package/lib/ui/Item.js +1 -1
- package/lib/ui/Label.js +1 -1
- package/lib/ui/NativeSelect.js +1 -1
- package/lib/ui/Pagination.js +1 -1
- package/lib/ui/Popover.js +1 -1
- package/lib/ui/Progress.js +1 -1
- package/lib/ui/RadioGroup.js +1 -1
- package/lib/ui/ScrollArea.js +1 -1
- package/lib/ui/Secret.js +1 -1
- package/lib/ui/Separator.js +1 -1
- package/lib/ui/Skeleton.js +1 -1
- package/lib/ui/Slider.js +1 -1
- package/lib/ui/Switch.js +1 -1
- package/lib/ui/SyntaxHighlight.js +3 -3
- package/lib/ui/Tabs.js +1 -1
- package/lib/ui/Textarea.js +1 -1
- package/lib/ui/Toggle.js +1 -1
- package/lib/ui/ToggleGroup.js +1 -1
- package/lib/ui/Value.js +1 -1
- package/lib/ui/util.js +1 -1
- package/lib/{useMutation-C6RqWmTS.js → useMutation-CFMGlAMW.js} +39 -17
- package/lib/useMutation-CFMGlAMW.js.map +1 -0
- package/lib/useSuspenseQuery-CSB_rVek.js +1226 -0
- package/lib/useSuspenseQuery-CSB_rVek.js.map +1 -0
- package/lib/zudoku.__internal.js +826 -1325
- package/lib/zudoku.__internal.js.map +1 -1
- package/lib/zudoku.auth-auth0.js +16 -16
- package/lib/zudoku.auth-auth0.js.map +1 -1
- package/lib/zudoku.auth-azureb2c.js +4 -4
- package/lib/zudoku.auth-clerk.js +52 -75
- package/lib/zudoku.auth-clerk.js.map +1 -1
- package/lib/zudoku.auth-firebase.js +6 -5
- package/lib/zudoku.auth-firebase.js.map +1 -1
- package/lib/zudoku.auth-openid.js +5 -5
- package/lib/zudoku.auth-supabase.js +31 -40
- package/lib/zudoku.auth-supabase.js.map +1 -1
- package/lib/zudoku.components.js +23 -21
- package/lib/zudoku.hooks.js +3 -3
- package/lib/zudoku.mermaid.js +3 -3
- package/lib/zudoku.plugin-api-catalog.js +8 -8
- package/lib/zudoku.plugin-api-keys.js +607 -552
- package/lib/zudoku.plugin-api-keys.js.map +1 -1
- package/lib/zudoku.plugin-custom-pages.js +1 -1
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +3 -3
- package/lib/zudoku.plugin-redirect.js +1 -1
- package/lib/zudoku.plugin-search-pagefind.js +30 -29
- package/lib/zudoku.plugin-search-pagefind.js.map +1 -1
- package/lib/zudoku.plugins.js +9 -8
- package/lib/zudoku.plugins.js.map +1 -1
- package/lib/zudoku.react-query.js +440 -0
- package/lib/zudoku.react-query.js.map +1 -0
- package/lib/zudoku.router.js +1130 -1404
- package/lib/zudoku.router.js.map +1 -1
- package/package.json +28 -21
- package/src/lib/auth/issuer.ts +1 -1
- package/src/lib/authentication/authentication.ts +8 -2
- package/src/lib/authentication/components/CallbackHandler.tsx +1 -1
- package/src/lib/authentication/components/SignIn.tsx +5 -2
- package/src/lib/authentication/components/SignUp.tsx +5 -2
- package/src/lib/authentication/hook.ts +16 -0
- package/src/lib/authentication/providers/auth0.tsx +15 -9
- package/src/lib/authentication/providers/clerk.tsx +0 -26
- package/src/lib/authentication/providers/firebase.tsx +98 -6
- package/src/lib/authentication/providers/supabase.tsx +6 -15
- package/src/lib/authentication/ui/EmailVerificationUi.tsx +129 -0
- package/src/lib/authentication/ui/ZudokuAuthUi.tsx +181 -39
- package/src/lib/authentication/utils/relativeRedirectUrl.ts +12 -0
- package/src/lib/components/Pagination.tsx +4 -5
- package/src/lib/components/index.ts +4 -0
- package/src/lib/components/navigation/NavigationItem.tsx +9 -3
- package/src/lib/core/RouteGuard.tsx +30 -24
- package/src/lib/core/plugins.ts +21 -1
- package/src/lib/core/react-query.ts +1 -0
- package/src/lib/core/transform-config.ts +29 -0
- package/src/lib/errors/ErrorMessage.tsx +38 -0
- package/src/lib/oas/graphql/circular.test.ts +221 -0
- package/src/lib/oas/graphql/circular.ts +31 -18
- package/src/lib/oas/graphql/index.ts +7 -3
- package/src/lib/plugins/api-keys/SettingsApiKeys.tsx +36 -476
- package/src/lib/plugins/api-keys/index.tsx +76 -32
- package/src/lib/plugins/api-keys/settings/ApiKeyItem.tsx +342 -0
- package/src/lib/plugins/api-keys/settings/ApiKeyList.tsx +67 -0
- package/src/lib/plugins/api-keys/settings/RevealApiKey.tsx +124 -0
- package/src/lib/plugins/openapi/OasProvider.tsx +10 -2
- package/src/lib/plugins/openapi/OperationList.tsx +4 -4
- package/src/lib/plugins/openapi/ParamInfos.tsx +1 -0
- package/src/lib/plugins/openapi/Sidecar.tsx +3 -2
- package/src/lib/plugins/openapi/interfaces.ts +6 -1
- package/src/lib/plugins/openapi/schema/SchemaView.tsx +6 -4
- package/src/lib/plugins/openapi/schema/utils.ts +15 -4
- package/src/lib/plugins/openapi/util/createHttpSnippet.ts +29 -1
- package/src/lib/plugins/openapi/util/getRoutes.tsx +4 -1
- package/src/lib/ui/Button.tsx +1 -0
- package/src/lib/util/invariant.ts +2 -1
- package/src/shiki/langs/c3.js +1 -0
- package/src/shiki/langs/gn.js +1 -0
- package/src/shiki/langs/moonbit.js +1 -0
- package/lib/ClaudeLogo-B4Xxt-x_.js.map +0 -1
- package/lib/ErrorAlert-DrOR8w3f.js.map +0 -1
- package/lib/OAuthErrorPage-Fq54RLgt.js.map +0 -1
- package/lib/OasProvider-DPH8mwDa.js +0 -40
- package/lib/OasProvider-DPH8mwDa.js.map +0 -1
- package/lib/RouteGuard-9wjejsKm.js +0 -77
- package/lib/RouteGuard-9wjejsKm.js.map +0 -1
- package/lib/RouterError-DSLXagd5.js +0 -42
- package/lib/RouterError-DSLXagd5.js.map +0 -1
- package/lib/SchemaView-DVae4RO2.js +0 -597
- package/lib/SchemaView-DVae4RO2.js.map +0 -1
- package/lib/Select-CkxXP5I7.js.map +0 -1
- package/lib/SignUp-BjS4ozA7.js +0 -50
- package/lib/SignUp-BjS4ozA7.js.map +0 -1
- package/lib/SyntaxHighlight-Kdyskw3C.js.map +0 -1
- package/lib/ZudokuContext-BXldanA8.js +0 -1508
- package/lib/ZudokuContext-BXldanA8.js.map +0 -1
- package/lib/___vite-browser-external_commonjs-proxy-Cga3HsWk.js.map +0 -1
- package/lib/chunk-PVWAREVJ-dLIqswPy.js +0 -7965
- package/lib/chunk-PVWAREVJ-dLIqswPy.js.map +0 -1
- package/lib/cn-dYga0KKN.js.map +0 -1
- package/lib/createVariantComponent-B9_dVBvu.js +0 -35
- package/lib/createVariantComponent-B9_dVBvu.js.map +0 -1
- package/lib/firebase-Cax7HPzn.js.map +0 -1
- package/lib/hook-BNxidGQq.js +0 -40
- package/lib/hook-BNxidGQq.js.map +0 -1
- package/lib/index-CCmMJp02.js +0 -1059
- package/lib/index-CCmMJp02.js.map +0 -1
- package/lib/index.esm-DDENMN4y.js.map +0 -1
- package/lib/invariant-CGOLuIIz.js.map +0 -1
- package/lib/mutation-BoVlx8yA.js.map +0 -1
- package/lib/useMutation-C6RqWmTS.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { KeyRoundIcon } from "lucide-react";
|
|
2
2
|
import type { RouteObject } from "react-router";
|
|
3
|
+
import type { ApiKeysOptions } from "../../../config/validators/validate.js";
|
|
3
4
|
import type { UseAuthReturn } from "../../authentication/hook.js";
|
|
4
5
|
import type {
|
|
5
6
|
ApiIdentityPlugin,
|
|
@@ -7,9 +8,7 @@ import type {
|
|
|
7
8
|
ZudokuPlugin,
|
|
8
9
|
} from "../../core/plugins.js";
|
|
9
10
|
import type { ZudokuContext } from "../../core/ZudokuContext.js";
|
|
10
|
-
import { RouterError } from "../../errors/RouterError.js";
|
|
11
11
|
import invariant from "../../util/invariant.js";
|
|
12
|
-
import { ProtectedRoute } from "./ProtectedRoute.js";
|
|
13
12
|
import { SettingsApiKeys } from "./SettingsApiKeys.js";
|
|
14
13
|
|
|
15
14
|
const DEFAULT_API_KEY_ENDPOINT = "https://api.zuploedge.com/v2/client";
|
|
@@ -38,9 +37,11 @@ export type ApiKeyService = {
|
|
|
38
37
|
}) => Promise<void>;
|
|
39
38
|
};
|
|
40
39
|
|
|
41
|
-
export type ApiKeyPluginOptions =
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
export type ApiKeyPluginOptions = ApiKeyService | DefaultApiKeyServiceOptions;
|
|
41
|
+
|
|
42
|
+
type DefaultApiKeyServiceOptions = {
|
|
43
|
+
deploymentName?: string;
|
|
44
|
+
} & Partial<ApiKeyService>;
|
|
44
45
|
|
|
45
46
|
export interface ApiKey {
|
|
46
47
|
id: string;
|
|
@@ -80,12 +81,19 @@ const throwIfProblemJson = async (response: Response) => {
|
|
|
80
81
|
}
|
|
81
82
|
};
|
|
82
83
|
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
const developerHintOptions = {
|
|
85
|
+
developerHint:
|
|
86
|
+
"This project is not linked to a Zuplo deployment. Run `zuplo link` to get started with API Keys.",
|
|
87
|
+
title: "Not linked to a Zuplo deployment",
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const createZuploService = ({
|
|
91
|
+
deploymentName,
|
|
92
|
+
...options
|
|
93
|
+
}: DefaultApiKeyServiceOptions): ApiKeyService => {
|
|
87
94
|
return {
|
|
88
95
|
deleteKey: async (consumerId, keyId, context) => {
|
|
96
|
+
invariant(deploymentName, "Cannot delete API key.", developerHintOptions);
|
|
89
97
|
const request = new Request(
|
|
90
98
|
DEFAULT_API_KEY_ENDPOINT +
|
|
91
99
|
`/${deploymentName}/consumers/${consumerId}/keys/${keyId}`,
|
|
@@ -93,17 +101,20 @@ const createDefaultHandler = (
|
|
|
93
101
|
method: "DELETE",
|
|
94
102
|
},
|
|
95
103
|
);
|
|
96
|
-
await context.signRequest(request);
|
|
97
|
-
const response = await fetch(request);
|
|
104
|
+
const response = await fetch(await context.signRequest(request));
|
|
98
105
|
await throwIfProblemJson(response);
|
|
99
106
|
invariant(response.ok, "Failed to delete API key");
|
|
100
107
|
},
|
|
101
108
|
updateConsumer: async (consumer, context) => {
|
|
109
|
+
invariant(
|
|
110
|
+
deploymentName,
|
|
111
|
+
"Cannot update API key description.",
|
|
112
|
+
developerHintOptions,
|
|
113
|
+
);
|
|
102
114
|
const response = await fetch(
|
|
103
115
|
await context.signRequest(
|
|
104
116
|
new Request(
|
|
105
|
-
DEFAULT_API_KEY_ENDPOINT
|
|
106
|
-
`/${deploymentName}/consumers/${consumer.id}`,
|
|
117
|
+
`${DEFAULT_API_KEY_ENDPOINT}/${deploymentName}/consumers/${consumer.id}`,
|
|
107
118
|
{
|
|
108
119
|
method: "PATCH",
|
|
109
120
|
headers: {
|
|
@@ -120,11 +131,11 @@ const createDefaultHandler = (
|
|
|
120
131
|
invariant(response.ok, "Failed to update API key description");
|
|
121
132
|
},
|
|
122
133
|
rollKey: async (consumerId, context) => {
|
|
134
|
+
invariant(deploymentName, "Cannot roll API key.", developerHintOptions);
|
|
123
135
|
const response = await fetch(
|
|
124
136
|
await context.signRequest(
|
|
125
137
|
new Request(
|
|
126
|
-
DEFAULT_API_KEY_ENDPOINT
|
|
127
|
-
`/${deploymentName}/consumers/${consumerId}/roll-key`,
|
|
138
|
+
`${DEFAULT_API_KEY_ENDPOINT}/${deploymentName}/consumers/${consumerId}/roll-key`,
|
|
128
139
|
{
|
|
129
140
|
method: "POST",
|
|
130
141
|
headers: {
|
|
@@ -136,9 +147,10 @@ const createDefaultHandler = (
|
|
|
136
147
|
),
|
|
137
148
|
);
|
|
138
149
|
await throwIfProblemJson(response);
|
|
139
|
-
invariant(response.ok, "Failed to
|
|
150
|
+
invariant(response.ok, "Failed to roll API key");
|
|
140
151
|
},
|
|
141
152
|
getConsumers: async (context) => {
|
|
153
|
+
invariant(deploymentName, "Cannot get API keys.", developerHintOptions);
|
|
142
154
|
const request = new Request(
|
|
143
155
|
`${DEFAULT_API_KEY_ENDPOINT}/${deploymentName}/consumers`,
|
|
144
156
|
);
|
|
@@ -154,6 +166,9 @@ const createDefaultHandler = (
|
|
|
154
166
|
id: string;
|
|
155
167
|
label?: string;
|
|
156
168
|
subject?: string;
|
|
169
|
+
createdOn?: string;
|
|
170
|
+
updatedOn?: string;
|
|
171
|
+
expiresOn?: string;
|
|
157
172
|
apiKeys: {
|
|
158
173
|
data: ApiKey[];
|
|
159
174
|
};
|
|
@@ -163,6 +178,9 @@ const createDefaultHandler = (
|
|
|
163
178
|
|
|
164
179
|
return data.data.map((consumer) => ({
|
|
165
180
|
id: consumer.id,
|
|
181
|
+
createdOn: consumer.createdOn,
|
|
182
|
+
updatedOn: consumer.updatedOn,
|
|
183
|
+
expiresOn: consumer.expiresOn,
|
|
166
184
|
label: consumer.label || consumer.subject || "API Key",
|
|
167
185
|
apiKeys: consumer.apiKeys.data,
|
|
168
186
|
key: consumer.apiKeys.data.at(0),
|
|
@@ -175,13 +193,40 @@ const createDefaultHandler = (
|
|
|
175
193
|
export const createApiKeyService = <T extends ApiKeyService>(service: T): T =>
|
|
176
194
|
service;
|
|
177
195
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
196
|
+
type InternalApiKeyPluginOptions = {
|
|
197
|
+
// The name of the Zuplo deployment
|
|
198
|
+
deploymentName?: string;
|
|
199
|
+
// Indicates that the plugin is running in Zuplo "mode"
|
|
200
|
+
isZuplo?: boolean;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
export const apiKeyPlugin = ({
|
|
204
|
+
deploymentName,
|
|
205
|
+
isZuplo,
|
|
206
|
+
...options
|
|
207
|
+
}: Omit<ApiKeysOptions, "enabled"> &
|
|
208
|
+
InternalApiKeyPluginOptions): ZudokuPlugin &
|
|
209
|
+
ApiIdentityPlugin &
|
|
210
|
+
ProfileMenuPlugin => {
|
|
211
|
+
if (isZuplo && !deploymentName) {
|
|
212
|
+
// biome-ignore lint/suspicious/noConsole: Important warning
|
|
213
|
+
console.warn(
|
|
214
|
+
"This project is not linked to a Zuplo deployment. Run `zuplo link` to get started.",
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const service = isZuplo
|
|
219
|
+
? createZuploService({ deploymentName, ...options })
|
|
220
|
+
: options;
|
|
221
|
+
|
|
222
|
+
if (!service.getConsumers) {
|
|
223
|
+
throw new Error("getConsumers is required when using the apiKeyPlugin");
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const verifiedService: ApiKeyService = {
|
|
227
|
+
...service,
|
|
228
|
+
getConsumers: service.getConsumers,
|
|
229
|
+
};
|
|
185
230
|
|
|
186
231
|
return {
|
|
187
232
|
getProfileMenuItems: () => [
|
|
@@ -195,7 +240,7 @@ export const apiKeyPlugin = (
|
|
|
195
240
|
|
|
196
241
|
getIdentities: async (context) => {
|
|
197
242
|
try {
|
|
198
|
-
const consumers = await
|
|
243
|
+
const consumers = await verifiedService.getConsumers(context);
|
|
199
244
|
|
|
200
245
|
return consumers.map((consumer) => ({
|
|
201
246
|
authorizeRequest: (request) => {
|
|
@@ -212,19 +257,18 @@ export const apiKeyPlugin = (
|
|
|
212
257
|
return [];
|
|
213
258
|
}
|
|
214
259
|
},
|
|
260
|
+
|
|
215
261
|
getRoutes: (): RouteObject[] => {
|
|
216
262
|
return [
|
|
217
263
|
{
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
children: [
|
|
221
|
-
{
|
|
222
|
-
path: "/settings/api-keys",
|
|
223
|
-
element: <SettingsApiKeys service={service} />,
|
|
224
|
-
},
|
|
225
|
-
],
|
|
264
|
+
path: "/settings/api-keys",
|
|
265
|
+
element: <SettingsApiKeys service={verifiedService} />,
|
|
226
266
|
},
|
|
227
267
|
];
|
|
228
268
|
},
|
|
269
|
+
|
|
270
|
+
getProtectedRoutes: () => {
|
|
271
|
+
return ["/settings/api-keys"];
|
|
272
|
+
},
|
|
229
273
|
};
|
|
230
274
|
};
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
2
|
+
import {
|
|
3
|
+
CheckIcon,
|
|
4
|
+
CircleSlashIcon,
|
|
5
|
+
PencilLineIcon,
|
|
6
|
+
RefreshCwIcon,
|
|
7
|
+
XIcon,
|
|
8
|
+
} from "lucide-react";
|
|
9
|
+
import { AnimatePresence } from "motion/react";
|
|
10
|
+
import { useState } from "react";
|
|
11
|
+
import { Alert, AlertTitle } from "zudoku/ui/Alert.js";
|
|
12
|
+
import { Button } from "zudoku/ui/Button.js";
|
|
13
|
+
import {
|
|
14
|
+
Dialog,
|
|
15
|
+
DialogClose,
|
|
16
|
+
DialogContent,
|
|
17
|
+
DialogDescription,
|
|
18
|
+
DialogFooter,
|
|
19
|
+
DialogHeader,
|
|
20
|
+
DialogTitle,
|
|
21
|
+
DialogTrigger,
|
|
22
|
+
} from "zudoku/ui/Dialog.js";
|
|
23
|
+
import {
|
|
24
|
+
Frame,
|
|
25
|
+
FrameDescription,
|
|
26
|
+
FrameHeader,
|
|
27
|
+
FramePanel,
|
|
28
|
+
FrameTitle,
|
|
29
|
+
} from "zudoku/ui/Frame.js";
|
|
30
|
+
import { Input } from "zudoku/ui/Input.js";
|
|
31
|
+
import { useZudoku } from "../../../components/context/ZudokuContext.js";
|
|
32
|
+
import type { ZudokuContext } from "../../../core/ZudokuContext.js";
|
|
33
|
+
import { cn } from "../../../util/cn.js";
|
|
34
|
+
import type { ApiConsumer } from "../index.js";
|
|
35
|
+
import { RevealApiKey } from "./RevealApiKey.js";
|
|
36
|
+
|
|
37
|
+
const ApiKeyItem = ({
|
|
38
|
+
consumer,
|
|
39
|
+
onUpdate,
|
|
40
|
+
onRollKey,
|
|
41
|
+
onDeleteKey,
|
|
42
|
+
}: {
|
|
43
|
+
consumer: ApiConsumer;
|
|
44
|
+
onUpdate?: (
|
|
45
|
+
data: { label: string; id: string },
|
|
46
|
+
context: ZudokuContext,
|
|
47
|
+
) => Promise<void>;
|
|
48
|
+
onRollKey?: (consumerId: string, context: ZudokuContext) => Promise<void>;
|
|
49
|
+
onDeleteKey?: (
|
|
50
|
+
consumerId: string,
|
|
51
|
+
keyId: string,
|
|
52
|
+
context: ZudokuContext,
|
|
53
|
+
) => Promise<void>;
|
|
54
|
+
}) => {
|
|
55
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
56
|
+
const [editingLabel, setEditingLabel] = useState(consumer.label);
|
|
57
|
+
const queryClient = useQueryClient();
|
|
58
|
+
const context = useZudoku();
|
|
59
|
+
|
|
60
|
+
const rollKeyMutation = useMutation({
|
|
61
|
+
mutationFn: async (id: string) => {
|
|
62
|
+
if (!onRollKey) {
|
|
63
|
+
throw new Error("rollKey not implemented");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return await onRollKey?.(id, context);
|
|
67
|
+
},
|
|
68
|
+
onSuccess: () =>
|
|
69
|
+
void queryClient.invalidateQueries({ queryKey: ["api-keys"] }),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const deleteKeyMutation = useMutation({
|
|
73
|
+
mutationFn: ({
|
|
74
|
+
consumerId,
|
|
75
|
+
keyId,
|
|
76
|
+
}: {
|
|
77
|
+
consumerId: string;
|
|
78
|
+
keyId: string;
|
|
79
|
+
}) => {
|
|
80
|
+
if (!onDeleteKey) {
|
|
81
|
+
throw new Error("deleteKey not implemented");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return onDeleteKey(consumerId, keyId, context);
|
|
85
|
+
},
|
|
86
|
+
onMutate: async ({ consumerId, keyId }) => {
|
|
87
|
+
await queryClient.cancelQueries({ queryKey: ["api-keys"] });
|
|
88
|
+
const previousData = queryClient.getQueryData<ApiConsumer[]>([
|
|
89
|
+
"api-keys",
|
|
90
|
+
]);
|
|
91
|
+
queryClient.setQueryData<ApiConsumer[]>(["api-keys"], (old) => {
|
|
92
|
+
if (!old) {
|
|
93
|
+
return old;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return old.map((consumer) => {
|
|
97
|
+
if (consumer.id === consumerId) {
|
|
98
|
+
return {
|
|
99
|
+
...consumer,
|
|
100
|
+
apiKeys: consumer.apiKeys.filter((key) => key.id !== keyId),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return consumer;
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
return { previousData };
|
|
108
|
+
},
|
|
109
|
+
onError: (_err, _variables, context) => {
|
|
110
|
+
if (context?.previousData) {
|
|
111
|
+
queryClient.setQueryData(["api-keys"], context.previousData);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
onSuccess: () => {
|
|
115
|
+
void queryClient.invalidateQueries({ queryKey: ["api-keys"] });
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const updateConsumerMutation = useMutation({
|
|
120
|
+
mutationFn: ({
|
|
121
|
+
consumerId,
|
|
122
|
+
label,
|
|
123
|
+
}: {
|
|
124
|
+
consumerId: string;
|
|
125
|
+
label: string;
|
|
126
|
+
}) => {
|
|
127
|
+
if (!onUpdate) {
|
|
128
|
+
throw new Error("updateConsumer not implemented");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return onUpdate({ id: consumerId, label }, context);
|
|
132
|
+
},
|
|
133
|
+
onMutate: async ({ consumerId, label }) => {
|
|
134
|
+
await queryClient.cancelQueries({ queryKey: ["api-keys"] });
|
|
135
|
+
|
|
136
|
+
const previousData = queryClient.getQueryData(["api-keys"]);
|
|
137
|
+
queryClient.setQueryData<ApiConsumer[]>(["api-keys"], (old) => {
|
|
138
|
+
if (!old) {
|
|
139
|
+
return old;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return old.map((consumer) => {
|
|
143
|
+
if (consumer.id === consumerId) {
|
|
144
|
+
return {
|
|
145
|
+
...consumer,
|
|
146
|
+
label,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return consumer;
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
return { previousData };
|
|
154
|
+
},
|
|
155
|
+
onError: (_err, _variables, context) => {
|
|
156
|
+
if (context?.previousData) {
|
|
157
|
+
queryClient.setQueryData(["api-keys"], context.previousData);
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
onSuccess: () => {
|
|
161
|
+
void queryClient.invalidateQueries({ queryKey: ["api-keys"] });
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const handleStartEdit = () => {
|
|
166
|
+
setIsEditing(true);
|
|
167
|
+
setEditingLabel(consumer.label);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const handleSaveEdit = () => {
|
|
171
|
+
if (editingLabel.trim()) {
|
|
172
|
+
updateConsumerMutation.mutate({
|
|
173
|
+
label: editingLabel.trim(),
|
|
174
|
+
consumerId: consumer.id,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
setIsEditing(false);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<>
|
|
182
|
+
{rollKeyMutation.isError && (
|
|
183
|
+
<Alert variant="destructive" className="mb-4">
|
|
184
|
+
<CircleSlashIcon size={16} />
|
|
185
|
+
<AlertTitle>{rollKeyMutation.error.message}</AlertTitle>
|
|
186
|
+
</Alert>
|
|
187
|
+
)}
|
|
188
|
+
{updateConsumerMutation.isError && (
|
|
189
|
+
<Alert variant="destructive" className="mb-4">
|
|
190
|
+
<CircleSlashIcon size={16} />
|
|
191
|
+
<AlertTitle>{updateConsumerMutation.error.message}</AlertTitle>
|
|
192
|
+
</Alert>
|
|
193
|
+
)}
|
|
194
|
+
{deleteKeyMutation.isError && (
|
|
195
|
+
<Alert variant="destructive" className="mb-4">
|
|
196
|
+
<CircleSlashIcon size={16} />
|
|
197
|
+
<AlertTitle>{deleteKeyMutation.error.message}</AlertTitle>
|
|
198
|
+
</Alert>
|
|
199
|
+
)}
|
|
200
|
+
<Frame
|
|
201
|
+
className="grid grid-cols-subgrid col-span-full items-center mb-4 group"
|
|
202
|
+
key={consumer.id}
|
|
203
|
+
>
|
|
204
|
+
<FrameHeader className="col-span-full flex-row items-start justify-between gap-4">
|
|
205
|
+
<div className="flex flex-col gap-1">
|
|
206
|
+
{isEditing ? (
|
|
207
|
+
<div className="flex items-center gap-2">
|
|
208
|
+
<Input
|
|
209
|
+
maxLength={32}
|
|
210
|
+
value={editingLabel}
|
|
211
|
+
onChange={(e) => setEditingLabel(e.target.value)}
|
|
212
|
+
onKeyDown={(e) => {
|
|
213
|
+
if (e.key === "Enter") {
|
|
214
|
+
handleSaveEdit();
|
|
215
|
+
} else if (e.key === "Escape") {
|
|
216
|
+
setIsEditing(false);
|
|
217
|
+
}
|
|
218
|
+
}}
|
|
219
|
+
autoFocus
|
|
220
|
+
/>
|
|
221
|
+
<div className="flex items-center">
|
|
222
|
+
<Button
|
|
223
|
+
size="icon"
|
|
224
|
+
variant="ghost"
|
|
225
|
+
onClick={handleSaveEdit}
|
|
226
|
+
disabled={!editingLabel.trim()}
|
|
227
|
+
>
|
|
228
|
+
<CheckIcon size={16} />
|
|
229
|
+
</Button>
|
|
230
|
+
<Button
|
|
231
|
+
size="icon"
|
|
232
|
+
variant="ghost"
|
|
233
|
+
onClick={() => setIsEditing(false)}
|
|
234
|
+
>
|
|
235
|
+
<XIcon size={16} />
|
|
236
|
+
</Button>
|
|
237
|
+
</div>
|
|
238
|
+
</div>
|
|
239
|
+
) : (
|
|
240
|
+
<FrameTitle>{consumer.label}</FrameTitle>
|
|
241
|
+
)}
|
|
242
|
+
<FrameDescription>
|
|
243
|
+
{consumer.createdOn && (
|
|
244
|
+
<div>
|
|
245
|
+
Created on {new Date(consumer.createdOn).toLocaleDateString()}
|
|
246
|
+
</div>
|
|
247
|
+
)}
|
|
248
|
+
{consumer.expiresOn && (
|
|
249
|
+
<div>
|
|
250
|
+
Expires on {new Date(consumer.expiresOn).toLocaleDateString()}
|
|
251
|
+
</div>
|
|
252
|
+
)}
|
|
253
|
+
</FrameDescription>
|
|
254
|
+
</div>
|
|
255
|
+
|
|
256
|
+
<div className="flex gap-1">
|
|
257
|
+
{onUpdate && (
|
|
258
|
+
<Button
|
|
259
|
+
variant="ghost"
|
|
260
|
+
onClick={handleStartEdit}
|
|
261
|
+
className={cn(
|
|
262
|
+
"flex gap-2",
|
|
263
|
+
isEditing && "opacity-0! pointer-events-none",
|
|
264
|
+
)}
|
|
265
|
+
disabled={isEditing}
|
|
266
|
+
>
|
|
267
|
+
<PencilLineIcon size={16} />
|
|
268
|
+
<span className="hidden md:block">Edit label</span>
|
|
269
|
+
</Button>
|
|
270
|
+
)}
|
|
271
|
+
{onRollKey && (
|
|
272
|
+
<Dialog>
|
|
273
|
+
<DialogTrigger asChild>
|
|
274
|
+
<Button
|
|
275
|
+
title="Roll this key"
|
|
276
|
+
variant="ghost"
|
|
277
|
+
disabled={rollKeyMutation.isPending}
|
|
278
|
+
className="flex items-center gap-2"
|
|
279
|
+
>
|
|
280
|
+
<RefreshCwIcon
|
|
281
|
+
size={16}
|
|
282
|
+
className={
|
|
283
|
+
rollKeyMutation.isPending ? "animate-spin" : undefined
|
|
284
|
+
}
|
|
285
|
+
/>
|
|
286
|
+
<span className="hidden md:block">Roll key</span>
|
|
287
|
+
</Button>
|
|
288
|
+
</DialogTrigger>
|
|
289
|
+
<DialogContent>
|
|
290
|
+
<DialogHeader>
|
|
291
|
+
<DialogTitle>Roll API Key</DialogTitle>
|
|
292
|
+
<DialogDescription>
|
|
293
|
+
Are you sure you want to roll this API key?
|
|
294
|
+
</DialogDescription>
|
|
295
|
+
</DialogHeader>
|
|
296
|
+
<DialogFooter>
|
|
297
|
+
<DialogClose asChild>
|
|
298
|
+
<Button variant="outline">Cancel</Button>
|
|
299
|
+
</DialogClose>
|
|
300
|
+
<DialogClose asChild>
|
|
301
|
+
<Button
|
|
302
|
+
onClick={() => {
|
|
303
|
+
rollKeyMutation.mutate(consumer.id);
|
|
304
|
+
}}
|
|
305
|
+
>
|
|
306
|
+
Roll Key
|
|
307
|
+
</Button>
|
|
308
|
+
</DialogClose>
|
|
309
|
+
</DialogFooter>
|
|
310
|
+
</DialogContent>
|
|
311
|
+
</Dialog>
|
|
312
|
+
)}
|
|
313
|
+
</div>
|
|
314
|
+
</FrameHeader>
|
|
315
|
+
<FramePanel className="p-0 grid grid-cols-subgrid col-span-full divide-y divide-border">
|
|
316
|
+
<AnimatePresence>
|
|
317
|
+
{consumer.apiKeys.map((apiKey) => (
|
|
318
|
+
<RevealApiKey
|
|
319
|
+
key={apiKey.id}
|
|
320
|
+
apiKey={apiKey}
|
|
321
|
+
onDeleteKey={() => {
|
|
322
|
+
deleteKeyMutation.mutate({
|
|
323
|
+
consumerId: consumer.id,
|
|
324
|
+
keyId: apiKey.id,
|
|
325
|
+
});
|
|
326
|
+
}}
|
|
327
|
+
className={
|
|
328
|
+
deleteKeyMutation.variables?.keyId === apiKey.id &&
|
|
329
|
+
deleteKeyMutation.isPending
|
|
330
|
+
? "opacity-10!"
|
|
331
|
+
: undefined
|
|
332
|
+
}
|
|
333
|
+
/>
|
|
334
|
+
))}
|
|
335
|
+
</AnimatePresence>
|
|
336
|
+
</FramePanel>
|
|
337
|
+
</Frame>
|
|
338
|
+
</>
|
|
339
|
+
);
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
export default ApiKeyItem;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useZudoku } from "../../../components/context/ZudokuContext.js";
|
|
4
|
+
import { cn } from "../../../util/cn.js";
|
|
5
|
+
import { ZudokuError } from "../../../util/invariant.js";
|
|
6
|
+
import { CreateApiKeyDialog } from "../CreateApiKeyDialog.js";
|
|
7
|
+
import type { ApiKeyService } from "../index.js";
|
|
8
|
+
import ApiKeyItem from "./ApiKeyItem.js";
|
|
9
|
+
|
|
10
|
+
export const ApiKeyList = ({ service }: { service: ApiKeyService }) => {
|
|
11
|
+
const context = useZudoku();
|
|
12
|
+
|
|
13
|
+
const { data } = useSuspenseQuery({
|
|
14
|
+
queryFn: async () => {
|
|
15
|
+
try {
|
|
16
|
+
return await service.getConsumers(context);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error instanceof ZudokuError) {
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
throw new ZudokuError("Cannot get API keys", {
|
|
22
|
+
cause: error,
|
|
23
|
+
title: "Error getting API keys",
|
|
24
|
+
developerHint:
|
|
25
|
+
"Check the response of the API request for more information.",
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
queryKey: ["api-keys"],
|
|
30
|
+
retry: false,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const [isCreateApiKeyOpen, setIsCreateApiKeyOpen] = useState(false);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div className="mt-8">
|
|
37
|
+
{data.length === 0 ? (
|
|
38
|
+
<div className="flex col-span-full flex-col justify-center gap-4 items-center p-8 border rounded-sm bg-muted/30 text-muted-foreground">
|
|
39
|
+
<p className="text-center">
|
|
40
|
+
You have no API keys yet.
|
|
41
|
+
<br />
|
|
42
|
+
{service.createKey && "Get started and create your first key."}
|
|
43
|
+
</p>
|
|
44
|
+
{service.createKey && (
|
|
45
|
+
<CreateApiKeyDialog
|
|
46
|
+
service={service}
|
|
47
|
+
isOpen={isCreateApiKeyOpen}
|
|
48
|
+
onOpenChange={setIsCreateApiKeyOpen}
|
|
49
|
+
/>
|
|
50
|
+
)}
|
|
51
|
+
</div>
|
|
52
|
+
) : (
|
|
53
|
+
<ul className={cn("grid grid-cols-[1fr_min-content] col-span-6")}>
|
|
54
|
+
{data.map((consumer) => (
|
|
55
|
+
<ApiKeyItem
|
|
56
|
+
key={consumer.id}
|
|
57
|
+
consumer={consumer}
|
|
58
|
+
onUpdate={service.updateConsumer}
|
|
59
|
+
onRollKey={service.rollKey}
|
|
60
|
+
onDeleteKey={service.deleteKey}
|
|
61
|
+
/>
|
|
62
|
+
))}
|
|
63
|
+
</ul>
|
|
64
|
+
)}
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
};
|