rimecms 0.32.1 → 1.0.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 (497) hide show
  1. package/dist/adapter-sqlite/auth.server.d.ts +2 -2
  2. package/dist/adapter-sqlite/columns.server.js +2 -2
  3. package/dist/adapter-sqlite/connect.server.d.ts +12 -0
  4. package/dist/adapter-sqlite/connect.server.js +31 -0
  5. package/dist/adapter-sqlite/generate-schema/column.server.js +1 -1
  6. package/dist/adapter-sqlite/generate-schema/index.server.js +11 -3
  7. package/dist/adapter-sqlite/generate-schema/root.server.d.ts +13 -4
  8. package/dist/adapter-sqlite/generate-schema/root.server.js +75 -131
  9. package/dist/adapter-sqlite/generate-schema/templates.server.d.ts +27 -6
  10. package/dist/adapter-sqlite/generate-schema/templates.server.js +63 -11
  11. package/dist/adapter-sqlite/index.server.d.ts +13 -5
  12. package/dist/adapter-sqlite/index.server.js +9 -6
  13. package/dist/adapter-sqlite/naming.server.d.ts +6 -8
  14. package/dist/adapter-sqlite/naming.server.js +22 -4
  15. package/dist/adapter-sqlite/paths.server.d.ts +10 -0
  16. package/dist/adapter-sqlite/paths.server.js +122 -0
  17. package/dist/adapter-sqlite/read.server.d.ts +10 -1
  18. package/dist/adapter-sqlite/read.server.js +22 -10
  19. package/dist/adapter-sqlite/select.server.d.ts +19 -0
  20. package/dist/adapter-sqlite/select.server.js +71 -63
  21. package/dist/adapter-sqlite/table.server.d.ts +2 -2
  22. package/dist/adapter-sqlite/transform.server.js +33 -3
  23. package/dist/adapter-sqlite/types.server.d.ts +10 -3
  24. package/dist/adapter-sqlite/where.server.d.ts +2 -3
  25. package/dist/adapter-sqlite/where.server.js +19 -1
  26. package/dist/core/adapter.d.ts +94 -0
  27. package/dist/core/auth/better-auth/config.server.d.ts +3 -3
  28. package/dist/core/auth/better-auth/instance.server.d.ts +6 -6
  29. package/dist/core/auth/handler/index.server.js +1 -1
  30. package/dist/core/auth/staff/derive.js +1 -1
  31. package/dist/core/auth/validate-config.js +3 -5
  32. package/dist/core/boot.server.d.ts +6 -6
  33. package/dist/core/config/types.d.ts +53 -5
  34. package/dist/core/config/validate.server.js +34 -51
  35. package/dist/core/dev/cli/commands/build.js +21 -6
  36. package/dist/core/dev/cli/commands/init.server.d.ts +2 -1
  37. package/dist/core/dev/cli/commands/init.server.js +32 -6
  38. package/dist/core/dev/cli/index.js +1 -0
  39. package/dist/core/dev/cli/templates/init.d.ts +6 -1
  40. package/dist/core/dev/cli/templates/init.js +30 -2
  41. package/dist/core/dev/cli/util/package-manager.server.d.ts +1 -0
  42. package/dist/core/dev/cli/util/package-manager.server.js +11 -8
  43. package/dist/core/dev/cli/util/package.server.d.ts +9 -0
  44. package/dist/core/dev/cli/util/package.server.js +43 -0
  45. package/dist/core/dev/codegen/types/contributions.server.d.ts +3 -2
  46. package/dist/core/dev/codegen/types/contributions.server.js +10 -3
  47. package/dist/core/dev/vite.server.js +4 -3
  48. package/dist/core/fields/blank.d.ts +21 -0
  49. package/dist/core/fields/blank.js +37 -0
  50. package/dist/core/fields/builders/field-builder.d.ts +53 -0
  51. package/dist/core/fields/builders/field-builder.js +14 -1
  52. package/dist/core/fields/builders/form-field-builder.d.ts +8 -0
  53. package/dist/core/fields/builders/form-field-builder.js +14 -1
  54. package/dist/core/fields/util.d.ts +9 -2
  55. package/dist/core/fields/util.js +123 -135
  56. package/dist/core/fields/walk.d.ts +44 -0
  57. package/dist/core/fields/walk.js +55 -0
  58. package/dist/core/handler.server.js +4 -0
  59. package/dist/core/i18n/context.d.ts +5 -0
  60. package/dist/core/i18n/context.js +6 -0
  61. package/dist/core/i18n/en/common.d.ts +71 -0
  62. package/dist/core/i18n/en/common.js +72 -1
  63. package/dist/core/i18n/en/fields.d.ts +68 -0
  64. package/dist/core/i18n/en/fields.js +69 -1
  65. package/dist/core/i18n/fr/common.d.ts +71 -0
  66. package/dist/core/i18n/fr/common.js +72 -1
  67. package/dist/core/i18n/fr/fields.d.ts +68 -0
  68. package/dist/core/i18n/fr/fields.js +69 -1
  69. package/dist/core/i18n/index.d.ts +29 -3
  70. package/dist/core/i18n/index.js +55 -29
  71. package/dist/core/locale/copy.server.js +3 -3
  72. package/dist/core/logger.server.js +15 -6
  73. package/dist/core/pipeline/build-document.server.d.ts +3 -0
  74. package/dist/core/pipeline/build-document.server.js +10 -7
  75. package/dist/core/pipeline/config-map/index.d.ts +9 -0
  76. package/dist/core/pipeline/config-map/index.js +16 -50
  77. package/dist/core/pipeline/hooks/process-document-fields.server.d.ts +3 -0
  78. package/dist/core/pipeline/hooks/process-document-fields.server.js +48 -12
  79. package/dist/core/pipeline/hooks/set-default-values.server.d.ts +1 -0
  80. package/dist/core/pipeline/hooks/set-default-values.server.js +1 -0
  81. package/dist/core/pipeline/persist/blocks/extract.server.js +1 -1
  82. package/dist/core/pipeline/persist/relations/extract.server.js +2 -0
  83. package/dist/core/pipeline/populate-relations.server.d.ts +27 -0
  84. package/dist/core/pipeline/populate-relations.server.js +42 -0
  85. package/dist/core/pipeline/run.server.d.ts +17 -6
  86. package/dist/core/pipeline/run.server.js +44 -30
  87. package/dist/core/plugins/cache/module.server.d.ts +1 -1
  88. package/dist/core/plugins/cache/module.server.js +5 -5
  89. package/dist/core/plugins/defaults/module.server.js +2 -2
  90. package/dist/core/plugins/defaults/types.d.ts +5 -3
  91. package/dist/core/plugins/sse/index.d.ts +1 -1
  92. package/dist/core/plugins/sse/index.server.d.ts +5 -6
  93. package/dist/core/plugins/sse/index.server.js +3 -2
  94. package/dist/core/plugins/sse/types.d.ts +5 -0
  95. package/dist/core/prototype/area/api.server.js +1 -2
  96. package/dist/core/prototype/area/definition.js +1 -10
  97. package/dist/core/prototype/area/definition.server.js +4 -5
  98. package/dist/core/prototype/area/hooks.server.js +3 -2
  99. package/dist/core/prototype/area/operations/find.js +2 -0
  100. package/dist/core/prototype/blank.d.ts +26 -0
  101. package/dist/core/prototype/blank.js +22 -0
  102. package/dist/core/prototype/collection/api.server.d.ts +29 -3
  103. package/dist/core/prototype/collection/api.server.js +47 -4
  104. package/dist/core/prototype/collection/definition.js +0 -3
  105. package/dist/core/prototype/collection/hooks/merge-with-blank.server.d.ts +5 -1
  106. package/dist/core/prototype/collection/hooks/merge-with-blank.server.js +8 -22
  107. package/dist/core/prototype/collection/hooks.server.js +11 -5
  108. package/dist/core/prototype/collection/nested/module.server.js +3 -1
  109. package/dist/core/prototype/collection/nested/tree.d.ts +12 -0
  110. package/dist/core/prototype/collection/nested/tree.js +42 -0
  111. package/dist/core/prototype/collection/operations/find-by-id.js +2 -0
  112. package/dist/core/prototype/collection/operations/find-by-ids.d.ts +19 -0
  113. package/dist/core/prototype/collection/operations/find-by-ids.js +54 -0
  114. package/dist/core/prototype/collection/operations/find.js +21 -27
  115. package/dist/core/prototype/collection/operations/update-slug-by-id.d.ts +20 -0
  116. package/dist/core/prototype/collection/operations/update-slug-by-id.js +53 -0
  117. package/dist/core/prototype/collection/rest/index.server.js +3 -1
  118. package/dist/core/prototype/collection/rest/update-slug-by-id.server.d.ts +2 -0
  119. package/dist/core/prototype/collection/rest/update-slug-by-id.server.js +20 -0
  120. package/dist/core/prototype/collection/thumbnail/find-thumbnail.d.ts +2 -1
  121. package/dist/core/prototype/collection/thumbnail/find-thumbnail.js +4 -27
  122. package/dist/core/prototype/collection/upload/directories/derive.js +3 -1
  123. package/dist/core/prototype/collection/upload/disk/delete.server.js +1 -2
  124. package/dist/core/prototype/define.js +2 -0
  125. package/dist/core/prototype/shared/metas/fields.js +2 -1
  126. package/dist/core/prototype/shared/title/find-title.d.ts +2 -1
  127. package/dist/core/prototype/shared/title/find-title.js +5 -28
  128. package/dist/core/prototype/shared/url/addresses.server.d.ts +26 -0
  129. package/dist/core/prototype/shared/url/addresses.server.js +119 -0
  130. package/dist/core/prototype/shared/url/doc-type.d.ts +6 -0
  131. package/dist/core/prototype/shared/url/doc-type.js +9 -0
  132. package/dist/core/prototype/shared/url/format.server.d.ts +27 -0
  133. package/dist/core/prototype/shared/url/format.server.js +38 -0
  134. package/dist/core/prototype/shared/url/hooks/create-paths.server.d.ts +2 -0
  135. package/dist/core/prototype/shared/url/hooks/create-paths.server.js +9 -0
  136. package/dist/core/prototype/shared/url/hooks/detach-paths.server.d.ts +5 -0
  137. package/dist/core/prototype/shared/url/hooks/detach-paths.server.js +18 -0
  138. package/dist/core/prototype/shared/url/hooks/index.server.d.ts +5 -1
  139. package/dist/core/prototype/shared/url/hooks/index.server.js +5 -1
  140. package/dist/core/prototype/shared/url/hooks/set-area-url.server.d.ts +2 -0
  141. package/dist/core/prototype/shared/url/hooks/set-area-url.server.js +8 -0
  142. package/dist/core/prototype/shared/url/hooks/set-live-url.server.d.ts +5 -0
  143. package/dist/core/prototype/shared/url/hooks/set-live-url.server.js +19 -0
  144. package/dist/core/prototype/shared/url/hooks/sync-paths.server.d.ts +7 -0
  145. package/dist/core/prototype/shared/url/hooks/sync-paths.server.js +37 -0
  146. package/dist/core/prototype/shared/url/refresh.server.d.ts +36 -0
  147. package/dist/core/prototype/shared/url/refresh.server.js +58 -0
  148. package/dist/core/prototype/shared/versions/configure.server.js +3 -0
  149. package/dist/core/routes/context.server.d.ts +2 -1
  150. package/dist/fields/blocks/component/AddBlockButton.svelte +48 -137
  151. package/dist/fields/blocks/component/Block.svelte +153 -117
  152. package/dist/fields/blocks/component/Block.svelte.d.ts +11 -5
  153. package/dist/fields/blocks/component/BlockActions.svelte +76 -26
  154. package/dist/fields/blocks/component/BlockActions.svelte.d.ts +3 -0
  155. package/dist/fields/blocks/component/Blocks.svelte +248 -91
  156. package/dist/fields/blocks/component/focus/BlocksFocus.svelte +680 -0
  157. package/dist/fields/blocks/component/focus/BlocksFocus.svelte.d.ts +7 -0
  158. package/dist/fields/blocks/component/focus/Layers.svelte +145 -0
  159. package/dist/fields/blocks/component/focus/Layers.svelte.d.ts +9 -0
  160. package/dist/fields/blocks/component/focus/LayersList.svelte +304 -0
  161. package/dist/fields/blocks/component/focus/LayersList.svelte.d.ts +10 -0
  162. package/dist/fields/blocks/component/focus/Palette.svelte +135 -0
  163. package/dist/fields/blocks/component/focus/Palette.svelte.d.ts +9 -0
  164. package/dist/fields/blocks/component/focus/RenderPlaceholder.svelte +77 -0
  165. package/dist/fields/blocks/component/focus/RenderPlaceholder.svelte.d.ts +10 -0
  166. package/dist/fields/blocks/component/focus/Renders.svelte +302 -0
  167. package/dist/fields/blocks/component/focus/Renders.svelte.d.ts +11 -0
  168. package/dist/fields/blocks/component/focus/Stage.svelte +190 -0
  169. package/dist/fields/blocks/component/focus/Stage.svelte.d.ts +8 -0
  170. package/dist/fields/blocks/component/focus/StagePlaceholder.svelte +69 -0
  171. package/dist/fields/blocks/component/focus/StagePlaceholder.svelte.d.ts +3 -0
  172. package/dist/fields/blocks/component/focus/focus.svelte.d.ts +140 -0
  173. package/dist/fields/blocks/component/focus/focus.svelte.js +424 -0
  174. package/dist/fields/blocks/component/picker/BlockPicker.svelte +88 -0
  175. package/dist/fields/blocks/component/picker/BlockPicker.svelte.d.ts +10 -0
  176. package/dist/fields/blocks/component/picker/BlockTile.svelte +121 -0
  177. package/dist/fields/blocks/component/picker/BlockTile.svelte.d.ts +12 -0
  178. package/dist/fields/blocks/index.d.ts +49 -7
  179. package/dist/fields/blocks/index.js +61 -12
  180. package/dist/fields/checkbox/component/Checkbox.svelte +11 -37
  181. package/dist/fields/checkbox/component/Checkbox.svelte.d.ts +1 -0
  182. package/dist/fields/combobox/component/ComboBox.svelte +37 -7
  183. package/dist/fields/combobox/component/combobox.css +26 -10
  184. package/dist/fields/date/component/Date.svelte +43 -12
  185. package/dist/fields/group/component/Group.svelte +110 -41
  186. package/dist/fields/group/index.d.ts +5 -1
  187. package/dist/fields/group/index.js +10 -2
  188. package/dist/fields/link/component/Link.svelte +184 -143
  189. package/dist/fields/link/component/RessourceInput.svelte +26 -24
  190. package/dist/fields/link/index.d.ts +1 -0
  191. package/dist/fields/link/module.server.js +2 -4
  192. package/dist/fields/number/component/Number.svelte +38 -20
  193. package/dist/fields/number/component/number.css +22 -20
  194. package/dist/fields/number/index.d.ts +1 -0
  195. package/dist/fields/radio/component/Radio.svelte +12 -0
  196. package/dist/fields/radio/index.js +1 -1
  197. package/dist/fields/relation/component/Relation.svelte +169 -40
  198. package/dist/fields/relation/component/RelationInline.svelte +258 -0
  199. package/dist/fields/relation/component/RelationInline.svelte.d.ts +26 -0
  200. package/dist/fields/relation/component/default/Default.svelte +210 -100
  201. package/dist/fields/relation/component/default/Default.svelte.d.ts +14 -1
  202. package/dist/fields/relation/component/types.d.ts +4 -0
  203. package/dist/fields/relation/component/upload/Browse.svelte +619 -88
  204. package/dist/fields/relation/component/upload/Browse.svelte.d.ts +10 -2
  205. package/dist/fields/relation/component/upload/Create.svelte +41 -0
  206. package/dist/fields/relation/component/upload/Create.svelte.d.ts +13 -0
  207. package/dist/fields/relation/component/upload/Upload.svelte +287 -101
  208. package/dist/fields/relation/component/upload/Upload.svelte.d.ts +6 -1
  209. package/dist/fields/relation/component/upload/upload.css +5 -81
  210. package/dist/fields/relation/module.server.js +7 -1
  211. package/dist/fields/relation/value.d.ts +25 -0
  212. package/dist/fields/relation/value.js +27 -0
  213. package/dist/fields/rich-text/component/RichText.svelte +12 -80
  214. package/dist/fields/rich-text/component/RichText.svelte.d.ts +1 -1
  215. package/dist/fields/rich-text/component/RichTextInline.svelte +28 -0
  216. package/dist/fields/rich-text/component/RichTextInline.svelte.d.ts +11 -0
  217. package/dist/fields/rich-text/component/bubble-menu/bubble-menu.css +4 -3
  218. package/dist/fields/rich-text/component/bubble-menu/bubble-menu.svelte +3 -1
  219. package/dist/fields/rich-text/component/bubble-menu/icon-button/icon-button.css +2 -2
  220. package/dist/fields/rich-text/component/bubble-menu/node-selector/node-selector.css +7 -10
  221. package/dist/fields/rich-text/component/drag-handle/drag-handle.css +0 -2
  222. package/dist/fields/rich-text/component/styles/editor.css +111 -0
  223. package/dist/fields/rich-text/component/styles/field.css +71 -0
  224. package/dist/fields/rich-text/component/suggestion/suggestion.svelte +41 -56
  225. package/dist/fields/rich-text/core/build-editor-config.js +1 -1
  226. package/dist/fields/rich-text/core/extensions/drag-handle/drag-handle-plugin.js +29 -3
  227. package/dist/fields/rich-text/core/extensions/drag-handle/drag-handle.d.ts +1 -0
  228. package/dist/fields/rich-text/core/extensions/drag-handle/drag-handle.js +2 -1
  229. package/dist/fields/rich-text/core/features/fields/fields.css +2 -3
  230. package/dist/fields/rich-text/core/features/hr/hr.css +4 -4
  231. package/dist/fields/rich-text/core/features/link/component/link-selector.css +0 -4
  232. package/dist/fields/rich-text/core/features/link/component/link-selector.svelte +24 -8
  233. package/dist/fields/rich-text/core/features/resource/resource.svelte +20 -6
  234. package/dist/fields/rich-text/core/features/upload/upload.svelte +20 -8
  235. package/dist/fields/rich-text/core/rich-text-editor-core.svelte +103 -0
  236. package/dist/fields/rich-text/core/rich-text-editor-core.svelte.d.ts +15 -0
  237. package/dist/fields/select/component/Select.svelte +67 -28
  238. package/dist/fields/slug/component/Slug.svelte +26 -53
  239. package/dist/fields/slug/index.d.ts +1 -0
  240. package/dist/fields/slug/index.js +1 -1
  241. package/dist/fields/tabs/component/Tabs.svelte +28 -22
  242. package/dist/fields/tabs/index.d.ts +4 -1
  243. package/dist/fields/tabs/index.js +17 -5
  244. package/dist/fields/text/index.d.ts +1 -0
  245. package/dist/fields/textarea/component/TextArea.svelte +28 -13
  246. package/dist/fields/textarea/index.d.ts +1 -0
  247. package/dist/fields/time/component/Time.svelte +9 -2
  248. package/dist/fields/toggle/component/Toggle.svelte +8 -25
  249. package/dist/fields/toggle/component/Toggle.svelte.d.ts +1 -0
  250. package/dist/fields/toggle/index.d.ts +1 -0
  251. package/dist/fields/tree/component/AddItemButton.svelte +18 -5
  252. package/dist/fields/tree/component/Tree.svelte +48 -19
  253. package/dist/fields/tree/component/TreeBlock.svelte +318 -104
  254. package/dist/fields/tree/component/TreeBlockActions.svelte +71 -7
  255. package/dist/fields/tree/component/TreeBlockActions.svelte.d.ts +4 -0
  256. package/dist/fields/tree/component/props.d.ts +2 -1
  257. package/dist/fields/tree/index.d.ts +13 -1
  258. package/dist/fields/tree/index.js +35 -9
  259. package/dist/fields/types.d.ts +3 -1
  260. package/dist/index.d.ts +4 -3
  261. package/dist/index.js +3 -2
  262. package/dist/panel/components/Root.svelte +16 -44
  263. package/dist/panel/components/Root.svelte.d.ts +1 -1
  264. package/dist/panel/components/fields/Error.svelte +18 -3
  265. package/dist/panel/components/fields/FieldsPreview.svelte +30 -17
  266. package/dist/panel/components/fields/FieldsPreviewTrigger.svelte +25 -3
  267. package/dist/panel/components/fields/Hint.svelte +51 -8
  268. package/dist/panel/components/fields/Hint.svelte.d.ts +11 -0
  269. package/dist/panel/components/fields/Label.svelte +2 -0
  270. package/dist/panel/components/fields/LabelFor.svelte +7 -2
  271. package/dist/panel/components/fields/RenderFields.svelte +10 -3
  272. package/dist/panel/components/fields/fieldset.svelte.d.ts +4 -1
  273. package/dist/panel/components/fields/fieldset.svelte.js +9 -2
  274. package/dist/panel/components/fields/index.d.ts +1 -0
  275. package/dist/panel/components/fields/setting.css +82 -0
  276. package/dist/panel/components/sections/auth/AuthForm.svelte +25 -26
  277. package/dist/panel/components/sections/collection/Avatar.svelte +61 -0
  278. package/dist/panel/components/sections/collection/Avatar.svelte.d.ts +9 -0
  279. package/dist/panel/components/sections/collection/DocStatus.svelte +28 -0
  280. package/dist/panel/components/sections/collection/DocStatus.svelte.d.ts +7 -0
  281. package/dist/panel/components/sections/collection/Empty.svelte +3 -3
  282. package/dist/panel/components/sections/collection/StatusDot.svelte +7 -5
  283. package/dist/panel/components/sections/collection/When.svelte +33 -0
  284. package/dist/panel/components/sections/collection/When.svelte.d.ts +8 -0
  285. package/dist/panel/components/sections/collection/bulk-upload/BulkUploadDialog.svelte +65 -21
  286. package/dist/panel/components/sections/collection/bulk-upload/BulkUploadDialog.svelte.d.ts +3 -2
  287. package/dist/panel/components/sections/collection/bulk-upload/DropZone.svelte +45 -162
  288. package/dist/panel/components/sections/collection/bulk-upload/DropZone.svelte.d.ts +3 -2
  289. package/dist/panel/components/sections/collection/bulk-upload/FileDrop.svelte +151 -0
  290. package/dist/panel/components/sections/collection/bulk-upload/FileDrop.svelte.d.ts +17 -0
  291. package/dist/panel/components/sections/collection/bulk-upload/PageDrop.svelte +177 -0
  292. package/dist/panel/components/sections/collection/bulk-upload/PageDrop.svelte.d.ts +12 -0
  293. package/dist/panel/components/sections/collection/bulk-upload/UploadProgress.svelte +75 -0
  294. package/dist/panel/components/sections/collection/bulk-upload/UploadProgress.svelte.d.ts +8 -0
  295. package/dist/panel/components/sections/collection/folder/Folder.svelte +18 -3
  296. package/dist/panel/components/sections/collection/folder/FolderEdit.svelte +26 -18
  297. package/dist/panel/components/sections/collection/folder/FolderWithActions.svelte +98 -58
  298. package/dist/panel/components/sections/collection/folder/FolderWithActions.svelte.d.ts +0 -1
  299. package/dist/panel/components/sections/collection/folder/Folders.svelte +60 -0
  300. package/dist/panel/components/sections/collection/folder/Folders.svelte.d.ts +7 -0
  301. package/dist/panel/components/sections/collection/grid/CollectionGrid.svelte +31 -71
  302. package/dist/panel/components/sections/collection/grid/CollectionGrid.svelte.d.ts +1 -0
  303. package/dist/panel/components/sections/collection/grid/create-directory-dialog/CreateDirectoryDialog.svelte +5 -3
  304. package/dist/panel/components/sections/collection/grid/grid-item/GridItem.svelte +250 -37
  305. package/dist/panel/components/sections/collection/grid/grid-item/GridItem.svelte.d.ts +2 -0
  306. package/dist/panel/components/sections/collection/header/ButtonCreate.svelte +43 -18
  307. package/dist/panel/components/sections/collection/header/ButtonCreate.svelte.d.ts +6 -4
  308. package/dist/panel/components/sections/collection/header/DisplayMode.svelte +69 -58
  309. package/dist/panel/components/sections/collection/header/DisplayMode.svelte.d.ts +0 -1
  310. package/dist/panel/components/sections/collection/header/FilterMenu.svelte +60 -0
  311. package/dist/panel/components/sections/collection/header/FilterMenu.svelte.d.ts +14 -0
  312. package/dist/panel/components/sections/collection/header/SearchInput.svelte +17 -26
  313. package/dist/panel/components/sections/collection/header/SelectUI.svelte +19 -34
  314. package/dist/panel/components/sections/collection/list/CollectionList.svelte +99 -68
  315. package/dist/panel/components/sections/collection/list/columns.d.ts +21 -0
  316. package/dist/panel/components/sections/collection/list/columns.js +23 -0
  317. package/dist/panel/components/sections/collection/list/header/Header.svelte +99 -51
  318. package/dist/panel/components/sections/collection/list/row/Row.svelte +165 -82
  319. package/dist/panel/components/sections/collection/list/row/Row.svelte.d.ts +4 -0
  320. package/dist/panel/components/sections/collection/tree/CollectionTree.svelte +92 -44
  321. package/dist/panel/components/sections/collection/tree/CollectionTree.svelte.d.ts +1 -0
  322. package/dist/panel/components/sections/collection/tree/CollectionTreeNode.svelte +139 -43
  323. package/dist/panel/components/sections/collection/tree/CollectionTreeNode.svelte.d.ts +2 -0
  324. package/dist/panel/components/sections/collection/upload-thumb-cell/UploadThumbCell.svelte +1 -1
  325. package/dist/panel/components/sections/commands/CommandButton.svelte +99 -0
  326. package/dist/panel/components/sections/commands/CommandButton.svelte.d.ts +10 -0
  327. package/dist/panel/components/sections/commands/CommandPalette.svelte +275 -0
  328. package/dist/panel/components/sections/commands/CommandPalette.svelte.d.ts +8 -0
  329. package/dist/panel/components/sections/commands/Commands.svelte +18 -0
  330. package/dist/panel/components/sections/commands/Commands.svelte.d.ts +9 -0
  331. package/dist/panel/components/sections/document/AuthAPIKeyDialog.svelte +23 -7
  332. package/dist/panel/components/sections/document/AuthFooter.svelte +31 -12
  333. package/dist/panel/components/sections/document/AutoSaveBanner.svelte +24 -7
  334. package/dist/panel/components/sections/document/ButtonSave.svelte +32 -21
  335. package/dist/panel/components/sections/document/ButtonSave.svelte.d.ts +5 -5
  336. package/dist/panel/components/sections/document/ButtonStatus.svelte +68 -20
  337. package/dist/panel/components/sections/document/ChangeSlugDialog.svelte +199 -0
  338. package/dist/panel/components/sections/document/ChangeSlugDialog.svelte.d.ts +10 -0
  339. package/dist/panel/components/sections/document/CurrentlyEdited.svelte +2 -2
  340. package/dist/panel/components/sections/document/Document.svelte +96 -65
  341. package/dist/panel/components/sections/document/DocumentChildren.svelte +175 -0
  342. package/dist/panel/components/sections/document/DocumentChildren.svelte.d.ts +8 -0
  343. package/dist/panel/components/sections/document/DocumentUrl.svelte +119 -0
  344. package/dist/panel/components/sections/document/DocumentUrl.svelte.d.ts +9 -0
  345. package/dist/panel/components/sections/document/Header.svelte +171 -94
  346. package/dist/panel/components/sections/document/Settings.svelte +255 -110
  347. package/dist/panel/components/sections/document/Settings.svelte.d.ts +0 -1
  348. package/dist/panel/components/sections/document/Versions.svelte +5 -3
  349. package/dist/panel/components/sections/document/upload-header/UploadHeader.svelte +112 -53
  350. package/dist/panel/components/sections/document/upload-header/UploadHeader.svelte.d.ts +2 -2
  351. package/dist/panel/components/sections/document/upload-header/drop-zone/DropZone.svelte +74 -41
  352. package/dist/panel/components/sections/document/upload-header/drop-zone/DropZone.svelte.d.ts +1 -1
  353. package/dist/panel/components/sections/live/LiveEdit.svelte +2 -2
  354. package/dist/panel/components/sections/live/LiveFloatingUI.svelte +30 -11
  355. package/dist/panel/components/sections/live/live-edit-panel.css +2 -2
  356. package/dist/panel/components/sections/page-layout/Page.svelte +13 -1
  357. package/dist/panel/components/ui/breadcrumb/BreadCrumb.svelte +55 -27
  358. package/dist/panel/components/ui/button/button.svelte +81 -54
  359. package/dist/panel/components/ui/button/index.d.ts +7 -3
  360. package/dist/panel/components/ui/button/index.js +2 -2
  361. package/dist/panel/components/ui/calendar/calendar.css +27 -27
  362. package/dist/panel/components/ui/calendar/calendar.svelte.d.ts +1 -1
  363. package/dist/panel/components/ui/card/card-description.svelte +1 -1
  364. package/dist/panel/components/ui/card/card.svelte +21 -4
  365. package/dist/panel/components/ui/card-document/card-document.svelte +24 -12
  366. package/dist/panel/components/ui/card-resource/card-resource.svelte +26 -8
  367. package/dist/panel/components/ui/checkbox/checkbox.css +8 -10
  368. package/dist/panel/components/ui/command/command-dialog.css +28 -4
  369. package/dist/panel/components/ui/command/command-dialog.svelte +4 -1
  370. package/dist/panel/components/ui/command/command-dialog.svelte.d.ts +2 -0
  371. package/dist/panel/components/ui/command/command-empty.css +1 -1
  372. package/dist/panel/components/ui/command/command-group.css +3 -3
  373. package/dist/panel/components/ui/command/command-input-select.svelte +3 -3
  374. package/dist/panel/components/ui/command/command-input.svelte +38 -14
  375. package/dist/panel/components/ui/command/command-input.svelte.d.ts +6 -1
  376. package/dist/panel/components/ui/command/command-item.css +2 -2
  377. package/dist/panel/components/ui/command/command-list.css +1 -1
  378. package/dist/panel/components/ui/command/command-separator.css +1 -1
  379. package/dist/panel/components/ui/context-menu/context-menu-item.css +2 -2
  380. package/dist/panel/components/ui/context-menu/context-menu.css +6 -7
  381. package/dist/panel/components/ui/dialog/dialog-content.css +8 -10
  382. package/dist/panel/components/ui/dialog/dialog-content.svelte +19 -0
  383. package/dist/panel/components/ui/dialog/dialog-description.css +1 -1
  384. package/dist/panel/components/ui/dialog/dialog-footer.svelte +5 -1
  385. package/dist/panel/components/ui/dialog/dialog-overlay.css +1 -1
  386. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +19 -5
  387. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-content.css +6 -4
  388. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-item.css +1 -1
  389. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-radio-item.css +1 -1
  390. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-separator.css +1 -1
  391. package/dist/panel/components/ui/input/input.svelte +57 -31
  392. package/dist/panel/components/ui/kbd/Kbd.svelte +90 -0
  393. package/dist/panel/components/ui/kbd/Kbd.svelte.d.ts +11 -0
  394. package/dist/panel/components/ui/kbd/index.d.ts +1 -0
  395. package/dist/panel/components/ui/kbd/index.js +1 -0
  396. package/dist/panel/components/ui/label/label.css +5 -3
  397. package/dist/panel/components/ui/language-switcher/LanguageSwitcher.svelte +27 -15
  398. package/dist/panel/components/ui/nav/Nav.svelte +180 -110
  399. package/dist/panel/components/ui/nav/Nav.svelte.d.ts +0 -2
  400. package/dist/panel/components/ui/nav/NavGroup.svelte +87 -73
  401. package/dist/panel/components/ui/nav/NavItemButton.svelte +69 -29
  402. package/dist/panel/components/ui/nav/UserButton.svelte +132 -71
  403. package/dist/panel/components/ui/page-header/PageHeader.svelte +140 -42
  404. package/dist/panel/components/ui/page-header/PageHeader.svelte.d.ts +8 -1
  405. package/dist/panel/components/ui/popover/popover-content.css +4 -3
  406. package/dist/panel/components/ui/radio-group/radio-group.css +4 -6
  407. package/dist/panel/components/ui/radio-row-group/radio-row-group.css +19 -7
  408. package/dist/panel/components/ui/scroll-area/scroll-area.css +2 -2
  409. package/dist/panel/components/ui/separator/separator.svelte +1 -1
  410. package/dist/panel/components/ui/sheet/index.d.ts +4 -4
  411. package/dist/panel/components/ui/sheet/index.js +5 -5
  412. package/dist/panel/components/ui/sheet/sheet.css +50 -11
  413. package/dist/panel/components/ui/sonner/sonner.css +11 -8
  414. package/dist/panel/components/ui/switch/switch.css +13 -18
  415. package/dist/panel/components/ui/tabs/tabs.css +44 -35
  416. package/dist/panel/components/ui/tag/tag.svelte +20 -6
  417. package/dist/panel/components/ui/tooltip/tooltip-content.svelte +14 -4
  418. package/dist/panel/components/ui/tree/tree-rows.css +146 -0
  419. package/dist/panel/context/blocks-ops.d.ts +78 -0
  420. package/dist/panel/context/blocks-ops.js +170 -0
  421. package/dist/panel/context/collection.svelte.d.ts +28 -0
  422. package/dist/panel/context/collection.svelte.js +120 -65
  423. package/dist/panel/context/commands.svelte.d.ts +80 -0
  424. package/dist/panel/context/commands.svelte.js +108 -0
  425. package/dist/panel/context/documentForm.svelte.d.ts +34 -2
  426. package/dist/panel/context/documentForm.svelte.js +105 -102
  427. package/dist/panel/context/live.svelte.js +2 -73
  428. package/dist/panel/context/nav.svelte.d.ts +23 -0
  429. package/dist/panel/context/nav.svelte.js +56 -0
  430. package/dist/panel/fonts/Geist-VariableFont_wght.ttf +0 -0
  431. package/dist/panel/fonts/GeistMono-VariableFont_wght.ttf +0 -0
  432. package/dist/panel/index.d.ts +7 -1
  433. package/dist/panel/index.js +10 -1
  434. package/dist/panel/pages/auth/forgot-password/ForgotPassword.svelte +16 -1
  435. package/dist/panel/pages/collection/CollectionPage.svelte +236 -61
  436. package/dist/panel/pages/collection/load.server.js +1 -1
  437. package/dist/panel/pages/dashboard/Dashboard.svelte +135 -90
  438. package/dist/panel/pages/dashboard/DashboardCard.svelte +109 -0
  439. package/dist/panel/pages/dashboard/DashboardCard.svelte.d.ts +14 -0
  440. package/dist/panel/pages/dashboard/DashboardCollection.svelte +180 -57
  441. package/dist/panel/pages/dashboard/DashboardCollection.svelte.d.ts +1 -0
  442. package/dist/panel/pages/dashboard/DashboardRow.svelte +93 -0
  443. package/dist/panel/pages/dashboard/DashboardRow.svelte.d.ts +16 -0
  444. package/dist/panel/pages/dashboard/load.server.js +49 -25
  445. package/dist/panel/pages/dashboard/time.d.ts +19 -0
  446. package/dist/panel/pages/dashboard/time.js +29 -0
  447. package/dist/panel/pages/dashboard/types.d.ts +9 -2
  448. package/dist/panel/pages/live/Live.svelte +53 -50
  449. package/dist/panel/style/font.css +21 -32
  450. package/dist/panel/style/index.css +191 -122
  451. package/dist/panel/style/mixins/index.css +14 -0
  452. package/dist/panel/style/palette.css +35 -26
  453. package/dist/panel/style/postcss/size-function.d.ts +4 -0
  454. package/dist/panel/style/postcss/size-function.js +24 -0
  455. package/dist/panel/style/radius.css +4 -5
  456. package/dist/panel/style/scheme.css +111 -0
  457. package/dist/panel/style/size.css +3 -0
  458. package/dist/panel/util/Sortable.js +9 -4
  459. package/dist/panel/util/keys.d.ts +24 -0
  460. package/dist/panel/util/keys.js +63 -0
  461. package/dist/panel/util/populate.d.ts +8 -0
  462. package/dist/panel/util/populate.js +49 -0
  463. package/dist/panel/util/time.d.ts +12 -0
  464. package/dist/panel/util/time.js +35 -0
  465. package/dist/panel/util/upload-file.d.ts +106 -0
  466. package/dist/panel/util/upload-file.js +165 -0
  467. package/dist/types.d.ts +1 -0
  468. package/dist/util/index.d.ts +7 -10
  469. package/dist/util/index.js +7 -8
  470. package/dist/util/object.d.ts +10 -0
  471. package/dist/util/object.js +22 -1
  472. package/dist/util/string.d.ts +17 -0
  473. package/dist/util/string.js +23 -0
  474. package/package.json +1 -3
  475. package/dist/core/pipeline/config-map/build-tree-map.d.ts +0 -4
  476. package/dist/core/pipeline/config-map/build-tree-map.js +0 -30
  477. package/dist/core/prototype/doc.d.ts +0 -31
  478. package/dist/core/prototype/doc.js +0 -118
  479. package/dist/core/prototype/shared/url/augment.d.ts +0 -13
  480. package/dist/core/prototype/shared/url/augment.js +0 -11
  481. package/dist/core/prototype/shared/url/hooks/populate-url.server.d.ts +0 -4
  482. package/dist/core/prototype/shared/url/hooks/populate-url.server.js +0 -120
  483. package/dist/fields/rich-text/component/styles/rich-text.css +0 -183
  484. package/dist/panel/components/sections/collection/header/Header.svelte +0 -17
  485. package/dist/panel/components/sections/collection/header/Header.svelte.d.ts +0 -3
  486. package/dist/panel/components/sections/collection/header/Separator.svelte +0 -8
  487. package/dist/panel/components/sections/collection/header/Separator.svelte.d.ts +0 -26
  488. package/dist/panel/components/sections/collection/tree/util.d.ts +0 -12
  489. package/dist/panel/components/sections/collection/tree/util.js +0 -22
  490. package/dist/panel/fonts/ChivoMono-Italic-VariableFont_wght.ttf +0 -0
  491. package/dist/panel/fonts/ChivoMono-VariableFont_wght.ttf +0 -0
  492. package/dist/panel/fonts/Inter-VariableFont_slnt,wght.ttf +0 -0
  493. package/dist/panel/fonts/Lora-Italic-VariableFont_wght.ttf +0 -0
  494. package/dist/panel/fonts/Lora-VariableFont_wght.ttf +0 -0
  495. package/dist/panel/style/shadow.css +0 -10
  496. package/dist/util/path.d.ts +0 -16
  497. package/dist/util/path.js +0 -19
@@ -0,0 +1,20 @@
1
+ import type { PathRow } from '../../../adapter.js';
2
+ import type { BuiltCollection } from '../../../config/types.js';
3
+ import type { PrototypeApiContext } from '../../define.js';
4
+ export type UpdateSlugByIdArgs = {
5
+ id: string;
6
+ slug: string;
7
+ /** The locale whose address changes; the others keep theirs. */
8
+ locale?: string | undefined;
9
+ };
10
+ type Args = UpdateSlugByIdArgs & {
11
+ ctx: PrototypeApiContext<BuiltCollection>;
12
+ };
13
+ /**
14
+ * A page's slug in one locale: its address changes, and the pages under it follow.
15
+ *
16
+ * On the published page only, for whoever may update it. A slug a sibling holds is refused as a
17
+ * field error on `_slug`.
18
+ */
19
+ export declare const updateSlugById: (args: Args) => Promise<PathRow>;
20
+ export {};
@@ -0,0 +1,53 @@
1
+ import { RimeError, RimeFormError } from '../../../errors/index.js';
2
+ import { toSlug } from '../../shared/url/format.server.js';
3
+ import { refreshUrls } from '../../shared/url/refresh.server.js';
4
+ /**
5
+ * A page's slug in one locale: its address changes, and the pages under it follow.
6
+ *
7
+ * On the published page only, for whoever may update it. A slug a sibling holds is refused as a
8
+ * field error on `_slug`.
9
+ */
10
+ export const updateSlugById = async (args) => {
11
+ const { ctx, id } = args;
12
+ const { config, event, isSystemOperation } = ctx;
13
+ const { rime } = event.locals;
14
+ const locale = args.locale ?? '';
15
+ if (!config.$url) {
16
+ throw new RimeError(RimeError.BAD_REQUEST, `${config.slug} has no $url, so no slug`);
17
+ }
18
+ if (!isSystemOperation && !config.access.update(event.locals.user, { event, id })) {
19
+ throw new RimeError(RimeError.UNAUTHORIZED);
20
+ }
21
+ const collection = rime.collection(config.slug).system();
22
+ const byId = { where: { id: { equals: id } } };
23
+ // Without `latest`, a read with drafts answers the published version only.
24
+ const [page] = await collection.find({ query: byId, locale: locale || undefined });
25
+ if (!page) {
26
+ const [draft] = await collection.find({
27
+ query: byId,
28
+ locale: locale || undefined,
29
+ latest: true
30
+ });
31
+ if (!draft)
32
+ throw new RimeError(RimeError.NOT_FOUND);
33
+ throw new RimeError(RimeError.BAD_REQUEST, 'the slug changes on the published page');
34
+ }
35
+ const value = toSlug(args.slug);
36
+ if (!value)
37
+ throw new RimeFormError({ _slug: RimeFormError.REQUIRED_FIELD });
38
+ const [current] = await rime.adapter.paths.get({ slug: config.slug, ownerId: id, locale });
39
+ if (!current)
40
+ throw new RimeError(RimeError.NOT_FOUND);
41
+ if (current.slug === value)
42
+ return current;
43
+ const parentId = page._parent ?? null;
44
+ const taken = await rime.adapter.paths.siblingSlugs({ slug: config.slug, locale, parentId });
45
+ if (taken.includes(value))
46
+ throw new RimeFormError({ _slug: RimeFormError.UNIQUE_FIELD });
47
+ const row = await rime.adapter.paths.setSlug({ slug: config.slug, ownerId: id, locale, value });
48
+ if (!row)
49
+ throw new RimeError(RimeError.NOT_FOUND);
50
+ await refreshUrls({ event, config, locale, path: row.path });
51
+ const [updated] = await rime.adapter.paths.get({ slug: config.slug, ownerId: id, locale });
52
+ return updated;
53
+ };
@@ -6,6 +6,7 @@ import { restGet } from './get.server.js';
6
6
  import { restGetById } from './get-by-id.server.js';
7
7
  import { restLock, restUnlock } from './lock.server.js';
8
8
  import { restUpdateById } from './update-by-id.server.js';
9
+ import { restUpdateSlugById } from './update-slug-by-id.server.js';
9
10
  /**
10
11
  * The REST surface a collection provides.
11
12
  *
@@ -20,5 +21,6 @@ export const rest = {
20
21
  '': { GET: restGet, POST: restCreate, DELETE: restDelete },
21
22
  '[id]': { GET: restGetById, PATCH: restUpdateById, DELETE: restDeleteById },
22
23
  '[id]/duplicate': { POST: restDuplicate },
23
- '[id]/lock': { POST: restLock, DELETE: restUnlock }
24
+ '[id]/lock': { POST: restLock, DELETE: restUnlock },
25
+ '[id]/slug': { PATCH: restUpdateSlugById }
24
26
  };
@@ -0,0 +1,2 @@
1
+ /** `PATCH /api/<collection>/<id>/slug` with `{ slug }`: the page's address in the request's locale. */
2
+ export declare const restUpdateSlugById: import("@sveltejs/kit").RequestHandler;
@@ -0,0 +1,20 @@
1
+ import { ERROR_CONTEXT, handleError } from '../../../errors/handler.server.js';
2
+ import { trycatch } from '../../../../util/function.js';
3
+ import { error, json } from '@sveltejs/kit';
4
+ import { endpoint } from './endpoint.server.js';
5
+ /** `PATCH /api/<collection>/<id>/slug` with `{ slug }`: the page's address in the request's locale. */
6
+ export const restUpdateSlugById = endpoint(async ({ event, collection }) => {
7
+ if (!event.params.id)
8
+ throw error(404);
9
+ const [readError, body] = await trycatch(() => event.request.json());
10
+ if (readError || typeof body?.slug !== 'string')
11
+ throw error(400, 'a slug is expected');
12
+ const [updateError, row] = await trycatch(() => collection.updateSlugById({
13
+ id: event.params.id,
14
+ slug: body.slug,
15
+ locale: event.locals.rime.getLocale()
16
+ }));
17
+ if (updateError)
18
+ return handleError(updateError, { context: ERROR_CONTEXT.API });
19
+ return json({ slug: row.slug, path: row.path, url: row.url });
20
+ });
@@ -1,9 +1,10 @@
1
1
  import type { FieldBuilder } from '../../../fields/builders/field-builder.js';
2
- import { FormFieldBuilder } from '../../../fields/builders/form-field-builder.js';
2
+ import type { FormFieldBuilder } from '../../../fields/builders/form-field-builder.js';
3
3
  import type { Field, FormField } from '../../../../fields/types.js';
4
4
  interface ThumbnailFieldResult {
5
5
  field: FormFieldBuilder<FormField>;
6
6
  path: string;
7
7
  }
8
+ /** The first relation marked `isThumbnail()`, at a path a config alone can name. */
8
9
  export declare function findThumbnailField(fields?: FieldBuilder<Field>[], basePath?: string): ThumbnailFieldResult | null;
9
10
  export {};
@@ -1,34 +1,11 @@
1
- import { FormFieldBuilder } from '../../../fields/builders/form-field-builder.js';
2
- import { GroupFieldBuilder } from '../../../../fields/group/index.js';
1
+ import { walkFields } from '../../../fields/walk.js';
3
2
  import { RelationFieldBuilder } from '../../../../fields/relation/index.js';
4
- import { TabsBuilder } from '../../../../fields/tabs/index.js';
3
+ /** The first relation marked `isThumbnail()`, at a path a config alone can name. */
5
4
  export function findThumbnailField(fields = [], basePath = '') {
6
- for (const field of fields) {
7
- // Direct check for isThumbnail
8
- if (field instanceof RelationFieldBuilder &&
9
- 'isThumbnail' in field.get &&
10
- field.get.isThumbnail === true) {
11
- const path = basePath ? `${basePath}.${field.name}` : field.name;
5
+ for (const { field, path } of walkFields(fields, { path: basePath, determinate: true })) {
6
+ if (field instanceof RelationFieldBuilder && field.get.isThumbnail === true) {
12
7
  return { field, path };
13
8
  }
14
- // Check in group
15
- if (field instanceof GroupFieldBuilder && field.get.fields) {
16
- const groupPath = basePath ? `${basePath}.${field.name}` : field.name;
17
- const found = findThumbnailField(field.get.fields, groupPath);
18
- if (found)
19
- return found;
20
- }
21
- // Check in tabs
22
- if (field instanceof TabsBuilder && field.get.tabs) {
23
- for (const tab of field.get.tabs) {
24
- if (tab.get.fields) {
25
- const tabPath = basePath ? `${basePath}.${tab.name}` : tab.name;
26
- const found = findThumbnailField(tab.get.fields, tabPath);
27
- if (found)
28
- return found;
29
- }
30
- }
31
- }
32
9
  }
33
10
  return null;
34
11
  }
@@ -1,3 +1,4 @@
1
+ import { blank } from '../../../blank.js';
1
2
  import { prototypeKebab } from '../../../naming.js';
2
3
  import { date } from '../../../../../fields/date/index.js';
3
4
  import { text } from '../../../../../fields/text/index.js';
@@ -14,6 +15,7 @@ export function makeUploadDirectoriesCollectionClient(collection) {
14
15
  const directoriesCollection = {
15
16
  slug: slug,
16
17
  kebab: prototypeKebab(slug),
18
+ blank,
17
19
  versions: undefined,
18
20
  access: {
19
21
  read: directoriesConfig?.access?.read || collection.access.read,
@@ -40,7 +42,7 @@ export function makeUploadDirectoriesCollectionClient(collection) {
40
42
  text('parent').hidden(),
41
43
  ...(directoriesConfig?.fields || []),
42
44
  date('createdAt').hidden(),
43
- date('updatedAt').hidden()
45
+ date('updatedAt').hidden().$index()
44
46
  ],
45
47
  type: 'collection',
46
48
  label: {
@@ -1,5 +1,4 @@
1
1
  import { logger } from '../../../../logger.server.js';
2
- import { isFormField } from '../../../../fields/util.js';
3
2
  import { existsSync, unlink, unlinkSync } from 'fs';
4
3
  import path from 'path';
5
4
  /**
@@ -17,7 +16,7 @@ import path from 'path';
17
16
  * and with no feature importing another feature to do it.
18
17
  */
19
18
  const ownsField = (rime, config, name) => {
20
- const field = config.fields.filter(isFormField).find((one) => one.name === name);
19
+ const field = config.fields.find((one) => one.name === name);
21
20
  if (!field)
22
21
  return false;
23
22
  return config._versions ? !!field.get.root : true;
@@ -1,5 +1,6 @@
1
1
  import { isStaff } from '../auth/access.js';
2
2
  import { FileText } from '@lucide/svelte';
3
+ import { blank } from './blank.js';
3
4
  import { prototypeKebab } from './naming.js';
4
5
  export const definePrototype = (options = {}) => {
5
6
  const name = options.name ?? '';
@@ -23,6 +24,7 @@ export const definePrototype = (options = {}) => {
23
24
  ...augmented,
24
25
  type: name,
25
26
  slug,
27
+ blank,
26
28
  kebab: prototypeKebab(slug),
27
29
  fields: augmented.fields || [],
28
30
  icon: augmented.icon || FileText,
@@ -23,5 +23,6 @@ export const metasFields = {
23
23
  createdBy: () => text('createdBy').hidden().$root().access(staffOnly),
24
24
  createdAt: () => date('createdAt').hidden(),
25
25
  updatedBy: () => text('updatedBy').hidden().access(staffOnly),
26
- updatedAt: () => date('updatedAt').hidden()
26
+ // The default sort of every list
27
+ updatedAt: () => date('updatedAt').hidden().$index()
27
28
  };
@@ -1,5 +1,5 @@
1
1
  import type { FieldBuilder } from '../../../fields/builders/field-builder.js';
2
- import { FormFieldBuilder } from '../../../fields/builders/form-field-builder.js';
2
+ import type { FormFieldBuilder } from '../../../fields/builders/form-field-builder.js';
3
3
  import type { DateField } from '../../../../fields/date/index.js';
4
4
  import type { EmailField } from '../../../../fields/email/index.js';
5
5
  import type { SlugField } from '../../../../fields/slug/index.js';
@@ -10,5 +10,6 @@ interface TitleFieldResult {
10
10
  field: FormFieldBuilder<FormField>;
11
11
  path: string;
12
12
  }
13
+ /** The first field marked `isTitle()`, at a path a config alone can name. */
13
14
  export declare function findTitleField(fields?: FieldBuilder<Field>[], basePath?: string): TitleFieldResult | null;
14
15
  export {};
@@ -1,35 +1,12 @@
1
- import { FormFieldBuilder } from '../../../fields/builders/form-field-builder.js';
2
- import { GroupFieldBuilder } from '../../../../fields/group/index.js';
3
- import { TabsBuilder } from '../../../../fields/tabs/index.js';
1
+ import { isFormField } from '../../../fields/util.js';
2
+ import { walkFields } from '../../../fields/walk.js';
4
3
  export const hasMaybeTitle = (field) => ['text', 'date', 'slug', 'email', 'richText'].includes(field.type);
4
+ /** The first field marked `isTitle()`, at a path a config alone can name. */
5
5
  export function findTitleField(fields = [], basePath = '') {
6
- for (const field of fields) {
7
- // Direct check for isTitle
8
- if (field instanceof FormFieldBuilder &&
9
- hasMaybeTitle(field.get) &&
10
- 'isTitle' in field.get &&
11
- field.get.isTitle === true) {
12
- const path = basePath ? `${basePath}.${field.name}` : field.name;
6
+ for (const { field, path } of walkFields(fields, { path: basePath, determinate: true })) {
7
+ if (isFormField(field) && hasMaybeTitle(field.get) && field.get.isTitle === true) {
13
8
  return { field, path };
14
9
  }
15
- // Check in group
16
- if (field instanceof GroupFieldBuilder && field.get.fields) {
17
- const groupPath = basePath ? `${basePath}.${field.name}` : field.name;
18
- const found = findTitleField(field.get.fields, groupPath);
19
- if (found)
20
- return found;
21
- }
22
- // Check in tabs
23
- if (field instanceof TabsBuilder && field.get.tabs) {
24
- for (const tab of field.get.tabs) {
25
- if (tab.get.fields) {
26
- const tabPath = basePath ? `${basePath}.${tab.name}` : tab.name;
27
- const found = findTitleField(tab.get.fields, tabPath);
28
- if (found)
29
- return found;
30
- }
31
- }
32
- }
33
10
  }
34
11
  return null;
35
12
  }
@@ -0,0 +1,26 @@
1
+ import type { BuiltCollection } from '../../../config/types.js';
2
+ import type { GenericDoc } from '../../types.js';
3
+ import type { RequestEvent } from '@sveltejs/kit';
4
+ /** The locales a page has an address in: `''` when the config has no localization. */
5
+ export declare const addressLocales: (event: RequestEvent) => any;
6
+ /** Gives these pages their address in every locale they have none in. */
7
+ export declare const addAddresses: (args: {
8
+ event: RequestEvent;
9
+ config: BuiltCollection;
10
+ ids: string[];
11
+ }) => Promise<void>;
12
+ /**
13
+ * The document with its address as it now is: the read that produced it ran before a create or an
14
+ * update gave it one.
15
+ */
16
+ export declare const withAddress: <T extends GenericDoc>(args: {
17
+ event: RequestEvent;
18
+ config: BuiltCollection;
19
+ doc: T;
20
+ }) => Promise<T>;
21
+ /**
22
+ * Once per process, on the first request: every page of a collection with `$url` gets the address
23
+ * it is missing. One query per collection and locale once they all have one. The requests after
24
+ * it are not held: nothing to await once it is done.
25
+ */
26
+ export declare const ensureAddresses: (event: RequestEvent) => Promise<void>;
@@ -0,0 +1,119 @@
1
+ import { walkFields } from '../../../fields/walk.js';
2
+ import { logger } from '../../../logger.server.js';
3
+ import { getValueAtPath } from '../../../../util/object.js';
4
+ import { hasUrl } from './enabled.js';
5
+ import { freeSlug, toSlug } from './format.server.js';
6
+ import { formatRows, readForUrls } from './refresh.server.js';
7
+ /** The locales a page has an address in: `''` when the config has no localization. */
8
+ export const addressLocales = (event) => {
9
+ const codes = event.locals.rime.config.getLocalesCodes();
10
+ return codes.length ? codes : [''];
11
+ };
12
+ /**
13
+ * The slug a page starts with: the collection's own slug field when it has one, its title
14
+ * otherwise, its id as a last resort.
15
+ */
16
+ const initialSlug = (config, doc) => {
17
+ for (const { field, path } of walkFields(config.fields)) {
18
+ if (field.type !== 'slug')
19
+ continue;
20
+ const value = toSlug(getValueAtPath(path, doc));
21
+ if (value)
22
+ return value;
23
+ }
24
+ return toSlug(doc.title) || doc.id;
25
+ };
26
+ /**
27
+ * Gives these pages their address in one locale: a slug free among their siblings, under their
28
+ * parent, then their url.
29
+ *
30
+ * A page is placed once its parent is, so a whole tree goes in, top first, in one call.
31
+ */
32
+ const addAddressesIn = async (args) => {
33
+ const { event, config, ids, locale } = args;
34
+ const { paths } = event.locals.rime.adapter;
35
+ const docs = await readForUrls({ event, config, locale, ids });
36
+ const parentOf = (id) => docs.get(id)._parent ?? null;
37
+ let pending = ids.filter((id) => docs.has(id));
38
+ const inserted = [];
39
+ while (pending.length) {
40
+ const ready = pending.filter((id) => !pending.includes(parentOf(id) ?? ''));
41
+ if (!ready.length)
42
+ break;
43
+ for (const id of ready) {
44
+ const parentId = parentOf(id);
45
+ const taken = await paths.siblingSlugs({ slug: config.slug, locale, parentId });
46
+ const slug = freeSlug(initialSlug(config, docs.get(id)), taken);
47
+ inserted.push(...(await paths.insert({
48
+ slug: config.slug,
49
+ ownerId: id,
50
+ parentId,
51
+ rows: [{ locale, slug }]
52
+ })));
53
+ }
54
+ pending = pending.filter((id) => !ready.includes(id));
55
+ }
56
+ if (pending.length) {
57
+ logger.warn(`${config.slug}: no address for ${pending.join(', ')} in "${locale}"`);
58
+ }
59
+ await formatRows({ event, config, locale, rows: inserted, docs });
60
+ };
61
+ /** Gives these pages their address in every locale they have none in. */
62
+ export const addAddresses = async (args) => {
63
+ const { event, config, ids } = args;
64
+ if (!ids.length)
65
+ return;
66
+ for (const locale of addressLocales(event)) {
67
+ const missing = new Set(await event.locals.rime.adapter.paths.missingOwners({ slug: config.slug, locale }));
68
+ const idsHere = ids.filter((id) => missing.has(id));
69
+ if (idsHere.length)
70
+ await addAddressesIn({ event, config, ids: idsHere, locale });
71
+ }
72
+ };
73
+ /**
74
+ * The document with its address as it now is: the read that produced it ran before a create or an
75
+ * update gave it one.
76
+ */
77
+ export const withAddress = async (args) => {
78
+ const { event, config, doc } = args;
79
+ const [row] = await event.locals.rime.adapter.paths.get({
80
+ slug: config.slug,
81
+ ownerId: doc.id,
82
+ locale: doc.locale ?? ''
83
+ });
84
+ return { ...doc, url: row?.url ?? null, _urlPath: row?.path ?? null, _slug: row?.slug ?? null };
85
+ };
86
+ let ensured;
87
+ let done = false;
88
+ /**
89
+ * Once per process, on the first request: every page of a collection with `$url` gets the address
90
+ * it is missing. One query per collection and locale once they all have one. The requests after
91
+ * it are not held: nothing to await once it is done.
92
+ */
93
+ export const ensureAddresses = async (event) => {
94
+ if (done)
95
+ return;
96
+ ensured ??= (async () => {
97
+ const { rime } = event.locals;
98
+ for (const config of rime.config.raw.collections) {
99
+ if (!hasUrl(config))
100
+ continue;
101
+ const missing = new Set();
102
+ for (const locale of addressLocales(event)) {
103
+ const ids = await rime.adapter.paths.missingOwners({ slug: config.slug, locale });
104
+ ids.forEach((id) => missing.add(id));
105
+ }
106
+ if (!missing.size)
107
+ continue;
108
+ logger.info(`${config.slug}: giving ${missing.size} pages their address`);
109
+ await addAddresses({ event, config, ids: [...missing] });
110
+ }
111
+ })().then(() => {
112
+ done = true;
113
+ }, (error) => {
114
+ // Tried again on the next request.
115
+ ensured = undefined;
116
+ logger.error(`addresses: ${error.message}`, error);
117
+ });
118
+ await ensured;
119
+ };
@@ -0,0 +1,6 @@
1
+ import type { DocTypeContribution } from '../../../dev/codegen/types/contributions.server.js';
2
+ /**
3
+ * A document of a config with `$url` carries its url. A collection's also carries its address:
4
+ * the slugs down to it and its own slug. `null` until the page has one.
5
+ */
6
+ export declare const urlDocType: (type: "collection" | "area") => DocTypeContribution;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A document of a config with `$url` carries its url. A collection's also carries its address:
3
+ * the slugs down to it and its own slug. `null` until the page has one.
4
+ */
5
+ export const urlDocType = (type) => ({
6
+ members: type === 'collection'
7
+ ? ['url: string | null', '_urlPath: string | null', '_slug: string | null']
8
+ : ['url: string | null']
9
+ });
@@ -0,0 +1,27 @@
1
+ import type { BuiltArea, BuiltCollection } from '../../../config/types.js';
2
+ import type { GenericDoc } from '../../types.js';
3
+ /**
4
+ * A page's url: `$url` with its path, slug, locale and document, made absolute against
5
+ * `PUBLIC_RIME_URL`.
6
+ *
7
+ * ```ts
8
+ * formatUrl({ config, doc, path: 'services/web', locale: 'en' }) // 'https://site.test/en/services/web'
9
+ * formatUrl({ config, doc, path: '', locale: '' }) // an area: no path, no slug
10
+ * ```
11
+ */
12
+ export declare const formatUrl: (args: {
13
+ config: BuiltCollection | BuiltArea;
14
+ doc: GenericDoc;
15
+ path: string;
16
+ locale: string;
17
+ }) => string;
18
+ /** A slug made from any text: `'Web design!'` -> `'web-design'`. Empty when nothing is left. */
19
+ export declare const toSlug: (text: unknown) => string;
20
+ /**
21
+ * `wanted`, or the first of `wanted-2`, `wanted-3`… that no sibling holds.
22
+ *
23
+ * ```ts
24
+ * freeSlug('web', ['web', 'web-2']) // 'web-3'
25
+ * ```
26
+ */
27
+ export declare const freeSlug: (wanted: string, taken: string[]) => string;
@@ -0,0 +1,38 @@
1
+ import { RimeError } from '../../../errors/index.js';
2
+ import { slugify } from '../../../../util/string.js';
3
+ /**
4
+ * A page's url: `$url` with its path, slug, locale and document, made absolute against
5
+ * `PUBLIC_RIME_URL`.
6
+ *
7
+ * ```ts
8
+ * formatUrl({ config, doc, path: 'services/web', locale: 'en' }) // 'https://site.test/en/services/web'
9
+ * formatUrl({ config, doc, path: '', locale: '' }) // an area: no path, no slug
10
+ * ```
11
+ */
12
+ export const formatUrl = (args) => {
13
+ const { config, doc, path, locale } = args;
14
+ const segments = path ? path.split('/') : [];
15
+ const url = config.$url({ path: segments, slug: segments.at(-1) ?? '', locale, doc });
16
+ if (typeof url !== 'string') {
17
+ throw new RimeError(RimeError.CONFIG_ERROR, `$url of ${config.slug} must answer a string`);
18
+ }
19
+ const origin = process.env.PUBLIC_RIME_URL;
20
+ return origin ? new URL(url, origin).href : url;
21
+ };
22
+ /** A slug made from any text: `'Web design!'` -> `'web-design'`. Empty when nothing is left. */
23
+ export const toSlug = (text) => slugify(String(text ?? '')).replace(/^-+|-+$/g, '');
24
+ /**
25
+ * `wanted`, or the first of `wanted-2`, `wanted-3`… that no sibling holds.
26
+ *
27
+ * ```ts
28
+ * freeSlug('web', ['web', 'web-2']) // 'web-3'
29
+ * ```
30
+ */
31
+ export const freeSlug = (wanted, taken) => {
32
+ if (!taken.includes(wanted))
33
+ return wanted;
34
+ let n = 2;
35
+ while (taken.includes(`${wanted}-${n}`))
36
+ n++;
37
+ return `${wanted}-${n}`;
38
+ };
@@ -0,0 +1,2 @@
1
+ /** A new page gets its address in every locale: a slug from its title, under its parent, a url. */
2
+ export declare const createPaths: import("../../../../pipeline/types.js").Hook<"generic", "create", "after">;
@@ -0,0 +1,9 @@
1
+ import { Hooks } from '../../../../pipeline/define-hook.js';
2
+ import { addAddresses, withAddress } from '../addresses.server.js';
3
+ /** A new page gets its address in every locale: a slug from its title, under its parent, a url. */
4
+ export const createPaths = Hooks.afterCreate(async function createPaths(args) {
5
+ const { event, doc } = args;
6
+ const config = args.config;
7
+ await addAddresses({ event, config, ids: [doc.id] });
8
+ return { ...args, doc: await withAddress({ event, config, doc }) };
9
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Before a delete, the page's children go to the top level with their subtrees, as `_parent`
3
+ * does, and get their new urls. The page's own rows go with it by cascade.
4
+ */
5
+ export declare const detachPaths: import("../../../../pipeline/types.js").Hook<"generic", "delete", "before">;
@@ -0,0 +1,18 @@
1
+ import { Hooks } from '../../../../pipeline/define-hook.js';
2
+ import { refreshUrls } from '../refresh.server.js';
3
+ /**
4
+ * Before a delete, the page's children go to the top level with their subtrees, as `_parent`
5
+ * does, and get their new urls. The page's own rows go with it by cascade.
6
+ */
7
+ export const detachPaths = Hooks.beforeDelete(async function detachPaths(args) {
8
+ const { event, doc } = args;
9
+ const config = args.config;
10
+ const detached = await event.locals.rime.adapter.paths.detachChildren({
11
+ slug: config.slug,
12
+ ownerId: doc.id
13
+ });
14
+ for (const row of detached) {
15
+ await refreshUrls({ event, config, locale: row.locale, path: row.path });
16
+ }
17
+ return args;
18
+ });
@@ -6,4 +6,8 @@
6
6
  * It exists because a prototype's `hooks.server.ts` writes the run order and would otherwise carry
7
7
  * one import line per hook.
8
8
  */
9
- export { populateURL } from './populate-url.server.js';
9
+ export { createPaths } from './create-paths.server.js';
10
+ export { detachPaths } from './detach-paths.server.js';
11
+ export { setAreaUrl } from './set-area-url.server.js';
12
+ export { setLiveUrl } from './set-live-url.server.js';
13
+ export { syncPaths } from './sync-paths.server.js';
@@ -6,4 +6,8 @@
6
6
  * It exists because a prototype's `hooks.server.ts` writes the run order and would otherwise carry
7
7
  * one import line per hook.
8
8
  */
9
- export { populateURL } from './populate-url.server.js';
9
+ export { createPaths } from './create-paths.server.js';
10
+ export { detachPaths } from './detach-paths.server.js';
11
+ export { setAreaUrl } from './set-area-url.server.js';
12
+ export { setLiveUrl } from './set-live-url.server.js';
13
+ export { syncPaths } from './sync-paths.server.js';
@@ -0,0 +1,2 @@
1
+ /** An area's url, built on read: one document, no parent, nothing stored. */
2
+ export declare const setAreaUrl: import("../../../../pipeline/types.js").Hook<"generic", "read", "before">;
@@ -0,0 +1,8 @@
1
+ import { Hooks } from '../../../../pipeline/define-hook.js';
2
+ import { formatUrl } from '../format.server.js';
3
+ /** An area's url, built on read: one document, no parent, nothing stored. */
4
+ export const setAreaUrl = Hooks.beforeRead(async function setAreaUrl(args) {
5
+ const { config, context } = args;
6
+ const url = formatUrl({ config, doc: args.doc, path: '', locale: context.params.locale ?? '' });
7
+ return { ...args, doc: { ...args.doc, url } };
8
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The live edit link, for staff, from the document's url: the panel opens the page there and
3
+ * sends it the edited version's content. No query.
4
+ */
5
+ export declare const setLiveUrl: import("../../../../pipeline/types").Hook<"generic", "read", "before">;
@@ -0,0 +1,19 @@
1
+ import { env } from '$env/dynamic/private';
2
+ import { PARAMS } from '../../../../constants.js';
3
+ import { Hooks } from '../../../../pipeline/define-hook.js';
4
+ /**
5
+ * The live edit link, for staff, from the document's url: the panel opens the page there and
6
+ * sends it the edited version's content. No query.
7
+ */
8
+ export const setLiveUrl = Hooks.beforeRead(async function setLiveUrl(args) {
9
+ const { config, event, context } = args;
10
+ const doc = args.doc;
11
+ if (!config.live || !event.locals.user?.isStaff || !doc.url)
12
+ return args;
13
+ let live = `${process.env.PUBLIC_RIME_URL}/${env.RIME_PANEL_ROUTE || 'panel'}/live-edit?src=${doc.url}&slug=${config.slug}&id=${doc.id}`;
14
+ if (doc.contentId)
15
+ live += `&${PARAMS.VERSION_ID}=${doc.contentId}`;
16
+ if (context.params.locale)
17
+ live += `&${PARAMS.LOCALE}=${context.params.locale}`;
18
+ return { ...args, doc: { ...doc, _live: live } };
19
+ });
@@ -0,0 +1,7 @@
1
+ /**
2
+ * After a save. A move carries the page and its subtree under the new parent, in every locale at
3
+ * once. Any other save formats the page's own urls again, since `$url` may read any of its fields.
4
+ *
5
+ * An auto-save moves nothing and changes no url: it is skipped.
6
+ */
7
+ export declare const syncPaths: import("../../../../pipeline/types.js").Hook<"generic", "update", "after">;