includio-cms 0.1.4 → 0.5.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 (310) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/ROADMAP.md +26 -13
  3. package/dist/admin/api/accept-invite.js +1 -5
  4. package/dist/admin/api/invite.js +7 -16
  5. package/dist/admin/client/account/account-page.svelte +20 -50
  6. package/dist/admin/client/account/lang.d.ts +15 -23
  7. package/dist/admin/client/account/lang.js +51 -67
  8. package/dist/admin/client/account/preferences-section.svelte +26 -84
  9. package/dist/admin/client/account/profile-section.svelte +60 -40
  10. package/dist/admin/client/account/schema.d.ts +11 -3
  11. package/dist/admin/client/account/schema.js +25 -16
  12. package/dist/admin/client/account/security-section.svelte +139 -105
  13. package/dist/admin/client/account/sessions-section.svelte +35 -34
  14. package/dist/admin/client/admin/admin-after-login-layout-content.svelte +3 -5
  15. package/dist/admin/client/admin/admin-layout.svelte +3 -2
  16. package/dist/admin/client/admin/admin-preloader.svelte +36 -0
  17. package/dist/admin/client/admin/admin-preloader.svelte.d.ts +18 -0
  18. package/dist/admin/client/admin/dashboard-page.svelte +35 -67
  19. package/dist/admin/client/collection/a11y-score-cell.svelte +45 -0
  20. package/dist/admin/client/collection/a11y-score-cell.svelte.d.ts +6 -0
  21. package/dist/admin/client/collection/bulk-actions-bar.svelte +100 -0
  22. package/dist/admin/client/collection/bulk-actions-bar.svelte.d.ts +10 -0
  23. package/dist/admin/client/collection/collection-entries.svelte +277 -258
  24. package/dist/admin/client/collection/collection-view.svelte.d.ts +4 -3
  25. package/dist/admin/client/collection/collection-view.svelte.js +9 -5
  26. package/dist/admin/client/collection/collection.svelte +22 -12
  27. package/dist/admin/client/collection/data-table.svelte +50 -39
  28. package/dist/admin/client/collection/data-table.svelte.d.ts +1 -0
  29. package/dist/admin/client/collection/date-cell.svelte +7 -5
  30. package/dist/admin/client/collection/date-cell.svelte.d.ts +1 -1
  31. package/dist/admin/client/collection/empty-state.svelte +28 -0
  32. package/dist/admin/client/collection/empty-state.svelte.d.ts +9 -0
  33. package/dist/admin/client/collection/entry-link.svelte +10 -4
  34. package/dist/admin/client/collection/entry-link.svelte.d.ts +1 -0
  35. package/dist/admin/client/collection/grid-view.svelte +21 -23
  36. package/dist/admin/client/collection/grid-view.svelte.d.ts +1 -2
  37. package/dist/admin/client/collection/row-actions.svelte +69 -0
  38. package/dist/admin/client/collection/row-actions.svelte.d.ts +10 -0
  39. package/dist/admin/client/collection/status-badge.svelte +7 -8
  40. package/dist/admin/client/collection/table-pagination.svelte +122 -79
  41. package/dist/admin/client/collection/table-pagination.svelte.d.ts +1 -0
  42. package/dist/admin/client/collection/table-toolbar.svelte +108 -88
  43. package/dist/admin/client/collection/table-toolbar.svelte.d.ts +8 -9
  44. package/dist/admin/client/entry/entry-form.svelte +109 -1
  45. package/dist/admin/client/entry/entry-header.svelte +143 -37
  46. package/dist/admin/client/entry/entry-header.svelte.d.ts +8 -0
  47. package/dist/admin/client/entry/entry.svelte +272 -61
  48. package/dist/admin/client/entry/header/a11y-validator.d.ts +47 -0
  49. package/dist/admin/client/entry/header/a11y-validator.js +352 -0
  50. package/dist/admin/client/entry/header/publish-panel.svelte +531 -129
  51. package/dist/admin/client/entry/header/publish-panel.svelte.d.ts +4 -0
  52. package/dist/admin/client/entry/header/save-indicator.svelte +33 -23
  53. package/dist/admin/client/entry/header/schedule-popover.svelte +1 -1
  54. package/dist/admin/client/entry/header/status-badge.svelte +25 -118
  55. package/dist/admin/client/entry/header/version-history-sheet.svelte +322 -98
  56. package/dist/admin/client/form/form-submission/form-submission.svelte +271 -83
  57. package/dist/admin/client/form/form-submission/submission-field.svelte +12 -12
  58. package/dist/admin/client/form/form-submissions.svelte +421 -139
  59. package/dist/admin/client/form/submission-link.svelte +8 -2
  60. package/dist/admin/client/form/submission-link.svelte.d.ts +1 -0
  61. package/dist/admin/client/form/submission-status-badge.svelte +18 -4
  62. package/dist/admin/client/form/submission-status-badge.svelte.d.ts +1 -0
  63. package/dist/admin/client/login/lang.d.ts +32 -0
  64. package/dist/admin/client/login/lang.js +66 -2
  65. package/dist/admin/client/login/login-form.svelte +237 -95
  66. package/dist/admin/client/login/login-form.svelte.d.ts +2 -17
  67. package/dist/admin/client/login/login-page.svelte +34 -98
  68. package/dist/admin/client/login/reset-password-page.svelte +235 -0
  69. package/dist/admin/client/login/reset-password-page.svelte.d.ts +4 -0
  70. package/dist/admin/client/login/schema.d.ts +15 -0
  71. package/dist/admin/client/login/schema.js +21 -0
  72. package/dist/admin/client/users/accept-invite-page.svelte +166 -37
  73. package/dist/admin/client/users/create-user-dialog.svelte +15 -7
  74. package/dist/admin/client/users/delete-user-dialog.svelte +81 -16
  75. package/dist/admin/client/users/delete-user-dialog.svelte.d.ts +4 -1
  76. package/dist/admin/client/users/edit-user-dialog.svelte +3 -0
  77. package/dist/admin/client/users/invite-user-dialog.svelte +16 -3
  78. package/dist/admin/client/users/lang.d.ts +27 -0
  79. package/dist/admin/client/users/lang.js +64 -10
  80. package/dist/admin/client/users/pending-invitations.svelte +59 -23
  81. package/dist/admin/client/users/users-page.svelte +471 -72
  82. package/dist/admin/components/accessibility/accessibility-overview.svelte +2 -7
  83. package/dist/admin/components/dashboard/a11y-gauge.svelte +90 -0
  84. package/dist/admin/components/dashboard/a11y-gauge.svelte.d.ts +18 -0
  85. package/dist/admin/components/dashboard/accessibility-hub.svelte +13 -12
  86. package/dist/admin/components/dashboard/changelog-dialog.svelte +157 -0
  87. package/dist/admin/components/dashboard/changelog-dialog.svelte.d.ts +6 -0
  88. package/dist/admin/components/dashboard/form-submissions-widget.svelte +71 -113
  89. package/dist/admin/components/dashboard/index.d.ts +4 -2
  90. package/dist/admin/components/dashboard/index.js +4 -2
  91. package/dist/admin/components/dashboard/orphaned-entries-notice.svelte +240 -0
  92. package/dist/admin/components/dashboard/orphaned-entries-notice.svelte.d.ts +13 -0
  93. package/dist/admin/components/dashboard/recent-activity.svelte +53 -75
  94. package/dist/admin/components/dashboard/recent-entries.svelte +94 -0
  95. package/dist/admin/components/dashboard/recent-entries.svelte.d.ts +18 -0
  96. package/dist/admin/components/dashboard/stat-card.svelte +2 -2
  97. package/dist/admin/components/dashboard/tip-of-the-day.svelte +109 -0
  98. package/dist/admin/components/dashboard/tip-of-the-day.svelte.d.ts +3 -0
  99. package/dist/admin/components/dashboard/welcome-header.svelte +45 -0
  100. package/dist/admin/components/dashboard/welcome-header.svelte.d.ts +3 -0
  101. package/dist/admin/components/fields/{array-field.svelte → blocks-field.svelte} +4 -4
  102. package/dist/admin/components/fields/{array-field.svelte.d.ts → blocks-field.svelte.d.ts} +5 -5
  103. package/dist/admin/components/fields/content-field.svelte +27 -0
  104. package/dist/admin/components/fields/content-field.svelte.d.ts +31 -0
  105. package/dist/admin/components/fields/field-renderer.svelte +9 -7
  106. package/dist/admin/components/fields/image-field.svelte +2 -2
  107. package/dist/admin/components/fields/media-field.svelte +2 -2
  108. package/dist/admin/components/fields/seo-field.svelte +205 -25
  109. package/dist/admin/components/fields/simple-array-field.svelte +289 -0
  110. package/dist/admin/components/fields/simple-array-field.svelte.d.ts +30 -0
  111. package/dist/admin/components/fields/slug-field.svelte +3 -2
  112. package/dist/admin/components/fields/standalone-field-renderer.svelte +148 -0
  113. package/dist/admin/components/fields/standalone-field-renderer.svelte.d.ts +9 -0
  114. package/dist/admin/components/fields/text-field-wrapper.svelte +147 -3
  115. package/dist/admin/components/fields/text-field-wrapper.svelte.d.ts +2 -2
  116. package/dist/admin/components/fields/url-field.svelte +5 -4
  117. package/dist/admin/components/layout/app-sidebar.svelte +27 -24
  118. package/dist/admin/components/layout/lang.d.ts +6 -0
  119. package/dist/admin/components/layout/lang.js +13 -1
  120. package/dist/admin/components/layout/layout-renderer.svelte +352 -0
  121. package/dist/admin/components/layout/layout-renderer.svelte.d.ts +14 -0
  122. package/dist/admin/components/layout/nav-breadcrumbs.svelte +4 -4
  123. package/dist/admin/components/layout/nav-collections.svelte +65 -36
  124. package/dist/admin/components/layout/nav-footer.svelte +38 -0
  125. package/dist/admin/components/layout/nav-footer.svelte.d.ts +3 -0
  126. package/dist/admin/components/layout/nav-forms.svelte +55 -30
  127. package/dist/admin/components/layout/nav-main.svelte +14 -52
  128. package/dist/admin/components/layout/nav-search.svelte +4 -3
  129. package/dist/admin/components/layout/nav-singletons.svelte +59 -17
  130. package/dist/admin/components/layout/nav-singletons.svelte.d.ts +17 -8
  131. package/dist/admin/components/layout/site-header.svelte +74 -13
  132. package/dist/admin/components/media/alt-input.svelte +32 -22
  133. package/dist/admin/components/media/bulk-action-bar.svelte +139 -150
  134. package/dist/admin/components/media/file/file-details.svelte +299 -217
  135. package/dist/admin/components/media/file/file-miniature.svelte +54 -41
  136. package/dist/admin/components/media/file/file-miniature.svelte.d.ts +1 -0
  137. package/dist/admin/components/media/file/file-preview.svelte +1 -1
  138. package/dist/admin/components/media/file-upload.svelte +24 -26
  139. package/dist/admin/components/media/files-list.svelte +112 -40
  140. package/dist/admin/components/media/files-list.svelte.d.ts +2 -0
  141. package/dist/admin/components/media/focal-point-input.svelte +122 -26
  142. package/dist/admin/components/media/media-library.svelte +127 -70
  143. package/dist/admin/components/media/media-search.svelte +6 -6
  144. package/dist/admin/components/media/media-sort.svelte +3 -1
  145. package/dist/admin/components/media/multi-file-summary.svelte +88 -68
  146. package/dist/admin/components/media/tag-combobox.svelte +141 -66
  147. package/dist/admin/components/media/tag-combobox.svelte.d.ts +1 -0
  148. package/dist/admin/components/media/tag-sidebar.svelte +139 -121
  149. package/dist/admin/components/tiptap/FigureNodeView.svelte +144 -15
  150. package/dist/admin/components/tiptap/InlineBlockNodeView.svelte +254 -0
  151. package/dist/admin/components/tiptap/InlineBlockNodeView.svelte.d.ts +4 -0
  152. package/dist/admin/components/tiptap/SlashCommandPopup.svelte +212 -0
  153. package/dist/admin/components/tiptap/SlashCommandPopup.svelte.d.ts +8 -0
  154. package/dist/admin/components/tiptap/content-editor.svelte +280 -0
  155. package/dist/admin/components/tiptap/content-editor.svelte.d.ts +9 -0
  156. package/dist/admin/components/tiptap/editor-toolbar.svelte +230 -0
  157. package/dist/admin/components/tiptap/editor-toolbar.svelte.d.ts +16 -0
  158. package/dist/admin/components/tiptap/heading-a11y-plugin.d.ts +2 -0
  159. package/dist/admin/components/tiptap/heading-a11y-plugin.js +67 -0
  160. package/dist/admin/components/tiptap/image-dialog.svelte +172 -11
  161. package/dist/admin/components/tiptap/inline-block-node.d.ts +19 -0
  162. package/dist/admin/components/tiptap/inline-block-node.js +98 -0
  163. package/dist/admin/components/tiptap/link-dialog.svelte +9 -4
  164. package/dist/admin/components/tiptap/slash-command.d.ts +17 -0
  165. package/dist/admin/components/tiptap/slash-command.js +181 -0
  166. package/dist/admin/components/tiptap/structured-content-utils.d.ts +21 -0
  167. package/dist/admin/components/tiptap/structured-content-utils.js +150 -0
  168. package/dist/admin/components/tiptap/tiptap-editor.svelte +18 -190
  169. package/dist/admin/email/invite-template.d.ts +8 -0
  170. package/dist/admin/email/invite-template.js +99 -0
  171. package/dist/admin/email/reset-password-template.d.ts +7 -0
  172. package/dist/admin/email/reset-password-template.js +96 -0
  173. package/dist/admin/remote/ai.remote.d.ts +1 -0
  174. package/dist/admin/remote/ai.remote.js +4 -1
  175. package/dist/admin/remote/entry.remote.d.ts +9 -0
  176. package/dist/admin/remote/entry.remote.js +58 -8
  177. package/dist/admin/remote/preview.remote.js +2 -1
  178. package/dist/admin/shared/password-schema.d.ts +5 -0
  179. package/dist/admin/shared/password-schema.js +10 -0
  180. package/dist/admin/state/content-language.svelte.d.ts +3 -0
  181. package/dist/admin/state/content-language.svelte.js +8 -0
  182. package/dist/admin/styles/admin.css +1530 -151
  183. package/dist/admin/utils/formatDate.d.ts +1 -0
  184. package/dist/admin/utils/formatDate.js +8 -0
  185. package/dist/admin/utils/roleLabel.d.ts +2 -0
  186. package/dist/admin/utils/roleLabel.js +13 -0
  187. package/dist/admin/utils/translationStatus.d.ts +17 -0
  188. package/dist/admin/utils/translationStatus.js +134 -0
  189. package/dist/ai-claude/index.d.ts +2 -0
  190. package/dist/ai-claude/index.js +56 -0
  191. package/dist/cms/runtime/api.d.ts +6 -1
  192. package/dist/cms/runtime/api.js +3 -0
  193. package/dist/cms/runtime/schemas.d.ts +9 -1
  194. package/dist/cms/runtime/schemas.js +8 -0
  195. package/dist/cms/runtime/types.d.ts +82 -10
  196. package/dist/cms/runtime/types.js +4 -0
  197. package/dist/components/ui/accordion/accordion.stories.svelte +39 -0
  198. package/dist/components/ui/accordion/accordion.stories.svelte.d.ts +27 -0
  199. package/dist/components/ui/alert/alert.stories.svelte +53 -0
  200. package/dist/components/ui/alert/alert.stories.svelte.d.ts +27 -0
  201. package/dist/components/ui/alert/alert.svelte +5 -0
  202. package/dist/components/ui/alert/alert.svelte.d.ts +9 -0
  203. package/dist/components/ui/avatar/avatar.stories.svelte +16 -0
  204. package/dist/components/ui/avatar/avatar.stories.svelte.d.ts +27 -0
  205. package/dist/components/ui/badge/badge.stories.svelte +33 -0
  206. package/dist/components/ui/badge/badge.stories.svelte.d.ts +27 -0
  207. package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte +33 -0
  208. package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte.d.ts +27 -0
  209. package/dist/components/ui/button/button.stories.svelte +43 -0
  210. package/dist/components/ui/button/button.stories.svelte.d.ts +27 -0
  211. package/dist/components/ui/button/button.svelte +1 -2
  212. package/dist/components/ui/button/button.svelte.d.ts +0 -3
  213. package/dist/components/ui/button-group/button-group-separator.svelte.d.ts +1 -1
  214. package/dist/components/ui/card/card.stories.svelte +42 -0
  215. package/dist/components/ui/card/card.stories.svelte.d.ts +27 -0
  216. package/dist/components/ui/command/command.stories.svelte +51 -0
  217. package/dist/components/ui/command/command.stories.svelte.d.ts +27 -0
  218. package/dist/components/ui/dialog/dialog.stories.svelte +29 -0
  219. package/dist/components/ui/dialog/dialog.stories.svelte.d.ts +27 -0
  220. package/dist/components/ui/field/field-label.svelte.d.ts +1 -1
  221. package/dist/components/ui/field/field.stories.svelte +21 -0
  222. package/dist/components/ui/field/field.stories.svelte.d.ts +27 -0
  223. package/dist/components/ui/input/input.stories.svelte +40 -0
  224. package/dist/components/ui/input/input.stories.svelte.d.ts +27 -0
  225. package/dist/components/ui/input/input.svelte +2 -4
  226. package/dist/components/ui/item/item-separator.svelte.d.ts +1 -1
  227. package/dist/components/ui/label/label.stories.svelte +20 -0
  228. package/dist/components/ui/label/label.stories.svelte.d.ts +27 -0
  229. package/dist/components/ui/popover/popover.stories.svelte +29 -0
  230. package/dist/components/ui/popover/popover.stories.svelte.d.ts +27 -0
  231. package/dist/components/ui/select/select-group-heading.svelte.d.ts +1 -1
  232. package/dist/components/ui/select/select.stories.svelte +23 -0
  233. package/dist/components/ui/select/select.stories.svelte.d.ts +27 -0
  234. package/dist/components/ui/separator/separator.stories.svelte +24 -0
  235. package/dist/components/ui/separator/separator.stories.svelte.d.ts +27 -0
  236. package/dist/components/ui/sheet/sheet.stories.svelte +29 -0
  237. package/dist/components/ui/sheet/sheet.stories.svelte.d.ts +27 -0
  238. package/dist/components/ui/sidebar/sidebar-group.svelte +3 -3
  239. package/dist/components/ui/sidebar/sidebar-group.svelte.d.ts +2 -2
  240. package/dist/components/ui/sidebar/sidebar-menu-button.svelte +28 -30
  241. package/dist/components/ui/sidebar/sidebar-menu-button.svelte.d.ts +7 -7
  242. package/dist/components/ui/sidebar/sidebar-separator.svelte.d.ts +1 -1
  243. package/dist/components/ui/sidebar/sidebar-trigger.svelte +4 -4
  244. package/dist/components/ui/sonner/sonner.stories.svelte +22 -0
  245. package/dist/components/ui/sonner/sonner.stories.svelte.d.ts +26 -0
  246. package/dist/components/ui/sonner/sonner.svelte +8 -2
  247. package/dist/components/ui/sonner/toast-demo.svelte +29 -0
  248. package/dist/components/ui/sonner/toast-demo.svelte.d.ts +6 -0
  249. package/dist/components/ui/textarea/textarea.stories.svelte +22 -0
  250. package/dist/components/ui/textarea/textarea.stories.svelte.d.ts +27 -0
  251. package/dist/components/ui/textarea/textarea.svelte +0 -2
  252. package/dist/components/ui/toggle/toggle.stories.svelte +22 -0
  253. package/dist/components/ui/toggle/toggle.stories.svelte.d.ts +27 -0
  254. package/dist/components/ui/toggle-group/toggle-group.stories.svelte +17 -0
  255. package/dist/components/ui/toggle-group/toggle-group.stories.svelte.d.ts +27 -0
  256. package/dist/components/ui/tooltip/tooltip.stories.svelte +26 -0
  257. package/dist/components/ui/tooltip/tooltip.stories.svelte.d.ts +27 -0
  258. package/dist/core/fields/fieldSchemaToTs.d.ts +1 -0
  259. package/dist/core/fields/fieldSchemaToTs.js +133 -1
  260. package/dist/core/fields/layoutUtils.d.ts +17 -0
  261. package/dist/core/fields/layoutUtils.js +149 -0
  262. package/dist/core/fields/structuredToHtml.d.ts +9 -0
  263. package/dist/core/fields/structuredToHtml.js +161 -0
  264. package/dist/core/server/entries/operations/create.js +2 -1
  265. package/dist/core/server/entries/operations/get.js +10 -7
  266. package/dist/core/server/entries/operations/update.d.ts +3 -0
  267. package/dist/core/server/entries/operations/update.js +30 -2
  268. package/dist/core/server/fields/queryStructuredContent.d.ts +15 -0
  269. package/dist/core/server/fields/queryStructuredContent.js +65 -0
  270. package/dist/core/server/fields/resolveImageFields.js +51 -2
  271. package/dist/core/server/fields/resolveRelationFields.js +2 -2
  272. package/dist/core/server/fields/resolveRichtextLinks.js +80 -13
  273. package/dist/core/server/fields/resolveUrlFields.js +57 -6
  274. package/dist/core/server/fields/slugResolver.d.ts +10 -0
  275. package/dist/core/server/fields/slugResolver.js +34 -0
  276. package/dist/core/server/generator/fields.js +15 -4
  277. package/dist/core/server/generator/generator.js +3 -2
  278. package/dist/db-postgres/index.js +10 -6
  279. package/dist/files-local/index.js +126 -64
  280. package/dist/server/auth.d.ts +5 -0
  281. package/dist/server/auth.js +12 -1
  282. package/dist/sveltekit/components/structured-content.svelte +204 -0
  283. package/dist/sveltekit/components/structured-content.svelte.d.ts +21 -0
  284. package/dist/sveltekit/config.d.ts +13 -3
  285. package/dist/sveltekit/index.d.ts +3 -0
  286. package/dist/sveltekit/index.js +3 -0
  287. package/dist/sveltekit/server/handle.js +1 -0
  288. package/dist/types/config.d.ts +3 -0
  289. package/dist/types/entries.d.ts +3 -0
  290. package/dist/types/fields.d.ts +19 -2
  291. package/dist/types/index.d.ts +2 -0
  292. package/dist/types/index.js +2 -0
  293. package/dist/types/layout.d.ts +54 -0
  294. package/dist/types/layout.js +6 -0
  295. package/dist/types/structured-content.d.ts +63 -0
  296. package/dist/types/structured-content.js +1 -0
  297. package/dist/updates/0.1.5/index.d.ts +2 -0
  298. package/dist/updates/0.1.5/index.js +18 -0
  299. package/dist/updates/0.2.0/index.d.ts +2 -0
  300. package/dist/updates/0.2.0/index.js +11 -0
  301. package/dist/updates/0.2.2/index.d.ts +2 -0
  302. package/dist/updates/0.2.2/index.js +13 -0
  303. package/dist/updates/0.5.0/index.d.ts +2 -0
  304. package/dist/updates/0.5.0/index.js +14 -0
  305. package/dist/updates/0.5.1/index.d.ts +2 -0
  306. package/dist/updates/0.5.1/index.js +17 -0
  307. package/dist/updates/index.js +6 -1
  308. package/package.json +16 -9
  309. package/dist/admin/components/dashboard/updates-banner.svelte +0 -170
  310. package/dist/admin/components/dashboard/updates-banner.svelte.d.ts +0 -3
@@ -0,0 +1,204 @@
1
+ <script lang="ts" module>
2
+ import type { SCNode, SCMark, StructuredContentDoc, SCInlineBlockAttrs } from '../../types/structured-content.js';
3
+ import type { Snippet } from 'svelte';
4
+
5
+ export interface StructuredContentProps {
6
+ doc: StructuredContentDoc;
7
+ class?: string;
8
+ /** Override rendering for inline blocks. Receives blockType, blockData, blockId. */
9
+ inlineBlock?: Snippet<[string, Record<string, unknown>, string]>;
10
+ /** Override rendering for figure nodes. Receives node attrs. */
11
+ figure?: Snippet<[Record<string, unknown>]>;
12
+ /** Override rendering for video nodes. Receives node attrs. */
13
+ video?: Snippet<[Record<string, unknown>]>;
14
+ /** Override rendering for heading nodes. Receives level and children snippet. */
15
+ heading?: Snippet<[number, Snippet]>;
16
+ /** Override rendering for paragraph nodes. Receives children snippet. */
17
+ paragraph?: Snippet<[Snippet]>;
18
+ /** Override rendering for code block nodes. Receives language and text content. */
19
+ codeBlock?: Snippet<[string | undefined, string]>;
20
+ }
21
+ </script>
22
+
23
+ <script lang="ts">
24
+ import Image from './image.svelte';
25
+
26
+ let {
27
+ doc,
28
+ class: className,
29
+ inlineBlock: inlineBlockSnippet,
30
+ figure: figureSnippet,
31
+ video: videoSnippet,
32
+ heading: headingSnippet,
33
+ paragraph: paragraphSnippet,
34
+ codeBlock: codeBlockSnippet
35
+ }: StructuredContentProps = $props();
36
+
37
+ function getTextContent(node: SCNode): string {
38
+ if (node.type === 'text') return node.text ?? '';
39
+ return node.content?.map(getTextContent).join('') ?? '';
40
+ }
41
+ </script>
42
+
43
+ {#snippet renderMark(text: string, marks: SCMark[], index: number)}
44
+ {#if index >= marks.length}
45
+ {text}
46
+ {:else}
47
+ {@const mark = marks[index]}
48
+ {#if mark.type === 'bold'}
49
+ <strong>{@render renderMark(text, marks, index + 1)}</strong>
50
+ {:else if mark.type === 'italic'}
51
+ <em>{@render renderMark(text, marks, index + 1)}</em>
52
+ {:else if mark.type === 'underline'}
53
+ <u>{@render renderMark(text, marks, index + 1)}</u>
54
+ {:else if mark.type === 'strike'}
55
+ <s>{@render renderMark(text, marks, index + 1)}</s>
56
+ {:else if mark.type === 'code'}
57
+ <code>{@render renderMark(text, marks, index + 1)}</code>
58
+ {:else if mark.type === 'highlight'}
59
+ <mark>{@render renderMark(text, marks, index + 1)}</mark>
60
+ {:else if mark.type === 'link'}
61
+ {@const href = (mark.attrs?.href as string) ?? ''}
62
+ {@const target = mark.attrs?.target as string | undefined}
63
+ {@const title = mark.attrs?.title as string | undefined}
64
+ {@const ariaLabel = mark.attrs?.['aria-label'] as string | undefined}
65
+ <a
66
+ {href}
67
+ target={target ?? undefined}
68
+ rel={target === '_blank' ? 'noopener noreferrer' : undefined}
69
+ {title}
70
+ aria-label={ariaLabel ?? undefined}
71
+ >{@render renderMark(text, marks, index + 1)}</a>
72
+ {:else}
73
+ {@render renderMark(text, marks, index + 1)}
74
+ {/if}
75
+ {/if}
76
+ {/snippet}
77
+
78
+ {#snippet renderNode(node: SCNode)}
79
+ {#if node.type === 'text'}
80
+ {#if node.marks?.length}
81
+ {@render renderMark(node.text ?? '', node.marks, 0)}
82
+ {:else}
83
+ {node.text}
84
+ {/if}
85
+ {:else if node.type === 'paragraph'}
86
+ {#if paragraphSnippet}
87
+ {@render paragraphSnippet(renderChildren)}
88
+ {:else}
89
+ <p>{@render renderChildren()}</p>
90
+ {/if}
91
+ {:else if node.type === 'heading'}
92
+ {@const level = (node.attrs?.level as number) ?? 2}
93
+ {#if headingSnippet}
94
+ {@render headingSnippet(level, renderChildren)}
95
+ {:else if level === 2}
96
+ <h2>{@render renderChildren()}</h2>
97
+ {:else if level === 3}
98
+ <h3>{@render renderChildren()}</h3>
99
+ {/if}
100
+ {:else if node.type === 'blockquote'}
101
+ <blockquote>{@render renderChildren()}</blockquote>
102
+ {:else if node.type === 'bulletList'}
103
+ <ul>{@render renderChildren()}</ul>
104
+ {:else if node.type === 'orderedList'}
105
+ <ol>{@render renderChildren()}</ol>
106
+ {:else if node.type === 'listItem'}
107
+ <li>{@render renderChildren()}</li>
108
+ {:else if node.type === 'codeBlock'}
109
+ {#if codeBlockSnippet}
110
+ {@render codeBlockSnippet(node.attrs?.language as string | undefined, getTextContent(node))}
111
+ {:else}
112
+ {@const lang = node.attrs?.language as string | undefined}
113
+ <pre><code class={lang ? `language-${lang}` : undefined}>{@render renderChildren()}</code></pre>
114
+ {/if}
115
+ {:else if node.type === 'horizontalRule'}
116
+ <hr>
117
+ {:else if node.type === 'hardBreak'}
118
+ <br>
119
+ {:else if node.type === 'figure'}
120
+ {#if figureSnippet}
121
+ {@render figureSnippet(node.attrs ?? {})}
122
+ {:else}
123
+ {@const attrs = node.attrs ?? {}}
124
+ {@const rawMedia = attrs._media as { data: import('../../types/media.js').MediaFile; styles?: Record<string, import('../../types/media.js').ImageStyle>; blurDataUrl?: string | null } | undefined}
125
+ {@const figMedia = rawMedia?.data ? { data: rawMedia.data, styles: rawMedia.styles ?? {}, blurDataUrl: rawMedia.blurDataUrl } : undefined}
126
+ <figure>
127
+ {#if figMedia}
128
+ <Image data={figMedia} alt={attrs.alt as string ?? figMedia.data.alt ?? ''} />
129
+ {:else}
130
+ <img
131
+ src={attrs.src as string}
132
+ alt={(attrs.alt as string) ?? ''}
133
+ width={attrs.width as number ?? undefined}
134
+ height={attrs.height as number ?? undefined}
135
+ loading="lazy"
136
+ >
137
+ {/if}
138
+ {#if attrs.caption}
139
+ <figcaption>{attrs.caption}</figcaption>
140
+ {/if}
141
+ </figure>
142
+ {/if}
143
+ {:else if node.type === 'image'}
144
+ {@const attrs = node.attrs ?? {}}
145
+ {@const rawImgMedia = attrs._media as { data: import('../../types/media.js').MediaFile; styles?: Record<string, import('../../types/media.js').ImageStyle>; blurDataUrl?: string | null } | undefined}
146
+ {@const imgMedia = rawImgMedia?.data ? { data: rawImgMedia.data, styles: rawImgMedia.styles ?? {}, blurDataUrl: rawImgMedia.blurDataUrl } : undefined}
147
+ {#if imgMedia}
148
+ <Image data={imgMedia} alt={attrs.alt as string ?? imgMedia.data.alt ?? ''} />
149
+ {:else}
150
+ <img
151
+ src={attrs.src as string}
152
+ alt={(attrs.alt as string) ?? ''}
153
+ width={attrs.width as number ?? undefined}
154
+ height={attrs.height as number ?? undefined}
155
+ loading="lazy"
156
+ >
157
+ {/if}
158
+ {:else if node.type === 'video'}
159
+ {#if videoSnippet}
160
+ {@render videoSnippet(node.attrs ?? {})}
161
+ {:else}
162
+ {@const attrs = node.attrs ?? {}}
163
+ <video
164
+ controls
165
+ poster={attrs.poster as string ?? undefined}
166
+ width={attrs.width as number ?? undefined}
167
+ height={attrs.height as number ?? undefined}
168
+ >
169
+ <source src={attrs.src as string}>
170
+ </video>
171
+ {/if}
172
+ {:else if node.type === 'table'}
173
+ <table>{@render renderChildren()}</table>
174
+ {:else if node.type === 'tableRow'}
175
+ <tr>{@render renderChildren()}</tr>
176
+ {:else if node.type === 'tableCell'}
177
+ <td>{@render renderChildren()}</td>
178
+ {:else if node.type === 'tableHeader'}
179
+ <th>{@render renderChildren()}</th>
180
+ {:else if node.type === 'inlineBlock'}
181
+ {#if inlineBlockSnippet}
182
+ {@const attrs = node.attrs as unknown as SCInlineBlockAttrs}
183
+ {@render inlineBlockSnippet(attrs.blockType, attrs.blockData, attrs.blockId)}
184
+ {/if}
185
+ {:else}
186
+ {@render renderChildren()}
187
+ {/if}
188
+
189
+ {#snippet renderChildren()}
190
+ {#if node.content}
191
+ {#each node.content as child}
192
+ {@render renderNode(child)}
193
+ {/each}
194
+ {/if}
195
+ {/snippet}
196
+ {/snippet}
197
+
198
+ {#if doc?.content}
199
+ <div class={className}>
200
+ {#each doc.content as node}
201
+ {@render renderNode(node)}
202
+ {/each}
203
+ </div>
204
+ {/if}
@@ -0,0 +1,21 @@
1
+ import type { StructuredContentDoc } from '../../types/structured-content.js';
2
+ import type { Snippet } from 'svelte';
3
+ export interface StructuredContentProps {
4
+ doc: StructuredContentDoc;
5
+ class?: string;
6
+ /** Override rendering for inline blocks. Receives blockType, blockData, blockId. */
7
+ inlineBlock?: Snippet<[string, Record<string, unknown>, string]>;
8
+ /** Override rendering for figure nodes. Receives node attrs. */
9
+ figure?: Snippet<[Record<string, unknown>]>;
10
+ /** Override rendering for video nodes. Receives node attrs. */
11
+ video?: Snippet<[Record<string, unknown>]>;
12
+ /** Override rendering for heading nodes. Receives level and children snippet. */
13
+ heading?: Snippet<[number, Snippet]>;
14
+ /** Override rendering for paragraph nodes. Receives children snippet. */
15
+ paragraph?: Snippet<[Snippet]>;
16
+ /** Override rendering for code block nodes. Receives language and text content. */
17
+ codeBlock?: Snippet<[string | undefined, string]>;
18
+ }
19
+ declare const StructuredContent: import("svelte").Component<StructuredContentProps, {}, "">;
20
+ type StructuredContent = ReturnType<typeof StructuredContent>;
21
+ export default StructuredContent;
@@ -1,10 +1,20 @@
1
1
  import type { CMSConfig } from '../types/cms.js';
2
2
  import type { CollectionConfig } from '../types/collections.js';
3
3
  import type { SingleConfig } from '../types/singles.js';
4
- import type { ObjectField } from '../types/fields.js';
4
+ import type { Field, ObjectField } from '../types/fields.js';
5
5
  import type { FormConfig } from '../types/forms.js';
6
+ import type { Layout } from '../types/layout.js';
7
+ type CollectionInput = Omit<CollectionConfig, 'fields'> & {
8
+ fields: Field[];
9
+ layout?: Layout;
10
+ };
11
+ type SingleInput = Omit<SingleConfig, 'fields'> & {
12
+ fields: Field[];
13
+ layout?: Layout;
14
+ };
6
15
  export declare function defineConfig(config: CMSConfig): CMSConfig;
7
- export declare function defineCollection(config: CollectionConfig): CollectionConfig;
8
- export declare function defineSingle(config: SingleConfig): SingleConfig;
16
+ export declare function defineCollection(config: CollectionInput): CollectionConfig;
17
+ export declare function defineSingle(config: SingleInput): SingleConfig;
9
18
  export declare function defineForm(config: FormConfig): FormConfig;
10
19
  export declare function defineObject(config: Omit<ObjectField, 'type'>): ObjectField;
20
+ export {};
@@ -5,5 +5,8 @@ export { default as HybridTarget } from './components/hybrid-target.svelte';
5
5
  export { default as Image } from './components/image.svelte';
6
6
  export { default as Video } from './components/video.svelte';
7
7
  export { default as Media } from './components/media.svelte';
8
+ export { default as StructuredContent } from './components/structured-content.svelte';
8
9
  export { enableHybridEditing } from './components/hybrid-context.js';
9
10
  export { getLink, isImageFieldData, isVideoFieldData } from './utils/index.js';
11
+ export { structuredToHtml } from '../core/fields/structuredToHtml.js';
12
+ export { extractBlocks, extractInlineBlocks, extractText, extractMediaRefs } from '../core/server/fields/queryStructuredContent.js';
@@ -5,5 +5,8 @@ export { default as HybridTarget } from './components/hybrid-target.svelte';
5
5
  export { default as Image } from './components/image.svelte';
6
6
  export { default as Video } from './components/video.svelte';
7
7
  export { default as Media } from './components/media.svelte';
8
+ export { default as StructuredContent } from './components/structured-content.svelte';
8
9
  export { enableHybridEditing } from './components/hybrid-context.js';
9
10
  export { getLink, isImageFieldData, isVideoFieldData } from './utils/index.js';
11
+ export { structuredToHtml } from '../core/fields/structuredToHtml.js';
12
+ export { extractBlocks, extractInlineBlocks, extractText, extractMediaRefs } from '../core/server/fields/queryStructuredContent.js';
@@ -10,6 +10,7 @@ const adminGuard = async ({ event, resolve }) => {
10
10
  !event.url.pathname.startsWith('/api/admin/login') &&
11
11
  !event.url.pathname.startsWith('/admin/accept-invite') &&
12
12
  !event.url.pathname.startsWith('/admin/api/accept-invite') &&
13
+ !event.url.pathname.startsWith('/admin/reset-password') &&
13
14
  (!user || !session)) {
14
15
  setFlash({
15
16
  message: 'You must be logged in to access the admin panel.',
@@ -1,8 +1,11 @@
1
1
  import type { Field } from './fields.js';
2
2
  import type { Icon } from '@tabler/icons-svelte';
3
+ import type { Layout } from './layout.js';
3
4
  export interface ConfigBase {
4
5
  sidebarIcon?: Icon;
5
6
  slug: string;
6
7
  previewUrl?: string;
7
8
  fields: Field[];
9
+ layout?: Layout;
10
+ slugField?: string;
8
11
  }
@@ -77,6 +77,7 @@ export interface GetDbEntriesOptions extends PaginationOptions {
77
77
  slug?: string;
78
78
  type?: EntryType;
79
79
  onlyArchived?: boolean;
80
+ includeArchived?: boolean;
80
81
  }
81
82
  export interface GetDbEntryOptions {
82
83
  id?: string;
@@ -88,10 +89,12 @@ export interface GetRawEntriesOptions extends PaginationOptions {
88
89
  ids?: string[];
89
90
  slug?: string;
90
91
  onlyArchived?: boolean;
92
+ includeArchived?: boolean;
91
93
  }
92
94
  export interface getRawEntryOptions {
93
95
  id?: string;
94
96
  slug?: string;
97
+ includeArchived?: boolean;
95
98
  }
96
99
  export interface GetEntriesOptions {
97
100
  ids?: string[];
@@ -1,7 +1,8 @@
1
1
  import type { FormatEnum } from 'sharp';
2
2
  import type { ImageStyle, MediaFile } from './media.js';
3
3
  import type { Localized } from './languages.js';
4
- export type FieldType = 'text' | 'richtext' | 'number' | 'boolean' | 'date' | 'datetime' | 'file' | 'image' | 'media' | 'select' | 'radio' | 'checkboxes' | 'relation' | 'object' | 'array' | 'slug' | 'seo' | 'url';
4
+ import type { StructuredContentDoc } from './structured-content.js';
5
+ export type FieldType = 'text' | 'richtext' | 'content' | 'number' | 'boolean' | 'date' | 'datetime' | 'file' | 'image' | 'media' | 'select' | 'radio' | 'checkboxes' | 'relation' | 'object' | 'array' | 'blocks' | 'slug' | 'seo' | 'url';
5
6
  export interface BaseField {
6
7
  slug: string;
7
8
  label?: Localized;
@@ -25,6 +26,11 @@ export interface RichtextField extends BaseField {
25
26
  allowedFormats?: string[];
26
27
  defaultValue?: string;
27
28
  }
29
+ export interface ContentField extends BaseField {
30
+ type: 'content';
31
+ inlineBlocks?: ObjectField[];
32
+ defaultValue?: StructuredContentDoc;
33
+ }
28
34
  export interface NumberField extends BaseField {
29
35
  type: 'number';
30
36
  min?: number;
@@ -141,8 +147,16 @@ export interface ObjectFieldData {
141
147
  slug?: string;
142
148
  data: Record<string, unknown>;
143
149
  }
150
+ export type SimpleArrayItemType = 'text' | 'number' | 'url';
144
151
  export interface ArrayField extends BaseField {
145
152
  type: 'array';
153
+ of: SimpleArrayItemType;
154
+ minItems?: number;
155
+ maxItems?: number;
156
+ defaultValue?: (string | number | UrlFieldData)[];
157
+ }
158
+ export interface BlocksField extends BaseField {
159
+ type: 'blocks';
146
160
  of: ObjectField[];
147
161
  minItems?: number;
148
162
  maxItems?: number;
@@ -152,10 +166,13 @@ export interface ArrayField extends BaseField {
152
166
  export interface SlugField extends BaseField {
153
167
  type: 'slug';
154
168
  pattern?: string;
169
+ sourceField?: string;
155
170
  defaultValue?: string;
156
171
  }
157
172
  export interface SeoField extends BaseField {
158
173
  type: 'seo';
174
+ slugSource?: string;
175
+ titleSource?: string;
159
176
  }
160
177
  export interface SeoFieldData {
161
178
  slug: string;
@@ -178,4 +195,4 @@ export type UrlFieldData = {
178
195
  text?: Record<string, string>;
179
196
  newTab?: boolean;
180
197
  };
181
- export type Field = TextField | RichtextField | NumberField | BooleanField | DateField | DateTimeField | FileField | ImageField | MediaField | SelectField | RadioField | CheckboxesField | RelationField | ObjectField | ArrayField | SlugField | SeoField | UrlField;
198
+ export type Field = TextField | RichtextField | ContentField | NumberField | BooleanField | DateField | DateTimeField | FileField | ImageField | MediaField | SelectField | RadioField | CheckboxesField | RelationField | ObjectField | ArrayField | BlocksField | SlugField | SeoField | UrlField;
@@ -1,4 +1,5 @@
1
1
  export * from './fields.js';
2
+ export { type StructuredContentDoc, type SCNode, type SCMark, type SCInlineBlockAttrs, type SCFigureAttrs, type SCVideoAttrs } from './structured-content.js';
2
3
  export { type MediaFile, type MediaFileType, type ImageStyle, type MediaTag } from './media.js';
3
4
  export { type ConsentLogData } from './consent.js';
4
5
  export { type Entry, type EntryType, type EntryStatus, type EntryVersionStatus } from './entries.js';
@@ -8,3 +9,4 @@ export { type SingleConfig } from './singles.js';
8
9
  export { type FormConfig, type FormSubmission } from './forms.js';
9
10
  export { type CMSConfig } from './cms.js';
10
11
  export { type Language, type Localized } from './languages.js';
12
+ export { type Layout, type LayoutNode, type LayoutPreset, type LayoutNodeType, type ColumnRatio, type SectionNode, type ColumnsNode, type CardNode, type AccordionNode, type StackNode } from './layout.js';
@@ -1,4 +1,5 @@
1
1
  export * from './fields.js';
2
+ export {} from './structured-content.js';
2
3
  export {} from './media.js';
3
4
  export {} from './consent.js';
4
5
  export {} from './entries.js';
@@ -8,3 +9,4 @@ export {} from './singles.js';
8
9
  export {} from './forms.js';
9
10
  export {} from './cms.js';
10
11
  export {} from './languages.js';
12
+ export {} from './layout.js';
@@ -0,0 +1,54 @@
1
+ import type { Localized } from './languages.js';
2
+ export type Layout = LayoutPreset | LayoutNode[];
3
+ export type LayoutPreset = 'sidebar-right' | 'two-column' | {
4
+ preset: 'sidebar-right';
5
+ sidebar: string[];
6
+ } | {
7
+ preset: 'two-column';
8
+ left?: string[];
9
+ };
10
+ export type LayoutNodeType = 'section' | 'columns' | 'card' | 'accordion' | 'stack';
11
+ export type ColumnRatio = '1fr 1fr' | '2fr 1fr' | '1fr 2fr' | '3fr 1fr' | '1fr 3fr' | '1fr 1fr 1fr';
12
+ interface LayoutNodeBase {
13
+ type: LayoutNodeType;
14
+ label?: Localized;
15
+ icon?: string;
16
+ }
17
+ export interface SectionNode extends LayoutNodeBase {
18
+ type: 'section';
19
+ label: Localized;
20
+ fields?: string[];
21
+ children?: LayoutNode[];
22
+ }
23
+ export interface ColumnsNode extends LayoutNodeBase {
24
+ type: 'columns';
25
+ ratio: ColumnRatio;
26
+ children: LayoutNode[];
27
+ }
28
+ export interface CardNode extends LayoutNodeBase {
29
+ type: 'card';
30
+ label: Localized;
31
+ fields?: string[];
32
+ children?: LayoutNode[];
33
+ autoGrid?: boolean;
34
+ }
35
+ export interface AccordionNode extends LayoutNodeBase {
36
+ type: 'accordion';
37
+ label: Localized;
38
+ defaultOpen?: boolean;
39
+ fields?: string[];
40
+ children?: LayoutNode[];
41
+ }
42
+ export interface StackNode extends LayoutNodeBase {
43
+ type: 'stack';
44
+ fields?: string[];
45
+ children?: LayoutNode[];
46
+ }
47
+ export type LayoutNode = SectionNode | ColumnsNode | CardNode | AccordionNode | StackNode;
48
+ export declare function isLayoutLeaf(node: LayoutNode): node is LayoutNode & {
49
+ fields: string[];
50
+ };
51
+ export declare function isLayoutBranch(node: LayoutNode): node is LayoutNode & {
52
+ children: LayoutNode[];
53
+ };
54
+ export {};
@@ -0,0 +1,6 @@
1
+ export function isLayoutLeaf(node) {
2
+ return 'fields' in node && Array.isArray(node.fields);
3
+ }
4
+ export function isLayoutBranch(node) {
5
+ return 'children' in node && Array.isArray(node.children);
6
+ }
@@ -0,0 +1,63 @@
1
+ export type SCMarkType = 'bold' | 'italic' | 'underline' | 'strike' | 'code' | 'link' | 'highlight';
2
+ export interface SCMark {
3
+ type: SCMarkType;
4
+ attrs?: Record<string, unknown>;
5
+ }
6
+ export interface SCLinkMark extends SCMark {
7
+ type: 'link';
8
+ attrs: {
9
+ href: string;
10
+ target?: string;
11
+ title?: string;
12
+ 'aria-label'?: string;
13
+ 'data-entry-id'?: string;
14
+ };
15
+ }
16
+ export type SCBlockType = 'doc' | 'paragraph' | 'heading' | 'blockquote' | 'bulletList' | 'orderedList' | 'listItem' | 'codeBlock' | 'horizontalRule' | 'table' | 'tableRow' | 'tableCell' | 'tableHeader' | 'figure' | 'video' | 'image' | 'inlineBlock' | 'hardBreak' | 'text';
17
+ export interface SCNode {
18
+ type: string;
19
+ attrs?: Record<string, unknown>;
20
+ content?: SCNode[];
21
+ marks?: SCMark[];
22
+ text?: string;
23
+ }
24
+ export interface SCHeadingAttrs {
25
+ level: 2 | 3;
26
+ textAlign?: string;
27
+ }
28
+ export interface SCFigureAttrs {
29
+ src: string;
30
+ alt?: string;
31
+ caption?: string;
32
+ 'data-media-id'?: string;
33
+ width?: number;
34
+ height?: number;
35
+ align?: string;
36
+ /** Populated at runtime by resolveMediaFields. */
37
+ _media?: {
38
+ data: import('./media.js').MediaFile;
39
+ styles?: Record<string, import('./media.js').ImageStyle>;
40
+ blurDataUrl?: string | null;
41
+ };
42
+ }
43
+ export interface SCVideoAttrs {
44
+ src: string;
45
+ 'data-media-id'?: string;
46
+ poster?: string;
47
+ controls?: boolean;
48
+ width?: number;
49
+ height?: number;
50
+ /** Populated at runtime by resolveMediaFields. */
51
+ _media?: {
52
+ data: import('./media.js').MediaFile;
53
+ };
54
+ }
55
+ export interface SCInlineBlockAttrs {
56
+ blockType: string;
57
+ blockData: Record<string, unknown>;
58
+ blockId: string;
59
+ }
60
+ export interface StructuredContentDoc {
61
+ type: 'doc';
62
+ content: SCNode[];
63
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { CmsUpdate } from '../index.js';
2
+ export declare const update: CmsUpdate;
@@ -0,0 +1,18 @@
1
+ export const update = {
2
+ version: '0.1.5',
3
+ date: '2026-02-21',
4
+ description: 'Simplified entry versioning',
5
+ features: [
6
+ 'Auto-save now updates draft in-place instead of creating new versions',
7
+ 'Ctrl/Cmd+S shortcut for immediate save',
8
+ 'Simplified status badge — no version numbers, green dot for published',
9
+ 'Version history shows only meaningful changes with semantic grouping',
10
+ 'Cleaning migration removes duplicate versions with identical data'
11
+ ],
12
+ fixes: [
13
+ 'Auto-save no longer creates dozens of empty versions',
14
+ 'Pruning no longer deletes important versions to make room for empty ones'
15
+ ],
16
+ breakingChanges: [],
17
+ migration: 'Removes duplicate entry versions where data is identical to the previous version. Preserves published, scheduled, and latest draft versions.'
18
+ };
@@ -0,0 +1,2 @@
1
+ import type { CmsUpdate } from '../index.js';
2
+ export declare const update: CmsUpdate;
@@ -0,0 +1,11 @@
1
+ export const update = {
2
+ version: '0.2.0',
3
+ date: '2026-02-21',
4
+ description: 'Array→Blocks rename, new simple array field',
5
+ features: ['Simple array field for flat lists (text, number, url)'],
6
+ fixes: [],
7
+ breakingChanges: [
8
+ 'type:"array" with objects renamed to type:"blocks". Update collection/single configs.'
9
+ ],
10
+ migration: 'Config-only: rename type:"array" to type:"blocks" in field definitions. Stored data unchanged.'
11
+ };
@@ -0,0 +1,2 @@
1
+ import type { CmsUpdate } from '../index.js';
2
+ export declare const update: CmsUpdate;
@@ -0,0 +1,13 @@
1
+ export const update = {
2
+ version: '0.2.2',
3
+ date: '2026-02-21',
4
+ description: 'Structured Content field (TipTap JSON)',
5
+ features: [
6
+ 'New `content` field type — stores TipTap JSON instead of HTML',
7
+ 'Extracted shared editor toolbar component',
8
+ 'Content field link resolution in resolve pipeline'
9
+ ],
10
+ fixes: [],
11
+ breakingChanges: [],
12
+ migration: 'No migration needed. Add type:"content" fields to collection/single configs. Existing richtext fields unchanged.'
13
+ };
@@ -0,0 +1,2 @@
1
+ import type { CmsUpdate } from '../index.js';
2
+ export declare const update: CmsUpdate;
@@ -0,0 +1,14 @@
1
+ export const update = {
2
+ version: '0.5.0',
3
+ date: '2026-02-22',
4
+ description: 'Frontend rendering for structured content',
5
+ features: [
6
+ '`StructuredContent` Svelte component for rendering structured content on frontend',
7
+ '`structuredToHtml()` — convert structured content to HTML (RSS, email)',
8
+ 'Query helpers: `extractBlocks()`, `extractInlineBlocks()`, `extractText()`, `extractMediaRefs()`',
9
+ 'Media resolution in population pipeline for `content` field — figure/video nodes enriched with `_media`'
10
+ ],
11
+ fixes: [],
12
+ breakingChanges: [],
13
+ migration: 'No migration needed. Import `StructuredContent` from `includio/sveltekit` to render content fields.'
14
+ };
@@ -0,0 +1,2 @@
1
+ import type { CmsUpdate } from '../index.js';
2
+ export declare const update: CmsUpdate;
@@ -0,0 +1,17 @@
1
+ export const update = {
2
+ version: '0.5.1',
3
+ date: '2026-02-24',
4
+ description: 'Restore archived entries, dashboard redesign, translation fixes',
5
+ features: [
6
+ 'Restore archived entries from collection list (single + bulk)',
7
+ 'Archived entry page: read-only with restore banner',
8
+ 'Dashboard: changelog modal, orphaned entries redesign, grid layout'
9
+ ],
10
+ fixes: [
11
+ 'Opening archived entry no longer returns 500 (getRawEntry now supports includeArchived)',
12
+ 'Translation flow: reactive status, switcher UX, dynamic ref, copyFrom crash, panel scroll',
13
+ 'False "Niezapisane zmiany" alert on entry load',
14
+ 'Hide translation dots for non-required empty fields'
15
+ ],
16
+ breakingChanges: []
17
+ };
@@ -8,7 +8,12 @@ import { update as update011 } from './0.1.1/index.js';
8
8
  import { update as update012 } from './0.1.2/index.js';
9
9
  import { update as update013 } from './0.1.3/index.js';
10
10
  import { update as update014 } from './0.1.4/index.js';
11
- export const updates = [update0065, update0066, update0067, update0068, update0069, update010, update011, update012, update013, update014];
11
+ import { update as update015 } from './0.1.5/index.js';
12
+ import { update as update020 } from './0.2.0/index.js';
13
+ import { update as update022 } from './0.2.2/index.js';
14
+ import { update as update050 } from './0.5.0/index.js';
15
+ import { update as update051 } from './0.5.1/index.js';
16
+ export const updates = [update0065, update0066, update0067, update0068, update0069, update010, update011, update012, update013, update014, update015, update020, update022, update050, update051];
12
17
  export const getUpdatesFrom = (fromVersion) => {
13
18
  const fromParts = fromVersion.split('.').map(Number);
14
19
  return updates.filter((update) => {