@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,72 @@
1
+ import type { useOperationContext } from 'fumadocs-openapi/ui';
2
+ import { isJsonObject } from './json';
3
+
4
+ export type RequestExample = Pick<
5
+ ReturnType<typeof useOperationContext>['examples'][number],
6
+ 'id' | 'name' | 'description'
7
+ >;
8
+ type Location = 'path' | 'query' | 'header' | 'cookie';
9
+ type Resolve = (node: unknown) => unknown;
10
+
11
+ interface Example {
12
+ summary?: string;
13
+ description?: string;
14
+ }
15
+
16
+ // Fumadocs upgrades a 3.0 document's singular `example` into an example keyed `default`.
17
+ const PLACEHOLDER_IDS = new Set(['_default', 'default', 'Example']);
18
+
19
+ // The order codegen-v2 consults when the request body names no example ids.
20
+ const NAMING_ORDER: Location[] = ['query', 'header', 'path'];
21
+
22
+ export class Parameter {
23
+ private constructor(
24
+ public readonly location: Location,
25
+ private readonly examples: Map<string, Example>
26
+ ) {}
27
+
28
+ public static listIn(operation: unknown, pathItem: unknown, resolve: Resolve): Parameter[] {
29
+ return [...parametersOf(operation), ...parametersOf(pathItem)].flatMap(
30
+ (entry) => Parameter.from(resolve(entry), resolve) ?? []
31
+ );
32
+ }
33
+
34
+ private static from(entry: unknown, resolve: Resolve): Parameter | undefined {
35
+ if (!isJsonObject(entry) || !isLocation(entry.in) || typeof entry.name !== 'string') {
36
+ return undefined;
37
+ }
38
+ const examples = isJsonObject(entry.examples)
39
+ ? Object.entries(entry.examples)
40
+ .map(([id, example]): [string, unknown] => [id, resolve(example)])
41
+ .filter(isExampleEntry)
42
+ : [];
43
+ return new Parameter(entry.in, new Map(examples));
44
+ }
45
+
46
+ public namedExamples(): [string, Example][] {
47
+ return [...this.examples].filter(([id]) => !PLACEHOLDER_IDS.has(id));
48
+ }
49
+ }
50
+
51
+ export function requestExamples(bodyExamples: RequestExample[], parameters: Parameter[]): RequestExample[] {
52
+ const named = NAMING_ORDER.flatMap((location) =>
53
+ parameters.filter((parameter) => parameter.location === location).map((parameter) => parameter.namedExamples())
54
+ ).find((examples) => examples.length > 0);
55
+ if (bodyExamples.length > 1 || !PLACEHOLDER_IDS.has(bodyExamples[0].id) || named === undefined) {
56
+ return bodyExamples;
57
+ }
58
+ return named.map(([id, { summary, description }]) => ({ id, name: summary || id, description }));
59
+ }
60
+
61
+ function parametersOf(node: unknown): unknown[] {
62
+ return isJsonObject(node) && Array.isArray(node.parameters) ? node.parameters : [];
63
+ }
64
+
65
+ function isLocation(value: unknown): value is Location {
66
+ return value === 'path' || value === 'query' || value === 'header' || value === 'cookie';
67
+ }
68
+
69
+ function isExampleEntry(entry: [string, unknown]): entry is [string, Example] {
70
+ return isJsonObject(entry[1]) && 'value' in entry[1];
71
+ }
72
+
@@ -0,0 +1,21 @@
1
+ import { portal } from './portal';
2
+
3
+ /**
4
+ * Absolute URL of a page, or null when the portal has no configured address.
5
+ * Canonical links and the sitemap are both omitted in that case rather than
6
+ * guessed, since a wrong canonical is worse than none.
7
+ */
8
+ export function absoluteUrl(pageUrl: string): string | null {
9
+ if (!portal.siteUrl) return null;
10
+ return portal.siteUrl + pageUrl;
11
+ }
12
+
13
+ export function canonicalLink(pageUrl: string): { rel: string; href: string }[] {
14
+ const href = absoluteUrl(pageUrl);
15
+ return href === null ? [] : [{ rel: 'canonical', href }];
16
+ }
17
+
18
+ export function renderRobots(): string {
19
+ const sitemap = absoluteUrl('/sitemap.xml');
20
+ return ['User-agent: *', 'Allow: /', ...(sitemap === null ? [] : ['', `Sitemap: ${sitemap}`])].join('\n') + '\n';
21
+ }
@@ -0,0 +1,51 @@
1
+ import type * as PageTree from 'fumadocs-core/page-tree';
2
+ import { createGetUrl } from 'fumadocs-core/source';
3
+
4
+ export const docsRoute = '/';
5
+
6
+ /**
7
+ * Where the reference pages of every specification are mounted, one folder per section
8
+ * beneath it. Shared so the navigation transformer positions the same folder the OpenAPI
9
+ * sections are written into.
10
+ */
11
+ export const apiBaseDir = 'api';
12
+
13
+ const getDocsUrl = createGetUrl(docsRoute);
14
+
15
+ /** Whether a page at `url` sits among these nodes, at any depth. */
16
+ export function containsUrl(nodes: PageTree.Node[], url: string): boolean {
17
+ return nodes.some((node) => {
18
+ if (node.type === 'page') {
19
+ return node.url === url;
20
+ }
21
+ return node.type === 'folder' && (node.index?.url === url || containsUrl(node.children, url));
22
+ });
23
+ }
24
+
25
+ export function getPageMarkdownUrl(page: { slugs: string[]; locale?: string }) {
26
+ const segments = [...page.slugs];
27
+ if (segments.length === 0) {
28
+ segments.push('index.md');
29
+ } else {
30
+ segments[segments.length - 1] += '.md';
31
+ }
32
+
33
+ return { segments, url: getDocsUrl(segments, page.locale) };
34
+ }
35
+
36
+ export function slugsFromSplat(splat: string | undefined): string[] {
37
+ return (splat ?? '')
38
+ .split('/')
39
+ .filter((segment) => segment.length > 0)
40
+ .map(encodeURI);
41
+ }
42
+
43
+ /** @returns page slugs */
44
+ export function decodeMarkdownUrl(segments: string[]) {
45
+ if (segments.length === 0) return [];
46
+
47
+ const out = [...segments];
48
+ out[out.length - 1] = (out.at(-1) ?? '').replace(/\.md$/, '');
49
+ if (out.length === 1 && out[0] === 'index') out.pop();
50
+ return out;
51
+ }
@@ -0,0 +1,104 @@
1
+ import { createBundledHighlighter } from 'shiki/core';
2
+ import { createJavaScriptRegexEngine } from 'shiki/engine/javascript';
3
+
4
+ // Re-exported untouched: Fumadocs imports it from the `shiki` entry point this file stands
5
+ // in for, though the bundle itself builds its highlighter on the JavaScript engine.
6
+ export { createOnigurumaEngine } from 'shiki/engine/oniguruma';
7
+
8
+ type LanguageImport = () => Promise<unknown>;
9
+
10
+ /**
11
+ * Stands in for the `shiki` entry point Fumadocs imports to build its highlighter (see the
12
+ * alias in `vite.config.ts`). That entry carries Shiki's whole catalogue as dynamic imports,
13
+ * so the bundler emits a chunk per grammar and a one-endpoint portal ships some ten megabytes
14
+ * of them for languages nothing on the site is written in. Only what a generated portal can
15
+ * contain is bundled; Fumadocs falls back to plain text for anything outside this map, so an
16
+ * unlisted language renders unhighlighted rather than broken.
17
+ */
18
+ const languages = {
19
+ // The seven the CLI generates SDKs for (src/types/sdk/generate.ts).
20
+ csharp: () => import('shiki/dist/langs/csharp.mjs'),
21
+ go: () => import('shiki/dist/langs/go.mjs'),
22
+ java: () => import('shiki/dist/langs/java.mjs'),
23
+ php: () => import('shiki/dist/langs/php.mjs'),
24
+ python: () => import('shiki/dist/langs/python.mjs'),
25
+ ruby: () => import('shiki/dist/langs/ruby.mjs'),
26
+ typescript: () => import('shiki/dist/langs/typescript.mjs'),
27
+
28
+ // Shell commands, and the shapes a response or a specification is shown in.
29
+ http: () => import('shiki/dist/langs/http.mjs'),
30
+ json: () => import('shiki/dist/langs/json.mjs'),
31
+ jsonc: () => import('shiki/dist/langs/jsonc.mjs'),
32
+ shellscript: () => import('shiki/dist/langs/shellscript.mjs'),
33
+ shellsession: () => import('shiki/dist/langs/shellsession.mjs'),
34
+ xml: () => import('shiki/dist/langs/xml.mjs'),
35
+ yaml: () => import('shiki/dist/langs/yaml.mjs'),
36
+
37
+ // What the Markdown pages beside the reference are written in.
38
+ css: () => import('shiki/dist/langs/css.mjs'),
39
+ diff: () => import('shiki/dist/langs/diff.mjs'),
40
+ graphql: () => import('shiki/dist/langs/graphql.mjs'),
41
+ html: () => import('shiki/dist/langs/html.mjs'),
42
+ javascript: () => import('shiki/dist/langs/javascript.mjs'),
43
+ jsx: () => import('shiki/dist/langs/jsx.mjs'),
44
+ markdown: () => import('shiki/dist/langs/markdown.mjs'),
45
+ sql: () => import('shiki/dist/langs/sql.mjs'),
46
+ tsx: () => import('shiki/dist/langs/tsx.mjs')
47
+ } satisfies Record<string, LanguageImport>;
48
+
49
+ /**
50
+ * Shiki's own bundle resolves `ts` or `yml` through an alias table beside its grammars; a
51
+ * hand-built map has none, so an alias reaches Fumadocs as an unknown language and is replaced
52
+ * with `text`. Each shares its grammar's import, as Shiki's `bundledLanguagesAlias` does, so
53
+ * the bundler still emits one chunk per language rather than one per spelling. Taken from
54
+ * Shiki's `bundledLanguagesInfo`; `test/portal-template.test.ts` holds them to it.
55
+ */
56
+ const aliases: Record<string, keyof typeof languages> = {
57
+ 'c#': 'csharp',
58
+ cs: 'csharp',
59
+ py: 'python',
60
+ rb: 'ruby',
61
+ ts: 'typescript',
62
+ cts: 'typescript',
63
+ mts: 'typescript',
64
+ js: 'javascript',
65
+ cjs: 'javascript',
66
+ mjs: 'javascript',
67
+ bash: 'shellscript',
68
+ sh: 'shellscript',
69
+ shell: 'shellscript',
70
+ zsh: 'shellscript',
71
+ console: 'shellsession',
72
+ yml: 'yaml',
73
+ md: 'markdown',
74
+ gql: 'graphql'
75
+ };
76
+
77
+ export type BundledLanguage = keyof typeof languages;
78
+
79
+ /** The grammar a fence's language names, by its own name or an alias; null for one not bundled. */
80
+ export function bundledLanguage(name: string): BundledLanguage | null {
81
+ if (Object.hasOwn(languages, name)) {
82
+ return name as BundledLanguage;
83
+ }
84
+ return Object.hasOwn(aliases, name) ? aliases[name] : null;
85
+ }
86
+
87
+ const bundledLanguages = {
88
+ ...languages,
89
+ ...Object.fromEntries(Object.entries(aliases).map(([alias, id]) => [alias, languages[id]]))
90
+ } as never;
91
+
92
+ /** The two Fumadocs asks for by default; the rest of Shiki's themes are never requested. */
93
+ const bundledThemes = {
94
+ 'github-light': () => import('shiki/dist/themes/github-light.mjs'),
95
+ 'github-dark': () => import('shiki/dist/themes/github-dark.mjs')
96
+ } as never;
97
+
98
+ export const createHighlighter = createBundledHighlighter({
99
+ langs: bundledLanguages,
100
+ themes: bundledThemes,
101
+ engine: () => createJavaScriptRegexEngine()
102
+ });
103
+
104
+ export { createJavaScriptRegexEngine };
@@ -0,0 +1,20 @@
1
+ import { absoluteUrl } from './seo';
2
+ import { source } from './source.server';
3
+
4
+ export function renderSitemap(): string {
5
+ const urls = ['/', ...source.getPages().map((page) => page.url)];
6
+ const entries = [...new Set(urls)]
7
+ .map((url) => ` <url>\n <loc>${escapeXml(absoluteUrl(url) ?? url)}</loc>\n </url>`)
8
+ .join('\n');
9
+
10
+ return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${entries}\n</urlset>\n`;
11
+ }
12
+
13
+ function escapeXml(value: string): string {
14
+ return value
15
+ .replaceAll('&', '&amp;')
16
+ .replaceAll('<', '&lt;')
17
+ .replaceAll('>', '&gt;')
18
+ .replaceAll('"', '&quot;')
19
+ .replaceAll("'", '&apos;');
20
+ }
@@ -0,0 +1,27 @@
1
+ import { loader } from 'fumadocs-core/source';
2
+ import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons';
3
+ import { openapiPlugin } from 'fumadocs-openapi/server';
4
+ import { docsRoute } from './shared';
5
+ import { docs, generated } from './source';
6
+ import { GENERATED_SOURCE, navigationTransformer, OPENAPI_SOURCE, tabsTransformer } from './navigation';
7
+ import { openApiSource } from './openapi.server';
8
+
9
+ // Reads every OpenAPI document off disk, so this only runs at build time, inside server
10
+ // functions and server route handlers. Importing it from client code fails the build.
11
+ // The generated and reference pages go in under the keys the transformer tells them apart by.
12
+ export const source = loader(
13
+ {
14
+ docs: docs.toFumadocsSource(),
15
+ [GENERATED_SOURCE]: generated.toFumadocsSource(),
16
+ [OPENAPI_SOURCE]: await openApiSource()
17
+ },
18
+ {
19
+ baseUrl: docsRoute,
20
+ plugins: [lucideIconsPlugin(), openapiPlugin()],
21
+ // No fallback tree: it is built from the files that became no node, and `nav.json` never
22
+ // does, so every build would otherwise grow a second tree that nothing renders and that
23
+ // the sidebar payload carries to every visitor. The tabs are formed from the root once it
24
+ // is ordered, which is why their transformer comes second.
25
+ pageTree: { transformers: [navigationTransformer(), tabsTransformer()], generateFallback: false }
26
+ }
27
+ );
@@ -0,0 +1,49 @@
1
+ import { defineDocs } from 'fumadocs-mdx/macro';
2
+ import { applyMdxPreset } from 'fumadocs-mdx/config';
3
+ import { rehypeCodeDefaultOptions } from 'fumadocs-core/mdx-plugins';
4
+ import rehypeRaw from 'rehype-raw';
5
+ import { rehypeCodeTitles, rehypeKeepCodeMeta } from './rehype-code-titles';
6
+
7
+ // What `rehype-raw` must hand on untouched, being MDX's own nodes rather than HTML.
8
+ const MDX_NODE_TYPES = ['mdxFlowExpression', 'mdxJsxFlowElement', 'mdxJsxTextElement', 'mdxTextExpression', 'mdxjsEsm'];
9
+
10
+ // The CLI copies the source's pages here. Relative, because the macro embeds the literal in the
11
+ // browser bundle, and an absolute one would publish the build machine's directories.
12
+ //
13
+ // This module is imported by the browser bundle, so it must stay free of anything that touches
14
+ // the filesystem. The loader that reads the OpenAPI documents lives in `source.server.ts`.
15
+ export const docs = defineDocs({
16
+ dir: 'content',
17
+ docs: { async: true, postprocess: { includeProcessedMarkdown: true } },
18
+ // Restricted to our own file, replacing the default of every .json and .yaml in the
19
+ // content directory. Without it a leftover `meta.json` is loaded as a folder's metadata
20
+ // and applied before the transformer runs -- and since a metadata file hides whatever it
21
+ // does not name, the transformer could not put those pages back.
22
+ meta: { files: ['**/nav.json'] }
23
+ });
24
+
25
+ // The pages the CLI writes into this project, resolved against the Vite root like `content`.
26
+ export const generated = defineDocs({
27
+ dir: 'generated',
28
+ docs: {
29
+ async: true,
30
+ // Its components give their own Markdown, where a string would keep them as JSX tags.
31
+ postprocess: { includeProcessedMarkdown: { output: 'function' } },
32
+ // Options given here replace Fumadocs' defaults, hence the preset.
33
+ mdxOptions: applyMdxPreset({
34
+ // A remote image is never fetched for its size, which would make the build depend on its host.
35
+ remarkImageOptions: { external: false },
36
+ // The SDK pages' design heads a block with its title alone, without Fumadocs' language icon.
37
+ rehypeCodeOptions: { ...rehypeCodeDefaultOptions, icon: false },
38
+ // The SDK docs' HTML fails the build unrendered; not sanitized, as it comes from the owner's own spec.
39
+ // The titles go in after it, and ahead of `rehypeCode`, the first of the defaults, which reads them.
40
+ rehypePlugins: (defaults) => [
41
+ rehypeKeepCodeMeta,
42
+ [rehypeRaw, { passThrough: MDX_NODE_TYPES }],
43
+ rehypeCodeTitles,
44
+ ...defaults
45
+ ]
46
+ })
47
+ },
48
+ meta: { files: ['**/nav.json'] }
49
+ });
@@ -0,0 +1,37 @@
1
+ import type * as PageTree from 'fumadocs-core/page-tree';
2
+ import type { LayoutTab } from 'fumadocs-ui/layouts/shared';
3
+ import { containsUrl, docsRoute } from './shared';
4
+
5
+ /**
6
+ * One tab per root folder at the top of the tree, which is every top-level node once the tabs
7
+ * transformer has run. Given to the layout rather than left to Fumadocs, which links a tab to
8
+ * its folder's first direct page and so leaves out a tab holding only folders -- as the API
9
+ * reference does whenever its operations are grouped. Each stays bound to its folder, which is
10
+ * how the active tab is found.
11
+ */
12
+ export function portalTabs(tree: PageTree.Root): LayoutTab[] {
13
+ return tree.children.flatMap((node) => {
14
+ if (node.type !== 'folder' || node.root !== true) return [];
15
+ // Home keeps the order the root nav.json gives, which need not put the home page first.
16
+ const url = containsUrl([node], docsRoute) ? docsRoute : firstPageUrl(node);
17
+ return url === undefined
18
+ ? []
19
+ : [{ title: node.name, description: node.description, icon: node.icon, url, $folder: node }];
20
+ });
21
+ }
22
+
23
+ /**
24
+ * Depth first, as the sidebar lists them, so the tab opens on the page at its top. A link
25
+ * that leaves the portal is passed over, as Fumadocs passes it over for a folder's own link.
26
+ */
27
+ function firstPageUrl(folder: PageTree.Folder): string | undefined {
28
+ if (folder.index !== undefined) return folder.index.url;
29
+ for (const child of folder.children) {
30
+ if (child.type === 'page' && !child.external) return child.url;
31
+ if (child.type === 'folder') {
32
+ const url = firstPageUrl(child);
33
+ if (url !== undefined) return url;
34
+ }
35
+ }
36
+ return undefined;
37
+ }
@@ -0,0 +1,12 @@
1
+ import { createRouter as createTanStackRouter } from '@tanstack/react-router';
2
+ import { routeTree } from './routeTree.gen';
3
+ import { NotFound } from '@/components/not-found';
4
+
5
+ export function getRouter() {
6
+ return createTanStackRouter({
7
+ routeTree,
8
+ defaultPreload: 'intent',
9
+ scrollRestoration: true,
10
+ defaultNotFoundComponent: NotFound
11
+ });
12
+ }
@@ -0,0 +1,194 @@
1
+ import { createFileRoute, getRouteApi, isNotFound, isRedirect, notFound } from '@tanstack/react-router';
2
+ import { createServerFn } from '@tanstack/react-start';
3
+ import { docs, generated } from '@/lib/source';
4
+ import { source } from '@/lib/source.server';
5
+ import { PortalLayout } from '@/lib/layout';
6
+ import { getPageMarkdownUrl, slugsFromSplat } from '@/lib/shared';
7
+ import { portal } from '@/lib/portal';
8
+ import { absoluteUrl, canonicalLink } from '@/lib/seo';
9
+ import { useFumadocsLoader } from 'fumadocs-core/source/client';
10
+ import { usePathname } from 'fumadocs-core/framework';
11
+ import {
12
+ DocsBody,
13
+ DocsDescription,
14
+ DocsPage,
15
+ DocsTitle,
16
+ MarkdownCopyButton,
17
+ ViewOptionsPopover
18
+ } from 'fumadocs-ui/layouts/notebook/page';
19
+ import { staticFunctionMiddleware } from '@tanstack/start-static-server-functions';
20
+ import { Suspense, use, type ReactNode } from 'react';
21
+ import { useMDXComponents } from '@/components/mdx';
22
+ import { OpenAPIPage } from '@/components/api-page';
23
+ import { slimOpenAPIPageProps } from '@/lib/openapi-slim';
24
+
25
+ const rootRoute = getRouteApi('__root__');
26
+
27
+ /**
28
+ * The collections a Markdown page is compiled into, by the loader source it came from. A
29
+ * page's `path` is relative to its own collection's directory, so it is looked up there.
30
+ */
31
+ const collections = { docs, generated };
32
+
33
+ export const Route = createFileRoute('/$')({
34
+ component: Page,
35
+ loader: async ({ params }) => {
36
+ const slugs = slugsFromSplat(params._splat);
37
+ const data = await loadPage(slugs);
38
+
39
+ if (data.type === 'docs') {
40
+ await collections[data.collection].getPage(data.path)?.preload();
41
+ }
42
+ return data;
43
+ },
44
+ head: ({ loaderData, params }) => {
45
+ const title = loaderData && loaderData.type !== 'home' ? `${loaderData.title} | ${portal.name}` : portal.name;
46
+ const description = loaderData?.description ?? portal.description;
47
+ const pageUrl = `/${slugsFromSplat(params._splat).join('/')}`;
48
+ const absolute = absoluteUrl(pageUrl);
49
+ return {
50
+ // Without the og:* pair, a documentation link pasted into Slack, Teams or LinkedIn
51
+ // unfurls as a bare URL.
52
+ meta: [
53
+ { title },
54
+ ...(description ? [{ name: 'description', content: description }] : []),
55
+ { property: 'og:title', content: title },
56
+ ...(description ? [{ property: 'og:description', content: description }] : []),
57
+ { property: 'og:type', content: 'website' },
58
+ { property: 'og:site_name', content: portal.name },
59
+ ...(absolute ? [{ property: 'og:url', content: absolute }] : []),
60
+ { name: 'twitter:card', content: 'summary' }
61
+ ],
62
+ links: canonicalLink(pageUrl)
63
+ };
64
+ }
65
+ });
66
+
67
+ const serverLoader = createServerFn({
68
+ method: 'GET'
69
+ })
70
+ .validator((slugs: string[]) => slugs)
71
+ .middleware([staticFunctionMiddleware])
72
+ .handler(async ({ data: slugs }) => {
73
+ const page = source.getPage(slugs);
74
+
75
+ if (!page) {
76
+ // A project without content/index.md(x) still gets a landing page.
77
+ if (slugs.length === 0) {
78
+ return { type: 'home' as const, title: portal.name, description: portal.description };
79
+ }
80
+ throw notFound();
81
+ }
82
+
83
+ if (page.type === 'openapi') {
84
+ return {
85
+ type: 'openapi' as const,
86
+ title: page.data.title,
87
+ description: page.data.description ?? null,
88
+ props: slimOpenAPIPageProps(page.data.getOpenAPIPageProps())
89
+ };
90
+ }
91
+
92
+ return {
93
+ type: 'docs' as const,
94
+ collection: page.type,
95
+ title: page.data.title,
96
+ description: page.data.description ?? null,
97
+ path: page.path,
98
+ markdownUrl: getPageMarkdownUrl(page).url
99
+ };
100
+ });
101
+
102
+ // The condition `staticFunctionMiddleware` itself uses to answer from the prerendered cache
103
+ // instead of calling the handler.
104
+ const answeredFromStaticCache = process.env.NODE_ENV === 'production' && typeof document !== 'undefined';
105
+
106
+ /**
107
+ * An unknown URL has no prerendered response, and the middleware fetches one without checking
108
+ * the status, so `.json()` throws on whatever the host returns for a missing file and the
109
+ * error boundary renders in place of the not-found page. Only the cache path is rewritten,
110
+ * where a failed fetch can only mean the page does not exist; everywhere else -- the prerender
111
+ * pass, `portal serve` -- a real failure still surfaces.
112
+ */
113
+ async function loadPage(slugs: string[]) {
114
+ try {
115
+ return await serverLoader({ data: slugs });
116
+ } catch (error) {
117
+ if (!answeredFromStaticCache || isNotFound(error) || isRedirect(error)) throw error;
118
+ // A missing page is the ordinary reason to land here, but a network failure or a host
119
+ // answering with its own error page fails the same way, so the cause is named rather
120
+ // than assumed.
121
+ console.error('Falling back to the not-found page; loading this page failed with:', error);
122
+ throw notFound();
123
+ }
124
+ }
125
+
126
+ function Content({
127
+ collection,
128
+ path,
129
+ markdownUrl
130
+ }: Readonly<{ collection: keyof typeof collections; path: string; markdownUrl: string }>) {
131
+ const page = collections[collection].getPage(path);
132
+ if (!page) throw new Error(`unknown page: ${path}`);
133
+
134
+ const { toc } = use(page.load());
135
+ const PageBody = page.body;
136
+ const pathname = usePathname();
137
+ // Named, or the popover reads `window.location.href` and sends the reader's query and hash on.
138
+ const pageUrl = typeof window === 'undefined' ? pathname : new URL(pathname, window.location.origin).toString();
139
+
140
+ return (
141
+ <DocsPage toc={toc} full={page.full}>
142
+ <DocsTitle>{page.title}</DocsTitle>
143
+ <DocsDescription>{page.description}</DocsDescription>
144
+ <div className="flex flex-row gap-2 items-center border-b -mt-4 pb-6">
145
+ <MarkdownCopyButton markdownUrl={markdownUrl} />
146
+ {/* Sends the reader to an external AI vendor, so a portal published under someone
147
+ else's brand can turn it off. */}
148
+ {portal.pageActions ? <ViewOptionsPopover markdownUrl={markdownUrl} pageUrl={pageUrl} /> : null}
149
+ </div>
150
+ <DocsBody>
151
+ <PageBody components={useMDXComponents()} />
152
+ </DocsBody>
153
+ </DocsPage>
154
+ );
155
+ }
156
+
157
+ function Home({ title, description }: Readonly<{ title: string; description: string | null }>) {
158
+ return (
159
+ <DocsPage>
160
+ <DocsTitle>{title}</DocsTitle>
161
+ {description ? <DocsDescription>{description}</DocsDescription> : null}
162
+ <DocsBody>
163
+ <p>Use the navigation to browse the API reference and guides.</p>
164
+ </DocsBody>
165
+ </DocsPage>
166
+ );
167
+ }
168
+
169
+ function Page() {
170
+ const page = useFumadocsLoader(Route.useLoaderData());
171
+ const { pageTree } = useFumadocsLoader(rootRoute.useLoaderData());
172
+ let content: ReactNode;
173
+
174
+ if (page.type === 'home') {
175
+ content = <Home title={page.title} description={page.description} />;
176
+ } else if (page.type === 'openapi') {
177
+ content = (
178
+ <DocsPage full>
179
+ <DocsTitle>{page.title}</DocsTitle>
180
+ <DocsBody>
181
+ <OpenAPIPage {...page.props} />
182
+ </DocsBody>
183
+ </DocsPage>
184
+ );
185
+ } else {
186
+ content = (
187
+ <Suspense>
188
+ <Content collection={page.collection} path={page.path} markdownUrl={page.markdownUrl} />
189
+ </Suspense>
190
+ );
191
+ }
192
+
193
+ return <PortalLayout tree={pageTree}>{content}</PortalLayout>;
194
+ }
@@ -0,0 +1,56 @@
1
+ import { createRootRoute, HeadContent, Outlet, Scripts } from '@tanstack/react-router';
2
+ import { createServerFn } from '@tanstack/react-start';
3
+ import { staticFunctionMiddleware } from '@tanstack/start-static-server-functions';
4
+ import { source } from '@/lib/source.server';
5
+ import appCss from '@/styles/app.css?url';
6
+ import { RootProvider } from 'fumadocs-ui/provider/tanstack';
7
+ import SearchDialog from '@/components/search';
8
+ import { portal } from '@/lib/portal';
9
+
10
+ // The sidebar tree is the same on every page. Loaded here, once, it is written to a single
11
+ // cache file instead of being repeated in every page's own loader payload.
12
+ const loadPageTree = createServerFn({ method: 'GET' })
13
+ .middleware([staticFunctionMiddleware])
14
+ .handler(async () => ({ pageTree: await source.serializePageTree(source.getPageTree()) }));
15
+
16
+ // Without one the browser tab shows the blank-document icon on every page.
17
+ const iconLinks = portal.favicon
18
+ ? [{ rel: 'icon', href: portal.favicon.url, ...(portal.favicon.type ? { type: portal.favicon.type } : {}) }]
19
+ : [];
20
+
21
+ // A portal fixed to one mode keeps to it whatever the visitor's system prefers, and offers no
22
+ // way out: the layout hides the switch, and the `D` hotkey is turned off here.
23
+ const theme =
24
+ portal.colorMode === 'both'
25
+ ? undefined
26
+ : { forcedTheme: portal.colorMode, defaultTheme: portal.colorMode, enableSystem: false, hotKey: false as const };
27
+
28
+ export const Route = createRootRoute({
29
+ loader: () => loadPageTree(),
30
+ head: () => ({
31
+ meta: [
32
+ { charSet: 'utf-8' },
33
+ { name: 'viewport', content: 'width=device-width, initial-scale=1' },
34
+ { title: portal.name },
35
+ ...(portal.description ? [{ name: 'description', content: portal.description }] : [])
36
+ ],
37
+ links: [{ rel: 'stylesheet', href: appCss }, ...iconLinks]
38
+ }),
39
+ component: RootComponent
40
+ });
41
+
42
+ function RootComponent() {
43
+ return (
44
+ <html lang="en" suppressHydrationWarning>
45
+ <head>
46
+ <HeadContent />
47
+ </head>
48
+ <body className="flex flex-col min-h-screen">
49
+ <RootProvider search={{ SearchDialog }} theme={theme}>
50
+ <Outlet />
51
+ </RootProvider>
52
+ <Scripts />
53
+ </body>
54
+ </html>
55
+ );
56
+ }
@@ -0,0 +1,9 @@
1
+ import { createFileRoute } from '@tanstack/react-router';
2
+ import { source } from '@/lib/source.server';
3
+ import { createFromSource } from 'fumadocs-core/search/server';
4
+
5
+ const server = createFromSource(source, { language: 'english' });
6
+
7
+ export const Route = createFileRoute('/api/search.json')({
8
+ server: { handlers: { GET: () => server.staticGET() } }
9
+ });
@@ -0,0 +1,10 @@
1
+ import { createFileRoute } from '@tanstack/react-router';
2
+ import { renderFull } from '@/lib/llms.server';
3
+
4
+ export const Route = createFileRoute('/llms-full.txt')({
5
+ server: {
6
+ handlers: {
7
+ GET: async () => new Response(await renderFull())
8
+ }
9
+ }
10
+ });