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.
Files changed (137) hide show
  1. package/dist/app/App.js +8 -1
  2. package/dist/app/App.js.map +1 -1
  3. package/dist/config/config.d.ts +7 -0
  4. package/dist/lib/components/Header.js +1 -1
  5. package/dist/lib/components/Header.js.map +1 -1
  6. package/dist/lib/components/Layout.js +1 -2
  7. package/dist/lib/components/Layout.js.map +1 -1
  8. package/dist/lib/components/SyntaxHighlight.d.ts +1 -0
  9. package/dist/lib/components/SyntaxHighlight.js +1 -1
  10. package/dist/lib/components/SyntaxHighlight.js.map +1 -1
  11. package/dist/lib/components/context/DevPortalProvider.js +1 -1
  12. package/dist/lib/components/context/DevPortalProvider.js.map +1 -1
  13. package/dist/lib/components/navigation/SideNavigation.js +1 -1
  14. package/dist/lib/components/navigation/SideNavigation.js.map +1 -1
  15. package/dist/lib/components/navigation/SideNavigationCategory.js +1 -1
  16. package/dist/lib/components/navigation/SideNavigationCategory.js.map +1 -1
  17. package/dist/lib/components/navigation/SideNavigationItem.d.ts +2 -1
  18. package/dist/lib/components/navigation/SideNavigationItem.js +11 -4
  19. package/dist/lib/components/navigation/SideNavigationItem.js.map +1 -1
  20. package/dist/lib/components/navigation/SideNavigationWrapper.d.ts +3 -0
  21. package/dist/lib/components/navigation/SideNavigationWrapper.js +2 -3
  22. package/dist/lib/components/navigation/SideNavigationWrapper.js.map +1 -1
  23. package/dist/lib/core/DevPortalContext.d.ts +1 -0
  24. package/dist/lib/core/DevPortalContext.js +2 -2
  25. package/dist/lib/core/DevPortalContext.js.map +1 -1
  26. package/dist/lib/core/plugins.d.ts +1 -1
  27. package/dist/lib/core/plugins.js +1 -1
  28. package/dist/lib/core/plugins.js.map +1 -1
  29. package/dist/lib/plugins/api-key/CreateApiKeys.d.ts +5 -0
  30. package/dist/lib/plugins/api-key/CreateApiKeys.js +37 -0
  31. package/dist/lib/plugins/api-key/CreateApiKeys.js.map +1 -0
  32. package/dist/lib/plugins/api-key/SettingsApiKeys.d.ts +3 -2
  33. package/dist/lib/plugins/api-key/SettingsApiKeys.js +35 -4
  34. package/dist/lib/plugins/api-key/SettingsApiKeys.js.map +1 -1
  35. package/dist/lib/plugins/api-key/index.d.ts +19 -21
  36. package/dist/lib/plugins/api-key/index.js +57 -36
  37. package/dist/lib/plugins/api-key/index.js.map +1 -1
  38. package/dist/lib/plugins/index.js +0 -1
  39. package/dist/lib/plugins/index.js.map +1 -1
  40. package/dist/lib/plugins/openapi/MakeRequest.js +27 -12
  41. package/dist/lib/plugins/openapi/MakeRequest.js.map +1 -1
  42. package/dist/lib/plugins/openapi/OperationListItem.js +24 -1
  43. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  44. package/dist/lib/plugins/openapi/RequestBodySidecarBox.js +1 -1
  45. package/dist/lib/plugins/openapi/RequestBodySidecarBox.js.map +1 -1
  46. package/dist/lib/plugins/openapi/ResponsesSidecarBox.js +2 -2
  47. package/dist/lib/plugins/openapi/ResponsesSidecarBox.js.map +1 -1
  48. package/dist/lib/plugins/openapi/Sidecar.js +13 -13
  49. package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
  50. package/dist/lib/plugins/openapi/graphql/gql.d.ts +2 -2
  51. package/dist/lib/plugins/openapi/graphql/gql.js +1 -1
  52. package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
  53. package/dist/lib/plugins/openapi/graphql/graphql.d.ts +1 -0
  54. package/dist/lib/plugins/openapi/graphql/graphql.js +4 -0
  55. package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
  56. package/dist/lib/plugins/openapi/index.js +2 -0
  57. package/dist/lib/plugins/openapi/index.js.map +1 -1
  58. package/dist/lib/plugins/openapi/playground/Headers.js +5 -16
  59. package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
  60. package/dist/lib/plugins/openapi/playground/InlineInput.d.ts +1 -0
  61. package/dist/lib/plugins/openapi/playground/InlineInput.js +1 -1
  62. package/dist/lib/plugins/openapi/playground/{UrlParts.d.ts → PathParams.d.ts} +2 -2
  63. package/dist/lib/plugins/openapi/playground/{UrlParts.js → PathParams.js} +4 -4
  64. package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -0
  65. package/dist/lib/plugins/openapi/playground/Playground.d.ts +8 -4
  66. package/dist/lib/plugins/openapi/playground/Playground.js +49 -46
  67. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  68. package/dist/lib/plugins/openapi/playground/QueryParams.d.ts +4 -6
  69. package/dist/lib/plugins/openapi/playground/QueryParams.js +27 -22
  70. package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
  71. package/dist/lib/plugins/openapi/playground/UrlDisplay.d.ts +4 -0
  72. package/dist/lib/plugins/openapi/playground/UrlDisplay.js +22 -0
  73. package/dist/lib/plugins/openapi/playground/UrlDisplay.js.map +1 -0
  74. package/dist/lib/plugins/openapi/playground/createUrl.d.ts +2 -0
  75. package/dist/lib/plugins/openapi/playground/createUrl.js +15 -0
  76. package/dist/lib/plugins/openapi/playground/createUrl.js.map +1 -0
  77. package/dist/lib/plugins/openapi/util/generateSchemaExample.d.ts +1 -1
  78. package/dist/lib/plugins/openapi/util/generateSchemaExample.js +19 -9
  79. package/dist/lib/plugins/openapi/util/generateSchemaExample.js.map +1 -1
  80. package/dist/lib/plugins/redirect/index.d.ts +1 -2
  81. package/dist/lib/util/MdxComponents.js +1 -1
  82. package/dist/lib/util/MdxComponents.js.map +1 -1
  83. package/dist/lib/util/createVariantComponent.d.ts +4 -3
  84. package/dist/lib/util/createVariantComponent.js +9 -5
  85. package/dist/lib/util/createVariantComponent.js.map +1 -1
  86. package/dist/vite/plugin-api-keys.d.ts +4 -0
  87. package/dist/vite/plugin-api-keys.js +33 -0
  88. package/dist/vite/plugin-api-keys.js.map +1 -0
  89. package/dist/vite/plugin-mdx.js +1 -1
  90. package/dist/vite/plugin-mdx.js.map +1 -1
  91. package/dist/vite/plugin-redirect.d.ts +4 -0
  92. package/dist/vite/plugin-redirect.js +32 -0
  93. package/dist/vite/plugin-redirect.js.map +1 -0
  94. package/dist/vite/plugin.js +4 -0
  95. package/dist/vite/plugin.js.map +1 -1
  96. package/lib/{urql-B7mLfVog.js → urql-DMlBWUKL.js} +301 -321
  97. package/lib/{DevPortal-Dh66z5c3.js → util-BJVAslZ-.js} +3666 -4913
  98. package/lib/zudoku.components.js +1310 -4
  99. package/lib/zudoku.openapi-worker.js +1 -1
  100. package/lib/zudoku.plugins.js +12876 -12545
  101. package/package.json +1 -1
  102. package/src/app/App.tsx +8 -1
  103. package/src/lib/components/Header.tsx +2 -2
  104. package/src/lib/components/Layout.tsx +10 -6
  105. package/src/lib/components/SyntaxHighlight.tsx +6 -3
  106. package/src/lib/components/context/DevPortalProvider.ts +1 -1
  107. package/src/lib/components/navigation/SideNavigation.tsx +4 -1
  108. package/src/lib/components/navigation/SideNavigationCategory.tsx +3 -1
  109. package/src/lib/components/navigation/SideNavigationItem.tsx +15 -5
  110. package/src/lib/components/navigation/SideNavigationWrapper.tsx +14 -11
  111. package/src/lib/core/DevPortalContext.ts +3 -2
  112. package/src/lib/core/plugins.ts +1 -1
  113. package/src/lib/plugins/api-key/CreateApiKeys.tsx +84 -0
  114. package/src/lib/plugins/api-key/SettingsApiKeys.tsx +111 -11
  115. package/src/lib/plugins/api-key/index.tsx +80 -77
  116. package/src/lib/plugins/index.ts +0 -1
  117. package/src/lib/plugins/openapi/MakeRequest.tsx +38 -29
  118. package/src/lib/plugins/openapi/OperationListItem.tsx +137 -1
  119. package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +1 -1
  120. package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +1 -2
  121. package/src/lib/plugins/openapi/Sidecar.tsx +20 -20
  122. package/src/lib/plugins/openapi/graphql/gql.ts +3 -3
  123. package/src/lib/plugins/openapi/graphql/graphql.ts +5 -0
  124. package/src/lib/plugins/openapi/index.tsx +2 -0
  125. package/src/lib/plugins/openapi/playground/Headers.tsx +14 -20
  126. package/src/lib/plugins/openapi/playground/InlineInput.tsx +1 -1
  127. package/src/lib/plugins/openapi/playground/{UrlParts.tsx → PathParams.tsx} +22 -26
  128. package/src/lib/plugins/openapi/playground/Playground.tsx +205 -155
  129. package/src/lib/plugins/openapi/playground/QueryParams.tsx +89 -57
  130. package/src/lib/plugins/openapi/playground/UrlDisplay.tsx +32 -0
  131. package/src/lib/plugins/openapi/playground/createUrl.ts +22 -0
  132. package/src/lib/plugins/openapi/util/generateSchemaExample.ts +24 -9
  133. package/src/lib/plugins/redirect/index.tsx +1 -1
  134. package/src/lib/util/MdxComponents.tsx +1 -0
  135. package/src/lib/util/createVariantComponent.tsx +11 -8
  136. package/dist/lib/plugins/openapi/playground/UrlParts.js.map +0 -1
  137. 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 GetConsumerOptions =
10
- | {
11
- getConsumers: (context: DevPortalContext) => Promise<ConsumerData | void>;
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 ApiKeyPluginOptions = {
16
- rollKey?: (
17
- id: string,
18
- consumerName: string,
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
- deleteKey?: (
22
- id: string,
23
- consumerName: string,
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
- updateConsumerDescription?: (
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 interface ConsumerData {
42
- consumers: Consumer[];
43
- }
28
+ export type GetApiKeysOptions = ApiKeyService | { endpoint: string } | {};
44
29
 
45
- export interface Consumer {
46
- name: string;
47
- createdOn?: string;
48
- description?: string;
49
- apiKeys: ConsumerApiKey[];
50
- }
30
+ export type ApiKeyPluginOptions = {} & GetApiKeysOptions;
51
31
 
52
- export interface ConsumerApiKey {
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 defaultGetConsumers = async (context: DevPortalContext) => {
62
- const accessToken = await context.authentication?.getToken?.(context);
41
+ const createDefaultHandler = (endpoint: string): ApiKeyService => {
42
+ return {
43
+ deleteKey: async (id, context) => {
44
+ const accessToken = await context.authentication?.getToken?.(context);
63
45
 
64
- if (!accessToken) {
65
- throw new Error("No token found");
66
- }
46
+ if (!accessToken) {
47
+ throw new Error("Not authenticated");
48
+ }
67
49
 
68
- const consumers = await fetch(
69
- "https://zudoku-customer-main-b36fa2f.d2.zuplo.dev/v1/developer/api-keys",
70
- {
71
- headers: {
72
- Authorization: `Bearer ${accessToken}`,
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
- return { consumers: [await consumers.json()] };
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 getConsumers =
84
- "getConsumers" in options ? options.getConsumers : defaultGetConsumers;
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
- getNavigation: async (path: string) => {
88
- if (path !== DevPortalSystemPaths.Settings) {
89
- return [];
90
- }
101
+ getIdentities: async (context) => {
102
+ const keys = await service.getKeys(context);
91
103
 
92
- return [
93
- {
94
- path: "settings/api-keys",
95
- label: "API Keys",
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
- getIdentities: async (context) => {
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
  },
@@ -1,4 +1,3 @@
1
- // Plugins
2
1
  export { apiKeyPlugin } from "./api-key/index.js";
3
2
  export { markdownPlugin } from "./markdown/index.js";
4
3
  export { openApiPlugin } from "./openapi/index.js";
@@ -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 { gql, useQuery } from "urql";
4
+ import { graphql } from "./graphql/index.js";
6
5
 
7
- const getServerQuery = gql`
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: getServerQuery, variables });
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
- <div>
26
- <Playground
27
- host={server.data?.schema.url}
28
- method={operation.method}
29
- url={operation.path}
30
- // defaultHeaders={}
31
- />
32
- {identities.data.map((identity) => (
33
- <button
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
+ };
@@ -34,7 +34,7 @@ export const RequestBodySidecarBox = ({ content }: { content: Content }) => {
34
34
  <SyntaxHighlight
35
35
  language="json"
36
36
  noBackground
37
- copyable={false}
37
+ copyable
38
38
  className="text-xs"
39
39
  code={JSON.stringify(
40
40
  selected === "example"
@@ -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
  &nbsp;
121
120
  {path}
122
121
  </span>
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
- />
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">