zudoku 0.3.0-dev.31 → 0.3.0-dev.32
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/App.d.ts +1 -0
- package/dist/app/App.js +2 -0
- package/dist/app/App.js.map +1 -0
- package/dist/app/entry.client.d.ts +5 -0
- package/dist/app/entry.client.js +28 -0
- package/dist/app/entry.client.js.map +1 -0
- package/dist/app/entry.server.d.ts +10 -0
- package/dist/app/entry.server.js +107 -0
- package/dist/app/entry.server.js.map +1 -0
- package/dist/app/main.d.ts +26 -2
- package/dist/app/main.js +39 -17
- package/dist/app/main.js.map +1 -1
- package/dist/app/tailwind.js +5 -0
- package/dist/app/tailwind.js.map +1 -1
- package/dist/app/zudoku-manifest.d.ts +1 -0
- package/dist/app/zudoku-manifest.js +20 -0
- package/dist/app/zudoku-manifest.js.map +1 -0
- package/dist/cli/cmds/dev.js +5 -0
- package/dist/cli/cmds/dev.js.map +1 -1
- package/dist/cli/dev/handler.d.ts +1 -0
- package/dist/cli/dev/handler.js +3 -1
- package/dist/cli/dev/handler.js.map +1 -1
- package/dist/config/config.d.ts +5 -0
- package/dist/lib/authentication/providers/clerk.js +2 -0
- package/dist/lib/authentication/providers/clerk.js.map +1 -1
- package/dist/lib/components/DevPortal.d.ts +1 -1
- package/dist/lib/components/DevPortal.js +6 -10
- package/dist/lib/components/DevPortal.js.map +1 -1
- package/dist/lib/components/ErrorPage.d.ts +6 -0
- package/dist/lib/components/ErrorPage.js +9 -0
- package/dist/lib/components/ErrorPage.js.map +1 -0
- package/dist/lib/components/InlineCode.d.ts +5 -0
- package/dist/lib/components/InlineCode.js +4 -0
- package/dist/lib/components/InlineCode.js.map +1 -0
- package/dist/lib/components/Layout.js +2 -1
- package/dist/lib/components/Layout.js.map +1 -1
- package/dist/lib/components/NotFoundPage.d.ts +1 -0
- package/dist/lib/components/NotFoundPage.js +12 -0
- package/dist/lib/components/NotFoundPage.js.map +1 -0
- package/dist/lib/components/SyntaxHighlight.d.ts +3 -2
- package/dist/lib/components/SyntaxHighlight.js +20 -22
- package/dist/lib/components/SyntaxHighlight.js.map +1 -1
- package/dist/lib/errors/RouterError.js +6 -3
- package/dist/lib/errors/RouterError.js.map +1 -1
- package/dist/lib/errors/ServerError.d.ts +3 -0
- package/dist/lib/errors/ServerError.js +6 -0
- package/dist/lib/errors/ServerError.js.map +1 -0
- package/dist/lib/oas/parser/index.d.ts +1 -1
- package/dist/lib/oas/parser/index.js +38 -14
- package/dist/lib/oas/parser/index.js.map +1 -1
- package/dist/lib/plugins/api-keys/index.js +3 -8
- package/dist/lib/plugins/api-keys/index.js.map +1 -1
- package/dist/lib/plugins/markdown/generateRoutes.js.map +1 -1
- package/dist/lib/plugins/markdown/index.js +3 -7
- package/dist/lib/plugins/markdown/index.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationList.js +11 -1
- package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +2 -1
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/SchemaListView.js +2 -1
- package/dist/lib/plugins/openapi/SchemaListView.js.map +1 -1
- package/dist/lib/plugins/openapi/client/createMemoryClient.js +1 -1
- package/dist/lib/plugins/openapi/client/createMemoryClient.js.map +1 -1
- package/dist/lib/plugins/openapi/index.js +9 -1
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/plugins/redirect/index.js +2 -3
- package/dist/lib/plugins/redirect/index.js.map +1 -1
- package/dist/lib/ui/Callout.js +1 -1
- package/dist/lib/ui/Callout.js.map +1 -1
- package/dist/lib/ui/button-variants.d.ts +1 -1
- package/dist/lib/util/MdxComponents.js +2 -2
- package/dist/lib/util/MdxComponents.js.map +1 -1
- package/dist/lib/util/groupBy.d.ts +1 -6
- package/dist/lib/util/groupBy.js +10 -8
- package/dist/lib/util/groupBy.js.map +1 -1
- package/dist/vite/build.js +23 -10
- package/dist/vite/build.js.map +1 -1
- package/dist/vite/config.d.ts +2 -1
- package/dist/vite/config.js +33 -7
- package/dist/vite/config.js.map +1 -1
- package/dist/vite/dev-server.d.ts +1 -1
- package/dist/vite/dev-server.js +15 -9
- package/dist/vite/dev-server.js.map +1 -1
- package/dist/vite/html.js +5 -4
- package/dist/vite/html.js.map +1 -1
- package/dist/vite/plugin-custom-css.d.ts +6 -0
- package/dist/vite/plugin-custom-css.js +55 -0
- package/dist/vite/plugin-custom-css.js.map +1 -0
- package/dist/vite/plugin-docs.js +14 -5
- package/dist/vite/plugin-docs.js.map +1 -1
- package/dist/vite/plugin-openapi-worker.js +4 -1
- package/dist/vite/plugin-openapi-worker.js.map +1 -1
- package/dist/vite/plugin.js +2 -0
- package/dist/vite/plugin.js.map +1 -1
- package/dist/vite/prerender.d.ts +1 -0
- package/dist/vite/prerender.js +57 -0
- package/dist/vite/prerender.js.map +1 -0
- package/lib/{DevPortalProvider-BMk-RCE0.js → DevPortalProvider-BlxLX6GG.js} +230 -250
- package/lib/DevPortalProvider-BlxLX6GG.js.map +1 -0
- package/lib/{Markdown-DDmW47R9.js → Markdown-CL8KPvJN.js} +8 -9
- package/lib/{Markdown-DDmW47R9.js.map → Markdown-CL8KPvJN.js.map} +1 -1
- package/lib/MdxComponents-Ev_hBHb2.js +5885 -0
- package/lib/MdxComponents-Ev_hBHb2.js.map +1 -0
- package/lib/{MdxPage-DyJAHF9y.js → MdxPage-Z3HKNTrj.js} +92 -89
- package/lib/MdxPage-Z3HKNTrj.js.map +1 -0
- package/lib/{OperationList-Dz9rHM9r.js → OperationList-KoITgfDT.js} +1967 -1785
- package/lib/OperationList-KoITgfDT.js.map +1 -0
- package/lib/Route-Bf1_D_vC.js +13 -0
- package/lib/{Route-CN_7-e5r.js.map → Route-Bf1_D_vC.js.map} +1 -1
- package/lib/Select-DSa3bN4t.js +4770 -0
- package/lib/Select-DSa3bN4t.js.map +1 -0
- package/lib/assets/{worker-BXS8hiSM.js → worker-BjPv-hjP.js} +3100 -2720
- package/lib/assets/worker-BjPv-hjP.js.map +1 -0
- package/lib/hook-CTmJ6CWq.js +35 -0
- package/lib/hook-CTmJ6CWq.js.map +1 -0
- package/lib/index-BdWBDosx.js +74 -0
- package/lib/index-BdWBDosx.js.map +1 -0
- package/lib/{index-Cpdpun6t.js → index-BoWzKb_9.js} +57 -41
- package/lib/index-BoWzKb_9.js.map +1 -0
- package/lib/{AnchorLink-ptdQk87q.js → index.esm-CPEExBJE.js} +156 -168
- package/lib/index.esm-CPEExBJE.js.map +1 -0
- package/lib/jsx-runtime-CM0TzjGp.js +866 -0
- package/lib/jsx-runtime-CM0TzjGp.js.map +1 -0
- package/lib/mutation-91kw0lHb.js +208 -0
- package/lib/mutation-91kw0lHb.js.map +1 -0
- package/lib/router-CcYTwKjf.js +183 -0
- package/lib/router-CcYTwKjf.js.map +1 -0
- package/lib/zudoku.auth-clerk.js.map +1 -1
- package/lib/zudoku.auth-openid.js +588 -441
- package/lib/zudoku.auth-openid.js.map +1 -1
- package/lib/zudoku.components.js +284 -595
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.openapi-worker.js +18 -18
- package/lib/zudoku.plugin-api-keys.js +143 -98
- package/lib/zudoku.plugin-api-keys.js.map +1 -1
- package/lib/zudoku.plugin-markdown.js +2 -49
- package/lib/zudoku.plugin-markdown.js.map +1 -1
- package/lib/zudoku.plugin-openapi.js +5 -3
- package/lib/zudoku.plugin-openapi.js.map +1 -1
- package/lib/zudoku.plugin-redirect.js +6 -7
- package/lib/zudoku.plugin-redirect.js.map +1 -1
- package/package.json +2 -1
- package/src/app/App.tsx +0 -0
- package/src/app/entry.client.tsx +51 -0
- package/src/app/entry.server.tsx +158 -0
- package/src/app/main.tsx +65 -43
- package/src/app/tailwind.ts +6 -0
- package/src/app/zudoku-manifest.ts +22 -0
- package/src/lib/authentication/providers/clerk.tsx +1 -0
- package/src/lib/components/DevPortal.tsx +25 -33
- package/src/lib/components/ErrorPage.tsx +28 -0
- package/src/lib/components/InlineCode.tsx +19 -0
- package/src/lib/components/Layout.tsx +7 -4
- package/src/lib/components/NotFoundPage.tsx +39 -0
- package/src/lib/components/SyntaxHighlight.tsx +26 -22
- package/src/lib/errors/RouterError.tsx +8 -7
- package/src/lib/errors/ServerError.tsx +5 -0
- package/src/lib/oas/parser/index.ts +41 -22
- package/src/lib/plugins/api-keys/index.tsx +4 -16
- package/src/lib/plugins/markdown/generateRoutes.tsx +1 -1
- package/src/lib/plugins/markdown/index.tsx +3 -7
- package/src/lib/plugins/openapi/OperationList.tsx +30 -0
- package/src/lib/plugins/openapi/OperationListItem.tsx +3 -1
- package/src/lib/plugins/openapi/SchemaListView.tsx +8 -10
- package/src/lib/plugins/openapi/client/createMemoryClient.ts +1 -1
- package/src/lib/plugins/openapi/index.tsx +18 -1
- package/src/lib/plugins/redirect/index.tsx +2 -2
- package/src/lib/ui/Callout.tsx +2 -2
- package/src/lib/util/MdxComponents.tsx +2 -11
- package/src/lib/util/groupBy.ts +7 -12
- package/dist/lib/components/Router.d.ts +0 -4
- package/dist/lib/components/Router.js +0 -21
- package/dist/lib/components/Router.js.map +0 -1
- package/lib/AnchorLink-ptdQk87q.js.map +0 -1
- package/lib/DevPortalProvider-BMk-RCE0.js.map +0 -1
- package/lib/MdxComponents-C0R6zobS.js +0 -3019
- package/lib/MdxComponents-C0R6zobS.js.map +0 -1
- package/lib/MdxPage-DyJAHF9y.js.map +0 -1
- package/lib/OperationList-Dz9rHM9r.js.map +0 -1
- package/lib/Route-CN_7-e5r.js +0 -14
- package/lib/Select-D-Jtx53Q.js +0 -4572
- package/lib/Select-D-Jtx53Q.js.map +0 -1
- package/lib/Spinner-BG1JnYy0.js +0 -182
- package/lib/Spinner-BG1JnYy0.js.map +0 -1
- package/lib/assets/worker-BXS8hiSM.js.map +0 -1
- package/lib/cn-DpqTslo9.js +0 -2342
- package/lib/cn-DpqTslo9.js.map +0 -1
- package/lib/hook-BzBeIPL4.js +0 -25
- package/lib/hook-BzBeIPL4.js.map +0 -1
- package/lib/index-BaOOUFsA.js +0 -412
- package/lib/index-BaOOUFsA.js.map +0 -1
- package/lib/index-CPvRaBBB.js +0 -713
- package/lib/index-CPvRaBBB.js.map +0 -1
- package/lib/index-Cpdpun6t.js.map +0 -1
- package/lib/index-DLS6fPwU.js +0 -464
- package/lib/index-DLS6fPwU.js.map +0 -1
- package/lib/jsx-runtime-SV6hXQua.js +0 -3009
- package/lib/jsx-runtime-SV6hXQua.js.map +0 -1
- package/lib/loglevel-CA34MiFn.js +0 -153
- package/lib/loglevel-CA34MiFn.js.map +0 -1
- package/lib/util-CCWvaWo7.js +0 -41
- package/lib/util-CCWvaWo7.js.map +0 -1
- package/src/lib/components/Router.tsx +0 -24
|
@@ -7,25 +7,23 @@ import {
|
|
|
7
7
|
|
|
8
8
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
import("prismjs/components/prism-objectivec.min.js");
|
|
28
|
-
}
|
|
10
|
+
globalThis.Prism = Prism;
|
|
11
|
+
// @ts-expect-error This is untyped
|
|
12
|
+
import("prismjs/components/prism-bash.min.js");
|
|
13
|
+
// @ts-expect-error This is untyped
|
|
14
|
+
import("prismjs/components/prism-ruby.min.js");
|
|
15
|
+
// @ts-expect-error This is untyped
|
|
16
|
+
import("prismjs/components/prism-markup-templating.js");
|
|
17
|
+
// @ts-expect-error This is untyped
|
|
18
|
+
import("prismjs/components/prism-php.min.js");
|
|
19
|
+
// @ts-expect-error This is untyped
|
|
20
|
+
import("prismjs/components/prism-json.min.js");
|
|
21
|
+
// @ts-expect-error This is untyped
|
|
22
|
+
import("prismjs/components/prism-java.min.js");
|
|
23
|
+
// @ts-expect-error This is untyped
|
|
24
|
+
import("prismjs/components/prism-csharp.min.js");
|
|
25
|
+
// @ts-expect-error This is untyped
|
|
26
|
+
import("prismjs/components/prism-objectivec.min.js");
|
|
29
27
|
|
|
30
28
|
import { useState } from "react";
|
|
31
29
|
import { cn } from "../util/cn.js";
|
|
@@ -37,10 +35,12 @@ type SyntaxHighlightProps = {
|
|
|
37
35
|
wrapLines?: boolean;
|
|
38
36
|
copyable?: boolean;
|
|
39
37
|
showLanguageIndicator?: boolean;
|
|
40
|
-
|
|
38
|
+
language?: string;
|
|
39
|
+
} & Omit<HighlightProps, "children" | "language">;
|
|
41
40
|
|
|
42
41
|
export const SyntaxHighlight = ({
|
|
43
42
|
copyable = true,
|
|
43
|
+
language = "plain",
|
|
44
44
|
...props
|
|
45
45
|
}: SyntaxHighlightProps) => {
|
|
46
46
|
const [isDark] = useTheme();
|
|
@@ -51,7 +51,11 @@ export const SyntaxHighlight = ({
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
return (
|
|
54
|
-
<Highlight
|
|
54
|
+
<Highlight
|
|
55
|
+
theme={isDark ? themes.vsDark : themes.github}
|
|
56
|
+
language={language}
|
|
57
|
+
{...props}
|
|
58
|
+
>
|
|
55
59
|
{({ className, style, tokens, getLineProps, getTokenProps }) => (
|
|
56
60
|
<pre
|
|
57
61
|
className={cn(
|
|
@@ -88,7 +92,7 @@ export const SyntaxHighlight = ({
|
|
|
88
92
|
)}
|
|
89
93
|
{props.showLanguageIndicator && (
|
|
90
94
|
<span className="absolute top-1.5 right-3 text-[11px] font-mono text-muted-foreground transition group-hover:opacity-0">
|
|
91
|
-
{
|
|
95
|
+
{language}
|
|
92
96
|
</span>
|
|
93
97
|
)}
|
|
94
98
|
{tokens.map((line, i) => (
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { useRouteError } from "react-router-dom";
|
|
2
|
-
import {
|
|
1
|
+
import { isRouteErrorResponse, useRouteError } from "react-router-dom";
|
|
2
|
+
import { NotFoundPage } from "../components/NotFoundPage.js";
|
|
3
3
|
import { ErrorAlert } from "./ErrorAlert.js";
|
|
4
4
|
|
|
5
5
|
export function RouterError() {
|
|
6
6
|
const error = useRouteError();
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
|
|
8
|
+
if (isRouteErrorResponse(error) && error.status === 404) {
|
|
9
|
+
return <NotFoundPage />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return <ErrorAlert error={error} />;
|
|
12
13
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GraphQLError } from "graphql/error/index.js";
|
|
1
2
|
import { OpenAPIV3, type OpenAPIV3_1 } from "openapi-types";
|
|
2
3
|
import { dereference, type JSONSchema } from "./dereference/index.js";
|
|
3
4
|
import { upgradeSchema } from "./upgrade/index.js";
|
|
@@ -9,10 +10,6 @@ type DeepOmitReference<T> = T extends ReferenceObject
|
|
|
9
10
|
? { [K in keyof T]: DeepOmitReference<T[K]> }
|
|
10
11
|
: T;
|
|
11
12
|
|
|
12
|
-
// type Prettify<T> = {
|
|
13
|
-
// [K in keyof T]: T[K];
|
|
14
|
-
// } & {};
|
|
15
|
-
|
|
16
13
|
export type OpenAPIDocument = DeepOmitReference<OpenAPIV3_1.Document>;
|
|
17
14
|
export type ResponseObject = DeepOmitReference<OpenAPIV3_1.ResponseObject>;
|
|
18
15
|
export type OperationObject = DeepOmitReference<OpenAPIV3_1.OperationObject>;
|
|
@@ -46,37 +43,63 @@ export const HttpMethods = Object.values(OpenAPIV3.HttpMethods);
|
|
|
46
43
|
// };
|
|
47
44
|
|
|
48
45
|
const parseSchemaInput = async (
|
|
49
|
-
|
|
50
|
-
schemaInput: any,
|
|
46
|
+
schemaInput: unknown,
|
|
51
47
|
): Promise<JSONSchema & { openapi?: string }> => {
|
|
52
48
|
if (typeof schemaInput === "string") {
|
|
53
49
|
if (schemaInput.trim().startsWith("{")) {
|
|
54
|
-
|
|
50
|
+
try {
|
|
51
|
+
return JSON.parse(schemaInput);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
throw new GraphQLError("Invalid JSON schema", {
|
|
54
|
+
originalError: err,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
55
57
|
}
|
|
56
58
|
if (schemaInput.includes("://")) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
let response;
|
|
60
|
+
try {
|
|
61
|
+
response = await fetch(schemaInput, {
|
|
62
|
+
cache: "force-cache",
|
|
63
|
+
});
|
|
64
|
+
} catch (err) {
|
|
65
|
+
throw new GraphQLError("Failed to fetch schema", {
|
|
66
|
+
originalError: err,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
throw new GraphQLError(
|
|
72
|
+
`Failed to fetch schema: ${response.statusText}`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
return (await response.json()) as JSONSchema;
|
|
78
|
+
} catch (err) {
|
|
79
|
+
throw new GraphQLError("Fetched invalid JSON schema", {
|
|
80
|
+
originalError: err,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
61
83
|
}
|
|
62
84
|
const yaml = await import("yaml");
|
|
63
|
-
|
|
85
|
+
const parsed = yaml.parse(schemaInput);
|
|
86
|
+
|
|
87
|
+
if (typeof parsed === "object") return parsed;
|
|
64
88
|
}
|
|
65
89
|
|
|
66
|
-
if (typeof schemaInput === "object") return schemaInput;
|
|
90
|
+
if (typeof schemaInput === "object") return schemaInput as JSONSchema;
|
|
67
91
|
|
|
68
|
-
throw new
|
|
92
|
+
throw new GraphQLError("Unsupported schema input: " + schemaInput);
|
|
69
93
|
};
|
|
70
94
|
|
|
71
95
|
/**
|
|
72
96
|
* Validates, dereferences and upgrades the OpenAPI schema (to v3.1) if necessary.
|
|
73
97
|
*/
|
|
74
|
-
|
|
75
|
-
export const validate = async (schemaInput: any) => {
|
|
98
|
+
export const validate = async (schemaInput: unknown) => {
|
|
76
99
|
const schema = await parseSchemaInput(schemaInput);
|
|
77
100
|
|
|
78
101
|
if (!schema.openapi) {
|
|
79
|
-
throw new
|
|
102
|
+
throw new GraphQLError("OpenAPI version is not defined");
|
|
80
103
|
}
|
|
81
104
|
|
|
82
105
|
// const validator = await getValidator(schema.openapi);
|
|
@@ -88,9 +111,5 @@ export const validate = async (schemaInput: any) => {
|
|
|
88
111
|
|
|
89
112
|
const dereferenced = await dereference(schema);
|
|
90
113
|
|
|
91
|
-
|
|
92
|
-
dereferenced as OpenAPIV3_1.Document | OpenAPIV3.Document,
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
return upgraded;
|
|
114
|
+
return upgradeSchema(dereferenced);
|
|
96
115
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Outlet, useRouteError } from "react-router-dom";
|
|
1
|
+
import { Outlet, type RouteObject } from "react-router-dom";
|
|
3
2
|
import invariant from "tiny-invariant";
|
|
4
3
|
import { useAuth } from "../../authentication/hook.js";
|
|
5
4
|
import { DevPortalContext } from "../../core/DevPortalContext.js";
|
|
@@ -7,6 +6,7 @@ import {
|
|
|
7
6
|
type ApiIdentityPlugin,
|
|
8
7
|
type DevPortalPlugin,
|
|
9
8
|
} from "../../core/plugins.js";
|
|
9
|
+
import { RouterError } from "../../errors/RouterError.js";
|
|
10
10
|
import { Button } from "../../ui/Button.js";
|
|
11
11
|
import { CreateApiKey } from "./CreateApiKey.js";
|
|
12
12
|
import { SettingsApiKeys } from "./SettingsApiKeys.js";
|
|
@@ -100,18 +100,6 @@ const ProtectedRoute = () => {
|
|
|
100
100
|
);
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
-
const SettingsErrorBoundary = () => {
|
|
104
|
-
const error = useRouteError();
|
|
105
|
-
logger.error(String(error));
|
|
106
|
-
|
|
107
|
-
return (
|
|
108
|
-
<div className="flex flex-col justify-center gap-2 items-center h-1/2 my-12">
|
|
109
|
-
<h1>Something went wrong</h1>
|
|
110
|
-
{error instanceof Error && <p>{error.message}</p>}
|
|
111
|
-
</div>
|
|
112
|
-
);
|
|
113
|
-
};
|
|
114
|
-
|
|
115
103
|
export const apiKeyPlugin = (
|
|
116
104
|
options: ApiKeyPluginOptions,
|
|
117
105
|
): DevPortalPlugin & ApiIdentityPlugin => {
|
|
@@ -138,12 +126,12 @@ export const apiKeyPlugin = (
|
|
|
138
126
|
return [];
|
|
139
127
|
}
|
|
140
128
|
},
|
|
141
|
-
getRoutes: () => {
|
|
129
|
+
getRoutes: (): RouteObject[] => {
|
|
142
130
|
// TODO: Make lazy
|
|
143
131
|
return [
|
|
144
132
|
{
|
|
145
133
|
element: <ProtectedRoute />,
|
|
146
|
-
errorElement: <
|
|
134
|
+
errorElement: <RouterError />,
|
|
147
135
|
children: [
|
|
148
136
|
{
|
|
149
137
|
path: "/settings/api-keys",
|
|
@@ -29,10 +29,6 @@ export type MDXImport = {
|
|
|
29
29
|
export const markdownPlugin = ({
|
|
30
30
|
markdownFiles,
|
|
31
31
|
defaultOptions,
|
|
32
|
-
}: MarkdownPluginOptions): DevPortalPlugin => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return generateRoutes(markdownFiles, defaultOptions);
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
};
|
|
32
|
+
}: MarkdownPluginOptions): DevPortalPlugin => ({
|
|
33
|
+
getRoutes: () => generateRoutes(markdownFiles, defaultOptions),
|
|
34
|
+
});
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { ResultOf } from "@graphql-typed-document-node/core";
|
|
2
2
|
import { CategoryHeading } from "../../components/CategoryHeading.js";
|
|
3
|
+
import { ErrorPage } from "../../components/ErrorPage.js";
|
|
3
4
|
import { Heading } from "../../components/Heading.js";
|
|
5
|
+
import { InlineCode } from "../../components/InlineCode.js";
|
|
4
6
|
import { Markdown } from "../../components/Markdown.js";
|
|
7
|
+
import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
|
|
8
|
+
import { Callout } from "../../ui/Callout.js";
|
|
5
9
|
import { cn } from "../../util/cn.js";
|
|
6
10
|
import { OperationListItem } from "./OperationListItem.js";
|
|
7
11
|
import { useOasConfig } from "./context.js";
|
|
@@ -91,6 +95,32 @@ export const OperationList = () => {
|
|
|
91
95
|
context: suspenseContext,
|
|
92
96
|
});
|
|
93
97
|
|
|
98
|
+
const error = result.error?.graphQLErrors.at(0);
|
|
99
|
+
|
|
100
|
+
// Looks like there is no Suspense level error handling (yet)?
|
|
101
|
+
// So we handle the error case in the component directly
|
|
102
|
+
if (error) {
|
|
103
|
+
return (
|
|
104
|
+
<ErrorPage
|
|
105
|
+
category="Error"
|
|
106
|
+
title="Schema cannot be displayed"
|
|
107
|
+
message={
|
|
108
|
+
<>
|
|
109
|
+
{import.meta.env.DEV && (
|
|
110
|
+
<Callout type="danger" title="Developer hint" className="mb-4">
|
|
111
|
+
Check your configuration value{" "}
|
|
112
|
+
<InlineCode>apis.type</InlineCode> and{" "}
|
|
113
|
+
<InlineCode>apis.input</InlineCode> in the Zudoku config.
|
|
114
|
+
</Callout>
|
|
115
|
+
)}
|
|
116
|
+
An error occurred while trying to fetch the API reference:
|
|
117
|
+
<SyntaxHighlight code={error.toString()} language="plain" />
|
|
118
|
+
</>
|
|
119
|
+
}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
94
124
|
if (!result.data) return null;
|
|
95
125
|
|
|
96
126
|
return (
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Heading } from "../../components/Heading.js";
|
|
2
2
|
import { Markdown } from "../../components/Markdown.js";
|
|
3
3
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/Tabs.js";
|
|
4
|
+
import { groupBy } from "../../util/groupBy.js";
|
|
4
5
|
import { renderIf } from "../../util/renderIf.js";
|
|
5
6
|
import { OperationsFragment } from "./OperationList.js";
|
|
6
7
|
import { ParameterList } from "./ParameterList.js";
|
|
@@ -18,10 +19,11 @@ export const OperationListItem = ({
|
|
|
18
19
|
operationFragment: FragmentType<typeof OperationsFragment>;
|
|
19
20
|
}) => {
|
|
20
21
|
const operation = useFragment(OperationsFragment, operationFragment);
|
|
21
|
-
const groupedParameters =
|
|
22
|
+
const groupedParameters = groupBy(
|
|
22
23
|
operation.parameters ?? [],
|
|
23
24
|
(param) => param.in,
|
|
24
25
|
);
|
|
26
|
+
|
|
25
27
|
const first = operation.responses.at(0);
|
|
26
28
|
return (
|
|
27
29
|
<div
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Markdown } from "../../components/Markdown.js";
|
|
2
2
|
import { SchemaObject } from "../../oas/parser/index.js";
|
|
3
|
+
import { groupBy } from "../../util/groupBy.js";
|
|
3
4
|
import { objectEntries } from "../../util/objectEntries.js";
|
|
4
5
|
import { SchemaListViewItemGroup } from "./SchemaListViewItemGroup.js";
|
|
5
6
|
import { SchemaProseClasses } from "./util/prose.js";
|
|
@@ -25,16 +26,13 @@ export const SchemaListView = ({
|
|
|
25
26
|
Array.isArray(additionalProperties) ? additionalProperties : [],
|
|
26
27
|
);
|
|
27
28
|
|
|
28
|
-
const groups =
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
? "
|
|
33
|
-
:
|
|
34
|
-
|
|
35
|
-
: "optional";
|
|
36
|
-
},
|
|
37
|
-
);
|
|
29
|
+
const groups = groupBy(combinedProperties, ([propertyName, property]) => {
|
|
30
|
+
return property.deprecated
|
|
31
|
+
? "deprecated"
|
|
32
|
+
: schema.required?.includes(propertyName)
|
|
33
|
+
? "required"
|
|
34
|
+
: "optional";
|
|
35
|
+
});
|
|
38
36
|
|
|
39
37
|
return (
|
|
40
38
|
<div className="flex flex-col gap-2.5">
|
|
@@ -25,7 +25,7 @@ export const createClient: CreateClientFunction = () => {
|
|
|
25
25
|
fetch: async (req, init) => {
|
|
26
26
|
if (!init?.body) throw new Error("No body");
|
|
27
27
|
const response = await localServer.fetch(
|
|
28
|
-
new Request("/__z/graphql", {
|
|
28
|
+
new Request("http://localhost/__z/graphql", {
|
|
29
29
|
method: "POST",
|
|
30
30
|
body: init.body,
|
|
31
31
|
headers: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { matchPath, type RouteObject } from "react-router-dom";
|
|
1
|
+
import { matchPath, useRouteError, type RouteObject } from "react-router-dom";
|
|
2
2
|
import {
|
|
3
3
|
type DevPortalPlugin,
|
|
4
4
|
type PluginNavigationCategory,
|
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
} from "./util/urql.js";
|
|
13
13
|
|
|
14
14
|
import { createClient } from "virtual:zudoku-openapi-worker";
|
|
15
|
+
import { ErrorPage } from "../../components/ErrorPage.js";
|
|
16
|
+
import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
|
|
15
17
|
import { OasPluginConfig } from "./interfaces.js";
|
|
16
18
|
|
|
17
19
|
const GetCategoriesQuery = graphql(`
|
|
@@ -34,6 +36,20 @@ const GetCategoriesQuery = graphql(`
|
|
|
34
36
|
}
|
|
35
37
|
`);
|
|
36
38
|
|
|
39
|
+
const OpenApiErrorPage = () => {
|
|
40
|
+
const error = useRouteError();
|
|
41
|
+
const message =
|
|
42
|
+
error instanceof Error ? (
|
|
43
|
+
<SyntaxHighlight code={error.message} />
|
|
44
|
+
) : (
|
|
45
|
+
"An unknown error occurred"
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<ErrorPage category="Error" title="An error occurred" message={message} />
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
37
53
|
export const openApiPlugin = (config: OasPluginConfig): DevPortalPlugin => {
|
|
38
54
|
const basePath = config.path ?? "/reference";
|
|
39
55
|
|
|
@@ -112,6 +128,7 @@ export const openApiPlugin = (config: OasPluginConfig): DevPortalPlugin => {
|
|
|
112
128
|
element: <OpenApiRoute client={client} config={config} />,
|
|
113
129
|
};
|
|
114
130
|
},
|
|
131
|
+
errorElement: <OpenApiErrorPage />,
|
|
115
132
|
children: [
|
|
116
133
|
{
|
|
117
134
|
path: basePath,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { redirect } from "react-router-dom";
|
|
2
2
|
import type { DevPortalPlugin } from "../../core/plugins.js";
|
|
3
3
|
|
|
4
4
|
export type Redirect = {
|
|
@@ -14,7 +14,7 @@ export const redirectPlugin = (options: {
|
|
|
14
14
|
getRoutes: () =>
|
|
15
15
|
options.redirects.map(({ from, to, replace }) => ({
|
|
16
16
|
path: from,
|
|
17
|
-
|
|
17
|
+
loader: () => redirect(to),
|
|
18
18
|
})),
|
|
19
19
|
};
|
|
20
20
|
};
|
package/src/lib/ui/Callout.tsx
CHANGED
|
@@ -64,9 +64,9 @@ export const Callout = ({ type, children, title, className }: CalloutProps) => {
|
|
|
64
64
|
return (
|
|
65
65
|
<div
|
|
66
66
|
className={cn(
|
|
67
|
-
"not-prose grid grid-cols-[
|
|
67
|
+
"not-prose grid grid-cols-[min-content_1fr] grid-rows-[fit-content_1fr] gap-x-4 gap-y-2 text-md rounded-md border p-4",
|
|
68
68
|
"[&_a]:underline [&_a]:decoration-current [&_a]:decoration-from-font [&_a]:underline-offset-4 hover:[&_a]:decoration-1",
|
|
69
|
-
"[&_code]:!bg-
|
|
69
|
+
"[&_code]:!bg-gray-50 [&_code]:dark:!bg-gray-800 [&_code]:!border-none",
|
|
70
70
|
title && "items-center",
|
|
71
71
|
border,
|
|
72
72
|
bg,
|
|
@@ -2,9 +2,9 @@ import { MDXProvider } from "@mdx-js/react";
|
|
|
2
2
|
import type { ComponentProps } from "react";
|
|
3
3
|
import { Link } from "react-router-dom";
|
|
4
4
|
import { Heading } from "../components/Heading.js";
|
|
5
|
+
import { InlineCode } from "../components/InlineCode.js";
|
|
5
6
|
import { SyntaxHighlight } from "../components/SyntaxHighlight.js";
|
|
6
7
|
import { Callout } from "../ui/Callout.js";
|
|
7
|
-
import { cn } from "./cn.js";
|
|
8
8
|
|
|
9
9
|
export type MdxComponentsType = ComponentProps<
|
|
10
10
|
typeof MDXProvider
|
|
@@ -80,15 +80,6 @@ export const MdxComponents = {
|
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
return
|
|
84
|
-
<code
|
|
85
|
-
className={cn(
|
|
86
|
-
className,
|
|
87
|
-
"font-mono border border-border p-1 py-0.5 rounded bg-border/50 dark:bg-border/70 whitespace-nowrap",
|
|
88
|
-
)}
|
|
89
|
-
>
|
|
90
|
-
{children}
|
|
91
|
-
</code>
|
|
92
|
-
);
|
|
83
|
+
return <InlineCode className={className}>{children}</InlineCode>;
|
|
93
84
|
},
|
|
94
85
|
} satisfies MdxComponentsType;
|
package/src/lib/util/groupBy.ts
CHANGED
|
@@ -1,24 +1,19 @@
|
|
|
1
|
-
type MapValuesToKeysIfAllowed<T> = {
|
|
2
|
-
[K in keyof T]: T[K] extends PropertyKey ? K : never;
|
|
3
|
-
};
|
|
4
|
-
type Filter<T> = MapValuesToKeysIfAllowed<T>[keyof T];
|
|
5
|
-
|
|
6
1
|
export const groupBy = <
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
2
|
T extends Record<PropertyKey, any>,
|
|
9
|
-
|
|
3
|
+
KeySelector extends (item: T) => PropertyKey,
|
|
10
4
|
>(
|
|
11
5
|
arr: T[],
|
|
12
|
-
|
|
13
|
-
): Record<
|
|
14
|
-
arr.reduce(
|
|
6
|
+
keySelector: KeySelector,
|
|
7
|
+
): Partial<Record<ReturnType<KeySelector>, T[]>> => {
|
|
8
|
+
return arr.reduce(
|
|
15
9
|
(accumulator, val) => {
|
|
16
|
-
const groupedKey = val
|
|
10
|
+
const groupedKey = keySelector(val) as ReturnType<KeySelector>;
|
|
17
11
|
if (!accumulator[groupedKey]) {
|
|
18
12
|
accumulator[groupedKey] = [];
|
|
19
13
|
}
|
|
20
14
|
accumulator[groupedKey].push(val);
|
|
21
15
|
return accumulator;
|
|
22
16
|
},
|
|
23
|
-
{} as Record<
|
|
17
|
+
{} as Record<ReturnType<KeySelector>, T[]>,
|
|
24
18
|
);
|
|
19
|
+
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from "react";
|
|
3
|
-
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
|
4
|
-
import { isNavigationPlugin } from "../core/plugins.js";
|
|
5
|
-
import { RouterError } from "../errors/RouterError.js";
|
|
6
|
-
import { Layout } from "./Layout.js";
|
|
7
|
-
export function Router({ plugins }) {
|
|
8
|
-
const router = useMemo(() => {
|
|
9
|
-
const routes = (plugins ?? []).flatMap((plugin) => isNavigationPlugin(plugin) ? plugin.getRoutes() : []);
|
|
10
|
-
return createBrowserRouter([
|
|
11
|
-
{
|
|
12
|
-
path: "/",
|
|
13
|
-
element: _jsx(Layout, {}),
|
|
14
|
-
errorElement: _jsx(RouterError, {}),
|
|
15
|
-
children: routes,
|
|
16
|
-
},
|
|
17
|
-
]);
|
|
18
|
-
}, [plugins]);
|
|
19
|
-
return _jsx(RouterProvider, { router: router });
|
|
20
|
-
}
|
|
21
|
-
//# sourceMappingURL=Router.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Router.js","sourceRoot":"","sources":["../../../src/lib/components/Router.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAmB,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,MAAM,CAAC,EAAE,OAAO,EAAmC;IACjE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE;QAC1B,MAAM,MAAM,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAChD,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CACrD,CAAC;QAEF,OAAO,mBAAmB,CAAC;YACzB;gBACE,IAAI,EAAE,GAAG;gBACT,OAAO,EAAE,KAAC,MAAM,KAAG;gBACnB,YAAY,EAAE,KAAC,WAAW,KAAG;gBAC7B,QAAQ,EAAE,MAAM;aACjB;SACF,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACd,OAAO,KAAC,cAAc,IAAC,MAAM,EAAE,MAAM,GAAI,CAAC;AAC5C,CAAC"}
|