@xleddyl/nuxt-cms 0.9.4 → 0.10.1

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 (431) hide show
  1. package/README.md +1 -1
  2. package/dist/module.d.mts +20 -1
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +1037 -148
  5. package/dist/runtime/app/blocks/CmsBlocks.d.vue.ts +1 -1
  6. package/dist/runtime/app/blocks/CmsBlocks.vue +57 -9
  7. package/dist/runtime/app/blocks/CmsBlocks.vue.d.ts +1 -1
  8. package/dist/runtime/app/blocks/CmsField.d.ts +24 -0
  9. package/dist/runtime/app/blocks/CmsField.js +16 -0
  10. package/dist/runtime/app/blocks/node.d.ts +37 -0
  11. package/dist/runtime/app/blocks/node.js +17 -0
  12. package/dist/runtime/app/blocks/resolve.d.ts +18 -0
  13. package/dist/runtime/app/blocks/resolve.js +34 -0
  14. package/dist/runtime/app/components/cms/BlockPicker.d.vue.ts +22 -0
  15. package/dist/runtime/app/components/cms/BlockPicker.vue +87 -0
  16. package/dist/runtime/app/components/cms/BlockPicker.vue.d.ts +22 -0
  17. package/dist/runtime/app/components/cms/BlockPickerPopover.d.vue.ts +38 -0
  18. package/dist/runtime/app/components/cms/BlockPickerPopover.vue +44 -0
  19. package/dist/runtime/app/components/cms/BlockPickerPopover.vue.d.ts +38 -0
  20. package/dist/runtime/app/components/cms/BlockTree.d.vue.ts +29 -0
  21. package/dist/runtime/app/components/cms/BlockTree.vue +322 -0
  22. package/dist/runtime/app/components/cms/BlockTree.vue.d.ts +29 -0
  23. package/dist/runtime/app/components/cms/BlocksField.vue +569 -219
  24. package/dist/runtime/app/components/cms/BrandMark.vue +7 -13
  25. package/dist/runtime/app/components/cms/ConfirmGroups.vue +15 -13
  26. package/dist/runtime/app/components/cms/{BlockPalette.vue.d.ts → EditorHistory.d.vue.ts} +6 -5
  27. package/dist/runtime/app/components/cms/EditorHistory.vue +34 -0
  28. package/dist/runtime/app/components/cms/{BlockPalette.d.vue.ts → EditorHistory.vue.d.ts} +6 -5
  29. package/dist/runtime/app/components/cms/EntryDrawer.d.vue.ts +11 -5
  30. package/dist/runtime/app/components/cms/EntryDrawer.vue +183 -152
  31. package/dist/runtime/app/components/cms/EntryDrawer.vue.d.ts +11 -5
  32. package/dist/runtime/app/components/cms/EntryForm.d.vue.ts +16 -4
  33. package/dist/runtime/app/components/cms/EntryForm.vue +106 -147
  34. package/dist/runtime/app/components/cms/EntryForm.vue.d.ts +16 -4
  35. package/dist/runtime/app/components/cms/FieldInput.vue +10 -2
  36. package/dist/runtime/app/components/cms/FormSections.d.vue.ts +22 -0
  37. package/dist/runtime/app/components/cms/FormSections.vue +71 -0
  38. package/dist/runtime/app/components/cms/FormSections.vue.d.ts +22 -0
  39. package/dist/runtime/app/components/cms/ImportModal.vue +46 -58
  40. package/dist/runtime/app/components/cms/LinkField.d.vue.ts +16 -0
  41. package/dist/runtime/app/components/cms/LinkField.vue +250 -0
  42. package/dist/runtime/app/components/cms/LinkField.vue.d.ts +16 -0
  43. package/dist/runtime/app/components/cms/ListFilters.vue +10 -12
  44. package/dist/runtime/app/components/cms/LocaleSwitch.d.vue.ts +2 -1
  45. package/dist/runtime/app/components/cms/LocaleSwitch.vue +19 -11
  46. package/dist/runtime/app/components/cms/LocaleSwitch.vue.d.ts +2 -1
  47. package/dist/runtime/app/components/cms/MediaDetail.d.vue.ts +2 -0
  48. package/dist/runtime/app/components/cms/MediaDetail.vue +112 -83
  49. package/dist/runtime/app/components/cms/MediaDetail.vue.d.ts +2 -0
  50. package/dist/runtime/app/components/cms/MediaField.vue +35 -25
  51. package/dist/runtime/app/components/cms/MediaFolderPicker.vue +26 -71
  52. package/dist/runtime/app/components/cms/MediaGallery.d.vue.ts +1 -0
  53. package/dist/runtime/app/components/cms/MediaGallery.vue +442 -419
  54. package/dist/runtime/app/components/cms/MediaGallery.vue.d.ts +1 -0
  55. package/dist/runtime/app/components/cms/MediaThumb.vue +9 -25
  56. package/dist/runtime/app/components/cms/MediaUpload.vue +1 -1
  57. package/dist/runtime/app/components/cms/{BlockOutline.d.vue.ts → NestedBlockList.d.vue.ts} +5 -5
  58. package/dist/runtime/app/components/cms/NestedBlockList.vue +87 -0
  59. package/dist/runtime/app/components/cms/{BlockOutline.vue.d.ts → NestedBlockList.vue.d.ts} +5 -5
  60. package/dist/runtime/app/components/cms/PoweredBy.vue +12 -5
  61. package/dist/runtime/app/components/cms/PresetModal.d.vue.ts +18 -0
  62. package/dist/runtime/app/components/cms/PresetModal.vue +70 -0
  63. package/dist/runtime/app/components/cms/PresetModal.vue.d.ts +18 -0
  64. package/dist/runtime/app/components/cms/RelationField.vue +2 -8
  65. package/dist/runtime/app/components/cms/SettingsAccount.vue +60 -71
  66. package/dist/runtime/app/components/cms/SettingsColumns.vue +47 -69
  67. package/dist/runtime/app/components/cms/SettingsEmptyAdd.d.vue.ts +13 -0
  68. package/dist/runtime/app/components/cms/SettingsEmptyAdd.vue +21 -0
  69. package/dist/runtime/app/components/cms/SettingsEmptyAdd.vue.d.ts +13 -0
  70. package/dist/runtime/app/components/cms/SettingsEntries.d.vue.ts +13 -0
  71. package/dist/runtime/app/components/cms/SettingsEntries.vue +50 -0
  72. package/dist/runtime/app/components/cms/SettingsEntries.vue.d.ts +13 -0
  73. package/dist/runtime/app/components/cms/SettingsEntry.d.vue.ts +1 -10
  74. package/dist/runtime/app/components/cms/SettingsEntry.vue +11 -95
  75. package/dist/runtime/app/components/cms/SettingsEntry.vue.d.ts +1 -10
  76. package/dist/runtime/app/components/cms/SettingsEntryActions.d.vue.ts +7 -0
  77. package/dist/runtime/app/components/cms/SettingsEntryActions.vue +40 -0
  78. package/dist/runtime/app/components/cms/SettingsEntryActions.vue.d.ts +7 -0
  79. package/dist/runtime/app/components/cms/SettingsEntryTabs.d.vue.ts +7 -0
  80. package/dist/runtime/app/components/cms/SettingsEntryTabs.vue +21 -0
  81. package/dist/runtime/app/components/cms/SettingsEntryTabs.vue.d.ts +7 -0
  82. package/dist/runtime/app/components/cms/SettingsFormAction.d.vue.ts +3 -0
  83. package/dist/runtime/app/components/cms/SettingsFormAction.vue +17 -0
  84. package/dist/runtime/app/components/cms/SettingsFormAction.vue.d.ts +3 -0
  85. package/dist/runtime/app/components/cms/SettingsLayout.vue +18 -14
  86. package/dist/runtime/app/components/cms/SettingsPresetForm.d.vue.ts +11 -0
  87. package/dist/runtime/app/components/cms/SettingsPresetForm.vue +60 -0
  88. package/dist/runtime/app/components/cms/SettingsPresetForm.vue.d.ts +11 -0
  89. package/dist/runtime/app/components/cms/SettingsPresets.d.vue.ts +13 -0
  90. package/dist/runtime/app/components/cms/SettingsPresets.vue +65 -0
  91. package/dist/runtime/app/components/cms/SettingsPresets.vue.d.ts +13 -0
  92. package/dist/runtime/app/components/cms/SettingsRecordActions.d.vue.ts +32 -0
  93. package/dist/runtime/app/components/cms/SettingsRecordActions.vue +45 -0
  94. package/dist/runtime/app/components/cms/SettingsRecordActions.vue.d.ts +32 -0
  95. package/dist/runtime/app/components/cms/SettingsRedirectActions.d.vue.ts +3 -0
  96. package/dist/runtime/app/components/cms/SettingsRedirectActions.vue +59 -0
  97. package/dist/runtime/app/components/cms/SettingsRedirectActions.vue.d.ts +3 -0
  98. package/dist/runtime/app/components/cms/SettingsRedirectForm.d.vue.ts +11 -0
  99. package/dist/runtime/app/components/cms/SettingsRedirectForm.vue +77 -0
  100. package/dist/runtime/app/components/cms/SettingsRedirectForm.vue.d.ts +11 -0
  101. package/dist/runtime/app/components/cms/SettingsRedirects.d.vue.ts +13 -0
  102. package/dist/runtime/app/components/cms/SettingsRedirects.vue +117 -0
  103. package/dist/runtime/app/components/cms/SettingsRedirects.vue.d.ts +13 -0
  104. package/dist/runtime/app/components/cms/SettingsSecretCard.d.vue.ts +17 -0
  105. package/dist/runtime/app/components/cms/SettingsSecretCard.vue +43 -0
  106. package/dist/runtime/app/components/cms/SettingsSecretCard.vue.d.ts +17 -0
  107. package/dist/runtime/app/components/cms/SettingsSite.d.vue.ts +3 -0
  108. package/dist/runtime/app/components/cms/SettingsSite.vue +140 -0
  109. package/dist/runtime/app/components/cms/SettingsSite.vue.d.ts +3 -0
  110. package/dist/runtime/app/components/cms/SettingsUserCreate.d.vue.ts +8 -0
  111. package/dist/runtime/app/components/cms/SettingsUserCreate.vue +82 -0
  112. package/dist/runtime/app/components/cms/SettingsUserCreate.vue.d.ts +8 -0
  113. package/dist/runtime/app/components/cms/SettingsUserDetail.d.vue.ts +11 -0
  114. package/dist/runtime/app/components/cms/SettingsUserDetail.vue +179 -0
  115. package/dist/runtime/app/components/cms/SettingsUserDetail.vue.d.ts +11 -0
  116. package/dist/runtime/app/components/cms/SettingsUsers.d.vue.ts +9 -6
  117. package/dist/runtime/app/components/cms/SettingsUsers.vue +88 -234
  118. package/dist/runtime/app/components/cms/SettingsUsers.vue.d.ts +9 -6
  119. package/dist/runtime/app/components/cms/SharePreview.d.vue.ts +18 -0
  120. package/dist/runtime/app/components/cms/SharePreview.vue +219 -0
  121. package/dist/runtime/app/components/cms/SharePreview.vue.d.ts +18 -0
  122. package/dist/runtime/app/components/cms/SlugField.vue +5 -3
  123. package/dist/runtime/app/components/cms/StatusBadge.vue +8 -8
  124. package/dist/runtime/app/components/cms/TranslationBadges.d.vue.ts +7 -0
  125. package/dist/runtime/app/components/cms/TranslationBadges.vue +44 -0
  126. package/dist/runtime/app/components/cms/TranslationBadges.vue.d.ts +7 -0
  127. package/dist/runtime/app/components/cms/TranslationMenu.d.vue.ts +17 -0
  128. package/dist/runtime/app/components/cms/TranslationMenu.vue +28 -0
  129. package/dist/runtime/app/components/cms/TranslationMenu.vue.d.ts +17 -0
  130. package/dist/runtime/app/components/cms/VisualEditor.d.vue.ts +22 -4
  131. package/dist/runtime/app/components/cms/VisualEditor.vue +1153 -338
  132. package/dist/runtime/app/components/cms/VisualEditor.vue.d.ts +22 -4
  133. package/dist/runtime/app/components/cms/WelcomeModal.vue +32 -50
  134. package/dist/runtime/app/composables/cms-clipboard.d.ts +8 -0
  135. package/dist/runtime/app/composables/cms-clipboard.js +38 -0
  136. package/dist/runtime/app/composables/cms-confirm.d.ts +6 -8
  137. package/dist/runtime/app/composables/cms-confirm.js +5 -7
  138. package/dist/runtime/app/composables/cms-entry-disabled.d.ts +5 -1
  139. package/dist/runtime/app/composables/cms-entry-disabled.js +7 -0
  140. package/dist/runtime/app/composables/cms-entry-form.d.ts +15 -0
  141. package/dist/runtime/app/composables/cms-entry-form.js +40 -0
  142. package/dist/runtime/app/composables/cms-entry-settings.d.ts +30 -0
  143. package/dist/runtime/app/composables/cms-entry-settings.js +122 -0
  144. package/dist/runtime/app/composables/cms-entry.d.ts +5 -1
  145. package/dist/runtime/app/composables/cms-entry.js +36 -11
  146. package/dist/runtime/app/composables/cms-history.d.ts +10 -0
  147. package/dist/runtime/app/composables/cms-history.js +24 -0
  148. package/dist/runtime/app/composables/cms-link-targets.d.ts +10 -0
  149. package/dist/runtime/app/composables/cms-link-targets.js +40 -0
  150. package/dist/runtime/app/composables/cms-link-usage.d.ts +1 -0
  151. package/dist/runtime/app/composables/cms-link-usage.js +45 -0
  152. package/dist/runtime/app/composables/cms-media-library.d.ts +19 -9
  153. package/dist/runtime/app/composables/cms-media-library.js +31 -13
  154. package/dist/runtime/app/composables/cms-media-uploader.js +6 -20
  155. package/dist/runtime/app/composables/cms-permissions.d.ts +18 -0
  156. package/dist/runtime/app/composables/cms-permissions.js +54 -0
  157. package/dist/runtime/app/composables/cms-presets.d.ts +11 -0
  158. package/dist/runtime/app/composables/cms-presets.js +40 -0
  159. package/dist/runtime/app/composables/cms-preview-mode.d.ts +4 -0
  160. package/dist/runtime/app/composables/cms-preview-mode.js +8 -0
  161. package/dist/runtime/app/composables/cms-query.d.ts +3 -0
  162. package/dist/runtime/app/composables/cms-query.js +45 -20
  163. package/dist/runtime/app/composables/cms-record-list.d.ts +31 -0
  164. package/dist/runtime/app/composables/cms-record-list.js +75 -0
  165. package/dist/runtime/app/composables/cms-route.d.ts +6 -0
  166. package/dist/runtime/app/composables/cms-route.js +36 -0
  167. package/dist/runtime/app/composables/cms-runtime.d.ts +1 -0
  168. package/dist/runtime/app/composables/cms-save-handoff.d.ts +4 -0
  169. package/dist/runtime/app/composables/cms-save-handoff.js +19 -0
  170. package/dist/runtime/app/composables/cms-seo.d.ts +12 -0
  171. package/dist/runtime/app/composables/cms-seo.js +69 -0
  172. package/dist/runtime/app/composables/cms-settings-form.d.ts +13 -0
  173. package/dist/runtime/app/composables/cms-settings-form.js +29 -0
  174. package/dist/runtime/app/composables/cms-settings-sections.d.ts +26 -0
  175. package/dist/runtime/app/composables/cms-settings-sections.js +181 -0
  176. package/dist/runtime/app/composables/cms-settings-stores.d.ts +52 -0
  177. package/dist/runtime/app/composables/cms-settings-stores.js +156 -0
  178. package/dist/runtime/app/composables/cms-settings.d.ts +3 -3
  179. package/dist/runtime/app/composables/cms-settings.js +14 -8
  180. package/dist/runtime/app/composables/cms-site-disabled.d.ts +7 -0
  181. package/dist/runtime/app/composables/cms-site-disabled.js +8 -0
  182. package/dist/runtime/app/composables/cms-site.d.ts +7 -0
  183. package/dist/runtime/app/composables/cms-site.js +22 -0
  184. package/dist/runtime/app/composables/cms-toast.d.ts +2 -8
  185. package/dist/runtime/app/composables/cms-toast.js +3 -9
  186. package/dist/runtime/app/composables/cms-translation-actions.d.ts +15 -0
  187. package/dist/runtime/app/composables/cms-translation-actions.js +108 -0
  188. package/dist/runtime/app/css-url.d.ts +4 -0
  189. package/dist/runtime/app/image/CmsImage.d.vue.ts +89 -0
  190. package/dist/runtime/app/image/CmsImage.vue +91 -0
  191. package/dist/runtime/app/image/CmsImage.vue.d.ts +89 -0
  192. package/dist/runtime/app/layouts/cms-admin.d.vue.ts +2 -2
  193. package/dist/runtime/app/layouts/cms-admin.vue +98 -76
  194. package/dist/runtime/app/layouts/cms-admin.vue.d.ts +2 -2
  195. package/dist/runtime/app/layouts/cms-editor.vue +7 -2
  196. package/dist/runtime/app/links/CmsLink.d.vue.ts +18 -0
  197. package/dist/runtime/app/links/CmsLink.vue +18 -0
  198. package/dist/runtime/app/links/CmsLink.vue.d.ts +18 -0
  199. package/dist/runtime/app/middleware/cms-auth.js +13 -1
  200. package/dist/runtime/app/pages/admin-collection.vue +473 -297
  201. package/dist/runtime/app/pages/admin-content.vue +191 -54
  202. package/dist/runtime/app/pages/admin-entry.vue +79 -75
  203. package/dist/runtime/app/pages/admin-index.vue +18 -5
  204. package/dist/runtime/app/pages/admin-login.vue +1 -1
  205. package/dist/runtime/app/pages/admin-logout.vue +1 -1
  206. package/dist/runtime/app/pages/admin-media.vue +3 -3
  207. package/dist/runtime/app/pages/admin-preview.vue +112 -24
  208. package/dist/runtime/app/plugins/cms-field.d.ts +2 -0
  209. package/dist/runtime/app/plugins/cms-field.js +8 -0
  210. package/dist/runtime/app/plugins/cms-preview-banner.client.d.ts +2 -0
  211. package/dist/runtime/app/plugins/cms-preview-banner.client.js +19 -0
  212. package/dist/runtime/app/plugins/cms-preview.d.ts +2 -0
  213. package/dist/runtime/app/plugins/cms-preview.js +27 -0
  214. package/dist/runtime/app/preview/CmsPreviewBanner.d.vue.ts +7 -0
  215. package/dist/runtime/app/preview/CmsPreviewBanner.vue +63 -0
  216. package/dist/runtime/app/preview/CmsPreviewBanner.vue.d.ts +7 -0
  217. package/dist/runtime/app/preview/PreviewOverlay.d.vue.ts +17 -3
  218. package/dist/runtime/app/preview/PreviewOverlay.vue +629 -166
  219. package/dist/runtime/app/preview/PreviewOverlay.vue.d.ts +17 -3
  220. package/dist/runtime/app/preview/field-marker.d.ts +12 -0
  221. package/dist/runtime/app/preview/field-marker.js +20 -0
  222. package/dist/runtime/app/preview/inline-text.d.ts +15 -0
  223. package/dist/runtime/app/preview/inline-text.js +158 -0
  224. package/dist/runtime/app/utils/block-editor.d.ts +22 -0
  225. package/dist/runtime/app/utils/block-editor.js +12 -0
  226. package/dist/runtime/app/utils/keyboard.d.ts +6 -0
  227. package/dist/runtime/app/utils/keyboard.js +52 -0
  228. package/dist/runtime/app/utils/redirects.d.ts +6 -0
  229. package/dist/runtime/app/utils/redirects.js +7 -0
  230. package/dist/runtime/app/utils/ui.d.ts +8 -0
  231. package/dist/runtime/app/utils/ui.js +15 -1
  232. package/dist/runtime/app/utils/users.d.ts +15 -0
  233. package/dist/runtime/app/utils/users.js +14 -0
  234. package/dist/runtime/assets/cms.css +1 -1
  235. package/dist/runtime/generate.js +16 -2
  236. package/dist/runtime/server/api/collection-export.get.js +3 -2
  237. package/dist/runtime/server/api/collection-import.post.js +39 -11
  238. package/dist/runtime/server/api/collection.get.js +27 -9
  239. package/dist/runtime/server/api/collection.post.js +28 -11
  240. package/dist/runtime/server/api/collection.put.js +35 -13
  241. package/dist/runtime/server/api/item.delete.js +19 -7
  242. package/dist/runtime/server/api/item.get.js +3 -2
  243. package/dist/runtime/server/api/item.put.js +52 -18
  244. package/dist/runtime/server/api/link-usage.post.d.ts +5 -0
  245. package/dist/runtime/server/api/link-usage.post.js +21 -0
  246. package/dist/runtime/server/api/media-delete.post.js +4 -2
  247. package/dist/runtime/server/api/media-download.get.js +2 -2
  248. package/dist/runtime/server/api/media-folder.delete.js +8 -2
  249. package/dist/runtime/server/api/media-folder.patch.js +10 -2
  250. package/dist/runtime/server/api/media-folder.post.js +4 -2
  251. package/dist/runtime/server/api/media-move.post.js +7 -4
  252. package/dist/runtime/server/api/media-presign.post.js +2 -2
  253. package/dist/runtime/server/api/media-upload.put.js +2 -2
  254. package/dist/runtime/server/api/media-usage.post.d.ts +2 -4
  255. package/dist/runtime/server/api/media-usage.post.js +13 -9
  256. package/dist/runtime/server/api/media.delete.js +4 -2
  257. package/dist/runtime/server/api/media.get.js +22 -7
  258. package/dist/runtime/server/api/media.post.js +4 -2
  259. package/dist/runtime/server/api/media.put.js +33 -16
  260. package/dist/runtime/server/api/preset.delete.d.ts +4 -0
  261. package/dist/runtime/server/api/preset.delete.js +9 -0
  262. package/dist/runtime/server/api/preset.put.d.ts +3 -0
  263. package/dist/runtime/server/api/preset.put.js +23 -0
  264. package/dist/runtime/server/api/presets-field.get.d.ts +3 -0
  265. package/dist/runtime/server/api/presets-field.get.js +13 -0
  266. package/dist/runtime/server/api/presets-field.post.d.ts +3 -0
  267. package/dist/runtime/server/api/presets-field.post.js +36 -0
  268. package/dist/runtime/server/api/presets.get.d.ts +3 -0
  269. package/dist/runtime/server/api/presets.get.js +7 -0
  270. package/dist/runtime/server/api/preview-link.delete.d.ts +4 -0
  271. package/dist/runtime/server/api/preview-link.delete.js +15 -0
  272. package/dist/runtime/server/api/preview-links.get.d.ts +3 -0
  273. package/dist/runtime/server/api/preview-links.get.js +10 -0
  274. package/dist/runtime/server/api/preview-links.post.d.ts +3 -0
  275. package/dist/runtime/server/api/preview-links.post.js +17 -0
  276. package/dist/runtime/server/api/preview.get.d.ts +3 -0
  277. package/dist/runtime/server/api/preview.get.js +7 -0
  278. package/dist/runtime/server/api/redirect.delete.d.ts +4 -0
  279. package/dist/runtime/server/api/redirect.delete.js +10 -0
  280. package/dist/runtime/server/api/redirect.put.d.ts +3 -0
  281. package/dist/runtime/server/api/redirect.put.js +8 -0
  282. package/dist/runtime/server/api/redirects-import.post.d.ts +3 -0
  283. package/dist/runtime/server/api/redirects-import.post.js +13 -0
  284. package/dist/runtime/server/api/redirects.get.d.ts +3 -0
  285. package/dist/runtime/server/api/redirects.get.js +7 -0
  286. package/dist/runtime/server/api/redirects.post.d.ts +3 -0
  287. package/dist/runtime/server/api/redirects.post.js +7 -0
  288. package/dist/runtime/server/api/search.get.js +8 -3
  289. package/dist/runtime/server/api/settings.delete.js +2 -2
  290. package/dist/runtime/server/api/settings.get.js +4 -2
  291. package/dist/runtime/server/api/settings.put.js +2 -2
  292. package/dist/runtime/server/api/site.get.d.ts +3 -0
  293. package/dist/runtime/server/api/site.get.js +7 -0
  294. package/dist/runtime/server/api/site.put.d.ts +3 -0
  295. package/dist/runtime/server/api/site.put.js +16 -0
  296. package/dist/runtime/server/api/tags.get.js +3 -2
  297. package/dist/runtime/server/api/user.delete.js +8 -2
  298. package/dist/runtime/server/api/user.put.js +14 -4
  299. package/dist/runtime/server/api/users.get.js +2 -2
  300. package/dist/runtime/server/api/users.post.js +8 -4
  301. package/dist/runtime/server/middleware/hidden-site.d.ts +2 -0
  302. package/dist/runtime/server/middleware/hidden-site.js +8 -0
  303. package/dist/runtime/server/middleware/preview-links.d.ts +2 -0
  304. package/dist/runtime/server/middleware/preview-links.js +6 -0
  305. package/dist/runtime/server/middleware/redirects.d.ts +2 -0
  306. package/dist/runtime/server/middleware/redirects.js +18 -0
  307. package/dist/runtime/server/plugins/session-validate.js +4 -1
  308. package/dist/runtime/server/plugins/webhooks.d.ts +3 -0
  309. package/dist/runtime/server/plugins/webhooks.js +27 -0
  310. package/dist/runtime/server/routes/graphql.js +5 -3
  311. package/dist/runtime/server/routes/robots.d.ts +2 -0
  312. package/dist/runtime/server/routes/robots.js +16 -0
  313. package/dist/runtime/server/routes/sitemap.d.ts +2 -0
  314. package/dist/runtime/server/routes/sitemap.js +67 -0
  315. package/dist/runtime/server/utils/cached-value.d.ts +5 -0
  316. package/dist/runtime/server/utils/cached-value.js +24 -0
  317. package/dist/runtime/server/utils/content-routes.d.ts +5 -0
  318. package/dist/runtime/server/utils/content-routes.js +29 -0
  319. package/dist/runtime/server/utils/field-rules.d.ts +19 -0
  320. package/dist/runtime/server/utils/field-rules.js +72 -0
  321. package/dist/runtime/server/utils/graphql.d.ts +3 -1
  322. package/dist/runtime/server/utils/graphql.js +143 -28
  323. package/dist/runtime/server/utils/hooks.d.ts +14 -0
  324. package/dist/runtime/server/utils/hooks.js +71 -0
  325. package/dist/runtime/server/utils/import.d.ts +7 -2
  326. package/dist/runtime/server/utils/import.js +108 -14
  327. package/dist/runtime/server/utils/link-usage.d.ts +4 -0
  328. package/dist/runtime/server/utils/link-usage.js +28 -0
  329. package/dist/runtime/server/utils/media-references.d.ts +6 -1
  330. package/dist/runtime/server/utils/media-references.js +49 -20
  331. package/dist/runtime/server/utils/media-usage.d.ts +2 -0
  332. package/dist/runtime/server/utils/media-usage.js +5 -3
  333. package/dist/runtime/server/utils/page-rows.d.ts +2 -0
  334. package/dist/runtime/server/utils/page-rows.js +42 -29
  335. package/dist/runtime/server/utils/permissions.d.ts +14 -0
  336. package/dist/runtime/server/utils/permissions.js +43 -0
  337. package/dist/runtime/server/utils/presets.d.ts +18 -0
  338. package/dist/runtime/server/utils/presets.js +68 -0
  339. package/dist/runtime/server/utils/preview-links.d.ts +207 -0
  340. package/dist/runtime/server/utils/preview-links.js +161 -0
  341. package/dist/runtime/server/utils/redirects.d.ts +31 -0
  342. package/dist/runtime/server/utils/redirects.js +240 -0
  343. package/dist/runtime/server/utils/registry.js +4 -1
  344. package/dist/runtime/server/utils/relations.d.ts +8 -0
  345. package/dist/runtime/server/utils/relations.js +25 -6
  346. package/dist/runtime/server/utils/require-admin.d.ts +0 -1
  347. package/dist/runtime/server/utils/require-admin.js +4 -8
  348. package/dist/runtime/server/utils/search.d.ts +1 -0
  349. package/dist/runtime/server/utils/search.js +44 -19
  350. package/dist/runtime/server/utils/site.d.ts +23 -0
  351. package/dist/runtime/server/utils/site.js +79 -0
  352. package/dist/runtime/server/utils/sitemap.d.ts +12 -0
  353. package/dist/runtime/server/utils/sitemap.js +109 -0
  354. package/dist/runtime/server/utils/user-management.d.ts +4 -0
  355. package/dist/runtime/server/utils/user-management.js +20 -0
  356. package/dist/runtime/server/utils/users.d.ts +1 -1
  357. package/dist/runtime/server/utils/users.js +1 -1
  358. package/dist/runtime/server/utils/visibility.d.ts +1 -0
  359. package/dist/runtime/server/utils/visibility.js +6 -1
  360. package/dist/runtime/server/utils/webhooks.d.ts +24 -0
  361. package/dist/runtime/server/utils/webhooks.js +90 -0
  362. package/dist/runtime/shared/block-paths.d.ts +66 -0
  363. package/dist/runtime/shared/block-paths.js +310 -0
  364. package/dist/runtime/shared/block-picker.d.ts +18 -0
  365. package/dist/runtime/shared/block-picker.js +31 -0
  366. package/dist/runtime/shared/block-signature.d.ts +4 -0
  367. package/dist/runtime/shared/block-signature.js +46 -0
  368. package/dist/runtime/shared/clipboard.d.ts +31 -0
  369. package/dist/runtime/shared/clipboard.js +206 -0
  370. package/dist/runtime/shared/conditions.d.ts +36 -0
  371. package/dist/runtime/shared/conditions.js +100 -0
  372. package/dist/runtime/shared/content-routes.d.ts +42 -0
  373. package/dist/runtime/shared/content-routes.js +237 -0
  374. package/dist/runtime/shared/duplicate.js +2 -1
  375. package/dist/runtime/shared/editor-layout.d.ts +18 -0
  376. package/dist/runtime/shared/editor-layout.js +9 -0
  377. package/dist/runtime/shared/field-options.d.ts +21 -0
  378. package/dist/runtime/shared/field-options.js +90 -0
  379. package/dist/runtime/shared/graphql-sdl.d.ts +1 -0
  380. package/dist/runtime/shared/graphql-sdl.js +50 -26
  381. package/dist/runtime/shared/history.d.ts +27 -0
  382. package/dist/runtime/shared/history.js +123 -0
  383. package/dist/runtime/shared/hooks.d.ts +45 -0
  384. package/dist/runtime/shared/hooks.js +28 -0
  385. package/dist/runtime/shared/index.d.ts +90 -21
  386. package/dist/runtime/shared/index.js +121 -37
  387. package/dist/runtime/shared/inline-text.d.ts +38 -0
  388. package/dist/runtime/shared/inline-text.js +85 -0
  389. package/dist/runtime/shared/layout.d.ts +2 -1
  390. package/dist/runtime/shared/layout.js +3 -0
  391. package/dist/runtime/shared/links.d.ts +48 -0
  392. package/dist/runtime/shared/links.js +155 -0
  393. package/dist/runtime/shared/list-filters.d.ts +2 -0
  394. package/dist/runtime/shared/list-filters.js +2 -0
  395. package/dist/runtime/shared/media-focal.d.ts +30 -0
  396. package/dist/runtime/shared/media-focal.js +52 -0
  397. package/dist/runtime/shared/migrations-dir.d.ts +14 -0
  398. package/dist/runtime/shared/migrations-dir.js +48 -2
  399. package/dist/runtime/shared/presets.d.ts +67 -0
  400. package/dist/runtime/shared/presets.js +127 -0
  401. package/dist/runtime/shared/preview-links.d.ts +64 -0
  402. package/dist/runtime/shared/preview-links.js +54 -0
  403. package/dist/runtime/shared/preview.d.ts +124 -21
  404. package/dist/runtime/shared/preview.js +419 -81
  405. package/dist/runtime/shared/redirects.d.ts +75 -0
  406. package/dist/runtime/shared/redirects.js +230 -0
  407. package/dist/runtime/shared/roles.d.ts +57 -0
  408. package/dist/runtime/shared/roles.js +293 -0
  409. package/dist/runtime/shared/save-state.d.ts +8 -0
  410. package/dist/runtime/shared/save-state.js +15 -0
  411. package/dist/runtime/shared/search.d.ts +16 -1
  412. package/dist/runtime/shared/search.js +41 -7
  413. package/dist/runtime/shared/seo.d.ts +167 -0
  414. package/dist/runtime/shared/seo.js +335 -0
  415. package/dist/runtime/shared/transfer.js +2 -1
  416. package/dist/runtime/shared/translations.d.ts +29 -0
  417. package/dist/runtime/shared/translations.js +123 -0
  418. package/dist/runtime/shared/users.d.ts +1 -1
  419. package/dist/runtime/shared/validation.d.ts +23 -1
  420. package/dist/runtime/shared/validation.js +214 -64
  421. package/dist/runtime/webhooks.d.ts +33 -0
  422. package/dist/runtime/webhooks.js +57 -0
  423. package/dist/types.d.mts +5 -1
  424. package/package.json +6 -2
  425. package/dist/runtime/app/components/cms/BlockOutline.vue +0 -88
  426. package/dist/runtime/app/components/cms/BlockPalette.vue +0 -31
  427. package/dist/runtime/app/components/cms/SettingsModal.d.vue.ts +0 -12
  428. package/dist/runtime/app/components/cms/SettingsModal.vue +0 -126
  429. package/dist/runtime/app/components/cms/SettingsModal.vue.d.ts +0 -12
  430. package/dist/runtime/app/composables/cms-field-focus.d.ts +0 -4
  431. package/dist/runtime/app/composables/cms-field-focus.js +0 -20
@@ -3,10 +3,11 @@ import { z } from "zod";
3
3
  import { normalizeMediaFolder } from "../../shared/index.js";
4
4
  import { useMediaStorage } from "../utils/media.js";
5
5
  import { writeMediaFolderMarker } from "../utils/media-folders.js";
6
- import { requireAdmin } from "../utils/require-admin.js";
6
+ import { emitMediaChange } from "../utils/hooks.js";
7
+ import { requireCmsPermission } from "../utils/permissions.js";
7
8
  const bodySchema = z.object({ name: z.string().min(1).max(255) });
8
9
  export default defineEventHandler(async (event) => {
9
- await requireAdmin(event);
10
+ const { user } = await requireCmsPermission(event, "media.write");
10
11
  const { store } = useMediaStorage(event);
11
12
  const { name } = await readValidatedBody(event, bodySchema.parse);
12
13
  const folder = normalizeMediaFolder(name);
@@ -14,5 +15,6 @@ export default defineEventHandler(async (event) => {
14
15
  throw createError({ statusCode: 400, statusMessage: "Invalid folder name" });
15
16
  }
16
17
  await writeMediaFolderMarker(store, folder);
18
+ emitMediaChange(event, user, { action: "folder-create", keys: [], folder });
17
19
  return { folder };
18
20
  });
@@ -7,13 +7,14 @@ import { MEDIA_FOLDER_MARKER, normalizeMediaFolder } from "../../shared/index.js
7
7
  import { objectKeySchema } from "../../shared/validation.js";
8
8
  import { useMediaStorage } from "../utils/media.js";
9
9
  import { keyChunks } from "../utils/media-folders.js";
10
- import { requireAdmin } from "../utils/require-admin.js";
10
+ import { emitMediaChange } from "../utils/hooks.js";
11
+ import { requireCmsPermission } from "../utils/permissions.js";
11
12
  const bodySchema = z.object({
12
13
  keys: z.array(objectKeySchema).min(1).max(1e3),
13
14
  folder: z.string().max(255).nullable()
14
15
  });
15
16
  export default defineEventHandler(async (event) => {
16
- await requireAdmin(event);
17
+ const { user } = await requireCmsPermission(event, "media.write");
17
18
  useMediaStorage(event);
18
19
  const { keys, folder } = await readValidatedBody(event, bodySchema.parse);
19
20
  const target = normalizeMediaFolder(folder);
@@ -27,6 +28,8 @@ export default defineEventHandler(async (event) => {
27
28
  ).returning({ key: cms_media.key })
28
29
  )
29
30
  );
30
- const moved = results.reduce((total, rows) => total + rows.length, 0);
31
- return { folder: target, moved };
31
+ const keysMoved = results.flatMap((rows) => rows.map((row) => row.key));
32
+ if (keysMoved.length)
33
+ emitMediaChange(event, user, { action: "move", keys: keysMoved, folder: target });
34
+ return { folder: target, moved: keysMoved.length };
32
35
  });
@@ -3,7 +3,7 @@ import { defineEventHandler, readValidatedBody } from "h3";
3
3
  import { z } from "zod";
4
4
  import { normalizeMediaFolder, slugify } from "../../shared/index.js";
5
5
  import { assertUploadContentType, assertUploadSize, useMediaStorage } from "../utils/media.js";
6
- import { requireAdmin } from "../utils/require-admin.js";
6
+ import { requireCmsPermission } from "../utils/permissions.js";
7
7
  const MAX_BASE_LENGTH = 80;
8
8
  const MAX_EXT_LENGTH = 10;
9
9
  const bodySchema = z.object({
@@ -19,7 +19,7 @@ function slugifyFilename(filename) {
19
19
  return ext ? `${base}.${ext}` : base;
20
20
  }
21
21
  export default defineEventHandler(async (event) => {
22
- await requireAdmin(event);
22
+ await requireCmsPermission(event, "media.write");
23
23
  const { media, store, publicUrl } = useMediaStorage(event);
24
24
  const { filename, contentType, size, folder } = await readValidatedBody(event, bodySchema.parse);
25
25
  assertUploadContentType(contentType);
@@ -12,10 +12,10 @@ import { isMediaFolderMarker } from "../../shared/index.js";
12
12
  import { objectKeySchema } from "../../shared/validation.js";
13
13
  import { requireMediaFilePath, writeMediaFile } from "../utils/media-fs.js";
14
14
  import { assertUploadContentType, assertUploadSize, useMediaStorage } from "../utils/media.js";
15
- import { requireAdmin } from "../utils/require-admin.js";
15
+ import { requireCmsPermission } from "../utils/permissions.js";
16
16
  const querySchema = z.object({ key: objectKeySchema });
17
17
  export default defineEventHandler(async (event) => {
18
- await requireAdmin(event);
18
+ await requireCmsPermission(event, "media.write");
19
19
  const { media } = useMediaStorage(event);
20
20
  if (media.storage !== "filesystem") {
21
21
  throw createError({
@@ -1,5 +1,3 @@
1
- import type { MediaUsage } from '../../shared/index.js';
2
- declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
3
- usage: Record<string, MediaUsage[]>;
4
- }>>;
1
+ import type { MediaUsageReport } from '../../shared/index.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<MediaUsageReport>>;
5
3
  export default _default;
@@ -1,15 +1,19 @@
1
1
  import { defineEventHandler, readValidatedBody } from "h3";
2
2
  import { z } from "zod";
3
+ import { can } from "../../shared/roles.js";
3
4
  import { objectKeySchema } from "../../shared/validation.js";
4
5
  import { useMediaConfig } from "../utils/media.js";
6
+ import { redactMediaUsage } from "../utils/media-references.js";
5
7
  import { loadMediaUsage } from "../utils/media-usage.js";
6
- import { requireAdmin } from "../utils/require-admin.js";
8
+ import { requireCmsPermission } from "../utils/permissions.js";
7
9
  const bodySchema = z.object({ keys: z.array(objectKeySchema).min(1).max(1e3) });
8
- export default defineEventHandler(
9
- async (event) => {
10
- await requireAdmin(event);
11
- useMediaConfig(event);
12
- const { keys } = await readValidatedBody(event, bodySchema.parse);
13
- return { usage: await loadMediaUsage([...new Set(keys)]) };
14
- }
15
- );
10
+ export default defineEventHandler(async (event) => {
11
+ const { access } = await requireCmsPermission(event, "media.read");
12
+ useMediaConfig(event);
13
+ const { keys } = await readValidatedBody(event, bodySchema.parse);
14
+ const usage = await loadMediaUsage([...new Set(keys)]);
15
+ return redactMediaUsage(
16
+ usage,
17
+ (item) => can(access, item.kind === "site" ? "settings.manage" : `${item.collection}.read`)
18
+ );
19
+ });
@@ -6,10 +6,11 @@ import { cms_media } from "#cms-tables";
6
6
  import { isMediaFolderMarker } from "../../shared/index.js";
7
7
  import { objectKeySchema } from "../../shared/validation.js";
8
8
  import { useMediaStorage } from "../utils/media.js";
9
- import { requireAdmin } from "../utils/require-admin.js";
9
+ import { emitMediaChange } from "../utils/hooks.js";
10
+ import { requireCmsPermission } from "../utils/permissions.js";
10
11
  const querySchema = z.object({ key: objectKeySchema });
11
12
  export default defineEventHandler(async (event) => {
12
- await requireAdmin(event);
13
+ const { user } = await requireCmsPermission(event, "media.delete");
13
14
  const { store } = useMediaStorage(event);
14
15
  const { key } = await getValidatedQuery(event, querySchema.parse);
15
16
  const db = useDb();
@@ -19,5 +20,6 @@ export default defineEventHandler(async (event) => {
19
20
  }
20
21
  await db.delete(cms_media).where(eq(cms_media.key, key));
21
22
  await store.remove(key);
23
+ emitMediaChange(event, user, { action: "delete", keys: [key], folder: row.folder });
22
24
  return { ok: true };
23
25
  });
@@ -5,7 +5,7 @@ import { cms_media } from "#cms-tables";
5
5
  import { isMediaFolderMarker } from "../../shared/index.js";
6
6
  import { useMediaIndex } from "../utils/media-index.js";
7
7
  import { toMediaItem, useMediaConfig } from "../utils/media.js";
8
- import { requireAdmin } from "../utils/require-admin.js";
8
+ import { requireCmsPermission } from "../utils/permissions.js";
9
9
  function foldersOf(items) {
10
10
  const folders = /* @__PURE__ */ new Set();
11
11
  for (const item of items) {
@@ -14,15 +14,30 @@ function foldersOf(items) {
14
14
  return [...folders].sort();
15
15
  }
16
16
  export default defineEventHandler(async (event) => {
17
- await requireAdmin(event);
17
+ await requireCmsPermission(event, "media.read");
18
18
  const { media, publicUrl } = useMediaConfig(event);
19
19
  if (media.storage === "local") {
20
20
  const index = await useMediaIndex();
21
- const rows2 = await useDb().select({ key: cms_media.key, alt: cms_media.alt }).from(cms_media);
22
- const altByKey = new Map(rows2.map((row) => [row.key, row.alt]));
23
- const items2 = index.files.map(
24
- (file) => toMediaItem({ ...file, alt: altByKey.get(file.key) ?? null, createdAt: null }, publicUrl)
25
- );
21
+ const rows2 = await useDb().select({
22
+ key: cms_media.key,
23
+ alt: cms_media.alt,
24
+ focalX: cms_media.focalX,
25
+ focalY: cms_media.focalY
26
+ }).from(cms_media);
27
+ const metaByKey = new Map(rows2.map((row) => [row.key, row]));
28
+ const items2 = index.files.map((file) => {
29
+ const meta = metaByKey.get(file.key);
30
+ return toMediaItem(
31
+ {
32
+ ...file,
33
+ alt: meta?.alt ?? null,
34
+ focalX: meta?.focalX ?? null,
35
+ focalY: meta?.focalY ?? null,
36
+ createdAt: null
37
+ },
38
+ publicUrl
39
+ );
40
+ });
26
41
  return { items: items2, folders: foldersOf(items2), source: index.source };
27
42
  }
28
43
  const rows = await useDb().select().from(cms_media).orderBy(desc(cms_media.createdAt), desc(cms_media.id));
@@ -14,7 +14,8 @@ import {
14
14
  toMediaItem,
15
15
  useMediaConfig
16
16
  } from "../utils/media.js";
17
- import { requireAdmin } from "../utils/require-admin.js";
17
+ import { emitMediaChange } from "../utils/hooks.js";
18
+ import { requireCmsPermission } from "../utils/permissions.js";
18
19
  const bodySchema = z.object({
19
20
  key: objectKeySchema,
20
21
  mime: z.string().max(255).nullish(),
@@ -25,7 +26,7 @@ const bodySchema = z.object({
25
26
  folder: z.string().max(255).nullish()
26
27
  });
27
28
  export default defineEventHandler(async (event) => {
28
- await requireAdmin(event);
29
+ const { user } = await requireCmsPermission(event, "media.write");
29
30
  const { media, publicUrl } = useMediaConfig(event);
30
31
  assertMediaWritable(media);
31
32
  const body = await readValidatedBody(event, bodySchema.parse);
@@ -43,5 +44,6 @@ export default defineEventHandler(async (event) => {
43
44
  folder: normalizeMediaFolder(body.folder)
44
45
  };
45
46
  const [row] = await useDb().insert(cms_media).values({ ...values, createdAt: nowTimestamp() }).onConflictDoUpdate({ target: cms_media.key, set: values }).returning();
47
+ emitMediaChange(event, user, { action: "upload", keys: [body.key], folder: values.folder });
46
48
  return toMediaItem(row, publicUrl);
47
49
  });
@@ -1,23 +1,28 @@
1
1
  import { eq } from "drizzle-orm";
2
2
  import { createError, defineEventHandler, readValidatedBody } from "h3";
3
- import { z } from "zod";
4
3
  import { useDb } from "#cms-db";
5
4
  import { cms_media } from "#cms-tables";
6
- import { normalizeMediaFolder } from "../../shared/index.js";
5
+ import { normalizeMediaFolder, roundFocalCoordinate } from "../../shared/index.js";
7
6
  import { nowTimestamp } from "../../shared/timestamps.js";
8
- import { objectKeySchema } from "../../shared/validation.js";
7
+ import { mediaUpdateSchema } from "../../shared/validation.js";
9
8
  import { useMediaIndex } from "../utils/media-index.js";
10
9
  import { assertMediaWritable, toMediaItem, useMediaConfig } from "../utils/media.js";
11
- import { requireAdmin } from "../utils/require-admin.js";
12
- const bodySchema = z.object({
13
- key: objectKeySchema,
14
- alt: z.string().max(1024).nullish(),
15
- folder: z.string().max(255).nullish()
16
- });
10
+ import { emitMediaChange } from "../utils/hooks.js";
11
+ import { requireCmsPermission } from "../utils/permissions.js";
12
+ function metaUpdates(body) {
13
+ const updates = {};
14
+ if (body.alt !== void 0) updates.alt = body.alt;
15
+ if (body.focalX !== void 0 && body.focalY !== void 0) {
16
+ updates.focalX = body.focalX === null ? null : roundFocalCoordinate(body.focalX);
17
+ updates.focalY = body.focalY === null ? null : roundFocalCoordinate(body.focalY);
18
+ }
19
+ return updates;
20
+ }
17
21
  export default defineEventHandler(async (event) => {
18
- await requireAdmin(event);
22
+ const { user } = await requireCmsPermission(event, "media.write");
19
23
  const { media, publicUrl } = useMediaConfig(event);
20
- const body = await readValidatedBody(event, bodySchema.parse);
24
+ const body = await readValidatedBody(event, mediaUpdateSchema.parse);
25
+ const meta = metaUpdates(body);
21
26
  if (media.storage === "local") {
22
27
  if (body.folder !== void 0) {
23
28
  throw createError({
@@ -29,13 +34,24 @@ export default defineEventHandler(async (event) => {
29
34
  if (!file) {
30
35
  throw createError({ statusCode: 404, statusMessage: "Media not found" });
31
36
  }
32
- const alt = body.alt ?? null;
33
- await useDb().insert(cms_media).values({ key: body.key, alt, createdAt: nowTimestamp() }).onConflictDoUpdate({ target: cms_media.key, set: { alt } });
34
- return toMediaItem({ ...file, alt, createdAt: null }, publicUrl);
37
+ if (Object.keys(meta).length === 0) {
38
+ throw createError({ statusCode: 400, statusMessage: "No fields to update" });
39
+ }
40
+ const [row2] = await useDb().insert(cms_media).values({ key: body.key, ...meta, createdAt: nowTimestamp() }).onConflictDoUpdate({ target: cms_media.key, set: meta }).returning();
41
+ emitMediaChange(event, user, { action: "update", keys: [body.key], folder: file.folder });
42
+ return toMediaItem(
43
+ {
44
+ ...file,
45
+ alt: row2?.alt ?? null,
46
+ focalX: row2?.focalX ?? null,
47
+ focalY: row2?.focalY ?? null,
48
+ createdAt: null
49
+ },
50
+ publicUrl
51
+ );
35
52
  }
36
53
  assertMediaWritable(media);
37
- const updates = {};
38
- if (body.alt !== void 0) updates.alt = body.alt;
54
+ const updates = { ...meta };
39
55
  if (body.folder !== void 0) updates.folder = normalizeMediaFolder(body.folder);
40
56
  if (Object.keys(updates).length === 0) {
41
57
  throw createError({ statusCode: 400, statusMessage: "No fields to update" });
@@ -44,5 +60,6 @@ export default defineEventHandler(async (event) => {
44
60
  if (!row) {
45
61
  throw createError({ statusCode: 404, statusMessage: "Media not found" });
46
62
  }
63
+ emitMediaChange(event, user, { action: "update", keys: [body.key], folder: row.folder });
47
64
  return toMediaItem(row, publicUrl);
48
65
  });
@@ -0,0 +1,4 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
2
+ ok: boolean;
3
+ }>>;
4
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { deletePreset, presetIdParam, readPreset, requirePresetAccess } from "../utils/presets.js";
3
+ export default defineEventHandler(async (event) => {
4
+ await requirePresetAccess(event, "manage");
5
+ const id = presetIdParam(event);
6
+ await readPreset(id);
7
+ await deletePreset(id);
8
+ return { ok: true };
9
+ });
@@ -0,0 +1,3 @@
1
+ import type { CmsBlockPreset } from '../../shared/presets.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<CmsBlockPreset>>;
3
+ export default _default;
@@ -0,0 +1,23 @@
1
+ import { createError, defineEventHandler } from "h3";
2
+ import { presetUpdateSchema, renamePreset } from "../../shared/presets.js";
3
+ import {
4
+ presetIdParam,
5
+ readPreset,
6
+ readPresetBody,
7
+ requirePresetAccess,
8
+ writePreset
9
+ } from "../utils/presets.js";
10
+ export default defineEventHandler(async (event) => {
11
+ await requirePresetAccess(event, "manage");
12
+ const id = presetIdParam(event);
13
+ const parsed = presetUpdateSchema.safeParse(await readPresetBody(event));
14
+ if (!parsed.success) {
15
+ throw createError({
16
+ statusCode: 400,
17
+ statusMessage: parsed.error.issues[0]?.message ?? "Invalid preset"
18
+ });
19
+ }
20
+ const preset = renamePreset(await readPreset(id), parsed.data, (/* @__PURE__ */ new Date()).toISOString());
21
+ await writePreset(preset);
22
+ return preset;
23
+ });
@@ -0,0 +1,3 @@
1
+ import type { CmsBlockPreset } from '../../shared/presets.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<CmsBlockPreset[]>>;
3
+ export default _default;
@@ -0,0 +1,13 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { presetFits, presetReadable, sortPresets } from "../../shared/presets.js";
3
+ import { can } from "../../shared/roles.js";
4
+ import { presetBlocksField, readPresets, requirePresetAccess } from "../utils/presets.js";
5
+ export default defineEventHandler(async (event) => {
6
+ const { access } = await requirePresetAccess(event, "use");
7
+ const { source, field } = presetBlocksField(event);
8
+ return sortPresets(
9
+ (await readPresets()).filter(
10
+ (preset) => presetFits(preset, field, source) && presetReadable(preset, (permission) => can(access, permission))
11
+ )
12
+ );
13
+ });
@@ -0,0 +1,3 @@
1
+ import type { CmsBlockPreset } from '../../shared/presets.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<CmsBlockPreset>>;
3
+ export default _default;
@@ -0,0 +1,36 @@
1
+ import { createError, defineEventHandler } from "h3";
2
+ import { CMS_PRESET_MAX_COUNT, buildPreset, presetCreateSchema } from "../../shared/presets.js";
3
+ import { customId } from "../utils/custom-id.js";
4
+ import {
5
+ presetBlocksField,
6
+ readPresetBody,
7
+ readPresets,
8
+ requirePresetAccess,
9
+ writePreset
10
+ } from "../utils/presets.js";
11
+ import { getContentI18n } from "../utils/registry.js";
12
+ export default defineEventHandler(async (event) => {
13
+ await requirePresetAccess(event, "use");
14
+ const { source, field } = presetBlocksField(event);
15
+ const parsed = presetCreateSchema.safeParse(await readPresetBody(event));
16
+ if (!parsed.success) {
17
+ throw createError({
18
+ statusCode: 400,
19
+ statusMessage: parsed.error.issues[0]?.message ?? "Invalid preset"
20
+ });
21
+ }
22
+ if ((await readPresets()).length >= CMS_PRESET_MAX_COUNT) {
23
+ throw createError({
24
+ statusCode: 409,
25
+ statusMessage: `There are already ${CMS_PRESET_MAX_COUNT} presets, delete one first`
26
+ });
27
+ }
28
+ const built = buildPreset(parsed.data, field, getContentI18n(), {
29
+ id: customId("preset"),
30
+ source,
31
+ now: (/* @__PURE__ */ new Date()).toISOString()
32
+ });
33
+ if ("error" in built) throw createError({ statusCode: 400, statusMessage: built.error });
34
+ await writePreset(built.preset);
35
+ return built.preset;
36
+ });
@@ -0,0 +1,3 @@
1
+ import type { CmsBlockPreset } from '../../shared/presets.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<CmsBlockPreset[]>>;
3
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { sortPresets } from "../../shared/presets.js";
3
+ import { readPresets, requirePresetAccess } from "../utils/presets.js";
4
+ export default defineEventHandler(async (event) => {
5
+ await requirePresetAccess(event, "manage");
6
+ return sortPresets(await readPresets());
7
+ });
@@ -0,0 +1,4 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
2
+ ok: boolean;
3
+ }>>;
4
+ export default _default;
@@ -0,0 +1,15 @@
1
+ import { defineEventHandler, getRouterParam } from "h3";
2
+ import { requirePreviewLinkAccess, revokePreviewLink } from "../utils/preview-links.js";
3
+ export default defineEventHandler(async (event) => {
4
+ const access = await requirePreviewLinkAccess(
5
+ event,
6
+ getRouterParam(event, "collection") ?? "",
7
+ "update"
8
+ );
9
+ await revokePreviewLink(
10
+ access,
11
+ getRouterParam(event, "id") ?? "",
12
+ getRouterParam(event, "linkId") ?? ""
13
+ );
14
+ return { ok: true };
15
+ });
@@ -0,0 +1,3 @@
1
+ import type { CmsPreviewLink } from '../../shared/index.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<CmsPreviewLink[]>>;
3
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import { defineEventHandler, getRouterParam } from "h3";
2
+ import { listPreviewLinks, requirePreviewLinkAccess } from "../utils/preview-links.js";
3
+ export default defineEventHandler(async (event) => {
4
+ const access = await requirePreviewLinkAccess(
5
+ event,
6
+ getRouterParam(event, "collection") ?? "",
7
+ "read"
8
+ );
9
+ return listPreviewLinks(access, getRouterParam(event, "id") ?? "");
10
+ });
@@ -0,0 +1,3 @@
1
+ import type { CmsCreatedPreviewLink } from '../../shared/index.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<CmsCreatedPreviewLink>>;
3
+ export default _default;
@@ -0,0 +1,17 @@
1
+ import { defineEventHandler, getRouterParam, readValidatedBody } from "h3";
2
+ import {
3
+ createPreviewLink,
4
+ markPreviewResponse,
5
+ previewLinkInputSchema,
6
+ requirePreviewLinkAccess
7
+ } from "../utils/preview-links.js";
8
+ export default defineEventHandler(async (event) => {
9
+ const access = await requirePreviewLinkAccess(
10
+ event,
11
+ getRouterParam(event, "collection") ?? "",
12
+ "update"
13
+ );
14
+ const input = await readValidatedBody(event, previewLinkInputSchema.parse);
15
+ markPreviewResponse(event);
16
+ return createPreviewLink(access, getRouterParam(event, "id") ?? "", input);
17
+ });
@@ -0,0 +1,3 @@
1
+ import type { CmsPreviewMode } from '../../shared/index.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<CmsPreviewMode | null>>;
3
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { markPreviewResponse, readPreviewGrant } from "../utils/preview-links.js";
3
+ export default defineEventHandler(async (event) => {
4
+ markPreviewResponse(event);
5
+ const grant = await readPreviewGrant(event);
6
+ return grant ? { entry: grant.entry, id: grant.itemId, expiresAt: grant.expiresAt } : null;
7
+ });
@@ -0,0 +1,4 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
2
+ ok: boolean;
3
+ }>>;
4
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import { createError, defineEventHandler, getRouterParam } from "h3";
2
+ import { deleteRedirects } from "../utils/redirects.js";
3
+ import { requireCmsPermission } from "../utils/permissions.js";
4
+ export default defineEventHandler(async (event) => {
5
+ await requireCmsPermission(event, "redirects.manage");
6
+ const id = getRouterParam(event, "id") ?? "";
7
+ if (!await deleteRedirects([id]))
8
+ throw createError({ statusCode: 404, statusMessage: "Redirect not found" });
9
+ return { ok: true };
10
+ });
@@ -0,0 +1,3 @@
1
+ import type { CmsRedirect } from '../../shared/index.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<CmsRedirect>>;
3
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import { defineEventHandler, getRouterParam, readValidatedBody } from "h3";
2
+ import { redirectInputSchema, updateRedirect } from "../utils/redirects.js";
3
+ import { requireCmsPermission } from "../utils/permissions.js";
4
+ export default defineEventHandler(async (event) => {
5
+ await requireCmsPermission(event, "redirects.manage");
6
+ const id = getRouterParam(event, "id") ?? "";
7
+ return updateRedirect(id, await readValidatedBody(event, redirectInputSchema.parse));
8
+ });
@@ -0,0 +1,3 @@
1
+ import type { RedirectImportResult } from '../utils/redirects.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<RedirectImportResult>>;
3
+ export default _default;
@@ -0,0 +1,13 @@
1
+ import { defineEventHandler, readValidatedBody } from "h3";
2
+ import { z } from "zod";
3
+ import { REDIRECT_IMPORT_MAX_ROWS } from "../../shared/index.js";
4
+ import { requireCmsPermission } from "../utils/permissions.js";
5
+ import { importRedirects, redirectInputSchema } from "../utils/redirects.js";
6
+ const bodySchema = z.object({
7
+ redirects: z.array(redirectInputSchema).min(1).max(REDIRECT_IMPORT_MAX_ROWS)
8
+ });
9
+ export default defineEventHandler(async (event) => {
10
+ await requireCmsPermission(event, "redirects.manage");
11
+ const { redirects } = await readValidatedBody(event, bodySchema.parse);
12
+ return importRedirects(redirects);
13
+ });
@@ -0,0 +1,3 @@
1
+ import type { CmsRedirect } from '../../shared/index.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<CmsRedirect[]>>;
3
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { listRedirects } from "../utils/redirects.js";
3
+ import { requireCmsPermission } from "../utils/permissions.js";
4
+ export default defineEventHandler(async (event) => {
5
+ await requireCmsPermission(event, "redirects.manage");
6
+ return listRedirects();
7
+ });
@@ -0,0 +1,3 @@
1
+ import type { CmsRedirect } from '../../shared/index.js';
2
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<CmsRedirect>>;
3
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import { defineEventHandler, readValidatedBody } from "h3";
2
+ import { createRedirect, redirectInputSchema } from "../utils/redirects.js";
3
+ import { requireCmsPermission } from "../utils/permissions.js";
4
+ export default defineEventHandler(async (event) => {
5
+ await requireCmsPermission(event, "redirects.manage");
6
+ return createRedirect(await readValidatedBody(event, redirectInputSchema.parse));
7
+ });
@@ -5,18 +5,23 @@ import { cmsDialect, useDb } from "#cms-db";
5
5
  import * as cmsTables from "#cms-tables";
6
6
  import { CMS_SEARCH_MAX_LENGTH } from "../../shared/search.js";
7
7
  import { getContentI18n } from "../utils/registry.js";
8
- import { requireAdmin } from "../utils/require-admin.js";
8
+ import { requireCmsAccess } from "../utils/permissions.js";
9
+ import { can } from "../../shared/roles.js";
9
10
  import { searchCms } from "../utils/search.js";
10
11
  const querySchema = z.object({
11
12
  q: z.string().max(CMS_SEARCH_MAX_LENGTH).default("")
12
13
  });
13
14
  export default defineEventHandler(async (event) => {
14
- await requireAdmin(event);
15
+ const { access } = await requireCmsAccess(event);
15
16
  const { q } = await getValidatedQuery(event, querySchema.parse);
17
+ const readable = Object.fromEntries(
18
+ Object.entries(cmsConfig).filter(([name]) => can(access, `${name}.read`))
19
+ );
16
20
  return searchCms({
17
21
  db: useDb(),
18
22
  dialect: cmsDialect,
19
- config: cmsConfig,
23
+ config: readable,
24
+ media: can(access, "media.read"),
20
25
  tables: cmsTables,
21
26
  i18n: getContentI18n(),
22
27
  query: q
@@ -2,10 +2,10 @@ import { eq } from "drizzle-orm";
2
2
  import { defineEventHandler } from "h3";
3
3
  import { useDb } from "#cms-db";
4
4
  import { cms_settings } from "#cms-tables";
5
- import { requireAdmin } from "../utils/require-admin.js";
5
+ import { requireCmsPermission } from "../utils/permissions.js";
6
6
  import { requireSettingsKey } from "../utils/settings.js";
7
7
  export default defineEventHandler(async (event) => {
8
- await requireAdmin(event);
8
+ await requireCmsPermission(event, "settings.manage");
9
9
  const key = requireSettingsKey(event);
10
10
  await useDb().delete(cms_settings).where(eq(cms_settings.key, key));
11
11
  return { ok: true };