zudoku 0.3.0-dev.30 → 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/demo.js +15 -11
- package/dist/app/demo.js.map +1 -1
- 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 -15
- package/dist/app/main.js.map +1 -1
- package/dist/app/standalone.js +14 -10
- package/dist/app/standalone.js.map +1 -1
- package/dist/app/tailwind.d.ts +1 -1
- package/dist/app/tailwind.js +0 -4
- 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 +5 -2
- package/dist/lib/components/DevPortal.js +11 -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/components/index.d.ts +4 -1
- package/dist/lib/errors/ErrorAlert.d.ts +3 -0
- package/dist/lib/errors/ErrorAlert.js +8 -0
- package/dist/lib/errors/ErrorAlert.js.map +1 -0
- package/dist/lib/errors/RouterError.d.ts +1 -0
- package/dist/lib/errors/RouterError.js +12 -0
- package/dist/lib/errors/RouterError.js.map +1 -0
- 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/errors/TopLevelError.d.ts +2 -0
- package/dist/lib/errors/TopLevelError.js +7 -0
- package/dist/lib/errors/TopLevelError.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 -2
- package/dist/vite/config.js +36 -8
- 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--xZTs0RJ.js → DevPortalProvider-BlxLX6GG.js} +230 -250
- package/lib/DevPortalProvider-BlxLX6GG.js.map +1 -0
- package/lib/{Markdown-oJFqm0uk.js → Markdown-CL8KPvJN.js} +8 -9
- package/lib/{Markdown-oJFqm0uk.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-BV_9ncEk.js → MdxPage-Z3HKNTrj.js} +92 -89
- package/lib/MdxPage-Z3HKNTrj.js.map +1 -0
- package/lib/{OperationList-DfG_E0Xa.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-CHqr53jb.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-B2qLeglF.js → index-BoWzKb_9.js} +57 -41
- package/lib/index-BoWzKb_9.js.map +1 -0
- package/lib/{AnchorLink-BtVKbEwm.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 +330 -543
- 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 +3 -1
- package/src/app/App.tsx +0 -0
- package/src/app/demo.tsx +18 -13
- package/src/app/entry.client.tsx +51 -0
- package/src/app/entry.server.tsx +158 -0
- package/src/app/main.tsx +65 -41
- package/src/app/standalone.tsx +15 -11
- package/src/app/tailwind.ts +2 -6
- package/src/app/zudoku-manifest.ts +22 -0
- package/src/lib/authentication/providers/clerk.tsx +1 -0
- package/src/lib/components/DevPortal.tsx +34 -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/ErrorAlert.tsx +21 -0
- package/src/lib/errors/RouterError.tsx +13 -0
- package/src/lib/errors/ServerError.tsx +5 -0
- package/src/lib/errors/TopLevelError.tsx +8 -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/Error.d.ts +0 -1
- package/dist/lib/components/Error.js +0 -10
- package/dist/lib/components/Error.js.map +0 -1
- 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-BtVKbEwm.js.map +0 -1
- package/lib/DevPortalProvider--xZTs0RJ.js.map +0 -1
- package/lib/MdxComponents-CsU8yR42.js +0 -3019
- package/lib/MdxComponents-CsU8yR42.js.map +0 -1
- package/lib/MdxPage-BV_9ncEk.js.map +0 -1
- package/lib/OperationList-DfG_E0Xa.js.map +0 -1
- package/lib/Route-CHqr53jb.js +0 -14
- package/lib/Select-CNmXi4JU.js +0 -4572
- package/lib/Select-CNmXi4JU.js.map +0 -1
- package/lib/Spinner-By5opWs5.js +0 -182
- package/lib/Spinner-By5opWs5.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-kVJ4gpk5.js +0 -25
- package/lib/hook-kVJ4gpk5.js.map +0 -1
- package/lib/index-B2qLeglF.js.map +0 -1
- package/lib/index-CUIxJAeE.js +0 -713
- package/lib/index-CUIxJAeE.js.map +0 -1
- package/lib/index-Cr3hgaqt.js +0 -412
- package/lib/index-Cr3hgaqt.js.map +0 -1
- package/lib/index-fXFJf9Ua.js +0 -464
- package/lib/index-fXFJf9Ua.js.map +0 -1
- package/lib/jsx-runtime-D7DwziLW.js +0 -3009
- package/lib/jsx-runtime-D7DwziLW.js.map +0 -1
- package/lib/loglevel-CA34MiFn.js +0 -153
- package/lib/loglevel-CA34MiFn.js.map +0 -1
- package/lib/util-DnDPBx_j.js +0 -41
- package/lib/util-DnDPBx_j.js.map +0 -1
- package/src/lib/components/Error.tsx +0 -15
- package/src/lib/components/Router.tsx +0 -23
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { Link } from "react-router-dom";
|
|
3
|
+
import { CategoryHeading } from "./CategoryHeading.js";
|
|
4
|
+
import { Heading } from "./Heading.js";
|
|
5
|
+
import { ProseClasses } from "./Markdown.js";
|
|
6
|
+
|
|
7
|
+
export const ErrorPage = ({
|
|
8
|
+
title = "An error occurred",
|
|
9
|
+
message,
|
|
10
|
+
category,
|
|
11
|
+
}: {
|
|
12
|
+
title?: ReactNode;
|
|
13
|
+
message?: ReactNode;
|
|
14
|
+
category?: ReactNode;
|
|
15
|
+
}) => {
|
|
16
|
+
return (
|
|
17
|
+
<div className={ProseClasses + " h-full pt-[--padding-content-top]"}>
|
|
18
|
+
{category && <CategoryHeading>{category}</CategoryHeading>}
|
|
19
|
+
{title && (
|
|
20
|
+
<Heading level={1} className="flex gap-3.5 items-center">
|
|
21
|
+
{title}
|
|
22
|
+
</Heading>
|
|
23
|
+
)}
|
|
24
|
+
<p>{message}</p>
|
|
25
|
+
<Link to="/">Go back home</Link>
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { cn } from "../util/cn.js";
|
|
3
|
+
|
|
4
|
+
export const InlineCode = ({
|
|
5
|
+
className,
|
|
6
|
+
children,
|
|
7
|
+
}: {
|
|
8
|
+
className?: string;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
}) => (
|
|
11
|
+
<code
|
|
12
|
+
className={cn(
|
|
13
|
+
className,
|
|
14
|
+
"font-mono border border-border p-1 py-0.5 rounded bg-border/50 dark:bg-border/70 whitespace-nowrap",
|
|
15
|
+
)}
|
|
16
|
+
>
|
|
17
|
+
{children}
|
|
18
|
+
</code>
|
|
19
|
+
);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Suspense, useEffect, useRef, type ReactNode } from "react";
|
|
2
2
|
import { Helmet } from "react-helmet-async";
|
|
3
3
|
import { Outlet, useLocation } from "react-router-dom";
|
|
4
|
+
import { cn } from "../util/cn.js";
|
|
4
5
|
import { useScrollToAnchor } from "../util/useScrollToAnchor.js";
|
|
5
6
|
import { useScrollToTop } from "../util/useScrollToTop.js";
|
|
6
7
|
import { useDevPortal } from "./context/DevPortalProvider.js";
|
|
@@ -47,10 +48,12 @@ export const Layout = ({ children }: { children?: ReactNode }) => {
|
|
|
47
48
|
>
|
|
48
49
|
<SideNavigation />
|
|
49
50
|
<main
|
|
50
|
-
className=
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
className={cn(
|
|
52
|
+
"dark:border-white/10 translate-x-0 h-full",
|
|
53
|
+
"lg:overflow-visible",
|
|
54
|
+
"lg:peer-data-[navigation=true]:w-[calc(100%-var(--side-nav-width))]",
|
|
55
|
+
"lg:peer-data-[navigation=true]:translate-x-[--side-nav-width] peer-data-[navigation=true]:pl-12",
|
|
56
|
+
)}
|
|
54
57
|
>
|
|
55
58
|
{children ?? <Outlet />}
|
|
56
59
|
</main>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { UnlinkIcon } from "lucide-react";
|
|
2
|
+
import { Link, useParams } from "react-router-dom";
|
|
3
|
+
import { Callout } from "../ui/Callout.js";
|
|
4
|
+
import { CategoryHeading } from "./CategoryHeading.js";
|
|
5
|
+
import { Heading } from "./Heading.js";
|
|
6
|
+
import { ProseClasses } from "./Markdown.js";
|
|
7
|
+
|
|
8
|
+
export const NotFoundPage = () => {
|
|
9
|
+
const params = useParams();
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<div className={ProseClasses + " h-full pt-[--padding-content-top]"}>
|
|
13
|
+
<CategoryHeading>404</CategoryHeading>
|
|
14
|
+
<Heading level={1} className="flex gap-3.5 items-center">
|
|
15
|
+
Page not found
|
|
16
|
+
<UnlinkIcon size={24} />
|
|
17
|
+
</Heading>
|
|
18
|
+
{import.meta.env.DEV && (
|
|
19
|
+
<Callout type="caution" title="Developer hint">
|
|
20
|
+
Start by adding a file at{" "}
|
|
21
|
+
<code>
|
|
22
|
+
{"{PROJECT_ROOT}"}/{params["*"]}.mdx
|
|
23
|
+
</code>{" "}
|
|
24
|
+
and add some content to make this error go away.
|
|
25
|
+
<br />
|
|
26
|
+
<small className="italic">
|
|
27
|
+
Note: This hint is only shown in development mode.
|
|
28
|
+
</small>
|
|
29
|
+
</Callout>
|
|
30
|
+
)}
|
|
31
|
+
<p>
|
|
32
|
+
It seems that the page you are looking for does not exist or may have
|
|
33
|
+
been moved. Please check the URL for any typos or use the navigation
|
|
34
|
+
menu to find the correct page.
|
|
35
|
+
</p>
|
|
36
|
+
<Link to="/">Go back home</Link>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
@@ -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) => (
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2
|
+
export function ErrorAlert({ error }: { error: any }) {
|
|
3
|
+
const message = error?.message ?? "Something went wrong";
|
|
4
|
+
const stack = error?.stack;
|
|
5
|
+
|
|
6
|
+
return (
|
|
7
|
+
<div className="flex h-screen max-h-screen min-h-full items-center justify-center bg-primary-background px-4 py-16 lg:px-8">
|
|
8
|
+
<div className="mx-auto max-w-[85%] sm:max-w-[50%]">
|
|
9
|
+
<h1 className="text-4xl font-bold tracking-tight text-h1-text sm:text-5xl">
|
|
10
|
+
Something went wrong
|
|
11
|
+
</h1>
|
|
12
|
+
<p className="mt-5 text-h1-text">{message}</p>
|
|
13
|
+
{stack ? (
|
|
14
|
+
<pre className="mt-5 max-h-[400px] w-full overflow-scroll rounded-md border border-input-border bg-input-background p-3 text-property-name-text text-red-700">
|
|
15
|
+
{stack}
|
|
16
|
+
</pre>
|
|
17
|
+
) : null}
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { isRouteErrorResponse, useRouteError } from "react-router-dom";
|
|
2
|
+
import { NotFoundPage } from "../components/NotFoundPage.js";
|
|
3
|
+
import { ErrorAlert } from "./ErrorAlert.js";
|
|
4
|
+
|
|
5
|
+
export function RouterError() {
|
|
6
|
+
const error = useRouteError();
|
|
7
|
+
|
|
8
|
+
if (isRouteErrorResponse(error) && error.status === 404) {
|
|
9
|
+
return <NotFoundPage />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return <ErrorAlert error={error} />;
|
|
13
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FallbackProps } from "react-error-boundary";
|
|
2
|
+
import { ErrorAlert } from "./ErrorAlert.js";
|
|
3
|
+
|
|
4
|
+
export function TopLevelError({ error, resetErrorBoundary }: FallbackProps) {
|
|
5
|
+
// Call resetErrorBoundary() to reset the error boundary and retry the render.
|
|
6
|
+
|
|
7
|
+
return <ErrorAlert error={error} />;
|
|
8
|
+
}
|
|
@@ -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;
|