rimecms 0.28.10 → 0.30.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/README.md +3 -3
- package/dist/adapter-sqlite/area.server.js +8 -8
- package/dist/adapter-sqlite/generate-schema/column.server.d.ts +13 -0
- package/dist/adapter-sqlite/generate-schema/column.server.js +77 -0
- package/dist/adapter-sqlite/generate-schema/index.server.js +7 -12
- package/dist/adapter-sqlite/generate-schema/root.server.js +35 -39
- package/dist/adapter-sqlite/generate-schema/templates.server.d.ts +12 -0
- package/dist/adapter-sqlite/generate-schema/templates.server.js +19 -0
- package/dist/adapter-sqlite/generate-schema/{util.d.ts → util.server.d.ts} +2 -2
- package/dist/adapter-sqlite/generate-schema/{util.js → util.server.js} +2 -2
- package/dist/adapter-sqlite/generate-schema/write.server.js +1 -1
- package/dist/adapter-sqlite/relations.server.js +6 -1
- package/dist/adapter-sqlite/transform.server.js +1 -1
- package/dist/adapter-sqlite/util.server.d.ts +1 -6
- package/dist/adapter-sqlite/util.server.js +6 -0
- package/dist/adapter-sqlite/where.server.js +17 -16
- package/dist/adapter-sqlite/with.server.js +10 -10
- package/dist/core/areas/{api → rest}/get.server.d.ts +4 -2
- package/dist/core/areas/rest/get.server.js +45 -0
- package/dist/core/areas/rest/index.server.d.ts +6 -0
- package/dist/core/areas/rest/index.server.js +3 -0
- package/dist/core/areas/{api → rest}/update.server.d.ts +4 -2
- package/dist/core/areas/rest/update.server.js +43 -0
- package/dist/core/collections/auth/fields.d.ts +2 -182
- package/dist/core/collections/auth/hooks/before-upsert/augment-fields-password.server.d.ts +1 -1
- package/dist/core/collections/config/augment-auth.server.js +1 -1
- package/dist/core/collections/config/augment-nested.server.js +1 -1
- package/dist/core/collections/config/augment-panel.d.ts +1 -1
- package/dist/core/collections/config/augment-upload.js +2 -2
- package/dist/core/collections/config/augment-upload.server.js +4 -1
- package/dist/core/collections/operations/duplicate.js +31 -12
- package/dist/core/collections/operations/updateById.js +6 -5
- package/dist/core/collections/{api → rest}/create.server.d.ts +4 -2
- package/dist/core/collections/rest/create.server.js +37 -0
- package/dist/core/collections/{api → rest}/delete.server.d.ts +4 -2
- package/dist/core/collections/rest/delete.server.js +37 -0
- package/dist/core/collections/{api → rest}/deleteById.server.d.ts +4 -2
- package/dist/core/collections/rest/deleteById.server.js +21 -0
- package/dist/core/collections/{api → rest}/duplicate.server.d.ts +1 -1
- package/dist/core/collections/rest/duplicate.server.js +20 -0
- package/dist/core/collections/{api → rest}/get.server.d.ts +4 -2
- package/dist/core/collections/rest/get.server.js +50 -0
- package/dist/core/collections/{api → rest}/getById.server.d.ts +4 -2
- package/dist/core/collections/rest/getById.server.js +35 -0
- package/dist/core/collections/rest/index.server.d.ts +16 -0
- package/dist/core/collections/rest/index.server.js +16 -0
- package/dist/core/collections/{api → rest}/updateById.server.d.ts +4 -2
- package/dist/core/collections/rest/updateById.server.js +44 -0
- package/dist/core/collections/upload/disk/delete.server.d.ts +1 -1
- package/dist/core/collections/upload/disk/delete.server.js +48 -1
- package/dist/core/collections/upload/hooks/clean-up-files.server.js +2 -2
- package/dist/core/collections/upload/hooks/convert-base64.server.d.ts +1 -1
- package/dist/core/collections/upload/hooks/extract-path.server.d.ts +2 -2
- package/dist/core/collections/upload/hooks/extract-path.server.js +1 -1
- package/dist/core/collections/upload/hooks/handle-path-creation.server.d.ts +1 -1
- package/dist/core/collections/upload/hooks/process-file-upload.server.d.ts +1 -1
- package/dist/core/collections/upload/hooks/process-file-upload.server.js +3 -3
- package/dist/core/config/auth/better-auth.server.d.ts +2 -2
- package/dist/core/config/client/augment-directories.js +1 -1
- package/dist/core/config/config-context.server.d.ts +3 -3
- package/dist/core/config/server/augment-directories.server.js +1 -1
- package/dist/core/config/server/augment-panel-access.server.d.ts +1 -1
- package/dist/core/config/server/build-config.server.d.ts +11 -11
- package/dist/core/config/server/validate.server.js +51 -31
- package/dist/core/config/shared/find-thumbnail.js +13 -13
- package/dist/core/config/shared/find-title.js +13 -13
- package/dist/core/config/shared/upload-directories.js +1 -1
- package/dist/core/constant.d.ts +1 -1
- package/dist/core/constant.js +1 -1
- package/dist/core/constant.server.d.ts +1 -0
- package/dist/core/constant.server.js +2 -0
- package/dist/core/dev/cache/index.server.js +9 -9
- package/dist/core/dev/cli/build/index.d.ts +1 -0
- package/dist/core/dev/cli/build/index.js +37 -8
- package/dist/core/dev/cli/build/templates.d.ts +1 -0
- package/dist/core/dev/cli/build/templates.js +24 -0
- package/dist/core/dev/cli/clear/index.server.js +3 -2
- package/dist/core/dev/cli/generate/index.server.js +3 -2
- package/dist/core/dev/cli/index.js +20 -0
- package/dist/core/dev/cli/init/index.server.js +4 -4
- package/dist/core/dev/cli/init/templates.d.ts +1 -1
- package/dist/core/dev/cli/init/templates.js +2 -2
- package/dist/core/dev/cli/util/log.server.d.ts +1 -0
- package/dist/core/dev/cli/util/log.server.js +4 -0
- package/dist/core/dev/cli/util/package-manager.server.d.ts +9 -0
- package/dist/core/dev/cli/{init/package-manager-util.server.js → util/package-manager.server.js} +15 -0
- package/dist/core/dev/cli/util/package.server.d.ts +9 -0
- package/dist/core/dev/cli/{init/get-package-info.server.js → util/package.server.js} +10 -0
- package/dist/core/dev/generate/routes/common.server.d.ts +10 -1
- package/dist/core/dev/generate/routes/common.server.js +248 -29
- package/dist/core/dev/generate/routes/index.server.d.ts +7 -1
- package/dist/core/dev/generate/routes/index.server.js +16 -55
- package/dist/core/dev/generate/routes/util.server.d.ts +6 -16
- package/dist/core/dev/generate/routes/util.server.js +8 -21
- package/dist/core/dev/generate/types/index.server.js +22 -20
- package/dist/core/dev/vite/index.server.js +22 -6
- package/dist/core/errors/handler.server.d.ts +22 -1
- package/dist/core/errors/handler.server.js +25 -2
- package/dist/core/errors/index.d.ts +0 -1
- package/dist/core/errors/index.js +0 -1
- package/dist/core/fields/builders/boolean-builder.d.ts +3 -1
- package/dist/core/fields/builders/boolean-builder.js +3 -0
- package/dist/core/fields/builders/field-builder.d.ts +35 -2
- package/dist/core/fields/builders/field-builder.js +33 -2
- package/dist/core/fields/builders/form-field-builder.d.ts +71 -12
- package/dist/core/fields/builders/form-field-builder.js +96 -6
- package/dist/core/fields/builders/select-builder.d.ts +4 -1
- package/dist/core/fields/builders/select-builder.js +3 -0
- package/dist/core/fields/util.d.ts +9 -17
- package/dist/core/fields/util.js +49 -83
- package/dist/core/handlers/routes.server.d.ts +70 -1
- package/dist/core/handlers/routes.server.js +71 -4
- package/dist/core/naming.d.ts +34 -0
- package/dist/core/naming.js +39 -0
- package/dist/core/operations/blocks/diff.server.js +1 -1
- package/dist/core/operations/blocks/extract.server.js +1 -1
- package/dist/core/operations/configMap/buildTreeMap.d.ts +3 -2
- package/dist/core/operations/configMap/buildTreeMap.js +1 -1
- package/dist/core/operations/configMap/index.d.ts +2 -1
- package/dist/core/operations/configMap/index.js +13 -13
- package/dist/core/operations/configMap/types.d.ts +2 -2
- package/dist/core/operations/hooks/before-read/process-document-fields.server.js +14 -17
- package/dist/core/operations/hooks/before-upsert/data-config-map.server.d.ts +1 -1
- package/dist/core/operations/hooks/before-upsert/data-config-map.server.js +1 -1
- package/dist/core/operations/hooks/before-upsert/handle-new-version.server.d.ts +1 -1
- package/dist/core/operations/hooks/before-upsert/original-config-map.server.d.ts +1 -1
- package/dist/core/operations/hooks/before-upsert/original-config-map.server.js +1 -1
- package/dist/core/operations/hooks/before-upsert/set-default-values.server.d.ts +3 -5
- package/dist/core/operations/hooks/before-upsert/set-default-values.server.js +10 -15
- package/dist/core/operations/hooks/before-upsert/validate-fields.server.d.ts +1 -1
- package/dist/core/operations/hooks/before-upsert/validate-fields.server.js +49 -31
- package/dist/core/operations/relations/extract.server.js +5 -5
- package/dist/core/operations/shared/fallback-data-from-original.js +2 -2
- package/dist/core/operations/tree/diff.server.js +1 -1
- package/dist/core/operations/tree/extract.server.js +1 -1
- package/dist/core/plugins/api-init/index.server.js +10 -5
- package/dist/core/plugins/cache/cache.server.js +4 -4
- package/dist/core/rime.server.d.ts +10 -10
- package/dist/core/rime.server.js +5 -1
- package/dist/fields/blocks/component/AddBlockButton.svelte +7 -7
- package/dist/fields/blocks/component/AddBlockButton.svelte.d.ts +2 -2
- package/dist/fields/blocks/component/Blocks.svelte +6 -7
- package/dist/fields/blocks/component/props.d.ts +2 -2
- package/dist/fields/blocks/index.d.ts +1 -1
- package/dist/fields/blocks/index.js +3 -3
- package/dist/fields/blocks/index.server.js +1 -1
- package/dist/fields/checkbox/component/Checkbox.svelte +2 -2
- package/dist/fields/checkbox/component/props.d.ts +2 -2
- package/dist/fields/checkbox/index.server.d.ts +1 -2
- package/dist/fields/checkbox/index.server.js +1 -10
- package/dist/fields/combobox/component/ComboBox.svelte +3 -3
- package/dist/fields/combobox/component/props.d.ts +2 -2
- package/dist/fields/combobox/index.server.d.ts +1 -2
- package/dist/fields/combobox/index.server.js +2 -11
- package/dist/fields/component/index.d.ts +1 -1
- package/dist/fields/date/component/Date.svelte +4 -4
- package/dist/fields/date/component/Date.svelte.d.ts +2 -2
- package/dist/fields/date/index.d.ts +3 -1
- package/dist/fields/date/index.js +3 -0
- package/dist/fields/date/index.server.d.ts +1 -2
- package/dist/fields/date/index.server.js +1 -10
- package/dist/fields/email/component/Email.svelte +5 -6
- package/dist/fields/email/component/props.d.ts +2 -3
- package/dist/fields/email/index.d.ts +3 -2
- package/dist/fields/email/index.js +5 -2
- package/dist/fields/email/index.server.d.ts +0 -3
- package/dist/fields/email/index.server.js +0 -9
- package/dist/fields/group/component/Group.svelte +9 -15
- package/dist/fields/group/component/Group.svelte.d.ts +2 -2
- package/dist/fields/group/index.d.ts +4 -2
- package/dist/fields/group/index.server.js +2 -2
- package/dist/fields/index.server.d.ts +1 -4
- package/dist/fields/index.server.js +17 -13
- package/dist/fields/link/component/Link.svelte +5 -5
- package/dist/fields/link/component/RessourceInput.svelte +1 -1
- package/dist/fields/link/component/props.d.ts +2 -2
- package/dist/fields/link/index.d.ts +5 -2
- package/dist/fields/link/index.js +10 -11
- package/dist/fields/link/runtime.d.ts +2 -0
- package/dist/fields/link/runtime.js +1 -0
- package/dist/fields/link/{index.server.d.ts → runtime.server.d.ts} +1 -2
- package/dist/fields/link/{index.server.js → runtime.server.js} +2 -11
- package/dist/fields/number/component/Number.svelte +6 -6
- package/dist/fields/number/component/props.d.ts +2 -2
- package/dist/fields/number/index.d.ts +4 -10
- package/dist/fields/number/index.js +3 -4
- package/dist/fields/number/index.server.d.ts +1 -2
- package/dist/fields/number/index.server.js +1 -10
- package/dist/fields/radio/component/Radio.svelte +6 -7
- package/dist/fields/radio/component/props.d.ts +2 -2
- package/dist/fields/radio/index.server.d.ts +1 -2
- package/dist/fields/radio/index.server.js +2 -11
- package/dist/fields/relation/client.d.ts +1 -1
- package/dist/fields/relation/client.js +1 -1
- package/dist/fields/relation/component/Cell.svelte +1 -1
- package/dist/fields/relation/component/Relation.svelte +19 -15
- package/dist/fields/relation/component/Relation.svelte.d.ts +2 -2
- package/dist/fields/relation/component/upload/Browse.svelte +1 -1
- package/dist/fields/relation/index.d.ts +8 -5
- package/dist/fields/relation/index.js +8 -47
- package/dist/fields/relation/runtime.d.ts +5 -0
- package/dist/fields/relation/runtime.js +4 -0
- package/dist/fields/relation/runtime.server.d.ts +8 -0
- package/dist/fields/relation/runtime.server.js +49 -0
- package/dist/fields/rich-text/component/RichText.svelte +5 -5
- package/dist/fields/rich-text/component/props.d.ts +2 -2
- package/dist/fields/rich-text/core/features/fields/extension.d.ts +2 -2
- package/dist/fields/rich-text/core/features/fields/fields.svelte +2 -2
- package/dist/fields/rich-text/core/features/link/component/link-selector.svelte +1 -1
- package/dist/fields/rich-text/core/features/resource/resource-extension.d.ts +1 -1
- package/dist/fields/rich-text/core/features/resource/resource.svelte +1 -1
- package/dist/fields/rich-text/core/features/upload/upload-extension.d.ts +1 -1
- package/dist/fields/rich-text/core/features/upload/upload.svelte +1 -1
- package/dist/fields/rich-text/index.d.ts +2 -0
- package/dist/fields/rich-text/index.js +7 -2
- package/dist/fields/rich-text/index.server.d.ts +1 -2
- package/dist/fields/rich-text/index.server.js +1 -10
- package/dist/fields/select/component/Select.svelte +16 -16
- package/dist/fields/select/component/props.d.ts +2 -2
- package/dist/fields/select/index.d.ts +2 -0
- package/dist/fields/select/index.js +3 -0
- package/dist/fields/select/index.server.d.ts +1 -2
- package/dist/fields/select/index.server.js +2 -17
- package/dist/fields/slug/component/Slug.svelte +14 -10
- package/dist/fields/slug/component/Slug.svelte.d.ts +2 -2
- package/dist/fields/slug/index.d.ts +5 -2
- package/dist/fields/slug/index.js +3 -0
- package/dist/fields/slug/index.server.d.ts +1 -2
- package/dist/fields/slug/index.server.js +1 -10
- package/dist/fields/tabs/component/Tabs.svelte +15 -15
- package/dist/fields/tabs/component/Tabs.svelte.d.ts +2 -2
- package/dist/fields/tabs/index.d.ts +4 -16
- package/dist/fields/tabs/index.js +1 -8
- package/dist/fields/tabs/index.server.js +3 -3
- package/dist/fields/text/component/Text.svelte +5 -5
- package/dist/fields/text/component/props.d.ts +2 -3
- package/dist/fields/text/index.d.ts +4 -10
- package/dist/fields/text/index.js +3 -4
- package/dist/fields/text/index.server.d.ts +1 -2
- package/dist/fields/text/index.server.js +1 -10
- package/dist/fields/textarea/component/TextArea.svelte +3 -3
- package/dist/fields/textarea/component/props.d.ts +2 -2
- package/dist/fields/textarea/index.d.ts +4 -1
- package/dist/fields/textarea/index.js +3 -0
- package/dist/fields/textarea/index.server.d.ts +1 -2
- package/dist/fields/textarea/index.server.js +1 -10
- package/dist/fields/time/component/Time.svelte +5 -5
- package/dist/fields/time/component/Time.svelte.d.ts +1 -1
- package/dist/fields/time/component/props.d.ts +2 -2
- package/dist/fields/time/index.d.ts +2 -0
- package/dist/fields/time/index.js +3 -0
- package/dist/fields/time/index.server.d.ts +1 -2
- package/dist/fields/time/index.server.js +1 -10
- package/dist/fields/toggle/component/Toggle.svelte +3 -3
- package/dist/fields/toggle/component/Toggle.svelte.d.ts +1 -1
- package/dist/fields/toggle/component/props.d.ts +2 -2
- package/dist/fields/toggle/index.d.ts +2 -1
- package/dist/fields/toggle/index.server.d.ts +1 -2
- package/dist/fields/toggle/index.server.js +1 -10
- package/dist/fields/tree/component/AddItemButton.svelte +1 -2
- package/dist/fields/tree/component/Tree.svelte +6 -6
- package/dist/fields/tree/component/TreeBlock.svelte +5 -12
- package/dist/fields/tree/component/props.d.ts +3 -3
- package/dist/fields/tree/index.d.ts +3 -1
- package/dist/fields/tree/index.js +2 -2
- package/dist/fields/types.d.ts +11 -5
- package/dist/index.d.ts +8 -3
- package/dist/index.js +7 -3
- package/dist/panel/components/fields/FieldsPreview.svelte +4 -5
- package/dist/panel/components/fields/Hint.svelte +5 -4
- package/dist/panel/components/fields/Hint.svelte.d.ts +3 -2
- package/dist/panel/components/fields/Label.svelte +6 -11
- package/dist/panel/components/fields/Label.svelte.d.ts +3 -2
- package/dist/panel/components/fields/LabelFor.svelte +4 -4
- package/dist/panel/components/fields/LabelFor.svelte.d.ts +2 -1
- package/dist/panel/components/fields/RenderFields.svelte +11 -16
- package/dist/panel/components/fields/{root.svelte.d.ts → fieldset.svelte.d.ts} +1 -1
- package/dist/panel/components/fields/{root.svelte.js → fieldset.svelte.js} +1 -1
- package/dist/panel/components/fields/index.d.ts +5 -5
- package/dist/panel/components/fields/index.js +2 -2
- package/dist/panel/components/sections/collection/folder/FolderWithActions.svelte +1 -1
- package/dist/panel/components/sections/document/AuthFooter.svelte +2 -7
- package/dist/panel/components/sections/document/ButtonStatus.svelte +1 -1
- package/dist/panel/components/sections/document/CurrentlyEdited.svelte +1 -1
- package/dist/panel/components/sections/document/Settings.svelte +1 -1
- package/dist/panel/components/sections/live/LiveEditPanel.svelte +2 -2
- package/dist/panel/context/collection.svelte.js +10 -10
- package/dist/panel/context/documentForm.svelte.d.ts +8 -21
- package/dist/panel/context/documentForm.svelte.js +46 -54
- package/dist/panel/context/form.svelte.d.ts +6 -3
- package/dist/panel/context/form.svelte.js +22 -18
- package/dist/panel/context/live.svelte.js +1 -1
- package/dist/panel/index.d.ts +9 -1
- package/dist/panel/index.js +7 -1
- package/dist/panel/pages/area/actions.server.d.ts +2 -21
- package/dist/panel/pages/area/actions.server.js +28 -27
- package/dist/panel/pages/area/load.server.d.ts +2 -17
- package/dist/panel/pages/area/load.server.js +37 -46
- package/dist/panel/pages/auth/fields.d.ts +4 -4
- package/dist/panel/pages/auth/fields.js +6 -22
- package/dist/panel/pages/auth/reset-password/ResetPassword.svelte +3 -10
- package/dist/panel/pages/auth/sign-in/SignIn.svelte +7 -1
- package/dist/panel/pages/collection/load.server.d.ts +6 -6
- package/dist/panel/pages/collection/load.server.js +70 -72
- package/dist/panel/pages/collection-document/actions.server.d.ts +1 -1
- package/dist/panel/pages/collection-document/actions.server.js +78 -70
- package/dist/panel/pages/collection-document/load.server.d.ts +5 -20
- package/dist/panel/pages/collection-document/load.server.js +80 -82
- package/dist/server.d.ts +7 -0
- package/dist/server.js +7 -0
- package/dist/types.d.ts +1 -0
- package/dist/util/doc.js +15 -17
- package/dist/util/index.d.ts +9 -1
- package/dist/util/index.js +12 -1
- package/package.json +8 -50
- package/dist/core/api/index.d.ts +0 -7
- package/dist/core/api/index.js +0 -10
- package/dist/core/api/index.server.d.ts +0 -3
- package/dist/core/api/index.server.js +0 -3
- package/dist/core/areas/api/get.server.js +0 -36
- package/dist/core/areas/api/index.server.d.ts +0 -7
- package/dist/core/areas/api/index.server.js +0 -4
- package/dist/core/areas/api/update.server.js +0 -33
- package/dist/core/collections/api/create.server.js +0 -29
- package/dist/core/collections/api/delete.server.js +0 -32
- package/dist/core/collections/api/deleteById.server.js +0 -16
- package/dist/core/collections/api/duplicate.server.js +0 -18
- package/dist/core/collections/api/get.server.js +0 -45
- package/dist/core/collections/api/getById.server.js +0 -30
- package/dist/core/collections/api/index.server.d.ts +0 -17
- package/dist/core/collections/api/index.server.js +0 -9
- package/dist/core/collections/api/updateById.server.js +0 -38
- package/dist/core/dev/cli/init/get-package-info.server.d.ts +0 -1
- package/dist/core/dev/cli/init/package-manager-util.server.d.ts +0 -3
- package/dist/core/dev/generate/routes/area.server.d.ts +0 -7
- package/dist/core/dev/generate/routes/area.server.js +0 -69
- package/dist/core/dev/generate/routes/collection.server.d.ts +0 -14
- package/dist/core/dev/generate/routes/collection.server.js +0 -129
- package/dist/fields/relation/index.server.d.ts +0 -4
- package/dist/fields/relation/index.server.js +0 -13
- package/dist/live.d.ts +0 -4
- package/dist/live.js +0 -4
- package/dist/panel/index.server.d.ts +0 -4
- package/dist/panel/index.server.js +0 -4
- package/dist/panel/pages/auth/index.d.ts +0 -4
- package/dist/panel/pages/auth/index.js +0 -4
- package/dist/panel/pages/auth/index.server.d.ts +0 -18
- package/dist/panel/pages/auth/index.server.js +0 -12
- package/dist/panel/pages/index.actions.server.d.ts +0 -13
- package/dist/panel/pages/index.actions.server.js +0 -10
- package/dist/panel/pages/index.load.server.d.ts +0 -23
- package/dist/panel/pages/index.load.server.js +0 -16
- package/dist/panel/ui.d.ts +0 -4
- package/dist/panel/ui.js +0 -5
- /package/dist/core/dev/cli/{util.server.d.ts → util/prompt.server.d.ts} +0 -0
- /package/dist/core/dev/cli/{util.server.js → util/prompt.server.js} +0 -0
package/README.md
CHANGED
|
@@ -93,7 +93,7 @@ export default defineConfig({
|
|
|
93
93
|
```typescript
|
|
94
94
|
// src/hooks.server.ts (should be created)
|
|
95
95
|
import config from '$lib/+rime.generated/rime.config.server.js';
|
|
96
|
-
import { handlers } from 'rimecms';
|
|
96
|
+
import { handlers } from 'rimecms/server';
|
|
97
97
|
import { sequence } from '@sveltejs/kit/hooks';
|
|
98
98
|
|
|
99
99
|
export const handle = sequence(...(await handlers(config)));
|
|
@@ -131,7 +131,7 @@ curl -v POST http://localhost:5173/api/init \
|
|
|
131
131
|
```typescript
|
|
132
132
|
// ./src/lib/+rime/rime.config.ts
|
|
133
133
|
import { rime, Collection, Area } from '$rime/config';
|
|
134
|
-
import { adapterSqlite } from 'rimecms/sqlite';
|
|
134
|
+
import { adapterSqlite } from 'rimecms/adapter-sqlite';
|
|
135
135
|
import { Settings2 } from '@lucide/svelte';
|
|
136
136
|
import { relation, link, richText, text, toggle } from 'rimecms/fields';
|
|
137
137
|
import { access } from "rimecms/util";
|
|
@@ -261,10 +261,10 @@ It's doing bascically `vite build` under the hood and create the polka server fi
|
|
|
261
261
|
- [x] more better-auth integration
|
|
262
262
|
- [x] Handle relation poperties in queries
|
|
263
263
|
- [~] Documentation
|
|
264
|
+
- [ ] Live Edit system in practice
|
|
264
265
|
- [ ] configurable files storage adapter (local, s3, etc)
|
|
265
266
|
- [ ] other storage adapter (postgress, turso, etc)
|
|
266
267
|
- [ ] auto-saved draft
|
|
267
|
-
- [ ] Live Edit system in practice
|
|
268
268
|
- [ ] Put bin commands in a separate package ex: @rime/kit
|
|
269
269
|
|
|
270
270
|
## Acknowledgments
|
|
@@ -23,18 +23,20 @@ const createAreaFacade = (args) => {
|
|
|
23
23
|
if (!areaConfig) {
|
|
24
24
|
throw new RimeError(RimeError.INIT, slug + ' is not an area, should never happen');
|
|
25
25
|
}
|
|
26
|
+
// `db.query[slug]` can't be typed precisely: with a single registered area,
|
|
27
|
+
// AreaSlug collapses to one string literal and Drizzle infers an overly
|
|
28
|
+
// precise (and here incorrect) per-table shape instead of the general one.
|
|
29
|
+
const queryTable = db.query[slug];
|
|
26
30
|
const hasVersions = !!areaConfig.versions;
|
|
27
31
|
if (!hasVersions) {
|
|
28
32
|
const params = {
|
|
29
33
|
columns: adapterUtil.columnsParams({ table: tables[slug], select }),
|
|
30
34
|
with: buildWithParam({ slug, select, locale, tables, config: areaConfig }) || undefined
|
|
31
35
|
};
|
|
32
|
-
|
|
33
|
-
let doc = await db.query[slug].findFirst(params);
|
|
36
|
+
let doc = await queryTable.findFirst(params);
|
|
34
37
|
if (!doc) {
|
|
35
38
|
await createArea(slug, createBlankDocument(areaConfig, getRequestEvent()), locale);
|
|
36
|
-
|
|
37
|
-
doc = await db.query[slug].findFirst(params);
|
|
39
|
+
doc = await queryTable.findFirst(params);
|
|
38
40
|
}
|
|
39
41
|
if (!doc) {
|
|
40
42
|
throw new Error('Database error');
|
|
@@ -43,8 +45,7 @@ const createAreaFacade = (args) => {
|
|
|
43
45
|
}
|
|
44
46
|
else {
|
|
45
47
|
// First check for record presence
|
|
46
|
-
|
|
47
|
-
const area = await db.query[slug].findFirst({ id: true });
|
|
48
|
+
const area = await queryTable.findFirst({ id: true });
|
|
48
49
|
// If no area exists yet, create it
|
|
49
50
|
if (!area) {
|
|
50
51
|
await createArea(slug, createBlankDocument(areaConfig, getRequestEvent()), locale);
|
|
@@ -98,8 +99,7 @@ const createAreaFacade = (args) => {
|
|
|
98
99
|
}
|
|
99
100
|
};
|
|
100
101
|
}
|
|
101
|
-
|
|
102
|
-
const doc = await db.query[slug].findFirst(params);
|
|
102
|
+
const doc = await queryTable.findFirst(params);
|
|
103
103
|
if (!doc) {
|
|
104
104
|
throw new RimeError(RimeError.OPERATION_ERROR);
|
|
105
105
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FormFieldBuilder } from '../../core/fields/builders/form-field-builder.js';
|
|
2
|
+
import type { FormField } from '../../fields/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Renders a single Drizzle column definition for any leaf FormFieldBuilder,
|
|
5
|
+
* driven by the field's own `dataType` (storage type) and `_references`
|
|
6
|
+
* (foreign key) — the adapter owns all Drizzle syntax, fields only declare
|
|
7
|
+
* storage semantics via `dataType`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* // returns "title: text('title').notNull().default(\"\"),"
|
|
11
|
+
* toSchemaColumn(text('title').required())
|
|
12
|
+
*/
|
|
13
|
+
export declare function toSchemaColumn(field: FormFieldBuilder<FormField>, parentPath?: string): string;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { templateReferences, templateUniqueRequired } from './templates.server.js';
|
|
2
|
+
import { getSchemaColumnNames } from './util.server.js';
|
|
3
|
+
const COLUMN_EXPR = {
|
|
4
|
+
text: (snake) => `text('${snake}')`,
|
|
5
|
+
boolean: (snake) => `integer('${snake}', { mode: 'boolean' })`,
|
|
6
|
+
number: (snake) => `real('${snake}')`,
|
|
7
|
+
timestamp: (snake) => `integer('${snake}', { mode: 'timestamp_ms' })`,
|
|
8
|
+
json: (snake) => `text('${snake}', { mode: 'json' })`
|
|
9
|
+
};
|
|
10
|
+
// Single-call type guards for RESOLVE_DEFAULT below — calling
|
|
11
|
+
// f.get.defaultValue itself has no reason to run twice per branch.
|
|
12
|
+
// `ensureObject` intentionally matches `typeof v === 'object'` including
|
|
13
|
+
// `null` (not `v !== null`), since that's what the pre-refactor per-field
|
|
14
|
+
// toSchema checks did — a field with no explicit default (constructor sets
|
|
15
|
+
// `defaultValue = null`) will keep `null`, not fall back to `{}`. Not
|
|
16
|
+
// touching that here, even though it looks like a latent bug.
|
|
17
|
+
const ensureString = (v) => (typeof v === 'string' ? v : undefined);
|
|
18
|
+
const ensureNumber = (v) => (typeof v === 'number' ? v : undefined);
|
|
19
|
+
const ensureBoolean = (v) => (typeof v === 'boolean' ? v : undefined);
|
|
20
|
+
const ensureDate = (v) => (v instanceof Date ? v : undefined);
|
|
21
|
+
const ensureObject = (v) => typeof v === 'object' ? v : undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Resolves the `.default(...)` fallback used when a field is required but has
|
|
24
|
+
* no usable value in `field.defaultValue` — SQLite needs a type-correct
|
|
25
|
+
* DEFAULT to add a NOT NULL column via drizzle-kit migration on a table with
|
|
26
|
+
* existing rows. Keyed by field type (not dataType) and reading
|
|
27
|
+
* `field.get.defaultValue` directly, exactly mirroring what each field's own
|
|
28
|
+
* `toSchema` did before this refactor — kept here, not on the field builders,
|
|
29
|
+
* since it's schema-generation-only and not part of a field's public API.
|
|
30
|
+
*/
|
|
31
|
+
const RESOLVE_DEFAULT = {
|
|
32
|
+
text: (f) => ensureString(f.get.defaultValue) ?? '',
|
|
33
|
+
email: (f) => ensureString(f.get.defaultValue) ?? '',
|
|
34
|
+
slug: (f) => ensureString(f.get.defaultValue) ?? '',
|
|
35
|
+
combobox: (f) => ensureString(f.get.defaultValue) ?? '',
|
|
36
|
+
radio: (f) => ensureString(f.get.defaultValue) ?? '',
|
|
37
|
+
textarea: (f) => ensureString(f.get.defaultValue) ?? '',
|
|
38
|
+
time: (f) => ensureString(f.get.defaultValue) ?? '00:00',
|
|
39
|
+
checkbox: (f) => f.get.defaultValue ?? false,
|
|
40
|
+
toggle: (f) => ensureBoolean(f.get.defaultValue) ?? false,
|
|
41
|
+
number: (f) => ensureNumber(f.get.defaultValue) ?? 0,
|
|
42
|
+
date: (f) => ensureDate(f.get.defaultValue)?.getTime() ?? 0,
|
|
43
|
+
link: (f) => ensureObject(f.get.defaultValue) ?? {},
|
|
44
|
+
richText: (f) => ensureObject(f.get.defaultValue) ?? {},
|
|
45
|
+
relation: () => ({}),
|
|
46
|
+
select: (f) => {
|
|
47
|
+
const many = f.get.many;
|
|
48
|
+
const empty = many ? [] : '';
|
|
49
|
+
const value = f.get.defaultValue;
|
|
50
|
+
return typeof value === 'undefined' ? empty : value;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Renders a single Drizzle column definition for any leaf FormFieldBuilder,
|
|
55
|
+
* driven by the field's own `dataType` (storage type) and `_references`
|
|
56
|
+
* (foreign key) — the adapter owns all Drizzle syntax, fields only declare
|
|
57
|
+
* storage semantics via `dataType`.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* // returns "title: text('title').notNull().default(\"\"),"
|
|
61
|
+
* toSchemaColumn(text('title').required())
|
|
62
|
+
*/
|
|
63
|
+
export function toSchemaColumn(field, parentPath) {
|
|
64
|
+
const { camel, snake } = getSchemaColumnNames({ name: field.name, parentPath });
|
|
65
|
+
// `unique` only exists on the field types that support it (text/email/slug);
|
|
66
|
+
// reading it off the generic FormField base needs a narrow cast, same as
|
|
67
|
+
// each field's own toSchema did today by typing against its concrete field.
|
|
68
|
+
const { unique, required } = field.get;
|
|
69
|
+
// `dataType` is implemented by every leaf field builder but isn't declared
|
|
70
|
+
// on the FormFieldBuilder base (see the comment there) — narrow cast here.
|
|
71
|
+
const dataType = field.dataType;
|
|
72
|
+
const columnExpr = COLUMN_EXPR[dataType](snake);
|
|
73
|
+
const referencesStr = field._references ? templateReferences(field._references) : '';
|
|
74
|
+
const defaultValue = RESOLVE_DEFAULT[field.type]?.(field);
|
|
75
|
+
const suffix = templateUniqueRequired({ unique, required }, defaultValue);
|
|
76
|
+
return `${camel}: ${columnExpr}${referencesStr}${suffix}`;
|
|
77
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { withVersionsSuffix } from '../../core/naming.js';
|
|
2
2
|
import { date } from '../../fields/date/index.js';
|
|
3
|
-
import { getFieldPrivateModule } from '../../fields/index.server.js';
|
|
4
3
|
import { toCamelCase, toCamelCasePreserveTrailingUnderscoreSuffix, toPascalCase, toSnakeCase } from '../../util/string.js';
|
|
4
|
+
import { toSchemaColumn } from './column.server.js';
|
|
5
5
|
import { generateRelationshipDefinitions } from './relations/definition.server.js';
|
|
6
6
|
import { generateJunctionTableDefinition } from './relations/junction.server.js';
|
|
7
7
|
import buildRootTable from './root.server.js';
|
|
@@ -20,9 +20,6 @@ export async function generateSchemaString(config) {
|
|
|
20
20
|
let rootTableName = collectionSlug;
|
|
21
21
|
let versionsRelationsDefinitions = [];
|
|
22
22
|
schema.push(templateHead(collectionSlug));
|
|
23
|
-
// utility function to filter out fields
|
|
24
|
-
const isRootField = (field) => '_root' in field.raw && field.raw._root;
|
|
25
|
-
const isNotRootField = (field) => !('_root' in field.raw) || !field.raw._root;
|
|
26
23
|
if (collection.versions) {
|
|
27
24
|
// Collection that have versions may need some fields forced on the root table and not root_versions
|
|
28
25
|
// process the root table with these fields first then, handle versions related tables creation
|
|
@@ -30,7 +27,7 @@ export async function generateSchemaString(config) {
|
|
|
30
27
|
// base root fields for versioned tables
|
|
31
28
|
const baseRootFields = [date('createdAt').hidden(), date('updatedAt').hidden()];
|
|
32
29
|
// Split fields that should be used on the root table
|
|
33
|
-
const rootFieldsFromConfig = [...collection.fields].filter(
|
|
30
|
+
const rootFieldsFromConfig = [...collection.fields].filter((f) => f.get.root);
|
|
34
31
|
const rootFields = [...rootFieldsFromConfig, ...baseRootFields];
|
|
35
32
|
// Build the main root buildRootTable with only _root fields and created/updatedAt
|
|
36
33
|
const { schema: rootCollectionSchema } = await buildRootTable({
|
|
@@ -72,7 +69,9 @@ export async function generateSchemaString(config) {
|
|
|
72
69
|
}
|
|
73
70
|
const { schema: collectionSchema, relationsDic, relationFieldsMap, relationFieldsHasLocale } = await buildRootTable({
|
|
74
71
|
blocksRegister,
|
|
75
|
-
fields: collection.versions
|
|
72
|
+
fields: collection.versions
|
|
73
|
+
? collection.fields.filter((f) => !f.get.root)
|
|
74
|
+
: collection.fields,
|
|
76
75
|
rootName: rootTableName,
|
|
77
76
|
locales: config.localization?.locales || [],
|
|
78
77
|
hasAuth: !!collection.auth,
|
|
@@ -120,12 +119,8 @@ export async function generateSchemaString(config) {
|
|
|
120
119
|
const manyVersionsToOneName = `rel_${rootTableName}HasOne${toPascalCase(areaSlug)}`;
|
|
121
120
|
const oneToManyVersionsName = `rel_${areaSlug}HasMany${toPascalCase(rootTableName)}`;
|
|
122
121
|
const baseRootFields = [date('createdAt').hidden(), date('updatedAt').hidden()];
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return serverField && serverField.toSchema(field);
|
|
126
|
-
}
|
|
127
|
-
const schemaResults = await Promise.all(baseRootFields.map(fieldToSchema));
|
|
128
|
-
schema.push(templateTable(areaSlug, schemaResults.filter(Boolean).join(',\n')));
|
|
122
|
+
const schemaResults = baseRootFields.map((field) => toSchemaColumn(field));
|
|
123
|
+
schema.push(templateTable(areaSlug, schemaResults.join(',\n')));
|
|
129
124
|
versionsRelationsDefinitions = [
|
|
130
125
|
templateRelationOne({
|
|
131
126
|
name: manyVersionsToOneName,
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import {} from '../../core/fields/builders/field-builder.js';
|
|
2
2
|
import { FormFieldBuilder } from '../../core/fields/builders/form-field-builder.js';
|
|
3
|
-
import { isFormField } from '../../core/fields/util.js';
|
|
4
3
|
import { withLocalesSuffix } from '../../core/naming.js';
|
|
5
|
-
import {
|
|
6
|
-
import { GroupFieldBuilder
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { isTabsField } from '../../fields/tabs/index.js';
|
|
4
|
+
import { BlocksBuilder } from '../../fields/blocks/index.js';
|
|
5
|
+
import { GroupFieldBuilder } from '../../fields/group/index.js';
|
|
6
|
+
import { RelationFieldBuilder } from '../../fields/relation/index.js';
|
|
7
|
+
import { TabsBuilder } from '../../fields/tabs/index.js';
|
|
10
8
|
import { TreeBuilder } from '../../fields/tree/index.js';
|
|
11
9
|
import { toPascalCase } from '../../util/string.js';
|
|
10
|
+
import { toSchemaColumn } from './column.server.js';
|
|
12
11
|
import { templateHasAuth, templateLocale, templateParent, templateTable } from './templates.server.js';
|
|
13
12
|
const p = toPascalCase;
|
|
14
13
|
/**
|
|
@@ -22,38 +21,38 @@ const buildRootTable = async ({ fields: incomingFields, tableName, rootName, has
|
|
|
22
21
|
const generateFieldsTemplates = async (fields, withLocalized, parentPath = '') => {
|
|
23
22
|
let templates = [];
|
|
24
23
|
const checkLocalized = (field) => {
|
|
25
|
-
return ((withLocalized && field.
|
|
26
|
-
(!withLocalized && !field.
|
|
24
|
+
return ((withLocalized && field.get.localized) ||
|
|
25
|
+
(!withLocalized && !field.get.localized) ||
|
|
27
26
|
withLocalized === undefined);
|
|
28
27
|
};
|
|
29
28
|
for (const field of fields) {
|
|
30
29
|
if (field instanceof GroupFieldBuilder) {
|
|
31
30
|
const groupPath = parentPath ? `${parentPath}__${field.name}` : field.name;
|
|
32
|
-
const groupFields = await generateFieldsTemplates(field.
|
|
31
|
+
const groupFields = await generateFieldsTemplates(field.get.fields, withLocalized, groupPath);
|
|
33
32
|
templates = [...templates, ...groupFields];
|
|
34
33
|
}
|
|
35
|
-
else if (
|
|
36
|
-
for (const tab of field.
|
|
37
|
-
const tabPath = parentPath ? `${parentPath}__${tab.
|
|
38
|
-
const tabFields = await generateFieldsTemplates(tab.
|
|
34
|
+
else if (field instanceof TabsBuilder) {
|
|
35
|
+
for (const tab of field.get.tabs) {
|
|
36
|
+
const tabPath = parentPath ? `${parentPath}__${tab.name}` : tab.name;
|
|
37
|
+
const tabFields = await generateFieldsTemplates(tab.get.fields, withLocalized, tabPath);
|
|
39
38
|
templates = [...templates, ...tabFields];
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
|
-
else if (
|
|
43
|
-
if (field.
|
|
41
|
+
else if (field instanceof RelationFieldBuilder) {
|
|
42
|
+
if (field.get.localized) {
|
|
44
43
|
relationFieldsHasLocale = true;
|
|
45
44
|
}
|
|
46
45
|
relationFieldsMap = {
|
|
47
46
|
...relationFieldsMap,
|
|
48
|
-
[field.
|
|
49
|
-
to: field.
|
|
50
|
-
localized: field.
|
|
47
|
+
[field.name]: {
|
|
48
|
+
to: field.get.relationTo,
|
|
49
|
+
localized: field.get.localized
|
|
51
50
|
}
|
|
52
51
|
};
|
|
53
52
|
}
|
|
54
|
-
else if (
|
|
55
|
-
for (const block of field.
|
|
56
|
-
const blockTableName = `${rootName}Blocks${p(block.
|
|
53
|
+
else if (field instanceof BlocksBuilder) {
|
|
54
|
+
for (const block of field.get.blocks) {
|
|
55
|
+
const blockTableName = `${rootName}Blocks${p(block.name)}`;
|
|
57
56
|
if (!blocksRegister.includes(blockTableName)) {
|
|
58
57
|
// Add the blocks as a relation of the root collection
|
|
59
58
|
relationsDic = {
|
|
@@ -63,7 +62,7 @@ const buildRootTable = async ({ fields: incomingFields, tableName, rootName, has
|
|
|
63
62
|
// Build the child blocks table
|
|
64
63
|
const { schema: blockTable, relationsDic: nestedRelationsDic, relationFieldsMap: nestedRelationFieldsDic, relationFieldsHasLocale: nestedRelationFieldsHasLocale } = await buildRootTable({
|
|
65
64
|
blocksRegister,
|
|
66
|
-
fields: block.
|
|
65
|
+
fields: block.get.fields,
|
|
67
66
|
tableName: blockTableName,
|
|
68
67
|
hasParent: true,
|
|
69
68
|
relationsDic,
|
|
@@ -90,7 +89,7 @@ const buildRootTable = async ({ fields: incomingFields, tableName, rootName, has
|
|
|
90
89
|
};
|
|
91
90
|
const { schema: treeTable, relationsDic: nestedRelationsDic, relationFieldsMap: nestedRelationFieldsDic, relationFieldsHasLocale: nestedRelationFieldsHasLocale } = await buildRootTable({
|
|
92
91
|
blocksRegister,
|
|
93
|
-
fields: field.
|
|
92
|
+
fields: field.get.fields,
|
|
94
93
|
tableName: treeTableName,
|
|
95
94
|
hasParent: true,
|
|
96
95
|
relationsDic,
|
|
@@ -108,10 +107,7 @@ const buildRootTable = async ({ fields: incomingFields, tableName, rootName, has
|
|
|
108
107
|
}
|
|
109
108
|
else if (field instanceof FormFieldBuilder) {
|
|
110
109
|
if (checkLocalized(field)) {
|
|
111
|
-
|
|
112
|
-
if (serverField) {
|
|
113
|
-
templates.push(serverField.toSchema(field, parentPath) + ',');
|
|
114
|
-
}
|
|
110
|
+
templates.push(toSchemaColumn(field, parentPath) + ',');
|
|
115
111
|
}
|
|
116
112
|
}
|
|
117
113
|
}
|
|
@@ -159,39 +155,39 @@ function hasLocalizedField(fields) {
|
|
|
159
155
|
// Iterate through each field in the array
|
|
160
156
|
for (const field of fields) {
|
|
161
157
|
// Case 1: If it's a group field, check all fields within the group
|
|
162
|
-
if (
|
|
163
|
-
if (hasLocalizedField(field.
|
|
158
|
+
if (field instanceof GroupFieldBuilder) {
|
|
159
|
+
if (hasLocalizedField(field.get.fields)) {
|
|
164
160
|
return true;
|
|
165
161
|
}
|
|
166
162
|
}
|
|
167
163
|
// Case 2: If it's a tabs field, check all fields within each tab
|
|
168
|
-
else if (
|
|
169
|
-
for (const tab of field.
|
|
170
|
-
if (hasLocalizedField(tab.
|
|
164
|
+
else if (field instanceof TabsBuilder) {
|
|
165
|
+
for (const tab of field.get.tabs) {
|
|
166
|
+
if (hasLocalizedField(tab.get.fields)) {
|
|
171
167
|
return true;
|
|
172
168
|
}
|
|
173
169
|
}
|
|
174
170
|
}
|
|
175
171
|
// Case 3: If it's a blocks field, check all fields within each block
|
|
176
|
-
else if (
|
|
177
|
-
if (field.
|
|
172
|
+
else if (field instanceof BlocksBuilder) {
|
|
173
|
+
if (field.get.localized)
|
|
178
174
|
return true;
|
|
179
|
-
for (const block of field.
|
|
180
|
-
if (hasLocalizedField(block.
|
|
175
|
+
for (const block of field.get.blocks) {
|
|
176
|
+
if (hasLocalizedField(block.get.fields)) {
|
|
181
177
|
return true;
|
|
182
178
|
}
|
|
183
179
|
}
|
|
184
180
|
}
|
|
185
181
|
// Case 3: If it's a tree field, check all fields
|
|
186
182
|
else if (field instanceof TreeBuilder) {
|
|
187
|
-
if (field.
|
|
183
|
+
if (field.get.localized)
|
|
188
184
|
return true;
|
|
189
|
-
if (hasLocalizedField(field.
|
|
185
|
+
if (hasLocalizedField(field.get.fields)) {
|
|
190
186
|
return true;
|
|
191
187
|
}
|
|
192
188
|
}
|
|
193
189
|
// Case 4: For regular form fields, check if it's marked as localized
|
|
194
|
-
else if (
|
|
190
|
+
else if (field instanceof FormFieldBuilder && field.get.localized) {
|
|
195
191
|
return true;
|
|
196
192
|
}
|
|
197
193
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { FieldReference } from '../../core/fields/builders/form-field-builder.js';
|
|
1
2
|
/**
|
|
2
3
|
* Generates the standard imports needed for Drizzle ORM schema definitions
|
|
3
4
|
* Includes SQLite table definitions, relations, and a primary key helper function
|
|
@@ -36,6 +37,17 @@ export declare const templateLocale: () => string;
|
|
|
36
37
|
* ```
|
|
37
38
|
*/
|
|
38
39
|
export declare const templateParent: (parent: string) => string;
|
|
40
|
+
/**
|
|
41
|
+
* Generates a `.references(...)` suffix for a field-level foreign key,
|
|
42
|
+
* used by column.server.ts's toSchemaColumn for fields configured via
|
|
43
|
+
* FormFieldBuilder#$references(...).
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* .references(() => staff.id, { onDelete: 'cascade' })
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare const templateReferences: ({ table, onDelete, onUpdate, selfReferencing }: FieldReference) => string;
|
|
39
51
|
/**
|
|
40
52
|
* Generates authentication-related fields for a table
|
|
41
53
|
* Adds super admin flag for the panel users table
|
|
@@ -55,6 +55,25 @@ export const templateLocale = () => 'locale: text("locale"),';
|
|
|
55
55
|
export const templateParent = (parent) => {
|
|
56
56
|
return `ownerId: text("owner_id").references(() => ${parent}.id, { onDelete: 'cascade' }),`;
|
|
57
57
|
};
|
|
58
|
+
/**
|
|
59
|
+
* Generates a `.references(...)` suffix for a field-level foreign key,
|
|
60
|
+
* used by column.server.ts's toSchemaColumn for fields configured via
|
|
61
|
+
* FormFieldBuilder#$references(...).
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* .references(() => staff.id, { onDelete: 'cascade' })
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export const templateReferences = ({ table, onDelete, onUpdate, selfReferencing }) => {
|
|
69
|
+
const arrow = selfReferencing ? '(): any =>' : '() =>';
|
|
70
|
+
const opts = [
|
|
71
|
+
onDelete ? `onDelete: '${onDelete}'` : '',
|
|
72
|
+
onUpdate ? `onUpdate: '${onUpdate}'` : ''
|
|
73
|
+
].filter(Boolean);
|
|
74
|
+
const optsStr = opts.length ? `, { ${opts.join(', ')} }` : '';
|
|
75
|
+
return `.references(${arrow} ${table}.id${optsStr})`;
|
|
76
|
+
};
|
|
58
77
|
/**
|
|
59
78
|
* Generates authentication-related fields for a table
|
|
60
79
|
* Adds super admin flag for the panel users table
|
|
@@ -33,8 +33,8 @@ export declare const getBlocksTableNames: (slug: string, tables: Record<string,
|
|
|
33
33
|
*/
|
|
34
34
|
export declare const makeBlockTableSlug: (slug: string, blockType: string) => string;
|
|
35
35
|
/**
|
|
36
|
-
* Generate the column
|
|
37
|
-
* Snake case is used for sqlite column name and Camel case is
|
|
36
|
+
* Generate the column and property names for a field given its name and its parent path.
|
|
37
|
+
* Snake case is used for the sqlite column name and Camel case is used for the drizzle column property name.
|
|
38
38
|
*
|
|
39
39
|
* @example
|
|
40
40
|
* // returns { camel : 'groupTitle', snake: 'group__title' }
|
|
@@ -34,8 +34,8 @@ export const getBlocksTableNames = (slug, tables) => Object.keys(tables).filter(
|
|
|
34
34
|
*/
|
|
35
35
|
export const makeBlockTableSlug = (slug, blockType) => `${slug}Blocks${toPascalCase(blockType)}`;
|
|
36
36
|
/**
|
|
37
|
-
* Generate the column
|
|
38
|
-
* Snake case is used for sqlite column name and Camel case is
|
|
37
|
+
* Generate the column and property names for a field given its name and its parent path.
|
|
38
|
+
* Snake case is used for the sqlite column name and Camel case is used for the drizzle column property name.
|
|
39
39
|
*
|
|
40
40
|
* @example
|
|
41
41
|
* // returns { camel : 'groupTitle', snake: 'group__title' }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import cache from '../../core/dev/cache/index.server.js';
|
|
2
|
-
import { getPackageManager } from '../../core/dev/cli/
|
|
2
|
+
import { getPackageManager } from '../../core/dev/cli/util/package-manager.server.js';
|
|
3
3
|
import { logger } from '../../core/logger/index.server.js';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
@@ -10,8 +10,13 @@ const createRelationsFacade = ({ db, tables }) => {
|
|
|
10
10
|
const table = tables[relationTableName];
|
|
11
11
|
if (!table)
|
|
12
12
|
return true;
|
|
13
|
+
// Only some relation tables have a `locale` column at all — it's added
|
|
14
|
+
// only when the collection has at least one .localized() relation field
|
|
15
|
+
// (see getAll's identical guard below). Without this check, eq(undefined,
|
|
16
|
+
// locale) produces SQL with a missing column reference.
|
|
17
|
+
const columns = Object.keys(getTableColumns(table));
|
|
13
18
|
const conditions = [eq(table.ownerId, ownerId)];
|
|
14
|
-
if (locale) {
|
|
19
|
+
if (locale && columns.includes('locale')) {
|
|
15
20
|
conditions.push(eq(table.locale, locale));
|
|
16
21
|
}
|
|
17
22
|
const existingRelations = await db
|
|
@@ -5,7 +5,7 @@ import { flatten, unflatten } from 'flat';
|
|
|
5
5
|
import { logger } from '../core/logger/index.server.js';
|
|
6
6
|
import { extractFieldName } from '../fields/tree/util.js';
|
|
7
7
|
import { isObjectLiteral, omit } from '../util/object.js';
|
|
8
|
-
import { getBlocksTableNames, getTreeTableNames, makeBlockTableSlug, makeTreeTableSlug } from './generate-schema/util.js';
|
|
8
|
+
import { getBlocksTableNames, getTreeTableNames, makeBlockTableSlug, makeTreeTableSlug } from './generate-schema/util.server.js';
|
|
9
9
|
import { transformDatabaseColumnsToPaths } from './util.server.js';
|
|
10
10
|
/**
|
|
11
11
|
* Facade responsible of converting raw database document
|
|
@@ -69,12 +69,7 @@ export declare function prepareSchemaData(data: any, options: {
|
|
|
69
69
|
* 4. Adds version fields while avoiding duplicates
|
|
70
70
|
* 5. Includes the versionId in the result
|
|
71
71
|
*/
|
|
72
|
-
export declare function mergeRawDocumentWithVersion(doc: RawDoc, versionTableName: string, select?: string[]):
|
|
73
|
-
versionId: any;
|
|
74
|
-
id: string;
|
|
75
|
-
} | {
|
|
76
|
-
versionId: any;
|
|
77
|
-
};
|
|
72
|
+
export declare function mergeRawDocumentWithVersion(doc: RawDoc, versionTableName: string, select?: string[]): RawDoc;
|
|
78
73
|
/**
|
|
79
74
|
* Build the query params to get either the latest updated document
|
|
80
75
|
* or the published one if version.draft is enabled and draft is true
|
|
@@ -139,6 +139,8 @@ export function mergeRawDocumentWithVersion(doc, versionTableName, select) {
|
|
|
139
139
|
// Filter out root props as they should come from the doc,
|
|
140
140
|
// plus the ownerId wich is equals to doc.id
|
|
141
141
|
const versionFields = omit([...rootProps, 'ownerId'], versionData);
|
|
142
|
+
// `pick`/`omit` return generic Dic types, so TS can't statically confirm
|
|
143
|
+
// `id` survived — it always does, since we explicitly pick it above.
|
|
142
144
|
return {
|
|
143
145
|
...docFields,
|
|
144
146
|
...versionFields,
|
|
@@ -146,6 +148,10 @@ export function mergeRawDocumentWithVersion(doc, versionTableName, select) {
|
|
|
146
148
|
};
|
|
147
149
|
}
|
|
148
150
|
// Default case - return all fields
|
|
151
|
+
// `versionTableName` is a plain `string`, not a literal, so `Omit<T, string>`
|
|
152
|
+
// widens to `Omit<T, keyof T>` and TS loses track of every spread key
|
|
153
|
+
// (including `id`) — the object is correct at runtime, only its inferred
|
|
154
|
+
// type collapses, hence the double cast through `unknown`.
|
|
149
155
|
return {
|
|
150
156
|
...omit([versionTableName], doc),
|
|
151
157
|
...omit(['id', 'ownerId', 'createdAt', 'updatedAt'], versionData),
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RimeError } from '../core/errors/index.js';
|
|
2
|
-
import {
|
|
2
|
+
import { getFieldAtPath } from '../core/fields/util.js';
|
|
3
3
|
import { logger } from '../core/logger/index.server.js';
|
|
4
4
|
import { hasVersionsSuffix, withLocalesSuffix } from '../core/naming.js';
|
|
5
|
-
import {
|
|
5
|
+
import { RelationFieldBuilder } from '../fields/relation/index.js';
|
|
6
6
|
import {} from '../index.js';
|
|
7
7
|
import * as drizzleORM from 'drizzle-orm';
|
|
8
8
|
import { and, eq, getTableColumns, inArray, or } from 'drizzle-orm';
|
|
@@ -65,9 +65,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
|
|
|
65
65
|
// Look for a relation field
|
|
66
66
|
// Get document config
|
|
67
67
|
const documentConfig = configCtx.getBySlug(slug);
|
|
68
|
-
|
|
69
|
-
const compiledFields = documentConfig.fields.map((f) => f.compile());
|
|
70
|
-
let fieldConfig = getFieldConfigByPath(column, compiledFields);
|
|
68
|
+
let fieldConfig = getFieldAtPath(column, documentConfig.fields);
|
|
71
69
|
// Track relation-property detection (e.g. attributes.author.name)
|
|
72
70
|
let matchedPrefix = column;
|
|
73
71
|
let relationPropertyPath = null;
|
|
@@ -78,7 +76,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
|
|
|
78
76
|
const parts = column.split('.');
|
|
79
77
|
for (let i = parts.length - 1; i > 0; i--) {
|
|
80
78
|
const prefix = parts.slice(0, i).join('.');
|
|
81
|
-
const candidate =
|
|
79
|
+
const candidate = getFieldAtPath(prefix, documentConfig.fields);
|
|
82
80
|
if (candidate) {
|
|
83
81
|
fieldConfig = candidate;
|
|
84
82
|
// If prefix shorter than original column, record the property suffix
|
|
@@ -92,7 +90,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
|
|
|
92
90
|
}
|
|
93
91
|
}
|
|
94
92
|
// If still not found or not a relation field, log warning and return false condition
|
|
95
|
-
if (!fieldConfig
|
|
93
|
+
if (!(fieldConfig instanceof RelationFieldBuilder)) {
|
|
96
94
|
const message = `the query contains the field "${column}", not found for ${documentConfig.slug} document`;
|
|
97
95
|
logger.warn(message);
|
|
98
96
|
// Return a condition that will always be false instead of returning false
|
|
@@ -116,7 +114,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
|
|
|
116
114
|
// Handle relation property queries (e.g., attributes.author.name)
|
|
117
115
|
// by building a subquery on the related collection
|
|
118
116
|
const buildRelationPropertyCondition = () => {
|
|
119
|
-
const relatedSlug = fieldConfig.relationTo;
|
|
117
|
+
const relatedSlug = fieldConfig.get.relationTo;
|
|
120
118
|
const relatedTable = getTable(relatedSlug);
|
|
121
119
|
// Build a where clause for the related collection using the same operator/value
|
|
122
120
|
const relatedWhere = { [relationPropertyPath]: { [operator]: rawValue } };
|
|
@@ -143,7 +141,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
|
|
|
143
141
|
const ownersWithMatching = db
|
|
144
142
|
.select({ id: relsTable.ownerId })
|
|
145
143
|
.from(relsTable)
|
|
146
|
-
.where(and(inArray(relsTable[`${relatedSlug}Id`], matchingRelatedIds), eq(relsTable.path, matchedPrefix), ...(fieldConfig.localized ? [eq(relsTable.locale, locale)] : [])));
|
|
144
|
+
.where(and(inArray(relsTable[`${relatedSlug}Id`], matchingRelatedIds), eq(relsTable.path, matchedPrefix), ...(fieldConfig.get.localized ? [eq(relsTable.locale, locale)] : [])));
|
|
147
145
|
return inArray(table.id, ownersWithMatching);
|
|
148
146
|
};
|
|
149
147
|
// If this is a relation property query, delegate to the relation property handler
|
|
@@ -152,19 +150,22 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
|
|
|
152
150
|
}
|
|
153
151
|
// Handle direct relation field queries (e.g., attributes.author)
|
|
154
152
|
// only support a subset of operators for multi-valued relations
|
|
155
|
-
// Unsupported operator for multi-valued relations :
|
|
156
153
|
const supportedRelationManyOperators = ['equals', 'not_equals', 'in_array', 'not_in_array'];
|
|
157
154
|
// Only enforce the restriction for direct relation field queries.
|
|
158
155
|
// If this is a relation property query (e.g. attributes.author.name) we allow
|
|
159
156
|
// any operator because those will be applied to the related collection.
|
|
160
|
-
if (fieldConfig.many && !supportedRelationManyOperators.includes(operator)) {
|
|
157
|
+
if (fieldConfig.get.many && !supportedRelationManyOperators.includes(operator)) {
|
|
161
158
|
const unsupportedMessage = `the operator "${operator}" is not supported for multi-valued relation field "${column}" in ${documentConfig.slug} document`;
|
|
162
159
|
logger.warn(unsupportedMessage);
|
|
163
160
|
// Return a condition that will always be false
|
|
164
161
|
return eq(table.id, '-1');
|
|
165
162
|
}
|
|
166
163
|
// Build relation condition
|
|
167
|
-
const [to, localized] = [
|
|
164
|
+
const [to, localized, many] = [
|
|
165
|
+
fieldConfig.get.relationTo,
|
|
166
|
+
fieldConfig.get.localized,
|
|
167
|
+
fieldConfig.get.many
|
|
168
|
+
];
|
|
168
169
|
const relsTableName = `${slug}Rels`;
|
|
169
170
|
const relsTable = getTable(relsTableName);
|
|
170
171
|
// Helpers for building common relation-owner subqueries (operate on the relations table)
|
|
@@ -197,7 +198,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
|
|
|
197
198
|
.having(drizzleORM.gt(drizzleORM.count(relsTable.id), 0));
|
|
198
199
|
// Handle multi-valued relations specially when operator is `equals` to provide
|
|
199
200
|
// strict equality semantics (the relation set must equal the provided value(s)).
|
|
200
|
-
if (
|
|
201
|
+
if (many && operator === 'equals') {
|
|
201
202
|
// Accept various input forms and normalize to a unique array
|
|
202
203
|
const values = normalizeValues(rawValue, value);
|
|
203
204
|
// Owners with total relation count equal to values.length
|
|
@@ -208,7 +209,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
|
|
|
208
209
|
}
|
|
209
210
|
// For multi-valued relations, allow `in_array` to act as a subset check:
|
|
210
211
|
// The provided values must contain ALL relation values of the document.
|
|
211
|
-
if (
|
|
212
|
+
if (many && operator === 'in_array') {
|
|
212
213
|
// Accept various input forms and normalize to a unique array
|
|
213
214
|
const values = normalizeValues(rawValue, value);
|
|
214
215
|
// Owners that have at least one relation row not included in the provided set
|
|
@@ -220,14 +221,14 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
|
|
|
220
221
|
}
|
|
221
222
|
// For multi-valued relations, `not_in_array` should match documents where the provided
|
|
222
223
|
// set does NOT contain all of the document's relation values (inverse of `in_array`).
|
|
223
|
-
if (
|
|
224
|
+
if (many && operator === 'not_in_array') {
|
|
224
225
|
// Accept various input forms and normalize to a unique array
|
|
225
226
|
const values = normalizeValues(rawValue, value);
|
|
226
227
|
const ownersWithNonMatching = buildOwnersWithNonMatching(values);
|
|
227
228
|
return inArray(table.id, ownersWithNonMatching);
|
|
228
229
|
}
|
|
229
230
|
// For multi-valued relations, `not_equals` is the inverse of `equals` (exact-set inequality)
|
|
230
|
-
if (
|
|
231
|
+
if (many && operator === 'not_equals') {
|
|
231
232
|
// Accept various input forms and normalize to a unique array
|
|
232
233
|
const values = normalizeValues(rawValue, value);
|
|
233
234
|
const ownersWithTotalCount = buildOwnersWithTotalCount(values.length);
|