zudoku 0.3.0-dev.2 → 0.3.0-dev.20
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.js +11 -8
- package/dist/app/App.js.map +1 -1
- package/dist/config/config.d.ts +8 -15
- package/dist/lib/authentication/authentication.d.ts +2 -2
- package/dist/lib/authentication/hook.d.ts +1 -0
- package/dist/lib/authentication/hook.js +1 -0
- package/dist/lib/authentication/hook.js.map +1 -1
- package/dist/lib/authentication/providers/auth0.js +1 -0
- package/dist/lib/authentication/providers/auth0.js.map +1 -1
- package/dist/lib/authentication/providers/clerk.js +2 -0
- package/dist/lib/authentication/providers/clerk.js.map +1 -1
- package/dist/lib/authentication/providers/openid.js +2 -0
- package/dist/lib/authentication/providers/openid.js.map +1 -1
- package/dist/lib/authentication/state.d.ts +1 -0
- package/dist/lib/authentication/state.js +1 -0
- package/dist/lib/authentication/state.js.map +1 -1
- package/dist/lib/components/DevPortal.d.ts +2 -20
- package/dist/lib/components/DevPortal.js +13 -9
- package/dist/lib/components/DevPortal.js.map +1 -1
- package/dist/lib/components/Header.js +4 -4
- package/dist/lib/components/Header.js.map +1 -1
- package/dist/lib/components/Heading.d.ts +9 -4
- package/dist/lib/components/Heading.js +17 -2
- package/dist/lib/components/Heading.js.map +1 -1
- package/dist/lib/components/Layout.js +1 -1
- package/dist/lib/components/Layout.js.map +1 -1
- package/dist/lib/components/SyntaxHighlight.js +5 -1
- package/dist/lib/components/SyntaxHighlight.js.map +1 -1
- package/dist/lib/components/context/DevPortalProvider.d.ts +1 -1
- package/dist/lib/components/context/DevPortalProvider.js +2 -2
- package/dist/lib/components/context/DevPortalProvider.js.map +1 -1
- package/dist/lib/components/index.d.ts +2 -0
- package/dist/lib/components/index.js +2 -0
- package/dist/lib/components/index.js.map +1 -1
- package/dist/lib/core/DevPortalContext.d.ts +33 -3
- package/dist/lib/core/DevPortalContext.js +8 -4
- package/dist/lib/core/DevPortalContext.js.map +1 -1
- package/dist/lib/core/plugins.d.ts +7 -4
- package/dist/lib/core/plugins.js +1 -0
- package/dist/lib/core/plugins.js.map +1 -1
- package/dist/lib/oas/graphql/index.js +1 -1
- package/dist/lib/oas/graphql/index.js.map +1 -1
- package/dist/lib/oas/parser/index.js +3 -1
- package/dist/lib/oas/parser/index.js.map +1 -1
- package/dist/lib/plugins/api-keys/CreateApiKey.d.ts +4 -0
- package/dist/lib/plugins/{api-key → api-keys}/CreateApiKey.js +1 -1
- package/dist/lib/plugins/api-keys/CreateApiKey.js.map +1 -0
- package/dist/lib/plugins/api-keys/SettingsApiKeys.d.ts +4 -0
- package/dist/lib/plugins/api-keys/SettingsApiKeys.js +38 -0
- package/dist/lib/plugins/api-keys/SettingsApiKeys.js.map +1 -0
- package/dist/lib/plugins/api-keys/index.js +94 -0
- package/dist/lib/plugins/api-keys/index.js.map +1 -0
- package/dist/lib/plugins/markdown/MdxPage.d.ts +3 -2
- package/dist/lib/plugins/markdown/MdxPage.js +5 -4
- package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
- package/dist/lib/plugins/markdown/generateRoutes.d.ts +2 -2
- package/dist/lib/plugins/markdown/generateRoutes.js +2 -2
- package/dist/lib/plugins/markdown/generateRoutes.js.map +1 -1
- package/dist/lib/plugins/markdown/index.d.ts +4 -1
- package/dist/lib/plugins/markdown/index.js +2 -2
- package/dist/lib/plugins/markdown/index.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationList.js +4 -3
- package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +8 -4
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/ParameterList.js +1 -1
- package/dist/lib/plugins/openapi/ParameterList.js.map +1 -1
- package/dist/lib/plugins/openapi/ParameterListItem.js +1 -1
- package/dist/lib/plugins/openapi/ParameterListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/{MakeRequest.d.ts → PlaygroundDialogWrapper.d.ts} +1 -1
- package/dist/lib/plugins/openapi/{MakeRequest.js → PlaygroundDialogWrapper.js} +4 -4
- package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js.map +1 -0
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.js +1 -9
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.js.map +1 -1
- package/dist/lib/plugins/openapi/ResponsesSidecarBox.js +1 -1
- package/dist/lib/plugins/openapi/ResponsesSidecarBox.js.map +1 -1
- package/dist/lib/plugins/openapi/SchemaListView.js +4 -26
- package/dist/lib/plugins/openapi/SchemaListView.js.map +1 -1
- package/dist/lib/plugins/openapi/SchemaListViewItem.d.ts +7 -0
- package/dist/lib/plugins/openapi/SchemaListViewItem.js +16 -0
- package/dist/lib/plugins/openapi/SchemaListViewItem.js.map +1 -0
- package/dist/lib/plugins/openapi/SchemaListViewItemGroup.d.ts +8 -0
- package/dist/lib/plugins/openapi/SchemaListViewItemGroup.js +17 -0
- package/dist/lib/plugins/openapi/SchemaListViewItemGroup.js.map +1 -0
- package/dist/lib/plugins/openapi/Sidecar.js +10 -8
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/{Select.d.ts → SimpleSelect.d.ts} +3 -2
- package/dist/lib/plugins/openapi/SimpleSelect.js +5 -0
- package/dist/lib/plugins/openapi/SimpleSelect.js.map +1 -0
- package/dist/lib/plugins/openapi/index.js +8 -0
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Headers.d.ts +2 -3
- package/dist/lib/plugins/openapi/playground/Headers.js +16 -6
- package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.d.ts +4 -3
- package/dist/lib/plugins/openapi/playground/Playground.js +8 -12
- package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/PlaygroundDialog.d.ts +3 -0
- package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js +10 -0
- package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js.map +1 -0
- package/dist/lib/plugins/openapi/util/prose.d.ts +1 -0
- package/dist/lib/plugins/openapi/util/prose.js +4 -0
- package/dist/lib/plugins/openapi/util/prose.js.map +1 -0
- package/dist/lib/plugins/openapi/worker/worker.js +25 -1
- package/dist/lib/plugins/openapi/worker/worker.js.map +1 -1
- package/dist/lib/ui/button-variants.d.ts +1 -1
- package/dist/lib/util/MdxComponents.js +1 -1
- package/dist/lib/util/MdxComponents.js.map +1 -1
- package/dist/lib/util/objectEntries.d.ts +4 -0
- package/dist/lib/util/objectEntries.js +2 -0
- package/dist/lib/util/objectEntries.js.map +1 -0
- package/dist/lib/util/renderIf.d.ts +1 -0
- package/dist/lib/util/renderIf.js +2 -0
- package/dist/lib/util/renderIf.js.map +1 -0
- package/dist/vite/config.js +1 -2
- package/dist/vite/config.js.map +1 -1
- package/dist/vite/config.test.js +1 -1
- package/dist/vite/config.test.js.map +1 -1
- package/dist/vite/dev-server.js +1 -1
- package/dist/vite/dev-server.js.map +1 -1
- package/dist/vite/plugin-api-keys.js +2 -2
- package/dist/vite/plugin-api-keys.js.map +1 -1
- package/dist/vite/plugin-api.js +3 -3
- package/dist/vite/plugin-api.js.map +1 -1
- package/dist/vite/plugin-docs.js +2 -2
- package/dist/vite/plugin-docs.js.map +1 -1
- package/dist/vite/plugin-docs.test.js +1 -1
- package/dist/vite/plugin-docs.test.js.map +1 -1
- package/dist/vite/plugin-redirect.js +2 -2
- package/dist/vite/plugin-redirect.js.map +1 -1
- package/lib/DevPortalProvider-CRKuwoXc.js +4123 -0
- package/lib/Markdown-5LmPZyLV.js +8620 -0
- package/lib/MdxComponents-DYD_QPVF.js +3017 -0
- package/lib/Select-DR3PiqjV.js +4569 -0
- package/lib/Spinner-DjQ2eBxC.js +181 -0
- package/lib/assets/{worker-BCcpCNJ7.js → worker-DGvzLstc.js} +9843 -9800
- package/lib/hook-FCY9-FHO.js +24 -0
- package/lib/index-By9bEW57.js +411 -0
- package/lib/{index-DNx3xWa2.js → index-PyGcnQFX.js} +13 -12
- package/lib/loglevel-CA34MiFn.js +152 -0
- package/lib/prism-csharp.min-Yizuc34Y.js +34 -0
- package/lib/prism-objectivec.min-BXSWqpJJ.js +1 -0
- package/lib/{state-oycsxkHz.js → state-Ds_OxRHP.js} +19 -18
- package/lib/util-voKLTRDG.js +740 -0
- package/lib/zudoku.auth-auth0.js +2 -1
- package/lib/zudoku.auth-clerk.js +10 -8
- package/lib/zudoku.auth-openid.js +442 -588
- package/lib/zudoku.components.js +283 -292
- package/lib/zudoku.openapi-worker.js +12 -12
- package/lib/zudoku.plugin-api-keys.js +292 -0
- package/lib/zudoku.plugin-markdown.js +255 -0
- package/lib/zudoku.plugin-openapi.js +6240 -0
- package/lib/zudoku.plugin-redirect.js +10 -0
- package/package.json +17 -4
- package/src/app/App.tsx +12 -8
- package/src/lib/authentication/authentication.ts +2 -5
- package/src/lib/authentication/hook.ts +1 -0
- package/src/lib/authentication/providers/auth0.tsx +1 -0
- package/src/lib/authentication/providers/clerk.tsx +2 -0
- package/src/lib/authentication/providers/openid.tsx +2 -0
- package/src/lib/authentication/state.ts +2 -0
- package/src/lib/components/DevPortal.tsx +12 -28
- package/src/lib/components/Header.tsx +25 -22
- package/src/lib/components/Heading.tsx +26 -7
- package/src/lib/components/Layout.tsx +2 -2
- package/src/lib/components/SyntaxHighlight.tsx +5 -1
- package/src/lib/components/context/DevPortalProvider.ts +2 -2
- package/src/lib/components/index.ts +3 -0
- package/src/lib/core/DevPortalContext.ts +42 -12
- package/src/lib/core/plugins.ts +10 -5
- package/src/lib/oas/graphql/index.ts +2 -2
- package/src/lib/oas/parser/index.ts +3 -1
- package/src/lib/plugins/{api-key → api-keys}/CreateApiKey.tsx +2 -8
- package/src/lib/plugins/{api-key → api-keys}/SettingsApiKeys.tsx +21 -14
- package/src/lib/plugins/{api-key → api-keys}/index.tsx +67 -18
- package/src/lib/plugins/markdown/MdxPage.tsx +50 -33
- package/src/lib/plugins/markdown/generateRoutes.tsx +12 -2
- package/src/lib/plugins/markdown/index.tsx +8 -1
- package/src/lib/plugins/openapi/OperationList.tsx +9 -3
- package/src/lib/plugins/openapi/OperationListItem.tsx +66 -41
- package/src/lib/plugins/openapi/ParameterList.tsx +1 -1
- package/src/lib/plugins/openapi/ParameterListItem.tsx +3 -4
- package/src/lib/plugins/openapi/{MakeRequest.tsx → PlaygroundDialogWrapper.tsx} +3 -3
- package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +2 -16
- package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +3 -1
- package/src/lib/plugins/openapi/SchemaListView.tsx +15 -182
- package/src/lib/plugins/openapi/SchemaListViewItem.tsx +110 -0
- package/src/lib/plugins/openapi/SchemaListViewItemGroup.tsx +63 -0
- package/src/lib/plugins/openapi/Sidecar.tsx +15 -10
- package/src/lib/plugins/openapi/{Select.tsx → SimpleSelect.tsx} +5 -2
- package/src/lib/plugins/openapi/index.tsx +17 -4
- package/src/lib/plugins/openapi/playground/Headers.tsx +60 -33
- package/src/lib/plugins/openapi/playground/Playground.tsx +158 -193
- package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +34 -0
- package/src/lib/plugins/openapi/util/prose.ts +7 -0
- package/src/lib/plugins/openapi/worker/worker.ts +27 -1
- package/src/lib/util/MdxComponents.tsx +1 -1
- package/src/lib/util/objectEntries.ts +5 -0
- package/src/lib/util/renderIf.ts +4 -0
- package/dist/lib/plugins/api-key/CreateApiKey.d.ts +0 -5
- package/dist/lib/plugins/api-key/CreateApiKey.js.map +0 -1
- package/dist/lib/plugins/api-key/SettingsApiKeys.d.ts +0 -5
- package/dist/lib/plugins/api-key/SettingsApiKeys.js +0 -38
- package/dist/lib/plugins/api-key/SettingsApiKeys.js.map +0 -1
- package/dist/lib/plugins/api-key/index.js +0 -62
- package/dist/lib/plugins/api-key/index.js.map +0 -1
- package/dist/lib/plugins/index.d.ts +0 -4
- package/dist/lib/plugins/index.js +0 -5
- package/dist/lib/plugins/index.js.map +0 -1
- package/dist/lib/plugins/openapi/MakeRequest.js.map +0 -1
- package/dist/lib/plugins/openapi/Select.js +0 -5
- package/dist/lib/plugins/openapi/Select.js.map +0 -1
- package/dist/vite/common.d.ts +0 -1
- package/dist/vite/common.js +0 -5
- package/dist/vite/common.js.map +0 -1
- package/lib/Spinner-7LezPqGn.js +0 -8393
- package/lib/clerk-Wslx_mPo.js +0 -19685
- package/lib/zudoku.plugins.js +0 -19857
- package/src/lib/plugins/index.ts +0 -4
- /package/dist/lib/plugins/{api-key → api-keys}/index.d.ts +0 -0
|
@@ -8,21 +8,15 @@ import { useState } from "react";
|
|
|
8
8
|
import { Link } from "react-router-dom";
|
|
9
9
|
import { useDevPortal } from "../../components/context/DevPortalProvider.js";
|
|
10
10
|
import { Button } from "../../ui/Button.js";
|
|
11
|
-
import {
|
|
12
|
-
import { type ApiKeyPluginOptions, ApiKeyService } from "./index.js";
|
|
11
|
+
import { ApiKeyService } from "./index.js";
|
|
13
12
|
|
|
14
|
-
export const SettingsApiKeys = ({
|
|
15
|
-
options,
|
|
16
|
-
service,
|
|
17
|
-
}: {
|
|
18
|
-
options: ApiKeyPluginOptions;
|
|
19
|
-
service: ApiKeyService;
|
|
20
|
-
}) => {
|
|
13
|
+
export const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {
|
|
21
14
|
const context = useDevPortal();
|
|
22
15
|
const queryClient = useQueryClient();
|
|
23
16
|
const { data } = useSuspenseQuery({
|
|
24
17
|
queryFn: () => service.getKeys(context),
|
|
25
18
|
queryKey: ["api-keys"],
|
|
19
|
+
retry: false,
|
|
26
20
|
});
|
|
27
21
|
|
|
28
22
|
const deleteKeyMutation = useMutation({
|
|
@@ -39,7 +33,7 @@ export const SettingsApiKeys = ({
|
|
|
39
33
|
});
|
|
40
34
|
|
|
41
35
|
return (
|
|
42
|
-
<div className="max-w-screen-lg pt-[--padding-content-top] pb-[--padding-content-bottom]">
|
|
36
|
+
<div className="max-w-screen-lg h-full pt-[--padding-content-top] pb-[--padding-content-bottom]">
|
|
43
37
|
<div className="flex justify-between mb-4 border-b border-border pb-3">
|
|
44
38
|
<h1 className="font-medium text-2xl">API Keys</h1>
|
|
45
39
|
{service.createKey && (
|
|
@@ -49,9 +43,22 @@ export const SettingsApiKeys = ({
|
|
|
49
43
|
)}
|
|
50
44
|
</div>
|
|
51
45
|
|
|
52
|
-
|
|
53
|
-
<
|
|
54
|
-
|
|
46
|
+
{data.length === 0 ? (
|
|
47
|
+
<div className="flex flex-col justify-center gap-4 items-center h-1/2 my-8">
|
|
48
|
+
<div className="text-center">
|
|
49
|
+
No API keys created yet.
|
|
50
|
+
<br />
|
|
51
|
+
Get started and create the first one now
|
|
52
|
+
</div>
|
|
53
|
+
{service.createKey && (
|
|
54
|
+
<Button asChild>
|
|
55
|
+
<Link to="/settings/api-keys/new">Create API Key</Link>
|
|
56
|
+
</Button>
|
|
57
|
+
)}
|
|
58
|
+
</div>
|
|
59
|
+
) : (
|
|
60
|
+
<ul className="grid grid-cols-[minmax(250px,min-content)_1fr_min-content] ">
|
|
61
|
+
{data.map((key: any) => (
|
|
55
62
|
<li
|
|
56
63
|
className="border-b border-border p-5 grid grid-cols-subgrid col-span-full gap-2 items-center"
|
|
57
64
|
key={key.id}
|
|
@@ -100,7 +107,7 @@ export const SettingsApiKeys = ({
|
|
|
100
107
|
</li>
|
|
101
108
|
))}
|
|
102
109
|
</ul>
|
|
103
|
-
|
|
110
|
+
)}
|
|
104
111
|
</div>
|
|
105
112
|
);
|
|
106
113
|
};
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import logger from "loglevel";
|
|
2
|
+
import { Outlet, useRouteError } from "react-router-dom";
|
|
3
|
+
import invariant from "tiny-invariant";
|
|
4
|
+
import { useAuth } from "../../authentication/hook.js";
|
|
1
5
|
import { DevPortalContext } from "../../core/DevPortalContext.js";
|
|
2
6
|
import {
|
|
3
7
|
type ApiIdentityPlugin,
|
|
4
8
|
type DevPortalPlugin,
|
|
5
9
|
} from "../../core/plugins.js";
|
|
10
|
+
import { Button } from "../../ui/Button.js";
|
|
6
11
|
import { CreateApiKey } from "./CreateApiKey.js";
|
|
7
12
|
import { SettingsApiKeys } from "./SettingsApiKeys.js";
|
|
8
13
|
|
|
@@ -47,7 +52,8 @@ const createDefaultHandler = (endpoint: string): ApiKeyService => {
|
|
|
47
52
|
|
|
48
53
|
await context.signRequest(request);
|
|
49
54
|
|
|
50
|
-
await fetch(request);
|
|
55
|
+
const response = await fetch(request);
|
|
56
|
+
invariant(response.ok, "Failed to delete API key");
|
|
51
57
|
},
|
|
52
58
|
createKey: async (apiKey, context) => {
|
|
53
59
|
const request = new Request(endpoint + `/v1/developer/api-keys`, {
|
|
@@ -59,7 +65,9 @@ const createDefaultHandler = (endpoint: string): ApiKeyService => {
|
|
|
59
65
|
});
|
|
60
66
|
|
|
61
67
|
await context.signRequest(request);
|
|
62
|
-
|
|
68
|
+
|
|
69
|
+
const response = await fetch(request);
|
|
70
|
+
invariant(response.ok, "Failed to create API key");
|
|
63
71
|
},
|
|
64
72
|
getKeys: async (context) => {
|
|
65
73
|
const request = new Request(endpoint + `/v1/developer/api-keys`);
|
|
@@ -67,12 +75,43 @@ const createDefaultHandler = (endpoint: string): ApiKeyService => {
|
|
|
67
75
|
await context.signRequest(request);
|
|
68
76
|
|
|
69
77
|
const keys = await fetch(request);
|
|
78
|
+
invariant(keys.ok, "Failed to fetch API keys");
|
|
70
79
|
|
|
71
80
|
return await keys.json();
|
|
72
81
|
},
|
|
73
82
|
};
|
|
74
83
|
};
|
|
75
84
|
|
|
85
|
+
const ProtectedRoute = () => {
|
|
86
|
+
const auth = useAuth();
|
|
87
|
+
|
|
88
|
+
// TODO: should we suspend here somehow?
|
|
89
|
+
if (auth.isPending) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return auth.isAuthenticated ? (
|
|
94
|
+
<Outlet />
|
|
95
|
+
) : (
|
|
96
|
+
<div className="flex flex-col justify-center gap-2 items-center h-1/2 my-12">
|
|
97
|
+
Please login first to view this page
|
|
98
|
+
<Button onClick={() => auth.login()}>Login</Button>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
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
|
+
|
|
76
115
|
export const apiKeyPlugin = (
|
|
77
116
|
options: ApiKeyPluginOptions,
|
|
78
117
|
): DevPortalPlugin & ApiIdentityPlugin => {
|
|
@@ -84,26 +123,36 @@ export const apiKeyPlugin = (
|
|
|
84
123
|
|
|
85
124
|
return {
|
|
86
125
|
getIdentities: async (context) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
request
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
126
|
+
try {
|
|
127
|
+
const keys = await service.getKeys(context);
|
|
128
|
+
|
|
129
|
+
return keys.map((key) => ({
|
|
130
|
+
authorizeRequest: (request) => {
|
|
131
|
+
request.headers.set("Authorization", `Bearer ${key.key}`);
|
|
132
|
+
return request;
|
|
133
|
+
},
|
|
134
|
+
id: key.id,
|
|
135
|
+
label: key.description ?? key.id,
|
|
136
|
+
}));
|
|
137
|
+
} catch {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
97
140
|
},
|
|
98
141
|
getRoutes: () => {
|
|
99
142
|
return [
|
|
100
143
|
{
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
144
|
+
element: <ProtectedRoute />,
|
|
145
|
+
errorElement: <SettingsErrorBoundary />,
|
|
146
|
+
children: [
|
|
147
|
+
{
|
|
148
|
+
path: "/settings/api-keys",
|
|
149
|
+
element: <SettingsApiKeys service={service} />,
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
path: "/settings/api-keys/new",
|
|
153
|
+
element: <CreateApiKey service={service} />,
|
|
154
|
+
},
|
|
155
|
+
],
|
|
107
156
|
},
|
|
108
157
|
];
|
|
109
158
|
},
|
|
@@ -12,7 +12,7 @@ import { cn } from "../../util/cn.js";
|
|
|
12
12
|
import slugify from "../../util/slugify.js";
|
|
13
13
|
import { traverseNavigation } from "../../util/traverseNavigation.js";
|
|
14
14
|
import { Toc } from "./Toc.js";
|
|
15
|
-
import
|
|
15
|
+
import { MarkdownPluginDefaultOptions, MDXImport } from "./index.js";
|
|
16
16
|
|
|
17
17
|
const MarkdownHeadings = {
|
|
18
18
|
h2: ({ children, id }) => (
|
|
@@ -30,11 +30,13 @@ const MarkdownHeadings = {
|
|
|
30
30
|
|
|
31
31
|
export const MdxPage = ({
|
|
32
32
|
mdxComponent: MdxComponent,
|
|
33
|
-
frontmatter,
|
|
33
|
+
frontmatter = {},
|
|
34
|
+
defaultOptions,
|
|
34
35
|
tableOfContents,
|
|
35
36
|
}: PropsWithChildren<
|
|
36
37
|
Omit<MDXImport, "default"> & {
|
|
37
38
|
mdxComponent: MDXImport["default"];
|
|
39
|
+
defaultOptions?: MarkdownPluginDefaultOptions;
|
|
38
40
|
}
|
|
39
41
|
>) => {
|
|
40
42
|
const navItem = useTopNavigationItem();
|
|
@@ -50,10 +52,11 @@ export const MdxPage = ({
|
|
|
50
52
|
|
|
51
53
|
const title = frontmatter.title;
|
|
52
54
|
const category = frontmatter.category ?? categoryTitle;
|
|
53
|
-
const hideToc = frontmatter.toc === false;
|
|
54
|
-
|
|
55
|
+
const hideToc = frontmatter.toc === false || defaultOptions?.toc === false;
|
|
55
56
|
const pageTitle =
|
|
56
57
|
tableOfContents.find((item) => item.depth === 1)?.value ?? title;
|
|
58
|
+
const hidePager =
|
|
59
|
+
frontmatter.disablePager ?? defaultOptions?.disablePager ?? false;
|
|
57
60
|
|
|
58
61
|
const tocEntries =
|
|
59
62
|
tableOfContents.find((item) => item.depth === 1)?.children ??
|
|
@@ -112,35 +115,49 @@ export const MdxPage = ({
|
|
|
112
115
|
<MdxComponent
|
|
113
116
|
components={{ ...useMDXComponents(), ...MarkdownHeadings }}
|
|
114
117
|
/>
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
118
|
+
{!hidePager && (
|
|
119
|
+
<>
|
|
120
|
+
<hr />
|
|
121
|
+
<div className="not-prose flex items-center justify-between gap-8">
|
|
122
|
+
{prev.path ? (
|
|
123
|
+
<Link
|
|
124
|
+
to={prev.path}
|
|
125
|
+
className="flex flex-col items-stretch gap-2 flex-1 truncate border border-border rounded px-6 py-4 text-start hover:border-primary/85 transition shadow-sm hover:shadow-md"
|
|
126
|
+
title={
|
|
127
|
+
typeof prev.label === "string" ? prev.label : undefined
|
|
128
|
+
}
|
|
129
|
+
>
|
|
130
|
+
<div className="text-sm text-muted-foreground">
|
|
131
|
+
← Previous page
|
|
132
|
+
</div>
|
|
133
|
+
<div className="text-lg text-primary truncate">
|
|
134
|
+
{prev.label}
|
|
135
|
+
</div>
|
|
136
|
+
</Link>
|
|
137
|
+
) : (
|
|
138
|
+
<div className="flex-1" />
|
|
139
|
+
)}
|
|
140
|
+
{next.path ? (
|
|
141
|
+
<Link
|
|
142
|
+
to={next.path}
|
|
143
|
+
className="flex flex-col items-stretch gap-2 flex-1 truncate border border-border rounded px-6 py-4 text-end hover:border-primary/85 transition shadow-sm hover:shadow-md"
|
|
144
|
+
title={
|
|
145
|
+
typeof next.label === "string" ? next.label : undefined
|
|
146
|
+
}
|
|
147
|
+
>
|
|
148
|
+
<div className="text-sm text-muted-foreground">
|
|
149
|
+
Next page →
|
|
150
|
+
</div>
|
|
151
|
+
<div className="text-lg text-primary truncate">
|
|
152
|
+
{next.label}
|
|
153
|
+
</div>
|
|
154
|
+
</Link>
|
|
155
|
+
) : (
|
|
156
|
+
<div className="flex-1" />
|
|
157
|
+
)}
|
|
158
|
+
</div>
|
|
159
|
+
</>
|
|
160
|
+
)}
|
|
144
161
|
</div>
|
|
145
162
|
<div className="hidden xl:block">
|
|
146
163
|
{showToc && <Toc entries={tocEntries} />}
|
|
@@ -3,10 +3,14 @@ import { isPathItem } from "../../components/navigation/util.js";
|
|
|
3
3
|
import { Navigate, type RouteObject } from "../../core/router.js";
|
|
4
4
|
import { traverseNavigation } from "../../util/traverseNavigation.js";
|
|
5
5
|
import { MdxPage } from "./MdxPage.js";
|
|
6
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
MarkdownPluginDefaultOptions,
|
|
8
|
+
MarkdownPluginOptions,
|
|
9
|
+
} from "./index.js";
|
|
7
10
|
|
|
8
11
|
export const generateRoutes = (
|
|
9
12
|
markdownFiles: MarkdownPluginOptions["markdownFiles"],
|
|
13
|
+
defaultOptions?: MarkdownPluginDefaultOptions,
|
|
10
14
|
): RouteObject[] => {
|
|
11
15
|
const routes = Object.entries(markdownFiles).flatMap(
|
|
12
16
|
([file, importPromise]) => {
|
|
@@ -28,7 +32,13 @@ export const generateRoutes = (
|
|
|
28
32
|
const { default: Component, ...props } = await importPromise();
|
|
29
33
|
|
|
30
34
|
return {
|
|
31
|
-
element:
|
|
35
|
+
element: (
|
|
36
|
+
<MdxPage
|
|
37
|
+
mdxComponent={Component}
|
|
38
|
+
{...props}
|
|
39
|
+
defaultOptions={defaultOptions}
|
|
40
|
+
/>
|
|
41
|
+
),
|
|
32
42
|
};
|
|
33
43
|
},
|
|
34
44
|
} satisfies RouteObject;
|
|
@@ -5,13 +5,19 @@ import { generateRoutes } from "./generateRoutes.js";
|
|
|
5
5
|
|
|
6
6
|
export type MarkdownPluginOptions = {
|
|
7
7
|
markdownFiles: Record<string, () => Promise<MDXImport>>;
|
|
8
|
+
defaultOptions?: MarkdownPluginDefaultOptions;
|
|
8
9
|
};
|
|
10
|
+
export type MarkdownPluginDefaultOptions = Pick<
|
|
11
|
+
Frontmatter,
|
|
12
|
+
"toc" | "disablePager"
|
|
13
|
+
>;
|
|
9
14
|
|
|
10
15
|
export type Frontmatter = {
|
|
11
16
|
title?: string;
|
|
12
17
|
description?: string;
|
|
13
18
|
category?: string;
|
|
14
19
|
toc?: boolean;
|
|
20
|
+
disablePager?: boolean;
|
|
15
21
|
};
|
|
16
22
|
|
|
17
23
|
export type MDXImport = {
|
|
@@ -22,10 +28,11 @@ export type MDXImport = {
|
|
|
22
28
|
|
|
23
29
|
export const markdownPlugin = ({
|
|
24
30
|
markdownFiles,
|
|
31
|
+
defaultOptions,
|
|
25
32
|
}: MarkdownPluginOptions): DevPortalPlugin => {
|
|
26
33
|
return {
|
|
27
34
|
getRoutes() {
|
|
28
|
-
return generateRoutes(markdownFiles);
|
|
35
|
+
return generateRoutes(markdownFiles, defaultOptions);
|
|
29
36
|
},
|
|
30
37
|
};
|
|
31
38
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ResultOf } from "@graphql-typed-document-node/core";
|
|
2
2
|
import { CategoryHeading } from "../../components/CategoryHeading.js";
|
|
3
3
|
import { Heading } from "../../components/Heading.js";
|
|
4
|
-
import { Markdown
|
|
4
|
+
import { Markdown } from "../../components/Markdown.js";
|
|
5
5
|
import { cn } from "../../util/cn.js";
|
|
6
6
|
import { OperationListItem } from "./OperationListItem.js";
|
|
7
7
|
import { graphql } from "./graphql/index.js";
|
|
8
8
|
import { useOasConfig } from "./index.js";
|
|
9
|
+
import { SchemaProseClasses } from "./util/prose.js";
|
|
9
10
|
import { useQuery } from "./util/urql.js";
|
|
10
11
|
|
|
11
12
|
export const OperationsFragment = graphql(/* GraphQL */ `
|
|
@@ -94,7 +95,12 @@ export const OperationList = () => {
|
|
|
94
95
|
|
|
95
96
|
return (
|
|
96
97
|
<div className="pt-[--padding-content-top]">
|
|
97
|
-
<div
|
|
98
|
+
<div
|
|
99
|
+
className={cn(
|
|
100
|
+
SchemaProseClasses,
|
|
101
|
+
"mb-16 max-w-full prose-img:max-w-prose",
|
|
102
|
+
)}
|
|
103
|
+
>
|
|
98
104
|
<CategoryHeading>Overview</CategoryHeading>
|
|
99
105
|
<Heading level={1} id="description" registerSidebarAnchor>
|
|
100
106
|
{result.data.schema.title}
|
|
@@ -108,7 +114,7 @@ export const OperationList = () => {
|
|
|
108
114
|
{tag.name && <CategoryHeading>{tag.name}</CategoryHeading>}
|
|
109
115
|
{tag.description && (
|
|
110
116
|
<Markdown
|
|
111
|
-
className={`${
|
|
117
|
+
className={`${SchemaProseClasses} mt-2 mb-12`}
|
|
112
118
|
content={tag.description}
|
|
113
119
|
/>
|
|
114
120
|
)}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Heading } from "../../components/Heading.js";
|
|
2
|
-
import { Markdown
|
|
2
|
+
import { Markdown } from "../../components/Markdown.js";
|
|
3
3
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/Tabs.js";
|
|
4
|
+
import { renderIf } from "../../util/renderIf.js";
|
|
4
5
|
import { OperationsFragment } from "./OperationList.js";
|
|
5
6
|
import { ParameterList } from "./ParameterList.js";
|
|
6
7
|
import { SchemaListView } from "./SchemaListView.js";
|
|
7
8
|
import { Sidecar } from "./Sidecar.js";
|
|
8
9
|
import { FragmentType, useFragment } from "./graphql/index.js";
|
|
10
|
+
import { SchemaProseClasses } from "./util/prose.js";
|
|
9
11
|
|
|
10
12
|
export const PARAM_GROUPS = ["path", "query", "header", "cookie"] as const;
|
|
11
13
|
export type ParameterGroup = (typeof PARAM_GROUPS)[number];
|
|
@@ -20,24 +22,24 @@ export const OperationListItem = ({
|
|
|
20
22
|
operation.parameters ?? [],
|
|
21
23
|
(param) => param.in,
|
|
22
24
|
);
|
|
23
|
-
const first = operation.responses.
|
|
25
|
+
const first = operation.responses.at(0);
|
|
24
26
|
return (
|
|
25
27
|
<div
|
|
26
28
|
key={operation.operationId}
|
|
27
|
-
className="grid grid-cols-
|
|
29
|
+
className="grid grid-cols-[4fr_3fr] gap-8 items-start border-b-2 mb-16 pb-16 border-border"
|
|
28
30
|
>
|
|
29
|
-
<div className=
|
|
30
|
-
<Heading
|
|
31
|
-
level={2}
|
|
32
|
-
className="mt-0"
|
|
33
|
-
id={operation.slug}
|
|
34
|
-
registerSidebarAnchor
|
|
35
|
-
>
|
|
31
|
+
<div className="flex flex-col gap-4">
|
|
32
|
+
<Heading level={2} id={operation.slug} registerSidebarAnchor>
|
|
36
33
|
{operation.summary}
|
|
37
34
|
</Heading>
|
|
38
|
-
{operation.description &&
|
|
35
|
+
{operation.description && (
|
|
36
|
+
<Markdown
|
|
37
|
+
className={SchemaProseClasses}
|
|
38
|
+
content={operation.description}
|
|
39
|
+
/>
|
|
40
|
+
)}
|
|
39
41
|
{operation.parameters && operation.parameters.length > 0 && (
|
|
40
|
-
|
|
42
|
+
<>
|
|
41
43
|
{PARAM_GROUPS.flatMap((group) =>
|
|
42
44
|
groupedParameters[group]?.length ? (
|
|
43
45
|
<ParameterList
|
|
@@ -50,37 +52,60 @@ export const OperationListItem = ({
|
|
|
50
52
|
[]
|
|
51
53
|
),
|
|
52
54
|
)}
|
|
55
|
+
</>
|
|
56
|
+
)}
|
|
57
|
+
{renderIf(operation.requestBody?.content?.at(0)?.schema, (schema) => (
|
|
58
|
+
<div className="mt-4 flex flex-col gap-4">
|
|
59
|
+
<Heading level={3} className="capitalize">
|
|
60
|
+
Request Body
|
|
61
|
+
</Heading>
|
|
62
|
+
<SchemaListView schema={schema} />
|
|
53
63
|
</div>
|
|
64
|
+
))}
|
|
65
|
+
{operation.responses.length > 0 && (
|
|
66
|
+
<>
|
|
67
|
+
<Heading
|
|
68
|
+
level={3}
|
|
69
|
+
className="capitalize mt-8 pt-8 border-border border-t"
|
|
70
|
+
>
|
|
71
|
+
Responses
|
|
72
|
+
</Heading>
|
|
73
|
+
<Tabs defaultValue={`${first?.statusCode}${first?.description}`}>
|
|
74
|
+
<TabsList>
|
|
75
|
+
{operation.responses.map((response) => (
|
|
76
|
+
<TabsTrigger
|
|
77
|
+
value={response.statusCode + response.description}
|
|
78
|
+
key={response.statusCode}
|
|
79
|
+
title={response.description}
|
|
80
|
+
>
|
|
81
|
+
{response.statusCode}
|
|
82
|
+
</TabsTrigger>
|
|
83
|
+
))}
|
|
84
|
+
</TabsList>
|
|
85
|
+
<ul className="list-none m-0 px-0 overflow-hidden">
|
|
86
|
+
{operation.responses.map((response) => (
|
|
87
|
+
<TabsContent
|
|
88
|
+
value={response.statusCode + response.description}
|
|
89
|
+
key={response.statusCode}
|
|
90
|
+
>
|
|
91
|
+
{renderIf(
|
|
92
|
+
response.content?.find((content) => content.schema),
|
|
93
|
+
(content) => {
|
|
94
|
+
return (
|
|
95
|
+
<SchemaListView schema={content.schema} name="" />
|
|
96
|
+
);
|
|
97
|
+
},
|
|
98
|
+
) ?? (
|
|
99
|
+
<div className="border-border font-mono text-sm border rounded p-4">
|
|
100
|
+
No response body
|
|
101
|
+
</div>
|
|
102
|
+
)}
|
|
103
|
+
</TabsContent>
|
|
104
|
+
))}
|
|
105
|
+
</ul>
|
|
106
|
+
</Tabs>
|
|
107
|
+
</>
|
|
54
108
|
)}
|
|
55
|
-
<Heading level={3} className="capitalize">
|
|
56
|
-
Responses
|
|
57
|
-
</Heading>
|
|
58
|
-
<Tabs defaultValue={`${first?.statusCode}${first?.description}`}>
|
|
59
|
-
<TabsList>
|
|
60
|
-
{operation.responses.map((response) => (
|
|
61
|
-
<TabsTrigger
|
|
62
|
-
value={response.statusCode + response.description}
|
|
63
|
-
key={response.statusCode}
|
|
64
|
-
title={response.description}
|
|
65
|
-
>
|
|
66
|
-
{response.statusCode}
|
|
67
|
-
</TabsTrigger>
|
|
68
|
-
))}
|
|
69
|
-
</TabsList>
|
|
70
|
-
<ul className="list-none m-0 px-0 overflow-hidden">
|
|
71
|
-
{operation.responses.map((response) => (
|
|
72
|
-
<TabsContent
|
|
73
|
-
value={response.statusCode + response.description}
|
|
74
|
-
key={response.statusCode}
|
|
75
|
-
>
|
|
76
|
-
<SchemaListView
|
|
77
|
-
schema={response.content?.at(0)?.schema}
|
|
78
|
-
name=""
|
|
79
|
-
/>
|
|
80
|
-
</TabsContent>
|
|
81
|
-
))}
|
|
82
|
-
</ul>
|
|
83
|
-
</Tabs>
|
|
84
109
|
</div>
|
|
85
110
|
|
|
86
111
|
<Sidecar operation={operation} />
|
|
@@ -18,7 +18,7 @@ export const ParameterList = ({
|
|
|
18
18
|
<Heading level={3} id={`${id}/${group}-parameters`} className="capitalize">
|
|
19
19
|
{group === "header" ? "Headers" : `${group} Parameters`}
|
|
20
20
|
</Heading>
|
|
21
|
-
<ul className="list-none m-0 px-0 overflow-hidden">
|
|
21
|
+
<ul className="list-none m-0 px-0 overflow-hidden border border-border divide-y divide-border rounded">
|
|
22
22
|
{parameters.map((parameter) => (
|
|
23
23
|
<ParameterListItem
|
|
24
24
|
key={`${parameter.name}-${parameter.in}`}
|
|
@@ -28,14 +28,13 @@ export const ParameterListItem = ({
|
|
|
28
28
|
group: ParameterGroup;
|
|
29
29
|
id: string;
|
|
30
30
|
}) => (
|
|
31
|
-
<li className="
|
|
31
|
+
<li className="p-4 bg-border/20 text-sm flex flex-col gap-1">
|
|
32
32
|
<div className="flex items-center gap-2">
|
|
33
33
|
<code>
|
|
34
34
|
{group === "path" ? (
|
|
35
35
|
<ColorizedParam
|
|
36
36
|
name={parameter.name}
|
|
37
37
|
backgroundOpacity="15%"
|
|
38
|
-
className="px-1"
|
|
39
38
|
slug={id + "-" + parameter.name.toLocaleLowerCase()}
|
|
40
39
|
/>
|
|
41
40
|
) : (
|
|
@@ -43,12 +42,12 @@ export const ParameterListItem = ({
|
|
|
43
42
|
)}
|
|
44
43
|
</code>
|
|
45
44
|
{parameter.required && (
|
|
46
|
-
<span className="py-px px-1.5 font-medium
|
|
45
|
+
<span className="py-px px-1.5 font-medium bg-primary/75 text-muted rounded-lg">
|
|
47
46
|
required
|
|
48
47
|
</span>
|
|
49
48
|
)}
|
|
50
49
|
{getParameterSchema(parameter).type && (
|
|
51
|
-
<span className="text-
|
|
50
|
+
<span className="text-muted-foreground">
|
|
52
51
|
{getParameterSchema(parameter).type}
|
|
53
52
|
</span>
|
|
54
53
|
)}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { graphql } from "./graphql/index.js";
|
|
2
2
|
import { useOasConfig } from "./index.js";
|
|
3
3
|
import type { OperationListItemResult } from "./OperationList.js";
|
|
4
|
-
import {
|
|
4
|
+
import { PlaygroundDialog } from "./playground/PlaygroundDialog.js";
|
|
5
5
|
|
|
6
6
|
import { useQuery } from "urql";
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ const GetServerQuery = graphql(/* GraphQL */ `
|
|
|
13
13
|
}
|
|
14
14
|
`);
|
|
15
15
|
|
|
16
|
-
export const
|
|
16
|
+
export const PlaygroundDialogWrapper = ({
|
|
17
17
|
operation,
|
|
18
18
|
}: {
|
|
19
19
|
operation: OperationListItemResult;
|
|
@@ -50,7 +50,7 @@ export const MakeRequest = ({
|
|
|
50
50
|
false;
|
|
51
51
|
|
|
52
52
|
return (
|
|
53
|
-
<
|
|
53
|
+
<PlaygroundDialog
|
|
54
54
|
host={server.data?.schema.url ?? ""}
|
|
55
55
|
method={operation.method}
|
|
56
56
|
url={operation.path}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
1
|
import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
|
|
3
2
|
import { type SchemaObject } from "../../oas/graphql/index.js";
|
|
4
3
|
import type { OperationListItemResult } from "./OperationList.js";
|
|
5
|
-
import { Select } from "./Select.js";
|
|
6
4
|
import * as SidecarBox from "./SidecarBox.js";
|
|
7
5
|
import { generateSchemaExample } from "./util/generateSchemaExample.js";
|
|
8
6
|
|
|
@@ -12,23 +10,13 @@ type Content = NonNullable<
|
|
|
12
10
|
|
|
13
11
|
// @todo should we handle multiple content types?
|
|
14
12
|
export const RequestBodySidecarBox = ({ content }: { content: Content }) => {
|
|
15
|
-
const [selected, setSelected] = useState("example");
|
|
16
|
-
|
|
17
13
|
if (!content.length) return null;
|
|
18
14
|
|
|
19
15
|
return (
|
|
20
16
|
<>
|
|
21
|
-
<div>lol</div>
|
|
22
17
|
<SidecarBox.Root>
|
|
23
18
|
<SidecarBox.Head className="text-xs flex justify-between items-center">
|
|
24
|
-
<span className="font-mono">Request Body</span>
|
|
25
|
-
<Select
|
|
26
|
-
onChange={(e) => setSelected(e.target.value)}
|
|
27
|
-
options={[
|
|
28
|
-
{ value: "example", label: "Example" },
|
|
29
|
-
{ value: "schema", label: "Schema" },
|
|
30
|
-
]}
|
|
31
|
-
/>
|
|
19
|
+
<span className="font-mono">Request Body Example</span>
|
|
32
20
|
</SidecarBox.Head>
|
|
33
21
|
<SidecarBox.Body>
|
|
34
22
|
<SyntaxHighlight
|
|
@@ -37,9 +25,7 @@ export const RequestBodySidecarBox = ({ content }: { content: Content }) => {
|
|
|
37
25
|
copyable
|
|
38
26
|
className="text-xs"
|
|
39
27
|
code={JSON.stringify(
|
|
40
|
-
|
|
41
|
-
? generateSchemaExample(content[0].schema as SchemaObject)
|
|
42
|
-
: content[0].schema,
|
|
28
|
+
generateSchemaExample(content[0].schema as SchemaObject),
|
|
43
29
|
null,
|
|
44
30
|
2,
|
|
45
31
|
)}
|