zudoku 0.1.1-dev.31 → 0.1.1-dev.33
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 +8 -1
- package/dist/app/App.js.map +1 -1
- package/dist/config/config.d.ts +7 -0
- package/dist/lib/components/Header.js +1 -1
- package/dist/lib/components/Header.js.map +1 -1
- package/dist/lib/components/Layout.js +1 -2
- package/dist/lib/components/Layout.js.map +1 -1
- package/dist/lib/components/SyntaxHighlight.d.ts +1 -0
- package/dist/lib/components/SyntaxHighlight.js +1 -1
- package/dist/lib/components/SyntaxHighlight.js.map +1 -1
- package/dist/lib/components/context/DevPortalProvider.js +1 -1
- package/dist/lib/components/context/DevPortalProvider.js.map +1 -1
- package/dist/lib/components/navigation/SideNavigation.js +1 -1
- package/dist/lib/components/navigation/SideNavigation.js.map +1 -1
- package/dist/lib/components/navigation/SideNavigationCategory.js +1 -1
- package/dist/lib/components/navigation/SideNavigationCategory.js.map +1 -1
- package/dist/lib/components/navigation/SideNavigationItem.d.ts +2 -1
- package/dist/lib/components/navigation/SideNavigationItem.js +11 -4
- package/dist/lib/components/navigation/SideNavigationItem.js.map +1 -1
- package/dist/lib/components/navigation/SideNavigationWrapper.d.ts +3 -0
- package/dist/lib/components/navigation/SideNavigationWrapper.js +2 -3
- package/dist/lib/components/navigation/SideNavigationWrapper.js.map +1 -1
- package/dist/lib/core/DevPortalContext.d.ts +1 -0
- package/dist/lib/core/DevPortalContext.js +2 -2
- package/dist/lib/core/DevPortalContext.js.map +1 -1
- package/dist/lib/core/plugins.d.ts +1 -1
- package/dist/lib/core/plugins.js +1 -1
- package/dist/lib/core/plugins.js.map +1 -1
- package/dist/lib/plugins/api-key/CreateApiKeys.d.ts +5 -0
- package/dist/lib/plugins/api-key/CreateApiKeys.js +37 -0
- package/dist/lib/plugins/api-key/CreateApiKeys.js.map +1 -0
- package/dist/lib/plugins/api-key/SettingsApiKeys.d.ts +3 -2
- package/dist/lib/plugins/api-key/SettingsApiKeys.js +35 -4
- package/dist/lib/plugins/api-key/SettingsApiKeys.js.map +1 -1
- package/dist/lib/plugins/api-key/index.d.ts +19 -21
- package/dist/lib/plugins/api-key/index.js +57 -36
- package/dist/lib/plugins/api-key/index.js.map +1 -1
- package/dist/lib/plugins/index.js +0 -1
- package/dist/lib/plugins/index.js.map +1 -1
- package/dist/lib/plugins/openapi/MakeRequest.js +27 -12
- package/dist/lib/plugins/openapi/MakeRequest.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +24 -1
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.js +1 -1
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.js.map +1 -1
- package/dist/lib/plugins/openapi/ResponsesSidecarBox.js +2 -2
- package/dist/lib/plugins/openapi/ResponsesSidecarBox.js.map +1 -1
- package/dist/lib/plugins/openapi/Sidecar.js +13 -13
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/graphql/gql.d.ts +2 -2
- package/dist/lib/plugins/openapi/graphql/gql.js +1 -1
- package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
- package/dist/lib/plugins/openapi/graphql/graphql.d.ts +1 -0
- package/dist/lib/plugins/openapi/graphql/graphql.js +4 -0
- package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
- package/dist/lib/plugins/openapi/index.js +2 -0
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Headers.js +5 -16
- package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/InlineInput.d.ts +1 -0
- package/dist/lib/plugins/openapi/playground/InlineInput.js +1 -1
- package/dist/lib/plugins/openapi/playground/{UrlParts.d.ts → PathParams.d.ts} +2 -2
- package/dist/lib/plugins/openapi/playground/{UrlParts.js → PathParams.js} +4 -4
- package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/Playground.d.ts +8 -4
- package/dist/lib/plugins/openapi/playground/Playground.js +49 -46
- package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/QueryParams.d.ts +4 -6
- package/dist/lib/plugins/openapi/playground/QueryParams.js +27 -22
- package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/UrlDisplay.d.ts +4 -0
- package/dist/lib/plugins/openapi/playground/UrlDisplay.js +22 -0
- package/dist/lib/plugins/openapi/playground/UrlDisplay.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/createUrl.d.ts +2 -0
- package/dist/lib/plugins/openapi/playground/createUrl.js +15 -0
- package/dist/lib/plugins/openapi/playground/createUrl.js.map +1 -0
- package/dist/lib/plugins/openapi/util/generateSchemaExample.d.ts +1 -1
- package/dist/lib/plugins/openapi/util/generateSchemaExample.js +19 -9
- package/dist/lib/plugins/openapi/util/generateSchemaExample.js.map +1 -1
- package/dist/lib/plugins/redirect/index.d.ts +1 -2
- package/dist/lib/util/MdxComponents.js +1 -1
- package/dist/lib/util/MdxComponents.js.map +1 -1
- package/dist/lib/util/createVariantComponent.d.ts +4 -3
- package/dist/lib/util/createVariantComponent.js +9 -5
- package/dist/lib/util/createVariantComponent.js.map +1 -1
- package/dist/vite/plugin-api-keys.d.ts +4 -0
- package/dist/vite/plugin-api-keys.js +33 -0
- package/dist/vite/plugin-api-keys.js.map +1 -0
- package/dist/vite/plugin-mdx.js +1 -1
- package/dist/vite/plugin-mdx.js.map +1 -1
- package/dist/vite/plugin-redirect.d.ts +4 -0
- package/dist/vite/plugin-redirect.js +32 -0
- package/dist/vite/plugin-redirect.js.map +1 -0
- package/dist/vite/plugin.js +4 -0
- package/dist/vite/plugin.js.map +1 -1
- package/lib/{urql-B7mLfVog.js → urql-DMlBWUKL.js} +301 -321
- package/lib/{DevPortal-Dh66z5c3.js → util-BJVAslZ-.js} +3666 -4913
- package/lib/zudoku.components.js +1310 -4
- package/lib/zudoku.openapi-worker.js +1 -1
- package/lib/zudoku.plugins.js +12876 -12545
- package/package.json +1 -1
- package/src/app/App.tsx +8 -1
- package/src/lib/components/Header.tsx +2 -2
- package/src/lib/components/Layout.tsx +10 -6
- package/src/lib/components/SyntaxHighlight.tsx +6 -3
- package/src/lib/components/context/DevPortalProvider.ts +1 -1
- package/src/lib/components/navigation/SideNavigation.tsx +4 -1
- package/src/lib/components/navigation/SideNavigationCategory.tsx +3 -1
- package/src/lib/components/navigation/SideNavigationItem.tsx +15 -5
- package/src/lib/components/navigation/SideNavigationWrapper.tsx +14 -11
- package/src/lib/core/DevPortalContext.ts +3 -2
- package/src/lib/core/plugins.ts +1 -1
- package/src/lib/plugins/api-key/CreateApiKeys.tsx +84 -0
- package/src/lib/plugins/api-key/SettingsApiKeys.tsx +111 -11
- package/src/lib/plugins/api-key/index.tsx +80 -77
- package/src/lib/plugins/index.ts +0 -1
- package/src/lib/plugins/openapi/MakeRequest.tsx +38 -29
- package/src/lib/plugins/openapi/OperationListItem.tsx +137 -1
- package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +1 -1
- package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +1 -2
- package/src/lib/plugins/openapi/Sidecar.tsx +20 -20
- package/src/lib/plugins/openapi/graphql/gql.ts +3 -3
- package/src/lib/plugins/openapi/graphql/graphql.ts +5 -0
- package/src/lib/plugins/openapi/index.tsx +2 -0
- package/src/lib/plugins/openapi/playground/Headers.tsx +14 -20
- package/src/lib/plugins/openapi/playground/InlineInput.tsx +1 -1
- package/src/lib/plugins/openapi/playground/{UrlParts.tsx → PathParams.tsx} +22 -26
- package/src/lib/plugins/openapi/playground/Playground.tsx +205 -155
- package/src/lib/plugins/openapi/playground/QueryParams.tsx +89 -57
- package/src/lib/plugins/openapi/playground/UrlDisplay.tsx +32 -0
- package/src/lib/plugins/openapi/playground/createUrl.ts +22 -0
- package/src/lib/plugins/openapi/util/generateSchemaExample.ts +24 -9
- package/src/lib/plugins/redirect/index.tsx +1 -1
- package/src/lib/util/MdxComponents.tsx +1 -0
- package/src/lib/util/createVariantComponent.tsx +11 -8
- package/dist/lib/plugins/openapi/playground/UrlParts.js.map +0 -1
- package/src/lib/plugins/openapi/queries.graphql +0 -6
|
@@ -1,55 +1,35 @@
|
|
|
1
|
-
import { DevPortalSystemPaths } from "../../components/DevPortal.js";
|
|
2
1
|
import { DevPortalContext } from "../../core/DevPortalContext.js";
|
|
3
2
|
import {
|
|
4
3
|
type ApiIdentityPlugin,
|
|
5
4
|
type DevPortalPlugin,
|
|
6
5
|
} from "../../core/plugins.js";
|
|
7
6
|
import { SettingsApiKeys } from "./SettingsApiKeys.js";
|
|
7
|
+
import { CreateApiKey } from "./CreateApiKeys.js";
|
|
8
8
|
|
|
9
|
-
export type
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
| { consumerEndpoint: string };
|
|
9
|
+
export type ApiKeyResults = Promise<ApiKey[]>;
|
|
10
|
+
const DEFAULT_API_KEY_ENDPOINT =
|
|
11
|
+
"https://zudoku-rewiringamerica-main-ef9c9c0.d2.zuplo.dev";
|
|
14
12
|
|
|
15
|
-
export type
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
export type ApiKeyService = {
|
|
14
|
+
getKeys: (context: DevPortalContext) => ApiKeyResults;
|
|
15
|
+
rollKey?: (id: string, context: DevPortalContext) => Promise<void>;
|
|
16
|
+
deleteKey?: (id: string, context: DevPortalContext) => Promise<void>;
|
|
17
|
+
updateKeyDescription?: (
|
|
18
|
+
apiKey: { jd: string; description: string },
|
|
19
19
|
context: DevPortalContext,
|
|
20
20
|
) => Promise<void>;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
getUsage?: (apiKeys: string[], context: DevPortalContext) => Promise<void>;
|
|
22
|
+
createKey?: (
|
|
23
|
+
apiKey: { description: string; expiresAt?: string },
|
|
24
24
|
context: DevPortalContext,
|
|
25
25
|
) => Promise<void>;
|
|
26
|
-
|
|
27
|
-
consumerName: string,
|
|
28
|
-
description: string,
|
|
29
|
-
context: DevPortalContext,
|
|
30
|
-
) => Promise<void>;
|
|
31
|
-
createConsumer?: (
|
|
32
|
-
description: string,
|
|
33
|
-
context: DevPortalContext,
|
|
34
|
-
) => Promise<void>;
|
|
35
|
-
deleteConsumer?: (
|
|
36
|
-
consumerName: string,
|
|
37
|
-
context: DevPortalContext,
|
|
38
|
-
) => Promise<void>;
|
|
39
|
-
} & GetConsumerOptions;
|
|
26
|
+
};
|
|
40
27
|
|
|
41
|
-
export
|
|
42
|
-
consumers: Consumer[];
|
|
43
|
-
}
|
|
28
|
+
export type GetApiKeysOptions = ApiKeyService | { endpoint: string } | {};
|
|
44
29
|
|
|
45
|
-
export
|
|
46
|
-
name: string;
|
|
47
|
-
createdOn?: string;
|
|
48
|
-
description?: string;
|
|
49
|
-
apiKeys: ConsumerApiKey[];
|
|
50
|
-
}
|
|
30
|
+
export type ApiKeyPluginOptions = {} & GetApiKeysOptions;
|
|
51
31
|
|
|
52
|
-
export interface
|
|
32
|
+
export interface ApiKey {
|
|
53
33
|
id: string;
|
|
54
34
|
description?: string;
|
|
55
35
|
createdOn?: string;
|
|
@@ -58,64 +38,87 @@ export interface ConsumerApiKey {
|
|
|
58
38
|
key: string;
|
|
59
39
|
}
|
|
60
40
|
|
|
61
|
-
const
|
|
62
|
-
|
|
41
|
+
const createDefaultHandler = (endpoint: string): ApiKeyService => {
|
|
42
|
+
return {
|
|
43
|
+
deleteKey: async (id, context) => {
|
|
44
|
+
const accessToken = await context.authentication?.getToken?.(context);
|
|
63
45
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
46
|
+
if (!accessToken) {
|
|
47
|
+
throw new Error("Not authenticated");
|
|
48
|
+
}
|
|
67
49
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
50
|
+
await fetch(endpoint + `/v1/developer/api-keys/${id}`, {
|
|
51
|
+
method: "DELETE",
|
|
52
|
+
headers: {
|
|
53
|
+
Authorization: `Bearer ${accessToken}`,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
createKey: async (apiKey, context) => {
|
|
58
|
+
const accessToken = await context.authentication?.getToken?.(context);
|
|
59
|
+
|
|
60
|
+
if (!accessToken) {
|
|
61
|
+
throw new Error("Not authenticated");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
await fetch(endpoint + `/v1/developer/api-keys`, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
headers: {
|
|
67
|
+
Authorization: `Bearer ${accessToken}`,
|
|
68
|
+
"Content-Type": "application/json",
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify(apiKey),
|
|
71
|
+
});
|
|
74
72
|
},
|
|
75
|
-
|
|
73
|
+
getKeys: async (context) => {
|
|
74
|
+
const accessToken = await context.authentication?.getToken?.(context);
|
|
76
75
|
|
|
77
|
-
|
|
76
|
+
if (!accessToken) {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const keys = await fetch(endpoint + `/v1/developer/api-keys`, {
|
|
81
|
+
headers: {
|
|
82
|
+
Authorization: `Bearer ${accessToken}`,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return await keys.json();
|
|
87
|
+
},
|
|
88
|
+
};
|
|
78
89
|
};
|
|
79
90
|
|
|
80
91
|
export const apiKeyPlugin = (
|
|
81
92
|
options: ApiKeyPluginOptions,
|
|
82
93
|
): DevPortalPlugin & ApiIdentityPlugin => {
|
|
83
|
-
const
|
|
84
|
-
"
|
|
94
|
+
const endpoint =
|
|
95
|
+
"endpoint" in options ? options.endpoint : DEFAULT_API_KEY_ENDPOINT;
|
|
96
|
+
|
|
97
|
+
const service =
|
|
98
|
+
"getKeys" in options ? options : createDefaultHandler(endpoint);
|
|
85
99
|
|
|
86
100
|
return {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return [];
|
|
90
|
-
}
|
|
101
|
+
getIdentities: async (context) => {
|
|
102
|
+
const keys = await service.getKeys(context);
|
|
91
103
|
|
|
92
|
-
return
|
|
93
|
-
{
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
children: [],
|
|
104
|
+
return keys.map((key) => ({
|
|
105
|
+
authorizeRequest: (request) => {
|
|
106
|
+
request.headers.set("Authorization", `Bearer ${key.key}`);
|
|
107
|
+
return request;
|
|
97
108
|
},
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return [];
|
|
102
|
-
// throw new Error("Not implemented");
|
|
103
|
-
// const keys = await getConsumers(context);
|
|
104
|
-
// return (keys ?? { consumers: [] }).consumers
|
|
105
|
-
// .flatMap((consumer) => consumer.apiKeys)
|
|
106
|
-
// .map((key) => ({
|
|
107
|
-
// authorizeRequest: (request: Request) => {
|
|
108
|
-
// request.headers.set("Authorization", `Bearer ${key.key}`);
|
|
109
|
-
// },
|
|
110
|
-
// id: key.id,
|
|
111
|
-
// name: key.id,
|
|
112
|
-
// }));
|
|
109
|
+
id: key.id,
|
|
110
|
+
name: key.id,
|
|
111
|
+
}));
|
|
113
112
|
},
|
|
114
113
|
getRoutes: () => {
|
|
115
114
|
return [
|
|
116
115
|
{
|
|
117
116
|
path: "/settings/api-keys",
|
|
118
|
-
element: <SettingsApiKeys options={options} />,
|
|
117
|
+
element: <SettingsApiKeys options={options} service={service} />,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
path: "/settings/api-keys/new",
|
|
121
|
+
element: <CreateApiKey options={options} service={service} />,
|
|
119
122
|
},
|
|
120
123
|
];
|
|
121
124
|
},
|
package/src/lib/plugins/index.ts
CHANGED
|
@@ -1,49 +1,58 @@
|
|
|
1
|
-
import { useApiIdentities } from "../../components/context/DevPortalProvider.js";
|
|
2
1
|
import type { OperationListItemResult } from "./OperationList.js";
|
|
3
2
|
import { Playground } from "./playground/Playground.js";
|
|
4
3
|
import { useOasConfig } from "./index.js";
|
|
5
|
-
import {
|
|
4
|
+
import { graphql } from "./graphql/index.js";
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
import { useQuery } from "urql";
|
|
7
|
+
|
|
8
|
+
const GetServerQuery = graphql(/* GraphQL */ `
|
|
8
9
|
query getServerQuery($input: JSON!, $type: SchemaType!) {
|
|
9
10
|
schema(input: $input, type: $type) {
|
|
10
11
|
url
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
+
`);
|
|
14
15
|
|
|
15
16
|
export const MakeRequest = ({
|
|
16
17
|
operation,
|
|
17
18
|
}: {
|
|
18
19
|
operation: OperationListItemResult;
|
|
19
20
|
}) => {
|
|
20
|
-
const identities = useApiIdentities();
|
|
21
21
|
const variables = useOasConfig();
|
|
22
|
-
const [server] = useQuery({ query:
|
|
22
|
+
const [server] = useQuery({ query: GetServerQuery, variables });
|
|
23
|
+
|
|
24
|
+
const headers = operation.parameters
|
|
25
|
+
?.filter((p) => p.in === "header")
|
|
26
|
+
?.map((p) => ({
|
|
27
|
+
name: p.name,
|
|
28
|
+
value: "",
|
|
29
|
+
}));
|
|
30
|
+
const queryParams = operation.parameters
|
|
31
|
+
?.filter((p) => p.in === "query")
|
|
32
|
+
?.map((p) => ({
|
|
33
|
+
name: p.name,
|
|
34
|
+
value: "",
|
|
35
|
+
}));
|
|
36
|
+
const pathParams = operation.parameters
|
|
37
|
+
?.filter((p) => p.in === "path")
|
|
38
|
+
?.map((p) => ({
|
|
39
|
+
name: p.name,
|
|
40
|
+
value: "",
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
const hasParams =
|
|
44
|
+
operation.parameters?.some((p) => p.in === "query" || p.in === "path") ??
|
|
45
|
+
false;
|
|
23
46
|
|
|
24
47
|
return (
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
|
|
34
|
-
key={identity.id}
|
|
35
|
-
onClick={() => {
|
|
36
|
-
const test = new Request(
|
|
37
|
-
"https://zudoku-customer-main-b36fa2f.d2.zuplo.dev" +
|
|
38
|
-
operation.path,
|
|
39
|
-
);
|
|
40
|
-
void fetch(identity.authorizeRequest(test));
|
|
41
|
-
}}
|
|
42
|
-
className="p-2 border border-border rounded hover:bg-accent"
|
|
43
|
-
>
|
|
44
|
-
Test Request {operation.path} ({identity.name})
|
|
45
|
-
</button>
|
|
46
|
-
))}
|
|
47
|
-
</div>
|
|
48
|
+
<Playground
|
|
49
|
+
host={server.data?.schema.url ?? ""}
|
|
50
|
+
method={operation.method}
|
|
51
|
+
url={operation.path}
|
|
52
|
+
headers={headers}
|
|
53
|
+
queryParams={queryParams}
|
|
54
|
+
pathParams={pathParams}
|
|
55
|
+
hasParams={hasParams}
|
|
56
|
+
/>
|
|
48
57
|
);
|
|
49
58
|
};
|
|
@@ -5,6 +5,10 @@ import { OperationsFragment } from "./OperationList.js";
|
|
|
5
5
|
import { ParameterList } from "./ParameterList.js";
|
|
6
6
|
import { Sidecar } from "./Sidecar.js";
|
|
7
7
|
import { FragmentType, useFragment } from "./graphql/index.js";
|
|
8
|
+
import { SchemaObject } from "../../oas/parser/index.js";
|
|
9
|
+
import { useState } from "react";
|
|
10
|
+
import { cn } from "../../util/cn.js";
|
|
11
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/Tabs.js";
|
|
8
12
|
|
|
9
13
|
export const PARAM_GROUPS = ["path", "query", "header", "cookie"] as const;
|
|
10
14
|
export type ParameterGroup = (typeof PARAM_GROUPS)[number];
|
|
@@ -16,7 +20,7 @@ export const OperationListItem = ({
|
|
|
16
20
|
}) => {
|
|
17
21
|
const operation = useFragment(OperationsFragment, operationFragment);
|
|
18
22
|
const groupedParameters = groupBy(operation?.parameters ?? [], "in");
|
|
19
|
-
|
|
23
|
+
const first = operation.responses.find((re) => re.statusCode === "200");
|
|
20
24
|
return (
|
|
21
25
|
<div
|
|
22
26
|
key={operation.operationId}
|
|
@@ -48,8 +52,140 @@ export const OperationListItem = ({
|
|
|
48
52
|
)}
|
|
49
53
|
</div>
|
|
50
54
|
)}
|
|
55
|
+
<Heading level={3} className="capitalize">
|
|
56
|
+
Repsonses
|
|
57
|
+
</Heading>
|
|
58
|
+
<Tabs defaultValue={`${first?.statusCode}${first?.description}`}>
|
|
59
|
+
<TabsList>
|
|
60
|
+
{operation.responses.map((response) => (
|
|
61
|
+
<TabsTrigger value={response.statusCode + response.description}>
|
|
62
|
+
{response.description} ({response.statusCode})
|
|
63
|
+
</TabsTrigger>
|
|
64
|
+
))}
|
|
65
|
+
</TabsList>
|
|
66
|
+
<ul className="list-none m-0 px-0 overflow-hidden">
|
|
67
|
+
{operation.responses.map((response) => (
|
|
68
|
+
<TabsContent value={response.statusCode + response.description}>
|
|
69
|
+
<ViewSchema schema={response.content?.at(0)?.schema} name="" />
|
|
70
|
+
</TabsContent>
|
|
71
|
+
))}
|
|
72
|
+
</ul>
|
|
73
|
+
</Tabs>
|
|
51
74
|
</div>
|
|
75
|
+
|
|
52
76
|
<Sidecar operation={operation} />
|
|
53
77
|
</div>
|
|
54
78
|
);
|
|
55
79
|
};
|
|
80
|
+
|
|
81
|
+
const ViewSchema = ({
|
|
82
|
+
name,
|
|
83
|
+
schema,
|
|
84
|
+
level = 0,
|
|
85
|
+
collapsible = false,
|
|
86
|
+
}: {
|
|
87
|
+
level?: number;
|
|
88
|
+
collapsible?: boolean;
|
|
89
|
+
name?: string;
|
|
90
|
+
schema: SchemaObject;
|
|
91
|
+
}) => {
|
|
92
|
+
const [open, setOpen] = useState(!collapsible);
|
|
93
|
+
|
|
94
|
+
const properties = Object.entries(schema.properties ?? {});
|
|
95
|
+
const additionalProperties =
|
|
96
|
+
typeof schema.additionalProperties === "object"
|
|
97
|
+
? Object.entries(schema.additionalProperties)
|
|
98
|
+
: [];
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
className={cn(
|
|
103
|
+
"not-prose",
|
|
104
|
+
level > 0 && "border border-border rounded text-sm",
|
|
105
|
+
)}
|
|
106
|
+
onClick={
|
|
107
|
+
collapsible
|
|
108
|
+
? () => {
|
|
109
|
+
setOpen((open) => !open);
|
|
110
|
+
}
|
|
111
|
+
: undefined
|
|
112
|
+
}
|
|
113
|
+
>
|
|
114
|
+
{(schema.title ?? name) && (
|
|
115
|
+
<div className="ml-2 my-1 font-bold">{schema.title ?? name}</div>
|
|
116
|
+
)}
|
|
117
|
+
{level === 0 && <p>schema.description</p>}
|
|
118
|
+
<ul>
|
|
119
|
+
{open &&
|
|
120
|
+
properties
|
|
121
|
+
.concat(additionalProperties)
|
|
122
|
+
.map(([propertyName, property]) => (
|
|
123
|
+
<div
|
|
124
|
+
className={cn(
|
|
125
|
+
level > 0 ? "py-2" : "py-4",
|
|
126
|
+
"px-2 border-t border-border bg-border/20 hover:bg-border/30 flex gap-1 flex-col",
|
|
127
|
+
property.deprecated && "opacity-50",
|
|
128
|
+
)}
|
|
129
|
+
>
|
|
130
|
+
<div className="flex items-center gap-2 relative">
|
|
131
|
+
<code>
|
|
132
|
+
{propertyName} {property.title}
|
|
133
|
+
</code>
|
|
134
|
+
|
|
135
|
+
{property.type && (
|
|
136
|
+
<span className="text-sm text-muted-foreground">
|
|
137
|
+
{property.type}
|
|
138
|
+
</span>
|
|
139
|
+
)}
|
|
140
|
+
{property.deprecated && (
|
|
141
|
+
<span className="text-sm text-muted-foreground">
|
|
142
|
+
Deprecated
|
|
143
|
+
</span>
|
|
144
|
+
)}
|
|
145
|
+
|
|
146
|
+
{!schema.required?.includes(propertyName) &&
|
|
147
|
+
!property.required && (
|
|
148
|
+
<span className="py-px px-1.5 font-medium text-xs border border-border rounded-lg">
|
|
149
|
+
optional
|
|
150
|
+
</span>
|
|
151
|
+
)}
|
|
152
|
+
{/*{property.type === "object" && (*/}
|
|
153
|
+
{/* <div className="absolute right-3">+</div>*/}
|
|
154
|
+
{/*)}*/}
|
|
155
|
+
</div>
|
|
156
|
+
{property.description && (
|
|
157
|
+
<Markdown
|
|
158
|
+
content={property.description}
|
|
159
|
+
className="prose text-sm prose-p:my-1 leading-normal line-clamp-4"
|
|
160
|
+
/>
|
|
161
|
+
)}
|
|
162
|
+
|
|
163
|
+
{property.enum && (
|
|
164
|
+
<span className="text-sm text-muted-foreground flex gap-1 flex-wrap items-center">
|
|
165
|
+
<span>Possible values</span>
|
|
166
|
+
{property.enum
|
|
167
|
+
.filter((value) => value)
|
|
168
|
+
.map((value) => (
|
|
169
|
+
<span className="font-mono text-xs border-border border bg-muted rounded px-1">
|
|
170
|
+
{value}
|
|
171
|
+
</span>
|
|
172
|
+
))}
|
|
173
|
+
</span>
|
|
174
|
+
)}
|
|
175
|
+
{property.type === "object" && (
|
|
176
|
+
<div className="mt-2.5">
|
|
177
|
+
<ViewSchema schema={property} level={level + 1} />
|
|
178
|
+
</div>
|
|
179
|
+
)}
|
|
180
|
+
{property.type === "array" &&
|
|
181
|
+
property.items.type === "object" && (
|
|
182
|
+
<div className="mt-2.5">
|
|
183
|
+
<ViewSchema schema={property.items} level={level + 1} />
|
|
184
|
+
</div>
|
|
185
|
+
)}
|
|
186
|
+
</div>
|
|
187
|
+
))}
|
|
188
|
+
</ul>
|
|
189
|
+
</div>
|
|
190
|
+
);
|
|
191
|
+
};
|
|
@@ -20,7 +20,7 @@ export const ResponsesSidecarBox = ({
|
|
|
20
20
|
return (
|
|
21
21
|
<SidecarBox.Root>
|
|
22
22
|
<SidecarBox.Head className="text-xs grid grid-rows-2 pb-0">
|
|
23
|
-
<span className="font-mono">Responses</span>
|
|
23
|
+
<span className="font-mono">Example Responses</span>
|
|
24
24
|
<div className="flex gap-2">
|
|
25
25
|
{responses.map((response, index) => (
|
|
26
26
|
<div
|
|
@@ -43,7 +43,6 @@ export const ResponsesSidecarBox = ({
|
|
|
43
43
|
<SyntaxHighlight
|
|
44
44
|
language="json"
|
|
45
45
|
noBackground
|
|
46
|
-
copyable={false}
|
|
47
46
|
className="text-xs"
|
|
48
47
|
code={JSON.stringify(generateSchemaExample(schema), null, 2)}
|
|
49
48
|
/>
|
|
@@ -111,7 +111,6 @@ export const Sidecar = ({
|
|
|
111
111
|
return (
|
|
112
112
|
<aside className="flex flex-col overflow-hidden sticky top-[--scroll-padding] gap-4">
|
|
113
113
|
<SidecarBox.Root>
|
|
114
|
-
<MakeRequest operation={operation} />
|
|
115
114
|
<SidecarBox.Head className="flex justify-between items-center flex-nowrap p-2 gap-2 text-xs">
|
|
116
115
|
<span className="font-mono break-words">
|
|
117
116
|
<span className={cn("font-semibold", methodTextColor)}>
|
|
@@ -120,35 +119,36 @@ export const Sidecar = ({
|
|
|
120
119
|
|
|
121
120
|
{path}
|
|
122
121
|
</span>
|
|
123
|
-
<
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
{
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
122
|
+
<div className="flex gap-2 items-center">
|
|
123
|
+
<Select
|
|
124
|
+
className="self-start"
|
|
125
|
+
onChange={(e) => setOption(e.target.value)}
|
|
126
|
+
options={[
|
|
127
|
+
{ value: "shell", label: "cURL" },
|
|
128
|
+
{ value: "js", label: "Javascript" },
|
|
129
|
+
{ value: "python", label: "Python" },
|
|
130
|
+
{ value: "java", label: "Java" },
|
|
131
|
+
{ value: "go", label: "Go" },
|
|
132
|
+
{ value: "csharp", label: "C#" },
|
|
133
|
+
{ value: "kotlin", label: "Kotlin" },
|
|
134
|
+
{ value: "objc", label: "Objective C" },
|
|
135
|
+
{ value: "php", label: "PHP" },
|
|
136
|
+
{ value: "ruby", label: "Ruby" },
|
|
137
|
+
{ value: "swift", label: "Swift" },
|
|
138
|
+
]}
|
|
139
|
+
/>
|
|
140
|
+
<MakeRequest operation={operation} />
|
|
141
|
+
</div>
|
|
140
142
|
</SidecarBox.Head>
|
|
141
143
|
<SidecarBox.Body>
|
|
142
144
|
<SyntaxHighlight
|
|
143
145
|
language={option}
|
|
144
|
-
copyable={false}
|
|
145
146
|
noBackground
|
|
146
147
|
className="text-xs"
|
|
147
148
|
code={code}
|
|
148
149
|
/>
|
|
149
150
|
</SidecarBox.Body>
|
|
150
151
|
</SidecarBox.Root>
|
|
151
|
-
{/*<MakeRequest />*/}
|
|
152
152
|
{requestBodyContent && (
|
|
153
153
|
<RequestBodySidecarBox content={requestBodyContent} />
|
|
154
154
|
)}
|
|
@@ -19,7 +19,7 @@ const documents = {
|
|
|
19
19
|
types.OperationsFragmentFragmentDoc,
|
|
20
20
|
"\n query AllOperations($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n description\n title\n url\n version\n tags {\n name\n description\n operations {\n slug\n ...OperationsFragment\n }\n }\n }\n }\n":
|
|
21
21
|
types.AllOperationsDocument,
|
|
22
|
-
"\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n tags {\n __typename\n name\n operations {\n __typename\n slug\n method\n summary\n operationId\n path\n }\n }\n }\n }\n":
|
|
22
|
+
"\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n tags {\n __typename\n name\n operations {\n __typename\n slug\n deprecated\n method\n summary\n operationId\n path\n }\n }\n }\n }\n":
|
|
23
23
|
types.GetCategoriesDocument,
|
|
24
24
|
};
|
|
25
25
|
|
|
@@ -59,8 +59,8 @@ export function graphql(
|
|
|
59
59
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
60
60
|
*/
|
|
61
61
|
export function graphql(
|
|
62
|
-
source: "\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n tags {\n __typename\n name\n operations {\n __typename\n slug\n method\n summary\n operationId\n path\n }\n }\n }\n }\n",
|
|
63
|
-
): (typeof documents)["\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n tags {\n __typename\n name\n operations {\n __typename\n slug\n method\n summary\n operationId\n path\n }\n }\n }\n }\n"];
|
|
62
|
+
source: "\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n tags {\n __typename\n name\n operations {\n __typename\n slug\n deprecated\n method\n summary\n operationId\n path\n }\n }\n }\n }\n",
|
|
63
|
+
): (typeof documents)["\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n tags {\n __typename\n name\n operations {\n __typename\n slug\n deprecated\n method\n summary\n operationId\n path\n }\n }\n }\n }\n"];
|
|
64
64
|
|
|
65
65
|
export function graphql(source: string) {
|
|
66
66
|
return (documents as any)[source] ?? {};
|
|
@@ -259,6 +259,7 @@ export type GetCategoriesQuery = {
|
|
|
259
259
|
operations: Array<{
|
|
260
260
|
__typename: "OperationItem";
|
|
261
261
|
slug: string;
|
|
262
|
+
deprecated?: boolean | null;
|
|
262
263
|
method: string;
|
|
263
264
|
summary?: string | null;
|
|
264
265
|
operationId?: string | null;
|
|
@@ -763,6 +764,10 @@ export const GetCategoriesDocument = {
|
|
|
763
764
|
kind: "Field",
|
|
764
765
|
name: { kind: "Name", value: "slug" },
|
|
765
766
|
},
|
|
767
|
+
{
|
|
768
|
+
kind: "Field",
|
|
769
|
+
name: { kind: "Name", value: "deprecated" },
|
|
770
|
+
},
|
|
766
771
|
{
|
|
767
772
|
kind: "Field",
|
|
768
773
|
name: { kind: "Name", value: "method" },
|
|
@@ -66,6 +66,7 @@ const GetCategoriesQuery = graphql(`
|
|
|
66
66
|
operations {
|
|
67
67
|
__typename
|
|
68
68
|
slug
|
|
69
|
+
deprecated
|
|
69
70
|
method
|
|
70
71
|
summary
|
|
71
72
|
operationId
|
|
@@ -109,6 +110,7 @@ export const openApiPlugin = (config: OasPluginConfig): DevPortalPlugin => {
|
|
|
109
110
|
collapsible: false,
|
|
110
111
|
children: tag.operations.map((operation) => ({
|
|
111
112
|
path: `#${operation.slug}`,
|
|
113
|
+
muted: !!operation.deprecated,
|
|
112
114
|
title: operation.summary ?? operation.path,
|
|
113
115
|
label: (
|
|
114
116
|
<div className="flex flex-1 min-w-0 justify-between gap-2">
|