@elytracms/studio 0.0.1
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 +21 -0
- package/README.md +3 -0
- package/convex/assets.ts +107 -0
- package/convex/auth.config.ts +15 -0
- package/convex/auth.ts +50 -0
- package/convex/cliTokens.ts +63 -0
- package/convex/cms.ts +174 -0
- package/convex/content.ts +316 -0
- package/convex/delivery.ts +266 -0
- package/convex/functions.ts +35 -0
- package/convex/graphs.ts +51 -0
- package/convex/guard.ts +67 -0
- package/convex/http.ts +30 -0
- package/convex/members.ts +83 -0
- package/convex/publishing.ts +102 -0
- package/convex/references.ts +168 -0
- package/convex/schema.ts +173 -0
- package/convex/sync.ts +322 -0
- package/convex/tsconfig.json +12 -0
- package/convex/users.ts +23 -0
- package/convex/webhooks.ts +85 -0
- package/dist/components/assets/asset-library.d.ts +14 -0
- package/dist/components/assets/asset-library.js +191 -0
- package/dist/components/assets/asset-library.js.map +1 -0
- package/dist/components/assets/asset-metadata.d.ts +34 -0
- package/dist/components/assets/asset-metadata.js +40 -0
- package/dist/components/assets/asset-metadata.js.map +1 -0
- package/dist/components/assets/asset-search.d.ts +7 -0
- package/dist/components/assets/asset-search.js +12 -0
- package/dist/components/assets/asset-search.js.map +1 -0
- package/dist/components/assets/asset-selection.d.ts +17 -0
- package/dist/components/assets/asset-selection.js +33 -0
- package/dist/components/assets/asset-selection.js.map +1 -0
- package/dist/components/assets/assets-store.d.ts +51 -0
- package/dist/components/assets/assets-store.js +153 -0
- package/dist/components/assets/assets-store.js.map +1 -0
- package/dist/components/auth-context.d.ts +38 -0
- package/dist/components/auth-context.js +88 -0
- package/dist/components/auth-context.js.map +1 -0
- package/dist/components/backend-gate.d.ts +19 -0
- package/dist/components/backend-gate.js +63 -0
- package/dist/components/backend-gate.js.map +1 -0
- package/dist/components/breadcrumb-context.d.ts +39 -0
- package/dist/components/breadcrumb-context.js +38 -0
- package/dist/components/breadcrumb-context.js.map +1 -0
- package/dist/components/builder/blocks-model.d.ts +80 -0
- package/dist/components/builder/blocks-model.js +181 -0
- package/dist/components/builder/blocks-model.js.map +1 -0
- package/dist/components/builder/blocks-panel.d.ts +44 -0
- package/dist/components/builder/blocks-panel.js +147 -0
- package/dist/components/builder/blocks-panel.js.map +1 -0
- package/dist/components/builder/builder-store.d.ts +69 -0
- package/dist/components/builder/builder-store.js +294 -0
- package/dist/components/builder/builder-store.js.map +1 -0
- package/dist/components/builder/canvas-stylesheet.d.ts +4 -0
- package/dist/components/builder/canvas-stylesheet.js +24 -0
- package/dist/components/builder/canvas-stylesheet.js.map +1 -0
- package/dist/components/builder/canvas.d.ts +8 -0
- package/dist/components/builder/canvas.js +723 -0
- package/dist/components/builder/canvas.js.map +1 -0
- package/dist/components/builder/clipboard-actions.d.ts +93 -0
- package/dist/components/builder/clipboard-actions.js +246 -0
- package/dist/components/builder/clipboard-actions.js.map +1 -0
- package/dist/components/builder/composition-field-editor.d.ts +11 -0
- package/dist/components/builder/composition-field-editor.js +150 -0
- package/dist/components/builder/composition-field-editor.js.map +1 -0
- package/dist/components/builder/composition-scope.d.ts +16 -0
- package/dist/components/builder/composition-scope.js +7 -0
- package/dist/components/builder/composition-scope.js.map +1 -0
- package/dist/components/builder/drag-session.d.ts +41 -0
- package/dist/components/builder/drag-session.js +51 -0
- package/dist/components/builder/drag-session.js.map +1 -0
- package/dist/components/builder/fixture-thumbnail.d.ts +18 -0
- package/dist/components/builder/fixture-thumbnail.js +97 -0
- package/dist/components/builder/fixture-thumbnail.js.map +1 -0
- package/dist/components/builder/inline-edit.d.ts +142 -0
- package/dist/components/builder/inline-edit.js +136 -0
- package/dist/components/builder/inline-edit.js.map +1 -0
- package/dist/components/builder/insert-context.d.ts +14 -0
- package/dist/components/builder/insert-context.js +65 -0
- package/dist/components/builder/insert-context.js.map +1 -0
- package/dist/components/builder/insert-menu.d.ts +9 -0
- package/dist/components/builder/insert-menu.js +9 -0
- package/dist/components/builder/insert-menu.js.map +1 -0
- package/dist/components/builder/layout-inspector.d.ts +14 -0
- package/dist/components/builder/layout-inspector.js +84 -0
- package/dist/components/builder/layout-inspector.js.map +1 -0
- package/dist/components/builder/node-factory.d.ts +17 -0
- package/dist/components/builder/node-factory.js +90 -0
- package/dist/components/builder/node-factory.js.map +1 -0
- package/dist/components/builder/page-tree.d.ts +3 -0
- package/dist/components/builder/page-tree.js +207 -0
- package/dist/components/builder/page-tree.js.map +1 -0
- package/dist/components/builder/property-inspector.d.ts +1 -0
- package/dist/components/builder/property-inspector.js +233 -0
- package/dist/components/builder/property-inspector.js.map +1 -0
- package/dist/components/builder/rich-text-toolbar.d.ts +4 -0
- package/dist/components/builder/rich-text-toolbar.js +104 -0
- package/dist/components/builder/rich-text-toolbar.js.map +1 -0
- package/dist/components/builder/spacing-handles.d.ts +22 -0
- package/dist/components/builder/spacing-handles.js +213 -0
- package/dist/components/builder/spacing-handles.js.map +1 -0
- package/dist/components/cms/asset-picker.d.ts +12 -0
- package/dist/components/cms/asset-picker.js +60 -0
- package/dist/components/cms/asset-picker.js.map +1 -0
- package/dist/components/cms/bulk-actions.d.ts +60 -0
- package/dist/components/cms/bulk-actions.js +95 -0
- package/dist/components/cms/bulk-actions.js.map +1 -0
- package/dist/components/cms/bulk-bar.d.ts +23 -0
- package/dist/components/cms/bulk-bar.js +26 -0
- package/dist/components/cms/bulk-bar.js.map +1 -0
- package/dist/components/cms/cell-edit.d.ts +91 -0
- package/dist/components/cms/cell-edit.js +144 -0
- package/dist/components/cms/cell-edit.js.map +1 -0
- package/dist/components/cms/cell.d.ts +29 -0
- package/dist/components/cms/cell.js +127 -0
- package/dist/components/cms/cell.js.map +1 -0
- package/dist/components/cms/cms-index.d.ts +8 -0
- package/dist/components/cms/cms-index.js +23 -0
- package/dist/components/cms/cms-index.js.map +1 -0
- package/dist/components/cms/cms-store.d.ts +188 -0
- package/dist/components/cms/cms-store.js +702 -0
- package/dist/components/cms/cms-store.js.map +1 -0
- package/dist/components/cms/collection-table.d.ts +6 -0
- package/dist/components/cms/collection-table.js +250 -0
- package/dist/components/cms/collection-table.js.map +1 -0
- package/dist/components/cms/collections-sidebar.d.ts +9 -0
- package/dist/components/cms/collections-sidebar.js +25 -0
- package/dist/components/cms/collections-sidebar.js.map +1 -0
- package/dist/components/cms/detail-editor.d.ts +7 -0
- package/dist/components/cms/detail-editor.js +386 -0
- package/dist/components/cms/detail-editor.js.map +1 -0
- package/dist/components/cms/doc-state.d.ts +13 -0
- package/dist/components/cms/doc-state.js +18 -0
- package/dist/components/cms/doc-state.js.map +1 -0
- package/dist/components/cms/document-editor-context.d.ts +48 -0
- package/dist/components/cms/document-editor-context.js +23 -0
- package/dist/components/cms/document-editor-context.js.map +1 -0
- package/dist/components/cms/editable-cell.d.ts +22 -0
- package/dist/components/cms/editable-cell.js +176 -0
- package/dist/components/cms/editable-cell.js.map +1 -0
- package/dist/components/cms/field-control.d.ts +8 -0
- package/dist/components/cms/field-control.js +149 -0
- package/dist/components/cms/field-control.js.map +1 -0
- package/dist/components/cms/filter-builder.d.ts +12 -0
- package/dist/components/cms/filter-builder.js +84 -0
- package/dist/components/cms/filter-builder.js.map +1 -0
- package/dist/components/cms/import-export.d.ts +6 -0
- package/dist/components/cms/import-export.js +33 -0
- package/dist/components/cms/import-export.js.map +1 -0
- package/dist/components/cms/new-page-dialog.d.ts +22 -0
- package/dist/components/cms/new-page-dialog.js +42 -0
- package/dist/components/cms/new-page-dialog.js.map +1 -0
- package/dist/components/cms/reference-confirm.d.ts +25 -0
- package/dist/components/cms/reference-confirm.js +124 -0
- package/dist/components/cms/reference-confirm.js.map +1 -0
- package/dist/components/cms/relation-picker.d.ts +16 -0
- package/dist/components/cms/relation-picker.js +47 -0
- package/dist/components/cms/relation-picker.js.map +1 -0
- package/dist/components/cms/use-cell-edit.d.ts +33 -0
- package/dist/components/cms/use-cell-edit.js +125 -0
- package/dist/components/cms/use-cell-edit.js.map +1 -0
- package/dist/components/cms/versions-model.d.ts +15 -0
- package/dist/components/cms/versions-model.js +23 -0
- package/dist/components/cms/versions-model.js.map +1 -0
- package/dist/components/cms/versions-pane.d.ts +14 -0
- package/dist/components/cms/versions-pane.js +86 -0
- package/dist/components/cms/versions-pane.js.map +1 -0
- package/dist/components/cms/view-bar.d.ts +11 -0
- package/dist/components/cms/view-bar.js +80 -0
- package/dist/components/cms/view-bar.js.map +1 -0
- package/dist/components/collab/collab-context.d.ts +34 -0
- package/dist/components/collab/collab-context.js +52 -0
- package/dist/components/collab/collab-context.js.map +1 -0
- package/dist/components/collab/collab-seed.d.ts +27 -0
- package/dist/components/collab/collab-seed.js +42 -0
- package/dist/components/collab/collab-seed.js.map +1 -0
- package/dist/components/components/component-detail.d.ts +9 -0
- package/dist/components/components/component-detail.js +30 -0
- package/dist/components/components/component-detail.js.map +1 -0
- package/dist/components/components/component-status.d.ts +10 -0
- package/dist/components/components/component-status.js +30 -0
- package/dist/components/components/component-status.js.map +1 -0
- package/dist/components/components/components-index.d.ts +8 -0
- package/dist/components/components/components-index.js +42 -0
- package/dist/components/components/components-index.js.map +1 -0
- package/dist/components/components/field-inspector.d.ts +9 -0
- package/dist/components/components/field-inspector.js +38 -0
- package/dist/components/components/field-inspector.js.map +1 -0
- package/dist/components/components/fixture-runner.d.ts +10 -0
- package/dist/components/components/fixture-runner.js +24 -0
- package/dist/components/components/fixture-runner.js.map +1 -0
- package/dist/components/components/registry-browser.d.ts +4 -0
- package/dist/components/components/registry-browser.js +64 -0
- package/dist/components/components/registry-browser.js.map +1 -0
- package/dist/components/current-user-menu.d.ts +13 -0
- package/dist/components/current-user-menu.js +31 -0
- package/dist/components/current-user-menu.js.map +1 -0
- package/dist/components/dev-login-badge.d.ts +9 -0
- package/dist/components/dev-login-badge.js +18 -0
- package/dist/components/dev-login-badge.js.map +1 -0
- package/dist/components/extensions/extensions-view.d.ts +7 -0
- package/dist/components/extensions/extensions-view.js +126 -0
- package/dist/components/extensions/extensions-view.js.map +1 -0
- package/dist/components/guards.d.ts +27 -0
- package/dist/components/guards.js +46 -0
- package/dist/components/guards.js.map +1 -0
- package/dist/components/inspector/inspector-sidebar.d.ts +26 -0
- package/dist/components/inspector/inspector-sidebar.js +17 -0
- package/dist/components/inspector/inspector-sidebar.js.map +1 -0
- package/dist/components/operation-error.d.ts +17 -0
- package/dist/components/operation-error.js +54 -0
- package/dist/components/operation-error.js.map +1 -0
- package/dist/components/playground-badge.d.ts +10 -0
- package/dist/components/playground-badge.js +19 -0
- package/dist/components/playground-badge.js.map +1 -0
- package/dist/components/project-list.d.ts +15 -0
- package/dist/components/project-list.js +52 -0
- package/dist/components/project-list.js.map +1 -0
- package/dist/components/project-session.d.ts +46 -0
- package/dist/components/project-session.js +107 -0
- package/dist/components/project-session.js.map +1 -0
- package/dist/components/project-switcher.d.ts +11 -0
- package/dist/components/project-switcher.js +44 -0
- package/dist/components/project-switcher.js.map +1 -0
- package/dist/components/references/builder-deep-link.d.ts +12 -0
- package/dist/components/references/builder-deep-link.js +53 -0
- package/dist/components/references/builder-deep-link.js.map +1 -0
- package/dist/components/references/references-panel.d.ts +17 -0
- package/dist/components/references/references-panel.js +66 -0
- package/dist/components/references/references-panel.js.map +1 -0
- package/dist/components/routes/redirect-chain.d.ts +9 -0
- package/dist/components/routes/redirect-chain.js +16 -0
- package/dist/components/routes/redirect-chain.js.map +1 -0
- package/dist/components/routes/redirect-manager.d.ts +13 -0
- package/dist/components/routes/redirect-manager.js +24 -0
- package/dist/components/routes/redirect-manager.js.map +1 -0
- package/dist/components/routes/route-list.d.ts +35 -0
- package/dist/components/routes/route-list.js +69 -0
- package/dist/components/routes/route-list.js.map +1 -0
- package/dist/components/routes/routes-shell.d.ts +14 -0
- package/dist/components/routes/routes-shell.js +68 -0
- package/dist/components/routes/routes-shell.js.map +1 -0
- package/dist/components/section-nav.d.ts +17 -0
- package/dist/components/section-nav.js +33 -0
- package/dist/components/section-nav.js.map +1 -0
- package/dist/components/section-state.d.ts +24 -0
- package/dist/components/section-state.js +78 -0
- package/dist/components/section-state.js.map +1 -0
- package/dist/components/section-surface.d.ts +31 -0
- package/dist/components/section-surface.js +46 -0
- package/dist/components/section-surface.js.map +1 -0
- package/dist/components/sections.d.ts +38 -0
- package/dist/components/sections.js +72 -0
- package/dist/components/sections.js.map +1 -0
- package/dist/components/settings-form.d.ts +10 -0
- package/dist/components/settings-form.js +17 -0
- package/dist/components/settings-form.js.map +1 -0
- package/dist/components/studio-context.d.ts +22 -0
- package/dist/components/studio-context.js +48 -0
- package/dist/components/studio-context.js.map +1 -0
- package/dist/components/studio-project-screen.d.ts +19 -0
- package/dist/components/studio-project-screen.js +195 -0
- package/dist/components/studio-project-screen.js.map +1 -0
- package/dist/components/studio-shell.d.ts +18 -0
- package/dist/components/studio-shell.js +64 -0
- package/dist/components/studio-shell.js.map +1 -0
- package/dist/components/theme-context.d.ts +17 -0
- package/dist/components/theme-context.js +26 -0
- package/dist/components/theme-context.js.map +1 -0
- package/dist/components/workspace-gate.d.ts +12 -0
- package/dist/components/workspace-gate.js +27 -0
- package/dist/components/workspace-gate.js.map +1 -0
- package/dist/components/workspace-projects.d.ts +13 -0
- package/dist/components/workspace-projects.js +18 -0
- package/dist/components/workspace-projects.js.map +1 -0
- package/dist/lib/assets/delete-asset.d.ts +34 -0
- package/dist/lib/assets/delete-asset.js +34 -0
- package/dist/lib/assets/delete-asset.js.map +1 -0
- package/dist/lib/assets/image-dimensions.d.ts +18 -0
- package/dist/lib/assets/image-dimensions.js +26 -0
- package/dist/lib/assets/image-dimensions.js.map +1 -0
- package/dist/lib/assets/index.d.ts +9 -0
- package/dist/lib/assets/index.js +10 -0
- package/dist/lib/assets/index.js.map +1 -0
- package/dist/lib/assets/upload-state.d.ts +53 -0
- package/dist/lib/assets/upload-state.js +59 -0
- package/dist/lib/assets/upload-state.js.map +1 -0
- package/dist/lib/assets/upload.d.ts +56 -0
- package/dist/lib/assets/upload.js +125 -0
- package/dist/lib/assets/upload.js.map +1 -0
- package/dist/lib/auth/auth-adapter.d.ts +57 -0
- package/dist/lib/auth/auth-adapter.js +13 -0
- package/dist/lib/auth/auth-adapter.js.map +1 -0
- package/dist/lib/auth/convex-auth-adapter.d.ts +39 -0
- package/dist/lib/auth/convex-auth-adapter.js +171 -0
- package/dist/lib/auth/convex-auth-adapter.js.map +1 -0
- package/dist/lib/auth/dev-auto-login-adapter.d.ts +25 -0
- package/dist/lib/auth/dev-auto-login-adapter.js +40 -0
- package/dist/lib/auth/dev-auto-login-adapter.js.map +1 -0
- package/dist/lib/auth/index.d.ts +28 -0
- package/dist/lib/auth/index.js +61 -0
- package/dist/lib/auth/index.js.map +1 -0
- package/dist/lib/auth/local-auth-adapter.d.ts +57 -0
- package/dist/lib/auth/local-auth-adapter.js +78 -0
- package/dist/lib/auth/local-auth-adapter.js.map +1 -0
- package/dist/lib/auth/route-guard.d.ts +33 -0
- package/dist/lib/auth/route-guard.js +51 -0
- package/dist/lib/auth/route-guard.js.map +1 -0
- package/dist/lib/auth-errors.d.ts +42 -0
- package/dist/lib/auth-errors.js +74 -0
- package/dist/lib/auth-errors.js.map +1 -0
- package/dist/lib/bindings/section-bindings.d.ts +24 -0
- package/dist/lib/bindings/section-bindings.js +9 -0
- package/dist/lib/bindings/section-bindings.js.map +1 -0
- package/dist/lib/clipboard/index.d.ts +7 -0
- package/dist/lib/clipboard/index.js +8 -0
- package/dist/lib/clipboard/index.js.map +1 -0
- package/dist/lib/clipboard/os-clipboard.d.ts +46 -0
- package/dist/lib/clipboard/os-clipboard.js +105 -0
- package/dist/lib/clipboard/os-clipboard.js.map +1 -0
- package/dist/lib/clipboard/paste-issues.d.ts +34 -0
- package/dist/lib/clipboard/paste-issues.js +67 -0
- package/dist/lib/clipboard/paste-issues.js.map +1 -0
- package/dist/lib/clipboard/paste-target.d.ts +20 -0
- package/dist/lib/clipboard/paste-target.js +28 -0
- package/dist/lib/clipboard/paste-target.js.map +1 -0
- package/dist/lib/cms/published-documents.d.ts +30 -0
- package/dist/lib/cms/published-documents.js +75 -0
- package/dist/lib/cms/published-documents.js.map +1 -0
- package/dist/lib/cms-views/index.d.ts +9 -0
- package/dist/lib/cms-views/index.js +10 -0
- package/dist/lib/cms-views/index.js.map +1 -0
- package/dist/lib/cms-views/selection.d.ts +29 -0
- package/dist/lib/cms-views/selection.js +46 -0
- package/dist/lib/cms-views/selection.js.map +1 -0
- package/dist/lib/cms-views/view-model.d.ts +192 -0
- package/dist/lib/cms-views/view-model.js +353 -0
- package/dist/lib/cms-views/view-model.js.map +1 -0
- package/dist/lib/cms-views/views-store.d.ts +70 -0
- package/dist/lib/cms-views/views-store.js +129 -0
- package/dist/lib/cms-views/views-store.js.map +1 -0
- package/dist/lib/data/collection-content.d.ts +105 -0
- package/dist/lib/data/collection-content.js +196 -0
- package/dist/lib/data/collection-content.js.map +1 -0
- package/dist/lib/data/data-store.d.ts +97 -0
- package/dist/lib/data/data-store.js +205 -0
- package/dist/lib/data/data-store.js.map +1 -0
- package/dist/lib/data/index.d.ts +4 -0
- package/dist/lib/data/index.js +8 -0
- package/dist/lib/data/index.js.map +1 -0
- package/dist/lib/data/providers.d.ts +143 -0
- package/dist/lib/data/providers.js +255 -0
- package/dist/lib/data/providers.js.map +1 -0
- package/dist/lib/data/sample-capture.d.ts +30 -0
- package/dist/lib/data/sample-capture.js +70 -0
- package/dist/lib/data/sample-capture.js.map +1 -0
- package/dist/lib/data/sources-store.d.ts +42 -0
- package/dist/lib/data/sources-store.js +120 -0
- package/dist/lib/data/sources-store.js.map +1 -0
- package/dist/lib/dnd/drop-rules.d.ts +219 -0
- package/dist/lib/dnd/drop-rules.js +257 -0
- package/dist/lib/dnd/drop-rules.js.map +1 -0
- package/dist/lib/dnd/gap-drag.d.ts +66 -0
- package/dist/lib/dnd/gap-drag.js +95 -0
- package/dist/lib/dnd/gap-drag.js.map +1 -0
- package/dist/lib/locale/binding-fallback.d.ts +28 -0
- package/dist/lib/locale/binding-fallback.js +66 -0
- package/dist/lib/locale/binding-fallback.js.map +1 -0
- package/dist/lib/locale/fallback.d.ts +43 -0
- package/dist/lib/locale/fallback.js +52 -0
- package/dist/lib/locale/fallback.js.map +1 -0
- package/dist/lib/locale/index.d.ts +6 -0
- package/dist/lib/locale/index.js +7 -0
- package/dist/lib/locale/index.js.map +1 -0
- package/dist/lib/locale/locale-store.d.ts +40 -0
- package/dist/lib/locale/locale-store.js +61 -0
- package/dist/lib/locale/locale-store.js.map +1 -0
- package/dist/lib/locale/locale-switcher.d.ts +10 -0
- package/dist/lib/locale/locale-switcher.js +24 -0
- package/dist/lib/locale/locale-switcher.js.map +1 -0
- package/dist/lib/locale/route-variant.d.ts +14 -0
- package/dist/lib/locale/route-variant.js +11 -0
- package/dist/lib/locale/route-variant.js.map +1 -0
- package/dist/lib/locale/use-studio-locale.d.ts +10 -0
- package/dist/lib/locale/use-studio-locale.js +8 -0
- package/dist/lib/locale/use-studio-locale.js.map +1 -0
- package/dist/lib/operations/asset-repository.d.ts +15 -0
- package/dist/lib/operations/asset-repository.js +56 -0
- package/dist/lib/operations/asset-repository.js.map +1 -0
- package/dist/lib/operations/cms-persistence.d.ts +35 -0
- package/dist/lib/operations/cms-persistence.js +75 -0
- package/dist/lib/operations/cms-persistence.js.map +1 -0
- package/dist/lib/operations/graph-commands.d.ts +140 -0
- package/dist/lib/operations/graph-commands.js +86 -0
- package/dist/lib/operations/graph-commands.js.map +1 -0
- package/dist/lib/operations/graph-persistence.d.ts +27 -0
- package/dist/lib/operations/graph-persistence.js +35 -0
- package/dist/lib/operations/graph-persistence.js.map +1 -0
- package/dist/lib/operations/index.d.ts +13 -0
- package/dist/lib/operations/index.js +14 -0
- package/dist/lib/operations/index.js.map +1 -0
- package/dist/lib/operations/operations-package.d.ts +6 -0
- package/dist/lib/operations/operations-package.js +7 -0
- package/dist/lib/operations/operations-package.js.map +1 -0
- package/dist/lib/operations/persist-queue.d.ts +16 -0
- package/dist/lib/operations/persist-queue.js +18 -0
- package/dist/lib/operations/persist-queue.js.map +1 -0
- package/dist/lib/operations/session-hydration.d.ts +84 -0
- package/dist/lib/operations/session-hydration.js +112 -0
- package/dist/lib/operations/session-hydration.js.map +1 -0
- package/dist/lib/operations/studio-operations.d.ts +59 -0
- package/dist/lib/operations/studio-operations.js +92 -0
- package/dist/lib/operations/studio-operations.js.map +1 -0
- package/dist/lib/persistence/backend-mode.d.ts +69 -0
- package/dist/lib/persistence/backend-mode.js +120 -0
- package/dist/lib/persistence/backend-mode.js.map +1 -0
- package/dist/lib/persistence/convex-adapter.d.ts +34 -0
- package/dist/lib/persistence/convex-adapter.js +681 -0
- package/dist/lib/persistence/convex-adapter.js.map +1 -0
- package/dist/lib/persistence/convex-blob-storage.d.ts +57 -0
- package/dist/lib/persistence/convex-blob-storage.js +97 -0
- package/dist/lib/persistence/convex-blob-storage.js.map +1 -0
- package/dist/lib/persistence/convex-client.d.ts +19 -0
- package/dist/lib/persistence/convex-client.js +40 -0
- package/dist/lib/persistence/convex-client.js.map +1 -0
- package/dist/lib/persistence/index.d.ts +30 -0
- package/dist/lib/persistence/index.js +60 -0
- package/dist/lib/persistence/index.js.map +1 -0
- package/dist/lib/persona/labels.d.ts +23 -0
- package/dist/lib/persona/labels.js +122 -0
- package/dist/lib/persona/labels.js.map +1 -0
- package/dist/lib/rail.d.ts +11 -0
- package/dist/lib/rail.js +26 -0
- package/dist/lib/rail.js.map +1 -0
- package/dist/lib/references/impact.d.ts +64 -0
- package/dist/lib/references/impact.js +62 -0
- package/dist/lib/references/impact.js.map +1 -0
- package/dist/lib/references/index.d.ts +7 -0
- package/dist/lib/references/index.js +8 -0
- package/dist/lib/references/index.js.map +1 -0
- package/dist/lib/references/reference-model.d.ts +125 -0
- package/dist/lib/references/reference-model.js +242 -0
- package/dist/lib/references/reference-model.js.map +1 -0
- package/dist/lib/references/references-store.d.ts +65 -0
- package/dist/lib/references/references-store.js +221 -0
- package/dist/lib/references/references-store.js.map +1 -0
- package/dist/lib/registry/index.d.ts +65 -0
- package/dist/lib/registry/index.js +114 -0
- package/dist/lib/registry/index.js.map +1 -0
- package/dist/lib/registry/preview.d.ts +15 -0
- package/dist/lib/registry/preview.js +110 -0
- package/dist/lib/registry/preview.js.map +1 -0
- package/dist/lib/registry/project-components.d.ts +16 -0
- package/dist/lib/registry/project-components.js +152 -0
- package/dist/lib/registry/project-components.js.map +1 -0
- package/dist/lib/routing/index.d.ts +10 -0
- package/dist/lib/routing/index.js +11 -0
- package/dist/lib/routing/index.js.map +1 -0
- package/dist/lib/routing/routing-analysis.d.ts +26 -0
- package/dist/lib/routing/routing-analysis.js +37 -0
- package/dist/lib/routing/routing-analysis.js.map +1 -0
- package/dist/lib/routing/routing-store.d.ts +50 -0
- package/dist/lib/routing/routing-store.js +72 -0
- package/dist/lib/routing/routing-store.js.map +1 -0
- package/dist/lib/starters/kit-session.d.ts +5 -0
- package/dist/lib/starters/kit-session.js +17 -0
- package/dist/lib/starters/kit-session.js.map +1 -0
- package/dist/lib/theme.d.ts +21 -0
- package/dist/lib/theme.js +32 -0
- package/dist/lib/theme.js.map +1 -0
- package/dist/lib/utils.d.ts +11 -0
- package/dist/lib/utils.js +28 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/webhooks/config.d.ts +15 -0
- package/dist/lib/webhooks/config.js +64 -0
- package/dist/lib/webhooks/config.js.map +1 -0
- package/dist/lib/webhooks/dispatcher.d.ts +67 -0
- package/dist/lib/webhooks/dispatcher.js +61 -0
- package/dist/lib/webhooks/dispatcher.js.map +1 -0
- package/dist/lib/webhooks/index.d.ts +11 -0
- package/dist/lib/webhooks/index.js +10 -0
- package/dist/lib/webhooks/index.js.map +1 -0
- package/dist/lib/webhooks/signing.d.ts +15 -0
- package/dist/lib/webhooks/signing.js +24 -0
- package/dist/lib/webhooks/signing.js.map +1 -0
- package/dist/lib/webhooks/tags.d.ts +25 -0
- package/dist/lib/webhooks/tags.js +173 -0
- package/dist/lib/webhooks/tags.js.map +1 -0
- package/dist/lib/working-graph.d.ts +82 -0
- package/dist/lib/working-graph.js +113 -0
- package/dist/lib/working-graph.js.map +1 -0
- package/dist/lib/workspace/index.d.ts +109 -0
- package/dist/lib/workspace/index.js +206 -0
- package/dist/lib/workspace/index.js.map +1 -0
- package/dist/lib/workspace/switcher-source.d.ts +39 -0
- package/dist/lib/workspace/switcher-source.js +23 -0
- package/dist/lib/workspace/switcher-source.js.map +1 -0
- package/dist/lib/workspace/workspace-source.d.ts +47 -0
- package/dist/lib/workspace/workspace-source.js +67 -0
- package/dist/lib/workspace/workspace-source.js.map +1 -0
- package/dist/router/index.d.ts +32 -0
- package/dist/router/index.js +32 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/match.d.ts +75 -0
- package/dist/router/match.js +87 -0
- package/dist/router/match.js.map +1 -0
- package/dist/router/search.d.ts +22 -0
- package/dist/router/search.js +16 -0
- package/dist/router/search.js.map +1 -0
- package/dist/ui/avatar.d.ts +17 -0
- package/dist/ui/avatar.js +38 -0
- package/dist/ui/avatar.js.map +1 -0
- package/dist/ui/badge.d.ts +9 -0
- package/dist/ui/badge.js +23 -0
- package/dist/ui/badge.js.map +1 -0
- package/dist/ui/button.d.ts +11 -0
- package/dist/ui/button.js +30 -0
- package/dist/ui/button.js.map +1 -0
- package/dist/ui/card.d.ts +11 -0
- package/dist/ui/card.js +23 -0
- package/dist/ui/card.js.map +1 -0
- package/dist/ui/dialog.d.ts +12 -0
- package/dist/ui/dialog.js +27 -0
- package/dist/ui/dialog.js.map +1 -0
- package/dist/ui/dropdown-menu.d.ts +15 -0
- package/dist/ui/dropdown-menu.js +24 -0
- package/dist/ui/dropdown-menu.js.map +1 -0
- package/dist/ui/field.d.ts +15 -0
- package/dist/ui/field.js +14 -0
- package/dist/ui/field.js.map +1 -0
- package/dist/ui/index.d.ts +14 -0
- package/dist/ui/index.js +15 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/input.d.ts +3 -0
- package/dist/ui/input.js +7 -0
- package/dist/ui/input.js.map +1 -0
- package/dist/ui/inspector.d.ts +18 -0
- package/dist/ui/inspector.js +14 -0
- package/dist/ui/inspector.js.map +1 -0
- package/dist/ui/layout.d.ts +45 -0
- package/dist/ui/layout.js +48 -0
- package/dist/ui/layout.js.map +1 -0
- package/dist/ui/panel.d.ts +12 -0
- package/dist/ui/panel.js +20 -0
- package/dist/ui/panel.js.map +1 -0
- package/dist/ui/separator.d.ts +6 -0
- package/dist/ui/separator.js +7 -0
- package/dist/ui/separator.js.map +1 -0
- package/dist/ui/toolbar.d.ts +9 -0
- package/dist/ui/toolbar.js +16 -0
- package/dist/ui/toolbar.js.map +1 -0
- package/dist/ui/typography.d.ts +50 -0
- package/dist/ui/typography.js +43 -0
- package/dist/ui/typography.js.map +1 -0
- package/package.json +149 -0
- package/src/styles/studio.css +101 -0
- package/src/styles/tokens.css +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 finaldream
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
package/convex/assets.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { v } from 'convex/values'
|
|
2
|
+
import type { GenericId } from 'convex/values'
|
|
3
|
+
import { mutation, query } from './functions'
|
|
4
|
+
import { requireRole, requireUserId } from './guard'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Asset metadata persistence (EC-044) + byte storage (EC-151). Bytes live in
|
|
8
|
+
* Convex file storage; `storageKey` on a metadata record is the Convex storage
|
|
9
|
+
* id. These functions are reachable only through the app's
|
|
10
|
+
* `ConvexBlobStorage` / `ConvexAssetRepository` adapters — never from UI code.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** Convex storage ids arrive as plain strings over the wire; rebrand for the typed API. */
|
|
14
|
+
const asStorageId = (storageKey: string) => storageKey as GenericId<'_storage'>
|
|
15
|
+
|
|
16
|
+
export const upsert = mutation({
|
|
17
|
+
args: {
|
|
18
|
+
assetId: v.string(),
|
|
19
|
+
filename: v.string(),
|
|
20
|
+
contentType: v.string(),
|
|
21
|
+
byteSize: v.number(),
|
|
22
|
+
width: v.optional(v.number()),
|
|
23
|
+
height: v.optional(v.number()),
|
|
24
|
+
alt: v.optional(v.string()),
|
|
25
|
+
title: v.optional(v.string()),
|
|
26
|
+
storageKey: v.string(),
|
|
27
|
+
url: v.optional(v.string()),
|
|
28
|
+
focalPoint: v.optional(v.object({ x: v.number(), y: v.number() })),
|
|
29
|
+
createdAt: v.string(),
|
|
30
|
+
updatedAt: v.string(),
|
|
31
|
+
},
|
|
32
|
+
handler: async (ctx, args) => {
|
|
33
|
+
await requireRole(ctx, 'editor') // EC-150
|
|
34
|
+
const existing = await ctx.db
|
|
35
|
+
.query('assets')
|
|
36
|
+
.withIndex('by_asset', (q) => q.eq('assetId', args.assetId))
|
|
37
|
+
.first()
|
|
38
|
+
if (existing) {
|
|
39
|
+
await ctx.db.patch(existing._id, { ...args, createdAt: existing.createdAt })
|
|
40
|
+
return ctx.db.get(existing._id)
|
|
41
|
+
}
|
|
42
|
+
const id = await ctx.db.insert('assets', args)
|
|
43
|
+
return ctx.db.get(id)
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
export const get = query({
|
|
48
|
+
args: { assetId: v.string() },
|
|
49
|
+
handler: async (ctx, args) => {
|
|
50
|
+
await requireRole(ctx, 'viewer') // EC-150
|
|
51
|
+
return ctx.db
|
|
52
|
+
.query('assets')
|
|
53
|
+
.withIndex('by_asset', (q) => q.eq('assetId', args.assetId))
|
|
54
|
+
.first()
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
export const list = query({
|
|
59
|
+
args: {},
|
|
60
|
+
handler: async (ctx) => {
|
|
61
|
+
await requireRole(ctx, 'viewer') // EC-150
|
|
62
|
+
return ctx.db.query('assets').withIndex('by_asset').collect()
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
export const remove = mutation({
|
|
67
|
+
args: { assetId: v.string() },
|
|
68
|
+
handler: async (ctx, args) => {
|
|
69
|
+
await requireRole(ctx, 'editor') // EC-150
|
|
70
|
+
const existing = await ctx.db
|
|
71
|
+
.query('assets')
|
|
72
|
+
.withIndex('by_asset', (q) => q.eq('assetId', args.assetId))
|
|
73
|
+
.first()
|
|
74
|
+
if (existing) await ctx.db.delete(existing._id)
|
|
75
|
+
},
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
// --- Byte storage (EC-151) — Convex file storage behind the blob adapter ----
|
|
79
|
+
|
|
80
|
+
/** Mint a short-lived URL the studio POSTs file bytes to (Convex upload flow). */
|
|
81
|
+
export const generateUploadUrl = mutation({
|
|
82
|
+
args: {},
|
|
83
|
+
handler: async (ctx) => {
|
|
84
|
+
// EC-150: any authenticated user may mint an upload URL; the metadata write
|
|
85
|
+
// (`assets:upsert`) is what enforces the deployment role.
|
|
86
|
+
await requireUserId(ctx)
|
|
87
|
+
return ctx.storage.generateUploadUrl()
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
/** Resolve the serve URL for a stored blob; `null` when the blob is gone. */
|
|
92
|
+
export const getServeUrl = query({
|
|
93
|
+
args: { storageKey: v.string() },
|
|
94
|
+
handler: async (ctx, { storageKey }) => {
|
|
95
|
+
await requireUserId(ctx) // EC-150: storage keys are unguessable; auth is the gate.
|
|
96
|
+
return ctx.storage.getUrl(asStorageId(storageKey))
|
|
97
|
+
},
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
/** Delete stored bytes. Metadata removal is a separate `assets:remove` call. */
|
|
101
|
+
export const deleteBlob = mutation({
|
|
102
|
+
args: { storageKey: v.string() },
|
|
103
|
+
handler: async (ctx, { storageKey }) => {
|
|
104
|
+
await requireUserId(ctx) // EC-150
|
|
105
|
+
await ctx.storage.delete(asStorageId(storageKey))
|
|
106
|
+
},
|
|
107
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC provider configuration for Convex Auth (EC-150): the Convex deployment itself
|
|
3
|
+
* issues the JWTs (`CONVEX_SITE_URL` is set automatically on every deployment), so no
|
|
4
|
+
* third-party identity provider is involved. Generic for every deployment — the
|
|
5
|
+
* consumer's `convex/auth.config.ts` is a one-line re-export shim (EC-252). See
|
|
6
|
+
* https://labs.convex.dev/auth/setup.
|
|
7
|
+
*/
|
|
8
|
+
export default {
|
|
9
|
+
providers: [
|
|
10
|
+
{
|
|
11
|
+
domain: process.env.CONVEX_SITE_URL,
|
|
12
|
+
applicationID: 'convex',
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
}
|
package/convex/auth.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { convexAuth } from '@convex-dev/auth/server'
|
|
2
|
+
import { Password } from '@convex-dev/auth/providers/Password'
|
|
3
|
+
|
|
4
|
+
/** The provider list `convexAuth` accepts, derived from its own signature. */
|
|
5
|
+
type ConvexAuthProviders = Parameters<typeof convexAuth>[0]['providers']
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* EC-252 — the studio's Convex Auth (EC-150) as a **default + override seam**. Only the
|
|
9
|
+
* PROVIDER choice is legitimately consumer-specific; the first-principal admin bootstrap
|
|
10
|
+
* callback is engine logic and stays here, so consumers stop copying it. The consumer's
|
|
11
|
+
* `convex/auth.ts` is a one-liner that picks up the default:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* export const { auth, signIn, signOut, store, isAuthenticated } = defineStudioAuth()
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* or composes its own providers (OAuth, etc.) while keeping the engine bootstrap:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* export const { auth, ... } = defineStudioAuth({ providers: [Password, GitHub] })
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Decision record (EC-150): Convex Auth over Clerk — self-contained on the Convex stack,
|
|
24
|
+
* sessions live in our own tables, and the studio only talks to it through the
|
|
25
|
+
* project-owned `AuthAdapter`, so swapping providers later is one factory call, not UI.
|
|
26
|
+
*/
|
|
27
|
+
export function defineStudioAuth(options?: { providers?: ConvexAuthProviders }) {
|
|
28
|
+
return convexAuth({
|
|
29
|
+
providers: options?.providers ?? [Password],
|
|
30
|
+
callbacks: {
|
|
31
|
+
/**
|
|
32
|
+
* First-principal admin bootstrap (EC-182 follow-up). On a freshly-provisioned
|
|
33
|
+
* deployment the `members` table is empty, so no one can pass the role guard and
|
|
34
|
+
* the studio is unreachable. Rather than require a manual seed step, the **first
|
|
35
|
+
* user to authenticate while the deployment has no members** is auto-granted
|
|
36
|
+
* `admin`. Once any membership exists this is a no-op (one indexed read) — further
|
|
37
|
+
* roles are assigned by an admin via `members:set`. Single-tenant: one `members`
|
|
38
|
+
* table per deployment. `beforeSessionCreation` fires on every sign-in (not just
|
|
39
|
+
* account creation), so it also recovers a member-less account and never lets a
|
|
40
|
+
* deployment lock itself out.
|
|
41
|
+
*/
|
|
42
|
+
async beforeSessionCreation(ctx, { userId }) {
|
|
43
|
+
const existing = await ctx.db.query('members').first()
|
|
44
|
+
if (existing) return
|
|
45
|
+
const now = new Date().toISOString()
|
|
46
|
+
await ctx.db.insert('members', { userId, role: 'admin', createdAt: now, updatedAt: now })
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { v } from 'convex/values'
|
|
2
|
+
import { mutation, query } from './functions'
|
|
3
|
+
import { requireRole } from './guard'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CLI token persistence (EC-150). Only SHA-256 hashes are stored — hashing and
|
|
7
|
+
* plaintext generation happen in `@elytracms/operations` (`tokens.issue`), and
|
|
8
|
+
* verification goes through `verifyCliToken`, which calls `byHash` below via
|
|
9
|
+
* the `ConvexCliTokenRepository`. All user-facing access is admin-only.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const create = mutation({
|
|
13
|
+
args: {
|
|
14
|
+
tokenId: v.string(),
|
|
15
|
+
label: v.string(),
|
|
16
|
+
tokenHash: v.string(),
|
|
17
|
+
createdAt: v.string(),
|
|
18
|
+
},
|
|
19
|
+
handler: async (ctx, args) => {
|
|
20
|
+
await requireRole(ctx, 'admin')
|
|
21
|
+
const id = await ctx.db.insert('cliTokens', args)
|
|
22
|
+
return ctx.db.get(id)
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
export const list = query({
|
|
27
|
+
args: {},
|
|
28
|
+
handler: async (ctx) => {
|
|
29
|
+
await requireRole(ctx, 'admin')
|
|
30
|
+
const rows = await ctx.db.query('cliTokens').collect()
|
|
31
|
+
return rows.sort((a, b) => (a.tokenId < b.tokenId ? -1 : a.tokenId > b.tokenId ? 1 : 0))
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
export const revoke = mutation({
|
|
36
|
+
args: { tokenId: v.string(), revokedAt: v.string() },
|
|
37
|
+
handler: async (ctx, { tokenId, revokedAt }) => {
|
|
38
|
+
await requireRole(ctx, 'admin')
|
|
39
|
+
const existing = await ctx.db
|
|
40
|
+
.query('cliTokens')
|
|
41
|
+
.withIndex('by_token', (q) => q.eq('tokenId', tokenId))
|
|
42
|
+
.first()
|
|
43
|
+
if (!existing) throw new Error(`not-found: cli-token "${tokenId}"`)
|
|
44
|
+
if (!existing.revokedAt) await ctx.db.patch(existing._id, { revokedAt })
|
|
45
|
+
return ctx.db.get(existing._id)
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Hash lookup for Bearer-token verification. Deliberately *unauthenticated*:
|
|
51
|
+
* the future registry-sync HTTP endpoint (EC-156) calls it with the hash of a
|
|
52
|
+
* presented token, and knowing a hash's preimage IS the credential. No token
|
|
53
|
+
* material beyond what the caller already holds is revealed.
|
|
54
|
+
*/
|
|
55
|
+
export const byHash = query({
|
|
56
|
+
args: { tokenHash: v.string() },
|
|
57
|
+
handler: async (ctx, { tokenHash }) => {
|
|
58
|
+
return ctx.db
|
|
59
|
+
.query('cliTokens')
|
|
60
|
+
.withIndex('by_hash', (q) => q.eq('tokenHash', tokenHash))
|
|
61
|
+
.first()
|
|
62
|
+
},
|
|
63
|
+
})
|
package/convex/cms.ts
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { v } from 'convex/values'
|
|
2
|
+
import { mutation, query } from './functions'
|
|
3
|
+
import { requireRole } from './guard'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CMS document persistence (EC-043). The backend stores **documents only**
|
|
7
|
+
* (AD-11, EC-183): CMS collection schemas are config-owned — they live in
|
|
8
|
+
* `elytra.config.ts`, read by the studio + host — so there is no `cmsSchemas`
|
|
9
|
+
* table and no schema read/write function here. Collection-membership
|
|
10
|
+
* validation lives in `@elytracms/cms-core` `validateDocument` (the studio runs it
|
|
11
|
+
* pre-dispatch); this layer is a pure document store.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export const upsertDocument = mutation({
|
|
15
|
+
args: {
|
|
16
|
+
collection: v.string(),
|
|
17
|
+
docId: v.string(),
|
|
18
|
+
document: v.any(),
|
|
19
|
+
createdAt: v.string(),
|
|
20
|
+
updatedAt: v.string(),
|
|
21
|
+
},
|
|
22
|
+
handler: async (ctx, args) => {
|
|
23
|
+
await requireRole(ctx, 'editor') // EC-150
|
|
24
|
+
const existing = await ctx.db
|
|
25
|
+
.query('cmsDocuments')
|
|
26
|
+
.withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
|
|
27
|
+
.first()
|
|
28
|
+
if (existing) {
|
|
29
|
+
// EC-153 parity: updates preserve `createdAt`, exactly like in-memory.
|
|
30
|
+
await ctx.db.patch(existing._id, { ...args, createdAt: existing.createdAt })
|
|
31
|
+
return ctx.db.get(existing._id)
|
|
32
|
+
}
|
|
33
|
+
const id = await ctx.db.insert('cmsDocuments', args)
|
|
34
|
+
return ctx.db.get(id)
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
export const getDocument = query({
|
|
39
|
+
args: { collection: v.string(), docId: v.string() },
|
|
40
|
+
handler: async (ctx, args) => {
|
|
41
|
+
await requireRole(ctx, 'viewer') // EC-150
|
|
42
|
+
return ctx.db
|
|
43
|
+
.query('cmsDocuments')
|
|
44
|
+
.withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
|
|
45
|
+
.first()
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
export const listDocuments = query({
|
|
50
|
+
args: { collection: v.optional(v.string()) },
|
|
51
|
+
handler: async (ctx, args) => {
|
|
52
|
+
await requireRole(ctx, 'viewer') // EC-150
|
|
53
|
+
if (args.collection) {
|
|
54
|
+
const collection = args.collection
|
|
55
|
+
return ctx.db
|
|
56
|
+
.query('cmsDocuments')
|
|
57
|
+
.withIndex('by_collection', (q) => q.eq('collection', collection))
|
|
58
|
+
.collect()
|
|
59
|
+
}
|
|
60
|
+
return ctx.db.query('cmsDocuments').collect()
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
export const deleteDocument = mutation({
|
|
65
|
+
args: { collection: v.string(), docId: v.string() },
|
|
66
|
+
handler: async (ctx, args) => {
|
|
67
|
+
await requireRole(ctx, 'editor') // EC-150
|
|
68
|
+
const existing = await ctx.db
|
|
69
|
+
.query('cmsDocuments')
|
|
70
|
+
.withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
|
|
71
|
+
.first()
|
|
72
|
+
if (existing) await ctx.db.delete(existing._id)
|
|
73
|
+
// Cascade the version history (EC-224) — no orphaned snapshots survive a delete.
|
|
74
|
+
const versions = await ctx.db
|
|
75
|
+
.query('documentVersions')
|
|
76
|
+
.withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
|
|
77
|
+
.collect()
|
|
78
|
+
for (const row of versions) await ctx.db.delete(row._id)
|
|
79
|
+
},
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Document version history (EC-224) — the document analogue of `graphs:*`.
|
|
84
|
+
* Append-only snapshots in `documentVersions`; the live one is pinned by
|
|
85
|
+
* `cmsDocuments.publishedVersion`. Version numbers are 1-based, monotonic per
|
|
86
|
+
* document, computed atomically inside the mutation.
|
|
87
|
+
*/
|
|
88
|
+
export const saveDocumentVersion = mutation({
|
|
89
|
+
args: {
|
|
90
|
+
collection: v.string(),
|
|
91
|
+
docId: v.string(),
|
|
92
|
+
snapshot: v.any(),
|
|
93
|
+
label: v.optional(v.string()),
|
|
94
|
+
createdAt: v.string(),
|
|
95
|
+
},
|
|
96
|
+
handler: async (ctx, args) => {
|
|
97
|
+
await requireRole(ctx, 'editor') // EC-150
|
|
98
|
+
const existing = await ctx.db
|
|
99
|
+
.query('documentVersions')
|
|
100
|
+
.withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
|
|
101
|
+
.collect()
|
|
102
|
+
const version = existing.reduce((max, r) => Math.max(max, r.version), 0) + 1
|
|
103
|
+
const id = await ctx.db.insert('documentVersions', { ...args, version })
|
|
104
|
+
return ctx.db.get(id)
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
export const listDocumentVersions = query({
|
|
109
|
+
args: { collection: v.string(), docId: v.string() },
|
|
110
|
+
handler: async (ctx, args) => {
|
|
111
|
+
await requireRole(ctx, 'viewer') // EC-150
|
|
112
|
+
const rows = await ctx.db
|
|
113
|
+
.query('documentVersions')
|
|
114
|
+
.withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
|
|
115
|
+
.collect()
|
|
116
|
+
// Newest first (parity with the in-memory `listDocumentVersions`).
|
|
117
|
+
return rows.sort((a, b) => b.version - a.version)
|
|
118
|
+
},
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
export const getDocumentVersion = query({
|
|
122
|
+
args: { collection: v.string(), docId: v.string(), version: v.number() },
|
|
123
|
+
handler: async (ctx, args) => {
|
|
124
|
+
await requireRole(ctx, 'viewer') // EC-150
|
|
125
|
+
const rows = await ctx.db
|
|
126
|
+
.query('documentVersions')
|
|
127
|
+
.withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
|
|
128
|
+
.collect()
|
|
129
|
+
return rows.find((r) => r.version === args.version) ?? null
|
|
130
|
+
},
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
/** Every version across all documents (EC-224) — backs the delivery feeders. */
|
|
134
|
+
export const listAllDocumentVersions = query({
|
|
135
|
+
args: {},
|
|
136
|
+
handler: async (ctx) => {
|
|
137
|
+
await requireRole(ctx, 'viewer') // EC-150
|
|
138
|
+
return ctx.db.query('documentVersions').collect()
|
|
139
|
+
},
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
export const publishDocumentVersion = mutation({
|
|
143
|
+
args: {
|
|
144
|
+
collection: v.string(),
|
|
145
|
+
docId: v.string(),
|
|
146
|
+
version: v.number(),
|
|
147
|
+
updatedAt: v.string(),
|
|
148
|
+
},
|
|
149
|
+
handler: async (ctx, args) => {
|
|
150
|
+
await requireRole(ctx, 'editor') // EC-150
|
|
151
|
+
const doc = await ctx.db
|
|
152
|
+
.query('cmsDocuments')
|
|
153
|
+
.withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
|
|
154
|
+
.first()
|
|
155
|
+
if (!doc) return null
|
|
156
|
+
await ctx.db.patch(doc._id, { publishedVersion: args.version, updatedAt: args.updatedAt })
|
|
157
|
+
return ctx.db.get(doc._id)
|
|
158
|
+
},
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
export const unpublishDocument = mutation({
|
|
162
|
+
args: { collection: v.string(), docId: v.string(), updatedAt: v.string() },
|
|
163
|
+
handler: async (ctx, args) => {
|
|
164
|
+
await requireRole(ctx, 'editor') // EC-150
|
|
165
|
+
const doc = await ctx.db
|
|
166
|
+
.query('cmsDocuments')
|
|
167
|
+
.withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
|
|
168
|
+
.first()
|
|
169
|
+
if (!doc) return null
|
|
170
|
+
// Convex patch removes a field set to `undefined` — clears the live pin.
|
|
171
|
+
await ctx.db.patch(doc._id, { publishedVersion: undefined, updatedAt: args.updatedAt })
|
|
172
|
+
return ctx.db.get(doc._id)
|
|
173
|
+
},
|
|
174
|
+
})
|