@xleddyl/nuxt-cms 0.9.3 → 0.10.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 (433) 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 -218
  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 -146
  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 +29 -5
  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 +42 -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 +9 -8
  124. package/dist/runtime/app/components/cms/TranslationBadges.d.vue.ts +7 -0
  125. package/dist/runtime/app/components/cms/TranslationBadges.vue +45 -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 +1152 -335
  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 +190 -53
  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 +29 -10
  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 +145 -29
  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/single-row.d.ts +3 -0
  351. package/dist/runtime/server/utils/single-row.js +4 -0
  352. package/dist/runtime/server/utils/site.d.ts +23 -0
  353. package/dist/runtime/server/utils/site.js +79 -0
  354. package/dist/runtime/server/utils/sitemap.d.ts +12 -0
  355. package/dist/runtime/server/utils/sitemap.js +109 -0
  356. package/dist/runtime/server/utils/user-management.d.ts +4 -0
  357. package/dist/runtime/server/utils/user-management.js +20 -0
  358. package/dist/runtime/server/utils/users.d.ts +1 -1
  359. package/dist/runtime/server/utils/users.js +1 -1
  360. package/dist/runtime/server/utils/visibility.d.ts +1 -0
  361. package/dist/runtime/server/utils/visibility.js +6 -1
  362. package/dist/runtime/server/utils/webhooks.d.ts +24 -0
  363. package/dist/runtime/server/utils/webhooks.js +90 -0
  364. package/dist/runtime/shared/block-paths.d.ts +66 -0
  365. package/dist/runtime/shared/block-paths.js +310 -0
  366. package/dist/runtime/shared/block-picker.d.ts +18 -0
  367. package/dist/runtime/shared/block-picker.js +31 -0
  368. package/dist/runtime/shared/block-signature.d.ts +4 -0
  369. package/dist/runtime/shared/block-signature.js +46 -0
  370. package/dist/runtime/shared/clipboard.d.ts +31 -0
  371. package/dist/runtime/shared/clipboard.js +206 -0
  372. package/dist/runtime/shared/conditions.d.ts +36 -0
  373. package/dist/runtime/shared/conditions.js +100 -0
  374. package/dist/runtime/shared/content-routes.d.ts +42 -0
  375. package/dist/runtime/shared/content-routes.js +237 -0
  376. package/dist/runtime/shared/duplicate.js +2 -1
  377. package/dist/runtime/shared/editor-layout.d.ts +18 -0
  378. package/dist/runtime/shared/editor-layout.js +9 -0
  379. package/dist/runtime/shared/field-options.d.ts +21 -0
  380. package/dist/runtime/shared/field-options.js +90 -0
  381. package/dist/runtime/shared/graphql-sdl.d.ts +1 -0
  382. package/dist/runtime/shared/graphql-sdl.js +50 -26
  383. package/dist/runtime/shared/history.d.ts +27 -0
  384. package/dist/runtime/shared/history.js +123 -0
  385. package/dist/runtime/shared/hooks.d.ts +45 -0
  386. package/dist/runtime/shared/hooks.js +28 -0
  387. package/dist/runtime/shared/index.d.ts +90 -21
  388. package/dist/runtime/shared/index.js +121 -37
  389. package/dist/runtime/shared/inline-text.d.ts +38 -0
  390. package/dist/runtime/shared/inline-text.js +85 -0
  391. package/dist/runtime/shared/layout.d.ts +2 -1
  392. package/dist/runtime/shared/layout.js +3 -0
  393. package/dist/runtime/shared/links.d.ts +48 -0
  394. package/dist/runtime/shared/links.js +155 -0
  395. package/dist/runtime/shared/list-filters.d.ts +2 -0
  396. package/dist/runtime/shared/list-filters.js +2 -0
  397. package/dist/runtime/shared/media-focal.d.ts +30 -0
  398. package/dist/runtime/shared/media-focal.js +52 -0
  399. package/dist/runtime/shared/migrations-dir.d.ts +14 -0
  400. package/dist/runtime/shared/migrations-dir.js +48 -2
  401. package/dist/runtime/shared/presets.d.ts +67 -0
  402. package/dist/runtime/shared/presets.js +127 -0
  403. package/dist/runtime/shared/preview-links.d.ts +64 -0
  404. package/dist/runtime/shared/preview-links.js +54 -0
  405. package/dist/runtime/shared/preview.d.ts +124 -21
  406. package/dist/runtime/shared/preview.js +419 -81
  407. package/dist/runtime/shared/redirects.d.ts +75 -0
  408. package/dist/runtime/shared/redirects.js +230 -0
  409. package/dist/runtime/shared/roles.d.ts +57 -0
  410. package/dist/runtime/shared/roles.js +293 -0
  411. package/dist/runtime/shared/save-state.d.ts +8 -0
  412. package/dist/runtime/shared/save-state.js +15 -0
  413. package/dist/runtime/shared/search.d.ts +16 -1
  414. package/dist/runtime/shared/search.js +41 -7
  415. package/dist/runtime/shared/seo.d.ts +167 -0
  416. package/dist/runtime/shared/seo.js +335 -0
  417. package/dist/runtime/shared/transfer.js +2 -1
  418. package/dist/runtime/shared/translations.d.ts +29 -0
  419. package/dist/runtime/shared/translations.js +123 -0
  420. package/dist/runtime/shared/users.d.ts +1 -1
  421. package/dist/runtime/shared/validation.d.ts +23 -1
  422. package/dist/runtime/shared/validation.js +214 -64
  423. package/dist/runtime/webhooks.d.ts +33 -0
  424. package/dist/runtime/webhooks.js +57 -0
  425. package/dist/types.d.mts +5 -1
  426. package/package.json +6 -2
  427. package/dist/runtime/app/components/cms/BlockOutline.vue +0 -88
  428. package/dist/runtime/app/components/cms/BlockPalette.vue +0 -31
  429. package/dist/runtime/app/components/cms/SettingsModal.d.vue.ts +0 -12
  430. package/dist/runtime/app/components/cms/SettingsModal.vue +0 -126
  431. package/dist/runtime/app/components/cms/SettingsModal.vue.d.ts +0 -12
  432. package/dist/runtime/app/composables/cms-field-focus.d.ts +0 -4
  433. package/dist/runtime/app/composables/cms-field-focus.js +0 -20
@@ -0,0 +1,24 @@
1
+ import { getCurrentScope, onScopeDispose, readonly, ref, watch } from "#imports";
2
+ import { createCmsHistory } from "../../shared/history.js";
3
+ export function useCmsHistory(options) {
4
+ const canUndo = ref(false);
5
+ const canRedo = ref(false);
6
+ const history = createCmsHistory({
7
+ ...options,
8
+ onUpdate: (status) => {
9
+ canUndo.value = status.canUndo;
10
+ canRedo.value = status.canRedo;
11
+ }
12
+ });
13
+ watch(options.state, history.observe);
14
+ if (getCurrentScope()) onScopeDispose(history.dispose);
15
+ return {
16
+ canUndo: readonly(canUndo),
17
+ canRedo: readonly(canRedo),
18
+ change: history.change,
19
+ release: history.release,
20
+ undo: history.undo,
21
+ redo: history.redo,
22
+ reset: history.reset
23
+ };
24
+ }
@@ -0,0 +1,10 @@
1
+ import type { CmsConfig, CmsLinkValue } from '#nuxt-cms';
2
+ type Row = Record<string, unknown>;
3
+ export type CmsLinkTargetState = 'loading' | 'live' | 'draft' | 'scheduled' | 'missing';
4
+ export declare function useCmsLinkTargets(config: CmsConfig): {
5
+ load: (entry: string, id: string) => void;
6
+ remember: (entry: string, row: Row) => void;
7
+ target: (entry: string, id: string) => Row | null | undefined;
8
+ state: (link: CmsLinkValue | null | undefined) => CmsLinkTargetState | null;
9
+ };
10
+ export {};
@@ -0,0 +1,40 @@
1
+ import { isScheduledContent, linkTargetKey, pageLinkPath } from "#nuxt-cms";
2
+ import { reactive } from "#imports";
3
+ import { useCmsPermissions } from "./cms-permissions.js";
4
+ const rows = reactive(/* @__PURE__ */ new Map());
5
+ const pending = /* @__PURE__ */ new Set();
6
+ function statusOf(error) {
7
+ return error?.statusCode ?? error?.status;
8
+ }
9
+ export function useCmsLinkTargets(config) {
10
+ const { can } = useCmsPermissions();
11
+ function load(entry, id) {
12
+ const key = linkTargetKey(entry, id);
13
+ if (!import.meta.client || rows.has(key) || pending.has(key)) return;
14
+ if (config[entry]?.kind !== "content" || !can(`${entry}.read`)) return;
15
+ pending.add(key);
16
+ $fetch(`/api/cms/admin/${entry}/${encodeURIComponent(id)}`).then((row) => rows.set(key, row)).catch((error) => {
17
+ if (statusOf(error) === 404) rows.set(key, null);
18
+ }).finally(() => pending.delete(key));
19
+ }
20
+ function remember(entry, row) {
21
+ if (row.id == null) return;
22
+ const key = linkTargetKey(entry, String(row.id));
23
+ rows.set(key, { ...rows.get(key), ...row });
24
+ }
25
+ function target(entry, id) {
26
+ return rows.get(linkTargetKey(entry, id));
27
+ }
28
+ function state(link) {
29
+ if (!link?.entry || !link.id || link.url) return null;
30
+ const entry = config[link.entry];
31
+ if (!entry) return "missing";
32
+ if (entry.kind === "page") return pageLinkPath(entry, link.id) ? "live" : "missing";
33
+ const row = target(link.entry, link.id);
34
+ if (row === void 0) return "loading";
35
+ if (row === null) return "missing";
36
+ if (row.status !== "published") return "draft";
37
+ return isScheduledContent(row) ? "scheduled" : "live";
38
+ }
39
+ return { load, remember, target, state };
40
+ }
@@ -0,0 +1 @@
1
+ export declare function useCmsLinkedDelete(): (entry: string, ids: string[], question: string, titles?: Record<string, string>) => Promise<boolean>;
@@ -0,0 +1,45 @@
1
+ import { groupMediaUsage, isLinkTargetEntry, linkTargetKey } from "#nuxt-cms";
2
+ import cmsConfig from "#cms-config";
3
+ import { cmsApi } from "../utils/api.js";
4
+ import { useCmsConfirm } from "./cms-confirm.js";
5
+ import { usageItem } from "./cms-media-library.js";
6
+ function linksLabel(count) {
7
+ return `${count} ${count === 1 ? "entry" : "entries"}`;
8
+ }
9
+ async function loadUsage(entry, ids) {
10
+ try {
11
+ const { usage } = await cmsApi(
12
+ "/api/cms/link-usage",
13
+ { method: "POST", body: { targets: ids.map((id) => ({ entry, id })) } }
14
+ );
15
+ return usage;
16
+ } catch {
17
+ return null;
18
+ }
19
+ }
20
+ export function useCmsLinkedDelete() {
21
+ const confirmAction = useCmsConfirm();
22
+ return async (entry, ids, question, titles = {}) => {
23
+ if (!ids.length || !isLinkTargetEntry(cmsConfig[entry]))
24
+ return confirmAction({ title: question });
25
+ const usage = await loadUsage(entry, ids);
26
+ if (!usage)
27
+ return confirmAction({
28
+ title: question,
29
+ description: "Could not check where it is linked."
30
+ });
31
+ const groups = ids.map((id) => ({ id, entries: groupMediaUsage(usage[linkTargetKey(entry, id)] ?? []) })).filter((group) => group.entries.length > 0);
32
+ if (!groups.length) return confirmAction({ title: question });
33
+ const single = ids.length === 1;
34
+ const linked = single ? `It is linked from ${linksLabel(groups[0].entries.length)}.` : `${groups.length} of ${ids.length} are linked from your content.`;
35
+ return confirmAction({
36
+ title: single ? "Item is linked" : "Items are linked",
37
+ description: `${question} ${linked} Those links disappear from the site until they point somewhere else.`,
38
+ confirmLabel: "Delete anyway",
39
+ groups: groups.map((group) => ({
40
+ title: titles[group.id] ?? `#${group.id}`,
41
+ items: group.entries.map(usageItem)
42
+ }))
43
+ });
44
+ };
45
+ }
@@ -1,4 +1,5 @@
1
- import type { MediaItem, MediaSourceInfo, MediaUsage } from '../../shared/index.js';
1
+ import type { RecordListItem } from '@xleddyl/443-components-vue';
2
+ import type { MediaItem, MediaSourceInfo, MediaUsage, MediaUsageEntry, MediaUsageReport } from '../../shared/index.js';
2
3
  export interface MediaFolderStats {
3
4
  files: number;
4
5
  folders: number;
@@ -13,8 +14,10 @@ export declare function useCmsMediaLibrary(): {
13
14
  size: number | null;
14
15
  width: number | null;
15
16
  height: number | null;
17
+ focalX: number | null;
18
+ focalY: number | null;
16
19
  createdAt: string | null;
17
- type: import("../../shared/index.js").MediaType;
20
+ type: import("#nuxt-cms").MediaType;
18
21
  url: string | null;
19
22
  }[], MediaItem[] | {
20
23
  id?: number | undefined;
@@ -25,16 +28,18 @@ export declare function useCmsMediaLibrary(): {
25
28
  size: number | null;
26
29
  width: number | null;
27
30
  height: number | null;
31
+ focalX: number | null;
32
+ focalY: number | null;
28
33
  createdAt: string | null;
29
- type: import("../../shared/index.js").MediaType;
34
+ type: import("#nuxt-cms").MediaType;
30
35
  url: string | null;
31
36
  }[]>;
32
37
  source: import("vue").Ref<{
33
- kind: import("../../shared/index.js").MediaSourceKind;
38
+ kind: import("#nuxt-cms").MediaSourceKind;
34
39
  root: string;
35
40
  builtAt: string | null;
36
41
  } | null, MediaSourceInfo | {
37
- kind: import("../../shared/index.js").MediaSourceKind;
42
+ kind: import("#nuxt-cms").MediaSourceKind;
38
43
  root: string;
39
44
  builtAt: string | null;
40
45
  } | null>;
@@ -55,8 +60,10 @@ export declare function useCmsMediaLibrary(): {
55
60
  size: number | null;
56
61
  width: number | null;
57
62
  height: number | null;
63
+ focalX: number | null;
64
+ focalY: number | null;
58
65
  createdAt: string | null;
59
- type: import("../../shared/index.js").MediaType;
66
+ type: import("#nuxt-cms").MediaType;
60
67
  url: string | null;
61
68
  }[];
62
69
  createFolder: (name: string) => Promise<boolean>;
@@ -67,8 +74,11 @@ export declare function useCmsMediaLibrary(): {
67
74
  updateItem: (key: string, changes: {
68
75
  alt?: string | null;
69
76
  folder?: string | null;
70
- }) => Promise<boolean>;
71
- usage: (keys: string[]) => Promise<Record<string, MediaUsage[]> | null>;
77
+ focalX?: number | null;
78
+ focalY?: number | null;
79
+ }) => Promise<void>;
80
+ usage: (keys: string[]) => Promise<MediaUsageReport | null>;
72
81
  };
73
82
  export type CmsMediaLibrary = ReturnType<typeof useCmsMediaLibrary>;
74
- export declare function usageLink(usage: Pick<MediaUsage, 'collection' | 'id'>): string;
83
+ export declare function usageLink(usage: Pick<MediaUsage, 'collection' | 'id' | 'kind'>): string;
84
+ export declare function usageItem(entry: MediaUsageEntry, index: number): RecordListItem;
@@ -1,3 +1,4 @@
1
+ import { toast } from "@xleddyl/443-components-vue";
1
2
  import {
2
3
  expandMediaFolders,
3
4
  isWithinMediaFolder,
@@ -5,13 +6,13 @@ import {
5
6
  mediaFolderParent
6
7
  } from "../../shared/index.js";
7
8
  import { computed, ref } from "#imports";
8
- import { errorMessage } from "../utils/ui.js";
9
+ import cmsConfig from "#cms-config";
10
+ import { cmsIcon, cmsSettingsLink, errorMessage } from "../utils/ui.js";
11
+ import { CMS_ENTRY_KIND_ICONS } from "./cms-entry-settings.js";
9
12
  import { invalidateCmsMediaKeys } from "./cms-media-keys.js";
10
- import { useCmsToast } from "./cms-toast.js";
11
13
  const endpoint = "/api/cms/admin/media";
12
14
  const USAGE_CHUNK = 1e3;
13
15
  export function useCmsMediaLibrary() {
14
- const toast = useCmsToast();
15
16
  const items = ref([]);
16
17
  const serverFolders = ref([]);
17
18
  const source = ref(null);
@@ -61,7 +62,7 @@ export function useCmsMediaLibrary() {
61
62
  await action();
62
63
  return true;
63
64
  } catch (err) {
64
- toast.add({ title, description: errorMessage(err), color: "error" });
65
+ toast.error(title, { description: errorMessage(err) });
65
66
  return false;
66
67
  }
67
68
  }
@@ -101,22 +102,23 @@ export function useCmsMediaLibrary() {
101
102
  });
102
103
  }
103
104
  function updateItem(key, changes) {
104
- return attempt("Save failed", async () => {
105
+ return (async () => {
105
106
  await $fetch(endpoint, { method: "PUT", body: { key, ...changes } });
106
107
  await reload({ quiet: true });
107
- });
108
+ })();
108
109
  }
109
110
  async function usage(keys) {
110
111
  const unique = [...new Set(keys)];
111
- if (!unique.length) return {};
112
+ const merged = { usage: {}, hidden: {} };
113
+ if (!unique.length) return merged;
112
114
  try {
113
- const merged = {};
114
115
  for (let index = 0; index < unique.length; index += USAGE_CHUNK) {
115
- const result = await $fetch(
116
- `${endpoint}/usage`,
117
- { method: "POST", body: { keys: unique.slice(index, index + USAGE_CHUNK) } }
118
- );
119
- Object.assign(merged, result.usage);
116
+ const result = await $fetch(`${endpoint}/usage`, {
117
+ method: "POST",
118
+ body: { keys: unique.slice(index, index + USAGE_CHUNK) }
119
+ });
120
+ Object.assign(merged.usage, result.usage);
121
+ Object.assign(merged.hidden, result.hidden);
120
122
  }
121
123
  return merged;
122
124
  } catch {
@@ -143,5 +145,21 @@ export function useCmsMediaLibrary() {
143
145
  };
144
146
  }
145
147
  export function usageLink(usage) {
148
+ if (usage.kind === "site") return cmsSettingsLink("site", "/cms/media");
146
149
  return usage.id === null ? `/cms/${usage.collection}` : `/cms/${usage.collection}/${usage.id}`;
147
150
  }
151
+ function usageIcon(usage) {
152
+ if (usage.kind === "site") return cmsIcon("globe-alt");
153
+ const entry = cmsConfig[usage.collection];
154
+ return cmsIcon(entry?.icon ?? CMS_ENTRY_KIND_ICONS[usage.kind]);
155
+ }
156
+ export function usageItem(entry, index) {
157
+ return {
158
+ id: index,
159
+ title: entry.title ?? entry.label,
160
+ description: entry.fields.join(", "),
161
+ meta: entry.title ? entry.label : void 0,
162
+ icon: usageIcon(entry),
163
+ to: usageLink(entry)
164
+ };
165
+ }
@@ -5,9 +5,8 @@ import {
5
5
  normalizeMediaFolder
6
6
  } from "../../shared/index.js";
7
7
  import { ref } from "#imports";
8
- import { readDroppedFiles } from "@xleddyl/443-components-vue";
8
+ import { readDroppedFiles, toast } from "@xleddyl/443-components-vue";
9
9
  import { useCmsRuntime } from "./cms-runtime.js";
10
- import { useCmsToast } from "./cms-toast.js";
11
10
  async function imageDimensions(file) {
12
11
  try {
13
12
  const bitmap = await createImageBitmap(file);
@@ -105,7 +104,6 @@ function isWithinOrAbove(folder, other) {
105
104
  return other === folder || other.startsWith(`${folder}/`);
106
105
  }
107
106
  export function useCmsMediaUploader() {
108
- const toast = useCmsToast();
109
107
  const { mediaMaxFileSize } = useCmsRuntime();
110
108
  const uploading = ref(false);
111
109
  const done = ref(0);
@@ -149,11 +147,7 @@ export function useCmsMediaUploader() {
149
147
  })
150
148
  );
151
149
  const failed = results.filter((r) => r.status === "rejected").length;
152
- if (failed)
153
- toast.add({
154
- title: `${failed} folder${failed > 1 ? "s" : ""} could not be created`,
155
- color: "error"
156
- });
150
+ if (failed) toast.error(`${failed} folder${failed > 1 ? "s" : ""} could not be created`);
157
151
  }
158
152
  async function upload(source, options) {
159
153
  const tree = Array.isArray(source) || source instanceof FileList ? uploadTreeFromFiles(source) : source;
@@ -161,16 +155,10 @@ export function useCmsMediaUploader() {
161
155
  let files = all.filter((entry) => matchesAccept(entry.file, options.accept));
162
156
  const rejected = all.length - files.length;
163
157
  if (rejected) {
164
- toast.add({
165
- title: `${rejected} file${rejected > 1 ? "s" : ""} of an unsupported type skipped`,
166
- color: "error"
167
- });
158
+ toast.error(`${rejected} file${rejected > 1 ? "s" : ""} of an unsupported type skipped`);
168
159
  }
169
160
  for (const { file } of files.filter((entry) => entry.file.size > mediaMaxFileSize)) {
170
- toast.add({
171
- title: `File too large (max ${formatFileSize(mediaMaxFileSize)}): ${file.name}`,
172
- color: "error"
173
- });
161
+ toast.error(`File too large (max ${formatFileSize(mediaMaxFileSize)}): ${file.name}`);
174
162
  }
175
163
  files = files.filter((entry) => entry.file.size <= mediaMaxFileSize);
176
164
  const nested = options.multiple !== false;
@@ -188,8 +176,7 @@ export function useCmsMediaUploader() {
188
176
  )
189
177
  ].filter((folder) => !fileFolders.some((other) => isWithinOrAbove(folder, other)));
190
178
  if (planned.some((entry) => entry.flattened)) {
191
- toast.add({
192
- title: `Folders nest up to ${MEDIA_FOLDER_MAX_DEPTH} levels`,
179
+ toast(`Folders nest up to ${MEDIA_FOLDER_MAX_DEPTH} levels`, {
193
180
  description: "Files in deeper folders were uploaded to the deepest allowed folder."
194
181
  });
195
182
  }
@@ -205,8 +192,7 @@ export function useCmsMediaUploader() {
205
192
  );
206
193
  const ok = results.filter((r) => r.status === "fulfilled").map((r) => r.value);
207
194
  const failed = results.length - ok.length;
208
- if (failed)
209
- toast.add({ title: `${failed} upload${failed > 1 ? "s" : ""} failed`, color: "error" });
195
+ if (failed) toast.error(`${failed} upload${failed > 1 ? "s" : ""} failed`);
210
196
  return ok;
211
197
  } finally {
212
198
  uploading.value = false;
@@ -0,0 +1,18 @@
1
+ import type { CmsEntry } from '#nuxt-cms';
2
+ import type { CmsRoles } from '../../shared/roles.js';
3
+ export interface CmsEntryLockOptions {
4
+ isNew: boolean;
5
+ status?: unknown;
6
+ }
7
+ export declare function useCmsPermissions(): {
8
+ role: import("vue").ComputedRef<import("#nuxt-cms").CmsUserRole | null | undefined>;
9
+ access: import("vue").ComputedRef<import("#nuxt-cms").CmsAccess | null>;
10
+ roles: CmsRoles;
11
+ can: (permission: string) => boolean;
12
+ entryLock: (name: string, entry: CmsEntry, options: CmsEntryLockOptions) => "Your role cannot create entries here." | "Your role can view this entry but not edit it." | "This entry is published. Your role can only edit drafts." | null;
13
+ firstPath: () => string | null;
14
+ roleLabel: (key: string | null | undefined) => string;
15
+ roleOptions: import("#nuxt-cms").CmsRoleOption[];
16
+ canGrant: (key: string) => boolean;
17
+ canManage: (key: string) => boolean;
18
+ };
@@ -0,0 +1,54 @@
1
+ import { computed } from "#imports";
2
+ import cmsConfig from "#cms-config";
3
+ import cmsRoles from "#cms-roles";
4
+ import {
5
+ can as canAccess,
6
+ canGrantRole,
7
+ canManageAccount,
8
+ cmsRoleLabel,
9
+ cmsRoleOptions,
10
+ CMS_SUPERADMIN_ROLE,
11
+ resolveCmsAccess
12
+ } from "../../shared/roles.js";
13
+ import { useCmsAccount } from "./cms-account.js";
14
+ export function useCmsPermissions() {
15
+ const { user, isSuperAdmin } = useCmsAccount();
16
+ const roles = cmsRoles;
17
+ const config = cmsConfig;
18
+ const role = computed(
19
+ () => user.value ? isSuperAdmin.value ? CMS_SUPERADMIN_ROLE : user.value.role : null
20
+ );
21
+ const access = computed(
22
+ () => role.value === null ? null : resolveCmsAccess(role.value, roles, config)
23
+ );
24
+ function can(permission) {
25
+ return canAccess(access.value, permission);
26
+ }
27
+ function entryLock(name, entry, options) {
28
+ if (options.isNew) {
29
+ return can(`${name}.create`) ? null : "Your role cannot create entries here.";
30
+ }
31
+ if (!can(`${name}.update`)) return "Your role can view this entry but not edit it.";
32
+ if (entry.drafts && options.status === "published" && !can(`${name}.publish`)) {
33
+ return "This entry is published. Your role can only edit drafts.";
34
+ }
35
+ return null;
36
+ }
37
+ function firstPath() {
38
+ const first = Object.keys(config).find((name) => can(`${name}.read`));
39
+ if (first) return `/cms/${first}`;
40
+ return can("media.read") ? "/cms/media" : null;
41
+ }
42
+ return {
43
+ role,
44
+ access,
45
+ roles,
46
+ can,
47
+ entryLock,
48
+ firstPath,
49
+ roleLabel: (key) => cmsRoleLabel(key, roles),
50
+ roleOptions: cmsRoleOptions(roles),
51
+ canGrant: (key) => canGrantRole(access.value, key, roles, config),
52
+ canManage: (key) => canManageAccount(access.value, key, roles, config)
53
+ };
54
+ }
@@ -0,0 +1,11 @@
1
+ import type { CmsBlockPreset } from '../../shared/presets.js';
2
+ import type { CmsBlockValue } from '../../shared/preview.js';
3
+ export declare function useCmsPresets(entryName: () => string | undefined, fieldKey: () => string | undefined): {
4
+ presets: import("vue").ComputedRef<CmsBlockPreset[]>;
5
+ load: () => Promise<void>;
6
+ create: (input: {
7
+ name: string;
8
+ description?: string;
9
+ items: CmsBlockValue[];
10
+ }) => Promise<CmsBlockPreset>;
11
+ };
@@ -0,0 +1,40 @@
1
+ import { computed, useState } from "#imports";
2
+ import { cmsApi } from "../utils/api.js";
3
+ const PRESETS_ENDPOINT = "/api/cms/presets";
4
+ function usePresetCache() {
5
+ return useState("cms-presets", () => ({}));
6
+ }
7
+ function fieldEndpoint(entryName, fieldKey) {
8
+ return `${PRESETS_ENDPOINT}/${encodeURIComponent(entryName)}/${encodeURIComponent(fieldKey)}`;
9
+ }
10
+ export function useCmsPresets(entryName, fieldKey) {
11
+ const cache = usePresetCache();
12
+ const scope = computed(() => {
13
+ const entry = entryName();
14
+ const field = fieldKey();
15
+ return entry && field ? { entry, field, key: `${entry}.${field}` } : null;
16
+ });
17
+ const presets = computed(() => scope.value ? cache.value[scope.value.key] ?? [] : []);
18
+ async function load() {
19
+ const current = scope.value;
20
+ if (!current) return;
21
+ try {
22
+ const list = await cmsApi(fieldEndpoint(current.entry, current.field));
23
+ cache.value = { ...cache.value, [current.key]: list };
24
+ } catch {
25
+ cache.value = { ...cache.value, [current.key]: cache.value[current.key] ?? [] };
26
+ }
27
+ }
28
+ async function create(input) {
29
+ const current = scope.value;
30
+ if (!current) throw new Error("This field cannot hold presets");
31
+ const preset = await cmsApi(fieldEndpoint(current.entry, current.field), {
32
+ method: "POST",
33
+ body: input
34
+ });
35
+ cache.value = {};
36
+ await load();
37
+ return preset;
38
+ }
39
+ return { presets, load, create };
40
+ }
@@ -0,0 +1,4 @@
1
+ import type { ComputedRef, Ref } from 'vue';
2
+ import type { CmsPreviewMode } from '../../shared/index.js';
3
+ export declare function useCmsPreviewState(): Ref<CmsPreviewMode | null>;
4
+ export declare function useCmsPreviewMode(): ComputedRef<CmsPreviewMode | null>;
@@ -0,0 +1,8 @@
1
+ import { computed, useState } from "#imports";
2
+ export function useCmsPreviewState() {
3
+ return useState("cms-preview-mode", () => null);
4
+ }
5
+ export function useCmsPreviewMode() {
6
+ const state = useCmsPreviewState();
7
+ return computed(() => state.value);
8
+ }
@@ -4,6 +4,9 @@ export interface CmsAsyncDataOptions<ResT, DefaultT> extends Pick<AsyncDataOptio
4
4
  key?: string;
5
5
  default?: () => DefaultT;
6
6
  }
7
+ export declare function cmsPreviewToken(): string | null;
8
+ export declare function cmsPreviewKey(key: string, preview: string | null): string;
7
9
  export declare function cmsQueryKey(query: string, variables?: unknown): string;
10
+ export declare function cmsQueryWithPreview<const Q extends string>(query: Q, variables: CmsVariables<Q> | undefined, preview: string | null): Promise<CmsResult<Q>>;
8
11
  export declare function $cmsQuery<const Q extends string>(query: Q, variables?: CmsVariables<Q>): Promise<CmsResult<Q>>;
9
12
  export declare function useCms<const Q extends string, DefaultT = undefined>(query: Q, variables?: CmsVariables<Q>, options?: CmsAsyncDataOptions<CmsResult<Q>, DefaultT>): AsyncData<CmsResult<Q> | DefaultT | undefined, Error | undefined>;
@@ -1,28 +1,35 @@
1
- import { useAsyncData } from "#imports";
2
- import { CMS_GRAPHQL_BATCH_LIMIT } from "../../shared/index.js";
1
+ import { tryUseNuxtApp, useAsyncData } from "#imports";
2
+ import {
3
+ CMS_GRAPHQL_BATCH_LIMIT,
4
+ PREVIEW_HEADER,
5
+ PREVIEW_QUERY_PARAM,
6
+ previewTokenFrom
7
+ } from "../../shared/index.js";
3
8
  const ENDPOINT = "/api/cms/graphql";
4
9
  const inFlight = /* @__PURE__ */ new Map();
5
- let queue = [];
10
+ let queues = /* @__PURE__ */ new Map();
6
11
  let scheduled = false;
7
12
  function responseError(response) {
8
13
  return new Error(
9
14
  response?.errors?.map((e) => e.message).join("; ") || "Invalid batched GraphQL response"
10
15
  );
11
16
  }
12
- async function sendBatch(batch) {
17
+ async function sendBatch(batch, preview) {
18
+ const headers = preview ? { headers: { [PREVIEW_HEADER]: preview } } : {};
13
19
  try {
14
20
  if (batch.length === 1) {
15
21
  batch[0].resolve(
16
22
  await $fetch(ENDPOINT, {
17
23
  method: "POST",
18
- body: batch[0].body
24
+ body: batch[0].body,
25
+ ...headers
19
26
  })
20
27
  );
21
28
  return;
22
29
  }
23
30
  const responses = await $fetch(
24
31
  ENDPOINT,
25
- { method: "POST", body: batch.map((pending) => pending.body) }
32
+ { method: "POST", body: batch.map((pending) => pending.body), ...headers }
26
33
  );
27
34
  if (!Array.isArray(responses)) throw responseError(responses);
28
35
  batch.forEach((pending, index) => {
@@ -35,42 +42,60 @@ async function sendBatch(batch) {
35
42
  }
36
43
  }
37
44
  function flushQueue() {
38
- const pending = queue;
39
- queue = [];
45
+ const pending = queues;
46
+ queues = /* @__PURE__ */ new Map();
40
47
  scheduled = false;
41
- for (let index = 0; index < pending.length; index += CMS_GRAPHQL_BATCH_LIMIT) {
42
- void sendBatch(pending.slice(index, index + CMS_GRAPHQL_BATCH_LIMIT));
48
+ for (const [preview, list] of pending) {
49
+ for (let index = 0; index < list.length; index += CMS_GRAPHQL_BATCH_LIMIT) {
50
+ void sendBatch(list.slice(index, index + CMS_GRAPHQL_BATCH_LIMIT), preview);
51
+ }
43
52
  }
44
53
  }
45
- function requestGraphql(body) {
46
- const key = JSON.stringify(body);
47
- const existing = inFlight.get(key);
48
- if (existing) return existing;
49
- const request = new Promise((resolve, reject) => {
54
+ function enqueue(body, preview) {
55
+ return new Promise((resolve, reject) => {
56
+ const queue = queues.get(preview) ?? [];
50
57
  queue.push({ body, resolve, reject });
58
+ queues.set(preview, queue);
51
59
  if (!scheduled) {
52
60
  scheduled = true;
53
61
  setTimeout(flushQueue, 0);
54
62
  }
55
- }).finally(() => inFlight.delete(key));
63
+ });
64
+ }
65
+ function requestGraphql(body, preview) {
66
+ if (preview) return enqueue(body, preview);
67
+ const key = JSON.stringify(body);
68
+ const existing = inFlight.get(key);
69
+ if (existing) return existing;
70
+ const request = enqueue(body, "").finally(() => inFlight.delete(key));
56
71
  inFlight.set(key, request);
57
72
  return request;
58
73
  }
74
+ export function cmsPreviewToken() {
75
+ return previewTokenFrom(tryUseNuxtApp()?._route?.query?.[PREVIEW_QUERY_PARAM]);
76
+ }
77
+ export function cmsPreviewKey(key, preview) {
78
+ return preview ? `${key}:cms-preview` : key;
79
+ }
59
80
  export function cmsQueryKey(query, variables) {
60
81
  return `cms-gql:${query}:${JSON.stringify(variables ?? {})}`;
61
82
  }
62
- export async function $cmsQuery(query, variables) {
63
- const res = await requestGraphql({ query, variables });
83
+ export async function cmsQueryWithPreview(query, variables, preview) {
84
+ const res = await requestGraphql({ query, variables }, preview);
64
85
  if (res.errors?.length) {
65
86
  throw new Error(res.errors.map((e) => e.message).join("; "));
66
87
  }
67
88
  return res.data;
68
89
  }
90
+ export function $cmsQuery(query, variables) {
91
+ return cmsQueryWithPreview(query, variables, cmsPreviewToken());
92
+ }
69
93
  export function useCms(query, variables, options = {}) {
70
94
  const { key, ...asyncDataOptions } = options;
95
+ const preview = cmsPreviewToken();
71
96
  return useAsyncData(
72
- key ?? cmsQueryKey(query, variables),
73
- () => $cmsQuery(query, variables),
97
+ key ?? cmsPreviewKey(cmsQueryKey(query, variables), preview),
98
+ () => cmsQueryWithPreview(query, variables, preview),
74
99
  asyncDataOptions
75
100
  );
76
101
  }
@@ -0,0 +1,31 @@
1
+ export interface CmsListRecord {
2
+ id: string;
3
+ }
4
+ export interface CmsRecordListOptions<T> {
5
+ key: string;
6
+ url: string;
7
+ label: (item: T) => string;
8
+ compare?: (a: T, b: T) => number;
9
+ loadError: string;
10
+ confirmDelete?: (item: T) => {
11
+ title: string;
12
+ description?: string;
13
+ };
14
+ deleted?: string;
15
+ deleteError?: string;
16
+ }
17
+ export declare function useCmsRecordList<T extends CmsListRecord>(options: CmsRecordListOptions<T>): {
18
+ items: import("vue").Ref<T[], T[]>;
19
+ sorted: import("vue").ComputedRef<T[]>;
20
+ loaded: import("vue").Ref<boolean, boolean>;
21
+ loading: import("vue").Ref<boolean, boolean>;
22
+ load: () => Promise<void>;
23
+ ensureLoaded: () => Promise<void>;
24
+ find: (id: string | null | undefined) => T | undefined;
25
+ upsert: (record: T) => void;
26
+ removeLocal: (id: string) => void;
27
+ resolveLabel: (id: string) => Promise<string | undefined>;
28
+ remove: (record: T) => Promise<boolean>;
29
+ label: (item: T) => string;
30
+ };
31
+ export type CmsRecordList<T extends CmsListRecord> = ReturnType<typeof useCmsRecordList<T>>;