zudoku 0.64.0 → 0.64.2
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/config/config.d.ts +15 -46
- package/dist/config/validators/InputNavigationSchema.d.ts +53 -53
- package/dist/config/validators/ProtectedRoutesSchema.d.ts +1 -1
- package/dist/config/validators/validate.d.ts +105 -1
- package/dist/config/validators/validate.js +30 -0
- package/dist/config/validators/validate.js.map +1 -1
- package/dist/flat-config.d.ts +16 -0
- package/dist/lib/auth/issuer.js +3 -0
- package/dist/lib/auth/issuer.js.map +1 -1
- package/dist/lib/authentication/authentication.d.ts +1 -1
- package/dist/lib/authentication/providers/firebase.d.ts +4 -0
- package/dist/lib/authentication/providers/firebase.js +215 -0
- package/dist/lib/authentication/providers/firebase.js.map +1 -0
- package/dist/lib/authentication/providers/supabase.js +1 -6
- package/dist/lib/authentication/providers/supabase.js.map +1 -1
- package/dist/lib/authentication/ui/ZudokuAuthUi.d.ts +24 -0
- package/dist/lib/authentication/ui/ZudokuAuthUi.js +124 -0
- package/dist/lib/authentication/ui/ZudokuAuthUi.js.map +1 -0
- package/dist/lib/authentication/ui/icons/Apple.d.ts +3 -0
- package/dist/lib/authentication/ui/icons/Apple.js +4 -0
- package/dist/lib/authentication/ui/icons/Apple.js.map +1 -0
- package/dist/lib/authentication/ui/icons/Facebook.d.ts +3 -0
- package/dist/lib/authentication/ui/icons/Facebook.js +4 -0
- package/dist/lib/authentication/ui/icons/Facebook.js.map +1 -0
- package/dist/lib/authentication/ui/icons/Github.d.ts +3 -0
- package/dist/lib/authentication/ui/icons/Github.js +4 -0
- package/dist/lib/authentication/ui/icons/Github.js.map +1 -0
- package/dist/lib/authentication/ui/icons/Google.d.ts +3 -0
- package/dist/lib/authentication/ui/icons/Google.js +4 -0
- package/dist/lib/authentication/ui/icons/Google.js.map +1 -0
- package/dist/lib/authentication/ui/icons/Microsoft.d.ts +3 -0
- package/dist/lib/authentication/ui/icons/Microsoft.js +4 -0
- package/dist/lib/authentication/ui/icons/Microsoft.js.map +1 -0
- package/dist/lib/authentication/ui/icons/X.d.ts +3 -0
- package/dist/lib/authentication/ui/icons/X.js +4 -0
- package/dist/lib/authentication/ui/icons/X.js.map +1 -0
- package/dist/lib/components/Heading.d.ts +1 -1
- package/dist/lib/core/RouteGuard.js +6 -6
- package/dist/lib/core/RouteGuard.js.map +1 -1
- package/dist/lib/oas/parser/index.js +7 -3
- package/dist/lib/oas/parser/index.js.map +1 -1
- package/dist/lib/plugins/api-keys/ProtectedRoute.js +4 -1
- package/dist/lib/plugins/api-keys/ProtectedRoute.js.map +1 -1
- package/dist/lib/plugins/openapi/CollapsibleCode.d.ts +1 -0
- package/dist/lib/plugins/openapi/CollapsibleCode.js +2 -1
- package/dist/lib/plugins/openapi/CollapsibleCode.js.map +1 -1
- package/dist/lib/plugins/openapi/GeneratedExampleSidecarBox.d.ts +5 -0
- package/dist/lib/plugins/openapi/GeneratedExampleSidecarBox.js +10 -0
- package/dist/lib/plugins/openapi/GeneratedExampleSidecarBox.js.map +1 -0
- package/dist/lib/plugins/openapi/OperationList.js +4 -1
- package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.d.ts +2 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +2 -2
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.d.ts +9 -2
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.js +2 -2
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.js.map +1 -1
- package/dist/lib/plugins/openapi/ResponsesSidecarBox.d.ts +3 -1
- package/dist/lib/plugins/openapi/ResponsesSidecarBox.js +14 -2
- package/dist/lib/plugins/openapi/ResponsesSidecarBox.js.map +1 -1
- package/dist/lib/plugins/openapi/Sidecar.d.ts +2 -1
- package/dist/lib/plugins/openapi/Sidecar.js +33 -30
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/SidecarExamples.d.ts +9 -2
- package/dist/lib/plugins/openapi/SidecarExamples.js +15 -33
- package/dist/lib/plugins/openapi/SidecarExamples.js.map +1 -1
- package/dist/lib/plugins/openapi/components/NonHighlightedCode.d.ts +4 -0
- package/dist/lib/plugins/openapi/components/NonHighlightedCode.js +5 -0
- package/dist/lib/plugins/openapi/components/NonHighlightedCode.js.map +1 -0
- package/dist/lib/plugins/openapi/components/ResponseContent.js +1 -1
- package/dist/lib/plugins/openapi/components/ResponseContent.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/InlineInput.d.ts +1 -1
- package/dist/lib/plugins/openapi/playground/ParamsGrid.d.ts +2 -2
- package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js +1 -2
- package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/SchemaView.js +0 -4
- package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/union-helpers.js +0 -1
- package/dist/lib/plugins/openapi/schema/union-helpers.js.map +1 -1
- package/dist/lib/plugins/openapi/util/generateSchemaExample.js +9 -11
- package/dist/lib/plugins/openapi/util/generateSchemaExample.js.map +1 -1
- package/dist/lib/ui/CodeBlock.d.ts +0 -1
- package/dist/lib/ui/CodeBlock.js.map +1 -1
- package/dist/lib/ui/Command.d.ts +3 -3
- package/dist/lib/ui/EmbeddedCodeBlock.d.ts +0 -1
- package/dist/lib/ui/EmbeddedCodeBlock.js +1 -1
- package/dist/lib/ui/EmbeddedCodeBlock.js.map +1 -1
- package/dist/lib/ui/Separator.d.ts +4 -0
- package/dist/lib/ui/Separator.js +8 -0
- package/dist/lib/ui/Separator.js.map +1 -0
- package/dist/lib/ui/Tooltip.d.ts +7 -7
- package/dist/lib/ui/Tooltip.js +16 -10
- package/dist/lib/ui/Tooltip.js.map +1 -1
- package/dist/lib/util/createVariantComponent.d.ts +5 -2
- package/dist/lib/util/createVariantComponent.js +5 -2
- package/dist/lib/util/createVariantComponent.js.map +1 -1
- package/dist/lib/util/flattenAllOf.d.ts +4 -0
- package/dist/lib/util/flattenAllOf.js +65 -0
- package/dist/lib/util/flattenAllOf.js.map +1 -0
- package/dist/lib/util/flattenAllOf.test.d.ts +1 -0
- package/dist/lib/util/flattenAllOf.test.js +532 -0
- package/dist/lib/util/flattenAllOf.test.js.map +1 -0
- package/dist/vite/api/SchemaManager.js +6 -18
- package/dist/vite/api/SchemaManager.js.map +1 -1
- package/dist/vite/plugin-theme.js +10 -1
- package/dist/vite/plugin-theme.js.map +1 -1
- package/lib/{ErrorAlert-DE3Sf66a.js → ErrorAlert--3alJ_-b.js} +1340 -1311
- package/lib/{ErrorAlert-DE3Sf66a.js.map → ErrorAlert--3alJ_-b.js.map} +1 -1
- package/lib/{MdxPage-DZfeC0QY.js → MdxPage-Bpa9tL63.js} +5 -5
- package/lib/{MdxPage-DZfeC0QY.js.map → MdxPage-Bpa9tL63.js.map} +1 -1
- package/lib/{OAuthErrorPage-BycMozgn.js → OAuthErrorPage-B79J86Fo.js} +4 -4
- package/lib/{OAuthErrorPage-BycMozgn.js.map → OAuthErrorPage-B79J86Fo.js.map} +1 -1
- package/lib/{OasProvider-Bf5zBDBY.js → OasProvider-jr0oDSFy.js} +2 -2
- package/lib/{OasProvider-Bf5zBDBY.js.map → OasProvider-jr0oDSFy.js.map} +1 -1
- package/lib/OperationList-DLEAg4qw.js +5465 -0
- package/lib/OperationList-DLEAg4qw.js.map +1 -0
- package/lib/{Pagination-CJszmeSA.js → Pagination-H2HW9-Er.js} +2 -2
- package/lib/{Pagination-CJszmeSA.js.map → Pagination-H2HW9-Er.js.map} +1 -1
- package/lib/RouteGuard-CjzxosTf.js +77 -0
- package/lib/RouteGuard-CjzxosTf.js.map +1 -0
- package/lib/{RouterError-VDLnrFqF.js → RouterError-DZS2d6Sc.js} +2 -2
- package/lib/{RouterError-VDLnrFqF.js.map → RouterError-DZS2d6Sc.js.map} +1 -1
- package/lib/{SchemaList-xZSf3IMh.js → SchemaList-CSDSazqV.js} +6 -6
- package/lib/{SchemaList-xZSf3IMh.js.map → SchemaList-CSDSazqV.js.map} +1 -1
- package/lib/SchemaView-DJiBd0_5.js +397 -0
- package/lib/SchemaView-DJiBd0_5.js.map +1 -0
- package/lib/{SignUp-6SGx9Yyq.js → SignUp-Fycafbyg.js} +2 -2
- package/lib/{SignUp-6SGx9Yyq.js.map → SignUp-Fycafbyg.js.map} +1 -1
- package/lib/{SyntaxHighlight-zvlnSnHB.js → SyntaxHighlight-C19vH0V_.js} +525 -509
- package/lib/SyntaxHighlight-C19vH0V_.js.map +1 -0
- package/lib/{Toc-Da9yp7lo.js → Toc-ChkOg2UU.js} +2 -2
- package/lib/{Toc-Da9yp7lo.js.map → Toc-ChkOg2UU.js.map} +1 -1
- package/lib/{circular-DvuimBGQ.js → circular-DGfd8SGc.js} +2 -2
- package/lib/{circular-DvuimBGQ.js.map → circular-DGfd8SGc.js.map} +1 -1
- package/lib/{createServer-D9UvCoDf.js → createServer-DGD8hEzT.js} +4662 -4238
- package/lib/createServer-DGD8hEzT.js.map +1 -0
- package/lib/{errors-CuGgh3hf.js → errors-BTpjwHS6.js} +2 -2
- package/lib/{errors-CuGgh3hf.js.map → errors-BTpjwHS6.js.map} +1 -1
- package/lib/{index-rYHsvtTo.js → index-Bvas0H4x.js} +2 -2
- package/lib/{index-rYHsvtTo.js.map → index-Bvas0H4x.js.map} +1 -1
- package/lib/{index-Cr9_YzOZ.js → index-DP1xZgfJ.js} +9 -9
- package/lib/index-DP1xZgfJ.js.map +1 -0
- package/lib/{index-B1rmok4X.js → index-FNRZUtwo.js} +2 -2
- package/lib/{index-B1rmok4X.js.map → index-FNRZUtwo.js.map} +1 -1
- package/lib/ui/CodeBlock.js.map +1 -1
- package/lib/ui/EmbeddedCodeBlock.js +9 -9
- package/lib/ui/EmbeddedCodeBlock.js.map +1 -1
- package/lib/ui/Separator.js +27 -0
- package/lib/ui/Separator.js.map +1 -0
- package/lib/ui/SyntaxHighlight.js +1 -1
- package/lib/ui/Tooltip.js +55 -28
- package/lib/ui/Tooltip.js.map +1 -1
- package/lib/zudoku.__internal.js +4 -4
- package/lib/zudoku.auth-azureb2c.js +3 -3
- package/lib/zudoku.auth-clerk.js +1 -1
- package/lib/zudoku.auth-openid.js +3 -3
- package/lib/zudoku.auth-supabase.js +30 -33
- package/lib/zudoku.auth-supabase.js.map +1 -1
- package/lib/zudoku.components.js +2 -2
- package/lib/zudoku.plugin-api-catalog.js +3 -3
- package/lib/zudoku.plugin-api-keys.js +3 -3
- package/lib/zudoku.plugin-api-keys.js.map +1 -1
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +1 -1
- package/lib/zudoku.plugin-search-pagefind.js +1 -1
- package/package.json +16 -11
- package/src/app/main.css +1 -1
- package/src/lib/auth/issuer.ts +3 -0
- package/src/lib/authentication/authentication.ts +1 -1
- package/src/lib/authentication/providers/firebase.tsx +284 -0
- package/src/lib/authentication/providers/supabase.tsx +2 -7
- package/src/lib/authentication/ui/ZudokuAuthUi.tsx +335 -0
- package/src/lib/authentication/ui/icons/Apple.tsx +10 -0
- package/src/lib/authentication/ui/icons/Facebook.tsx +15 -0
- package/src/lib/authentication/ui/icons/Github.tsx +16 -0
- package/src/lib/authentication/ui/icons/Google.tsx +16 -0
- package/src/lib/authentication/ui/icons/Microsoft.tsx +12 -0
- package/src/lib/authentication/ui/icons/X.tsx +10 -0
- package/src/lib/core/RouteGuard.tsx +8 -8
- package/src/lib/oas/parser/index.ts +8 -3
- package/src/lib/plugins/api-keys/ProtectedRoute.tsx +11 -7
- package/src/lib/plugins/openapi/CollapsibleCode.tsx +5 -3
- package/src/lib/plugins/openapi/GeneratedExampleSidecarBox.tsx +52 -0
- package/src/lib/plugins/openapi/OperationList.tsx +5 -0
- package/src/lib/plugins/openapi/OperationListItem.tsx +3 -0
- package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +20 -2
- package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +26 -1
- package/src/lib/plugins/openapi/Sidecar.tsx +84 -63
- package/src/lib/plugins/openapi/SidecarExamples.tsx +38 -48
- package/src/lib/plugins/openapi/components/NonHighlightedCode.tsx +22 -0
- package/src/lib/plugins/openapi/components/ResponseContent.tsx +1 -1
- package/src/lib/plugins/openapi/schema/SchemaPropertyItem.tsx +1 -4
- package/src/lib/plugins/openapi/schema/SchemaView.tsx +0 -5
- package/src/lib/plugins/openapi/schema/union-helpers.ts +0 -1
- package/src/lib/plugins/openapi/util/generateSchemaExample.ts +11 -11
- package/src/lib/ui/CodeBlock.tsx +0 -1
- package/src/lib/ui/EmbeddedCodeBlock.tsx +1 -2
- package/src/lib/ui/Separator.tsx +25 -0
- package/src/lib/ui/Tooltip.tsx +54 -32
- package/src/lib/util/createVariantComponent.tsx +31 -5
- package/src/lib/util/flattenAllOf.test.ts +637 -0
- package/src/lib/util/flattenAllOf.ts +101 -0
- package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupConnector.d.ts +0 -5
- package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupConnector.js +0 -7
- package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupConnector.js.map +0 -1
- package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupItem.d.ts +0 -4
- package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupItem.js +0 -10
- package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupItem.js.map +0 -1
- package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupView.d.ts +0 -5
- package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupView.js +0 -16
- package/dist/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupView.js.map +0 -1
- package/lib/OperationList-Cmiw1xm2.js +0 -5446
- package/lib/OperationList-Cmiw1xm2.js.map +0 -1
- package/lib/RouteGuard-DhU3LRr1.js +0 -81
- package/lib/RouteGuard-DhU3LRr1.js.map +0 -1
- package/lib/SchemaView-tHXTm5oM.js +0 -458
- package/lib/SchemaView-tHXTm5oM.js.map +0 -1
- package/lib/SyntaxHighlight-zvlnSnHB.js.map +0 -1
- package/lib/createServer-D9UvCoDf.js.map +0 -1
- package/lib/index-Cr9_YzOZ.js.map +0 -1
- package/src/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupConnector.tsx +0 -36
- package/src/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupItem.tsx +0 -25
- package/src/lib/plugins/openapi/schema/AllOfGroup/AllOfGroupView.tsx +0 -42
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SVGProps } from "react";
|
|
2
|
+
|
|
3
|
+
const GoogleIcon = (props: SVGProps<SVGSVGElement>) => (
|
|
4
|
+
<svg
|
|
5
|
+
viewBox="0 0 24 24"
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
width="1em"
|
|
8
|
+
height="1em"
|
|
9
|
+
{...props}
|
|
10
|
+
>
|
|
11
|
+
<title>{"Google"}</title>
|
|
12
|
+
<path d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z" />
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
export default GoogleIcon;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SVGProps } from "react";
|
|
2
|
+
|
|
3
|
+
const MicrosoftIcon = (props: SVGProps<SVGSVGElement>) => (
|
|
4
|
+
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" {...props}>
|
|
5
|
+
<path fill="#f25022" d="M1 1h9v9H1z" />
|
|
6
|
+
<path fill="#00a4ef" d="M1 11h9v9H1z" />
|
|
7
|
+
<path fill="#7fba00" d="M11 1h9v9h-9z" />
|
|
8
|
+
<path fill="#ffb900" d="M11 11h9v9h-9z" />
|
|
9
|
+
</svg>
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export default MicrosoftIcon;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SVGProps } from "react";
|
|
2
|
+
|
|
3
|
+
const XIcon = (props: SVGProps<SVGSVGElement>) => (
|
|
4
|
+
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" {...props}>
|
|
5
|
+
<title>{"X"}</title>
|
|
6
|
+
<path d="M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z" />
|
|
7
|
+
</svg>
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
export default XIcon;
|
|
@@ -38,6 +38,14 @@ export const RouteGuard = () => {
|
|
|
38
38
|
const needsToSignIn =
|
|
39
39
|
isProtectedRoute && !authCheckFn({ auth, context: zudoku });
|
|
40
40
|
|
|
41
|
+
if (isProtectedRoute && !auth.isAuthEnabled) {
|
|
42
|
+
throw new ZudokuError("Authentication is not enabled", {
|
|
43
|
+
title: "Authentication is not enabled",
|
|
44
|
+
developerHint:
|
|
45
|
+
"To use protectedRoutes you need authentication to be enabled",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
41
49
|
if (needsToSignIn && auth.isPending && typeof window !== "undefined") {
|
|
42
50
|
return null;
|
|
43
51
|
}
|
|
@@ -91,14 +99,6 @@ export const RouteGuard = () => {
|
|
|
91
99
|
);
|
|
92
100
|
}
|
|
93
101
|
|
|
94
|
-
if (isProtectedRoute && !auth.isAuthEnabled) {
|
|
95
|
-
throw new ZudokuError("Authentication is not enabled", {
|
|
96
|
-
title: "Authentication is not enabled",
|
|
97
|
-
developerHint:
|
|
98
|
-
"To use protectedRoutes you need authentication to be enabled",
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
102
|
return (
|
|
103
103
|
<>
|
|
104
104
|
{shouldBypass && (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { merge as mergeAllOf } from "allof-merge";
|
|
2
1
|
import { GraphQLError } from "graphql/error/index.js";
|
|
3
2
|
import { OpenAPIV3, type OpenAPIV3_1 } from "openapi-types";
|
|
3
|
+
import { flattenAllOfProcessor } from "../../util/flattenAllOf.js";
|
|
4
4
|
import { dereference, type JSONSchema } from "./dereference/index.js";
|
|
5
5
|
import { upgradeSchema } from "./upgrade/index.js";
|
|
6
6
|
|
|
@@ -101,7 +101,12 @@ export const validate = async (schemaInput: unknown) => {
|
|
|
101
101
|
|
|
102
102
|
const dereferenced = await dereference(schema);
|
|
103
103
|
const upgraded = upgradeSchema(dereferenced);
|
|
104
|
-
const merged = mergeAllOf(upgraded) as OpenAPIDocument;
|
|
105
104
|
|
|
106
|
-
|
|
105
|
+
const flattened = await flattenAllOfProcessor({
|
|
106
|
+
schema: upgraded,
|
|
107
|
+
file: "schema.json",
|
|
108
|
+
dereference: async (schema) => schema,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return flattened;
|
|
107
112
|
};
|
|
@@ -11,15 +11,19 @@ export const ProtectedRoute = () => {
|
|
|
11
11
|
return null;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
if (!auth.isAuthEnabled) {
|
|
15
|
+
return (
|
|
16
|
+
<div className="flex flex-col justify-center gap-2 items-center h-1/2">
|
|
17
|
+
<DeveloperHint className="max-w-[600px]">
|
|
18
|
+
Authentication needs to be enabled for API keys to work. Enable it in
|
|
19
|
+
your Zudoku configuration under <code>authentication</code>.
|
|
20
|
+
</DeveloperHint>
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
14
25
|
return auth.isAuthenticated ? (
|
|
15
26
|
<Outlet />
|
|
16
|
-
) : !auth.isAuthEnabled ? (
|
|
17
|
-
<div className="flex flex-col justify-center gap-2 items-center h-1/2">
|
|
18
|
-
<DeveloperHint className="max-w-[600px]">
|
|
19
|
-
Authentication needs to be enabled for API keys to work. Enable it in
|
|
20
|
-
your Zudoku configuration under <code>authentication</code>.
|
|
21
|
-
</DeveloperHint>
|
|
22
|
-
</div>
|
|
23
27
|
) : (
|
|
24
28
|
<div className="flex flex-col justify-center gap-2 items-center h-1/2">
|
|
25
29
|
Please login first to view this page
|
|
@@ -9,6 +9,10 @@ import {
|
|
|
9
9
|
import { cn } from "../../util/cn.js";
|
|
10
10
|
import useIsomorphicLayoutEffect from "../../util/useIsomorphicLayoutEffect.js";
|
|
11
11
|
|
|
12
|
+
export const OverflowOverlay = () => (
|
|
13
|
+
<div className="absolute inset-0 bg-linear-to-b from-transparent to-zinc-50/60 dark:to-zinc-950/90 z-10 transition-all group-hover:to-transparent" />
|
|
14
|
+
);
|
|
15
|
+
|
|
12
16
|
export const CollapsibleCode = ({
|
|
13
17
|
children,
|
|
14
18
|
maxHeight = 250,
|
|
@@ -48,9 +52,7 @@ export const CollapsibleCode = ({
|
|
|
48
52
|
!open && isOverflowing && "max-h-(--max-height)",
|
|
49
53
|
)}
|
|
50
54
|
>
|
|
51
|
-
{!open && isOverflowing &&
|
|
52
|
-
<div className=" absolute inset-0 bg-gradient-to-b from-transparent to-zinc-50/60 dark:to-zinc-950/90 z-10 transition-all group-hover:to-transparent"></div>
|
|
53
|
-
)}
|
|
55
|
+
{!open && isOverflowing && <OverflowOverlay />}
|
|
54
56
|
<div ref={contentRef}>{children}</div>
|
|
55
57
|
{!open && isOverflowing && (
|
|
56
58
|
<CollapsibleTrigger
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { InfoIcon } from "lucide-react";
|
|
2
|
+
import { SyntaxHighlight } from "zudoku/ui/SyntaxHighlight.js";
|
|
3
|
+
import {
|
|
4
|
+
Tooltip,
|
|
5
|
+
TooltipContent,
|
|
6
|
+
TooltipProvider,
|
|
7
|
+
TooltipTrigger,
|
|
8
|
+
} from "zudoku/ui/Tooltip.js";
|
|
9
|
+
import { NonHighlightedCode } from "./components/NonHighlightedCode.js";
|
|
10
|
+
import * as SidecarBox from "./SidecarBox.js";
|
|
11
|
+
|
|
12
|
+
export const GeneratedExampleSidecarBox = ({
|
|
13
|
+
code,
|
|
14
|
+
isOnScreen,
|
|
15
|
+
shouldLazyHighlight,
|
|
16
|
+
}: {
|
|
17
|
+
code: string;
|
|
18
|
+
isOnScreen: boolean;
|
|
19
|
+
shouldLazyHighlight?: boolean;
|
|
20
|
+
}) => {
|
|
21
|
+
return (
|
|
22
|
+
<SidecarBox.Root>
|
|
23
|
+
<SidecarBox.Head className="text-xs flex justify-between items-center">
|
|
24
|
+
<div className="flex items-center gap-1.5 font-mono">
|
|
25
|
+
Request Body Example
|
|
26
|
+
<TooltipProvider>
|
|
27
|
+
<Tooltip>
|
|
28
|
+
<TooltipTrigger asChild>
|
|
29
|
+
<InfoIcon size={13} />
|
|
30
|
+
</TooltipTrigger>
|
|
31
|
+
<TooltipContent>
|
|
32
|
+
This example is auto-generated from the schema.
|
|
33
|
+
</TooltipContent>
|
|
34
|
+
</Tooltip>
|
|
35
|
+
</TooltipProvider>
|
|
36
|
+
</div>
|
|
37
|
+
</SidecarBox.Head>
|
|
38
|
+
<SidecarBox.Body className="p-0">
|
|
39
|
+
{shouldLazyHighlight && !isOnScreen ? (
|
|
40
|
+
<NonHighlightedCode code={code} />
|
|
41
|
+
) : (
|
|
42
|
+
<SyntaxHighlight
|
|
43
|
+
embedded
|
|
44
|
+
language="json"
|
|
45
|
+
code={code}
|
|
46
|
+
className="[--scrollbar-color:gray] rounded-none text-xs max-h-[200px]"
|
|
47
|
+
/>
|
|
48
|
+
)}
|
|
49
|
+
</SidecarBox.Body>
|
|
50
|
+
</SidecarBox.Root>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -200,6 +200,10 @@ export const OperationList = ({
|
|
|
200
200
|
|
|
201
201
|
const { operations, next, prev, description: tagDescription } = schema.tag;
|
|
202
202
|
|
|
203
|
+
// Simple heuristic to determine if we should lazy highlight the code
|
|
204
|
+
// This is to avoid the performance issues when there are a lot of operations
|
|
205
|
+
const shouldLazyHighlight = operations.length > 30;
|
|
206
|
+
|
|
203
207
|
// The summary property is preferable here as it is a short description of
|
|
204
208
|
// the API, whereas the description property is typically longer and supports
|
|
205
209
|
// commonmark formatting, making it ill-suited for use in the meta description
|
|
@@ -337,6 +341,7 @@ export const OperationList = ({
|
|
|
337
341
|
<OperationListItem
|
|
338
342
|
operationFragment={fragment}
|
|
339
343
|
globalSelectedServer={globalSelectedServer}
|
|
344
|
+
shouldLazyHighlight={shouldLazyHighlight}
|
|
340
345
|
/>
|
|
341
346
|
<hr className="my-10" />
|
|
342
347
|
</div>
|
|
@@ -23,9 +23,11 @@ export type ParameterGroup = (typeof PARAM_GROUPS)[number];
|
|
|
23
23
|
export const OperationListItem = ({
|
|
24
24
|
operationFragment,
|
|
25
25
|
globalSelectedServer,
|
|
26
|
+
shouldLazyHighlight,
|
|
26
27
|
}: {
|
|
27
28
|
operationFragment: FragmentType<typeof OperationsFragment>;
|
|
28
29
|
globalSelectedServer?: string;
|
|
30
|
+
shouldLazyHighlight?: boolean;
|
|
29
31
|
}) => {
|
|
30
32
|
const operation = useFragment(OperationsFragment, operationFragment);
|
|
31
33
|
const groupedParameters = groupBy(
|
|
@@ -173,6 +175,7 @@ export const OperationListItem = ({
|
|
|
173
175
|
onSelectResponse={setSelectedResponse}
|
|
174
176
|
operation={operation}
|
|
175
177
|
globalSelectedServer={globalSelectedServer}
|
|
178
|
+
shouldLazyHighlight={shouldLazyHighlight}
|
|
176
179
|
/>
|
|
177
180
|
))}
|
|
178
181
|
</div>
|
|
@@ -5,9 +5,20 @@ import { SidecarExamples } from "./SidecarExamples.js";
|
|
|
5
5
|
export const RequestBodySidecarBox = ({
|
|
6
6
|
content,
|
|
7
7
|
onExampleChange,
|
|
8
|
+
isOnScreen,
|
|
9
|
+
shouldLazyHighlight,
|
|
10
|
+
selectedContentIndex,
|
|
11
|
+
selectedExampleIndex,
|
|
8
12
|
}: {
|
|
9
13
|
content: MediaTypeObject[];
|
|
10
|
-
onExampleChange?: (
|
|
14
|
+
onExampleChange?: (selected: {
|
|
15
|
+
contentTypeIndex: number;
|
|
16
|
+
exampleIndex: number;
|
|
17
|
+
}) => void;
|
|
18
|
+
isOnScreen: boolean;
|
|
19
|
+
shouldLazyHighlight?: boolean;
|
|
20
|
+
selectedContentIndex: number;
|
|
21
|
+
selectedExampleIndex: number;
|
|
11
22
|
}) => {
|
|
12
23
|
if (content.length === 0) return null;
|
|
13
24
|
|
|
@@ -16,7 +27,14 @@ export const RequestBodySidecarBox = ({
|
|
|
16
27
|
<SidecarBox.Head className="text-xs flex justify-between items-center">
|
|
17
28
|
<span className="font-mono">Request Body Example</span>
|
|
18
29
|
</SidecarBox.Head>
|
|
19
|
-
<SidecarExamples
|
|
30
|
+
<SidecarExamples
|
|
31
|
+
selectedContentIndex={selectedContentIndex}
|
|
32
|
+
selectedExampleIndex={selectedExampleIndex}
|
|
33
|
+
content={content}
|
|
34
|
+
onExampleChange={onExampleChange}
|
|
35
|
+
isOnScreen={isOnScreen}
|
|
36
|
+
shouldLazyHighlight={shouldLazyHighlight}
|
|
37
|
+
/>
|
|
20
38
|
</SidecarBox.Root>
|
|
21
39
|
);
|
|
22
40
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Tabs from "@radix-ui/react-tabs";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
2
3
|
import { cn } from "../../util/cn.js";
|
|
3
4
|
import type { ResponseItem } from "./graphql/graphql.js";
|
|
4
5
|
import * as SidecarBox from "./SidecarBox.js";
|
|
@@ -8,11 +9,25 @@ export const ResponsesSidecarBox = ({
|
|
|
8
9
|
responses,
|
|
9
10
|
selectedResponse,
|
|
10
11
|
onSelectResponse,
|
|
12
|
+
isOnScreen,
|
|
13
|
+
shouldLazyHighlight,
|
|
11
14
|
}: {
|
|
12
15
|
responses: ResponseItem[];
|
|
13
16
|
selectedResponse?: string;
|
|
14
17
|
onSelectResponse: (response: string) => void;
|
|
18
|
+
isOnScreen: boolean;
|
|
19
|
+
shouldLazyHighlight?: boolean;
|
|
15
20
|
}) => {
|
|
21
|
+
const [selectedContentIndex, setSelectedContentIndex] = useState(0);
|
|
22
|
+
const [selectedExampleIndex, setSelectedExampleIndex] = useState(0);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!selectedResponse) return;
|
|
26
|
+
|
|
27
|
+
setSelectedContentIndex(0);
|
|
28
|
+
setSelectedExampleIndex(0);
|
|
29
|
+
}, [selectedResponse]);
|
|
30
|
+
|
|
16
31
|
return (
|
|
17
32
|
<SidecarBox.Root>
|
|
18
33
|
<Tabs.Root
|
|
@@ -40,7 +55,17 @@ export const ResponsesSidecarBox = ({
|
|
|
40
55
|
</SidecarBox.Head>
|
|
41
56
|
{responses.map((response) => (
|
|
42
57
|
<Tabs.Content key={response.statusCode} value={response.statusCode}>
|
|
43
|
-
<SidecarExamples
|
|
58
|
+
<SidecarExamples
|
|
59
|
+
selectedContentIndex={selectedContentIndex}
|
|
60
|
+
selectedExampleIndex={selectedExampleIndex}
|
|
61
|
+
onExampleChange={(selected) => {
|
|
62
|
+
setSelectedContentIndex(selected.contentTypeIndex);
|
|
63
|
+
setSelectedExampleIndex(selected.exampleIndex);
|
|
64
|
+
}}
|
|
65
|
+
content={response.content ?? []}
|
|
66
|
+
isOnScreen={isOnScreen}
|
|
67
|
+
shouldLazyHighlight={shouldLazyHighlight}
|
|
68
|
+
/>
|
|
44
69
|
</Tabs.Content>
|
|
45
70
|
))}
|
|
46
71
|
</Tabs.Root>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { useMemo, useState, useTransition } from "react";
|
|
2
2
|
import { useSearchParams } from "react-router";
|
|
3
3
|
import { useZudoku } from "zudoku/hooks";
|
|
4
|
+
import { SyntaxHighlight } from "zudoku/ui/SyntaxHighlight.js";
|
|
4
5
|
import { useAuthState } from "../../authentication/state.js";
|
|
5
6
|
import { PathRenderer } from "../../components/PathRenderer.js";
|
|
6
|
-
import type { SchemaObject } from "../../oas/parser/index.js";
|
|
7
|
-
import { SyntaxHighlight } from "../../ui/SyntaxHighlight.js";
|
|
8
7
|
import { cn } from "../../util/cn.js";
|
|
9
8
|
import { useOnScreen } from "../../util/useOnScreen.js";
|
|
10
|
-
import { CollapsibleCode } from "./CollapsibleCode.js";
|
|
11
9
|
import { ColorizedParam } from "./ColorizedParam.js";
|
|
10
|
+
import { NonHighlightedCode } from "./components/NonHighlightedCode.js";
|
|
12
11
|
import { useOasConfig } from "./context.js";
|
|
12
|
+
import { GeneratedExampleSidecarBox } from "./GeneratedExampleSidecarBox.js";
|
|
13
13
|
import type { OperationsFragmentFragment } from "./graphql/graphql.js";
|
|
14
14
|
import { graphql } from "./graphql/index.js";
|
|
15
15
|
import { PlaygroundDialogWrapper } from "./PlaygroundDialogWrapper.js";
|
|
@@ -51,11 +51,13 @@ export const Sidecar = ({
|
|
|
51
51
|
selectedResponse,
|
|
52
52
|
onSelectResponse,
|
|
53
53
|
globalSelectedServer,
|
|
54
|
+
shouldLazyHighlight,
|
|
54
55
|
}: {
|
|
55
56
|
operation: OperationsFragmentFragment;
|
|
56
57
|
selectedResponse?: string;
|
|
57
58
|
onSelectResponse: (response: string) => void;
|
|
58
59
|
globalSelectedServer?: string;
|
|
60
|
+
shouldLazyHighlight?: boolean;
|
|
59
61
|
}) => {
|
|
60
62
|
const { options } = useOasConfig();
|
|
61
63
|
const auth = useAuthState();
|
|
@@ -65,13 +67,8 @@ export const Sidecar = ({
|
|
|
65
67
|
|
|
66
68
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
67
69
|
const [, startTransition] = useTransition();
|
|
68
|
-
const [selectedExample, setSelectedExample] = useState<unknown>();
|
|
69
|
-
|
|
70
|
-
const selectedLang =
|
|
71
|
-
searchParams.get("lang") ?? options?.examplesLanguage ?? "shell";
|
|
72
70
|
|
|
73
71
|
const requestBodyContent = operation.requestBody?.content;
|
|
74
|
-
|
|
75
72
|
const transformedRequestBodyContent =
|
|
76
73
|
requestBodyContent && options?.transformExamples
|
|
77
74
|
? options.transformExamples({
|
|
@@ -83,6 +80,30 @@ export const Sidecar = ({
|
|
|
83
80
|
})
|
|
84
81
|
: requestBodyContent;
|
|
85
82
|
|
|
83
|
+
const [selectedRequestExample, setSelectedRequestExample] = useState<{
|
|
84
|
+
contentTypeIndex: number;
|
|
85
|
+
exampleIndex: number;
|
|
86
|
+
}>({
|
|
87
|
+
contentTypeIndex: 0,
|
|
88
|
+
exampleIndex: 0,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const selectedContent = transformedRequestBodyContent?.at(
|
|
92
|
+
selectedRequestExample.contentTypeIndex,
|
|
93
|
+
);
|
|
94
|
+
const currentExample = selectedContent?.examples?.at(
|
|
95
|
+
selectedRequestExample.exampleIndex,
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
const selectedLang =
|
|
99
|
+
searchParams.get("lang") ?? options?.examplesLanguage ?? "shell";
|
|
100
|
+
|
|
101
|
+
const currentExampleCode = currentExample
|
|
102
|
+
? (currentExample?.value ?? currentExample)
|
|
103
|
+
: selectedContent?.schema
|
|
104
|
+
? generateSchemaExample(selectedContent?.schema)
|
|
105
|
+
: undefined;
|
|
106
|
+
|
|
86
107
|
const path = (
|
|
87
108
|
<PathRenderer
|
|
88
109
|
path={operation.path}
|
|
@@ -104,34 +125,21 @@ export const Sidecar = ({
|
|
|
104
125
|
const selectedServer =
|
|
105
126
|
globalSelectedServer || operation.servers.at(0)?.url || "";
|
|
106
127
|
|
|
107
|
-
const
|
|
108
|
-
const exampleBody =
|
|
109
|
-
selectedExample ??
|
|
110
|
-
(transformedRequestBodyContent?.[0]?.schema
|
|
111
|
-
? generateSchemaExample(
|
|
112
|
-
transformedRequestBodyContent[0].schema as SchemaObject,
|
|
113
|
-
)
|
|
114
|
-
: undefined);
|
|
115
|
-
|
|
128
|
+
const httpSnippetCode = useMemo<string | undefined>(() => {
|
|
116
129
|
const snippet = createHttpSnippet({
|
|
117
130
|
operation,
|
|
118
131
|
selectedServer,
|
|
119
|
-
exampleBody:
|
|
132
|
+
exampleBody: currentExampleCode
|
|
120
133
|
? {
|
|
121
134
|
mimeType: "application/json",
|
|
122
|
-
text: JSON.stringify(
|
|
135
|
+
text: JSON.stringify(currentExampleCode, null, 2),
|
|
123
136
|
}
|
|
124
137
|
: { mimeType: "application/json" },
|
|
125
138
|
});
|
|
126
139
|
|
|
127
140
|
return getConverted(snippet, selectedLang);
|
|
128
|
-
}, [
|
|
129
|
-
|
|
130
|
-
transformedRequestBodyContent,
|
|
131
|
-
operation,
|
|
132
|
-
selectedServer,
|
|
133
|
-
selectedLang,
|
|
134
|
-
]);
|
|
141
|
+
}, [operation, selectedServer, selectedLang, currentExampleCode]);
|
|
142
|
+
|
|
135
143
|
const [ref, isOnScreen] = useOnScreen({ rootMargin: "200px 0px 200px 0px" });
|
|
136
144
|
|
|
137
145
|
const showPlayground =
|
|
@@ -150,7 +158,7 @@ export const Sidecar = ({
|
|
|
150
158
|
>
|
|
151
159
|
<SidecarBox.Root>
|
|
152
160
|
<SidecarBox.Head className="flex justify-between items-center flex-nowrap py-2.5 gap-2 text-xs">
|
|
153
|
-
<span className="font-mono break-
|
|
161
|
+
<span className="font-mono wrap-break-word leading-6">
|
|
154
162
|
<span className={cn("font-semibold", methodTextColor)}>
|
|
155
163
|
{operation.method.toUpperCase()}
|
|
156
164
|
</span>
|
|
@@ -165,47 +173,60 @@ export const Sidecar = ({
|
|
|
165
173
|
/>
|
|
166
174
|
)}
|
|
167
175
|
</SidecarBox.Head>
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
<
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
</SidecarBox.Footer>
|
|
198
|
-
</>
|
|
199
|
-
)}
|
|
176
|
+
<SidecarBox.Body className="p-0">
|
|
177
|
+
{shouldLazyHighlight && !isOnScreen ? (
|
|
178
|
+
<NonHighlightedCode code={httpSnippetCode ?? ""} />
|
|
179
|
+
) : (
|
|
180
|
+
<SyntaxHighlight
|
|
181
|
+
embedded
|
|
182
|
+
language={selectedLang}
|
|
183
|
+
className="[--scrollbar-color:gray] rounded-none text-xs max-h-[200px]"
|
|
184
|
+
// biome-ignore lint/style/noNonNullAssertion: code is guaranteed to be defined
|
|
185
|
+
code={httpSnippetCode!}
|
|
186
|
+
/>
|
|
187
|
+
)}
|
|
188
|
+
</SidecarBox.Body>
|
|
189
|
+
<SidecarBox.Footer className="flex items-center text-xs gap-2 justify-end py-2.5">
|
|
190
|
+
<span>Show example in</span>
|
|
191
|
+
<SimpleSelect
|
|
192
|
+
className="self-start max-w-[150px]"
|
|
193
|
+
value={selectedLang}
|
|
194
|
+
onChange={(e) => {
|
|
195
|
+
startTransition(() => {
|
|
196
|
+
setSearchParams((prev) => {
|
|
197
|
+
prev.set("lang", e.target.value);
|
|
198
|
+
return prev;
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
}}
|
|
202
|
+
options={EXAMPLE_LANGUAGES}
|
|
203
|
+
/>
|
|
204
|
+
</SidecarBox.Footer>
|
|
200
205
|
</SidecarBox.Root>
|
|
201
|
-
|
|
206
|
+
|
|
207
|
+
{transformedRequestBodyContent && currentExample ? (
|
|
202
208
|
<RequestBodySidecarBox
|
|
203
209
|
content={transformedRequestBodyContent}
|
|
204
|
-
onExampleChange={
|
|
210
|
+
onExampleChange={(selected) => {
|
|
211
|
+
setSelectedRequestExample(selected);
|
|
212
|
+
}}
|
|
213
|
+
selectedContentIndex={selectedRequestExample.contentTypeIndex}
|
|
214
|
+
selectedExampleIndex={selectedRequestExample.exampleIndex}
|
|
215
|
+
isOnScreen={isOnScreen}
|
|
216
|
+
shouldLazyHighlight={shouldLazyHighlight}
|
|
205
217
|
/>
|
|
206
|
-
)
|
|
207
|
-
|
|
218
|
+
) : transformedRequestBodyContent && currentExampleCode ? (
|
|
219
|
+
<GeneratedExampleSidecarBox
|
|
220
|
+
isOnScreen={isOnScreen}
|
|
221
|
+
shouldLazyHighlight={shouldLazyHighlight}
|
|
222
|
+
code={JSON.stringify(currentExampleCode, null, 2)}
|
|
223
|
+
/>
|
|
224
|
+
) : null}
|
|
225
|
+
|
|
226
|
+
{operation.responses.length > 0 && (
|
|
208
227
|
<ResponsesSidecarBox
|
|
228
|
+
isOnScreen={isOnScreen}
|
|
229
|
+
shouldLazyHighlight={shouldLazyHighlight}
|
|
209
230
|
selectedResponse={selectedResponse}
|
|
210
231
|
onSelectResponse={onSelectResponse}
|
|
211
232
|
responses={operation.responses.map((response) => ({
|