blodemd 0.0.15 → 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 (286) hide show
  1. package/README.md +26 -1
  2. package/dist/cli.mjs +217 -217
  3. package/dist/cli.mjs.map +1 -1
  4. package/package.json +3 -36
  5. package/dev-server/app/[[...slug]]/page.tsx +0 -140
  6. package/dev-server/app/blodemd-dev/invalidate/route.ts +0 -12
  7. package/dev-server/app/blodemd-dev/static/[...path]/route.ts +0 -32
  8. package/dev-server/app/blodemd-dev/version/route.ts +0 -14
  9. package/dev-server/app/blodemd-internal/proxy/route.ts +0 -86
  10. package/dev-server/app/error.tsx +0 -24
  11. package/dev-server/app/favicon.ico +0 -0
  12. package/dev-server/app/globals.css +0 -4
  13. package/dev-server/app/layout.tsx +0 -38
  14. package/dev-server/app/not-found.tsx +0 -18
  15. package/dev-server/app/search/route.ts +0 -17
  16. package/dev-server/components/dev-reload-script.tsx +0 -86
  17. package/dev-server/components/providers.tsx +0 -15
  18. package/dev-server/lib/dev-state.ts +0 -8
  19. package/dev-server/lib/local-content-source.ts +0 -103
  20. package/dev-server/lib/local-runtime.tsx +0 -555
  21. package/dev-server/next-env.d.ts +0 -5
  22. package/dev-server/next.config.js +0 -54
  23. package/dev-server/package.json +0 -61
  24. package/dev-server/postcss.config.mjs +0 -7
  25. package/dev-server/public/glide-variable.woff2 +0 -0
  26. package/dev-server/tsconfig.json +0 -50
  27. package/docs/app/globals.css +0 -471
  28. package/docs/components/animate-ui/primitives/buttons/button.tsx +0 -14
  29. package/docs/components/api/api-playground.tsx +0 -467
  30. package/docs/components/api/api-reference.tsx +0 -157
  31. package/docs/components/content/collection-index.tsx +0 -114
  32. package/docs/components/docs/contextual-menu.tsx +0 -495
  33. package/docs/components/docs/copy-page-menu.tsx +0 -364
  34. package/docs/components/docs/doc-header.tsx +0 -223
  35. package/docs/components/docs/doc-shell.tsx +0 -355
  36. package/docs/components/docs/doc-sidebar.tsx +0 -256
  37. package/docs/components/docs/doc-toc.tsx +0 -46
  38. package/docs/components/docs/mobile-nav.tsx +0 -195
  39. package/docs/components/docs/sidebar-active-highlight.tsx +0 -34
  40. package/docs/components/docs/sidebar-scroll-area.tsx +0 -63
  41. package/docs/components/git/repo-picker.tsx +0 -529
  42. package/docs/components/icons/doc-icon.tsx +0 -96
  43. package/docs/components/mdx/accordion.tsx +0 -83
  44. package/docs/components/mdx/agent-instructions.tsx +0 -17
  45. package/docs/components/mdx/badge.tsx +0 -79
  46. package/docs/components/mdx/callout.tsx +0 -88
  47. package/docs/components/mdx/card.tsx +0 -110
  48. package/docs/components/mdx/code-block.tsx +0 -80
  49. package/docs/components/mdx/code-group.tsx +0 -203
  50. package/docs/components/mdx/color.tsx +0 -87
  51. package/docs/components/mdx/columns.tsx +0 -25
  52. package/docs/components/mdx/expandable.tsx +0 -45
  53. package/docs/components/mdx/field-layout.tsx +0 -77
  54. package/docs/components/mdx/frame.tsx +0 -23
  55. package/docs/components/mdx/get-text-content.ts +0 -18
  56. package/docs/components/mdx/icon.tsx +0 -12
  57. package/docs/components/mdx/iframe.tsx +0 -62
  58. package/docs/components/mdx/index.tsx +0 -121
  59. package/docs/components/mdx/installer.tsx +0 -20
  60. package/docs/components/mdx/panel.tsx +0 -11
  61. package/docs/components/mdx/param-field.tsx +0 -56
  62. package/docs/components/mdx/preview.tsx +0 -36
  63. package/docs/components/mdx/prompt.tsx +0 -63
  64. package/docs/components/mdx/request-example.tsx +0 -27
  65. package/docs/components/mdx/response-field.tsx +0 -42
  66. package/docs/components/mdx/steps.tsx +0 -92
  67. package/docs/components/mdx/tabs.tsx +0 -193
  68. package/docs/components/mdx/tile.tsx +0 -43
  69. package/docs/components/mdx/tooltip.tsx +0 -71
  70. package/docs/components/mdx/tree.tsx +0 -120
  71. package/docs/components/mdx/type-table.tsx +0 -71
  72. package/docs/components/mdx/update.tsx +0 -44
  73. package/docs/components/mdx/video.tsx +0 -45
  74. package/docs/components/mdx/view.tsx +0 -66
  75. package/docs/components/posthog-provider.tsx +0 -42
  76. package/docs/components/providers.tsx +0 -15
  77. package/docs/components/tenant-analytics.tsx +0 -49
  78. package/docs/components/third-parties.tsx +0 -32
  79. package/docs/components/ui/badge.tsx +0 -61
  80. package/docs/components/ui/breadcrumb.tsx +0 -112
  81. package/docs/components/ui/button-group.tsx +0 -83
  82. package/docs/components/ui/button.tsx +0 -65
  83. package/docs/components/ui/card.tsx +0 -92
  84. package/docs/components/ui/command.tsx +0 -167
  85. package/docs/components/ui/copy-button.tsx +0 -129
  86. package/docs/components/ui/dialog.tsx +0 -146
  87. package/docs/components/ui/field.tsx +0 -237
  88. package/docs/components/ui/input.tsx +0 -23
  89. package/docs/components/ui/kbd.tsx +0 -98
  90. package/docs/components/ui/label.tsx +0 -22
  91. package/docs/components/ui/morph-icon.tsx +0 -79
  92. package/docs/components/ui/popover.tsx +0 -267
  93. package/docs/components/ui/search-dialog.tsx +0 -431
  94. package/docs/components/ui/search.tsx +0 -101
  95. package/docs/components/ui/separator.tsx +0 -26
  96. package/docs/components/ui/sheet.tsx +0 -133
  97. package/docs/components/ui/sidebar.tsx +0 -758
  98. package/docs/components/ui/skeleton.tsx +0 -11
  99. package/docs/components/ui/switch.tsx +0 -32
  100. package/docs/components/ui/tabs.tsx +0 -138
  101. package/docs/components/ui/theme-toggle.tsx +0 -62
  102. package/docs/components/ui/tooltip.tsx +0 -53
  103. package/docs/components/web-mcp.tsx +0 -115
  104. package/docs/lib/agent-skills.ts +0 -48
  105. package/docs/lib/api-client.ts +0 -72
  106. package/docs/lib/config.ts +0 -6
  107. package/docs/lib/content-root.ts +0 -33
  108. package/docs/lib/content-source.ts +0 -70
  109. package/docs/lib/contextual-options.ts +0 -222
  110. package/docs/lib/dashboard-session.ts +0 -167
  111. package/docs/lib/db.ts +0 -13
  112. package/docs/lib/docs-collection.ts +0 -7
  113. package/docs/lib/docs-runtime.tsx +0 -745
  114. package/docs/lib/edge-config.ts +0 -95
  115. package/docs/lib/env.ts +0 -23
  116. package/docs/lib/etag.ts +0 -22
  117. package/docs/lib/github-install.ts +0 -33
  118. package/docs/lib/llms-full.ts +0 -82
  119. package/docs/lib/marketing-markdown.ts +0 -79
  120. package/docs/lib/marketing-site.ts +0 -31
  121. package/docs/lib/mdx.ts +0 -98
  122. package/docs/lib/navigation.ts +0 -288
  123. package/docs/lib/openapi-proxy.ts +0 -88
  124. package/docs/lib/openapi.ts +0 -158
  125. package/docs/lib/platform-config.ts +0 -6
  126. package/docs/lib/project-authz.ts +0 -46
  127. package/docs/lib/routes.ts +0 -103
  128. package/docs/lib/server-cache.ts +0 -83
  129. package/docs/lib/shiki.ts +0 -44
  130. package/docs/lib/supabase.ts +0 -37
  131. package/docs/lib/tenancy.ts +0 -364
  132. package/docs/lib/tenant-headers.ts +0 -43
  133. package/docs/lib/tenant-static.ts +0 -705
  134. package/docs/lib/tenant-utility-context.ts +0 -62
  135. package/docs/lib/tenants.ts +0 -72
  136. package/docs/lib/theme.ts +0 -29
  137. package/docs/lib/time-ago.ts +0 -24
  138. package/docs/lib/toc.ts +0 -2
  139. package/docs/lib/use-mobile.ts +0 -19
  140. package/docs/lib/use-tab-observer.ts +0 -71
  141. package/docs/lib/utils.ts +0 -5
  142. package/packages/@repo/common/dist/index.d.ts +0 -16
  143. package/packages/@repo/common/dist/index.d.ts.map +0 -1
  144. package/packages/@repo/common/dist/index.js +0 -84
  145. package/packages/@repo/common/package.json +0 -34
  146. package/packages/@repo/common/src/index.ts +0 -101
  147. package/packages/@repo/contracts/dist/analytics.d.ts +0 -21
  148. package/packages/@repo/contracts/dist/analytics.d.ts.map +0 -1
  149. package/packages/@repo/contracts/dist/analytics.js +0 -18
  150. package/packages/@repo/contracts/dist/dates.d.ts +0 -4
  151. package/packages/@repo/contracts/dist/dates.d.ts.map +0 -1
  152. package/packages/@repo/contracts/dist/dates.js +0 -2
  153. package/packages/@repo/contracts/dist/deployment.d.ts +0 -71
  154. package/packages/@repo/contracts/dist/deployment.d.ts.map +0 -1
  155. package/packages/@repo/contracts/dist/deployment.js +0 -46
  156. package/packages/@repo/contracts/dist/domain.d.ts +0 -94
  157. package/packages/@repo/contracts/dist/domain.d.ts.map +0 -1
  158. package/packages/@repo/contracts/dist/domain.js +0 -36
  159. package/packages/@repo/contracts/dist/git.d.ts +0 -28
  160. package/packages/@repo/contracts/dist/git.d.ts.map +0 -1
  161. package/packages/@repo/contracts/dist/git.js +0 -24
  162. package/packages/@repo/contracts/dist/ids.d.ts +0 -14
  163. package/packages/@repo/contracts/dist/ids.d.ts.map +0 -1
  164. package/packages/@repo/contracts/dist/ids.js +0 -11
  165. package/packages/@repo/contracts/dist/index.d.ts +0 -11
  166. package/packages/@repo/contracts/dist/index.d.ts.map +0 -1
  167. package/packages/@repo/contracts/dist/index.js +0 -12
  168. package/packages/@repo/contracts/dist/pagination.d.ts +0 -23
  169. package/packages/@repo/contracts/dist/pagination.d.ts.map +0 -1
  170. package/packages/@repo/contracts/dist/pagination.js +0 -15
  171. package/packages/@repo/contracts/dist/project.d.ts +0 -42
  172. package/packages/@repo/contracts/dist/project.d.ts.map +0 -1
  173. package/packages/@repo/contracts/dist/project.js +0 -25
  174. package/packages/@repo/contracts/dist/tenant.d.ts +0 -147
  175. package/packages/@repo/contracts/dist/tenant.d.ts.map +0 -1
  176. package/packages/@repo/contracts/dist/tenant.js +0 -58
  177. package/packages/@repo/contracts/dist/user.d.ts +0 -9
  178. package/packages/@repo/contracts/dist/user.d.ts.map +0 -1
  179. package/packages/@repo/contracts/dist/user.js +0 -9
  180. package/packages/@repo/contracts/package.json +0 -37
  181. package/packages/@repo/contracts/src/analytics.ts +0 -33
  182. package/packages/@repo/contracts/src/dates.ts +0 -4
  183. package/packages/@repo/contracts/src/deployment.ts +0 -73
  184. package/packages/@repo/contracts/src/domain.ts +0 -51
  185. package/packages/@repo/contracts/src/git.ts +0 -31
  186. package/packages/@repo/contracts/src/ids.ts +0 -23
  187. package/packages/@repo/contracts/src/index.ts +0 -12
  188. package/packages/@repo/contracts/src/pagination.ts +0 -21
  189. package/packages/@repo/contracts/src/project.ts +0 -32
  190. package/packages/@repo/contracts/src/tenant.ts +0 -94
  191. package/packages/@repo/contracts/src/user.ts +0 -12
  192. package/packages/@repo/models/dist/docs-config.d.ts +0 -961
  193. package/packages/@repo/models/dist/docs-config.d.ts.map +0 -1
  194. package/packages/@repo/models/dist/docs-config.js +0 -531
  195. package/packages/@repo/models/dist/index.d.ts +0 -3
  196. package/packages/@repo/models/dist/index.d.ts.map +0 -1
  197. package/packages/@repo/models/dist/index.js +0 -3
  198. package/packages/@repo/models/dist/tenant.d.ts +0 -37
  199. package/packages/@repo/models/dist/tenant.d.ts.map +0 -1
  200. package/packages/@repo/models/dist/tenant.js +0 -1
  201. package/packages/@repo/models/package.json +0 -37
  202. package/packages/@repo/models/src/docs-config.ts +0 -629
  203. package/packages/@repo/models/src/index.ts +0 -3
  204. package/packages/@repo/models/src/tenant.ts +0 -44
  205. package/packages/@repo/prebuild/dist/index.d.ts +0 -2
  206. package/packages/@repo/prebuild/dist/index.d.ts.map +0 -1
  207. package/packages/@repo/prebuild/dist/index.js +0 -2
  208. package/packages/@repo/prebuild/dist/openapi.d.ts +0 -43
  209. package/packages/@repo/prebuild/dist/openapi.d.ts.map +0 -1
  210. package/packages/@repo/prebuild/dist/openapi.js +0 -86
  211. package/packages/@repo/prebuild/package.json +0 -39
  212. package/packages/@repo/prebuild/src/index.ts +0 -2
  213. package/packages/@repo/prebuild/src/openapi.ts +0 -154
  214. package/packages/@repo/previewing/dist/blob-source.d.ts +0 -16
  215. package/packages/@repo/previewing/dist/blob-source.d.ts.map +0 -1
  216. package/packages/@repo/previewing/dist/blob-source.js +0 -128
  217. package/packages/@repo/previewing/dist/config-loader.d.ts +0 -134
  218. package/packages/@repo/previewing/dist/config-loader.d.ts.map +0 -1
  219. package/packages/@repo/previewing/dist/config-loader.js +0 -231
  220. package/packages/@repo/previewing/dist/constants.d.ts +0 -15
  221. package/packages/@repo/previewing/dist/constants.d.ts.map +0 -1
  222. package/packages/@repo/previewing/dist/constants.js +0 -14
  223. package/packages/@repo/previewing/dist/content-index.d.ts +0 -7
  224. package/packages/@repo/previewing/dist/content-index.d.ts.map +0 -1
  225. package/packages/@repo/previewing/dist/content-index.js +0 -291
  226. package/packages/@repo/previewing/dist/content-source.d.ts +0 -12
  227. package/packages/@repo/previewing/dist/content-source.d.ts.map +0 -1
  228. package/packages/@repo/previewing/dist/content-source.js +0 -1
  229. package/packages/@repo/previewing/dist/fs-source.d.ts +0 -11
  230. package/packages/@repo/previewing/dist/fs-source.d.ts.map +0 -1
  231. package/packages/@repo/previewing/dist/fs-source.js +0 -71
  232. package/packages/@repo/previewing/dist/index.d.ts +0 -16
  233. package/packages/@repo/previewing/dist/index.d.ts.map +0 -1
  234. package/packages/@repo/previewing/dist/index.js +0 -13
  235. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts +0 -3
  236. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts.map +0 -1
  237. package/packages/@repo/previewing/dist/markdown/agent-markdown.js +0 -176
  238. package/packages/@repo/previewing/dist/markdown/format.d.ts +0 -8
  239. package/packages/@repo/previewing/dist/markdown/format.d.ts.map +0 -1
  240. package/packages/@repo/previewing/dist/markdown/format.js +0 -43
  241. package/packages/@repo/previewing/dist/markdown/links.d.ts +0 -3
  242. package/packages/@repo/previewing/dist/markdown/links.d.ts.map +0 -1
  243. package/packages/@repo/previewing/dist/markdown/links.js +0 -31
  244. package/packages/@repo/previewing/dist/openapi-pages.d.ts +0 -7
  245. package/packages/@repo/previewing/dist/openapi-pages.d.ts.map +0 -1
  246. package/packages/@repo/previewing/dist/openapi-pages.js +0 -200
  247. package/packages/@repo/previewing/dist/search-index.d.ts +0 -4
  248. package/packages/@repo/previewing/dist/search-index.d.ts.map +0 -1
  249. package/packages/@repo/previewing/dist/search-index.js +0 -23
  250. package/packages/@repo/previewing/dist/serialization.d.ts +0 -13
  251. package/packages/@repo/previewing/dist/serialization.d.ts.map +0 -1
  252. package/packages/@repo/previewing/dist/serialization.js +0 -108
  253. package/packages/@repo/previewing/dist/toc-index.d.ts +0 -5
  254. package/packages/@repo/previewing/dist/toc-index.d.ts.map +0 -1
  255. package/packages/@repo/previewing/dist/toc-index.js +0 -53
  256. package/packages/@repo/previewing/dist/types.d.ts +0 -92
  257. package/packages/@repo/previewing/dist/types.d.ts.map +0 -1
  258. package/packages/@repo/previewing/dist/types.js +0 -1
  259. package/packages/@repo/previewing/dist/utility-index.d.ts +0 -7
  260. package/packages/@repo/previewing/dist/utility-index.d.ts.map +0 -1
  261. package/packages/@repo/previewing/dist/utility-index.js +0 -201
  262. package/packages/@repo/previewing/package.json +0 -41
  263. package/packages/@repo/previewing/src/blob-source.ts +0 -185
  264. package/packages/@repo/previewing/src/config-loader.ts +0 -316
  265. package/packages/@repo/previewing/src/constants.ts +0 -16
  266. package/packages/@repo/previewing/src/content-index.ts +0 -384
  267. package/packages/@repo/previewing/src/content-source.ts +0 -12
  268. package/packages/@repo/previewing/src/fs-source.ts +0 -103
  269. package/packages/@repo/previewing/src/index.ts +0 -71
  270. package/packages/@repo/previewing/src/markdown/agent-markdown.ts +0 -254
  271. package/packages/@repo/previewing/src/markdown/format.ts +0 -63
  272. package/packages/@repo/previewing/src/markdown/links.ts +0 -46
  273. package/packages/@repo/previewing/src/openapi-pages.ts +0 -319
  274. package/packages/@repo/previewing/src/search-index.ts +0 -38
  275. package/packages/@repo/previewing/src/serialization.ts +0 -191
  276. package/packages/@repo/previewing/src/toc-index.ts +0 -72
  277. package/packages/@repo/previewing/src/types.ts +0 -105
  278. package/packages/@repo/previewing/src/utility-index.ts +0 -304
  279. package/packages/@repo/validation/dist/index.d.ts +0 -12
  280. package/packages/@repo/validation/dist/index.d.ts.map +0 -1
  281. package/packages/@repo/validation/dist/index.js +0 -30
  282. package/packages/@repo/validation/package.json +0 -38
  283. package/packages/@repo/validation/src/blodemd-docs-schema.json +0 -3575
  284. package/packages/@repo/validation/src/index.ts +0 -59
  285. package/scripts/prepare-package.mjs +0 -53
  286. 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
- };