zudoku 0.42.2 → 0.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/dist/app/entry.client.js +21 -0
  2. package/dist/app/entry.client.js.map +1 -1
  3. package/dist/config/loader.d.ts +1 -16
  4. package/dist/config/loader.js +9 -90
  5. package/dist/config/loader.js.map +1 -1
  6. package/dist/config/validators/common.d.ts +193 -0
  7. package/dist/config/validators/common.js +2 -0
  8. package/dist/config/validators/common.js.map +1 -1
  9. package/dist/config/validators/validate.d.ts +70 -0
  10. package/dist/lib/components/Banner.js +1 -1
  11. package/dist/lib/components/Banner.js.map +1 -1
  12. package/dist/lib/components/Heading.d.ts +2 -2
  13. package/dist/lib/components/Heading.js +1 -1
  14. package/dist/lib/components/Heading.js.map +1 -1
  15. package/dist/lib/components/Layout.js +1 -1
  16. package/dist/lib/components/Layout.js.map +1 -1
  17. package/dist/lib/components/Main.js +3 -2
  18. package/dist/lib/components/Main.js.map +1 -1
  19. package/dist/lib/components/MobileTopNavigation.js +1 -1
  20. package/dist/lib/components/MobileTopNavigation.js.map +1 -1
  21. package/dist/lib/components/Pagination.js +2 -2
  22. package/dist/lib/components/Pagination.js.map +1 -1
  23. package/dist/lib/components/Search.js +1 -1
  24. package/dist/lib/components/Search.js.map +1 -1
  25. package/dist/lib/components/TopNavigation.js +1 -1
  26. package/dist/lib/components/TopNavigation.js.map +1 -1
  27. package/dist/lib/components/navigation/PoweredByZudoku.js +1 -1
  28. package/dist/lib/components/navigation/PoweredByZudoku.js.map +1 -1
  29. package/dist/lib/components/navigation/Sidebar.js +1 -1
  30. package/dist/lib/components/navigation/Sidebar.js.map +1 -1
  31. package/dist/lib/components/navigation/SidebarCategory.js +9 -5
  32. package/dist/lib/components/navigation/SidebarCategory.js.map +1 -1
  33. package/dist/lib/components/navigation/SidebarItem.js +2 -3
  34. package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
  35. package/dist/lib/components/navigation/Toc.js +2 -2
  36. package/dist/lib/components/navigation/Toc.js.map +1 -1
  37. package/dist/lib/core/ZudokuContext.d.ts +2 -1
  38. package/dist/lib/core/ZudokuContext.js.map +1 -1
  39. package/dist/lib/oas/parser/upgrade/index.d.ts +1 -0
  40. package/dist/lib/oas/parser/upgrade/index.js +76 -24
  41. package/dist/lib/oas/parser/upgrade/index.js.map +1 -1
  42. package/dist/lib/plugins/openapi/CollapsibleCode.js +1 -1
  43. package/dist/lib/plugins/openapi/OperationList.js +1 -1
  44. package/dist/lib/plugins/openapi/OperationListItem.js +4 -2
  45. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  46. package/dist/lib/plugins/openapi/ParamInfos.js +1 -0
  47. package/dist/lib/plugins/openapi/ParamInfos.js.map +1 -1
  48. package/dist/lib/plugins/openapi/SchemaList.js +1 -1
  49. package/dist/lib/plugins/openapi/client/useCreateQuery.d.ts +5 -0
  50. package/dist/lib/plugins/openapi/client/useCreateQuery.js +10 -4
  51. package/dist/lib/plugins/openapi/client/useCreateQuery.js.map +1 -1
  52. package/dist/lib/plugins/openapi/components/ConstValue.d.ts +5 -0
  53. package/dist/lib/plugins/openapi/components/ConstValue.js +6 -0
  54. package/dist/lib/plugins/openapi/components/ConstValue.js.map +1 -0
  55. package/dist/lib/plugins/openapi/index.d.ts +3 -4
  56. package/dist/lib/plugins/openapi/index.js +6 -4
  57. package/dist/lib/plugins/openapi/index.js.map +1 -1
  58. package/dist/lib/plugins/openapi/interfaces.d.ts +4 -3
  59. package/dist/lib/plugins/openapi/playground/IdentitySelector.js +1 -1
  60. package/dist/lib/plugins/openapi/playground/Playground.js +2 -2
  61. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  62. package/dist/lib/plugins/openapi/playground/QueryParams.d.ts +1 -1
  63. package/dist/lib/plugins/openapi/playground/QueryParams.js +1 -1
  64. package/dist/lib/plugins/openapi/playground/SubmitButton.d.ts +1 -1
  65. package/dist/lib/plugins/openapi/playground/SubmitButton.js +1 -1
  66. package/dist/lib/plugins/openapi/playground/result-panel/RequestTab.js +1 -1
  67. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +1 -1
  68. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js +1 -1
  69. package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js +6 -4
  70. package/dist/lib/plugins/openapi/schema/SchemaPropertyItem.js.map +1 -1
  71. package/dist/lib/plugins/openapi/schema/SchemaView.js +8 -5
  72. package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -1
  73. package/dist/lib/plugins/openapi/util/generateSchemaExample.js +40 -0
  74. package/dist/lib/plugins/openapi/util/generateSchemaExample.js.map +1 -1
  75. package/dist/lib/plugins/openapi/util/getRoutes.js +33 -3
  76. package/dist/lib/plugins/openapi/util/getRoutes.js.map +1 -1
  77. package/dist/lib/ui/SyntaxHighlight.js +1 -1
  78. package/dist/lib/ui/SyntaxHighlight.js.map +1 -1
  79. package/dist/lib/util/traverse.d.ts +1 -1
  80. package/dist/lib/util/traverse.js +6 -5
  81. package/dist/lib/util/traverse.js.map +1 -1
  82. package/dist/vite/build.js +1 -0
  83. package/dist/vite/build.js.map +1 -1
  84. package/dist/vite/config.js +1 -1
  85. package/dist/vite/config.js.map +1 -1
  86. package/dist/vite/dev-server.js +5 -2
  87. package/dist/vite/dev-server.js.map +1 -1
  88. package/dist/vite/html.d.ts +6 -2
  89. package/dist/vite/html.js +11 -8
  90. package/dist/vite/html.js.map +1 -1
  91. package/dist/vite/plugin-api.js +2 -2
  92. package/dist/vite/plugin-api.js.map +1 -1
  93. package/lib/{AuthenticationPlugin-ByDF051g.js → AuthenticationPlugin-BxoEZCSJ.js} +4 -4
  94. package/lib/{AuthenticationPlugin-ByDF051g.js.map → AuthenticationPlugin-BxoEZCSJ.js.map} +1 -1
  95. package/lib/{Markdown-mFpg_n9p.js → Markdown-DvdVn1O7.js} +1839 -1836
  96. package/lib/Markdown-DvdVn1O7.js.map +1 -0
  97. package/lib/{MdxPage-Cm7atiW3.js → MdxPage-DUcuusMU.js} +7 -7
  98. package/lib/{MdxPage-Cm7atiW3.js.map → MdxPage-DUcuusMU.js.map} +1 -1
  99. package/lib/{OasProvider-CDtbrUG_.js → OasProvider-CjMm8pB7.js} +8 -9
  100. package/lib/{OasProvider-CDtbrUG_.js.map → OasProvider-CjMm8pB7.js.map} +1 -1
  101. package/lib/{OperationList-DTyJIxKW.js → OperationList-BhJcPgGi.js} +1353 -1316
  102. package/lib/{OperationList-DTyJIxKW.js.map → OperationList-BhJcPgGi.js.map} +1 -1
  103. package/lib/Pagination-BgQxwq5j.js +48 -0
  104. package/lib/Pagination-BgQxwq5j.js.map +1 -0
  105. package/lib/{RouteGuard-DRtEu9nh.js → RouteGuard-D2gX29iI.js} +3 -3
  106. package/lib/{RouteGuard-DRtEu9nh.js.map → RouteGuard-D2gX29iI.js.map} +1 -1
  107. package/lib/{SchemaList-B9lvArDe.js → SchemaList-BexhT_Z0.js} +22 -23
  108. package/lib/{SchemaList-B9lvArDe.js.map → SchemaList-BexhT_Z0.js.map} +1 -1
  109. package/lib/SchemaView-Dt_-u8rW.js +365 -0
  110. package/lib/SchemaView-Dt_-u8rW.js.map +1 -0
  111. package/lib/{Select-CT64Ou40.js → Select-CYaEBIYK.js} +3 -3
  112. package/lib/{Select-CT64Ou40.js.map → Select-CYaEBIYK.js.map} +1 -1
  113. package/lib/{SlotletProvider-CS_nO-XT.js → SlotletProvider-wWbHYqWf.js} +7 -7
  114. package/lib/SlotletProvider-wWbHYqWf.js.map +1 -0
  115. package/lib/{SyntaxHighlight-CxhyyMkF.js → SyntaxHighlight-o7q0acut.js} +81 -81
  116. package/lib/{SyntaxHighlight-CxhyyMkF.js.map → SyntaxHighlight-o7q0acut.js.map} +1 -1
  117. package/lib/{Toc-D_tV8_Ri.js → Toc-BnN4zBb3.js} +17 -17
  118. package/lib/Toc-BnN4zBb3.js.map +1 -0
  119. package/lib/{chunk-BAXFHI7N-BVBOl9s0.js → chunk-BAXFHI7N-BLTsN6tl.js} +679 -659
  120. package/lib/{chunk-BAXFHI7N-BVBOl9s0.js.map → chunk-BAXFHI7N-BLTsN6tl.js.map} +1 -1
  121. package/lib/{circular-ByJI6Mci.js → circular-BWEIet3w.js} +4616 -5567
  122. package/lib/circular-BWEIet3w.js.map +1 -0
  123. package/lib/{createServer-IW7v5hWm.js → createServer-BQD3Eeqb.js} +1998 -1970
  124. package/lib/createServer-BQD3Eeqb.js.map +1 -0
  125. package/lib/{hook-CldJlP5c.js → hook-8GM2HXNM.js} +24 -24
  126. package/lib/{hook-CldJlP5c.js.map → hook-8GM2HXNM.js.map} +1 -1
  127. package/lib/index-CFf9AN-y.js +3208 -0
  128. package/lib/index-CFf9AN-y.js.map +1 -0
  129. package/lib/{index-DnQftvP4.js → index-DGNSSXgR.js} +77 -69
  130. package/lib/{index-DnQftvP4.js.map → index-DGNSSXgR.js.map} +1 -1
  131. package/lib/{mutation-DBQh7AOZ.js → mutation-Bq5bn7Hf.js} +2 -2
  132. package/lib/{mutation-DBQh7AOZ.js.map → mutation-Bq5bn7Hf.js.map} +1 -1
  133. package/lib/processors/traverse.js +9 -7
  134. package/lib/processors/traverse.js.map +1 -1
  135. package/lib/ui/SyntaxHighlight.js +1 -1
  136. package/lib/{useExposedProps-DbIZXspi.js → useExposedProps-DmTJxEXG.js} +2 -2
  137. package/lib/{useExposedProps-DbIZXspi.js.map → useExposedProps-DmTJxEXG.js.map} +1 -1
  138. package/lib/zudoku.auth-auth0.js +1 -1
  139. package/lib/zudoku.auth-clerk.js +2 -2
  140. package/lib/zudoku.auth-openid.js +3 -3
  141. package/lib/zudoku.components.js +6 -6
  142. package/lib/zudoku.hooks.js +1 -1
  143. package/lib/zudoku.plugin-api-catalog.js +5 -5
  144. package/lib/zudoku.plugin-api-keys.js +4 -4
  145. package/lib/zudoku.plugin-custom-pages.js +2 -2
  146. package/lib/zudoku.plugin-markdown.js +1 -1
  147. package/lib/zudoku.plugin-openapi.js +6 -5
  148. package/lib/zudoku.plugin-redirect.js +1 -1
  149. package/lib/zudoku.plugin-search-pagefind.js +3 -3
  150. package/package.json +4 -4
  151. package/src/app/entry.client.tsx +26 -0
  152. package/src/app/main.css +2 -2
  153. package/src/lib/components/Banner.tsx +1 -1
  154. package/src/lib/components/Heading.tsx +3 -3
  155. package/src/lib/components/Layout.tsx +1 -4
  156. package/src/lib/components/Main.tsx +4 -3
  157. package/src/lib/components/MobileTopNavigation.tsx +2 -2
  158. package/src/lib/components/Pagination.tsx +3 -3
  159. package/src/lib/components/Search.tsx +1 -1
  160. package/src/lib/components/TopNavigation.tsx +1 -1
  161. package/src/lib/components/navigation/PoweredByZudoku.tsx +6 -1
  162. package/src/lib/components/navigation/Sidebar.tsx +1 -1
  163. package/src/lib/components/navigation/SidebarCategory.tsx +9 -5
  164. package/src/lib/components/navigation/SidebarItem.tsx +2 -3
  165. package/src/lib/components/navigation/Toc.tsx +4 -4
  166. package/src/lib/core/ZudokuContext.ts +2 -1
  167. package/src/lib/oas/parser/upgrade/index.ts +97 -27
  168. package/src/lib/plugins/openapi/CollapsibleCode.tsx +2 -2
  169. package/src/lib/plugins/openapi/OperationList.tsx +1 -1
  170. package/src/lib/plugins/openapi/OperationListItem.tsx +15 -6
  171. package/src/lib/plugins/openapi/ParamInfos.tsx +1 -0
  172. package/src/lib/plugins/openapi/SchemaList.tsx +1 -1
  173. package/src/lib/plugins/openapi/client/useCreateQuery.ts +23 -4
  174. package/src/lib/plugins/openapi/components/ConstValue.tsx +24 -0
  175. package/src/lib/plugins/openapi/index.tsx +8 -7
  176. package/src/lib/plugins/openapi/interfaces.ts +4 -3
  177. package/src/lib/plugins/openapi/playground/IdentitySelector.tsx +2 -2
  178. package/src/lib/plugins/openapi/playground/Playground.tsx +5 -5
  179. package/src/lib/plugins/openapi/playground/QueryParams.tsx +2 -2
  180. package/src/lib/plugins/openapi/playground/SubmitButton.tsx +2 -2
  181. package/src/lib/plugins/openapi/playground/result-panel/RequestTab.tsx +2 -2
  182. package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +1 -1
  183. package/src/lib/plugins/openapi/playground/result-panel/ResultPanel.tsx +1 -1
  184. package/src/lib/plugins/openapi/schema/SchemaPropertyItem.tsx +6 -3
  185. package/src/lib/plugins/openapi/schema/SchemaView.tsx +31 -15
  186. package/src/lib/plugins/openapi/util/generateSchemaExample.ts +45 -0
  187. package/src/lib/plugins/openapi/util/getRoutes.tsx +67 -3
  188. package/src/lib/ui/SyntaxHighlight.tsx +2 -2
  189. package/src/lib/util/traverse.ts +8 -5
  190. package/lib/Markdown-mFpg_n9p.js.map +0 -1
  191. package/lib/Pagination-DLPL5z77.js +0 -48
  192. package/lib/Pagination-DLPL5z77.js.map +0 -1
  193. package/lib/SchemaView-DXjql-Bl.js +0 -356
  194. package/lib/SchemaView-DXjql-Bl.js.map +0 -1
  195. package/lib/SlotletProvider-CS_nO-XT.js.map +0 -1
  196. package/lib/Toc-D_tV8_Ri.js.map +0 -1
  197. package/lib/circular-ByJI6Mci.js.map +0 -1
  198. package/lib/context-Lrf2Y9bR.js +0 -22
  199. package/lib/context-Lrf2Y9bR.js.map +0 -1
  200. package/lib/createServer-IW7v5hWm.js.map +0 -1
  201. package/lib/index-Ckl3s_w-.js +0 -2184
  202. package/lib/index-Ckl3s_w-.js.map +0 -1
@@ -7,6 +7,7 @@ import type { SchemaObject } from "../../../oas/parser/index.js";
7
7
  import { Button } from "../../../ui/Button.js";
8
8
  import { cn } from "../../../util/cn.js";
9
9
  import { objectEntries } from "../../../util/objectEntries.js";
10
+ import { ConstValue } from "../components/ConstValue.js";
10
11
  import { EnumValues } from "../components/EnumValues.js";
11
12
  import { SelectOnClick } from "../components/SelectOnClick.js";
12
13
  import { ParamInfos } from "../ParamInfos.js";
@@ -68,7 +69,7 @@ export const SchemaPropertyItem = ({
68
69
  return (
69
70
  <li className="p-4 bg-border/20 hover:bg-border/30">
70
71
  <div className="flex flex-col gap-2.5 justify-between text-sm">
71
- <div className="space-x-2">
72
+ <div className="space-x-2 rtl:space-x-reverse">
72
73
  <code>{name}</code>
73
74
  <ParamInfos
74
75
  schema={schema}
@@ -84,7 +85,7 @@ export const SchemaPropertyItem = ({
84
85
  return (
85
86
  <li className="p-4 bg-border/20 hover:bg-border/30">
86
87
  <div className="flex flex-col gap-2.5 justify-between text-sm">
87
- <div className="space-x-2">
88
+ <div className="space-x-2 rtl:space-x-reverse">
88
89
  <SelectOnClick asChild>
89
90
  <code>{name}</code>
90
91
  </SelectOnClick>
@@ -109,11 +110,13 @@ export const SchemaPropertyItem = ({
109
110
  {schema.type === "array" && "items" in schema && schema.items.enum && (
110
111
  <EnumValues values={schema.items.enum} />
111
112
  )}
113
+ {schema.const && <ConstValue schema={schema} hideDescription />}
112
114
  {schema.enum && <EnumValues values={schema.enum} />}
113
115
  <SchemaExampleAndDefault schema={schema} />
114
116
  {(hasLogicalGroupings(schema) ||
115
117
  isComplexType(schema) ||
116
- isArrayType(schema)) && (
118
+ isArrayType(schema) ||
119
+ schema.additionalProperties) && (
117
120
  <Collapsible.Root
118
121
  defaultOpen={defaultOpen}
119
122
  open={isOpen}
@@ -1,8 +1,10 @@
1
+ import { InfoIcon } from "lucide-react";
1
2
  import { Markdown, ProseClasses } from "../../../components/Markdown.js";
2
3
  import type { SchemaObject } from "../../../oas/parser/index.js";
3
- import { Card, CardContent, CardHeader, CardTitle } from "../../../ui/Card.js";
4
+ import { Card } from "../../../ui/Card.js";
4
5
  import { cn } from "../../../util/cn.js";
5
6
  import { groupBy } from "../../../util/groupBy.js";
7
+ import { ConstValue } from "../components/ConstValue.js";
6
8
  import { EnumValues } from "../components/EnumValues.js";
7
9
  import { ParamInfos } from "../ParamInfos.js";
8
10
  import { SchemaExampleAndDefault } from "./SchemaExampleAndDefault.js";
@@ -48,6 +50,10 @@ export const SchemaView = ({
48
50
  );
49
51
  }
50
52
 
53
+ if (schema.const) {
54
+ return <ConstValue schema={schema} />;
55
+ }
56
+
51
57
  if (hasLogicalGroupings(schema)) {
52
58
  return <SchemaLogicalGroup schema={schema} />;
53
59
  }
@@ -57,7 +63,7 @@ export const SchemaView = ({
57
63
  }
58
64
 
59
65
  if (schema.type === "array" && typeof schema.items === "object") {
60
- return <SchemaView schema={schema.items as SchemaObject} />;
66
+ return <SchemaView schema={schema.items} />;
61
67
  }
62
68
 
63
69
  if (schema.type === "object") {
@@ -73,6 +79,28 @@ export const SchemaView = ({
73
79
  );
74
80
  const groupNames = ["required", "optional", "deprecated"] as const;
75
81
 
82
+ const additionalProperties =
83
+ typeof schema.additionalProperties === "object" ? (
84
+ <SchemaView schema={schema.additionalProperties} />
85
+ ) : schema.additionalProperties === true ? (
86
+ <div
87
+ className={cn(
88
+ ProseClasses,
89
+ "text-sm p-4 bg-border/20 hover:bg-border/30 flex items-center gap-1",
90
+ )}
91
+ >
92
+ <span>Additional properties are allowed</span>
93
+ <a
94
+ className="p-0.5 -m-0.5"
95
+ href="https://swagger.io/docs/specification/v3_0/data-models/dictionaries/"
96
+ rel="noopener noreferrer"
97
+ target="_blank"
98
+ >
99
+ <InfoIcon size={14} />
100
+ </a>
101
+ </div>
102
+ ) : null;
103
+
76
104
  return (
77
105
  <Card className="divide-y overflow-hidden">
78
106
  {groupNames.map(
@@ -91,19 +119,7 @@ export const SchemaView = ({
91
119
  </ul>
92
120
  ),
93
121
  )}
94
- </Card>
95
- );
96
- }
97
-
98
- if (schema.additionalProperties) {
99
- return (
100
- <Card className="my-2">
101
- <CardHeader>
102
- <CardTitle>Additional Properties:</CardTitle>
103
- </CardHeader>
104
- <CardContent>
105
- <SchemaView schema={schema.additionalProperties as SchemaObject} />
106
- </CardContent>
122
+ {additionalProperties}
107
123
  </Card>
108
124
  );
109
125
  }
@@ -24,6 +24,11 @@ export const generateSchemaExample = (
24
24
  }
25
25
  }
26
26
 
27
+ // No example needed for const values
28
+ if (schema.const !== undefined) {
29
+ return schema.const;
30
+ }
31
+
27
32
  // For object schemas with properties
28
33
  if (schema.type === "object" && schema.properties) {
29
34
  const example: Record<string, any> = {};
@@ -50,10 +55,50 @@ export const generateSchemaExample = (
50
55
  return [];
51
56
  }
52
57
 
58
+ if (schema.format !== undefined) {
59
+ // Partial implementation of JSON Schema format examples
60
+ // https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.7.3
61
+ switch (schema.format) {
62
+ case "date-time":
63
+ return "2024-08-25T15:00:00Z";
64
+ case "date":
65
+ return "2024-08-25";
66
+ case "time":
67
+ return "15:00:00";
68
+ case "email":
69
+ return "test@example.com";
70
+ case "uri":
71
+ return "https://www.example.com/path/to/resource";
72
+ case "uri-reference":
73
+ return "/path/to/resource";
74
+ case "uuid":
75
+ return "00000000-0000-0000-0000-000000000000";
76
+ }
77
+ }
78
+
53
79
  if (schema.enum) {
54
80
  return schema.enum[0];
55
81
  }
56
82
 
83
+ if (schema.oneOf) {
84
+ const randomIndex = Math.floor(Math.random() * schema.oneOf.length);
85
+ return generateSchemaExample(schema.oneOf[randomIndex] as SchemaObject);
86
+ }
87
+
88
+ if (schema.anyOf) {
89
+ // Should likely be expanded to return a partial set of values, but it would require
90
+ // detection if being used within an array or a string type.
91
+ const randomIndex = Math.floor(Math.random() * schema.anyOf.length);
92
+ return generateSchemaExample(schema.anyOf[randomIndex] as SchemaObject);
93
+ }
94
+
95
+ if (schema.allOf) {
96
+ // https://swagger.io/docs/specification/v3_0/data-models/oneof-anyof-allof-not/#allof
97
+ return schema.allOf.reduce((acc, allOfSchema) => {
98
+ return { ...acc, ...generateSchemaExample(allOfSchema as SchemaObject) };
99
+ }, {});
100
+ }
101
+
57
102
  switch (schema.type) {
58
103
  case "string":
59
104
  return name || "string";
@@ -1,7 +1,21 @@
1
- import { redirect, type RouteObject } from "react-router";
1
+ import { useSuspenseQuery } from "@tanstack/react-query";
2
+ import {
3
+ generatePath,
4
+ Navigate,
5
+ redirect,
6
+ type RouteObject,
7
+ useLocation,
8
+ useParams,
9
+ } from "react-router";
2
10
  import { joinUrl } from "../../../util/joinUrl.js";
3
11
  import type { GraphQLClient } from "../client/GraphQLClient.js";
4
- import { type OpenApiPluginOptions, UNTAGGED_PATH } from "../index.js";
12
+ import { useCreateQuery } from "../client/useCreateQuery.js";
13
+ import { useOasConfig } from "../context.js";
14
+ import {
15
+ GetSidebarOperationsQuery,
16
+ type OpenApiPluginOptions,
17
+ UNTAGGED_PATH,
18
+ } from "../index.js";
5
19
  import type { OasPluginConfig } from "../interfaces.js";
6
20
 
7
21
  // Creates the main provider route that wraps operation routes.
@@ -47,6 +61,56 @@ const createRoute = ({
47
61
  },
48
62
  });
49
63
 
64
+ const NonTagPagesOperationList = ({
65
+ render,
66
+ path,
67
+ }: {
68
+ render: (tag: string) => React.ReactNode;
69
+ path: string;
70
+ }) => {
71
+ const { type, input } = useOasConfig();
72
+ const { tag: currentTag } = useParams();
73
+ const location = useLocation();
74
+ const query = useCreateQuery(GetSidebarOperationsQuery, { type, input });
75
+ const {
76
+ data: { schema },
77
+ } = useSuspenseQuery(query);
78
+
79
+ const firstTag = schema.tags.at(0);
80
+
81
+ if (!currentTag && firstTag?.slug) {
82
+ return (
83
+ <Navigate
84
+ to={{
85
+ pathname: generatePath(path, { tag: firstTag.slug }),
86
+ search: location.search,
87
+ }}
88
+ />
89
+ );
90
+ }
91
+
92
+ if (currentTag && schema.tags.some((t) => t.slug === currentTag)) {
93
+ return render(currentTag);
94
+ }
95
+
96
+ return null;
97
+ };
98
+
99
+ const createNonTagPagesRoute = ({ path }: { path: string }): RouteObject => ({
100
+ path,
101
+ async lazy() {
102
+ const { OperationList } = await import("../OperationList.js");
103
+ return {
104
+ element: (
105
+ <NonTagPagesOperationList
106
+ path={path}
107
+ render={(tag) => <OperationList tag={tag} />}
108
+ />
109
+ ),
110
+ };
111
+ },
112
+ });
113
+
50
114
  const createAdditionalRoutes = (basePath: string) => [
51
115
  // Category without tagged operations
52
116
  createRoute({
@@ -106,7 +170,7 @@ export const getRoutes = ({
106
170
  basePath,
107
171
  routePath: basePath,
108
172
  routes: [
109
- createRoute({ path: basePath + "/:tag?" }),
173
+ createNonTagPagesRoute({ path: basePath + "/:tag?" }),
110
174
  ...createAdditionalRoutes(basePath),
111
175
  ],
112
176
  client,
@@ -108,7 +108,7 @@ const SyntaxHighlightInner = ({
108
108
  {children}
109
109
  </pre>
110
110
  {props.showLanguageIndicator && (
111
- <span className="absolute top-1.5 right-3 text-[11px] font-mono text-muted-foreground transition group-hover:opacity-0">
111
+ <span className="absolute top-1.5 end-3 text-[11px] font-mono text-muted-foreground transition group-hover:opacity-0">
112
112
  {language}
113
113
  </span>
114
114
  )}
@@ -118,7 +118,7 @@ const SyntaxHighlightInner = ({
118
118
  aria-label="Copy code"
119
119
  title="Copy code"
120
120
  className={cn(
121
- "absolute top-2 right-2 p-2 hover:outline hover:outline-border/75 dark:hover:outline-border rounded-md text-sm text-muted-foreground transition",
121
+ "absolute top-2 end-2 p-2 hover:outline hover:outline-border/75 dark:hover:outline-border rounded-md text-sm text-muted-foreground transition",
122
122
  showCopy === "hover"
123
123
  ? "opacity-0 group-hover:opacity-100 group-hover:bg-zinc-100 group-hover:dark:bg-zinc-700"
124
124
  : "bg-zinc-100 dark:bg-zinc-700",
@@ -4,9 +4,10 @@ export type { RecordAny };
4
4
 
5
5
  export const traverse = <T extends JsonValue = RecordAny>(
6
6
  specification: RecordAny,
7
- transform: (specification: RecordAny) => T,
7
+ transform: (specification: RecordAny, path?: string[]) => T,
8
+ path: string[] = [],
8
9
  ) => {
9
- const transformed = transform(specification);
10
+ const transformed = transform(specification, path);
10
11
  if (typeof transformed !== "object" || transformed === null) {
11
12
  return transformed;
12
13
  }
@@ -14,14 +15,16 @@ export const traverse = <T extends JsonValue = RecordAny>(
14
15
  const result: RecordAny = Array.isArray(transformed) ? [] : {};
15
16
 
16
17
  for (const [key, value] of Object.entries(transformed)) {
18
+ const currentPath = [...path, key];
19
+
17
20
  if (Array.isArray(value)) {
18
- result[key] = value.map((item) =>
21
+ result[key] = value.map((item, index) =>
19
22
  typeof item === "object" && item != null
20
- ? traverse(item, transform)
23
+ ? traverse(item, transform, [...currentPath, index.toString()])
21
24
  : item,
22
25
  );
23
26
  } else if (typeof value === "object" && value != null) {
24
- result[key] = traverse(value, transform);
27
+ result[key] = traverse(value, transform, currentPath);
25
28
  } else {
26
29
  result[key] = value;
27
30
  }