zudoku 0.66.3 → 0.66.5
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/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/core/RouteGuard.js +12 -7
- package/dist/lib/core/RouteGuard.js.map +1 -1
- 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/index.d.ts +9 -5
- package/dist/lib/plugins/api-keys/index.js +20 -11
- package/dist/lib/plugins/api-keys/index.js.map +1 -1
- package/dist/lib/plugins/api-keys/settings/ApiKeyList.js +3 -0
- package/dist/lib/plugins/api-keys/settings/ApiKeyList.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/schema/SchemaView.js +1 -1
- package/dist/lib/plugins/openapi/schema/SchemaView.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/ui/Button.js +1 -1
- package/dist/lib/ui/Button.js.map +1 -1
- 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/mdx/remark-link-rewrite.js +1 -1
- package/dist/vite/plugin-api-keys.js +1 -0
- package/dist/vite/plugin-api-keys.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/worker.js +3 -0
- package/dist/vite/prerender/worker.js.map +1 -1
- 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-BZslN9XF.js → ClaudeLogo-ByzA8TYR.js} +3 -3
- package/lib/{ClaudeLogo-BZslN9XF.js.map → ClaudeLogo-ByzA8TYR.js.map} +1 -1
- 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-BRMcpfuF.js → Drawer-Ch7927PF.js} +2 -2
- package/lib/{Drawer-BRMcpfuF.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-DxlznfVd.js → Frame-DKlOmSkU.js} +2 -2
- package/lib/{Frame-DxlznfVd.js.map → Frame-DKlOmSkU.js.map} +1 -1
- 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-D-kqEQ5M.js → Input-nskrp_mj.js} +39 -18
- package/lib/Input-nskrp_mj.js.map +1 -0
- package/lib/{MdxPage-B4zZq5aR.js → MdxPage-Bh5YNRV9.js} +10 -10
- package/lib/{MdxPage-B4zZq5aR.js.map → MdxPage-Bh5YNRV9.js.map} +1 -1
- package/lib/{Mermaid-BjSczjLW.js → Mermaid-CGRoylZf.js} +4 -4
- package/lib/{Mermaid-BjSczjLW.js.map → Mermaid-CGRoylZf.js.map} +1 -1
- package/lib/{OAuthErrorPage-DRY2hlga.js → OAuthErrorPage-CsTKz5hX.js} +8 -8
- package/lib/OAuthErrorPage-CsTKz5hX.js.map +1 -0
- package/lib/{OasProvider-lMwTD76Y.js → OasProvider-BBAbJiYa.js} +3 -3
- package/lib/{OasProvider-lMwTD76Y.js.map → OasProvider-BBAbJiYa.js.map} +1 -1
- package/lib/{OperationList-Bm76b4vl.js → OperationList-DUxrNisd.js} +1104 -1089
- package/lib/{OperationList-Bm76b4vl.js.map → OperationList-DUxrNisd.js.map} +1 -1
- package/lib/RouteGuard-CIN9Ou-r.js +77 -0
- package/lib/RouteGuard-CIN9Ou-r.js.map +1 -0
- package/lib/{SchemaList-DX4FPogg.js → SchemaList-BbnkfjIe.js} +9 -9
- package/lib/{SchemaList-DX4FPogg.js.map → SchemaList-BbnkfjIe.js.map} +1 -1
- package/lib/{SchemaView-CjXvSRxy.js → SchemaView-BrUf6_nP.js} +112 -111
- package/lib/SchemaView-BrUf6_nP.js.map +1 -0
- package/lib/{Secret-BxGpIhDP.js → Secret-BDBqq4p3.js} +2 -2
- package/lib/{Secret-BxGpIhDP.js.map → Secret-BDBqq4p3.js.map} +1 -1
- 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-AlaaduyY.js +50 -0
- package/lib/SignUp-AlaaduyY.js.map +1 -0
- package/lib/{SyntaxHighlight-Dgd0AaaX.js → SyntaxHighlight-DveJcTOQ.js} +4 -4
- package/lib/{SyntaxHighlight-Dgd0AaaX.js.map → SyntaxHighlight-DveJcTOQ.js.map} +1 -1
- package/lib/{Toc-L1vGGHA1.js → Toc-B4ShtN-I.js} +3 -3
- package/lib/{Toc-L1vGGHA1.js.map → Toc-B4ShtN-I.js.map} +1 -1
- package/lib/{ZudokuContext-DNHMZfcP.js → ZudokuContext-CDJYKqMY.js} +542 -469
- package/lib/ZudokuContext-CDJYKqMY.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-PVWAREVJ-ClM0m2aJ.js.map +1 -1
- package/lib/{circular-BIN_WQ0c.js → circular-CuSWVYOZ.js} +2 -2
- package/lib/{circular-BIN_WQ0c.js.map → circular-CuSWVYOZ.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-BEl12QFw.js → createServer-B1_RUTJP.js} +12 -12
- package/lib/{createServer-BEl12QFw.js.map → createServer-B1_RUTJP.js.map} +1 -1
- package/lib/{createVariantComponent-CQVt-H3r.js → createVariantComponent-Dc0vtOvr.js} +2 -2
- package/lib/{createVariantComponent-CQVt-H3r.js.map → createVariantComponent-Dc0vtOvr.js.map} +1 -1
- package/lib/{errors-CtBbD47A.js → errors-iDfQAr_v.js} +3 -3
- package/lib/{errors-CtBbD47A.js.map → errors-iDfQAr_v.js.map} +1 -1
- package/lib/{firebase-CT38ugg4.js → firebase-I54w2ZsH.js} +20 -20
- package/lib/{firebase-CT38ugg4.js.map → firebase-I54w2ZsH.js.map} +1 -1
- package/lib/{hook-CHw_R_xu.js → hook-BxWvqzB0.js} +2 -2
- package/lib/{hook-CHw_R_xu.js.map → hook-BxWvqzB0.js.map} +1 -1
- package/lib/{index-CG2v-T7-.js → index-A5Cre871.js} +11 -11
- package/lib/{index-CG2v-T7-.js.map → index-A5Cre871.js.map} +1 -1
- package/lib/{index-jI2Fjpy-.js → index-B4puReRo.js} +20 -20
- package/lib/{index-jI2Fjpy-.js.map → index-B4puReRo.js.map} +1 -1
- package/lib/{index-DXXZDuSJ.js → index-CjTisMeX.js} +3 -3
- package/lib/{index-DXXZDuSJ.js.map → index-CjTisMeX.js.map} +1 -1
- package/lib/index-CrcNWbel.js.map +1 -1
- package/lib/{index-CISwSpdT.js → index-Dbrv6d94.js} +2 -2
- package/lib/{index-CISwSpdT.js.map → index-Dbrv6d94.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-Bu35TNgg.js → index.esm-BxIXRKtj.js} +2 -2
- package/lib/index.esm-BxIXRKtj.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-DMHWqmFp.js → mutation-Cq0wKBqW.js} +70 -44
- package/lib/mutation-Cq0wKBqW.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 +2 -2
- 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/zudoku.__internal.js +576 -574
- package/lib/zudoku.__internal.js.map +1 -1
- package/lib/zudoku.auth-auth0.js +1 -1
- package/lib/zudoku.auth-azureb2c.js +4 -4
- package/lib/zudoku.auth-clerk.js +2 -2
- package/lib/zudoku.auth-firebase.js +5 -5
- package/lib/zudoku.auth-openid.js +5 -5
- package/lib/zudoku.auth-supabase.js +4 -4
- package/lib/zudoku.components.js +5 -5
- package/lib/zudoku.hooks.js +3 -3
- package/lib/zudoku.mermaid.js +3 -3
- package/lib/zudoku.plugin-api-catalog.js +4 -4
- package/lib/zudoku.plugin-api-keys.js +258 -242
- 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 +2 -2
- package/lib/zudoku.plugin-search-pagefind.js +6 -6
- package/lib/zudoku.router.js.map +1 -1
- package/package.json +6 -6
- 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/core/RouteGuard.tsx +30 -24
- package/src/lib/oas/graphql/index.ts +7 -3
- package/src/lib/plugins/api-keys/index.tsx +48 -19
- package/src/lib/plugins/api-keys/settings/ApiKeyList.tsx +3 -0
- package/src/lib/plugins/openapi/ParamInfos.tsx +1 -0
- package/src/lib/plugins/openapi/Sidecar.tsx +3 -2
- package/src/lib/plugins/openapi/schema/SchemaView.tsx +6 -4
- package/src/lib/plugins/openapi/util/createHttpSnippet.ts +29 -1
- package/src/lib/ui/Button.tsx +1 -0
- package/src/lib/util/invariant.ts +2 -1
- package/lib/Input-D-kqEQ5M.js.map +0 -1
- package/lib/OAuthErrorPage-DRY2hlga.js.map +0 -1
- package/lib/RouteGuard-DGc32XJV.js +0 -77
- package/lib/RouteGuard-DGc32XJV.js.map +0 -1
- package/lib/SchemaView-CjXvSRxy.js.map +0 -1
- package/lib/SignUp-CntxjFGS.js +0 -50
- package/lib/SignUp-CntxjFGS.js.map +0 -1
- package/lib/ZudokuContext-DNHMZfcP.js.map +0 -1
- package/lib/___vite-browser-external_commonjs-proxy-Cga3HsWk.js.map +0 -1
- package/lib/cn-dYga0KKN.js.map +0 -1
- package/lib/index.esm-Bu35TNgg.js.map +0 -1
- package/lib/invariant-CGOLuIIz.js.map +0 -1
- package/lib/mutation-DMHWqmFp.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zudoku",
|
|
3
|
-
"version": "0.66.
|
|
3
|
+
"version": "0.66.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://zudoku.dev",
|
|
6
6
|
"repository": {
|
|
@@ -190,7 +190,7 @@
|
|
|
190
190
|
"@tailwindcss/typography": "0.5.19",
|
|
191
191
|
"@tailwindcss/vite": "4.1.16",
|
|
192
192
|
"@tanem/react-nprogress": "5.0.56",
|
|
193
|
-
"@tanstack/react-query": "5.
|
|
193
|
+
"@tanstack/react-query": "5.90.12",
|
|
194
194
|
"@types/react": "19.2.7",
|
|
195
195
|
"@types/react-dom": "19.2.3",
|
|
196
196
|
"@vitejs/plugin-react": "5.1.0",
|
|
@@ -231,7 +231,7 @@
|
|
|
231
231
|
"posthog-node": "5.14.1",
|
|
232
232
|
"react-error-boundary": "6.0.0",
|
|
233
233
|
"react-hook-form": "7.66.0",
|
|
234
|
-
"react-is": "19.2.
|
|
234
|
+
"react-is": "19.2.3",
|
|
235
235
|
"react-markdown": "10.1.0",
|
|
236
236
|
"react-router": "7.8.2",
|
|
237
237
|
"rehype-mdx-import-media": "1.2.0",
|
|
@@ -248,7 +248,7 @@
|
|
|
248
248
|
"shiki": "3.19.0",
|
|
249
249
|
"sitemap": "9.0.0",
|
|
250
250
|
"strip-ansi": "7.1.2",
|
|
251
|
-
"tailwind-merge": "3.
|
|
251
|
+
"tailwind-merge": "3.4.0",
|
|
252
252
|
"tailwindcss": "4.1.17",
|
|
253
253
|
"tw-animate-css": "1.4.0",
|
|
254
254
|
"unified": "^11.0.5",
|
|
@@ -284,8 +284,8 @@
|
|
|
284
284
|
"esbuild": "0.27.0",
|
|
285
285
|
"happy-dom": "20.0.10",
|
|
286
286
|
"mdast-util-mdx": "3.0.0",
|
|
287
|
-
"react": "19.2.
|
|
288
|
-
"react-dom": "19.2.
|
|
287
|
+
"react": "19.2.3",
|
|
288
|
+
"react-dom": "19.2.3",
|
|
289
289
|
"rollup-plugin-visualizer": "6.0.5",
|
|
290
290
|
"tsx": "4.20.6",
|
|
291
291
|
"typescript": "5.9.3",
|
|
@@ -13,7 +13,7 @@ export function CallbackHandler({
|
|
|
13
13
|
const { options } = useZudoku();
|
|
14
14
|
const executeCallback = useSuspenseQuery({
|
|
15
15
|
retry: false,
|
|
16
|
-
queryKey: ["oauth-callback"],
|
|
16
|
+
queryKey: ["oauth-callback", window.location.search],
|
|
17
17
|
queryFn: async () => {
|
|
18
18
|
const url = new URL(window.location.href);
|
|
19
19
|
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
CardHeader,
|
|
9
9
|
CardTitle,
|
|
10
10
|
} from "zudoku/ui/Card.js";
|
|
11
|
+
import { useLatest } from "../../util/useLatest.js";
|
|
11
12
|
import { useAuth } from "../hook.js";
|
|
12
13
|
|
|
13
14
|
export const SignIn = () => {
|
|
@@ -15,12 +16,14 @@ export const SignIn = () => {
|
|
|
15
16
|
const [search] = useSearchParams();
|
|
16
17
|
const redirectTo = search.get("redirect") ?? undefined;
|
|
17
18
|
|
|
19
|
+
const login = useLatest(auth.login);
|
|
20
|
+
|
|
18
21
|
useEffect(() => {
|
|
19
|
-
void
|
|
22
|
+
void login.current({
|
|
20
23
|
redirectTo,
|
|
21
24
|
replace: true,
|
|
22
25
|
});
|
|
23
|
-
}, [
|
|
26
|
+
}, [login, redirectTo]);
|
|
24
27
|
|
|
25
28
|
return (
|
|
26
29
|
<div className="flex items-center justify-center mt-8">
|
|
@@ -7,14 +7,17 @@ import {
|
|
|
7
7
|
CardHeader,
|
|
8
8
|
CardTitle,
|
|
9
9
|
} from "zudoku/ui/Card.js";
|
|
10
|
+
import { useLatest } from "../../util/useLatest.js";
|
|
10
11
|
import { useAuth } from "../hook.js";
|
|
11
12
|
|
|
12
13
|
export const SignUp = () => {
|
|
13
14
|
const auth = useAuth();
|
|
14
15
|
|
|
16
|
+
const signup = useLatest(auth.signup);
|
|
17
|
+
|
|
15
18
|
useEffect(() => {
|
|
16
|
-
void
|
|
17
|
-
}, [
|
|
19
|
+
void signup.current();
|
|
20
|
+
}, [signup]);
|
|
18
21
|
|
|
19
22
|
return (
|
|
20
23
|
<div className="flex items-center justify-center mt-8">
|
|
@@ -27,16 +27,31 @@ export const RouteGuard = () => {
|
|
|
27
27
|
const shouldBypass = use(BypassProtectedRoutesContext);
|
|
28
28
|
const { protectedRoutes } = zudoku.options;
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
: undefined;
|
|
30
|
+
const protectedRouteEntry = protectedRoutes
|
|
31
|
+
? Object.entries(protectedRoutes).find(([path]) =>
|
|
32
|
+
matchPath({ path, end: true }, location.pathname),
|
|
33
|
+
)
|
|
34
|
+
: undefined;
|
|
36
35
|
|
|
37
|
-
const isProtectedRoute =
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
const isProtectedRoute = protectedRouteEntry !== undefined;
|
|
37
|
+
|
|
38
|
+
// SSR/prerendering mode: render content with search meta tag, skip all auth
|
|
39
|
+
if (shouldBypass) {
|
|
40
|
+
return (
|
|
41
|
+
<>
|
|
42
|
+
{isProtectedRoute && (
|
|
43
|
+
<Helmet>
|
|
44
|
+
<meta
|
|
45
|
+
name="pagefind"
|
|
46
|
+
data-pagefind-filter={`section:${SEARCH_PROTECTED_SECTION}`}
|
|
47
|
+
content="true"
|
|
48
|
+
/>
|
|
49
|
+
</Helmet>
|
|
50
|
+
)}
|
|
51
|
+
<Outlet />
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
40
55
|
|
|
41
56
|
if (isProtectedRoute && !auth.isAuthEnabled) {
|
|
42
57
|
throw new ZudokuError("Authentication is not enabled", {
|
|
@@ -46,6 +61,10 @@ export const RouteGuard = () => {
|
|
|
46
61
|
});
|
|
47
62
|
}
|
|
48
63
|
|
|
64
|
+
const authCheckFn = protectedRouteEntry?.[1];
|
|
65
|
+
const needsToSignIn =
|
|
66
|
+
isProtectedRoute && !authCheckFn?.({ auth, context: zudoku });
|
|
67
|
+
|
|
49
68
|
if (needsToSignIn && auth.isPending && typeof window !== "undefined") {
|
|
50
69
|
return null;
|
|
51
70
|
}
|
|
@@ -91,7 +110,7 @@ export const RouteGuard = () => {
|
|
|
91
110
|
)
|
|
92
111
|
}
|
|
93
112
|
>
|
|
94
|
-
Login
|
|
113
|
+
Login
|
|
95
114
|
</Button>
|
|
96
115
|
</DialogFooter>
|
|
97
116
|
</DialogContent>
|
|
@@ -99,18 +118,5 @@ export const RouteGuard = () => {
|
|
|
99
118
|
);
|
|
100
119
|
}
|
|
101
120
|
|
|
102
|
-
return
|
|
103
|
-
<>
|
|
104
|
-
{shouldBypass && isProtectedRoute && (
|
|
105
|
-
<Helmet>
|
|
106
|
-
<meta
|
|
107
|
-
name="pagefind"
|
|
108
|
-
data-pagefind-filter={`section:${SEARCH_PROTECTED_SECTION}`}
|
|
109
|
-
content="true"
|
|
110
|
-
/>
|
|
111
|
-
</Helmet>
|
|
112
|
-
)}
|
|
113
|
-
<Outlet />
|
|
114
|
-
</>
|
|
115
|
-
);
|
|
121
|
+
return <Outlet />;
|
|
116
122
|
};
|
|
@@ -473,7 +473,9 @@ const OperationItem = builder
|
|
|
473
473
|
name,
|
|
474
474
|
...(typeof value === "string" ? { value } : value),
|
|
475
475
|
}))
|
|
476
|
-
:
|
|
476
|
+
: content.example !== undefined
|
|
477
|
+
? [{ name: "", value: content.example }]
|
|
478
|
+
: [],
|
|
477
479
|
encoding: Object.entries(content.encoding ?? {}).map(
|
|
478
480
|
([name, value]) => ({ name, ...value }),
|
|
479
481
|
),
|
|
@@ -490,7 +492,7 @@ const OperationItem = builder
|
|
|
490
492
|
statusCode,
|
|
491
493
|
description: response.description,
|
|
492
494
|
content: Object.entries(response.content ?? {}).map(
|
|
493
|
-
([mediaType, { schema, examples }]) => ({
|
|
495
|
+
([mediaType, { schema, examples, example }]) => ({
|
|
494
496
|
mediaType,
|
|
495
497
|
schema,
|
|
496
498
|
examples: examples
|
|
@@ -498,7 +500,9 @@ const OperationItem = builder
|
|
|
498
500
|
name,
|
|
499
501
|
...(typeof value === "string" ? { value } : value),
|
|
500
502
|
}))
|
|
501
|
-
:
|
|
503
|
+
: example !== undefined
|
|
504
|
+
? [{ name: "", value: example }]
|
|
505
|
+
: [],
|
|
502
506
|
}),
|
|
503
507
|
),
|
|
504
508
|
headers: response.headers,
|
|
@@ -37,9 +37,11 @@ export type ApiKeyService = {
|
|
|
37
37
|
}) => Promise<void>;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
export type ApiKeyPluginOptions =
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
export type ApiKeyPluginOptions = ApiKeyService | DefaultApiKeyServiceOptions;
|
|
41
|
+
|
|
42
|
+
type DefaultApiKeyServiceOptions = {
|
|
43
|
+
deploymentName?: string;
|
|
44
|
+
} & Partial<ApiKeyService>;
|
|
43
45
|
|
|
44
46
|
export interface ApiKey {
|
|
45
47
|
id: string;
|
|
@@ -79,12 +81,19 @@ const throwIfProblemJson = async (response: Response) => {
|
|
|
79
81
|
}
|
|
80
82
|
};
|
|
81
83
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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 => {
|
|
86
94
|
return {
|
|
87
95
|
deleteKey: async (consumerId, keyId, context) => {
|
|
96
|
+
invariant(deploymentName, "Cannot delete API key.", developerHintOptions);
|
|
88
97
|
const request = new Request(
|
|
89
98
|
DEFAULT_API_KEY_ENDPOINT +
|
|
90
99
|
`/${deploymentName}/consumers/${consumerId}/keys/${keyId}`,
|
|
@@ -92,17 +101,20 @@ const createDefaultHandler = (
|
|
|
92
101
|
method: "DELETE",
|
|
93
102
|
},
|
|
94
103
|
);
|
|
95
|
-
await context.signRequest(request);
|
|
96
|
-
const response = await fetch(request);
|
|
104
|
+
const response = await fetch(await context.signRequest(request));
|
|
97
105
|
await throwIfProblemJson(response);
|
|
98
106
|
invariant(response.ok, "Failed to delete API key");
|
|
99
107
|
},
|
|
100
108
|
updateConsumer: async (consumer, context) => {
|
|
109
|
+
invariant(
|
|
110
|
+
deploymentName,
|
|
111
|
+
"Cannot update API key description.",
|
|
112
|
+
developerHintOptions,
|
|
113
|
+
);
|
|
101
114
|
const response = await fetch(
|
|
102
115
|
await context.signRequest(
|
|
103
116
|
new Request(
|
|
104
|
-
DEFAULT_API_KEY_ENDPOINT
|
|
105
|
-
`/${deploymentName}/consumers/${consumer.id}`,
|
|
117
|
+
`${DEFAULT_API_KEY_ENDPOINT}/${deploymentName}/consumers/${consumer.id}`,
|
|
106
118
|
{
|
|
107
119
|
method: "PATCH",
|
|
108
120
|
headers: {
|
|
@@ -119,11 +131,11 @@ const createDefaultHandler = (
|
|
|
119
131
|
invariant(response.ok, "Failed to update API key description");
|
|
120
132
|
},
|
|
121
133
|
rollKey: async (consumerId, context) => {
|
|
134
|
+
invariant(deploymentName, "Cannot roll API key.", developerHintOptions);
|
|
122
135
|
const response = await fetch(
|
|
123
136
|
await context.signRequest(
|
|
124
137
|
new Request(
|
|
125
|
-
DEFAULT_API_KEY_ENDPOINT
|
|
126
|
-
`/${deploymentName}/consumers/${consumerId}/roll-key`,
|
|
138
|
+
`${DEFAULT_API_KEY_ENDPOINT}/${deploymentName}/consumers/${consumerId}/roll-key`,
|
|
127
139
|
{
|
|
128
140
|
method: "POST",
|
|
129
141
|
headers: {
|
|
@@ -135,9 +147,10 @@ const createDefaultHandler = (
|
|
|
135
147
|
),
|
|
136
148
|
);
|
|
137
149
|
await throwIfProblemJson(response);
|
|
138
|
-
invariant(response.ok, "Failed to
|
|
150
|
+
invariant(response.ok, "Failed to roll API key");
|
|
139
151
|
},
|
|
140
152
|
getConsumers: async (context) => {
|
|
153
|
+
invariant(deploymentName, "Cannot get API keys.", developerHintOptions);
|
|
141
154
|
const request = new Request(
|
|
142
155
|
`${DEFAULT_API_KEY_ENDPOINT}/${deploymentName}/consumers`,
|
|
143
156
|
);
|
|
@@ -180,14 +193,30 @@ const createDefaultHandler = (
|
|
|
180
193
|
export const createApiKeyService = <T extends ApiKeyService>(service: T): T =>
|
|
181
194
|
service;
|
|
182
195
|
|
|
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
|
+
|
|
183
203
|
export const apiKeyPlugin = ({
|
|
184
204
|
deploymentName,
|
|
205
|
+
isZuplo,
|
|
185
206
|
...options
|
|
186
|
-
}: Omit<ApiKeysOptions, "enabled"> &
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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 })
|
|
191
220
|
: options;
|
|
192
221
|
|
|
193
222
|
if (!service.getConsumers) {
|
|
@@ -15,6 +15,9 @@ export const ApiKeyList = ({ service }: { service: ApiKeyService }) => {
|
|
|
15
15
|
try {
|
|
16
16
|
return await service.getConsumers(context);
|
|
17
17
|
} catch (error) {
|
|
18
|
+
if (error instanceof ZudokuError) {
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
18
21
|
throw new ZudokuError("Cannot get API keys", {
|
|
19
22
|
cause: error,
|
|
20
23
|
title: "Error getting API keys",
|
|
@@ -40,6 +40,7 @@ const getSchemaInfos = (schema?: SchemaObject) => {
|
|
|
40
40
|
schema.enum && "enum",
|
|
41
41
|
schema.const && "const",
|
|
42
42
|
schema.format,
|
|
43
|
+
schema.type === "array" && schema.items?.contentMediaType,
|
|
43
44
|
schema.minimum !== undefined && `min: ${schema.minimum}`,
|
|
44
45
|
schema.maximum !== undefined && `max: ${schema.maximum}`,
|
|
45
46
|
schema.minLength !== undefined && `minLength: ${schema.minLength}`,
|
|
@@ -149,10 +149,10 @@ export const Sidecar = ({
|
|
|
149
149
|
selectedServer,
|
|
150
150
|
exampleBody: currentExampleCode
|
|
151
151
|
? {
|
|
152
|
-
mimeType: "application/json",
|
|
152
|
+
mimeType: selectedContent?.mediaType ?? "application/json",
|
|
153
153
|
text: JSON.stringify(currentExampleCode, null, 2),
|
|
154
154
|
}
|
|
155
|
-
: { mimeType: "application/json" },
|
|
155
|
+
: { mimeType: selectedContent?.mediaType ?? "application/json" },
|
|
156
156
|
});
|
|
157
157
|
|
|
158
158
|
return getConverted(snippet, selectedLang);
|
|
@@ -161,6 +161,7 @@ export const Sidecar = ({
|
|
|
161
161
|
operation,
|
|
162
162
|
selectedServer,
|
|
163
163
|
selectedLang,
|
|
164
|
+
selectedContent,
|
|
164
165
|
options,
|
|
165
166
|
auth,
|
|
166
167
|
context,
|
|
@@ -154,10 +154,12 @@ export const SchemaView = ({
|
|
|
154
154
|
<FrameDescription>{schema.description}</FrameDescription>
|
|
155
155
|
</FrameHeader>
|
|
156
156
|
)}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
{(itemsList.length > 0 || additionalObjectProperties) && (
|
|
158
|
+
<FramePanel className="p-0!">
|
|
159
|
+
{itemsList}
|
|
160
|
+
{additionalObjectProperties}
|
|
161
|
+
</FramePanel>
|
|
162
|
+
)}
|
|
161
163
|
{schema.additionalProperties === true && (
|
|
162
164
|
<FrameFooter>
|
|
163
165
|
<a
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { HTTPSnippet } from "@zudoku/httpsnippet";
|
|
2
2
|
import type { OperationsFragmentFragment } from "../graphql/graphql.js";
|
|
3
3
|
|
|
4
|
+
const toFormDataParams = (text?: string) => {
|
|
5
|
+
const stringify = (v: unknown) =>
|
|
6
|
+
typeof v === "string" ? v : JSON.stringify(v);
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
const obj = text && JSON.parse(text);
|
|
10
|
+
if (typeof obj !== "object" || !obj) return [];
|
|
11
|
+
|
|
12
|
+
return Object.entries(obj).flatMap(([name, value]) => {
|
|
13
|
+
const values = Array.isArray(value) ? value : [value];
|
|
14
|
+
return values.map((v) => ({ name, value: stringify(v) }));
|
|
15
|
+
});
|
|
16
|
+
} catch {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
4
21
|
export const createHttpSnippet = ({
|
|
5
22
|
operation,
|
|
6
23
|
selectedServer,
|
|
@@ -13,11 +30,22 @@ export const createHttpSnippet = ({
|
|
|
13
30
|
text?: string;
|
|
14
31
|
};
|
|
15
32
|
}) => {
|
|
33
|
+
const isMultipart =
|
|
34
|
+
exampleBody.mimeType === "multipart/form-data" ||
|
|
35
|
+
exampleBody.mimeType === "application/x-www-form-urlencoded";
|
|
36
|
+
|
|
37
|
+
const postData = isMultipart
|
|
38
|
+
? {
|
|
39
|
+
mimeType: exampleBody.mimeType,
|
|
40
|
+
params: toFormDataParams(exampleBody.text),
|
|
41
|
+
}
|
|
42
|
+
: exampleBody;
|
|
43
|
+
|
|
16
44
|
return new HTTPSnippet({
|
|
17
45
|
method: operation.method.toUpperCase(),
|
|
18
46
|
url:
|
|
19
47
|
selectedServer + operation.path.replaceAll("{", ":").replaceAll("}", ""),
|
|
20
|
-
postData
|
|
48
|
+
postData,
|
|
21
49
|
headers: [
|
|
22
50
|
...(exampleBody.text
|
|
23
51
|
? [{ name: "Content-Type", value: exampleBody.mimeType }]
|
package/src/lib/ui/Button.tsx
CHANGED
|
@@ -51,6 +51,7 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
|
51
51
|
const Comp = asChild ? Slot : "button";
|
|
52
52
|
return (
|
|
53
53
|
<Comp
|
|
54
|
+
type={asChild ? undefined : "button"}
|
|
54
55
|
className={cn(buttonVariants({ variant, size, className }))}
|
|
55
56
|
ref={ref}
|
|
56
57
|
{...props}
|
|
@@ -7,6 +7,7 @@ export default function invariant(
|
|
|
7
7
|
* the message takes a fair amount of effort to compute
|
|
8
8
|
*/
|
|
9
9
|
message?: string | (() => string),
|
|
10
|
+
options?: ZudokuErrorOptions,
|
|
10
11
|
): asserts condition {
|
|
11
12
|
if (condition) {
|
|
12
13
|
return;
|
|
@@ -16,7 +17,7 @@ export default function invariant(
|
|
|
16
17
|
const provided: string | undefined =
|
|
17
18
|
typeof message === "function" ? message() : message;
|
|
18
19
|
|
|
19
|
-
throw new ZudokuError(provided ?? "Invariant failed");
|
|
20
|
+
throw new ZudokuError(provided ?? "Invariant failed", options);
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export type ZudokuErrorOptions = {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Input-D-kqEQ5M.js","sources":["../../../node_modules/.pnpm/@tanstack+query-core@5.85.5/node_modules/@tanstack/query-core/build/modern/mutationObserver.js","../../../node_modules/.pnpm/@tanstack+react-query@5.85.5_react@19.2.1/node_modules/@tanstack/react-query/build/modern/useMutation.js","../src/lib/ui/Input.tsx"],"sourcesContent":["// src/mutationObserver.ts\nimport { getDefaultState } from \"./mutation.js\";\nimport { notifyManager } from \"./notifyManager.js\";\nimport { Subscribable } from \"./subscribable.js\";\nimport { hashKey, shallowEqualObjects } from \"./utils.js\";\nvar MutationObserver = class extends Subscribable {\n #client;\n #currentResult = void 0;\n #currentMutation;\n #mutateOptions;\n constructor(client, options) {\n super();\n this.#client = client;\n this.setOptions(options);\n this.bindMethods();\n this.#updateResult();\n }\n bindMethods() {\n this.mutate = this.mutate.bind(this);\n this.reset = this.reset.bind(this);\n }\n setOptions(options) {\n const prevOptions = this.options;\n this.options = this.#client.defaultMutationOptions(options);\n if (!shallowEqualObjects(this.options, prevOptions)) {\n this.#client.getMutationCache().notify({\n type: \"observerOptionsUpdated\",\n mutation: this.#currentMutation,\n observer: this\n });\n }\n if (prevOptions?.mutationKey && this.options.mutationKey && hashKey(prevOptions.mutationKey) !== hashKey(this.options.mutationKey)) {\n this.reset();\n } else if (this.#currentMutation?.state.status === \"pending\") {\n this.#currentMutation.setOptions(this.options);\n }\n }\n onUnsubscribe() {\n if (!this.hasListeners()) {\n this.#currentMutation?.removeObserver(this);\n }\n }\n onMutationUpdate(action) {\n this.#updateResult();\n this.#notify(action);\n }\n getCurrentResult() {\n return this.#currentResult;\n }\n reset() {\n this.#currentMutation?.removeObserver(this);\n this.#currentMutation = void 0;\n this.#updateResult();\n this.#notify();\n }\n mutate(variables, options) {\n this.#mutateOptions = options;\n this.#currentMutation?.removeObserver(this);\n this.#currentMutation = this.#client.getMutationCache().build(this.#client, this.options);\n this.#currentMutation.addObserver(this);\n return this.#currentMutation.execute(variables);\n }\n #updateResult() {\n const state = this.#currentMutation?.state ?? getDefaultState();\n this.#currentResult = {\n ...state,\n isPending: state.status === \"pending\",\n isSuccess: state.status === \"success\",\n isError: state.status === \"error\",\n isIdle: state.status === \"idle\",\n mutate: this.mutate,\n reset: this.reset\n };\n }\n #notify(action) {\n notifyManager.batch(() => {\n if (this.#mutateOptions && this.hasListeners()) {\n const variables = this.#currentResult.variables;\n const context = this.#currentResult.context;\n if (action?.type === \"success\") {\n this.#mutateOptions.onSuccess?.(action.data, variables, context);\n this.#mutateOptions.onSettled?.(action.data, null, variables, context);\n } else if (action?.type === \"error\") {\n this.#mutateOptions.onError?.(action.error, variables, context);\n this.#mutateOptions.onSettled?.(\n void 0,\n action.error,\n variables,\n context\n );\n }\n }\n this.listeners.forEach((listener) => {\n listener(this.#currentResult);\n });\n });\n }\n};\nexport {\n MutationObserver\n};\n//# sourceMappingURL=mutationObserver.js.map","\"use client\";\n\n// src/useMutation.ts\nimport * as React from \"react\";\nimport {\n MutationObserver,\n noop,\n notifyManager,\n shouldThrowError\n} from \"@tanstack/query-core\";\nimport { useQueryClient } from \"./QueryClientProvider.js\";\nfunction useMutation(options, queryClient) {\n const client = useQueryClient(queryClient);\n const [observer] = React.useState(\n () => new MutationObserver(\n client,\n options\n )\n );\n React.useEffect(() => {\n observer.setOptions(options);\n }, [observer, options]);\n const result = React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer]\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult()\n );\n const mutate = React.useCallback(\n (variables, mutateOptions) => {\n observer.mutate(variables, mutateOptions).catch(noop);\n },\n [observer]\n );\n if (result.error && shouldThrowError(observer.options.throwOnError, [result.error])) {\n throw result.error;\n }\n return { ...result, mutate, mutateAsync: result.mutate };\n}\nexport {\n useMutation\n};\n//# sourceMappingURL=useMutation.js.map","import * as React from \"react\";\nimport { cn } from \"../util/cn.js\";\n\ntype InputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n"],"names":["MutationObserver","Subscribable","#client","#currentResult","#currentMutation","#mutateOptions","client","options","#updateResult","prevOptions","shallowEqualObjects","hashKey","action","#notify","variables","state","getDefaultState","notifyManager","context","listener","useMutation","queryClient","useQueryClient","observer","React","result","onStoreChange","mutate","mutateOptions","noop","shouldThrowError","Input","className","type","props","ref","jsx","cn"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"OAuthErrorPage-DRY2hlga.js","sources":["../src/lib/util/url.ts","../src/lib/authentication/components/CallbackHandler.tsx","../src/lib/authentication/components/OAuthErrorPage.tsx"],"sourcesContent":["/**\n * Normalizes a redirect URL by removing the origin and optionally the root path\n */\nexport function normalizeRedirectUrl(\n redirectTo: string,\n origin: string,\n basePath: string = \"/\",\n): string {\n if (!redirectTo.startsWith(origin)) {\n return redirectTo;\n }\n\n if (basePath !== \"/\" && redirectTo.startsWith(origin + basePath)) {\n return redirectTo.slice(origin.length + basePath.length);\n }\n\n return redirectTo.slice(origin.length);\n}\n","import { useSuspenseQuery } from \"@tanstack/react-query\";\nimport { Navigate } from \"react-router\";\nimport { useZudoku } from \"zudoku/components\";\nimport { joinUrl } from \"../../util/joinUrl.js\";\nimport { normalizeRedirectUrl } from \"../../util/url.js\";\nimport { OAuthAuthorizationError, type OAuthErrorType } from \"../errors.js\";\n\nexport function CallbackHandler({\n handleCallback,\n}: {\n handleCallback: () => Promise<string>;\n}) {\n const { options } = useZudoku();\n const executeCallback = useSuspenseQuery({\n retry: false,\n queryKey: [\"oauth-callback\"],\n queryFn: async () => {\n const url = new URL(window.location.href);\n\n const errorParam = url.searchParams.get(\"error\");\n const errorDescription =\n url.searchParams.get(\"error_description\") ?? undefined;\n const errorUri = url.searchParams.get(\"error_uri\") ?? undefined;\n if (errorParam) {\n throw new OAuthAuthorizationError(\n `OAuth error '${errorParam}': ${errorDescription}`,\n {\n error: errorParam as OAuthErrorType,\n error_description: errorDescription,\n error_uri: errorUri,\n },\n );\n }\n return joinUrl(\n normalizeRedirectUrl(\n await handleCallback(),\n window.location.origin,\n options.basePath,\n ),\n );\n },\n });\n\n return <Navigate to={executeCallback.data} replace />;\n}\n","import { HomeIcon } from \"lucide-react\";\nimport { Link } from \"react-router\";\nimport { Heading } from \"../../components/Heading.js\";\nimport { Typography } from \"../../components/Typography.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { OAuthAuthorizationError } from \"../errors.js\";\nimport { useAuth } from \"../hook.js\";\n\nconst errorDetailsMap: Record<string, { message: string }> = {\n invalid_request: {\n message:\n \"The authentication request was invalid. Please try signing in again.\",\n },\n unauthorized_client: {\n message:\n \"This application is not authorized to access your account. Please contact support.\",\n },\n access_denied: {\n message:\n \"You denied access to this application. To continue, please sign in and grant access.\",\n },\n unsupported_response_type: {\n message:\n \"The authentication method is not supported. Please contact support.\",\n },\n invalid_scope: {\n message: \"The requested permissions are invalid. Please contact support.\",\n },\n server_error: {\n message:\n \"The authentication server encountered an error. Please try again in a few moments.\",\n },\n temporarily_unavailable: {\n message:\n \"The authentication service is temporarily unavailable. Please try again in a few moments.\",\n },\n // Token errors\n invalid_client: {\n message: \"Invalid application credentials. Please contact support.\",\n },\n invalid_grant: {\n message:\n \"The authentication code has expired or is invalid. Please sign in again.\",\n },\n unsupported_grant_type: {\n message:\n \"The authentication method is not supported. Please contact support.\",\n },\n // Custom errors\n invalid_state: {\n message:\n \"Security validation failed. This may be due to a potential security attack. Please try signing in again.\",\n },\n missing_code_verifier: {\n message:\n \"Authentication security information is missing. Please clear your browser cache and try again.\",\n },\n network_error: {\n message:\n \"A network error occurred during authentication. Please check your connection and try again.\",\n },\n token_expired: {\n message: \"Your authentication session has expired. Please sign in again.\",\n },\n configuration_error: {\n message:\n \"There is an issue with the authentication configuration. Please contact support.\",\n },\n unknown_error: {\n message:\n \"An unexpected error occurred during authentication. Please try again or contact support.\",\n },\n};\n\nexport function OAuthErrorPage({ error }: { error: unknown }) {\n const { login } = useAuth();\n\n if (!(error instanceof OAuthAuthorizationError)) {\n throw error;\n }\n\n const oauthError = error.error;\n const type = oauthError.error;\n\n const details = errorDetailsMap[type] ?? errorDetailsMap.unknown_error;\n\n return (\n <div className=\"min-h-[400px] flex items-center justify-center p-4\">\n <div className=\"max-w-md w-full text-center space-y-6\">\n <div className=\"space-y-4 items-center\">\n <Heading level={2} className=\"text-2xl inline-block font-bold\">\n {titles[type] || \"Authentication Error\"}\n </Heading>\n\n <Typography className=\"text-gray-600 dark:text-gray-300 leading-relaxed\">\n {details?.message}\n </Typography>\n\n {/* Technical details for developers (only in development) */}\n </div>\n\n {/* Action Buttons */}\n <div className=\"space-y-3 pt-4\">\n <div className=\"space-y-2\">\n {(type === \"access_denied\" ||\n type === \"invalid_grant\" ||\n type === \"token_expired\") && (\n <Button\n onClick={() => login()}\n className=\"w-full capitalize\"\n variant={\"default\"}\n >\n Sign in again\n </Button>\n )}\n </div>\n\n <div className=\"flex gap-2\">\n <Button asChild className=\"flex-1\" variant=\"outline\">\n <Link to=\"/\">\n <HomeIcon className=\"w-4 h-4 mr-2\" />\n Go Home\n </Link>\n </Button>\n </div>\n </div>\n\n {/* Additional Help */}\n {helpMessages[type] && (\n <Typography className=\"text-sm text-gray-500 dark:text-gray-400\">\n {helpMessages[type]}\n </Typography>\n )}\n </div>\n </div>\n );\n}\n\nconst titles: Record<string, string> = {\n access_denied: \"Access Denied\",\n invalid_request: \"Invalid Request\",\n unauthorized_client: \"Unauthorized Application\",\n unsupported_response_type: \"Unsupported Method\",\n invalid_scope: \"Invalid Permissions\",\n server_error: \"Server Error\",\n temporarily_unavailable: \"Service Unavailable\",\n invalid_client: \"Invalid Credentials\",\n invalid_grant: \"Authentication Expired\",\n unsupported_grant_type: \"Unsupported Authentication\",\n invalid_state: \"Security Check Failed\",\n missing_code_verifier: \"Security Information Missing\",\n network_error: \"Network Error\",\n token_expired: \"Session Expired\",\n configuration_error: \"Configuration Error\",\n unknown_error: \"Authentication Failed\",\n};\n\nconst helpMessages: Record<string, string> = {\n access_denied:\n \"If you changed your mind, you can try signing in again to grant access.\",\n invalid_state:\n \"This error can occur if you have multiple tabs open or if your session was compromised.\",\n missing_code_verifier:\n \"Try clearing your browser's cache and cookies for this site.\",\n network_error:\n \"Check your internet connection and ensure you can access other websites.\",\n server_error:\n \"The issue is on our end. Our team has been notified and is working to fix it.\",\n temporarily_unavailable:\n \"This is usually temporary. Try again in a few minutes.\",\n};\n"],"names":["normalizeRedirectUrl","redirectTo","origin","basePath","CallbackHandler","handleCallback","options","useZudoku","executeCallback","useSuspenseQuery","url","errorParam","errorDescription","errorUri","OAuthAuthorizationError","joinUrl","Navigate","errorDetailsMap","OAuthErrorPage","error","login","useAuth","type","details","jsxs","jsx","Heading","titles","Typography","Button","Link","HomeIcon","helpMessages"],"mappings":"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"}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { j as t } from "./jsx-runtime-BzflLqGi.js";
|
|
2
|
-
import { H as m } from "./index.esm-DtzT_KoE.js";
|
|
3
|
-
import { createContext as p, use as f } from "react";
|
|
4
|
-
import { u as g, a as x, m as j, O as v } from "./chunk-PVWAREVJ-ClM0m2aJ.js";
|
|
5
|
-
import { B as a } from "./Button-CynVW1JV.js";
|
|
6
|
-
import { D as C, a as R, b as D, c as w, d as T, e as b } from "./Dialog-BQciPiHN.js";
|
|
7
|
-
import { u as k } from "./hook-CHw_R_xu.js";
|
|
8
|
-
import { a as E } from "./ZudokuContext-DNHMZfcP.js";
|
|
9
|
-
import { Z as P } from "./invariant-CGOLuIIz.js";
|
|
10
|
-
import { u as y } from "./useLatest-hmRS46UF.js";
|
|
11
|
-
const O = p(!1), A = "protected", G = () => {
|
|
12
|
-
const n = k(), e = E(), o = g(), r = x(), c = y(r.pathname), u = f(O), { protectedRoutes: d } = e.options, l = !u && d ? Object.entries(d).find(
|
|
13
|
-
([s]) => j({ path: s, end: !0 }, r.pathname)
|
|
14
|
-
)?.[1] : void 0, i = l !== void 0, h = i && !l({ auth: n, context: e });
|
|
15
|
-
if (i && !n.isAuthEnabled)
|
|
16
|
-
throw new P("Authentication is not enabled", {
|
|
17
|
-
title: "Authentication is not enabled",
|
|
18
|
-
developerHint: "To use protectedRoutes you need authentication to be enabled"
|
|
19
|
-
});
|
|
20
|
-
return h && n.isPending && typeof window < "u" ? null : h ? /* @__PURE__ */ t.jsx(
|
|
21
|
-
C,
|
|
22
|
-
{
|
|
23
|
-
open: !0,
|
|
24
|
-
onOpenChange: (s) => {
|
|
25
|
-
s || o(-1);
|
|
26
|
-
},
|
|
27
|
-
children: /* @__PURE__ */ t.jsxs(R, { children: [
|
|
28
|
-
/* @__PURE__ */ t.jsx(D, { children: /* @__PURE__ */ t.jsx(w, { children: "Login to continue" }) }),
|
|
29
|
-
/* @__PURE__ */ t.jsx(T, { children: "Please wait while we log you in." }),
|
|
30
|
-
/* @__PURE__ */ t.jsxs(b, { children: [
|
|
31
|
-
/* @__PURE__ */ t.jsx(a, { variant: "outline", onClick: () => void o(-1), children: "Cancel" }),
|
|
32
|
-
/* @__PURE__ */ t.jsx("div", { className: "w-full" }),
|
|
33
|
-
/* @__PURE__ */ t.jsx(
|
|
34
|
-
a,
|
|
35
|
-
{
|
|
36
|
-
variant: "secondary",
|
|
37
|
-
onClick: () => void e.authentication?.signUp(
|
|
38
|
-
{ navigate: o },
|
|
39
|
-
{ redirectTo: c.current }
|
|
40
|
-
),
|
|
41
|
-
children: "Register"
|
|
42
|
-
}
|
|
43
|
-
),
|
|
44
|
-
/* @__PURE__ */ t.jsxs(
|
|
45
|
-
a,
|
|
46
|
-
{
|
|
47
|
-
onClick: () => void e.authentication?.signIn(
|
|
48
|
-
{ navigate: o },
|
|
49
|
-
{ redirectTo: c.current }
|
|
50
|
-
),
|
|
51
|
-
children: [
|
|
52
|
-
"Login",
|
|
53
|
-
" "
|
|
54
|
-
]
|
|
55
|
-
}
|
|
56
|
-
)
|
|
57
|
-
] })
|
|
58
|
-
] })
|
|
59
|
-
}
|
|
60
|
-
) : /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
|
|
61
|
-
u && i && /* @__PURE__ */ t.jsx(m, { children: /* @__PURE__ */ t.jsx(
|
|
62
|
-
"meta",
|
|
63
|
-
{
|
|
64
|
-
name: "pagefind",
|
|
65
|
-
"data-pagefind-filter": `section:${A}`,
|
|
66
|
-
content: "true"
|
|
67
|
-
}
|
|
68
|
-
) }),
|
|
69
|
-
/* @__PURE__ */ t.jsx(v, {})
|
|
70
|
-
] });
|
|
71
|
-
};
|
|
72
|
-
export {
|
|
73
|
-
O as B,
|
|
74
|
-
G as R,
|
|
75
|
-
A as S
|
|
76
|
-
};
|
|
77
|
-
//# sourceMappingURL=RouteGuard-DGc32XJV.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RouteGuard-DGc32XJV.js","sources":["../src/lib/components/context/BypassProtectedRoutesContext.ts","../src/lib/core/RouteGuard.tsx"],"sourcesContent":["import { createContext } from \"react\";\n\nexport const BypassProtectedRoutesContext = createContext(false);\n","import { Helmet } from \"@zudoku/react-helmet-async\";\nimport { use } from \"react\";\nimport { matchPath, Outlet, useLocation, useNavigate } from \"react-router\";\nimport { Button } from \"zudoku/ui/Button.js\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"zudoku/ui/Dialog.js\";\nimport { useAuth } from \"../authentication/hook.js\";\nimport { BypassProtectedRoutesContext } from \"../components/context/BypassProtectedRoutesContext.js\";\nimport { useZudoku } from \"../components/context/ZudokuContext.js\";\nimport { ZudokuError } from \"../util/invariant.js\";\nimport { useLatest } from \"../util/useLatest.js\";\n\nexport const SEARCH_PROTECTED_SECTION = \"protected\";\n\nexport const RouteGuard = () => {\n const auth = useAuth();\n const zudoku = useZudoku();\n const navigate = useNavigate();\n const location = useLocation();\n const latestPath = useLatest(location.pathname);\n const shouldBypass = use(BypassProtectedRoutesContext);\n const { protectedRoutes } = zudoku.options;\n\n const authCheckFn =\n !shouldBypass && protectedRoutes\n ? Object.entries(protectedRoutes).find(([path]) =>\n matchPath({ path, end: true }, location.pathname),\n )?.[1]\n : undefined;\n\n const isProtectedRoute = authCheckFn !== undefined;\n const needsToSignIn =\n isProtectedRoute && !authCheckFn({ auth, context: zudoku });\n\n if (isProtectedRoute && !auth.isAuthEnabled) {\n throw new ZudokuError(\"Authentication is not enabled\", {\n title: \"Authentication is not enabled\",\n developerHint:\n \"To use protectedRoutes you need authentication to be enabled\",\n });\n }\n\n if (needsToSignIn && auth.isPending && typeof window !== \"undefined\") {\n return null;\n }\n\n if (needsToSignIn) {\n return (\n <Dialog\n open={true}\n onOpenChange={(open) => {\n if (!open) {\n void navigate(-1);\n }\n }}\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Login to continue</DialogTitle>\n </DialogHeader>\n <DialogDescription>\n Please wait while we log you in.\n </DialogDescription>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => void navigate(-1)}>\n Cancel\n </Button>\n <div className=\"w-full\"></div>\n <Button\n variant=\"secondary\"\n onClick={() =>\n void zudoku.authentication?.signUp(\n { navigate },\n { redirectTo: latestPath.current },\n )\n }\n >\n Register\n </Button>\n <Button\n onClick={() =>\n void zudoku.authentication?.signIn(\n { navigate },\n { redirectTo: latestPath.current },\n )\n }\n >\n Login{\" \"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n }\n\n return (\n <>\n {shouldBypass && isProtectedRoute && (\n <Helmet>\n <meta\n name=\"pagefind\"\n data-pagefind-filter={`section:${SEARCH_PROTECTED_SECTION}`}\n content=\"true\"\n />\n </Helmet>\n )}\n <Outlet />\n </>\n );\n};\n"],"names":["BypassProtectedRoutesContext","createContext","SEARCH_PROTECTED_SECTION","RouteGuard","auth","useAuth","zudoku","useZudoku","navigate","useNavigate","location","useLocation","latestPath","useLatest","shouldBypass","use","protectedRoutes","authCheckFn","path","matchPath","isProtectedRoute","needsToSignIn","ZudokuError","jsx","Dialog","open","DialogContent","DialogHeader","DialogTitle","DialogDescription","DialogFooter","Button","jsxs","Fragment","Helmet","Outlet"],"mappings":";;;;;;;;;;AAEO,MAAMA,IAA+BC,EAAc,EAAK,GCgBlDC,IAA2B,aAE3BC,IAAa,MAAM;AAC9B,QAAMC,IAAOC,EAAA,GACPC,IAASC,EAAA,GACTC,IAAWC,EAAA,GACXC,IAAWC,EAAA,GACXC,IAAaC,EAAUH,EAAS,QAAQ,GACxCI,IAAeC,EAAIf,CAA4B,GAC/C,EAAE,iBAAAgB,MAAoBV,EAAO,SAE7BW,IACJ,CAACH,KAAgBE,IACb,OAAO,QAAQA,CAAe,EAAE;AAAA,IAAK,CAAC,CAACE,CAAI,MACzCC,EAAU,EAAE,MAAAD,GAAM,KAAK,MAAQR,EAAS,QAAQ;AAAA,EAAA,IAC9C,CAAC,IACL,QAEAU,IAAmBH,MAAgB,QACnCI,IACJD,KAAoB,CAACH,EAAY,EAAE,MAAAb,GAAM,SAASE,GAAQ;AAE5D,MAAIc,KAAoB,CAAChB,EAAK;AAC5B,UAAM,IAAIkB,EAAY,iCAAiC;AAAA,MACrD,OAAO;AAAA,MACP,eACE;AAAA,IAAA,CACH;AAGH,SAAID,KAAiBjB,EAAK,aAAa,OAAO,SAAW,MAChD,OAGLiB,IAEAE,gBAAAA,EAAAA;AAAAA,IAACC;AAAA,IAAA;AAAA,MACC,MAAM;AAAA,MACN,cAAc,CAACC,MAAS;AACtB,QAAKA,KACEjB,EAAS,EAAE;AAAA,MAEpB;AAAA,MAEA,iCAACkB,GAAA,EACC,UAAA;AAAA,QAAAH,gBAAAA,MAACI,GAAA,EACC,UAAAJ,gBAAAA,EAAAA,IAACK,GAAA,EAAY,UAAA,oBAAA,CAAiB,GAChC;AAAA,QACAL,gBAAAA,EAAAA,IAACM,KAAkB,UAAA,mCAAA,CAEnB;AAAA,+BACCC,GAAA,EACC,UAAA;AAAA,UAAAP,gBAAAA,EAAAA,IAACQ,GAAA,EAAO,SAAQ,WAAU,SAAS,MAAM,KAAKvB,EAAS,EAAE,GAAG,UAAA,SAAA,CAE5D;AAAA,UACAe,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAU,SAAA,CAAS;AAAA,UACxBA,gBAAAA,EAAAA;AAAAA,YAACQ;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,SAAS,MACP,KAAKzB,EAAO,gBAAgB;AAAA,gBAC1B,EAAE,UAAAE,EAAA;AAAA,gBACF,EAAE,YAAYI,EAAW,QAAA;AAAA,cAAQ;AAAA,cAGtC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGDoB,gBAAAA,EAAAA;AAAAA,YAACD;AAAA,YAAA;AAAA,cACC,SAAS,MACP,KAAKzB,EAAO,gBAAgB;AAAA,gBAC1B,EAAE,UAAAE,EAAA;AAAA,gBACF,EAAE,YAAYI,EAAW,QAAA;AAAA,cAAQ;AAAA,cAGtC,UAAA;AAAA,gBAAA;AAAA,gBACO;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QACR,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EAAA,IAMJoB,gBAAAA,EAAAA,KAAAC,YAAA,EACG,UAAA;AAAA,IAAAnB,KAAgBM,2BACdc,GAAA,EACC,UAAAX,gBAAAA,EAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,wBAAsB,WAAWrB,CAAwB;AAAA,QACzD,SAAQ;AAAA,MAAA;AAAA,IAAA,GAEZ;AAAA,0BAEDiC,GAAA,CAAA,CAAO;AAAA,EAAA,GACV;AAEJ;"}
|