zudoku 0.24.1 → 0.25.1

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.
Files changed (108) hide show
  1. package/dist/config/validators/InputSidebarSchema.d.ts +15 -0
  2. package/dist/config/validators/InputSidebarSchema.js +1 -0
  3. package/dist/config/validators/InputSidebarSchema.js.map +1 -1
  4. package/dist/config/validators/common.d.ts +45 -34
  5. package/dist/config/validators/common.js +2 -1
  6. package/dist/config/validators/common.js.map +1 -1
  7. package/dist/config/validators/validate.d.ts +19 -14
  8. package/dist/lib/authentication/components/SignOut.js +1 -1
  9. package/dist/lib/authentication/components/SignOut.js.map +1 -1
  10. package/dist/lib/authentication/providers/clerk.js +29 -6
  11. package/dist/lib/authentication/providers/clerk.js.map +1 -1
  12. package/dist/lib/components/Header.js +13 -13
  13. package/dist/lib/components/Header.js.map +1 -1
  14. package/dist/lib/components/Layout.js +1 -1
  15. package/dist/lib/components/Layout.js.map +1 -1
  16. package/dist/lib/components/TopNavigation.js +2 -2
  17. package/dist/lib/components/TopNavigation.js.map +1 -1
  18. package/dist/lib/components/navigation/SidebarBadge.d.ts +11 -1
  19. package/dist/lib/components/navigation/SidebarBadge.js +11 -2
  20. package/dist/lib/components/navigation/SidebarBadge.js.map +1 -1
  21. package/dist/lib/components/navigation/SidebarCategory.js +2 -2
  22. package/dist/lib/components/navigation/SidebarCategory.js.map +1 -1
  23. package/dist/lib/components/navigation/SidebarWrapper.js +1 -1
  24. package/dist/lib/components/navigation/SidebarWrapper.js.map +1 -1
  25. package/dist/lib/oas/graphql/index.js +16 -3
  26. package/dist/lib/oas/graphql/index.js.map +1 -1
  27. package/dist/lib/oas/parser/upgrade/index.js +17 -3
  28. package/dist/lib/oas/parser/upgrade/index.js.map +1 -1
  29. package/dist/lib/plugins/openapi/CollapsibleCode.js +2 -1
  30. package/dist/lib/plugins/openapi/CollapsibleCode.js.map +1 -1
  31. package/dist/lib/plugins/openapi/Endpoint.d.ts +1 -1
  32. package/dist/lib/plugins/openapi/Endpoint.js +3 -1
  33. package/dist/lib/plugins/openapi/Endpoint.js.map +1 -1
  34. package/dist/lib/plugins/openapi/ExampleDisplay.d.ts +12 -0
  35. package/dist/lib/plugins/openapi/ExampleDisplay.js +78 -0
  36. package/dist/lib/plugins/openapi/ExampleDisplay.js.map +1 -0
  37. package/dist/lib/plugins/openapi/OperationListItem.js +1 -1
  38. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  39. package/dist/lib/plugins/openapi/ParameterListItem.js +1 -1
  40. package/dist/lib/plugins/openapi/ParameterListItem.js.map +1 -1
  41. package/dist/lib/plugins/openapi/RequestBodySidecarBox.d.ts +2 -4
  42. package/dist/lib/plugins/openapi/RequestBodySidecarBox.js +6 -13
  43. package/dist/lib/plugins/openapi/RequestBodySidecarBox.js.map +1 -1
  44. package/dist/lib/plugins/openapi/ResponsesSidecarBox.js +11 -13
  45. package/dist/lib/plugins/openapi/ResponsesSidecarBox.js.map +1 -1
  46. package/dist/lib/plugins/openapi/Sidecar.js +1 -1
  47. package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
  48. package/dist/lib/plugins/openapi/SidecarBox.js +4 -4
  49. package/dist/lib/plugins/openapi/SidecarBox.js.map +1 -1
  50. package/dist/lib/plugins/openapi/index.js +1 -0
  51. package/dist/lib/plugins/openapi/index.js.map +1 -1
  52. package/dist/lib/plugins/openapi/playground/Headers.js +1 -1
  53. package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
  54. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js +1 -1
  55. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js.map +1 -1
  56. package/dist/lib/ui/Card.js +1 -1
  57. package/dist/lib/ui/Card.js.map +1 -1
  58. package/dist/vite/build.js +10 -8
  59. package/dist/vite/build.js.map +1 -1
  60. package/dist/vite/config.js +10 -0
  61. package/dist/vite/config.js.map +1 -1
  62. package/lib/{AuthenticationPlugin-DVLEc6cm.js → AuthenticationPlugin-D7G3me8L.js} +16 -16
  63. package/lib/AuthenticationPlugin-D7G3me8L.js.map +1 -0
  64. package/lib/{OperationList-CqLL5P5l.js → OperationList-BLdHAQ39.js} +1865 -1811
  65. package/lib/OperationList-BLdHAQ39.js.map +1 -0
  66. package/lib/assets/{worker-DV9Ecqy9.js → worker-Cbp2r2BQ.js} +26 -14
  67. package/lib/assets/{worker-DV9Ecqy9.js.map → worker-Cbp2r2BQ.js.map} +1 -1
  68. package/lib/{createServer-C4C0OO0m.js → createServer-Bf5_6o6G.js} +796 -784
  69. package/lib/{createServer-C4C0OO0m.js.map → createServer-Bf5_6o6G.js.map} +1 -1
  70. package/lib/{index-DzRORsY1.js → index-BNx95gkf.js} +7 -5
  71. package/lib/index-BNx95gkf.js.map +1 -0
  72. package/lib/ui/Card.js +7 -7
  73. package/lib/ui/Card.js.map +1 -1
  74. package/lib/zudoku.auth-clerk.js +80 -52
  75. package/lib/zudoku.auth-clerk.js.map +1 -1
  76. package/lib/zudoku.auth-openid.js +1 -1
  77. package/lib/zudoku.components.js +222 -218
  78. package/lib/zudoku.components.js.map +1 -1
  79. package/lib/zudoku.openapi-worker.js +1 -1
  80. package/lib/zudoku.plugin-openapi.js +1 -1
  81. package/package.json +4 -4
  82. package/src/app/main.css +50 -37
  83. package/src/lib/authentication/components/SignOut.tsx +2 -1
  84. package/src/lib/authentication/providers/clerk.tsx +38 -7
  85. package/src/lib/components/Header.tsx +9 -5
  86. package/src/lib/components/Layout.tsx +1 -1
  87. package/src/lib/components/TopNavigation.tsx +2 -2
  88. package/src/lib/components/navigation/SidebarBadge.tsx +13 -1
  89. package/src/lib/components/navigation/SidebarCategory.tsx +3 -7
  90. package/src/lib/components/navigation/SidebarWrapper.tsx +3 -2
  91. package/src/lib/oas/graphql/index.ts +16 -7
  92. package/src/lib/oas/parser/upgrade/index.ts +19 -4
  93. package/src/lib/plugins/openapi/CollapsibleCode.tsx +10 -7
  94. package/src/lib/plugins/openapi/Endpoint.tsx +3 -3
  95. package/src/lib/plugins/openapi/ExampleDisplay.tsx +163 -0
  96. package/src/lib/plugins/openapi/OperationListItem.tsx +5 -3
  97. package/src/lib/plugins/openapi/ParameterListItem.tsx +1 -1
  98. package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +11 -37
  99. package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +49 -63
  100. package/src/lib/plugins/openapi/Sidecar.tsx +4 -6
  101. package/src/lib/plugins/openapi/SidecarBox.tsx +4 -16
  102. package/src/lib/plugins/openapi/index.tsx +1 -0
  103. package/src/lib/plugins/openapi/playground/Headers.tsx +1 -0
  104. package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +1 -1
  105. package/src/lib/ui/Card.tsx +1 -1
  106. package/lib/AuthenticationPlugin-DVLEc6cm.js.map +0 -1
  107. package/lib/OperationList-CqLL5P5l.js.map +0 -1
  108. package/lib/index-DzRORsY1.js.map +0 -1
@@ -0,0 +1,163 @@
1
+ import { useState } from "react";
2
+ import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
3
+ import { type SchemaObject } from "../../oas/graphql/index.js";
4
+ import { CollapsibleCode } from "./CollapsibleCode.js";
5
+ import type { OperationListItemResult } from "./OperationList.js";
6
+ import * as SidecarBox from "./SidecarBox.js";
7
+ import { SimpleSelect } from "./SimpleSelect.js";
8
+ import { generateSchemaExample } from "./util/generateSchemaExample.js";
9
+
10
+ export type Content = NonNullable<
11
+ NonNullable<OperationListItemResult["requestBody"]>["content"]
12
+ >;
13
+ export type Example = NonNullable<
14
+ NonNullable<Content[number]["examples"]>
15
+ >[number];
16
+
17
+ const formatExample = (example: unknown) => {
18
+ if (example == null) return "No example";
19
+
20
+ if (typeof example === "string" || typeof example !== "object") {
21
+ return String(example).trim();
22
+ }
23
+
24
+ return JSON.stringify(example, null, 2);
25
+ };
26
+
27
+ const getLanguageForContentType = (mediaType?: string) =>
28
+ mediaType
29
+ ? ({
30
+ "application/json": "json",
31
+ "application/xml": "xml",
32
+ "application/x-yaml": "yaml",
33
+ "text/csv": "csv",
34
+ "application/javascript": "javascript",
35
+ "application/graphql": "graphql",
36
+ "text/plain": "plain",
37
+ "application/x-www-form-urlencoded": "plain",
38
+ "multipart/form-data": "plain",
39
+ "application/x-protobuf": "plain",
40
+ }[mediaType] ?? "plain")
41
+ : "plain";
42
+
43
+ const getExampleName = (example: Example) => {
44
+ if (example.summary) return example.summary;
45
+ if (example.name) return example.name;
46
+ if (example.description) return example.description;
47
+ };
48
+
49
+ const getExampleValue = (example?: Example) => {
50
+ if (!example) return undefined;
51
+
52
+ if (example.value !== undefined) return example.value;
53
+ if (example.externalValue) return example.externalValue;
54
+ if (example.name) return example;
55
+ };
56
+
57
+ export interface UseExampleDisplayProps {
58
+ content: Content;
59
+ description?: string;
60
+ }
61
+
62
+ export const useSidecarExamples = ({
63
+ content,
64
+ description,
65
+ }: UseExampleDisplayProps) => {
66
+ const [selectedContentTypeIndex, setSelectedContentTypeIndex] = useState(0);
67
+ const [selectedExampleIndex, setSelectedExampleIndex] = useState(0);
68
+
69
+ const selectedContent = content[selectedContentTypeIndex];
70
+ const examples = (selectedContent?.examples ?? []) as Example[];
71
+ const hasExamples = examples.length > 0;
72
+
73
+ const selectedExample = hasExamples
74
+ ? examples[selectedExampleIndex]
75
+ : undefined;
76
+
77
+ const example = hasExamples
78
+ ? getExampleValue(selectedExample)
79
+ : selectedContent?.schema
80
+ ? generateSchemaExample(selectedContent.schema as SchemaObject)
81
+ : undefined;
82
+
83
+ const formattedExample = formatExample(example);
84
+ const language = getLanguageForContentType(selectedContent?.mediaType);
85
+
86
+ const SidecarBody = () => (
87
+ <SidecarBox.Body className="p-0">
88
+ {selectedExample?.externalValue ? (
89
+ <div className="p-2">
90
+ <a
91
+ href={selectedExample.externalValue}
92
+ target="_blank"
93
+ rel="noopener noreferrer"
94
+ className="text-xs text-primary hover:underline"
95
+ >
96
+ View External Example →
97
+ </a>
98
+ </div>
99
+ ) : (
100
+ <CollapsibleCode>
101
+ <SyntaxHighlight
102
+ language={language}
103
+ noBackground
104
+ copyable
105
+ className="[--scrollbar-color:gray] text-xs max-h-[500px] p-2"
106
+ code={formattedExample}
107
+ />
108
+ </CollapsibleCode>
109
+ )}
110
+ {selectedExample?.description && (
111
+ <div className="border-t text-xs px-2 py-1">
112
+ {selectedExample.description}
113
+ </div>
114
+ )}
115
+ </SidecarBox.Body>
116
+ );
117
+
118
+ const SidebarFooter = () => (
119
+ <SidecarBox.Footer className="flex items-center text-xs gap-2 justify-between py-1">
120
+ <div className="flex items-center gap-2 min-w-0">
121
+ {content.length > 1 ? (
122
+ <div className="flex items-center gap-1">
123
+ <SimpleSelect
124
+ className="max-w-[200px]"
125
+ value={selectedContentTypeIndex.toString()}
126
+ onChange={(e) =>
127
+ setSelectedContentTypeIndex(Number(e.target.value))
128
+ }
129
+ options={content.map((c, index) => ({
130
+ value: index.toString(),
131
+ label: c.mediaType,
132
+ }))}
133
+ />
134
+ </div>
135
+ ) : (
136
+ <span className="font-mono text-[11px]">{content[0]?.mediaType}</span>
137
+ )}
138
+ {description && (
139
+ <span className="text-muted-foreground truncate">{description}</span>
140
+ )}
141
+ </div>
142
+ {examples.length > 1 && (
143
+ <div className="flex items-center gap-1">
144
+ <SimpleSelect
145
+ className="max-w-[180px]"
146
+ value={selectedExampleIndex.toString()}
147
+ onChange={(e) => setSelectedExampleIndex(Number(e.target.value))}
148
+ options={examples.map((example, index) => ({
149
+ value: index.toString(),
150
+ label: getExampleName(example) ?? `Example ${index + 1}`,
151
+ }))}
152
+ />
153
+ </div>
154
+ )}
155
+ </SidecarBox.Footer>
156
+ );
157
+
158
+ return {
159
+ SidecarBody,
160
+ SidebarFooter,
161
+ hasContent: hasExamples || content.length > 0,
162
+ };
163
+ };
@@ -57,9 +57,11 @@ export const OperationListItem = ({
57
57
  }
58
58
  }}
59
59
  >
60
- <div className="text-neutral-400 dark:text-neutral-500 truncate">
61
- {serverUrl}
62
- </div>
60
+ {serverUrl && (
61
+ <div className="text-neutral-400 dark:text-neutral-500 truncate">
62
+ {serverUrl}
63
+ </div>
64
+ )}
63
65
  <div className="text-neutral-900 dark:text-neutral-200">
64
66
  {operation.path}
65
67
  </div>
@@ -45,7 +45,7 @@ export const ParameterListItem = ({
45
45
  )}
46
46
  </code>
47
47
  {parameter.required && (
48
- <span className="py-px px-1.5 font-medium bg-primary/75 text-muted rounded-lg">
48
+ <span className="py-px px-1.5 font-medium bg-primary/75 text-primary-foreground rounded-lg">
49
49
  required
50
50
  </span>
51
51
  )}
@@ -1,44 +1,18 @@
1
- import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
2
- import { type SchemaObject } from "../../oas/graphql/index.js";
3
- import { CollapsibleCode } from "./CollapsibleCode.js";
4
- import type { OperationListItemResult } from "./OperationList.js";
1
+ import { Content, useSidecarExamples } from "./ExampleDisplay.js";
5
2
  import * as SidecarBox from "./SidecarBox.js";
6
- import { generateSchemaExample } from "./util/generateSchemaExample.js";
7
3
 
8
- type Content = NonNullable<
9
- NonNullable<OperationListItemResult["requestBody"]>["content"]
10
- >;
11
-
12
- // @todo should we handle multiple content types?
13
4
  export const RequestBodySidecarBox = ({ content }: { content: Content }) => {
14
- if (!content.length) return null;
15
-
16
- const firstContent = content.at(0);
17
-
18
- const example =
19
- firstContent?.examples?.at(0)?.value ??
20
- (firstContent?.schema
21
- ? generateSchemaExample(firstContent.schema as SchemaObject)
22
- : "");
5
+ const { SidecarBody, SidebarFooter, hasContent } = useSidecarExamples({
6
+ content,
7
+ });
23
8
 
24
9
  return (
25
- <>
26
- <SidecarBox.Root>
27
- <SidecarBox.Head className="text-xs flex justify-between items-center">
28
- <span className="font-mono">Request Body Example</span>
29
- </SidecarBox.Head>
30
- <SidecarBox.Body className="p-0">
31
- <CollapsibleCode>
32
- <SyntaxHighlight
33
- language={example ? "json" : "plain"}
34
- noBackground
35
- copyable
36
- className="[--scrollbar-color:gray] text-xs max-h-[500px] p-2"
37
- code={example ? JSON.stringify(example, null, 2) : "No example"}
38
- />
39
- </CollapsibleCode>
40
- </SidecarBox.Body>
41
- </SidecarBox.Root>
42
- </>
10
+ <SidecarBox.Root>
11
+ <SidecarBox.Head className="text-xs flex justify-between items-center">
12
+ <span className="font-mono">Request Body Example</span>
13
+ </SidecarBox.Head>
14
+ <SidecarBody />
15
+ {hasContent && <SidebarFooter />}
16
+ </SidecarBox.Root>
43
17
  );
44
18
  };
@@ -1,13 +1,25 @@
1
1
  import * as Tabs from "@radix-ui/react-tabs";
2
- import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
3
- import { type SchemaObject } from "../../oas/graphql/index.js";
4
2
  import { cn } from "../../util/cn.js";
5
- import { CollapsibleCode } from "./CollapsibleCode.js";
3
+ import { useSidecarExamples } from "./ExampleDisplay.js";
6
4
  import type { OperationListItemResult } from "./OperationList.js";
7
5
  import * as SidecarBox from "./SidecarBox.js";
8
- import { generateSchemaExample } from "./util/generateSchemaExample.js";
9
6
 
10
7
  type Responses = OperationListItemResult["responses"];
8
+
9
+ const ResponseContent = ({ response }: { response: Responses[number] }) => {
10
+ const { SidecarBody, SidebarFooter, hasContent } = useSidecarExamples({
11
+ content: response.content ?? [],
12
+ description: response.description ?? undefined,
13
+ });
14
+
15
+ return (
16
+ <Tabs.Content value={response.statusCode}>
17
+ <SidecarBody />
18
+ {hasContent && <SidebarFooter />}
19
+ </Tabs.Content>
20
+ );
21
+ };
22
+
11
23
  export const ResponsesSidecarBox = ({
12
24
  responses,
13
25
  selectedResponse,
@@ -16,62 +28,36 @@ export const ResponsesSidecarBox = ({
16
28
  responses: Responses;
17
29
  selectedResponse?: string;
18
30
  onSelectResponse: (response: string) => void;
19
- }) => (
20
- <SidecarBox.Root>
21
- <Tabs.Root
22
- defaultValue={responses[0]?.statusCode}
23
- value={selectedResponse}
24
- onValueChange={(value) => onSelectResponse(value)}
25
- >
26
- <SidecarBox.Head className="text-xs flex flex-col gap-2 pb-0">
27
- <span className="font-mono">Example Responses</span>
28
- <Tabs.List className="flex gap-2">
29
- {responses.map((response) => (
30
- <Tabs.Trigger
31
- key={response.statusCode}
32
- value={response.statusCode}
33
- className={cn(
34
- "text-xs font-mono px-1.5 py-1 pb-px translate-y-px border-b-2 border-transparent rounded-t cursor-pointer",
35
- "data-[state=active]:text-primary data-[state=active]:dark:text-inherit data-[state=active]:border-primary",
36
- "hover:border-accent-foreground/25",
37
- )}
38
- >
39
- {response.statusCode}
40
- </Tabs.Trigger>
41
- ))}
42
- </Tabs.List>
43
- </SidecarBox.Head>
44
- {responses.map((response) => {
45
- const firstContent = response.content?.at(0);
46
-
47
- const example =
48
- firstContent?.examples?.at(0)?.value ??
49
- (firstContent?.schema
50
- ? generateSchemaExample(firstContent.schema as SchemaObject)
51
- : "");
52
-
53
- return (
54
- <Tabs.Content key={response.statusCode} value={response.statusCode}>
55
- <SidecarBox.Body className="p-0">
56
- <CollapsibleCode>
57
- <SyntaxHighlight
58
- language={example ? "json" : "plain"}
59
- noBackground
60
- className="[--scrollbar-color:gray] text-xs max-h-[500px] p-2"
61
- code={
62
- example
63
- ? JSON.stringify(example, null, 2)
64
- : "Empty response"
65
- }
66
- />
67
- </CollapsibleCode>
68
- </SidecarBox.Body>
69
- <SidecarBox.Footer className="flex justify-end text-xs">
70
- {response.description}
71
- </SidecarBox.Footer>
72
- </Tabs.Content>
73
- );
74
- })}
75
- </Tabs.Root>
76
- </SidecarBox.Root>
77
- );
31
+ }) => {
32
+ return (
33
+ <SidecarBox.Root>
34
+ <Tabs.Root
35
+ defaultValue={responses[0]?.statusCode}
36
+ value={selectedResponse}
37
+ onValueChange={(value) => onSelectResponse(value)}
38
+ >
39
+ <SidecarBox.Head className="text-xs flex flex-col gap-2 pb-0">
40
+ <span className="font-mono">Example Responses</span>
41
+ <Tabs.List className="flex gap-2">
42
+ {responses.map((response) => (
43
+ <Tabs.Trigger
44
+ key={response.statusCode}
45
+ value={response.statusCode}
46
+ className={cn(
47
+ "text-xs font-mono px-1.5 py-1 pb-px translate-y-px border-b-2 border-transparent rounded-t cursor-pointer",
48
+ "data-[state=active]:text-primary data-[state=active]:dark:text-inherit data-[state=active]:border-primary",
49
+ "hover:border-accent-foreground/25",
50
+ )}
51
+ >
52
+ {response.statusCode}
53
+ </Tabs.Trigger>
54
+ ))}
55
+ </Tabs.List>
56
+ </SidecarBox.Head>
57
+ {responses.map((response) => (
58
+ <ResponseContent key={response.statusCode} response={response} />
59
+ ))}
60
+ </Tabs.Root>
61
+ </SidecarBox.Root>
62
+ );
63
+ };
@@ -181,7 +181,7 @@ export const Sidecar = ({
181
181
  className="flex flex-col overflow-hidden sticky top-[--scroll-padding] gap-4"
182
182
  >
183
183
  <SidecarBox.Root>
184
- <SidecarBox.Head className="flex justify-between items-center flex-nowrap py-3 gap-2 text-xs">
184
+ <SidecarBox.Head className="flex justify-between items-center flex-nowrap py-4 gap-2 text-xs">
185
185
  <span className="font-mono break-words">
186
186
  <span className={cn("font-semibold", methodTextColor)}>
187
187
  {operation.method.toLocaleUpperCase()}
@@ -191,10 +191,8 @@ export const Sidecar = ({
191
191
  </span>
192
192
  {isOnScreen && (
193
193
  <PlaygroundDialogWrapper
194
- server={result.data.schema.url ?? ""}
195
- servers={
196
- result.data.schema.servers.map((server) => server.url) ?? []
197
- }
194
+ server={result.data.schema.url}
195
+ servers={result.data.schema.servers.map((server) => server.url)}
198
196
  operation={operation}
199
197
  />
200
198
  )}
@@ -211,7 +209,7 @@ export const Sidecar = ({
211
209
  />
212
210
  </CollapsibleCode>
213
211
  </SidecarBox.Body>
214
- <SidecarBox.Footer className="flex items-center text-xs gap-2 justify-end py-1">
212
+ <SidecarBox.Footer className="flex items-center text-xs gap-2 justify-end py-3">
215
213
  <span>Show example in</span>
216
214
  <SimpleSelect
217
215
  className="self-start max-w-[150px]"
@@ -7,10 +7,7 @@ type BaseComponentProps<T = unknown> = PropsWithChildren<
7
7
 
8
8
  export const Root = ({ children, className }: BaseComponentProps) => (
9
9
  <div
10
- className={cn(
11
- "rounded-lg overflow-hidden border dark:border-transparent",
12
- className,
13
- )}
10
+ className={cn("rounded-xl overflow-hidden border border-border", className)}
14
11
  >
15
12
  {children}
16
13
  </div>
@@ -19,7 +16,7 @@ export const Root = ({ children, className }: BaseComponentProps) => (
19
16
  export const Head = ({ children, className }: BaseComponentProps) => (
20
17
  <div
21
18
  className={cn(
22
- "border-b dark:border-zinc-600 bg-zinc-100 dark:bg-zinc-700 p-2",
19
+ "border-b bg-muted dark:bg-transparent text-card-foreground p-3",
23
20
  className,
24
21
  )}
25
22
  >
@@ -28,20 +25,11 @@ export const Head = ({ children, className }: BaseComponentProps) => (
28
25
  );
29
26
 
30
27
  export const Body = ({ children, className }: BaseComponentProps) => (
31
- <div
32
- className={cn("bg-zinc-50 dark:bg-zinc-800 overflow-auto p-2", className)}
33
- >
34
- {children}
35
- </div>
28
+ <div className={cn("bg-card overflow-auto p-2", className)}>{children}</div>
36
29
  );
37
30
 
38
31
  export const Footer = ({ children, className }: BaseComponentProps) => (
39
- <div
40
- className={cn(
41
- "border-t dark:border-zinc-600 bg-zinc-100 dark:bg-zinc-700 p-2",
42
- className,
43
- )}
44
- >
32
+ <div className={cn("border-t bg-muted dark:bg-transparent p-3", className)}>
45
33
  {children}
46
34
  </div>
47
35
  );
@@ -151,6 +151,7 @@ export const openApiPlugin = (config: OpenApiPluginOptions): ZudokuPlugin => {
151
151
  badge: {
152
152
  label: operation.method,
153
153
  color: MethodColorMap[operation.method.toLowerCase()]!,
154
+ invert: true,
154
155
  },
155
156
  })),
156
157
  }));
@@ -63,6 +63,7 @@ export const Headers = ({
63
63
  className=""
64
64
  onClick={() => append({ name: "", value: "" })}
65
65
  type="button"
66
+ variant="secondary"
66
67
  >
67
68
  Add header
68
69
  </Button>
@@ -39,7 +39,7 @@ const PlaygroundDialog = (props: PlaygroundDialogProps) => {
39
39
  <Dialog onOpenChange={(open) => setOpen(open)}>
40
40
  <DialogTrigger asChild>
41
41
  {props.children ?? (
42
- <button className="flex gap-1 items-center px-2 py-1 rounded-md bg-primary/80 hover:bg-primary transition text-primary-foreground text-xs">
42
+ <button className="flex gap-1 items-center px-2 py-1 rounded-md transition text-xs bg-primary text-primary-foreground shadow-sm hover:bg-primary/80">
43
43
  Test
44
44
  <HeroPlayIcon className="" size={14} />
45
45
  </button>
@@ -8,7 +8,7 @@ const Card = React.forwardRef<
8
8
  <div
9
9
  ref={ref}
10
10
  className={cn(
11
- "rounded-xl border bg-card text-card-foreground shadow",
11
+ "rounded-xl border bg-card text-card-foreground shadow-sm",
12
12
  className,
13
13
  )}
14
14
  {...props}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AuthenticationPlugin-DVLEc6cm.js","sources":["../src/lib/authentication/components/SignIn.tsx","../src/lib/authentication/components/SignOut.tsx","../src/lib/authentication/components/SignUp.tsx","../src/lib/authentication/AuthenticationPlugin.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useSearchParams } from \"react-router\";\nimport { useZudoku } from \"../../components/context/ZudokuContext.js\";\n\nexport const SignIn = () => {\n const context = useZudoku();\n const [search] = useSearchParams();\n useEffect(() => {\n void context.authentication?.signIn({\n redirectTo: search.get(\"redirect\") ?? undefined,\n });\n }, [context.authentication, search]);\n\n return null;\n};\n","import { useEffect } from \"react\";\nimport { useNavigate } from \"react-router\";\nimport { useZudoku } from \"../../components/context/ZudokuContext.js\";\n\nexport const SignOut = () => {\n const context = useZudoku();\n const navigate = useNavigate();\n useEffect(() => {\n void context.authentication?.signOut().then(() => navigate(\"/\"));\n }, [navigate, context.authentication]);\n\n return null;\n};\n","import { useEffect } from \"react\";\nimport { useZudoku } from \"../../components/context/ZudokuContext.js\";\n\nexport const SignUp = () => {\n const context = useZudoku();\n useEffect(() => {\n void (context.authentication?.signUp() ?? context.authentication?.signIn());\n }, [context.authentication]);\n\n return null;\n};\n","import { LogOutIcon } from \"lucide-react\";\nimport {\n CommonPlugin,\n NavigationPlugin,\n ProfileMenuPlugin,\n} from \"../core/plugins.js\";\nimport { SignIn } from \"./components/SignIn.js\";\nimport { SignOut } from \"./components/SignOut.js\";\nimport { SignUp } from \"./components/SignUp.js\";\n\ntype PluginInterface = NavigationPlugin & CommonPlugin & ProfileMenuPlugin;\n\nexport class AuthenticationPlugin implements PluginInterface {\n getRoutes() {\n return [\n {\n path: \"/signout\",\n element: <SignOut />,\n },\n {\n path: \"/signin\",\n element: <SignIn />,\n },\n {\n path: \"/signup\",\n element: <SignUp />,\n },\n ];\n }\n\n getProfileMenuItems() {\n return [\n {\n label: \"Logout\",\n path: \"/signout\",\n category: \"bottom\",\n icon: LogOutIcon,\n } as const,\n ];\n }\n}\n"],"names":["SignIn","context","useZudoku","search","useSearchParams","useEffect","_a","SignOut","navigate","useNavigate","SignUp","_b","AuthenticationPlugin","LogOutIcon"],"mappings":";;;;;AAIO,MAAMA,IAAS,MAAM;AAC1B,QAAMC,IAAUC,EAAU,GACpB,CAACC,CAAM,IAAIC,EAAgB;AACjC,SAAAC,EAAU,MAAM;;AACT,KAAAC,IAAAL,EAAQ,mBAAR,QAAAK,EAAwB,OAAO;AAAA,MAClC,YAAYH,EAAO,IAAI,UAAU,KAAK;AAAA,IAAA;AAAA,EAEvC,GAAA,CAACF,EAAQ,gBAAgBE,CAAM,CAAC,GAE5B;AACT,GCVaI,IAAU,MAAM;AAC3B,QAAMN,IAAUC,EAAU,GACpBM,IAAWC,EAAY;AAC7B,SAAAJ,EAAU,MAAM;;AACT,KAAAC,IAAAL,EAAQ,mBAAR,QAAAK,EAAwB,UAAU,KAAK,MAAME,EAAS,GAAG;AAAA,EAC7D,GAAA,CAACA,GAAUP,EAAQ,cAAc,CAAC,GAE9B;AACT,GCTaS,IAAS,MAAM;AAC1B,QAAMT,IAAUC,EAAU;AAC1B,SAAAG,EAAU,MAAM;;AACd,MAAMC,IAAAL,EAAQ,mBAAR,gBAAAK,EAAwB,eAAYK,IAAAV,EAAQ,mBAAR,QAAAU,EAAwB;AAAA,EAAO,GACxE,CAACV,EAAQ,cAAc,CAAC,GAEpB;AACT;ACEO,MAAMW,EAAgD;AAAA,EAC3D,YAAY;AACH,WAAA;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,+BAAUL,GAAQ,CAAA,CAAA;AAAA,MACpB;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,+BAAUP,GAAO,CAAA,CAAA;AAAA,MACnB;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,+BAAUU,GAAO,CAAA,CAAA;AAAA,MAAA;AAAA,IAErB;AAAA,EAAA;AAAA,EAGF,sBAAsB;AACb,WAAA;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAMG;AAAA,MAAA;AAAA,IAEV;AAAA,EAAA;AAEJ;"}