@flanksource/clicky-ui 0.2.14 → 0.2.16

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 (489) hide show
  1. package/dist/chat.cjs +20 -0
  2. package/dist/chat.cjs.map +1 -0
  3. package/dist/chat.d.ts +2 -0
  4. package/dist/chat.d.ts.map +1 -0
  5. package/dist/chat.js +20 -0
  6. package/dist/chat.js.map +1 -0
  7. package/dist/components/Combobox.cjs +19 -9
  8. package/dist/components/Combobox.cjs.map +1 -1
  9. package/dist/components/Combobox.d.ts +10 -0
  10. package/dist/components/Combobox.d.ts.map +1 -1
  11. package/dist/components/Combobox.js +19 -9
  12. package/dist/components/Combobox.js.map +1 -1
  13. package/dist/components/DateTimePicker.cjs +6 -1
  14. package/dist/components/DateTimePicker.cjs.map +1 -1
  15. package/dist/components/DateTimePicker.d.ts +11 -3
  16. package/dist/components/DateTimePicker.d.ts.map +1 -1
  17. package/dist/components/DateTimePicker.js +6 -1
  18. package/dist/components/DateTimePicker.js.map +1 -1
  19. package/dist/components/Field.cjs +33 -0
  20. package/dist/components/Field.cjs.map +1 -0
  21. package/dist/components/Field.d.ts +27 -0
  22. package/dist/components/Field.d.ts.map +1 -0
  23. package/dist/components/Field.js +33 -0
  24. package/dist/components/Field.js.map +1 -0
  25. package/dist/components/FilterBar.cjs +49 -55
  26. package/dist/components/FilterBar.cjs.map +1 -1
  27. package/dist/components/FilterBar.d.ts +2 -2
  28. package/dist/components/FilterBar.d.ts.map +1 -1
  29. package/dist/components/FilterBar.js +44 -50
  30. package/dist/components/FilterBar.js.map +1 -1
  31. package/dist/components/FormatOptionsDropdown.cjs +2 -18
  32. package/dist/components/FormatOptionsDropdown.cjs.map +1 -1
  33. package/dist/components/FormatOptionsDropdown.d.ts +1 -17
  34. package/dist/components/FormatOptionsDropdown.d.ts.map +1 -1
  35. package/dist/components/FormatOptionsDropdown.js +1 -17
  36. package/dist/components/FormatOptionsDropdown.js.map +1 -1
  37. package/dist/components/JsonSchemaForm.cjs +128 -12
  38. package/dist/components/JsonSchemaForm.cjs.map +1 -1
  39. package/dist/components/JsonSchemaForm.d.ts +1 -1
  40. package/dist/components/JsonSchemaForm.d.ts.map +1 -1
  41. package/dist/components/JsonSchemaForm.js +131 -15
  42. package/dist/components/JsonSchemaForm.js.map +1 -1
  43. package/dist/components/MultiSelect.cjs +2 -1
  44. package/dist/components/MultiSelect.cjs.map +1 -1
  45. package/dist/components/MultiSelect.d.ts +5 -1
  46. package/dist/components/MultiSelect.d.ts.map +1 -1
  47. package/dist/components/MultiSelect.js +2 -1
  48. package/dist/components/MultiSelect.js.map +1 -1
  49. package/dist/components/SecretKeySelector.cjs +0 -1
  50. package/dist/components/SecretKeySelector.cjs.map +1 -1
  51. package/dist/components/SecretKeySelector.d.ts +0 -2
  52. package/dist/components/SecretKeySelector.d.ts.map +1 -1
  53. package/dist/components/SecretKeySelector.js +1 -2
  54. package/dist/components/SecretKeySelector.js.map +1 -1
  55. package/dist/components/TreePickerField.cjs +137 -0
  56. package/dist/components/TreePickerField.cjs.map +1 -0
  57. package/dist/components/TreePickerField.d.ts +30 -0
  58. package/dist/components/TreePickerField.d.ts.map +1 -0
  59. package/dist/components/TreePickerField.js +137 -0
  60. package/dist/components/TreePickerField.js.map +1 -0
  61. package/dist/components/WorkloadPicker.cjs +6 -81
  62. package/dist/components/WorkloadPicker.cjs.map +1 -1
  63. package/dist/components/WorkloadPicker.d.ts +1 -20
  64. package/dist/components/WorkloadPicker.d.ts.map +1 -1
  65. package/dist/components/WorkloadPicker.js +3 -78
  66. package/dist/components/WorkloadPicker.js.map +1 -1
  67. package/dist/components/button-variants.cjs +30 -0
  68. package/dist/components/button-variants.cjs.map +1 -0
  69. package/dist/components/button-variants.d.ts +5 -0
  70. package/dist/components/button-variants.d.ts.map +1 -0
  71. package/dist/components/button-variants.js +30 -0
  72. package/dist/components/button-variants.js.map +1 -0
  73. package/dist/components/button.cjs +11 -82
  74. package/dist/components/button.cjs.map +1 -1
  75. package/dist/components/button.d.ts +1 -5
  76. package/dist/components/button.d.ts.map +1 -1
  77. package/dist/components/button.js +5 -76
  78. package/dist/components/button.js.map +1 -1
  79. package/dist/components/filter-bar-utils.cjs +37 -0
  80. package/dist/components/filter-bar-utils.cjs.map +1 -0
  81. package/dist/components/filter-bar-utils.d.ts +4 -0
  82. package/dist/components/filter-bar-utils.d.ts.map +1 -0
  83. package/dist/components/filter-bar-utils.js +37 -0
  84. package/dist/components/filter-bar-utils.js.map +1 -0
  85. package/dist/components/format-options.cjs +20 -0
  86. package/dist/components/format-options.cjs.map +1 -0
  87. package/dist/components/format-options.d.ts +18 -0
  88. package/dist/components/format-options.d.ts.map +1 -0
  89. package/dist/components/format-options.js +20 -0
  90. package/dist/components/format-options.js.map +1 -0
  91. package/dist/components/json-schema-form-array.cjs +13 -17
  92. package/dist/components/json-schema-form-array.cjs.map +1 -1
  93. package/dist/components/json-schema-form-array.d.ts +1 -2
  94. package/dist/components/json-schema-form-array.d.ts.map +1 -1
  95. package/dist/components/json-schema-form-array.js +3 -7
  96. package/dist/components/json-schema-form-array.js.map +1 -1
  97. package/dist/components/json-schema-form-fields.cjs +97 -232
  98. package/dist/components/json-schema-form-fields.cjs.map +1 -1
  99. package/dist/components/json-schema-form-fields.d.ts +51 -6
  100. package/dist/components/json-schema-form-fields.d.ts.map +1 -1
  101. package/dist/components/json-schema-form-fields.js +89 -224
  102. package/dist/components/json-schema-form-fields.js.map +1 -1
  103. package/dist/components/json-schema-form-object.cjs +149 -0
  104. package/dist/components/json-schema-form-object.cjs.map +1 -0
  105. package/dist/components/json-schema-form-object.d.ts +10 -0
  106. package/dist/components/json-schema-form-object.d.ts.map +1 -0
  107. package/dist/components/json-schema-form-object.js +149 -0
  108. package/dist/components/json-schema-form-object.js.map +1 -0
  109. package/dist/components/json-schema-form-preferences.cjs +41 -0
  110. package/dist/components/json-schema-form-preferences.cjs.map +1 -0
  111. package/dist/components/json-schema-form-preferences.d.ts +10 -0
  112. package/dist/components/json-schema-form-preferences.d.ts.map +1 -0
  113. package/dist/components/json-schema-form-preferences.js +41 -0
  114. package/dist/components/json-schema-form-preferences.js.map +1 -0
  115. package/dist/components/json-schema-form-render.cjs +43 -72
  116. package/dist/components/json-schema-form-render.cjs.map +1 -1
  117. package/dist/components/json-schema-form-render.d.ts +5 -33
  118. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  119. package/dist/components/json-schema-form-render.js +41 -70
  120. package/dist/components/json-schema-form-render.js.map +1 -1
  121. package/dist/components/json-schema-form-resolve.cjs +9 -1
  122. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  123. package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
  124. package/dist/components/json-schema-form-resolve.js +9 -1
  125. package/dist/components/json-schema-form-resolve.js.map +1 -1
  126. package/dist/components/json-schema-form-types.d.ts +59 -1
  127. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  128. package/dist/components/json-schema-form-utils.cjs +96 -0
  129. package/dist/components/json-schema-form-utils.cjs.map +1 -0
  130. package/dist/components/json-schema-form-utils.d.ts +17 -0
  131. package/dist/components/json-schema-form-utils.d.ts.map +1 -0
  132. package/dist/components/json-schema-form-utils.js +96 -0
  133. package/dist/components/json-schema-form-utils.js.map +1 -0
  134. package/dist/components/loading.cjs +109 -0
  135. package/dist/components/loading.cjs.map +1 -0
  136. package/dist/components/loading.d.ts +29 -0
  137. package/dist/components/loading.d.ts.map +1 -0
  138. package/dist/components/loading.js +109 -0
  139. package/dist/components/loading.js.map +1 -0
  140. package/dist/components/use-form.cjs +27 -0
  141. package/dist/components/use-form.cjs.map +1 -0
  142. package/dist/components/use-form.d.ts +30 -0
  143. package/dist/components/use-form.d.ts.map +1 -0
  144. package/dist/components/use-form.js +27 -0
  145. package/dist/components/use-form.js.map +1 -0
  146. package/dist/components/workload-picker-utils.cjs +88 -0
  147. package/dist/components/workload-picker-utils.cjs.map +1 -0
  148. package/dist/components/workload-picker-utils.d.ts +34 -0
  149. package/dist/components/workload-picker-utils.d.ts.map +1 -0
  150. package/dist/components/workload-picker-utils.js +88 -0
  151. package/dist/components/workload-picker-utils.js.map +1 -0
  152. package/dist/components.cjs +25 -6
  153. package/dist/components.cjs.map +1 -1
  154. package/dist/components.d.ts +14 -4
  155. package/dist/components.d.ts.map +1 -1
  156. package/dist/components.js +24 -5
  157. package/dist/components.js.map +1 -1
  158. package/dist/data/Badge.cjs +11 -91
  159. package/dist/data/Badge.cjs.map +1 -1
  160. package/dist/data/Badge.d.ts +1 -5
  161. package/dist/data/Badge.d.ts.map +1 -1
  162. package/dist/data/Badge.js +11 -91
  163. package/dist/data/Badge.js.map +1 -1
  164. package/dist/data/Clicky.cjs +4 -3
  165. package/dist/data/Clicky.cjs.map +1 -1
  166. package/dist/data/Clicky.d.ts.map +1 -1
  167. package/dist/data/Clicky.js +4 -3
  168. package/dist/data/Clicky.js.map +1 -1
  169. package/dist/data/DataTable.cjs +161 -156
  170. package/dist/data/DataTable.cjs.map +1 -1
  171. package/dist/data/DataTable.d.ts +25 -4
  172. package/dist/data/DataTable.d.ts.map +1 -1
  173. package/dist/data/DataTable.js +140 -135
  174. package/dist/data/DataTable.js.map +1 -1
  175. package/dist/data/FilterPill.cjs +3 -0
  176. package/dist/data/FilterPill.cjs.map +1 -1
  177. package/dist/data/FilterPill.d.ts.map +1 -1
  178. package/dist/data/FilterPill.js +3 -0
  179. package/dist/data/FilterPill.js.map +1 -1
  180. package/dist/data/Icon.cjs +7 -7
  181. package/dist/data/Icon.cjs.map +1 -1
  182. package/dist/data/Icon.js +7 -7
  183. package/dist/data/Icon.js.map +1 -1
  184. package/dist/data/LogDetails.cjs +5 -14
  185. package/dist/data/LogDetails.cjs.map +1 -1
  186. package/dist/data/LogDetails.d.ts +8 -4
  187. package/dist/data/LogDetails.d.ts.map +1 -1
  188. package/dist/data/LogDetails.js +4 -13
  189. package/dist/data/LogDetails.js.map +1 -1
  190. package/dist/data/LogsTable.cjs +6 -165
  191. package/dist/data/LogsTable.cjs.map +1 -1
  192. package/dist/data/LogsTable.d.ts +2 -15
  193. package/dist/data/LogsTable.d.ts.map +1 -1
  194. package/dist/data/LogsTable.js +6 -165
  195. package/dist/data/LogsTable.js.map +1 -1
  196. package/dist/data/TimeseriesPanel.axes.cjs.map +1 -1
  197. package/dist/data/TimeseriesPanel.axes.js.map +1 -1
  198. package/dist/data/TreeNode.cjs +13 -7
  199. package/dist/data/TreeNode.cjs.map +1 -1
  200. package/dist/data/TreeNode.d.ts.map +1 -1
  201. package/dist/data/TreeNode.js +13 -7
  202. package/dist/data/TreeNode.js.map +1 -1
  203. package/dist/data/badge-variants.cjs +85 -0
  204. package/dist/data/badge-variants.cjs.map +1 -0
  205. package/dist/data/badge-variants.d.ts +6 -0
  206. package/dist/data/badge-variants.d.ts.map +1 -0
  207. package/dist/data/badge-variants.js +85 -0
  208. package/dist/data/badge-variants.js.map +1 -0
  209. package/dist/data/cache-browser/CacheBrowser.cjs +59 -0
  210. package/dist/data/cache-browser/CacheBrowser.cjs.map +1 -0
  211. package/dist/data/cache-browser/CacheBrowser.d.ts +26 -0
  212. package/dist/data/cache-browser/CacheBrowser.d.ts.map +1 -0
  213. package/dist/data/cache-browser/CacheBrowser.js +59 -0
  214. package/dist/data/cache-browser/CacheBrowser.js.map +1 -0
  215. package/dist/data/cache-browser/CacheDetailPanel.cjs +193 -0
  216. package/dist/data/cache-browser/CacheDetailPanel.cjs.map +1 -0
  217. package/dist/data/cache-browser/CacheDetailPanel.d.ts +20 -0
  218. package/dist/data/cache-browser/CacheDetailPanel.d.ts.map +1 -0
  219. package/dist/data/cache-browser/CacheDetailPanel.js +193 -0
  220. package/dist/data/cache-browser/CacheDetailPanel.js.map +1 -0
  221. package/dist/data/cache-browser/CacheStatsOverview.cjs +126 -0
  222. package/dist/data/cache-browser/CacheStatsOverview.cjs.map +1 -0
  223. package/dist/data/cache-browser/CacheStatsOverview.d.ts +17 -0
  224. package/dist/data/cache-browser/CacheStatsOverview.d.ts.map +1 -0
  225. package/dist/data/cache-browser/CacheStatsOverview.js +126 -0
  226. package/dist/data/cache-browser/CacheStatsOverview.js.map +1 -0
  227. package/dist/data/cache-browser/CacheTree.cjs +189 -0
  228. package/dist/data/cache-browser/CacheTree.cjs.map +1 -0
  229. package/dist/data/cache-browser/CacheTree.d.ts +27 -0
  230. package/dist/data/cache-browser/CacheTree.d.ts.map +1 -0
  231. package/dist/data/cache-browser/CacheTree.js +189 -0
  232. package/dist/data/cache-browser/CacheTree.js.map +1 -0
  233. package/dist/data/cache-browser/CacheValue.cjs +86 -0
  234. package/dist/data/cache-browser/CacheValue.cjs.map +1 -0
  235. package/dist/data/cache-browser/CacheValue.d.ts +11 -0
  236. package/dist/data/cache-browser/CacheValue.d.ts.map +1 -0
  237. package/dist/data/cache-browser/CacheValue.js +86 -0
  238. package/dist/data/cache-browser/CacheValue.js.map +1 -0
  239. package/dist/data/cache-browser/adapter.cjs +52 -0
  240. package/dist/data/cache-browser/adapter.cjs.map +1 -0
  241. package/dist/data/cache-browser/adapter.d.ts +48 -0
  242. package/dist/data/cache-browser/adapter.d.ts.map +1 -0
  243. package/dist/data/cache-browser/adapter.js +52 -0
  244. package/dist/data/cache-browser/adapter.js.map +1 -0
  245. package/dist/data/cache-browser/api.cjs +42 -0
  246. package/dist/data/cache-browser/api.cjs.map +1 -0
  247. package/dist/data/cache-browser/api.d.ts +33 -0
  248. package/dist/data/cache-browser/api.d.ts.map +1 -0
  249. package/dist/data/cache-browser/api.js +42 -0
  250. package/dist/data/cache-browser/api.js.map +1 -0
  251. package/dist/data/cache-browser/index.d.ts +9 -0
  252. package/dist/data/cache-browser/index.d.ts.map +1 -0
  253. package/dist/data/cache-browser/types.cjs +7 -0
  254. package/dist/data/cache-browser/types.cjs.map +1 -0
  255. package/dist/data/cache-browser/types.d.ts +78 -0
  256. package/dist/data/cache-browser/types.d.ts.map +1 -0
  257. package/dist/data/cache-browser/types.js +7 -0
  258. package/dist/data/cache-browser/types.js.map +1 -0
  259. package/dist/data/cells/TagList.cjs +4 -101
  260. package/dist/data/cells/TagList.cjs.map +1 -1
  261. package/dist/data/cells/TagList.d.ts +1 -49
  262. package/dist/data/cells/TagList.d.ts.map +1 -1
  263. package/dist/data/cells/TagList.js +3 -100
  264. package/dist/data/cells/TagList.js.map +1 -1
  265. package/dist/data/cells/Timestamp.cjs +3 -192
  266. package/dist/data/cells/Timestamp.cjs.map +1 -1
  267. package/dist/data/cells/Timestamp.d.ts +1 -50
  268. package/dist/data/cells/Timestamp.d.ts.map +1 -1
  269. package/dist/data/cells/Timestamp.js +2 -191
  270. package/dist/data/cells/Timestamp.js.map +1 -1
  271. package/dist/data/cells/tag-utils.cjs +103 -0
  272. package/dist/data/cells/tag-utils.cjs.map +1 -0
  273. package/dist/data/cells/tag-utils.d.ts +51 -0
  274. package/dist/data/cells/tag-utils.d.ts.map +1 -0
  275. package/dist/data/cells/tag-utils.js +103 -0
  276. package/dist/data/cells/tag-utils.js.map +1 -0
  277. package/dist/data/cells/timestamp-format.cjs +193 -0
  278. package/dist/data/cells/timestamp-format.cjs.map +1 -0
  279. package/dist/data/cells/timestamp-format.d.ts +51 -0
  280. package/dist/data/cells/timestamp-format.d.ts.map +1 -0
  281. package/dist/data/cells/timestamp-format.js +193 -0
  282. package/dist/data/cells/timestamp-format.js.map +1 -0
  283. package/dist/data/chat/Chat.cjs +48 -0
  284. package/dist/data/chat/Chat.cjs.map +1 -0
  285. package/dist/data/chat/Chat.d.ts +26 -0
  286. package/dist/data/chat/Chat.d.ts.map +1 -0
  287. package/dist/data/chat/Chat.fixtures.d.ts +6 -0
  288. package/dist/data/chat/Chat.fixtures.d.ts.map +1 -0
  289. package/dist/data/chat/Chat.js +48 -0
  290. package/dist/data/chat/Chat.js.map +1 -0
  291. package/dist/data/chat/Conversation.cjs +34 -0
  292. package/dist/data/chat/Conversation.cjs.map +1 -0
  293. package/dist/data/chat/Conversation.d.ts +11 -0
  294. package/dist/data/chat/Conversation.d.ts.map +1 -0
  295. package/dist/data/chat/Conversation.js +34 -0
  296. package/dist/data/chat/Conversation.js.map +1 -0
  297. package/dist/data/chat/Message.cjs +44 -0
  298. package/dist/data/chat/Message.cjs.map +1 -0
  299. package/dist/data/chat/Message.d.ts +10 -0
  300. package/dist/data/chat/Message.d.ts.map +1 -0
  301. package/dist/data/chat/Message.js +44 -0
  302. package/dist/data/chat/Message.js.map +1 -0
  303. package/dist/data/chat/PromptInput.cjs +61 -0
  304. package/dist/data/chat/PromptInput.cjs.map +1 -0
  305. package/dist/data/chat/PromptInput.d.ts +16 -0
  306. package/dist/data/chat/PromptInput.d.ts.map +1 -0
  307. package/dist/data/chat/PromptInput.js +61 -0
  308. package/dist/data/chat/PromptInput.js.map +1 -0
  309. package/dist/data/chat/ToolCall.cjs +92 -0
  310. package/dist/data/chat/ToolCall.cjs.map +1 -0
  311. package/dist/data/chat/ToolCall.d.ts +14 -0
  312. package/dist/data/chat/ToolCall.d.ts.map +1 -0
  313. package/dist/data/chat/ToolCall.js +92 -0
  314. package/dist/data/chat/ToolCall.js.map +1 -0
  315. package/dist/data/chat/clickyOperationsToTools.cjs +73 -0
  316. package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -0
  317. package/dist/data/chat/clickyOperationsToTools.d.ts +10 -0
  318. package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -0
  319. package/dist/data/chat/clickyOperationsToTools.js +73 -0
  320. package/dist/data/chat/clickyOperationsToTools.js.map +1 -0
  321. package/dist/data/chat/index.d.ts +8 -0
  322. package/dist/data/chat/index.d.ts.map +1 -0
  323. package/dist/data/chat/types.cjs +18 -0
  324. package/dist/data/chat/types.cjs.map +1 -0
  325. package/dist/data/chat/types.d.ts +41 -0
  326. package/dist/data/chat/types.d.ts.map +1 -0
  327. package/dist/data/chat/types.js +18 -0
  328. package/dist/data/chat/types.js.map +1 -0
  329. package/dist/data/data-table-utils.cjs +55 -0
  330. package/dist/data/data-table-utils.cjs.map +1 -0
  331. package/dist/data/data-table-utils.d.ts +24 -0
  332. package/dist/data/data-table-utils.d.ts.map +1 -0
  333. package/dist/data/data-table-utils.js +55 -0
  334. package/dist/data/data-table-utils.js.map +1 -0
  335. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +2 -1
  336. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
  337. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
  338. package/dist/data/diagnostics/DiagnosticsDetailPanel.js +3 -2
  339. package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
  340. package/dist/data/diagnostics/GoroutineCard.cjs +3 -22
  341. package/dist/data/diagnostics/GoroutineCard.cjs.map +1 -1
  342. package/dist/data/diagnostics/GoroutineCard.d.ts +0 -2
  343. package/dist/data/diagnostics/GoroutineCard.d.ts.map +1 -1
  344. package/dist/data/diagnostics/GoroutineCard.js +2 -21
  345. package/dist/data/diagnostics/GoroutineCard.js.map +1 -1
  346. package/dist/data/diagnostics/ThreadCard.cjs +3 -38
  347. package/dist/data/diagnostics/ThreadCard.cjs.map +1 -1
  348. package/dist/data/diagnostics/ThreadCard.d.ts +0 -2
  349. package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -1
  350. package/dist/data/diagnostics/ThreadCard.js +2 -37
  351. package/dist/data/diagnostics/ThreadCard.js.map +1 -1
  352. package/dist/data/diagnostics/state-styles.cjs +59 -0
  353. package/dist/data/diagnostics/state-styles.cjs.map +1 -0
  354. package/dist/data/diagnostics/state-styles.d.ts +5 -0
  355. package/dist/data/diagnostics/state-styles.d.ts.map +1 -0
  356. package/dist/data/diagnostics/state-styles.js +59 -0
  357. package/dist/data/diagnostics/state-styles.js.map +1 -0
  358. package/dist/data/logs-normalize.cjs +166 -0
  359. package/dist/data/logs-normalize.cjs.map +1 -0
  360. package/dist/data/logs-normalize.d.ts +16 -0
  361. package/dist/data/logs-normalize.d.ts.map +1 -0
  362. package/dist/data/logs-normalize.js +166 -0
  363. package/dist/data/logs-normalize.js.map +1 -0
  364. package/dist/data/task-status.cjs +19 -19
  365. package/dist/data/task-status.cjs.map +1 -1
  366. package/dist/data/task-status.js +19 -19
  367. package/dist/data/task-status.js.map +1 -1
  368. package/dist/data/version-info.cjs +3 -3
  369. package/dist/data/version-info.js +3 -3
  370. package/dist/data.cjs +43 -18
  371. package/dist/data.cjs.map +1 -1
  372. package/dist/data.d.ts +11 -5
  373. package/dist/data.d.ts.map +1 -1
  374. package/dist/data.js +30 -5
  375. package/dist/data.js.map +1 -1
  376. package/dist/hooks/density-provider.cjs +38 -0
  377. package/dist/hooks/density-provider.cjs.map +1 -0
  378. package/dist/hooks/density-provider.d.ts +20 -0
  379. package/dist/hooks/density-provider.d.ts.map +1 -0
  380. package/dist/hooks/density-provider.js +38 -0
  381. package/dist/hooks/density-provider.js.map +1 -0
  382. package/dist/hooks/theme-provider.cjs +43 -0
  383. package/dist/hooks/theme-provider.cjs.map +1 -0
  384. package/dist/hooks/theme-provider.d.ts +9 -0
  385. package/dist/hooks/theme-provider.d.ts.map +1 -0
  386. package/dist/hooks/theme-provider.js +43 -0
  387. package/dist/hooks/theme-provider.js.map +1 -0
  388. package/dist/hooks/use-density.cjs +8 -37
  389. package/dist/hooks/use-density.cjs.map +1 -1
  390. package/dist/hooks/use-density.d.ts +5 -20
  391. package/dist/hooks/use-density.d.ts.map +1 -1
  392. package/dist/hooks/use-density.js +9 -38
  393. package/dist/hooks/use-density.js.map +1 -1
  394. package/dist/hooks/use-theme.cjs +10 -43
  395. package/dist/hooks/use-theme.cjs.map +1 -1
  396. package/dist/hooks/use-theme.d.ts +6 -9
  397. package/dist/hooks/use-theme.d.ts.map +1 -1
  398. package/dist/hooks/use-theme.js +11 -44
  399. package/dist/hooks/use-theme.js.map +1 -1
  400. package/dist/hooks.cjs +5 -2
  401. package/dist/hooks.cjs.map +1 -1
  402. package/dist/hooks.d.ts +4 -2
  403. package/dist/hooks.d.ts.map +1 -1
  404. package/dist/hooks.js +5 -2
  405. package/dist/hooks.js.map +1 -1
  406. package/dist/icons/changeIconAliases.cjs +13 -13
  407. package/dist/icons/changeIconAliases.cjs.map +1 -1
  408. package/dist/icons/changeIconAliases.d.ts.map +1 -1
  409. package/dist/icons/changeIconAliases.js +13 -13
  410. package/dist/icons/changeIconAliases.js.map +1 -1
  411. package/dist/index.cjs +78 -30
  412. package/dist/index.cjs.map +1 -1
  413. package/dist/index.js +61 -13
  414. package/dist/index.js.map +1 -1
  415. package/dist/overlay/DropdownMenu.cjs +2 -0
  416. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  417. package/dist/overlay/DropdownMenu.d.ts +3 -1
  418. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  419. package/dist/overlay/DropdownMenu.js +2 -0
  420. package/dist/overlay/DropdownMenu.js.map +1 -1
  421. package/dist/overlay/Modal.cjs +38 -27
  422. package/dist/overlay/Modal.cjs.map +1 -1
  423. package/dist/overlay/Modal.d.ts +8 -2
  424. package/dist/overlay/Modal.d.ts.map +1 -1
  425. package/dist/overlay/Modal.js +38 -27
  426. package/dist/overlay/Modal.js.map +1 -1
  427. package/dist/overlay/modalStack.cjs +35 -0
  428. package/dist/overlay/modalStack.cjs.map +1 -0
  429. package/dist/overlay/modalStack.d.ts +13 -0
  430. package/dist/overlay/modalStack.d.ts.map +1 -0
  431. package/dist/overlay/modalStack.js +35 -0
  432. package/dist/overlay/modalStack.js.map +1 -0
  433. package/dist/rpc/AcceptPicker.cjs +2 -18
  434. package/dist/rpc/AcceptPicker.cjs.map +1 -1
  435. package/dist/rpc/AcceptPicker.d.ts +1 -41
  436. package/dist/rpc/AcceptPicker.d.ts.map +1 -1
  437. package/dist/rpc/AcceptPicker.js +2 -18
  438. package/dist/rpc/AcceptPicker.js.map +1 -1
  439. package/dist/rpc/CommandOutput.cjs +1 -1
  440. package/dist/rpc/CommandOutput.cjs.map +1 -1
  441. package/dist/rpc/CommandOutput.js +1 -1
  442. package/dist/rpc/CommandOutput.js.map +1 -1
  443. package/dist/rpc/EndpointList.cjs +1 -1
  444. package/dist/rpc/EndpointList.cjs.map +1 -1
  445. package/dist/rpc/EndpointList.js +1 -1
  446. package/dist/rpc/EndpointList.js.map +1 -1
  447. package/dist/rpc/FilterForm.cjs +4 -4
  448. package/dist/rpc/FilterForm.cjs.map +1 -1
  449. package/dist/rpc/FilterForm.js +4 -4
  450. package/dist/rpc/FilterForm.js.map +1 -1
  451. package/dist/rpc/OperationCatalog.cjs +38 -60
  452. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  453. package/dist/rpc/OperationCatalog.d.ts +3 -3
  454. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  455. package/dist/rpc/OperationCatalog.js +40 -62
  456. package/dist/rpc/OperationCatalog.js.map +1 -1
  457. package/dist/rpc/OperationCommandPage.cjs.map +1 -1
  458. package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
  459. package/dist/rpc/OperationCommandPage.js.map +1 -1
  460. package/dist/rpc/accept-options.cjs +20 -0
  461. package/dist/rpc/accept-options.cjs.map +1 -0
  462. package/dist/rpc/accept-options.d.ts +42 -0
  463. package/dist/rpc/accept-options.d.ts.map +1 -0
  464. package/dist/rpc/accept-options.js +20 -0
  465. package/dist/rpc/accept-options.js.map +1 -0
  466. package/dist/rpc/classify.cjs +15 -4
  467. package/dist/rpc/classify.cjs.map +1 -1
  468. package/dist/rpc/classify.d.ts.map +1 -1
  469. package/dist/rpc/classify.js +15 -4
  470. package/dist/rpc/classify.js.map +1 -1
  471. package/dist/rpc/clickyMetadata.cjs +13 -3
  472. package/dist/rpc/clickyMetadata.cjs.map +1 -1
  473. package/dist/rpc/clickyMetadata.d.ts +2 -0
  474. package/dist/rpc/clickyMetadata.d.ts.map +1 -1
  475. package/dist/rpc/clickyMetadata.js +14 -4
  476. package/dist/rpc/clickyMetadata.js.map +1 -1
  477. package/dist/rpc/formMetadata.cjs +5 -3
  478. package/dist/rpc/formMetadata.cjs.map +1 -1
  479. package/dist/rpc/formMetadata.d.ts.map +1 -1
  480. package/dist/rpc/formMetadata.js +5 -3
  481. package/dist/rpc/formMetadata.js.map +1 -1
  482. package/dist/rpc.cjs +3 -2
  483. package/dist/rpc.cjs.map +1 -1
  484. package/dist/rpc.d.ts +2 -1
  485. package/dist/rpc.d.ts.map +1 -1
  486. package/dist/rpc.js +2 -1
  487. package/dist/rpc.js.map +1 -1
  488. package/dist/styles.css +1 -1
  489. package/package.json +16 -1
@@ -1 +1 @@
1
- {"version":3,"file":"OperationCommandPage.js","sources":["../../src/rpc/OperationCommandPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { FilterBar } from \"../components/FilterBar\";\nimport type {\n ClickyCommandRuntime,\n ClickyNode,\n ClickyRow,\n ClickyTableRowClick,\n ClickyTableRowHref,\n} from \"../data/Clicky\";\nimport { MethodBadge } from \"../data/MethodBadge\";\nimport { AcceptPicker, type OperationPreviewMode } from \"./AcceptPicker\";\nimport { CommandForm, pathParamNames, submitValue } from \"./CommandForm\";\nimport { CommandOutput } from \"./CommandOutput\";\nimport type { RenderLink } from \"./EndpointList\";\nimport {\n buildInitialParameterValues,\n dataTablePaginationFromForm,\n packParameterValues,\n parametersToFormConfig,\n pruneParameterValues,\n titleCase,\n useDebouncedRecord,\n type ParameterValues,\n} from \"./formMetadata\";\nimport { InlineError } from \"./InlineError\";\nimport { OperationActionDialog } from \"./OperationActionDialog\";\nimport { isPositionalParam, type ExecutionResponse, type ResolvedOperation } from \"./types\";\nimport { useOperationById, type OperationsApiClient } from \"./useOperations\";\n\nexport type OperationCommandPageProps = {\n client: OperationsApiClient;\n operationId?: string;\n operation?: ResolvedOperation;\n operations?: ResolvedOperation[];\n initialValues?: ParameterValues;\n autoRun?: boolean;\n backHref?: string;\n backLabel?: string;\n renderLink?: RenderLink;\n commandRuntime?: ClickyCommandRuntime;\n onNavigate?: (href: string) => void;\n hideLockedPathFilters?: boolean;\n className?: string;\n};\n\nconst EMPTY_PARAMETER_VALUES: ParameterValues = {};\n\nexport function OperationCommandPage({\n client,\n operationId,\n operation: providedOperation,\n operations = providedOperation ? [providedOperation] : [],\n initialValues = EMPTY_PARAMETER_VALUES,\n autoRun,\n backHref,\n backLabel = \"Back\",\n renderLink,\n onNavigate,\n hideLockedPathFilters = Boolean(providedOperation),\n className,\n}: OperationCommandPageProps) {\n const lookup = useOperationById(client, providedOperation ? undefined : operationId);\n const operation = providedOperation ?? lookup.operation;\n const isLoading = providedOperation ? false : lookup.isLoading;\n const [accept, setAccept] = useState(\"application/clicky+json\");\n const [previewMode, setPreviewMode] = useState<OperationPreviewMode>(\"hidden\");\n const [isExecuting, setIsExecuting] = useState(false);\n const [result, setResult] = useState<ExecutionResponse | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [submitError, setSubmitError] = useState(\"\");\n const [hasAutoRun, setHasAutoRun] = useState(false);\n const parameters = operation?.operation.parameters ?? [];\n const isGet = (operation?.method ?? \"\").toUpperCase() === \"GET\";\n const effectiveAutoRun = operation ? (autoRun ?? isGet) : false;\n const parameterSignature = JSON.stringify(\n parameters.map((param) => ({\n name: param.name,\n in: param.in,\n required: param.required ?? false,\n default: param.schema?.default ?? null,\n })),\n );\n const operationKey = `${operation?.method ?? \"\"}:${operation?.path ?? \"\"}:${operation?.operation.operationId ?? \"\"}`;\n const effectiveInitialValues = useMemo(\n () =>\n operation\n ? buildInitialParameterValues(\n parameters,\n operation.method,\n {},\n stripRunnerParams(initialValues),\n )\n : stripRunnerParams(initialValues),\n [initialValues, operation?.method, parameterSignature],\n );\n const pathParameters = parameters.filter((param) => param.in === \"path\");\n const lockedPathValues = useMemo<ParameterValues>(() => {\n const values: ParameterValues = {};\n for (const param of pathParameters) {\n const value = effectiveInitialValues[param.name];\n if (typeof value === \"string\" && value.trim() !== \"\") {\n values[param.name] = value;\n }\n }\n return values;\n }, [effectiveInitialValues, pathParameters]);\n const detailOperation = useMemo(\n () => (operation ? findDetailOperation(operation, operations) : undefined),\n [operation, operations],\n );\n const relatedOperations = useMemo(\n () => (operation ? findRelatedOperations(operation, operations, lockedPathValues) : []),\n [lockedPathValues, operation, operations],\n );\n\n // GET-mode parameter state: filter values + pagination cursor are driven\n // by the page so they can flow natively into <CommandOutput>'s filter bar\n // and pagination footer instead of through a separate OperationQueryFilterBar.\n const [values, setValues] = useState<ParameterValues>(effectiveInitialValues);\n useEffect(() => {\n setValues(effectiveInitialValues);\n setSubmitError(\"\");\n }, [effectiveInitialValues]);\n const debouncedValues = useDebouncedRecord(values, 250);\n\n const lookupQuery = useQuery({\n queryKey: [\"operation-query-lookup\", operation?.method, operation?.path, debouncedValues],\n queryFn: async () => {\n if (!operation) return { filters: {} };\n return (\n (await client.lookupFilters?.(\n operation.path,\n operation.method,\n packParameterValues(debouncedValues, parameters),\n { Accept: \"application/json+clicky\" },\n )) ?? { filters: {} }\n );\n },\n enabled:\n isGet &&\n !!operation &&\n !!client.lookupFilters &&\n parameters.some((param) => param.in === \"query\"),\n staleTime: 30_000,\n retry: 0,\n });\n\n const formConfig = useMemo(() => {\n if (!isGet) return { filters: [] };\n return parametersToFormConfig(parameters, values, setValues, {\n lookup: lookupQuery.data,\n lockedValues: lockedPathValues,\n hideLocked: hideLockedPathFilters,\n });\n }, [isGet, parameters, values, lookupQuery.data, lockedPathValues, hideLockedPathFilters]);\n\n const dataTablePagination = useMemo(\n () => dataTablePaginationFromForm(formConfig.pagination, result),\n [formConfig.pagination, result],\n );\n\n // Ref tracking the last submitted parameter signature so that the\n // auto-submit-on-debounced-change effect and the manual submit button\n // both coordinate against the same \"have I already fired this set of\n // values\" check.\n const lastSubmittedSignature = useRef(\"\");\n\n function handleManualSubmit() {\n if (!operation) return;\n const merged = { ...values, ...lockedPathValues };\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n return (merged[param.name] ?? \"\").trim() === \"\";\n });\n if (missingRequired.length > 0) {\n setSubmitError(\n `Missing required fields: ${missingRequired\n .map((param) => titleCase(param.name))\n .join(\", \")}`,\n );\n return;\n }\n setSubmitError(\"\");\n setHasAutoRun(true);\n lastSubmittedSignature.current = JSON.stringify(pruneParameterValues(merged));\n void executeOperation(merged);\n }\n\n async function executeOperation(values: ParameterValues) {\n if (!operation) return;\n\n setIsExecuting(true);\n setError(null);\n\n try {\n const response = await client.executeCommand(\n operation.path,\n operation.method,\n packParameterValues(values, operation.operation.parameters ?? []),\n { Accept: accept },\n );\n setResult(response);\n } catch (err) {\n setResult(null);\n setError(err);\n } finally {\n setIsExecuting(false);\n }\n }\n\n useEffect(() => {\n setHasAutoRun(false);\n setResult(null);\n setError(null);\n lastSubmittedSignature.current = \"\";\n }, [effectiveAutoRun, operationKey]);\n\n useEffect(() => {\n if (!effectiveAutoRun || !operation || hasAutoRun) return;\n // Auto-run a GET as long as every required parameter has a value. Optional\n // params (limit/offset, filter chips, etc.) get their defaults; the\n // sidebar's \"click → instant table\" flow depends on this not bailing just\n // because the operation declares any parameters at all.\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n return (effectiveInitialValues[param.name] ?? \"\").trim() === \"\";\n });\n if (missingRequired.length > 0) return;\n\n setHasAutoRun(true);\n lastSubmittedSignature.current = JSON.stringify(pruneParameterValues(effectiveInitialValues));\n void executeOperation(effectiveInitialValues);\n }, [\n accept,\n effectiveAutoRun,\n effectiveInitialValues,\n hasAutoRun,\n operationKey,\n parameterSignature,\n ]);\n\n // GET re-runs on debounced filter/pagination changes once the initial\n // auto-run has fired; non-GETs keep their explicit-submit behavior.\n useEffect(() => {\n if (!isGet || !operation || !hasAutoRun) return;\n const merged = { ...debouncedValues, ...lockedPathValues };\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n return (merged[param.name] ?? \"\").trim() === \"\";\n });\n if (missingRequired.length > 0) return;\n const signature = JSON.stringify(pruneParameterValues(merged));\n if (lastSubmittedSignature.current === signature) return;\n lastSubmittedSignature.current = signature;\n void executeOperation(merged);\n }, [isGet, hasAutoRun, debouncedValues, lockedPathValues, parameterSignature]);\n\n const getRowDetailHref = useCallback<ClickyTableRowHref>(\n (row) => {\n if (!detailOperation) return undefined;\n const id = getClickyRowId(row);\n if (!id) return undefined;\n return hrefForOperation(detailOperation, [], { id });\n },\n [detailOperation],\n );\n\n const handleTableRowClick = useCallback<ClickyTableRowClick>(\n (row) => {\n const href = getRowDetailHref(row);\n if (href) onNavigate?.(href);\n },\n [getRowDetailHref, onNavigate],\n );\n\n const backLink =\n backHref == null ? null : renderLink ? (\n renderLink({\n to: backHref,\n className: \"text-sm text-primary underline-offset-4 hover:underline\",\n children: backLabel,\n })\n ) : (\n <a href={backHref} className=\"text-sm text-primary underline-offset-4 hover:underline\">\n {backLabel}\n </a>\n );\n\n if (isLoading) {\n return <div className=\"text-sm text-muted-foreground\">Loading operation...</div>;\n }\n\n if (!operation) {\n return (\n <div className=\"space-y-4\">\n <div className=\"text-sm text-muted-foreground\">\n Unknown operation: <code>{operationId}</code>\n </div>\n {backLink}\n </div>\n );\n }\n\n const { path, method, operation: op } = operation;\n const preview = buildOperationPreview(operation, effectiveInitialValues, accept, previewMode);\n\n return (\n <div className={className ?? \"min-w-0 flex-1 space-y-6 p-6\"}>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0 flex-1\">\n {backLink}\n <div className=\"flex items-center gap-3\">\n <MethodBadge method={method} />\n <h1 className=\"truncate text-xl font-bold\">{op.summary || op.operationId || path}</h1>\n </div>\n <p className=\"mt-1 font-mono text-xs text-muted-foreground\">{path}</p>\n {op.operationId && op.summary && (\n <p className=\"mt-2 font-mono text-xs text-muted-foreground\">{op.operationId}</p>\n )}\n {op.description && op.description !== op.summary && (\n <p className=\"mt-1 text-sm text-muted-foreground\">{op.description}</p>\n )}\n </div>\n <div className=\"flex shrink-0 flex-col items-end gap-3\">\n <div>\n <div className=\"mb-1 text-right text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n Accept\n </div>\n <AcceptPicker\n value={accept}\n onChange={setAccept}\n previewMode={previewMode}\n onPreviewModeChange={setPreviewMode}\n />\n </div>\n {relatedOperations.length > 0 && (\n <div className=\"flex flex-wrap justify-end gap-2\">\n {relatedOperations.map((related) =>\n related.href ? (\n renderLink ? (\n renderLink({\n key: `${related.operation.method}:${related.operation.path}`,\n to: related.href,\n className:\n \"inline-flex h-8 items-center justify-center gap-2 rounded-md border border-input bg-background px-3 text-xs font-medium hover:bg-accent hover:text-accent-foreground\",\n children: related.label,\n })\n ) : (\n <a\n key={`${related.operation.method}:${related.operation.path}`}\n href={related.href}\n className=\"inline-flex h-8 items-center justify-center gap-2 rounded-md border border-input bg-background px-3 text-xs font-medium hover:bg-accent hover:text-accent-foreground\"\n >\n {related.label}\n </a>\n )\n ) : (\n <OperationActionDialog\n key={`${related.operation.method}:${related.operation.path}`}\n operation={related.operation}\n client={client}\n initialValues={lockedPathValues}\n label={related.label}\n defaultAccept={accept}\n {...(onNavigate ? { onNavigateAction: onNavigate } : {})}\n />\n ),\n )}\n </div>\n )}\n </div>\n </div>\n\n <section className=\"space-y-3\">\n {method.toUpperCase() === \"GET\" ? (\n parameters.length > 0 ? (\n // Before a result lands the FilterBar lives here so users can\n // fill in path params / required inputs and submit. Once a\n // result is showing AND auto-run is on (sidebar flow), the same\n // filter chips relocate into the DataTable's filter bar via\n // externalFilters, which is the unified placement the user asked\n // for. The two branches share `formConfig.filters` so the values\n // stay in sync.\n !result || !effectiveAutoRun ? (\n <div className=\"space-y-2\">\n <FilterBar\n autoSubmit={effectiveAutoRun}\n filters={formConfig.filters}\n {...(!effectiveAutoRun ? { onApply: () => handleManualSubmit() } : {})}\n applyLabel=\"Execute request\"\n isPending={isExecuting}\n {...(formConfig.timeRange ? { timeRange: formConfig.timeRange } : {})}\n />\n {submitError && (\n <div className=\"rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive\">\n {submitError}\n </div>\n )}\n </div>\n ) : null\n ) : null\n ) : (\n <div className=\"rounded-lg border p-4\">\n <CommandForm\n parameters={parameters}\n onExecute={(params) => executeOperation(params)}\n isPending={isExecuting}\n method={method}\n path={path}\n accept={accept}\n initialValues={effectiveInitialValues}\n />\n </div>\n )}\n\n {preview && (\n <pre className=\"overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs\">{preview}</pre>\n )}\n </section>\n\n {error ? (\n <InlineError title={`Failed to load ${path} as ${accept}`} error={error} />\n ) : isExecuting || result ? (\n <div role=\"region\" aria-label=\"Response body\">\n <CommandOutput\n response={result}\n loading={isExecuting}\n loadingMessage=\"Loading execution results…\"\n bare\n {...(detailOperation\n ? {\n getTableRowHref: getRowDetailHref,\n onTableRowClick: handleTableRowClick,\n isTableRowClickable: (row: ClickyRow) => Boolean(getRowDetailHref(row)),\n }\n : {})}\n {...(isGet && effectiveAutoRun && formConfig.filters.length > 0\n ? { externalFilters: formConfig.filters }\n : {})}\n {...(isGet && effectiveAutoRun && dataTablePagination\n ? { pagination: dataTablePagination }\n : {})}\n />\n </div>\n ) : null}\n </div>\n );\n}\n\ntype RelatedOperation = {\n operation: ResolvedOperation;\n label: string;\n href?: string;\n};\n\nfunction findRelatedOperations(\n current: ResolvedOperation,\n operations: ResolvedOperation[],\n pathValues: Record<string, string>,\n): RelatedOperation[] {\n if (current.method.toUpperCase() !== \"GET\") return [];\n if (!pathTemplateSatisfied(current.path, pathValues)) return [];\n\n const basePath = current.path.replace(/\\/+$/, \"\");\n return operations\n .filter((candidate) => {\n if (candidate === current) return false;\n if (!candidate.path.startsWith(`${basePath}/`)) return false;\n if (!pathTemplateSatisfied(candidate.path, pathValues)) return false;\n const method = candidate.method.toUpperCase();\n return method === \"GET\" || method === \"POST\" || method === \"PUT\" || method === \"DELETE\";\n })\n .map((related) => {\n const method = related.method.toUpperCase();\n const href = method === \"GET\" ? hrefForOperation(related, [], pathValues) : undefined;\n return {\n operation: related,\n label: operationLabel(related),\n ...(href ? { href } : {}),\n };\n })\n .filter((related) => related.operation.method.toUpperCase() !== \"GET\" || related.href);\n}\n\nfunction findDetailOperation(current: ResolvedOperation, operations: ResolvedOperation[]) {\n const method = current.method.toUpperCase();\n const detailPath = `${current.path.replace(/\\/+$/, \"\")}/{id}`;\n return operations.find(\n (candidate) =>\n candidate.method.toUpperCase() === method &&\n candidate.path === detailPath &&\n candidate.operation.parameters?.some(\n (param) => param.in === \"path\" && param.name === \"id\" && param.required,\n ),\n );\n}\n\nfunction hrefForOperation(\n operation: ResolvedOperation,\n args: string[] = [],\n flags: Record<string, string> = {},\n): string | undefined {\n let route = apiPathToRoutePath(operation.path);\n const consumedFlags = new Set<string>();\n\n pathParamNames(operation.path).forEach((name, index) => {\n const value = flags[name] ?? args[index];\n if (!value) return;\n consumedFlags.add(name);\n route = route.replace(`:${name}`, encodeURIComponent(value));\n });\n\n if (route.includes(\":\")) return undefined;\n\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(flags)) {\n if (value && !consumedFlags.has(key)) search.set(key, value);\n }\n const query = search.toString();\n return query ? `${route}?${query}` : route;\n}\n\nfunction apiPathToRoutePath(path: string): string {\n const cliPath = path\n .trim()\n .replace(/^\\/api\\/v1\\/?/, \"\")\n .replace(/^\\/+/, \"\")\n .replace(/\\/+$/, \"\");\n if (!cliPath) return \"/\";\n return `/${cliPath.replace(/\\{([^}]+)\\}/g, \":$1\")}`;\n}\n\nfunction pathTemplateSatisfied(path: string, values: Record<string, string>) {\n return pathParamNames(path).every((name) => Boolean(values[name]));\n}\n\nfunction operationLabel(operation: ResolvedOperation): string {\n const actionName =\n operation.operation[\"x-clicky\"]?.actionName ||\n operation.path.split(\"/\").filter(Boolean).at(-1) ||\n operation.operation.operationId ||\n operation.method;\n return titleCase(actionName.replace(/[_-]+/g, \" \"));\n}\n\nfunction buildOperationPreview(\n operation: ResolvedOperation,\n values: ParameterValues,\n accept: string,\n mode: OperationPreviewMode,\n) {\n if (mode === \"hidden\") return \"\";\n if (mode === \"cli\") return buildCliPreview(operation, values);\n return buildCurlPreview(operation, values, accept);\n}\n\nfunction buildCurlPreview(operation: ResolvedOperation, values: ParameterValues, accept: string) {\n const params = operation.operation.parameters ?? [];\n const parts = [`curl -X ${operation.method.toUpperCase()}`];\n if (accept !== \"application/json\") parts.push(`-H \"Accept: ${accept}\"`);\n let url = operation.path;\n const queryParts: string[] = [];\n for (const param of params) {\n const value = submitValue(param, values[param.name]);\n if (!value) continue;\n if (param.in === \"path\") {\n url = url.replace(`{${param.name}}`, encodeURIComponent(value));\n } else if (param.in === \"query\") {\n queryParts.push(`${encodeURIComponent(param.name)}=${encodeURIComponent(value)}`);\n }\n }\n if (queryParts.length > 0) url += `?${queryParts.join(\"&\")}`;\n parts.push(`\"${url}\"`);\n return parts.join(\" \");\n}\n\nfunction buildCliPreview(operation: ResolvedOperation, values: ParameterValues) {\n const command = operation.operation[\"x-clicky\"]?.command;\n if (!command) return buildCurlPreview(operation, values, \"application/json\");\n const params = operation.operation.parameters ?? [];\n const positionalNames = new Set(params.filter(isPositionalParam).map((param) => param.name));\n const parts = [command.replaceAll(\"/\", \" \")];\n for (const param of params) {\n const value = submitValue(param, values[param.name]);\n if (!value) continue;\n if (param.in === \"path\" || positionalNames.has(param.name)) {\n parts.push(shellQuote(value));\n continue;\n }\n parts.push(`--${param.name}`, shellQuote(value));\n }\n return parts.join(\" \");\n}\n\nfunction shellQuote(value: string) {\n if (/^[a-zA-Z0-9_./:@-]+$/.test(value)) return value;\n return `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n}\n\nfunction stripRunnerParams(values: ParameterValues): ParameterValues {\n const next: ParameterValues = {};\n for (const [key, value] of Object.entries(values)) {\n if (key === \"autoRun\" || key.startsWith(\"__\")) continue;\n next[key] = value;\n }\n return next;\n}\n\nfunction getClickyRowId(row: ClickyRow) {\n const candidates = [\"_id\", \"id\", \"ID\", \"guid\", \"GUID\"];\n for (const key of candidates) {\n const value = clickyNodeText(row.cells[key]);\n if (value) return value;\n }\n return undefined;\n}\n\nfunction clickyNodeText(node: ClickyNode | undefined): string {\n if (!node) return \"\";\n if (node.plain) return node.plain;\n if (node.text) return node.text;\n if (node.source) return node.source;\n if (node.children) return node.children.map(clickyNodeText).join(\"\");\n if (node.items) return node.items.map(clickyNodeText).join(\" \");\n if (node.fields) return node.fields.map((field) => clickyNodeText(field.value)).join(\" \");\n return \"\";\n}\n"],"names":["values"],"mappings":"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"}
1
+ {"version":3,"file":"OperationCommandPage.js","sources":["../../src/rpc/OperationCommandPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { FilterBar } from \"../components/FilterBar\";\nimport type {\n ClickyCommandRuntime,\n ClickyNode,\n ClickyRow,\n ClickyTableRowClick,\n ClickyTableRowHref,\n} from \"../data/Clicky\";\nimport { MethodBadge } from \"../data/MethodBadge\";\nimport { AcceptPicker } from \"./AcceptPicker\";\nimport type { OperationPreviewMode } from \"./accept-options\";\nimport { CommandForm, pathParamNames, submitValue } from \"./CommandForm\";\nimport { CommandOutput } from \"./CommandOutput\";\nimport type { RenderLink } from \"./EndpointList\";\nimport {\n buildInitialParameterValues,\n dataTablePaginationFromForm,\n packParameterValues,\n parametersToFormConfig,\n pruneParameterValues,\n titleCase,\n useDebouncedRecord,\n type ParameterValues,\n} from \"./formMetadata\";\nimport { InlineError } from \"./InlineError\";\nimport { OperationActionDialog } from \"./OperationActionDialog\";\nimport { isPositionalParam, type ExecutionResponse, type ResolvedOperation } from \"./types\";\nimport { useOperationById, type OperationsApiClient } from \"./useOperations\";\n\nexport type OperationCommandPageProps = {\n client: OperationsApiClient;\n operationId?: string;\n operation?: ResolvedOperation;\n operations?: ResolvedOperation[];\n initialValues?: ParameterValues;\n autoRun?: boolean;\n backHref?: string;\n backLabel?: string;\n renderLink?: RenderLink;\n commandRuntime?: ClickyCommandRuntime;\n onNavigate?: (href: string) => void;\n hideLockedPathFilters?: boolean;\n className?: string;\n};\n\nconst EMPTY_PARAMETER_VALUES: ParameterValues = {};\n\nexport function OperationCommandPage({\n client,\n operationId,\n operation: providedOperation,\n operations = providedOperation ? [providedOperation] : [],\n initialValues = EMPTY_PARAMETER_VALUES,\n autoRun,\n backHref,\n backLabel = \"Back\",\n renderLink,\n onNavigate,\n hideLockedPathFilters = Boolean(providedOperation),\n className,\n}: OperationCommandPageProps) {\n const lookup = useOperationById(client, providedOperation ? undefined : operationId);\n const operation = providedOperation ?? lookup.operation;\n const isLoading = providedOperation ? false : lookup.isLoading;\n const [accept, setAccept] = useState(\"application/clicky+json\");\n const [previewMode, setPreviewMode] = useState<OperationPreviewMode>(\"hidden\");\n const [isExecuting, setIsExecuting] = useState(false);\n const [result, setResult] = useState<ExecutionResponse | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [submitError, setSubmitError] = useState(\"\");\n const [hasAutoRun, setHasAutoRun] = useState(false);\n const parameters = operation?.operation.parameters ?? [];\n const isGet = (operation?.method ?? \"\").toUpperCase() === \"GET\";\n const effectiveAutoRun = operation ? (autoRun ?? isGet) : false;\n const parameterSignature = JSON.stringify(\n parameters.map((param) => ({\n name: param.name,\n in: param.in,\n required: param.required ?? false,\n default: param.schema?.default ?? null,\n })),\n );\n const operationKey = `${operation?.method ?? \"\"}:${operation?.path ?? \"\"}:${operation?.operation.operationId ?? \"\"}`;\n const effectiveInitialValues = useMemo(\n () =>\n operation\n ? buildInitialParameterValues(\n parameters,\n operation.method,\n {},\n stripRunnerParams(initialValues),\n )\n : stripRunnerParams(initialValues),\n [initialValues, operation?.method, parameterSignature],\n );\n const pathParameters = parameters.filter((param) => param.in === \"path\");\n const lockedPathValues = useMemo<ParameterValues>(() => {\n const values: ParameterValues = {};\n for (const param of pathParameters) {\n const value = effectiveInitialValues[param.name];\n if (typeof value === \"string\" && value.trim() !== \"\") {\n values[param.name] = value;\n }\n }\n return values;\n }, [effectiveInitialValues, pathParameters]);\n const detailOperation = useMemo(\n () => (operation ? findDetailOperation(operation, operations) : undefined),\n [operation, operations],\n );\n const relatedOperations = useMemo(\n () => (operation ? findRelatedOperations(operation, operations, lockedPathValues) : []),\n [lockedPathValues, operation, operations],\n );\n\n // GET-mode parameter state: filter values + pagination cursor are driven\n // by the page so they can flow natively into <CommandOutput>'s filter bar\n // and pagination footer instead of through a separate OperationQueryFilterBar.\n const [values, setValues] = useState<ParameterValues>(effectiveInitialValues);\n useEffect(() => {\n setValues(effectiveInitialValues);\n setSubmitError(\"\");\n }, [effectiveInitialValues]);\n const debouncedValues = useDebouncedRecord(values, 250);\n\n const lookupQuery = useQuery({\n queryKey: [\"operation-query-lookup\", operation?.method, operation?.path, debouncedValues],\n queryFn: async () => {\n if (!operation) return { filters: {} };\n return (\n (await client.lookupFilters?.(\n operation.path,\n operation.method,\n packParameterValues(debouncedValues, parameters),\n { Accept: \"application/json+clicky\" },\n )) ?? { filters: {} }\n );\n },\n enabled:\n isGet &&\n !!operation &&\n !!client.lookupFilters &&\n parameters.some((param) => param.in === \"query\"),\n staleTime: 30_000,\n retry: 0,\n });\n\n const formConfig = useMemo(() => {\n if (!isGet) return { filters: [] };\n return parametersToFormConfig(parameters, values, setValues, {\n lookup: lookupQuery.data,\n lockedValues: lockedPathValues,\n hideLocked: hideLockedPathFilters,\n });\n }, [isGet, parameters, values, lookupQuery.data, lockedPathValues, hideLockedPathFilters]);\n\n const dataTablePagination = useMemo(\n () => dataTablePaginationFromForm(formConfig.pagination, result),\n [formConfig.pagination, result],\n );\n\n // Ref tracking the last submitted parameter signature so that the\n // auto-submit-on-debounced-change effect and the manual submit button\n // both coordinate against the same \"have I already fired this set of\n // values\" check.\n const lastSubmittedSignature = useRef(\"\");\n\n function handleManualSubmit() {\n if (!operation) return;\n const merged = { ...values, ...lockedPathValues };\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n return (merged[param.name] ?? \"\").trim() === \"\";\n });\n if (missingRequired.length > 0) {\n setSubmitError(\n `Missing required fields: ${missingRequired\n .map((param) => titleCase(param.name))\n .join(\", \")}`,\n );\n return;\n }\n setSubmitError(\"\");\n setHasAutoRun(true);\n lastSubmittedSignature.current = JSON.stringify(pruneParameterValues(merged));\n void executeOperation(merged);\n }\n\n async function executeOperation(values: ParameterValues) {\n if (!operation) return;\n\n setIsExecuting(true);\n setError(null);\n\n try {\n const response = await client.executeCommand(\n operation.path,\n operation.method,\n packParameterValues(values, operation.operation.parameters ?? []),\n { Accept: accept },\n );\n setResult(response);\n } catch (err) {\n setResult(null);\n setError(err);\n } finally {\n setIsExecuting(false);\n }\n }\n\n useEffect(() => {\n setHasAutoRun(false);\n setResult(null);\n setError(null);\n lastSubmittedSignature.current = \"\";\n }, [effectiveAutoRun, operationKey]);\n\n useEffect(() => {\n if (!effectiveAutoRun || !operation || hasAutoRun) return;\n // Auto-run a GET as long as every required parameter has a value. Optional\n // params (limit/offset, filter chips, etc.) get their defaults; the\n // sidebar's \"click → instant table\" flow depends on this not bailing just\n // because the operation declares any parameters at all.\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n return (effectiveInitialValues[param.name] ?? \"\").trim() === \"\";\n });\n if (missingRequired.length > 0) return;\n\n setHasAutoRun(true);\n lastSubmittedSignature.current = JSON.stringify(pruneParameterValues(effectiveInitialValues));\n void executeOperation(effectiveInitialValues);\n }, [\n accept,\n effectiveAutoRun,\n effectiveInitialValues,\n hasAutoRun,\n operationKey,\n parameterSignature,\n ]);\n\n // GET re-runs on debounced filter/pagination changes once the initial\n // auto-run has fired; non-GETs keep their explicit-submit behavior.\n useEffect(() => {\n if (!isGet || !operation || !hasAutoRun) return;\n const merged = { ...debouncedValues, ...lockedPathValues };\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n return (merged[param.name] ?? \"\").trim() === \"\";\n });\n if (missingRequired.length > 0) return;\n const signature = JSON.stringify(pruneParameterValues(merged));\n if (lastSubmittedSignature.current === signature) return;\n lastSubmittedSignature.current = signature;\n void executeOperation(merged);\n }, [isGet, hasAutoRun, debouncedValues, lockedPathValues, parameterSignature]);\n\n const getRowDetailHref = useCallback<ClickyTableRowHref>(\n (row) => {\n if (!detailOperation) return undefined;\n const id = getClickyRowId(row);\n if (!id) return undefined;\n return hrefForOperation(detailOperation, [], { id });\n },\n [detailOperation],\n );\n\n const handleTableRowClick = useCallback<ClickyTableRowClick>(\n (row) => {\n const href = getRowDetailHref(row);\n if (href) onNavigate?.(href);\n },\n [getRowDetailHref, onNavigate],\n );\n\n const backLink =\n backHref == null ? null : renderLink ? (\n renderLink({\n to: backHref,\n className: \"text-sm text-primary underline-offset-4 hover:underline\",\n children: backLabel,\n })\n ) : (\n <a href={backHref} className=\"text-sm text-primary underline-offset-4 hover:underline\">\n {backLabel}\n </a>\n );\n\n if (isLoading) {\n return <div className=\"text-sm text-muted-foreground\">Loading operation...</div>;\n }\n\n if (!operation) {\n return (\n <div className=\"space-y-4\">\n <div className=\"text-sm text-muted-foreground\">\n Unknown operation: <code>{operationId}</code>\n </div>\n {backLink}\n </div>\n );\n }\n\n const { path, method, operation: op } = operation;\n const preview = buildOperationPreview(operation, effectiveInitialValues, accept, previewMode);\n\n return (\n <div className={className ?? \"min-w-0 flex-1 space-y-6 p-6\"}>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0 flex-1\">\n {backLink}\n <div className=\"flex items-center gap-3\">\n <MethodBadge method={method} />\n <h1 className=\"truncate text-xl font-bold\">{op.summary || op.operationId || path}</h1>\n </div>\n <p className=\"mt-1 font-mono text-xs text-muted-foreground\">{path}</p>\n {op.operationId && op.summary && (\n <p className=\"mt-2 font-mono text-xs text-muted-foreground\">{op.operationId}</p>\n )}\n {op.description && op.description !== op.summary && (\n <p className=\"mt-1 text-sm text-muted-foreground\">{op.description}</p>\n )}\n </div>\n <div className=\"flex shrink-0 flex-col items-end gap-3\">\n <div>\n <div className=\"mb-1 text-right text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n Accept\n </div>\n <AcceptPicker\n value={accept}\n onChange={setAccept}\n previewMode={previewMode}\n onPreviewModeChange={setPreviewMode}\n />\n </div>\n {relatedOperations.length > 0 && (\n <div className=\"flex flex-wrap justify-end gap-2\">\n {relatedOperations.map((related) =>\n related.href ? (\n renderLink ? (\n renderLink({\n key: `${related.operation.method}:${related.operation.path}`,\n to: related.href,\n className:\n \"inline-flex h-8 items-center justify-center gap-2 rounded-md border border-input bg-background px-3 text-xs font-medium hover:bg-accent hover:text-accent-foreground\",\n children: related.label,\n })\n ) : (\n <a\n key={`${related.operation.method}:${related.operation.path}`}\n href={related.href}\n className=\"inline-flex h-8 items-center justify-center gap-2 rounded-md border border-input bg-background px-3 text-xs font-medium hover:bg-accent hover:text-accent-foreground\"\n >\n {related.label}\n </a>\n )\n ) : (\n <OperationActionDialog\n key={`${related.operation.method}:${related.operation.path}`}\n operation={related.operation}\n client={client}\n initialValues={lockedPathValues}\n label={related.label}\n defaultAccept={accept}\n {...(onNavigate ? { onNavigateAction: onNavigate } : {})}\n />\n ),\n )}\n </div>\n )}\n </div>\n </div>\n\n <section className=\"space-y-3\">\n {method.toUpperCase() === \"GET\" ? (\n parameters.length > 0 ? (\n // Before a result lands the FilterBar lives here so users can\n // fill in path params / required inputs and submit. Once a\n // result is showing AND auto-run is on (sidebar flow), the same\n // filter chips relocate into the DataTable's filter bar via\n // externalFilters, which is the unified placement the user asked\n // for. The two branches share `formConfig.filters` so the values\n // stay in sync.\n !result || !effectiveAutoRun ? (\n <div className=\"space-y-2\">\n <FilterBar\n autoSubmit={effectiveAutoRun}\n filters={formConfig.filters}\n {...(!effectiveAutoRun ? { onApply: () => handleManualSubmit() } : {})}\n applyLabel=\"Execute request\"\n isPending={isExecuting}\n {...(formConfig.timeRange ? { timeRange: formConfig.timeRange } : {})}\n />\n {submitError && (\n <div className=\"rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive\">\n {submitError}\n </div>\n )}\n </div>\n ) : null\n ) : null\n ) : (\n <div className=\"rounded-lg border p-4\">\n <CommandForm\n parameters={parameters}\n onExecute={(params) => executeOperation(params)}\n isPending={isExecuting}\n method={method}\n path={path}\n accept={accept}\n initialValues={effectiveInitialValues}\n />\n </div>\n )}\n\n {preview && (\n <pre className=\"overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs\">{preview}</pre>\n )}\n </section>\n\n {error ? (\n <InlineError title={`Failed to load ${path} as ${accept}`} error={error} />\n ) : isExecuting || result ? (\n <div role=\"region\" aria-label=\"Response body\">\n <CommandOutput\n response={result}\n loading={isExecuting}\n loadingMessage=\"Loading execution results…\"\n bare\n {...(detailOperation\n ? {\n getTableRowHref: getRowDetailHref,\n onTableRowClick: handleTableRowClick,\n isTableRowClickable: (row: ClickyRow) => Boolean(getRowDetailHref(row)),\n }\n : {})}\n {...(isGet && effectiveAutoRun && formConfig.filters.length > 0\n ? { externalFilters: formConfig.filters }\n : {})}\n {...(isGet && effectiveAutoRun && dataTablePagination\n ? { pagination: dataTablePagination }\n : {})}\n />\n </div>\n ) : null}\n </div>\n );\n}\n\ntype RelatedOperation = {\n operation: ResolvedOperation;\n label: string;\n href?: string;\n};\n\nfunction findRelatedOperations(\n current: ResolvedOperation,\n operations: ResolvedOperation[],\n pathValues: Record<string, string>,\n): RelatedOperation[] {\n if (current.method.toUpperCase() !== \"GET\") return [];\n if (!pathTemplateSatisfied(current.path, pathValues)) return [];\n\n const basePath = current.path.replace(/\\/+$/, \"\");\n return operations\n .filter((candidate) => {\n if (candidate === current) return false;\n if (!candidate.path.startsWith(`${basePath}/`)) return false;\n if (!pathTemplateSatisfied(candidate.path, pathValues)) return false;\n const method = candidate.method.toUpperCase();\n return method === \"GET\" || method === \"POST\" || method === \"PUT\" || method === \"DELETE\";\n })\n .map((related) => {\n const method = related.method.toUpperCase();\n const href = method === \"GET\" ? hrefForOperation(related, [], pathValues) : undefined;\n return {\n operation: related,\n label: operationLabel(related),\n ...(href ? { href } : {}),\n };\n })\n .filter((related) => related.operation.method.toUpperCase() !== \"GET\" || related.href);\n}\n\nfunction findDetailOperation(current: ResolvedOperation, operations: ResolvedOperation[]) {\n const method = current.method.toUpperCase();\n const detailPath = `${current.path.replace(/\\/+$/, \"\")}/{id}`;\n return operations.find(\n (candidate) =>\n candidate.method.toUpperCase() === method &&\n candidate.path === detailPath &&\n candidate.operation.parameters?.some(\n (param) => param.in === \"path\" && param.name === \"id\" && param.required,\n ),\n );\n}\n\nfunction hrefForOperation(\n operation: ResolvedOperation,\n args: string[] = [],\n flags: Record<string, string> = {},\n): string | undefined {\n let route = apiPathToRoutePath(operation.path);\n const consumedFlags = new Set<string>();\n\n pathParamNames(operation.path).forEach((name, index) => {\n const value = flags[name] ?? args[index];\n if (!value) return;\n consumedFlags.add(name);\n route = route.replace(`:${name}`, encodeURIComponent(value));\n });\n\n if (route.includes(\":\")) return undefined;\n\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(flags)) {\n if (value && !consumedFlags.has(key)) search.set(key, value);\n }\n const query = search.toString();\n return query ? `${route}?${query}` : route;\n}\n\nfunction apiPathToRoutePath(path: string): string {\n const cliPath = path\n .trim()\n .replace(/^\\/api\\/v1\\/?/, \"\")\n .replace(/^\\/+/, \"\")\n .replace(/\\/+$/, \"\");\n if (!cliPath) return \"/\";\n return `/${cliPath.replace(/\\{([^}]+)\\}/g, \":$1\")}`;\n}\n\nfunction pathTemplateSatisfied(path: string, values: Record<string, string>) {\n return pathParamNames(path).every((name) => Boolean(values[name]));\n}\n\nfunction operationLabel(operation: ResolvedOperation): string {\n const actionName =\n operation.operation[\"x-clicky\"]?.actionName ||\n operation.path.split(\"/\").filter(Boolean).at(-1) ||\n operation.operation.operationId ||\n operation.method;\n return titleCase(actionName.replace(/[_-]+/g, \" \"));\n}\n\nfunction buildOperationPreview(\n operation: ResolvedOperation,\n values: ParameterValues,\n accept: string,\n mode: OperationPreviewMode,\n) {\n if (mode === \"hidden\") return \"\";\n if (mode === \"cli\") return buildCliPreview(operation, values);\n return buildCurlPreview(operation, values, accept);\n}\n\nfunction buildCurlPreview(operation: ResolvedOperation, values: ParameterValues, accept: string) {\n const params = operation.operation.parameters ?? [];\n const parts = [`curl -X ${operation.method.toUpperCase()}`];\n if (accept !== \"application/json\") parts.push(`-H \"Accept: ${accept}\"`);\n let url = operation.path;\n const queryParts: string[] = [];\n for (const param of params) {\n const value = submitValue(param, values[param.name]);\n if (!value) continue;\n if (param.in === \"path\") {\n url = url.replace(`{${param.name}}`, encodeURIComponent(value));\n } else if (param.in === \"query\") {\n queryParts.push(`${encodeURIComponent(param.name)}=${encodeURIComponent(value)}`);\n }\n }\n if (queryParts.length > 0) url += `?${queryParts.join(\"&\")}`;\n parts.push(`\"${url}\"`);\n return parts.join(\" \");\n}\n\nfunction buildCliPreview(operation: ResolvedOperation, values: ParameterValues) {\n const command = operation.operation[\"x-clicky\"]?.command;\n if (!command) return buildCurlPreview(operation, values, \"application/json\");\n const params = operation.operation.parameters ?? [];\n const positionalNames = new Set(params.filter(isPositionalParam).map((param) => param.name));\n const parts = [command.replaceAll(\"/\", \" \")];\n for (const param of params) {\n const value = submitValue(param, values[param.name]);\n if (!value) continue;\n if (param.in === \"path\" || positionalNames.has(param.name)) {\n parts.push(shellQuote(value));\n continue;\n }\n parts.push(`--${param.name}`, shellQuote(value));\n }\n return parts.join(\" \");\n}\n\nfunction shellQuote(value: string) {\n if (/^[a-zA-Z0-9_./:@-]+$/.test(value)) return value;\n return `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n}\n\nfunction stripRunnerParams(values: ParameterValues): ParameterValues {\n const next: ParameterValues = {};\n for (const [key, value] of Object.entries(values)) {\n if (key === \"autoRun\" || key.startsWith(\"__\")) continue;\n next[key] = value;\n }\n return next;\n}\n\nfunction getClickyRowId(row: ClickyRow) {\n const candidates = [\"_id\", \"id\", \"ID\", \"guid\", \"GUID\"];\n for (const key of candidates) {\n const value = clickyNodeText(row.cells[key]);\n if (value) return value;\n }\n return undefined;\n}\n\nfunction clickyNodeText(node: ClickyNode | undefined): string {\n if (!node) return \"\";\n if (node.plain) return node.plain;\n if (node.text) return node.text;\n if (node.source) return node.source;\n if (node.children) return node.children.map(clickyNodeText).join(\"\");\n if (node.items) return node.items.map(clickyNodeText).join(\" \");\n if (node.fields) return node.fields.map((field) => clickyNodeText(field.value)).join(\" \");\n return \"\";\n}\n"],"names":["values"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const ACCEPT_OPTIONS = [
4
+ { value: "application/json", label: "JSON" },
5
+ { value: "application/clicky+json", label: "Clicky" },
6
+ { value: "text/markdown", label: "Markdown" },
7
+ { value: "text/html", label: "HTML" },
8
+ { value: "application/x-yaml", label: "YAML" },
9
+ { value: "text/csv", label: "CSV" },
10
+ { value: "application/pdf", label: "PDF" },
11
+ { value: "text/plain", label: "Pretty" }
12
+ ];
13
+ const VIEW_OPTIONS = [
14
+ { value: "application/json", label: "JSON" },
15
+ { value: "application/clicky+json", label: "Clicky" },
16
+ { value: "application/pdf", label: "PDF" }
17
+ ];
18
+ exports.ACCEPT_OPTIONS = ACCEPT_OPTIONS;
19
+ exports.VIEW_OPTIONS = VIEW_OPTIONS;
20
+ //# sourceMappingURL=accept-options.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept-options.cjs","sources":["../../src/rpc/accept-options.ts"],"sourcesContent":["export const ACCEPT_OPTIONS = [\n { value: \"application/json\", label: \"JSON\" },\n { value: \"application/clicky+json\", label: \"Clicky\" },\n { value: \"text/markdown\", label: \"Markdown\" },\n { value: \"text/html\", label: \"HTML\" },\n { value: \"application/x-yaml\", label: \"YAML\" },\n { value: \"text/csv\", label: \"CSV\" },\n { value: \"application/pdf\", label: \"PDF\" },\n { value: \"text/plain\", label: \"Pretty\" },\n] as const;\n\nexport const VIEW_OPTIONS = [\n { value: \"application/json\", label: \"JSON\" },\n { value: \"application/clicky+json\", label: \"Clicky\" },\n { value: \"application/pdf\", label: \"PDF\" },\n] as const;\n\nexport type AcceptOption = { value: string; label: string };\nexport type AcceptValue = (typeof ACCEPT_OPTIONS)[number][\"value\"];\nexport type OperationPreviewMode = \"hidden\" | \"curl\" | \"cli\";\n"],"names":[],"mappings":";;AAAO,MAAM,iBAAiB;AAAA,EAC5B,EAAE,OAAO,oBAAoB,OAAO,OAAA;AAAA,EACpC,EAAE,OAAO,2BAA2B,OAAO,SAAA;AAAA,EAC3C,EAAE,OAAO,iBAAiB,OAAO,WAAA;AAAA,EACjC,EAAE,OAAO,aAAa,OAAO,OAAA;AAAA,EAC7B,EAAE,OAAO,sBAAsB,OAAO,OAAA;AAAA,EACtC,EAAE,OAAO,YAAY,OAAO,MAAA;AAAA,EAC5B,EAAE,OAAO,mBAAmB,OAAO,MAAA;AAAA,EACnC,EAAE,OAAO,cAAc,OAAO,SAAA;AAChC;AAEO,MAAM,eAAe;AAAA,EAC1B,EAAE,OAAO,oBAAoB,OAAO,OAAA;AAAA,EACpC,EAAE,OAAO,2BAA2B,OAAO,SAAA;AAAA,EAC3C,EAAE,OAAO,mBAAmB,OAAO,MAAA;AACrC;;;"}
@@ -0,0 +1,42 @@
1
+ export declare const ACCEPT_OPTIONS: readonly [{
2
+ readonly value: "application/json";
3
+ readonly label: "JSON";
4
+ }, {
5
+ readonly value: "application/clicky+json";
6
+ readonly label: "Clicky";
7
+ }, {
8
+ readonly value: "text/markdown";
9
+ readonly label: "Markdown";
10
+ }, {
11
+ readonly value: "text/html";
12
+ readonly label: "HTML";
13
+ }, {
14
+ readonly value: "application/x-yaml";
15
+ readonly label: "YAML";
16
+ }, {
17
+ readonly value: "text/csv";
18
+ readonly label: "CSV";
19
+ }, {
20
+ readonly value: "application/pdf";
21
+ readonly label: "PDF";
22
+ }, {
23
+ readonly value: "text/plain";
24
+ readonly label: "Pretty";
25
+ }];
26
+ export declare const VIEW_OPTIONS: readonly [{
27
+ readonly value: "application/json";
28
+ readonly label: "JSON";
29
+ }, {
30
+ readonly value: "application/clicky+json";
31
+ readonly label: "Clicky";
32
+ }, {
33
+ readonly value: "application/pdf";
34
+ readonly label: "PDF";
35
+ }];
36
+ export type AcceptOption = {
37
+ value: string;
38
+ label: string;
39
+ };
40
+ export type AcceptValue = (typeof ACCEPT_OPTIONS)[number]["value"];
41
+ export type OperationPreviewMode = "hidden" | "curl" | "cli";
42
+ //# sourceMappingURL=accept-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept-options.d.ts","sourceRoot":"","sources":["../../src/rpc/accept-options.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;EASjB,CAAC;AAEX,eAAO,MAAM,YAAY;;;;;;;;;EAIf,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAC5D,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;AACnE,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC"}
@@ -0,0 +1,20 @@
1
+ const ACCEPT_OPTIONS = [
2
+ { value: "application/json", label: "JSON" },
3
+ { value: "application/clicky+json", label: "Clicky" },
4
+ { value: "text/markdown", label: "Markdown" },
5
+ { value: "text/html", label: "HTML" },
6
+ { value: "application/x-yaml", label: "YAML" },
7
+ { value: "text/csv", label: "CSV" },
8
+ { value: "application/pdf", label: "PDF" },
9
+ { value: "text/plain", label: "Pretty" }
10
+ ];
11
+ const VIEW_OPTIONS = [
12
+ { value: "application/json", label: "JSON" },
13
+ { value: "application/clicky+json", label: "Clicky" },
14
+ { value: "application/pdf", label: "PDF" }
15
+ ];
16
+ export {
17
+ ACCEPT_OPTIONS,
18
+ VIEW_OPTIONS
19
+ };
20
+ //# sourceMappingURL=accept-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept-options.js","sources":["../../src/rpc/accept-options.ts"],"sourcesContent":["export const ACCEPT_OPTIONS = [\n { value: \"application/json\", label: \"JSON\" },\n { value: \"application/clicky+json\", label: \"Clicky\" },\n { value: \"text/markdown\", label: \"Markdown\" },\n { value: \"text/html\", label: \"HTML\" },\n { value: \"application/x-yaml\", label: \"YAML\" },\n { value: \"text/csv\", label: \"CSV\" },\n { value: \"application/pdf\", label: \"PDF\" },\n { value: \"text/plain\", label: \"Pretty\" },\n] as const;\n\nexport const VIEW_OPTIONS = [\n { value: \"application/json\", label: \"JSON\" },\n { value: \"application/clicky+json\", label: \"Clicky\" },\n { value: \"application/pdf\", label: \"PDF\" },\n] as const;\n\nexport type AcceptOption = { value: string; label: string };\nexport type AcceptValue = (typeof ACCEPT_OPTIONS)[number][\"value\"];\nexport type OperationPreviewMode = \"hidden\" | \"curl\" | \"cli\";\n"],"names":[],"mappings":"AAAO,MAAM,iBAAiB;AAAA,EAC5B,EAAE,OAAO,oBAAoB,OAAO,OAAA;AAAA,EACpC,EAAE,OAAO,2BAA2B,OAAO,SAAA;AAAA,EAC3C,EAAE,OAAO,iBAAiB,OAAO,WAAA;AAAA,EACjC,EAAE,OAAO,aAAa,OAAO,OAAA;AAAA,EAC7B,EAAE,OAAO,sBAAsB,OAAO,OAAA;AAAA,EACtC,EAAE,OAAO,YAAY,OAAO,MAAA;AAAA,EAC5B,EAAE,OAAO,mBAAmB,OAAO,MAAA;AAAA,EACnC,EAAE,OAAO,cAAc,OAAO,SAAA;AAChC;AAEO,MAAM,eAAe;AAAA,EAC1B,EAAE,OAAO,oBAAoB,OAAO,OAAA;AAAA,EACpC,EAAE,OAAO,2BAA2B,OAAO,SAAA;AAAA,EAC3C,EAAE,OAAO,mBAAmB,OAAO,MAAA;AACrC;"}
@@ -2,10 +2,18 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const types = require("./types.cjs");
4
4
  function findListEndpoint(operations, entities) {
5
- const wanted = new Set(entities.map((e) => `${e}_list`));
6
- if (wanted.size === 0) return void 0;
5
+ if (entities.length === 0) return void 0;
6
+ const listIds = new Set(entities.map((e) => `${e}_list`));
7
+ const explicit = operations.find(
8
+ (op) => op.method === "get" && !!op.operation.operationId && listIds.has(op.operation.operationId)
9
+ );
10
+ if (explicit) return explicit;
11
+ const rootIds = new Set(entities);
7
12
  return operations.find(
8
- (op) => op.method === "get" && !!op.operation.operationId && wanted.has(op.operation.operationId)
13
+ (op) => {
14
+ var _a;
15
+ return op.method === "get" && rootIds.has(op.operation.operationId ?? "") && !((_a = op.operation.parameters) == null ? void 0 : _a.some((p) => p.in === "path" || types.isPositionalParam(p)));
16
+ }
9
17
  );
10
18
  }
11
19
  function findDetailEndpoint(operations) {
@@ -65,7 +73,10 @@ function normalizeRows(data) {
65
73
  function filterOperationsByDomain(operations, entities) {
66
74
  if (entities.length === 0) return [];
67
75
  const wanted = new Set(entities);
68
- return operations.filter((op) => (op.operation.tags ?? []).some((tag) => wanted.has(tag)));
76
+ return operations.filter((op) => {
77
+ if ((op.operation.tags ?? []).some((tag) => wanted.has(tag))) return true;
78
+ return op.method === "get" && wanted.has(op.operation.operationId ?? "");
79
+ });
69
80
  }
70
81
  exports.filterOperationsByDomain = filterOperationsByDomain;
71
82
  exports.findDetailEndpoint = findDetailEndpoint;
@@ -1 +1 @@
1
- {"version":3,"file":"classify.cjs","sources":["../../src/rpc/classify.ts"],"sourcesContent":["import { isPositionalParam, type ExecutionResponse, type ResolvedOperation } from \"./types\";\n\n// findListEndpoint picks the canonical list operation for a set of\n// entities. Clicky-rpc auto-registers `<entity> list` commands and mints\n// operationIds of the form `<entity>_list`. Matching exactly on that form\n// keeps the default table view deterministic — a non-list GET never gets\n// promoted to list by accident.\nexport function findListEndpoint(\n operations: ResolvedOperation[],\n entities: string[],\n): ResolvedOperation | undefined {\n const wanted = new Set(entities.map((e) => `${e}_list`));\n if (wanted.size === 0) return undefined;\n return operations.find(\n (op) =>\n op.method === \"get\" && !!op.operation.operationId && wanted.has(op.operation.operationId),\n );\n}\n\nexport function findDetailEndpoint(operations: ResolvedOperation[]): ResolvedOperation | undefined {\n return operations.find(\n (op) =>\n op.method === \"get\" &&\n op.operation.parameters?.some((p) => p.in === \"path\" || isPositionalParam(p)),\n );\n}\n\nfunction splitPath(path: string) {\n return path.split(\"/\").filter(Boolean);\n}\n\n// findDetailEndpointForList prefers the detail GET that belongs to the\n// resolved list route. This keeps sibling surfaces that share tags\n// (for example `stack_*` and `admin_stack_*`) from cross-contaminating\n// default entity-detail routing.\nexport function findDetailEndpointForList(\n operations: ResolvedOperation[],\n listEndpoint: ResolvedOperation | undefined,\n): ResolvedOperation | undefined {\n if (!listEndpoint) {\n return findDetailEndpoint(operations);\n }\n\n const baseSegments = splitPath(listEndpoint.path);\n const candidates = operations.filter(\n (op) =>\n op.method === \"get\" &&\n op.path !== listEndpoint.path &&\n op.operation.parameters?.some((p) => p.in === \"path\" || isPositionalParam(p)),\n );\n\n const exactChild = candidates.find((op) => {\n const segments = splitPath(op.path);\n if (segments.length !== baseSegments.length + 1) {\n return false;\n }\n return baseSegments.every((segment, index) => segments[index] === segment);\n });\n\n if (exactChild) {\n return exactChild;\n }\n\n const descendant = candidates.find((op) => op.path.startsWith(`${listEndpoint.path}/`));\n return descendant ?? findDetailEndpoint(operations);\n}\n\nexport function parseJsonBody(response: ExecutionResponse | undefined): unknown {\n if (!response) return null;\n const text = response.stdout || response.output || \"\";\n if (!text.trim()) return null;\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nexport function normalizeRows(data: unknown): Record<string, unknown>[] {\n if (Array.isArray(data)) return data as Record<string, unknown>[];\n if (data && typeof data === \"object\") {\n for (const value of Object.values(data)) {\n if (Array.isArray(value)) return value as Record<string, unknown>[];\n }\n }\n return [];\n}\n\n// filterOperationsByDomain returns operations whose OpenAPI `tags` intersect\n// the given entity list. Clicky-rpc's converter stamps the parent command\n// name into `op.tags`, so passing the entities that belong to a domain\n// yields that domain's operations.\nexport function filterOperationsByDomain(\n operations: ResolvedOperation[],\n entities: string[],\n): ResolvedOperation[] {\n if (entities.length === 0) return [];\n const wanted = new Set(entities);\n return operations.filter((op) => (op.operation.tags ?? []).some((tag) => wanted.has(tag)));\n}\n"],"names":["isPositionalParam"],"mappings":";;;AAOO,SAAS,iBACd,YACA,UAC+B;AAC/B,QAAM,SAAS,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC;AACvD,MAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,SAAO,WAAW;AAAA,IAChB,CAAC,OACC,GAAG,WAAW,SAAS,CAAC,CAAC,GAAG,UAAU,eAAe,OAAO,IAAI,GAAG,UAAU,WAAW;AAAA,EAAA;AAE9F;AAEO,SAAS,mBAAmB,YAAgE;AACjG,SAAO,WAAW;AAAA,IAChB,CAAC,OAAA;;AACC,gBAAG,WAAW,WACd,QAAG,UAAU,eAAb,mBAAyB,KAAK,CAAC,MAAM,EAAE,OAAO,UAAUA,MAAAA,kBAAkB,CAAC;AAAA;AAAA,EAAC;AAElF;AAEA,SAAS,UAAU,MAAc;AAC/B,SAAO,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AACvC;AAMO,SAAS,0BACd,YACA,cAC+B;AAC/B,MAAI,CAAC,cAAc;AACjB,WAAO,mBAAmB,UAAU;AAAA,EACtC;AAEA,QAAM,eAAe,UAAU,aAAa,IAAI;AAChD,QAAM,aAAa,WAAW;AAAA,IAC5B,CAAC;;AACC,gBAAG,WAAW,SACd,GAAG,SAAS,aAAa,UACzB,QAAG,UAAU,eAAb,mBAAyB,KAAK,CAAC,MAAM,EAAE,OAAO,UAAUA,MAAAA,kBAAkB,CAAC;AAAA;AAAA,EAAC;AAGhF,QAAM,aAAa,WAAW,KAAK,CAAC,OAAO;AACzC,UAAM,WAAW,UAAU,GAAG,IAAI;AAClC,QAAI,SAAS,WAAW,aAAa,SAAS,GAAG;AAC/C,aAAO;AAAA,IACT;AACA,WAAO,aAAa,MAAM,CAAC,SAAS,UAAU,SAAS,KAAK,MAAM,OAAO;AAAA,EAC3E,CAAC;AAED,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,WAAW,KAAK,CAAC,OAAO,GAAG,KAAK,WAAW,GAAG,aAAa,IAAI,GAAG,CAAC;AACtF,SAAO,cAAc,mBAAmB,UAAU;AACpD;AAEO,SAAS,cAAc,UAAkD;AAC9E,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,OAAO,SAAS,UAAU,SAAS,UAAU;AACnD,MAAI,CAAC,KAAK,KAAA,EAAQ,QAAO;AACzB,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cAAc,MAA0C;AACtE,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO;AAChC,MAAI,QAAQ,OAAO,SAAS,UAAU;AACpC,eAAW,SAAS,OAAO,OAAO,IAAI,GAAG;AACvC,UAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AAAA,IACnC;AAAA,EACF;AACA,SAAO,CAAA;AACT;AAMO,SAAS,yBACd,YACA,UACqB;AACrB,MAAI,SAAS,WAAW,EAAG,QAAO,CAAA;AAClC,QAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,SAAO,WAAW,OAAO,CAAC,QAAQ,GAAG,UAAU,QAAQ,CAAA,GAAI,KAAK,CAAC,QAAQ,OAAO,IAAI,GAAG,CAAC,CAAC;AAC3F;;;;;;;"}
1
+ {"version":3,"file":"classify.cjs","sources":["../../src/rpc/classify.ts"],"sourcesContent":["import { isPositionalParam, type ExecutionResponse, type ResolvedOperation } from \"./types\";\n\n// findListEndpoint picks the canonical list operation for a set of\n// entities. Clicky-rpc auto-registers `<entity> list` commands and mints\n// operationIds of the form `<entity>_list`. Matching exactly on that form\n// keeps the default table view deterministic — a non-list GET never gets\n// promoted to list by accident.\n//\n// When a `<entity> list` command is promoted onto the bare entity-root\n// (clicky's promoteListToEntityRoot), the collection is exposed instead as\n// `GET /api/v1/<entity>` with operationId `<entity>` and no `_list` suffix.\n// Fall back to that promoted root when no explicit `<entity>_list` exists.\n// A path/positional parameter disqualifies it, so a `<entity>/{id}` detail\n// GET can never be mistaken for the listing.\nexport function findListEndpoint(\n operations: ResolvedOperation[],\n entities: string[],\n): ResolvedOperation | undefined {\n if (entities.length === 0) return undefined;\n const listIds = new Set(entities.map((e) => `${e}_list`));\n const explicit = operations.find(\n (op) =>\n op.method === \"get\" && !!op.operation.operationId && listIds.has(op.operation.operationId),\n );\n if (explicit) return explicit;\n\n const rootIds = new Set(entities);\n return operations.find(\n (op) =>\n op.method === \"get\" &&\n rootIds.has(op.operation.operationId ?? \"\") &&\n !op.operation.parameters?.some((p) => p.in === \"path\" || isPositionalParam(p)),\n );\n}\n\nexport function findDetailEndpoint(operations: ResolvedOperation[]): ResolvedOperation | undefined {\n return operations.find(\n (op) =>\n op.method === \"get\" &&\n op.operation.parameters?.some((p) => p.in === \"path\" || isPositionalParam(p)),\n );\n}\n\nfunction splitPath(path: string) {\n return path.split(\"/\").filter(Boolean);\n}\n\n// findDetailEndpointForList prefers the detail GET that belongs to the\n// resolved list route. This keeps sibling surfaces that share tags\n// (for example `stack_*` and `admin_stack_*`) from cross-contaminating\n// default entity-detail routing.\nexport function findDetailEndpointForList(\n operations: ResolvedOperation[],\n listEndpoint: ResolvedOperation | undefined,\n): ResolvedOperation | undefined {\n if (!listEndpoint) {\n return findDetailEndpoint(operations);\n }\n\n const baseSegments = splitPath(listEndpoint.path);\n const candidates = operations.filter(\n (op) =>\n op.method === \"get\" &&\n op.path !== listEndpoint.path &&\n op.operation.parameters?.some((p) => p.in === \"path\" || isPositionalParam(p)),\n );\n\n const exactChild = candidates.find((op) => {\n const segments = splitPath(op.path);\n if (segments.length !== baseSegments.length + 1) {\n return false;\n }\n return baseSegments.every((segment, index) => segments[index] === segment);\n });\n\n if (exactChild) {\n return exactChild;\n }\n\n const descendant = candidates.find((op) => op.path.startsWith(`${listEndpoint.path}/`));\n return descendant ?? findDetailEndpoint(operations);\n}\n\nexport function parseJsonBody(response: ExecutionResponse | undefined): unknown {\n if (!response) return null;\n const text = response.stdout || response.output || \"\";\n if (!text.trim()) return null;\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nexport function normalizeRows(data: unknown): Record<string, unknown>[] {\n if (Array.isArray(data)) return data as Record<string, unknown>[];\n if (data && typeof data === \"object\") {\n for (const value of Object.values(data)) {\n if (Array.isArray(value)) return value as Record<string, unknown>[];\n }\n }\n return [];\n}\n\n// filterOperationsByDomain returns operations whose OpenAPI `tags` intersect\n// the given entity list. Clicky-rpc's converter stamps the parent command\n// name into `op.tags`, so passing the entities that belong to a domain\n// yields that domain's operations.\nexport function filterOperationsByDomain(\n operations: ResolvedOperation[],\n entities: string[],\n): ResolvedOperation[] {\n if (entities.length === 0) return [];\n const wanted = new Set(entities);\n return operations.filter((op) => {\n if ((op.operation.tags ?? []).some((tag) => wanted.has(tag))) return true;\n // clicky promotes a collection to a bare entity-root GET (operationId\n // `<entity>`, no tag). Include it so the catalog can resolve the listing.\n return op.method === \"get\" && wanted.has(op.operation.operationId ?? \"\");\n });\n}\n"],"names":["isPositionalParam"],"mappings":";;;AAcO,SAAS,iBACd,YACA,UAC+B;AAC/B,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,QAAM,UAAU,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC;AACxD,QAAM,WAAW,WAAW;AAAA,IAC1B,CAAC,OACC,GAAG,WAAW,SAAS,CAAC,CAAC,GAAG,UAAU,eAAe,QAAQ,IAAI,GAAG,UAAU,WAAW;AAAA,EAAA;AAE7F,MAAI,SAAU,QAAO;AAErB,QAAM,UAAU,IAAI,IAAI,QAAQ;AAChC,SAAO,WAAW;AAAA,IAChB,CAAC,OAAA;;AACC,gBAAG,WAAW,SACd,QAAQ,IAAI,GAAG,UAAU,eAAe,EAAE,KAC1C,GAAC,QAAG,UAAU,eAAb,mBAAyB,KAAK,CAAC,MAAM,EAAE,OAAO,UAAUA,MAAAA,kBAAkB,CAAC;AAAA;AAAA,EAAC;AAEnF;AAEO,SAAS,mBAAmB,YAAgE;AACjG,SAAO,WAAW;AAAA,IAChB,CAAC,OAAA;;AACC,gBAAG,WAAW,WACd,QAAG,UAAU,eAAb,mBAAyB,KAAK,CAAC,MAAM,EAAE,OAAO,UAAUA,MAAAA,kBAAkB,CAAC;AAAA;AAAA,EAAC;AAElF;AAEA,SAAS,UAAU,MAAc;AAC/B,SAAO,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AACvC;AAMO,SAAS,0BACd,YACA,cAC+B;AAC/B,MAAI,CAAC,cAAc;AACjB,WAAO,mBAAmB,UAAU;AAAA,EACtC;AAEA,QAAM,eAAe,UAAU,aAAa,IAAI;AAChD,QAAM,aAAa,WAAW;AAAA,IAC5B,CAAC;;AACC,gBAAG,WAAW,SACd,GAAG,SAAS,aAAa,UACzB,QAAG,UAAU,eAAb,mBAAyB,KAAK,CAAC,MAAM,EAAE,OAAO,UAAUA,MAAAA,kBAAkB,CAAC;AAAA;AAAA,EAAC;AAGhF,QAAM,aAAa,WAAW,KAAK,CAAC,OAAO;AACzC,UAAM,WAAW,UAAU,GAAG,IAAI;AAClC,QAAI,SAAS,WAAW,aAAa,SAAS,GAAG;AAC/C,aAAO;AAAA,IACT;AACA,WAAO,aAAa,MAAM,CAAC,SAAS,UAAU,SAAS,KAAK,MAAM,OAAO;AAAA,EAC3E,CAAC;AAED,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,WAAW,KAAK,CAAC,OAAO,GAAG,KAAK,WAAW,GAAG,aAAa,IAAI,GAAG,CAAC;AACtF,SAAO,cAAc,mBAAmB,UAAU;AACpD;AAEO,SAAS,cAAc,UAAkD;AAC9E,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,OAAO,SAAS,UAAU,SAAS,UAAU;AACnD,MAAI,CAAC,KAAK,KAAA,EAAQ,QAAO;AACzB,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cAAc,MAA0C;AACtE,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO;AAChC,MAAI,QAAQ,OAAO,SAAS,UAAU;AACpC,eAAW,SAAS,OAAO,OAAO,IAAI,GAAG;AACvC,UAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AAAA,IACnC;AAAA,EACF;AACA,SAAO,CAAA;AACT;AAMO,SAAS,yBACd,YACA,UACqB;AACrB,MAAI,SAAS,WAAW,EAAG,QAAO,CAAA;AAClC,QAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,SAAO,WAAW,OAAO,CAAC,OAAO;AAC/B,SAAK,GAAG,UAAU,QAAQ,CAAA,GAAI,KAAK,CAAC,QAAQ,OAAO,IAAI,GAAG,CAAC,EAAG,QAAO;AAGrE,WAAO,GAAG,WAAW,SAAS,OAAO,IAAI,GAAG,UAAU,eAAe,EAAE;AAAA,EACzE,CAAC;AACH;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/rpc/classify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAO5F,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,iBAAiB,EAAE,EAC/B,QAAQ,EAAE,MAAM,EAAE,GACjB,iBAAiB,GAAG,SAAS,CAO/B;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,GAAG,SAAS,CAMjG;AAUD,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,YAAY,EAAE,iBAAiB,GAAG,SAAS,GAC1C,iBAAiB,GAAG,SAAS,CA2B/B;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,iBAAiB,GAAG,SAAS,GAAG,OAAO,CAS9E;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAQtE;AAMD,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,QAAQ,EAAE,MAAM,EAAE,GACjB,iBAAiB,EAAE,CAIrB"}
1
+ {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/rpc/classify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAc5F,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,iBAAiB,EAAE,EAC/B,QAAQ,EAAE,MAAM,EAAE,GACjB,iBAAiB,GAAG,SAAS,CAgB/B;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,GAAG,SAAS,CAMjG;AAUD,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,YAAY,EAAE,iBAAiB,GAAG,SAAS,GAC1C,iBAAiB,GAAG,SAAS,CA2B/B;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,iBAAiB,GAAG,SAAS,GAAG,OAAO,CAS9E;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAQtE;AAMD,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,QAAQ,EAAE,MAAM,EAAE,GACjB,iBAAiB,EAAE,CASrB"}
@@ -1,9 +1,17 @@
1
1
  import { isPositionalParam } from "./types.js";
2
2
  function findListEndpoint(operations, entities) {
3
- const wanted = new Set(entities.map((e) => `${e}_list`));
4
- if (wanted.size === 0) return void 0;
3
+ if (entities.length === 0) return void 0;
4
+ const listIds = new Set(entities.map((e) => `${e}_list`));
5
+ const explicit = operations.find(
6
+ (op) => op.method === "get" && !!op.operation.operationId && listIds.has(op.operation.operationId)
7
+ );
8
+ if (explicit) return explicit;
9
+ const rootIds = new Set(entities);
5
10
  return operations.find(
6
- (op) => op.method === "get" && !!op.operation.operationId && wanted.has(op.operation.operationId)
11
+ (op) => {
12
+ var _a;
13
+ return op.method === "get" && rootIds.has(op.operation.operationId ?? "") && !((_a = op.operation.parameters) == null ? void 0 : _a.some((p) => p.in === "path" || isPositionalParam(p)));
14
+ }
7
15
  );
8
16
  }
9
17
  function findDetailEndpoint(operations) {
@@ -63,7 +71,10 @@ function normalizeRows(data) {
63
71
  function filterOperationsByDomain(operations, entities) {
64
72
  if (entities.length === 0) return [];
65
73
  const wanted = new Set(entities);
66
- return operations.filter((op) => (op.operation.tags ?? []).some((tag) => wanted.has(tag)));
74
+ return operations.filter((op) => {
75
+ if ((op.operation.tags ?? []).some((tag) => wanted.has(tag))) return true;
76
+ return op.method === "get" && wanted.has(op.operation.operationId ?? "");
77
+ });
67
78
  }
68
79
  export {
69
80
  filterOperationsByDomain,
@@ -1 +1 @@
1
- {"version":3,"file":"classify.js","sources":["../../src/rpc/classify.ts"],"sourcesContent":["import { isPositionalParam, type ExecutionResponse, type ResolvedOperation } from \"./types\";\n\n// findListEndpoint picks the canonical list operation for a set of\n// entities. Clicky-rpc auto-registers `<entity> list` commands and mints\n// operationIds of the form `<entity>_list`. Matching exactly on that form\n// keeps the default table view deterministic — a non-list GET never gets\n// promoted to list by accident.\nexport function findListEndpoint(\n operations: ResolvedOperation[],\n entities: string[],\n): ResolvedOperation | undefined {\n const wanted = new Set(entities.map((e) => `${e}_list`));\n if (wanted.size === 0) return undefined;\n return operations.find(\n (op) =>\n op.method === \"get\" && !!op.operation.operationId && wanted.has(op.operation.operationId),\n );\n}\n\nexport function findDetailEndpoint(operations: ResolvedOperation[]): ResolvedOperation | undefined {\n return operations.find(\n (op) =>\n op.method === \"get\" &&\n op.operation.parameters?.some((p) => p.in === \"path\" || isPositionalParam(p)),\n );\n}\n\nfunction splitPath(path: string) {\n return path.split(\"/\").filter(Boolean);\n}\n\n// findDetailEndpointForList prefers the detail GET that belongs to the\n// resolved list route. This keeps sibling surfaces that share tags\n// (for example `stack_*` and `admin_stack_*`) from cross-contaminating\n// default entity-detail routing.\nexport function findDetailEndpointForList(\n operations: ResolvedOperation[],\n listEndpoint: ResolvedOperation | undefined,\n): ResolvedOperation | undefined {\n if (!listEndpoint) {\n return findDetailEndpoint(operations);\n }\n\n const baseSegments = splitPath(listEndpoint.path);\n const candidates = operations.filter(\n (op) =>\n op.method === \"get\" &&\n op.path !== listEndpoint.path &&\n op.operation.parameters?.some((p) => p.in === \"path\" || isPositionalParam(p)),\n );\n\n const exactChild = candidates.find((op) => {\n const segments = splitPath(op.path);\n if (segments.length !== baseSegments.length + 1) {\n return false;\n }\n return baseSegments.every((segment, index) => segments[index] === segment);\n });\n\n if (exactChild) {\n return exactChild;\n }\n\n const descendant = candidates.find((op) => op.path.startsWith(`${listEndpoint.path}/`));\n return descendant ?? findDetailEndpoint(operations);\n}\n\nexport function parseJsonBody(response: ExecutionResponse | undefined): unknown {\n if (!response) return null;\n const text = response.stdout || response.output || \"\";\n if (!text.trim()) return null;\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nexport function normalizeRows(data: unknown): Record<string, unknown>[] {\n if (Array.isArray(data)) return data as Record<string, unknown>[];\n if (data && typeof data === \"object\") {\n for (const value of Object.values(data)) {\n if (Array.isArray(value)) return value as Record<string, unknown>[];\n }\n }\n return [];\n}\n\n// filterOperationsByDomain returns operations whose OpenAPI `tags` intersect\n// the given entity list. Clicky-rpc's converter stamps the parent command\n// name into `op.tags`, so passing the entities that belong to a domain\n// yields that domain's operations.\nexport function filterOperationsByDomain(\n operations: ResolvedOperation[],\n entities: string[],\n): ResolvedOperation[] {\n if (entities.length === 0) return [];\n const wanted = new Set(entities);\n return operations.filter((op) => (op.operation.tags ?? []).some((tag) => wanted.has(tag)));\n}\n"],"names":[],"mappings":";AAOO,SAAS,iBACd,YACA,UAC+B;AAC/B,QAAM,SAAS,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC;AACvD,MAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,SAAO,WAAW;AAAA,IAChB,CAAC,OACC,GAAG,WAAW,SAAS,CAAC,CAAC,GAAG,UAAU,eAAe,OAAO,IAAI,GAAG,UAAU,WAAW;AAAA,EAAA;AAE9F;AAEO,SAAS,mBAAmB,YAAgE;AACjG,SAAO,WAAW;AAAA,IAChB,CAAC,OAAA;;AACC,gBAAG,WAAW,WACd,QAAG,UAAU,eAAb,mBAAyB,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,kBAAkB,CAAC;AAAA;AAAA,EAAC;AAElF;AAEA,SAAS,UAAU,MAAc;AAC/B,SAAO,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AACvC;AAMO,SAAS,0BACd,YACA,cAC+B;AAC/B,MAAI,CAAC,cAAc;AACjB,WAAO,mBAAmB,UAAU;AAAA,EACtC;AAEA,QAAM,eAAe,UAAU,aAAa,IAAI;AAChD,QAAM,aAAa,WAAW;AAAA,IAC5B,CAAC;;AACC,gBAAG,WAAW,SACd,GAAG,SAAS,aAAa,UACzB,QAAG,UAAU,eAAb,mBAAyB,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,kBAAkB,CAAC;AAAA;AAAA,EAAC;AAGhF,QAAM,aAAa,WAAW,KAAK,CAAC,OAAO;AACzC,UAAM,WAAW,UAAU,GAAG,IAAI;AAClC,QAAI,SAAS,WAAW,aAAa,SAAS,GAAG;AAC/C,aAAO;AAAA,IACT;AACA,WAAO,aAAa,MAAM,CAAC,SAAS,UAAU,SAAS,KAAK,MAAM,OAAO;AAAA,EAC3E,CAAC;AAED,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,WAAW,KAAK,CAAC,OAAO,GAAG,KAAK,WAAW,GAAG,aAAa,IAAI,GAAG,CAAC;AACtF,SAAO,cAAc,mBAAmB,UAAU;AACpD;AAEO,SAAS,cAAc,UAAkD;AAC9E,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,OAAO,SAAS,UAAU,SAAS,UAAU;AACnD,MAAI,CAAC,KAAK,KAAA,EAAQ,QAAO;AACzB,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cAAc,MAA0C;AACtE,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO;AAChC,MAAI,QAAQ,OAAO,SAAS,UAAU;AACpC,eAAW,SAAS,OAAO,OAAO,IAAI,GAAG;AACvC,UAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AAAA,IACnC;AAAA,EACF;AACA,SAAO,CAAA;AACT;AAMO,SAAS,yBACd,YACA,UACqB;AACrB,MAAI,SAAS,WAAW,EAAG,QAAO,CAAA;AAClC,QAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,SAAO,WAAW,OAAO,CAAC,QAAQ,GAAG,UAAU,QAAQ,CAAA,GAAI,KAAK,CAAC,QAAQ,OAAO,IAAI,GAAG,CAAC,CAAC;AAC3F;"}
1
+ {"version":3,"file":"classify.js","sources":["../../src/rpc/classify.ts"],"sourcesContent":["import { isPositionalParam, type ExecutionResponse, type ResolvedOperation } from \"./types\";\n\n// findListEndpoint picks the canonical list operation for a set of\n// entities. Clicky-rpc auto-registers `<entity> list` commands and mints\n// operationIds of the form `<entity>_list`. Matching exactly on that form\n// keeps the default table view deterministic — a non-list GET never gets\n// promoted to list by accident.\n//\n// When a `<entity> list` command is promoted onto the bare entity-root\n// (clicky's promoteListToEntityRoot), the collection is exposed instead as\n// `GET /api/v1/<entity>` with operationId `<entity>` and no `_list` suffix.\n// Fall back to that promoted root when no explicit `<entity>_list` exists.\n// A path/positional parameter disqualifies it, so a `<entity>/{id}` detail\n// GET can never be mistaken for the listing.\nexport function findListEndpoint(\n operations: ResolvedOperation[],\n entities: string[],\n): ResolvedOperation | undefined {\n if (entities.length === 0) return undefined;\n const listIds = new Set(entities.map((e) => `${e}_list`));\n const explicit = operations.find(\n (op) =>\n op.method === \"get\" && !!op.operation.operationId && listIds.has(op.operation.operationId),\n );\n if (explicit) return explicit;\n\n const rootIds = new Set(entities);\n return operations.find(\n (op) =>\n op.method === \"get\" &&\n rootIds.has(op.operation.operationId ?? \"\") &&\n !op.operation.parameters?.some((p) => p.in === \"path\" || isPositionalParam(p)),\n );\n}\n\nexport function findDetailEndpoint(operations: ResolvedOperation[]): ResolvedOperation | undefined {\n return operations.find(\n (op) =>\n op.method === \"get\" &&\n op.operation.parameters?.some((p) => p.in === \"path\" || isPositionalParam(p)),\n );\n}\n\nfunction splitPath(path: string) {\n return path.split(\"/\").filter(Boolean);\n}\n\n// findDetailEndpointForList prefers the detail GET that belongs to the\n// resolved list route. This keeps sibling surfaces that share tags\n// (for example `stack_*` and `admin_stack_*`) from cross-contaminating\n// default entity-detail routing.\nexport function findDetailEndpointForList(\n operations: ResolvedOperation[],\n listEndpoint: ResolvedOperation | undefined,\n): ResolvedOperation | undefined {\n if (!listEndpoint) {\n return findDetailEndpoint(operations);\n }\n\n const baseSegments = splitPath(listEndpoint.path);\n const candidates = operations.filter(\n (op) =>\n op.method === \"get\" &&\n op.path !== listEndpoint.path &&\n op.operation.parameters?.some((p) => p.in === \"path\" || isPositionalParam(p)),\n );\n\n const exactChild = candidates.find((op) => {\n const segments = splitPath(op.path);\n if (segments.length !== baseSegments.length + 1) {\n return false;\n }\n return baseSegments.every((segment, index) => segments[index] === segment);\n });\n\n if (exactChild) {\n return exactChild;\n }\n\n const descendant = candidates.find((op) => op.path.startsWith(`${listEndpoint.path}/`));\n return descendant ?? findDetailEndpoint(operations);\n}\n\nexport function parseJsonBody(response: ExecutionResponse | undefined): unknown {\n if (!response) return null;\n const text = response.stdout || response.output || \"\";\n if (!text.trim()) return null;\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nexport function normalizeRows(data: unknown): Record<string, unknown>[] {\n if (Array.isArray(data)) return data as Record<string, unknown>[];\n if (data && typeof data === \"object\") {\n for (const value of Object.values(data)) {\n if (Array.isArray(value)) return value as Record<string, unknown>[];\n }\n }\n return [];\n}\n\n// filterOperationsByDomain returns operations whose OpenAPI `tags` intersect\n// the given entity list. Clicky-rpc's converter stamps the parent command\n// name into `op.tags`, so passing the entities that belong to a domain\n// yields that domain's operations.\nexport function filterOperationsByDomain(\n operations: ResolvedOperation[],\n entities: string[],\n): ResolvedOperation[] {\n if (entities.length === 0) return [];\n const wanted = new Set(entities);\n return operations.filter((op) => {\n if ((op.operation.tags ?? []).some((tag) => wanted.has(tag))) return true;\n // clicky promotes a collection to a bare entity-root GET (operationId\n // `<entity>`, no tag). Include it so the catalog can resolve the listing.\n return op.method === \"get\" && wanted.has(op.operation.operationId ?? \"\");\n });\n}\n"],"names":[],"mappings":"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"}
@@ -39,12 +39,21 @@ function findSurfaceDetailOperation(operations, surfaceKey) {
39
39
  (meta) => meta.verb === "get" && meta.scope === "entity"
40
40
  );
41
41
  }
42
- function findSurfaceCollectionActions(operations, surfaceKey) {
42
+ function findSurfaceActions(operations, surfaceKey) {
43
43
  return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {
44
44
  const meta = getOperationClickyMeta(operation);
45
- return meta != null && meta.scope === "collection" && meta.verb !== "list";
45
+ return meta != null && meta.verb !== "list" && meta.verb !== "get";
46
46
  });
47
47
  }
48
+ function surfaceActionLabel(operation) {
49
+ var _a, _b;
50
+ const meta = getOperationClickyMeta(operation);
51
+ const short = ((_a = meta == null ? void 0 : meta.actionName) == null ? void 0 : _a.trim()) || ((_b = meta == null ? void 0 : meta.verb) == null ? void 0 : _b.trim());
52
+ if (short && short !== "action") {
53
+ return short.charAt(0).toUpperCase() + short.slice(1);
54
+ }
55
+ return operation.operation.operationId || operation.path;
56
+ }
48
57
  function findSurfaceEntityActions(operations, surfaceKey) {
49
58
  return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {
50
59
  const meta = getOperationClickyMeta(operation);
@@ -59,7 +68,7 @@ function makeSurfaceDefinition(surface) {
59
68
  };
60
69
  }
61
70
  exports.filterOperationsBySurface = filterOperationsBySurface;
62
- exports.findSurfaceCollectionActions = findSurfaceCollectionActions;
71
+ exports.findSurfaceActions = findSurfaceActions;
63
72
  exports.findSurfaceDetailOperation = findSurfaceDetailOperation;
64
73
  exports.findSurfaceEntityActions = findSurfaceEntityActions;
65
74
  exports.findSurfaceListOperation = findSurfaceListOperation;
@@ -68,4 +77,5 @@ exports.getClickySpecMeta = getClickySpecMeta;
68
77
  exports.getClickySurfaces = getClickySurfaces;
69
78
  exports.getOperationClickyMeta = getOperationClickyMeta;
70
79
  exports.makeSurfaceDefinition = makeSurfaceDefinition;
80
+ exports.surfaceActionLabel = surfaceActionLabel;
71
81
  //# sourceMappingURL=clickyMetadata.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"clickyMetadata.cjs","sources":["../../src/rpc/clickyMetadata.ts"],"sourcesContent":["import type {\n ClickyOperationMeta,\n ClickySpecMeta,\n ClickySurface,\n DomainDefinition,\n OpenAPISpec,\n ResolvedOperation,\n} from \"./types\";\n\nexport function getClickySpecMeta(spec: OpenAPISpec | undefined): ClickySpecMeta | undefined {\n return spec?.[\"x-clicky\"];\n}\n\nexport function getClickySurfaces(spec: OpenAPISpec | undefined): ClickySurface[] {\n return getClickySpecMeta(spec)?.surfaces ?? [];\n}\n\nexport function getOperationClickyMeta(\n operation: Pick<ResolvedOperation, \"operation\">,\n): ClickyOperationMeta | undefined {\n return operation.operation[\"x-clicky\"];\n}\n\nexport function filterOperationsBySurface(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n if (!surfaceKey) return [];\n return operations.filter(\n (operation) => getOperationClickyMeta(operation)?.surface === surfaceKey,\n );\n}\n\nexport function findSurfaceOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n predicate: (meta: ClickyOperationMeta) => boolean,\n): ResolvedOperation | undefined {\n return filterOperationsBySurface(operations, surfaceKey).find((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && predicate(meta);\n });\n}\n\nexport function findSurfaceListOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation | undefined {\n return findSurfaceOperation(\n operations,\n surfaceKey,\n (meta) => meta.verb === \"list\" && meta.scope === \"collection\",\n );\n}\n\nexport function findSurfaceDetailOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation | undefined {\n return findSurfaceOperation(\n operations,\n surfaceKey,\n (meta) => meta.verb === \"get\" && meta.scope === \"entity\",\n );\n}\n\nexport function findSurfaceCollectionActions(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && meta.scope === \"collection\" && meta.verb !== \"list\";\n });\n}\n\nexport function findSurfaceEntityActions(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && meta.scope === \"entity\" && meta.verb !== \"get\";\n });\n}\n\nexport function makeSurfaceDefinition(surface: ClickySurface): DomainDefinition {\n return {\n key: surface.key,\n title: surface.title,\n description: surface.description || `Manage ${surface.title.toLowerCase()} resources.`,\n };\n}\n"],"names":[],"mappings":";;AASO,SAAS,kBAAkB,MAA2D;AAC3F,SAAO,6BAAO;AAChB;AAEO,SAAS,kBAAkB,MAAgD;;AAChF,WAAO,uBAAkB,IAAI,MAAtB,mBAAyB,aAAY,CAAA;AAC9C;AAEO,SAAS,uBACd,WACiC;AACjC,SAAO,UAAU,UAAU,UAAU;AACvC;AAEO,SAAS,0BACd,YACA,YACqB;AACrB,MAAI,CAAC,WAAY,QAAO,CAAA;AACxB,SAAO,WAAW;AAAA,IAChB,CAAC,cAAA;;AAAc,2CAAuB,SAAS,MAAhC,mBAAmC,aAAY;AAAA;AAAA,EAAA;AAElE;AAEO,SAAS,qBACd,YACA,YACA,WAC+B;AAC/B,SAAO,0BAA0B,YAAY,UAAU,EAAE,KAAK,CAAC,cAAc;AAC3E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,UAAU,IAAI;AAAA,EACvC,CAAC;AACH;AAEO,SAAS,yBACd,YACA,YAC+B;AAC/B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,UAAU;AAAA,EAAA;AAErD;AAEO,SAAS,2BACd,YACA,YAC+B;AAC/B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC,SAAS,KAAK,SAAS,SAAS,KAAK,UAAU;AAAA,EAAA;AAEpD;AAEO,SAAS,6BACd,YACA,YACqB;AACrB,SAAO,0BAA0B,YAAY,UAAU,EAAE,OAAO,CAAC,cAAc;AAC7E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,KAAK,UAAU,gBAAgB,KAAK,SAAS;AAAA,EACtE,CAAC;AACH;AAEO,SAAS,yBACd,YACA,YACqB;AACrB,SAAO,0BAA0B,YAAY,UAAU,EAAE,OAAO,CAAC,cAAc;AAC7E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,KAAK,UAAU,YAAY,KAAK,SAAS;AAAA,EAClE,CAAC;AACH;AAEO,SAAS,sBAAsB,SAA0C;AAC9E,SAAO;AAAA,IACL,KAAK,QAAQ;AAAA,IACb,OAAO,QAAQ;AAAA,IACf,aAAa,QAAQ,eAAe,UAAU,QAAQ,MAAM,aAAa;AAAA,EAAA;AAE7E;;;;;;;;;;;"}
1
+ {"version":3,"file":"clickyMetadata.cjs","sources":["../../src/rpc/clickyMetadata.ts"],"sourcesContent":["import type {\n ClickyOperationMeta,\n ClickySpecMeta,\n ClickySurface,\n DomainDefinition,\n OpenAPISpec,\n ResolvedOperation,\n} from \"./types\";\n\nexport function getClickySpecMeta(spec: OpenAPISpec | undefined): ClickySpecMeta | undefined {\n return spec?.[\"x-clicky\"];\n}\n\nexport function getClickySurfaces(spec: OpenAPISpec | undefined): ClickySurface[] {\n return getClickySpecMeta(spec)?.surfaces ?? [];\n}\n\nexport function getOperationClickyMeta(\n operation: Pick<ResolvedOperation, \"operation\">,\n): ClickyOperationMeta | undefined {\n return operation.operation[\"x-clicky\"];\n}\n\nexport function filterOperationsBySurface(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n if (!surfaceKey) return [];\n return operations.filter(\n (operation) => getOperationClickyMeta(operation)?.surface === surfaceKey,\n );\n}\n\nexport function findSurfaceOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n predicate: (meta: ClickyOperationMeta) => boolean,\n): ResolvedOperation | undefined {\n return filterOperationsBySurface(operations, surfaceKey).find((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && predicate(meta);\n });\n}\n\nexport function findSurfaceListOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation | undefined {\n return findSurfaceOperation(\n operations,\n surfaceKey,\n (meta) => meta.verb === \"list\" && meta.scope === \"collection\",\n );\n}\n\nexport function findSurfaceDetailOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation | undefined {\n return findSurfaceOperation(\n operations,\n surfaceKey,\n (meta) => meta.verb === \"get\" && meta.scope === \"entity\",\n );\n}\n\nexport function findSurfaceCollectionActions(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && meta.scope === \"collection\" && meta.verb !== \"list\";\n });\n}\n\n// findSurfaceActions returns every runnable action on a surface — both\n// collection-scoped (e.g. create) and entity-scoped (e.g. update/delete, and\n// custom Actions which clicky always annotates scope:\"entity\"). The action bar\n// surfaces these as buttons that open the execution dialog (the dialog collects\n// any id the entity-scoped action needs). Only the list and the entity get are\n// excluded — they drive the table and the row click-through respectively.\nexport function findSurfaceActions(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && meta.verb !== \"list\" && meta.verb !== \"get\";\n });\n}\n\n// surfaceActionLabel prefers the short clicky actionName/verb (capitalized)\n// over the OpenAPI summary, which is often a full sentence. Falls back to the\n// operationId/path so a button always has a label.\nexport function surfaceActionLabel(operation: ResolvedOperation): string {\n const meta = getOperationClickyMeta(operation);\n const short = meta?.actionName?.trim() || meta?.verb?.trim();\n if (short && short !== \"action\") {\n return short.charAt(0).toUpperCase() + short.slice(1);\n }\n return operation.operation.operationId || operation.path;\n}\n\nexport function findSurfaceEntityActions(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && meta.scope === \"entity\" && meta.verb !== \"get\";\n });\n}\n\nexport function makeSurfaceDefinition(surface: ClickySurface): DomainDefinition {\n return {\n key: surface.key,\n title: surface.title,\n description: surface.description || `Manage ${surface.title.toLowerCase()} resources.`,\n };\n}\n"],"names":[],"mappings":";;AASO,SAAS,kBAAkB,MAA2D;AAC3F,SAAO,6BAAO;AAChB;AAEO,SAAS,kBAAkB,MAAgD;;AAChF,WAAO,uBAAkB,IAAI,MAAtB,mBAAyB,aAAY,CAAA;AAC9C;AAEO,SAAS,uBACd,WACiC;AACjC,SAAO,UAAU,UAAU,UAAU;AACvC;AAEO,SAAS,0BACd,YACA,YACqB;AACrB,MAAI,CAAC,WAAY,QAAO,CAAA;AACxB,SAAO,WAAW;AAAA,IAChB,CAAC,cAAA;;AAAc,2CAAuB,SAAS,MAAhC,mBAAmC,aAAY;AAAA;AAAA,EAAA;AAElE;AAEO,SAAS,qBACd,YACA,YACA,WAC+B;AAC/B,SAAO,0BAA0B,YAAY,UAAU,EAAE,KAAK,CAAC,cAAc;AAC3E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,UAAU,IAAI;AAAA,EACvC,CAAC;AACH;AAEO,SAAS,yBACd,YACA,YAC+B;AAC/B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,UAAU;AAAA,EAAA;AAErD;AAEO,SAAS,2BACd,YACA,YAC+B;AAC/B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC,SAAS,KAAK,SAAS,SAAS,KAAK,UAAU;AAAA,EAAA;AAEpD;AAkBO,SAAS,mBACd,YACA,YACqB;AACrB,SAAO,0BAA0B,YAAY,UAAU,EAAE,OAAO,CAAC,cAAc;AAC7E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,KAAK,SAAS,UAAU,KAAK,SAAS;AAAA,EAC/D,CAAC;AACH;AAKO,SAAS,mBAAmB,WAAsC;;AACvE,QAAM,OAAO,uBAAuB,SAAS;AAC7C,QAAM,UAAQ,kCAAM,eAAN,mBAAkB,aAAU,kCAAM,SAAN,mBAAY;AACtD,MAAI,SAAS,UAAU,UAAU;AAC/B,WAAO,MAAM,OAAO,CAAC,EAAE,gBAAgB,MAAM,MAAM,CAAC;AAAA,EACtD;AACA,SAAO,UAAU,UAAU,eAAe,UAAU;AACtD;AAEO,SAAS,yBACd,YACA,YACqB;AACrB,SAAO,0BAA0B,YAAY,UAAU,EAAE,OAAO,CAAC,cAAc;AAC7E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,KAAK,UAAU,YAAY,KAAK,SAAS;AAAA,EAClE,CAAC;AACH;AAEO,SAAS,sBAAsB,SAA0C;AAC9E,SAAO;AAAA,IACL,KAAK,QAAQ;AAAA,IACb,OAAO,QAAQ;AAAA,IACf,aAAa,QAAQ,eAAe,UAAU,QAAQ,MAAM,aAAa;AAAA,EAAA;AAE7E;;;;;;;;;;;;"}
@@ -7,6 +7,8 @@ export declare function findSurfaceOperation(operations: ResolvedOperation[], su
7
7
  export declare function findSurfaceListOperation(operations: ResolvedOperation[], surfaceKey: string | undefined): ResolvedOperation | undefined;
8
8
  export declare function findSurfaceDetailOperation(operations: ResolvedOperation[], surfaceKey: string | undefined): ResolvedOperation | undefined;
9
9
  export declare function findSurfaceCollectionActions(operations: ResolvedOperation[], surfaceKey: string | undefined): ResolvedOperation[];
10
+ export declare function findSurfaceActions(operations: ResolvedOperation[], surfaceKey: string | undefined): ResolvedOperation[];
11
+ export declare function surfaceActionLabel(operation: ResolvedOperation): string;
10
12
  export declare function findSurfaceEntityActions(operations: ResolvedOperation[], surfaceKey: string | undefined): ResolvedOperation[];
11
13
  export declare function makeSurfaceDefinition(surface: ClickySurface): DomainDefinition;
12
14
  //# sourceMappingURL=clickyMetadata.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"clickyMetadata.d.ts","sourceRoot":"","sources":["../../src/rpc/clickyMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAE3F;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,aAAa,EAAE,CAEhF;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,GAC9C,mBAAmB,GAAG,SAAS,CAEjC;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,EAAE,CAKrB;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,OAAO,GAChD,iBAAiB,GAAG,SAAS,CAK/B;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,GAAG,SAAS,CAM/B;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,GAAG,SAAS,CAM/B;AAED,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,EAAE,CAKrB;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,EAAE,CAKrB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,gBAAgB,CAM9E"}
1
+ {"version":3,"file":"clickyMetadata.d.ts","sourceRoot":"","sources":["../../src/rpc/clickyMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAE3F;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,aAAa,EAAE,CAEhF;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,GAC9C,mBAAmB,GAAG,SAAS,CAEjC;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,EAAE,CAKrB;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,OAAO,GAChD,iBAAiB,GAAG,SAAS,CAK/B;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,GAAG,SAAS,CAM/B;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,GAAG,SAAS,CAM/B;AAED,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,EAAE,CAKrB;AAQD,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,EAAE,CAKrB;AAKD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,GAAG,MAAM,CAOvE;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,iBAAiB,EAAE,CAKrB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,gBAAgB,CAM9E"}
@@ -37,12 +37,21 @@ function findSurfaceDetailOperation(operations, surfaceKey) {
37
37
  (meta) => meta.verb === "get" && meta.scope === "entity"
38
38
  );
39
39
  }
40
- function findSurfaceCollectionActions(operations, surfaceKey) {
40
+ function findSurfaceActions(operations, surfaceKey) {
41
41
  return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {
42
42
  const meta = getOperationClickyMeta(operation);
43
- return meta != null && meta.scope === "collection" && meta.verb !== "list";
43
+ return meta != null && meta.verb !== "list" && meta.verb !== "get";
44
44
  });
45
45
  }
46
+ function surfaceActionLabel(operation) {
47
+ var _a, _b;
48
+ const meta = getOperationClickyMeta(operation);
49
+ const short = ((_a = meta == null ? void 0 : meta.actionName) == null ? void 0 : _a.trim()) || ((_b = meta == null ? void 0 : meta.verb) == null ? void 0 : _b.trim());
50
+ if (short && short !== "action") {
51
+ return short.charAt(0).toUpperCase() + short.slice(1);
52
+ }
53
+ return operation.operation.operationId || operation.path;
54
+ }
46
55
  function findSurfaceEntityActions(operations, surfaceKey) {
47
56
  return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {
48
57
  const meta = getOperationClickyMeta(operation);
@@ -58,7 +67,7 @@ function makeSurfaceDefinition(surface) {
58
67
  }
59
68
  export {
60
69
  filterOperationsBySurface,
61
- findSurfaceCollectionActions,
70
+ findSurfaceActions,
62
71
  findSurfaceDetailOperation,
63
72
  findSurfaceEntityActions,
64
73
  findSurfaceListOperation,
@@ -66,6 +75,7 @@ export {
66
75
  getClickySpecMeta,
67
76
  getClickySurfaces,
68
77
  getOperationClickyMeta,
69
- makeSurfaceDefinition
78
+ makeSurfaceDefinition,
79
+ surfaceActionLabel
70
80
  };
71
81
  //# sourceMappingURL=clickyMetadata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"clickyMetadata.js","sources":["../../src/rpc/clickyMetadata.ts"],"sourcesContent":["import type {\n ClickyOperationMeta,\n ClickySpecMeta,\n ClickySurface,\n DomainDefinition,\n OpenAPISpec,\n ResolvedOperation,\n} from \"./types\";\n\nexport function getClickySpecMeta(spec: OpenAPISpec | undefined): ClickySpecMeta | undefined {\n return spec?.[\"x-clicky\"];\n}\n\nexport function getClickySurfaces(spec: OpenAPISpec | undefined): ClickySurface[] {\n return getClickySpecMeta(spec)?.surfaces ?? [];\n}\n\nexport function getOperationClickyMeta(\n operation: Pick<ResolvedOperation, \"operation\">,\n): ClickyOperationMeta | undefined {\n return operation.operation[\"x-clicky\"];\n}\n\nexport function filterOperationsBySurface(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n if (!surfaceKey) return [];\n return operations.filter(\n (operation) => getOperationClickyMeta(operation)?.surface === surfaceKey,\n );\n}\n\nexport function findSurfaceOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n predicate: (meta: ClickyOperationMeta) => boolean,\n): ResolvedOperation | undefined {\n return filterOperationsBySurface(operations, surfaceKey).find((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && predicate(meta);\n });\n}\n\nexport function findSurfaceListOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation | undefined {\n return findSurfaceOperation(\n operations,\n surfaceKey,\n (meta) => meta.verb === \"list\" && meta.scope === \"collection\",\n );\n}\n\nexport function findSurfaceDetailOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation | undefined {\n return findSurfaceOperation(\n operations,\n surfaceKey,\n (meta) => meta.verb === \"get\" && meta.scope === \"entity\",\n );\n}\n\nexport function findSurfaceCollectionActions(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && meta.scope === \"collection\" && meta.verb !== \"list\";\n });\n}\n\nexport function findSurfaceEntityActions(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && meta.scope === \"entity\" && meta.verb !== \"get\";\n });\n}\n\nexport function makeSurfaceDefinition(surface: ClickySurface): DomainDefinition {\n return {\n key: surface.key,\n title: surface.title,\n description: surface.description || `Manage ${surface.title.toLowerCase()} resources.`,\n };\n}\n"],"names":[],"mappings":"AASO,SAAS,kBAAkB,MAA2D;AAC3F,SAAO,6BAAO;AAChB;AAEO,SAAS,kBAAkB,MAAgD;AAJ3E;AAKL,WAAO,uBAAkB,IAAI,MAAtB,mBAAyB,aAAY,CAAA;AAC9C;AAEO,SAAS,uBACd,WACiC;AACjC,SAAO,UAAU,UAAU,UAAU;AACvC;AAEO,SAAS,0BACd,YACA,YACqB;AACrB,MAAI,CAAC,WAAY,QAAO,CAAA;AACxB,SAAO,WAAW;AAAA,IAChB,CAAC,cAAA;AApBE;AAoBY,2CAAuB,SAAS,MAAhC,mBAAmC,aAAY;AAAA;AAAA,EAAA;AAElE;AAEO,SAAS,qBACd,YACA,YACA,WAC+B;AAC/B,SAAO,0BAA0B,YAAY,UAAU,EAAE,KAAK,CAAC,cAAc;AAC3E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,UAAU,IAAI;AAAA,EACvC,CAAC;AACH;AAEO,SAAS,yBACd,YACA,YAC+B;AAC/B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,UAAU;AAAA,EAAA;AAErD;AAEO,SAAS,2BACd,YACA,YAC+B;AAC/B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC,SAAS,KAAK,SAAS,SAAS,KAAK,UAAU;AAAA,EAAA;AAEpD;AAEO,SAAS,6BACd,YACA,YACqB;AACrB,SAAO,0BAA0B,YAAY,UAAU,EAAE,OAAO,CAAC,cAAc;AAC7E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,KAAK,UAAU,gBAAgB,KAAK,SAAS;AAAA,EACtE,CAAC;AACH;AAEO,SAAS,yBACd,YACA,YACqB;AACrB,SAAO,0BAA0B,YAAY,UAAU,EAAE,OAAO,CAAC,cAAc;AAC7E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,KAAK,UAAU,YAAY,KAAK,SAAS;AAAA,EAClE,CAAC;AACH;AAEO,SAAS,sBAAsB,SAA0C;AAC9E,SAAO;AAAA,IACL,KAAK,QAAQ;AAAA,IACb,OAAO,QAAQ;AAAA,IACf,aAAa,QAAQ,eAAe,UAAU,QAAQ,MAAM,aAAa;AAAA,EAAA;AAE7E;"}
1
+ {"version":3,"file":"clickyMetadata.js","sources":["../../src/rpc/clickyMetadata.ts"],"sourcesContent":["import type {\n ClickyOperationMeta,\n ClickySpecMeta,\n ClickySurface,\n DomainDefinition,\n OpenAPISpec,\n ResolvedOperation,\n} from \"./types\";\n\nexport function getClickySpecMeta(spec: OpenAPISpec | undefined): ClickySpecMeta | undefined {\n return spec?.[\"x-clicky\"];\n}\n\nexport function getClickySurfaces(spec: OpenAPISpec | undefined): ClickySurface[] {\n return getClickySpecMeta(spec)?.surfaces ?? [];\n}\n\nexport function getOperationClickyMeta(\n operation: Pick<ResolvedOperation, \"operation\">,\n): ClickyOperationMeta | undefined {\n return operation.operation[\"x-clicky\"];\n}\n\nexport function filterOperationsBySurface(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n if (!surfaceKey) return [];\n return operations.filter(\n (operation) => getOperationClickyMeta(operation)?.surface === surfaceKey,\n );\n}\n\nexport function findSurfaceOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n predicate: (meta: ClickyOperationMeta) => boolean,\n): ResolvedOperation | undefined {\n return filterOperationsBySurface(operations, surfaceKey).find((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && predicate(meta);\n });\n}\n\nexport function findSurfaceListOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation | undefined {\n return findSurfaceOperation(\n operations,\n surfaceKey,\n (meta) => meta.verb === \"list\" && meta.scope === \"collection\",\n );\n}\n\nexport function findSurfaceDetailOperation(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation | undefined {\n return findSurfaceOperation(\n operations,\n surfaceKey,\n (meta) => meta.verb === \"get\" && meta.scope === \"entity\",\n );\n}\n\nexport function findSurfaceCollectionActions(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && meta.scope === \"collection\" && meta.verb !== \"list\";\n });\n}\n\n// findSurfaceActions returns every runnable action on a surface — both\n// collection-scoped (e.g. create) and entity-scoped (e.g. update/delete, and\n// custom Actions which clicky always annotates scope:\"entity\"). The action bar\n// surfaces these as buttons that open the execution dialog (the dialog collects\n// any id the entity-scoped action needs). Only the list and the entity get are\n// excluded — they drive the table and the row click-through respectively.\nexport function findSurfaceActions(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && meta.verb !== \"list\" && meta.verb !== \"get\";\n });\n}\n\n// surfaceActionLabel prefers the short clicky actionName/verb (capitalized)\n// over the OpenAPI summary, which is often a full sentence. Falls back to the\n// operationId/path so a button always has a label.\nexport function surfaceActionLabel(operation: ResolvedOperation): string {\n const meta = getOperationClickyMeta(operation);\n const short = meta?.actionName?.trim() || meta?.verb?.trim();\n if (short && short !== \"action\") {\n return short.charAt(0).toUpperCase() + short.slice(1);\n }\n return operation.operation.operationId || operation.path;\n}\n\nexport function findSurfaceEntityActions(\n operations: ResolvedOperation[],\n surfaceKey: string | undefined,\n): ResolvedOperation[] {\n return filterOperationsBySurface(operations, surfaceKey).filter((operation) => {\n const meta = getOperationClickyMeta(operation);\n return meta != null && meta.scope === \"entity\" && meta.verb !== \"get\";\n });\n}\n\nexport function makeSurfaceDefinition(surface: ClickySurface): DomainDefinition {\n return {\n key: surface.key,\n title: surface.title,\n description: surface.description || `Manage ${surface.title.toLowerCase()} resources.`,\n };\n}\n"],"names":[],"mappings":"AASO,SAAS,kBAAkB,MAA2D;AAC3F,SAAO,6BAAO;AAChB;AAEO,SAAS,kBAAkB,MAAgD;AAJ3E;AAKL,WAAO,uBAAkB,IAAI,MAAtB,mBAAyB,aAAY,CAAA;AAC9C;AAEO,SAAS,uBACd,WACiC;AACjC,SAAO,UAAU,UAAU,UAAU;AACvC;AAEO,SAAS,0BACd,YACA,YACqB;AACrB,MAAI,CAAC,WAAY,QAAO,CAAA;AACxB,SAAO,WAAW;AAAA,IAChB,CAAC,cAAA;AApBE;AAoBY,2CAAuB,SAAS,MAAhC,mBAAmC,aAAY;AAAA;AAAA,EAAA;AAElE;AAEO,SAAS,qBACd,YACA,YACA,WAC+B;AAC/B,SAAO,0BAA0B,YAAY,UAAU,EAAE,KAAK,CAAC,cAAc;AAC3E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,UAAU,IAAI;AAAA,EACvC,CAAC;AACH;AAEO,SAAS,yBACd,YACA,YAC+B;AAC/B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,UAAU;AAAA,EAAA;AAErD;AAEO,SAAS,2BACd,YACA,YAC+B;AAC/B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC,SAAS,KAAK,SAAS,SAAS,KAAK,UAAU;AAAA,EAAA;AAEpD;AAkBO,SAAS,mBACd,YACA,YACqB;AACrB,SAAO,0BAA0B,YAAY,UAAU,EAAE,OAAO,CAAC,cAAc;AAC7E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,KAAK,SAAS,UAAU,KAAK,SAAS;AAAA,EAC/D,CAAC;AACH;AAKO,SAAS,mBAAmB,WAAsC;AAtFlE;AAuFL,QAAM,OAAO,uBAAuB,SAAS;AAC7C,QAAM,UAAQ,kCAAM,eAAN,mBAAkB,aAAU,kCAAM,SAAN,mBAAY;AACtD,MAAI,SAAS,UAAU,UAAU;AAC/B,WAAO,MAAM,OAAO,CAAC,EAAE,gBAAgB,MAAM,MAAM,CAAC;AAAA,EACtD;AACA,SAAO,UAAU,UAAU,eAAe,UAAU;AACtD;AAEO,SAAS,yBACd,YACA,YACqB;AACrB,SAAO,0BAA0B,YAAY,UAAU,EAAE,OAAO,CAAC,cAAc;AAC7E,UAAM,OAAO,uBAAuB,SAAS;AAC7C,WAAO,QAAQ,QAAQ,KAAK,UAAU,YAAY,KAAK,SAAS;AAAA,EAClE,CAAC;AACH;AAEO,SAAS,sBAAsB,SAA0C;AAC9E,SAAO;AAAA,IACL,KAAK,QAAQ;AAAA,IACb,OAAO,QAAQ;AAAA,IACf,aAAa,QAAQ,eAAe,UAAU,QAAQ,MAAM,aAAa;AAAA,EAAA;AAE7E;"}