@apimatic/cli 1.4.0 → 2.0.0-beta.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 (610) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +128 -212
  3. package/apimatic.schema.json +550 -0
  4. package/lib/actions/action-result.js +3 -0
  5. package/lib/actions/action-result.js.map +1 -1
  6. package/lib/actions/api/transform.js +36 -33
  7. package/lib/actions/api/transform.js.map +1 -1
  8. package/lib/actions/api/validate.d.ts +9 -6
  9. package/lib/actions/api/validate.js +44 -38
  10. package/lib/actions/api/validate.js.map +1 -1
  11. package/lib/actions/auth/login.js +7 -4
  12. package/lib/actions/auth/login.js.map +1 -1
  13. package/lib/actions/auth/logout.js +2 -1
  14. package/lib/actions/auth/logout.js.map +1 -1
  15. package/lib/actions/auth/status.js +5 -3
  16. package/lib/actions/auth/status.js.map +1 -1
  17. package/lib/actions/plugin/generate.d.ts +5 -1
  18. package/lib/actions/plugin/generate.js +83 -56
  19. package/lib/actions/plugin/generate.js.map +1 -1
  20. package/lib/actions/plugin/publish.d.ts +2 -1
  21. package/lib/actions/plugin/publish.js +34 -37
  22. package/lib/actions/plugin/publish.js.map +1 -1
  23. package/lib/actions/plugin/record-metadata.d.ts +3 -2
  24. package/lib/actions/plugin/record-metadata.js +33 -30
  25. package/lib/actions/plugin/record-metadata.js.map +1 -1
  26. package/lib/actions/portal/generate.d.ts +8 -6
  27. package/lib/actions/portal/generate.js +50 -61
  28. package/lib/actions/portal/generate.js.map +1 -1
  29. package/lib/actions/portal/prepare-project.d.ts +25 -0
  30. package/lib/actions/portal/prepare-project.js +68 -0
  31. package/lib/actions/portal/prepare-project.js.map +1 -0
  32. package/lib/actions/portal/serve.d.ts +21 -6
  33. package/lib/actions/portal/serve.js +170 -153
  34. package/lib/actions/portal/serve.js.map +1 -1
  35. package/lib/actions/publishing/profile/list.js +4 -2
  36. package/lib/actions/publishing/profile/list.js.map +1 -1
  37. package/lib/actions/quickstart.d.ts +23 -5
  38. package/lib/actions/quickstart.js +222 -21
  39. package/lib/actions/quickstart.js.map +1 -1
  40. package/lib/actions/sdk/generate.d.ts +4 -7
  41. package/lib/actions/sdk/generate.js +53 -93
  42. package/lib/actions/sdk/generate.js.map +1 -1
  43. package/lib/actions/sdk/publish/interactive.d.ts +4 -3
  44. package/lib/actions/sdk/publish/interactive.js +96 -97
  45. package/lib/actions/sdk/publish/interactive.js.map +1 -1
  46. package/lib/actions/sdk/publish/non-interactive.d.ts +4 -2
  47. package/lib/actions/sdk/publish/non-interactive.js +91 -90
  48. package/lib/actions/sdk/publish/non-interactive.js.map +1 -1
  49. package/lib/actions/sdk/publish.d.ts +3 -2
  50. package/lib/actions/sdk/publish.js +55 -53
  51. package/lib/actions/sdk/publish.js.map +1 -1
  52. package/lib/actions/sdk/record-published-sdk.d.ts +14 -0
  53. package/lib/actions/sdk/record-published-sdk.js +57 -0
  54. package/lib/actions/sdk/record-published-sdk.js.map +1 -0
  55. package/lib/client-utils/auth-manager.js +1 -1
  56. package/lib/client-utils/auth-manager.js.map +1 -1
  57. package/lib/commands/api/transform.d.ts +1 -1
  58. package/lib/commands/api/transform.js +44 -40
  59. package/lib/commands/api/transform.js.map +1 -1
  60. package/lib/commands/api/validate.js +16 -16
  61. package/lib/commands/api/validate.js.map +1 -1
  62. package/lib/commands/auth/login.js +14 -15
  63. package/lib/commands/auth/login.js.map +1 -1
  64. package/lib/commands/auth/logout.js +5 -6
  65. package/lib/commands/auth/logout.js.map +1 -1
  66. package/lib/commands/auth/status.js +4 -5
  67. package/lib/commands/auth/status.js.map +1 -1
  68. package/lib/commands/plugin/generate.d.ts +3 -3
  69. package/lib/commands/plugin/generate.js +20 -20
  70. package/lib/commands/plugin/generate.js.map +1 -1
  71. package/lib/commands/plugin/publish.js +18 -18
  72. package/lib/commands/plugin/publish.js.map +1 -1
  73. package/lib/commands/portal/generate.d.ts +9 -8
  74. package/lib/commands/portal/generate.js +36 -27
  75. package/lib/commands/portal/generate.js.map +1 -1
  76. package/lib/commands/portal/serve.d.ts +7 -9
  77. package/lib/commands/portal/serve.js +41 -44
  78. package/lib/commands/portal/serve.js.map +1 -1
  79. package/lib/commands/publishing/profile/list.js +8 -12
  80. package/lib/commands/publishing/profile/list.js.map +1 -1
  81. package/lib/commands/quickstart.d.ts +5 -5
  82. package/lib/commands/quickstart.js +18 -24
  83. package/lib/commands/quickstart.js.map +1 -1
  84. package/lib/commands/sdk/generate.d.ts +5 -7
  85. package/lib/commands/sdk/generate.js +58 -70
  86. package/lib/commands/sdk/generate.js.map +1 -1
  87. package/lib/commands/sdk/publish.d.ts +6 -7
  88. package/lib/commands/sdk/publish.js +66 -60
  89. package/lib/commands/sdk/publish.js.map +1 -1
  90. package/lib/hooks/node-version.d.ts +3 -0
  91. package/lib/hooks/node-version.js +12 -0
  92. package/lib/hooks/node-version.js.map +1 -0
  93. package/lib/hooks/not-found.js +2 -3
  94. package/lib/hooks/not-found.js.map +1 -1
  95. package/lib/hooks/utils.d.ts +4 -2
  96. package/lib/hooks/utils.js +2 -2
  97. package/lib/hooks/utils.js.map +1 -1
  98. package/lib/infrastructure/env-info.d.ts +3 -0
  99. package/lib/infrastructure/env-info.js +13 -6
  100. package/lib/infrastructure/env-info.js.map +1 -1
  101. package/lib/infrastructure/file-service.d.ts +35 -8
  102. package/lib/infrastructure/file-service.js +149 -53
  103. package/lib/infrastructure/file-service.js.map +1 -1
  104. package/lib/infrastructure/file-watch-service.d.ts +40 -0
  105. package/lib/infrastructure/file-watch-service.js +167 -0
  106. package/lib/infrastructure/file-watch-service.js.map +1 -0
  107. package/lib/infrastructure/generation-status-poller.d.ts +8 -7
  108. package/lib/infrastructure/generation-status-poller.js +20 -12
  109. package/lib/infrastructure/generation-status-poller.js.map +1 -1
  110. package/lib/infrastructure/launcher-service.js +6 -6
  111. package/lib/infrastructure/launcher-service.js.map +1 -1
  112. package/lib/infrastructure/network-service.d.ts +3 -0
  113. package/lib/infrastructure/network-service.js +15 -1
  114. package/lib/infrastructure/network-service.js.map +1 -1
  115. package/lib/infrastructure/portal-build-service.d.ts +19 -0
  116. package/lib/infrastructure/portal-build-service.js +58 -0
  117. package/lib/infrastructure/portal-build-service.js.map +1 -0
  118. package/lib/infrastructure/portal-dev-server-service.d.ts +29 -0
  119. package/lib/infrastructure/portal-dev-server-service.js +135 -0
  120. package/lib/infrastructure/portal-dev-server-service.js.map +1 -0
  121. package/lib/infrastructure/portal-pages-service.d.ts +17 -0
  122. package/lib/infrastructure/portal-pages-service.js +103 -0
  123. package/lib/infrastructure/portal-pages-service.js.map +1 -0
  124. package/lib/infrastructure/portal-project-service.d.ts +77 -0
  125. package/lib/infrastructure/portal-project-service.js +309 -0
  126. package/lib/infrastructure/portal-project-service.js.map +1 -0
  127. package/lib/infrastructure/service-error.d.ts +1 -0
  128. package/lib/infrastructure/service-error.js +39 -41
  129. package/lib/infrastructure/service-error.js.map +1 -1
  130. package/lib/infrastructure/services/api-client-factory.js +15 -13
  131. package/lib/infrastructure/services/api-client-factory.js.map +1 -1
  132. package/lib/infrastructure/services/api-service.d.ts +7 -5
  133. package/lib/infrastructure/services/api-service.js +28 -20
  134. package/lib/infrastructure/services/api-service.js.map +1 -1
  135. package/lib/infrastructure/services/auth-service.js +4 -9
  136. package/lib/infrastructure/services/auth-service.js.map +1 -1
  137. package/lib/infrastructure/services/file-download-service.js +3 -3
  138. package/lib/infrastructure/services/file-download-service.js.map +1 -1
  139. package/lib/infrastructure/services/plugin-service.d.ts +1 -8
  140. package/lib/infrastructure/services/plugin-service.js +11 -22
  141. package/lib/infrastructure/services/plugin-service.js.map +1 -1
  142. package/lib/infrastructure/services/portal-artifacts-service.d.ts +44 -0
  143. package/lib/infrastructure/services/portal-artifacts-service.js +268 -0
  144. package/lib/infrastructure/services/portal-artifacts-service.js.map +1 -0
  145. package/lib/infrastructure/services/portal-authorization-service.d.ts +22 -0
  146. package/lib/infrastructure/services/portal-authorization-service.js +23 -0
  147. package/lib/infrastructure/services/portal-authorization-service.js.map +1 -0
  148. package/lib/infrastructure/services/publishing-api-service.d.ts +1 -1
  149. package/lib/infrastructure/services/publishing-api-service.js +11 -15
  150. package/lib/infrastructure/services/publishing-api-service.js.map +1 -1
  151. package/lib/infrastructure/services/sdk-generation-service.d.ts +21 -0
  152. package/lib/infrastructure/services/sdk-generation-service.js +118 -0
  153. package/lib/infrastructure/services/sdk-generation-service.js.map +1 -0
  154. package/lib/infrastructure/services/telemetry-service.js +5 -4
  155. package/lib/infrastructure/services/telemetry-service.js.map +1 -1
  156. package/lib/infrastructure/services/transformation-service.js +29 -32
  157. package/lib/infrastructure/services/transformation-service.js.map +1 -1
  158. package/lib/infrastructure/services/validation-service.d.ts +12 -53
  159. package/lib/infrastructure/services/validation-service.js +24 -199
  160. package/lib/infrastructure/services/validation-service.js.map +1 -1
  161. package/lib/infrastructure/timer-extensions.d.ts +2 -0
  162. package/lib/infrastructure/timer-extensions.js +10 -0
  163. package/lib/infrastructure/timer-extensions.js.map +1 -0
  164. package/lib/infrastructure/tmp-extensions.d.ts +31 -1
  165. package/lib/infrastructure/tmp-extensions.js +86 -3
  166. package/lib/infrastructure/tmp-extensions.js.map +1 -1
  167. package/lib/infrastructure/zip-service.js +2 -2
  168. package/lib/infrastructure/zip-service.js.map +1 -1
  169. package/lib/prompts/api/validate.d.ts +6 -7
  170. package/lib/prompts/api/validate.js +12 -12
  171. package/lib/prompts/api/validate.js.map +1 -1
  172. package/lib/prompts/format.d.ts +4 -0
  173. package/lib/prompts/format.js +5 -0
  174. package/lib/prompts/format.js.map +1 -1
  175. package/lib/prompts/plugin/generate.d.ts +17 -12
  176. package/lib/prompts/plugin/generate.js +94 -44
  177. package/lib/prompts/plugin/generate.js.map +1 -1
  178. package/lib/prompts/plugin/publish.d.ts +2 -1
  179. package/lib/prompts/plugin/publish.js +8 -7
  180. package/lib/prompts/plugin/publish.js.map +1 -1
  181. package/lib/prompts/plugin/record-metadata.d.ts +1 -0
  182. package/lib/prompts/plugin/record-metadata.js +10 -7
  183. package/lib/prompts/plugin/record-metadata.js.map +1 -1
  184. package/lib/prompts/portal/artifacts.d.ts +8 -0
  185. package/lib/prompts/portal/artifacts.js +26 -0
  186. package/lib/prompts/portal/artifacts.js.map +1 -0
  187. package/lib/prompts/portal/authorization.d.ts +6 -0
  188. package/lib/prompts/portal/authorization.js +29 -0
  189. package/lib/prompts/portal/authorization.js.map +1 -0
  190. package/lib/prompts/portal/code-samples.d.ts +1 -0
  191. package/lib/prompts/portal/code-samples.js +9 -0
  192. package/lib/prompts/portal/code-samples.js.map +1 -0
  193. package/lib/prompts/portal/generate.d.ts +14 -9
  194. package/lib/prompts/portal/generate.js +48 -26
  195. package/lib/prompts/portal/generate.js.map +1 -1
  196. package/lib/prompts/portal/prepare-project.d.ts +20 -0
  197. package/lib/prompts/portal/prepare-project.js +36 -0
  198. package/lib/prompts/portal/prepare-project.js.map +1 -0
  199. package/lib/prompts/portal/serve.d.ts +32 -12
  200. package/lib/prompts/portal/serve.js +102 -39
  201. package/lib/prompts/portal/serve.js.map +1 -1
  202. package/lib/prompts/portal/source.d.ts +26 -0
  203. package/lib/prompts/portal/source.js +253 -0
  204. package/lib/prompts/portal/source.js.map +1 -0
  205. package/lib/prompts/prompt.d.ts +11 -3
  206. package/lib/prompts/prompt.js +39 -15
  207. package/lib/prompts/prompt.js.map +1 -1
  208. package/lib/prompts/quickstart.d.ts +46 -3
  209. package/lib/prompts/quickstart.js +199 -12
  210. package/lib/prompts/quickstart.js.map +1 -1
  211. package/lib/prompts/sdk/generate.d.ts +15 -13
  212. package/lib/prompts/sdk/generate.js +29 -32
  213. package/lib/prompts/sdk/generate.js.map +1 -1
  214. package/lib/prompts/sdk/publish/interactive.d.ts +10 -6
  215. package/lib/prompts/sdk/publish/interactive.js +26 -24
  216. package/lib/prompts/sdk/publish/interactive.js.map +1 -1
  217. package/lib/prompts/sdk/publish/non-interactive.d.ts +2 -1
  218. package/lib/prompts/sdk/publish/non-interactive.js +5 -4
  219. package/lib/prompts/sdk/publish/non-interactive.js.map +1 -1
  220. package/lib/prompts/sdk/publish.d.ts +3 -3
  221. package/lib/prompts/sdk/publish.js +13 -17
  222. package/lib/prompts/sdk/publish.js.map +1 -1
  223. package/lib/prompts/sdk/record-published-sdk.d.ts +7 -0
  224. package/lib/prompts/sdk/record-published-sdk.js +26 -0
  225. package/lib/prompts/sdk/record-published-sdk.js.map +1 -0
  226. package/lib/types/apimatic-config/document.d.ts +70 -0
  227. package/lib/types/apimatic-config/document.js +167 -0
  228. package/lib/types/apimatic-config/document.js.map +1 -0
  229. package/lib/types/apimatic-config/languages-block.d.ts +39 -0
  230. package/lib/types/apimatic-config/languages-block.js +58 -0
  231. package/lib/types/apimatic-config/languages-block.js.map +1 -0
  232. package/lib/types/apimatic-config-context.d.ts +48 -0
  233. package/lib/types/apimatic-config-context.js +121 -0
  234. package/lib/types/apimatic-config-context.js.map +1 -0
  235. package/lib/types/build/build.d.ts +1 -89
  236. package/lib/types/build/build.js +6 -161
  237. package/lib/types/build/build.js.map +1 -1
  238. package/lib/types/events/domain-event.js +3 -0
  239. package/lib/types/events/domain-event.js.map +1 -1
  240. package/lib/types/events/quickstart-completed.js +3 -3
  241. package/lib/types/events/quickstart-completed.js.map +1 -1
  242. package/lib/types/events/quickstart-initiated.js +3 -3
  243. package/lib/types/events/quickstart-initiated.js.map +1 -1
  244. package/lib/types/events/sdk-publish-validation-failed.js +1 -1
  245. package/lib/types/events/sdk-publish-validation-failed.js.map +1 -1
  246. package/lib/types/file/directory.d.ts +4 -9
  247. package/lib/types/file/directory.js +17 -65
  248. package/lib/types/file/directory.js.map +1 -1
  249. package/lib/types/file/directoryPath.d.ts +17 -0
  250. package/lib/types/file/directoryPath.js +47 -2
  251. package/lib/types/file/directoryPath.js.map +1 -1
  252. package/lib/types/file/fileName.d.ts +8 -0
  253. package/lib/types/file/fileName.js +28 -6
  254. package/lib/types/file/fileName.js.map +1 -1
  255. package/lib/types/file/filePath.d.ts +18 -2
  256. package/lib/types/file/filePath.js +39 -4
  257. package/lib/types/file/filePath.js.map +1 -1
  258. package/lib/types/file/resource-input.js +1 -2
  259. package/lib/types/file/resource-input.js.map +1 -1
  260. package/lib/types/file/urlPath.js +2 -1
  261. package/lib/types/file/urlPath.js.map +1 -1
  262. package/lib/types/flags-provider.js +22 -22
  263. package/lib/types/flags-provider.js.map +1 -1
  264. package/lib/types/package-settings-context.js +2 -1
  265. package/lib/types/package-settings-context.js.map +1 -1
  266. package/lib/types/plugin/plugin-config.d.ts +10 -50
  267. package/lib/types/plugin/plugin-config.js +7 -1
  268. package/lib/types/plugin/plugin-config.js.map +1 -1
  269. package/lib/types/plugin-config-context.d.ts +30 -37
  270. package/lib/types/plugin-config-context.js +108 -139
  271. package/lib/types/plugin-config-context.js.map +1 -1
  272. package/lib/types/plugin-context.js +3 -2
  273. package/lib/types/plugin-context.js.map +1 -1
  274. package/lib/types/portal/code-samples.d.ts +27 -0
  275. package/lib/types/portal/code-samples.js +67 -0
  276. package/lib/types/portal/code-samples.js.map +1 -0
  277. package/lib/types/portal/config/ai-config.d.ts +15 -0
  278. package/lib/types/portal/config/ai-config.js +26 -0
  279. package/lib/types/portal/config/ai-config.js.map +1 -0
  280. package/lib/types/portal/config/brand-config.d.ts +55 -0
  281. package/lib/types/portal/config/brand-config.js +105 -0
  282. package/lib/types/portal/config/brand-config.js.map +1 -0
  283. package/lib/types/portal/config/color.d.ts +19 -0
  284. package/lib/types/portal/config/color.js +43 -0
  285. package/lib/types/portal/config/color.js.map +1 -0
  286. package/lib/types/portal/config/fields.d.ts +23 -0
  287. package/lib/types/portal/config/fields.js +67 -0
  288. package/lib/types/portal/config/fields.js.map +1 -0
  289. package/lib/types/portal/config/link.d.ts +18 -0
  290. package/lib/types/portal/config/link.js +72 -0
  291. package/lib/types/portal/config/link.js.map +1 -0
  292. package/lib/types/portal/config/navigation-config.d.ts +13 -0
  293. package/lib/types/portal/config/navigation-config.js +30 -0
  294. package/lib/types/portal/config/navigation-config.js.map +1 -0
  295. package/lib/types/portal/config/site-config.d.ts +32 -0
  296. package/lib/types/portal/config/site-config.js +88 -0
  297. package/lib/types/portal/config/site-config.js.map +1 -0
  298. package/lib/types/portal/config/static-asset.d.ts +25 -0
  299. package/lib/types/portal/config/static-asset.js +77 -0
  300. package/lib/types/portal/config/static-asset.js.map +1 -0
  301. package/lib/types/portal/content-notices.d.ts +20 -0
  302. package/lib/types/portal/content-notices.js +2 -0
  303. package/lib/types/portal/content-notices.js.map +1 -0
  304. package/lib/types/portal/content-tree.d.ts +103 -0
  305. package/lib/types/portal/content-tree.js +344 -0
  306. package/lib/types/portal/content-tree.js.map +1 -0
  307. package/lib/types/portal/endpoint.d.ts +6 -0
  308. package/lib/types/portal/endpoint.js +12 -0
  309. package/lib/types/portal/endpoint.js.map +1 -0
  310. package/lib/types/portal/generated-pages.d.ts +68 -0
  311. package/lib/types/portal/generated-pages.js +111 -0
  312. package/lib/types/portal/generated-pages.js.map +1 -0
  313. package/lib/types/portal/generation-status.d.ts +31 -0
  314. package/lib/types/portal/generation-status.js +26 -0
  315. package/lib/types/portal/generation-status.js.map +1 -0
  316. package/lib/types/portal/openapi-document.d.ts +48 -0
  317. package/lib/types/portal/openapi-document.js +138 -0
  318. package/lib/types/portal/openapi-document.js.map +1 -0
  319. package/lib/types/portal/page-fragments.d.ts +13 -0
  320. package/lib/types/portal/page-fragments.js +24 -0
  321. package/lib/types/portal/page-fragments.js.map +1 -0
  322. package/lib/types/portal/page-template.d.ts +15 -0
  323. package/lib/types/portal/page-template.js +64 -0
  324. package/lib/types/portal/page-template.js.map +1 -0
  325. package/lib/types/portal/page.d.ts +24 -0
  326. package/lib/types/portal/page.js +100 -0
  327. package/lib/types/portal/page.js.map +1 -0
  328. package/lib/types/portal/portal-artifacts.d.ts +25 -0
  329. package/lib/types/portal/portal-artifacts.js +30 -0
  330. package/lib/types/portal/portal-artifacts.js.map +1 -0
  331. package/lib/types/portal/portal-config.d.ts +69 -0
  332. package/lib/types/portal/portal-config.js +105 -0
  333. package/lib/types/portal/portal-config.js.map +1 -0
  334. package/lib/types/portal/portal-downloads.d.ts +8 -0
  335. package/lib/types/portal/portal-downloads.js +14 -0
  336. package/lib/types/portal/portal-downloads.js.map +1 -0
  337. package/lib/types/portal/portal-languages.d.ts +15 -0
  338. package/lib/types/portal/portal-languages.js +45 -0
  339. package/lib/types/portal/portal-languages.js.map +1 -0
  340. package/lib/types/portal/portal-navigation.d.ts +65 -0
  341. package/lib/types/portal/portal-navigation.js +217 -0
  342. package/lib/types/portal/portal-navigation.js.map +1 -0
  343. package/lib/types/portal/portal-sdk.d.ts +15 -0
  344. package/lib/types/portal/portal-sdk.js +28 -0
  345. package/lib/types/portal/portal-sdk.js.map +1 -0
  346. package/lib/types/portal/portal-source.d.ts +129 -0
  347. package/lib/types/portal/portal-source.js +2 -0
  348. package/lib/types/portal/portal-source.js.map +1 -0
  349. package/lib/types/portal/portal-stylesheet.d.ts +19 -0
  350. package/lib/types/portal/portal-stylesheet.js +40 -0
  351. package/lib/types/portal/portal-stylesheet.js.map +1 -0
  352. package/lib/types/portal/portal-tabs.d.ts +33 -0
  353. package/lib/types/portal/portal-tabs.js +38 -0
  354. package/lib/types/portal/portal-tabs.js.map +1 -0
  355. package/lib/types/portal/preview-config.d.ts +20 -0
  356. package/lib/types/portal/preview-config.js +32 -0
  357. package/lib/types/portal/preview-config.js.map +1 -0
  358. package/lib/types/portal/preview-content.d.ts +18 -0
  359. package/lib/types/portal/preview-content.js +50 -0
  360. package/lib/types/portal/preview-content.js.map +1 -0
  361. package/lib/types/portal/published-package.d.ts +12 -0
  362. package/lib/types/portal/published-package.js +35 -0
  363. package/lib/types/portal/published-package.js.map +1 -0
  364. package/lib/types/portal/unknown-fields.d.ts +5 -0
  365. package/lib/types/portal/unknown-fields.js +10 -0
  366. package/lib/types/portal/unknown-fields.js.map +1 -0
  367. package/lib/types/portal-context.d.ts +38 -6
  368. package/lib/types/portal-context.js +71 -24
  369. package/lib/types/portal-context.js.map +1 -1
  370. package/lib/types/portal-source-context.d.ts +77 -0
  371. package/lib/types/portal-source-context.js +408 -0
  372. package/lib/types/portal-source-context.js.map +1 -0
  373. package/lib/types/project-context.d.ts +49 -0
  374. package/lib/types/project-context.js +151 -0
  375. package/lib/types/project-context.js.map +1 -0
  376. package/lib/types/project-layout.d.ts +9 -0
  377. package/lib/types/project-layout.js +10 -0
  378. package/lib/types/project-layout.js.map +1 -0
  379. package/lib/types/publish/package-settings-configuration.d.ts +2 -0
  380. package/lib/types/publish/profile-id.js +1 -0
  381. package/lib/types/publish/profile-id.js.map +1 -1
  382. package/lib/types/publish/publishing-profile.d.ts +3 -1
  383. package/lib/types/publish/publishing-profile.js +33 -15
  384. package/lib/types/publish/publishing-profile.js.map +1 -1
  385. package/lib/types/publish/publishing-profiles.js +2 -1
  386. package/lib/types/publish/publishing-profiles.js.map +1 -1
  387. package/lib/types/publish/version.js +1 -0
  388. package/lib/types/publish/version.js.map +1 -1
  389. package/lib/types/resource-context.js +3 -2
  390. package/lib/types/resource-context.js.map +1 -1
  391. package/lib/types/sdk/generate.d.ts +22 -16
  392. package/lib/types/sdk/generate.js +64 -41
  393. package/lib/types/sdk/generate.js.map +1 -1
  394. package/lib/types/sdk/stability-choice.d.ts +12 -0
  395. package/lib/types/sdk/stability-choice.js +24 -0
  396. package/lib/types/sdk/stability-choice.js.map +1 -0
  397. package/lib/types/sdk-context.d.ts +4 -5
  398. package/lib/types/sdk-context.js +10 -18
  399. package/lib/types/sdk-context.js.map +1 -1
  400. package/lib/types/spec-context.d.ts +5 -4
  401. package/lib/types/spec-context.js +9 -8
  402. package/lib/types/spec-context.js.map +1 -1
  403. package/lib/types/temp-context.d.ts +1 -1
  404. package/lib/types/temp-context.js +5 -4
  405. package/lib/types/temp-context.js.map +1 -1
  406. package/lib/types/transform-context.d.ts +9 -5
  407. package/lib/types/transform-context.js +21 -18
  408. package/lib/types/transform-context.js.map +1 -1
  409. package/lib/utils/error-utils.d.ts +2 -0
  410. package/lib/utils/error-utils.js +5 -0
  411. package/lib/utils/error-utils.js.map +1 -0
  412. package/lib/utils/json-utils.d.ts +2 -0
  413. package/lib/utils/json-utils.js +4 -0
  414. package/lib/utils/json-utils.js.map +1 -0
  415. package/lib/utils/string-utils.d.ts +8 -1
  416. package/lib/utils/string-utils.js +13 -26
  417. package/lib/utils/string-utils.js.map +1 -1
  418. package/lib/utils/utils.d.ts +1 -3
  419. package/lib/utils/utils.js +12 -40
  420. package/lib/utils/utils.js.map +1 -1
  421. package/oclif.manifest.json +69 -357
  422. package/package.json +47 -25
  423. package/portal-pages/context-plugin.mdx +26 -0
  424. package/portal-pages/sdk.mdx +8 -0
  425. package/portal-pages/sdks.mdx +11 -0
  426. package/portal-template/NOTICE +37 -0
  427. package/portal-template/downloads.ts +41 -0
  428. package/portal-template/generated-pages-reload.ts +51 -0
  429. package/portal-template/package.json +11 -0
  430. package/portal-template/portal-config.ts +32 -0
  431. package/portal-template/prerender-pages.ts +81 -0
  432. package/portal-template/spec-reload.ts +26 -0
  433. package/portal-template/src/components/api-page.tsx +15 -0
  434. package/portal-template/src/components/code-block.tsx +9 -0
  435. package/portal-template/src/components/command-block.tsx +50 -0
  436. package/portal-template/src/components/example-layout.tsx +99 -0
  437. package/portal-template/src/components/logos.tsx +127 -0
  438. package/portal-template/src/components/mdx.tsx +28 -0
  439. package/portal-template/src/components/not-found.tsx +11 -0
  440. package/portal-template/src/components/plugin-install.tsx +22 -0
  441. package/portal-template/src/components/plugin-support.tsx +53 -0
  442. package/portal-template/src/components/sdk-actions.tsx +79 -0
  443. package/portal-template/src/components/sdk-cards.tsx +100 -0
  444. package/portal-template/src/components/search.tsx +41 -0
  445. package/portal-template/src/components/usage-tabs.tsx +92 -0
  446. package/portal-template/src/lib/code-samples.server.ts +40 -0
  447. package/portal-template/src/lib/code-samples.ts +43 -0
  448. package/portal-template/src/lib/code-titles.ts +29 -0
  449. package/portal-template/src/lib/install-command.ts +13 -0
  450. package/portal-template/src/lib/json.ts +5 -0
  451. package/portal-template/src/lib/layout.shared.tsx +41 -0
  452. package/portal-template/src/lib/layout.tsx +16 -0
  453. package/portal-template/src/lib/llms.server.ts +54 -0
  454. package/portal-template/src/lib/media-adapters.ts +34 -0
  455. package/portal-template/src/lib/navigation.ts +406 -0
  456. package/portal-template/src/lib/openapi-bundle.server.ts +343 -0
  457. package/portal-template/src/lib/openapi-filter.ts +191 -0
  458. package/portal-template/src/lib/openapi-labels.ts +15 -0
  459. package/portal-template/src/lib/openapi-methods.ts +12 -0
  460. package/portal-template/src/lib/openapi-section.server.ts +280 -0
  461. package/portal-template/src/lib/openapi-slim.ts +202 -0
  462. package/portal-template/src/lib/openapi.server.ts +16 -0
  463. package/portal-template/src/lib/portal-types.ts +36 -0
  464. package/portal-template/src/lib/portal.server.ts +13 -0
  465. package/portal-template/src/lib/portal.ts +11 -0
  466. package/portal-template/src/lib/rehype-code-titles.ts +53 -0
  467. package/portal-template/src/lib/request-examples.ts +72 -0
  468. package/portal-template/src/lib/seo.ts +21 -0
  469. package/portal-template/src/lib/shared.ts +51 -0
  470. package/portal-template/src/lib/shiki-bundle.ts +104 -0
  471. package/portal-template/src/lib/sitemap.server.ts +20 -0
  472. package/portal-template/src/lib/source.server.ts +27 -0
  473. package/portal-template/src/lib/source.ts +49 -0
  474. package/portal-template/src/lib/tabs.ts +37 -0
  475. package/portal-template/src/router.tsx +12 -0
  476. package/portal-template/src/routes/$.tsx +194 -0
  477. package/portal-template/src/routes/__root.tsx +56 -0
  478. package/portal-template/src/routes/api/search[.]json.ts +9 -0
  479. package/portal-template/src/routes/llms-full[.]txt.ts +10 -0
  480. package/portal-template/src/routes/llms[.]txt.ts +10 -0
  481. package/portal-template/src/routes/robots[.]txt.ts +10 -0
  482. package/portal-template/src/routes/sitemap[.]xml.ts +10 -0
  483. package/portal-template/src/routes/spa-shell.tsx +7 -0
  484. package/portal-template/src/routes/{$}[.]md.ts +21 -0
  485. package/portal-template/src/styles/app.css +33 -0
  486. package/portal-template/tsconfig.json +26 -0
  487. package/portal-template/vite.config.ts +68 -0
  488. package/lib/actions/plugin/record-sdk.d.ts +0 -14
  489. package/lib/actions/plugin/record-sdk.js +0 -60
  490. package/lib/actions/plugin/record-sdk.js.map +0 -1
  491. package/lib/actions/portal/copilot.d.ts +0 -17
  492. package/lib/actions/portal/copilot.js +0 -89
  493. package/lib/actions/portal/copilot.js.map +0 -1
  494. package/lib/actions/portal/quickstart.d.ts +0 -18
  495. package/lib/actions/portal/quickstart.js +0 -238
  496. package/lib/actions/portal/quickstart.js.map +0 -1
  497. package/lib/actions/portal/recipe/new-recipe.d.ts +0 -15
  498. package/lib/actions/portal/recipe/new-recipe.js +0 -177
  499. package/lib/actions/portal/recipe/new-recipe.js.map +0 -1
  500. package/lib/actions/portal/toc/new-toc.d.ts +0 -21
  501. package/lib/actions/portal/toc/new-toc.js +0 -95
  502. package/lib/actions/portal/toc/new-toc.js.map +0 -1
  503. package/lib/actions/sdk/merge-source-tree.d.ts +0 -12
  504. package/lib/actions/sdk/merge-source-tree.js +0 -78
  505. package/lib/actions/sdk/merge-source-tree.js.map +0 -1
  506. package/lib/actions/sdk/quickstart.d.ts +0 -18
  507. package/lib/actions/sdk/quickstart.js +0 -188
  508. package/lib/actions/sdk/quickstart.js.map +0 -1
  509. package/lib/actions/sdk/save-changes.d.ts +0 -8
  510. package/lib/actions/sdk/save-changes.js +0 -93
  511. package/lib/actions/sdk/save-changes.js.map +0 -1
  512. package/lib/application/portal/recipe/portal-recipe.d.ts +0 -8
  513. package/lib/application/portal/recipe/portal-recipe.js +0 -33
  514. package/lib/application/portal/recipe/portal-recipe.js.map +0 -1
  515. package/lib/application/portal/recipe/recipe-generator.d.ts +0 -21
  516. package/lib/application/portal/recipe/recipe-generator.js +0 -130
  517. package/lib/application/portal/recipe/recipe-generator.js.map +0 -1
  518. package/lib/application/portal/toc/toc-content-parser.d.ts +0 -5
  519. package/lib/application/portal/toc/toc-content-parser.js +0 -44
  520. package/lib/application/portal/toc/toc-content-parser.js.map +0 -1
  521. package/lib/application/portal/toc/toc-structure-generator.d.ts +0 -11
  522. package/lib/application/portal/toc/toc-structure-generator.js +0 -165
  523. package/lib/application/portal/toc/toc-structure-generator.js.map +0 -1
  524. package/lib/commands/portal/copilot.d.ts +0 -13
  525. package/lib/commands/portal/copilot.js +0 -34
  526. package/lib/commands/portal/copilot.js.map +0 -1
  527. package/lib/commands/portal/recipe/new.d.ts +0 -12
  528. package/lib/commands/portal/recipe/new.js +0 -45
  529. package/lib/commands/portal/recipe/new.js.map +0 -1
  530. package/lib/commands/portal/toc/new.d.ts +0 -16
  531. package/lib/commands/portal/toc/new.js +0 -68
  532. package/lib/commands/portal/toc/new.js.map +0 -1
  533. package/lib/commands/sdk/save-changes.d.ts +0 -14
  534. package/lib/commands/sdk/save-changes.js +0 -51
  535. package/lib/commands/sdk/save-changes.js.map +0 -1
  536. package/lib/infrastructure/debounce-service.d.ts +0 -10
  537. package/lib/infrastructure/debounce-service.js +0 -55
  538. package/lib/infrastructure/debounce-service.js.map +0 -1
  539. package/lib/infrastructure/services/portal-service.d.ts +0 -43
  540. package/lib/infrastructure/services/portal-service.js +0 -337
  541. package/lib/infrastructure/services/portal-service.js.map +0 -1
  542. package/lib/prompts/plugin/record-sdk.d.ts +0 -9
  543. package/lib/prompts/plugin/record-sdk.js +0 -40
  544. package/lib/prompts/plugin/record-sdk.js.map +0 -1
  545. package/lib/prompts/portal/copilot.d.ts +0 -18
  546. package/lib/prompts/portal/copilot.js +0 -82
  547. package/lib/prompts/portal/copilot.js.map +0 -1
  548. package/lib/prompts/portal/quickstart.d.ts +0 -42
  549. package/lib/prompts/portal/quickstart.js +0 -243
  550. package/lib/prompts/portal/quickstart.js.map +0 -1
  551. package/lib/prompts/portal/recipe/new-recipe.d.ts +0 -29
  552. package/lib/prompts/portal/recipe/new-recipe.js +0 -165
  553. package/lib/prompts/portal/recipe/new-recipe.js.map +0 -1
  554. package/lib/prompts/portal/toc/new-toc.d.ts +0 -16
  555. package/lib/prompts/portal/toc/new-toc.js +0 -50
  556. package/lib/prompts/portal/toc/new-toc.js.map +0 -1
  557. package/lib/prompts/sdk/merge-source-tree.d.ts +0 -22
  558. package/lib/prompts/sdk/merge-source-tree.js +0 -90
  559. package/lib/prompts/sdk/merge-source-tree.js.map +0 -1
  560. package/lib/prompts/sdk/quickstart.d.ts +0 -38
  561. package/lib/prompts/sdk/quickstart.js +0 -196
  562. package/lib/prompts/sdk/quickstart.js.map +0 -1
  563. package/lib/prompts/sdk/save-changes.d.ts +0 -21
  564. package/lib/prompts/sdk/save-changes.js +0 -84
  565. package/lib/prompts/sdk/save-changes.js.map +0 -1
  566. package/lib/types/build-context.d.ts +0 -26
  567. package/lib/types/build-context.js +0 -111
  568. package/lib/types/build-context.js.map +0 -1
  569. package/lib/types/events/recipe-creation-failed.d.ts +0 -5
  570. package/lib/types/events/recipe-creation-failed.js +0 -8
  571. package/lib/types/events/recipe-creation-failed.js.map +0 -1
  572. package/lib/types/events/sdk-changes-saved.d.ts +0 -8
  573. package/lib/types/events/sdk-changes-saved.js +0 -11
  574. package/lib/types/events/sdk-changes-saved.js.map +0 -1
  575. package/lib/types/events/sdk-changes-tracked.d.ts +0 -8
  576. package/lib/types/events/sdk-changes-tracked.js +0 -11
  577. package/lib/types/events/sdk-changes-tracked.js.map +0 -1
  578. package/lib/types/events/sdk-conflicts-resolved.d.ts +0 -8
  579. package/lib/types/events/sdk-conflicts-resolved.js +0 -11
  580. package/lib/types/events/sdk-conflicts-resolved.js.map +0 -1
  581. package/lib/types/events/toc-creation-failed.d.ts +0 -5
  582. package/lib/types/events/toc-creation-failed.js +0 -8
  583. package/lib/types/events/toc-creation-failed.js.map +0 -1
  584. package/lib/types/merge-source-tree-context.d.ts +0 -28
  585. package/lib/types/merge-source-tree-context.js +0 -63
  586. package/lib/types/merge-source-tree-context.js.map +0 -1
  587. package/lib/types/plugin/language-entry.d.ts +0 -9
  588. package/lib/types/plugin/language-entry.js +0 -64
  589. package/lib/types/plugin/language-entry.js.map +0 -1
  590. package/lib/types/recipe/recipe.d.ts +0 -22
  591. package/lib/types/recipe/recipe.js +0 -6
  592. package/lib/types/recipe/recipe.js.map +0 -1
  593. package/lib/types/recipe-context.d.ts +0 -9
  594. package/lib/types/recipe-context.js +0 -26
  595. package/lib/types/recipe-context.js.map +0 -1
  596. package/lib/types/save-changes-context.d.ts +0 -17
  597. package/lib/types/save-changes-context.js +0 -42
  598. package/lib/types/save-changes-context.js.map +0 -1
  599. package/lib/types/sdl/sdl.d.ts +0 -10
  600. package/lib/types/sdl/sdl.js +0 -18
  601. package/lib/types/sdl/sdl.js.map +0 -1
  602. package/lib/types/toc/toc-components.d.ts +0 -36
  603. package/lib/types/toc/toc-components.js +0 -94
  604. package/lib/types/toc/toc-components.js.map +0 -1
  605. package/lib/types/toc/toc.d.ts +0 -67
  606. package/lib/types/toc/toc.js +0 -2
  607. package/lib/types/toc/toc.js.map +0 -1
  608. package/lib/types/toc-context.d.ts +0 -12
  609. package/lib/types/toc-context.js +0 -26
  610. package/lib/types/toc-context.js.map +0 -1
@@ -0,0 +1,99 @@
1
+ import { createContext, useContext, useMemo, useState, type ReactNode } from 'react';
2
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@fumadocs/api-docs/components/select';
3
+ import { useOperationContext, useRenderContext } from 'fumadocs-openapi/ui';
4
+ import { CodeSample } from '@/lib/code-samples';
5
+ import { Parameter, requestExamples, type RequestExample } from '@/lib/request-examples';
6
+
7
+ interface ExampleSelection {
8
+ operation: unknown;
9
+ examples: RequestExample[];
10
+ selected: RequestExample;
11
+ select: (id: string) => void;
12
+ }
13
+
14
+ interface LayoutSlots {
15
+ selector: ReactNode;
16
+ usageTabs: ReactNode;
17
+ responseTabs: ReactNode;
18
+ }
19
+
20
+ const SelectionContext = createContext<ExampleSelection | undefined>(undefined);
21
+
22
+ export function useExampleSelection(): ExampleSelection {
23
+ const selection = useContext(SelectionContext);
24
+ if (selection === undefined) throw new Error('useExampleSelection needs an ExampleLayout above it');
25
+ return selection;
26
+ }
27
+
28
+ // Fumadocs' own selector lists request body examples only, and ignores an id outside that list.
29
+ export function renderExampleLayout(slots: Readonly<LayoutSlots>): ReactNode {
30
+ return <ExampleLayout selector={slots.selector} usageTabs={slots.usageTabs} responseTabs={slots.responseTabs} />;
31
+ }
32
+
33
+ // Fumadocs passes a null selector for an operation with `x-exclusiveCodeSample`.
34
+ function ExampleLayout({ selector, usageTabs, responseTabs }: Readonly<LayoutSlots>) {
35
+ const { schema } = useRenderContext();
36
+ const { route, examples: bodyExamples, example: defaultId, setExample } = useOperationContext();
37
+ const pathItem = schema.resolve(schema.dereferenced.paths?.[route]);
38
+ const operation = pathItem?.[bodyExamples[0].data.method];
39
+ // Only SDK samples follow a parameter's example ids; fumadocs' cURL and playground ignore them.
40
+ const examples = useMemo(
41
+ () =>
42
+ CodeSample.listIn(operation).length === 0
43
+ ? bodyExamples
44
+ : requestExamples(bodyExamples, Parameter.listIn(operation, pathItem, schema.resolve)),
45
+ [bodyExamples, operation, pathItem, schema]
46
+ );
47
+ const [selectedId, setSelectedId] = useState(defaultId);
48
+
49
+ const selection = useMemo<ExampleSelection>(
50
+ () => ({
51
+ operation,
52
+ examples,
53
+ selected: examples.find((example) => example.id === selectedId) ?? examples[0],
54
+ select: (id) => {
55
+ setSelectedId(id);
56
+ setExample(id);
57
+ }
58
+ }),
59
+ [operation, examples, selectedId, setExample]
60
+ );
61
+ return (
62
+ <SelectionContext.Provider value={selection}>
63
+ <div className="prose-no-margin">
64
+ {selector === null ? null : <ExampleSelector />}
65
+ {usageTabs}
66
+ {responseTabs}
67
+ </div>
68
+ </SelectionContext.Provider>
69
+ );
70
+ }
71
+
72
+ function ExampleSelector() {
73
+ const { examples, selected, select } = useExampleSelection();
74
+ if (examples.length === 1) return null;
75
+
76
+ const items = examples.map((example) => ({
77
+ value: example.id,
78
+ label: (
79
+ <div>
80
+ <p className="font-medium text-sm">{example.name}</p>
81
+ <p className="text-fd-muted-foreground">{example.description}</p>
82
+ </div>
83
+ )
84
+ }));
85
+ return (
86
+ <Select items={items} value={selected.id} onValueChange={(id) => id !== null && select(id)}>
87
+ <SelectTrigger className="not-prose mb-2">
88
+ <SelectValue />
89
+ </SelectTrigger>
90
+ <SelectContent>
91
+ {items.map((item) => (
92
+ <SelectItem key={item.value} value={item.value}>
93
+ {item.label}
94
+ </SelectItem>
95
+ ))}
96
+ </SelectContent>
97
+ </Select>
98
+ );
99
+ }
@@ -0,0 +1,127 @@
1
+ import { useId, type ReactNode } from 'react';
2
+
3
+ interface LogoProps {
4
+ className?: string;
5
+ }
6
+
7
+ // The languages' own coloured marks, from Devicon 2.17.0 (MIT). Python's drop shadow is left out.
8
+ function CSharpLogo({ className }: Readonly<LogoProps>) {
9
+ return (
10
+ <svg viewBox="0 0 128 128" className={className} aria-hidden="true">
11
+ <path
12
+ fill="#9B4F96"
13
+ d="M115.4 30.7L67.1 2.9c-.8-.5-1.9-.7-3.1-.7-1.2 0-2.3.3-3.1.7l-48 27.9c-1.7 1-2.9 3.5-2.9 5.4v55.7c0 1.1.2 2.4 1 3.5l106.8-62c-.6-1.2-1.5-2.1-2.4-2.7z"
14
+ />
15
+ <path
16
+ fill="#68217A"
17
+ d="M10.7 95.3c.5.8 1.2 1.5 1.9 1.9l48.2 27.9c.8.5 1.9.7 3.1.7 1.2 0 2.3-.3 3.1-.7l48-27.9c1.7-1 2.9-3.5 2.9-5.4V36.1c0-.9-.1-1.9-.6-2.8l-106.6 62z"
18
+ />
19
+ <path
20
+ fill="#fff"
21
+ d="M85.3 76.1C81.1 83.5 73.1 88.5 64 88.5c-13.5 0-24.5-11-24.5-24.5s11-24.5 24.5-24.5c9.1 0 17.1 5 21.3 12.5l13-7.5c-6.8-11.9-19.6-20-34.3-20-21.8 0-39.5 17.7-39.5 39.5s17.7 39.5 39.5 39.5c14.6 0 27.4-8 34.2-19.8l-12.9-7.6zM97 66.2l.9-4.3h-4.2v-4.7h5.1L100 51h4.9l-1.2 6.1h3.8l1.2-6.1h4.8l-1.2 6.1h2.4v4.7h-3.3l-.9 4.3h4.2v4.7h-5.1l-1.2 6h-4.9l1.2-6h-3.8l-1.2 6h-4.8l1.2-6h-2.4v-4.7H97zm4.8 0h3.8l.9-4.3h-3.8l-.9 4.3z"
22
+ />
23
+ </svg>
24
+ );
25
+ }
26
+
27
+ function PythonLogo({ className }: Readonly<LogoProps>) {
28
+ // Unique per logo, so two on one page do not share, or lose, a gradient.
29
+ const id = useId();
30
+ return (
31
+ <svg viewBox="0 0 128 128" className={className} aria-hidden="true">
32
+ <linearGradient
33
+ id={`${id}a`}
34
+ gradientUnits="userSpaceOnUse"
35
+ x1="70.252"
36
+ y1="1237.476"
37
+ x2="170.659"
38
+ y2="1151.089"
39
+ gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"
40
+ >
41
+ <stop offset="0" stopColor="#5A9FD4" />
42
+ <stop offset="1" stopColor="#306998" />
43
+ </linearGradient>
44
+ <linearGradient
45
+ id={`${id}b`}
46
+ gradientUnits="userSpaceOnUse"
47
+ x1="209.474"
48
+ y1="1098.811"
49
+ x2="173.62"
50
+ y2="1149.537"
51
+ gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"
52
+ >
53
+ <stop offset="0" stopColor="#FFD43B" />
54
+ <stop offset="1" stopColor="#FFE873" />
55
+ </linearGradient>
56
+ <path
57
+ fill={`url(#${id}a)`}
58
+ transform="translate(0 10.26)"
59
+ d="M63.391 1.988c-4.222.02-8.252.379-11.8 1.007-10.45 1.846-12.346 5.71-12.346 12.837v9.411h24.693v3.137H29.977c-7.176 0-13.46 4.313-15.426 12.521-2.268 9.405-2.368 15.275 0 25.096 1.755 7.311 5.947 12.519 13.124 12.519h8.491V67.234c0-8.151 7.051-15.34 15.426-15.34h24.665c6.866 0 12.346-5.654 12.346-12.548V15.833c0-6.693-5.646-11.72-12.346-12.837-4.244-.706-8.645-1.027-12.866-1.008zM50.037 9.557c2.55 0 4.634 2.117 4.634 4.721 0 2.593-2.083 4.69-4.634 4.69-2.56 0-4.633-2.097-4.633-4.69-.001-2.604 2.073-4.721 4.633-4.721z"
60
+ />
61
+ <path
62
+ fill={`url(#${id}b)`}
63
+ transform="translate(0 10.26)"
64
+ d="M91.682 28.38v10.966c0 8.5-7.208 15.655-15.426 15.655H51.591c-6.756 0-12.346 5.783-12.346 12.549v23.515c0 6.691 5.818 10.628 12.346 12.547 7.816 2.297 15.312 2.713 24.665 0 6.216-1.801 12.346-5.423 12.346-12.547v-9.412H63.938v-3.138h37.012c7.176 0 9.852-5.005 12.348-12.519 2.578-7.735 2.467-15.174 0-25.096-1.774-7.145-5.161-12.521-12.348-12.521h-9.268zM77.809 87.927c2.561 0 4.634 2.097 4.634 4.692 0 2.602-2.074 4.719-4.634 4.719-2.55 0-4.633-2.117-4.633-4.719 0-2.595 2.083-4.692 4.633-4.692z"
65
+ />
66
+ </svg>
67
+ );
68
+ }
69
+
70
+ function TypeScriptLogo({ className }: Readonly<LogoProps>) {
71
+ return (
72
+ <svg viewBox="0 0 128 128" className={className} aria-hidden="true">
73
+ <path fill="#fff" d="M22.67 47h99.67v73.67H22.67z" />
74
+ <path
75
+ fill="#007acc"
76
+ d="M1.5 63.91v62.5h125v-125H1.5zm100.73-5a15.56 15.56 0 017.82 4.5 20.58 20.58 0 013 4c0 .16-5.4 3.81-8.69 5.85-.12.08-.6-.44-1.13-1.23a7.09 7.09 0 00-5.87-3.53c-3.79-.26-6.23 1.73-6.21 5a4.58 4.58 0 00.54 2.34c.83 1.73 2.38 2.76 7.24 4.86 8.95 3.85 12.78 6.39 15.16 10 2.66 4 3.25 10.46 1.45 15.24-2 5.2-6.9 8.73-13.83 9.9a38.32 38.32 0 01-9.52-.1 23 23 0 01-12.72-6.63c-1.15-1.27-3.39-4.58-3.25-4.82a9.34 9.34 0 011.15-.73L82 101l3.59-2.08.75 1.11a16.78 16.78 0 004.74 4.54c4 2.1 9.46 1.81 12.16-.62a5.43 5.43 0 00.69-6.92c-1-1.39-3-2.56-8.59-5-6.45-2.78-9.23-4.5-11.77-7.24a16.48 16.48 0 01-3.43-6.25 25 25 0 01-.22-8c1.33-6.23 6-10.58 12.82-11.87a31.66 31.66 0 019.49.26zm-29.34 5.24v5.12H56.66v46.23H45.15V69.26H28.88v-5a49.19 49.19 0 01.12-5.17C29.08 59 39 59 51 59h21.83z"
77
+ />
78
+ </svg>
79
+ );
80
+ }
81
+
82
+ // One-colour marks from Simple Icons 16.32.0 (CC0), drawn in the text colour so they follow the theme.
83
+ function ClaudeLogo({ className }: Readonly<LogoProps>) {
84
+ return (
85
+ <svg viewBox="0 0 24 24" className={className} fill="currentColor" aria-hidden="true">
86
+ <path d="m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z" />
87
+ </svg>
88
+ );
89
+ }
90
+
91
+ function CursorLogo({ className }: Readonly<LogoProps>) {
92
+ return (
93
+ <svg viewBox="0 0 24 24" className={className} fill="currentColor" aria-hidden="true">
94
+ <path d="M11.503.131 1.891 5.678a.84.84 0 0 0-.42.726v11.188c0 .3.162.575.42.724l9.609 5.55a1 1 0 0 0 .998 0l9.61-5.55a.84.84 0 0 0 .42-.724V6.404a.84.84 0 0 0-.42-.726L12.497.131a1.01 1.01 0 0 0-.996 0M2.657 6.338h18.55c.263 0 .43.287.297.515L12.23 22.918c-.062.107-.229.064-.229-.06V12.335a.59.59 0 0 0-.295-.51l-9.11-5.257c-.109-.063-.064-.23.061-.23" />
95
+ </svg>
96
+ );
97
+ }
98
+
99
+ function GitHubCopilotLogo({ className }: Readonly<LogoProps>) {
100
+ return (
101
+ <svg viewBox="0 0 24 24" className={className} fill="currentColor" aria-hidden="true">
102
+ <path d="M23.922 16.997C23.061 18.492 18.063 22.02 12 22.02 5.937 22.02.939 18.492.078 16.997A.641.641 0 0 1 0 16.741v-2.869a.883.883 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.098 10.098 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952C7.255 2.937 9.248 1.98 11.978 1.98c2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.841.841 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256Zm-11.75-5.992h-.344a4.359 4.359 0 0 1-.355.508c-.77.947-1.918 1.492-3.508 1.492-1.725 0-2.989-.359-3.782-1.259a2.137 2.137 0 0 1-.085-.104L4 11.746v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.359 4.359 0 0 1-.355-.508Zm2.328 3.25c.549 0 1 .451 1 1v2c0 .549-.451 1-1 1-.549 0-1-.451-1-1v-2c0-.549.451-1 1-1Zm-5 0c.549 0 1 .451 1 1v2c0 .549-.451 1-1 1-.549 0-1-.451-1-1v-2c0-.549.451-1 1-1Zm3.313-6.185c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z" />
103
+ </svg>
104
+ );
105
+ }
106
+
107
+ const LANGUAGE_LOGOS: Record<string, (props: Readonly<LogoProps>) => ReactNode> = {
108
+ csharp: CSharpLogo,
109
+ python: PythonLogo,
110
+ typescript: TypeScriptLogo
111
+ };
112
+
113
+ export const PLATFORMS = [
114
+ { name: 'Claude Code', Logo: ClaudeLogo },
115
+ { name: 'Cursor', Logo: CursorLogo },
116
+ { name: 'GitHub Copilot', Logo: GitHubCopilotLogo }
117
+ ];
118
+
119
+ /** Nothing for a language without a mark, so a language added before its logo still renders. */
120
+ export function LanguageLogo({ language, className }: Readonly<LogoProps & { language: string }>) {
121
+ const Logo = LANGUAGE_LOGOS[language];
122
+ return Logo === undefined ? null : <Logo className={className} />;
123
+ }
124
+
125
+ export function LogoTile({ children }: Readonly<{ children: ReactNode }>) {
126
+ return <span className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-fd-muted">{children}</span>;
127
+ }
@@ -0,0 +1,28 @@
1
+ import defaultMdxComponents from 'fumadocs-ui/mdx';
2
+ import { PluginInstall } from './plugin-install';
3
+ import { PluginLanguage, PluginLanguages, PluginPlatforms } from './plugin-support';
4
+ import { SdkActions } from './sdk-actions';
5
+ import { SdkCard, SdkCards } from './sdk-cards';
6
+
7
+ type MDXComponents = Record<string, unknown>;
8
+
9
+ export function getMDXComponents(components?: MDXComponents) {
10
+ return {
11
+ ...defaultMdxComponents,
12
+ // What the generated SDK and context plugin pages are made of.
13
+ SdkCards,
14
+ SdkCard,
15
+ SdkActions,
16
+ PluginInstall,
17
+ PluginLanguages,
18
+ PluginLanguage,
19
+ PluginPlatforms,
20
+ ...components
21
+ };
22
+ }
23
+
24
+ export const useMDXComponents = getMDXComponents;
25
+
26
+ declare global {
27
+ type MDXProvidedComponents = ReturnType<typeof getMDXComponents>;
28
+ }
@@ -0,0 +1,11 @@
1
+ import { baseOptions } from '@/lib/layout.shared';
2
+ import { HomeLayout } from 'fumadocs-ui/layouts/home';
3
+ import { DefaultNotFound } from 'fumadocs-ui/layouts/home/not-found';
4
+
5
+ export function NotFound() {
6
+ return (
7
+ <HomeLayout {...baseOptions()}>
8
+ <DefaultNotFound />
9
+ </HomeLayout>
10
+ );
11
+ }
@@ -0,0 +1,22 @@
1
+ import { useSyncExternalStore } from 'react';
2
+ import { asMarkdown } from 'fumadocs-core/server';
3
+ import { CommandBlock } from './command-block';
4
+ import { installCommand } from '@/lib/install-command';
5
+ import { portal } from '@/lib/portal';
6
+
7
+ // The origin never changes while the page is open, so there is nothing to subscribe to.
8
+ const noSubscribe = () => () => {};
9
+
10
+ /** The prerender cannot know where the portal is hosted, so the browser swaps in its own origin. */
11
+ export function PluginInstall({ path }: Readonly<{ path: string }>) {
12
+ // Ahead of the hook, which only React may call; either branch is taken in every render of one environment.
13
+ if (asMarkdown()) {
14
+ return <CommandBlock command={installCommand(path, portal.siteUrl)} />;
15
+ }
16
+ const origin = useSyncExternalStore(
17
+ noSubscribe,
18
+ () => window.location.origin,
19
+ () => portal.siteUrl
20
+ );
21
+ return <CommandBlock command={installCommand(path, origin)} />;
22
+ }
@@ -0,0 +1,53 @@
1
+ import type { ReactNode } from 'react';
2
+ import { asMarkdown } from 'fumadocs-core/server';
3
+ import { LanguageLogo, LogoTile, PLATFORMS } from './logos';
4
+
5
+ const CARD = 'flex items-center gap-3 rounded-xl border bg-fd-card p-3 font-medium text-fd-card-foreground';
6
+
7
+ // By the width the page gives the list, not the screen's, up to three to a row.
8
+ function CardGrid({ children }: Readonly<{ children: ReactNode }>) {
9
+ return (
10
+ <div className="not-prose @container my-4">
11
+ <ul className="grid grid-cols-1 gap-3 @md:grid-cols-2 @2xl:grid-cols-3">{children}</ul>
12
+ </div>
13
+ );
14
+ }
15
+
16
+ export function PluginLanguages({ children }: Readonly<{ children?: ReactNode }>) {
17
+ if (asMarkdown()) {
18
+ return children;
19
+ }
20
+ return <CardGrid>{children}</CardGrid>;
21
+ }
22
+
23
+ export function PluginLanguage({ language, name }: Readonly<{ language: string; name: string }>) {
24
+ if (asMarkdown()) {
25
+ return `- ${name}`;
26
+ }
27
+ return (
28
+ <li className={CARD}>
29
+ <LogoTile>
30
+ <LanguageLogo language={language} className="size-5" />
31
+ </LogoTile>
32
+ {name}
33
+ </li>
34
+ );
35
+ }
36
+
37
+ export function PluginPlatforms() {
38
+ if (asMarkdown()) {
39
+ return PLATFORMS.map(({ name }) => `- ${name}`).join('\n');
40
+ }
41
+ return (
42
+ <CardGrid>
43
+ {PLATFORMS.map(({ name, Logo }) => (
44
+ <li key={name} className={CARD}>
45
+ <LogoTile>
46
+ <Logo className="size-5" />
47
+ </LogoTile>
48
+ {name}
49
+ </li>
50
+ ))}
51
+ </CardGrid>
52
+ );
53
+ }
@@ -0,0 +1,79 @@
1
+ import type { ReactNode } from 'react';
2
+ import { asMarkdown } from 'fumadocs-core/server';
3
+ import { buttonVariants } from 'fumadocs-ui/components/ui/button';
4
+ import { Code, Download, Package } from 'lucide-react';
5
+
6
+ export interface SdkActionsProps {
7
+ download: string;
8
+ /** Empty when no source repository is recorded. */
9
+ source: string;
10
+ /** Empty until a release is recorded. */
11
+ packageUrl: string;
12
+ registry: string;
13
+ }
14
+
15
+ export const LINK =
16
+ 'inline-flex items-center gap-1.5 rounded-sm text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fd-ring';
17
+
18
+ export const QUIET_LINK = `${LINK} text-fd-muted-foreground hover:text-fd-foreground`;
19
+
20
+ /** Download, View source and View package: each shown only when there is something behind it. */
21
+ export function SdkActions({ download, source, packageUrl, registry }: Readonly<SdkActionsProps>) {
22
+ // The page's Markdown twin, which the page actions and llms-full.txt hand to an AI assistant.
23
+ if (asMarkdown()) {
24
+ const links = [
25
+ `[Download SDK](${download})`,
26
+ source ? `[View source](${source})` : null,
27
+ packageUrl ? `[View on ${registry}](${packageUrl})` : null
28
+ ];
29
+ return links.filter((link) => link !== null).join(' · ');
30
+ }
31
+ // With a package to install from, the download is one way in among others; without one, it is the way in.
32
+ const leads = packageUrl === '';
33
+ return (
34
+ <div className="not-prose flex flex-wrap items-center gap-x-5 gap-y-2">
35
+ <DownloadLink
36
+ href={download}
37
+ className={leads ? buttonVariants({ color: 'primary', className: 'gap-1.5' }) : QUIET_LINK}
38
+ >
39
+ <Download className="size-4" />
40
+ Download SDK
41
+ </DownloadLink>
42
+ {source ? (
43
+ <ExternalLink href={source} className={QUIET_LINK}>
44
+ <Code className="size-4" />
45
+ View source
46
+ </ExternalLink>
47
+ ) : null}
48
+ {packageUrl ? (
49
+ <ExternalLink href={packageUrl} className={QUIET_LINK}>
50
+ <Package className="size-4" />
51
+ View on {registry}
52
+ </ExternalLink>
53
+ ) : null}
54
+ </div>
55
+ );
56
+ }
57
+
58
+ interface LinkProps {
59
+ href: string;
60
+ className: string;
61
+ children: ReactNode;
62
+ }
63
+
64
+ /** A plain link, not a route: the zip is a file the site serves beside its pages. */
65
+ export function DownloadLink({ href, className, children }: Readonly<LinkProps>) {
66
+ return (
67
+ <a href={href} download className={className}>
68
+ {children}
69
+ </a>
70
+ );
71
+ }
72
+
73
+ export function ExternalLink({ href, className, children }: Readonly<LinkProps>) {
74
+ return (
75
+ <a href={href} target="_blank" rel="noopener noreferrer" className={className}>
76
+ {children}
77
+ </a>
78
+ );
79
+ }
@@ -0,0 +1,100 @@
1
+ import type { ReactNode } from 'react';
2
+ import Link from 'fumadocs-core/link';
3
+ import { asMarkdown } from 'fumadocs-core/server';
4
+ import { ArrowDownToLine, ArrowRight, ExternalLink as ExternalLinkIcon } from 'lucide-react';
5
+ import { CommandBlock } from './command-block';
6
+ import { LanguageLogo, LogoTile } from './logos';
7
+ import { DownloadLink, ExternalLink, LINK, QUIET_LINK, SdkActions, type SdkActionsProps } from './sdk-actions';
8
+
9
+ interface SdkCardProps extends SdkActionsProps {
10
+ language: string;
11
+ name: string;
12
+ /** The language's own page. */
13
+ page: string;
14
+ /** Empty until a release is recorded. */
15
+ install: string;
16
+ }
17
+
18
+ // The height and look of the compact install command, whose place it takes.
19
+ const DOWNLOAD_SLOT =
20
+ 'flex items-center gap-2 rounded-lg border bg-fd-secondary px-4 py-1.5 text-sm font-medium text-fd-secondary-foreground transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fd-ring';
21
+
22
+ // By the width the page gives the cards, not the screen's, so each keeps room for its install command.
23
+ export function SdkCards({ children }: Readonly<{ children?: ReactNode }>) {
24
+ if (asMarkdown()) {
25
+ return children;
26
+ }
27
+ return (
28
+ <div className="not-prose @container my-6">
29
+ <div className="grid grid-cols-1 gap-4 @2xl:grid-cols-2 @4xl:grid-cols-3">{children}</div>
30
+ </div>
31
+ );
32
+ }
33
+
34
+ /** The card's language, for a screen reader's list of links, where every card's would otherwise read the same. */
35
+ function LinkContext({ name }: Readonly<{ name: string }>) {
36
+ return <span className="sr-only">, {name}</span>;
37
+ }
38
+
39
+ // Not a Fumadocs `Card`, which is one link as a whole: the links inside would be links in a link.
40
+ export function SdkCard({ language, name, page, install, ...actions }: Readonly<SdkCardProps>) {
41
+ if (asMarkdown()) {
42
+ const command = install ? `\`${install}\` · ` : '';
43
+ return [`- [${name}](${page}): ${command}`, <SdkActions key="actions" {...actions} />];
44
+ }
45
+ const { download, source, packageUrl, registry } = actions;
46
+ return (
47
+ <article className="flex flex-col rounded-xl border bg-fd-card text-fd-card-foreground">
48
+ <div className="flex flex-1 flex-col gap-4 p-4">
49
+ <div className="flex items-center gap-3">
50
+ <LogoTile>
51
+ <LanguageLogo language={language} className="size-5" />
52
+ </LogoTile>
53
+ <h2 className="text-base font-semibold">{name}</h2>
54
+ </div>
55
+ {/* The way in: the install command once a package is published, the download until then. */}
56
+ {install ? (
57
+ <CommandBlock command={install} compact />
58
+ ) : (
59
+ <DownloadLink href={download} className={DOWNLOAD_SLOT}>
60
+ <ArrowDownToLine className="size-4" />
61
+ Download SDK
62
+ <LinkContext name={name} />
63
+ </DownloadLink>
64
+ )}
65
+ <div className="mt-auto flex flex-wrap items-center gap-x-5 gap-y-2">
66
+ {install ? (
67
+ <DownloadLink href={download} className={`${QUIET_LINK} font-medium`}>
68
+ Download SDK
69
+ <LinkContext name={name} />
70
+ <ArrowDownToLine className="size-4" />
71
+ </DownloadLink>
72
+ ) : null}
73
+ <Link href={page} className={`${LINK} font-medium hover:text-fd-primary`}>
74
+ Overview
75
+ <LinkContext name={name} />
76
+ <ArrowRight className="size-4" />
77
+ </Link>
78
+ </div>
79
+ </div>
80
+ {packageUrl || source ? (
81
+ <div className="flex flex-wrap items-center gap-x-4 gap-y-1 border-t px-4 py-2.5">
82
+ {packageUrl ? (
83
+ <ExternalLink href={packageUrl} className={QUIET_LINK}>
84
+ {registry}
85
+ <LinkContext name={name} />
86
+ <ExternalLinkIcon className="size-3.5" />
87
+ </ExternalLink>
88
+ ) : null}
89
+ {source ? (
90
+ <ExternalLink href={source} className={QUIET_LINK}>
91
+ Source
92
+ <LinkContext name={name} />
93
+ <ExternalLinkIcon className="size-3.5" />
94
+ </ExternalLink>
95
+ ) : null}
96
+ </div>
97
+ ) : null}
98
+ </article>
99
+ );
100
+ }
@@ -0,0 +1,41 @@
1
+ 'use client';
2
+ import {
3
+ SearchDialog,
4
+ SearchDialogClose,
5
+ SearchDialogContent,
6
+ SearchDialogHeader,
7
+ SearchDialogIcon,
8
+ SearchDialogInput,
9
+ SearchDialogList,
10
+ SearchDialogOverlay,
11
+ type SharedProps
12
+ } from 'fumadocs-ui/components/dialog/search';
13
+ import { useDocsSearch } from 'fumadocs-core/search/client';
14
+ import { staticClient } from 'fumadocs-core/search/client/orama-static';
15
+ import { useI18n } from 'fumadocs-ui/contexts/i18n';
16
+
17
+ export default function DefaultSearchDialog(props: SharedProps) {
18
+ const { locale } = useI18n();
19
+ const { search, setSearch, query } = useDocsSearch({
20
+ // Served with an extension so hosts and CDNs give it a JSON content type; without one
21
+ // it went out as application/octet-stream, which some of them attach or refuse.
22
+ client: staticClient({
23
+ from: '/api/search.json',
24
+ locale
25
+ })
26
+ });
27
+
28
+ return (
29
+ <SearchDialog search={search} onSearchChange={setSearch} isLoading={query.isLoading} {...props}>
30
+ <SearchDialogOverlay />
31
+ <SearchDialogContent>
32
+ <SearchDialogHeader>
33
+ <SearchDialogIcon />
34
+ <SearchDialogInput />
35
+ <SearchDialogClose />
36
+ </SearchDialogHeader>
37
+ <SearchDialogList items={query.data !== 'empty' ? query.data : null} />
38
+ </SearchDialogContent>
39
+ </SearchDialog>
40
+ );
41
+ }
@@ -0,0 +1,92 @@
1
+ import { useEffect, useState, type ReactNode } from 'react';
2
+ import { CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger } from 'fumadocs-ui/components/codeblock';
3
+ import { useOperationContext, useRenderContext, useServerContext } from 'fumadocs-openapi/ui';
4
+ import { pathnameFromRequest } from 'fumadocs-openapi/requests/generators';
5
+ import { curl } from 'fumadocs-openapi/requests/generators/curl';
6
+ import { joinURL, resolveServerUrl } from '@fumadocs/api-docs/utils/url';
7
+ import { CodeSample } from '@/lib/code-samples';
8
+ import { CodeBlock } from './code-block';
9
+ import { useExampleSelection } from './example-layout';
10
+
11
+ interface UsageTab {
12
+ id: string;
13
+ label: string;
14
+ body: ReactNode;
15
+ }
16
+
17
+ // The registry Fumadocs passes in adds the operation's `x-codeSamples`, which cannot follow the example selector.
18
+ export function renderUsageTabs(): ReactNode {
19
+ return <UsageTabs />;
20
+ }
21
+
22
+ function UsageTabs() {
23
+ const tabs: UsageTab[] = [
24
+ { id: 'curl', label: curl.label ?? curl.lang, body: <CurlCode /> },
25
+ ...CodeSample.listIn(useExampleSelection().operation).map((sample) => ({
26
+ id: sample.lang,
27
+ label: sample.label,
28
+ body: <SampleCode sample={sample} />
29
+ }))
30
+ ];
31
+
32
+ return (
33
+ <CodeBlockTabs groupId="fumadocs_openapi_requests" defaultValue={tabs[0].id}>
34
+ <CodeBlockTabsList>
35
+ {tabs.map((tab) => (
36
+ <CodeBlockTabsTrigger key={tab.id} value={tab.id}>
37
+ {tab.label}
38
+ </CodeBlockTabsTrigger>
39
+ ))}
40
+ </CodeBlockTabsList>
41
+ {tabs.map((tab) => (
42
+ <CodeBlockTab key={tab.id} value={tab.id}>
43
+ {tab.body}
44
+ </CodeBlockTab>
45
+ ))}
46
+ </CodeBlockTabs>
47
+ );
48
+ }
49
+
50
+ function SampleCode({ sample }: Readonly<{ sample: CodeSample }>) {
51
+ const { examples, selected } = useExampleSelection();
52
+ const source = sample.sourceFor(selected.id, examples.length);
53
+
54
+ if (source === undefined) {
55
+ return <p className="px-4 py-3 text-sm text-fd-muted-foreground">No {sample.label} sample for this example.</p>;
56
+ }
57
+ return <CodeBlock lang={sample.lang} code={source} />;
58
+ }
59
+
60
+ function CurlCode() {
61
+ const { mediaAdapters } = useRenderContext();
62
+ const { route } = useOperationContext();
63
+ const request = useSelectedRequest();
64
+ const serverUrl = useServerUrl();
65
+
66
+ if (request === undefined) return null;
67
+ const url = joinURL(serverUrl, pathnameFromRequest(route, request));
68
+ return <CodeBlock lang={curl.lang} code={curl.generate({ ...request, url }, { mediaAdapters, custom: null })} />;
69
+ }
70
+
71
+ // Fumadocs reports the playground's edits to the selected example through its listeners.
72
+ function useSelectedRequest() {
73
+ const { examples, example, addListener, removeListener } = useOperationContext();
74
+ const [request, setRequest] = useState(() => examples.find((item) => item.id === example)?.encoded);
75
+
76
+ useEffect(() => {
77
+ const listener = (_: unknown, encoded: typeof request) => setRequest(encoded);
78
+ addListener(listener);
79
+ return () => removeListener(listener);
80
+ }, [addListener, removeListener]);
81
+ return request;
82
+ }
83
+
84
+ function useServerUrl(): string {
85
+ const { server } = useServerContext();
86
+ const [origin, setOrigin] = useState<string>();
87
+
88
+ useEffect(() => setOrigin(window.location.origin), []);
89
+ return server && origin
90
+ ? new URL(resolveServerUrl(server.url, server.variables), origin).href
91
+ : 'https://example.com';
92
+ }