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.
- package/dist/adapter-sqlite/auth.server.d.ts +2 -2
- package/dist/adapter-sqlite/columns.server.js +2 -2
- package/dist/adapter-sqlite/connect.server.d.ts +12 -0
- package/dist/adapter-sqlite/connect.server.js +31 -0
- package/dist/adapter-sqlite/generate-schema/index.server.js +11 -3
- package/dist/adapter-sqlite/generate-schema/root.server.d.ts +13 -4
- package/dist/adapter-sqlite/generate-schema/root.server.js +75 -131
- package/dist/adapter-sqlite/generate-schema/templates.server.d.ts +27 -6
- package/dist/adapter-sqlite/generate-schema/templates.server.js +52 -10
- package/dist/adapter-sqlite/index.server.d.ts +13 -5
- package/dist/adapter-sqlite/index.server.js +9 -6
- package/dist/adapter-sqlite/naming.server.d.ts +6 -8
- package/dist/adapter-sqlite/naming.server.js +22 -4
- package/dist/adapter-sqlite/paths.server.d.ts +10 -0
- package/dist/adapter-sqlite/paths.server.js +122 -0
- package/dist/adapter-sqlite/read.server.d.ts +10 -1
- package/dist/adapter-sqlite/read.server.js +22 -10
- package/dist/adapter-sqlite/select.server.d.ts +19 -0
- package/dist/adapter-sqlite/select.server.js +71 -63
- package/dist/adapter-sqlite/table.server.d.ts +2 -2
- package/dist/adapter-sqlite/transform.server.js +33 -3
- package/dist/adapter-sqlite/types.server.d.ts +10 -3
- package/dist/adapter-sqlite/where.server.d.ts +2 -3
- package/dist/adapter-sqlite/where.server.js +19 -1
- package/dist/core/adapter.d.ts +94 -0
- package/dist/core/auth/better-auth/config.server.d.ts +3 -3
- package/dist/core/auth/better-auth/instance.server.d.ts +6 -6
- package/dist/core/auth/handler/index.server.js +1 -1
- package/dist/core/auth/staff/derive.js +1 -1
- package/dist/core/auth/validate-config.js +3 -5
- package/dist/core/boot.server.d.ts +6 -6
- package/dist/core/config/types.d.ts +43 -5
- package/dist/core/config/validate.server.js +34 -51
- package/dist/core/dev/cli/commands/build.js +21 -6
- package/dist/core/dev/cli/commands/init.server.d.ts +2 -1
- package/dist/core/dev/cli/commands/init.server.js +32 -6
- package/dist/core/dev/cli/index.js +1 -0
- package/dist/core/dev/cli/templates/init.d.ts +6 -1
- package/dist/core/dev/cli/templates/init.js +30 -2
- package/dist/core/dev/cli/util/package-manager.server.d.ts +1 -0
- package/dist/core/dev/cli/util/package-manager.server.js +11 -8
- package/dist/core/dev/cli/util/package.server.d.ts +9 -0
- package/dist/core/dev/cli/util/package.server.js +43 -0
- package/dist/core/dev/codegen/types/contributions.server.d.ts +3 -2
- package/dist/core/dev/codegen/types/contributions.server.js +10 -3
- package/dist/core/dev/vite.server.js +4 -3
- package/dist/core/fields/blank.d.ts +21 -0
- package/dist/core/fields/blank.js +37 -0
- package/dist/core/fields/builders/field-builder.d.ts +53 -0
- package/dist/core/fields/builders/field-builder.js +14 -1
- package/dist/core/fields/builders/form-field-builder.d.ts +8 -0
- package/dist/core/fields/builders/form-field-builder.js +14 -1
- package/dist/core/fields/util.d.ts +9 -2
- package/dist/core/fields/util.js +123 -135
- package/dist/core/fields/walk.d.ts +44 -0
- package/dist/core/fields/walk.js +55 -0
- package/dist/core/handler.server.js +4 -0
- package/dist/core/i18n/context.d.ts +5 -0
- package/dist/core/i18n/context.js +6 -0
- package/dist/core/i18n/en/common.d.ts +71 -0
- package/dist/core/i18n/en/common.js +72 -1
- package/dist/core/i18n/en/fields.d.ts +68 -0
- package/dist/core/i18n/en/fields.js +69 -1
- package/dist/core/i18n/fr/common.d.ts +71 -0
- package/dist/core/i18n/fr/common.js +72 -1
- package/dist/core/i18n/fr/fields.d.ts +68 -0
- package/dist/core/i18n/fr/fields.js +69 -1
- package/dist/core/i18n/index.d.ts +29 -3
- package/dist/core/i18n/index.js +55 -29
- package/dist/core/locale/copy.server.js +3 -3
- package/dist/core/logger.server.js +15 -6
- package/dist/core/pipeline/build-document.server.d.ts +3 -0
- package/dist/core/pipeline/build-document.server.js +10 -7
- package/dist/core/pipeline/config-map/index.d.ts +9 -0
- package/dist/core/pipeline/config-map/index.js +16 -50
- package/dist/core/pipeline/hooks/process-document-fields.server.d.ts +3 -0
- package/dist/core/pipeline/hooks/process-document-fields.server.js +48 -12
- package/dist/core/pipeline/hooks/set-default-values.server.d.ts +1 -0
- package/dist/core/pipeline/hooks/set-default-values.server.js +1 -0
- package/dist/core/pipeline/persist/blocks/extract.server.js +1 -1
- package/dist/core/pipeline/persist/relations/extract.server.js +2 -0
- package/dist/core/pipeline/populate-relations.server.d.ts +27 -0
- package/dist/core/pipeline/populate-relations.server.js +42 -0
- package/dist/core/pipeline/run.server.d.ts +17 -6
- package/dist/core/pipeline/run.server.js +44 -30
- package/dist/core/plugins/cache/module.server.d.ts +1 -1
- package/dist/core/plugins/cache/module.server.js +5 -5
- package/dist/core/prototype/area/api.server.js +1 -2
- package/dist/core/prototype/area/definition.js +1 -10
- package/dist/core/prototype/area/definition.server.js +4 -5
- package/dist/core/prototype/area/hooks.server.js +3 -2
- package/dist/core/prototype/area/operations/find.js +2 -0
- package/dist/core/prototype/blank.d.ts +26 -0
- package/dist/core/prototype/blank.js +22 -0
- package/dist/core/prototype/collection/api.server.d.ts +29 -3
- package/dist/core/prototype/collection/api.server.js +47 -4
- package/dist/core/prototype/collection/definition.js +0 -3
- package/dist/core/prototype/collection/hooks/merge-with-blank.server.d.ts +5 -1
- package/dist/core/prototype/collection/hooks/merge-with-blank.server.js +8 -22
- package/dist/core/prototype/collection/hooks.server.js +11 -5
- package/dist/core/prototype/collection/nested/module.server.js +3 -1
- package/dist/core/prototype/collection/nested/tree.d.ts +12 -0
- package/dist/core/prototype/collection/nested/tree.js +42 -0
- package/dist/core/prototype/collection/operations/find-by-id.js +2 -0
- package/dist/core/prototype/collection/operations/find-by-ids.d.ts +19 -0
- package/dist/core/prototype/collection/operations/find-by-ids.js +54 -0
- package/dist/core/prototype/collection/operations/find.js +21 -27
- package/dist/core/prototype/collection/operations/update-slug-by-id.d.ts +20 -0
- package/dist/core/prototype/collection/operations/update-slug-by-id.js +53 -0
- package/dist/core/prototype/collection/rest/index.server.js +3 -1
- package/dist/core/prototype/collection/rest/update-slug-by-id.server.d.ts +2 -0
- package/dist/core/prototype/collection/rest/update-slug-by-id.server.js +20 -0
- package/dist/core/prototype/collection/thumbnail/find-thumbnail.d.ts +2 -1
- package/dist/core/prototype/collection/thumbnail/find-thumbnail.js +4 -27
- package/dist/core/prototype/collection/upload/directories/derive.js +3 -1
- package/dist/core/prototype/collection/upload/disk/delete.server.js +1 -2
- package/dist/core/prototype/define.js +2 -0
- package/dist/core/prototype/shared/metas/fields.js +2 -1
- package/dist/core/prototype/shared/title/find-title.d.ts +2 -1
- package/dist/core/prototype/shared/title/find-title.js +5 -28
- package/dist/core/prototype/shared/url/addresses.server.d.ts +26 -0
- package/dist/core/prototype/shared/url/addresses.server.js +119 -0
- package/dist/core/prototype/shared/url/doc-type.d.ts +6 -0
- package/dist/core/prototype/shared/url/doc-type.js +9 -0
- package/dist/core/prototype/shared/url/format.server.d.ts +27 -0
- package/dist/core/prototype/shared/url/format.server.js +38 -0
- package/dist/core/prototype/shared/url/hooks/create-paths.server.d.ts +2 -0
- package/dist/core/prototype/shared/url/hooks/create-paths.server.js +9 -0
- package/dist/core/prototype/shared/url/hooks/detach-paths.server.d.ts +5 -0
- package/dist/core/prototype/shared/url/hooks/detach-paths.server.js +18 -0
- package/dist/core/prototype/shared/url/hooks/index.server.d.ts +5 -1
- package/dist/core/prototype/shared/url/hooks/index.server.js +5 -1
- package/dist/core/prototype/shared/url/hooks/set-area-url.server.d.ts +2 -0
- package/dist/core/prototype/shared/url/hooks/set-area-url.server.js +8 -0
- package/dist/core/prototype/shared/url/hooks/set-live-url.server.d.ts +5 -0
- package/dist/core/prototype/shared/url/hooks/set-live-url.server.js +19 -0
- package/dist/core/prototype/shared/url/hooks/sync-paths.server.d.ts +7 -0
- package/dist/core/prototype/shared/url/hooks/sync-paths.server.js +37 -0
- package/dist/core/prototype/shared/url/refresh.server.d.ts +36 -0
- package/dist/core/prototype/shared/url/refresh.server.js +58 -0
- package/dist/core/prototype/shared/versions/configure.server.js +3 -0
- package/dist/core/routes/context.server.d.ts +2 -1
- package/dist/fields/blocks/component/AddBlockButton.svelte +48 -137
- package/dist/fields/blocks/component/Block.svelte +153 -117
- package/dist/fields/blocks/component/Block.svelte.d.ts +11 -5
- package/dist/fields/blocks/component/BlockActions.svelte +76 -26
- package/dist/fields/blocks/component/BlockActions.svelte.d.ts +3 -0
- package/dist/fields/blocks/component/Blocks.svelte +248 -91
- package/dist/fields/blocks/component/focus/BlocksFocus.svelte +680 -0
- package/dist/fields/blocks/component/focus/BlocksFocus.svelte.d.ts +7 -0
- package/dist/fields/blocks/component/focus/Layers.svelte +145 -0
- package/dist/fields/blocks/component/focus/Layers.svelte.d.ts +9 -0
- package/dist/fields/blocks/component/focus/LayersList.svelte +304 -0
- package/dist/fields/blocks/component/focus/LayersList.svelte.d.ts +10 -0
- package/dist/fields/blocks/component/focus/Palette.svelte +135 -0
- package/dist/fields/blocks/component/focus/Palette.svelte.d.ts +9 -0
- package/dist/fields/blocks/component/focus/RenderPlaceholder.svelte +77 -0
- package/dist/fields/blocks/component/focus/RenderPlaceholder.svelte.d.ts +10 -0
- package/dist/fields/blocks/component/focus/Renders.svelte +302 -0
- package/dist/fields/blocks/component/focus/Renders.svelte.d.ts +11 -0
- package/dist/fields/blocks/component/focus/Stage.svelte +190 -0
- package/dist/fields/blocks/component/focus/Stage.svelte.d.ts +8 -0
- package/dist/fields/blocks/component/focus/StagePlaceholder.svelte +69 -0
- package/dist/fields/blocks/component/focus/StagePlaceholder.svelte.d.ts +3 -0
- package/dist/fields/blocks/component/focus/focus.svelte.d.ts +140 -0
- package/dist/fields/blocks/component/focus/focus.svelte.js +424 -0
- package/dist/fields/blocks/component/picker/BlockPicker.svelte +88 -0
- package/dist/fields/blocks/component/picker/BlockPicker.svelte.d.ts +10 -0
- package/dist/fields/blocks/component/picker/BlockTile.svelte +121 -0
- package/dist/fields/blocks/component/picker/BlockTile.svelte.d.ts +12 -0
- package/dist/fields/blocks/index.d.ts +49 -7
- package/dist/fields/blocks/index.js +61 -12
- package/dist/fields/checkbox/component/Checkbox.svelte +11 -37
- package/dist/fields/checkbox/component/Checkbox.svelte.d.ts +1 -0
- package/dist/fields/combobox/component/ComboBox.svelte +37 -7
- package/dist/fields/combobox/component/combobox.css +26 -10
- package/dist/fields/date/component/Date.svelte +43 -12
- package/dist/fields/group/component/Group.svelte +110 -41
- package/dist/fields/group/index.d.ts +5 -1
- package/dist/fields/group/index.js +10 -2
- package/dist/fields/link/component/Link.svelte +184 -143
- package/dist/fields/link/component/RessourceInput.svelte +26 -24
- package/dist/fields/link/index.d.ts +1 -0
- package/dist/fields/link/module.server.js +2 -4
- package/dist/fields/number/component/Number.svelte +38 -20
- package/dist/fields/number/component/number.css +22 -20
- package/dist/fields/number/index.d.ts +1 -0
- package/dist/fields/radio/component/Radio.svelte +12 -0
- package/dist/fields/radio/index.js +1 -1
- package/dist/fields/relation/component/Relation.svelte +169 -40
- package/dist/fields/relation/component/RelationInline.svelte +258 -0
- package/dist/fields/relation/component/RelationInline.svelte.d.ts +26 -0
- package/dist/fields/relation/component/default/Default.svelte +210 -100
- package/dist/fields/relation/component/default/Default.svelte.d.ts +14 -1
- package/dist/fields/relation/component/types.d.ts +4 -0
- package/dist/fields/relation/component/upload/Browse.svelte +619 -88
- package/dist/fields/relation/component/upload/Browse.svelte.d.ts +10 -2
- package/dist/fields/relation/component/upload/Create.svelte +41 -0
- package/dist/fields/relation/component/upload/Create.svelte.d.ts +13 -0
- package/dist/fields/relation/component/upload/Upload.svelte +287 -101
- package/dist/fields/relation/component/upload/Upload.svelte.d.ts +6 -1
- package/dist/fields/relation/component/upload/upload.css +5 -81
- package/dist/fields/relation/module.server.js +7 -1
- package/dist/fields/relation/value.d.ts +25 -0
- package/dist/fields/relation/value.js +27 -0
- package/dist/fields/rich-text/component/RichText.svelte +12 -80
- package/dist/fields/rich-text/component/RichText.svelte.d.ts +1 -1
- package/dist/fields/rich-text/component/RichTextInline.svelte +28 -0
- package/dist/fields/rich-text/component/RichTextInline.svelte.d.ts +11 -0
- package/dist/fields/rich-text/component/bubble-menu/bubble-menu.css +4 -3
- package/dist/fields/rich-text/component/bubble-menu/bubble-menu.svelte +3 -1
- package/dist/fields/rich-text/component/bubble-menu/icon-button/icon-button.css +2 -2
- package/dist/fields/rich-text/component/bubble-menu/node-selector/node-selector.css +7 -10
- package/dist/fields/rich-text/component/drag-handle/drag-handle.css +0 -2
- package/dist/fields/rich-text/component/styles/editor.css +111 -0
- package/dist/fields/rich-text/component/styles/field.css +71 -0
- package/dist/fields/rich-text/component/suggestion/suggestion.svelte +41 -56
- package/dist/fields/rich-text/core/build-editor-config.js +1 -1
- package/dist/fields/rich-text/core/extensions/drag-handle/drag-handle-plugin.js +29 -3
- package/dist/fields/rich-text/core/extensions/drag-handle/drag-handle.d.ts +1 -0
- package/dist/fields/rich-text/core/extensions/drag-handle/drag-handle.js +2 -1
- package/dist/fields/rich-text/core/features/fields/fields.css +2 -3
- package/dist/fields/rich-text/core/features/hr/hr.css +4 -4
- package/dist/fields/rich-text/core/features/link/component/link-selector.css +0 -4
- package/dist/fields/rich-text/core/features/link/component/link-selector.svelte +24 -8
- package/dist/fields/rich-text/core/features/resource/resource.svelte +20 -6
- package/dist/fields/rich-text/core/features/upload/upload.svelte +20 -8
- package/dist/fields/rich-text/core/rich-text-editor-core.svelte +103 -0
- package/dist/fields/rich-text/core/rich-text-editor-core.svelte.d.ts +15 -0
- package/dist/fields/select/component/Select.svelte +67 -28
- package/dist/fields/slug/component/Slug.svelte +26 -53
- package/dist/fields/slug/index.d.ts +1 -0
- package/dist/fields/slug/index.js +1 -1
- package/dist/fields/tabs/component/Tabs.svelte +28 -22
- package/dist/fields/tabs/index.d.ts +4 -1
- package/dist/fields/tabs/index.js +17 -5
- package/dist/fields/text/index.d.ts +1 -0
- package/dist/fields/textarea/component/TextArea.svelte +28 -13
- package/dist/fields/textarea/index.d.ts +1 -0
- package/dist/fields/time/component/Time.svelte +9 -2
- package/dist/fields/toggle/component/Toggle.svelte +8 -25
- package/dist/fields/toggle/component/Toggle.svelte.d.ts +1 -0
- package/dist/fields/toggle/index.d.ts +1 -0
- package/dist/fields/tree/component/AddItemButton.svelte +18 -5
- package/dist/fields/tree/component/Tree.svelte +48 -19
- package/dist/fields/tree/component/TreeBlock.svelte +318 -104
- package/dist/fields/tree/component/TreeBlockActions.svelte +71 -7
- package/dist/fields/tree/component/TreeBlockActions.svelte.d.ts +4 -0
- package/dist/fields/tree/component/props.d.ts +2 -1
- package/dist/fields/tree/index.d.ts +13 -1
- package/dist/fields/tree/index.js +35 -9
- package/dist/fields/types.d.ts +3 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +3 -2
- package/dist/panel/components/Root.svelte +16 -44
- package/dist/panel/components/Root.svelte.d.ts +1 -1
- package/dist/panel/components/fields/Error.svelte +18 -3
- package/dist/panel/components/fields/FieldsPreview.svelte +30 -17
- package/dist/panel/components/fields/FieldsPreviewTrigger.svelte +25 -3
- package/dist/panel/components/fields/Hint.svelte +51 -8
- package/dist/panel/components/fields/Hint.svelte.d.ts +11 -0
- package/dist/panel/components/fields/Label.svelte +2 -0
- package/dist/panel/components/fields/LabelFor.svelte +7 -2
- package/dist/panel/components/fields/RenderFields.svelte +10 -3
- package/dist/panel/components/fields/fieldset.svelte.d.ts +4 -1
- package/dist/panel/components/fields/fieldset.svelte.js +9 -2
- package/dist/panel/components/fields/index.d.ts +1 -0
- package/dist/panel/components/fields/setting.css +82 -0
- package/dist/panel/components/sections/auth/AuthForm.svelte +25 -26
- package/dist/panel/components/sections/collection/Avatar.svelte +61 -0
- package/dist/panel/components/sections/collection/Avatar.svelte.d.ts +9 -0
- package/dist/panel/components/sections/collection/DocStatus.svelte +28 -0
- package/dist/panel/components/sections/collection/DocStatus.svelte.d.ts +7 -0
- package/dist/panel/components/sections/collection/Empty.svelte +3 -3
- package/dist/panel/components/sections/collection/StatusDot.svelte +7 -5
- package/dist/panel/components/sections/collection/When.svelte +33 -0
- package/dist/panel/components/sections/collection/When.svelte.d.ts +8 -0
- package/dist/panel/components/sections/collection/bulk-upload/BulkUploadDialog.svelte +65 -21
- package/dist/panel/components/sections/collection/bulk-upload/BulkUploadDialog.svelte.d.ts +3 -2
- package/dist/panel/components/sections/collection/bulk-upload/DropZone.svelte +45 -162
- package/dist/panel/components/sections/collection/bulk-upload/DropZone.svelte.d.ts +3 -2
- package/dist/panel/components/sections/collection/bulk-upload/FileDrop.svelte +151 -0
- package/dist/panel/components/sections/collection/bulk-upload/FileDrop.svelte.d.ts +17 -0
- package/dist/panel/components/sections/collection/bulk-upload/PageDrop.svelte +177 -0
- package/dist/panel/components/sections/collection/bulk-upload/PageDrop.svelte.d.ts +12 -0
- package/dist/panel/components/sections/collection/bulk-upload/UploadProgress.svelte +75 -0
- package/dist/panel/components/sections/collection/bulk-upload/UploadProgress.svelte.d.ts +8 -0
- package/dist/panel/components/sections/collection/folder/Folder.svelte +18 -3
- package/dist/panel/components/sections/collection/folder/FolderEdit.svelte +26 -18
- package/dist/panel/components/sections/collection/folder/FolderWithActions.svelte +98 -58
- package/dist/panel/components/sections/collection/folder/FolderWithActions.svelte.d.ts +0 -1
- package/dist/panel/components/sections/collection/folder/Folders.svelte +60 -0
- package/dist/panel/components/sections/collection/folder/Folders.svelte.d.ts +7 -0
- package/dist/panel/components/sections/collection/grid/CollectionGrid.svelte +31 -71
- package/dist/panel/components/sections/collection/grid/CollectionGrid.svelte.d.ts +1 -0
- package/dist/panel/components/sections/collection/grid/create-directory-dialog/CreateDirectoryDialog.svelte +5 -3
- package/dist/panel/components/sections/collection/grid/grid-item/GridItem.svelte +250 -37
- package/dist/panel/components/sections/collection/grid/grid-item/GridItem.svelte.d.ts +2 -0
- package/dist/panel/components/sections/collection/header/ButtonCreate.svelte +43 -18
- package/dist/panel/components/sections/collection/header/ButtonCreate.svelte.d.ts +6 -4
- package/dist/panel/components/sections/collection/header/DisplayMode.svelte +69 -58
- package/dist/panel/components/sections/collection/header/DisplayMode.svelte.d.ts +0 -1
- package/dist/panel/components/sections/collection/header/FilterMenu.svelte +60 -0
- package/dist/panel/components/sections/collection/header/FilterMenu.svelte.d.ts +14 -0
- package/dist/panel/components/sections/collection/header/SearchInput.svelte +17 -26
- package/dist/panel/components/sections/collection/header/SelectUI.svelte +19 -34
- package/dist/panel/components/sections/collection/list/CollectionList.svelte +99 -68
- package/dist/panel/components/sections/collection/list/columns.d.ts +21 -0
- package/dist/panel/components/sections/collection/list/columns.js +23 -0
- package/dist/panel/components/sections/collection/list/header/Header.svelte +99 -51
- package/dist/panel/components/sections/collection/list/row/Row.svelte +165 -82
- package/dist/panel/components/sections/collection/list/row/Row.svelte.d.ts +4 -0
- package/dist/panel/components/sections/collection/tree/CollectionTree.svelte +92 -44
- package/dist/panel/components/sections/collection/tree/CollectionTree.svelte.d.ts +1 -0
- package/dist/panel/components/sections/collection/tree/CollectionTreeNode.svelte +139 -43
- package/dist/panel/components/sections/collection/tree/CollectionTreeNode.svelte.d.ts +2 -0
- package/dist/panel/components/sections/collection/upload-thumb-cell/UploadThumbCell.svelte +1 -1
- package/dist/panel/components/sections/commands/CommandButton.svelte +99 -0
- package/dist/panel/components/sections/commands/CommandButton.svelte.d.ts +10 -0
- package/dist/panel/components/sections/commands/CommandPalette.svelte +275 -0
- package/dist/panel/components/sections/commands/CommandPalette.svelte.d.ts +8 -0
- package/dist/panel/components/sections/commands/Commands.svelte +18 -0
- package/dist/panel/components/sections/commands/Commands.svelte.d.ts +9 -0
- package/dist/panel/components/sections/document/AuthAPIKeyDialog.svelte +23 -7
- package/dist/panel/components/sections/document/AuthFooter.svelte +31 -12
- package/dist/panel/components/sections/document/AutoSaveBanner.svelte +24 -7
- package/dist/panel/components/sections/document/ButtonSave.svelte +32 -21
- package/dist/panel/components/sections/document/ButtonSave.svelte.d.ts +5 -5
- package/dist/panel/components/sections/document/ButtonStatus.svelte +68 -20
- package/dist/panel/components/sections/document/ChangeSlugDialog.svelte +199 -0
- package/dist/panel/components/sections/document/ChangeSlugDialog.svelte.d.ts +10 -0
- package/dist/panel/components/sections/document/CurrentlyEdited.svelte +2 -2
- package/dist/panel/components/sections/document/Document.svelte +96 -65
- package/dist/panel/components/sections/document/DocumentChildren.svelte +175 -0
- package/dist/panel/components/sections/document/DocumentChildren.svelte.d.ts +8 -0
- package/dist/panel/components/sections/document/DocumentUrl.svelte +119 -0
- package/dist/panel/components/sections/document/DocumentUrl.svelte.d.ts +9 -0
- package/dist/panel/components/sections/document/Header.svelte +171 -94
- package/dist/panel/components/sections/document/Settings.svelte +255 -110
- package/dist/panel/components/sections/document/Settings.svelte.d.ts +0 -1
- package/dist/panel/components/sections/document/Versions.svelte +5 -3
- package/dist/panel/components/sections/document/upload-header/UploadHeader.svelte +112 -53
- package/dist/panel/components/sections/document/upload-header/UploadHeader.svelte.d.ts +2 -2
- package/dist/panel/components/sections/document/upload-header/drop-zone/DropZone.svelte +74 -41
- package/dist/panel/components/sections/document/upload-header/drop-zone/DropZone.svelte.d.ts +1 -1
- package/dist/panel/components/sections/live/LiveEdit.svelte +2 -2
- package/dist/panel/components/sections/live/LiveFloatingUI.svelte +30 -11
- package/dist/panel/components/sections/live/live-edit-panel.css +2 -2
- package/dist/panel/components/sections/page-layout/Page.svelte +13 -1
- package/dist/panel/components/ui/breadcrumb/BreadCrumb.svelte +55 -27
- package/dist/panel/components/ui/button/button.svelte +81 -54
- package/dist/panel/components/ui/button/index.d.ts +7 -3
- package/dist/panel/components/ui/button/index.js +2 -2
- package/dist/panel/components/ui/calendar/calendar.css +27 -27
- package/dist/panel/components/ui/calendar/calendar.svelte.d.ts +1 -1
- package/dist/panel/components/ui/card/card-description.svelte +1 -1
- package/dist/panel/components/ui/card/card.svelte +21 -4
- package/dist/panel/components/ui/card-document/card-document.svelte +24 -12
- package/dist/panel/components/ui/card-resource/card-resource.svelte +26 -8
- package/dist/panel/components/ui/checkbox/checkbox.css +8 -10
- package/dist/panel/components/ui/command/command-dialog.css +28 -4
- package/dist/panel/components/ui/command/command-dialog.svelte +4 -1
- package/dist/panel/components/ui/command/command-dialog.svelte.d.ts +2 -0
- package/dist/panel/components/ui/command/command-empty.css +1 -1
- package/dist/panel/components/ui/command/command-group.css +3 -3
- package/dist/panel/components/ui/command/command-input-select.svelte +3 -3
- package/dist/panel/components/ui/command/command-input.svelte +38 -14
- package/dist/panel/components/ui/command/command-input.svelte.d.ts +6 -1
- package/dist/panel/components/ui/command/command-item.css +2 -2
- package/dist/panel/components/ui/command/command-list.css +1 -1
- package/dist/panel/components/ui/command/command-separator.css +1 -1
- package/dist/panel/components/ui/context-menu/context-menu-item.css +2 -2
- package/dist/panel/components/ui/context-menu/context-menu.css +6 -7
- package/dist/panel/components/ui/dialog/dialog-content.css +8 -10
- package/dist/panel/components/ui/dialog/dialog-content.svelte +19 -0
- package/dist/panel/components/ui/dialog/dialog-description.css +1 -1
- package/dist/panel/components/ui/dialog/dialog-footer.svelte +5 -1
- package/dist/panel/components/ui/dialog/dialog-overlay.css +1 -1
- package/dist/panel/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +19 -5
- package/dist/panel/components/ui/dropdown-menu/dropdown-menu-content.css +6 -4
- package/dist/panel/components/ui/dropdown-menu/dropdown-menu-item.css +1 -1
- package/dist/panel/components/ui/dropdown-menu/dropdown-menu-radio-item.css +1 -1
- package/dist/panel/components/ui/dropdown-menu/dropdown-menu-separator.css +1 -1
- package/dist/panel/components/ui/input/input.svelte +57 -31
- package/dist/panel/components/ui/kbd/Kbd.svelte +90 -0
- package/dist/panel/components/ui/kbd/Kbd.svelte.d.ts +11 -0
- package/dist/panel/components/ui/kbd/index.d.ts +1 -0
- package/dist/panel/components/ui/kbd/index.js +1 -0
- package/dist/panel/components/ui/label/label.css +5 -3
- package/dist/panel/components/ui/language-switcher/LanguageSwitcher.svelte +27 -15
- package/dist/panel/components/ui/nav/Nav.svelte +180 -110
- package/dist/panel/components/ui/nav/Nav.svelte.d.ts +0 -2
- package/dist/panel/components/ui/nav/NavGroup.svelte +87 -73
- package/dist/panel/components/ui/nav/NavItemButton.svelte +69 -29
- package/dist/panel/components/ui/nav/UserButton.svelte +132 -71
- package/dist/panel/components/ui/page-header/PageHeader.svelte +140 -42
- package/dist/panel/components/ui/page-header/PageHeader.svelte.d.ts +8 -1
- package/dist/panel/components/ui/popover/popover-content.css +4 -3
- package/dist/panel/components/ui/radio-group/radio-group.css +4 -6
- package/dist/panel/components/ui/radio-row-group/radio-row-group.css +19 -7
- package/dist/panel/components/ui/scroll-area/scroll-area.css +2 -2
- package/dist/panel/components/ui/separator/separator.svelte +1 -1
- package/dist/panel/components/ui/sheet/index.d.ts +4 -4
- package/dist/panel/components/ui/sheet/index.js +5 -5
- package/dist/panel/components/ui/sheet/sheet.css +50 -11
- package/dist/panel/components/ui/sonner/sonner.css +11 -8
- package/dist/panel/components/ui/switch/switch.css +13 -18
- package/dist/panel/components/ui/tabs/tabs.css +44 -35
- package/dist/panel/components/ui/tag/tag.svelte +20 -6
- package/dist/panel/components/ui/tooltip/tooltip-content.svelte +14 -4
- package/dist/panel/components/ui/tree/tree-rows.css +146 -0
- package/dist/panel/context/blocks-ops.d.ts +78 -0
- package/dist/panel/context/blocks-ops.js +170 -0
- package/dist/panel/context/collection.svelte.d.ts +28 -0
- package/dist/panel/context/collection.svelte.js +120 -65
- package/dist/panel/context/commands.svelte.d.ts +80 -0
- package/dist/panel/context/commands.svelte.js +108 -0
- package/dist/panel/context/documentForm.svelte.d.ts +34 -2
- package/dist/panel/context/documentForm.svelte.js +105 -102
- package/dist/panel/context/live.svelte.js +2 -73
- package/dist/panel/context/nav.svelte.d.ts +23 -0
- package/dist/panel/context/nav.svelte.js +56 -0
- package/dist/panel/fonts/Geist-VariableFont_wght.ttf +0 -0
- package/dist/panel/fonts/GeistMono-VariableFont_wght.ttf +0 -0
- package/dist/panel/index.d.ts +7 -1
- package/dist/panel/index.js +10 -1
- package/dist/panel/pages/auth/forgot-password/ForgotPassword.svelte +16 -1
- package/dist/panel/pages/collection/CollectionPage.svelte +236 -61
- package/dist/panel/pages/collection/load.server.js +1 -1
- package/dist/panel/pages/dashboard/Dashboard.svelte +135 -90
- package/dist/panel/pages/dashboard/DashboardCard.svelte +109 -0
- package/dist/panel/pages/dashboard/DashboardCard.svelte.d.ts +14 -0
- package/dist/panel/pages/dashboard/DashboardCollection.svelte +180 -57
- package/dist/panel/pages/dashboard/DashboardCollection.svelte.d.ts +1 -0
- package/dist/panel/pages/dashboard/DashboardRow.svelte +93 -0
- package/dist/panel/pages/dashboard/DashboardRow.svelte.d.ts +16 -0
- package/dist/panel/pages/dashboard/load.server.js +49 -25
- package/dist/panel/pages/dashboard/time.d.ts +19 -0
- package/dist/panel/pages/dashboard/time.js +29 -0
- package/dist/panel/pages/dashboard/types.d.ts +9 -2
- package/dist/panel/pages/live/Live.svelte +53 -50
- package/dist/panel/style/font.css +21 -32
- package/dist/panel/style/index.css +191 -122
- package/dist/panel/style/mixins/index.css +14 -0
- package/dist/panel/style/palette.css +35 -26
- package/dist/panel/style/postcss/size-function.d.ts +4 -0
- package/dist/panel/style/postcss/size-function.js +24 -0
- package/dist/panel/style/radius.css +4 -5
- package/dist/panel/style/scheme.css +111 -0
- package/dist/panel/style/size.css +3 -0
- package/dist/panel/util/Sortable.js +9 -4
- package/dist/panel/util/keys.d.ts +24 -0
- package/dist/panel/util/keys.js +63 -0
- package/dist/panel/util/populate.d.ts +8 -0
- package/dist/panel/util/populate.js +49 -0
- package/dist/panel/util/time.d.ts +12 -0
- package/dist/panel/util/time.js +35 -0
- package/dist/panel/util/upload-file.d.ts +106 -0
- package/dist/panel/util/upload-file.js +165 -0
- package/dist/util/index.d.ts +7 -10
- package/dist/util/index.js +7 -8
- package/dist/util/object.d.ts +10 -0
- package/dist/util/object.js +22 -1
- package/dist/util/string.d.ts +17 -0
- package/dist/util/string.js +23 -0
- package/package.json +1 -3
- package/dist/core/pipeline/config-map/build-tree-map.d.ts +0 -4
- package/dist/core/pipeline/config-map/build-tree-map.js +0 -30
- package/dist/core/prototype/doc.d.ts +0 -31
- package/dist/core/prototype/doc.js +0 -118
- package/dist/core/prototype/shared/url/augment.d.ts +0 -13
- package/dist/core/prototype/shared/url/augment.js +0 -11
- package/dist/core/prototype/shared/url/hooks/populate-url.server.d.ts +0 -4
- package/dist/core/prototype/shared/url/hooks/populate-url.server.js +0 -120
- package/dist/fields/rich-text/component/styles/rich-text.css +0 -183
- package/dist/panel/components/sections/collection/header/Header.svelte +0 -17
- package/dist/panel/components/sections/collection/header/Header.svelte.d.ts +0 -3
- package/dist/panel/components/sections/collection/header/Separator.svelte +0 -8
- package/dist/panel/components/sections/collection/header/Separator.svelte.d.ts +0 -26
- package/dist/panel/components/sections/collection/tree/util.d.ts +0 -12
- package/dist/panel/components/sections/collection/tree/util.js +0 -22
- package/dist/panel/fonts/ChivoMono-Italic-VariableFont_wght.ttf +0 -0
- package/dist/panel/fonts/ChivoMono-VariableFont_wght.ttf +0 -0
- package/dist/panel/fonts/Inter-VariableFont_slnt,wght.ttf +0 -0
- package/dist/panel/fonts/Lora-Italic-VariableFont_wght.ttf +0 -0
- package/dist/panel/fonts/Lora-VariableFont_wght.ttf +0 -0
- package/dist/panel/style/shadow.css +0 -10
- package/dist/util/path.d.ts +0 -16
- 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 {
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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,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 {
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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 {
|
|
2
|
-
import {
|
|
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
|
-
|
|
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;
|