@kywi-software/core 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/README.md +57 -2
  2. package/dist/admin/app.d.ts +10 -1
  3. package/dist/admin/app.d.ts.map +1 -1
  4. package/dist/admin/app.js +2 -2
  5. package/dist/admin/app.js.map +1 -1
  6. package/dist/admin/approval-queue.d.ts +3 -1
  7. package/dist/admin/approval-queue.d.ts.map +1 -1
  8. package/dist/admin/approval-queue.js +2 -2
  9. package/dist/admin/approval-queue.js.map +1 -1
  10. package/dist/admin/audience-list.d.ts.map +1 -1
  11. package/dist/admin/audience-list.js +9 -1
  12. package/dist/admin/audience-list.js.map +1 -1
  13. package/dist/admin/chrome.d.ts +7 -1
  14. package/dist/admin/chrome.d.ts.map +1 -1
  15. package/dist/admin/chrome.js +2 -1
  16. package/dist/admin/chrome.js.map +1 -1
  17. package/dist/admin/content-editor-api.d.ts +27 -1
  18. package/dist/admin/content-editor-api.d.ts.map +1 -1
  19. package/dist/admin/content-editor-api.js +60 -2
  20. package/dist/admin/content-editor-api.js.map +1 -1
  21. package/dist/admin/content-form.d.ts +62 -6
  22. package/dist/admin/content-form.d.ts.map +1 -1
  23. package/dist/admin/content-form.js +118 -13
  24. package/dist/admin/content-form.js.map +1 -1
  25. package/dist/admin/content-permissions-tab.d.ts +13 -0
  26. package/dist/admin/content-permissions-tab.d.ts.map +1 -0
  27. package/dist/admin/content-permissions-tab.js +90 -0
  28. package/dist/admin/content-permissions-tab.js.map +1 -0
  29. package/dist/admin/context.d.ts +8 -0
  30. package/dist/admin/context.d.ts.map +1 -1
  31. package/dist/admin/context.js.map +1 -1
  32. package/dist/admin/feed-builder.d.ts.map +1 -1
  33. package/dist/admin/feed-builder.js +20 -1
  34. package/dist/admin/feed-builder.js.map +1 -1
  35. package/dist/admin/field-components.d.ts.map +1 -1
  36. package/dist/admin/field-components.js +26 -1
  37. package/dist/admin/field-components.js.map +1 -1
  38. package/dist/admin/form-builder.js +6 -1
  39. package/dist/admin/form-builder.js.map +1 -1
  40. package/dist/admin/form-helpers.d.ts.map +1 -1
  41. package/dist/admin/form-helpers.js +2 -0
  42. package/dist/admin/form-helpers.js.map +1 -1
  43. package/dist/admin/layout-editor/component-actions.d.ts +18 -0
  44. package/dist/admin/layout-editor/component-actions.d.ts.map +1 -1
  45. package/dist/admin/layout-editor/component-actions.js +19 -0
  46. package/dist/admin/layout-editor/component-actions.js.map +1 -1
  47. package/dist/admin/layout-editor/component-picker-field.d.ts +20 -0
  48. package/dist/admin/layout-editor/component-picker-field.d.ts.map +1 -0
  49. package/dist/admin/layout-editor/component-picker-field.js +16 -0
  50. package/dist/admin/layout-editor/component-picker-field.js.map +1 -0
  51. package/dist/admin/layout-editor/drag-utils.d.ts +48 -0
  52. package/dist/admin/layout-editor/drag-utils.d.ts.map +1 -1
  53. package/dist/admin/layout-editor/drag-utils.js +43 -0
  54. package/dist/admin/layout-editor/drag-utils.js.map +1 -1
  55. package/dist/admin/layout-editor/editor-canvas.d.ts +9 -1
  56. package/dist/admin/layout-editor/editor-canvas.d.ts.map +1 -1
  57. package/dist/admin/layout-editor/editor-canvas.js +41 -15
  58. package/dist/admin/layout-editor/editor-canvas.js.map +1 -1
  59. package/dist/admin/layout-editor/editor-state.d.ts +9 -1
  60. package/dist/admin/layout-editor/editor-state.d.ts.map +1 -1
  61. package/dist/admin/layout-editor/editor-state.js +34 -0
  62. package/dist/admin/layout-editor/editor-state.js.map +1 -1
  63. package/dist/admin/layout-editor/editor.css +83 -0
  64. package/dist/admin/layout-editor/form-picker-field.d.ts +17 -0
  65. package/dist/admin/layout-editor/form-picker-field.d.ts.map +1 -0
  66. package/dist/admin/layout-editor/form-picker-field.js +35 -0
  67. package/dist/admin/layout-editor/form-picker-field.js.map +1 -0
  68. package/dist/admin/layout-editor/layout-editor.d.ts.map +1 -1
  69. package/dist/admin/layout-editor/layout-editor.js +95 -28
  70. package/dist/admin/layout-editor/layout-editor.js.map +1 -1
  71. package/dist/admin/layout-editor/mode-toggle.d.ts.map +1 -1
  72. package/dist/admin/layout-editor/mode-toggle.js +1 -1
  73. package/dist/admin/layout-editor/mode-toggle.js.map +1 -1
  74. package/dist/admin/layout-editor/module-overlay.d.ts +10 -1
  75. package/dist/admin/layout-editor/module-overlay.d.ts.map +1 -1
  76. package/dist/admin/layout-editor/module-overlay.js +3 -3
  77. package/dist/admin/layout-editor/module-overlay.js.map +1 -1
  78. package/dist/admin/layout-editor/props-panel.d.ts +10 -1
  79. package/dist/admin/layout-editor/props-panel.d.ts.map +1 -1
  80. package/dist/admin/layout-editor/props-panel.js +25 -2
  81. package/dist/admin/layout-editor/props-panel.js.map +1 -1
  82. package/dist/admin/layout-editor/section-insert-line.d.ts.map +1 -1
  83. package/dist/admin/layout-editor/section-insert-line.js +1 -1
  84. package/dist/admin/layout-editor/section-insert-line.js.map +1 -1
  85. package/dist/admin/layout-editor/section-overlay.d.ts.map +1 -1
  86. package/dist/admin/layout-editor/section-overlay.js +1 -1
  87. package/dist/admin/layout-editor/section-overlay.js.map +1 -1
  88. package/dist/admin/layout-editor/section-template-picker.d.ts +9 -1
  89. package/dist/admin/layout-editor/section-template-picker.d.ts.map +1 -1
  90. package/dist/admin/layout-editor/section-template-picker.js +45 -2
  91. package/dist/admin/layout-editor/section-template-picker.js.map +1 -1
  92. package/dist/admin/registry.d.ts.map +1 -1
  93. package/dist/admin/registry.js +11 -0
  94. package/dist/admin/registry.js.map +1 -1
  95. package/dist/admin/server.d.ts +15 -2
  96. package/dist/admin/server.d.ts.map +1 -1
  97. package/dist/admin/server.js +37 -1
  98. package/dist/admin/server.js.map +1 -1
  99. package/dist/admin/styles/admin.css +16 -4
  100. package/dist/admin/surface-matcher.d.ts +27 -0
  101. package/dist/admin/surface-matcher.d.ts.map +1 -1
  102. package/dist/admin/surface-matcher.js +11 -0
  103. package/dist/admin/surface-matcher.js.map +1 -1
  104. package/dist/admin/surfaces/approvals/approvals-data.d.ts +29 -9
  105. package/dist/admin/surfaces/approvals/approvals-data.d.ts.map +1 -1
  106. package/dist/admin/surfaces/approvals/approvals-data.js +65 -22
  107. package/dist/admin/surfaces/approvals/approvals-data.js.map +1 -1
  108. package/dist/admin/surfaces/approvals/approvals-index.d.ts.map +1 -1
  109. package/dist/admin/surfaces/approvals/approvals-index.js +47 -14
  110. package/dist/admin/surfaces/approvals/approvals-index.js.map +1 -1
  111. package/dist/admin/surfaces/content/content-edit.d.ts.map +1 -1
  112. package/dist/admin/surfaces/content/content-edit.js +34 -8
  113. package/dist/admin/surfaces/content/content-edit.js.map +1 -1
  114. package/dist/admin/surfaces/content/content-index.d.ts.map +1 -1
  115. package/dist/admin/surfaces/content/content-index.js +29 -2
  116. package/dist/admin/surfaces/content/content-index.js.map +1 -1
  117. package/dist/admin/surfaces/content/content-new.d.ts.map +1 -1
  118. package/dist/admin/surfaces/content/content-new.js +6 -4
  119. package/dist/admin/surfaces/content/content-new.js.map +1 -1
  120. package/dist/admin/surfaces/contentTree/content-tree.d.ts.map +1 -1
  121. package/dist/admin/surfaces/contentTree/content-tree.js +25 -2
  122. package/dist/admin/surfaces/contentTree/content-tree.js.map +1 -1
  123. package/dist/admin/surfaces/contentTypes/content-types-designer.d.ts.map +1 -1
  124. package/dist/admin/surfaces/contentTypes/content-types-designer.js +78 -47
  125. package/dist/admin/surfaces/contentTypes/content-types-designer.js.map +1 -1
  126. package/dist/admin/surfaces/feeds/feed-editor.d.ts.map +1 -1
  127. package/dist/admin/surfaces/feeds/feed-editor.js +21 -4
  128. package/dist/admin/surfaces/feeds/feed-editor.js.map +1 -1
  129. package/dist/admin/surfaces/layouts/layout-editor-client.d.ts.map +1 -1
  130. package/dist/admin/surfaces/layouts/layout-editor-client.js +7 -4
  131. package/dist/admin/surfaces/layouts/layout-editor-client.js.map +1 -1
  132. package/dist/admin/surfaces/media/media-client.d.ts.map +1 -1
  133. package/dist/admin/surfaces/media/media-client.js +10 -2
  134. package/dist/admin/surfaces/media/media-client.js.map +1 -1
  135. package/dist/admin/surfaces/settings/settings-site.d.ts.map +1 -1
  136. package/dist/admin/surfaces/settings/settings-site.js +39 -2
  137. package/dist/admin/surfaces/settings/settings-site.js.map +1 -1
  138. package/dist/admin/surfaces/settings/settings-sites.js +18 -0
  139. package/dist/admin/surfaces/settings/settings-sites.js.map +1 -1
  140. package/dist/admin/surfaces/trash/trash-index.d.ts.map +1 -1
  141. package/dist/admin/surfaces/trash/trash-index.js +45 -8
  142. package/dist/admin/surfaces/trash/trash-index.js.map +1 -1
  143. package/dist/admin/surfaces/users/users-data.d.ts +11 -0
  144. package/dist/admin/surfaces/users/users-data.d.ts.map +1 -1
  145. package/dist/admin/surfaces/users/users-data.js +20 -1
  146. package/dist/admin/surfaces/users/users-data.js.map +1 -1
  147. package/dist/admin/surfaces/webServices/web-services-data.d.ts +11 -1
  148. package/dist/admin/surfaces/webServices/web-services-data.d.ts.map +1 -1
  149. package/dist/admin/surfaces/webServices/web-services-data.js +13 -0
  150. package/dist/admin/surfaces/webServices/web-services-data.js.map +1 -1
  151. package/dist/admin/surfaces/webServices/webhooks.d.ts +3 -0
  152. package/dist/admin/surfaces/webServices/webhooks.d.ts.map +1 -0
  153. package/dist/admin/surfaces/webServices/webhooks.js +69 -0
  154. package/dist/admin/surfaces/webServices/webhooks.js.map +1 -0
  155. package/dist/admin/webhook-manager.d.ts +32 -0
  156. package/dist/admin/webhook-manager.d.ts.map +1 -0
  157. package/dist/admin/webhook-manager.js +62 -0
  158. package/dist/admin/webhook-manager.js.map +1 -0
  159. package/dist/api/admin-features-routes.d.ts.map +1 -1
  160. package/dist/api/admin-features-routes.js +30 -0
  161. package/dist/api/admin-features-routes.js.map +1 -1
  162. package/dist/api/api-key-routes.d.ts.map +1 -1
  163. package/dist/api/api-key-routes.js +6 -1
  164. package/dist/api/api-key-routes.js.map +1 -1
  165. package/dist/api/auth.d.ts +8 -0
  166. package/dist/api/auth.d.ts.map +1 -1
  167. package/dist/api/auth.js +11 -1
  168. package/dist/api/auth.js.map +1 -1
  169. package/dist/api/comment-routes.d.ts.map +1 -1
  170. package/dist/api/comment-routes.js +102 -47
  171. package/dist/api/comment-routes.js.map +1 -1
  172. package/dist/api/config-routes.d.ts +10 -2
  173. package/dist/api/config-routes.d.ts.map +1 -1
  174. package/dist/api/config-routes.js +46 -25
  175. package/dist/api/config-routes.js.map +1 -1
  176. package/dist/api/content-routes.d.ts.map +1 -1
  177. package/dist/api/content-routes.js +41 -0
  178. package/dist/api/content-routes.js.map +1 -1
  179. package/dist/api/content-schemas.d.ts.map +1 -1
  180. package/dist/api/content-schemas.js +34 -1
  181. package/dist/api/content-schemas.js.map +1 -1
  182. package/dist/api/content-type-routes.d.ts.map +1 -1
  183. package/dist/api/content-type-routes.js +58 -3
  184. package/dist/api/content-type-routes.js.map +1 -1
  185. package/dist/api/feed-routes.d.ts +180 -0
  186. package/dist/api/feed-routes.d.ts.map +1 -1
  187. package/dist/api/feed-routes.js +10 -2
  188. package/dist/api/feed-routes.js.map +1 -1
  189. package/dist/api/form-routes.d.ts +6 -0
  190. package/dist/api/form-routes.d.ts.map +1 -1
  191. package/dist/api/form-routes.js +93 -14
  192. package/dist/api/form-routes.js.map +1 -1
  193. package/dist/api/graphql/resolvers.d.ts +4 -4
  194. package/dist/api/index.d.ts.map +1 -1
  195. package/dist/api/index.js +12 -1
  196. package/dist/api/index.js.map +1 -1
  197. package/dist/api/media-routes.d.ts.map +1 -1
  198. package/dist/api/media-routes.js +18 -1
  199. package/dist/api/media-routes.js.map +1 -1
  200. package/dist/api/webhook-routes.d.ts.map +1 -1
  201. package/dist/api/webhook-routes.js +19 -2
  202. package/dist/api/webhook-routes.js.map +1 -1
  203. package/dist/api/workflow-routes.d.ts.map +1 -1
  204. package/dist/api/workflow-routes.js +163 -4
  205. package/dist/api/workflow-routes.js.map +1 -1
  206. package/dist/auth/roles.d.ts +28 -0
  207. package/dist/auth/roles.d.ts.map +1 -1
  208. package/dist/auth/roles.js +49 -0
  209. package/dist/auth/roles.js.map +1 -1
  210. package/dist/config/reserved-field-names.d.ts +29 -0
  211. package/dist/config/reserved-field-names.d.ts.map +1 -0
  212. package/dist/config/reserved-field-names.js +59 -0
  213. package/dist/config/reserved-field-names.js.map +1 -0
  214. package/dist/config/types.d.ts +31 -2
  215. package/dist/config/types.d.ts.map +1 -1
  216. package/dist/config/types.js.map +1 -1
  217. package/dist/db/analytics-queries.d.ts +1 -1
  218. package/dist/db/api-key-queries.d.ts +7 -2
  219. package/dist/db/api-key-queries.d.ts.map +1 -1
  220. package/dist/db/api-key-queries.js +8 -2
  221. package/dist/db/api-key-queries.js.map +1 -1
  222. package/dist/db/apply-snapshot.d.ts +58 -0
  223. package/dist/db/apply-snapshot.d.ts.map +1 -0
  224. package/dist/db/apply-snapshot.js +142 -0
  225. package/dist/db/apply-snapshot.js.map +1 -0
  226. package/dist/db/audit-queries.d.ts +3 -3
  227. package/dist/db/category-queries.d.ts +3 -3
  228. package/dist/db/changeset-audit-queries.d.ts +2 -2
  229. package/dist/db/changeset-queries.d.ts +5 -5
  230. package/dist/db/changeset-queries.d.ts.map +1 -1
  231. package/dist/db/changeset-queries.js +24 -7
  232. package/dist/db/changeset-queries.js.map +1 -1
  233. package/dist/db/content-queries.d.ts +6 -0
  234. package/dist/db/content-queries.d.ts.map +1 -1
  235. package/dist/db/content-queries.js +8 -0
  236. package/dist/db/content-queries.js.map +1 -1
  237. package/dist/db/content-type-queries.d.ts +20 -0
  238. package/dist/db/content-type-queries.d.ts.map +1 -1
  239. package/dist/db/content-type-queries.js +32 -0
  240. package/dist/db/content-type-queries.js.map +1 -1
  241. package/dist/db/dashboard-queries.d.ts.map +1 -1
  242. package/dist/db/dashboard-queries.js +5 -1
  243. package/dist/db/dashboard-queries.js.map +1 -1
  244. package/dist/db/dynamic-schema.d.ts.map +1 -1
  245. package/dist/db/dynamic-schema.js +2 -0
  246. package/dist/db/dynamic-schema.js.map +1 -1
  247. package/dist/db/extension-queries.d.ts +8 -8
  248. package/dist/db/feed-queries.d.ts +3 -3
  249. package/dist/db/index.d.ts +3 -0
  250. package/dist/db/index.d.ts.map +1 -1
  251. package/dist/db/index.js +7 -0
  252. package/dist/db/index.js.map +1 -1
  253. package/dist/db/media-queries.d.ts +31 -7
  254. package/dist/db/media-queries.d.ts.map +1 -1
  255. package/dist/db/media-queries.js +13 -1
  256. package/dist/db/media-queries.js.map +1 -1
  257. package/dist/db/membership-dedupe.d.ts +26 -0
  258. package/dist/db/membership-dedupe.d.ts.map +1 -0
  259. package/dist/db/membership-dedupe.js +68 -0
  260. package/dist/db/membership-dedupe.js.map +1 -0
  261. package/dist/db/revision-queries.d.ts +122 -0
  262. package/dist/db/revision-queries.d.ts.map +1 -0
  263. package/dist/db/revision-queries.js +213 -0
  264. package/dist/db/revision-queries.js.map +1 -0
  265. package/dist/db/schema-apply.d.ts +8 -0
  266. package/dist/db/schema-apply.d.ts.map +1 -1
  267. package/dist/db/schema-apply.js +17 -0
  268. package/dist/db/schema-apply.js.map +1 -1
  269. package/dist/db/schema-field-queries.d.ts +2 -0
  270. package/dist/db/schema-field-queries.d.ts.map +1 -1
  271. package/dist/db/schema-field-queries.js +4 -0
  272. package/dist/db/schema-field-queries.js.map +1 -1
  273. package/dist/db/site-plugin-queries.d.ts +2 -2
  274. package/dist/db/user-queries.d.ts +12 -0
  275. package/dist/db/user-queries.d.ts.map +1 -1
  276. package/dist/db/user-queries.js +18 -4
  277. package/dist/db/user-queries.js.map +1 -1
  278. package/dist/db/version-queries.d.ts +37 -0
  279. package/dist/db/version-queries.d.ts.map +1 -1
  280. package/dist/db/version-queries.js +36 -0
  281. package/dist/db/version-queries.js.map +1 -1
  282. package/dist/db/webhook-queries.d.ts +27 -5
  283. package/dist/db/webhook-queries.d.ts.map +1 -1
  284. package/dist/db/webhook-queries.js +17 -0
  285. package/dist/db/webhook-queries.js.map +1 -1
  286. package/dist/db/workflow-queries.d.ts +2 -2
  287. package/dist/experiments/schema.d.ts +1 -1
  288. package/dist/hooks/index.d.ts +1 -1
  289. package/dist/hooks/index.d.ts.map +1 -1
  290. package/dist/hooks/index.js +1 -1
  291. package/dist/hooks/index.js.map +1 -1
  292. package/dist/hooks/webhook-retry.d.ts +22 -1
  293. package/dist/hooks/webhook-retry.d.ts.map +1 -1
  294. package/dist/hooks/webhook-retry.js +38 -1
  295. package/dist/hooks/webhook-retry.js.map +1 -1
  296. package/dist/host/index.d.ts +28 -0
  297. package/dist/host/index.d.ts.map +1 -1
  298. package/dist/host/index.js +56 -1
  299. package/dist/host/index.js.map +1 -1
  300. package/dist/layout/comments-module.d.ts +18 -0
  301. package/dist/layout/comments-module.d.ts.map +1 -0
  302. package/dist/layout/comments-module.js +130 -0
  303. package/dist/layout/comments-module.js.map +1 -0
  304. package/dist/layout/feed-hydration.d.ts +75 -0
  305. package/dist/layout/feed-hydration.d.ts.map +1 -0
  306. package/dist/layout/feed-hydration.js +158 -0
  307. package/dist/layout/feed-hydration.js.map +1 -0
  308. package/dist/layout/index.d.ts +2 -1
  309. package/dist/layout/index.d.ts.map +1 -1
  310. package/dist/layout/index.js +2 -1
  311. package/dist/layout/index.js.map +1 -1
  312. package/dist/layout/module-render-context.d.ts +13 -0
  313. package/dist/layout/module-render-context.d.ts.map +1 -0
  314. package/dist/layout/module-render-context.js +15 -0
  315. package/dist/layout/module-render-context.js.map +1 -0
  316. package/dist/layout/modules-extended.d.ts.map +1 -1
  317. package/dist/layout/modules-extended.js +92 -13
  318. package/dist/layout/modules-extended.js.map +1 -1
  319. package/dist/layout/registry.d.ts.map +1 -1
  320. package/dist/layout/registry.js +22 -6
  321. package/dist/layout/registry.js.map +1 -1
  322. package/dist/layout/renderer.d.ts +17 -1
  323. package/dist/layout/renderer.d.ts.map +1 -1
  324. package/dist/layout/renderer.js +11 -4
  325. package/dist/layout/renderer.js.map +1 -1
  326. package/dist/nav/index.d.ts +1 -0
  327. package/dist/nav/index.d.ts.map +1 -1
  328. package/dist/nav/index.js +4 -0
  329. package/dist/nav/index.js.map +1 -1
  330. package/dist/nav/url-resolver.d.ts +10 -2
  331. package/dist/nav/url-resolver.d.ts.map +1 -1
  332. package/dist/nav/url-resolver.js +17 -3
  333. package/dist/nav/url-resolver.js.map +1 -1
  334. package/dist/schema/base.d.ts +37 -1
  335. package/dist/schema/base.d.ts.map +1 -1
  336. package/dist/schema/base.js +20 -2
  337. package/dist/schema/base.js.map +1 -1
  338. package/dist/schema/generate.d.ts +8 -0
  339. package/dist/schema/generate.d.ts.map +1 -1
  340. package/dist/schema/generate.js +7 -4
  341. package/dist/schema/generate.js.map +1 -1
  342. package/dist/schema/mapper.d.ts.map +1 -1
  343. package/dist/schema/mapper.js +2 -0
  344. package/dist/schema/mapper.js.map +1 -1
  345. package/dist/schema/mysql-tables.d.ts +34 -0
  346. package/dist/schema/mysql-tables.d.ts.map +1 -1
  347. package/dist/schema/mysql-tables.js +14 -2
  348. package/dist/schema/mysql-tables.js.map +1 -1
  349. package/dist/server.d.ts +1 -0
  350. package/dist/server.d.ts.map +1 -1
  351. package/dist/server.js +1 -0
  352. package/dist/server.js.map +1 -1
  353. package/dist/site/styles.css +384 -0
  354. package/package.json +2 -1
@@ -0,0 +1,122 @@
1
+ import type { PgTableWithColumns } from 'drizzle-orm/pg-core';
2
+ import { type ContentWithCustomFields } from './content-queries.js';
3
+ import type { KywiDb } from './client.js';
4
+ /**
5
+ * Pending revisions (#42) — reviewing edits to already-published content without
6
+ * unpublishing the live version.
7
+ *
8
+ * The problem: an editor could only push edits to a live page by direct-publish;
9
+ * `published → pending` was a forbidden transition, and even if allowed it would
10
+ * pull the page off the live site (only `published` renders). There was no
11
+ * "draft of a published page under review" concept.
12
+ *
13
+ * The model, built entirely on the EXISTING kywi_content_versions table (no new
14
+ * table, no schema migration): a pending revision is a version row with
15
+ * `status = 'pending'` whose snapshot carries the {@link REVISION_MARKER} flag
16
+ * and the PROPOSED (edited) content. The live kywi_content row is never touched
17
+ * on submit, so the published page keeps serving its current content. The marker
18
+ * distinguishes an OUTSTANDING revision from the ordinary historical
19
+ * status='pending' snapshot the draft→pending→approve cycle also produces, so the
20
+ * approvals queue never confuses the two. On resolution the marked row is
21
+ * deleted, so "outstanding revision" == "a marked pending version exists".
22
+ */
23
+ /** Snapshot flag marking a version row as an outstanding pending revision. */
24
+ export declare const REVISION_MARKER = "__pendingRevision";
25
+ /** Return a copy of a revision snapshot with the internal marker removed. */
26
+ export declare function stripRevisionMarker(snapshot: Record<string, unknown>): Record<string, unknown>;
27
+ /** A pending-revision version joined with its live content, for the queue. */
28
+ export interface PendingRevisionRow {
29
+ versionId: string;
30
+ version: number;
31
+ contentId: string;
32
+ contentTypeName: string;
33
+ title: string;
34
+ siteId: string;
35
+ status: string;
36
+ createdBy: string | null;
37
+ createdAt: Date;
38
+ changeNote: string | null;
39
+ snapshot: Record<string, unknown>;
40
+ }
41
+ /**
42
+ * Create a pending revision: a version snapshot of the proposed content with the
43
+ * revision marker, status 'pending'. The live content row is deliberately NOT
44
+ * modified — the caller has already confirmed the content is published/approved
45
+ * and the point is that it keeps serving until approval.
46
+ *
47
+ * Uses createVersion directly (not recordContentVersion) so a pending revision is
48
+ * never pruned by the retention cap while it awaits review.
49
+ */
50
+ export declare function createPendingRevision(db: KywiDb, data: {
51
+ contentId: string;
52
+ siteId: string;
53
+ proposed: Record<string, unknown>;
54
+ changeNote?: string | undefined;
55
+ createdBy: string | null;
56
+ }): Promise<{
57
+ id: string;
58
+ siteId: string;
59
+ status: string;
60
+ createdAt: Date;
61
+ createdBy: string | null;
62
+ contentId: string;
63
+ version: number;
64
+ snapshot: unknown;
65
+ changeNote: string | null;
66
+ }>;
67
+ /**
68
+ * List outstanding pending revisions for a site — one row per revision version
69
+ * carrying the marker, joined to its (non-deleted) live content. Ordered newest
70
+ * first. Feeds the approvals queue alongside the plain status='pending' drafts.
71
+ */
72
+ export declare function listPendingRevisions(db: KywiDb, siteId: string): Promise<PendingRevisionRow[]>;
73
+ /**
74
+ * Fetch a single pending-revision version by id, validating it is a marked,
75
+ * still-pending revision belonging to `contentId`. Returns null otherwise (an
76
+ * already-resolved or non-revision version id).
77
+ */
78
+ export declare function getPendingRevision(db: KywiDb, contentId: string, versionId: string): Promise<{
79
+ id: string;
80
+ version: number;
81
+ siteId: string;
82
+ snapshot: Record<string, unknown>;
83
+ changeNote: string | null;
84
+ } | null>;
85
+ /**
86
+ * Approve a pending revision: apply its proposed snapshot onto the live content
87
+ * (publishing it), record a normal published version of the result, and delete
88
+ * the marked revision row so it leaves the queue. The live page transitions from
89
+ * its old content to the approved content in one step, staying published.
90
+ */
91
+ export declare function approvePendingRevision(db: KywiDb, opts: {
92
+ contentId: string;
93
+ versionId: string;
94
+ userId: string;
95
+ userEmail: string;
96
+ customTable: PgTableWithColumns<any> | null;
97
+ customFieldNames?: readonly string[];
98
+ }): Promise<{
99
+ success: boolean;
100
+ content?: ContentWithCustomFields;
101
+ error?: string;
102
+ }>;
103
+ /**
104
+ * Reject a pending revision: discard the proposed snapshot (delete the marked
105
+ * row) and record a version on the UNCHANGED live content whose changeNote is
106
+ * `Rejected: <reason>`. Recording it as a version (matching the draft-reject
107
+ * flow) is what surfaces the reason back to the editor — the edit screen reads
108
+ * the latest `Rejected:` version note. The live content is never modified.
109
+ */
110
+ export declare function rejectPendingRevision(db: KywiDb, opts: {
111
+ contentId: string;
112
+ versionId: string;
113
+ reason?: string | undefined;
114
+ userId: string;
115
+ userEmail: string;
116
+ customTable: PgTableWithColumns<any> | null;
117
+ }): Promise<{
118
+ success: boolean;
119
+ content?: ContentWithCustomFields;
120
+ error?: string;
121
+ }>;
122
+ //# sourceMappingURL=revision-queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revision-queries.d.ts","sourceRoot":"","sources":["../../src/db/revision-queries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,213 @@
1
+ import { eq, and, desc, sql } from 'drizzle-orm';
2
+ import { kywiContent, kywiContentVersions } from '../schema/base.js';
3
+ import { createVersion, getLatestVersionNumber, recordContentVersion } from './version-queries.js';
4
+ import { getContentById } from './content-queries.js';
5
+ import { applyContentSnapshot } from './apply-snapshot.js';
6
+ import { createAuditEntry } from './audit-queries.js';
7
+ /**
8
+ * Pending revisions (#42) — reviewing edits to already-published content without
9
+ * unpublishing the live version.
10
+ *
11
+ * The problem: an editor could only push edits to a live page by direct-publish;
12
+ * `published → pending` was a forbidden transition, and even if allowed it would
13
+ * pull the page off the live site (only `published` renders). There was no
14
+ * "draft of a published page under review" concept.
15
+ *
16
+ * The model, built entirely on the EXISTING kywi_content_versions table (no new
17
+ * table, no schema migration): a pending revision is a version row with
18
+ * `status = 'pending'` whose snapshot carries the {@link REVISION_MARKER} flag
19
+ * and the PROPOSED (edited) content. The live kywi_content row is never touched
20
+ * on submit, so the published page keeps serving its current content. The marker
21
+ * distinguishes an OUTSTANDING revision from the ordinary historical
22
+ * status='pending' snapshot the draft→pending→approve cycle also produces, so the
23
+ * approvals queue never confuses the two. On resolution the marked row is
24
+ * deleted, so "outstanding revision" == "a marked pending version exists".
25
+ */
26
+ /** Snapshot flag marking a version row as an outstanding pending revision. */
27
+ export const REVISION_MARKER = '__pendingRevision';
28
+ /** Return a copy of a revision snapshot with the internal marker removed. */
29
+ export function stripRevisionMarker(snapshot) {
30
+ const { [REVISION_MARKER]: _marker, ...rest } = snapshot;
31
+ return rest;
32
+ }
33
+ /**
34
+ * Create a pending revision: a version snapshot of the proposed content with the
35
+ * revision marker, status 'pending'. The live content row is deliberately NOT
36
+ * modified — the caller has already confirmed the content is published/approved
37
+ * and the point is that it keeps serving until approval.
38
+ *
39
+ * Uses createVersion directly (not recordContentVersion) so a pending revision is
40
+ * never pruned by the retention cap while it awaits review.
41
+ */
42
+ export async function createPendingRevision(db, data) {
43
+ const latest = await getLatestVersionNumber(db, data.contentId);
44
+ const snapshot = { ...data.proposed, [REVISION_MARKER]: true };
45
+ return createVersion(db, {
46
+ contentId: data.contentId,
47
+ siteId: data.siteId,
48
+ version: latest + 1,
49
+ snapshot,
50
+ status: 'pending',
51
+ createdBy: data.createdBy,
52
+ ...(data.changeNote !== undefined ? { changeNote: data.changeNote } : {}),
53
+ });
54
+ }
55
+ /**
56
+ * List outstanding pending revisions for a site — one row per revision version
57
+ * carrying the marker, joined to its (non-deleted) live content. Ordered newest
58
+ * first. Feeds the approvals queue alongside the plain status='pending' drafts.
59
+ */
60
+ export async function listPendingRevisions(db, siteId) {
61
+ const rows = await db
62
+ .select({
63
+ versionId: kywiContentVersions.id,
64
+ version: kywiContentVersions.version,
65
+ contentId: kywiContentVersions.contentId,
66
+ siteId: kywiContentVersions.siteId,
67
+ createdBy: kywiContentVersions.createdBy,
68
+ createdAt: kywiContentVersions.createdAt,
69
+ changeNote: kywiContentVersions.changeNote,
70
+ snapshot: kywiContentVersions.snapshot,
71
+ contentTypeName: kywiContent.contentTypeName,
72
+ title: kywiContent.title,
73
+ contentStatus: kywiContent.status,
74
+ })
75
+ .from(kywiContentVersions)
76
+ .innerJoin(kywiContent, eq(kywiContent.id, kywiContentVersions.contentId))
77
+ .where(and(eq(kywiContentVersions.siteId, siteId), eq(kywiContentVersions.status, 'pending'), sql `(${kywiContentVersions.snapshot} ->> ${REVISION_MARKER}) = 'true'`, sql `${kywiContent.deletedAt} IS NULL`))
78
+ .orderBy(desc(kywiContentVersions.createdAt));
79
+ return rows.map((r) => ({
80
+ versionId: r.versionId,
81
+ version: r.version,
82
+ contentId: r.contentId,
83
+ contentTypeName: r.contentTypeName,
84
+ title: r.title,
85
+ siteId: r.siteId,
86
+ status: r.contentStatus,
87
+ createdBy: r.createdBy ?? null,
88
+ createdAt: r.createdAt,
89
+ changeNote: r.changeNote ?? null,
90
+ snapshot: r.snapshot,
91
+ }));
92
+ }
93
+ /**
94
+ * Fetch a single pending-revision version by id, validating it is a marked,
95
+ * still-pending revision belonging to `contentId`. Returns null otherwise (an
96
+ * already-resolved or non-revision version id).
97
+ */
98
+ export async function getPendingRevision(db, contentId, versionId) {
99
+ const [row] = await db
100
+ .select()
101
+ .from(kywiContentVersions)
102
+ .where(eq(kywiContentVersions.id, versionId))
103
+ .limit(1);
104
+ if (!row)
105
+ return null;
106
+ if (row.contentId !== contentId)
107
+ return null;
108
+ if (row.status !== 'pending')
109
+ return null;
110
+ const snapshot = row.snapshot;
111
+ if (snapshot?.[REVISION_MARKER] !== true)
112
+ return null;
113
+ return {
114
+ id: row.id,
115
+ version: row.version,
116
+ siteId: row.siteId,
117
+ snapshot,
118
+ changeNote: row.changeNote ?? null,
119
+ };
120
+ }
121
+ /**
122
+ * Approve a pending revision: apply its proposed snapshot onto the live content
123
+ * (publishing it), record a normal published version of the result, and delete
124
+ * the marked revision row so it leaves the queue. The live page transitions from
125
+ * its old content to the approved content in one step, staying published.
126
+ */
127
+ export async function approvePendingRevision(db, opts) {
128
+ const revision = await getPendingRevision(db, opts.contentId, opts.versionId);
129
+ if (!revision)
130
+ return { success: false, error: 'Pending revision not found' };
131
+ const content = await db.transaction(async (rawTx) => {
132
+ const tx = rawTx;
133
+ const clean = stripRevisionMarker(revision.snapshot);
134
+ await applyContentSnapshot(tx, opts.contentId, clean, {
135
+ forceStatus: 'published',
136
+ userId: opts.userId,
137
+ customTable: opts.customTable,
138
+ customFieldNames: opts.customFieldNames ?? [],
139
+ });
140
+ // Remove the revision row first so the published version we record next is
141
+ // the highest version number (and the revision leaves the queue).
142
+ await tx.delete(kywiContentVersions).where(eq(kywiContentVersions.id, opts.versionId));
143
+ const applied = await getContentById(tx, opts.customTable, opts.contentId);
144
+ if (applied) {
145
+ await recordContentVersion(tx, {
146
+ contentId: opts.contentId,
147
+ siteId: revision.siteId,
148
+ snapshot: applied,
149
+ status: 'published',
150
+ createdBy: opts.userId,
151
+ changeNote: revision.changeNote
152
+ ? `Approved revision: ${revision.changeNote}`
153
+ : 'Approved revision',
154
+ });
155
+ }
156
+ await createAuditEntry(tx, {
157
+ siteId: revision.siteId,
158
+ contentId: opts.contentId,
159
+ action: 'approve',
160
+ fromStatus: 'published',
161
+ toStatus: 'published',
162
+ userId: opts.userId,
163
+ userEmail: opts.userEmail,
164
+ });
165
+ return applied;
166
+ });
167
+ const result = { success: true };
168
+ if (content)
169
+ result.content = content;
170
+ return result;
171
+ }
172
+ /**
173
+ * Reject a pending revision: discard the proposed snapshot (delete the marked
174
+ * row) and record a version on the UNCHANGED live content whose changeNote is
175
+ * `Rejected: <reason>`. Recording it as a version (matching the draft-reject
176
+ * flow) is what surfaces the reason back to the editor — the edit screen reads
177
+ * the latest `Rejected:` version note. The live content is never modified.
178
+ */
179
+ export async function rejectPendingRevision(db, opts) {
180
+ const revision = await getPendingRevision(db, opts.contentId, opts.versionId);
181
+ if (!revision)
182
+ return { success: false, error: 'Pending revision not found' };
183
+ const content = await db.transaction(async (rawTx) => {
184
+ const tx = rawTx;
185
+ await tx.delete(kywiContentVersions).where(eq(kywiContentVersions.id, opts.versionId));
186
+ const current = await getContentById(tx, opts.customTable, opts.contentId);
187
+ if (current) {
188
+ await recordContentVersion(tx, {
189
+ contentId: opts.contentId,
190
+ siteId: revision.siteId,
191
+ snapshot: current,
192
+ status: current.status ?? 'published',
193
+ createdBy: opts.userId,
194
+ changeNote: opts.reason !== undefined ? `Rejected: ${opts.reason}` : 'Rejected',
195
+ });
196
+ }
197
+ await createAuditEntry(tx, {
198
+ siteId: revision.siteId,
199
+ contentId: opts.contentId,
200
+ action: 'reject',
201
+ fromStatus: current?.status ?? 'published',
202
+ toStatus: current?.status ?? 'published',
203
+ userId: opts.userId,
204
+ userEmail: opts.userEmail,
205
+ });
206
+ return current;
207
+ });
208
+ const result = { success: true };
209
+ if (content)
210
+ result.content = content;
211
+ return result;
212
+ }
213
+ //# sourceMappingURL=revision-queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revision-queries.js","sourceRoot":"","sources":["../../src/db/revision-queries.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,14 @@ export interface SchemaDiff {
13
13
  export declare function diffFields(actualColumns: string[], desiredFields: FieldDefinition[]): SchemaDiff;
14
14
  /** Read actual column names for a table from information_schema. */
15
15
  export declare function getActualColumns(db: KywiDb, tableName: string): Promise<string[]>;
16
+ /**
17
+ * List every dynamic content-type table (`kywi_ct_*`) that physically exists in
18
+ * the public schema. Used by `migrate:generate` (#38) to compute which dynamic
19
+ * tables are orphans (present in the DB but backed by neither a config type nor
20
+ * a currently-registered admin type) so they can be excluded from the drizzle-kit
21
+ * diff instead of being offered for DROP.
22
+ */
23
+ export declare function listCustomContentTables(db: KywiDb): Promise<string[]>;
16
24
  /** Does a table exist in the public schema? */
17
25
  export declare function tableExists(db: KywiDb, tableName: string): Promise<boolean>;
18
26
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"schema-apply.d.ts","sourceRoot":"","sources":["../../src/db/schema-apply.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAGzD,MAAM,WAAW,UAAU;IACzB,6EAA6E;IAC7E,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,8GAA8G;IAC9G,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,UAAU,CAQhG;AAiCD,oEAAoE;AACpE,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASvF;AAED,+CAA+C;AAC/C,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOjF;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUlG;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAelE"}
1
+ {"version":3,"file":"schema-apply.d.ts","sourceRoot":"","sources":["../../src/db/schema-apply.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAGzD,MAAM,WAAW,UAAU;IACzB,6EAA6E;IAC7E,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,8GAA8G;IAC9G,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,UAAU,CAQhG;AAmCD,oEAAoE;AACpE,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASvF;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAO3E;AAED,+CAA+C;AAC/C,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOjF;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUlG;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAelE"}
@@ -17,9 +17,11 @@ function fieldTypeToSql(field) {
17
17
  case 'text':
18
18
  case 'richText':
19
19
  case 'textarea':
20
+ case 'url':
20
21
  return 'text';
21
22
  case 'select':
22
23
  case 'slug':
24
+ case 'email':
23
25
  return 'varchar(255)';
24
26
  case 'color':
25
27
  return 'varchar(7)';
@@ -52,6 +54,21 @@ export async function getActualColumns(db, tableName) {
52
54
  `);
53
55
  return rows.map((r) => r.column_name);
54
56
  }
57
+ /**
58
+ * List every dynamic content-type table (`kywi_ct_*`) that physically exists in
59
+ * the public schema. Used by `migrate:generate` (#38) to compute which dynamic
60
+ * tables are orphans (present in the DB but backed by neither a config type nor
61
+ * a currently-registered admin type) so they can be excluded from the drizzle-kit
62
+ * diff instead of being offered for DROP.
63
+ */
64
+ export async function listCustomContentTables(db) {
65
+ const rows = await db.execute(sql `
66
+ SELECT table_name FROM information_schema.tables
67
+ WHERE table_schema = 'public' AND table_name LIKE 'kywi\\_ct\\_%'
68
+ ORDER BY table_name
69
+ `);
70
+ return rows.map((r) => r.table_name);
71
+ }
55
72
  /** Does a table exist in the public schema? */
56
73
  export async function tableExists(db, tableName) {
57
74
  const rows = await db.execute(sql `
@@ -1 +1 @@
1
- {"version":3,"file":"schema-apply.js","sourceRoot":"","sources":["../../src/db/schema-apply.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema-apply.js","sourceRoot":"","sources":["../../src/db/schema-apply.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,8 @@ export interface AdminFieldInput {
8
8
  options?: string[] | undefined;
9
9
  required?: boolean | undefined;
10
10
  validation?: FieldValidation | undefined;
11
+ /** Target content type (or 'user') for a 'relationship' field (kywi-cms#12). */
12
+ relatedType?: string | undefined;
11
13
  sortOrder?: number | undefined;
12
14
  }
13
15
  /** Load admin-defined fields for one content type. */
@@ -1 +1 @@
1
- {"version":3,"file":"schema-field-queries.d.ts","sourceRoot":"","sources":["../../src/db/schema-field-queries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAE1E,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,MAAM,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IAC9B,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9B,UAAU,CAAC,EAAE,eAAe,GAAG,SAAS,CAAA;IACxC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC/B;AAgBD,sDAAsD;AACtD,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;AACtG,6DAA6D;AAC7D,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC,CAAA;AA4B1F,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBtF;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED,8FAA8F;AAC9F,wBAAsB,wBAAwB,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjG"}
1
+ {"version":3,"file":"schema-field-queries.d.ts","sourceRoot":"","sources":["../../src/db/schema-field-queries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAE1E,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,MAAM,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IAC9B,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9B,UAAU,CAAC,EAAE,eAAe,GAAG,SAAS,CAAA;IACxC,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC/B;AAkBD,sDAAsD;AACtD,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;AACtG,6DAA6D;AAC7D,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC,CAAA;AA4B1F,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BtF;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED,8FAA8F;AAC9F,wBAAsB,wBAAwB,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjG"}
@@ -3,6 +3,7 @@ import { kywiContentTypeFields } from '../schema/base.js';
3
3
  function rowToFieldDef(row) {
4
4
  const options = row.options ?? undefined;
5
5
  const validation = row.validation ?? undefined;
6
+ const relatedType = row.relatedType ?? undefined;
6
7
  return {
7
8
  name: row.name,
8
9
  type: row.type,
@@ -10,6 +11,7 @@ function rowToFieldDef(row) {
10
11
  required: row.required,
11
12
  ...(options !== undefined && { options }),
12
13
  ...(validation !== undefined && { validation }),
14
+ ...(relatedType !== undefined && { relatedType }),
13
15
  source: 'admin',
14
16
  };
15
17
  }
@@ -45,6 +47,7 @@ export async function saveAdminField(db, input) {
45
47
  options: input.options ?? null,
46
48
  required: input.required ?? false,
47
49
  validation: input.validation ?? null,
50
+ relatedType: input.relatedType ?? null,
48
51
  sortOrder: input.sortOrder ?? 0,
49
52
  })
50
53
  .onConflictDoUpdate({
@@ -55,6 +58,7 @@ export async function saveAdminField(db, input) {
55
58
  options: input.options ?? null,
56
59
  required: input.required ?? false,
57
60
  validation: input.validation ?? null,
61
+ relatedType: input.relatedType ?? null,
58
62
  sortOrder: input.sortOrder ?? 0,
59
63
  updatedAt: new Date(),
60
64
  },
@@ -1 +1 @@
1
- {"version":3,"file":"schema-field-queries.js","sourceRoot":"","sources":["../../src/db/schema-field-queries.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema-field-queries.js","sourceRoot":"","sources":["../../src/db/schema-field-queries.ts"],"names":[],"mappings":"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"}
@@ -7,9 +7,9 @@ export declare function activatePlugin(db: KywiDb, siteId: string, pluginPackage
7
7
  id: string;
8
8
  siteId: string;
9
9
  updatedAt: Date;
10
- config: unknown;
11
10
  createdAt: Date;
12
11
  isActive: boolean;
12
+ config: unknown;
13
13
  pluginPackage: string;
14
14
  }>;
15
15
  export declare function deactivatePlugin(db: KywiDb, siteId: string, pluginPackage: string): Promise<{
@@ -25,9 +25,9 @@ export declare function listPluginsForSite(db: KywiDb, siteId: string, activeOnl
25
25
  id: string;
26
26
  siteId: string;
27
27
  updatedAt: Date;
28
- config: unknown;
29
28
  createdAt: Date;
30
29
  isActive: boolean;
30
+ config: unknown;
31
31
  pluginPackage: string;
32
32
  }[]>;
33
33
  export declare function getPluginConfig(db: KywiDb, siteId: string, pluginPackage: string): Promise<Record<string, unknown> | null>;
@@ -19,6 +19,18 @@ export declare function getUserById(db: KywiDb, id: string): Promise<KywiUsersRo
19
19
  export declare function getUserGroups(db: KywiDb, userId: string): Promise<string[]>;
20
20
  /**
21
21
  * List users. If siteId is provided, return only users with a membership in that site.
22
+ *
23
+ * #40: this used to `innerJoin` kywi_site_memberships and filter on siteId —
24
+ * correct when a user has exactly one membership row for that site, but
25
+ * `kywi_site_memberships` has no uniqueness constraint on (userId, siteId), so
26
+ * a duplicate row (e.g. the New User form granting the same site twice — once
27
+ * implicitly via POST /users, once explicitly via POST /users/:id/sites/:sid)
28
+ * fanned the join out into one kywi_users row PER membership row, rendering
29
+ * the same user 2-3x in All Users, the ACL "Grant to → User" dropdown (both
30
+ * read this same query), and — downstream — the group-members panel (which
31
+ * filters this same user list by membership id). Filtering by an `IN`
32
+ * subquery instead of joining can never fan out kywi_users' own rows, no
33
+ * matter how many (or how few, post schema fix) membership rows exist.
22
34
  */
23
35
  export declare function listUsers(db: KywiDb, siteId?: string): Promise<KywiUsersRow[]>;
24
36
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"user-queries.d.ts","sourceRoot":"","sources":["../../src/db/user-queries.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGrD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,MAAM,CAAC,EACvC,UAAU,EAAE,MAAM,EAAE,GACnB,WAAW,CAMb;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAOtF;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOjF;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CASpF;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9E,OAAO,CAAC,YAAY,CAAC,CAYvB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC,GACpD,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMzE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE;IAAE,iBAAiB,EAAE,IAAI,GAAG,IAAI,CAAA;CAAE,EACxC,UAAU,EAAE,MAAM,GACjB,OAAO,CAIT"}
1
+ {"version":3,"file":"user-queries.d.ts","sourceRoot":"","sources":["../../src/db/user-queries.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGrD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,MAAM,CAAC,EACvC,UAAU,EAAE,MAAM,EAAE,GACnB,WAAW,CAMb;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAOtF;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOjF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBpF;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9E,OAAO,CAAC,YAAY,CAAC,CAYvB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC,GACpD,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMzE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE;IAAE,iBAAiB,EAAE,IAAI,GAAG,IAAI,CAAA;CAAE,EACxC,UAAU,EAAE,MAAM,GACjB,OAAO,CAIT"}
@@ -1,4 +1,4 @@
1
- import { eq, getTableColumns } from 'drizzle-orm';
1
+ import { eq, inArray } from 'drizzle-orm';
2
2
  import { kywiUsers, kywiUserGroups, kywiGroups, kywiSiteMemberships } from '../schema/base.js';
3
3
  import { hashPassword } from '../auth/passwords.js';
4
4
  /**
@@ -46,14 +46,28 @@ export async function getUserGroups(db, userId) {
46
46
  }
47
47
  /**
48
48
  * List users. If siteId is provided, return only users with a membership in that site.
49
+ *
50
+ * #40: this used to `innerJoin` kywi_site_memberships and filter on siteId —
51
+ * correct when a user has exactly one membership row for that site, but
52
+ * `kywi_site_memberships` has no uniqueness constraint on (userId, siteId), so
53
+ * a duplicate row (e.g. the New User form granting the same site twice — once
54
+ * implicitly via POST /users, once explicitly via POST /users/:id/sites/:sid)
55
+ * fanned the join out into one kywi_users row PER membership row, rendering
56
+ * the same user 2-3x in All Users, the ACL "Grant to → User" dropdown (both
57
+ * read this same query), and — downstream — the group-members panel (which
58
+ * filters this same user list by membership id). Filtering by an `IN`
59
+ * subquery instead of joining can never fan out kywi_users' own rows, no
60
+ * matter how many (or how few, post schema fix) membership rows exist.
49
61
  */
50
62
  export async function listUsers(db, siteId) {
51
63
  if (siteId) {
52
64
  return db
53
- .select(getTableColumns(kywiUsers))
65
+ .select()
54
66
  .from(kywiUsers)
55
- .innerJoin(kywiSiteMemberships, eq(kywiSiteMemberships.userId, kywiUsers.id))
56
- .where(eq(kywiSiteMemberships.siteId, siteId));
67
+ .where(inArray(kywiUsers.id, db
68
+ .select({ userId: kywiSiteMemberships.userId })
69
+ .from(kywiSiteMemberships)
70
+ .where(eq(kywiSiteMemberships.siteId, siteId))));
57
71
  }
58
72
  return db.select().from(kywiUsers);
59
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"user-queries.js","sourceRoot":"","sources":["../../src/db/user-queries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAI9F,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAuC,EACvC,UAAoB;IAEpB,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,UAAU;KACnB,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,EAAU,EACV,KAAa;IAEb,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE;SACpB,MAAM,EAAE;SACR,IAAI,CAAC,SAAS,CAAC;SACf,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SACjC,KAAK,CAAC,CAAC,CAAC,CAAA;IACX,OAAO,IAAI,IAAI,IAAI,CAAA;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAU,EAAE,EAAU;IACtD,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE;SACpB,MAAM,EAAE;SACR,IAAI,CAAC,SAAS,CAAC;SACf,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;SAC3B,KAAK,CAAC,CAAC,CAAC,CAAA;IACX,OAAO,IAAI,IAAI,IAAI,CAAA;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAU,EAAE,MAAc;IAC5D,MAAM,IAAI,GAAG,MAAM,EAAE;SAClB,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;SACjC,IAAI,CAAC,cAAc,CAAC;SACpB,SAAS,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;SAChE,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC3C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAU,EAAE,MAAe;IACzD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE;aACN,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;aAClC,IAAI,CAAC,SAAS,CAAC;aACf,SAAS,CAAC,mBAAmB,EAAE,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;aAC5E,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAClD,CAAC;IACD,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AACpC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,EAAU,EACV,IAA+E;IAE/E,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;IAC1C,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAA;IACjD,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE;SACpB,MAAM,CAAC,SAAS,CAAC;SACjB,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,CAAC;SACjC,SAAS,EAAE,CAAA;IACd,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IACnD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;IAC1E,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,EAAU,EACV,EAAU,EACV,IAAqD;IAErD,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE;SACpB,MAAM,CAAC,SAAS,CAAC;SACjB,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;SACvC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;SAC3B,SAAS,EAAE,CAAA;IACd,OAAO,IAAI,IAAI,IAAI,CAAA;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,EAAU,EAAE,EAAU;IACrD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE;SACnB,MAAM,CAAC,SAAS,CAAC;SACjB,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;SAC3B,SAAS,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAA;IAClC,OAAO,GAAG,KAAK,SAAS,CAAA;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAU,EAAE,EAAU;IAC1D,MAAM,EAAE;SACL,MAAM,CAAC,SAAS,CAAC;SACjB,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;SAChC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAwC,EACxC,UAAkB;IAElB,IAAI,CAAC,IAAI,CAAC,iBAAiB;QAAE,OAAO,IAAI,CAAA;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAA;IACzD,OAAO,GAAG,GAAG,UAAU,GAAG,QAAQ,CAAA;AACpC,CAAC"}
1
+ {"version":3,"file":"user-queries.js","sourceRoot":"","sources":["../../src/db/user-queries.ts"],"names":[],"mappings":"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"}