rimecms 0.33.0 → 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 (489) 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/index.server.js +11 -3
  6. package/dist/adapter-sqlite/generate-schema/root.server.d.ts +13 -4
  7. package/dist/adapter-sqlite/generate-schema/root.server.js +75 -131
  8. package/dist/adapter-sqlite/generate-schema/templates.server.d.ts +27 -6
  9. package/dist/adapter-sqlite/generate-schema/templates.server.js +52 -10
  10. package/dist/adapter-sqlite/index.server.d.ts +13 -5
  11. package/dist/adapter-sqlite/index.server.js +9 -6
  12. package/dist/adapter-sqlite/naming.server.d.ts +6 -8
  13. package/dist/adapter-sqlite/naming.server.js +22 -4
  14. package/dist/adapter-sqlite/paths.server.d.ts +10 -0
  15. package/dist/adapter-sqlite/paths.server.js +122 -0
  16. package/dist/adapter-sqlite/read.server.d.ts +10 -1
  17. package/dist/adapter-sqlite/read.server.js +22 -10
  18. package/dist/adapter-sqlite/select.server.d.ts +19 -0
  19. package/dist/adapter-sqlite/select.server.js +71 -63
  20. package/dist/adapter-sqlite/table.server.d.ts +2 -2
  21. package/dist/adapter-sqlite/transform.server.js +33 -3
  22. package/dist/adapter-sqlite/types.server.d.ts +10 -3
  23. package/dist/adapter-sqlite/where.server.d.ts +2 -3
  24. package/dist/adapter-sqlite/where.server.js +19 -1
  25. package/dist/core/adapter.d.ts +94 -0
  26. package/dist/core/auth/better-auth/config.server.d.ts +3 -3
  27. package/dist/core/auth/better-auth/instance.server.d.ts +6 -6
  28. package/dist/core/auth/handler/index.server.js +1 -1
  29. package/dist/core/auth/staff/derive.js +1 -1
  30. package/dist/core/auth/validate-config.js +3 -5
  31. package/dist/core/boot.server.d.ts +6 -6
  32. package/dist/core/config/types.d.ts +43 -5
  33. package/dist/core/config/validate.server.js +34 -51
  34. package/dist/core/dev/cli/commands/build.js +21 -6
  35. package/dist/core/dev/cli/commands/init.server.d.ts +2 -1
  36. package/dist/core/dev/cli/commands/init.server.js +32 -6
  37. package/dist/core/dev/cli/index.js +1 -0
  38. package/dist/core/dev/cli/templates/init.d.ts +6 -1
  39. package/dist/core/dev/cli/templates/init.js +30 -2
  40. package/dist/core/dev/cli/util/package-manager.server.d.ts +1 -0
  41. package/dist/core/dev/cli/util/package-manager.server.js +11 -8
  42. package/dist/core/dev/cli/util/package.server.d.ts +9 -0
  43. package/dist/core/dev/cli/util/package.server.js +43 -0
  44. package/dist/core/dev/codegen/types/contributions.server.d.ts +3 -2
  45. package/dist/core/dev/codegen/types/contributions.server.js +10 -3
  46. package/dist/core/dev/vite.server.js +4 -3
  47. package/dist/core/fields/blank.d.ts +21 -0
  48. package/dist/core/fields/blank.js +37 -0
  49. package/dist/core/fields/builders/field-builder.d.ts +53 -0
  50. package/dist/core/fields/builders/field-builder.js +14 -1
  51. package/dist/core/fields/builders/form-field-builder.d.ts +8 -0
  52. package/dist/core/fields/builders/form-field-builder.js +14 -1
  53. package/dist/core/fields/util.d.ts +9 -2
  54. package/dist/core/fields/util.js +123 -135
  55. package/dist/core/fields/walk.d.ts +44 -0
  56. package/dist/core/fields/walk.js +55 -0
  57. package/dist/core/handler.server.js +4 -0
  58. package/dist/core/i18n/context.d.ts +5 -0
  59. package/dist/core/i18n/context.js +6 -0
  60. package/dist/core/i18n/en/common.d.ts +71 -0
  61. package/dist/core/i18n/en/common.js +72 -1
  62. package/dist/core/i18n/en/fields.d.ts +68 -0
  63. package/dist/core/i18n/en/fields.js +69 -1
  64. package/dist/core/i18n/fr/common.d.ts +71 -0
  65. package/dist/core/i18n/fr/common.js +72 -1
  66. package/dist/core/i18n/fr/fields.d.ts +68 -0
  67. package/dist/core/i18n/fr/fields.js +69 -1
  68. package/dist/core/i18n/index.d.ts +29 -3
  69. package/dist/core/i18n/index.js +55 -29
  70. package/dist/core/locale/copy.server.js +3 -3
  71. package/dist/core/logger.server.js +15 -6
  72. package/dist/core/pipeline/build-document.server.d.ts +3 -0
  73. package/dist/core/pipeline/build-document.server.js +10 -7
  74. package/dist/core/pipeline/config-map/index.d.ts +9 -0
  75. package/dist/core/pipeline/config-map/index.js +16 -50
  76. package/dist/core/pipeline/hooks/process-document-fields.server.d.ts +3 -0
  77. package/dist/core/pipeline/hooks/process-document-fields.server.js +48 -12
  78. package/dist/core/pipeline/hooks/set-default-values.server.d.ts +1 -0
  79. package/dist/core/pipeline/hooks/set-default-values.server.js +1 -0
  80. package/dist/core/pipeline/persist/blocks/extract.server.js +1 -1
  81. package/dist/core/pipeline/persist/relations/extract.server.js +2 -0
  82. package/dist/core/pipeline/populate-relations.server.d.ts +27 -0
  83. package/dist/core/pipeline/populate-relations.server.js +42 -0
  84. package/dist/core/pipeline/run.server.d.ts +17 -6
  85. package/dist/core/pipeline/run.server.js +44 -30
  86. package/dist/core/plugins/cache/module.server.d.ts +1 -1
  87. package/dist/core/plugins/cache/module.server.js +5 -5
  88. package/dist/core/prototype/area/api.server.js +1 -2
  89. package/dist/core/prototype/area/definition.js +1 -10
  90. package/dist/core/prototype/area/definition.server.js +4 -5
  91. package/dist/core/prototype/area/hooks.server.js +3 -2
  92. package/dist/core/prototype/area/operations/find.js +2 -0
  93. package/dist/core/prototype/blank.d.ts +26 -0
  94. package/dist/core/prototype/blank.js +22 -0
  95. package/dist/core/prototype/collection/api.server.d.ts +29 -3
  96. package/dist/core/prototype/collection/api.server.js +47 -4
  97. package/dist/core/prototype/collection/definition.js +0 -3
  98. package/dist/core/prototype/collection/hooks/merge-with-blank.server.d.ts +5 -1
  99. package/dist/core/prototype/collection/hooks/merge-with-blank.server.js +8 -22
  100. package/dist/core/prototype/collection/hooks.server.js +11 -5
  101. package/dist/core/prototype/collection/nested/module.server.js +3 -1
  102. package/dist/core/prototype/collection/nested/tree.d.ts +12 -0
  103. package/dist/core/prototype/collection/nested/tree.js +42 -0
  104. package/dist/core/prototype/collection/operations/find-by-id.js +2 -0
  105. package/dist/core/prototype/collection/operations/find-by-ids.d.ts +19 -0
  106. package/dist/core/prototype/collection/operations/find-by-ids.js +54 -0
  107. package/dist/core/prototype/collection/operations/find.js +21 -27
  108. package/dist/core/prototype/collection/operations/update-slug-by-id.d.ts +20 -0
  109. package/dist/core/prototype/collection/operations/update-slug-by-id.js +53 -0
  110. package/dist/core/prototype/collection/rest/index.server.js +3 -1
  111. package/dist/core/prototype/collection/rest/update-slug-by-id.server.d.ts +2 -0
  112. package/dist/core/prototype/collection/rest/update-slug-by-id.server.js +20 -0
  113. package/dist/core/prototype/collection/thumbnail/find-thumbnail.d.ts +2 -1
  114. package/dist/core/prototype/collection/thumbnail/find-thumbnail.js +4 -27
  115. package/dist/core/prototype/collection/upload/directories/derive.js +3 -1
  116. package/dist/core/prototype/collection/upload/disk/delete.server.js +1 -2
  117. package/dist/core/prototype/define.js +2 -0
  118. package/dist/core/prototype/shared/metas/fields.js +2 -1
  119. package/dist/core/prototype/shared/title/find-title.d.ts +2 -1
  120. package/dist/core/prototype/shared/title/find-title.js +5 -28
  121. package/dist/core/prototype/shared/url/addresses.server.d.ts +26 -0
  122. package/dist/core/prototype/shared/url/addresses.server.js +119 -0
  123. package/dist/core/prototype/shared/url/doc-type.d.ts +6 -0
  124. package/dist/core/prototype/shared/url/doc-type.js +9 -0
  125. package/dist/core/prototype/shared/url/format.server.d.ts +27 -0
  126. package/dist/core/prototype/shared/url/format.server.js +38 -0
  127. package/dist/core/prototype/shared/url/hooks/create-paths.server.d.ts +2 -0
  128. package/dist/core/prototype/shared/url/hooks/create-paths.server.js +9 -0
  129. package/dist/core/prototype/shared/url/hooks/detach-paths.server.d.ts +5 -0
  130. package/dist/core/prototype/shared/url/hooks/detach-paths.server.js +18 -0
  131. package/dist/core/prototype/shared/url/hooks/index.server.d.ts +5 -1
  132. package/dist/core/prototype/shared/url/hooks/index.server.js +5 -1
  133. package/dist/core/prototype/shared/url/hooks/set-area-url.server.d.ts +2 -0
  134. package/dist/core/prototype/shared/url/hooks/set-area-url.server.js +8 -0
  135. package/dist/core/prototype/shared/url/hooks/set-live-url.server.d.ts +5 -0
  136. package/dist/core/prototype/shared/url/hooks/set-live-url.server.js +19 -0
  137. package/dist/core/prototype/shared/url/hooks/sync-paths.server.d.ts +7 -0
  138. package/dist/core/prototype/shared/url/hooks/sync-paths.server.js +37 -0
  139. package/dist/core/prototype/shared/url/refresh.server.d.ts +36 -0
  140. package/dist/core/prototype/shared/url/refresh.server.js +58 -0
  141. package/dist/core/prototype/shared/versions/configure.server.js +3 -0
  142. package/dist/core/routes/context.server.d.ts +2 -1
  143. package/dist/fields/blocks/component/AddBlockButton.svelte +48 -137
  144. package/dist/fields/blocks/component/Block.svelte +153 -117
  145. package/dist/fields/blocks/component/Block.svelte.d.ts +11 -5
  146. package/dist/fields/blocks/component/BlockActions.svelte +76 -26
  147. package/dist/fields/blocks/component/BlockActions.svelte.d.ts +3 -0
  148. package/dist/fields/blocks/component/Blocks.svelte +248 -91
  149. package/dist/fields/blocks/component/focus/BlocksFocus.svelte +680 -0
  150. package/dist/fields/blocks/component/focus/BlocksFocus.svelte.d.ts +7 -0
  151. package/dist/fields/blocks/component/focus/Layers.svelte +145 -0
  152. package/dist/fields/blocks/component/focus/Layers.svelte.d.ts +9 -0
  153. package/dist/fields/blocks/component/focus/LayersList.svelte +304 -0
  154. package/dist/fields/blocks/component/focus/LayersList.svelte.d.ts +10 -0
  155. package/dist/fields/blocks/component/focus/Palette.svelte +135 -0
  156. package/dist/fields/blocks/component/focus/Palette.svelte.d.ts +9 -0
  157. package/dist/fields/blocks/component/focus/RenderPlaceholder.svelte +77 -0
  158. package/dist/fields/blocks/component/focus/RenderPlaceholder.svelte.d.ts +10 -0
  159. package/dist/fields/blocks/component/focus/Renders.svelte +302 -0
  160. package/dist/fields/blocks/component/focus/Renders.svelte.d.ts +11 -0
  161. package/dist/fields/blocks/component/focus/Stage.svelte +190 -0
  162. package/dist/fields/blocks/component/focus/Stage.svelte.d.ts +8 -0
  163. package/dist/fields/blocks/component/focus/StagePlaceholder.svelte +69 -0
  164. package/dist/fields/blocks/component/focus/StagePlaceholder.svelte.d.ts +3 -0
  165. package/dist/fields/blocks/component/focus/focus.svelte.d.ts +140 -0
  166. package/dist/fields/blocks/component/focus/focus.svelte.js +424 -0
  167. package/dist/fields/blocks/component/picker/BlockPicker.svelte +88 -0
  168. package/dist/fields/blocks/component/picker/BlockPicker.svelte.d.ts +10 -0
  169. package/dist/fields/blocks/component/picker/BlockTile.svelte +121 -0
  170. package/dist/fields/blocks/component/picker/BlockTile.svelte.d.ts +12 -0
  171. package/dist/fields/blocks/index.d.ts +49 -7
  172. package/dist/fields/blocks/index.js +61 -12
  173. package/dist/fields/checkbox/component/Checkbox.svelte +11 -37
  174. package/dist/fields/checkbox/component/Checkbox.svelte.d.ts +1 -0
  175. package/dist/fields/combobox/component/ComboBox.svelte +37 -7
  176. package/dist/fields/combobox/component/combobox.css +26 -10
  177. package/dist/fields/date/component/Date.svelte +43 -12
  178. package/dist/fields/group/component/Group.svelte +110 -41
  179. package/dist/fields/group/index.d.ts +5 -1
  180. package/dist/fields/group/index.js +10 -2
  181. package/dist/fields/link/component/Link.svelte +184 -143
  182. package/dist/fields/link/component/RessourceInput.svelte +26 -24
  183. package/dist/fields/link/index.d.ts +1 -0
  184. package/dist/fields/link/module.server.js +2 -4
  185. package/dist/fields/number/component/Number.svelte +38 -20
  186. package/dist/fields/number/component/number.css +22 -20
  187. package/dist/fields/number/index.d.ts +1 -0
  188. package/dist/fields/radio/component/Radio.svelte +12 -0
  189. package/dist/fields/radio/index.js +1 -1
  190. package/dist/fields/relation/component/Relation.svelte +169 -40
  191. package/dist/fields/relation/component/RelationInline.svelte +258 -0
  192. package/dist/fields/relation/component/RelationInline.svelte.d.ts +26 -0
  193. package/dist/fields/relation/component/default/Default.svelte +210 -100
  194. package/dist/fields/relation/component/default/Default.svelte.d.ts +14 -1
  195. package/dist/fields/relation/component/types.d.ts +4 -0
  196. package/dist/fields/relation/component/upload/Browse.svelte +619 -88
  197. package/dist/fields/relation/component/upload/Browse.svelte.d.ts +10 -2
  198. package/dist/fields/relation/component/upload/Create.svelte +41 -0
  199. package/dist/fields/relation/component/upload/Create.svelte.d.ts +13 -0
  200. package/dist/fields/relation/component/upload/Upload.svelte +287 -101
  201. package/dist/fields/relation/component/upload/Upload.svelte.d.ts +6 -1
  202. package/dist/fields/relation/component/upload/upload.css +5 -81
  203. package/dist/fields/relation/module.server.js +7 -1
  204. package/dist/fields/relation/value.d.ts +25 -0
  205. package/dist/fields/relation/value.js +27 -0
  206. package/dist/fields/rich-text/component/RichText.svelte +12 -80
  207. package/dist/fields/rich-text/component/RichText.svelte.d.ts +1 -1
  208. package/dist/fields/rich-text/component/RichTextInline.svelte +28 -0
  209. package/dist/fields/rich-text/component/RichTextInline.svelte.d.ts +11 -0
  210. package/dist/fields/rich-text/component/bubble-menu/bubble-menu.css +4 -3
  211. package/dist/fields/rich-text/component/bubble-menu/bubble-menu.svelte +3 -1
  212. package/dist/fields/rich-text/component/bubble-menu/icon-button/icon-button.css +2 -2
  213. package/dist/fields/rich-text/component/bubble-menu/node-selector/node-selector.css +7 -10
  214. package/dist/fields/rich-text/component/drag-handle/drag-handle.css +0 -2
  215. package/dist/fields/rich-text/component/styles/editor.css +111 -0
  216. package/dist/fields/rich-text/component/styles/field.css +71 -0
  217. package/dist/fields/rich-text/component/suggestion/suggestion.svelte +41 -56
  218. package/dist/fields/rich-text/core/build-editor-config.js +1 -1
  219. package/dist/fields/rich-text/core/extensions/drag-handle/drag-handle-plugin.js +29 -3
  220. package/dist/fields/rich-text/core/extensions/drag-handle/drag-handle.d.ts +1 -0
  221. package/dist/fields/rich-text/core/extensions/drag-handle/drag-handle.js +2 -1
  222. package/dist/fields/rich-text/core/features/fields/fields.css +2 -3
  223. package/dist/fields/rich-text/core/features/hr/hr.css +4 -4
  224. package/dist/fields/rich-text/core/features/link/component/link-selector.css +0 -4
  225. package/dist/fields/rich-text/core/features/link/component/link-selector.svelte +24 -8
  226. package/dist/fields/rich-text/core/features/resource/resource.svelte +20 -6
  227. package/dist/fields/rich-text/core/features/upload/upload.svelte +20 -8
  228. package/dist/fields/rich-text/core/rich-text-editor-core.svelte +103 -0
  229. package/dist/fields/rich-text/core/rich-text-editor-core.svelte.d.ts +15 -0
  230. package/dist/fields/select/component/Select.svelte +67 -28
  231. package/dist/fields/slug/component/Slug.svelte +26 -53
  232. package/dist/fields/slug/index.d.ts +1 -0
  233. package/dist/fields/slug/index.js +1 -1
  234. package/dist/fields/tabs/component/Tabs.svelte +28 -22
  235. package/dist/fields/tabs/index.d.ts +4 -1
  236. package/dist/fields/tabs/index.js +17 -5
  237. package/dist/fields/text/index.d.ts +1 -0
  238. package/dist/fields/textarea/component/TextArea.svelte +28 -13
  239. package/dist/fields/textarea/index.d.ts +1 -0
  240. package/dist/fields/time/component/Time.svelte +9 -2
  241. package/dist/fields/toggle/component/Toggle.svelte +8 -25
  242. package/dist/fields/toggle/component/Toggle.svelte.d.ts +1 -0
  243. package/dist/fields/toggle/index.d.ts +1 -0
  244. package/dist/fields/tree/component/AddItemButton.svelte +18 -5
  245. package/dist/fields/tree/component/Tree.svelte +48 -19
  246. package/dist/fields/tree/component/TreeBlock.svelte +318 -104
  247. package/dist/fields/tree/component/TreeBlockActions.svelte +71 -7
  248. package/dist/fields/tree/component/TreeBlockActions.svelte.d.ts +4 -0
  249. package/dist/fields/tree/component/props.d.ts +2 -1
  250. package/dist/fields/tree/index.d.ts +13 -1
  251. package/dist/fields/tree/index.js +35 -9
  252. package/dist/fields/types.d.ts +3 -1
  253. package/dist/index.d.ts +4 -3
  254. package/dist/index.js +3 -2
  255. package/dist/panel/components/Root.svelte +16 -44
  256. package/dist/panel/components/Root.svelte.d.ts +1 -1
  257. package/dist/panel/components/fields/Error.svelte +18 -3
  258. package/dist/panel/components/fields/FieldsPreview.svelte +30 -17
  259. package/dist/panel/components/fields/FieldsPreviewTrigger.svelte +25 -3
  260. package/dist/panel/components/fields/Hint.svelte +51 -8
  261. package/dist/panel/components/fields/Hint.svelte.d.ts +11 -0
  262. package/dist/panel/components/fields/Label.svelte +2 -0
  263. package/dist/panel/components/fields/LabelFor.svelte +7 -2
  264. package/dist/panel/components/fields/RenderFields.svelte +10 -3
  265. package/dist/panel/components/fields/fieldset.svelte.d.ts +4 -1
  266. package/dist/panel/components/fields/fieldset.svelte.js +9 -2
  267. package/dist/panel/components/fields/index.d.ts +1 -0
  268. package/dist/panel/components/fields/setting.css +82 -0
  269. package/dist/panel/components/sections/auth/AuthForm.svelte +25 -26
  270. package/dist/panel/components/sections/collection/Avatar.svelte +61 -0
  271. package/dist/panel/components/sections/collection/Avatar.svelte.d.ts +9 -0
  272. package/dist/panel/components/sections/collection/DocStatus.svelte +28 -0
  273. package/dist/panel/components/sections/collection/DocStatus.svelte.d.ts +7 -0
  274. package/dist/panel/components/sections/collection/Empty.svelte +3 -3
  275. package/dist/panel/components/sections/collection/StatusDot.svelte +7 -5
  276. package/dist/panel/components/sections/collection/When.svelte +33 -0
  277. package/dist/panel/components/sections/collection/When.svelte.d.ts +8 -0
  278. package/dist/panel/components/sections/collection/bulk-upload/BulkUploadDialog.svelte +65 -21
  279. package/dist/panel/components/sections/collection/bulk-upload/BulkUploadDialog.svelte.d.ts +3 -2
  280. package/dist/panel/components/sections/collection/bulk-upload/DropZone.svelte +45 -162
  281. package/dist/panel/components/sections/collection/bulk-upload/DropZone.svelte.d.ts +3 -2
  282. package/dist/panel/components/sections/collection/bulk-upload/FileDrop.svelte +151 -0
  283. package/dist/panel/components/sections/collection/bulk-upload/FileDrop.svelte.d.ts +17 -0
  284. package/dist/panel/components/sections/collection/bulk-upload/PageDrop.svelte +177 -0
  285. package/dist/panel/components/sections/collection/bulk-upload/PageDrop.svelte.d.ts +12 -0
  286. package/dist/panel/components/sections/collection/bulk-upload/UploadProgress.svelte +75 -0
  287. package/dist/panel/components/sections/collection/bulk-upload/UploadProgress.svelte.d.ts +8 -0
  288. package/dist/panel/components/sections/collection/folder/Folder.svelte +18 -3
  289. package/dist/panel/components/sections/collection/folder/FolderEdit.svelte +26 -18
  290. package/dist/panel/components/sections/collection/folder/FolderWithActions.svelte +98 -58
  291. package/dist/panel/components/sections/collection/folder/FolderWithActions.svelte.d.ts +0 -1
  292. package/dist/panel/components/sections/collection/folder/Folders.svelte +60 -0
  293. package/dist/panel/components/sections/collection/folder/Folders.svelte.d.ts +7 -0
  294. package/dist/panel/components/sections/collection/grid/CollectionGrid.svelte +31 -71
  295. package/dist/panel/components/sections/collection/grid/CollectionGrid.svelte.d.ts +1 -0
  296. package/dist/panel/components/sections/collection/grid/create-directory-dialog/CreateDirectoryDialog.svelte +5 -3
  297. package/dist/panel/components/sections/collection/grid/grid-item/GridItem.svelte +250 -37
  298. package/dist/panel/components/sections/collection/grid/grid-item/GridItem.svelte.d.ts +2 -0
  299. package/dist/panel/components/sections/collection/header/ButtonCreate.svelte +43 -18
  300. package/dist/panel/components/sections/collection/header/ButtonCreate.svelte.d.ts +6 -4
  301. package/dist/panel/components/sections/collection/header/DisplayMode.svelte +69 -58
  302. package/dist/panel/components/sections/collection/header/DisplayMode.svelte.d.ts +0 -1
  303. package/dist/panel/components/sections/collection/header/FilterMenu.svelte +60 -0
  304. package/dist/panel/components/sections/collection/header/FilterMenu.svelte.d.ts +14 -0
  305. package/dist/panel/components/sections/collection/header/SearchInput.svelte +17 -26
  306. package/dist/panel/components/sections/collection/header/SelectUI.svelte +19 -34
  307. package/dist/panel/components/sections/collection/list/CollectionList.svelte +99 -68
  308. package/dist/panel/components/sections/collection/list/columns.d.ts +21 -0
  309. package/dist/panel/components/sections/collection/list/columns.js +23 -0
  310. package/dist/panel/components/sections/collection/list/header/Header.svelte +99 -51
  311. package/dist/panel/components/sections/collection/list/row/Row.svelte +165 -82
  312. package/dist/panel/components/sections/collection/list/row/Row.svelte.d.ts +4 -0
  313. package/dist/panel/components/sections/collection/tree/CollectionTree.svelte +92 -44
  314. package/dist/panel/components/sections/collection/tree/CollectionTree.svelte.d.ts +1 -0
  315. package/dist/panel/components/sections/collection/tree/CollectionTreeNode.svelte +139 -43
  316. package/dist/panel/components/sections/collection/tree/CollectionTreeNode.svelte.d.ts +2 -0
  317. package/dist/panel/components/sections/collection/upload-thumb-cell/UploadThumbCell.svelte +1 -1
  318. package/dist/panel/components/sections/commands/CommandButton.svelte +99 -0
  319. package/dist/panel/components/sections/commands/CommandButton.svelte.d.ts +10 -0
  320. package/dist/panel/components/sections/commands/CommandPalette.svelte +275 -0
  321. package/dist/panel/components/sections/commands/CommandPalette.svelte.d.ts +8 -0
  322. package/dist/panel/components/sections/commands/Commands.svelte +18 -0
  323. package/dist/panel/components/sections/commands/Commands.svelte.d.ts +9 -0
  324. package/dist/panel/components/sections/document/AuthAPIKeyDialog.svelte +23 -7
  325. package/dist/panel/components/sections/document/AuthFooter.svelte +31 -12
  326. package/dist/panel/components/sections/document/AutoSaveBanner.svelte +24 -7
  327. package/dist/panel/components/sections/document/ButtonSave.svelte +32 -21
  328. package/dist/panel/components/sections/document/ButtonSave.svelte.d.ts +5 -5
  329. package/dist/panel/components/sections/document/ButtonStatus.svelte +68 -20
  330. package/dist/panel/components/sections/document/ChangeSlugDialog.svelte +199 -0
  331. package/dist/panel/components/sections/document/ChangeSlugDialog.svelte.d.ts +10 -0
  332. package/dist/panel/components/sections/document/CurrentlyEdited.svelte +2 -2
  333. package/dist/panel/components/sections/document/Document.svelte +96 -65
  334. package/dist/panel/components/sections/document/DocumentChildren.svelte +175 -0
  335. package/dist/panel/components/sections/document/DocumentChildren.svelte.d.ts +8 -0
  336. package/dist/panel/components/sections/document/DocumentUrl.svelte +119 -0
  337. package/dist/panel/components/sections/document/DocumentUrl.svelte.d.ts +9 -0
  338. package/dist/panel/components/sections/document/Header.svelte +171 -94
  339. package/dist/panel/components/sections/document/Settings.svelte +255 -110
  340. package/dist/panel/components/sections/document/Settings.svelte.d.ts +0 -1
  341. package/dist/panel/components/sections/document/Versions.svelte +5 -3
  342. package/dist/panel/components/sections/document/upload-header/UploadHeader.svelte +112 -53
  343. package/dist/panel/components/sections/document/upload-header/UploadHeader.svelte.d.ts +2 -2
  344. package/dist/panel/components/sections/document/upload-header/drop-zone/DropZone.svelte +74 -41
  345. package/dist/panel/components/sections/document/upload-header/drop-zone/DropZone.svelte.d.ts +1 -1
  346. package/dist/panel/components/sections/live/LiveEdit.svelte +2 -2
  347. package/dist/panel/components/sections/live/LiveFloatingUI.svelte +30 -11
  348. package/dist/panel/components/sections/live/live-edit-panel.css +2 -2
  349. package/dist/panel/components/sections/page-layout/Page.svelte +13 -1
  350. package/dist/panel/components/ui/breadcrumb/BreadCrumb.svelte +55 -27
  351. package/dist/panel/components/ui/button/button.svelte +81 -54
  352. package/dist/panel/components/ui/button/index.d.ts +7 -3
  353. package/dist/panel/components/ui/button/index.js +2 -2
  354. package/dist/panel/components/ui/calendar/calendar.css +27 -27
  355. package/dist/panel/components/ui/calendar/calendar.svelte.d.ts +1 -1
  356. package/dist/panel/components/ui/card/card-description.svelte +1 -1
  357. package/dist/panel/components/ui/card/card.svelte +21 -4
  358. package/dist/panel/components/ui/card-document/card-document.svelte +24 -12
  359. package/dist/panel/components/ui/card-resource/card-resource.svelte +26 -8
  360. package/dist/panel/components/ui/checkbox/checkbox.css +8 -10
  361. package/dist/panel/components/ui/command/command-dialog.css +28 -4
  362. package/dist/panel/components/ui/command/command-dialog.svelte +4 -1
  363. package/dist/panel/components/ui/command/command-dialog.svelte.d.ts +2 -0
  364. package/dist/panel/components/ui/command/command-empty.css +1 -1
  365. package/dist/panel/components/ui/command/command-group.css +3 -3
  366. package/dist/panel/components/ui/command/command-input-select.svelte +3 -3
  367. package/dist/panel/components/ui/command/command-input.svelte +38 -14
  368. package/dist/panel/components/ui/command/command-input.svelte.d.ts +6 -1
  369. package/dist/panel/components/ui/command/command-item.css +2 -2
  370. package/dist/panel/components/ui/command/command-list.css +1 -1
  371. package/dist/panel/components/ui/command/command-separator.css +1 -1
  372. package/dist/panel/components/ui/context-menu/context-menu-item.css +2 -2
  373. package/dist/panel/components/ui/context-menu/context-menu.css +6 -7
  374. package/dist/panel/components/ui/dialog/dialog-content.css +8 -10
  375. package/dist/panel/components/ui/dialog/dialog-content.svelte +19 -0
  376. package/dist/panel/components/ui/dialog/dialog-description.css +1 -1
  377. package/dist/panel/components/ui/dialog/dialog-footer.svelte +5 -1
  378. package/dist/panel/components/ui/dialog/dialog-overlay.css +1 -1
  379. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +19 -5
  380. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-content.css +6 -4
  381. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-item.css +1 -1
  382. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-radio-item.css +1 -1
  383. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-separator.css +1 -1
  384. package/dist/panel/components/ui/input/input.svelte +57 -31
  385. package/dist/panel/components/ui/kbd/Kbd.svelte +90 -0
  386. package/dist/panel/components/ui/kbd/Kbd.svelte.d.ts +11 -0
  387. package/dist/panel/components/ui/kbd/index.d.ts +1 -0
  388. package/dist/panel/components/ui/kbd/index.js +1 -0
  389. package/dist/panel/components/ui/label/label.css +5 -3
  390. package/dist/panel/components/ui/language-switcher/LanguageSwitcher.svelte +27 -15
  391. package/dist/panel/components/ui/nav/Nav.svelte +180 -110
  392. package/dist/panel/components/ui/nav/Nav.svelte.d.ts +0 -2
  393. package/dist/panel/components/ui/nav/NavGroup.svelte +87 -73
  394. package/dist/panel/components/ui/nav/NavItemButton.svelte +69 -29
  395. package/dist/panel/components/ui/nav/UserButton.svelte +132 -71
  396. package/dist/panel/components/ui/page-header/PageHeader.svelte +140 -42
  397. package/dist/panel/components/ui/page-header/PageHeader.svelte.d.ts +8 -1
  398. package/dist/panel/components/ui/popover/popover-content.css +4 -3
  399. package/dist/panel/components/ui/radio-group/radio-group.css +4 -6
  400. package/dist/panel/components/ui/radio-row-group/radio-row-group.css +19 -7
  401. package/dist/panel/components/ui/scroll-area/scroll-area.css +2 -2
  402. package/dist/panel/components/ui/separator/separator.svelte +1 -1
  403. package/dist/panel/components/ui/sheet/index.d.ts +4 -4
  404. package/dist/panel/components/ui/sheet/index.js +5 -5
  405. package/dist/panel/components/ui/sheet/sheet.css +50 -11
  406. package/dist/panel/components/ui/sonner/sonner.css +11 -8
  407. package/dist/panel/components/ui/switch/switch.css +13 -18
  408. package/dist/panel/components/ui/tabs/tabs.css +44 -35
  409. package/dist/panel/components/ui/tag/tag.svelte +20 -6
  410. package/dist/panel/components/ui/tooltip/tooltip-content.svelte +14 -4
  411. package/dist/panel/components/ui/tree/tree-rows.css +146 -0
  412. package/dist/panel/context/blocks-ops.d.ts +78 -0
  413. package/dist/panel/context/blocks-ops.js +170 -0
  414. package/dist/panel/context/collection.svelte.d.ts +28 -0
  415. package/dist/panel/context/collection.svelte.js +120 -65
  416. package/dist/panel/context/commands.svelte.d.ts +80 -0
  417. package/dist/panel/context/commands.svelte.js +108 -0
  418. package/dist/panel/context/documentForm.svelte.d.ts +34 -2
  419. package/dist/panel/context/documentForm.svelte.js +105 -102
  420. package/dist/panel/context/live.svelte.js +2 -73
  421. package/dist/panel/context/nav.svelte.d.ts +23 -0
  422. package/dist/panel/context/nav.svelte.js +56 -0
  423. package/dist/panel/fonts/Geist-VariableFont_wght.ttf +0 -0
  424. package/dist/panel/fonts/GeistMono-VariableFont_wght.ttf +0 -0
  425. package/dist/panel/index.d.ts +7 -1
  426. package/dist/panel/index.js +10 -1
  427. package/dist/panel/pages/auth/forgot-password/ForgotPassword.svelte +16 -1
  428. package/dist/panel/pages/collection/CollectionPage.svelte +236 -61
  429. package/dist/panel/pages/collection/load.server.js +1 -1
  430. package/dist/panel/pages/dashboard/Dashboard.svelte +135 -90
  431. package/dist/panel/pages/dashboard/DashboardCard.svelte +109 -0
  432. package/dist/panel/pages/dashboard/DashboardCard.svelte.d.ts +14 -0
  433. package/dist/panel/pages/dashboard/DashboardCollection.svelte +180 -57
  434. package/dist/panel/pages/dashboard/DashboardCollection.svelte.d.ts +1 -0
  435. package/dist/panel/pages/dashboard/DashboardRow.svelte +93 -0
  436. package/dist/panel/pages/dashboard/DashboardRow.svelte.d.ts +16 -0
  437. package/dist/panel/pages/dashboard/load.server.js +49 -25
  438. package/dist/panel/pages/dashboard/time.d.ts +19 -0
  439. package/dist/panel/pages/dashboard/time.js +29 -0
  440. package/dist/panel/pages/dashboard/types.d.ts +9 -2
  441. package/dist/panel/pages/live/Live.svelte +53 -50
  442. package/dist/panel/style/font.css +21 -32
  443. package/dist/panel/style/index.css +191 -122
  444. package/dist/panel/style/mixins/index.css +14 -0
  445. package/dist/panel/style/palette.css +35 -26
  446. package/dist/panel/style/postcss/size-function.d.ts +4 -0
  447. package/dist/panel/style/postcss/size-function.js +24 -0
  448. package/dist/panel/style/radius.css +4 -5
  449. package/dist/panel/style/scheme.css +111 -0
  450. package/dist/panel/style/size.css +3 -0
  451. package/dist/panel/util/Sortable.js +9 -4
  452. package/dist/panel/util/keys.d.ts +24 -0
  453. package/dist/panel/util/keys.js +63 -0
  454. package/dist/panel/util/populate.d.ts +8 -0
  455. package/dist/panel/util/populate.js +49 -0
  456. package/dist/panel/util/time.d.ts +12 -0
  457. package/dist/panel/util/time.js +35 -0
  458. package/dist/panel/util/upload-file.d.ts +106 -0
  459. package/dist/panel/util/upload-file.js +165 -0
  460. package/dist/util/index.d.ts +7 -10
  461. package/dist/util/index.js +7 -8
  462. package/dist/util/object.d.ts +10 -0
  463. package/dist/util/object.js +22 -1
  464. package/dist/util/string.d.ts +17 -0
  465. package/dist/util/string.js +23 -0
  466. package/package.json +1 -3
  467. package/dist/core/pipeline/config-map/build-tree-map.d.ts +0 -4
  468. package/dist/core/pipeline/config-map/build-tree-map.js +0 -30
  469. package/dist/core/prototype/doc.d.ts +0 -31
  470. package/dist/core/prototype/doc.js +0 -118
  471. package/dist/core/prototype/shared/url/augment.d.ts +0 -13
  472. package/dist/core/prototype/shared/url/augment.js +0 -11
  473. package/dist/core/prototype/shared/url/hooks/populate-url.server.d.ts +0 -4
  474. package/dist/core/prototype/shared/url/hooks/populate-url.server.js +0 -120
  475. package/dist/fields/rich-text/component/styles/rich-text.css +0 -183
  476. package/dist/panel/components/sections/collection/header/Header.svelte +0 -17
  477. package/dist/panel/components/sections/collection/header/Header.svelte.d.ts +0 -3
  478. package/dist/panel/components/sections/collection/header/Separator.svelte +0 -8
  479. package/dist/panel/components/sections/collection/header/Separator.svelte.d.ts +0 -26
  480. package/dist/panel/components/sections/collection/tree/util.d.ts +0 -12
  481. package/dist/panel/components/sections/collection/tree/util.js +0 -22
  482. package/dist/panel/fonts/ChivoMono-Italic-VariableFont_wght.ttf +0 -0
  483. package/dist/panel/fonts/ChivoMono-VariableFont_wght.ttf +0 -0
  484. package/dist/panel/fonts/Inter-VariableFont_slnt,wght.ttf +0 -0
  485. package/dist/panel/fonts/Lora-Italic-VariableFont_wght.ttf +0 -0
  486. package/dist/panel/fonts/Lora-VariableFont_wght.ttf +0 -0
  487. package/dist/panel/style/shadow.css +0 -10
  488. package/dist/util/path.d.ts +0 -16
  489. package/dist/util/path.js +0 -19
@@ -0,0 +1,19 @@
1
+ import type { BuiltCollection } from '../../../config/types.js';
2
+ import type { PrototypeApiContext } from '../../define.js';
3
+ import type { GenericDoc } from '../../types.js';
4
+ export type FindByIdsArgs = {
5
+ ids: string[];
6
+ locale?: string | undefined;
7
+ depth?: number;
8
+ /** See the collection's findById. */
9
+ localeFallback?: boolean;
10
+ };
11
+ type Args = FindByIdsArgs & {
12
+ ctx: PrototypeApiContext<BuiltCollection>;
13
+ };
14
+ /**
15
+ * The published documents with these ids, in one read. A missing id, or one this reader is refused,
16
+ * is left out.
17
+ */
18
+ export declare const findByIds: <T extends GenericDoc>(args: Args) => Promise<T[]>;
19
+ export {};
@@ -0,0 +1,54 @@
1
+ import { readableReferences } from '../../../fields/util.js';
2
+ import { RimeError } from '../../../errors/index.js';
3
+ import { logger } from '../../../logger.server.js';
4
+ import { readDocuments, runBeforeOperation } from '../../../pipeline/run.server.js';
5
+ import { trycatch } from '../../../../util/function.js';
6
+ /**
7
+ * The published documents with these ids, in one read. A missing id, or one this reader is refused,
8
+ * is left out.
9
+ */
10
+ export const findByIds = async (args) => {
11
+ const { ctx, ids, locale, depth, localeFallback } = args;
12
+ const { config, event, isSystemOperation } = ctx;
13
+ // The beforeOperation chain findById runs, once per id: a read rule that looks at `id` answers
14
+ // for each document as it would one at a time. A refusal leaves the id out; anything else throws.
15
+ const readable = [];
16
+ for (const id of ids) {
17
+ const [error] = await trycatch(() => runBeforeOperation({
18
+ config,
19
+ event,
20
+ operation: 'read',
21
+ context: { isSystemOperation, params: { id, locale, depth } }
22
+ }));
23
+ if (!error)
24
+ readable.push(id);
25
+ else if (!(error instanceof RimeError && error.code === RimeError.UNAUTHORIZED))
26
+ throw error;
27
+ }
28
+ if (!readable.length)
29
+ return [];
30
+ const documentsRaw = await event.locals.rime.adapter.collection(config.slug).findMany({
31
+ // `id` names the document on a versioned collection too: the adapter reads it as `ownerId`.
32
+ query: { where: { id: { in_array: readable } } },
33
+ locale,
34
+ localeFallback,
35
+ resolve: isSystemOperation ? undefined : readableReferences(config.fields, event.locals.user),
36
+ // The published row, as findById reads with no `latest` and no `versionId`.
37
+ content: ctx.versionQuery({})
38
+ });
39
+ const results = await readDocuments({
40
+ raws: documentsRaw,
41
+ config,
42
+ event,
43
+ context: { isSystemOperation, params: { locale, depth, select: [] } },
44
+ locale,
45
+ localeFallback,
46
+ depth
47
+ });
48
+ return results.flatMap((result) => {
49
+ if (result.status === 'fulfilled')
50
+ return [result.value.doc];
51
+ logger.error(result.reason.message, result.reason);
52
+ return [];
53
+ });
54
+ };
@@ -1,5 +1,6 @@
1
+ import { readableReferences } from '../../../fields/util.js';
1
2
  import { logger } from '../../../logger.server.js';
2
- import { readDocument, runBeforeOperation } from '../../../pipeline/run.server.js';
3
+ import { readDocuments, runBeforeOperation } from '../../../pipeline/run.server.js';
3
4
  export const find = async (args) => {
4
5
  //
5
6
  const { ctx, locale, sort, limit, offset, depth, query, latest, select = [], localeFallback } = args;
@@ -32,34 +33,27 @@ export const find = async (args) => {
32
33
  locale,
33
34
  localeFallback,
34
35
  select,
36
+ resolve: isSystemOperation ? undefined : readableReferences(config.fields, event.locals.user),
35
37
  // Which content row each document shows. `and`ed with `query` by the adapter, rather than
36
38
  // spliced into it — see the collection's findById for where the answer comes from.
37
39
  content: ctx.versionQuery({ latest })
38
40
  });
39
- async function processDocument(documentRaw) {
40
- try {
41
- const result = await readDocument({
42
- raw: documentRaw,
43
- config,
44
- event,
45
- context,
46
- locale,
47
- localeFallback,
48
- depth,
49
- select
50
- });
51
- context = result.context;
52
- return result.doc;
53
- }
54
- catch (error) {
55
- // Skip this document and carry on with the next one. The transform is inside the try
56
- // alongside the hooks now: a row rime cannot turn into a document is the same kind of
57
- // per-row problem as a beforeRead hook rejecting one, and taking the whole query down
58
- // for it made a single bad row look like an empty collection.
59
- logger.error(error.message, error);
60
- return null;
61
- }
62
- }
63
- const documents = await Promise.all(documentsRaw.map((doc) => processDocument(doc)));
64
- return documents.filter((d) => !!d);
41
+ const results = await readDocuments({
42
+ raws: documentsRaw,
43
+ config,
44
+ event,
45
+ context,
46
+ locale,
47
+ localeFallback,
48
+ depth,
49
+ select
50
+ });
51
+ // A row rime cannot turn into a document, or that a beforeRead hook rejects, is skipped: one bad
52
+ // row does not take the whole list down.
53
+ return results.flatMap((result) => {
54
+ if (result.status === 'fulfilled')
55
+ return [result.value.doc];
56
+ logger.error(result.reason.message, result.reason);
57
+ return [];
58
+ });
65
59
  };
@@ -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;