blodemd 0.1.0 → 0.2.0

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 (289) hide show
  1. package/dist/cli.mjs +50 -174
  2. package/dist/cli.mjs.map +1 -1
  3. package/package.json +3 -36
  4. package/dev-server/app/[[...slug]]/page.tsx +0 -140
  5. package/dev-server/app/blodemd-dev/invalidate/route.ts +0 -12
  6. package/dev-server/app/blodemd-dev/static/[...path]/route.ts +0 -32
  7. package/dev-server/app/blodemd-dev/version/route.ts +0 -14
  8. package/dev-server/app/blodemd-internal/proxy/route.ts +0 -86
  9. package/dev-server/app/error.tsx +0 -24
  10. package/dev-server/app/favicon.ico +0 -0
  11. package/dev-server/app/globals.css +0 -4
  12. package/dev-server/app/layout.tsx +0 -38
  13. package/dev-server/app/not-found.tsx +0 -18
  14. package/dev-server/app/search/route.ts +0 -17
  15. package/dev-server/components/dev-reload-script.tsx +0 -86
  16. package/dev-server/components/providers.tsx +0 -15
  17. package/dev-server/lib/dev-state.ts +0 -8
  18. package/dev-server/lib/local-content-source.ts +0 -103
  19. package/dev-server/lib/local-runtime.tsx +0 -555
  20. package/dev-server/next-env.d.ts +0 -5
  21. package/dev-server/next.config.js +0 -54
  22. package/dev-server/package.json +0 -61
  23. package/dev-server/postcss.config.mjs +0 -7
  24. package/dev-server/public/glide-variable.woff2 +0 -0
  25. package/dev-server/tsconfig.json +0 -50
  26. package/docs/app/globals.css +0 -471
  27. package/docs/components/animate-ui/primitives/buttons/button.tsx +0 -14
  28. package/docs/components/api/api-playground.tsx +0 -467
  29. package/docs/components/api/api-reference.tsx +0 -157
  30. package/docs/components/content/collection-index.tsx +0 -114
  31. package/docs/components/docs/contextual-menu.tsx +0 -495
  32. package/docs/components/docs/copy-page-menu.tsx +0 -364
  33. package/docs/components/docs/doc-header.tsx +0 -223
  34. package/docs/components/docs/doc-shell.tsx +0 -355
  35. package/docs/components/docs/doc-sidebar.tsx +0 -256
  36. package/docs/components/docs/doc-toc.tsx +0 -46
  37. package/docs/components/docs/mobile-nav.tsx +0 -195
  38. package/docs/components/docs/sidebar-active-highlight.tsx +0 -34
  39. package/docs/components/docs/sidebar-scroll-area.tsx +0 -63
  40. package/docs/components/git/repo-picker.tsx +0 -529
  41. package/docs/components/icons/doc-icon.tsx +0 -96
  42. package/docs/components/mdx/accordion.tsx +0 -83
  43. package/docs/components/mdx/agent-instructions.tsx +0 -17
  44. package/docs/components/mdx/badge.tsx +0 -79
  45. package/docs/components/mdx/callout.tsx +0 -88
  46. package/docs/components/mdx/card.tsx +0 -110
  47. package/docs/components/mdx/code-block.tsx +0 -80
  48. package/docs/components/mdx/code-group.tsx +0 -203
  49. package/docs/components/mdx/color.tsx +0 -87
  50. package/docs/components/mdx/columns.tsx +0 -25
  51. package/docs/components/mdx/expandable.tsx +0 -45
  52. package/docs/components/mdx/field-layout.tsx +0 -77
  53. package/docs/components/mdx/frame.tsx +0 -23
  54. package/docs/components/mdx/get-text-content.ts +0 -18
  55. package/docs/components/mdx/icon.tsx +0 -12
  56. package/docs/components/mdx/iframe.tsx +0 -62
  57. package/docs/components/mdx/index.tsx +0 -121
  58. package/docs/components/mdx/installer.tsx +0 -20
  59. package/docs/components/mdx/panel.tsx +0 -11
  60. package/docs/components/mdx/param-field.tsx +0 -56
  61. package/docs/components/mdx/preview.tsx +0 -36
  62. package/docs/components/mdx/prompt.tsx +0 -63
  63. package/docs/components/mdx/request-example.tsx +0 -27
  64. package/docs/components/mdx/response-field.tsx +0 -42
  65. package/docs/components/mdx/steps.tsx +0 -92
  66. package/docs/components/mdx/tabs.tsx +0 -193
  67. package/docs/components/mdx/tile.tsx +0 -43
  68. package/docs/components/mdx/tooltip.tsx +0 -71
  69. package/docs/components/mdx/tree.tsx +0 -120
  70. package/docs/components/mdx/type-table.tsx +0 -71
  71. package/docs/components/mdx/update.tsx +0 -44
  72. package/docs/components/mdx/video.tsx +0 -45
  73. package/docs/components/mdx/view.tsx +0 -66
  74. package/docs/components/posthog-provider.tsx +0 -42
  75. package/docs/components/providers.tsx +0 -15
  76. package/docs/components/tenant-analytics.tsx +0 -49
  77. package/docs/components/third-parties.tsx +0 -32
  78. package/docs/components/ui/badge.tsx +0 -61
  79. package/docs/components/ui/breadcrumb.tsx +0 -112
  80. package/docs/components/ui/button-group.tsx +0 -83
  81. package/docs/components/ui/button.tsx +0 -65
  82. package/docs/components/ui/card.tsx +0 -92
  83. package/docs/components/ui/command.tsx +0 -167
  84. package/docs/components/ui/copy-button.tsx +0 -129
  85. package/docs/components/ui/dialog.tsx +0 -146
  86. package/docs/components/ui/field.tsx +0 -237
  87. package/docs/components/ui/input.tsx +0 -23
  88. package/docs/components/ui/kbd.tsx +0 -98
  89. package/docs/components/ui/label.tsx +0 -22
  90. package/docs/components/ui/morph-icon.tsx +0 -79
  91. package/docs/components/ui/popover.tsx +0 -267
  92. package/docs/components/ui/search-dialog.tsx +0 -431
  93. package/docs/components/ui/search.tsx +0 -101
  94. package/docs/components/ui/separator.tsx +0 -26
  95. package/docs/components/ui/sheet.tsx +0 -133
  96. package/docs/components/ui/sidebar.tsx +0 -758
  97. package/docs/components/ui/skeleton.tsx +0 -11
  98. package/docs/components/ui/switch.tsx +0 -32
  99. package/docs/components/ui/tabs.tsx +0 -138
  100. package/docs/components/ui/theme-toggle.tsx +0 -62
  101. package/docs/components/ui/tooltip.tsx +0 -53
  102. package/docs/components/web-mcp.tsx +0 -115
  103. package/docs/lib/agent-skills.ts +0 -48
  104. package/docs/lib/api-client.ts +0 -72
  105. package/docs/lib/config.ts +0 -6
  106. package/docs/lib/content-root.ts +0 -33
  107. package/docs/lib/content-source.ts +0 -70
  108. package/docs/lib/contextual-options.ts +0 -222
  109. package/docs/lib/dashboard-session.ts +0 -167
  110. package/docs/lib/db.ts +0 -13
  111. package/docs/lib/docs-collection.ts +0 -7
  112. package/docs/lib/docs-runtime.tsx +0 -745
  113. package/docs/lib/edge-config.ts +0 -95
  114. package/docs/lib/env.ts +0 -23
  115. package/docs/lib/etag.ts +0 -22
  116. package/docs/lib/github-install.ts +0 -33
  117. package/docs/lib/llms-full.ts +0 -82
  118. package/docs/lib/marketing-markdown.ts +0 -79
  119. package/docs/lib/marketing-site.ts +0 -31
  120. package/docs/lib/mdx.ts +0 -98
  121. package/docs/lib/navigation.ts +0 -288
  122. package/docs/lib/openapi-proxy.ts +0 -88
  123. package/docs/lib/openapi.ts +0 -158
  124. package/docs/lib/platform-config.ts +0 -6
  125. package/docs/lib/project-authz.ts +0 -46
  126. package/docs/lib/routes.ts +0 -103
  127. package/docs/lib/server-cache.ts +0 -83
  128. package/docs/lib/shiki.ts +0 -44
  129. package/docs/lib/supabase.ts +0 -37
  130. package/docs/lib/tenancy.ts +0 -364
  131. package/docs/lib/tenant-headers.ts +0 -43
  132. package/docs/lib/tenant-static.ts +0 -705
  133. package/docs/lib/tenant-utility-context.ts +0 -62
  134. package/docs/lib/tenants.ts +0 -72
  135. package/docs/lib/theme.ts +0 -29
  136. package/docs/lib/time-ago.ts +0 -24
  137. package/docs/lib/toc.ts +0 -2
  138. package/docs/lib/use-mobile.ts +0 -19
  139. package/docs/lib/use-tab-observer.ts +0 -71
  140. package/docs/lib/utils.ts +0 -5
  141. package/packages/@repo/common/dist/index.d.ts +0 -16
  142. package/packages/@repo/common/dist/index.d.ts.map +0 -1
  143. package/packages/@repo/common/dist/index.js +0 -84
  144. package/packages/@repo/common/package.json +0 -34
  145. package/packages/@repo/common/src/index.ts +0 -101
  146. package/packages/@repo/contracts/dist/analytics.d.ts +0 -21
  147. package/packages/@repo/contracts/dist/analytics.d.ts.map +0 -1
  148. package/packages/@repo/contracts/dist/analytics.js +0 -18
  149. package/packages/@repo/contracts/dist/api-key.d.ts +0 -27
  150. package/packages/@repo/contracts/dist/api-key.d.ts.map +0 -1
  151. package/packages/@repo/contracts/dist/api-key.js +0 -20
  152. package/packages/@repo/contracts/dist/dates.d.ts +0 -4
  153. package/packages/@repo/contracts/dist/dates.d.ts.map +0 -1
  154. package/packages/@repo/contracts/dist/dates.js +0 -2
  155. package/packages/@repo/contracts/dist/deployment.d.ts +0 -71
  156. package/packages/@repo/contracts/dist/deployment.d.ts.map +0 -1
  157. package/packages/@repo/contracts/dist/deployment.js +0 -46
  158. package/packages/@repo/contracts/dist/domain.d.ts +0 -94
  159. package/packages/@repo/contracts/dist/domain.d.ts.map +0 -1
  160. package/packages/@repo/contracts/dist/domain.js +0 -36
  161. package/packages/@repo/contracts/dist/git.d.ts +0 -28
  162. package/packages/@repo/contracts/dist/git.d.ts.map +0 -1
  163. package/packages/@repo/contracts/dist/git.js +0 -24
  164. package/packages/@repo/contracts/dist/ids.d.ts +0 -14
  165. package/packages/@repo/contracts/dist/ids.d.ts.map +0 -1
  166. package/packages/@repo/contracts/dist/ids.js +0 -11
  167. package/packages/@repo/contracts/dist/index.d.ts +0 -12
  168. package/packages/@repo/contracts/dist/index.d.ts.map +0 -1
  169. package/packages/@repo/contracts/dist/index.js +0 -13
  170. package/packages/@repo/contracts/dist/pagination.d.ts +0 -23
  171. package/packages/@repo/contracts/dist/pagination.d.ts.map +0 -1
  172. package/packages/@repo/contracts/dist/pagination.js +0 -15
  173. package/packages/@repo/contracts/dist/project.d.ts +0 -42
  174. package/packages/@repo/contracts/dist/project.d.ts.map +0 -1
  175. package/packages/@repo/contracts/dist/project.js +0 -25
  176. package/packages/@repo/contracts/dist/tenant.d.ts +0 -147
  177. package/packages/@repo/contracts/dist/tenant.d.ts.map +0 -1
  178. package/packages/@repo/contracts/dist/tenant.js +0 -58
  179. package/packages/@repo/contracts/dist/user.d.ts +0 -9
  180. package/packages/@repo/contracts/dist/user.d.ts.map +0 -1
  181. package/packages/@repo/contracts/dist/user.js +0 -9
  182. package/packages/@repo/contracts/package.json +0 -37
  183. package/packages/@repo/contracts/src/analytics.ts +0 -33
  184. package/packages/@repo/contracts/src/api-key.ts +0 -27
  185. package/packages/@repo/contracts/src/dates.ts +0 -4
  186. package/packages/@repo/contracts/src/deployment.ts +0 -73
  187. package/packages/@repo/contracts/src/domain.ts +0 -51
  188. package/packages/@repo/contracts/src/git.ts +0 -31
  189. package/packages/@repo/contracts/src/ids.ts +0 -23
  190. package/packages/@repo/contracts/src/index.ts +0 -13
  191. package/packages/@repo/contracts/src/pagination.ts +0 -21
  192. package/packages/@repo/contracts/src/project.ts +0 -32
  193. package/packages/@repo/contracts/src/tenant.ts +0 -94
  194. package/packages/@repo/contracts/src/user.ts +0 -12
  195. package/packages/@repo/models/dist/docs-config.d.ts +0 -961
  196. package/packages/@repo/models/dist/docs-config.d.ts.map +0 -1
  197. package/packages/@repo/models/dist/docs-config.js +0 -531
  198. package/packages/@repo/models/dist/index.d.ts +0 -3
  199. package/packages/@repo/models/dist/index.d.ts.map +0 -1
  200. package/packages/@repo/models/dist/index.js +0 -3
  201. package/packages/@repo/models/dist/tenant.d.ts +0 -37
  202. package/packages/@repo/models/dist/tenant.d.ts.map +0 -1
  203. package/packages/@repo/models/dist/tenant.js +0 -1
  204. package/packages/@repo/models/package.json +0 -37
  205. package/packages/@repo/models/src/docs-config.ts +0 -629
  206. package/packages/@repo/models/src/index.ts +0 -3
  207. package/packages/@repo/models/src/tenant.ts +0 -44
  208. package/packages/@repo/prebuild/dist/index.d.ts +0 -2
  209. package/packages/@repo/prebuild/dist/index.d.ts.map +0 -1
  210. package/packages/@repo/prebuild/dist/index.js +0 -2
  211. package/packages/@repo/prebuild/dist/openapi.d.ts +0 -43
  212. package/packages/@repo/prebuild/dist/openapi.d.ts.map +0 -1
  213. package/packages/@repo/prebuild/dist/openapi.js +0 -86
  214. package/packages/@repo/prebuild/package.json +0 -39
  215. package/packages/@repo/prebuild/src/index.ts +0 -2
  216. package/packages/@repo/prebuild/src/openapi.ts +0 -154
  217. package/packages/@repo/previewing/dist/blob-source.d.ts +0 -16
  218. package/packages/@repo/previewing/dist/blob-source.d.ts.map +0 -1
  219. package/packages/@repo/previewing/dist/blob-source.js +0 -128
  220. package/packages/@repo/previewing/dist/config-loader.d.ts +0 -134
  221. package/packages/@repo/previewing/dist/config-loader.d.ts.map +0 -1
  222. package/packages/@repo/previewing/dist/config-loader.js +0 -231
  223. package/packages/@repo/previewing/dist/constants.d.ts +0 -15
  224. package/packages/@repo/previewing/dist/constants.d.ts.map +0 -1
  225. package/packages/@repo/previewing/dist/constants.js +0 -14
  226. package/packages/@repo/previewing/dist/content-index.d.ts +0 -7
  227. package/packages/@repo/previewing/dist/content-index.d.ts.map +0 -1
  228. package/packages/@repo/previewing/dist/content-index.js +0 -291
  229. package/packages/@repo/previewing/dist/content-source.d.ts +0 -12
  230. package/packages/@repo/previewing/dist/content-source.d.ts.map +0 -1
  231. package/packages/@repo/previewing/dist/content-source.js +0 -1
  232. package/packages/@repo/previewing/dist/fs-source.d.ts +0 -11
  233. package/packages/@repo/previewing/dist/fs-source.d.ts.map +0 -1
  234. package/packages/@repo/previewing/dist/fs-source.js +0 -71
  235. package/packages/@repo/previewing/dist/index.d.ts +0 -16
  236. package/packages/@repo/previewing/dist/index.d.ts.map +0 -1
  237. package/packages/@repo/previewing/dist/index.js +0 -13
  238. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts +0 -3
  239. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts.map +0 -1
  240. package/packages/@repo/previewing/dist/markdown/agent-markdown.js +0 -176
  241. package/packages/@repo/previewing/dist/markdown/format.d.ts +0 -8
  242. package/packages/@repo/previewing/dist/markdown/format.d.ts.map +0 -1
  243. package/packages/@repo/previewing/dist/markdown/format.js +0 -43
  244. package/packages/@repo/previewing/dist/markdown/links.d.ts +0 -3
  245. package/packages/@repo/previewing/dist/markdown/links.d.ts.map +0 -1
  246. package/packages/@repo/previewing/dist/markdown/links.js +0 -31
  247. package/packages/@repo/previewing/dist/openapi-pages.d.ts +0 -7
  248. package/packages/@repo/previewing/dist/openapi-pages.d.ts.map +0 -1
  249. package/packages/@repo/previewing/dist/openapi-pages.js +0 -200
  250. package/packages/@repo/previewing/dist/search-index.d.ts +0 -4
  251. package/packages/@repo/previewing/dist/search-index.d.ts.map +0 -1
  252. package/packages/@repo/previewing/dist/search-index.js +0 -23
  253. package/packages/@repo/previewing/dist/serialization.d.ts +0 -13
  254. package/packages/@repo/previewing/dist/serialization.d.ts.map +0 -1
  255. package/packages/@repo/previewing/dist/serialization.js +0 -108
  256. package/packages/@repo/previewing/dist/toc-index.d.ts +0 -5
  257. package/packages/@repo/previewing/dist/toc-index.d.ts.map +0 -1
  258. package/packages/@repo/previewing/dist/toc-index.js +0 -53
  259. package/packages/@repo/previewing/dist/types.d.ts +0 -92
  260. package/packages/@repo/previewing/dist/types.d.ts.map +0 -1
  261. package/packages/@repo/previewing/dist/types.js +0 -1
  262. package/packages/@repo/previewing/dist/utility-index.d.ts +0 -7
  263. package/packages/@repo/previewing/dist/utility-index.d.ts.map +0 -1
  264. package/packages/@repo/previewing/dist/utility-index.js +0 -201
  265. package/packages/@repo/previewing/package.json +0 -41
  266. package/packages/@repo/previewing/src/blob-source.ts +0 -185
  267. package/packages/@repo/previewing/src/config-loader.ts +0 -316
  268. package/packages/@repo/previewing/src/constants.ts +0 -16
  269. package/packages/@repo/previewing/src/content-index.ts +0 -384
  270. package/packages/@repo/previewing/src/content-source.ts +0 -12
  271. package/packages/@repo/previewing/src/fs-source.ts +0 -103
  272. package/packages/@repo/previewing/src/index.ts +0 -71
  273. package/packages/@repo/previewing/src/markdown/agent-markdown.ts +0 -254
  274. package/packages/@repo/previewing/src/markdown/format.ts +0 -63
  275. package/packages/@repo/previewing/src/markdown/links.ts +0 -46
  276. package/packages/@repo/previewing/src/openapi-pages.ts +0 -319
  277. package/packages/@repo/previewing/src/search-index.ts +0 -38
  278. package/packages/@repo/previewing/src/serialization.ts +0 -191
  279. package/packages/@repo/previewing/src/toc-index.ts +0 -72
  280. package/packages/@repo/previewing/src/types.ts +0 -105
  281. package/packages/@repo/previewing/src/utility-index.ts +0 -304
  282. package/packages/@repo/validation/dist/index.d.ts +0 -12
  283. package/packages/@repo/validation/dist/index.d.ts.map +0 -1
  284. package/packages/@repo/validation/dist/index.js +0 -30
  285. package/packages/@repo/validation/package.json +0 -38
  286. package/packages/@repo/validation/src/blodemd-docs-schema.json +0 -3575
  287. package/packages/@repo/validation/src/index.ts +0 -59
  288. package/scripts/prepare-package.mjs +0 -53
  289. package/scripts/repo-packages.mjs +0 -8
@@ -1,467 +0,0 @@
1
- "use client";
2
-
3
- import { useCallback, useMemo, useReducer } from "react";
4
- import type { ChangeEvent } from "react";
5
-
6
- import { Button } from "@/components/ui/button";
7
- import { Field, FieldLabel } from "@/components/ui/field";
8
- import { Input } from "@/components/ui/input";
9
- import type { OpenApiEntry } from "@/lib/openapi";
10
-
11
- interface OperationParameter {
12
- description?: string;
13
- name?: string;
14
- required?: boolean;
15
- }
16
-
17
- const extractParams = (entry: OpenApiEntry, location: "path" | "query") =>
18
- (entry.operation.parameters ?? []).filter(
19
- (param) => (param as { in?: string }).in === location
20
- ) as OperationParameter[];
21
-
22
- interface PlaygroundState {
23
- authToken: string;
24
- body: string;
25
- isLoading: boolean;
26
- pathValues: Record<string, string>;
27
- queryValues: Record<string, string>;
28
- response: string | null;
29
- serverIndex: number;
30
- status: number | null;
31
- useProxyPreference: boolean;
32
- }
33
-
34
- type PlaygroundAction =
35
- | { type: "requestError"; response: string }
36
- | { type: "requestStart" }
37
- | { type: "requestSuccess"; response: string; status: number }
38
- | { type: "setAuthToken"; value: string }
39
- | { type: "setBody"; value: string }
40
- | { type: "setPathValue"; name: string; value: string }
41
- | { type: "setQueryValue"; name: string; value: string }
42
- | { type: "setServerIndex"; value: number }
43
- | { type: "setUseProxyPreference"; value: boolean };
44
-
45
- const initialPlaygroundState: PlaygroundState = {
46
- authToken: "",
47
- body: "{}",
48
- isLoading: false,
49
- pathValues: {},
50
- queryValues: {},
51
- response: null,
52
- serverIndex: 0,
53
- status: null,
54
- useProxyPreference: true,
55
- };
56
-
57
- const playgroundReducer = (
58
- state: PlaygroundState,
59
- action: PlaygroundAction
60
- ) => {
61
- switch (action.type) {
62
- case "requestError": {
63
- return {
64
- ...state,
65
- isLoading: false,
66
- response: action.response,
67
- status: 0,
68
- };
69
- }
70
- case "requestStart": {
71
- return {
72
- ...state,
73
- isLoading: true,
74
- response: null,
75
- status: null,
76
- };
77
- }
78
- case "requestSuccess": {
79
- return {
80
- ...state,
81
- isLoading: false,
82
- response: action.response,
83
- status: action.status,
84
- };
85
- }
86
- case "setAuthToken": {
87
- return {
88
- ...state,
89
- authToken: action.value,
90
- };
91
- }
92
- case "setBody": {
93
- return {
94
- ...state,
95
- body: action.value,
96
- };
97
- }
98
- case "setPathValue": {
99
- return {
100
- ...state,
101
- pathValues: {
102
- ...state.pathValues,
103
- [action.name]: action.value,
104
- },
105
- };
106
- }
107
- case "setQueryValue": {
108
- return {
109
- ...state,
110
- queryValues: {
111
- ...state.queryValues,
112
- [action.name]: action.value,
113
- },
114
- };
115
- }
116
- case "setServerIndex": {
117
- return {
118
- ...state,
119
- serverIndex: action.value,
120
- };
121
- }
122
- case "setUseProxyPreference": {
123
- return {
124
- ...state,
125
- useProxyPreference: action.value,
126
- };
127
- }
128
- default: {
129
- return state;
130
- }
131
- }
132
- };
133
-
134
- const ParameterFieldGrid = ({
135
- idPrefix,
136
- onChange,
137
- parameters,
138
- values,
139
- }: {
140
- idPrefix: "path" | "query";
141
- onChange: (event: ChangeEvent<HTMLInputElement>) => void;
142
- parameters: OperationParameter[];
143
- values: Record<string, string>;
144
- }) => {
145
- if (!parameters.length) {
146
- return null;
147
- }
148
-
149
- return (
150
- <div className="grid gap-2.5 grid-cols-[repeat(auto-fit,minmax(180px,1fr))]">
151
- {parameters.map((param) => (
152
- <Field key={param.name}>
153
- <FieldLabel htmlFor={`${idPrefix}-${param.name}`}>
154
- {param.name}
155
- </FieldLabel>
156
- <Input
157
- id={`${idPrefix}-${param.name}`}
158
- name={param.name ?? ""}
159
- onChange={onChange}
160
- placeholder={param.required ? "Required" : "Optional"}
161
- type="text"
162
- value={values[param.name ?? ""] ?? ""}
163
- />
164
- </Field>
165
- ))}
166
- </div>
167
- );
168
- };
169
-
170
- const ResponsePanel = ({
171
- response,
172
- status,
173
- }: {
174
- response: string | null;
175
- status: number | null;
176
- }) => {
177
- if (response === null) {
178
- return null;
179
- }
180
-
181
- return (
182
- <div className="rounded-xl border border-border bg-primary/[0.08] p-3">
183
- <div className="font-semibold">Status: {status}</div>
184
- <pre className="mt-2 overflow-x-auto">{response}</pre>
185
- </div>
186
- );
187
- };
188
-
189
- export const ApiPlayground = ({
190
- entry,
191
- proxyEnabled,
192
- proxyPath = "/_internal/proxy",
193
- tenantSlug,
194
- }: {
195
- entry: OpenApiEntry;
196
- proxyEnabled: boolean;
197
- proxyPath?: string;
198
- tenantSlug?: string;
199
- }) => {
200
- const servers = entry.spec.servers ?? [];
201
- const [state, dispatch] = useReducer(
202
- playgroundReducer,
203
- initialPlaygroundState
204
- );
205
- const {
206
- authToken,
207
- body,
208
- isLoading,
209
- pathValues,
210
- queryValues,
211
- response,
212
- serverIndex,
213
- status,
214
- } = state;
215
- const useProxy = proxyEnabled && state.useProxyPreference;
216
-
217
- const pathParams = useMemo(() => extractParams(entry, "path"), [entry]);
218
- const queryParams = useMemo(() => extractParams(entry, "query"), [entry]);
219
-
220
- const baseUrl = servers[serverIndex]?.url ?? "";
221
- const canSend = Boolean(baseUrl);
222
-
223
- const buildUrl = useCallback(() => {
224
- let { path } = entry.operation;
225
- for (const param of pathParams) {
226
- const key = param.name ?? "";
227
- const value = pathValues[key] ?? "";
228
- path = path.replace(`{${key}}`, encodeURIComponent(value));
229
- }
230
-
231
- const url = new URL(path, baseUrl || "http://localhost");
232
- for (const param of queryParams) {
233
- const key = param.name ?? "";
234
- const value = queryValues[key];
235
- if (value) {
236
- url.searchParams.set(key, value);
237
- }
238
- }
239
-
240
- return url.toString();
241
- }, [
242
- baseUrl,
243
- entry.operation,
244
- pathParams,
245
- pathValues,
246
- queryParams,
247
- queryValues,
248
- ]);
249
-
250
- const handleUseProxyChange = useCallback(
251
- (event: ChangeEvent<HTMLInputElement>) => {
252
- dispatch({
253
- type: "setUseProxyPreference",
254
- value: event.target.checked,
255
- });
256
- },
257
- []
258
- );
259
- const handleServerChange = useCallback(
260
- (event: ChangeEvent<HTMLSelectElement>) => {
261
- dispatch({
262
- type: "setServerIndex",
263
- value: Number(event.target.value),
264
- });
265
- },
266
- []
267
- );
268
- const handlePathValueChange = useCallback(
269
- (event: ChangeEvent<HTMLInputElement>) => {
270
- dispatch({
271
- name: event.target.name,
272
- type: "setPathValue",
273
- value: event.target.value,
274
- });
275
- },
276
- []
277
- );
278
- const handleQueryValueChange = useCallback(
279
- (event: ChangeEvent<HTMLInputElement>) => {
280
- dispatch({
281
- name: event.target.name,
282
- type: "setQueryValue",
283
- value: event.target.value,
284
- });
285
- },
286
- []
287
- );
288
- const handleAuthTokenChange = useCallback(
289
- (event: ChangeEvent<HTMLInputElement>) => {
290
- dispatch({
291
- type: "setAuthToken",
292
- value: event.target.value,
293
- });
294
- },
295
- []
296
- );
297
- const handleBodyChange = useCallback(
298
- (event: ChangeEvent<HTMLTextAreaElement>) => {
299
- dispatch({
300
- type: "setBody",
301
- value: event.target.value,
302
- });
303
- },
304
- []
305
- );
306
-
307
- const handleSend = useCallback(async () => {
308
- const url = buildUrl();
309
- dispatch({ type: "requestStart" });
310
-
311
- try {
312
- const { method } = entry.operation;
313
- const requestHeaders = {
314
- "Content-Type": "application/json",
315
- ...(authToken ? { Authorization: `Bearer ${authToken}` } : {}),
316
- };
317
-
318
- const payload = {
319
- body,
320
- headers: requestHeaders,
321
- method,
322
- url,
323
- ...(tenantSlug ? { tenantSlug } : {}),
324
- };
325
-
326
- const requestUrl = useProxy ? proxyPath : url;
327
- const requestMethod = useProxy ? "POST" : method;
328
- const requestHeadersToSend = useProxy
329
- ? { "Content-Type": "application/json" }
330
- : requestHeaders;
331
-
332
- let requestBody: string | undefined;
333
- if (useProxy) {
334
- requestBody = JSON.stringify(payload);
335
- } else if (method === "GET") {
336
- requestBody = undefined;
337
- } else {
338
- requestBody = body;
339
- }
340
-
341
- const res = await fetch(requestUrl, {
342
- body: requestBody,
343
- headers: requestHeadersToSend,
344
- method: requestMethod,
345
- });
346
-
347
- const text = await res.text();
348
- let formatted = text;
349
- try {
350
- formatted = JSON.stringify(JSON.parse(text), null, 2);
351
- } catch {
352
- formatted = text;
353
- }
354
- dispatch({
355
- response: formatted || "(empty response)",
356
- status: res.status,
357
- type: "requestSuccess",
358
- });
359
- } catch (error) {
360
- dispatch({
361
- response: error instanceof Error ? error.message : "Request failed.",
362
- type: "requestError",
363
- });
364
- }
365
- }, [
366
- authToken,
367
- body,
368
- buildUrl,
369
- entry.operation,
370
- proxyPath,
371
- tenantSlug,
372
- useProxy,
373
- ]);
374
-
375
- return (
376
- <section className="mt-7 grid gap-3">
377
- <div className="grid gap-3 rounded-xl border border-border bg-surface p-4">
378
- <div className="flex items-center justify-between">
379
- <h2>Try it out</h2>
380
- {proxyEnabled ? (
381
- <label className="flex items-center gap-2 text-sm">
382
- <input
383
- checked={useProxy}
384
- className="accent-primary"
385
- onChange={handleUseProxyChange}
386
- type="checkbox"
387
- />
388
- Use docs proxy
389
- </label>
390
- ) : null}
391
- </div>
392
-
393
- {servers.length ? (
394
- <Field>
395
- <FieldLabel htmlFor="api-server">Server</FieldLabel>
396
- <select
397
- className="flex h-[var(--field-height)] w-full rounded-[var(--field-radius)] border border-input bg-card px-[var(--field-padding-x)] py-[var(--field-padding-y)] font-sans text-base text-foreground transition-colors hover:border-input-hover focus:border-ring focus:outline-hidden focus:ring-2 focus:ring-ring/15 focus:ring-offset-1 focus:ring-offset-background"
398
- id="api-server"
399
- onChange={handleServerChange}
400
- value={serverIndex}
401
- >
402
- {servers.map((server, index) => (
403
- <option key={server.url} value={index}>
404
- {server.url}
405
- </option>
406
- ))}
407
- </select>
408
- </Field>
409
- ) : null}
410
-
411
- <ParameterFieldGrid
412
- idPrefix="path"
413
- onChange={handlePathValueChange}
414
- parameters={pathParams}
415
- values={pathValues}
416
- />
417
-
418
- <ParameterFieldGrid
419
- idPrefix="query"
420
- onChange={handleQueryValueChange}
421
- parameters={queryParams}
422
- values={queryValues}
423
- />
424
-
425
- <Field>
426
- <FieldLabel htmlFor="auth-token">Auth token</FieldLabel>
427
- <Input
428
- id="auth-token"
429
- onChange={handleAuthTokenChange}
430
- placeholder="Bearer token"
431
- type="password"
432
- value={authToken}
433
- />
434
- </Field>
435
-
436
- {entry.operation.method === "GET" ? null : (
437
- <Field>
438
- <FieldLabel htmlFor="request-body">Request body</FieldLabel>
439
- <textarea
440
- className="flex w-full rounded-[var(--field-radius)] border border-input bg-card px-[var(--field-padding-x)] py-[var(--field-padding-y)] font-sans text-base text-foreground transition-colors placeholder:text-placeholder-foreground hover:border-input-hover focus:border-ring focus:outline-hidden focus:ring-2 focus:ring-ring/15 focus:ring-offset-1 focus:ring-offset-background"
441
- id="request-body"
442
- onChange={handleBodyChange}
443
- rows={6}
444
- value={body}
445
- />
446
- </Field>
447
- )}
448
-
449
- <Button
450
- className="w-full"
451
- disabled={isLoading || !canSend}
452
- onClick={handleSend}
453
- type="button"
454
- >
455
- {isLoading ? "Sending..." : "Send request"}
456
- </Button>
457
- {canSend ? null : (
458
- <p className="text-sm text-muted-foreground">
459
- Add a server URL in your OpenAPI spec to enable requests.
460
- </p>
461
- )}
462
-
463
- <ResponsePanel response={response} status={status} />
464
- </div>
465
- </section>
466
- );
467
- };
@@ -1,157 +0,0 @@
1
- import dynamic from "next/dynamic";
2
-
3
- import type { OpenApiEntry } from "@/lib/openapi";
4
- import { cn } from "@/lib/utils";
5
-
6
- const ApiPlayground = dynamic(async () => {
7
- const apiModule = await import("@/components/api/api-playground");
8
- return { default: apiModule.ApiPlayground };
9
- });
10
-
11
- const methodColors: Record<string, string> = {
12
- delete: "bg-red-500",
13
- get: "bg-blue-500",
14
- patch: "bg-amber-500",
15
- post: "bg-green-500",
16
- put: "bg-orange-500",
17
- };
18
-
19
- export const ApiReference = ({
20
- entry,
21
- proxyEnabled,
22
- proxyPath,
23
- tenantSlug,
24
- }: {
25
- entry: OpenApiEntry;
26
- proxyEnabled: boolean;
27
- proxyPath?: string;
28
- tenantSlug?: string;
29
- }) => {
30
- const { operation } = entry;
31
- const parameters = operation.parameters ?? [];
32
- const requestBody = operation.requestBody as
33
- | { content?: Record<string, { schema?: unknown }> }
34
- | undefined;
35
- const responses = operation.responses ?? {};
36
-
37
- return (
38
- <div>
39
- <header className="mb-4 flex items-center gap-4">
40
- <div
41
- className={cn(
42
- "rounded-full px-2.5 py-1.5 text-xs font-semibold uppercase text-white",
43
- methodColors[operation.method.toLowerCase()] ?? "bg-primary"
44
- )}
45
- >
46
- {operation.method}
47
- </div>
48
- <div className="font-mono">{operation.path}</div>
49
- </header>
50
- {operation.summary ? (
51
- <p className="font-semibold">{operation.summary}</p>
52
- ) : null}
53
- {operation.description ? (
54
- <p className="text-muted-foreground">{operation.description}</p>
55
- ) : null}
56
-
57
- {parameters.length ? (
58
- <section className="mt-7 grid gap-3">
59
- <h2>Parameters</h2>
60
- <div className="grid gap-2">
61
- <div className="grid grid-cols-[120px_80px_80px_1fr] gap-3 rounded-lg border border-border bg-background/60 p-2.5 font-bold">
62
- <span>Name</span>
63
- <span>In</span>
64
- <span>Required</span>
65
- <span>Description</span>
66
- </div>
67
- {parameters.map((param) => {
68
- const name = (param as { name?: string }).name ?? "";
69
- const location = (param as { in?: string }).in ?? "";
70
- const required = (param as { required?: boolean }).required
71
- ? "Yes"
72
- : "No";
73
- const description =
74
- (param as { description?: string }).description ?? "";
75
-
76
- return (
77
- <div
78
- className="grid grid-cols-[120px_80px_80px_1fr] gap-3 rounded-lg border border-border bg-background/60 p-2.5"
79
- key={name}
80
- >
81
- <span>{name}</span>
82
- <span>{location}</span>
83
- <span>{required}</span>
84
- <span>{description}</span>
85
- </div>
86
- );
87
- })}
88
- </div>
89
- </section>
90
- ) : null}
91
-
92
- {requestBody?.content ? (
93
- <section className="mt-7 grid gap-3">
94
- <h2>Request Body</h2>
95
- <div className="grid gap-2">
96
- {Object.entries(requestBody.content).map(([mediaType, value]) => {
97
- const { schema } = value as { schema?: unknown };
98
- const ref =
99
- schema &&
100
- typeof schema === "object" &&
101
- "$ref" in schema &&
102
- typeof (schema as { $ref?: unknown }).$ref === "string"
103
- ? ((schema as { $ref: string }).$ref.split("/").pop() ??
104
- "object")
105
- : null;
106
- const type =
107
- schema &&
108
- typeof schema === "object" &&
109
- "type" in schema &&
110
- typeof (schema as { type?: unknown }).type === "string"
111
- ? (schema as { type: string }).type
112
- : "object";
113
- return (
114
- <div
115
- className="flex justify-between rounded-lg border border-border bg-background/60 p-2.5"
116
- key={mediaType}
117
- >
118
- <span className="font-mono">{mediaType}</span>
119
- <span className="text-muted-foreground">{ref ?? type}</span>
120
- </div>
121
- );
122
- })}
123
- </div>
124
- </section>
125
- ) : null}
126
-
127
- {Object.keys(responses).length ? (
128
- <section className="mt-7 grid gap-3">
129
- <h2>Responses</h2>
130
- <div className="grid gap-2">
131
- {Object.entries(responses).map(([status, response]) => {
132
- const description =
133
- (response as { description?: string }).description ?? "";
134
- return (
135
- <div
136
- className="flex justify-between rounded-lg border border-border bg-background/60 p-2.5"
137
- key={status}
138
- >
139
- <span className="font-semibold">{status}</span>
140
- <span className="text-muted-foreground">{description}</span>
141
- </div>
142
- );
143
- })}
144
- </div>
145
- </section>
146
- ) : null}
147
-
148
- <ApiPlayground
149
- entry={entry}
150
- key={`${entry.identifier}:${operation.method}:${operation.path}`}
151
- proxyEnabled={proxyEnabled}
152
- proxyPath={proxyPath}
153
- tenantSlug={tenantSlug}
154
- />
155
- </div>
156
- );
157
- };