@btst/stack 3.0.0-rc.2 → 3.0.0-rc.3

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 (1168) hide show
  1. package/README.md +118 -38
  2. package/dist/api/index.cjs +133 -29
  3. package/dist/api/index.d.cts +14 -32
  4. package/dist/api/index.d.mts +14 -32
  5. package/dist/api/index.d.ts +14 -32
  6. package/dist/api/index.mjs +133 -28
  7. package/dist/authorization/client.cjs +154 -0
  8. package/dist/authorization/client.d.cts +70 -0
  9. package/dist/authorization/client.d.mts +70 -0
  10. package/dist/authorization/client.d.ts +70 -0
  11. package/dist/authorization/client.mjs +152 -0
  12. package/dist/authorization/index.cjs +371 -0
  13. package/dist/authorization/index.d.cts +201 -0
  14. package/dist/authorization/index.d.mts +201 -0
  15. package/dist/authorization/index.d.ts +201 -0
  16. package/dist/authorization/index.mjs +365 -0
  17. package/dist/authorization/remote.cjs +117 -0
  18. package/dist/authorization/remote.d.cts +79 -0
  19. package/dist/authorization/remote.d.mts +79 -0
  20. package/dist/authorization/remote.d.ts +79 -0
  21. package/dist/authorization/remote.mjs +111 -0
  22. package/dist/authorization/server.cjs +77 -0
  23. package/dist/authorization/server.d.cts +51 -0
  24. package/dist/authorization/server.d.mts +51 -0
  25. package/dist/authorization/server.d.ts +51 -0
  26. package/dist/authorization/server.mjs +73 -0
  27. package/dist/client/components/index.cjs +1 -0
  28. package/dist/client/components/index.d.cts +23 -6
  29. package/dist/client/components/index.d.mts +23 -6
  30. package/dist/client/components/index.d.ts +23 -6
  31. package/dist/client/components/index.mjs +1 -1
  32. package/dist/client/hooks/index.cjs +8 -0
  33. package/dist/client/hooks/index.d.cts +25 -0
  34. package/dist/client/hooks/index.d.mts +25 -0
  35. package/dist/client/hooks/index.d.ts +25 -0
  36. package/dist/client/hooks/index.mjs +2 -0
  37. package/dist/client/index.cjs +38 -7
  38. package/dist/client/index.d.cts +30 -100
  39. package/dist/client/index.d.mts +30 -100
  40. package/dist/client/index.d.ts +30 -100
  41. package/dist/client/index.mjs +38 -7
  42. package/dist/client/server.cjs +96 -0
  43. package/dist/client/server.d.cts +57 -0
  44. package/dist/client/server.d.mts +57 -0
  45. package/dist/client/server.d.ts +57 -0
  46. package/dist/client/server.mjs +92 -0
  47. package/dist/components/auto-form/index.d.cts +2 -2
  48. package/dist/components/auto-form/index.d.mts +2 -2
  49. package/dist/components/auto-form/index.d.ts +2 -2
  50. package/dist/components/form-builder/index.d.cts +1 -1
  51. package/dist/components/form-builder/index.d.mts +1 -1
  52. package/dist/components/form-builder/index.d.ts +1 -1
  53. package/dist/components/stepped-auto-form/index.d.cts +1 -1
  54. package/dist/components/stepped-auto-form/index.d.mts +1 -1
  55. package/dist/components/stepped-auto-form/index.d.ts +1 -1
  56. package/dist/context/index.cjs +8 -2
  57. package/dist/context/index.d.cts +111 -89
  58. package/dist/context/index.d.mts +111 -89
  59. package/dist/context/index.d.ts +111 -89
  60. package/dist/context/index.mjs +3 -1
  61. package/dist/index.cjs +1 -2
  62. package/dist/index.d.cts +8 -3
  63. package/dist/index.d.mts +8 -3
  64. package/dist/index.d.ts +8 -3
  65. package/dist/index.mjs +1 -1
  66. package/dist/next/index.d.cts +19 -7
  67. package/dist/next/index.d.mts +19 -7
  68. package/dist/next/index.d.ts +19 -7
  69. package/dist/next/server.cjs +7 -0
  70. package/dist/next/server.d.cts +56 -0
  71. package/dist/next/server.d.mts +56 -0
  72. package/dist/next/server.d.ts +56 -0
  73. package/dist/next/server.mjs +1 -0
  74. package/dist/packages/stack/src/authorization/json.cjs +57 -0
  75. package/dist/packages/stack/src/authorization/json.mjs +55 -0
  76. package/dist/packages/stack/src/client/components/compose.cjs +91 -9
  77. package/dist/packages/stack/src/client/components/compose.mjs +92 -11
  78. package/dist/packages/stack/src/client/runtime.cjs +295 -0
  79. package/dist/packages/stack/src/client/runtime.mjs +293 -0
  80. package/dist/packages/stack/src/context/auth.cjs +141 -73
  81. package/dist/packages/stack/src/context/auth.mjs +139 -73
  82. package/dist/packages/stack/src/context/provider.cjs +11 -5
  83. package/dist/packages/stack/src/context/provider.mjs +11 -5
  84. package/dist/packages/stack/src/context/router.cjs +9 -0
  85. package/dist/packages/stack/src/context/router.mjs +7 -0
  86. package/dist/packages/stack/src/context/site-navigation.cjs +40 -0
  87. package/dist/packages/stack/src/context/site-navigation.mjs +38 -0
  88. package/dist/packages/stack/src/next/layout.cjs +27 -0
  89. package/dist/packages/stack/src/next/layout.mjs +25 -0
  90. package/dist/packages/stack/src/plugin-registration.cjs +59 -0
  91. package/dist/packages/stack/src/plugin-registration.mjs +57 -0
  92. package/dist/packages/stack/src/plugins/ai-chat/api/lifecycle-migrations.cjs +18 -0
  93. package/dist/packages/stack/src/plugins/ai-chat/api/lifecycle-migrations.mjs +16 -0
  94. package/dist/packages/stack/src/plugins/ai-chat/api/operations.cjs +1341 -0
  95. package/dist/packages/stack/src/plugins/ai-chat/api/operations.mjs +1333 -0
  96. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +82 -640
  97. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +78 -641
  98. package/dist/packages/stack/src/plugins/ai-chat/api/serializers.cjs +23 -0
  99. package/dist/packages/stack/src/plugins/ai-chat/api/serializers.mjs +20 -0
  100. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.cjs +183 -111
  101. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.mjs +187 -115
  102. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.cjs +562 -116
  103. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.mjs +567 -121
  104. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.cjs +6 -6
  105. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.mjs +6 -6
  106. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-message.cjs +1 -1
  107. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-message.mjs +1 -1
  108. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.cjs +45 -29
  109. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.mjs +46 -30
  110. package/dist/packages/stack/src/plugins/ai-chat/client/components/pages/404-page.cjs +1 -1
  111. package/dist/packages/stack/src/plugins/ai-chat/client/components/pages/404-page.mjs +1 -1
  112. package/dist/packages/stack/src/plugins/ai-chat/client/components/pages/chat-page.cjs +46 -7
  113. package/dist/packages/stack/src/plugins/ai-chat/client/components/pages/chat-page.internal.cjs +5 -3
  114. package/dist/packages/stack/src/plugins/ai-chat/client/components/pages/chat-page.internal.mjs +5 -3
  115. package/dist/packages/stack/src/plugins/ai-chat/client/components/pages/chat-page.mjs +48 -9
  116. package/dist/packages/stack/src/plugins/ai-chat/client/components/shared/default-error.cjs +1 -1
  117. package/dist/packages/stack/src/plugins/ai-chat/client/components/shared/default-error.mjs +1 -1
  118. package/dist/packages/stack/src/plugins/ai-chat/client/components/tool-call-display.cjs +1 -1
  119. package/dist/packages/stack/src/plugins/ai-chat/client/components/tool-call-display.mjs +1 -1
  120. package/dist/packages/stack/src/plugins/ai-chat/client/hooks/ai-chat-resource.cjs +1 -1
  121. package/dist/packages/stack/src/plugins/ai-chat/client/hooks/ai-chat-resource.mjs +1 -1
  122. package/dist/packages/stack/src/plugins/ai-chat/client/hooks/chat-hooks.cjs +179 -19
  123. package/dist/packages/stack/src/plugins/ai-chat/client/hooks/chat-hooks.mjs +180 -21
  124. package/dist/packages/stack/src/plugins/ai-chat/client/navigation.cjs +11 -0
  125. package/dist/packages/stack/src/plugins/ai-chat/client/navigation.mjs +9 -0
  126. package/dist/packages/stack/src/plugins/ai-chat/client/overrides.cjs +24 -0
  127. package/dist/packages/stack/src/plugins/ai-chat/client/overrides.mjs +21 -1
  128. package/dist/packages/stack/src/plugins/ai-chat/client/plugin.cjs +152 -82
  129. package/dist/packages/stack/src/plugins/ai-chat/client/plugin.mjs +152 -82
  130. package/dist/packages/stack/src/plugins/api/create-endpoint.cjs +27 -9
  131. package/dist/packages/stack/src/plugins/api/create-endpoint.mjs +27 -10
  132. package/dist/packages/stack/src/plugins/api/endpoint-inventory.cjs +125 -0
  133. package/dist/packages/stack/src/plugins/api/endpoint-inventory.mjs +123 -0
  134. package/dist/packages/stack/src/plugins/api/operation.cjs +208 -0
  135. package/dist/packages/stack/src/plugins/api/operation.mjs +198 -0
  136. package/dist/packages/stack/src/plugins/blog/api/lifecycle-migrations.cjs +17 -0
  137. package/dist/packages/stack/src/plugins/blog/api/lifecycle-migrations.mjs +15 -0
  138. package/dist/packages/stack/src/plugins/blog/api/mutations.cjs +10 -2
  139. package/dist/packages/stack/src/plugins/blog/api/mutations.mjs +10 -2
  140. package/dist/packages/stack/src/plugins/blog/api/operations.cjs +455 -0
  141. package/dist/packages/stack/src/plugins/blog/api/operations.mjs +448 -0
  142. package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +51 -298
  143. package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +55 -304
  144. package/dist/packages/stack/src/plugins/blog/client/components/forms/image-field.cjs +2 -1
  145. package/dist/packages/stack/src/plugins/blog/client/components/forms/image-field.mjs +2 -1
  146. package/dist/packages/stack/src/plugins/blog/client/components/forms/markdown-editor-with-overrides.cjs +2 -1
  147. package/dist/packages/stack/src/plugins/blog/client/components/forms/markdown-editor-with-overrides.mjs +2 -1
  148. package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.cjs +82 -67
  149. package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.mjs +84 -69
  150. package/dist/packages/stack/src/plugins/blog/client/components/pages/404-page.cjs +2 -1
  151. package/dist/packages/stack/src/plugins/blog/client/components/pages/404-page.mjs +2 -1
  152. package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.cjs +22 -4
  153. package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.cjs +2 -1
  154. package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.mjs +2 -1
  155. package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.mjs +23 -5
  156. package/dist/packages/stack/src/plugins/blog/client/components/pages/home-page.cjs +6 -2
  157. package/dist/packages/stack/src/plugins/blog/client/components/pages/home-page.internal.cjs +2 -1
  158. package/dist/packages/stack/src/plugins/blog/client/components/pages/home-page.internal.mjs +2 -1
  159. package/dist/packages/stack/src/plugins/blog/client/components/pages/home-page.mjs +6 -2
  160. package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.cjs +4 -2
  161. package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.cjs +2 -1
  162. package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.mjs +2 -1
  163. package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.mjs +4 -2
  164. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.cjs +30 -3
  165. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.cjs +2 -1
  166. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.mjs +2 -1
  167. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.mjs +31 -4
  168. package/dist/packages/stack/src/plugins/blog/client/components/pages/tag-page.cjs +4 -1
  169. package/dist/packages/stack/src/plugins/blog/client/components/pages/tag-page.internal.cjs +2 -1
  170. package/dist/packages/stack/src/plugins/blog/client/components/pages/tag-page.internal.mjs +2 -1
  171. package/dist/packages/stack/src/plugins/blog/client/components/pages/tag-page.mjs +4 -1
  172. package/dist/packages/stack/src/plugins/blog/client/components/shared/collapsible-tag-list.cjs +2 -1
  173. package/dist/packages/stack/src/plugins/blog/client/components/shared/collapsible-tag-list.mjs +2 -1
  174. package/dist/packages/stack/src/plugins/blog/client/components/shared/default-error.cjs +2 -1
  175. package/dist/packages/stack/src/plugins/blog/client/components/shared/default-error.mjs +2 -1
  176. package/dist/packages/stack/src/plugins/blog/client/components/shared/on-this-page.cjs +3 -2
  177. package/dist/packages/stack/src/plugins/blog/client/components/shared/on-this-page.mjs +3 -2
  178. package/dist/packages/stack/src/plugins/blog/client/components/shared/page-wrapper.cjs +2 -1
  179. package/dist/packages/stack/src/plugins/blog/client/components/shared/page-wrapper.mjs +2 -1
  180. package/dist/packages/stack/src/plugins/blog/client/components/shared/post-card.cjs +2 -1
  181. package/dist/packages/stack/src/plugins/blog/client/components/shared/post-card.mjs +2 -1
  182. package/dist/packages/stack/src/plugins/blog/client/components/shared/posts-list.cjs +2 -1
  183. package/dist/packages/stack/src/plugins/blog/client/components/shared/posts-list.mjs +2 -1
  184. package/dist/packages/stack/src/plugins/blog/client/components/shared/recent-posts-carousel.cjs +2 -1
  185. package/dist/packages/stack/src/plugins/blog/client/components/shared/recent-posts-carousel.mjs +2 -1
  186. package/dist/packages/stack/src/plugins/blog/client/components/shared/search-input.cjs +2 -2
  187. package/dist/packages/stack/src/plugins/blog/client/components/shared/search-input.mjs +1 -1
  188. package/dist/packages/stack/src/plugins/blog/client/constants.cjs +5 -0
  189. package/dist/packages/stack/src/plugins/blog/client/constants.mjs +3 -0
  190. package/dist/packages/stack/src/plugins/blog/client/hooks/blog-resource.cjs +2 -1
  191. package/dist/packages/stack/src/plugins/blog/client/hooks/blog-resource.mjs +2 -1
  192. package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +169 -163
  193. package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +169 -163
  194. package/dist/packages/stack/src/plugins/client/resource/hooks.cjs +31 -16
  195. package/dist/packages/stack/src/plugins/client/resource/hooks.mjs +31 -16
  196. package/dist/packages/stack/src/plugins/client/resource/internal.cjs +66 -52
  197. package/dist/packages/stack/src/plugins/client/resource/internal.mjs +66 -52
  198. package/dist/packages/stack/src/plugins/client/resource/use-form.cjs +20 -17
  199. package/dist/packages/stack/src/plugins/client/resource/use-form.mjs +20 -17
  200. package/dist/packages/stack/src/plugins/client/resource/use-select.cjs +39 -33
  201. package/dist/packages/stack/src/plugins/client/resource/use-select.mjs +39 -33
  202. package/dist/packages/stack/src/plugins/cms/api/lifecycle-migrations.cjs +13 -0
  203. package/dist/packages/stack/src/plugins/cms/api/lifecycle-migrations.mjs +11 -0
  204. package/dist/packages/stack/src/plugins/cms/api/operations.cjs +1763 -0
  205. package/dist/packages/stack/src/plugins/cms/api/operations.mjs +1756 -0
  206. package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +165 -752
  207. package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +164 -755
  208. package/dist/packages/stack/src/plugins/cms/client/components/forms/content-form.cjs +2 -1
  209. package/dist/packages/stack/src/plugins/cms/client/components/forms/content-form.mjs +2 -1
  210. package/dist/packages/stack/src/plugins/cms/client/components/forms/file-upload.cjs +2 -1
  211. package/dist/packages/stack/src/plugins/cms/client/components/forms/file-upload.mjs +2 -1
  212. package/dist/packages/stack/src/plugins/cms/client/components/forms/relation-field.cjs +2 -1
  213. package/dist/packages/stack/src/plugins/cms/client/components/forms/relation-field.mjs +2 -1
  214. package/dist/packages/stack/src/plugins/cms/client/components/inverse-relations-panel.cjs +23 -13
  215. package/dist/packages/stack/src/plugins/cms/client/components/inverse-relations-panel.mjs +24 -14
  216. package/dist/packages/stack/src/plugins/cms/client/components/pages/404-page.cjs +5 -4
  217. package/dist/packages/stack/src/plugins/cms/client/components/pages/404-page.mjs +6 -5
  218. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.cjs +40 -7
  219. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.cjs +15 -9
  220. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.mjs +14 -8
  221. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.mjs +41 -8
  222. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-list-page.cjs +7 -1
  223. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-list-page.internal.cjs +42 -29
  224. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-list-page.internal.mjs +40 -27
  225. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-list-page.mjs +7 -1
  226. package/dist/packages/stack/src/plugins/cms/client/components/pages/dashboard-page.cjs +4 -1
  227. package/dist/packages/stack/src/plugins/cms/client/components/pages/dashboard-page.internal.cjs +13 -7
  228. package/dist/packages/stack/src/plugins/cms/client/components/pages/dashboard-page.internal.mjs +12 -6
  229. package/dist/packages/stack/src/plugins/cms/client/components/pages/dashboard-page.mjs +4 -1
  230. package/dist/packages/stack/src/plugins/cms/client/components/shared/page-wrapper.cjs +2 -1
  231. package/dist/packages/stack/src/plugins/cms/client/components/shared/page-wrapper.mjs +2 -1
  232. package/dist/packages/stack/src/plugins/cms/client/constants.cjs +5 -0
  233. package/dist/packages/stack/src/plugins/cms/client/constants.mjs +3 -0
  234. package/dist/packages/stack/src/plugins/cms/client/hooks/cms-resource.cjs +2 -1
  235. package/dist/packages/stack/src/plugins/cms/client/hooks/cms-resource.mjs +2 -1
  236. package/dist/packages/stack/src/plugins/cms/client/overrides.cjs +26 -0
  237. package/dist/packages/stack/src/plugins/cms/client/overrides.mjs +24 -0
  238. package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +102 -81
  239. package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +103 -82
  240. package/dist/packages/stack/src/plugins/comments/api/getters.cjs +6 -2
  241. package/dist/packages/stack/src/plugins/comments/api/getters.mjs +6 -3
  242. package/dist/packages/stack/src/plugins/comments/api/lifecycle-migrations.cjs +18 -0
  243. package/dist/packages/stack/src/plugins/comments/api/lifecycle-migrations.mjs +16 -0
  244. package/dist/packages/stack/src/plugins/comments/api/mutations.cjs +179 -68
  245. package/dist/packages/stack/src/plugins/comments/api/mutations.mjs +179 -68
  246. package/dist/packages/stack/src/plugins/comments/api/operations.cjs +453 -0
  247. package/dist/packages/stack/src/plugins/comments/api/operations.mjs +445 -0
  248. package/dist/packages/stack/src/plugins/comments/api/plugin.cjs +51 -276
  249. package/dist/packages/stack/src/plugins/comments/api/plugin.mjs +48 -277
  250. package/dist/packages/stack/src/plugins/comments/client/components/comment-count.cjs +32 -5
  251. package/dist/packages/stack/src/plugins/comments/client/components/comment-count.mjs +34 -7
  252. package/dist/packages/stack/src/plugins/comments/client/components/comment-thread.cjs +160 -104
  253. package/dist/packages/stack/src/plugins/comments/client/components/comment-thread.mjs +161 -105
  254. package/dist/packages/stack/src/plugins/comments/client/components/pages/moderation-page.cjs +14 -2
  255. package/dist/packages/stack/src/plugins/comments/client/components/pages/moderation-page.internal.cjs +141 -71
  256. package/dist/packages/stack/src/plugins/comments/client/components/pages/moderation-page.internal.mjs +142 -72
  257. package/dist/packages/stack/src/plugins/comments/client/components/pages/moderation-page.mjs +14 -2
  258. package/dist/packages/stack/src/plugins/comments/client/components/pages/moderation-state.cjs +12 -0
  259. package/dist/packages/stack/src/plugins/comments/client/components/pages/moderation-state.mjs +9 -0
  260. package/dist/packages/stack/src/plugins/comments/client/components/pages/my-comments-page.cjs +2 -1
  261. package/dist/packages/stack/src/plugins/comments/client/components/pages/my-comments-page.internal.cjs +40 -26
  262. package/dist/packages/stack/src/plugins/comments/client/components/pages/my-comments-page.internal.mjs +40 -26
  263. package/dist/packages/stack/src/plugins/comments/client/components/pages/my-comments-page.mjs +2 -1
  264. package/dist/packages/stack/src/plugins/comments/client/components/pages/resource-comments-page.cjs +9 -1
  265. package/dist/packages/stack/src/plugins/comments/client/components/pages/resource-comments-page.internal.cjs +25 -20
  266. package/dist/packages/stack/src/plugins/comments/client/components/pages/resource-comments-page.internal.mjs +26 -21
  267. package/dist/packages/stack/src/plugins/comments/client/components/pages/resource-comments-page.mjs +9 -1
  268. package/dist/packages/stack/src/plugins/comments/client/components/shared/page-wrapper.cjs +2 -1
  269. package/dist/packages/stack/src/plugins/comments/client/components/shared/page-wrapper.mjs +2 -1
  270. package/dist/packages/stack/src/plugins/comments/client/components/shared/pagination.cjs +2 -1
  271. package/dist/packages/stack/src/plugins/comments/client/components/shared/pagination.mjs +2 -1
  272. package/dist/packages/stack/src/plugins/comments/client/constants.cjs +5 -0
  273. package/dist/packages/stack/src/plugins/comments/client/constants.mjs +3 -0
  274. package/dist/packages/stack/src/plugins/comments/client/hooks/use-comments.cjs +323 -290
  275. package/dist/packages/stack/src/plugins/comments/client/hooks/use-comments.mjs +325 -292
  276. package/dist/packages/stack/src/plugins/comments/client/localization/comments-thread.cjs +1 -0
  277. package/dist/packages/stack/src/plugins/comments/client/localization/comments-thread.mjs +1 -0
  278. package/dist/packages/stack/src/plugins/comments/client/plugin.cjs +78 -46
  279. package/dist/packages/stack/src/plugins/comments/client/plugin.mjs +80 -48
  280. package/dist/packages/stack/src/plugins/form-builder/api/getters.cjs +9 -0
  281. package/dist/packages/stack/src/plugins/form-builder/api/getters.mjs +9 -1
  282. package/dist/packages/stack/src/plugins/form-builder/api/lifecycle-migrations.cjs +15 -0
  283. package/dist/packages/stack/src/plugins/form-builder/api/lifecycle-migrations.mjs +13 -0
  284. package/dist/packages/stack/src/plugins/form-builder/api/operations.cjs +1093 -0
  285. package/dist/packages/stack/src/plugins/form-builder/api/operations.mjs +1082 -0
  286. package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +97 -466
  287. package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +92 -468
  288. package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.cjs +5 -0
  289. package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.mjs +5 -0
  290. package/dist/packages/stack/src/plugins/form-builder/client/components/forms/form-renderer.cjs +41 -11
  291. package/dist/packages/stack/src/plugins/form-builder/client/components/forms/form-renderer.mjs +42 -12
  292. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/404-page.cjs +8 -5
  293. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/404-page.mjs +9 -6
  294. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-builder-page.cjs +36 -3
  295. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-builder-page.internal.cjs +32 -11
  296. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-builder-page.internal.mjs +35 -14
  297. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-builder-page.mjs +37 -4
  298. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-list-page.cjs +6 -1
  299. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-list-page.internal.cjs +34 -26
  300. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-list-page.internal.mjs +34 -26
  301. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-list-page.mjs +6 -1
  302. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.cjs +24 -7
  303. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.cjs +72 -40
  304. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.mjs +76 -44
  305. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.mjs +25 -8
  306. package/dist/packages/stack/src/plugins/form-builder/client/components/shared/page-wrapper.cjs +2 -1
  307. package/dist/packages/stack/src/plugins/form-builder/client/components/shared/page-wrapper.mjs +2 -1
  308. package/dist/packages/stack/src/plugins/form-builder/client/constants.cjs +5 -0
  309. package/dist/packages/stack/src/plugins/form-builder/client/constants.mjs +3 -0
  310. package/dist/packages/stack/src/plugins/form-builder/client/hooks/form-builder-hooks.cjs +29 -0
  311. package/dist/packages/stack/src/plugins/form-builder/client/hooks/form-builder-hooks.mjs +28 -1
  312. package/dist/packages/stack/src/plugins/form-builder/client/hooks/form-builder-resource.cjs +2 -1
  313. package/dist/packages/stack/src/plugins/form-builder/client/hooks/form-builder-resource.mjs +2 -1
  314. package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +113 -86
  315. package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +114 -87
  316. package/dist/packages/stack/src/plugins/form-builder/schemas.cjs +9 -3
  317. package/dist/packages/stack/src/plugins/form-builder/schemas.mjs +9 -3
  318. package/dist/packages/stack/src/plugins/kanban/api/getters.cjs +47 -36
  319. package/dist/packages/stack/src/plugins/kanban/api/getters.mjs +47 -37
  320. package/dist/packages/stack/src/plugins/kanban/api/lifecycle-migrations.cjs +23 -0
  321. package/dist/packages/stack/src/plugins/kanban/api/lifecycle-migrations.mjs +21 -0
  322. package/dist/packages/stack/src/plugins/kanban/api/operations.cjs +1552 -0
  323. package/dist/packages/stack/src/plugins/kanban/api/operations.mjs +1543 -0
  324. package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +64 -631
  325. package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +62 -634
  326. package/dist/packages/stack/src/plugins/kanban/api/serializers.cjs +21 -0
  327. package/dist/packages/stack/src/plugins/kanban/api/serializers.mjs +21 -1
  328. package/dist/packages/stack/src/plugins/kanban/client/components/forms/board-form.cjs +2 -1
  329. package/dist/packages/stack/src/plugins/kanban/client/components/forms/board-form.mjs +2 -1
  330. package/dist/packages/stack/src/plugins/kanban/client/components/forms/column-form.cjs +2 -1
  331. package/dist/packages/stack/src/plugins/kanban/client/components/forms/column-form.mjs +2 -1
  332. package/dist/packages/stack/src/plugins/kanban/client/components/forms/task-form.cjs +72 -54
  333. package/dist/packages/stack/src/plugins/kanban/client/components/forms/task-form.mjs +74 -56
  334. package/dist/packages/stack/src/plugins/kanban/client/components/pages/404-page.cjs +4 -6
  335. package/dist/packages/stack/src/plugins/kanban/client/components/pages/404-page.mjs +5 -7
  336. package/dist/packages/stack/src/plugins/kanban/client/components/pages/board-page.cjs +22 -6
  337. package/dist/packages/stack/src/plugins/kanban/client/components/pages/board-page.internal.cjs +82 -77
  338. package/dist/packages/stack/src/plugins/kanban/client/components/pages/board-page.internal.mjs +83 -78
  339. package/dist/packages/stack/src/plugins/kanban/client/components/pages/board-page.mjs +23 -7
  340. package/dist/packages/stack/src/plugins/kanban/client/components/pages/boards-list-page.cjs +2 -1
  341. package/dist/packages/stack/src/plugins/kanban/client/components/pages/boards-list-page.internal.cjs +34 -24
  342. package/dist/packages/stack/src/plugins/kanban/client/components/pages/boards-list-page.internal.mjs +35 -25
  343. package/dist/packages/stack/src/plugins/kanban/client/components/pages/boards-list-page.mjs +2 -1
  344. package/dist/packages/stack/src/plugins/kanban/client/components/pages/new-board-page.cjs +2 -1
  345. package/dist/packages/stack/src/plugins/kanban/client/components/pages/new-board-page.internal.cjs +6 -9
  346. package/dist/packages/stack/src/plugins/kanban/client/components/pages/new-board-page.internal.mjs +7 -10
  347. package/dist/packages/stack/src/plugins/kanban/client/components/pages/new-board-page.mjs +2 -1
  348. package/dist/packages/stack/src/plugins/kanban/client/components/shared/column-content.cjs +72 -45
  349. package/dist/packages/stack/src/plugins/kanban/client/components/shared/column-content.mjs +73 -46
  350. package/dist/packages/stack/src/plugins/kanban/client/components/shared/default-error.cjs +2 -1
  351. package/dist/packages/stack/src/plugins/kanban/client/components/shared/default-error.mjs +2 -1
  352. package/dist/packages/stack/src/plugins/kanban/client/components/shared/kanban-board.cjs +4 -4
  353. package/dist/packages/stack/src/plugins/kanban/client/components/shared/kanban-board.mjs +4 -4
  354. package/dist/packages/stack/src/plugins/kanban/client/components/shared/permission-access-any.cjs +23 -0
  355. package/dist/packages/stack/src/plugins/kanban/client/components/shared/permission-access-any.mjs +21 -0
  356. package/dist/packages/stack/src/plugins/kanban/client/components/shared/task-card.cjs +54 -17
  357. package/dist/packages/stack/src/plugins/kanban/client/components/shared/task-card.mjs +55 -18
  358. package/dist/packages/stack/src/plugins/kanban/client/components/shared/user-avatar.cjs +2 -1
  359. package/dist/packages/stack/src/plugins/kanban/client/components/shared/user-avatar.mjs +2 -1
  360. package/dist/packages/stack/src/plugins/kanban/client/constants.cjs +5 -0
  361. package/dist/packages/stack/src/plugins/kanban/client/constants.mjs +3 -0
  362. package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-hooks.cjs +38 -9
  363. package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-hooks.mjs +39 -10
  364. package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-resource.cjs +2 -1
  365. package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-resource.mjs +2 -1
  366. package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +177 -104
  367. package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +178 -105
  368. package/dist/packages/stack/src/plugins/kanban/schemas.cjs +32 -23
  369. package/dist/packages/stack/src/plugins/kanban/schemas.mjs +33 -21
  370. package/dist/packages/stack/src/plugins/media/api/lifecycle-migrations.cjs +9 -0
  371. package/dist/packages/stack/src/plugins/media/api/lifecycle-migrations.mjs +7 -0
  372. package/dist/packages/stack/src/plugins/media/api/mutations.cjs +7 -2
  373. package/dist/packages/stack/src/plugins/media/api/mutations.mjs +7 -2
  374. package/dist/packages/stack/src/plugins/media/api/operations.cjs +1299 -0
  375. package/dist/packages/stack/src/plugins/media/api/operations.mjs +1290 -0
  376. package/dist/packages/stack/src/plugins/media/api/plugin.cjs +131 -508
  377. package/dist/packages/stack/src/plugins/media/api/plugin.mjs +127 -510
  378. package/dist/packages/stack/src/plugins/media/api/query-key-defs.cjs +26 -2
  379. package/dist/packages/stack/src/plugins/media/api/query-key-defs.mjs +25 -3
  380. package/dist/packages/stack/src/plugins/media/api/serializers.cjs +4 -2
  381. package/dist/packages/stack/src/plugins/media/api/serializers.mjs +4 -2
  382. package/dist/packages/stack/src/plugins/media/asset-url.cjs +13 -0
  383. package/dist/packages/stack/src/plugins/media/asset-url.mjs +11 -0
  384. package/dist/packages/stack/src/plugins/media/client/components/media-picker/asset-card.cjs +10 -10
  385. package/dist/packages/stack/src/plugins/media/client/components/media-picker/asset-card.mjs +12 -12
  386. package/dist/packages/stack/src/plugins/media/client/components/media-picker/folder-tree.cjs +47 -27
  387. package/dist/packages/stack/src/plugins/media/client/components/media-picker/folder-tree.mjs +49 -29
  388. package/dist/packages/stack/src/plugins/media/client/components/media-picker/index.cjs +225 -180
  389. package/dist/packages/stack/src/plugins/media/client/components/media-picker/index.mjs +228 -183
  390. package/dist/packages/stack/src/plugins/media/client/components/media-picker/upload-tab.cjs +1 -8
  391. package/dist/packages/stack/src/plugins/media/client/components/media-picker/upload-tab.mjs +2 -9
  392. package/dist/packages/stack/src/plugins/media/client/components/media-picker/url-tab.cjs +0 -6
  393. package/dist/packages/stack/src/plugins/media/client/components/media-picker/url-tab.mjs +1 -7
  394. package/dist/packages/stack/src/plugins/media/client/components/pages/library-page.cjs +4 -2
  395. package/dist/packages/stack/src/plugins/media/client/components/pages/library-page.internal.cjs +92 -75
  396. package/dist/packages/stack/src/plugins/media/client/components/pages/library-page.internal.mjs +93 -76
  397. package/dist/packages/stack/src/plugins/media/client/components/pages/library-page.mjs +4 -2
  398. package/dist/packages/stack/src/plugins/media/client/components/upload-permission-check.cjs +52 -0
  399. package/dist/packages/stack/src/plugins/media/client/components/upload-permission-check.mjs +49 -0
  400. package/dist/packages/stack/src/plugins/media/client/constants.cjs +5 -0
  401. package/dist/packages/stack/src/plugins/media/client/constants.mjs +3 -0
  402. package/dist/packages/stack/src/plugins/media/client/hooks/media-resource.cjs +2 -1
  403. package/dist/packages/stack/src/plugins/media/client/hooks/media-resource.mjs +2 -1
  404. package/dist/packages/stack/src/plugins/media/client/hooks/use-media.cjs +214 -43
  405. package/dist/packages/stack/src/plugins/media/client/hooks/use-media.mjs +217 -46
  406. package/dist/packages/stack/src/plugins/media/client/plugin.cjs +122 -62
  407. package/dist/packages/stack/src/plugins/media/client/plugin.mjs +123 -63
  408. package/dist/packages/stack/src/plugins/media/client/upload.cjs +121 -52
  409. package/dist/packages/stack/src/plugins/media/client/upload.mjs +121 -53
  410. package/dist/packages/stack/src/plugins/media/db.cjs +8 -0
  411. package/dist/packages/stack/src/plugins/media/db.mjs +8 -0
  412. package/dist/packages/stack/src/plugins/open-api/api/generator.cjs +36 -5
  413. package/dist/packages/stack/src/plugins/open-api/api/generator.mjs +36 -5
  414. package/dist/packages/stack/src/plugins/open-api/api/plugin.cjs +22 -11
  415. package/dist/packages/stack/src/plugins/open-api/api/plugin.mjs +22 -11
  416. package/dist/packages/stack/src/plugins/route-docs/client/components/pages/docs-page.cjs +65 -34
  417. package/dist/packages/stack/src/plugins/route-docs/client/components/pages/docs-page.mjs +56 -25
  418. package/dist/packages/stack/src/plugins/route-docs/client/constants.cjs +5 -0
  419. package/dist/packages/stack/src/plugins/route-docs/client/constants.mjs +3 -0
  420. package/dist/packages/stack/src/plugins/route-docs/client/hooks.cjs +9 -8
  421. package/dist/packages/stack/src/plugins/route-docs/client/hooks.mjs +10 -9
  422. package/dist/packages/stack/src/plugins/route-docs/client/plugin.cjs +143 -75
  423. package/dist/packages/stack/src/plugins/route-docs/client/plugin.mjs +144 -74
  424. package/dist/packages/stack/src/plugins/route-docs/client/schema.cjs +26 -0
  425. package/dist/packages/stack/src/plugins/route-docs/client/schema.mjs +23 -0
  426. package/dist/packages/stack/src/plugins/route-docs/generator.cjs +7 -4
  427. package/dist/packages/stack/src/plugins/route-docs/generator.mjs +7 -4
  428. package/dist/packages/stack/src/plugins/ui-builder/client/components/page-renderer.cjs +41 -12
  429. package/dist/packages/stack/src/plugins/ui-builder/client/components/page-renderer.mjs +42 -13
  430. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.cjs +37 -3
  431. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.cjs +32 -20
  432. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.mjs +34 -22
  433. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.mjs +38 -4
  434. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-list-page.cjs +8 -2
  435. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-list-page.internal.cjs +37 -19
  436. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-list-page.internal.mjs +38 -20
  437. package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-list-page.mjs +8 -2
  438. package/dist/packages/stack/src/plugins/ui-builder/client/components/shared/default-error.cjs +2 -1
  439. package/dist/packages/stack/src/plugins/ui-builder/client/components/shared/default-error.mjs +2 -1
  440. package/dist/packages/stack/src/plugins/ui-builder/client/components/shared/page-wrapper.cjs +2 -1
  441. package/dist/packages/stack/src/plugins/ui-builder/client/components/shared/page-wrapper.mjs +2 -1
  442. package/dist/packages/stack/src/plugins/ui-builder/client/constants.cjs +5 -0
  443. package/dist/packages/stack/src/plugins/ui-builder/client/constants.mjs +3 -0
  444. package/dist/packages/stack/src/plugins/ui-builder/client/hooks/ui-builder-resource.cjs +2 -1
  445. package/dist/packages/stack/src/plugins/ui-builder/client/hooks/ui-builder-resource.mjs +2 -1
  446. package/dist/packages/stack/src/plugins/ui-builder/client/overrides.cjs +8 -0
  447. package/dist/packages/stack/src/plugins/ui-builder/client/overrides.mjs +6 -0
  448. package/dist/packages/stack/src/plugins/ui-builder/client/plugin.cjs +93 -53
  449. package/dist/packages/stack/src/plugins/ui-builder/client/plugin.mjs +94 -54
  450. package/dist/packages/stack/src/plugins/utils.cjs +4 -12
  451. package/dist/packages/stack/src/plugins/utils.mjs +5 -12
  452. package/dist/packages/stack/src/react-router/layout.cjs +14 -0
  453. package/dist/packages/stack/src/react-router/layout.mjs +12 -0
  454. package/dist/packages/stack/src/react-router/page.cjs +10 -5
  455. package/dist/packages/stack/src/react-router/page.mjs +11 -6
  456. package/dist/packages/stack/src/shared/initial-identity.cjs +27 -0
  457. package/dist/packages/stack/src/shared/initial-identity.mjs +23 -0
  458. package/dist/packages/stack/src/tanstack/layout.cjs +10 -0
  459. package/dist/packages/stack/src/tanstack/layout.mjs +8 -0
  460. package/dist/packages/stack/src/tanstack/page.cjs +6 -2
  461. package/dist/packages/stack/src/tanstack/page.mjs +6 -2
  462. package/dist/plugins/ai-chat/api/index.cjs +10 -0
  463. package/dist/plugins/ai-chat/api/index.d.cts +31 -5
  464. package/dist/plugins/ai-chat/api/index.d.mts +31 -5
  465. package/dist/plugins/ai-chat/api/index.d.ts +31 -5
  466. package/dist/plugins/ai-chat/api/index.mjs +3 -1
  467. package/dist/plugins/ai-chat/client/components/index.d.cts +1 -1
  468. package/dist/plugins/ai-chat/client/components/index.d.mts +1 -1
  469. package/dist/plugins/ai-chat/client/components/index.d.ts +1 -1
  470. package/dist/plugins/ai-chat/client/hooks/index.cjs +1 -0
  471. package/dist/plugins/ai-chat/client/hooks/index.d.cts +14 -8
  472. package/dist/plugins/ai-chat/client/hooks/index.d.mts +14 -8
  473. package/dist/plugins/ai-chat/client/hooks/index.d.ts +14 -8
  474. package/dist/plugins/ai-chat/client/hooks/index.mjs +1 -1
  475. package/dist/plugins/ai-chat/client/index.d.cts +21 -25
  476. package/dist/plugins/ai-chat/client/index.d.mts +21 -25
  477. package/dist/plugins/ai-chat/client/index.d.ts +21 -25
  478. package/dist/plugins/ai-chat/permissions.cjs +90 -0
  479. package/dist/plugins/ai-chat/permissions.d.cts +84 -0
  480. package/dist/plugins/ai-chat/permissions.d.mts +84 -0
  481. package/dist/plugins/ai-chat/permissions.d.ts +84 -0
  482. package/dist/plugins/ai-chat/permissions.mjs +88 -0
  483. package/dist/plugins/ai-chat/query-keys.cjs +116 -18
  484. package/dist/plugins/ai-chat/query-keys.d.cts +6 -2
  485. package/dist/plugins/ai-chat/query-keys.d.mts +6 -2
  486. package/dist/plugins/ai-chat/query-keys.d.ts +6 -2
  487. package/dist/plugins/ai-chat/query-keys.mjs +116 -19
  488. package/dist/plugins/api/index.cjs +4 -0
  489. package/dist/plugins/api/index.d.cts +13 -18
  490. package/dist/plugins/api/index.d.mts +13 -18
  491. package/dist/plugins/api/index.d.ts +13 -18
  492. package/dist/plugins/api/index.mjs +1 -0
  493. package/dist/plugins/blog/api/index.cjs +9 -2
  494. package/dist/plugins/blog/api/index.d.cts +118 -4
  495. package/dist/plugins/blog/api/index.d.mts +118 -4
  496. package/dist/plugins/blog/api/index.d.ts +118 -4
  497. package/dist/plugins/blog/api/index.mjs +4 -1
  498. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  499. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  500. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  501. package/dist/plugins/blog/client/index.d.cts +210 -226
  502. package/dist/plugins/blog/client/index.d.mts +210 -226
  503. package/dist/plugins/blog/client/index.d.ts +210 -226
  504. package/dist/plugins/blog/permissions.cjs +47 -0
  505. package/dist/plugins/blog/permissions.d.cts +49 -0
  506. package/dist/plugins/blog/permissions.d.mts +49 -0
  507. package/dist/plugins/blog/permissions.d.ts +49 -0
  508. package/dist/plugins/blog/permissions.mjs +45 -0
  509. package/dist/plugins/blog/query-keys.d.cts +7 -3
  510. package/dist/plugins/blog/query-keys.d.mts +7 -3
  511. package/dist/plugins/blog/query-keys.d.ts +7 -3
  512. package/dist/plugins/client/hooks/index.d.cts +2 -2
  513. package/dist/plugins/client/hooks/index.d.mts +2 -2
  514. package/dist/plugins/client/hooks/index.d.ts +2 -2
  515. package/dist/plugins/client/index.cjs +3 -0
  516. package/dist/plugins/client/index.d.cts +30 -10
  517. package/dist/plugins/client/index.d.mts +30 -10
  518. package/dist/plugins/client/index.d.ts +30 -10
  519. package/dist/plugins/client/index.mjs +3 -0
  520. package/dist/plugins/cms/api/index.cjs +7 -0
  521. package/dist/plugins/cms/api/index.d.cts +173 -4
  522. package/dist/plugins/cms/api/index.d.mts +173 -4
  523. package/dist/plugins/cms/api/index.d.ts +173 -4
  524. package/dist/plugins/cms/api/index.mjs +2 -0
  525. package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
  526. package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
  527. package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
  528. package/dist/plugins/cms/client/index.d.cts +188 -184
  529. package/dist/plugins/cms/client/index.d.mts +188 -184
  530. package/dist/plugins/cms/client/index.d.ts +188 -184
  531. package/dist/plugins/cms/permissions.cjs +46 -0
  532. package/dist/plugins/cms/permissions.d.cts +42 -0
  533. package/dist/plugins/cms/permissions.d.mts +42 -0
  534. package/dist/plugins/cms/permissions.d.ts +42 -0
  535. package/dist/plugins/cms/permissions.mjs +44 -0
  536. package/dist/plugins/cms/query-keys.d.cts +4 -4
  537. package/dist/plugins/cms/query-keys.d.mts +4 -4
  538. package/dist/plugins/cms/query-keys.d.ts +4 -4
  539. package/dist/plugins/comments/api/index.cjs +10 -0
  540. package/dist/plugins/comments/api/index.d.cts +54 -18
  541. package/dist/plugins/comments/api/index.d.mts +54 -18
  542. package/dist/plugins/comments/api/index.d.ts +54 -18
  543. package/dist/plugins/comments/api/index.mjs +3 -0
  544. package/dist/plugins/comments/client/components/index.d.cts +2 -2
  545. package/dist/plugins/comments/client/components/index.d.mts +2 -2
  546. package/dist/plugins/comments/client/components/index.d.ts +2 -2
  547. package/dist/plugins/comments/client/hooks/index.d.cts +12 -18
  548. package/dist/plugins/comments/client/hooks/index.d.mts +12 -18
  549. package/dist/plugins/comments/client/hooks/index.d.ts +12 -18
  550. package/dist/plugins/comments/client/index.d.cts +96 -114
  551. package/dist/plugins/comments/client/index.d.mts +96 -114
  552. package/dist/plugins/comments/client/index.d.ts +96 -114
  553. package/dist/plugins/comments/permissions.cjs +70 -0
  554. package/dist/plugins/comments/permissions.d.cts +76 -0
  555. package/dist/plugins/comments/permissions.d.mts +76 -0
  556. package/dist/plugins/comments/permissions.d.ts +76 -0
  557. package/dist/plugins/comments/permissions.mjs +68 -0
  558. package/dist/plugins/comments/query-keys.cjs +1 -1
  559. package/dist/plugins/comments/query-keys.d.cts +16 -19
  560. package/dist/plugins/comments/query-keys.d.mts +16 -19
  561. package/dist/plugins/comments/query-keys.d.ts +16 -19
  562. package/dist/plugins/comments/query-keys.mjs +1 -1
  563. package/dist/plugins/form-builder/api/index.cjs +8 -0
  564. package/dist/plugins/form-builder/api/index.d.cts +115 -4
  565. package/dist/plugins/form-builder/api/index.d.mts +115 -4
  566. package/dist/plugins/form-builder/api/index.d.ts +115 -4
  567. package/dist/plugins/form-builder/api/index.mjs +4 -1
  568. package/dist/plugins/form-builder/client/components/index.d.cts +6 -2
  569. package/dist/plugins/form-builder/client/components/index.d.mts +6 -2
  570. package/dist/plugins/form-builder/client/components/index.d.ts +6 -2
  571. package/dist/plugins/form-builder/client/hooks/index.cjs +2 -0
  572. package/dist/plugins/form-builder/client/hooks/index.d.cts +34 -8
  573. package/dist/plugins/form-builder/client/hooks/index.d.mts +34 -8
  574. package/dist/plugins/form-builder/client/hooks/index.d.ts +34 -8
  575. package/dist/plugins/form-builder/client/hooks/index.mjs +1 -1
  576. package/dist/plugins/form-builder/client/index.d.cts +153 -174
  577. package/dist/plugins/form-builder/client/index.d.mts +153 -174
  578. package/dist/plugins/form-builder/client/index.d.ts +153 -174
  579. package/dist/plugins/form-builder/permissions.cjs +95 -0
  580. package/dist/plugins/form-builder/permissions.d.cts +94 -0
  581. package/dist/plugins/form-builder/permissions.d.mts +94 -0
  582. package/dist/plugins/form-builder/permissions.d.ts +94 -0
  583. package/dist/plugins/form-builder/permissions.mjs +93 -0
  584. package/dist/plugins/form-builder/query-keys.cjs +11 -4
  585. package/dist/plugins/form-builder/query-keys.d.cts +38 -12
  586. package/dist/plugins/form-builder/query-keys.d.mts +38 -12
  587. package/dist/plugins/form-builder/query-keys.d.ts +38 -12
  588. package/dist/plugins/form-builder/query-keys.mjs +11 -4
  589. package/dist/plugins/kanban/api/index.cjs +9 -0
  590. package/dist/plugins/kanban/api/index.d.cts +137 -5
  591. package/dist/plugins/kanban/api/index.d.mts +137 -5
  592. package/dist/plugins/kanban/api/index.d.ts +137 -5
  593. package/dist/plugins/kanban/api/index.mjs +5 -2
  594. package/dist/plugins/kanban/client/components/index.d.cts +18 -10
  595. package/dist/plugins/kanban/client/components/index.d.mts +18 -10
  596. package/dist/plugins/kanban/client/components/index.d.ts +18 -10
  597. package/dist/plugins/kanban/client/hooks/index.d.cts +15 -7
  598. package/dist/plugins/kanban/client/hooks/index.d.mts +15 -7
  599. package/dist/plugins/kanban/client/hooks/index.d.ts +15 -7
  600. package/dist/plugins/kanban/client/index.d.cts +32 -28
  601. package/dist/plugins/kanban/client/index.d.mts +32 -28
  602. package/dist/plugins/kanban/client/index.d.ts +32 -28
  603. package/dist/plugins/kanban/permissions.cjs +101 -0
  604. package/dist/plugins/kanban/permissions.d.cts +109 -0
  605. package/dist/plugins/kanban/permissions.d.mts +109 -0
  606. package/dist/plugins/kanban/permissions.d.ts +109 -0
  607. package/dist/plugins/kanban/permissions.mjs +99 -0
  608. package/dist/plugins/kanban/query-keys.cjs +14 -15
  609. package/dist/plugins/kanban/query-keys.d.cts +63 -42
  610. package/dist/plugins/kanban/query-keys.d.mts +63 -42
  611. package/dist/plugins/kanban/query-keys.d.ts +63 -42
  612. package/dist/plugins/kanban/query-keys.mjs +14 -15
  613. package/dist/plugins/media/api/adapters/local.d.cts +1 -1
  614. package/dist/plugins/media/api/adapters/local.d.mts +1 -1
  615. package/dist/plugins/media/api/adapters/local.d.ts +1 -1
  616. package/dist/plugins/media/api/adapters/s3.d.cts +1 -1
  617. package/dist/plugins/media/api/adapters/s3.d.mts +1 -1
  618. package/dist/plugins/media/api/adapters/s3.d.ts +1 -1
  619. package/dist/plugins/media/api/adapters/vercel-blob.cjs +46 -0
  620. package/dist/plugins/media/api/adapters/vercel-blob.d.cts +6 -9
  621. package/dist/plugins/media/api/adapters/vercel-blob.d.mts +6 -9
  622. package/dist/plugins/media/api/adapters/vercel-blob.d.ts +6 -9
  623. package/dist/plugins/media/api/adapters/vercel-blob.mjs +46 -0
  624. package/dist/plugins/media/api/index.cjs +10 -0
  625. package/dist/plugins/media/api/index.d.cts +93 -6
  626. package/dist/plugins/media/api/index.d.mts +93 -6
  627. package/dist/plugins/media/api/index.d.ts +93 -6
  628. package/dist/plugins/media/api/index.mjs +2 -0
  629. package/dist/plugins/media/client/components/index.d.cts +1 -1
  630. package/dist/plugins/media/client/components/index.d.mts +1 -1
  631. package/dist/plugins/media/client/components/index.d.ts +1 -1
  632. package/dist/plugins/media/client/hooks/index.d.cts +20 -10
  633. package/dist/plugins/media/client/hooks/index.d.mts +20 -10
  634. package/dist/plugins/media/client/hooks/index.d.ts +20 -10
  635. package/dist/plugins/media/client/index.cjs +1 -0
  636. package/dist/plugins/media/client/index.d.cts +112 -100
  637. package/dist/plugins/media/client/index.d.mts +112 -100
  638. package/dist/plugins/media/client/index.d.ts +112 -100
  639. package/dist/plugins/media/client/index.mjs +1 -1
  640. package/dist/plugins/media/permissions.cjs +63 -0
  641. package/dist/plugins/media/permissions.d.cts +64 -0
  642. package/dist/plugins/media/permissions.d.mts +64 -0
  643. package/dist/plugins/media/permissions.d.ts +64 -0
  644. package/dist/plugins/media/permissions.mjs +61 -0
  645. package/dist/plugins/media/query-keys.cjs +29 -17
  646. package/dist/plugins/media/query-keys.d.cts +24 -31
  647. package/dist/plugins/media/query-keys.d.mts +24 -31
  648. package/dist/plugins/media/query-keys.d.ts +24 -31
  649. package/dist/plugins/media/query-keys.mjs +30 -18
  650. package/dist/plugins/open-api/api/index.d.cts +9 -4
  651. package/dist/plugins/open-api/api/index.d.mts +9 -4
  652. package/dist/plugins/open-api/api/index.d.ts +9 -4
  653. package/dist/plugins/route-docs/client/index.cjs +2 -2
  654. package/dist/plugins/route-docs/client/index.d.cts +54 -53
  655. package/dist/plugins/route-docs/client/index.d.mts +54 -53
  656. package/dist/plugins/route-docs/client/index.d.ts +54 -53
  657. package/dist/plugins/route-docs/client/index.mjs +2 -1
  658. package/dist/plugins/ui-builder/client/components/index.d.cts +8 -5
  659. package/dist/plugins/ui-builder/client/components/index.d.mts +8 -5
  660. package/dist/plugins/ui-builder/client/components/index.d.ts +8 -5
  661. package/dist/plugins/ui-builder/client/hooks/index.d.cts +5 -5
  662. package/dist/plugins/ui-builder/client/hooks/index.d.mts +5 -5
  663. package/dist/plugins/ui-builder/client/hooks/index.d.ts +5 -5
  664. package/dist/plugins/ui-builder/client/index.d.cts +151 -199
  665. package/dist/plugins/ui-builder/client/index.d.mts +151 -199
  666. package/dist/plugins/ui-builder/client/index.d.ts +151 -199
  667. package/dist/plugins/ui-builder/index.d.cts +11 -8
  668. package/dist/plugins/ui-builder/index.d.mts +11 -8
  669. package/dist/plugins/ui-builder/index.d.ts +11 -8
  670. package/dist/plugins/ui-builder/query-keys.d.cts +6 -6
  671. package/dist/plugins/ui-builder/query-keys.d.mts +6 -6
  672. package/dist/plugins/ui-builder/query-keys.d.ts +6 -6
  673. package/dist/react-router/index.cjs +2 -0
  674. package/dist/react-router/index.d.cts +29 -5
  675. package/dist/react-router/index.d.mts +29 -5
  676. package/dist/react-router/index.d.ts +29 -5
  677. package/dist/react-router/index.mjs +1 -0
  678. package/dist/shared/stack.0O62uXqP.d.ts +613 -0
  679. package/dist/shared/stack.0y6iTP03.d.ts +533 -0
  680. package/dist/shared/{stack.CbZenbej.d.cts → stack.1ukVJym7.d.cts} +3 -4
  681. package/dist/shared/{stack.CbZenbej.d.mts → stack.1ukVJym7.d.mts} +3 -4
  682. package/dist/shared/{stack.CbZenbej.d.ts → stack.1ukVJym7.d.ts} +3 -4
  683. package/dist/shared/stack.3Sr6qRtT.d.ts +507 -0
  684. package/dist/shared/{stack.9BAOaSqE.d.cts → stack.5_zzCejP.d.cts} +16 -14
  685. package/dist/shared/{stack.9BAOaSqE.d.mts → stack.5_zzCejP.d.mts} +16 -14
  686. package/dist/shared/{stack.9BAOaSqE.d.ts → stack.5_zzCejP.d.ts} +16 -14
  687. package/dist/shared/stack.B1UrNoVl.d.mts +533 -0
  688. package/dist/shared/{stack.B2xi4jj7.d.cts → stack.B1srlBud.d.mts} +2 -2
  689. package/dist/shared/stack.B3_aDcYL.d.cts +281 -0
  690. package/dist/shared/stack.B3_aDcYL.d.mts +281 -0
  691. package/dist/shared/stack.B3_aDcYL.d.ts +281 -0
  692. package/dist/shared/stack.B5yPgHsp.d.mts +507 -0
  693. package/dist/shared/stack.B8PG21zX.d.mts +764 -0
  694. package/dist/shared/stack.BFP_9pRX.d.cts +707 -0
  695. package/dist/shared/{stack.DzwZw-Ck.d.cts → stack.BGzgFx3R.d.cts} +2 -2
  696. package/dist/shared/stack.BJx1ZXrN.d.cts +118 -0
  697. package/dist/shared/{stack.7b3vsM8_.d.ts → stack.BK9Z2dcL.d.ts} +2 -2
  698. package/dist/shared/stack.BMHoxAn7.d.mts +707 -0
  699. package/dist/shared/stack.BMmvEBH_.d.ts +118 -0
  700. package/dist/shared/stack.BOZRaVpu.d.cts +1184 -0
  701. package/dist/shared/stack.BPLykw4s.d.ts +436 -0
  702. package/dist/shared/{stack.aqVZ6PEW.d.mts → stack.BRvqQWGt.d.cts} +40 -1
  703. package/dist/shared/{stack.aqVZ6PEW.d.cts → stack.BRvqQWGt.d.mts} +40 -1
  704. package/dist/shared/{stack.aqVZ6PEW.d.ts → stack.BRvqQWGt.d.ts} +40 -1
  705. package/dist/shared/stack.BSACE667.d.cts +23 -0
  706. package/dist/shared/stack.BYMentwB.d.cts +47 -0
  707. package/dist/shared/stack.BYMentwB.d.mts +47 -0
  708. package/dist/shared/stack.BYMentwB.d.ts +47 -0
  709. package/dist/shared/stack.Bt8hfw9o.d.ts +707 -0
  710. package/dist/shared/{stack.D7bewlgt.d.mts → stack.Bu2IPOLi.d.cts} +1 -0
  711. package/dist/shared/{stack.D7bewlgt.d.ts → stack.Bu2IPOLi.d.mts} +1 -0
  712. package/dist/shared/{stack.D7bewlgt.d.cts → stack.Bu2IPOLi.d.ts} +1 -0
  713. package/dist/shared/stack.BuxUQqL8.d.ts +408 -0
  714. package/dist/shared/stack.BzWGB5MG.d.cts +436 -0
  715. package/dist/shared/stack.C3bU9w6L.d.ts +351 -0
  716. package/dist/shared/stack.C4oVW2qK.d.cts +507 -0
  717. package/dist/shared/stack.CKXzdGiJ.d.cts +3 -0
  718. package/dist/shared/stack.CKXzdGiJ.d.mts +3 -0
  719. package/dist/shared/stack.CKXzdGiJ.d.ts +3 -0
  720. package/dist/shared/{stack.C3GBG8in.d.ts → stack.COrJrztD.d.cts} +1 -1
  721. package/dist/shared/{stack.C3GBG8in.d.cts → stack.COrJrztD.d.mts} +1 -1
  722. package/dist/shared/{stack.C3GBG8in.d.mts → stack.COrJrztD.d.ts} +1 -1
  723. package/dist/shared/stack.CX83YNuS.d.cts +408 -0
  724. package/dist/shared/stack.Cbd7sD5M.d.mts +118 -0
  725. package/dist/shared/{stack.B9NtGpAR.d.ts → stack.CcjENrr4.d.cts} +1 -5
  726. package/dist/shared/stack.CfK5NKlK.d.mts +613 -0
  727. package/dist/shared/{stack.oVIdV7XS.d.mts → stack.CjCSDfWy.d.mts} +2 -2
  728. package/dist/shared/stack.Cmg7lzzy.d.cts +44 -0
  729. package/dist/shared/stack.Cmg7lzzy.d.mts +44 -0
  730. package/dist/shared/stack.Cmg7lzzy.d.ts +44 -0
  731. package/dist/shared/stack.CpE1mS3p.d.ts +331 -0
  732. package/dist/shared/stack.CskhFw3z.d.mts +23 -0
  733. package/dist/shared/stack.CvlC5kqe.d.cts +331 -0
  734. package/dist/shared/stack.CxKc9evq.d.ts +23 -0
  735. package/dist/shared/stack.CyalJ0j6.d.ts +764 -0
  736. package/dist/shared/stack.D6Pg-ufX.d.cts +764 -0
  737. package/dist/shared/{stack.lkebw2nj.d.mts → stack.DVEjWKCT.d.cts} +19 -5
  738. package/dist/shared/{stack.lkebw2nj.d.ts → stack.DVEjWKCT.d.mts} +19 -5
  739. package/dist/shared/{stack.lkebw2nj.d.cts → stack.DVEjWKCT.d.ts} +19 -5
  740. package/dist/shared/{stack.Cp_6mO5s.d.mts → stack.DbbvHbhn.d.mts} +1 -5
  741. package/dist/shared/stack.DiuRuzIs.d.cts +613 -0
  742. package/dist/shared/{stack.BMlLOMED.d.cts → stack.DjGixVx3.d.cts} +6 -2
  743. package/dist/shared/{stack.BMlLOMED.d.mts → stack.DjGixVx3.d.mts} +6 -2
  744. package/dist/shared/{stack.BMlLOMED.d.ts → stack.DjGixVx3.d.ts} +6 -2
  745. package/dist/shared/stack.DlBoNqYu.d.ts +1184 -0
  746. package/dist/shared/stack.DlCycSM-.d.mts +331 -0
  747. package/dist/shared/{stack.DycBcTeg.d.mts → stack.DmpPDPxA.d.cts} +2 -2
  748. package/dist/shared/{stack.DseBJmGF.d.ts → stack.Dpg_JjIo.d.ts} +2 -2
  749. package/dist/shared/stack.Dvy7FmaA.d.mts +1184 -0
  750. package/dist/shared/stack.DxHPKr2R.d.mts +436 -0
  751. package/dist/shared/stack.Egr3RWhA.d.mts +408 -0
  752. package/dist/shared/stack.Mak7pzIV.d.cts +533 -0
  753. package/dist/shared/stack.OYT8WU4n.d.mts +351 -0
  754. package/dist/shared/{stack.CPsYC2-Z.d.cts → stack.fdi94T4S.d.cts} +7 -7
  755. package/dist/shared/{stack.CPsYC2-Z.d.mts → stack.fdi94T4S.d.mts} +7 -7
  756. package/dist/shared/{stack.CPsYC2-Z.d.ts → stack.fdi94T4S.d.ts} +7 -7
  757. package/dist/shared/{stack.Dlgtumru.d.cts → stack.kaCV7vEL.d.ts} +1 -5
  758. package/dist/shared/stack.v2O65JqF.d.cts +351 -0
  759. package/dist/tanstack/index.cjs +2 -0
  760. package/dist/tanstack/index.d.cts +27 -5
  761. package/dist/tanstack/index.d.mts +27 -5
  762. package/dist/tanstack/index.d.ts +27 -5
  763. package/dist/tanstack/index.mjs +1 -0
  764. package/dist/tanstack/server.cjs +9 -0
  765. package/dist/tanstack/server.d.cts +15 -0
  766. package/dist/tanstack/server.d.mts +15 -0
  767. package/dist/tanstack/server.d.ts +15 -0
  768. package/dist/tanstack/server.mjs +7 -0
  769. package/package.json +198 -3
  770. package/src/__tests__/ai-chat-client-runtime.test.ts +481 -0
  771. package/src/__tests__/ai-chat-client-runtime.typecheck.tsx +130 -0
  772. package/src/__tests__/ai-chat-lifecycle-migrations.typecheck.ts +61 -0
  773. package/src/__tests__/ai-chat-query-keys.test.ts +125 -22
  774. package/src/__tests__/auth-provider.test.tsx +41 -314
  775. package/src/__tests__/auth-test-utils.ts +24 -0
  776. package/src/__tests__/authorization-client.test.tsx +767 -0
  777. package/src/__tests__/authorization-contraction.test.ts +182 -0
  778. package/src/__tests__/authorization-remote.test.ts +222 -0
  779. package/src/__tests__/authorization-server.test.ts +90 -0
  780. package/src/__tests__/authorization.test.ts +652 -0
  781. package/src/__tests__/authorization.typecheck.ts +671 -0
  782. package/src/__tests__/backend-plugin-factories.test.ts +54 -0
  783. package/src/__tests__/backend-plugin-factories.typecheck.ts +133 -0
  784. package/src/__tests__/client-plugin-ssr-loaders.test.ts +304 -138
  785. package/src/__tests__/client-runtime.test.ts +1021 -0
  786. package/src/__tests__/client-runtime.typecheck.ts +107 -0
  787. package/src/__tests__/client-stack-test-utils.ts +36 -0
  788. package/src/__tests__/content-lifecycle-migrations.typecheck.ts +122 -0
  789. package/src/__tests__/endpoint-inventory.test.ts +768 -0
  790. package/src/__tests__/form-builder-query-keys.test.ts +32 -0
  791. package/src/__tests__/i18n-provider.test.tsx +4 -3
  792. package/src/__tests__/initial-identity-hydration.test.tsx +156 -0
  793. package/src/__tests__/initial-identity-layouts.test.tsx +204 -0
  794. package/src/__tests__/kanban-query-keys.test.ts +189 -2
  795. package/src/__tests__/managed-origin-hydration.browser.test.tsx +163 -0
  796. package/src/__tests__/media-query-keys.test.ts +91 -17
  797. package/src/__tests__/notify-provider.test.tsx +3 -2
  798. package/src/__tests__/package-metadata.test.ts +294 -0
  799. package/src/__tests__/page-component-overrides.test.tsx +3 -4
  800. package/src/__tests__/plugin-registration.test.tsx +183 -0
  801. package/src/__tests__/plugin-registration.typecheck.tsx +139 -0
  802. package/src/__tests__/plugins.test.tsx +72 -42
  803. package/src/__tests__/resource-factory.test.tsx +79 -2
  804. package/src/__tests__/resource-use-form.test.tsx +2 -2
  805. package/src/__tests__/resource-use-select.test.tsx +2 -4
  806. package/src/__tests__/router-overrides.test.tsx +20 -8
  807. package/src/__tests__/sitemap.test.ts +38 -22
  808. package/src/__tests__/stack-api.test.ts +39 -34
  809. package/src/__tests__/stack-auth.test.ts +44 -140
  810. package/src/__tests__/stack-constructors.test.ts +96 -0
  811. package/src/__tests__/stack-constructors.typecheck.ts +115 -0
  812. package/src/__tests__/use-list-state.test.tsx +7 -6
  813. package/src/__tests__/workflow-lifecycle-migrations.typecheck.ts +150 -0
  814. package/src/api/index.ts +204 -99
  815. package/src/authorization/client.tsx +310 -0
  816. package/src/authorization/index.ts +873 -0
  817. package/src/authorization/json.ts +70 -0
  818. package/src/authorization/remote.ts +234 -0
  819. package/src/authorization/server.ts +171 -0
  820. package/src/client/__tests__/server-origin.test.ts +119 -0
  821. package/src/client/components/compose.tsx +126 -18
  822. package/src/client/hooks/index.ts +12 -0
  823. package/src/client/hooks/use-list-state.ts +7 -13
  824. package/src/client/index.ts +105 -50
  825. package/src/client/runtime.ts +414 -0
  826. package/src/client/server.ts +174 -0
  827. package/src/context/auth.tsx +205 -154
  828. package/src/context/index.ts +10 -4
  829. package/src/context/provider.tsx +96 -57
  830. package/src/context/router.tsx +7 -0
  831. package/src/context/site-navigation.ts +52 -0
  832. package/src/next/layout.tsx +81 -0
  833. package/src/next/page.tsx +16 -3
  834. package/src/next/router.tsx +1 -1
  835. package/src/next/server.ts +5 -0
  836. package/src/plugin-registration.ts +70 -0
  837. package/src/plugins/ai-chat/__tests__/authorization.test.ts +2051 -0
  838. package/src/plugins/ai-chat/__tests__/chat-hooks.test.tsx +147 -0
  839. package/src/plugins/ai-chat/__tests__/chat-input-authorization.test.tsx +188 -0
  840. package/src/plugins/ai-chat/__tests__/client-sweep.test.tsx +1506 -34
  841. package/src/plugins/ai-chat/__tests__/hooks.test.tsx +131 -23
  842. package/src/plugins/ai-chat/api/getters.ts +2 -2
  843. package/src/plugins/ai-chat/api/index.ts +6 -1
  844. package/src/plugins/ai-chat/api/lifecycle-migrations.ts +20 -0
  845. package/src/plugins/ai-chat/api/operations.ts +1865 -0
  846. package/src/plugins/ai-chat/api/plugin.ts +78 -1168
  847. package/src/plugins/ai-chat/api/serializers.ts +30 -0
  848. package/src/plugins/ai-chat/client/components/chat-input.tsx +228 -129
  849. package/src/plugins/ai-chat/client/components/chat-interface.tsx +776 -183
  850. package/src/plugins/ai-chat/client/components/chat-layout.tsx +6 -7
  851. package/src/plugins/ai-chat/client/components/chat-message.tsx +1 -1
  852. package/src/plugins/ai-chat/client/components/chat-sidebar.tsx +57 -37
  853. package/src/plugins/ai-chat/client/components/pages/404-page.tsx +1 -1
  854. package/src/plugins/ai-chat/client/components/pages/chat-page.internal.tsx +5 -3
  855. package/src/plugins/ai-chat/client/components/pages/chat-page.tsx +56 -15
  856. package/src/plugins/ai-chat/client/components/shared/default-error.tsx +1 -1
  857. package/src/plugins/ai-chat/client/components/tool-call-display.tsx +1 -1
  858. package/src/plugins/ai-chat/client/hooks/ai-chat-resource.ts +1 -1
  859. package/src/plugins/ai-chat/client/hooks/chat-hooks.tsx +253 -20
  860. package/src/plugins/ai-chat/client/index.ts +1 -0
  861. package/src/plugins/ai-chat/client/navigation.ts +11 -0
  862. package/src/plugins/ai-chat/client/overrides.ts +47 -11
  863. package/src/plugins/ai-chat/client/plugin.tsx +208 -111
  864. package/src/plugins/ai-chat/permissions.ts +89 -0
  865. package/src/plugins/ai-chat/query-keys.ts +183 -25
  866. package/src/plugins/ai-chat/types.ts +7 -5
  867. package/src/plugins/api/create-endpoint.ts +40 -22
  868. package/src/plugins/api/endpoint-inventory.ts +206 -0
  869. package/src/plugins/api/index.ts +38 -4
  870. package/src/plugins/api/operation.ts +600 -0
  871. package/src/plugins/blog/__tests__/authorization.test.ts +1366 -0
  872. package/src/plugins/blog/__tests__/client-runtime.browser.test.tsx +257 -0
  873. package/src/plugins/blog/__tests__/client-runtime.test.ts +283 -0
  874. package/src/plugins/blog/__tests__/client-runtime.typecheck.tsx +98 -0
  875. package/src/plugins/blog/__tests__/client-sweep.test.tsx +212 -37
  876. package/src/plugins/blog/api/getters.ts +3 -3
  877. package/src/plugins/blog/api/index.ts +2 -0
  878. package/src/plugins/blog/api/lifecycle-migrations.ts +19 -0
  879. package/src/plugins/blog/api/mutations.ts +26 -5
  880. package/src/plugins/blog/api/operations.ts +727 -0
  881. package/src/plugins/blog/api/plugin.ts +99 -504
  882. package/src/plugins/blog/client/components/forms/image-field.tsx +2 -1
  883. package/src/plugins/blog/client/components/forms/markdown-editor-with-overrides.tsx +2 -1
  884. package/src/plugins/blog/client/components/forms/post-forms.tsx +61 -33
  885. package/src/plugins/blog/client/components/pages/404-page.tsx +3 -1
  886. package/src/plugins/blog/client/components/pages/edit-post-page.internal.tsx +2 -1
  887. package/src/plugins/blog/client/components/pages/edit-post-page.tsx +28 -5
  888. package/src/plugins/blog/client/components/pages/home-page.internal.tsx +2 -1
  889. package/src/plugins/blog/client/components/pages/home-page.tsx +7 -4
  890. package/src/plugins/blog/client/components/pages/new-post-page.internal.tsx +2 -1
  891. package/src/plugins/blog/client/components/pages/new-post-page.tsx +5 -2
  892. package/src/plugins/blog/client/components/pages/post-page.internal.tsx +2 -1
  893. package/src/plugins/blog/client/components/pages/post-page.tsx +38 -4
  894. package/src/plugins/blog/client/components/pages/tag-page.internal.tsx +2 -1
  895. package/src/plugins/blog/client/components/pages/tag-page.tsx +5 -1
  896. package/src/plugins/blog/client/components/shared/collapsible-tag-list.tsx +2 -1
  897. package/src/plugins/blog/client/components/shared/default-error.tsx +3 -1
  898. package/src/plugins/blog/client/components/shared/on-this-page.tsx +5 -2
  899. package/src/plugins/blog/client/components/shared/page-wrapper.tsx +2 -1
  900. package/src/plugins/blog/client/components/shared/post-card.tsx +2 -1
  901. package/src/plugins/blog/client/components/shared/posts-list.tsx +2 -1
  902. package/src/plugins/blog/client/components/shared/recent-posts-carousel.tsx +2 -1
  903. package/src/plugins/blog/client/components/shared/search-input.tsx +1 -1
  904. package/src/plugins/blog/client/constants.ts +2 -0
  905. package/src/plugins/blog/client/hooks/blog-resource.ts +2 -1
  906. package/src/plugins/blog/client/overrides.ts +1 -6
  907. package/src/plugins/blog/client/plugin.tsx +145 -129
  908. package/src/plugins/blog/permissions.ts +44 -0
  909. package/src/plugins/client/index.ts +108 -7
  910. package/src/plugins/client/resource/hooks.tsx +41 -18
  911. package/src/plugins/client/resource/internal.ts +77 -61
  912. package/src/plugins/client/resource/queries.ts +3 -4
  913. package/src/plugins/client/resource/use-form.ts +23 -20
  914. package/src/plugins/client/resource/use-select.ts +40 -34
  915. package/src/plugins/cms/__tests__/authorization.test.ts +2188 -0
  916. package/src/plugins/cms/__tests__/client-runtime.browser.test.tsx +245 -0
  917. package/src/plugins/cms/__tests__/client-runtime.test.ts +320 -0
  918. package/src/plugins/cms/__tests__/client-runtime.typecheck.tsx +208 -0
  919. package/src/plugins/cms/__tests__/client-sweep.test.tsx +202 -50
  920. package/src/plugins/cms/api/getters.ts +4 -4
  921. package/src/plugins/cms/api/index.ts +20 -0
  922. package/src/plugins/cms/api/lifecycle-migrations.ts +15 -0
  923. package/src/plugins/cms/api/mutations.ts +2 -2
  924. package/src/plugins/cms/api/operations.ts +2218 -0
  925. package/src/plugins/cms/api/plugin.ts +169 -1047
  926. package/src/plugins/cms/api/relations.ts +3 -1
  927. package/src/plugins/cms/client/components/forms/content-form.tsx +2 -1
  928. package/src/plugins/cms/client/components/forms/file-upload.tsx +3 -1
  929. package/src/plugins/cms/client/components/forms/relation-field.tsx +3 -1
  930. package/src/plugins/cms/client/components/inverse-relations-panel.tsx +29 -17
  931. package/src/plugins/cms/client/components/pages/404-page.tsx +7 -5
  932. package/src/plugins/cms/client/components/pages/content-editor-page.internal.tsx +19 -10
  933. package/src/plugins/cms/client/components/pages/content-editor-page.tsx +50 -12
  934. package/src/plugins/cms/client/components/pages/content-list-page.internal.tsx +48 -34
  935. package/src/plugins/cms/client/components/pages/content-list-page.tsx +8 -1
  936. package/src/plugins/cms/client/components/pages/dashboard-page.internal.tsx +15 -8
  937. package/src/plugins/cms/client/components/pages/dashboard-page.tsx +5 -1
  938. package/src/plugins/cms/client/components/shared/page-wrapper.tsx +2 -1
  939. package/src/plugins/cms/client/constants.ts +2 -0
  940. package/src/plugins/cms/client/hooks/cms-resource.ts +2 -1
  941. package/src/plugins/cms/client/index.ts +6 -1
  942. package/src/plugins/cms/client/overrides.ts +46 -6
  943. package/src/plugins/cms/client/plugin.tsx +135 -80
  944. package/src/plugins/cms/permissions.ts +43 -0
  945. package/src/plugins/cms/types.ts +174 -46
  946. package/src/plugins/comments/__tests__/authorization.test.ts +1570 -0
  947. package/src/plugins/comments/__tests__/client-runtime.browser.test.tsx +207 -0
  948. package/src/plugins/comments/__tests__/client-runtime.test.ts +224 -0
  949. package/src/plugins/comments/__tests__/client-runtime.typecheck.tsx +85 -0
  950. package/src/plugins/comments/__tests__/client-sweep.test.tsx +445 -82
  951. package/src/plugins/comments/api/getters.ts +19 -3
  952. package/src/plugins/comments/api/index.ts +2 -6
  953. package/src/plugins/comments/api/lifecycle-migrations.ts +20 -0
  954. package/src/plugins/comments/api/mutations.ts +261 -88
  955. package/src/plugins/comments/api/operations.ts +742 -0
  956. package/src/plugins/comments/api/plugin.ts +76 -548
  957. package/src/plugins/comments/client/components/comment-count.tsx +38 -5
  958. package/src/plugins/comments/client/components/comment-thread.tsx +148 -110
  959. package/src/plugins/comments/client/components/pages/moderation-page.internal.tsx +144 -78
  960. package/src/plugins/comments/client/components/pages/moderation-page.tsx +18 -2
  961. package/src/plugins/comments/client/components/pages/moderation-state.ts +13 -0
  962. package/src/plugins/comments/client/components/pages/my-comments-page.internal.tsx +38 -30
  963. package/src/plugins/comments/client/components/pages/my-comments-page.tsx +3 -1
  964. package/src/plugins/comments/client/components/pages/resource-comments-page.internal.tsx +29 -30
  965. package/src/plugins/comments/client/components/pages/resource-comments-page.tsx +10 -1
  966. package/src/plugins/comments/client/components/shared/page-wrapper.tsx +2 -1
  967. package/src/plugins/comments/client/components/shared/pagination.tsx +2 -1
  968. package/src/plugins/comments/client/constants.ts +2 -0
  969. package/src/plugins/comments/client/hooks/use-comments.tsx +430 -421
  970. package/src/plugins/comments/client/localization/comments-thread.ts +1 -0
  971. package/src/plugins/comments/client/plugin.tsx +113 -72
  972. package/src/plugins/comments/permissions.ts +68 -0
  973. package/src/plugins/comments/query-keys.ts +9 -10
  974. package/src/plugins/comments/schemas.ts +7 -8
  975. package/src/plugins/form-builder/__tests__/authorization.test.ts +1600 -0
  976. package/src/plugins/form-builder/__tests__/client-runtime.browser.test.tsx +255 -0
  977. package/src/plugins/form-builder/__tests__/client-runtime.test.ts +132 -0
  978. package/src/plugins/form-builder/__tests__/client-runtime.typecheck.tsx +77 -0
  979. package/src/plugins/form-builder/__tests__/client-sweep.test.tsx +350 -54
  980. package/src/plugins/form-builder/__tests__/form-renderer-authorization.test.tsx +162 -0
  981. package/src/plugins/form-builder/api/getters.ts +21 -5
  982. package/src/plugins/form-builder/api/index.ts +31 -0
  983. package/src/plugins/form-builder/api/lifecycle-migrations.ts +17 -0
  984. package/src/plugins/form-builder/api/operations.ts +1493 -0
  985. package/src/plugins/form-builder/api/plugin.ts +125 -632
  986. package/src/plugins/form-builder/api/query-key-defs.ts +7 -0
  987. package/src/plugins/form-builder/api/serializers.ts +1 -0
  988. package/src/plugins/form-builder/client/components/forms/form-renderer.tsx +49 -19
  989. package/src/plugins/form-builder/client/components/pages/404-page.tsx +9 -9
  990. package/src/plugins/form-builder/client/components/pages/form-builder-page.internal.tsx +54 -30
  991. package/src/plugins/form-builder/client/components/pages/form-builder-page.tsx +42 -9
  992. package/src/plugins/form-builder/client/components/pages/form-list-page.internal.tsx +46 -34
  993. package/src/plugins/form-builder/client/components/pages/form-list-page.tsx +6 -2
  994. package/src/plugins/form-builder/client/components/pages/submissions-page.internal.tsx +98 -64
  995. package/src/plugins/form-builder/client/components/pages/submissions-page.tsx +29 -9
  996. package/src/plugins/form-builder/client/components/shared/page-wrapper.tsx +2 -1
  997. package/src/plugins/form-builder/client/constants.ts +2 -0
  998. package/src/plugins/form-builder/client/hooks/form-builder-hooks.tsx +68 -4
  999. package/src/plugins/form-builder/client/hooks/form-builder-resource.ts +2 -1
  1000. package/src/plugins/form-builder/client/hooks/index.tsx +1 -0
  1001. package/src/plugins/form-builder/client/overrides.ts +1 -6
  1002. package/src/plugins/form-builder/client/plugin.tsx +128 -96
  1003. package/src/plugins/form-builder/permissions.ts +94 -0
  1004. package/src/plugins/form-builder/query-keys.ts +28 -3
  1005. package/src/plugins/form-builder/schemas.ts +9 -1
  1006. package/src/plugins/form-builder/types.ts +173 -41
  1007. package/src/plugins/kanban/__tests__/authorization.test.ts +1382 -0
  1008. package/src/plugins/kanban/__tests__/client-runtime.browser.test.tsx +302 -0
  1009. package/src/plugins/kanban/__tests__/client-runtime.test.ts +130 -0
  1010. package/src/plugins/kanban/__tests__/client-runtime.typecheck.tsx +81 -0
  1011. package/src/plugins/kanban/__tests__/client-sweep.test.tsx +418 -33
  1012. package/src/plugins/kanban/__tests__/identity-partition.test.tsx +306 -0
  1013. package/src/plugins/kanban/api/getters.ts +65 -50
  1014. package/src/plugins/kanban/api/index.ts +55 -4
  1015. package/src/plugins/kanban/api/lifecycle-migrations.ts +25 -0
  1016. package/src/plugins/kanban/api/mutations.ts +3 -3
  1017. package/src/plugins/kanban/api/operations.ts +2065 -0
  1018. package/src/plugins/kanban/api/plugin.ts +83 -1013
  1019. package/src/plugins/kanban/api/serializers.ts +26 -0
  1020. package/src/plugins/kanban/client/components/forms/board-form.tsx +3 -1
  1021. package/src/plugins/kanban/client/components/forms/column-form.tsx +3 -1
  1022. package/src/plugins/kanban/client/components/forms/task-form.tsx +92 -74
  1023. package/src/plugins/kanban/client/components/pages/404-page.tsx +6 -9
  1024. package/src/plugins/kanban/client/components/pages/board-page.internal.tsx +57 -74
  1025. package/src/plugins/kanban/client/components/pages/board-page.tsx +31 -7
  1026. package/src/plugins/kanban/client/components/pages/boards-list-page.internal.tsx +54 -45
  1027. package/src/plugins/kanban/client/components/pages/boards-list-page.tsx +2 -1
  1028. package/src/plugins/kanban/client/components/pages/new-board-page.internal.tsx +8 -12
  1029. package/src/plugins/kanban/client/components/pages/new-board-page.tsx +2 -1
  1030. package/src/plugins/kanban/client/components/shared/column-content.tsx +61 -48
  1031. package/src/plugins/kanban/client/components/shared/default-error.tsx +3 -1
  1032. package/src/plugins/kanban/client/components/shared/kanban-board.tsx +6 -6
  1033. package/src/plugins/kanban/client/components/shared/permission-access-any.tsx +32 -0
  1034. package/src/plugins/kanban/client/components/shared/task-card.tsx +64 -20
  1035. package/src/plugins/kanban/client/components/shared/user-avatar.tsx +3 -1
  1036. package/src/plugins/kanban/client/constants.ts +2 -0
  1037. package/src/plugins/kanban/client/hooks/kanban-hooks.tsx +55 -10
  1038. package/src/plugins/kanban/client/hooks/kanban-resource.ts +2 -1
  1039. package/src/plugins/kanban/client/overrides.ts +0 -5
  1040. package/src/plugins/kanban/client/plugin.tsx +201 -113
  1041. package/src/plugins/kanban/permissions.ts +100 -0
  1042. package/src/plugins/kanban/query-keys.ts +61 -21
  1043. package/src/plugins/kanban/schemas.ts +44 -18
  1044. package/src/plugins/kanban/types.ts +381 -1
  1045. package/src/plugins/media/__tests__/authorization.test.ts +1769 -0
  1046. package/src/plugins/media/__tests__/client-runtime.browser.test.tsx +975 -0
  1047. package/src/plugins/media/__tests__/client-runtime.test.ts +539 -0
  1048. package/src/plugins/media/__tests__/client-runtime.typecheck.tsx +135 -0
  1049. package/src/plugins/media/__tests__/client-sweep.test.tsx +292 -24
  1050. package/src/plugins/media/__tests__/identity-partition.test.tsx +741 -0
  1051. package/src/plugins/media/__tests__/plugin.test.ts +68 -28
  1052. package/src/plugins/media/__tests__/query-key-defs.test.ts +32 -2
  1053. package/src/plugins/media/api/adapters/vercel-blob.ts +84 -8
  1054. package/src/plugins/media/api/getters.ts +6 -6
  1055. package/src/plugins/media/api/index.ts +3 -0
  1056. package/src/plugins/media/api/lifecycle-migrations.ts +11 -0
  1057. package/src/plugins/media/api/mutations.ts +19 -13
  1058. package/src/plugins/media/api/operations.ts +1873 -0
  1059. package/src/plugins/media/api/plugin.ts +211 -899
  1060. package/src/plugins/media/api/query-key-defs.ts +66 -4
  1061. package/src/plugins/media/api/serializers.ts +4 -2
  1062. package/src/plugins/media/api/storage-adapter.ts +22 -4
  1063. package/src/plugins/media/asset-url.ts +14 -0
  1064. package/src/plugins/media/client/components/media-picker/asset-card.tsx +105 -98
  1065. package/src/plugins/media/client/components/media-picker/folder-tree.tsx +82 -60
  1066. package/src/plugins/media/client/components/media-picker/index.tsx +235 -171
  1067. package/src/plugins/media/client/components/media-picker/upload-tab.tsx +2 -10
  1068. package/src/plugins/media/client/components/media-picker/url-tab.tsx +1 -8
  1069. package/src/plugins/media/client/components/pages/library-page.internal.tsx +103 -82
  1070. package/src/plugins/media/client/components/pages/library-page.tsx +4 -2
  1071. package/src/plugins/media/client/components/upload-permission-check.tsx +75 -0
  1072. package/src/plugins/media/client/constants.ts +2 -0
  1073. package/src/plugins/media/client/hooks/media-resource.ts +2 -1
  1074. package/src/plugins/media/client/hooks/use-media.tsx +292 -49
  1075. package/src/plugins/media/client/index.ts +16 -3
  1076. package/src/plugins/media/client/overrides.ts +6 -17
  1077. package/src/plugins/media/client/plugin.tsx +188 -123
  1078. package/src/plugins/media/client/upload.ts +170 -53
  1079. package/src/plugins/media/db.ts +8 -0
  1080. package/src/plugins/media/permissions.ts +61 -0
  1081. package/src/plugins/media/query-keys.ts +63 -19
  1082. package/src/plugins/media/types.ts +8 -2
  1083. package/src/plugins/open-api/__tests__/route-introspection.test.ts +277 -0
  1084. package/src/plugins/open-api/api/generator.ts +49 -8
  1085. package/src/plugins/open-api/api/plugin.ts +36 -14
  1086. package/src/plugins/route-docs/client/components/pages/docs-page.tsx +63 -23
  1087. package/src/plugins/route-docs/client/constants.ts +2 -0
  1088. package/src/plugins/route-docs/client/hooks.ts +23 -13
  1089. package/src/plugins/route-docs/client/index.ts +7 -1
  1090. package/src/plugins/route-docs/client/plugin.tsx +222 -145
  1091. package/src/plugins/route-docs/client/schema.ts +31 -0
  1092. package/src/plugins/route-docs/generator.ts +9 -5
  1093. package/src/plugins/ui-builder/__tests__/client-sweep.test.tsx +427 -48
  1094. package/src/plugins/ui-builder/client/components/page-renderer.tsx +58 -16
  1095. package/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.tsx +47 -26
  1096. package/src/plugins/ui-builder/client/components/pages/page-builder-page.tsx +43 -8
  1097. package/src/plugins/ui-builder/client/components/pages/page-list-page.internal.tsx +38 -19
  1098. package/src/plugins/ui-builder/client/components/pages/page-list-page.tsx +8 -2
  1099. package/src/plugins/ui-builder/client/components/shared/default-error.tsx +2 -1
  1100. package/src/plugins/ui-builder/client/components/shared/page-wrapper.tsx +2 -1
  1101. package/src/plugins/ui-builder/client/constants.ts +2 -0
  1102. package/src/plugins/ui-builder/client/hooks/ui-builder-resource.ts +2 -1
  1103. package/src/plugins/ui-builder/client/index.ts +4 -1
  1104. package/src/plugins/ui-builder/client/overrides.ts +16 -21
  1105. package/src/plugins/ui-builder/client/plugin.tsx +119 -66
  1106. package/src/plugins/ui-builder/client/registry.ts +3 -5
  1107. package/src/plugins/ui-builder/types.ts +7 -4
  1108. package/src/plugins/utils.ts +5 -1
  1109. package/src/react-router/index.tsx +5 -0
  1110. package/src/react-router/layout.ts +43 -0
  1111. package/src/react-router/page.tsx +12 -5
  1112. package/src/react-router/router.tsx +1 -1
  1113. package/src/shared/auth-types.ts +19 -70
  1114. package/src/shared/entry-factories.ts +3 -3
  1115. package/src/shared/initial-identity.ts +73 -0
  1116. package/src/shared/list-state.ts +12 -0
  1117. package/src/shared/types.ts +1 -0
  1118. package/src/tanstack/index.tsx +5 -0
  1119. package/src/tanstack/layout.ts +36 -0
  1120. package/src/tanstack/page.tsx +7 -2
  1121. package/src/tanstack/router.tsx +1 -1
  1122. package/src/tanstack/server.ts +18 -0
  1123. package/src/types.ts +557 -65
  1124. package/dist/shared/stack.B8vdOMnQ.d.cts +0 -329
  1125. package/dist/shared/stack.BISAZ5LX.d.mts +0 -492
  1126. package/dist/shared/stack.BL5PvShn.d.mts +0 -193
  1127. package/dist/shared/stack.Be1QIHEn.d.cts +0 -23
  1128. package/dist/shared/stack.Be1QIHEn.d.mts +0 -23
  1129. package/dist/shared/stack.Be1QIHEn.d.ts +0 -23
  1130. package/dist/shared/stack.BjvOk_Bs.d.cts +0 -492
  1131. package/dist/shared/stack.BozPgbrZ.d.cts +0 -201
  1132. package/dist/shared/stack.BozPgbrZ.d.mts +0 -201
  1133. package/dist/shared/stack.BozPgbrZ.d.ts +0 -201
  1134. package/dist/shared/stack.BqTR6qi2.d.ts +0 -193
  1135. package/dist/shared/stack.BsmDN8r9.d.cts +0 -406
  1136. package/dist/shared/stack.C1ATQ3pd.d.ts +0 -416
  1137. package/dist/shared/stack.C4_gEENS.d.cts +0 -97
  1138. package/dist/shared/stack.C4_gEENS.d.mts +0 -97
  1139. package/dist/shared/stack.C4_gEENS.d.ts +0 -97
  1140. package/dist/shared/stack.C5Y5lViI.d.cts +0 -461
  1141. package/dist/shared/stack.C8SwdUz8.d.ts +0 -461
  1142. package/dist/shared/stack.CBsp9rDM.d.cts +0 -193
  1143. package/dist/shared/stack.CKGjOI3Z.d.cts +0 -840
  1144. package/dist/shared/stack.Cf-DbL1A.d.ts +0 -329
  1145. package/dist/shared/stack.CuI_-z-_.d.cts +0 -560
  1146. package/dist/shared/stack.D2RVkQD8.d.mts +0 -560
  1147. package/dist/shared/stack.DHTvwoNG.d.mts +0 -329
  1148. package/dist/shared/stack.DJaKVY7v.d.cts +0 -76
  1149. package/dist/shared/stack.DJaKVY7v.d.mts +0 -76
  1150. package/dist/shared/stack.DJaKVY7v.d.ts +0 -76
  1151. package/dist/shared/stack.DKZMaVr6.d.cts +0 -416
  1152. package/dist/shared/stack.DOzsgzkY.d.ts +0 -406
  1153. package/dist/shared/stack.DQq8DEIv.d.mts +0 -461
  1154. package/dist/shared/stack.DXrOtuek.d.ts +0 -560
  1155. package/dist/shared/stack.DZHEHd-S.d.mts +0 -840
  1156. package/dist/shared/stack.Dd-8shBE.d.ts +0 -492
  1157. package/dist/shared/stack.EOPVnJrF.d.cts +0 -39
  1158. package/dist/shared/stack.EOPVnJrF.d.mts +0 -39
  1159. package/dist/shared/stack.EOPVnJrF.d.ts +0 -39
  1160. package/dist/shared/stack.NGKtwA6S.d.mts +0 -406
  1161. package/dist/shared/stack.WELCDuMs.d.ts +0 -840
  1162. package/dist/shared/stack.aXdBOJAR.d.cts +0 -173
  1163. package/dist/shared/stack.aXdBOJAR.d.mts +0 -173
  1164. package/dist/shared/stack.aXdBOJAR.d.ts +0 -173
  1165. package/dist/shared/stack.oBokjN_J.d.mts +0 -416
  1166. package/dist/shared/{stack.D18Dq3ve.d.mts → stack.Csi-4Mgz.d.cts} +1 -1
  1167. package/dist/shared/{stack.D18Dq3ve.d.ts → stack.Csi-4Mgz.d.mts} +1 -1
  1168. package/dist/shared/{stack.D18Dq3ve.d.cts → stack.Csi-4Mgz.d.ts} +1 -1
@@ -0,0 +1,1756 @@
1
+ import { defineOperation, OperationHttpError } from '@btst/stack/plugins/api';
2
+ import { z } from 'zod';
3
+ import { formSchemaToZod } from '../../../../../ui/src/lib/schema-converter.mjs';
4
+ import { cmsPermissions } from '../../../../../../plugins/cms/permissions.mjs';
5
+ import { createListContentQuerySchema, DEFAULT_MAX_PAGE_SIZE } from '../schemas.mjs';
6
+ import { slugify } from '../utils.mjs';
7
+ import { serializeContentType, getAllContentItems, getContentItemBySlug, serializeContentItemWithType } from './getters.mjs';
8
+ import { syncRelations, extractRelationFields, isNewRelationValue, isExistingRelationValue } from './relations.mjs';
9
+
10
+ function operationContentType(contentType) {
11
+ return { ...contentType };
12
+ }
13
+ function operationContentItem(item) {
14
+ const {
15
+ parsedData,
16
+ contentType,
17
+ _relations,
18
+ ...serializedItem
19
+ } = item;
20
+ return {
21
+ ...serializedItem,
22
+ parsedData,
23
+ ...contentType ? { contentType: operationContentType(contentType) } : {}
24
+ };
25
+ }
26
+ function operationContentList(result) {
27
+ return {
28
+ items: result.items.map(operationContentItem),
29
+ total: result.total,
30
+ ...result.limit !== void 0 ? { limit: result.limit } : {},
31
+ ...result.offset !== void 0 ? { offset: result.offset } : {}
32
+ };
33
+ }
34
+ const JSONValueSchema = z.lazy(
35
+ () => z.union([
36
+ z.string(),
37
+ z.number(),
38
+ z.boolean(),
39
+ z.null(),
40
+ z.array(JSONValueSchema),
41
+ z.record(z.string(), JSONValueSchema)
42
+ ])
43
+ );
44
+ const CMSDataSchema = z.record(
45
+ z.string(),
46
+ JSONValueSchema
47
+ );
48
+ const EmptyInputSchema = z.object({});
49
+ const CMSContentTypeParamsSchema = z.object({
50
+ slug: z.string().min(1)
51
+ });
52
+ const CMSContentItemParamsSchema = z.object({
53
+ typeSlug: z.string().min(1),
54
+ id: z.string().min(1)
55
+ });
56
+ const CMSCreateContentItemBodySchema = z.object({
57
+ slug: z.string().min(1),
58
+ data: CMSDataSchema
59
+ });
60
+ const CMSUpdateContentItemBodySchema = z.object({
61
+ slug: z.string().min(1).optional(),
62
+ data: CMSDataSchema.optional()
63
+ });
64
+ const ListContentTypesInputSchema = EmptyInputSchema;
65
+ const GetContentTypeInputSchema = CMSContentTypeParamsSchema;
66
+ const GetContentItemInputSchema = CMSContentItemParamsSchema;
67
+ const CreateContentItemInputSchema = z.object({
68
+ typeSlug: z.string().min(1),
69
+ body: CMSCreateContentItemBodySchema
70
+ });
71
+ const UpdateContentItemInputSchema = z.object({
72
+ typeSlug: z.string().min(1),
73
+ id: z.string().min(1),
74
+ body: CMSUpdateContentItemBodySchema
75
+ });
76
+ const DeleteContentItemInputSchema = CMSContentItemParamsSchema;
77
+ class CMSOperationError extends OperationHttpError {
78
+ constructor(statusCode, message, code = "CMS_OPERATION_ERROR", issues) {
79
+ super(statusCode, message, code, issues);
80
+ this.name = "CMSOperationError";
81
+ }
82
+ }
83
+ function normalizeOperationError(error, fallback) {
84
+ if (error instanceof Error) return error;
85
+ return new Error(typeof error === "string" ? error : fallback, {
86
+ cause: error
87
+ });
88
+ }
89
+ async function runBeforeHook(hook, defaultMessage) {
90
+ if (!hook) return;
91
+ try {
92
+ await hook();
93
+ } catch (error) {
94
+ throw new CMSOperationError(
95
+ 403,
96
+ error instanceof Error ? error.message : defaultMessage,
97
+ "HOOK_DENIED"
98
+ );
99
+ }
100
+ }
101
+ function requestFields(context) {
102
+ return {
103
+ ...context.request ? { request: context.request, headers: context.request.headers } : {},
104
+ ...context.identity ? { userId: context.identity.id } : {}
105
+ };
106
+ }
107
+ function createContext(context) {
108
+ return Object.freeze({
109
+ ...context,
110
+ typeSlug: context.facts.contentType,
111
+ body: context.input.body,
112
+ ...requestFields(context)
113
+ });
114
+ }
115
+ function updateContext(context) {
116
+ return Object.freeze({
117
+ ...context,
118
+ typeSlug: context.facts.contentType,
119
+ params: Object.freeze({
120
+ typeSlug: context.facts.contentType,
121
+ id: context.facts.recordId
122
+ }),
123
+ body: context.input.body,
124
+ ...requestFields(context)
125
+ });
126
+ }
127
+ function deleteContext(context) {
128
+ return Object.freeze({
129
+ ...context,
130
+ typeSlug: context.facts.contentType,
131
+ params: Object.freeze({
132
+ typeSlug: context.facts.contentType,
133
+ id: context.facts.recordId
134
+ }),
135
+ ...requestFields(context)
136
+ });
137
+ }
138
+ function genericContext(context, typeSlug) {
139
+ return Object.freeze({
140
+ ...context,
141
+ ...typeSlug ? { typeSlug } : {},
142
+ ...requestFields(context)
143
+ });
144
+ }
145
+ function operationErrorContext(context, error) {
146
+ return Object.freeze({ ...context, error });
147
+ }
148
+ function getContentTypeZodSchema(contentType) {
149
+ return formSchemaToZod(JSON.parse(contentType.jsonSchema));
150
+ }
151
+ async function getContentTypeOrThrow(adapter, ensureSynced, slug, message = "Content type not found") {
152
+ await ensureSynced();
153
+ const contentType = await adapter.findOne({
154
+ model: "contentType",
155
+ where: [{ field: "slug", value: slug, operator: "eq" }]
156
+ });
157
+ if (!contentType) {
158
+ throw new CMSOperationError(404, message, "CONTENT_TYPE_NOT_FOUND");
159
+ }
160
+ return contentType;
161
+ }
162
+ async function getRecordOrThrow(adapter, ensureSynced, typeSlug, id) {
163
+ await ensureSynced();
164
+ const item = await adapter.findOne({
165
+ model: "contentItem",
166
+ where: [{ field: "id", value: id, operator: "eq" }],
167
+ join: { contentType: true }
168
+ });
169
+ if (!item || item.contentType?.slug !== typeSlug) {
170
+ throw new CMSOperationError(
171
+ 404,
172
+ "Content item not found",
173
+ "RECORD_NOT_FOUND"
174
+ );
175
+ }
176
+ return item;
177
+ }
178
+ function recordFacts(item) {
179
+ if (!item.contentType) {
180
+ throw new CMSOperationError(
181
+ 500,
182
+ "Content item is missing its content type",
183
+ "CONTENT_TYPE_JOIN_MISSING"
184
+ );
185
+ }
186
+ return {
187
+ contentType: item.contentType.slug,
188
+ scope: "record",
189
+ recordId: item.id,
190
+ ...item.authorId ? { authorId: item.authorId } : {}
191
+ };
192
+ }
193
+ function collectionFacts(contentType) {
194
+ return { contentType, scope: "collection" };
195
+ }
196
+ function assertRecordFacts(item, facts) {
197
+ if (!facts.recordId || item.id !== facts.recordId || item.contentType?.slug !== facts.contentType || (item.authorId ?? void 0) !== facts.authorId) {
198
+ throw staleRecordError();
199
+ }
200
+ }
201
+ const AFFECTED_ROW_KEYS = [
202
+ "rowCount",
203
+ "affectedRows",
204
+ "rowsAffected",
205
+ "changes",
206
+ "numUpdatedRows"
207
+ ];
208
+ function hasPositiveCount(value) {
209
+ if (typeof value === "number") return Number.isFinite(value) && value > 0;
210
+ if (typeof value === "bigint") return value > 0n;
211
+ return false;
212
+ }
213
+ function didUpdateContentItem(result, expectedId) {
214
+ if (typeof result === "number" || typeof result === "bigint") {
215
+ return hasPositiveCount(result);
216
+ }
217
+ if (!result || typeof result !== "object") return false;
218
+ const record = result;
219
+ if ("count" in record) return hasPositiveCount(record.count);
220
+ if (Array.isArray(result)) {
221
+ return result.length > 0 && didUpdateContentItem(result[0], expectedId);
222
+ }
223
+ for (const key of AFFECTED_ROW_KEYS) {
224
+ if (key in record) return hasPositiveCount(record[key]);
225
+ }
226
+ if ("meta" in record) {
227
+ const meta = record.meta;
228
+ return Boolean(
229
+ meta && typeof meta === "object" && "changes" in meta && hasPositiveCount(meta.changes)
230
+ );
231
+ }
232
+ return record.id === expectedId;
233
+ }
234
+ function staleRecordError() {
235
+ return new CMSOperationError(
236
+ 409,
237
+ "Content item changed while authorization was being evaluated. Retry the operation.",
238
+ "RECORD_STATE_CHANGED"
239
+ );
240
+ }
241
+ function assertRecordSnapshot(current, expected) {
242
+ if (current.id !== expected.id || current.contentTypeId !== expected.contentTypeId || current.contentType?.slug !== expected.contentType?.slug || (current.authorId ?? void 0) !== (expected.authorId ?? void 0) || current.slug !== expected.slug || current.data !== expected.data || current.updatedAt.getTime() !== expected.updatedAt.getTime()) {
243
+ throw staleRecordError();
244
+ }
245
+ }
246
+ async function planRelatedItem(adapter, targetContentType, slug, data, authorId) {
247
+ const validation = getContentTypeZodSchema(targetContentType).safeParse(data);
248
+ if (!validation.success) {
249
+ throw new CMSOperationError(
250
+ 400,
251
+ `Validation failed for new ${targetContentType.slug}`,
252
+ "RELATED_RECORD_VALIDATION_FAILED",
253
+ validation.error.issues
254
+ );
255
+ }
256
+ const existing = await adapter.findOne({
257
+ model: "contentItem",
258
+ where: [
259
+ {
260
+ field: "contentTypeId",
261
+ value: targetContentType.id,
262
+ operator: "eq"
263
+ },
264
+ { field: "slug", value: slug, operator: "eq" }
265
+ ]
266
+ });
267
+ if (existing) {
268
+ throw relatedRecordSlugConflictError();
269
+ }
270
+ const now = /* @__PURE__ */ new Date();
271
+ return {
272
+ id: globalThis.crypto.randomUUID(),
273
+ contentTypeId: targetContentType.id,
274
+ slug,
275
+ data: JSON.stringify(validation.data),
276
+ ...authorId ? { authorId } : {},
277
+ createdAt: now,
278
+ updatedAt: now
279
+ };
280
+ }
281
+ function relatedRecordSlugConflictError() {
282
+ return new CMSOperationError(
283
+ 409,
284
+ "Inline related record could not be created because its slug is unavailable.",
285
+ "RELATED_RECORD_SLUG_CONFLICT"
286
+ );
287
+ }
288
+ async function planRelationsInData(adapter, contentType, data, ensureSynced, authorId) {
289
+ const relationFields = extractRelationFields(contentType);
290
+ const processedData = { ...data };
291
+ const relationIds = {};
292
+ const newItems = [];
293
+ const plannedSlugs = /* @__PURE__ */ new Set();
294
+ for (const [fieldName, relationConfig] of Object.entries(relationFields)) {
295
+ if (!(fieldName in data)) continue;
296
+ const fieldValue = data[fieldName];
297
+ if (!fieldValue) {
298
+ relationIds[fieldName] = [];
299
+ continue;
300
+ }
301
+ const targetContentType = await getContentTypeOrThrow(
302
+ adapter,
303
+ ensureSynced,
304
+ relationConfig.targetType,
305
+ `Target content type "${relationConfig.targetType}" not found for relation field "${fieldName}"`
306
+ );
307
+ const ids = [];
308
+ if (relationConfig.type === "belongsTo") {
309
+ const value = fieldValue;
310
+ if (isNewRelationValue(value)) {
311
+ const item = await resolvePlannedRelatedItem(
312
+ adapter,
313
+ targetContentType,
314
+ value.data,
315
+ authorId,
316
+ plannedSlugs,
317
+ newItems
318
+ );
319
+ ids.push(item.id);
320
+ processedData[fieldName] = { id: item.id };
321
+ } else if (isExistingRelationValue(value)) {
322
+ ids.push(value.id);
323
+ }
324
+ } else {
325
+ const values = Array.isArray(fieldValue) ? fieldValue : [];
326
+ const processedValues = [];
327
+ for (const value of values) {
328
+ if (isNewRelationValue(value)) {
329
+ const item = await resolvePlannedRelatedItem(
330
+ adapter,
331
+ targetContentType,
332
+ value.data,
333
+ authorId,
334
+ plannedSlugs,
335
+ newItems
336
+ );
337
+ ids.push(item.id);
338
+ processedValues.push({ id: item.id });
339
+ } else if (isExistingRelationValue(value)) {
340
+ ids.push(value.id);
341
+ processedValues.push({ id: value.id });
342
+ }
343
+ }
344
+ processedData[fieldName] = processedValues;
345
+ }
346
+ relationIds[fieldName] = ids;
347
+ }
348
+ return { processedData, relationIds, newItems };
349
+ }
350
+ async function resolvePlannedRelatedItem(adapter, targetContentType, data, authorId, plannedSlugs, newItems) {
351
+ const slug = slugify(
352
+ data.slug || data.name || data.title || `item-${Date.now()}`
353
+ );
354
+ const key = `${targetContentType.id}\0${slug}`;
355
+ if (plannedSlugs.has(key)) throw relatedRecordSlugConflictError();
356
+ const planned = await planRelatedItem(
357
+ adapter,
358
+ targetContentType,
359
+ slug,
360
+ data,
361
+ authorId
362
+ );
363
+ plannedSlugs.add(key);
364
+ newItems.push(planned);
365
+ return planned;
366
+ }
367
+ async function applyRelationWritePlan(adapter, plan) {
368
+ for (const item of plan.newItems) {
369
+ const existing = await adapter.findOne({
370
+ model: "contentItem",
371
+ where: [
372
+ {
373
+ field: "contentTypeId",
374
+ value: item.contentTypeId,
375
+ operator: "eq"
376
+ },
377
+ { field: "slug", value: item.slug, operator: "eq" }
378
+ ]
379
+ });
380
+ if (existing) throw staleRecordError();
381
+ await adapter.create({
382
+ model: "contentItem",
383
+ data: item
384
+ });
385
+ }
386
+ }
387
+ function relationFilterSnapshot(sourceContentType, fieldName, relation, targetContentType) {
388
+ return JSON.stringify([
389
+ sourceContentType.id,
390
+ sourceContentType.slug,
391
+ fieldName,
392
+ relation.type,
393
+ targetContentType.id,
394
+ targetContentType.slug
395
+ ]);
396
+ }
397
+ async function deriveRelationFilterAuthorization(adapter, ensureSynced, sourceContentType, fieldName, targetId) {
398
+ const relation = extractRelationFields(sourceContentType)[fieldName];
399
+ if (!relation) {
400
+ throw new CMSOperationError(
401
+ 404,
402
+ `Relation field "${fieldName}" was not found on content type "${sourceContentType.slug}".`,
403
+ "RELATION_FIELD_NOT_FOUND"
404
+ );
405
+ }
406
+ const targetContentType = await getContentTypeOrThrow(
407
+ adapter,
408
+ ensureSynced,
409
+ relation.targetType,
410
+ `Target content type "${relation.targetType}" not found for relation field "${fieldName}"`
411
+ );
412
+ const target = await getRecordOrThrow(
413
+ adapter,
414
+ ensureSynced,
415
+ targetContentType.slug,
416
+ targetId
417
+ );
418
+ const targetFacts = recordFacts(target);
419
+ return {
420
+ permission: cmsPermissions.record.read(targetFacts),
421
+ snapshot: relationFilterSnapshot(
422
+ sourceContentType,
423
+ fieldName,
424
+ relation,
425
+ targetContentType
426
+ ),
427
+ targetFacts
428
+ };
429
+ }
430
+ function relationTargetSnapshot(facts) {
431
+ return JSON.stringify([
432
+ facts.contentType,
433
+ facts.recordId,
434
+ facts.authorId ?? null
435
+ ]);
436
+ }
437
+ async function deriveRelationWriteAuthorization(adapter, contentType, data, ensureSynced, expectedSchemaSnapshot) {
438
+ const permissions = [];
439
+ const snapshot = [];
440
+ const targets = [];
441
+ const seenCreateTargetTypes = /* @__PURE__ */ new Set();
442
+ const seenReadTargets = /* @__PURE__ */ new Set();
443
+ const resolvedRelations = [];
444
+ for (const [fieldName, relationConfig] of Object.entries(
445
+ extractRelationFields(contentType)
446
+ )) {
447
+ if (!(fieldName in data)) continue;
448
+ const value = data[fieldName];
449
+ const values = relationConfig.type === "belongsTo" ? [value] : Array.isArray(value) ? value : [];
450
+ const targetContentType = await getContentTypeOrThrow(
451
+ adapter,
452
+ ensureSynced,
453
+ relationConfig.targetType,
454
+ `Target content type "${relationConfig.targetType}" not found for relation field "${fieldName}"`
455
+ );
456
+ snapshot.push(
457
+ JSON.stringify([
458
+ fieldName,
459
+ relationConfig.type,
460
+ targetContentType.id,
461
+ targetContentType.slug
462
+ ])
463
+ );
464
+ resolvedRelations.push({ values, targetContentType });
465
+ }
466
+ snapshot.sort();
467
+ if (expectedSchemaSnapshot) {
468
+ assertRelationSchemaSnapshot(expectedSchemaSnapshot, snapshot);
469
+ }
470
+ for (const { values, targetContentType } of resolvedRelations) {
471
+ if (values.some(isNewRelationValue) && !seenCreateTargetTypes.has(targetContentType.slug)) {
472
+ seenCreateTargetTypes.add(targetContentType.slug);
473
+ permissions.push(
474
+ cmsPermissions.record.create({ contentType: targetContentType.slug })
475
+ );
476
+ }
477
+ for (const reference of values) {
478
+ if (isNewRelationValue(reference) || !isExistingRelationValue(reference)) {
479
+ continue;
480
+ }
481
+ const target = await getRecordOrThrow(
482
+ adapter,
483
+ ensureSynced,
484
+ targetContentType.slug,
485
+ reference.id
486
+ );
487
+ const facts = recordFacts(target);
488
+ const targetKey = relationTargetSnapshot(facts);
489
+ if (seenReadTargets.has(targetKey)) continue;
490
+ seenReadTargets.add(targetKey);
491
+ targets.push(facts);
492
+ permissions.push(cmsPermissions.record.read(facts));
493
+ }
494
+ }
495
+ return {
496
+ permissions,
497
+ snapshot,
498
+ targets: targets.sort(
499
+ (left, right) => relationTargetSnapshot(left).localeCompare(relationTargetSnapshot(right))
500
+ )
501
+ };
502
+ }
503
+ function assertRelationSchemaSnapshot(authorized, current) {
504
+ if (JSON.stringify(authorized) !== JSON.stringify(current)) {
505
+ throw relationSchemaChangedError();
506
+ }
507
+ }
508
+ function assertRelationWriteAuthorization(authorized, current) {
509
+ assertRelationSchemaSnapshot(authorized.snapshot, current.snapshot);
510
+ if (JSON.stringify(authorized.targets.map(relationTargetSnapshot)) !== JSON.stringify(current.targets.map(relationTargetSnapshot))) {
511
+ throw staleRecordError();
512
+ }
513
+ }
514
+ function relationSchemaChangedError() {
515
+ return new CMSOperationError(
516
+ 409,
517
+ "Content type relations changed while authorization was being evaluated. Retry the operation.",
518
+ "RELATION_SCHEMA_CHANGED"
519
+ );
520
+ }
521
+ async function getPopulatedRelationSnapshot(adapter, sourceId) {
522
+ const relations = await adapter.findMany({
523
+ model: "contentRelation",
524
+ where: [{ field: "sourceId", value: sourceId, operator: "eq" }]
525
+ });
526
+ const targets = [];
527
+ const seenTargets = /* @__PURE__ */ new Set();
528
+ for (const relation of relations) {
529
+ if (seenTargets.has(relation.targetId)) continue;
530
+ const target = await adapter.findOne({
531
+ model: "contentItem",
532
+ where: [
533
+ { field: "id", value: relation.targetId, operator: "eq" }
534
+ ],
535
+ join: { contentType: true }
536
+ });
537
+ if (!target) continue;
538
+ seenTargets.add(target.id);
539
+ targets.push({
540
+ item: serializeContentItemWithType(target),
541
+ facts: recordFacts(target)
542
+ });
543
+ }
544
+ return {
545
+ relationKeys: relations.map((relation) => `${relation.fieldName}\0${relation.targetId}`).sort(),
546
+ targets: targets.sort(
547
+ (left, right) => (left.facts.recordId ?? "").localeCompare(right.facts.recordId ?? "")
548
+ )
549
+ };
550
+ }
551
+ function assertPopulatedRelationSnapshot(authorized, current) {
552
+ const factsKey = (facts) => JSON.stringify([facts.contentType, facts.recordId, facts.authorId ?? null]);
553
+ if (JSON.stringify(authorized.relationKeys) !== JSON.stringify(current.relationKeys) || JSON.stringify(authorized.targets.map(({ facts }) => factsKey(facts))) !== JSON.stringify(current.targets.map(({ facts }) => factsKey(facts)))) {
554
+ throw new CMSOperationError(
555
+ 409,
556
+ "Related content changed while authorization was being evaluated. Retry the operation.",
557
+ "RECORD_STATE_CHANGED"
558
+ );
559
+ }
560
+ }
561
+ function populatedRelationsFromSnapshot(snapshot) {
562
+ const targetsById = new Map(
563
+ snapshot.targets.map((target) => [target.facts.recordId, target.item])
564
+ );
565
+ const populated = {};
566
+ for (const relationKey of snapshot.relationKeys) {
567
+ const [fieldName, targetId] = relationKey.split("\0");
568
+ if (!fieldName || !targetId) continue;
569
+ const target = targetsById.get(targetId);
570
+ if (target) (populated[fieldName] ??= []).push(target);
571
+ }
572
+ return populated;
573
+ }
574
+ function inverseSourceKey(source) {
575
+ return JSON.stringify([
576
+ source.contentTypeId,
577
+ source.contentTypeSlug,
578
+ source.contentTypeName,
579
+ source.fieldName
580
+ ]);
581
+ }
582
+ async function deriveInverseSourceAuthorization(adapter, ensureSynced, targetType) {
583
+ await ensureSynced();
584
+ const permissions = [];
585
+ const sources = [];
586
+ const seenSourceTypes = /* @__PURE__ */ new Set();
587
+ for (const contentType of await adapter.findMany({
588
+ model: "contentType"
589
+ })) {
590
+ for (const [fieldName, relation] of Object.entries(
591
+ extractRelationFields(contentType)
592
+ )) {
593
+ if (relation.type !== "belongsTo" || relation.targetType !== targetType) {
594
+ continue;
595
+ }
596
+ sources.push({
597
+ contentTypeId: contentType.id,
598
+ contentTypeSlug: contentType.slug,
599
+ contentTypeName: contentType.name,
600
+ fieldName
601
+ });
602
+ if (seenSourceTypes.has(contentType.slug)) continue;
603
+ seenSourceTypes.add(contentType.slug);
604
+ permissions.push(
605
+ cmsPermissions.contentType.read({ contentType: contentType.slug })
606
+ );
607
+ }
608
+ }
609
+ sources.sort(
610
+ (left, right) => inverseSourceKey(left).localeCompare(inverseSourceKey(right))
611
+ );
612
+ return {
613
+ permissions,
614
+ snapshot: sources.map(inverseSourceKey),
615
+ sources
616
+ };
617
+ }
618
+ async function listRecordsForRelation(adapter, contentType, fieldName, targetId, limit, offset) {
619
+ const relations = await adapter.findMany({
620
+ model: "contentRelation",
621
+ where: [
622
+ { field: "targetId", value: targetId, operator: "eq" },
623
+ { field: "fieldName", value: fieldName, operator: "eq" }
624
+ ]
625
+ });
626
+ const ids = [...new Set(relations.map((relation) => relation.sourceId))];
627
+ const items = [];
628
+ for (const id of ids) {
629
+ const item = await adapter.findOne({
630
+ model: "contentItem",
631
+ where: [
632
+ { field: "id", value: id, operator: "eq" },
633
+ {
634
+ field: "contentTypeId",
635
+ value: contentType.id,
636
+ operator: "eq"
637
+ }
638
+ ],
639
+ join: { contentType: true }
640
+ });
641
+ if (item) items.push(item);
642
+ }
643
+ items.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
644
+ return {
645
+ items: items.slice(offset, offset + limit).map(serializeContentItemWithType),
646
+ total: items.length,
647
+ limit,
648
+ offset
649
+ };
650
+ }
651
+ function createCMSOperations(adapter, options) {
652
+ const { ensureSynced, getContentTypesWithCounts, hooks } = options;
653
+ const populatedRelationSnapshots = /* @__PURE__ */ new WeakMap();
654
+ const relationWriteAuthorizationSnapshots = /* @__PURE__ */ new WeakMap();
655
+ const relationFilterAuthorizationSnapshots = /* @__PURE__ */ new WeakMap();
656
+ const inverseSourceAuthorizationSnapshots = /* @__PURE__ */ new WeakMap();
657
+ const inverseTargetAuthorizationSnapshots = /* @__PURE__ */ new WeakMap();
658
+ const contentTypeListSnapshots = /* @__PURE__ */ new WeakMap();
659
+ const assertCurrentRelationWriteAuthorization = async (currentAdapter, authorized, contentTypeSlug, data) => {
660
+ let current;
661
+ try {
662
+ const contentType = await getContentTypeOrThrow(
663
+ currentAdapter,
664
+ ensureSynced,
665
+ contentTypeSlug
666
+ );
667
+ current = await deriveRelationWriteAuthorization(
668
+ currentAdapter,
669
+ contentType,
670
+ data,
671
+ ensureSynced,
672
+ authorized.snapshot
673
+ );
674
+ } catch (error) {
675
+ if (error instanceof CMSOperationError) {
676
+ if (error.code === "CONTENT_TYPE_NOT_FOUND") {
677
+ throw relationSchemaChangedError();
678
+ }
679
+ if (error.code === "RECORD_NOT_FOUND") throw staleRecordError();
680
+ }
681
+ throw error;
682
+ }
683
+ assertRelationWriteAuthorization(authorized, current);
684
+ };
685
+ const recheckRelationWriteAuthorization = async (input, contentTypeSlug, data) => {
686
+ const authorized = relationWriteAuthorizationSnapshots.get(input);
687
+ relationWriteAuthorizationSnapshots.delete(input);
688
+ if (!authorized) {
689
+ throw new CMSOperationError(
690
+ 500,
691
+ "Relation authorization snapshot is unavailable.",
692
+ "AUTHORIZATION_SNAPSHOT_MISSING"
693
+ );
694
+ }
695
+ await assertCurrentRelationWriteAuthorization(
696
+ adapter,
697
+ authorized,
698
+ contentTypeSlug,
699
+ data
700
+ );
701
+ return authorized;
702
+ };
703
+ const recheckInverseSourceAuthorization = async (input, targetType) => {
704
+ const authorized = inverseSourceAuthorizationSnapshots.get(input);
705
+ inverseSourceAuthorizationSnapshots.delete(input);
706
+ if (!authorized) {
707
+ throw new CMSOperationError(
708
+ 500,
709
+ "Inverse relation authorization snapshot is unavailable.",
710
+ "AUTHORIZATION_SNAPSHOT_MISSING"
711
+ );
712
+ }
713
+ const current = await deriveInverseSourceAuthorization(
714
+ adapter,
715
+ ensureSynced,
716
+ targetType
717
+ );
718
+ assertRelationSchemaSnapshot(authorized, current.snapshot);
719
+ return current.sources;
720
+ };
721
+ const recheckRelationFilterAuthorization = async (input, sourceType, fieldName, targetId) => {
722
+ const authorized = relationFilterAuthorizationSnapshots.get(input);
723
+ relationFilterAuthorizationSnapshots.delete(input);
724
+ if (!authorized) {
725
+ throw new CMSOperationError(
726
+ 500,
727
+ "Relation-filter authorization snapshot is unavailable.",
728
+ "AUTHORIZATION_SNAPSHOT_MISSING"
729
+ );
730
+ }
731
+ let sourceContentType;
732
+ try {
733
+ sourceContentType = await getContentTypeOrThrow(
734
+ adapter,
735
+ ensureSynced,
736
+ sourceType
737
+ );
738
+ } catch (error) {
739
+ if (error instanceof CMSOperationError && error.code === "CONTENT_TYPE_NOT_FOUND") {
740
+ throw relationSchemaChangedError();
741
+ }
742
+ throw error;
743
+ }
744
+ const relation = extractRelationFields(sourceContentType)[fieldName];
745
+ if (!relation) throw relationSchemaChangedError();
746
+ let targetContentType;
747
+ try {
748
+ targetContentType = await getContentTypeOrThrow(
749
+ adapter,
750
+ ensureSynced,
751
+ relation.targetType
752
+ );
753
+ } catch (error) {
754
+ if (error instanceof CMSOperationError && error.code === "CONTENT_TYPE_NOT_FOUND") {
755
+ throw relationSchemaChangedError();
756
+ }
757
+ throw error;
758
+ }
759
+ const currentSnapshot = relationFilterSnapshot(
760
+ sourceContentType,
761
+ fieldName,
762
+ relation,
763
+ targetContentType
764
+ );
765
+ if (authorized.snapshot !== currentSnapshot) {
766
+ throw relationSchemaChangedError();
767
+ }
768
+ let target;
769
+ try {
770
+ target = await getRecordOrThrow(
771
+ adapter,
772
+ ensureSynced,
773
+ targetContentType.slug,
774
+ targetId
775
+ );
776
+ } catch (error) {
777
+ if (error instanceof CMSOperationError && error.code === "RECORD_NOT_FOUND") {
778
+ throw staleRecordError();
779
+ }
780
+ throw error;
781
+ }
782
+ const currentFacts = recordFacts(target);
783
+ if (authorized.targetFacts.contentType !== currentFacts.contentType || authorized.targetFacts.recordId !== currentFacts.recordId || authorized.targetFacts.authorId !== currentFacts.authorId) {
784
+ throw staleRecordError();
785
+ }
786
+ return sourceContentType;
787
+ };
788
+ const recheckInverseTargetAuthorization = async (input, targetType, targetId) => {
789
+ const authorized = inverseTargetAuthorizationSnapshots.get(input);
790
+ if (!authorized || authorized.contentType !== targetType || authorized.recordId !== targetId) {
791
+ throw new CMSOperationError(
792
+ 500,
793
+ "Inverse-relation target authorization snapshot is unavailable.",
794
+ "AUTHORIZATION_SNAPSHOT_MISSING"
795
+ );
796
+ }
797
+ const current = await adapter.findOne({
798
+ model: "contentItem",
799
+ where: [{ field: "id", value: targetId, operator: "eq" }],
800
+ join: { contentType: true }
801
+ });
802
+ if (!current) throw staleRecordError();
803
+ assertRecordFacts(current, authorized);
804
+ };
805
+ const listQuerySchema = createListContentQuerySchema(options.maxPageSize);
806
+ const paginationSchema = z.object({
807
+ limit: z.coerce.number().min(1).max(options.maxPageSize ?? DEFAULT_MAX_PAGE_SIZE).optional().default(20),
808
+ offset: z.coerce.number().min(0).optional().default(0)
809
+ });
810
+ const ListContentItemsInputSchema = z.object({
811
+ typeSlug: z.string().min(1),
812
+ query: listQuerySchema
813
+ });
814
+ const ListContentByRelationInputSchema = z.object({
815
+ typeSlug: z.string().min(1),
816
+ query: z.object({ field: z.string().min(1), targetId: z.string().min(1) }).merge(paginationSchema)
817
+ });
818
+ const GetInverseRelationsInputSchema = z.object({
819
+ slug: z.string().min(1),
820
+ query: z.object({ itemId: z.string().min(1).optional() })
821
+ });
822
+ const ListInverseRelationItemsInputSchema = z.object({
823
+ slug: z.string().min(1),
824
+ sourceType: z.string().min(1),
825
+ query: z.object({
826
+ itemId: z.string().min(1),
827
+ fieldName: z.string().min(1)
828
+ }).merge(paginationSchema)
829
+ });
830
+ const notifyError = async (error, operation, context) => {
831
+ await hooks?.onErrorExecuteContentOperation?.(
832
+ normalizeOperationError(error, `CMS ${operation} operation failed.`),
833
+ operation,
834
+ operationErrorContext(context, error)
835
+ );
836
+ };
837
+ const listContentTypes = defineOperation({
838
+ input: ListContentTypesInputSchema,
839
+ permission: cmsPermissions.contentType.read,
840
+ facts: async () => {
841
+ await ensureSynced();
842
+ return {};
843
+ },
844
+ additionalPermissions: async ({ input }) => {
845
+ const contentTypes = await getContentTypesWithCounts();
846
+ contentTypeListSnapshots.set(input, contentTypes);
847
+ return contentTypes.map(
848
+ (contentType) => cmsPermissions.record.read(collectionFacts(contentType.slug))
849
+ );
850
+ },
851
+ execute: ({ input }) => {
852
+ const contentTypes = contentTypeListSnapshots.get(input);
853
+ contentTypeListSnapshots.delete(input);
854
+ if (!contentTypes) {
855
+ throw new CMSOperationError(
856
+ 500,
857
+ "Content-type catalog authorization snapshot is unavailable.",
858
+ "AUTHORIZATION_SNAPSHOT_MISSING"
859
+ );
860
+ }
861
+ return contentTypes.map((contentType) => ({
862
+ ...operationContentType(contentType),
863
+ itemCount: contentType.itemCount
864
+ }));
865
+ },
866
+ onError: ({ error, ...context }) => notifyError(error, "list", genericContext(context))
867
+ });
868
+ const getContentTypeBySlug = defineOperation({
869
+ input: GetContentTypeInputSchema,
870
+ permission: cmsPermissions.contentType.read,
871
+ facts: async ({ input }) => {
872
+ const contentType = await getContentTypeOrThrow(
873
+ adapter,
874
+ ensureSynced,
875
+ input.slug
876
+ );
877
+ return { contentType: contentType.slug };
878
+ },
879
+ execute: async ({ facts }) => operationContentType(
880
+ serializeContentType(
881
+ await getContentTypeOrThrow(
882
+ adapter,
883
+ ensureSynced,
884
+ facts.contentType ?? ""
885
+ )
886
+ )
887
+ ),
888
+ onError: ({ error, ...context }) => notifyError(
889
+ error,
890
+ "get",
891
+ genericContext(context, context.facts.contentType)
892
+ )
893
+ });
894
+ const listContentItems = defineOperation({
895
+ input: ListContentItemsInputSchema,
896
+ permission: cmsPermissions.record.read,
897
+ facts: async ({ input }) => {
898
+ const contentType = await getContentTypeOrThrow(
899
+ adapter,
900
+ ensureSynced,
901
+ input.typeSlug
902
+ );
903
+ if (!input.query.slug) {
904
+ return collectionFacts(contentType.slug);
905
+ }
906
+ const item = await getContentItemBySlug(
907
+ adapter,
908
+ contentType.slug,
909
+ input.query.slug
910
+ );
911
+ const facts = {
912
+ contentType: contentType.slug,
913
+ scope: "record",
914
+ ...item ? {
915
+ recordId: item.id,
916
+ ...item.authorId ? { authorId: item.authorId } : {}
917
+ } : {}
918
+ };
919
+ return facts;
920
+ },
921
+ additionalPermissions: ({ facts }) => [
922
+ cmsPermissions.contentType.read({ contentType: facts.contentType })
923
+ ],
924
+ execute: async ({ input, facts }) => {
925
+ const result = await getAllContentItems(
926
+ adapter,
927
+ facts.contentType,
928
+ input.query
929
+ );
930
+ if (facts.scope === "record") {
931
+ if (!facts.recordId) {
932
+ if (result.items.length > 0) throw staleRecordError();
933
+ if (await getContentItemBySlug(
934
+ adapter,
935
+ facts.contentType,
936
+ input.query.slug ?? ""
937
+ )) {
938
+ throw staleRecordError();
939
+ }
940
+ return operationContentList(result);
941
+ }
942
+ if (result.items.length > 1) throw staleRecordError();
943
+ if (result.items.length === 0) {
944
+ const current = await getContentItemBySlug(
945
+ adapter,
946
+ facts.contentType,
947
+ input.query.slug ?? ""
948
+ );
949
+ if (!current) throw staleRecordError();
950
+ assertRecordFacts(current, facts);
951
+ } else {
952
+ assertRecordFacts(result.items[0], facts);
953
+ }
954
+ }
955
+ return operationContentList(result);
956
+ },
957
+ onError: ({ error, ...context }) => notifyError(
958
+ error,
959
+ "list",
960
+ genericContext(context, context.facts.contentType)
961
+ )
962
+ });
963
+ const getContentItem = defineOperation({
964
+ input: GetContentItemInputSchema,
965
+ permission: cmsPermissions.record.read,
966
+ facts: async ({ input }) => recordFacts(
967
+ await getRecordOrThrow(adapter, ensureSynced, input.typeSlug, input.id)
968
+ ),
969
+ additionalPermissions: ({ facts }) => [
970
+ cmsPermissions.contentType.read({ contentType: facts.contentType })
971
+ ],
972
+ execute: async ({ facts }) => {
973
+ const item = await getRecordOrThrow(
974
+ adapter,
975
+ ensureSynced,
976
+ facts.contentType,
977
+ facts.recordId ?? ""
978
+ );
979
+ assertRecordFacts(item, facts);
980
+ return operationContentItem(serializeContentItemWithType(item));
981
+ },
982
+ onError: ({ error, ...context }) => notifyError(
983
+ error,
984
+ "get",
985
+ genericContext(context, context.facts.contentType)
986
+ )
987
+ });
988
+ const createContentItem = defineOperation({
989
+ input: CreateContentItemInputSchema,
990
+ permission: cmsPermissions.record.create,
991
+ facts: async ({ input }) => ({
992
+ contentType: (await getContentTypeOrThrow(adapter, ensureSynced, input.typeSlug)).slug
993
+ }),
994
+ additionalPermissions: async ({ input, facts }) => {
995
+ const authorization = await deriveRelationWriteAuthorization(
996
+ adapter,
997
+ await getContentTypeOrThrow(adapter, ensureSynced, facts.contentType),
998
+ input.body.data,
999
+ ensureSynced
1000
+ );
1001
+ relationWriteAuthorizationSnapshots.set(input, authorization);
1002
+ return [
1003
+ cmsPermissions.contentType.read({ contentType: facts.contentType }),
1004
+ ...authorization.permissions
1005
+ ];
1006
+ },
1007
+ execute: async (context) => {
1008
+ const lifecycleContext = createContext(context);
1009
+ const contentType = await getContentTypeOrThrow(
1010
+ adapter,
1011
+ ensureSynced,
1012
+ context.facts.contentType
1013
+ );
1014
+ const slug = slugify(context.input.body.slug);
1015
+ if (!slug) {
1016
+ throw new CMSOperationError(
1017
+ 400,
1018
+ "Invalid slug: must contain at least one alphanumeric character",
1019
+ "INVALID_SLUG"
1020
+ );
1021
+ }
1022
+ const relationAuthorization = await recheckRelationWriteAuthorization(
1023
+ context.input,
1024
+ contentType.slug,
1025
+ context.input.body.data
1026
+ );
1027
+ const relationPlan = await planRelationsInData(
1028
+ adapter,
1029
+ contentType,
1030
+ context.input.body.data,
1031
+ ensureSynced,
1032
+ context.identity?.id
1033
+ );
1034
+ const validation = getContentTypeZodSchema(contentType).safeParse(
1035
+ relationPlan.processedData
1036
+ );
1037
+ if (!validation.success) {
1038
+ throw new CMSOperationError(
1039
+ 400,
1040
+ "Validation failed",
1041
+ "RECORD_VALIDATION_FAILED",
1042
+ validation.error.issues
1043
+ );
1044
+ }
1045
+ const existing = await adapter.findOne({
1046
+ model: "contentItem",
1047
+ where: [
1048
+ {
1049
+ field: "contentTypeId",
1050
+ value: contentType.id,
1051
+ operator: "eq"
1052
+ },
1053
+ { field: "slug", value: slug, operator: "eq" }
1054
+ ]
1055
+ });
1056
+ if (existing) {
1057
+ throw new CMSOperationError(
1058
+ 409,
1059
+ "Content item with this slug already exists",
1060
+ "DUPLICATE_SLUG"
1061
+ );
1062
+ }
1063
+ const validatedData = validation.data;
1064
+ await runBeforeHook(
1065
+ () => hooks?.onBeforeCreateContent?.(validatedData, lifecycleContext),
1066
+ "Create operation denied"
1067
+ );
1068
+ return adapter.transaction(async (tx) => {
1069
+ await assertCurrentRelationWriteAuthorization(
1070
+ tx,
1071
+ relationAuthorization,
1072
+ contentType.slug,
1073
+ context.input.body.data
1074
+ );
1075
+ const currentDuplicate = await tx.findOne({
1076
+ model: "contentItem",
1077
+ where: [
1078
+ {
1079
+ field: "contentTypeId",
1080
+ value: contentType.id,
1081
+ operator: "eq"
1082
+ },
1083
+ { field: "slug", value: slug, operator: "eq" }
1084
+ ]
1085
+ });
1086
+ if (currentDuplicate) {
1087
+ throw new CMSOperationError(
1088
+ 409,
1089
+ "Content item with this slug already exists",
1090
+ "DUPLICATE_SLUG"
1091
+ );
1092
+ }
1093
+ await applyRelationWritePlan(tx, relationPlan);
1094
+ const item = await tx.create({
1095
+ model: "contentItem",
1096
+ data: {
1097
+ contentTypeId: contentType.id,
1098
+ slug,
1099
+ data: JSON.stringify(validatedData),
1100
+ ...context.identity ? { authorId: context.identity.id } : {},
1101
+ createdAt: /* @__PURE__ */ new Date(),
1102
+ updatedAt: /* @__PURE__ */ new Date()
1103
+ }
1104
+ });
1105
+ await syncRelations(tx, item.id, relationPlan.relationIds);
1106
+ const joined = await getRecordOrThrow(
1107
+ tx,
1108
+ ensureSynced,
1109
+ contentType.slug,
1110
+ item.id
1111
+ );
1112
+ return operationContentItem(serializeContentItemWithType(joined));
1113
+ });
1114
+ },
1115
+ after: async (context) => {
1116
+ const base = createContext(context);
1117
+ const afterCreateContent = hooks?.onAfterCreateContent;
1118
+ await afterCreateContent?.(
1119
+ context.result,
1120
+ Object.freeze({ ...base, result: context.result })
1121
+ );
1122
+ },
1123
+ onError: async ({ error, ...context }) => {
1124
+ await notifyError(error, "create", createContext(context));
1125
+ }
1126
+ });
1127
+ const updateContentItem = defineOperation({
1128
+ input: UpdateContentItemInputSchema,
1129
+ permission: cmsPermissions.record.update,
1130
+ facts: async ({ input }) => {
1131
+ const item = await getRecordOrThrow(
1132
+ adapter,
1133
+ ensureSynced,
1134
+ input.typeSlug,
1135
+ input.id
1136
+ );
1137
+ const facts = recordFacts(item);
1138
+ return {
1139
+ contentType: facts.contentType,
1140
+ recordId: facts.recordId ?? input.id,
1141
+ ...facts.authorId ? { authorId: facts.authorId } : {}
1142
+ };
1143
+ },
1144
+ additionalPermissions: async ({ input, facts }) => {
1145
+ const contentTypePermission = cmsPermissions.contentType.read({
1146
+ contentType: facts.contentType
1147
+ });
1148
+ if (!input.body.data) return [contentTypePermission];
1149
+ const authorization = await deriveRelationWriteAuthorization(
1150
+ adapter,
1151
+ await getContentTypeOrThrow(adapter, ensureSynced, facts.contentType),
1152
+ input.body.data,
1153
+ ensureSynced
1154
+ );
1155
+ relationWriteAuthorizationSnapshots.set(input, authorization);
1156
+ return [contentTypePermission, ...authorization.permissions];
1157
+ },
1158
+ execute: async (context) => {
1159
+ const lifecycleContext = updateContext(context);
1160
+ const contentType = await getContentTypeOrThrow(
1161
+ adapter,
1162
+ ensureSynced,
1163
+ context.facts.contentType
1164
+ );
1165
+ const rawSlug = context.input.body.slug;
1166
+ const slug = rawSlug ? slugify(rawSlug) : void 0;
1167
+ if (rawSlug && !slug) {
1168
+ throw new CMSOperationError(
1169
+ 400,
1170
+ "Invalid slug: must contain at least one alphanumeric character",
1171
+ "INVALID_SLUG"
1172
+ );
1173
+ }
1174
+ const bodyData = context.input.body.data;
1175
+ const relationAuthorization = bodyData ? await recheckRelationWriteAuthorization(
1176
+ context.input,
1177
+ contentType.slug,
1178
+ bodyData
1179
+ ) : void 0;
1180
+ const authorizedRecord = await getRecordOrThrow(
1181
+ adapter,
1182
+ ensureSynced,
1183
+ context.facts.contentType,
1184
+ context.facts.recordId
1185
+ );
1186
+ assertRecordFacts(authorizedRecord, context.facts);
1187
+ if (slug && slug !== authorizedRecord.slug) {
1188
+ const duplicate = await adapter.findOne({
1189
+ model: "contentItem",
1190
+ where: [
1191
+ {
1192
+ field: "contentTypeId",
1193
+ value: contentType.id,
1194
+ operator: "eq"
1195
+ },
1196
+ { field: "slug", value: slug, operator: "eq" }
1197
+ ]
1198
+ });
1199
+ if (duplicate) {
1200
+ throw new CMSOperationError(
1201
+ 409,
1202
+ "Content item with this slug already exists",
1203
+ "DUPLICATE_SLUG"
1204
+ );
1205
+ }
1206
+ }
1207
+ const relationPlan = bodyData ? await planRelationsInData(
1208
+ adapter,
1209
+ contentType,
1210
+ bodyData,
1211
+ ensureSynced,
1212
+ context.identity?.id
1213
+ ) : void 0;
1214
+ const currentData = authorizedRecord.data ? JSON.parse(authorizedRecord.data) : {};
1215
+ const validation = getContentTypeZodSchema(contentType).safeParse({
1216
+ ...currentData,
1217
+ ...relationPlan?.processedData ?? {}
1218
+ });
1219
+ if (!validation.success) {
1220
+ throw new CMSOperationError(
1221
+ 400,
1222
+ "Validation failed",
1223
+ "RECORD_VALIDATION_FAILED",
1224
+ validation.error.issues
1225
+ );
1226
+ }
1227
+ const mergedData = validation.data;
1228
+ await runBeforeHook(
1229
+ () => hooks?.onBeforeUpdateContent?.(
1230
+ context.facts.recordId,
1231
+ mergedData,
1232
+ lifecycleContext
1233
+ ),
1234
+ "Update operation denied"
1235
+ );
1236
+ return adapter.transaction(async (tx) => {
1237
+ if (bodyData && relationAuthorization) {
1238
+ await assertCurrentRelationWriteAuthorization(
1239
+ tx,
1240
+ relationAuthorization,
1241
+ contentType.slug,
1242
+ bodyData
1243
+ );
1244
+ }
1245
+ const current = await getRecordOrThrow(
1246
+ tx,
1247
+ ensureSynced,
1248
+ context.facts.contentType,
1249
+ context.facts.recordId
1250
+ );
1251
+ assertRecordFacts(current, context.facts);
1252
+ assertRecordSnapshot(current, authorizedRecord);
1253
+ if (slug && slug !== current.slug) {
1254
+ const duplicate = await tx.findOne({
1255
+ model: "contentItem",
1256
+ where: [
1257
+ {
1258
+ field: "contentTypeId",
1259
+ value: contentType.id,
1260
+ operator: "eq"
1261
+ },
1262
+ { field: "slug", value: slug, operator: "eq" }
1263
+ ]
1264
+ });
1265
+ if (duplicate) {
1266
+ throw new CMSOperationError(
1267
+ 409,
1268
+ "Content item with this slug already exists",
1269
+ "DUPLICATE_SLUG"
1270
+ );
1271
+ }
1272
+ }
1273
+ if (relationPlan) await applyRelationWritePlan(tx, relationPlan);
1274
+ const update = { updatedAt: /* @__PURE__ */ new Date() };
1275
+ if (slug) update.slug = slug;
1276
+ if (bodyData) update.data = JSON.stringify(mergedData);
1277
+ const matched = await tx.updateMany({
1278
+ model: "contentItem",
1279
+ where: [
1280
+ {
1281
+ field: "id",
1282
+ value: context.facts.recordId,
1283
+ operator: "eq"
1284
+ },
1285
+ {
1286
+ field: "contentTypeId",
1287
+ value: contentType.id,
1288
+ operator: "eq"
1289
+ },
1290
+ {
1291
+ field: "authorId",
1292
+ value: context.facts.authorId ?? null,
1293
+ operator: "eq"
1294
+ },
1295
+ {
1296
+ field: "updatedAt",
1297
+ value: current.updatedAt,
1298
+ operator: "eq"
1299
+ }
1300
+ ],
1301
+ update
1302
+ });
1303
+ if (!didUpdateContentItem(matched, context.facts.recordId)) {
1304
+ throw staleRecordError();
1305
+ }
1306
+ if (relationPlan) {
1307
+ await syncRelations(
1308
+ tx,
1309
+ context.facts.recordId,
1310
+ relationPlan.relationIds
1311
+ );
1312
+ }
1313
+ const updated = await getRecordOrThrow(
1314
+ tx,
1315
+ ensureSynced,
1316
+ context.facts.contentType,
1317
+ context.facts.recordId
1318
+ );
1319
+ return operationContentItem(serializeContentItemWithType(updated));
1320
+ });
1321
+ },
1322
+ after: async (context) => {
1323
+ const base = updateContext(context);
1324
+ const afterUpdateContent = hooks?.onAfterUpdateContent;
1325
+ await afterUpdateContent?.(
1326
+ context.result,
1327
+ Object.freeze({ ...base, result: context.result })
1328
+ );
1329
+ },
1330
+ onError: async ({ error, ...context }) => {
1331
+ await notifyError(error, "update", updateContext(context));
1332
+ }
1333
+ });
1334
+ const deleteContentItem = defineOperation({
1335
+ input: DeleteContentItemInputSchema,
1336
+ permission: cmsPermissions.record.delete,
1337
+ facts: async ({ input }) => {
1338
+ const item = await getRecordOrThrow(
1339
+ adapter,
1340
+ ensureSynced,
1341
+ input.typeSlug,
1342
+ input.id
1343
+ );
1344
+ const facts = recordFacts(item);
1345
+ return {
1346
+ contentType: facts.contentType,
1347
+ recordId: facts.recordId ?? input.id,
1348
+ ...facts.authorId ? { authorId: facts.authorId } : {}
1349
+ };
1350
+ },
1351
+ before: async (context) => {
1352
+ const current = await getRecordOrThrow(
1353
+ adapter,
1354
+ ensureSynced,
1355
+ context.facts.contentType,
1356
+ context.facts.recordId
1357
+ );
1358
+ assertRecordFacts(current, context.facts);
1359
+ await runBeforeHook(
1360
+ () => hooks?.onBeforeDeleteContent?.(
1361
+ context.facts.recordId,
1362
+ deleteContext(context)
1363
+ ),
1364
+ "Delete operation denied"
1365
+ );
1366
+ },
1367
+ execute: async ({ facts }) => adapter.transaction(async (tx) => {
1368
+ const existing = await getRecordOrThrow(
1369
+ tx,
1370
+ ensureSynced,
1371
+ facts.contentType,
1372
+ facts.recordId
1373
+ );
1374
+ assertRecordFacts(existing, facts);
1375
+ const matched = await tx.updateMany({
1376
+ model: "contentItem",
1377
+ where: [
1378
+ { field: "id", value: facts.recordId, operator: "eq" },
1379
+ {
1380
+ field: "contentTypeId",
1381
+ value: existing.contentTypeId,
1382
+ operator: "eq"
1383
+ },
1384
+ {
1385
+ field: "authorId",
1386
+ value: facts.authorId ?? null,
1387
+ operator: "eq"
1388
+ },
1389
+ {
1390
+ field: "updatedAt",
1391
+ value: existing.updatedAt,
1392
+ operator: "eq"
1393
+ }
1394
+ ],
1395
+ update: { updatedAt: /* @__PURE__ */ new Date() }
1396
+ });
1397
+ if (!didUpdateContentItem(matched, facts.recordId)) {
1398
+ throw staleRecordError();
1399
+ }
1400
+ await tx.delete({
1401
+ model: "contentItem",
1402
+ where: [
1403
+ { field: "id", value: facts.recordId, operator: "eq" },
1404
+ {
1405
+ field: "contentTypeId",
1406
+ value: existing.contentTypeId,
1407
+ operator: "eq"
1408
+ }
1409
+ ]
1410
+ });
1411
+ return { success: true };
1412
+ }),
1413
+ after: async (context) => {
1414
+ const base = deleteContext(context);
1415
+ await hooks?.onAfterDeleteContent?.(
1416
+ context.facts.recordId,
1417
+ Object.freeze({ ...base, result: context.result })
1418
+ );
1419
+ },
1420
+ onError: async ({ error, ...context }) => {
1421
+ await notifyError(error, "delete", deleteContext(context));
1422
+ }
1423
+ });
1424
+ const getContentItemPopulated = defineOperation({
1425
+ input: GetContentItemInputSchema,
1426
+ permission: cmsPermissions.record.read,
1427
+ facts: async ({ input }) => recordFacts(
1428
+ await getRecordOrThrow(adapter, ensureSynced, input.typeSlug, input.id)
1429
+ ),
1430
+ additionalPermissions: async ({ input, facts }) => {
1431
+ const snapshot = await getPopulatedRelationSnapshot(
1432
+ adapter,
1433
+ facts.recordId ?? ""
1434
+ );
1435
+ populatedRelationSnapshots.set(input, snapshot);
1436
+ const contentTypes = /* @__PURE__ */ new Set([
1437
+ facts.contentType,
1438
+ ...snapshot.targets.map(
1439
+ ({ facts: targetFacts }) => targetFacts.contentType
1440
+ )
1441
+ ]);
1442
+ return [
1443
+ ...[...contentTypes].map(
1444
+ (contentType) => cmsPermissions.contentType.read({ contentType })
1445
+ ),
1446
+ ...snapshot.targets.map(
1447
+ ({ facts: targetFacts }) => cmsPermissions.record.read(targetFacts)
1448
+ )
1449
+ ];
1450
+ },
1451
+ execute: async ({ input, facts }) => {
1452
+ try {
1453
+ const item = await getRecordOrThrow(
1454
+ adapter,
1455
+ ensureSynced,
1456
+ facts.contentType,
1457
+ facts.recordId ?? ""
1458
+ );
1459
+ assertRecordFacts(item, facts);
1460
+ const authorizedSnapshot = populatedRelationSnapshots.get(
1461
+ input
1462
+ );
1463
+ if (!authorizedSnapshot) {
1464
+ throw new CMSOperationError(
1465
+ 500,
1466
+ "Related-content authorization snapshot is unavailable.",
1467
+ "AUTHORIZATION_SNAPSHOT_MISSING"
1468
+ );
1469
+ }
1470
+ const currentSnapshot = await getPopulatedRelationSnapshot(
1471
+ adapter,
1472
+ facts.recordId ?? ""
1473
+ );
1474
+ assertPopulatedRelationSnapshot(authorizedSnapshot, currentSnapshot);
1475
+ const relations = populatedRelationsFromSnapshot(currentSnapshot);
1476
+ return {
1477
+ ...operationContentItem(serializeContentItemWithType(item)),
1478
+ _relations: Object.fromEntries(
1479
+ Object.entries(relations).map(([field, records]) => [
1480
+ field,
1481
+ records.map(operationContentItem)
1482
+ ])
1483
+ )
1484
+ };
1485
+ } finally {
1486
+ populatedRelationSnapshots.delete(input);
1487
+ }
1488
+ },
1489
+ onError: ({ error, ...context }) => notifyError(
1490
+ error,
1491
+ "get",
1492
+ genericContext(context, context.facts.contentType)
1493
+ )
1494
+ });
1495
+ const listContentByRelation = defineOperation({
1496
+ input: ListContentByRelationInputSchema,
1497
+ permission: cmsPermissions.record.read,
1498
+ facts: async ({ input }) => collectionFacts(
1499
+ (await getContentTypeOrThrow(adapter, ensureSynced, input.typeSlug)).slug
1500
+ ),
1501
+ additionalPermissions: async ({ input, facts }) => {
1502
+ const sourceContentType = await getContentTypeOrThrow(
1503
+ adapter,
1504
+ ensureSynced,
1505
+ facts.contentType
1506
+ );
1507
+ const authorization = await deriveRelationFilterAuthorization(
1508
+ adapter,
1509
+ ensureSynced,
1510
+ sourceContentType,
1511
+ input.query.field,
1512
+ input.query.targetId
1513
+ );
1514
+ relationFilterAuthorizationSnapshots.set(input, authorization);
1515
+ return [
1516
+ cmsPermissions.contentType.read({ contentType: facts.contentType }),
1517
+ authorization.permission
1518
+ ];
1519
+ },
1520
+ execute: async ({ input, facts }) => {
1521
+ const sourceContentType = await recheckRelationFilterAuthorization(
1522
+ input,
1523
+ facts.contentType,
1524
+ input.query.field,
1525
+ input.query.targetId
1526
+ );
1527
+ const result = await listRecordsForRelation(
1528
+ adapter,
1529
+ sourceContentType,
1530
+ input.query.field,
1531
+ input.query.targetId,
1532
+ input.query.limit,
1533
+ input.query.offset
1534
+ );
1535
+ return {
1536
+ ...result,
1537
+ items: result.items.map(operationContentItem)
1538
+ };
1539
+ },
1540
+ onError: ({ error, ...context }) => notifyError(
1541
+ error,
1542
+ "list",
1543
+ genericContext(context, context.facts.contentType)
1544
+ )
1545
+ });
1546
+ const getInverseRelations = defineOperation({
1547
+ input: GetInverseRelationsInputSchema,
1548
+ permission: cmsPermissions.contentType.read,
1549
+ facts: async ({ input }) => ({
1550
+ contentType: (await getContentTypeOrThrow(adapter, ensureSynced, input.slug)).slug
1551
+ }),
1552
+ additionalPermissions: async ({ input, facts }) => {
1553
+ const authorization = await deriveInverseSourceAuthorization(
1554
+ adapter,
1555
+ ensureSynced,
1556
+ facts.contentType ?? ""
1557
+ );
1558
+ inverseSourceAuthorizationSnapshots.set(
1559
+ input,
1560
+ authorization.snapshot
1561
+ );
1562
+ const permissions = [...authorization.permissions];
1563
+ if (input.query.itemId) {
1564
+ const targetFacts = recordFacts(
1565
+ await getRecordOrThrow(
1566
+ adapter,
1567
+ ensureSynced,
1568
+ facts.contentType ?? "",
1569
+ input.query.itemId
1570
+ )
1571
+ );
1572
+ inverseTargetAuthorizationSnapshots.set(input, targetFacts);
1573
+ permissions.push(cmsPermissions.record.read(targetFacts));
1574
+ const authorizedSourceTypes = /* @__PURE__ */ new Set();
1575
+ for (const source of authorization.sources) {
1576
+ if (authorizedSourceTypes.has(source.contentTypeSlug)) continue;
1577
+ authorizedSourceTypes.add(source.contentTypeSlug);
1578
+ permissions.push(
1579
+ cmsPermissions.record.read(collectionFacts(source.contentTypeSlug))
1580
+ );
1581
+ }
1582
+ }
1583
+ return permissions;
1584
+ },
1585
+ execute: async ({ input, facts }) => {
1586
+ try {
1587
+ const sources = await recheckInverseSourceAuthorization(
1588
+ input,
1589
+ facts.contentType ?? ""
1590
+ );
1591
+ if (input.query.itemId) {
1592
+ await recheckInverseTargetAuthorization(
1593
+ input,
1594
+ facts.contentType ?? "",
1595
+ input.query.itemId
1596
+ );
1597
+ }
1598
+ const inverseRelations = [];
1599
+ for (const source of sources) {
1600
+ let count = 0;
1601
+ if (input.query.itemId) {
1602
+ const relations = await adapter.findMany({
1603
+ model: "contentRelation",
1604
+ where: [
1605
+ {
1606
+ field: "targetId",
1607
+ value: input.query.itemId,
1608
+ operator: "eq"
1609
+ },
1610
+ {
1611
+ field: "fieldName",
1612
+ value: source.fieldName,
1613
+ operator: "eq"
1614
+ }
1615
+ ]
1616
+ });
1617
+ for (const sourceId of relations.map((value) => value.sourceId)) {
1618
+ const item = await adapter.findOne({
1619
+ model: "contentItem",
1620
+ where: [
1621
+ {
1622
+ field: "id",
1623
+ value: sourceId,
1624
+ operator: "eq"
1625
+ },
1626
+ {
1627
+ field: "contentTypeId",
1628
+ value: source.contentTypeId,
1629
+ operator: "eq"
1630
+ }
1631
+ ]
1632
+ });
1633
+ if (item) count += 1;
1634
+ }
1635
+ }
1636
+ inverseRelations.push({
1637
+ sourceType: source.contentTypeSlug,
1638
+ sourceTypeName: source.contentTypeName,
1639
+ fieldName: source.fieldName,
1640
+ count
1641
+ });
1642
+ }
1643
+ return {
1644
+ inverseRelations: inverseRelations.map((relation) => ({
1645
+ ...relation
1646
+ }))
1647
+ };
1648
+ } finally {
1649
+ inverseTargetAuthorizationSnapshots.delete(input);
1650
+ }
1651
+ },
1652
+ onError: ({ error, ...context }) => notifyError(
1653
+ error,
1654
+ "get",
1655
+ genericContext(context, context.facts.contentType)
1656
+ )
1657
+ });
1658
+ const listInverseRelationItems = defineOperation({
1659
+ input: ListInverseRelationItemsInputSchema,
1660
+ permission: cmsPermissions.record.read,
1661
+ facts: async ({ input }) => {
1662
+ await getContentTypeOrThrow(adapter, ensureSynced, input.slug);
1663
+ const sourceType = await getContentTypeOrThrow(
1664
+ adapter,
1665
+ ensureSynced,
1666
+ input.sourceType
1667
+ );
1668
+ return collectionFacts(sourceType.slug);
1669
+ },
1670
+ additionalPermissions: async ({ input, facts }) => {
1671
+ const authorization = await deriveInverseSourceAuthorization(
1672
+ adapter,
1673
+ ensureSynced,
1674
+ input.slug
1675
+ );
1676
+ const source = authorization.sources.find(
1677
+ (value) => value.contentTypeSlug === facts.contentType && value.fieldName === input.query.fieldName
1678
+ );
1679
+ if (!source) {
1680
+ throw new CMSOperationError(
1681
+ 404,
1682
+ "Inverse relation not found",
1683
+ "INVERSE_RELATION_NOT_FOUND"
1684
+ );
1685
+ }
1686
+ inverseSourceAuthorizationSnapshots.set(
1687
+ input,
1688
+ authorization.snapshot
1689
+ );
1690
+ const targetFacts = recordFacts(
1691
+ await getRecordOrThrow(
1692
+ adapter,
1693
+ ensureSynced,
1694
+ input.slug,
1695
+ input.query.itemId
1696
+ )
1697
+ );
1698
+ inverseTargetAuthorizationSnapshots.set(input, targetFacts);
1699
+ return [
1700
+ cmsPermissions.contentType.read({ contentType: facts.contentType }),
1701
+ cmsPermissions.record.read(targetFacts)
1702
+ ];
1703
+ },
1704
+ execute: async ({ input, facts }) => {
1705
+ try {
1706
+ const sources = await recheckInverseSourceAuthorization(
1707
+ input,
1708
+ input.slug
1709
+ );
1710
+ const source = sources.find(
1711
+ (value) => value.contentTypeSlug === facts.contentType && value.fieldName === input.query.fieldName
1712
+ );
1713
+ if (!source) throw relationSchemaChangedError();
1714
+ await recheckInverseTargetAuthorization(
1715
+ input,
1716
+ input.slug,
1717
+ input.query.itemId
1718
+ );
1719
+ const result = await listRecordsForRelation(
1720
+ adapter,
1721
+ await getContentTypeOrThrow(adapter, ensureSynced, facts.contentType),
1722
+ source.fieldName,
1723
+ input.query.itemId,
1724
+ input.query.limit,
1725
+ input.query.offset
1726
+ );
1727
+ return {
1728
+ ...result,
1729
+ items: result.items.map(operationContentItem)
1730
+ };
1731
+ } finally {
1732
+ inverseTargetAuthorizationSnapshots.delete(input);
1733
+ }
1734
+ },
1735
+ onError: ({ error, ...context }) => notifyError(
1736
+ error,
1737
+ "list",
1738
+ genericContext(context, context.facts.contentType)
1739
+ )
1740
+ });
1741
+ return {
1742
+ listContentTypes,
1743
+ getContentTypeBySlug,
1744
+ listContentItems,
1745
+ getContentItem,
1746
+ createContentItem,
1747
+ updateContentItem,
1748
+ deleteContentItem,
1749
+ getContentItemPopulated,
1750
+ listContentByRelation,
1751
+ getInverseRelations,
1752
+ listInverseRelationItems
1753
+ };
1754
+ }
1755
+
1756
+ export { CMSContentItemParamsSchema, CMSContentTypeParamsSchema, CMSCreateContentItemBodySchema, CMSOperationError, CMSUpdateContentItemBodySchema, createCMSOperations };