@apimatic/cli 1.5.0 → 2.0.0-beta.2

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 +221 -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 +100 -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 +193 -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 +68 -0
  227. package/lib/types/apimatic-config/document.js +161 -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 +154 -442
  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,343 @@
1
+ import type { Document } from 'fumadocs-openapi';
2
+ import { bundle } from '@scalar/json-magic/bundle';
3
+ import { fetchUrls, parseJson, parseYaml, readFiles } from '@scalar/json-magic/bundle/plugins/node';
4
+ import { escapeJsonPointer } from '@scalar/json-magic/helpers/escape-json-pointer';
5
+ import { getSegmentsFromPath } from '@scalar/json-magic/helpers/get-segments-from-path';
6
+ import { getValueByPath } from '@scalar/json-magic/helpers/get-value-by-path';
7
+ import { isJsonObject, JsonObject } from './json';
8
+
9
+ interface Reference {
10
+ /** As written, so a rewrite keeps whatever escaping the rest of the pointer had. */
11
+ raw: string[];
12
+ segments: string[];
13
+ }
14
+
15
+ interface Walk {
16
+ document: JsonObject;
17
+ path: string[];
18
+ references: Map<JsonObject, Reference>;
19
+ targets: Map<string, string[]>;
20
+ inStructure: WeakSet<object>;
21
+ inData: WeakSet<object>;
22
+ }
23
+
24
+ // Where the bundler embeds each referenced file, keyed by a hash of its location, and where it
25
+ // records which location each hash stands for.
26
+ const EXTERNAL = 'x-ext';
27
+ const EXTERNAL_LOCATIONS = 'x-ext-urls';
28
+
29
+ // Where OpenAPI and JSON Schema put a schema: under one of these keys, as a value in one of
30
+ // these maps, or as an entry in one of these lists.
31
+ const SCHEMA_KEYS = new Set([
32
+ 'schema',
33
+ 'itemSchema',
34
+ 'items',
35
+ 'not',
36
+ 'additionalProperties',
37
+ 'unevaluatedProperties',
38
+ 'unevaluatedItems',
39
+ 'contains',
40
+ 'propertyNames',
41
+ 'if',
42
+ 'then',
43
+ 'else',
44
+ 'contentSchema'
45
+ ]);
46
+ const SCHEMA_MAPS = new Set(['properties', 'patternProperties', 'dependentSchemas', '$defs', 'definitions']);
47
+ const SCHEMA_LISTS = new Set(['allOf', 'anyOf', 'oneOf', 'prefixItems']);
48
+
49
+ // Hold values, or examples of them, and never a schema.
50
+ const DATA_KEYS = new Set(['example', 'examples', 'default', 'enum', 'const']);
51
+
52
+ // The segments by which the OpenAPI 3.0 upgrader decides a node is a schema: `isSchemaPath`
53
+ // in @scalar/openapi-upgrader 0.2.15, which fumadocs-openapi bundles rather than depends on,
54
+ // so it cannot be imported. A schema anywhere this misses is upgraded as some other object.
55
+ const UPGRADER_SCHEMA_SEGMENTS = new Set([
56
+ 'properties',
57
+ 'items',
58
+ 'allOf',
59
+ 'anyOf',
60
+ 'oneOf',
61
+ 'not',
62
+ 'additionalProperties',
63
+ 'schema'
64
+ ]);
65
+
66
+ /**
67
+ * The document with every file and URL it references embedded in it, the way fumadocs-openapi
68
+ * bundles a document itself, then reshaped where fumadocs misreads the result.
69
+ *
70
+ * Handing fumadocs one document is also what upgrades a split OpenAPI 3.0 specification: the
71
+ * upgrader recognises a document by its own `openapi` key, so given a path it upgrades the
72
+ * root file alone and leaves `example`, `nullable` and the rest in every referenced file.
73
+ */
74
+ export async function bundleSpec(file: string): Promise<Document> {
75
+ const unresolved: string[] = [];
76
+ let document: JsonObject;
77
+ try {
78
+ document = (await bundle(file, {
79
+ plugins: [readFiles(), fetchUrls(), parseJson(), parseYaml()],
80
+ treeShake: true,
81
+ urlMap: true,
82
+ hooks: {
83
+ onResolveError(node) {
84
+ unresolved.push(String(node.$ref));
85
+ }
86
+ }
87
+ })) as JsonObject;
88
+ } catch (error) {
89
+ throw new Error(`[OpenAPI] Failed to resolve input: ${file}`, { cause: error });
90
+ }
91
+ if (unresolved.length > 0) {
92
+ throw new Error(`[OpenAPI] Failed to resolve $ref in ${file}: ${unresolved.join(', ')}`);
93
+ }
94
+
95
+ // Read for the names of the files, then dropped: every page carries the document's
96
+ // top-level fields, and these are paths on the machine running the build.
97
+ const locations = (document[EXTERNAL_LOCATIONS] ?? {}) as Record<string, string>;
98
+ delete document[EXTERNAL_LOCATIONS];
99
+
100
+ inlinePathItems(document);
101
+ hoistSchemas(document, locations);
102
+ return document as unknown as Document;
103
+ }
104
+
105
+ /**
106
+ * Fumadocs lists a document's operations by reading the methods off each path item without
107
+ * following a `$ref`, so every operation behind one gets no page and no error says so. It does
108
+ * follow a webhook's, but the portal's own readers of the document don't, so they're inlined too.
109
+ */
110
+ function inlinePathItems(document: JsonObject): void {
111
+ for (const items of [document.paths, document.webhooks]) {
112
+ if (!isJsonObject(items)) continue;
113
+ for (const [key, item] of Object.entries(items)) items[key] = dereference(document, item, new Set());
114
+ }
115
+ }
116
+
117
+ // Siblings of a `$ref` override what it points to, as OpenAPI 3.1 has it.
118
+ function dereference(document: JsonObject, item: unknown, seen: Set<string>): unknown {
119
+ if (!isJsonObject(item) || typeof item.$ref !== 'string' || seen.has(item.$ref)) return item;
120
+ seen.add(item.$ref);
121
+ const { $ref, ...siblings } = item;
122
+ const segments = pointerSegments($ref);
123
+ const target = segments && dereference(document, resolve(document, segments), seen);
124
+ return isJsonObject(target) ? { ...target, ...siblings } : item;
125
+ }
126
+
127
+ /**
128
+ * Gives each schema that comes from another file a place in `components/schemas`, named after
129
+ * the file, and points every reference to it there.
130
+ *
131
+ * Left where the bundler puts it, a schema is named after the last segment of the references
132
+ * to it, which for a whole file is the bundler's hash. And the upgrader tells a schema from
133
+ * anything else by where it sits, so a 3.0 `example` at the top of a schema file becomes an
134
+ * Example Object map where a schema's `examples` is a list of values.
135
+ */
136
+ function hoistSchemas(document: JsonObject, locations: Record<string, string>): void {
137
+ const externals = document[EXTERNAL];
138
+ if (!isJsonObject(externals)) return;
139
+
140
+ const { references, targets } = collectReferences(document);
141
+ for (const [target, segments] of passedOnSchemas(document, targets)) targets.set(target, segments);
142
+ if (targets.size === 0) return;
143
+
144
+ rewriteReferences(references, placeSchemas(document, targets, locations));
145
+ removeMovedFiles(document, externals, targets);
146
+ }
147
+
148
+ // Every reference is collected, since each one into a moved file has to follow it, but only
149
+ // those outside data say whether what they point to is a schema.
150
+ function collectReferences(document: JsonObject): Pick<Walk, 'references' | 'targets'> {
151
+ const walk: Walk = {
152
+ document,
153
+ path: [],
154
+ references: new Map(),
155
+ targets: new Map(),
156
+ inStructure: new WeakSet(),
157
+ inData: new WeakSet()
158
+ };
159
+ visit(walk, document, false);
160
+ return walk;
161
+ }
162
+
163
+ function visit(walk: Walk, value: unknown, data: boolean): void {
164
+ if (!firstVisit(walk, value, data)) return;
165
+
166
+ if (Array.isArray(value)) {
167
+ value.forEach((item, index) => visitChild(walk, String(index), item, data));
168
+ return;
169
+ }
170
+
171
+ const node = value as JsonObject;
172
+ record(walk, node, data);
173
+ const named = isNamedMap(walk.path);
174
+ for (const [name, child] of Object.entries(node)) {
175
+ visitChild(walk, name, child, data || (!named && DATA_KEYS.has(name)));
176
+ }
177
+ }
178
+
179
+ function visitChild(walk: Walk, name: string, child: unknown, data: boolean): void {
180
+ walk.path.push(name);
181
+ visit(walk, child, data);
182
+ walk.path.pop();
183
+ }
184
+
185
+ function firstVisit(walk: Walk, value: unknown, data: boolean): value is object {
186
+ if (typeof value !== 'object' || value === null) return false;
187
+ if (walk.inStructure.has(value) || (data && walk.inData.has(value))) return false;
188
+ (data ? walk.inData : walk.inStructure).add(value);
189
+ return true;
190
+ }
191
+
192
+ function record(walk: Walk, node: JsonObject, data: boolean): void {
193
+ const segments = typeof node.$ref === 'string' ? pointerSegments(node.$ref) : undefined;
194
+ if (!segments) return;
195
+ walk.references.set(node, { raw: (node.$ref as string).slice(2).split('/'), segments });
196
+ if (!data && isSchemaPosition(walk.path) && isHoistable(walk.document, segments)) {
197
+ walk.targets.set(key(segments), segments);
198
+ }
199
+ }
200
+
201
+ // In these maps a key is a name, so `default` there is a response and `enum` a property.
202
+ function isNamedMap(path: string[]): boolean {
203
+ const last = path.at(-1) ?? '';
204
+ return SCHEMA_MAPS.has(last) || last === 'responses' || isComponentMap(path);
205
+ }
206
+
207
+ // A schema file that is nothing but a reference makes what it names a schema too, though
208
+ // nothing may reference that from a schema position itself.
209
+ function passedOnSchemas(document: JsonObject, targets: Map<string, string[]>): Map<string, string[]> {
210
+ const found = new Map<string, string[]>();
211
+ for (const segments of targets.values()) {
212
+ let next = passedOn(document, segments);
213
+ while (next && !targets.has(key(next)) && !found.has(key(next))) {
214
+ found.set(key(next), next);
215
+ next = passedOn(document, next);
216
+ }
217
+ }
218
+ return found;
219
+ }
220
+
221
+ function passedOn(document: JsonObject, segments: string[]): string[] | undefined {
222
+ const node = resolve(document, segments);
223
+ const next = isJsonObject(node) && typeof node.$ref === 'string' ? pointerSegments(node.$ref) : undefined;
224
+ return next && isHoistable(document, next) ? next : undefined;
225
+ }
226
+
227
+ /** Files each target under `components/schemas`, and returns the pointer to where each one went. */
228
+ function placeSchemas(
229
+ document: JsonObject,
230
+ targets: Map<string, string[]>,
231
+ locations: Record<string, string>
232
+ ): Map<string, string> {
233
+ const schemas = componentSchemas(document);
234
+ const aliases = findAliases(schemas);
235
+ const moved = new Map<string, string>();
236
+ for (const [target, segments] of targets) {
237
+ const name = aliases.get(target) ?? uniqueName(schemas, preferredName(segments, locations));
238
+ schemas[name] = resolve(document, segments);
239
+ moved.set(target, `#/components/schemas/${escapeJsonPointer(name)}`);
240
+ }
241
+ return moved;
242
+ }
243
+
244
+ function componentSchemas(document: JsonObject): JsonObject {
245
+ if (!isJsonObject(document.components)) document.components = {};
246
+ const components = document.components as JsonObject;
247
+ if (!isJsonObject(components.schemas)) components.schemas = {};
248
+ return components.schemas as JsonObject;
249
+ }
250
+
251
+ // A component that is nothing but a reference to the file already names it; the file's
252
+ // content takes its place rather than sitting beside it under a second name.
253
+ function findAliases(schemas: JsonObject): Map<string, string> {
254
+ const aliases = new Map<string, string>();
255
+ for (const [name, schema] of Object.entries(schemas)) {
256
+ if (!isJsonObject(schema) || typeof schema.$ref !== 'string' || Object.keys(schema).length !== 1) continue;
257
+ const segments = pointerSegments(schema.$ref);
258
+ if (segments && !aliases.has(key(segments))) aliases.set(key(segments), name);
259
+ }
260
+ return aliases;
261
+ }
262
+
263
+ function rewriteReferences(references: Map<JsonObject, Reference>, moved: Map<string, string>): void {
264
+ for (const [node, { raw, segments }] of references) {
265
+ for (let length = segments.length; length >= 2; length--) {
266
+ const pointer = moved.get(key(segments.slice(0, length)));
267
+ if (pointer) {
268
+ node.$ref = [pointer, ...raw.slice(length)].join('/');
269
+ break;
270
+ }
271
+ }
272
+ }
273
+ }
274
+
275
+ // Nothing points into a moved file any more, and left in place the upgrader would convert it a
276
+ // second time. A node moved out of a file stays in it: the file may still be used.
277
+ function removeMovedFiles(document: JsonObject, externals: JsonObject, targets: Map<string, string[]>): void {
278
+ for (const segments of targets.values()) {
279
+ if (segments.length === 2) delete externals[segments[1]];
280
+ }
281
+ if (Object.keys(externals).length === 0) delete document[EXTERNAL];
282
+ }
283
+
284
+ function isSchemaPosition(path: string[]): boolean {
285
+ if (isComponentMap(path, path.length - 1)) return path.at(-2) === 'schemas';
286
+ const parent = path.at(-2) ?? '';
287
+ if (SCHEMA_MAPS.has(parent) || SCHEMA_LISTS.has(parent)) return true;
288
+ return SCHEMA_KEYS.has(path.at(-1) ?? '');
289
+ }
290
+
291
+ // Also a `components` map in a file embedded whole: a full OpenAPI document used as a library.
292
+ function isComponentMap(path: string[], length = path.length): boolean {
293
+ if (length === 2) return path[0] === 'components';
294
+ return length === 4 && path[0] === EXTERNAL && path[2] === 'components';
295
+ }
296
+
297
+ /**
298
+ * A node in an embedded file that the upgrader would not take for a schema where it sits. One
299
+ * inside a schema it does recognise is upgraded, and named, as that schema's part.
300
+ */
301
+ function isHoistable(document: JsonObject, segments: string[]): boolean {
302
+ if (segments[0] !== EXTERNAL || segments.length < 2) return false;
303
+ if (segments.some((segment) => UPGRADER_SCHEMA_SEGMENTS.has(segment) || segment.endsWith('Schema'))) return false;
304
+ return isJsonObject(resolve(document, segments));
305
+ }
306
+
307
+ function preferredName(segments: string[], locations: Record<string, string>): string {
308
+ const [, file, ...inner] = segments;
309
+ const name = inner.at(-1) ?? baseName(locations[file] ?? file);
310
+ // Read back out of a reference, `#` would start a fragment and `%` an escape.
311
+ return name.replace(/[#%]/g, '_').trim() || file;
312
+ }
313
+
314
+ function baseName(location: string): string {
315
+ const last = location.split(/[?#]/)[0].split('/').at(-1) ?? location;
316
+ return last.replace(/\.[^.]+$/, '');
317
+ }
318
+
319
+ function uniqueName(schemas: JsonObject, name: string): string {
320
+ let candidate = name;
321
+ let suffix = 1;
322
+ while (Object.hasOwn(schemas, candidate)) candidate = `${name}-${++suffix}`;
323
+ return candidate;
324
+ }
325
+
326
+ function resolve(document: JsonObject, segments: string[]): unknown {
327
+ return getValueByPath(document, segments).value;
328
+ }
329
+
330
+ // Decoded the way the renderer resolves a reference. `decodeURI` throws on a malformed escape,
331
+ // and a reference it cannot read is left as it is.
332
+ function pointerSegments(ref: string): string[] | undefined {
333
+ if (!ref.startsWith('#/')) return undefined;
334
+ try {
335
+ return getSegmentsFromPath(ref.slice(1));
336
+ } catch {
337
+ return undefined;
338
+ }
339
+ }
340
+
341
+ function key(segments: string[]): string {
342
+ return JSON.stringify(segments);
343
+ }
@@ -0,0 +1,191 @@
1
+ import type { Document } from 'fumadocs-openapi';
2
+ import { isJsonObject } from './json';
3
+ import { OPERATION_METHODS } from './openapi-methods';
4
+
5
+ type Json = Record<string, unknown>;
6
+
7
+ /**
8
+ * Leaves out the operations marked `x-internal: true`. Filtering the document rather than the
9
+ * generated pages is what keeps one out of everything built from it: no page, no sidebar row,
10
+ * no emptied tag folder, and no trace of it or its tag in another page's payload. Returns the
11
+ * very document it was given when nothing is left out, and modifies nothing it was given.
12
+ */
13
+ export function withoutInternalOperations(document: Document): Document {
14
+ const root = document as unknown as Json;
15
+ const paths = pathItemsShown(root, root.paths);
16
+ const webhooks = pathItemsShown(root, root.webhooks);
17
+ if (paths === root.paths && webhooks === root.webhooks) {
18
+ return document;
19
+ }
20
+ const shown: Json = { ...root };
21
+ if (paths !== root.paths) shown.paths = paths;
22
+ if (webhooks !== root.webhooks) shown.webhooks = webhooks;
23
+ withoutEmptiedTags(root, shown);
24
+ return shown as unknown as Document;
25
+ }
26
+
27
+ /** The map as given when nothing in it is hidden, else a copy without what is. */
28
+ function pathItemsShown(root: Json, items: unknown): unknown {
29
+ if (!isJsonObject(items)) {
30
+ return items;
31
+ }
32
+ let changed = false;
33
+ const kept: Json = {};
34
+ for (const [key, item] of Object.entries(items)) {
35
+ const shown = pathItemShown(root, item);
36
+ if (shown !== item) changed = true;
37
+ if (shown !== undefined) kept[key] = shown;
38
+ }
39
+ return changed ? kept : items;
40
+ }
41
+
42
+ /**
43
+ * The path item as given when none of its operations is hidden, a copy without them when some
44
+ * are, or undefined when none is left. A path item that is a reference into the document is
45
+ * followed, and inlined only when something in it is hidden: another path may share it.
46
+ */
47
+ function pathItemShown(root: Json, item: unknown): unknown {
48
+ const resolved = resolvePathItem(root, item);
49
+ if (resolved === undefined) {
50
+ return item;
51
+ }
52
+ // A whole path can be marked internal, as a single operation can.
53
+ if (isInternal(resolved)) {
54
+ return undefined;
55
+ }
56
+ if (!operationsOf(resolved).some(isInternal)) {
57
+ return item;
58
+ }
59
+ const copy = withoutInternal(resolved);
60
+ return holdsOperation(copy) ? copy : undefined;
61
+ }
62
+
63
+ function withoutInternal(item: Json): Json {
64
+ const isShown = (operation: unknown) => !isJsonObject(operation) || !isInternal(operation);
65
+ const copy: Json = { ...item };
66
+ for (const method of OPERATION_METHODS) {
67
+ if (!isShown(copy[method])) delete copy[method];
68
+ }
69
+ if (isJsonObject(item.additionalOperations)) {
70
+ const additional = Object.fromEntries(
71
+ Object.entries(item.additionalOperations).filter(([, operation]) => isShown(operation))
72
+ );
73
+ if (Object.keys(additional).length > 0) copy.additionalOperations = additional;
74
+ else delete copy.additionalOperations;
75
+ }
76
+ return copy;
77
+ }
78
+
79
+ function holdsOperation(item: Json): boolean {
80
+ return OPERATION_METHODS.some((method) => isJsonObject(item[method])) || isJsonObject(item.additionalOperations);
81
+ }
82
+
83
+ function operationsOf(item: Json): Json[] {
84
+ const additional = isJsonObject(item.additionalOperations) ? Object.values(item.additionalOperations) : [];
85
+ return [...OPERATION_METHODS.map((method) => item[method]), ...additional].filter(isJsonObject);
86
+ }
87
+
88
+ /**
89
+ * The path item as it reads once every `#/` reference is followed, the fields written beside
90
+ * each one winning over what it points to, as OpenAPI 3.1 has it and Fumadocs reads it: a
91
+ * split specification reaches a path item through a component that is itself a reference into
92
+ * the bundled files. Undefined for anything that is no object. A reference that cannot be
93
+ * followed is left in place, with what was found on the way.
94
+ */
95
+ function resolvePathItem(root: Json, item: unknown, seen = new Set<string>()): Json | undefined {
96
+ if (!isJsonObject(item)) {
97
+ return undefined;
98
+ }
99
+ const { $ref, ...siblings } = item;
100
+ if (typeof $ref !== 'string' || seen.has($ref)) {
101
+ return item;
102
+ }
103
+ seen.add($ref);
104
+ const target = resolvePathItem(root, resolveLocal(root, $ref), seen);
105
+ return target === undefined ? item : { ...target, ...siblings };
106
+ }
107
+
108
+ function isInternal(node: Json): boolean {
109
+ return node['x-internal'] === true;
110
+ }
111
+
112
+ // Every page's payload carries the document's tags, so a hidden section's name would still reach the reader.
113
+ function withoutEmptiedTags(root: Json, shown: Json): void {
114
+ const kept = tagsUsed(shown);
115
+ const emptied = new Set([...tagsUsed(root)].filter((name) => !kept.has(name)));
116
+ if (emptied.size === 0) {
117
+ return;
118
+ }
119
+ let gone = new Set<string>();
120
+ if (Array.isArray(shown.tags)) {
121
+ gone = tagsThatGo(shown.tags, emptied, kept);
122
+ shown.tags = shown.tags.filter((tag) => !isNamedIn(tag, gone));
123
+ }
124
+ // A tag stands for its operations here, so one kept in `tags` only as a group goes all the same.
125
+ const dropped = new Set([...emptied, ...gone]);
126
+ if (Array.isArray(shown['x-tagGroups'])) {
127
+ shown['x-tagGroups'] = (shown['x-tagGroups'] as unknown[]).flatMap((group) => {
128
+ if (!isJsonObject(group) || !Array.isArray(group.tags)) return [group];
129
+ const tags = group.tags.filter((name) => typeof name !== 'string' || !dropped.has(name));
130
+ return tags.length > 0 ? [{ ...group, tags }] : [];
131
+ });
132
+ }
133
+ }
134
+
135
+ /** The names in `tags` that go: those only removed operations carried, and groups left holding none of the rest. */
136
+ function tagsThatGo(tags: unknown[], emptied: Set<string>, kept: Set<string>): Set<string> {
137
+ const groups = new Set(tags.flatMap(parentOf).filter((name) => !kept.has(name)));
138
+ const names = tags.map(nameOf).filter((name): name is string => name !== undefined);
139
+ // Grown up from the tags that stay regardless, so a cycle of groups holds nothing up on its own.
140
+ const staying = new Set(names.filter((name) => !emptied.has(name) && !groups.has(name)));
141
+ let size = -1;
142
+ while (staying.size !== size) {
143
+ size = staying.size;
144
+ for (const tag of tags) {
145
+ const name = nameOf(tag);
146
+ if (name === undefined || staying.has(name)) parentOf(tag).forEach((parent) => staying.add(parent));
147
+ }
148
+ }
149
+ return new Set(names.filter((name) => !staying.has(name)));
150
+ }
151
+
152
+ function nameOf(tag: unknown): string | undefined {
153
+ return isJsonObject(tag) && typeof tag.name === 'string' ? tag.name : undefined;
154
+ }
155
+
156
+ function isNamedIn(tag: unknown, names: Set<string>): boolean {
157
+ const name = nameOf(tag);
158
+ return name !== undefined && names.has(name);
159
+ }
160
+
161
+ function parentOf(tag: unknown): string[] {
162
+ return isJsonObject(tag) && typeof tag.parent === 'string' ? [tag.parent] : [];
163
+ }
164
+
165
+ function tagsUsed(document: Json): Set<string> {
166
+ const tags = [document.paths, document.webhooks]
167
+ .flatMap((items) => (isJsonObject(items) ? Object.values(items) : []))
168
+ .flatMap((item) => operationsOf(resolvePathItem(document, item) ?? {}))
169
+ .flatMap((operation): unknown[] => (Array.isArray(operation.tags) ? operation.tags : []));
170
+ return new Set(tags.filter((tag): tag is string => typeof tag === 'string'));
171
+ }
172
+
173
+ /** A JSON pointer into the document itself, such as `#/components/pathItems/Pets`. */
174
+ function resolveLocal(root: Json, ref: string): unknown {
175
+ if (!ref.startsWith('#/')) {
176
+ return undefined;
177
+ }
178
+ let node: unknown = root;
179
+ for (const token of ref.slice(2).split('/')) {
180
+ if (!isJsonObject(node)) return undefined;
181
+ let key: string;
182
+ try {
183
+ key = decodeURIComponent(token);
184
+ } catch {
185
+ // A stray `%`: no key of the document is spelt that way, so the reference leads nowhere.
186
+ return undefined;
187
+ }
188
+ node = node[key.replaceAll('~1', '/').replaceAll('~0', '~')];
189
+ }
190
+ return node;
191
+ }
@@ -0,0 +1,15 @@
1
+ interface DocumentedItems {
2
+ operations?: { method: string; path: string }[];
3
+ webhooks?: { method: string; name: string }[];
4
+ }
5
+
6
+ /**
7
+ * The operations and webhooks a reference page documents, as a spec's author names them:
8
+ * `METHOD path`, and `METHOD name (webhook)`. `format` wraps the method and path or name.
9
+ */
10
+ export function operationLabels(page: DocumentedItems, format: (signature: string) => string = (s) => s): string[] {
11
+ return [
12
+ ...(page.operations ?? []).map(({ method, path }) => format(`${method.toUpperCase()} ${path}`)),
13
+ ...(page.webhooks ?? []).map(({ method, name }) => `${format(`${method.toUpperCase()} ${name}`)} (webhook)`)
14
+ ];
15
+ }
@@ -0,0 +1,12 @@
1
+ // Every path-item field holding an operation: Fumadocs pages fewer, but the rest still ride along in payloads.
2
+ export const OPERATION_METHODS: readonly string[] = [
3
+ 'get',
4
+ 'put',
5
+ 'post',
6
+ 'delete',
7
+ 'options',
8
+ 'head',
9
+ 'patch',
10
+ 'trace',
11
+ 'query'
12
+ ];