@phtngyn/cms 0.2.0-beta.7 → 0.3.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/LICENSE +18 -10
- package/README.md +59 -401
- package/drizzle/20261003215543_initial/migration.sql +251 -0
- package/drizzle/20261003215543_initial/snapshot.json +1941 -0
- package/package.json +75 -71
- package/src/Authoring.d.ts +41 -49
- package/src/Authoring.js +1 -1
- package/src/Blocks-BrxSemnd.js +40 -0
- package/src/Client.d.ts +8186 -0
- package/src/Client.js +41 -0
- package/src/Collections.d.ts +142 -0
- package/src/Collections.js +142 -0
- package/src/Config-CMiwciub.js +130 -0
- package/src/Config.d.ts +172 -0
- package/src/Config.js +2 -0
- package/src/Configuration-Dk2k3OIc.js +73 -0
- package/src/DataTransfer-BmECvPHB.js +488 -0
- package/src/Database-DSsNCGft.d.ts +3 -0
- package/src/Delivery.d.ts +28 -0
- package/src/Delivery.js +7 -0
- package/src/Document-CKXMSEf1.js +293 -0
- package/src/Document-TgwYKJZM.d.ts +220 -0
- package/src/DocumentRenderer-Wz2xaNyf.js +394 -0
- package/src/EditorSchema-wrDv-id6.js +296 -0
- package/src/Fields-BegSgYhj.d.ts +166 -0
- package/src/Fields-ioGaMEh9.js +130 -0
- package/src/Forms-BuKAXQxr.d.ts +203 -0
- package/src/Forms.d.ts +48 -11
- package/src/Forms.js +342 -7
- package/src/I18n-Ckf9h0rC.js +154 -0
- package/src/I18n.d.ts +45 -2
- package/src/I18n.js +2 -1
- package/src/Image-CJWPLnhP.js +110 -0
- package/src/Links-CJYyy7rC.js +28 -0
- package/src/Links-Dx1yOni8.d.ts +28 -0
- package/src/Locales-Ch7a5xuA.js +67 -0
- package/src/Locales-jwbmJaOp.d.ts +43 -0
- package/src/Locales.d.ts +3 -0
- package/src/Locales.js +3 -0
- package/src/Media-BQ0uL4w7.d.ts +15 -0
- package/src/Media-DSyvd14o.js +87 -0
- package/src/Module.d.ts +2 -10
- package/src/Module.js +1039 -162
- package/src/Operations.d.ts +57 -0
- package/src/Operations.js +263 -0
- package/src/People-DvNZauWw.js +69 -0
- package/src/PreviewFocus-C_EelZO5.js +104 -0
- package/src/Query-C0kGJF5_.d.ts +261 -0
- package/src/RevisionPreview-IVwbJ9Wy.js +133 -0
- package/src/Routes-BaZvm2LE.js +126 -0
- package/src/Routes-DM1rRp3r.d.ts +15 -0
- package/src/S3MediaObjects-y-WacEi9.js +193 -0
- package/src/Seo-BcpqxoAs.d.ts +57 -0
- package/src/Seo-CjNUtUkj.js +254 -0
- package/src/StudioApi-CXLwwocX.js +833 -0
- package/src/StudioErrors-T5zLGQ1M.js +117 -0
- package/src/StudioErrors-kq-E44lQ.d.ts +104 -0
- package/src/StudioServer.d.ts +20 -0
- package/src/StudioServer.js +34 -0
- package/src/answers-DcTg0Xv2.js +41 -0
- package/src/cli.js +681 -187
- package/src/contracts-rprW3ZOB.js +130 -0
- package/src/forms-3xuf0Ym7.d.ts +206 -0
- package/src/localeConfiguration-BPbkLi7-.js +32 -0
- package/src/localeContext-DhF3SPvM.js +59 -0
- package/src/locales-6OD4XGIZ.js +12 -0
- package/src/nuxtDelivery-BYX_Cddb.js +466 -0
- package/src/plugin-DTYuDaQu.js +7171 -0
- package/src/previewContext-dt3ZUh-w.js +4 -0
- package/src/previewRegions-CXjk5cbP.js +145 -0
- package/src/previewSource-fb-q3ESM.js +144 -0
- package/src/rendering-D9LVeEKX.js +47 -0
- package/src/rolldown-runtime-8H4AJuhK.js +14 -0
- package/src/runtime/CmsImage.js +38 -0
- package/src/runtime/DocumentPage.vue +10 -0
- package/src/runtime/DocumentPageContent.js +48 -0
- package/src/runtime/DocumentRenderer.d.ts +129 -0
- package/src/runtime/DocumentRenderer.js +2 -0
- package/src/runtime/api.js +48 -6
- package/src/runtime/delivery/useCmsDocument.js +2 -0
- package/src/runtime/delivery/useCmsDocumentQuery.js +2 -0
- package/src/runtime/delivery/useCmsDocumentSeo.js +2 -114
- package/src/runtime/delivery/useCmsLocale.js +10 -0
- package/src/runtime/plugin.js +2 -40
- package/src/runtime/preview.css +85 -0
- package/src/runtime/preview.js +277 -0
- package/src/runtime/previewSource.js +82 -0
- package/src/runtime/revisionPrivacy.js +13 -0
- package/src/runtime/studio.js +10 -0
- package/src/runtime/studioIcons.js +36 -0
- package/src/validation-3pggwcnm.js +396 -0
- package/src/validation-DpUwPC8Y.js +224 -0
- package/studio/THIRD-PARTY-LICENSES.md +2406 -0
- package/studio/chunks/AccountPage-DL3DitDM.js +288 -0
- package/studio/chunks/AccountPage-DL3DitDM.js.br +0 -0
- package/studio/chunks/AccountPage-DL3DitDM.js.gz +0 -0
- package/studio/chunks/ActivityPage-CLqVUqTh.js +584 -0
- package/studio/chunks/ActivityPage-CLqVUqTh.js.br +0 -0
- package/studio/chunks/ActivityPage-CLqVUqTh.js.gz +0 -0
- package/studio/chunks/Alert-D0D24z_a.js +335 -0
- package/studio/chunks/Alert-D0D24z_a.js.br +0 -0
- package/studio/chunks/Alert-D0D24z_a.js.gz +0 -0
- package/studio/chunks/Badge-BBFs88TI.js +346 -0
- package/studio/chunks/Badge-BBFs88TI.js.br +0 -0
- package/studio/chunks/Badge-BBFs88TI.js.gz +0 -0
- package/studio/chunks/Button-BT3ztSPx.js +14319 -0
- package/studio/chunks/Button-BT3ztSPx.js.br +0 -0
- package/studio/chunks/Button-BT3ztSPx.js.gz +0 -0
- package/studio/chunks/Collapsible-CKnEYIlp.js +246 -0
- package/studio/chunks/Collapsible-CKnEYIlp.js.br +0 -0
- package/studio/chunks/Collapsible-CKnEYIlp.js.gz +0 -0
- package/studio/chunks/ContentInventory-D7nsFA6U.js +1745 -0
- package/studio/chunks/ContentInventory-D7nsFA6U.js.br +0 -0
- package/studio/chunks/ContentInventory-D7nsFA6U.js.gz +0 -0
- package/studio/chunks/ContentPage-DCxt6BeD.js +18 -0
- package/studio/chunks/ContentPage-DCxt6BeD.js.br +0 -0
- package/studio/chunks/ContentPage-DCxt6BeD.js.gz +0 -0
- package/studio/chunks/DashboardSearch-DjyMjJwF.js +2413 -0
- package/studio/chunks/DashboardSearch-DjyMjJwF.js.br +0 -0
- package/studio/chunks/DashboardSearch-DjyMjJwF.js.gz +0 -0
- package/studio/chunks/DocumentLocaleMenu-0EkkOr6_.js +26063 -0
- package/studio/chunks/DocumentLocaleMenu-0EkkOr6_.js.br +0 -0
- package/studio/chunks/DocumentLocaleMenu-0EkkOr6_.js.gz +0 -0
- package/studio/chunks/DropdownMenu-CA9fB0uZ.js +4400 -0
- package/studio/chunks/DropdownMenu-CA9fB0uZ.js.br +0 -0
- package/studio/chunks/DropdownMenu-CA9fB0uZ.js.gz +0 -0
- package/studio/chunks/EditorPage-D_PAYEE4.js +7799 -0
- package/studio/chunks/EditorPage-D_PAYEE4.js.br +0 -0
- package/studio/chunks/EditorPage-D_PAYEE4.js.gz +0 -0
- package/studio/chunks/FormField-CgM6l2Yn.js +198 -0
- package/studio/chunks/FormField-CgM6l2Yn.js.br +0 -0
- package/studio/chunks/FormField-CgM6l2Yn.js.gz +0 -0
- package/studio/chunks/HelpPage-C-vrFcT_.js +552 -0
- package/studio/chunks/HelpPage-C-vrFcT_.js.br +0 -0
- package/studio/chunks/HelpPage-C-vrFcT_.js.gz +0 -0
- package/studio/chunks/Kbd-Ot7TIhVZ.js +271 -0
- package/studio/chunks/Kbd-Ot7TIhVZ.js.br +0 -0
- package/studio/chunks/Kbd-Ot7TIhVZ.js.gz +0 -0
- package/studio/chunks/MediaFolderDialog-DYu-eu-q.js +101 -0
- package/studio/chunks/MediaFolderDialog-DYu-eu-q.js.br +0 -0
- package/studio/chunks/MediaFolderDialog-DYu-eu-q.js.gz +0 -0
- package/studio/chunks/MediaPage-D-jaWtdl.js +923 -0
- package/studio/chunks/MediaPage-D-jaWtdl.js.br +0 -0
- package/studio/chunks/MediaPage-D-jaWtdl.js.gz +0 -0
- package/studio/chunks/MediaPicker-BZs2wUFz.js +837 -0
- package/studio/chunks/MediaPicker-BZs2wUFz.js.br +0 -0
- package/studio/chunks/MediaPicker-BZs2wUFz.js.gz +0 -0
- package/studio/chunks/MediaUploadPanel-C7Kyg6aR.js +1173 -0
- package/studio/chunks/MediaUploadPanel-C7Kyg6aR.js.br +0 -0
- package/studio/chunks/MediaUploadPanel-C7Kyg6aR.js.gz +0 -0
- package/studio/chunks/Modal-D6hSvxHd.js +265 -0
- package/studio/chunks/Modal-D6hSvxHd.js.br +0 -0
- package/studio/chunks/Modal-D6hSvxHd.js.gz +0 -0
- package/studio/chunks/NewDocumentDialog-C8B6_r3J.js +277 -0
- package/studio/chunks/NewDocumentDialog-C8B6_r3J.js.br +0 -0
- package/studio/chunks/NewDocumentDialog-C8B6_r3J.js.gz +0 -0
- package/studio/chunks/Pagination-D9BSo5H2.js +573 -0
- package/studio/chunks/Pagination-D9BSo5H2.js.br +0 -0
- package/studio/chunks/Pagination-D9BSo5H2.js.gz +0 -0
- package/studio/chunks/PeoplePage-CWIXitBD.js +783 -0
- package/studio/chunks/PeoplePage-CWIXitBD.js.br +0 -0
- package/studio/chunks/PeoplePage-CWIXitBD.js.gz +0 -0
- package/studio/chunks/Popover-B63bkTMS.js +128 -0
- package/studio/chunks/Popover-B63bkTMS.js.br +0 -0
- package/studio/chunks/Popover-B63bkTMS.js.gz +0 -0
- package/studio/chunks/PublicationActionDialog-Cm_P0C3I.js +255 -0
- package/studio/chunks/PublicationActionDialog-Cm_P0C3I.js.br +0 -0
- package/studio/chunks/PublicationActionDialog-Cm_P0C3I.js.gz +0 -0
- package/studio/chunks/Routes-DLYHmulE.js +102 -0
- package/studio/chunks/Routes-DLYHmulE.js.br +0 -0
- package/studio/chunks/Routes-DLYHmulE.js.gz +0 -0
- package/studio/chunks/RovingFocusItem-QZNg-wWF.js +95 -0
- package/studio/chunks/RovingFocusItem-QZNg-wWF.js.br +0 -0
- package/studio/chunks/RovingFocusItem-QZNg-wWF.js.gz +0 -0
- package/studio/chunks/ScheduledPage-C0hqrkr5.js +332 -0
- package/studio/chunks/ScheduledPage-C0hqrkr5.js.br +0 -0
- package/studio/chunks/ScheduledPage-C0hqrkr5.js.gz +0 -0
- package/studio/chunks/Search-BEgCe9Aj.js +14646 -0
- package/studio/chunks/Search-BEgCe9Aj.js.br +0 -0
- package/studio/chunks/Search-BEgCe9Aj.js.gz +0 -0
- package/studio/chunks/Select-B50WZMW-.js +2145 -0
- package/studio/chunks/Select-B50WZMW-.js.br +0 -0
- package/studio/chunks/Select-B50WZMW-.js.gz +0 -0
- package/studio/chunks/SelectMenu-DSweWGMz.js +2109 -0
- package/studio/chunks/SelectMenu-DSweWGMz.js.br +0 -0
- package/studio/chunks/SelectMenu-DSweWGMz.js.gz +0 -0
- package/studio/chunks/SeoPage-CNNxGe4h.js +846 -0
- package/studio/chunks/SeoPage-CNNxGe4h.js.br +0 -0
- package/studio/chunks/SeoPage-CNNxGe4h.js.gz +0 -0
- package/studio/chunks/Skeleton-COz8dcrw.js +39 -0
- package/studio/chunks/Skeleton-COz8dcrw.js.br +2 -0
- package/studio/chunks/Skeleton-COz8dcrw.js.gz +0 -0
- package/studio/chunks/Slideover-QMMHAAys.js +289 -0
- package/studio/chunks/Slideover-QMMHAAys.js.br +0 -0
- package/studio/chunks/Slideover-QMMHAAys.js.gz +0 -0
- package/studio/chunks/StudioPage-ngEIDr5d.js +80 -0
- package/studio/chunks/StudioPage-ngEIDr5d.js.br +0 -0
- package/studio/chunks/StudioPage-ngEIDr5d.js.gz +0 -0
- package/studio/chunks/StudioPageToolbar-BwHnqyr6.js +2524 -0
- package/studio/chunks/StudioPageToolbar-BwHnqyr6.js.br +0 -0
- package/studio/chunks/StudioPageToolbar-BwHnqyr6.js.gz +0 -0
- package/studio/chunks/Switch-qKl1aDn7.js +484 -0
- package/studio/chunks/Switch-qKl1aDn7.js.br +0 -0
- package/studio/chunks/Switch-qKl1aDn7.js.gz +0 -0
- package/studio/chunks/ToolPage-DxoVAJVk.js +29 -0
- package/studio/chunks/ToolPage-DxoVAJVk.js.br +0 -0
- package/studio/chunks/ToolPage-DxoVAJVk.js.gz +0 -0
- package/studio/chunks/Tooltip-Bu15m_DB.js +693 -0
- package/studio/chunks/Tooltip-Bu15m_DB.js.br +0 -0
- package/studio/chunks/Tooltip-Bu15m_DB.js.gz +0 -0
- package/studio/chunks/TrashPage-lhqLLdoG.js +12 -0
- package/studio/chunks/TrashPage-lhqLLdoG.js.br +0 -0
- package/studio/chunks/TrashPage-lhqLLdoG.js.gz +0 -0
- package/studio/chunks/VersionsPage-Cqy6UAp9.js +2349 -0
- package/studio/chunks/VersionsPage-Cqy6UAp9.js.br +0 -0
- package/studio/chunks/VersionsPage-Cqy6UAp9.js.gz +0 -0
- package/studio/chunks/VisuallyHiddenInput-Cu8hQLRf.js +113 -0
- package/studio/chunks/VisuallyHiddenInput-Cu8hQLRf.js.br +0 -0
- package/studio/chunks/VisuallyHiddenInput-Cu8hQLRf.js.gz +0 -0
- package/studio/chunks/arrays-CUJkmV4I.js +10 -0
- package/studio/chunks/arrays-CUJkmV4I.js.br +0 -0
- package/studio/chunks/arrays-CUJkmV4I.js.gz +0 -0
- package/studio/chunks/base-DkTekJe8.js +213 -0
- package/studio/chunks/base-DkTekJe8.js.br +0 -0
- package/studio/chunks/base-DkTekJe8.js.gz +0 -0
- package/studio/chunks/content-DUGl3N4d.js +6012 -0
- package/studio/chunks/content-DUGl3N4d.js.br +0 -0
- package/studio/chunks/content-DUGl3N4d.js.gz +0 -0
- package/studio/chunks/destinations-DPIQVQa6.js +227 -0
- package/studio/chunks/destinations-DPIQVQa6.js.br +0 -0
- package/studio/chunks/destinations-DPIQVQa6.js.gz +0 -0
- package/studio/chunks/en-073cjKW4.js +152 -0
- package/studio/chunks/en-073cjKW4.js.br +0 -0
- package/studio/chunks/en-073cjKW4.js.gz +0 -0
- package/studio/chunks/en-Bn8mxPuf.js +134 -0
- package/studio/chunks/en-Bn8mxPuf.js.br +0 -0
- package/studio/chunks/en-Bn8mxPuf.js.gz +0 -0
- package/studio/chunks/en-C9OiaUDZ.js +251 -0
- package/studio/chunks/en-C9OiaUDZ.js.br +0 -0
- package/studio/chunks/en-C9OiaUDZ.js.gz +0 -0
- package/studio/chunks/en-CHAR6jzx.js +147 -0
- package/studio/chunks/en-CHAR6jzx.js.br +0 -0
- package/studio/chunks/en-CHAR6jzx.js.gz +0 -0
- package/studio/chunks/en-Cq4N1vEF.js +93 -0
- package/studio/chunks/en-Cq4N1vEF.js.br +2 -0
- package/studio/chunks/en-Cq4N1vEF.js.gz +0 -0
- package/studio/chunks/en-D2hRqlse.js +140 -0
- package/studio/chunks/en-D2hRqlse.js.br +0 -0
- package/studio/chunks/en-D2hRqlse.js.gz +0 -0
- package/studio/chunks/en-DiUC3-j6.js +144 -0
- package/studio/chunks/en-DiUC3-j6.js.br +0 -0
- package/studio/chunks/en-DiUC3-j6.js.gz +0 -0
- package/studio/chunks/english-Cs_Adu-u.js +8 -0
- package/studio/chunks/english-Cs_Adu-u.js.br +0 -0
- package/studio/chunks/english-Cs_Adu-u.js.gz +0 -0
- package/studio/chunks/esm-D6DqSiL1.js +752 -0
- package/studio/chunks/esm-D6DqSiL1.js.br +0 -0
- package/studio/chunks/esm-D6DqSiL1.js.gz +0 -0
- package/studio/chunks/externalRequest-CTzr2nDq.js +23 -0
- package/studio/chunks/externalRequest-CTzr2nDq.js.br +0 -0
- package/studio/chunks/externalRequest-CTzr2nDq.js.gz +0 -0
- package/studio/chunks/iconify-DR9ryCPv.js +1007 -0
- package/studio/chunks/iconify-DR9ryCPv.js.br +0 -0
- package/studio/chunks/iconify-DR9ryCPv.js.gz +0 -0
- package/studio/chunks/icons-D2MsAaXq.js +183 -0
- package/studio/chunks/icons-D2MsAaXq.js.br +0 -0
- package/studio/chunks/icons-D2MsAaXq.js.gz +0 -0
- package/studio/chunks/leaveGuards-D22fTGgr.js +26 -0
- package/studio/chunks/leaveGuards-D22fTGgr.js.br +0 -0
- package/studio/chunks/leaveGuards-D22fTGgr.js.gz +0 -0
- package/studio/chunks/lucideIcons-EyqyPBsX.js +238 -0
- package/studio/chunks/lucideIcons-EyqyPBsX.js.br +0 -0
- package/studio/chunks/lucideIcons-EyqyPBsX.js.gz +0 -0
- package/studio/chunks/mediaRoute--8cY8rUe.js +17 -0
- package/studio/chunks/mediaRoute--8cY8rUe.js.br +0 -0
- package/studio/chunks/mediaRoute--8cY8rUe.js.gz +0 -0
- package/studio/chunks/newDocumentPlanning-C26DHpvh.js +77 -0
- package/studio/chunks/newDocumentPlanning-C26DHpvh.js.br +0 -0
- package/studio/chunks/newDocumentPlanning-C26DHpvh.js.gz +0 -0
- package/studio/chunks/notifications-OKOLc40v.js +110 -0
- package/studio/chunks/notifications-OKOLc40v.js.br +0 -0
- package/studio/chunks/notifications-OKOLc40v.js.gz +0 -0
- package/studio/chunks/operations-CjNHyrEX.js +57 -0
- package/studio/chunks/operations-CjNHyrEX.js.br +0 -0
- package/studio/chunks/operations-CjNHyrEX.js.gz +0 -0
- package/studio/chunks/overlay-DnqFLZTc.js +1733 -0
- package/studio/chunks/overlay-DnqFLZTc.js.br +0 -0
- package/studio/chunks/overlay-DnqFLZTc.js.gz +0 -0
- package/studio/chunks/presentation-DF83w0hE.js +57 -0
- package/studio/chunks/presentation-DF83w0hE.js.br +0 -0
- package/studio/chunks/presentation-DF83w0hE.js.gz +0 -0
- package/studio/chunks/runtime-core.esm-bundler-DKFA9Rep.js +4557 -0
- package/studio/chunks/runtime-core.esm-bundler-DKFA9Rep.js.br +0 -0
- package/studio/chunks/runtime-core.esm-bundler-DKFA9Rep.js.gz +0 -0
- package/studio/chunks/searchPresentation-DFwxQkt3.js +76 -0
- package/studio/chunks/searchPresentation-DFwxQkt3.js.br +0 -0
- package/studio/chunks/searchPresentation-DFwxQkt3.js.gz +0 -0
- package/studio/chunks/status-DQv6ihkU.js +38 -0
- package/studio/chunks/status-DQv6ihkU.js.br +0 -0
- package/studio/chunks/status-DQv6ihkU.js.gz +0 -0
- package/studio/chunks/studioContext-I8HozGU1.js +4953 -0
- package/studio/chunks/studioContext-I8HozGU1.js.br +0 -0
- package/studio/chunks/studioContext-I8HozGU1.js.gz +0 -0
- package/studio/chunks/studioQueries-BR-9NT5F.js +73 -0
- package/studio/chunks/studioQueries-BR-9NT5F.js.br +0 -0
- package/studio/chunks/studioQueries-BR-9NT5F.js.gz +0 -0
- package/studio/chunks/studioSearch-ByaL-QpM.js +1095 -0
- package/studio/chunks/studioSearch-ByaL-QpM.js.br +0 -0
- package/studio/chunks/studioSearch-ByaL-QpM.js.gz +0 -0
- package/studio/chunks/useAcknowledgedDraft-0_c9sWI6.js +62 -0
- package/studio/chunks/useAcknowledgedDraft-0_c9sWI6.js.br +0 -0
- package/studio/chunks/useAcknowledgedDraft-0_c9sWI6.js.gz +0 -0
- package/studio/chunks/useApi-CUWMwLLw-B3Q3g2nf.js +189 -0
- package/studio/chunks/useApi-CUWMwLLw-B3Q3g2nf.js.br +0 -0
- package/studio/chunks/useApi-CUWMwLLw-B3Q3g2nf.js.gz +0 -0
- package/studio/chunks/useDocumentMessage-BAWvc38w.js +16 -0
- package/studio/chunks/useDocumentMessage-BAWvc38w.js.br +3 -0
- package/studio/chunks/useDocumentMessage-BAWvc38w.js.gz +0 -0
- package/studio/chunks/useFilter-DzyiTR7f.js +87 -0
- package/studio/chunks/useFilter-DzyiTR7f.js.br +0 -0
- package/studio/chunks/useFilter-DzyiTR7f.js.gz +0 -0
- package/studio/chunks/useFormControl-CL7sSCUo.js +8 -0
- package/studio/chunks/useFormControl-CL7sSCUo.js.br +0 -0
- package/studio/chunks/useFormControl-CL7sSCUo.js.gz +0 -0
- package/studio/chunks/useGraceArea-Chcy25IQ.js +154 -0
- package/studio/chunks/useGraceArea-Chcy25IQ.js.br +0 -0
- package/studio/chunks/useGraceArea-Chcy25IQ.js.gz +0 -0
- package/studio/chunks/useLeaveConfirmation-_iCSnKEp.js +44 -0
- package/studio/chunks/useLeaveConfirmation-_iCSnKEp.js.br +8 -0
- package/studio/chunks/useLeaveConfirmation-_iCSnKEp.js.gz +0 -0
- package/studio/chunks/useLinkCopy-CMjQteCy.js +35 -0
- package/studio/chunks/useLinkCopy-CMjQteCy.js.br +0 -0
- package/studio/chunks/useLinkCopy-CMjQteCy.js.gz +0 -0
- package/studio/chunks/usePointerMotion-DwRcwBNQ.js +16 -0
- package/studio/chunks/usePointerMotion-DwRcwBNQ.js.br +0 -0
- package/studio/chunks/usePointerMotion-DwRcwBNQ.js.gz +0 -0
- package/studio/chunks/useStudioNavigation-CLwtSYpb.js +298 -0
- package/studio/chunks/useStudioNavigation-CLwtSYpb.js.br +0 -0
- package/studio/chunks/useStudioNavigation-CLwtSYpb.js.gz +0 -0
- package/studio/chunks/useStudioPages-DR9qmYLg.js +79 -0
- package/studio/chunks/useStudioPages-DR9qmYLg.js.br +0 -0
- package/studio/chunks/useStudioPages-DR9qmYLg.js.gz +0 -0
- package/studio/chunks/utils-mdScC0v0.js +59 -0
- package/studio/chunks/utils-mdScC0v0.js.br +0 -0
- package/studio/chunks/utils-mdScC0v0.js.gz +0 -0
- package/studio/chunks/virtualizer-D1S0bZ4t.js +781 -0
- package/studio/chunks/virtualizer-D1S0bZ4t.js.br +0 -0
- package/studio/chunks/virtualizer-D1S0bZ4t.js.gz +0 -0
- package/studio/help/64f767fe29c2-save-and-publish.svg +7 -0
- package/studio/host.css +1 -1
- package/studio/host.css.br +0 -0
- package/studio/host.css.gz +0 -0
- package/studio/host.js +8757 -39178
- package/studio/host.js.br +0 -0
- package/studio/host.js.gz +0 -0
- package/CHANGELOG.md +0 -13
- package/bin/cms.mjs +0 -2
- package/src/ApplicationTypes.d.ts +0 -84
- package/src/ApplicationTypes.js +0 -1
- package/src/Configuration-Da5B2PVH.js +0 -1191
- package/src/Configuration-Da5B2PVH.js.map +0 -1
- package/src/Configuration.d.ts +0 -82
- package/src/Configuration.js +0 -8
- package/src/Configuration.js.map +0 -1
- package/src/Content.d.ts +0 -68
- package/src/Content.js +0 -373
- package/src/Content.js.map +0 -1
- package/src/ContentTransfer-BxwswWn3.js +0 -86
- package/src/ContentTransfer-BxwswWn3.js.map +0 -1
- package/src/ContentTransfer-Z9FHyLez.d.ts +0 -72
- package/src/DocumentEngine-hh_IGPXO.js +0 -978
- package/src/DocumentEngine-hh_IGPXO.js.map +0 -1
- package/src/DocumentModel.d.ts +0 -52
- package/src/DocumentModel.js +0 -66
- package/src/DocumentModel.js.map +0 -1
- package/src/Forms-CX-hwmJF.js +0 -391
- package/src/Forms-CX-hwmJF.js.map +0 -1
- package/src/Forms-CfNPTiCr.js +0 -110
- package/src/Forms-CfNPTiCr.js.map +0 -1
- package/src/Forms-R0HoTR-o.d.ts +0 -92
- package/src/Forms.js.map +0 -1
- package/src/HttpPaths-c9nLZ9H2.js +0 -21
- package/src/HttpPaths-c9nLZ9H2.js.map +0 -1
- package/src/I18n-zbqpWxki.d.ts +0 -29
- package/src/Media-j1bTritO.js +0 -112
- package/src/Media-j1bTritO.js.map +0 -1
- package/src/Module.js.map +0 -1
- package/src/References-CCPDAPve.js +0 -45
- package/src/References-CCPDAPve.js.map +0 -1
- package/src/S3MediaObjects-Dwhl2deX.js +0 -2742
- package/src/S3MediaObjects-Dwhl2deX.js.map +0 -1
- package/src/Seo-402YumpT.d.ts +0 -198
- package/src/cli/content.js +0 -101
- package/src/cli/content.js.map +0 -1
- package/src/cli.js.map +0 -1
- package/src/connection-BP80q4d-.js +0 -92
- package/src/connection-BP80q4d-.js.map +0 -1
- package/src/dev-lifecycle-CjDq63Ft.js +0 -535
- package/src/dev-lifecycle-CjDq63Ft.js.map +0 -1
- package/src/installation-DYNQQBD3.js +0 -9114
- package/src/installation-DYNQQBD3.js.map +0 -1
- package/src/internal/application-types.js +0 -43
- package/src/internal/application-types.js.map +0 -1
- package/src/internal/authoring-catalog.js +0 -158
- package/src/internal/authoring-catalog.js.map +0 -1
- package/src/internal/authoring-compiler.js +0 -146
- package/src/internal/authoring-compiler.js.map +0 -1
- package/src/internal/authoring-metadata.js +0 -191
- package/src/internal/authoring-metadata.js.map +0 -1
- package/src/internal/cms-config.js +0 -45
- package/src/internal/cms-config.js.map +0 -1
- package/src/internal/configuration.js +0 -228
- package/src/internal/configuration.js.map +0 -1
- package/src/internal/dev-lifecycle.js +0 -3
- package/src/internal/diagnostics.js +0 -47
- package/src/internal/diagnostics.js.map +0 -1
- package/src/internal/document-model.js +0 -376
- package/src/internal/document-model.js.map +0 -1
- package/src/internal/field-metadata.js +0 -7
- package/src/internal/field-metadata.js.map +0 -1
- package/src/internal/form-capabilities.js +0 -12
- package/src/internal/form-capabilities.js.map +0 -1
- package/src/internal/i18n.js +0 -73
- package/src/internal/i18n.js.map +0 -1
- package/src/internal/studio-app.js +0 -68
- package/src/internal/studio-app.js.map +0 -1
- package/src/location-CMNGO3lU.js +0 -35
- package/src/location-CMNGO3lU.js.map +0 -1
- package/src/metadata-DN9_K6Yl.js +0 -201
- package/src/metadata-DN9_K6Yl.js.map +0 -1
- package/src/models-5j67LMqW.js +0 -131
- package/src/models-5j67LMqW.js.map +0 -1
- package/src/models-VmGmG19-.js +0 -628
- package/src/models-VmGmG19-.js.map +0 -1
- package/src/runtime/api.js.map +0 -1
- package/src/runtime/blocks.js +0 -30
- package/src/runtime/blocks.js.map +0 -1
- package/src/runtime/collaboration.js +0 -45
- package/src/runtime/collaboration.js.map +0 -1
- package/src/runtime/delivery/DocumentField.js +0 -23
- package/src/runtime/delivery/DocumentField.js.map +0 -1
- package/src/runtime/delivery/DocumentRenderer.js +0 -61
- package/src/runtime/delivery/DocumentRenderer.js.map +0 -1
- package/src/runtime/delivery/DocumentScope.js +0 -41
- package/src/runtime/delivery/DocumentScope.js.map +0 -1
- package/src/runtime/delivery/blocks.js +0 -8
- package/src/runtime/delivery/blocks.js.map +0 -1
- package/src/runtime/delivery/context.js +0 -12
- package/src/runtime/delivery/context.js.map +0 -1
- package/src/runtime/delivery/document-page.js +0 -21
- package/src/runtime/delivery/document-page.js.map +0 -1
- package/src/runtime/delivery/document.js +0 -43
- package/src/runtime/delivery/document.js.map +0 -1
- package/src/runtime/delivery/error.js +0 -11
- package/src/runtime/delivery/error.js.map +0 -1
- package/src/runtime/delivery/plugin.js +0 -99
- package/src/runtime/delivery/plugin.js.map +0 -1
- package/src/runtime/delivery/preview.d.ts +0 -11
- package/src/runtime/delivery/preview.js +0 -6
- package/src/runtime/delivery/preview.js.map +0 -1
- package/src/runtime/delivery/types.d.ts +0 -2
- package/src/runtime/delivery/types.js +0 -1
- package/src/runtime/delivery/useCmsDocumentSeo.d.ts +0 -67
- package/src/runtime/delivery/useCmsDocumentSeo.js.map +0 -1
- package/src/runtime/delivery/useDocument.d.ts +0 -6
- package/src/runtime/delivery/useDocument.js +0 -23
- package/src/runtime/delivery/useDocument.js.map +0 -1
- package/src/runtime/delivery/useDocumentQuery.d.ts +0 -7
- package/src/runtime/delivery/useDocumentQuery.js +0 -29
- package/src/runtime/delivery/useDocumentQuery.js.map +0 -1
- package/src/runtime/forms/document.js +0 -38
- package/src/runtime/forms/document.js.map +0 -1
- package/src/runtime/forms/useCmsForm.js +0 -257
- package/src/runtime/forms/useCmsForm.js.map +0 -1
- package/src/runtime/i18n/translator.js +0 -51
- package/src/runtime/i18n/translator.js.map +0 -1
- package/src/runtime/i18n/useCmsI18n.d.ts +0 -13
- package/src/runtime/i18n/useCmsI18n.js +0 -38
- package/src/runtime/i18n/useCmsI18n.js.map +0 -1
- package/src/runtime/installation.js +0 -3
- package/src/runtime/plugin.js.map +0 -1
- package/src/runtime/preview/CmsStudioPreviewMarker.js +0 -29
- package/src/runtime/preview/CmsStudioPreviewMarker.js.map +0 -1
- package/src/runtime/preview/comark-document.js +0 -37
- package/src/runtime/preview/comark-document.js.map +0 -1
- package/src/runtime/preview/connection.js +0 -3
- package/src/runtime/preview/controller.js +0 -265
- package/src/runtime/preview/controller.js.map +0 -1
- package/src/runtime/preview/crypto.js +0 -16
- package/src/runtime/preview/crypto.js.map +0 -1
- package/src/runtime/preview/overlay.js +0 -122
- package/src/runtime/preview/overlay.js.map +0 -1
- package/src/runtime/preview/plugin.client.js +0 -68
- package/src/runtime/preview/plugin.client.js.map +0 -1
- package/src/runtime/preview/preview.css +0 -91
- package/src/runtime/preview/protocol.d.ts +0 -16
- package/src/runtime/preview/protocol.js +0 -23
- package/src/runtime/preview/protocol.js.map +0 -1
- package/src/runtime/preview/regions.js +0 -142
- package/src/runtime/preview/regions.js.map +0 -1
- package/src/runtime/preview/store.js +0 -4
- package/src/runtime/sitemap-entries.js +0 -17
- package/src/runtime/sitemap-entries.js.map +0 -1
- package/src/runtime/sitemap.js +0 -23
- package/src/runtime/sitemap.js.map +0 -1
- package/src/runtime/studio-app.js +0 -17
- package/src/runtime/studio-app.js.map +0 -1
- package/src/runtime/studio-document.js +0 -46
- package/src/runtime/studio-document.js.map +0 -1
- package/src/runtime/studio-entry.js +0 -19
- package/src/runtime/studio-entry.js.map +0 -1
- package/src/runtime/studio-navigation.js +0 -11
- package/src/runtime/studio-navigation.js.map +0 -1
- package/src/scalars-CA6kyipS.d.ts +0 -7
- package/src/scalars-CVZqT3L0.js +0 -22
- package/src/scalars-CVZqT3L0.js.map +0 -1
- package/src/store-X1e1o_MF.js +0 -209
- package/src/store-X1e1o_MF.js.map +0 -1
- package/src/types-DZ0IV-Ow.d.ts +0 -101
- package/studio/CreateDocumentDialog-BpjBYGfI.js +0 -335
- package/studio/SelectMenu-KiXwx4Y_.js +0 -34032
- package/studio/collaboration-DcK2F6v9.js +0 -4566
- package/studio/editor-P2rB7Csp.js +0 -30128
- package/studio/rolldown-runtime-Dy4uBu1J.js +0 -11
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Context, Effect, Schema } from "effect";
|
|
2
|
+
//#region ../server/src/MediaObjects.d.ts
|
|
3
|
+
declare const MediaStorageError_base: Schema.Class<MediaStorageError, Schema.TaggedStruct<"Media.StorageError", {
|
|
4
|
+
readonly operation: Schema.NonEmptyString;
|
|
5
|
+
readonly cause: Schema.Defect;
|
|
6
|
+
}>, import("effect/Cause").YieldableError>;
|
|
7
|
+
declare class MediaStorageError extends MediaStorageError_base {}
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region ../server/src/internal/operations/error.d.ts
|
|
10
|
+
declare const OperationsError_base: Schema.Class<OperationsError, Schema.TaggedStruct<"Operations.Error", {
|
|
11
|
+
readonly operation: Schema.NonEmptyString;
|
|
12
|
+
readonly cause: Schema.Defect;
|
|
13
|
+
}>, import("effect/Cause").YieldableError>;
|
|
14
|
+
declare class OperationsError extends OperationsError_base {}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/Operations.d.ts
|
|
17
|
+
export interface CmsOperationsOptions {
|
|
18
|
+
readonly databaseFile: string;
|
|
19
|
+
readonly directory: string;
|
|
20
|
+
readonly s3: {
|
|
21
|
+
readonly bucket: string;
|
|
22
|
+
readonly region: string;
|
|
23
|
+
readonly prefix?: string;
|
|
24
|
+
readonly endpoint?: string;
|
|
25
|
+
readonly forcePathStyle?: boolean;
|
|
26
|
+
readonly credentials?: {
|
|
27
|
+
readonly accessKeyId: string;
|
|
28
|
+
readonly secretAccessKey: string;
|
|
29
|
+
readonly sessionToken?: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Back up a stopped installation to a new directory. */
|
|
34
|
+
export declare const backupCms: (options: CmsOperationsOptions) => Effect.Effect<{
|
|
35
|
+
readonly format: 1;
|
|
36
|
+
readonly createdAt: string;
|
|
37
|
+
readonly sqliteSha256: string;
|
|
38
|
+
readonly objects: readonly {
|
|
39
|
+
readonly key: string;
|
|
40
|
+
readonly byteSize: number;
|
|
41
|
+
readonly mimeType: string;
|
|
42
|
+
readonly sha256: string;
|
|
43
|
+
}[];
|
|
44
|
+
}, MediaStorageError | OperationsError, never>;
|
|
45
|
+
/** Restore into a fresh database path and media prefix while Nuxt is stopped. */
|
|
46
|
+
export declare const restoreCms: (options: CmsOperationsOptions) => Effect.Effect<{
|
|
47
|
+
readonly format: 1;
|
|
48
|
+
readonly createdAt: string;
|
|
49
|
+
readonly sqliteSha256: string;
|
|
50
|
+
readonly objects: readonly {
|
|
51
|
+
readonly key: string;
|
|
52
|
+
readonly byteSize: number;
|
|
53
|
+
readonly mimeType: string;
|
|
54
|
+
readonly sha256: string;
|
|
55
|
+
}[];
|
|
56
|
+
}, MediaStorageError | OperationsError, never>;
|
|
57
|
+
//#endregion
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { n as MediaObjects, t as layer } from "./S3MediaObjects-y-WacEi9.js";
|
|
2
|
+
import { Clock, Context, Crypto, Effect, FileSystem, Layer, Path, Schema, Stream } from "effect";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import * as NodeCrypto from "@effect/platform-node/NodeCrypto";
|
|
5
|
+
import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem";
|
|
6
|
+
import * as NodePath from "@effect/platform-node/NodePath";
|
|
7
|
+
import { SqliteClient } from "@effect/sql-sqlite-node";
|
|
8
|
+
import * as Hex from "effect/encoding/Hex";
|
|
9
|
+
//#region ../server/src/internal/operations/error.ts
|
|
10
|
+
var OperationsError = class extends Schema.TaggedError()("Operations.Error", {
|
|
11
|
+
operation: Schema.NonEmptyString,
|
|
12
|
+
cause: Schema.Defect()
|
|
13
|
+
}) {};
|
|
14
|
+
const operationsError = (operation, cause) => new OperationsError({
|
|
15
|
+
operation,
|
|
16
|
+
cause
|
|
17
|
+
});
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region ../server/src/internal/operations/files.ts
|
|
20
|
+
const hashChunks = Effect.fn("Operations.hashChunks")(function* (stream) {
|
|
21
|
+
const hash = createHash("sha256");
|
|
22
|
+
let byteSize = 0;
|
|
23
|
+
yield* stream.pipe(Stream.runForEach((chunk) => Effect.sync(() => {
|
|
24
|
+
hash.update(chunk);
|
|
25
|
+
byteSize += chunk.length;
|
|
26
|
+
})));
|
|
27
|
+
return {
|
|
28
|
+
byteSize,
|
|
29
|
+
sha256: hash.digest("hex")
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
const hashFile = Effect.fn("Operations.hashFile")((fs, path, operation) => hashChunks(fs.stream(path).pipe(Stream.mapError((cause) => operationsError(operation, cause)))));
|
|
33
|
+
/** The stream consumer cancels its reader; cancel here when consumption never started. */
|
|
34
|
+
const releaseStream = Effect.fn("Operations.releaseStream")((stream) => stream && !stream.locked ? Effect.promise(() => stream.cancel().catch(() => {})) : Effect.void);
|
|
35
|
+
const saveStream = Effect.fn("Operations.saveStream")((fs, path, stream) => Effect.scoped(Effect.gen(function* () {
|
|
36
|
+
const file = yield* fs.open(path, { flag: "wx" }).pipe(Effect.mapError((cause) => operationsError("media.copy", cause)));
|
|
37
|
+
const copied = yield* hashChunks(Stream.fromReadableStream({
|
|
38
|
+
evaluate: () => stream,
|
|
39
|
+
onError: (cause) => operationsError("media.copy", cause)
|
|
40
|
+
}).pipe(Stream.tap((chunk) => file.writeAll(chunk).pipe(Effect.mapError((cause) => operationsError("media.copy", cause))))));
|
|
41
|
+
yield* file.sync.pipe(Effect.mapError((cause) => operationsError("media.copy", cause)));
|
|
42
|
+
return copied;
|
|
43
|
+
})).pipe(Effect.catchDefect((cause) => Effect.fail(operationsError("media.copy", cause)))));
|
|
44
|
+
const hashStream = Effect.fn("Operations.hashStream")((stream) => hashChunks(Stream.fromReadableStream({
|
|
45
|
+
evaluate: () => stream,
|
|
46
|
+
onError: (cause) => operationsError("media.hash", cause)
|
|
47
|
+
})));
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region ../server/src/internal/operations/manifest.ts
|
|
50
|
+
const Digest = Schema.String.check(Schema.isPattern(/^[0-9a-f]{64}$/u));
|
|
51
|
+
const BackupManifest = Schema.Struct({
|
|
52
|
+
format: Schema.Literal(1),
|
|
53
|
+
createdAt: Schema.NonEmptyString,
|
|
54
|
+
sqliteSha256: Digest,
|
|
55
|
+
objects: Schema.Array(Schema.Struct({
|
|
56
|
+
key: Schema.NonEmptyString,
|
|
57
|
+
byteSize: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
58
|
+
mimeType: Schema.NonEmptyString,
|
|
59
|
+
sha256: Digest
|
|
60
|
+
}))
|
|
61
|
+
});
|
|
62
|
+
const objectPath = Effect.fn("Operations.objectPath")(function* (path, directory, key) {
|
|
63
|
+
const digest = yield* (yield* Crypto.Crypto).digest("SHA-256", new TextEncoder().encode(key)).pipe(Effect.mapError((cause) => operationsError("media.path", cause)));
|
|
64
|
+
return path.join(directory, "objects", `${Hex.encode(digest)}.bin`);
|
|
65
|
+
});
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region ../server/src/internal/operations/snapshot.ts
|
|
68
|
+
const ReadyMedia = Schema.Array(Schema.Struct({
|
|
69
|
+
key: Schema.NonEmptyString,
|
|
70
|
+
byteSize: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
71
|
+
mimeType: Schema.NonEmptyString
|
|
72
|
+
}));
|
|
73
|
+
/** Read one immutable backup snapshot for both backup and restore validation. */
|
|
74
|
+
const readSnapshot = Effect.fn("Operations.readSnapshot")(function* (filename, operation) {
|
|
75
|
+
const raw = yield* Effect.gen(function* () {
|
|
76
|
+
const db = yield* SqliteClient.SqliteClient;
|
|
77
|
+
return {
|
|
78
|
+
integrity: (yield* db`PRAGMA integrity_check`)[0],
|
|
79
|
+
ready: yield* db`
|
|
80
|
+
SELECT active_key AS key, byte_size AS byteSize, mime_type AS mimeType
|
|
81
|
+
FROM cms_media_assets WHERE status = 'ready'
|
|
82
|
+
`
|
|
83
|
+
};
|
|
84
|
+
}).pipe(Effect.provide(SqliteClient.layer({
|
|
85
|
+
filename,
|
|
86
|
+
readonly: true,
|
|
87
|
+
disableWAL: true
|
|
88
|
+
})), Effect.mapError((cause) => operationsError(operation, cause)), Effect.catchDefect((cause) => Effect.fail(operationsError(operation, cause))));
|
|
89
|
+
if ((yield* Schema.decodeUnknownEffect(Schema.Struct({ integrity_check: Schema.String }))(raw.integrity).pipe(Effect.mapError((cause) => operationsError(operation, cause)))).integrity_check !== "ok") return yield* operationsError(operation, /* @__PURE__ */ new Error(operation === "sqlite.inspect" ? "The SQLite snapshot failed its integrity check." : "The backup database failed its integrity check."));
|
|
90
|
+
return yield* Schema.decodeUnknownEffect(ReadyMedia)(raw.ready).pipe(Effect.mapError((cause) => operationsError(operation, cause)));
|
|
91
|
+
});
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region ../server/src/internal/operations/backup.ts
|
|
94
|
+
function snapshot(databaseFile, output) {
|
|
95
|
+
return Effect.gen(function* () {
|
|
96
|
+
yield* (yield* SqliteClient.SqliteClient).backup(output);
|
|
97
|
+
}).pipe(Effect.provide(SqliteClient.layer({
|
|
98
|
+
filename: databaseFile,
|
|
99
|
+
readonly: true,
|
|
100
|
+
disableWAL: true
|
|
101
|
+
})), Effect.uninterruptible, Effect.mapError((cause) => operationsError("sqlite.backup", cause)), Effect.catchDefect((cause) => Effect.fail(operationsError("sqlite.backup", cause))));
|
|
102
|
+
}
|
|
103
|
+
const backupInstallation = Effect.fn("Operations.backupInstallation")(function* (options) {
|
|
104
|
+
const fs = yield* FileSystem.FileSystem;
|
|
105
|
+
const path = yield* Path.Path;
|
|
106
|
+
const directory = options.directory;
|
|
107
|
+
yield* fs.makeDirectory(directory).pipe(Effect.mapError((cause) => operationsError("directory.create", cause)));
|
|
108
|
+
return yield* Effect.gen(function* () {
|
|
109
|
+
const sqlite = path.join(directory, "cms.sqlite");
|
|
110
|
+
yield* snapshot(options.databaseFile, sqlite);
|
|
111
|
+
const readyMedia = yield* readSnapshot(sqlite, "sqlite.inspect");
|
|
112
|
+
const database = yield* hashFile(fs, sqlite, "sqlite.hash");
|
|
113
|
+
const objects = [];
|
|
114
|
+
yield* fs.makeDirectory(path.join(directory, "objects")).pipe(Effect.mapError((cause) => operationsError("objects.create", cause)));
|
|
115
|
+
const seen = /* @__PURE__ */ new Set();
|
|
116
|
+
let cursor;
|
|
117
|
+
do {
|
|
118
|
+
const page = yield* options.media.list("", cursor).pipe(Effect.mapError((cause) => operationsError("media.list", cause)));
|
|
119
|
+
for (const listed of page.objects) {
|
|
120
|
+
if (seen.has(listed.key)) return yield* operationsError("media.list", /* @__PURE__ */ new Error(`Duplicate media object: ${listed.key}`));
|
|
121
|
+
seen.add(listed.key);
|
|
122
|
+
const metadata = yield* options.media.stat(listed.key).pipe(Effect.mapError((cause) => operationsError("media.stat", cause)));
|
|
123
|
+
if (!metadata) return yield* operationsError("media.missing", /* @__PURE__ */ new Error(`Media object disappeared: ${listed.key}`));
|
|
124
|
+
const copied = yield* Effect.scoped(Effect.gen(function* () {
|
|
125
|
+
const stream = yield* Effect.acquireRelease(options.media.read(listed.key).pipe(Effect.mapError((cause) => operationsError("media.read", cause))), releaseStream, { interruptible: true });
|
|
126
|
+
if (!stream) return yield* operationsError("media.missing", /* @__PURE__ */ new Error(`Media object disappeared: ${listed.key}`));
|
|
127
|
+
return yield* saveStream(fs, yield* objectPath(path, directory, listed.key), stream);
|
|
128
|
+
}));
|
|
129
|
+
if (copied.byteSize !== listed.byteSize || copied.byteSize !== metadata.byteSize) return yield* operationsError("media.size", /* @__PURE__ */ new Error(`Media object changed during backup: ${listed.key}`));
|
|
130
|
+
objects.push({
|
|
131
|
+
key: listed.key,
|
|
132
|
+
byteSize: copied.byteSize,
|
|
133
|
+
mimeType: metadata.mimeType,
|
|
134
|
+
sha256: copied.sha256
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if (page.nextCursor === cursor && cursor !== void 0) return yield* operationsError("media.list", /* @__PURE__ */ new Error("Media inventory cursor did not advance."));
|
|
138
|
+
cursor = page.nextCursor;
|
|
139
|
+
} while (cursor);
|
|
140
|
+
const copiedByKey = new Map(objects.map((object) => [object.key, object]));
|
|
141
|
+
for (const ready of readyMedia) {
|
|
142
|
+
const copied = copiedByKey.get(ready.key);
|
|
143
|
+
if (!copied) return yield* operationsError("media.missing", /* @__PURE__ */ new Error(`Ready media object is missing: ${ready.key}`));
|
|
144
|
+
if (copied.byteSize !== ready.byteSize || copied.mimeType !== ready.mimeType) return yield* operationsError("media.metadata", /* @__PURE__ */ new Error(`Ready media metadata differs from S3: ${ready.key}`));
|
|
145
|
+
}
|
|
146
|
+
objects.sort((left, right) => left.key.localeCompare(right.key));
|
|
147
|
+
const manifest = yield* Schema.decodeEffect(BackupManifest)({
|
|
148
|
+
format: 1,
|
|
149
|
+
createdAt: new Date(yield* Clock.currentTimeMillis).toISOString(),
|
|
150
|
+
sqliteSha256: database.sha256,
|
|
151
|
+
objects
|
|
152
|
+
}).pipe(Effect.mapError((cause) => operationsError("manifest.create", cause)));
|
|
153
|
+
yield* fs.writeFileString(path.join(directory, "manifest.json"), JSON.stringify(manifest, null, 2), { flag: "wx" }).pipe(Effect.mapError((cause) => operationsError("manifest.write", cause)));
|
|
154
|
+
return manifest;
|
|
155
|
+
}).pipe(Effect.onError(() => fs.remove(directory, {
|
|
156
|
+
recursive: true,
|
|
157
|
+
force: true
|
|
158
|
+
}).pipe(Effect.orDie)));
|
|
159
|
+
});
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region ../server/src/internal/operations/restore.ts
|
|
162
|
+
const verifyDatabase = Effect.fn("Operations.verifyDatabase")(function* (path, expected) {
|
|
163
|
+
const ready = yield* readSnapshot(path, "sqlite.verify");
|
|
164
|
+
for (const row of ready) {
|
|
165
|
+
const object = expected.get(row.key);
|
|
166
|
+
if (!object) return yield* operationsError("sqlite.verify", /* @__PURE__ */ new Error(`Ready media is absent from the backup: ${row.key}`));
|
|
167
|
+
if (object.byteSize !== row.byteSize || object.mimeType !== row.mimeType) return yield* operationsError("sqlite.verify", /* @__PURE__ */ new Error(`Ready media metadata differs from backup: ${row.key}`));
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
const restoreInstallation = Effect.fn("Operations.restoreInstallation")(function* (options) {
|
|
171
|
+
const fs = yield* FileSystem.FileSystem;
|
|
172
|
+
const path = yield* Path.Path;
|
|
173
|
+
const crypto = yield* Crypto.Crypto;
|
|
174
|
+
if (yield* fs.exists(options.databaseFile).pipe(Effect.mapError((cause) => operationsError("sqlite.target", cause)))) return yield* operationsError("sqlite.target", /* @__PURE__ */ new Error("Restore needs a fresh database path."));
|
|
175
|
+
const raw = yield* fs.readFileString(path.join(options.directory, "manifest.json")).pipe(Effect.mapError((cause) => operationsError("manifest.read", cause)));
|
|
176
|
+
const manifest = yield* Schema.decodeEffect(Schema.fromJsonString(BackupManifest))(raw).pipe(Effect.mapError((cause) => operationsError("manifest.validate", cause)));
|
|
177
|
+
const objectsByKey = new Map(manifest.objects.map((object) => [object.key, object]));
|
|
178
|
+
if (objectsByKey.size !== manifest.objects.length) return yield* operationsError("manifest.validate", /* @__PURE__ */ new Error("Media object keys must be unique."));
|
|
179
|
+
const sqlite = path.join(options.directory, "cms.sqlite");
|
|
180
|
+
if ((yield* hashFile(fs, sqlite, "sqlite.hash")).sha256 !== manifest.sqliteSha256) return yield* operationsError("sqlite.hash", /* @__PURE__ */ new Error("The backup database checksum does not match."));
|
|
181
|
+
yield* verifyDatabase(sqlite, objectsByKey);
|
|
182
|
+
for (const object of manifest.objects) {
|
|
183
|
+
const file = yield* hashFile(fs, yield* objectPath(path, options.directory, object.key), "media.hash");
|
|
184
|
+
if (file.sha256 !== object.sha256 || file.byteSize !== object.byteSize) return yield* operationsError("media.hash", /* @__PURE__ */ new Error(`Backup media checksum does not match: ${object.key}`));
|
|
185
|
+
}
|
|
186
|
+
const existing = /* @__PURE__ */ new Set();
|
|
187
|
+
let cursor;
|
|
188
|
+
do {
|
|
189
|
+
const page = yield* options.media.list("", cursor).pipe(Effect.mapError((cause) => operationsError("media.list", cause)));
|
|
190
|
+
for (const object of page.objects) {
|
|
191
|
+
if (!objectsByKey.has(object.key)) return yield* operationsError("media.target", /* @__PURE__ */ new Error(`Target media prefix is not empty: ${object.key}`));
|
|
192
|
+
existing.add(object.key);
|
|
193
|
+
}
|
|
194
|
+
if (page.nextCursor === cursor && cursor !== void 0) return yield* operationsError("media.list", /* @__PURE__ */ new Error("Media inventory cursor did not advance."));
|
|
195
|
+
cursor = page.nextCursor;
|
|
196
|
+
} while (cursor);
|
|
197
|
+
for (const object of manifest.objects) {
|
|
198
|
+
if (!existing.has(object.key)) yield* options.media.put({
|
|
199
|
+
key: object.key,
|
|
200
|
+
byteSize: object.byteSize,
|
|
201
|
+
mimeType: object.mimeType,
|
|
202
|
+
filePath: yield* objectPath(path, options.directory, object.key)
|
|
203
|
+
}).pipe(Effect.mapError((cause) => operationsError("media.put", cause)));
|
|
204
|
+
const metadata = yield* options.media.stat(object.key).pipe(Effect.mapError((cause) => operationsError("media.stat", cause)));
|
|
205
|
+
if (!metadata) return yield* operationsError("media.missing", /* @__PURE__ */ new Error(`Restored media is unreadable: ${object.key}`));
|
|
206
|
+
const current = yield* Effect.scoped(Effect.gen(function* () {
|
|
207
|
+
const stream = yield* Effect.acquireRelease(options.media.read(object.key).pipe(Effect.mapError((cause) => operationsError("media.read", cause))), releaseStream, { interruptible: true });
|
|
208
|
+
if (!stream) return yield* operationsError("media.missing", /* @__PURE__ */ new Error(`Restored media is unreadable: ${object.key}`));
|
|
209
|
+
return yield* hashStream(stream);
|
|
210
|
+
}));
|
|
211
|
+
if (metadata.byteSize !== object.byteSize || metadata.mimeType !== object.mimeType || current.byteSize !== object.byteSize || current.sha256 !== object.sha256) return yield* operationsError("media.target", /* @__PURE__ */ new Error(`Restored media differs from backup: ${object.key}`));
|
|
212
|
+
}
|
|
213
|
+
yield* fs.makeDirectory(path.dirname(options.databaseFile), { recursive: true }).pipe(Effect.mapError((cause) => operationsError("sqlite.directory", cause)));
|
|
214
|
+
const suffix = yield* crypto.randomUUIDv4.pipe(Effect.mapError((cause) => operationsError("sqlite.copy", cause)));
|
|
215
|
+
const temporary = `${options.databaseFile}.restore-${suffix}`;
|
|
216
|
+
yield* Effect.gen(function* () {
|
|
217
|
+
yield* fs.copyFile(sqlite, temporary).pipe(Effect.mapError((cause) => operationsError("sqlite.copy", cause)));
|
|
218
|
+
if ((yield* hashFile(fs, temporary, "sqlite.copy")).sha256 !== manifest.sqliteSha256) return yield* operationsError("sqlite.copy", /* @__PURE__ */ new Error("The copied database checksum does not match."));
|
|
219
|
+
yield* Effect.gen(function* () {
|
|
220
|
+
yield* (yield* SqliteClient.SqliteClient)`UPDATE cms_revision_links SET revoked_at = ${new Date(yield* Clock.currentTimeMillis).toISOString()}, revoked_by = 'system:restore' WHERE revoked_at IS NULL`;
|
|
221
|
+
}).pipe(Effect.provide(SqliteClient.layer({
|
|
222
|
+
filename: temporary,
|
|
223
|
+
disableWAL: true
|
|
224
|
+
})), Effect.mapError((cause) => operationsError("sqlite.revision-links", cause)));
|
|
225
|
+
yield* fs.link(temporary, options.databaseFile).pipe(Effect.mapError((cause) => operationsError("sqlite.install", cause)));
|
|
226
|
+
}).pipe(Effect.ensuring(fs.remove(temporary, { force: true }).pipe(Effect.orDie)));
|
|
227
|
+
return manifest;
|
|
228
|
+
});
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region ../server/src/Operations.ts
|
|
231
|
+
const platformLayer = Layer.mergeAll(NodeFileSystem.layer, NodePath.layer, NodeCrypto.layer);
|
|
232
|
+
/** Run while the Nuxt process is stopped. The backup directory must not exist. */
|
|
233
|
+
const backup = Effect.fn("Operations.backup")(backupInstallation, Effect.provide(platformLayer));
|
|
234
|
+
/** Run while the Nuxt process is stopped, into a fresh database and media prefix. */
|
|
235
|
+
const restore = Effect.fn("Operations.restore")(restoreInstallation, Effect.provide(platformLayer));
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region src/Operations.ts
|
|
238
|
+
/** Back up a stopped installation to a new directory. */
|
|
239
|
+
const backupCms = Effect.fn("CmsOperations.backup")(function* (options) {
|
|
240
|
+
return yield* Effect.scoped(Effect.gen(function* () {
|
|
241
|
+
const media = Context.get(yield* Layer.build(layer(options.s3)), MediaObjects);
|
|
242
|
+
yield* media.check;
|
|
243
|
+
return yield* backup({
|
|
244
|
+
databaseFile: options.databaseFile,
|
|
245
|
+
directory: options.directory,
|
|
246
|
+
media
|
|
247
|
+
});
|
|
248
|
+
}));
|
|
249
|
+
});
|
|
250
|
+
/** Restore into a fresh database path and media prefix while Nuxt is stopped. */
|
|
251
|
+
const restoreCms = Effect.fn("CmsOperations.restore")(function* (options) {
|
|
252
|
+
return yield* Effect.scoped(Effect.gen(function* () {
|
|
253
|
+
const media = Context.get(yield* Layer.build(layer(options.s3)), MediaObjects);
|
|
254
|
+
yield* media.check;
|
|
255
|
+
return yield* restore({
|
|
256
|
+
databaseFile: options.databaseFile,
|
|
257
|
+
directory: options.directory,
|
|
258
|
+
media
|
|
259
|
+
});
|
|
260
|
+
}));
|
|
261
|
+
});
|
|
262
|
+
//#endregion
|
|
263
|
+
export { backupCms, restoreCms };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
//#region ../model/src/Studio.ts
|
|
3
|
+
/** A same-origin Nuxt page contributed to Studio's Tools navigation. */
|
|
4
|
+
const StudioModule = Schema.Struct({
|
|
5
|
+
id: Schema.NonEmptyString,
|
|
6
|
+
label: Schema.NonEmptyString,
|
|
7
|
+
icon: Schema.NonEmptyString,
|
|
8
|
+
path: Schema.NonEmptyString,
|
|
9
|
+
access: Schema.Literals(["administrator", "signed-in"])
|
|
10
|
+
});
|
|
11
|
+
const reservedIds = /* @__PURE__ */ new Set([
|
|
12
|
+
"overview",
|
|
13
|
+
"content",
|
|
14
|
+
"documents",
|
|
15
|
+
"inbox",
|
|
16
|
+
"calendar",
|
|
17
|
+
"trash",
|
|
18
|
+
"media",
|
|
19
|
+
"seo",
|
|
20
|
+
"activity",
|
|
21
|
+
"people",
|
|
22
|
+
"users",
|
|
23
|
+
"account"
|
|
24
|
+
]);
|
|
25
|
+
/** Validates names and frame paths before they cross into the browser bundle. */
|
|
26
|
+
function defineStudioModules(modules) {
|
|
27
|
+
const ids = /* @__PURE__ */ new Set();
|
|
28
|
+
return modules.map((module) => {
|
|
29
|
+
if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(module.id) || reservedIds.has(module.id) || ids.has(module.id)) throw new Error(`Studio tool ID ${JSON.stringify(module.id)} is invalid or already used.`);
|
|
30
|
+
if (!module.label.trim() || !module.icon.trim()) throw new Error(`Studio tool ${module.id} needs a label and icon.`);
|
|
31
|
+
if (!/^\/(?!\/)[a-z0-9/_-]*$/u.test(module.path) || module.path === "/_cms" || module.path.startsWith("/_cms/")) throw new Error(`Studio tool ${module.id} needs a same-origin path outside Studio.`);
|
|
32
|
+
ids.add(module.id);
|
|
33
|
+
return Schema.decodeSync(StudioModule)({
|
|
34
|
+
...module,
|
|
35
|
+
access: module.access ?? "administrator"
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region ../model/src/People.ts
|
|
41
|
+
const Role = Schema.Literals([
|
|
42
|
+
"administrator",
|
|
43
|
+
"editor",
|
|
44
|
+
"viewer"
|
|
45
|
+
]);
|
|
46
|
+
const PersonEmail = Schema.NonEmptyString.check(Schema.isMaxLength(320), Schema.isPattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/u));
|
|
47
|
+
const Person = Schema.Struct({
|
|
48
|
+
id: Schema.NonEmptyString,
|
|
49
|
+
name: Schema.NonEmptyString,
|
|
50
|
+
email: PersonEmail,
|
|
51
|
+
role: Role,
|
|
52
|
+
createdAt: Schema.String
|
|
53
|
+
});
|
|
54
|
+
const PeoplePage = Schema.Struct({
|
|
55
|
+
people: Schema.Array(Person),
|
|
56
|
+
total: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))
|
|
57
|
+
});
|
|
58
|
+
const CreatePerson = Schema.Struct({
|
|
59
|
+
name: Schema.NonEmptyString.check(Schema.isMaxLength(200)),
|
|
60
|
+
email: PersonEmail,
|
|
61
|
+
role: Role
|
|
62
|
+
});
|
|
63
|
+
const Invitation = Schema.Struct({
|
|
64
|
+
email: PersonEmail,
|
|
65
|
+
token: Schema.NonEmptyString,
|
|
66
|
+
expiresAt: Schema.String
|
|
67
|
+
});
|
|
68
|
+
//#endregion
|
|
69
|
+
export { PersonEmail as a, defineStudioModules as c, Person as i, Invitation as n, Role as o, PeoplePage as r, StudioModule as s, CreatePerson as t };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { l as DocumentId } from "./Document-CKXMSEf1.js";
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
//#region ../model/src/PreviewFocus.ts
|
|
4
|
+
const NodeIndex = Schema.Int.check(Schema.isBetween({
|
|
5
|
+
minimum: 0,
|
|
6
|
+
maximum: 1e5
|
|
7
|
+
}));
|
|
8
|
+
const FieldPathSegment = Schema.Union([Schema.Struct({
|
|
9
|
+
kind: Schema.Literal("field"),
|
|
10
|
+
name: Schema.NonEmptyString
|
|
11
|
+
}), Schema.Struct({
|
|
12
|
+
kind: Schema.Literal("item"),
|
|
13
|
+
id: Schema.NonEmptyString
|
|
14
|
+
})]);
|
|
15
|
+
const FieldPath = Schema.Array(FieldPathSegment).check(Schema.isMinLength(1), Schema.isMaxLength(32));
|
|
16
|
+
const PreviewFocusTarget = Schema.Union([
|
|
17
|
+
Schema.Struct({ kind: Schema.Literal("title") }),
|
|
18
|
+
Schema.Struct({ kind: Schema.Literal("document") }),
|
|
19
|
+
Schema.Struct({
|
|
20
|
+
kind: Schema.Literal("field"),
|
|
21
|
+
path: FieldPath
|
|
22
|
+
}),
|
|
23
|
+
Schema.Struct({
|
|
24
|
+
kind: Schema.Literal("blockField"),
|
|
25
|
+
blockId: Schema.NonEmptyString,
|
|
26
|
+
path: FieldPath
|
|
27
|
+
}),
|
|
28
|
+
Schema.Struct({
|
|
29
|
+
kind: Schema.Literal("block"),
|
|
30
|
+
blockId: Schema.NonEmptyString
|
|
31
|
+
}),
|
|
32
|
+
Schema.Struct({
|
|
33
|
+
kind: Schema.Literal("body"),
|
|
34
|
+
path: Schema.Array(NodeIndex).check(Schema.isMinLength(1), Schema.isMaxLength(16)),
|
|
35
|
+
nodeId: Schema.optionalKey(Schema.NonEmptyString),
|
|
36
|
+
blockId: Schema.optionalKey(Schema.NonEmptyString)
|
|
37
|
+
})
|
|
38
|
+
]);
|
|
39
|
+
const PreviewSource = Schema.Struct({
|
|
40
|
+
documentId: DocumentId,
|
|
41
|
+
target: PreviewFocusTarget,
|
|
42
|
+
approximate: Schema.Boolean
|
|
43
|
+
});
|
|
44
|
+
Schema.Struct({
|
|
45
|
+
type: Schema.Literal("cms-preview:activate"),
|
|
46
|
+
documentId: DocumentId,
|
|
47
|
+
target: PreviewFocusTarget,
|
|
48
|
+
approximate: Schema.optionalKey(Schema.Boolean)
|
|
49
|
+
});
|
|
50
|
+
Schema.Struct({
|
|
51
|
+
type: Schema.Literal("cms-preview:ready"),
|
|
52
|
+
documentId: DocumentId
|
|
53
|
+
});
|
|
54
|
+
Schema.Struct({
|
|
55
|
+
type: Schema.Literal("cms-preview:navigate"),
|
|
56
|
+
path: Schema.String
|
|
57
|
+
});
|
|
58
|
+
const StudioFocusMessage = Schema.Struct({
|
|
59
|
+
type: Schema.Literal("cms-studio:focus"),
|
|
60
|
+
documentId: DocumentId,
|
|
61
|
+
target: PreviewFocusTarget,
|
|
62
|
+
reveal: Schema.Boolean
|
|
63
|
+
});
|
|
64
|
+
const StudioPreviewModeMessage = Schema.Struct({
|
|
65
|
+
type: Schema.Literal("cms-studio:mode"),
|
|
66
|
+
documentId: DocumentId,
|
|
67
|
+
mode: Schema.Literals(["edit", "browse"])
|
|
68
|
+
});
|
|
69
|
+
/** A structural key keeps field names and item IDs unambiguous. */
|
|
70
|
+
function previewTargetKey(target) {
|
|
71
|
+
if (target.kind === "body" && target.nodeId) return `node:${target.nodeId}`;
|
|
72
|
+
switch (target.kind) {
|
|
73
|
+
case "field": return JSON.stringify([target.kind, fieldPathKey(target.path)]);
|
|
74
|
+
case "blockField": return JSON.stringify([
|
|
75
|
+
target.kind,
|
|
76
|
+
target.blockId,
|
|
77
|
+
fieldPathKey(target.path)
|
|
78
|
+
]);
|
|
79
|
+
case "block": return JSON.stringify([target.kind, target.blockId]);
|
|
80
|
+
case "body": return JSON.stringify([
|
|
81
|
+
target.kind,
|
|
82
|
+
target.path,
|
|
83
|
+
target.blockId ?? null
|
|
84
|
+
]);
|
|
85
|
+
default: return target.kind;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function fieldPathKey(path) {
|
|
89
|
+
return JSON.stringify(path.map((segment) => [segment.kind, segment.kind === "field" ? segment.name : segment.id]));
|
|
90
|
+
}
|
|
91
|
+
function encodePreviewSource(source) {
|
|
92
|
+
return encodeURIComponent(JSON.stringify(source));
|
|
93
|
+
}
|
|
94
|
+
function parsePreviewSource(value) {
|
|
95
|
+
if (!value || value.length > 16384) return null;
|
|
96
|
+
try {
|
|
97
|
+
const decoded = JSON.parse(decodeURIComponent(value));
|
|
98
|
+
return Schema.is(PreviewSource)(decoded) ? decoded : null;
|
|
99
|
+
} catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
export { encodePreviewSource as a, StudioPreviewModeMessage as i, PreviewSource as n, parsePreviewSource as o, StudioFocusMessage as r, previewTargetKey as s, PreviewFocusTarget as t };
|