zudoku 0.35.2 → 0.35.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/components/InlineCode.js +2 -9
- package/dist/lib/components/InlineCode.js.map +1 -1
- package/dist/lib/components/Layout.js +1 -1
- package/dist/lib/components/Layout.js.map +1 -1
- package/dist/lib/errors/ErrorAlert.js +6 -1
- package/dist/lib/errors/ErrorAlert.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +3 -11
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/ParameterListItem.js +3 -2
- package/dist/lib/plugins/openapi/ParameterListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/components/EnumValues.d.ts +5 -0
- package/dist/lib/plugins/openapi/components/EnumValues.js +15 -0
- package/dist/lib/plugins/openapi/components/EnumValues.js.map +1 -0
- package/dist/lib/plugins/openapi/components/SelectOnClick.d.ts +5 -0
- package/dist/lib/plugins/openapi/components/SelectOnClick.js +16 -0
- package/dist/lib/plugins/openapi/components/SelectOnClick.js.map +1 -0
- package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js +3 -2
- package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js.map +1 -1
- package/dist/lib/ui/SyntaxHighlight.js +2 -0
- package/dist/lib/ui/SyntaxHighlight.js.map +1 -1
- package/lib/{Markdown-D1Y3cd9l.js → Markdown-hBN9vkm5.js} +1045 -1026
- package/lib/Markdown-hBN9vkm5.js.map +1 -0
- package/lib/{MdxPage-CUL_SQzW.js → MdxPage-UCWwxhzC.js} +2 -2
- package/lib/{MdxPage-CUL_SQzW.js.map → MdxPage-UCWwxhzC.js.map} +1 -1
- package/lib/{OasProvider-_ye9MUAd.js → OasProvider-7Z9UwS9y.js} +2 -2
- package/lib/{OasProvider-_ye9MUAd.js.map → OasProvider-7Z9UwS9y.js.map} +1 -1
- package/lib/{OperationList-Br5x22KD.js → OperationList-a7wnHdXv.js} +1627 -1604
- package/lib/OperationList-a7wnHdXv.js.map +1 -0
- package/lib/SlotletProvider-D-XPr1Wg.js +338 -0
- package/lib/SlotletProvider-D-XPr1Wg.js.map +1 -0
- package/lib/SyntaxHighlight-BEoSoPEo.js +2890 -0
- package/lib/SyntaxHighlight-BEoSoPEo.js.map +1 -0
- package/lib/{index-C7TIhpXK.js → index-UmhI2mj7.js} +4 -4
- package/lib/{index-C7TIhpXK.js.map → index-UmhI2mj7.js.map} +1 -1
- package/lib/prism-jsstacktrace.min-BfobCF2F.js +2 -0
- package/lib/prism-jsstacktrace.min-BfobCF2F.js.map +1 -0
- package/lib/ui/SyntaxHighlight.js +8 -2883
- package/lib/ui/SyntaxHighlight.js.map +1 -1
- package/lib/zudoku.components.js +38 -38
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.plugin-api-catalog.js +1 -1
- package/lib/zudoku.plugin-api-keys.js +1 -1
- package/lib/zudoku.plugin-custom-pages.js +1 -1
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +1 -1
- package/package.json +1 -1
- package/src/lib/components/InlineCode.tsx +11 -16
- package/src/lib/components/Layout.tsx +1 -1
- package/src/lib/errors/ErrorAlert.tsx +24 -17
- package/src/lib/plugins/openapi/OperationListItem.tsx +4 -16
- package/src/lib/plugins/openapi/ParameterListItem.tsx +3 -1
- package/src/lib/plugins/openapi/components/EnumValues.tsx +58 -0
- package/src/lib/plugins/openapi/components/SelectOnClick.tsx +29 -0
- package/src/lib/plugins/openapi/schema/SchemaPropertyItem.tsx +9 -2
- package/src/lib/ui/SyntaxHighlight.tsx +2 -0
- package/lib/Markdown-D1Y3cd9l.js.map +0 -1
- package/lib/OperationList-Br5x22KD.js.map +0 -1
- package/lib/SlotletProvider-iDmNlxD5.js +0 -221
- package/lib/SlotletProvider-iDmNlxD5.js.map +0 -1
|
@@ -5,7 +5,7 @@ import { j as d } from "./joinUrl-10po2Jdj.js";
|
|
|
5
5
|
import { u as j, b as y } from "./hook-CfCFKZ-2.js";
|
|
6
6
|
import { H as v } from "./index.esm-CltAN0Tf.js";
|
|
7
7
|
import { Link as N } from "./zudoku.components.js";
|
|
8
|
-
import { H as S, M as w } from "./Markdown-
|
|
8
|
+
import { H as S, M as w } from "./Markdown-hBN9vkm5.js";
|
|
9
9
|
const H = ({
|
|
10
10
|
items: s,
|
|
11
11
|
filterCatalogItems: l = (n) => n,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { j as e } from "./jsx-runtime-CYK1ROHF.js";
|
|
2
2
|
import { RotateCwIcon as j, TrashIcon as v, EyeOffIcon as w, EyeIcon as K, CheckIcon as b, CopyIcon as k, FileKey2Icon as N } from "lucide-react";
|
|
3
|
-
import { D as I, S as x, R as S } from "./SlotletProvider-
|
|
3
|
+
import { D as I, S as x, R as S } from "./SlotletProvider-D-XPr1Wg.js";
|
|
4
4
|
import { i as c } from "./invariant-Caa8-XvF.js";
|
|
5
5
|
import { u as h } from "./useQuery-CQUwWR9i.js";
|
|
6
6
|
import { u as d, S as A, a as C, b as E, c as P, d as D, e as p } from "./Select-FAYHOYTy.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { j as o } from "./jsx-runtime-CYK1ROHF.js";
|
|
2
2
|
import a from "react";
|
|
3
|
-
import { P as n } from "./Markdown-
|
|
3
|
+
import { P as n } from "./Markdown-hBN9vkm5.js";
|
|
4
4
|
import { c } from "./cn-qaFjX9_3.js";
|
|
5
5
|
import { u as p } from "./useExposedProps-BslIn-FE.js";
|
|
6
6
|
const u = ({
|
|
@@ -53,7 +53,7 @@ const P = (e) => ({
|
|
|
53
53
|
const u = {
|
|
54
54
|
path: r,
|
|
55
55
|
lazy: async () => {
|
|
56
|
-
const { MdxPage: p } = await import("./MdxPage-
|
|
56
|
+
const { MdxPage: p } = await import("./MdxPage-UCWwxhzC.js"), { default: f, ...l } = await i();
|
|
57
57
|
return {
|
|
58
58
|
element: /* @__PURE__ */ d.jsx(
|
|
59
59
|
p,
|
|
@@ -5,7 +5,7 @@ import "./chunk-HA7DTUK3-ZGg2W6yV.js";
|
|
|
5
5
|
import "./hook-CfCFKZ-2.js";
|
|
6
6
|
import "./ui/Button.js";
|
|
7
7
|
import "./joinUrl-10po2Jdj.js";
|
|
8
|
-
import { U as n, o as s } from "./index-
|
|
8
|
+
import { U as n, o as s } from "./index-UmhI2mj7.js";
|
|
9
9
|
export {
|
|
10
10
|
n as UNTAGGED_PATH,
|
|
11
11
|
s as openApiPlugin
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
+
import { SelectOnClick } from "../plugins/openapi/components/SelectOnClick.js";
|
|
2
3
|
import { cn } from "../util/cn.js";
|
|
3
4
|
|
|
4
5
|
export const InlineCode = ({
|
|
@@ -10,20 +11,14 @@ export const InlineCode = ({
|
|
|
10
11
|
children: ReactNode;
|
|
11
12
|
selectOnClick?: boolean;
|
|
12
13
|
}) => (
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"font-mono border p-1 py-0.5 rounded bg-border/50 dark:bg-border/70 [overflow-wrap:anywhere]",
|
|
24
|
-
className,
|
|
25
|
-
)}
|
|
26
|
-
>
|
|
27
|
-
{children}
|
|
28
|
-
</code>
|
|
14
|
+
<SelectOnClick asChild enabled={selectOnClick}>
|
|
15
|
+
<code
|
|
16
|
+
className={cn(
|
|
17
|
+
"font-mono border p-1 py-0.5 rounded bg-border/50 dark:bg-border/70 [overflow-wrap:anywhere]",
|
|
18
|
+
className,
|
|
19
|
+
)}
|
|
20
|
+
>
|
|
21
|
+
{children}
|
|
22
|
+
</code>
|
|
23
|
+
</SelectOnClick>
|
|
29
24
|
);
|
|
@@ -62,7 +62,7 @@ export const Layout = ({ children }: { children?: ReactNode }) => {
|
|
|
62
62
|
<Header />
|
|
63
63
|
<Slotlet name="layout-after-head" />
|
|
64
64
|
|
|
65
|
-
<div className="grid lg:grid-cols-[var(--side-nav-width)_1fr] max-w-screen-2xl w-full lg:mx-auto px-4 lg:px-8 2xl:border-x">
|
|
65
|
+
<div className="grid grid-cols-1 grid-rows-[min-content_1fr] lg:grid-cols-[var(--side-nav-width)_1fr] max-w-screen-2xl w-full lg:mx-auto px-4 lg:px-8 2xl:border-x">
|
|
66
66
|
{showSpinner ? (
|
|
67
67
|
<LoadingFallback />
|
|
68
68
|
) : (
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2
|
+
import { SyntaxHighlight } from "zudoku/ui/SyntaxHighlight.js";
|
|
2
3
|
import { DeveloperHint } from "../components/DeveloperHint.js";
|
|
4
|
+
import { Heading } from "../components/Heading.js";
|
|
5
|
+
import { ProseClasses } from "../components/Markdown.js";
|
|
6
|
+
import { cn } from "../util/cn.js";
|
|
3
7
|
import { ZudokuError } from "../util/invariant.js";
|
|
4
8
|
|
|
5
9
|
export function ErrorAlert({ error }: { error: unknown }) {
|
|
@@ -12,24 +16,27 @@ export function ErrorAlert({ error }: { error: unknown }) {
|
|
|
12
16
|
const stack = error instanceof Error ? error.stack : undefined;
|
|
13
17
|
const cause = error instanceof Error ? error.cause : undefined;
|
|
14
18
|
|
|
19
|
+
const stringError = cause instanceof Error ? String(cause.stack) : stack;
|
|
20
|
+
|
|
15
21
|
return (
|
|
16
|
-
<div
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
<div
|
|
23
|
+
className={cn(
|
|
24
|
+
ProseClasses,
|
|
25
|
+
"grid grid-cols-1 !max-w-none pt-[--padding-content-top]",
|
|
26
|
+
)}
|
|
27
|
+
>
|
|
28
|
+
<Heading level={1}>{title}</Heading>
|
|
29
|
+
Error: {message}
|
|
30
|
+
{hint && <DeveloperHint className="mb-4">{hint}</DeveloperHint>}
|
|
31
|
+
{stringError && (
|
|
32
|
+
<div>
|
|
33
|
+
<SyntaxHighlight
|
|
34
|
+
className="max-h-[400px] border mt-2"
|
|
35
|
+
language="jsstacktrace"
|
|
36
|
+
code={stringError}
|
|
37
|
+
/>
|
|
38
|
+
</div>
|
|
39
|
+
)}
|
|
33
40
|
</div>
|
|
34
41
|
);
|
|
35
42
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
|
|
2
|
-
import {
|
|
2
|
+
import { useState } from "react";
|
|
3
3
|
import { Badge } from "zudoku/ui/Badge.js";
|
|
4
4
|
import { Heading } from "../../components/Heading.js";
|
|
5
5
|
import { Markdown, ProseClasses } from "../../components/Markdown.js";
|
|
@@ -10,6 +10,7 @@ import { renderIf } from "../../util/renderIf.js";
|
|
|
10
10
|
import { OperationsFragment } from "./OperationList.js";
|
|
11
11
|
import { ParameterList } from "./ParameterList.js";
|
|
12
12
|
import { Sidecar } from "./Sidecar.js";
|
|
13
|
+
import { SelectOnClick } from "./components/SelectOnClick.js";
|
|
13
14
|
import { type FragmentType, useFragment } from "./graphql/index.js";
|
|
14
15
|
import { SchemaView } from "./schema/SchemaView.js";
|
|
15
16
|
import { methodForColor } from "./util/methodToColor.js";
|
|
@@ -29,7 +30,6 @@ export const OperationListItem = ({
|
|
|
29
30
|
operation.parameters ?? [],
|
|
30
31
|
(param) => param.in,
|
|
31
32
|
);
|
|
32
|
-
const parentRef = useRef<HTMLDivElement>(null);
|
|
33
33
|
|
|
34
34
|
const first = operation.responses.at(0);
|
|
35
35
|
const [selectedResponse, setSelectedResponse] = useState(first?.statusCode);
|
|
@@ -60,19 +60,7 @@ export const OperationListItem = ({
|
|
|
60
60
|
<span className={methodForColor(operation.method)}>
|
|
61
61
|
{operation.method.toUpperCase()}
|
|
62
62
|
</span>
|
|
63
|
-
<
|
|
64
|
-
ref={parentRef}
|
|
65
|
-
className="max-w-full truncate flex cursor-pointer"
|
|
66
|
-
onClick={() => {
|
|
67
|
-
if (parentRef.current) {
|
|
68
|
-
const range = document.createRange();
|
|
69
|
-
range.selectNodeContents(parentRef.current);
|
|
70
|
-
const selection = window.getSelection();
|
|
71
|
-
selection?.removeAllRanges();
|
|
72
|
-
selection?.addRange(range);
|
|
73
|
-
}
|
|
74
|
-
}}
|
|
75
|
-
>
|
|
63
|
+
<SelectOnClick className="max-w-full truncate flex cursor-pointer">
|
|
76
64
|
{serverUrl && (
|
|
77
65
|
<div className="text-neutral-400 dark:text-neutral-500 truncate">
|
|
78
66
|
{serverUrl}
|
|
@@ -81,7 +69,7 @@ export const OperationListItem = ({
|
|
|
81
69
|
<div className="text-neutral-900 dark:text-neutral-200">
|
|
82
70
|
{operation.path}
|
|
83
71
|
</div>
|
|
84
|
-
</
|
|
72
|
+
</SelectOnClick>
|
|
85
73
|
</div>
|
|
86
74
|
|
|
87
75
|
<div className="flex flex-col gap-4">
|
|
@@ -4,6 +4,7 @@ import { type SchemaObject } from "../../oas/graphql/index.js";
|
|
|
4
4
|
import { ColorizedParam } from "./ColorizedParam.js";
|
|
5
5
|
import type { OperationListItemResult } from "./OperationList.js";
|
|
6
6
|
import type { ParameterGroup } from "./OperationListItem.js";
|
|
7
|
+
import { EnumValues } from "./components/EnumValues.js";
|
|
7
8
|
|
|
8
9
|
const getParameterSchema = (
|
|
9
10
|
parameter: ParameterListItemResult,
|
|
@@ -32,7 +33,7 @@ export const ParameterListItem = ({
|
|
|
32
33
|
const paramSchema = getParameterSchema(parameter);
|
|
33
34
|
|
|
34
35
|
return (
|
|
35
|
-
<li className="p-4 bg-border/20 text-sm flex flex-col gap-1">
|
|
36
|
+
<li className="p-4 bg-border/20 text-sm flex flex-col gap-1.5">
|
|
36
37
|
<div className="flex items-center gap-2">
|
|
37
38
|
<code>
|
|
38
39
|
{group === "path" ? (
|
|
@@ -62,6 +63,7 @@ export const ParameterListItem = ({
|
|
|
62
63
|
className="text-sm prose-p:my-1 prose-code:whitespace-pre-line"
|
|
63
64
|
/>
|
|
64
65
|
)}
|
|
66
|
+
{paramSchema.enum && <EnumValues values={paramSchema.enum} />}
|
|
65
67
|
</li>
|
|
66
68
|
);
|
|
67
69
|
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Button } from "zudoku/ui/Button.js";
|
|
4
|
+
import { cn } from "../../../util/cn.js";
|
|
5
|
+
import { SelectOnClick } from "./SelectOnClick.js";
|
|
6
|
+
|
|
7
|
+
export const EnumValues = ({
|
|
8
|
+
values,
|
|
9
|
+
className,
|
|
10
|
+
maxVisibleValues = 8,
|
|
11
|
+
}: {
|
|
12
|
+
values: Array<string | number>;
|
|
13
|
+
className?: string;
|
|
14
|
+
maxVisibleValues?: number;
|
|
15
|
+
}) => {
|
|
16
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
17
|
+
|
|
18
|
+
if (!values.length) return null;
|
|
19
|
+
|
|
20
|
+
const shouldCollapse = values.length > maxVisibleValues;
|
|
21
|
+
const visibleValues =
|
|
22
|
+
shouldCollapse && !isOpen ? values.slice(0, maxVisibleValues) : values;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div className={cn("flex flex-wrap gap-1.5 text-xs", className)}>
|
|
26
|
+
<span className="text-muted-foreground">Enum values: </span>
|
|
27
|
+
{visibleValues.map((value) => (
|
|
28
|
+
<div key={value}>
|
|
29
|
+
<SelectOnClick className="border rounded px-1 font-mono cursor-pointer">
|
|
30
|
+
{value}
|
|
31
|
+
</SelectOnClick>
|
|
32
|
+
</div>
|
|
33
|
+
))}
|
|
34
|
+
{shouldCollapse && (
|
|
35
|
+
<Button
|
|
36
|
+
variant="ghost"
|
|
37
|
+
size="sm"
|
|
38
|
+
className="h-fit px-0"
|
|
39
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
40
|
+
>
|
|
41
|
+
{isOpen ? (
|
|
42
|
+
<div className="flex items-center gap-1">
|
|
43
|
+
<ChevronUpIcon size={12} />
|
|
44
|
+
<span className="text-muted-foreground">show less</span>
|
|
45
|
+
</div>
|
|
46
|
+
) : (
|
|
47
|
+
<div className="flex items-center gap-1">
|
|
48
|
+
<ChevronDownIcon size={12} />
|
|
49
|
+
<span className="text-muted-foreground">
|
|
50
|
+
show {values.length - maxVisibleValues} more
|
|
51
|
+
</span>
|
|
52
|
+
</div>
|
|
53
|
+
)}
|
|
54
|
+
</Button>
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Slot, type SlotProps } from "@radix-ui/react-slot";
|
|
2
|
+
|
|
3
|
+
export const SelectOnClick = ({
|
|
4
|
+
asChild,
|
|
5
|
+
onClick,
|
|
6
|
+
enabled = true,
|
|
7
|
+
...props
|
|
8
|
+
}: {
|
|
9
|
+
asChild?: boolean;
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
} & SlotProps) => {
|
|
12
|
+
const Component = asChild ? Slot : "span";
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<Component
|
|
16
|
+
onClick={(e) => {
|
|
17
|
+
if (enabled) {
|
|
18
|
+
const range = document.createRange();
|
|
19
|
+
range.selectNodeContents(e.currentTarget);
|
|
20
|
+
const selection = window.getSelection();
|
|
21
|
+
selection?.removeAllRanges();
|
|
22
|
+
selection?.addRange(range);
|
|
23
|
+
}
|
|
24
|
+
onClick?.(e);
|
|
25
|
+
}}
|
|
26
|
+
{...props}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -7,6 +7,7 @@ import type { SchemaObject } from "../../../oas/parser/index.js";
|
|
|
7
7
|
import { Button } from "../../../ui/Button.js";
|
|
8
8
|
import { cn } from "../../../util/cn.js";
|
|
9
9
|
import { objectEntries } from "../../../util/objectEntries.js";
|
|
10
|
+
import { EnumValues } from "../components/EnumValues.js";
|
|
10
11
|
import { LogicalGroup } from "./LogicalGroup/LogicalGroup.js";
|
|
11
12
|
import { SchemaView } from "./SchemaView.js";
|
|
12
13
|
import {
|
|
@@ -82,7 +83,7 @@ export const SchemaPropertyItem = ({
|
|
|
82
83
|
|
|
83
84
|
return (
|
|
84
85
|
<li className="p-4 bg-border/20 hover:bg-border/30">
|
|
85
|
-
<div className="flex flex-col gap-1 justify-between text-sm">
|
|
86
|
+
<div className="flex flex-col gap-1.5 justify-between text-sm">
|
|
86
87
|
<div className="flex gap-2 items-center">
|
|
87
88
|
<code>{name}</code>
|
|
88
89
|
<Badge variant="muted">
|
|
@@ -99,13 +100,19 @@ export const SchemaPropertyItem = ({
|
|
|
99
100
|
"items" in schema &&
|
|
100
101
|
isCircularRef(schema.items) && <RecursiveIndicator />}
|
|
101
102
|
</div>
|
|
102
|
-
|
|
103
103
|
{schema.description && (
|
|
104
104
|
<Markdown
|
|
105
105
|
className={cn(ProseClasses, "text-sm leading-normal line-clamp-4")}
|
|
106
106
|
content={schema.description}
|
|
107
107
|
/>
|
|
108
108
|
)}
|
|
109
|
+
{schema.format && (
|
|
110
|
+
<div>
|
|
111
|
+
<span className="text-sm text-muted-foreground">Format: </span>
|
|
112
|
+
<code>{schema.format}</code>
|
|
113
|
+
</div>
|
|
114
|
+
)}
|
|
115
|
+
{schema.enum && <EnumValues values={schema.enum} />}
|
|
109
116
|
|
|
110
117
|
{(hasLogicalGroupings(schema) || isComplexType(schema)) && (
|
|
111
118
|
<Collapsible.Root
|
|
@@ -28,6 +28,8 @@ void import("prismjs/components/prism-markdown.min.js");
|
|
|
28
28
|
void import("prismjs/components/prism-javascript.min.js");
|
|
29
29
|
// @ts-expect-error This is untyped
|
|
30
30
|
void import("prismjs/components/prism-typescript.min.js");
|
|
31
|
+
// @ts-expect-error This is untyped
|
|
32
|
+
void import("prismjs/components/prism-jsstacktrace.min.js");
|
|
31
33
|
|
|
32
34
|
import { useTheme } from "next-themes";
|
|
33
35
|
import { memo, useState } from "react";
|