@nocobase/app-plugin-releases 0.0.0-stage → 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (584) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +118 -2
  3. package/dist/client/components/actor-name.d.ts +5 -0
  4. package/dist/client/components/actor-name.d.ts.map +1 -0
  5. package/dist/client/components/actor-name.js +11 -0
  6. package/dist/client/components/actor-name.js.map +1 -0
  7. package/dist/client/components/advanced-section.d.ts +8 -0
  8. package/dist/client/components/advanced-section.d.ts.map +1 -0
  9. package/dist/client/components/advanced-section.js +13 -0
  10. package/dist/client/components/advanced-section.js.map +1 -0
  11. package/dist/client/components/app-settings-card.d.ts +7 -0
  12. package/dist/client/components/app-settings-card.d.ts.map +1 -0
  13. package/dist/client/components/app-settings-card.js +69 -0
  14. package/dist/client/components/app-settings-card.js.map +1 -0
  15. package/dist/client/components/artifacts.d.ts +9 -0
  16. package/dist/client/components/artifacts.d.ts.map +1 -0
  17. package/dist/client/components/artifacts.js +26 -0
  18. package/dist/client/components/artifacts.js.map +1 -0
  19. package/dist/client/components/config-secrets.d.ts +10 -0
  20. package/dist/client/components/config-secrets.d.ts.map +1 -0
  21. package/dist/client/components/config-secrets.js +34 -0
  22. package/dist/client/components/config-secrets.js.map +1 -0
  23. package/dist/client/components/confirm-dialog.d.ts +22 -0
  24. package/dist/client/components/confirm-dialog.d.ts.map +1 -0
  25. package/dist/client/components/confirm-dialog.js +47 -0
  26. package/dist/client/components/confirm-dialog.js.map +1 -0
  27. package/dist/client/components/connection-check.d.ts +13 -0
  28. package/dist/client/components/connection-check.d.ts.map +1 -0
  29. package/dist/client/components/connection-check.js +69 -0
  30. package/dist/client/components/connection-check.js.map +1 -0
  31. package/dist/client/components/data-table.d.ts +27 -0
  32. package/dist/client/components/data-table.d.ts.map +1 -0
  33. package/dist/client/components/data-table.js +41 -0
  34. package/dist/client/components/data-table.js.map +1 -0
  35. package/dist/client/components/driver-settings.d.ts +28 -0
  36. package/dist/client/components/driver-settings.d.ts.map +1 -0
  37. package/dist/client/components/driver-settings.js +158 -0
  38. package/dist/client/components/driver-settings.js.map +1 -0
  39. package/dist/client/components/environment-form.d.ts +18 -0
  40. package/dist/client/components/environment-form.d.ts.map +1 -0
  41. package/dist/client/components/environment-form.js +284 -0
  42. package/dist/client/components/environment-form.js.map +1 -0
  43. package/dist/client/components/image-source-fields.d.ts +16 -0
  44. package/dist/client/components/image-source-fields.d.ts.map +1 -0
  45. package/dist/client/components/image-source-fields.js +53 -0
  46. package/dist/client/components/image-source-fields.js.map +1 -0
  47. package/dist/client/components/labels-editor.d.ts +15 -0
  48. package/dist/client/components/labels-editor.d.ts.map +1 -0
  49. package/dist/client/components/labels-editor.js +40 -0
  50. package/dist/client/components/labels-editor.js.map +1 -0
  51. package/dist/client/components/page-container.d.ts +11 -0
  52. package/dist/client/components/page-container.d.ts.map +1 -0
  53. package/dist/client/components/page-container.js +13 -0
  54. package/dist/client/components/page-container.js.map +1 -0
  55. package/dist/client/components/page-header.d.ts +14 -0
  56. package/dist/client/components/page-header.d.ts.map +1 -0
  57. package/dist/client/components/page-header.js +10 -0
  58. package/dist/client/components/page-header.js.map +1 -0
  59. package/dist/client/components/page-tabs.d.ts +20 -0
  60. package/dist/client/components/page-tabs.d.ts.map +1 -0
  61. package/dist/client/components/page-tabs.js +7 -0
  62. package/dist/client/components/page-tabs.js.map +1 -0
  63. package/dist/client/components/people-picker.d.ts +5 -0
  64. package/dist/client/components/people-picker.d.ts.map +1 -0
  65. package/dist/client/components/people-picker.js +22 -0
  66. package/dist/client/components/people-picker.js.map +1 -0
  67. package/dist/client/components/refresh-button.d.ts +7 -0
  68. package/dist/client/components/refresh-button.d.ts.map +1 -0
  69. package/dist/client/components/refresh-button.js +21 -0
  70. package/dist/client/components/refresh-button.js.map +1 -0
  71. package/dist/client/components/registry-fields.d.ts +20 -0
  72. package/dist/client/components/registry-fields.d.ts.map +1 -0
  73. package/dist/client/components/registry-fields.js +47 -0
  74. package/dist/client/components/registry-fields.js.map +1 -0
  75. package/dist/client/components/release-badges.d.ts +42 -0
  76. package/dist/client/components/release-badges.d.ts.map +1 -0
  77. package/dist/client/components/release-badges.js +100 -0
  78. package/dist/client/components/release-badges.js.map +1 -0
  79. package/dist/client/components/request-decision.d.ts +8 -0
  80. package/dist/client/components/request-decision.d.ts.map +1 -0
  81. package/dist/client/components/request-decision.js +7 -0
  82. package/dist/client/components/request-decision.js.map +1 -0
  83. package/dist/client/components/route-dialog.d.ts +6 -0
  84. package/dist/client/components/route-dialog.d.ts.map +1 -0
  85. package/dist/client/components/route-dialog.js +7 -0
  86. package/dist/client/components/route-dialog.js.map +1 -0
  87. package/dist/client/components/route-overlay.d.ts +21 -0
  88. package/dist/client/components/route-overlay.d.ts.map +1 -0
  89. package/dist/client/components/route-overlay.js +87 -0
  90. package/dist/client/components/route-overlay.js.map +1 -0
  91. package/dist/client/components/row-actions.d.ts +9 -0
  92. package/dist/client/components/row-actions.d.ts.map +1 -0
  93. package/dist/client/components/row-actions.js +16 -0
  94. package/dist/client/components/row-actions.js.map +1 -0
  95. package/dist/client/components/runtime-policy-fields.d.ts +9 -0
  96. package/dist/client/components/runtime-policy-fields.d.ts.map +1 -0
  97. package/dist/client/components/runtime-policy-fields.js +26 -0
  98. package/dist/client/components/runtime-policy-fields.js.map +1 -0
  99. package/dist/client/components/section.d.ts +15 -0
  100. package/dist/client/components/section.d.ts.map +1 -0
  101. package/dist/client/components/section.js +6 -0
  102. package/dist/client/components/section.js.map +1 -0
  103. package/dist/client/components/states.d.ts +21 -0
  104. package/dist/client/components/states.d.ts.map +1 -0
  105. package/dist/client/components/states.js +29 -0
  106. package/dist/client/components/states.js.map +1 -0
  107. package/dist/client/components/tag.d.ts +15 -0
  108. package/dist/client/components/tag.d.ts.map +1 -0
  109. package/dist/client/components/tag.js +15 -0
  110. package/dist/client/components/tag.js.map +1 -0
  111. package/dist/client/components/ui/alert-dialog.d.ts +19 -0
  112. package/dist/client/components/ui/alert-dialog.d.ts.map +1 -0
  113. package/dist/client/components/ui/alert-dialog.js +42 -0
  114. package/dist/client/components/ui/alert-dialog.js.map +1 -0
  115. package/dist/client/components/ui/alert.d.ts +13 -0
  116. package/dist/client/components/ui/alert.d.ts.map +1 -0
  117. package/dist/client/components/ui/alert.js +31 -0
  118. package/dist/client/components/ui/alert.js.map +1 -0
  119. package/dist/client/components/ui/badge.d.ts +11 -0
  120. package/dist/client/components/ui/badge.d.ts.map +1 -0
  121. package/dist/client/components/ui/badge.js +37 -0
  122. package/dist/client/components/ui/badge.js.map +1 -0
  123. package/dist/client/components/ui/button.d.ts +12 -0
  124. package/dist/client/components/ui/button.d.ts.map +1 -0
  125. package/dist/client/components/ui/button.js +38 -0
  126. package/dist/client/components/ui/button.js.map +1 -0
  127. package/dist/client/components/ui/card.d.ts +12 -0
  128. package/dist/client/components/ui/card.d.ts.map +1 -0
  129. package/dist/client/components/ui/card.js +25 -0
  130. package/dist/client/components/ui/card.js.map +1 -0
  131. package/dist/client/components/ui/checkbox.d.ts +5 -0
  132. package/dist/client/components/ui/checkbox.d.ts.map +1 -0
  133. package/dist/client/components/ui/checkbox.js +9 -0
  134. package/dist/client/components/ui/checkbox.js.map +1 -0
  135. package/dist/client/components/ui/collapsible.d.ts +7 -0
  136. package/dist/client/components/ui/collapsible.d.ts.map +1 -0
  137. package/dist/client/components/ui/collapsible.js +13 -0
  138. package/dist/client/components/ui/collapsible.js.map +1 -0
  139. package/dist/client/components/ui/dialog.d.ts +18 -0
  140. package/dist/client/components/ui/dialog.d.ts.map +1 -0
  141. package/dist/client/components/ui/dialog.js +40 -0
  142. package/dist/client/components/ui/dialog.js.map +1 -0
  143. package/dist/client/components/ui/dropdown-menu.d.ts +30 -0
  144. package/dist/client/components/ui/dropdown-menu.d.ts.map +1 -0
  145. package/dist/client/components/ui/dropdown-menu.js +51 -0
  146. package/dist/client/components/ui/dropdown-menu.js.map +1 -0
  147. package/dist/client/components/ui/empty.d.ts +15 -0
  148. package/dist/client/components/ui/empty.d.ts.map +1 -0
  149. package/dist/client/components/ui/empty.js +37 -0
  150. package/dist/client/components/ui/empty.js.map +1 -0
  151. package/dist/client/components/ui/field.d.ts +28 -0
  152. package/dist/client/components/ui/field.d.ts.map +1 -0
  153. package/dist/client/components/ui/field.js +71 -0
  154. package/dist/client/components/ui/field.js.map +1 -0
  155. package/dist/client/components/ui/input-group.d.ts +22 -0
  156. package/dist/client/components/ui/input-group.d.ts.map +1 -0
  157. package/dist/client/components/ui/input-group.js +63 -0
  158. package/dist/client/components/ui/input-group.js.map +1 -0
  159. package/dist/client/components/ui/input.d.ts +4 -0
  160. package/dist/client/components/ui/input.d.ts.map +1 -0
  161. package/dist/client/components/ui/input.js +8 -0
  162. package/dist/client/components/ui/input.js.map +1 -0
  163. package/dist/client/components/ui/label.d.ts +4 -0
  164. package/dist/client/components/ui/label.d.ts.map +1 -0
  165. package/dist/client/components/ui/label.js +7 -0
  166. package/dist/client/components/ui/label.js.map +1 -0
  167. package/dist/client/components/ui/radio-group.d.ts +7 -0
  168. package/dist/client/components/ui/radio-group.d.ts.map +1 -0
  169. package/dist/client/components/ui/radio-group.js +12 -0
  170. package/dist/client/components/ui/radio-group.js.map +1 -0
  171. package/dist/client/components/ui/select.d.ts +16 -0
  172. package/dist/client/components/ui/select.d.ts.map +1 -0
  173. package/dist/client/components/ui/select.js +34 -0
  174. package/dist/client/components/ui/select.js.map +1 -0
  175. package/dist/client/components/ui/separator.d.ts +5 -0
  176. package/dist/client/components/ui/separator.d.ts.map +1 -0
  177. package/dist/client/components/ui/separator.js +8 -0
  178. package/dist/client/components/ui/separator.js.map +1 -0
  179. package/dist/client/components/ui/sheet.d.ts +15 -0
  180. package/dist/client/components/ui/sheet.d.ts.map +1 -0
  181. package/dist/client/components/ui/sheet.js +39 -0
  182. package/dist/client/components/ui/sheet.js.map +1 -0
  183. package/dist/client/components/ui/skeleton.d.ts +4 -0
  184. package/dist/client/components/ui/skeleton.d.ts.map +1 -0
  185. package/dist/client/components/ui/skeleton.js +7 -0
  186. package/dist/client/components/ui/skeleton.js.map +1 -0
  187. package/dist/client/components/ui/spinner.d.ts +4 -0
  188. package/dist/client/components/ui/spinner.d.ts.map +1 -0
  189. package/dist/client/components/ui/spinner.js +11 -0
  190. package/dist/client/components/ui/spinner.js.map +1 -0
  191. package/dist/client/components/ui/table.d.ts +11 -0
  192. package/dist/client/components/ui/table.d.ts.map +1 -0
  193. package/dist/client/components/ui/table.js +28 -0
  194. package/dist/client/components/ui/table.js.map +1 -0
  195. package/dist/client/components/ui/tabs.d.ts +14 -0
  196. package/dist/client/components/ui/tabs.d.ts.map +1 -0
  197. package/dist/client/components/ui/tabs.js +32 -0
  198. package/dist/client/components/ui/tabs.js.map +1 -0
  199. package/dist/client/components/ui/textarea.d.ts +4 -0
  200. package/dist/client/components/ui/textarea.d.ts.map +1 -0
  201. package/dist/client/components/ui/textarea.js +7 -0
  202. package/dist/client/components/ui/textarea.js.map +1 -0
  203. package/dist/client/components/ui/tooltip.d.ts +8 -0
  204. package/dist/client/components/ui/tooltip.d.ts.map +1 -0
  205. package/dist/client/components/ui/tooltip.js +17 -0
  206. package/dist/client/components/ui/tooltip.js.map +1 -0
  207. package/dist/client/components/upload-release-dialog.d.ts +8 -0
  208. package/dist/client/components/upload-release-dialog.d.ts.map +1 -0
  209. package/dist/client/components/upload-release-dialog.js +39 -0
  210. package/dist/client/components/upload-release-dialog.js.map +1 -0
  211. package/dist/client/components/use-route-overlay.d.ts +15 -0
  212. package/dist/client/components/use-route-overlay.d.ts.map +1 -0
  213. package/dist/client/components/use-route-overlay.js +15 -0
  214. package/dist/client/components/use-route-overlay.js.map +1 -0
  215. package/dist/client/components/variable-alerts.d.ts +24 -0
  216. package/dist/client/components/variable-alerts.d.ts.map +1 -0
  217. package/dist/client/components/variable-alerts.js +85 -0
  218. package/dist/client/components/variable-alerts.js.map +1 -0
  219. package/dist/client/components/variable-dialogs.d.ts +30 -0
  220. package/dist/client/components/variable-dialogs.d.ts.map +1 -0
  221. package/dist/client/components/variable-dialogs.js +155 -0
  222. package/dist/client/components/variable-dialogs.js.map +1 -0
  223. package/dist/client/components/variables-table.d.ts +26 -0
  224. package/dist/client/components/variables-table.d.ts.map +1 -0
  225. package/dist/client/components/variables-table.js +374 -0
  226. package/dist/client/components/variables-table.js.map +1 -0
  227. package/dist/client/driver-forms/host.d.ts +3 -0
  228. package/dist/client/driver-forms/host.d.ts.map +1 -0
  229. package/dist/client/driver-forms/host.js +100 -0
  230. package/dist/client/driver-forms/host.js.map +1 -0
  231. package/dist/client/driver-forms/index.d.ts +25 -0
  232. package/dist/client/driver-forms/index.d.ts.map +1 -0
  233. package/dist/client/driver-forms/index.js +40 -0
  234. package/dist/client/driver-forms/index.js.map +1 -0
  235. package/dist/client/driver-forms/mapping.d.ts +56 -0
  236. package/dist/client/driver-forms/mapping.d.ts.map +1 -0
  237. package/dist/client/driver-forms/mapping.js +308 -0
  238. package/dist/client/driver-forms/mapping.js.map +1 -0
  239. package/dist/client/driver-forms/types.d.ts +168 -0
  240. package/dist/client/driver-forms/types.d.ts.map +1 -0
  241. package/dist/client/driver-forms/types.js +16 -0
  242. package/dist/client/driver-forms/types.js.map +1 -0
  243. package/dist/client/hooks/use-connection-check.d.ts +18 -0
  244. package/dist/client/hooks/use-connection-check.d.ts.map +1 -0
  245. package/dist/client/hooks/use-connection-check.js +19 -0
  246. package/dist/client/hooks/use-connection-check.js.map +1 -0
  247. package/dist/client/hooks/use-driver-forms.d.ts +4 -0
  248. package/dist/client/hooks/use-driver-forms.d.ts.map +1 -0
  249. package/dist/client/hooks/use-driver-forms.js +12 -0
  250. package/dist/client/hooks/use-driver-forms.js.map +1 -0
  251. package/dist/client/hooks/use-driver-names.d.ts +14 -0
  252. package/dist/client/hooks/use-driver-names.d.ts.map +1 -0
  253. package/dist/client/hooks/use-driver-names.js +33 -0
  254. package/dist/client/hooks/use-driver-names.js.map +1 -0
  255. package/dist/client/hooks/use-environment-check.d.ts +8 -0
  256. package/dist/client/hooks/use-environment-check.d.ts.map +1 -0
  257. package/dist/client/hooks/use-environment-check.js +28 -0
  258. package/dist/client/hooks/use-environment-check.js.map +1 -0
  259. package/dist/client/hooks/use-notify.d.ts +7 -0
  260. package/dist/client/hooks/use-notify.d.ts.map +1 -0
  261. package/dist/client/hooks/use-notify.js +22 -0
  262. package/dist/client/hooks/use-notify.js.map +1 -0
  263. package/dist/client/hooks/use-registries.d.ts +6 -0
  264. package/dist/client/hooks/use-registries.d.ts.map +1 -0
  265. package/dist/client/hooks/use-registries.js +9 -0
  266. package/dist/client/hooks/use-registries.js.map +1 -0
  267. package/dist/client/hooks/use-registry-check.d.ts +16 -0
  268. package/dist/client/hooks/use-registry-check.d.ts.map +1 -0
  269. package/dist/client/hooks/use-registry-check.js +29 -0
  270. package/dist/client/hooks/use-registry-check.js.map +1 -0
  271. package/dist/client/hooks/use-releases.d.ts +42 -0
  272. package/dist/client/hooks/use-releases.d.ts.map +1 -0
  273. package/dist/client/hooks/use-releases.js +82 -0
  274. package/dist/client/hooks/use-releases.js.map +1 -0
  275. package/dist/client/hooks/use-request-decisions.d.ts +15 -0
  276. package/dist/client/hooks/use-request-decisions.d.ts.map +1 -0
  277. package/dist/client/hooks/use-request-decisions.js +69 -0
  278. package/dist/client/hooks/use-request-decisions.js.map +1 -0
  279. package/dist/client/hooks/use-tab-param.d.ts +5 -0
  280. package/dist/client/hooks/use-tab-param.d.ts.map +1 -0
  281. package/dist/client/hooks/use-tab-param.js +33 -0
  282. package/dist/client/hooks/use-tab-param.js.map +1 -0
  283. package/dist/client/index.d.ts +12 -0
  284. package/dist/client/index.d.ts.map +1 -0
  285. package/dist/client/index.js +13 -0
  286. package/dist/client/index.js.map +1 -0
  287. package/dist/client/lib/actor-names.d.ts +16 -0
  288. package/dist/client/lib/actor-names.d.ts.map +1 -0
  289. package/dist/client/lib/actor-names.js +8 -0
  290. package/dist/client/lib/actor-names.js.map +1 -0
  291. package/dist/client/lib/app-groups.d.ts +20 -0
  292. package/dist/client/lib/app-groups.d.ts.map +1 -0
  293. package/dist/client/lib/app-groups.js +36 -0
  294. package/dist/client/lib/app-groups.js.map +1 -0
  295. package/dist/client/lib/app-origin.d.ts +22 -0
  296. package/dist/client/lib/app-origin.d.ts.map +1 -0
  297. package/dist/client/lib/app-origin.js +10 -0
  298. package/dist/client/lib/app-origin.js.map +1 -0
  299. package/dist/client/lib/app-state.d.ts +7 -0
  300. package/dist/client/lib/app-state.d.ts.map +1 -0
  301. package/dist/client/lib/app-state.js +15 -0
  302. package/dist/client/lib/app-state.js.map +1 -0
  303. package/dist/client/lib/config-secrets.d.ts +12 -0
  304. package/dist/client/lib/config-secrets.d.ts.map +1 -0
  305. package/dist/client/lib/config-secrets.js +16 -0
  306. package/dist/client/lib/config-secrets.js.map +1 -0
  307. package/dist/client/lib/delete-app-impact.d.ts +17 -0
  308. package/dist/client/lib/delete-app-impact.d.ts.map +1 -0
  309. package/dist/client/lib/delete-app-impact.js +10 -0
  310. package/dist/client/lib/delete-app-impact.js.map +1 -0
  311. package/dist/client/lib/errors.d.ts +9 -0
  312. package/dist/client/lib/errors.d.ts.map +1 -0
  313. package/dist/client/lib/errors.js +76 -0
  314. package/dist/client/lib/errors.js.map +1 -0
  315. package/dist/client/lib/format.d.ts +8 -0
  316. package/dist/client/lib/format.d.ts.map +1 -0
  317. package/dist/client/lib/format.js +29 -0
  318. package/dist/client/lib/format.js.map +1 -0
  319. package/dist/client/lib/labels.d.ts +14 -0
  320. package/dist/client/lib/labels.d.ts.map +1 -0
  321. package/dist/client/lib/labels.js +42 -0
  322. package/dist/client/lib/labels.js.map +1 -0
  323. package/dist/client/lib/paths.d.ts +25 -0
  324. package/dist/client/lib/paths.d.ts.map +1 -0
  325. package/dist/client/lib/paths.js +31 -0
  326. package/dist/client/lib/paths.js.map +1 -0
  327. package/dist/client/lib/pending-requests.d.ts +7 -0
  328. package/dist/client/lib/pending-requests.d.ts.map +1 -0
  329. package/dist/client/lib/pending-requests.js +12 -0
  330. package/dist/client/lib/pending-requests.js.map +1 -0
  331. package/dist/client/lib/people-picker.d.ts +19 -0
  332. package/dist/client/lib/people-picker.d.ts.map +1 -0
  333. package/dist/client/lib/people-picker.js +8 -0
  334. package/dist/client/lib/people-picker.js.map +1 -0
  335. package/dist/client/lib/permissions.d.ts +6 -0
  336. package/dist/client/lib/permissions.d.ts.map +1 -0
  337. package/dist/client/lib/permissions.js +14 -0
  338. package/dist/client/lib/permissions.js.map +1 -0
  339. package/dist/client/lib/registry-draft.d.ts +26 -0
  340. package/dist/client/lib/registry-draft.d.ts.map +1 -0
  341. package/dist/client/lib/registry-draft.js +41 -0
  342. package/dist/client/lib/registry-draft.js.map +1 -0
  343. package/dist/client/lib/runtime-policy.d.ts +21 -0
  344. package/dist/client/lib/runtime-policy.d.ts.map +1 -0
  345. package/dist/client/lib/runtime-policy.js +63 -0
  346. package/dist/client/lib/runtime-policy.js.map +1 -0
  347. package/dist/client/lib/system-labels.d.ts +15 -0
  348. package/dist/client/lib/system-labels.d.ts.map +1 -0
  349. package/dist/client/lib/system-labels.js +14 -0
  350. package/dist/client/lib/system-labels.js.map +1 -0
  351. package/dist/client/lib/utils.d.ts +2 -0
  352. package/dist/client/lib/utils.d.ts.map +1 -0
  353. package/dist/client/lib/utils.js +2 -0
  354. package/dist/client/lib/utils.js.map +1 -0
  355. package/dist/client/lib/variables-text.d.ts +67 -0
  356. package/dist/client/lib/variables-text.d.ts.map +1 -0
  357. package/dist/client/lib/variables-text.js +156 -0
  358. package/dist/client/lib/variables-text.js.map +1 -0
  359. package/dist/client/locales/en-US.d.ts +670 -0
  360. package/dist/client/locales/en-US.d.ts.map +1 -0
  361. package/dist/client/locales/en-US.js +655 -0
  362. package/dist/client/locales/en-US.js.map +1 -0
  363. package/dist/client/locales/index.d.ts +4 -0
  364. package/dist/client/locales/index.d.ts.map +1 -0
  365. package/dist/client/locales/index.js +7 -0
  366. package/dist/client/locales/index.js.map +1 -0
  367. package/dist/client/locales/zh-CN.d.ts +4 -0
  368. package/dist/client/locales/zh-CN.d.ts.map +1 -0
  369. package/dist/client/locales/zh-CN.js +650 -0
  370. package/dist/client/locales/zh-CN.js.map +1 -0
  371. package/dist/client/pages/app-page.d.ts +3 -0
  372. package/dist/client/pages/app-page.d.ts.map +1 -0
  373. package/dist/client/pages/app-page.js +532 -0
  374. package/dist/client/pages/app-page.js.map +1 -0
  375. package/dist/client/pages/apps-page.d.ts +4 -0
  376. package/dist/client/pages/apps-page.d.ts.map +1 -0
  377. package/dist/client/pages/apps-page.js +116 -0
  378. package/dist/client/pages/apps-page.js.map +1 -0
  379. package/dist/client/pages/environment-page.d.ts +3 -0
  380. package/dist/client/pages/environment-page.d.ts.map +1 -0
  381. package/dist/client/pages/environment-page.js +147 -0
  382. package/dist/client/pages/environment-page.js.map +1 -0
  383. package/dist/client/pages/environments-page.d.ts +4 -0
  384. package/dist/client/pages/environments-page.d.ts.map +1 -0
  385. package/dist/client/pages/environments-page.js +115 -0
  386. package/dist/client/pages/environments-page.js.map +1 -0
  387. package/dist/client/pages/new-app-page.d.ts +10 -0
  388. package/dist/client/pages/new-app-page.d.ts.map +1 -0
  389. package/dist/client/pages/new-app-page.js +101 -0
  390. package/dist/client/pages/new-app-page.js.map +1 -0
  391. package/dist/client/pages/request-page.d.ts +7 -0
  392. package/dist/client/pages/request-page.d.ts.map +1 -0
  393. package/dist/client/pages/request-page.js +70 -0
  394. package/dist/client/pages/request-page.js.map +1 -0
  395. package/dist/client/pages.d.ts +10 -0
  396. package/dist/client/pages.d.ts.map +1 -0
  397. package/dist/client/pages.js +25 -0
  398. package/dist/client/pages.js.map +1 -0
  399. package/dist/client/plugin.d.ts +12 -0
  400. package/dist/client/plugin.d.ts.map +1 -0
  401. package/dist/client/plugin.js +12 -0
  402. package/dist/client/plugin.js.map +1 -0
  403. package/dist/client/routes.d.ts +19 -0
  404. package/dist/client/routes.d.ts.map +1 -0
  405. package/dist/client/routes.js +89 -0
  406. package/dist/client/routes.js.map +1 -0
  407. package/dist/client/service-provider.d.ts +11 -0
  408. package/dist/client/service-provider.d.ts.map +1 -0
  409. package/dist/client/service-provider.js +14 -0
  410. package/dist/client/service-provider.js.map +1 -0
  411. package/dist/database/migrations/.manifest.json +21 -0
  412. package/dist/database/migrations/202610020001_rel_create_tables.d.ts +8 -0
  413. package/dist/database/migrations/202610020001_rel_create_tables.d.ts.map +1 -0
  414. package/dist/database/migrations/202610020001_rel_create_tables.js +247 -0
  415. package/dist/database/migrations/202610020001_rel_create_tables.js.map +1 -0
  416. package/dist/database/migrations/202610100001_rel_variables_initial_admin.d.ts +16 -0
  417. package/dist/database/migrations/202610100001_rel_variables_initial_admin.d.ts.map +1 -0
  418. package/dist/database/migrations/202610100001_rel_variables_initial_admin.js +94 -0
  419. package/dist/database/migrations/202610100001_rel_variables_initial_admin.js.map +1 -0
  420. package/dist/database/migrations/202610170001_rel_drop_app_preview_values.d.ts +8 -0
  421. package/dist/database/migrations/202610170001_rel_drop_app_preview_values.d.ts.map +1 -0
  422. package/dist/database/migrations/202610170001_rel_drop_app_preview_values.js +25 -0
  423. package/dist/database/migrations/202610170001_rel_drop_app_preview_values.js.map +1 -0
  424. package/dist/database/migrations/202610210001_rel_protected_requires_approval.d.ts +9 -0
  425. package/dist/database/migrations/202610210001_rel_protected_requires_approval.d.ts.map +1 -0
  426. package/dist/database/migrations/202610210001_rel_protected_requires_approval.js +32 -0
  427. package/dist/database/migrations/202610210001_rel_protected_requires_approval.js.map +1 -0
  428. package/dist/package.d.ts +2 -0
  429. package/dist/package.d.ts.map +1 -0
  430. package/dist/package.js +2 -0
  431. package/dist/package.js.map +1 -0
  432. package/dist/server/access/caller.d.ts +74 -0
  433. package/dist/server/access/caller.d.ts.map +1 -0
  434. package/dist/server/access/caller.js +141 -0
  435. package/dist/server/access/caller.js.map +1 -0
  436. package/dist/server/access/key-scope-objects.d.ts +20 -0
  437. package/dist/server/access/key-scope-objects.d.ts.map +1 -0
  438. package/dist/server/access/key-scope-objects.js +42 -0
  439. package/dist/server/access/key-scope-objects.js.map +1 -0
  440. package/dist/server/composition.d.ts +52 -0
  441. package/dist/server/composition.d.ts.map +1 -0
  442. package/dist/server/composition.js +105 -0
  443. package/dist/server/composition.js.map +1 -0
  444. package/dist/server/config.d.ts +127 -0
  445. package/dist/server/config.d.ts.map +1 -0
  446. package/dist/server/config.js +2 -0
  447. package/dist/server/config.js.map +1 -0
  448. package/dist/server/drivers/host/driver.d.ts +87 -0
  449. package/dist/server/drivers/host/driver.d.ts.map +1 -0
  450. package/dist/server/drivers/host/driver.js +636 -0
  451. package/dist/server/drivers/host/driver.js.map +1 -0
  452. package/dist/server/drivers/types.d.ts +221 -0
  453. package/dist/server/drivers/types.d.ts.map +1 -0
  454. package/dist/server/drivers/types.js +27 -0
  455. package/dist/server/drivers/types.js.map +1 -0
  456. package/dist/server/errors.d.ts +20 -0
  457. package/dist/server/errors.d.ts.map +1 -0
  458. package/dist/server/errors.js +44 -0
  459. package/dist/server/errors.js.map +1 -0
  460. package/dist/server/index.d.ts +14 -0
  461. package/dist/server/index.d.ts.map +1 -0
  462. package/dist/server/index.js +13 -0
  463. package/dist/server/index.js.map +1 -0
  464. package/dist/server/locales/en-US.d.ts +6 -0
  465. package/dist/server/locales/en-US.d.ts.map +1 -0
  466. package/dist/server/locales/en-US.js +4 -0
  467. package/dist/server/locales/en-US.js.map +1 -0
  468. package/dist/server/locales/index.d.ts +4 -0
  469. package/dist/server/locales/index.d.ts.map +1 -0
  470. package/dist/server/locales/index.js +6 -0
  471. package/dist/server/locales/index.js.map +1 -0
  472. package/dist/server/locales/zh-CN.d.ts +4 -0
  473. package/dist/server/locales/zh-CN.d.ts.map +1 -0
  474. package/dist/server/locales/zh-CN.js +4 -0
  475. package/dist/server/locales/zh-CN.js.map +1 -0
  476. package/dist/server/plugin.d.ts +4 -0
  477. package/dist/server/plugin.d.ts.map +1 -0
  478. package/dist/server/plugin.js +16 -0
  479. package/dist/server/plugin.js.map +1 -0
  480. package/dist/server/providers/authorization.d.ts +17 -0
  481. package/dist/server/providers/authorization.d.ts.map +1 -0
  482. package/dist/server/providers/authorization.js +60 -0
  483. package/dist/server/providers/authorization.js.map +1 -0
  484. package/dist/server/providers/index.d.ts +4 -0
  485. package/dist/server/providers/index.d.ts.map +1 -0
  486. package/dist/server/providers/index.js +8 -0
  487. package/dist/server/providers/index.js.map +1 -0
  488. package/dist/server/providers/releases.d.ts +23 -0
  489. package/dist/server/providers/releases.d.ts.map +1 -0
  490. package/dist/server/providers/releases.js +219 -0
  491. package/dist/server/providers/releases.js.map +1 -0
  492. package/dist/server/routes/api.d.ts +24 -0
  493. package/dist/server/routes/api.d.ts.map +1 -0
  494. package/dist/server/routes/api.js +1610 -0
  495. package/dist/server/routes/api.js.map +1 -0
  496. package/dist/server/routes/index.d.ts +7 -0
  497. package/dist/server/routes/index.d.ts.map +1 -0
  498. package/dist/server/routes/index.js +39 -0
  499. package/dist/server/routes/index.js.map +1 -0
  500. package/dist/server/routes/schemas.d.ts +184 -0
  501. package/dist/server/routes/schemas.d.ts.map +1 -0
  502. package/dist/server/routes/schemas.js +763 -0
  503. package/dist/server/routes/schemas.js.map +1 -0
  504. package/dist/server/secrets-stores.d.ts +9 -0
  505. package/dist/server/secrets-stores.d.ts.map +1 -0
  506. package/dist/server/secrets-stores.js +80 -0
  507. package/dist/server/secrets-stores.js.map +1 -0
  508. package/dist/server/services/artifact.d.ts +30 -0
  509. package/dist/server/services/artifact.d.ts.map +1 -0
  510. package/dist/server/services/artifact.js +234 -0
  511. package/dist/server/services/artifact.js.map +1 -0
  512. package/dist/server/services/codec.d.ts +15 -0
  513. package/dist/server/services/codec.d.ts.map +1 -0
  514. package/dist/server/services/codec.js +58 -0
  515. package/dist/server/services/codec.js.map +1 -0
  516. package/dist/server/services/config-file.d.ts +26 -0
  517. package/dist/server/services/config-file.d.ts.map +1 -0
  518. package/dist/server/services/config-file.js +154 -0
  519. package/dist/server/services/config-file.js.map +1 -0
  520. package/dist/server/services/config-secrets.d.ts +23 -0
  521. package/dist/server/services/config-secrets.d.ts.map +1 -0
  522. package/dist/server/services/config-secrets.js +269 -0
  523. package/dist/server/services/config-secrets.js.map +1 -0
  524. package/dist/server/services/credentials.d.ts +44 -0
  525. package/dist/server/services/credentials.d.ts.map +1 -0
  526. package/dist/server/services/credentials.js +137 -0
  527. package/dist/server/services/credentials.js.map +1 -0
  528. package/dist/server/services/environments.d.ts +75 -0
  529. package/dist/server/services/environments.d.ts.map +1 -0
  530. package/dist/server/services/environments.js +508 -0
  531. package/dist/server/services/environments.js.map +1 -0
  532. package/dist/server/services/events.d.ts +11 -0
  533. package/dist/server/services/events.d.ts.map +1 -0
  534. package/dist/server/services/events.js +26 -0
  535. package/dist/server/services/events.js.map +1 -0
  536. package/dist/server/services/registries.d.ts +67 -0
  537. package/dist/server/services/registries.d.ts.map +1 -0
  538. package/dist/server/services/registries.js +409 -0
  539. package/dist/server/services/registries.js.map +1 -0
  540. package/dist/server/services/release-artifacts.d.ts +42 -0
  541. package/dist/server/services/release-artifacts.d.ts.map +1 -0
  542. package/dist/server/services/release-artifacts.js +165 -0
  543. package/dist/server/services/release-artifacts.js.map +1 -0
  544. package/dist/server/services/releases.d.ts +417 -0
  545. package/dist/server/services/releases.d.ts.map +1 -0
  546. package/dist/server/services/releases.js +2725 -0
  547. package/dist/server/services/releases.js.map +1 -0
  548. package/dist/server/services/requests.d.ts +54 -0
  549. package/dist/server/services/requests.d.ts.map +1 -0
  550. package/dist/server/services/requests.js +342 -0
  551. package/dist/server/services/requests.js.map +1 -0
  552. package/dist/server/services/secrets.d.ts +11 -0
  553. package/dist/server/services/secrets.d.ts.map +1 -0
  554. package/dist/server/services/secrets.js +36 -0
  555. package/dist/server/services/secrets.js.map +1 -0
  556. package/dist/server/services/validation.d.ts +21 -0
  557. package/dist/server/services/validation.d.ts.map +1 -0
  558. package/dist/server/services/validation.js +111 -0
  559. package/dist/server/services/validation.js.map +1 -0
  560. package/dist/server/services/variables.d.ts +132 -0
  561. package/dist/server/services/variables.d.ts.map +1 -0
  562. package/dist/server/services/variables.js +501 -0
  563. package/dist/server/services/variables.js.map +1 -0
  564. package/dist/server/tokens.d.ts +110 -0
  565. package/dist/server/tokens.d.ts.map +1 -0
  566. package/dist/server/tokens.js +9 -0
  567. package/dist/server/tokens.js.map +1 -0
  568. package/dist/shared/access.d.ts +212 -0
  569. package/dist/shared/access.d.ts.map +1 -0
  570. package/dist/shared/access.js +228 -0
  571. package/dist/shared/access.js.map +1 -0
  572. package/dist/shared/locales/access.en-US.d.ts +137 -0
  573. package/dist/shared/locales/access.en-US.d.ts.map +1 -0
  574. package/dist/shared/locales/access.en-US.js +133 -0
  575. package/dist/shared/locales/access.en-US.js.map +1 -0
  576. package/dist/shared/locales/access.zh-CN.d.ts +4 -0
  577. package/dist/shared/locales/access.zh-CN.d.ts.map +1 -0
  578. package/dist/shared/locales/access.zh-CN.js +127 -0
  579. package/dist/shared/locales/access.zh-CN.js.map +1 -0
  580. package/dist/shared/releases.d.ts +657 -0
  581. package/dist/shared/releases.d.ts.map +1 -0
  582. package/dist/shared/releases.js +56 -0
  583. package/dist/shared/releases.js.map +1 -0
  584. package/package.json +118 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,71 @@
1
+ # @nocobase/app-plugin-releases
2
+
3
+ ## 0.1.0-beta.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 68d4feb: Add `@nocobase/app-plugin-releases`: release management for a NocoBase application. Apps (always running, or started on demand and stopped when idle), releases, environments, deployments and rollbacks, configuration with write-only secrets sealed by the secrets service, logs, upload tickets for CI, and deployment requests with approval. Deployment targets are pluggable drivers; the plugin ships the `host` driver, which deploys through App Hosts in process or in Docker containers (`@nocobase/app-host-docker`). The plugin knows nothing about projects, agents or roles: it declares what can be granted in `shared/access.ts` and the assembling application decides who holds what. CI reaches it with a scoped API key and the application's CLI (`release upload`, `release image`).
8
+
9
+ ### Patch Changes
10
+
11
+ - 32d8faa: On PostgreSQL, a member who may see no project, no issue or no App no longer gets a server error: the filters used a NUL character as a placeholder id that matches nothing, which PostgreSQL refuses. The releases plugin's App list, for one, answered 500 to every member who had created no App.
12
+ - ee4da29: A row's menu in the releases plugin's lists no longer closes by itself when the list renders again, such as when other data on the page loads: the lists' cells are no longer remounted on every render.
13
+ - 6162033: Declare `@testing-library/user-event` as a development dependency, which the package's tests now use to open menus and selects. Nothing an application installs changes.
14
+ - Updated dependencies [37c8d20]
15
+ - Updated dependencies [37c8d20]
16
+ - Updated dependencies [37c8d20]
17
+ - Updated dependencies [37c8d20]
18
+ - Updated dependencies [37c8d20]
19
+ - Updated dependencies [37c8d20]
20
+ - Updated dependencies [37c8d20]
21
+ - Updated dependencies [37c8d20]
22
+ - Updated dependencies [37c8d20]
23
+ - Updated dependencies [37c8d20]
24
+ - Updated dependencies [bc1e83f]
25
+ - Updated dependencies [bc1e83f]
26
+ - Updated dependencies [bc1e83f]
27
+ - Updated dependencies [bc1e83f]
28
+ - Updated dependencies [37c8d20]
29
+ - Updated dependencies [37c8d20]
30
+ - Updated dependencies [bc1e83f]
31
+ - Updated dependencies [bc1e83f]
32
+ - Updated dependencies [37c8d20]
33
+ - Updated dependencies [37c8d20]
34
+ - Updated dependencies [37c8d20]
35
+ - Updated dependencies [37c8d20]
36
+ - Updated dependencies [37c8d20]
37
+ - Updated dependencies [37c8d20]
38
+ - Updated dependencies [bc1e83f]
39
+ - Updated dependencies [be0fbbd]
40
+ - Updated dependencies [bc1e83f]
41
+ - Updated dependencies [6993158]
42
+ - Updated dependencies [a6796d9]
43
+ - Updated dependencies [37c8d20]
44
+ - Updated dependencies [37c8d20]
45
+ - Updated dependencies [bc1e83f]
46
+ - Updated dependencies [37c8d20]
47
+ - Updated dependencies [37c8d20]
48
+ - Updated dependencies [bc1e83f]
49
+ - Updated dependencies [37c8d20]
50
+ - Updated dependencies [bc1e83f]
51
+ - Updated dependencies [37c8d20]
52
+ - Updated dependencies [bc1e83f]
53
+ - Updated dependencies [6162033]
54
+ - @nocobase/app-host-docker@0.1.0-beta.0
55
+ - @nocobase/secrets@0.1.0-beta.0
56
+ - @nocobase/app-client@2.0.0-beta.1
57
+ - @nocobase/app-host@0.1.0-beta.14
58
+ - @nocobase/app-server@2.0.0-beta.1
59
+ - @nocobase/app-plugin-authentication@2.0.0-beta.1
60
+ - @nocobase/authorization@1.0.0-beta.12
61
+ - @nocobase/app-plugin-authorization@1.0.0-beta.25
62
+ - @nocobase/db@1.0.0-beta.18
63
+ - @nocobase/config@0.1.0-beta.2
64
+ - @nocobase/i18n@1.0.0-beta.5
65
+ - @nocobase/service-provider@0.0.2-beta.1
66
+
67
+ ## 0.0.1
68
+
69
+ ### Patch Changes
70
+
71
+ - Add the initial plugin scaffold.
package/README.md CHANGED
@@ -1,3 +1,119 @@
1
- # Temporary Holding Version
1
+ # @nocobase/app-plugin-releases
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Release management for a NocoBase application: Apps (always running or started on demand, stopped when idle), releases, environments, deployments and rollbacks, configuration with write-only secrets, logs, upload tickets and deployment requests with approval. CI uses an API key with a scope (see below). Deployment targets are pluggable drivers; the plugin ships the `host` driver, which deploys through App Hosts in process or in Docker containers (see below).
4
+
5
+ The plugin is generic. It knows nothing about projects, issues, agents or roles: it declares what can be granted (`shared/access.ts`) and the application that assembles it decides who holds what.
6
+
7
+ ## Assembling it
8
+
9
+ Server: list `@nocobase/app-plugin-releases/server` with the authentication and authorization plugins, add a `releases` configuration section (`ReleasesPluginConfig`) and bind the ports:
10
+
11
+ | Token | What the application provides |
12
+ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
13
+ | `releasesAccessToken` | `ReleasesAccess`: each caller's `ReleasesPermissions` (pages, settings, the nine `rel.apps` actions at none/related/all), optionally `actorKindOf` (marks agents), `relatedAppIds` / `isRelated` (widens "related" beyond the Apps a user created) and `approversOf` (who decides deployment requests). Unbound, everyone holds nothing. |
14
+ | `releasesDriversToken` | Register more `DeploymentDriver`s (Kubernetes, say). `host` is registered when `releases.host.enabled`. |
15
+ | `releasesEventsToken` | Subscribe to `app.created`, `app.removed`, `release.created`, `deployment.succeeded`, `deployment.failed`, `deployment.rolledBack`, `request.created` (with the approvers to notify) and `request.decided`. The plugin sends no notifications itself. |
16
+ | `releasesToken` | The services, to call in process with a `Caller` (`callerForUser(userId, 'human' \| 'agent' \| 'rule')`). |
17
+ | `releasesHostToken` | `proxyTarget()` of the local Host, for a listener that forwards traffic outside the application's own mount. |
18
+
19
+ Environment credentials and registry passwords are sealed with the application's secrets service, so the application registers `SecretsProvider` and sets `secrets.keys`; without them, storing or reading credentials answers `SECRETS_NOT_CONFIGURED` (503). Both tables are registered as secrets stores, so `pnpm nocobase secrets rotate` reseals them.
20
+
21
+ Client: list `@nocobase/app-plugin-releases/client`. Pass `routes: false` and use `@nocobase/app-plugin-releases/client/pages` to place the pages yourself; otherwise they mount at `/releases` and `/release-environments` (paths are options), with an App's page at `:appId` (Overview, Deployments, Variables, Settings) and an environment's at `:environmentId` (Overview, Variables, Settings) below them, the tab in `?tab=`. An application that mounts the pages elsewhere provides `ReleasesPathsContext` (or wraps them with `withReleasesPaths`) so they link to one another.
22
+
23
+ ## CI and API keys with a scope
24
+
25
+ The plugin has no keys of its own. The API is authenticated by the application, which accepts a person's session or an API key, and opts into scoped keys (`auth.required({ scopedKeys: true })`). A request made with a scoped key (or any key of a service account) carries the key's `KeyScope` on its identity, and `callerOf` turns it into a `key` caller: its permissions are cut down to what the scope covers, and the Apps it reaches to the ones the scope picked (`keyScope.objects('rel.apps')`), for listing as well as every App check.
26
+
27
+ `shared/access.ts` declares what a key's scope may hold, for the application to hand to the API keys plugin: the `releases.apps` group (read: see Apps, releases, deployments and logs; write: also upload, deploy and start or stop; may be limited to some Apps, whose source is `releasesKeyScopeObjects(() => services)`), the `releases.environments` group, and the "CI deploy" preset (`releases.apps` read and write on the Apps chosen, 90 days). Configuring, creating and deleting Apps are not offered to keys.
28
+
29
+ ## HTTP API
30
+
31
+ Everything is under `/api/releases` and follows the application's HTTP API rules: `{ data }`, lists as `{ data, meta }`, and failures in the standard error body with domain `releases` and a stable `reason` (`APP_NOT_FOUND`, `CONFIRMATION_REQUIRED`, …). A route refuses a caller who may not use it at all (`403`) before it reads the input, and the input is checked against a schema (`400 INVALID_INPUT`, domain `app`, unknown body fields included) before the services check the record.
32
+
33
+ | Resource | Routes |
34
+ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
35
+ | Caller | `GET /me` |
36
+ | Drivers | `GET /drivers` (`meta.total`) |
37
+ | Environments | `GET`, `POST /environments`; `GET`, `PATCH`, `DELETE /environments/:environmentId`; `POST /environments/check` (unsaved settings), `POST /environments/:environmentId/check` |
38
+ | Registries | the same under `/registries`, `/registries/check` and `/registries/:registryId/check` |
39
+ | Apps | `GET /apps` (`q`, `environmentId`, `label=key=value`, `page`, `pageSize`), `POST /apps`; `GET`, `PATCH`, `DELETE /apps/:appId?confirm=<appId>`; `POST /apps/:appId/{start,stop,restart}`; `GET`, `PUT /apps/:appId/config` |
40
+ | Variables | `GET /environments/:environmentId/variables`, `PUT`, `DELETE …/variables/:name`; `GET /environments/:environmentId/declaredVariables`; `GET /apps/:appId/variables` (`releaseId`), `PUT`, `DELETE /apps/:appId/variables/:name` (`scope`); `GET /apps/:appId/releases/:releaseId/variables`; `GET /apps/:appId/initialAdmin`, `POST /apps/:appId/initialAdmin/dismiss` |
41
+ | Releases | `GET /apps/:appId/releases` (paged), `POST /apps/:appId/releases` (the archive as the body: `201`, `202` when it also deploys, `200` when it is a release already uploaded), `GET`, `PATCH /apps/:appId/releases/:releaseId`, `GET …/configTemplate`, `POST …/promote`, `POST /apps/:appId/imageReleases`, `POST /apps/:appId/uploadTickets` |
42
+ | Deployments | `POST /apps/:appId/deploy` and `/rollback` (`202` with the deployment), `GET /apps/:appId/deployments` (paged), `GET /apps/:appId/deployments/:deploymentId`, `GET /apps/:appId/logs` and `GET /apps/:appId/deployments/:deploymentId/logs` (`pageToken`, `q`, `level`, `source`, `since`, `until`, `fromStart`; entries as `data`, `meta.nextPageToken` to read on from) |
43
+ | Deployment requests | `GET /deploymentRequests` (`appId`, `status`, `awaitingMe`, paged), `POST /apps/:appId/deploymentRequests`, `GET /deploymentRequests/:requestId`, `POST /deploymentRequests/:requestId/{approve,reject,cancel}` |
44
+
45
+ `check` is a fixed segment beside environment and registry IDs, so neither may be called `check`.
46
+
47
+ ## Rules the plugin enforces
48
+
49
+ - An agent or a key never configures or deletes an App, or decides a deployment request, whatever it holds.
50
+ - A protected environment takes every deployment, rollbacks included, through a deployment request someone else (a person, not the requester) approves, typing the App ID again; nobody deploys there directly (`APPROVAL_REQUIRED`), and an upload ticket cannot deploy there. Anyone who may deploy the App, a key or an agent included, may make the request. Its approvers are the environment's `approvers` as the application resolves them (`ReleasesAccess.approversOf`); with nobody named, whoever holds `deploy-protected` on the App.
51
+ - Upload tickets are single use and expire; they act with what their issuer may still do. A key acts with what its owner may still do, within its scope.
52
+
53
+ ## Releases: archives and images
54
+
55
+ A release is one of two kinds (`kind`):
56
+
57
+ - `archive`: the `.tar.gz` a CI job built and uploaded (`POST /apps/:appId/releases`, `acme release upload`), identified by its checksum, plus the commit and build it came from when the upload says so (`x-release-source-commit`, `x-release-build`). In-process environments run it.
58
+ - `image`: an OCI image a CI job built and pushed to a registry, registered by digest with `POST /apps/:appId/imageReleases` (`{ version, ref, digest, platform?, sourceCommit?, build?, labels? }`, `acme release image`). It needs `upload` on the App, so a CI key that may upload may register too. Docker environments run it, pulled by digest. Registering the same digest again answers its release (`reused`); an image for another platform joins the image release of the same version; another digest for a platform the release has is refused (`IMAGE_CONFLICT`), because a release's image never changes. Its images are recorded in `relReleaseArtifacts`, and the release reads answer them as `artifacts`.
59
+
60
+ A promoted release carries its source's images, and an image registered later reaches the releases promoted from it, so staging and production run the same digest. Each deployment records what it ran (`DeploymentView.artifact`): `tarball` for the archive in process, `image` with the digest it pulled. A deployment the environment cannot run is refused before it starts: an archive in a Docker environment, or an image release without an image in the environment's registry (`IMAGE_REQUIRED`), and an image release in an in-process environment (`ARCHIVE_REQUIRED`).
61
+
62
+ Image registries (`/registries`, behind `rel.environments`: read lists them, manage changes them) are any OCI Distribution registry: an address, the namespace release images go under, and a write-only pull credential. The username is kept in the clear, the password sealed with the application's secrets service (`secrets.keys`), as an environment's credentials are; `secretKeys` says whether it is set and `secretChanges` replaces (a value) or removes (`null`) it. `POST /registries/check` tries unsaved settings and `POST /registries/:registryId/check` stored ones: `/v2/` anonymously, then the credential with Basic authentication or a token from the realm a Bearer challenge names. CI pushes with its own credentials; nothing here pushes. An environment names the registry it pulls from (`registryId`); for a driver with `capabilities.images`, a deployment hands the driver the release's images in that registry with its pull credentials (`AppDeploymentSpec.images`, `registryAuth`), and the driver reports what it ran (`DeploymentEvent.artifact`).
63
+
64
+ ## When Apps run
65
+
66
+ Each App has a runtime policy (`activation`, `idleStopMinutes`, `dormantAfterHours` on create and `PATCH /apps/:appId`):
67
+
68
+ - `activation: 'eager'` (the default) starts the App when it is deployed and whenever the runtime restarts; `'onDemand'` starts it by its first request after a deployment or a runtime restart. A deployment always starts the App once, so it proves the release runs.
69
+ - `idleStopMinutes` stops the App after that many minutes without a request; the next request starts it again (a browser gets a short "starting" page that refreshes itself, API calls wait). `null` never stops it.
70
+ - `dormantAfterHours` (fractions allowed, at least one minute) makes it dormant after that long without a request: stopped, with its unpacked release removed while its record, releases, configuration and data stay; the next request prepares it again from the stored release. It must be longer than the idle stop. `null` never does.
71
+
72
+ An App created without `idleStopMinutes` or `dormantAfterHours` takes its environment's `defaultIdleStopMinutes` and `defaultDormantAfterHours` (null: never), and an environment holds at most `maxApps` Apps.
73
+
74
+ A changed policy reaches the runtime without restarting the App. The App summary's `runtime.state` adds `starting` and `dormant`, and `runtime.lastAccessedAt` tells when it was last requested. A driver declares `capabilities.onDemand` when it honours the policy; the local Host driver does, and on other drivers the policy is stored but the App keeps running. Removing an App and its data is always an explicit `DELETE`, never a timer: Apps do not expire. Stops and dormancies count towards the Host's `restartAfterChurn`, which waits while an on-demand App is running; the Host settings `sweepIntervalSeconds`, `activationHoldMs` and `activationWaitMs` tune how often timers are checked and how long requests wait for a starting App.
75
+
76
+ Labels are opaque to the plugin. An assembling application that adds labels of its own may provide `ReleasesSystemLabelsContext` (client) with `explain(key, value)`; Apps lists and an App's page then leave those labels out (showing the application's `Summary`, below, in their place), its Settings tab shows them read-only with the explanation on hover, and editing the others keeps them. The create and upload dialogs and an App's Settings tab edit labels as rows of a name and a value under "Advanced (optional)".
77
+
78
+ Create App opens over the Apps page at `new`, so an App may not be called `new` or `requests`. A deployment request opens as a dialog (`ReleasesRequestPage`) over its App's page at `:appId/requests/:requestId`, and over the Apps page at `requests/:requestId` for older links. An App's pending request (there is at most one) is the first row of its deployments, on the Overview and the Deployments tab, with Review for an approver and View for anyone else; an approver also sees a one-line notice under the App's header. The dialog says what would run where and who asked, and an approver adds an optional comment and approves or rejects there; the comment is the decision note the requester is told. The Apps list marks an App with a pending request "Pending approval" beside its state. An application that builds Apps from something of its own may say where an App comes from by providing `ReleasesAppOriginContext` (client) with an `Origin` component, which the App's Overview renders under its details, and optionally a `Summary` component, a one-line description lists and the App's header show in place of its system labels; each renders nothing for an App it does not know. The assembling application uses them to name the repository that builds the App, and a preview's pull request.
79
+
80
+ Such an application may also say what deleting an App affects beyond the plugin's records by providing `ReleasesDeleteAppImpactContext` (client) with an `Impact` component, given the App's ID. The Delete App confirmation shows it under its own description; the component loads and words what it needs and renders nothing when nothing uses the App. The plugin's `app.removed` event is where the application then cleans up after the App.
81
+
82
+ `GET /api/releases/environments` answers each environment's `capabilities`: whether it runs uploaded release archives (`archives`) or release images CI registers (`images`), and whether it honours an App's runtime policy (`onDemand`).
83
+
84
+ ## Configuration and its secrets
85
+
86
+ Each deployment of an App in file mode stores its `config.yml` under `releases.dataDir` (mode 0600) and hands it to the runtime as written. Whatever leaves the server sees it masked (`server/services/config-secrets.ts`): `GET /apps/:appId/config`, the answer of `PUT`, the release's `configTemplate` and the services the CLI calls replace every secret value with `CONFIG_SECRET_MASK` (`••••••••`) and list the masked paths in `secrets`. A value is a secret when its nearest key names one by its last word (`password`, `secret`, `token`, `key`, `dsn`, `credential`, `salt`, `authorization`, … but not `publicKey` or `primaryKey`), when it is a URL with a password, or when it equals or contains a secret found that way. There is no way to read a value back through the API; an operator who needs one reads the file on the server.
87
+
88
+ `PUT /apps/:appId/config` takes `{ content, secretChanges? }`. A mask left in place keeps the stored value at its path (a mask where nothing is stored is refused with `CONFIG_SECRET_NOT_STORED`); a value typed over it replaces it. `secretChanges` (`[{ path, value }]`, `null` removes) replace or clear one secret without showing the others, which is what the App page's "Set · Replace · Clear" list sends. A deployment given `config.content` restores masks the same way, so content read from the API can be deployed again. Each deployment makes sure the App has `secrets.keys`, `auth.secret` and `session.secret`: one missing, empty or left at the placeholder takes the value the App already uses, or a generated one. One whose variable the build declares is generated as that variable instead (see Variables). An App built from a template older than `secrets.keys` still needs the other two. Clearing one makes the plugin restore the stored value; changing `secrets.keys`, `auth.secret` or `session.secret` signs everyone out of the App.
89
+
90
+ ## Variables
91
+
92
+ A build declares the environment variables it reads in `dist/variables.json`, which `pnpm build` writes and `pnpm build --tar` packs; the plugin keeps it on the release (`ReleaseView.variables` on the list; `GET …/releases/:releaseId/variables`), and an image release takes it from CI (`variables` of `POST /apps/:appId/imageReleases`, `--variables-file dist/variables.json`). A manifest that is not one is refused (`INVALID_VARIABLES_MANIFEST`); a build without one deploys as before, with only the values someone set.
93
+
94
+ Values are set per environment (`rel.environments` `manage`) and per App (`configure`), and sealed with the secrets service whether they are secrets or not (`relEnvironmentVariables`, `relAppVariables`, both secrets stores). An App created with `previewOf` is a preview of that App and is removed with it; it takes none of that App's values, only its own and its environment's. Names the runtime sets itself (`NODE_ENV`, `APP_BASE_PATH`, `APP_SERVER_HOST`, `APP_SERVER_PORT`, `APP_CONFIG_FILE`, `PATH`, `HOME`) are refused (`VARIABLE_RESERVED`). A secret's value never leaves the server.
95
+
96
+ Which variables an App has is declared by its most recent build: its newest release (uploaded or promoted to it) that carries a manifest, else the release it runs, else its newest (`GET /apps/:appId/variables` answers which in `meta.releaseId` and `meta.releaseVersion`; `AppSummary.variables` reads the same one). The Variables tab of an App's page lists what that build declares with where each value comes from (the App, its environment, `config.yml`, generated, the build's default, or unset), the required ones nothing sets first, an environment's value overridable in one click, and what the App or its environment set that the build does not declare under "Undeclared"; before any build it lists the App's own values. The Variables tab of an environment's page lists its values together with what the most recent build of each of its Apps declares (`GET /environments/:environmentId/declaredVariables`: the declaring Apps, whether the environment sets it, and the Apps that require it and would get no value), pull request previews named `<app>-pr-<number>` folded into one entry. Values are set one at a time, or edited together as `.env` text whose changes are shown before anything is sent, one `PUT` or `DELETE` per variable. The text holds only plain values: a line replaces a Secret, and leaving one out keeps it.
97
+
98
+ Each deployment resolves them, strongest first: the App's value, the environment's, then the App's `config.yml` (which a variable would override at runtime), what the plugin generates, and the build's defaults. A required variable nothing supplies refuses the deployment, a rollback, a deployment request when it is made and when it is approved, and an upload that would deploy (the release is kept) with `VARIABLES_MISSING` (`400`), naming the variables in `metadata.variables` with the App's `appId` and `environmentId`, so a client can link to both places a value can be set. The plugin generates what the manifest lets it: a secret with `generate` (`SECRETS_KEYS`, `AUTH_SECRET`, `SESSION_SECRET`) once, kept as the App's value (`generated`), instead of writing it into `config.yml`; `APP_PUBLIC_ORIGIN` from the App's URL (one under a path of this application takes its `app.publicOrigin`); `APP_SAMPLE_DATA=true` on a first deployment where the environment has `sampleDataOnFirstDeploy`; and on a first deployment whose administrator password nothing names (the example's `admin123` counts as none), `INITIAL_ADMIN_PASSWORD`. The deployment keeps what it ran with, sealed, and gives it to the driver (`AppDeploymentSpec.env`): the Host hands it to the in-process App's scope, the Docker Host to the container after its own fixed variables. Its log names the variables and their sources, never a value. `AppSummary.variables.changed` tells that a value changed since (one read only on the first start does not count); deploying the release again applies it.
99
+
100
+ The generated first administrator is sealed on the deployment: `GET /apps/:appId/initialAdmin` answers it to a person who may deploy the App (agents and keys are refused, and it is not a CLI command) until someone saves it (`POST …/initialAdmin/dismiss`) or 24 hours pass; a preview App's stays until the App goes. Nothing else is shown again.
101
+
102
+ ## Deploying previews
103
+
104
+ A preview served under another origin needs `app.publicOrigin`; the plugin fills it from the App's public URL when the configuration does not set it (as `APP_PUBLIC_ORIGIN` when the build declares that variable). Keep the application's own session cookie scoped to its own path or origin, since Apps on the same Host share the listener's origin. The Host runtime takes the supervisor's `env.allow`, `uid` / `gid` and `launchPrefix` so Apps cannot read the application's secrets, and `restartAfterChurn` to reclaim the memory of replaced, removed, stopped or dormant in-process Apps.
105
+
106
+ ## The `host` driver
107
+
108
+ The `host` driver deploys over the App Host management service (`@nocobase/app-host/management`, see the App Host README). An environment of driver `host` holds `{ backend, backendConfig? }` as its settings, its run mode and that backend's settings, and the backend's credentials as its write-only secret. Each environment is one scope on its Host: its own desired set with its own revision, so restoring one environment never touches another's Apps on the same Host, and an App belongs to one scope only.
109
+
110
+ | `backend` | Where Apps run |
111
+ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
112
+ | `in-process` | The App Host child this plugin starts with `releases.host.enabled`, which runs release archives in its own process, with on-demand start, idle stop and dormancy. It takes no settings and no credentials. |
113
+ | `docker` | A second Host child, started with `releases.docker.enabled`, that runs each App's release image in its own container (`@nocobase/app-host-docker`): pulled by digest, health-gated start-first switch, routing and on-demand start through its listener. It uses the local Docker Engine (`DOCKER_HOST`, else the current Docker context) with built-in container settings, so it takes no settings; its only credentials are the registry's. |
114
+
115
+ The in-process Host runs App code under preview, so it never holds Docker access and never receives an environment's credentials; the Docker Host runs no App code (`trustedApps` is refused otherwise), so Docker access and the registry credentials sit only there. The driver checks a Docker environment with the Docker Host (`checkScope`) before it is saved, and its connection test reports the Docker endpoint it found and what Docker answers. `capabilitiesOf` and `variants` tell the forms which run mode runs images and which offers subdomain URLs.
116
+
117
+ ## Deployments that outlive the process
118
+
119
+ A Host records each deployment's outcome under its deployment ID in an operation log that outlives the Host process (`host.controlDir`). At startup the plugin asks each environment's session for the `operation` of every deployment still marked `deploying`, records what the Host reports (one that finished while this application restarted succeeds and becomes the App's current deployment), and only then sends the environment its desired set; one the Host never saw is marked interrupted. A Host child that is told to stop lets a deployment under way finish and record its outcome first. Docker containers keep running while their Host restarts, and the Host adopts them again. Readers of Apps and deployments wait up to five seconds at startup for all of this.
@@ -0,0 +1,5 @@
1
+ /** An operator, requester or decider: the application's rendering (`ReleasesActorNameContext`), else the id. */
2
+ import { type ReactElement } from 'react';
3
+ import { type ActorNameProps } from '../lib/actor-names.js';
4
+ export declare function ActorName({ id, kind }: ActorNameProps): ReactElement;
5
+ //# sourceMappingURL=actor-name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actor-name.d.ts","sourceRoot":"","sources":["../../../client/components/actor-name.tsx"],"names":[],"mappings":"AAAA,gHAAgH;AAChH,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAEtD,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAE/B,wBAAgB,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,cAAc,GAAG,YAAY,CAIpE"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /** An operator, requester or decider: the application's rendering (`ReleasesActorNameContext`), else the id. */
3
+ import { useContext } from 'react';
4
+ import { ReleasesActorNameContext, } from '../lib/actor-names.js';
5
+ export function ActorName({ id, kind }) {
6
+ const names = useContext(ReleasesActorNameContext);
7
+ if (names)
8
+ return _jsx(names.Name, { id: id, kind: kind });
9
+ return _jsx("span", { className: 'font-mono text-xs', children: id });
10
+ }
11
+ //# sourceMappingURL=actor-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actor-name.js","sourceRoot":"","sources":["../../../client/components/actor-name.tsx"],"names":[],"mappings":";AAAA,gHAAgH;AAChH,OAAO,EAAE,UAAU,EAAqB,MAAM,OAAO,CAAC;AAEtD,OAAO,EACL,wBAAwB,GAEzB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,UAAU,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAkB;IACpD,MAAM,KAAK,GAAG,UAAU,CAAC,wBAAwB,CAAC,CAAC;IACnD,IAAI,KAAK;QAAE,OAAO,KAAC,KAAK,CAAC,IAAI,IAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,GAAI,CAAC;IACrD,OAAO,eAAM,SAAS,EAAC,mBAAmB,YAAE,EAAE,GAAQ,CAAC;AACzD,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type ReactElement, type ReactNode } from 'react';
2
+ export declare function AdvancedSection({ children, defaultOpen, summary, }: {
3
+ readonly children: ReactNode;
4
+ readonly defaultOpen?: boolean;
5
+ /** What is set inside, shown next to the title while it is folded. */
6
+ readonly summary?: string | null;
7
+ }): ReactElement;
8
+ //# sourceMappingURL=advanced-section.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advanced-section.d.ts","sourceRoot":"","sources":["../../../client/components/advanced-section.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AASpE,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,WAAmB,EACnB,OAAO,GACR,EAAE;IACD,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,GAAG,YAAY,CAwBf"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /** Optional settings folded under "Advanced (optional)" in a dialog, open once someone asks for them. */
3
+ import { useTranslation } from '@nocobase/i18n/client';
4
+ import { ChevronRightIcon } from 'lucide-react';
5
+ import { useState } from 'react';
6
+ import { ACCESS_NAMESPACE } from '../../shared/access.js';
7
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from './ui/collapsible.js';
8
+ export function AdvancedSection({ children, defaultOpen = false, summary, }) {
9
+ const { t } = useTranslation(ACCESS_NAMESPACE);
10
+ const [open, setOpen] = useState(defaultOpen);
11
+ return (_jsxs(Collapsible, { open: open, onOpenChange: setOpen, className: 'flex flex-col gap-4', children: [_jsxs(CollapsibleTrigger, { className: 'group/advanced flex w-fit items-center gap-1 text-sm font-medium text-muted-foreground hover:text-foreground', children: [_jsx(ChevronRightIcon, { className: 'size-4 transition-transform group-data-[panel-open]/advanced:rotate-90', "aria-hidden": 'true' }), t('ui.advanced'), !open && summary ? (_jsxs("span", { className: 'font-normal', children: ["\u00B7 ", summary] })) : null] }), _jsx(CollapsibleContent, { className: 'flex flex-col gap-5', children: children })] }));
12
+ }
13
+ //# sourceMappingURL=advanced-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advanced-section.js","sourceRoot":"","sources":["../../../client/components/advanced-section.tsx"],"names":[],"mappings":";AAAA,yGAAyG;AACzG,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAqC,MAAM,OAAO,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,UAAU,eAAe,CAAC,EAC9B,QAAQ,EACR,WAAW,GAAG,KAAK,EACnB,OAAO,GAMR;IACC,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,CAAC,gBAAgB,CAAC,CAAC;IAC/C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC9C,OAAO,CACL,MAAC,WAAW,IACV,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,OAAO,EACrB,SAAS,EAAC,qBAAqB,aAE/B,MAAC,kBAAkB,IAAC,SAAS,EAAC,8GAA8G,aAC1I,KAAC,gBAAgB,IACf,SAAS,EAAC,wEAAwE,iBACtE,MAAM,GAClB,EACD,CAAC,CAAC,aAAa,CAAC,EAChB,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAClB,gBAAM,SAAS,EAAC,aAAa,wBAAI,OAAO,IAAQ,CACjD,CAAC,CAAC,CAAC,IAAI,IACW,EACrB,KAAC,kBAAkB,IAAC,SAAS,EAAC,qBAAqB,YAChD,QAAQ,GACU,IACT,CACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type ReactElement } from 'react';
2
+ import type { AppSummary } from '../../shared/releases.js';
3
+ export declare function AppSettingsCard({ summary, onSaved, }: {
4
+ readonly summary: AppSummary;
5
+ readonly onSaved: () => void;
6
+ }): ReactElement;
7
+ //# sourceMappingURL=app-settings-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-settings-card.d.ts","sourceRoot":"","sources":["../../../client/components/app-settings-card.tsx"],"names":[],"mappings":"AAMA,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAGpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AA6B3D,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,OAAO,GACR,EAAE;IACD,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B,GAAG,YAAY,CA8Ff"}
@@ -0,0 +1,69 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * An App's runtime policy and labels, on its Settings tab: a card saved on its own. Labels the assembling application
4
+ * added stay as they are and show read-only; the rest are edited as rows. A policy change reaches the runtime without
5
+ * restarting the App.
6
+ */
7
+ import { useTranslation } from '@nocobase/i18n/client';
8
+ import { useState } from 'react';
9
+ import { ACCESS_NAMESPACE } from '../../shared/access.js';
10
+ import { useNotify } from '../hooks/use-notify.js';
11
+ import { useReleasesApi } from '../hooks/use-releases.js';
12
+ import { labelRowErrors, labelsOf, newLabelRow, } from '../lib/labels.js';
13
+ import { parsePolicyDraft, policyDraft, } from '../lib/runtime-policy.js';
14
+ import { useSystemLabels } from '../lib/system-labels.js';
15
+ import { LabelsEditor } from './labels-editor.js';
16
+ import { RuntimePolicyFields } from './runtime-policy-fields.js';
17
+ import { Button } from './ui/button.js';
18
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from './ui/card.js';
19
+ import { Field, FieldGroup, FieldLabel, FieldSeparator } from './ui/field.js';
20
+ import { Spinner } from './ui/spinner.js';
21
+ export function AppSettingsCard({ summary, onSaved, }) {
22
+ const { t } = useTranslation(ACCESS_NAMESPACE);
23
+ const api = useReleasesApi();
24
+ const notify = useNotify();
25
+ const systemOf = useSystemLabels();
26
+ const system = systemOf(summary.app.labels);
27
+ const initialRows = () => Object.entries(summary.app.labels)
28
+ .filter(([key]) => !(key in system))
29
+ .map(([key, value]) => newLabelRow(key, value));
30
+ const [policy, setPolicy] = useState(() => policyDraft(summary.app));
31
+ const [rows, setRows] = useState(initialRows);
32
+ const [dirty, setDirty] = useState(false);
33
+ const [busy, setBusy] = useState(false);
34
+ const parsed = parsePolicyDraft(policy);
35
+ const labelsValid = labelRowErrors(rows, Object.keys(system)).size === 0;
36
+ const submit = async (event) => {
37
+ event.preventDefault();
38
+ if (!parsed.policy || !labelsValid)
39
+ return;
40
+ setBusy(true);
41
+ try {
42
+ await api.send('PATCH', `apps/${summary.app.id}`, {
43
+ ...parsed.policy,
44
+ labels: { ...labelsOf(rows), ...system },
45
+ });
46
+ notify.success(t('ui.settings.saved'));
47
+ setDirty(false);
48
+ onSaved();
49
+ }
50
+ catch (reason) {
51
+ notify.error(reason);
52
+ }
53
+ finally {
54
+ setBusy(false);
55
+ }
56
+ };
57
+ return (_jsxs(Card, { "data-slot": 'app-settings', children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: t('ui.settings.edit') }), _jsx(CardDescription, { children: t('ui.settings.editDescription') })] }), _jsx(CardContent, { children: _jsx("form", { id: 'rel-app-settings', onSubmit: (event) => void submit(event), children: _jsxs(FieldGroup, { children: [_jsx(RuntimePolicyFields, { value: policy, onChange: (next) => {
58
+ setPolicy(next);
59
+ setDirty(true);
60
+ } }), _jsx(FieldSeparator, {}), _jsxs(Field, { children: [_jsx(FieldLabel, { children: t('ui.apps.labels') }), _jsx(LabelsEditor, { rows: rows, onChange: (next) => {
61
+ setRows(next);
62
+ setDirty(true);
63
+ }, systemLabels: system })] })] }) }) }), _jsxs(CardFooter, { className: 'justify-end gap-2', children: [dirty ? (_jsx(Button, { variant: 'outline', disabled: busy, onClick: () => {
64
+ setPolicy(policyDraft(summary.app));
65
+ setRows(initialRows());
66
+ setDirty(false);
67
+ }, children: t('ui.config.discard') })) : null, _jsxs(Button, { type: 'submit', form: 'rel-app-settings', disabled: busy || !dirty || !parsed.policy || !labelsValid, children: [busy ? _jsx(Spinner, { "data-icon": 'inline-start' }) : null, t('ui.settings.save')] })] })] }));
68
+ }
69
+ //# sourceMappingURL=app-settings-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-settings-card.js","sourceRoot":"","sources":["../../../client/components/app-settings-card.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { DeploymentArtifact, ReleaseView } from '../../shared/releases.js';
3
+ export declare function ReleaseArtifacts({ release, }: {
4
+ readonly release: ReleaseView;
5
+ }): ReactElement;
6
+ export declare function DeploymentArtifactTag({ artifact, }: {
7
+ readonly artifact: DeploymentArtifact | null;
8
+ }): ReactElement;
9
+ //# sourceMappingURL=artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../../client/components/artifacts.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAOhF,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,GACR,EAAE;IACD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B,GAAG,YAAY,CAwCf;AAED,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC9C,GAAG,YAAY,CA0Bf"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * A release's artifacts and what a deployment ran. An archive release lists its archive; an image release its OCI
4
+ * images by platform and digest. A deployment shows the digest it pulled or the archive it ran in process.
5
+ */
6
+ import { useTranslation } from '@nocobase/i18n/client';
7
+ import { BoxIcon, PackageIcon } from 'lucide-react';
8
+ import { ACCESS_NAMESPACE } from '../../shared/access.js';
9
+ /** `sha256:0123456789ab…` → `0123456789ab`. */
10
+ function shortDigest(digest) {
11
+ return digest.replace(/^sha256:/u, '').slice(0, 12);
12
+ }
13
+ export function ReleaseArtifacts({ release, }) {
14
+ const { t } = useTranslation(ACCESS_NAMESPACE);
15
+ const images = (release.artifacts ?? []).filter((artifact) => artifact.kind === 'oci-image');
16
+ return (_jsxs("ul", { className: 'flex min-w-0 flex-col gap-1', "data-slot": 'release-artifacts', children: [release.kind === 'archive' ? (_jsxs("li", { className: 'flex items-center gap-1.5 text-xs', title: `${t('ui.artifacts.tarball')} sha256:${release.checksum}`, children: [_jsx(PackageIcon, { className: 'size-3.5 shrink-0 text-muted-foreground' }), _jsx("span", { className: 'text-muted-foreground', children: t('ui.artifacts.tarball') }), _jsx("span", { className: 'font-mono', children: release.checksum.slice(0, 12) })] })) : null, images.map((image) => (_jsxs("li", { className: 'flex min-w-0 items-center gap-1.5 text-xs', title: `${image.ref}@${image.digest}`, "data-slot": 'release-image', children: [_jsx(BoxIcon, { className: 'size-3.5 shrink-0 text-muted-foreground' }), _jsx("span", { className: 'text-muted-foreground', children: t('ui.artifacts.image') }), _jsxs("span", { className: 'truncate font-mono', children: [image.ref.split('/').slice(-1)[0], "@", shortDigest(image.digest)] }), _jsx("span", { className: 'shrink-0 text-muted-foreground', children: image.platform })] }, image.id)))] }));
17
+ }
18
+ export function DeploymentArtifactTag({ artifact, }) {
19
+ const { t } = useTranslation(ACCESS_NAMESPACE);
20
+ if (!artifact)
21
+ return _jsx("span", { className: 'text-muted-foreground', children: "\u2014" });
22
+ if (artifact.kind === 'image')
23
+ return (_jsxs("span", { className: 'inline-flex min-w-0 items-center gap-1.5 text-xs', title: `${artifact.ref}@${artifact.digest} (${artifact.platform})`, "data-slot": 'deployment-artifact', "data-kind": 'image', children: [_jsx(BoxIcon, { className: 'size-3.5 shrink-0 text-muted-foreground' }), _jsx("span", { className: 'font-mono', children: shortDigest(artifact.digest) }), _jsx("span", { className: 'text-muted-foreground', children: artifact.platform })] }));
24
+ return (_jsxs("span", { className: 'inline-flex items-center gap-1.5 text-xs text-muted-foreground', "data-slot": 'deployment-artifact', "data-kind": 'tarball', children: [_jsx(PackageIcon, { className: 'size-3.5 shrink-0' }), t('ui.artifacts.ranTarball')] }));
25
+ }
26
+ //# sourceMappingURL=artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../../client/components/artifacts.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { ReactElement } from 'react';
2
+ import { type ConfigSecret } from '../../shared/releases.js';
3
+ import { type ConfigSecretDrafts } from '../lib/config-secrets.js';
4
+ export declare function ConfigSecrets({ secrets, drafts, disabled, onChange, }: {
5
+ readonly secrets: readonly ConfigSecret[];
6
+ readonly drafts: ConfigSecretDrafts;
7
+ readonly disabled?: boolean;
8
+ readonly onChange: (drafts: ConfigSecretDrafts) => void;
9
+ }): ReactElement | null;
10
+ //# sourceMappingURL=config-secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-secrets.d.ts","sourceRoot":"","sources":["../../../client/components/config-secrets.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAKlC,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,MAAM,EACN,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACzD,GAAG,YAAY,GAAG,IAAI,CA2GtB"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * The secrets an App's `config.yml` holds, write-only like an environment's credentials: each reads "Set" with Replace
4
+ * and Clear, and its value is never shown. The server masks them in the configuration text (`CONFIG_SECRET_MASK`); a
5
+ * replacement or a removal is sent beside the text as a `ConfigSecretChange`.
6
+ */
7
+ import { useTranslation } from '@nocobase/i18n/client';
8
+ import { ACCESS_NAMESPACE } from '../../shared/access.js';
9
+ import { formatConfigPath } from '../../shared/releases.js';
10
+ import { configPathKey, } from '../lib/config-secrets.js';
11
+ import { Badge } from './ui/badge.js';
12
+ import { Button } from './ui/button.js';
13
+ import { Input } from './ui/input.js';
14
+ export function ConfigSecrets({ secrets, drafts, disabled, onChange, }) {
15
+ const { t } = useTranslation(ACCESS_NAMESPACE);
16
+ if (secrets.length === 0)
17
+ return null;
18
+ const set = (key, draft) => {
19
+ const next = { ...drafts };
20
+ if (draft)
21
+ next[key] = draft;
22
+ else
23
+ delete next[key];
24
+ onChange(next);
25
+ };
26
+ return (_jsxs("div", { className: 'space-y-2', "data-slot": 'config-secrets', children: [_jsxs("div", { children: [_jsx("p", { className: 'text-sm font-medium', children: t('ui.config.secrets') }), _jsx("p", { className: 'text-sm text-muted-foreground', children: t('ui.config.secretsHint') })] }), _jsx("ul", { className: 'divide-y rounded-lg border bg-card', children: secrets.map((secret) => {
27
+ const key = configPathKey(secret.path);
28
+ const label = formatConfigPath(secret.path);
29
+ const draft = drafts[key];
30
+ const inputId = `rel-config-secret-${encodeURIComponent(key)}`;
31
+ return (_jsxs("li", { className: 'flex flex-col gap-2 p-3 sm:flex-row sm:items-center sm:justify-between', children: [_jsx("label", { htmlFor: draft?.mode === 'replace' ? inputId : undefined, className: 'min-w-0 truncate font-mono text-xs', children: label }), draft?.mode === 'replace' ? (_jsxs("div", { className: 'flex flex-wrap items-center gap-2', children: [_jsx(Input, { id: inputId, type: 'password', autoComplete: 'new-password', autoFocus: true, className: 'h-8 w-full sm:w-64', "aria-label": t('ui.config.newValue', { path: label }), value: draft.value, disabled: disabled, onChange: (event) => set(key, { mode: 'replace', value: event.target.value }) }), _jsx(Button, { type: 'button', size: 'sm', variant: 'ghost', disabled: disabled, onClick: () => set(key, null), children: t('ui.driverForm.keepStored') })] })) : draft?.mode === 'clear' ? (_jsxs("div", { className: 'flex flex-wrap items-center gap-2', children: [_jsx(Badge, { variant: 'destructive', children: t('ui.driverForm.secretCleared') }), _jsx(Button, { type: 'button', size: 'sm', variant: 'ghost', disabled: disabled, onClick: () => set(key, null), children: t('ui.driverForm.undo') })] })) : (_jsxs("div", { className: 'flex flex-wrap items-center gap-2', children: [_jsx(Badge, { variant: 'secondary', children: t('ui.driverForm.secretSet') }), _jsx(Button, { type: 'button', size: 'sm', variant: 'outline', disabled: disabled, "aria-label": t('ui.config.replace', { path: label }), onClick: () => set(key, { mode: 'replace', value: '' }), children: t('ui.driverForm.replace') }), _jsx(Button, { type: 'button', size: 'sm', variant: 'ghost', disabled: disabled, "aria-label": t('ui.config.clear', { path: label }), onClick: () => set(key, { mode: 'clear', value: '' }), children: t('ui.driverForm.clear') })] }))] }, key));
32
+ }) })] }));
33
+ }
34
+ //# sourceMappingURL=config-secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-secrets.js","sourceRoot":"","sources":["../../../client/components/config-secrets.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type ReactElement, type ReactNode } from 'react';
2
+ export interface ConfirmOptions {
3
+ readonly title: string;
4
+ readonly description?: string;
5
+ /** More under the description, such as what else the action affects. */
6
+ readonly details?: ReactNode;
7
+ /** The action button's text. */
8
+ readonly action: string;
9
+ readonly destructive?: boolean;
10
+ /** Text the person must type before the action is enabled. */
11
+ readonly typeToConfirm?: string;
12
+ /** An optional note to write, named by `label`. */
13
+ readonly note?: {
14
+ readonly label: string;
15
+ readonly placeholder?: string;
16
+ };
17
+ }
18
+ export declare function useConfirmDialog(): {
19
+ readonly ask: (options: ConfirmOptions) => Promise<string | null>;
20
+ readonly dialog: ReactElement;
21
+ };
22
+ //# sourceMappingURL=confirm-dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-dialog.d.ts","sourceRoot":"","sources":["../../../client/components/confirm-dialog.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAoB,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAgB5E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B,gCAAgC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,8DAA8D;IAC9D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,mDAAmD;IACnD,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AAMD,wBAAgB,gBAAgB,IAAI;IAClC,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B,CA0FA"}
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Confirmations as the application's alert dialog rather than the browser's `confirm` / `prompt`: `ask()` opens it and
4
+ * resolves with what the person entered ('' when nothing is typed), or null when they cancel. With `typeToConfirm` the
5
+ * action stays disabled until that text is typed exactly, as protected deploys and deleting an App require; with `note`
6
+ * the person may write an optional note, such as why a request is rejected, which is what it resolves with.
7
+ */
8
+ import { useTranslation } from '@nocobase/i18n/client';
9
+ import { useRef, useState } from 'react';
10
+ import { ACCESS_NAMESPACE } from '../../shared/access.js';
11
+ import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from './ui/alert-dialog.js';
12
+ import { Button } from './ui/button.js';
13
+ import { Input } from './ui/input.js';
14
+ import { Textarea } from './ui/textarea.js';
15
+ export function useConfirmDialog() {
16
+ const { t } = useTranslation(ACCESS_NAMESPACE);
17
+ const [pending, setPending] = useState(null);
18
+ const [typed, setTyped] = useState('');
19
+ const inputRef = useRef(null);
20
+ const noteRef = useRef(null);
21
+ const close = (value) => {
22
+ pending?.resolve(value);
23
+ setPending(null);
24
+ setTyped('');
25
+ };
26
+ const ask = (options) => new Promise((resolve) => {
27
+ setTyped('');
28
+ setPending({ ...options, resolve });
29
+ });
30
+ const matches = pending?.typeToConfirm === undefined || typed === pending.typeToConfirm;
31
+ const dialog = (_jsx(AlertDialog, { open: pending !== null, onOpenChange: (open) => {
32
+ if (!open)
33
+ close(null);
34
+ }, children: _jsx(AlertDialogContent, { initialFocus: pending?.typeToConfirm
35
+ ? inputRef
36
+ : pending?.note
37
+ ? noteRef
38
+ : undefined, children: _jsxs("form", { className: 'grid gap-4', onSubmit: (event) => {
39
+ event.preventDefault();
40
+ if (matches)
41
+ close(typed);
42
+ }, children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: pending?.title }), pending?.description ? (_jsx(AlertDialogDescription, { children: pending.description })) : null] }), pending?.details ?? null, pending?.typeToConfirm !== undefined ? (_jsx(Input, { ref: inputRef, "aria-label": t('ui.confirm.typeLabel', {
43
+ text: pending.typeToConfirm,
44
+ }), placeholder: pending.typeToConfirm, autoComplete: 'off', spellCheck: false, className: 'font-mono', value: typed, onChange: (event) => setTyped(event.target.value) })) : null, pending?.note ? (_jsx(Textarea, { ref: noteRef, "aria-label": pending.note.label, placeholder: pending.note.placeholder ?? pending.note.label, maxLength: 2000, className: 'min-h-20', value: typed, onChange: (event) => setTyped(event.target.value) })) : null, _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: t('ui.confirm.cancel') }), _jsx(Button, { type: 'submit', variant: pending?.destructive ? 'destructive' : 'default', disabled: !matches, children: pending?.action })] })] }) }) }));
45
+ return { ask, dialog };
46
+ }
47
+ //# sourceMappingURL=confirm-dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-dialog.js","sourceRoot":"","sources":["../../../client/components/confirm-dialog.tsx"],"names":[],"mappings":"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"}