canopycms 0.0.68-int.98 → 0.1.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/CHANGELOG.md +2131 -0
- package/README.md +47 -63
- package/dist/ai/generate.d.ts +5 -0
- package/dist/ai/generate.js +244 -115
- package/dist/ai/index.d.ts +1 -1
- package/dist/ai/json-to-markdown.d.ts +21 -1
- package/dist/ai/json-to-markdown.js +120 -57
- package/dist/ai/references.d.ts +72 -0
- package/dist/ai/references.js +223 -0
- package/dist/ai/resolve-branch.js +9 -2
- package/dist/ai/to-plain-text.d.ts +17 -8
- package/dist/ai/to-plain-text.js +18 -15
- package/dist/ai/types.d.ts +84 -3
- package/dist/api/admin-branch-health.d.ts +24 -1
- package/dist/api/admin-branch-health.js +52 -20
- package/dist/api/admin.d.ts +23 -5
- package/dist/api/admin.js +36 -1
- package/dist/api/assets.js +88 -78
- package/dist/api/branch-create-window.d.ts +12 -0
- package/dist/api/branch-create-window.js +13 -0
- package/dist/api/branch-merge.d.ts +1 -1
- package/dist/api/branch-merge.js +1 -1
- package/dist/api/branch-review.d.ts +3 -3
- package/dist/api/branch-review.js +16 -7
- package/dist/api/branch-status.d.ts +16 -6
- package/dist/api/branch-status.js +57 -12
- package/dist/api/branch-withdraw.d.ts +2 -2
- package/dist/api/branch-withdraw.js +8 -3
- package/dist/api/branch.d.ts +25 -12
- package/dist/api/branch.js +164 -103
- package/dist/api/client.d.ts +78 -58
- package/dist/api/client.js +150 -117
- package/dist/api/comments.d.ts +12 -3
- package/dist/api/comments.js +118 -9
- package/dist/api/content.d.ts +9 -9
- package/dist/api/content.js +131 -22
- package/dist/api/entries-constants.d.ts +14 -3
- package/dist/api/entries-constants.js +14 -3
- package/dist/api/entries.d.ts +40 -2
- package/dist/api/entries.js +102 -6
- package/dist/api/github-sync.d.ts +19 -0
- package/dist/api/github-sync.js +50 -3
- package/dist/api/groups.d.ts +4 -4
- package/dist/api/groups.js +2 -1
- package/dist/api/guards.js +23 -3
- package/dist/api/index.d.ts +3 -1
- package/dist/api/index.js +1 -0
- package/dist/api/permissions.d.ts +21 -2
- package/dist/api/permissions.js +50 -3
- package/dist/api/request-deadline.d.ts +59 -0
- package/dist/api/request-deadline.js +73 -0
- package/dist/api/resolve-references.js +8 -7
- package/dist/api/route-builder.d.ts +14 -0
- package/dist/api/route-builder.js +14 -1
- package/dist/api/schema.d.ts +11 -9
- package/dist/api/schema.js +2 -0
- package/dist/api/settings-helpers.d.ts +5 -1
- package/dist/api/settings-helpers.js +10 -2
- package/dist/api/types.d.ts +18 -0
- package/dist/api/users-constants.d.ts +6 -0
- package/dist/api/users-constants.js +6 -0
- package/dist/assets/asset-url.d.ts +28 -16
- package/dist/assets/asset-url.js +51 -25
- package/dist/assets/finalize.js +3 -0
- package/dist/assets/index.d.ts +1 -1
- package/dist/assets/materialize.d.ts +153 -0
- package/dist/assets/materialize.js +402 -0
- package/dist/assets/store-local.d.ts +19 -5
- package/dist/assets/store-local.js +69 -10
- package/dist/assets/store-s3.d.ts +38 -7
- package/dist/assets/store-s3.js +128 -22
- package/dist/assets/transform-directives.d.ts +52 -13
- package/dist/assets/transform-directives.js +87 -27
- package/dist/assets/transform.d.ts +3 -3
- package/dist/assets/transform.js +13 -8
- package/dist/assets/types.d.ts +31 -4
- package/dist/auth/cache.d.ts +1 -1
- package/dist/auth/cache.js +1 -1
- package/dist/auth/caching-auth-plugin.d.ts +2 -0
- package/dist/auth/caching-auth-plugin.js +12 -2
- package/dist/auth/file-based-auth-cache.d.ts +8 -0
- package/dist/auth/file-based-auth-cache.js +18 -8
- package/dist/auth/person-name.d.ts +5 -0
- package/dist/auth/person-name.js +8 -0
- package/dist/auth/plugin.d.ts +10 -1
- package/dist/auth/types.d.ts +2 -0
- package/dist/auth/user-metadata-lookup.d.ts +21 -0
- package/dist/auth/user-metadata-lookup.js +116 -0
- package/dist/authorization/branch.d.ts +1 -1
- package/dist/authorization/branch.js +12 -13
- package/dist/authorization/groups/schema.d.ts +4 -4
- package/dist/authorization/helpers.d.ts +8 -0
- package/dist/authorization/helpers.js +8 -0
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.js +1 -1
- package/dist/authorization/protected-branch.d.ts +5 -4
- package/dist/authorization/protected-branch.js +7 -5
- package/dist/branch-health.d.ts +35 -8
- package/dist/branch-health.js +54 -18
- package/dist/branch-metadata-error.d.ts +27 -0
- package/dist/branch-metadata-error.js +23 -0
- package/dist/branch-metadata-file.d.ts +205 -24
- package/dist/branch-metadata-file.js +126 -25
- package/dist/branch-metadata.d.ts +45 -6
- package/dist/branch-metadata.js +142 -50
- package/dist/branch-provisioning.d.ts +167 -0
- package/dist/branch-provisioning.js +501 -0
- package/dist/branch-registry.d.ts +8 -0
- package/dist/branch-registry.js +61 -9
- package/dist/branch-schema-cache.d.ts +29 -12
- package/dist/branch-schema-cache.js +64 -21
- package/dist/branch-sparse.d.ts +23 -0
- package/dist/branch-sparse.js +118 -0
- package/dist/branch-workspace.d.ts +42 -3
- package/dist/branch-workspace.js +239 -100
- package/dist/build/asset-refs.d.ts +94 -0
- package/dist/build/asset-refs.js +267 -0
- package/dist/build/generate-ai-content.js +5 -0
- package/dist/build/inline-flight.d.ts +37 -0
- package/dist/build/inline-flight.js +142 -0
- package/dist/cli/asset-refs.d.ts +52 -0
- package/dist/cli/asset-refs.js +194 -0
- package/dist/cli/cli.d.ts +15 -1
- package/dist/cli/cli.js +8543 -3193
- package/dist/cli/configured-asset-store.d.ts +12 -0
- package/dist/cli/configured-asset-store.js +46 -0
- package/dist/cli/generate-ai-content.js +4244 -1072
- package/dist/cli/init.js +217 -126
- package/dist/cli/project-detect.d.ts +2 -0
- package/dist/cli/project-detect.js +2 -0
- package/dist/cli/template-files/Dockerfile.cms.template +13 -5
- package/dist/cli/template-files/cms-stack.ts.template +16 -13
- package/dist/client.d.ts +1 -2
- package/dist/client.js +1 -2
- package/dist/comment-store.d.ts +25 -0
- package/dist/comment-store.js +43 -8
- package/dist/config/flatten.js +2 -0
- package/dist/config/helpers.js +2 -2
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schemas/config.d.ts +12 -29
- package/dist/config/schemas/config.js +9 -12
- package/dist/config/schemas/field.d.ts +3 -0
- package/dist/config/schemas/field.js +58 -4
- package/dist/config/schemas/media.d.ts +4 -13
- package/dist/config/schemas/media.js +5 -8
- package/dist/config/schemas/url.d.ts +2 -20
- package/dist/config/schemas/url.js +2 -25
- package/dist/config/types.d.ts +116 -22
- package/dist/config/types.js +3 -9
- package/dist/config/validation.d.ts +25 -4
- package/dist/config/validation.js +116 -3
- package/dist/content-id-index.js +2 -2
- package/dist/content-index-generation.d.ts +1 -1
- package/dist/content-index-generation.js +1 -1
- package/dist/content-listing.d.ts +10 -1
- package/dist/content-listing.js +22 -5
- package/dist/content-reader.d.ts +9 -0
- package/dist/content-reader.js +16 -11
- package/dist/content-store.d.ts +75 -12
- package/dist/content-store.js +249 -86
- package/dist/content-tree.js +2 -2
- package/dist/context.js +5 -2
- package/dist/dangling-reference-log.d.ts +17 -0
- package/dist/dangling-reference-log.js +29 -0
- package/dist/dev-content-watcher.d.ts +1 -1
- package/dist/dev-content-watcher.js +1 -1
- package/dist/editor/BranchManager.d.ts +23 -7
- package/dist/editor/BranchManager.js +119 -54
- package/dist/editor/CanopyEditor.d.ts +1 -1
- package/dist/editor/CanopyEditor.js +1 -2
- package/dist/editor/CommentsPanel.d.ts +14 -0
- package/dist/editor/CommentsPanel.js +68 -43
- package/dist/editor/Editor.d.ts +11 -5
- package/dist/editor/Editor.js +891 -218
- package/dist/editor/EditorAuthGate.d.ts +7 -1
- package/dist/editor/EditorAuthGate.js +41 -9
- package/dist/editor/EntryNavigator.d.ts +22 -0
- package/dist/editor/EntryNavigator.js +353 -105
- package/dist/editor/FormHeader.d.ts +25 -0
- package/dist/editor/FormHeader.js +82 -0
- package/dist/editor/FormRenderer.d.ts +27 -3
- package/dist/editor/FormRenderer.js +171 -76
- package/dist/editor/PreviewFrame.d.ts +40 -0
- package/dist/editor/PreviewFrame.js +215 -0
- package/dist/editor/PreviewPane.d.ts +47 -0
- package/dist/editor/PreviewPane.js +147 -0
- package/dist/editor/PreviewToolbarTools.d.ts +22 -0
- package/dist/editor/PreviewToolbarTools.js +73 -0
- package/dist/editor/admin/SystemHealthPanel.d.ts +2 -1
- package/dist/editor/admin/SystemHealthPanel.js +163 -33
- package/dist/editor/admin/useSystemHealth.d.ts +18 -0
- package/dist/editor/admin/useSystemHealth.js +70 -1
- package/dist/editor/branch-status.d.ts +17 -0
- package/dist/editor/branch-status.js +29 -0
- package/dist/editor/canopy-path.d.ts +9 -6
- package/dist/editor/canopy-path.js +8 -11
- package/dist/editor/client-reference-resolver.d.ts +43 -16
- package/dist/editor/client-reference-resolver.js +155 -64
- package/dist/editor/comments/BranchComments.d.ts +1 -1
- package/dist/editor/comments/BranchComments.js +2 -2
- package/dist/editor/comments/CloseRefusedNotice.d.ts +4 -0
- package/dist/editor/comments/CloseRefusedNotice.js +7 -0
- package/dist/editor/comments/CommentThreadsPopover.d.ts +47 -0
- package/dist/editor/comments/CommentThreadsPopover.js +274 -0
- package/dist/editor/comments/CommentWriteAlert.d.ts +11 -0
- package/dist/editor/comments/CommentWriteAlert.js +13 -0
- package/dist/editor/comments/EntryComments.d.ts +10 -4
- package/dist/editor/comments/EntryComments.js +14 -17
- package/dist/editor/comments/FieldWrapper.d.ts +18 -4
- package/dist/editor/comments/FieldWrapper.js +62 -28
- package/dist/editor/comments/InlineCommentThread.d.ts +9 -2
- package/dist/editor/comments/InlineCommentThread.js +11 -47
- package/dist/editor/comments/ThreadCarousel.d.ts +1 -1
- package/dist/editor/comments/ThreadCarousel.js +18 -21
- package/dist/editor/comments/ThreadReplyControls.d.ts +28 -0
- package/dist/editor/comments/ThreadReplyControls.js +92 -0
- package/dist/editor/comments/field-comment-context.d.ts +14 -0
- package/dist/editor/comments/field-comment-context.js +14 -0
- package/dist/editor/comments/form-comments.d.ts +48 -0
- package/dist/editor/comments/form-comments.js +178 -0
- package/dist/editor/comments/item-anchor-copy.d.ts +6 -0
- package/dist/editor/comments/item-anchor-copy.js +6 -0
- package/dist/editor/comments/move-focus-if-unmoved.d.ts +6 -0
- package/dist/editor/comments/move-focus-if-unmoved.js +11 -0
- package/dist/editor/comments/popover-placement.d.ts +18 -0
- package/dist/editor/comments/popover-placement.js +58 -0
- package/dist/editor/comments/use-tracked-writes.d.ts +16 -0
- package/dist/editor/comments/use-tracked-writes.js +53 -0
- package/dist/editor/components/BranchAccessList.d.ts +15 -0
- package/dist/editor/components/BranchAccessList.js +52 -0
- package/dist/editor/components/BranchLockBanner.d.ts +22 -0
- package/dist/editor/components/BranchLockBanner.js +39 -0
- package/dist/editor/components/BranchPill.d.ts +32 -0
- package/dist/editor/components/BranchPill.js +33 -0
- package/dist/editor/components/BranchesDrawer.d.ts +11 -0
- package/dist/editor/components/BranchesDrawer.js +5 -0
- package/dist/editor/components/ConfirmDeleteModal.d.ts +6 -1
- package/dist/editor/components/ConfirmDeleteModal.js +3 -2
- package/dist/editor/components/DestructiveMenuItem.d.ts +7 -0
- package/dist/editor/components/DestructiveMenuItem.js +8 -0
- package/dist/editor/components/EditorCrashScreen.d.ts +17 -0
- package/dist/editor/components/EditorCrashScreen.js +22 -0
- package/dist/editor/components/EditorErrorBoundary.d.ts +38 -0
- package/dist/editor/components/EditorErrorBoundary.js +40 -0
- package/dist/editor/components/EditorHeader.d.ts +56 -106
- package/dist/editor/components/EditorHeader.js +130 -131
- package/dist/editor/components/EditorRail.d.ts +49 -0
- package/dist/editor/components/EditorRail.js +65 -0
- package/dist/editor/components/EntryBreadcrumb.d.ts +33 -0
- package/dist/editor/components/EntryBreadcrumb.js +56 -0
- package/dist/editor/components/EntryCreateModal.d.ts +12 -7
- package/dist/editor/components/EntryCreateModal.js +51 -57
- package/dist/editor/components/NoEditPermissionNotice.d.ts +6 -5
- package/dist/editor/components/NoEditPermissionNotice.js +5 -4
- package/dist/editor/components/QuickOpenPalette.d.ts +22 -0
- package/dist/editor/components/QuickOpenPalette.js +66 -0
- package/dist/editor/components/ReadOnlyDraftNotice.d.ts +11 -0
- package/dist/editor/components/ReadOnlyDraftNotice.js +12 -0
- package/dist/editor/components/ReasonedMenuItem.d.ts +15 -0
- package/dist/editor/components/ReasonedMenuItem.js +15 -0
- package/dist/editor/components/ReferencedByList.d.ts +11 -0
- package/dist/editor/components/ReferencedByList.js +28 -0
- package/dist/editor/components/RelativeTime.d.ts +10 -0
- package/dist/editor/components/RelativeTime.js +10 -0
- package/dist/editor/components/RenameEntryModal.d.ts +9 -1
- package/dist/editor/components/RenameEntryModal.js +19 -31
- package/dist/editor/components/RetryToastMessage.d.ts +9 -0
- package/dist/editor/components/RetryToastMessage.js +6 -0
- package/dist/editor/components/SaveAllResult.d.ts +25 -0
- package/dist/editor/components/SaveAllResult.js +86 -0
- package/dist/editor/components/SaveSplitButton.d.ts +30 -0
- package/dist/editor/components/SaveSplitButton.js +108 -0
- package/dist/editor/components/StagedChangesDrawer.d.ts +39 -0
- package/dist/editor/components/StagedChangesDrawer.js +92 -0
- package/dist/editor/components/UnavailableEntryNotice.d.ts +6 -0
- package/dist/editor/components/UnavailableEntryNotice.js +9 -0
- package/dist/editor/components/UnavailableTypeMessage.d.ts +6 -0
- package/dist/editor/components/UnavailableTypeMessage.js +9 -0
- package/dist/editor/components/UndoToastMessage.d.ts +18 -0
- package/dist/editor/components/UndoToastMessage.js +10 -0
- package/dist/editor/components/UserBadge.d.ts +2 -5
- package/dist/editor/components/UserBadge.js +62 -33
- package/dist/editor/components/ValidationSummary.d.ts +14 -0
- package/dist/editor/components/ValidationSummary.js +24 -0
- package/dist/editor/components/index.d.ts +2 -2
- package/dist/editor/components/index.js +2 -2
- package/dist/editor/context/ApiClientContext.d.ts +8 -2
- package/dist/editor/context/ApiClientContext.js +19 -8
- package/dist/editor/context/AssetContext.d.ts +13 -35
- package/dist/editor/context/AssetContext.js +12 -31
- package/dist/editor/context/EditorStateContext.d.ts +4 -4
- package/dist/editor/context/EditorStateContext.js +4 -4
- package/dist/editor/context/SWRProvider.d.ts +3 -3
- package/dist/editor/context/SiteMdxAllowContext.d.ts +4 -0
- package/dist/editor/context/SiteMdxAllowContext.js +7 -0
- package/dist/editor/context/index.d.ts +2 -1
- package/dist/editor/context/index.js +2 -1
- package/dist/editor/contrast.d.ts +19 -0
- package/dist/editor/contrast.js +41 -0
- package/dist/editor/copy.d.ts +18 -0
- package/dist/editor/copy.js +18 -0
- package/dist/editor/editor-config.js +16 -0
- package/dist/editor/editor-utils.d.ts +34 -8
- package/dist/editor/editor-utils.js +42 -20
- package/dist/editor/entry-search.d.ts +20 -0
- package/dist/editor/entry-search.js +34 -0
- package/dist/editor/field-breadcrumb.d.ts +12 -0
- package/dist/editor/field-breadcrumb.js +85 -0
- package/dist/editor/field-props.d.ts +86 -0
- package/dist/editor/field-props.js +27 -0
- package/dist/editor/field-target.d.ts +30 -0
- package/dist/editor/field-target.js +77 -0
- package/dist/editor/fields/BlockField.d.ts +12 -0
- package/dist/editor/fields/BlockField.js +89 -73
- package/dist/editor/fields/CodeField.d.ts +2 -0
- package/dist/editor/fields/CodeField.js +6 -2
- package/dist/editor/fields/DateTimeField.d.ts +4 -29
- package/dist/editor/fields/DateTimeField.js +79 -41
- package/dist/editor/fields/ExpandAllButton.d.ts +6 -0
- package/dist/editor/fields/ExpandAllButton.js +4 -0
- package/dist/editor/fields/FieldCrashFallback.d.ts +17 -0
- package/dist/editor/fields/FieldCrashFallback.js +30 -0
- package/dist/editor/fields/FieldLabel.d.ts +37 -0
- package/dist/editor/fields/FieldLabel.js +19 -0
- package/dist/editor/fields/ImageField.d.ts +4 -0
- package/dist/editor/fields/ImageField.js +29 -14
- package/dist/editor/fields/InlineGroupField.js +4 -3
- package/dist/editor/fields/ItemList.d.ts +42 -0
- package/dist/editor/fields/ItemList.js +130 -0
- package/dist/editor/fields/MarkdownField.d.ts +32 -0
- package/dist/editor/fields/MarkdownField.js +223 -46
- package/dist/editor/fields/MdxImageDialog.js +1 -1
- package/dist/editor/fields/NumberField.d.ts +2 -0
- package/dist/editor/fields/NumberField.js +8 -5
- package/dist/editor/fields/NumberListField.d.ts +2 -0
- package/dist/editor/fields/NumberListField.js +19 -16
- package/dist/editor/fields/ObjectField.d.ts +2 -7
- package/dist/editor/fields/ObjectField.js +15 -5
- package/dist/editor/fields/ObjectListField.d.ts +29 -0
- package/dist/editor/fields/ObjectListField.js +57 -0
- package/dist/editor/fields/ReferenceField.d.ts +2 -0
- package/dist/editor/fields/ReferenceField.js +34 -9
- package/dist/editor/fields/SelectField.d.ts +2 -0
- package/dist/editor/fields/SelectField.js +11 -2
- package/dist/editor/fields/StringListField.d.ts +4 -1
- package/dist/editor/fields/StringListField.js +22 -8
- package/dist/editor/fields/TextField.d.ts +2 -0
- package/dist/editor/fields/TextField.js +6 -2
- package/dist/editor/fields/ToggleField.d.ts +2 -0
- package/dist/editor/fields/ToggleField.js +8 -3
- package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +1 -1
- package/dist/editor/fields/entry-link/InsertEntryLink.js +1 -1
- package/dist/editor/fields/form-expansion.d.ts +9 -0
- package/dist/editor/fields/form-expansion.js +2 -0
- package/dist/editor/fields/item-expansion.d.ts +15 -0
- package/dist/editor/fields/item-expansion.js +60 -0
- package/dist/editor/fields/list-item-keys.d.ts +8 -0
- package/dist/editor/fields/list-item-keys.js +50 -0
- package/dist/editor/fields/list-item-title.d.ts +20 -0
- package/dist/editor/fields/list-item-title.js +85 -0
- package/dist/editor/fields/markdown-export-options.d.ts +2 -0
- package/dist/editor/fields/markdown-export-options.js +8 -0
- package/dist/editor/fields/markdown-fidelity-visitors.d.ts +11 -0
- package/dist/editor/fields/markdown-fidelity-visitors.js +160 -0
- package/dist/editor/fields/mdx-jsx-support.d.ts +5 -1
- package/dist/editor/fields/mdx-jsx-support.js +157 -69
- package/dist/editor/fields/rich-text-failures.d.ts +5 -0
- package/dist/editor/fields/rich-text-failures.js +26 -0
- package/dist/editor/fields/toolbar-wrap.d.ts +7 -0
- package/dist/editor/fields/toolbar-wrap.js +35 -0
- package/dist/editor/form-outline.d.ts +13 -0
- package/dist/editor/form-outline.js +70 -0
- package/dist/editor/group-manager/GroupCard.d.ts +4 -1
- package/dist/editor/group-manager/GroupCard.js +12 -3
- package/dist/editor/group-manager/GroupForm.js +1 -1
- package/dist/editor/group-manager/InternalGroupsTab.d.ts +2 -1
- package/dist/editor/group-manager/InternalGroupsTab.js +4 -4
- package/dist/editor/group-manager/MemberList.d.ts +2 -1
- package/dist/editor/group-manager/MemberList.js +15 -4
- package/dist/editor/group-manager/hooks/useGroupState.d.ts +5 -0
- package/dist/editor/group-manager/hooks/useGroupState.js +30 -7
- package/dist/editor/group-manager/index.js +34 -5
- package/dist/editor/group-manager/types.d.ts +5 -2
- package/dist/editor/hooks/create-branch-request.d.ts +20 -0
- package/dist/editor/hooks/create-branch-request.js +54 -0
- package/dist/editor/hooks/save-all.d.ts +68 -0
- package/dist/editor/hooks/save-all.js +61 -0
- package/dist/editor/hooks/useBranchActions.d.ts +11 -1
- package/dist/editor/hooks/useBranchActions.js +42 -19
- package/dist/editor/hooks/useBranchManager.d.ts +21 -0
- package/dist/editor/hooks/useBranchManager.js +321 -125
- package/dist/editor/hooks/useBranchesData.d.ts +8 -4
- package/dist/editor/hooks/useBranchesData.js +9 -5
- package/dist/editor/hooks/useCommentSystem.d.ts +14 -2
- package/dist/editor/hooks/useCommentSystem.js +79 -55
- package/dist/editor/hooks/useCommentsData.d.ts +11 -7
- package/dist/editor/hooks/useCommentsData.js +20 -19
- package/dist/editor/hooks/useDraftManager.d.ts +77 -3
- package/dist/editor/hooks/useDraftManager.js +887 -94
- package/dist/editor/hooks/useEditorLayout.d.ts +53 -7
- package/dist/editor/hooks/useEditorLayout.js +98 -20
- package/dist/editor/hooks/useEntriesData.d.ts +2 -1
- package/dist/editor/hooks/useEntriesData.js +18 -4
- package/dist/editor/hooks/useEntryManager.d.ts +41 -2
- package/dist/editor/hooks/useEntryManager.js +227 -41
- package/dist/editor/hooks/useGroupManager.js +13 -16
- package/dist/editor/hooks/usePermissionManager.js +14 -6
- package/dist/editor/hooks/usePreviewMarks.d.ts +21 -0
- package/dist/editor/hooks/usePreviewMarks.js +33 -0
- package/dist/editor/hooks/useReferenceResolution.d.ts +10 -3
- package/dist/editor/hooks/useReferenceResolution.js +34 -177
- package/dist/editor/hooks/useSchemaManager.d.ts +25 -6
- package/dist/editor/hooks/useSchemaManager.js +97 -39
- package/dist/editor/hooks/useUserMetadata.d.ts +14 -4
- package/dist/editor/hooks/useUserMetadata.js +76 -47
- package/dist/editor/hooks/user-metadata-batcher.d.ts +8 -0
- package/dist/editor/hooks/user-metadata-batcher.js +33 -0
- package/dist/editor/media/AssetCard.d.ts +6 -7
- package/dist/editor/media/AssetCard.js +24 -31
- package/dist/editor/media/AssetListRow.d.ts +16 -0
- package/dist/editor/media/AssetListRow.js +41 -0
- package/dist/editor/media/CropStep.js +6 -1
- package/dist/editor/media/MediaLibrary.d.ts +4 -3
- package/dist/editor/media/MediaLibrary.js +11 -4
- package/dist/editor/media/MediaLibraryBody.d.ts +3 -3
- package/dist/editor/media/MediaLibraryBody.js +195 -80
- package/dist/editor/media/MediaLibrarySkeleton.d.ts +6 -0
- package/dist/editor/media/MediaLibrarySkeleton.js +14 -0
- package/dist/editor/media/crop-math.d.ts +3 -4
- package/dist/editor/media/crop-math.js +11 -22
- package/dist/editor/media/editor-image-src.d.ts +8 -0
- package/dist/editor/media/editor-image-src.js +10 -0
- package/dist/editor/media/format-bytes.d.ts +2 -0
- package/dist/editor/media/format-bytes.js +23 -0
- package/dist/editor/media/media-library-prefs.d.ts +23 -0
- package/dist/editor/media/media-library-prefs.js +49 -0
- package/dist/editor/media/media-library-view.d.ts +34 -0
- package/dist/editor/media/media-library-view.js +40 -0
- package/dist/editor/media/useAssetLibrary.d.ts +30 -0
- package/dist/editor/media/useAssetLibrary.js +126 -0
- package/dist/editor/media/useStableAssetOrder.d.ts +11 -0
- package/dist/editor/media/useStableAssetOrder.js +37 -0
- package/dist/editor/media/useThumbnailFailure.d.ts +6 -0
- package/dist/editor/media/useThumbnailFailure.js +16 -0
- package/dist/editor/permission-manager/GroupSelector.js +2 -2
- package/dist/editor/permission-manager/PermissionEditor.d.ts +1 -1
- package/dist/editor/permission-manager/PermissionEditor.js +15 -4
- package/dist/editor/permission-manager/PermissionLevelBadge.js +1 -1
- package/dist/editor/permission-manager/PermissionTree.d.ts +1 -1
- package/dist/editor/permission-manager/UserSelector.d.ts +1 -1
- package/dist/editor/permission-manager/UserSelector.js +3 -3
- package/dist/editor/permission-manager/index.js +12 -3
- package/dist/editor/permission-manager/types.d.ts +5 -2
- package/dist/editor/platform.d.ts +3 -0
- package/dist/editor/platform.js +9 -0
- package/dist/editor/preview-asset-base.d.ts +9 -0
- package/dist/editor/preview-asset-base.js +17 -0
- package/dist/editor/preview-bridge.d.ts +51 -27
- package/dist/editor/preview-bridge.js +103 -144
- package/dist/editor/preview-marks.d.ts +15 -0
- package/dist/editor/preview-marks.js +74 -0
- package/dist/editor/preview-path.d.ts +12 -0
- package/dist/editor/preview-path.js +45 -1
- package/dist/editor/preview-scale.d.ts +27 -0
- package/dist/editor/preview-scale.js +34 -0
- package/dist/editor/raw-asset-base.d.ts +5 -0
- package/dist/editor/raw-asset-base.js +14 -0
- package/dist/editor/relative-time.d.ts +4 -4
- package/dist/editor/relative-time.js +16 -8
- package/dist/editor/schema-editor/CollectionEditor.d.ts +20 -3
- package/dist/editor/schema-editor/CollectionEditor.js +361 -62
- package/dist/editor/schema-editor/EntryTypeEditor.d.ts +5 -1
- package/dist/editor/schema-editor/EntryTypeEditor.js +11 -6
- package/dist/editor/schema-editor/collection-draft.d.ts +22 -0
- package/dist/editor/schema-editor/collection-draft.js +40 -0
- package/dist/editor/schema-editor/index.d.ts +1 -1
- package/dist/editor/schema-label.d.ts +10 -0
- package/dist/editor/schema-label.js +17 -0
- package/dist/editor/settings-conflict.d.ts +5 -0
- package/dist/editor/settings-conflict.js +8 -0
- package/dist/editor/shell/ActivityRail.d.ts +37 -0
- package/dist/editor/shell/ActivityRail.js +91 -0
- package/dist/editor/shell/EditorShell.d.ts +17 -0
- package/dist/editor/shell/EditorShell.js +31 -0
- package/dist/editor/shell/PaneLayout.d.ts +28 -0
- package/dist/editor/shell/PaneLayout.js +116 -0
- package/dist/editor/shell/SidePanelHost.d.ts +35 -0
- package/dist/editor/shell/SidePanelHost.js +184 -0
- package/dist/editor/shell/TopBar.d.ts +12 -0
- package/dist/editor/shell/TopBar.js +14 -0
- package/dist/editor/shell/host-chrome.d.ts +16 -0
- package/dist/editor/shell/host-chrome.js +69 -0
- package/dist/editor/slug.d.ts +16 -0
- package/dist/editor/slug.js +43 -0
- package/dist/editor/theme.d.ts +2 -1
- package/dist/editor/theme.js +314 -13
- package/dist/editor/unanswered.d.ts +17 -0
- package/dist/editor/unanswered.js +26 -0
- package/dist/editor/unavailable-entry-type.d.ts +20 -0
- package/dist/editor/unavailable-entry-type.js +28 -0
- package/dist/editor/undo-removal.d.ts +57 -0
- package/dist/editor/undo-removal.js +163 -0
- package/dist/editor/user-display.d.ts +4 -0
- package/dist/editor/user-display.js +5 -0
- package/dist/editor/utils/confirm-modal.d.ts +8 -0
- package/dist/editor/utils/confirm-modal.js +12 -0
- package/dist/editor/utils/editor-errors.d.ts +19 -0
- package/dist/editor/utils/editor-errors.js +32 -0
- package/dist/editor/utils/focus-return.d.ts +56 -0
- package/dist/editor/utils/focus-return.js +106 -0
- package/dist/entry-link-resolver.d.ts +11 -1
- package/dist/entry-link-resolver.js +65 -5
- package/dist/entry-schema-registry.d.ts +3 -3
- package/dist/entry-schema-registry.js +7 -4
- package/dist/entry-schema.d.ts +49 -3
- package/dist/entry-schema.js +18 -0
- package/dist/git-manager.d.ts +172 -10
- package/dist/git-manager.js +449 -107
- package/dist/github-service.d.ts +39 -2
- package/dist/github-service.js +101 -7
- package/dist/http/handler.js +74 -9
- package/dist/http/types.d.ts +2 -0
- package/dist/http/worker-not-ready.d.ts +9 -4
- package/dist/http/worker-not-ready.js +59 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/item-keys.d.ts +46 -0
- package/dist/item-keys.js +235 -0
- package/dist/operating-mode/editor-mode-check.d.ts +15 -0
- package/dist/operating-mode/editor-mode-check.js +24 -0
- package/dist/operating-mode/mode-env.d.ts +13 -14
- package/dist/operating-mode/mode-env.js +13 -14
- package/dist/operating-mode/types.d.ts +2 -2
- package/dist/paths/branch.d.ts +0 -1
- package/dist/paths/branch.js +1 -8
- package/dist/paths/index.d.ts +1 -1
- package/dist/paths/index.js +1 -1
- package/dist/paths/validation.js +0 -2
- package/dist/preview.d.ts +8 -0
- package/dist/preview.js +7 -0
- package/dist/reference-resolver.js +1 -0
- package/dist/resolve-canopy-user.d.ts +1 -1
- package/dist/resolve-canopy-user.js +1 -1
- package/dist/schema/meta-loader.d.ts +18 -8
- package/dist/schema/meta-loader.js +42 -9
- package/dist/schema/registry-fingerprint.d.ts +14 -0
- package/dist/schema/registry-fingerprint.js +63 -0
- package/dist/schema/resolver.d.ts +7 -4
- package/dist/schema/resolver.js +7 -6
- package/dist/schema/schema-store.d.ts +7 -10
- package/dist/schema/schema-store.js +13 -11
- package/dist/schema/schema-unavailable-error.d.ts +11 -0
- package/dist/schema/schema-unavailable-error.js +15 -0
- package/dist/schema/types.d.ts +22 -0
- package/dist/schema-registry-record.d.ts +35 -0
- package/dist/schema-registry-record.js +134 -0
- package/dist/server.d.ts +79 -9
- package/dist/server.js +62 -8
- package/dist/services.d.ts +33 -5
- package/dist/services.js +155 -37
- package/dist/settings-workspace.d.ts +23 -3
- package/dist/settings-workspace.js +159 -45
- package/dist/stamp-on-publish.d.ts +36 -0
- package/dist/stamp-on-publish.js +71 -0
- package/dist/static/index.d.ts +58 -5
- package/dist/static/index.js +133 -3
- package/dist/static/seo.d.ts +5 -5
- package/dist/static/seo.js +5 -5
- package/dist/submission-attribution.d.ts +8 -0
- package/dist/submission-attribution.js +22 -0
- package/dist/system-users.d.ts +12 -0
- package/dist/system-users.js +12 -0
- package/dist/task-queue/cms-task-queue.d.ts +1 -1
- package/dist/task-queue/cms-task-queue.js +1 -1
- package/dist/task-queue/index.d.ts +1 -1
- package/dist/task-queue/index.js +1 -1
- package/dist/task-queue/task-queue.d.ts +6 -0
- package/dist/task-queue/task-queue.js +29 -0
- package/dist/task-queue/worker-status.d.ts +35 -9
- package/dist/task-queue/worker-status.js +84 -17
- package/dist/types.d.ts +90 -9
- package/dist/url-collision.js +3 -3
- package/dist/url-exclusivity-fixtures.d.ts +8 -1
- package/dist/url-exclusivity-fixtures.js +11 -1
- package/dist/user.js +2 -1
- package/dist/utils/atomic-write.js +2 -1
- package/dist/utils/base-branch.d.ts +13 -0
- package/dist/utils/base-branch.js +23 -0
- package/dist/utils/content-serialize.d.ts +15 -7
- package/dist/utils/content-serialize.js +353 -51
- package/dist/utils/content-write-lock.d.ts +6 -1
- package/dist/utils/content-write-lock.js +21 -6
- package/dist/utils/debug.d.ts +1 -1
- package/dist/utils/debug.js +5 -3
- package/dist/utils/error.js +13 -2
- package/dist/utils/escape-text.d.ts +7 -0
- package/dist/utils/escape-text.js +27 -0
- package/dist/utils/fs.d.ts +12 -4
- package/dist/utils/fs.js +18 -5
- package/dist/utils/git.d.ts +21 -1
- package/dist/utils/git.js +63 -8
- package/dist/utils/json-source-splice.d.ts +14 -0
- package/dist/utils/json-source-splice.js +120 -0
- package/dist/utils/markdown-body-splice.d.ts +39 -0
- package/dist/utils/markdown-body-splice.js +421 -0
- package/dist/utils/occ-json-write.js +18 -12
- package/dist/utils/provision-log.d.ts +25 -0
- package/dist/utils/provision-log.js +49 -0
- package/dist/utils/provisioning-lock.d.ts +32 -1
- package/dist/utils/provisioning-lock.js +78 -32
- package/dist/utils/sanitize-href.d.ts +9 -23
- package/dist/utils/sanitize-href.js +14 -28
- package/dist/utils/title-field.d.ts +10 -0
- package/dist/utils/title-field.js +47 -0
- package/dist/utils/yaml-source-splice.d.ts +58 -0
- package/dist/utils/yaml-source-splice.js +515 -0
- package/dist/validation/block-structural-keys.d.ts +1 -1
- package/dist/validation/block-structural-keys.js +1 -1
- package/dist/validation/deletion-checker.d.ts +21 -29
- package/dist/validation/deletion-checker.js +41 -117
- package/dist/validation/entry-validator.d.ts +6 -10
- package/dist/validation/entry-validator.js +19 -26
- package/dist/validation/field-traversal.d.ts +22 -0
- package/dist/validation/field-traversal.js +39 -8
- package/dist/validation/markdown-safety.d.ts +68 -0
- package/dist/validation/markdown-safety.js +596 -0
- package/dist/validation/mdx-allowlist.d.ts +55 -0
- package/dist/validation/mdx-allowlist.js +183 -0
- package/dist/validation/reference-validator.d.ts +2 -0
- package/dist/validation/reference-validator.js +3 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/branch-policy.d.ts +124 -0
- package/dist/worker/branch-policy.js +243 -0
- package/dist/worker/bundle-header.d.ts +117 -0
- package/dist/worker/bundle-header.js +253 -0
- package/dist/worker/cms-worker.d.ts +236 -142
- package/dist/worker/cms-worker.js +772 -285
- package/dist/worker/gateway-egress.d.ts +43 -0
- package/dist/worker/gateway-egress.js +209 -0
- package/dist/worker/gateway-instance.d.ts +42 -0
- package/dist/worker/gateway-instance.js +129 -0
- package/dist/worker/git-process.d.ts +81 -0
- package/dist/worker/git-process.js +234 -0
- package/dist/worker/git-sync.d.ts +34 -17
- package/dist/worker/git-sync.js +394 -131
- package/dist/worker/github-auth.d.ts +9 -9
- package/dist/worker/github-auth.js +13 -15
- package/dist/worker/github-gateway-http.d.ts +62 -0
- package/dist/worker/github-gateway-http.js +977 -0
- package/dist/worker/github-gateway-wire.d.ts +590 -0
- package/dist/worker/github-gateway-wire.js +488 -0
- package/dist/worker/github-gateway.d.ts +238 -0
- package/dist/worker/github-gateway.js +726 -0
- package/dist/worker/github-mirror-upkeep.d.ts +75 -0
- package/dist/worker/github-mirror-upkeep.js +266 -0
- package/dist/worker/github-mirror.d.ts +364 -0
- package/dist/worker/github-mirror.js +1030 -0
- package/dist/worker/github-transfer.d.ts +56 -0
- package/dist/worker/github-transfer.js +444 -0
- package/dist/worker/history-rewrite.d.ts +4 -5
- package/dist/worker/history-rewrite.js +12 -17
- package/dist/worker/provisioned-workspace.d.ts +5 -5
- package/dist/worker/provisioned-workspace.js +5 -5
- package/dist/worker/rebase.d.ts +1 -1
- package/dist/worker/rebase.js +58 -54
- package/dist/worker/remote-git-maintenance.d.ts +3 -0
- package/dist/worker/remote-git-maintenance.js +12 -0
- package/dist/worker/schema-gate.d.ts +49 -0
- package/dist/worker/schema-gate.js +226 -0
- package/dist/worker/self-checks.d.ts +107 -0
- package/dist/worker/self-checks.js +358 -0
- package/dist/worker/shared-repo-git.d.ts +96 -0
- package/dist/worker/shared-repo-git.js +459 -0
- package/dist/worker/sparse-cone.d.ts +20 -0
- package/dist/worker/sparse-cone.js +136 -0
- package/dist/worker/stale-mirror.d.ts +82 -0
- package/dist/worker/stale-mirror.js +130 -0
- package/dist/worker/task-runner.d.ts +5 -3
- package/dist/worker/task-runner.js +287 -186
- package/dist/worker/worker-context.d.ts +36 -37
- package/package.json +35 -7
- package/dist/editor/EditorPanes.d.ts +0 -10
- package/dist/editor/EditorPanes.js +0 -98
- package/dist/editor/components/EditorFooter.d.ts +0 -11
- package/dist/editor/components/EditorFooter.js +0 -9
- package/dist/editor/components/EditorSidebar.d.ts +0 -67
- package/dist/editor/components/EditorSidebar.js +0 -22
package/dist/server.js
CHANGED
|
@@ -96,6 +96,11 @@ export { collectRoutableEntries } from './static/index.js';
|
|
|
96
96
|
* hand-rolling the same scan over `listEntries`.
|
|
97
97
|
*/
|
|
98
98
|
export { findDuplicateUrlPaths } from './static/index.js';
|
|
99
|
+
/**
|
|
100
|
+
* Find every reference naming no entry — the check a production build runs and fails on unless
|
|
101
|
+
* `danglingReferences: 'warn'`. Pass an unscoped `listEntries()`.
|
|
102
|
+
*/
|
|
103
|
+
export { findDanglingReferences } from './static/index.js';
|
|
99
104
|
/**
|
|
100
105
|
* SEO field extraction and URL shaping, framework-agnostic. `isNoindexEntry` is the single
|
|
101
106
|
* predicate behind both `robots: noindex` and sitemap exclusion.
|
|
@@ -115,28 +120,77 @@ export { createAssetStore } from './assets/factory.js';
|
|
|
115
120
|
/**
|
|
116
121
|
* The five S3/local bucket-prefix strings (`asset-originals/`, `asset-staging/`, `asset-meta/`,
|
|
117
122
|
* `assets/`, `assets/t/`). Exported so server-only consumers outside this package — notably the
|
|
118
|
-
*
|
|
123
|
+
* lazy transform Lambda (`packages/canopycms-cdk/lambda/asset-transform`) — build and parse
|
|
119
124
|
* asset keys through the same constants `S3AssetStore` uses rather than duplicating the strings.
|
|
120
125
|
*/
|
|
121
126
|
export { ASSET_PREFIXES } from './assets/keys.js';
|
|
122
127
|
/**
|
|
123
128
|
* Parse the three path segments after `assets/t/` (`{directives}/{hash32}/{slug}.{ext}`) into a
|
|
124
|
-
* validated `TransformDirectives` set, or a structured parse error
|
|
125
|
-
*
|
|
126
|
-
* URL grammar is defined in exactly one place.
|
|
129
|
+
* validated `TransformDirectives` set, or a structured parse error, so the URL grammar is
|
|
130
|
+
* defined in exactly one place.
|
|
127
131
|
*/
|
|
128
132
|
export { parseTransformPath } from './assets/transform-directives.js';
|
|
129
133
|
/**
|
|
130
134
|
* Canonical string form of a `TransformDirectives` set — the cache key every transform output is
|
|
131
135
|
* stored under (`assets/t/{formatDirectives(...)}/{hash32}/{slug}.{ext}`). Equivalent directive
|
|
132
|
-
* sets (different key order or float formatting) always format to the same string.
|
|
133
|
-
* prod transform Lambda so its writes agree with the dev-mode emulation and `assetUrl()`.
|
|
136
|
+
* sets (different key order or float formatting) always format to the same string.
|
|
134
137
|
*/
|
|
135
138
|
export { formatDirectives } from './assets/transform-directives.js';
|
|
139
|
+
/**
|
|
140
|
+
* Parse `assets/t/` path segments and resolve them to the canonical spelling their output is
|
|
141
|
+
* stored under, with directives re-parsed from that spelling. The lazy transform Lambda 301s a
|
|
142
|
+
* non-canonical request to it; the authenticated raw route serves the canonical bytes.
|
|
143
|
+
*/
|
|
144
|
+
export { canonicalizeTransformPath } from './assets/transform-directives.js';
|
|
136
145
|
/**
|
|
137
146
|
* Apply a parsed `TransformDirectives` set to source image bytes with sharp:
|
|
138
147
|
* resize/format/quality/crop, EXIF stripped on every re-encode, identity included. Server-only
|
|
139
|
-
* (sharp);
|
|
140
|
-
* Lambda.
|
|
148
|
+
* (sharp); `storeTransform` below wraps it for every caller that stores the output.
|
|
141
149
|
*/
|
|
142
150
|
export { applyTransform } from './assets/transform.js';
|
|
151
|
+
/**
|
|
152
|
+
* Compute the transform a canonical `assets/t/` path names and store it under that key: meta
|
|
153
|
+
* lookup, raster-only, slug and ext checks, then `applyTransform`. Shared by the authenticated raw
|
|
154
|
+
* route, `materialize-assets` and the lazy transform Lambda. A 404's `error` names hashes and
|
|
155
|
+
* slugs, so a caller answering a browser replaces it.
|
|
156
|
+
*/
|
|
157
|
+
export { storeTransform } from './assets/materialize.js';
|
|
158
|
+
/** The `Cache-Control` every stored transform output carries: content-addressed, so immutable. */
|
|
159
|
+
export { TRANSFORM_CACHE_CONTROL } from './assets/materialize.js';
|
|
160
|
+
/** The object tag the lazy transform Lambda's outputs carry, which its `assets/t/` expiry filters on. */
|
|
161
|
+
export { LAZY_TRANSFORM_TAG } from './assets/materialize.js';
|
|
162
|
+
/**
|
|
163
|
+
* Make every `assets/t/` key a build references exist in `store` (transforming only the missing
|
|
164
|
+
* ones from the stored originals) and check every referenced svg/pdf key exists. Under an
|
|
165
|
+
* `outputPrefix`, keys are written beneath it, and those production already stores are copied. A
|
|
166
|
+
* release job that bundles its own tool calls this with a store from `createAssetStore` and gates
|
|
167
|
+
* on the returned report; no site config is involved. Needs sharp only when something is missing.
|
|
168
|
+
*/
|
|
169
|
+
export { materializeAssets } from './assets/materialize.js';
|
|
170
|
+
/**
|
|
171
|
+
* The live preview's asset prefix on the server: the signed-in raw route under a `basePath`, the
|
|
172
|
+
* same-origin check every preview prefix passes, and the hook registering the request-scoped getter
|
|
173
|
+
* `assetUrl` reads.
|
|
174
|
+
* @internal `canopycms-next`'s preview page is their consumer.
|
|
175
|
+
*/
|
|
176
|
+
export { authenticatedAssetBase, readAssetBase } from './editor/raw-asset-base.js';
|
|
177
|
+
/** @internal */
|
|
178
|
+
export { setServerPreviewAssetBaseGetter } from './editor/preview-asset-base.js';
|
|
179
|
+
/** Thrown by `materializeAssets` when sharp cannot load and keys are missing, so none can be produced. */
|
|
180
|
+
export { SharpUnavailableError } from './assets/materialize.js';
|
|
181
|
+
/**
|
|
182
|
+
* Thrown by `materializeAssets` before any store request when `outputPrefix` is not a relative,
|
|
183
|
+
* `/`-terminated run of `[A-Za-z0-9._-]` segments outside every canopy prefix.
|
|
184
|
+
*/
|
|
185
|
+
export { InvalidOutputPrefixError } from './assets/materialize.js';
|
|
186
|
+
/** The `schemaVersion` carried by every `MaterializeReport`. */
|
|
187
|
+
export { MATERIALIZE_REPORT_SCHEMA_VERSION } from './assets/materialize.js';
|
|
188
|
+
/**
|
|
189
|
+
* Scan a static build's output for `/assets/…` URLs and write `canopy-asset-refs.json` into it.
|
|
190
|
+
* Throws `AssetRefsError` for a URL no stored object can answer (non-canonical or malformed).
|
|
191
|
+
*/
|
|
192
|
+
export { collectAssetRefs } from './build/asset-refs.js';
|
|
193
|
+
/** Read and validate a `canopy-asset-refs.json`; throws when it is unreadable or malformed. */
|
|
194
|
+
export { readAssetRefsFile } from './build/asset-refs.js';
|
|
195
|
+
/** Thrown by `collectAssetRefs`; `problems` lists each offending file and URL. */
|
|
196
|
+
export { AssetRefsError } from './build/asset-refs.js';
|
package/dist/services.d.ts
CHANGED
|
@@ -17,22 +17,35 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { CanopyConfig } from './config/index.js';
|
|
19
19
|
import type { EntrySchemaRegistry } from './schema/types.js';
|
|
20
|
-
import type { BranchContext } from './types.js';
|
|
20
|
+
import type { BranchContext, BranchPaths } from './types.js';
|
|
21
21
|
import type { CanopyUser } from './user.js';
|
|
22
22
|
import { createCheckBranchAccess, createCheckContentAccess, type ContentAccessChecker } from './authorization/index.js';
|
|
23
23
|
import { GitManager } from './git-manager.js';
|
|
24
24
|
import { BranchRegistry } from './branch-registry.js';
|
|
25
25
|
import { type GitHubService } from './github-service.js';
|
|
26
26
|
import { BranchSchemaCache } from './branch-schema-cache.js';
|
|
27
|
-
import { type SubmissionEditor } from './submission-attribution.js';
|
|
27
|
+
import { type EditorLookup, type SubmissionEditor } from './submission-attribution.js';
|
|
28
|
+
import { type StampedEntry } from './stamp-on-publish.js';
|
|
28
29
|
/**
|
|
29
30
|
* Bootstrap admin IDs from the environment. These users are treated as Admins
|
|
30
31
|
* whatever their group membership.
|
|
31
32
|
*/
|
|
32
33
|
export declare const getBootstrapAdminIds: () => Set<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Submit found nothing to send: the branch's saved content, committed or not, matches its base
|
|
36
|
+
* as of the fork point. Raised before anything is pushed and after undoing any commit the
|
|
37
|
+
* submit made, so the branch's commits and saved edits are as they were.
|
|
38
|
+
*/
|
|
39
|
+
export declare class NothingToSubmitError extends Error {
|
|
40
|
+
constructor(branch: string, base: string);
|
|
41
|
+
}
|
|
33
42
|
export interface SubmitBranchResult {
|
|
34
43
|
/** Repo-relative paths the branch changes, excluding canopycms runtime metadata. */
|
|
35
44
|
changedPaths: string[];
|
|
45
|
+
/** Every recorded editor of the branch, for the PR body. */
|
|
46
|
+
editors: SubmissionEditor[];
|
|
47
|
+
/** The entries this submit stamped (stamp-on-publish.ts), for the editor's open forms. */
|
|
48
|
+
stamped: StampedEntry[];
|
|
36
49
|
}
|
|
37
50
|
export interface CanopyServices {
|
|
38
51
|
config: CanopyConfig;
|
|
@@ -42,6 +55,14 @@ export interface CanopyServices {
|
|
|
42
55
|
* content serving since the editor is pinned to its own branch via URL params.
|
|
43
56
|
*/
|
|
44
57
|
refreshActiveBranch: () => Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve a prod base branch that was still pending at creation because the worker had not yet
|
|
60
|
+
* created the remote it is read from; a no-op once resolved. Rejects with RemoteNotReadyError
|
|
61
|
+
* (a 503) until the remote exists. The HTTP handler (http/handler.ts) and
|
|
62
|
+
* createCanopyContext's getContext (context.ts) await it before reading
|
|
63
|
+
* `config.defaultBaseBranch`.
|
|
64
|
+
*/
|
|
65
|
+
resolvePendingBaseBranch: () => Promise<void>;
|
|
45
66
|
/** Entry schema registry mapping entry schema names to field definitions */
|
|
46
67
|
entrySchemaRegistry: EntrySchemaRegistry;
|
|
47
68
|
/** Per-branch schema cache */
|
|
@@ -73,14 +94,19 @@ export interface CanopyServices {
|
|
|
73
94
|
message: string;
|
|
74
95
|
}) => Promise<void>;
|
|
75
96
|
/**
|
|
76
|
-
* Submit branch:
|
|
77
|
-
*
|
|
97
|
+
* Submit branch: fill new entries' empty `stampOnPublish` fields
|
|
98
|
+
* (stamp-on-publish.ts), commit all changes (with the submitter's trailers)
|
|
99
|
+
* and push to remote. Resolves with every path the branch changes against its base,
|
|
100
|
+
* and with `stamped`, the entries this submit stamped.
|
|
78
101
|
* Holds the branch's content-write lock; rejects with
|
|
79
|
-
* `ContentWriteLockBusyError` when busy
|
|
102
|
+
* `ContentWriteLockBusyError` when busy, and with `NothingToSubmitError`
|
|
103
|
+
* before pushing when the branch changes nothing.
|
|
80
104
|
*/
|
|
81
105
|
submitBranch: (options: {
|
|
82
106
|
context: BranchContext;
|
|
83
107
|
submitter?: SubmissionEditor;
|
|
108
|
+
/** Names the recorded editors; without it they are credited by id. */
|
|
109
|
+
lookupEditor?: EditorLookup;
|
|
84
110
|
message?: string;
|
|
85
111
|
}) => Promise<SubmitBranchResult>;
|
|
86
112
|
/** Commit to the settings branch (for permissions/groups) and push it; never opens a PR */
|
|
@@ -96,6 +122,8 @@ export interface CanopyServices {
|
|
|
96
122
|
}>;
|
|
97
123
|
/** Get the root path for settings storage (ensures workspace exists) */
|
|
98
124
|
getSettingsBranchRoot: () => Promise<string>;
|
|
125
|
+
/** Records `user` as an editor of the branch for its next submit (branch-metadata.ts). */
|
|
126
|
+
recordBranchEditor: (context: BranchPaths, user: CanopyUser) => Promise<void>;
|
|
99
127
|
}
|
|
100
128
|
export interface CreateCanopyServicesOptions {
|
|
101
129
|
/** Entry schema names → field definitions, for resolving .collection.json references. */
|
package/dist/services.js
CHANGED
|
@@ -9,18 +9,22 @@ import { operatingStrategy } from './operating-mode/index.js';
|
|
|
9
9
|
import { BranchSchemaCache } from './branch-schema-cache.js';
|
|
10
10
|
import { enqueueTask } from './task-queue/cms-task-queue.js';
|
|
11
11
|
import { getTaskQueueDir } from './task-queue/task-queue-config.js';
|
|
12
|
+
import { baseBranchOf } from './utils/base-branch.js';
|
|
12
13
|
import { detectHeadBranch, isCanopyInternalPath } from './utils/git.js';
|
|
13
14
|
import { readsFromCheckout } from './build-mode.js';
|
|
14
15
|
import { timeRequestPhase } from './utils/request-timing.js';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
16
|
+
import { appendTrailers, buildEditorTrailers, describeEditors, } from './submission-attribution.js';
|
|
17
|
+
import { getBranchMetadataFileManager, recordBranchEditor } from './branch-metadata.js';
|
|
18
|
+
import { readBranchMetadataFile } from './branch-metadata-file.js';
|
|
17
19
|
import { getErrorMessage, redactCredentials } from './utils/error.js';
|
|
18
20
|
import { withContentWriteLock } from './utils/content-write-lock.js';
|
|
21
|
+
import { ContentStore } from './content-store.js';
|
|
22
|
+
import { stampNewEntries } from './stamp-on-publish.js';
|
|
19
23
|
/**
|
|
20
24
|
* A per-instance active-branch detector with its own 5s TTL cache, in priority
|
|
21
25
|
* order: an explicitly configured value; `defaultBaseBranch ?? 'main'` with no
|
|
22
26
|
* git for static deployments and builds; git HEAD in dev; and
|
|
23
|
-
* `defaultBaseBranch
|
|
27
|
+
* `defaultBaseBranch` in prod, `undefined` while that is still unresolved.
|
|
24
28
|
*/
|
|
25
29
|
function createActiveBranchDetector() {
|
|
26
30
|
let cache = null;
|
|
@@ -42,7 +46,7 @@ function createActiveBranchDetector() {
|
|
|
42
46
|
cache = { value: branch, expiresAt: now + 5000 };
|
|
43
47
|
return branch;
|
|
44
48
|
}
|
|
45
|
-
return config.defaultBaseBranch
|
|
49
|
+
return config.defaultBaseBranch;
|
|
46
50
|
};
|
|
47
51
|
}
|
|
48
52
|
/**
|
|
@@ -58,6 +62,42 @@ export const getBootstrapAdminIds = () => {
|
|
|
58
62
|
.map((id) => id.trim())
|
|
59
63
|
.filter(Boolean));
|
|
60
64
|
};
|
|
65
|
+
/**
|
|
66
|
+
* Submit found nothing to send: the branch's saved content, committed or not, matches its base
|
|
67
|
+
* as of the fork point. Raised before anything is pushed and after undoing any commit the
|
|
68
|
+
* submit made, so the branch's commits and saved edits are as they were.
|
|
69
|
+
*/
|
|
70
|
+
export class NothingToSubmitError extends Error {
|
|
71
|
+
constructor(branch, base) {
|
|
72
|
+
super(`Nothing to submit yet: "${branch}" has no saved changes compared with "${base}". ` +
|
|
73
|
+
'Save your edits, then submit.');
|
|
74
|
+
this.name = 'NothingToSubmitError';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** The branch's recorded editor ids, or undefined, with a warning, when branch.json cannot be read. */
|
|
78
|
+
async function readRecordedEditors(context) {
|
|
79
|
+
try {
|
|
80
|
+
return (await readBranchMetadataFile(context.branchRoot))?.branch;
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
console.warn(`CanopyCMS: Could not read the recorded editors of ${context.branch.name}:`, getErrorMessage(err));
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** One lookup per user per submit, however often the submit asks. */
|
|
88
|
+
function memoizeLookup(lookup) {
|
|
89
|
+
if (!lookup)
|
|
90
|
+
return undefined;
|
|
91
|
+
const seen = new Map();
|
|
92
|
+
return (userId) => {
|
|
93
|
+
let found = seen.get(userId);
|
|
94
|
+
if (!found) {
|
|
95
|
+
found = lookup(userId);
|
|
96
|
+
seen.set(userId, found);
|
|
97
|
+
}
|
|
98
|
+
return found;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
61
101
|
/**
|
|
62
102
|
* Build the reusable helpers from a validated CanopyConfig — once at startup,
|
|
63
103
|
* then injected into request handlers and loaders. Schema is not loaded here;
|
|
@@ -89,25 +129,30 @@ async function _createCanopyServicesInternal(config, options) {
|
|
|
89
129
|
const detectActiveBranch = createActiveBranchDetector();
|
|
90
130
|
const explicitActiveBranch = config.defaultActiveBranch;
|
|
91
131
|
const explicitBaseBranch = config.defaultBaseBranch;
|
|
92
|
-
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
132
|
+
// Unset, the base branch follows the rule workspace provisioning uses
|
|
133
|
+
// (GitManager.resolveWorkspaceBaseBranch): dev detects git HEAD, prod reads
|
|
134
|
+
// the remote's HEAD and fails loudly when it cannot. Prod stays pending
|
|
135
|
+
// (undefined) only while the worker has not created the remote yet; see
|
|
136
|
+
// resolvePendingBaseBranch.
|
|
96
137
|
const defaultBaseBranch = explicitBaseBranch ??
|
|
97
|
-
(
|
|
98
|
-
?
|
|
99
|
-
: '
|
|
138
|
+
(readsFromCheckout(config)
|
|
139
|
+
? 'main'
|
|
140
|
+
: config.mode === 'dev'
|
|
141
|
+
? await detectActiveBranch({ ...config, defaultActiveBranch: undefined })
|
|
142
|
+
: await GitManager.detectBaseBranch(config, 'pending'));
|
|
143
|
+
const defaultActiveBranch = await detectActiveBranch({ ...config, defaultBaseBranch });
|
|
100
144
|
config = { ...config, defaultActiveBranch, defaultBaseBranch };
|
|
101
145
|
const bootstrapAdminIds = getBootstrapAdminIds();
|
|
102
146
|
const branchSchemaCache = options.branchSchemaCache ?? new BranchSchemaCache(config.mode);
|
|
103
|
-
|
|
147
|
+
// Reads services.config per call: the protected base branch may resolve after creation.
|
|
148
|
+
const checkBranchAccess = (context, user) => createCheckBranchAccess(config.defaultBranchAccess ?? 'deny', services.config)(context, user);
|
|
104
149
|
// Content access loads permissions dynamically from the settings branch (orphan git branch)
|
|
105
150
|
const ensureSettingsBranchRoot = options.getSettingsBranchRoot ??
|
|
106
151
|
(async () => {
|
|
107
152
|
const strategy = operatingStrategy(config.mode);
|
|
108
153
|
const settingsRoot = strategy.getSettingsRoot();
|
|
109
154
|
const branchName = strategy.getSettingsBranchName(config);
|
|
110
|
-
const manager = new SettingsWorkspaceManager(config);
|
|
155
|
+
const manager = new SettingsWorkspaceManager(services.config);
|
|
111
156
|
await manager.ensureGitWorkspace({
|
|
112
157
|
settingsRoot,
|
|
113
158
|
branchName,
|
|
@@ -129,7 +174,7 @@ async function _createCanopyServicesInternal(config, options) {
|
|
|
129
174
|
const configDefaults = getConfigDefaults();
|
|
130
175
|
const createGitManagerFor = (repoPath, opts) => new GitManager({
|
|
131
176
|
repoPath,
|
|
132
|
-
baseBranch: opts?.baseBranch ?? config
|
|
177
|
+
baseBranch: opts?.baseBranch ?? baseBranchOf(services.config),
|
|
133
178
|
remote: opts?.remote ?? config.defaultRemoteName ?? configDefaults.remoteName,
|
|
134
179
|
skipIndexMarker: opts?.skipIndexMarker,
|
|
135
180
|
});
|
|
@@ -151,12 +196,33 @@ async function _createCanopyServicesInternal(config, options) {
|
|
|
151
196
|
await git.commit(options.message);
|
|
152
197
|
});
|
|
153
198
|
};
|
|
199
|
+
/** Runs inside submitBranch's content-write lock; a stamp that fails never blocks the submit. */
|
|
200
|
+
const stampNewEntriesOrWarn = async (context, git) => {
|
|
201
|
+
const contentRoot = services.config.contentRoot || 'content';
|
|
202
|
+
try {
|
|
203
|
+
const { flatSchema } = await services.branchSchemaCache.getSchema(context.branchRoot, services.entrySchemaRegistry, contentRoot);
|
|
204
|
+
return await stampNewEntries({
|
|
205
|
+
git,
|
|
206
|
+
store: new ContentStore(context.branchRoot, flatSchema, { contentRootName: contentRoot }),
|
|
207
|
+
branchRoot: context.branchRoot,
|
|
208
|
+
flatSchema,
|
|
209
|
+
contentRoot,
|
|
210
|
+
stampedAt: new Date().toISOString(),
|
|
211
|
+
warn: (message) => console.warn(redactCredentials(message)),
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
console.warn(`CanopyCMS: Could not finish stamping the new entries on ${context.branch.name}; ` +
|
|
216
|
+
'submitting with only the stamps already written:', redactCredentials(getErrorMessage(err)));
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
};
|
|
154
220
|
const submitBranch = async (options) => {
|
|
155
221
|
// Defense-in-depth: refuse to push the base branch to itself even if the
|
|
156
222
|
// 'submittableBranch' guard was somehow bypassed. Prefer the recorded fork
|
|
157
|
-
// point (context.branch.baseBranch) over config
|
|
158
|
-
//
|
|
159
|
-
const effectiveBase = options.context.branch.baseBranch ?? config
|
|
223
|
+
// point (context.branch.baseBranch) over the config value, which dev's
|
|
224
|
+
// refreshActiveBranch() can move.
|
|
225
|
+
const effectiveBase = options.context.branch.baseBranch ?? baseBranchOf(services.config);
|
|
160
226
|
if (sanitizeBranchName(options.context.branch.name) === sanitizeBranchName(effectiveBase)) {
|
|
161
227
|
throw new Error(`Refusing to commit and push the base branch "${options.context.branch.name}" — submitting requires a separate editing branch`);
|
|
162
228
|
}
|
|
@@ -173,9 +239,25 @@ async function _createCanopyServicesInternal(config, options) {
|
|
|
173
239
|
// lands on the branch, and the rebase's `--abort` resets the branch past it
|
|
174
240
|
// after this reported success. The push stays inside so no rebase rewrites
|
|
175
241
|
// the commit between commit and push.
|
|
242
|
+
const lookupEditor = memoizeLookup(options.lookupEditor);
|
|
243
|
+
const readRecorded = () => readRecordedEditors(options.context);
|
|
244
|
+
// Names are looked up before taking the lock, so a slow auth provider never holds it.
|
|
245
|
+
const named = new Map((await describeEditors((await readRecorded())?.editors ?? [], lookupEditor)).map((e) => [
|
|
246
|
+
e.userId,
|
|
247
|
+
e,
|
|
248
|
+
]));
|
|
249
|
+
let recorded = {};
|
|
250
|
+
let stamped = [];
|
|
176
251
|
const submitted = await withContentWriteLock(options.context.branchRoot, async () => {
|
|
177
252
|
await git.checkoutBranch(options.context.branch.name);
|
|
253
|
+
// Before the status read, so the stamp joins this commit even when an earlier attempt
|
|
254
|
+
// already committed the entry and only its push failed.
|
|
255
|
+
stamped = await stampNewEntriesOrWarn(options.context, git);
|
|
178
256
|
const status = await git.status();
|
|
257
|
+
// A save records its editor only after releasing this lock, so a save that lands just
|
|
258
|
+
// before this submit can be committed here while its editor is named by the next commit.
|
|
259
|
+
recorded = (await readRecorded()) ?? {};
|
|
260
|
+
const uncommitted = recorded.uncommittedEditors ?? [];
|
|
179
261
|
// Commit and push answer two DIFFERENT questions. Committing cleans the
|
|
180
262
|
// working tree, so one combined "tree is dirty" gate makes a retry after a
|
|
181
263
|
// failed push a silent no-op: nothing left to commit, the block is skipped,
|
|
@@ -185,34 +267,56 @@ async function _createCanopyServicesInternal(config, options) {
|
|
|
185
267
|
// canopycms's own state under .canopy-meta/ is never content, so it neither
|
|
186
268
|
// makes a commit worth creating nor gets staged into one.
|
|
187
269
|
let committed = false;
|
|
270
|
+
const preCommitSha = await git.headSha();
|
|
188
271
|
if (status.files.some((f) => !isCanopyInternalPath(f.path))) {
|
|
189
272
|
await git.addAllExceptCanopyState();
|
|
190
|
-
const
|
|
273
|
+
const committers = uncommitted.map((userId) => named.get(userId) ?? { userId });
|
|
274
|
+
const trailers = buildEditorTrailers(options.submitter ? [options.submitter, ...committers] : committers, {
|
|
191
275
|
editedBy: config.gitEditedByTrailers ?? true,
|
|
192
276
|
coAuthoredBy: config.gitCoAuthoredByTrailers ?? false,
|
|
193
277
|
});
|
|
194
278
|
await git.commit(appendTrailers(options.message ?? `Submit ${options.context.branch.name}`, trailers));
|
|
195
279
|
committed = true;
|
|
196
280
|
}
|
|
281
|
+
// The diff runs after the commit so it covers saved-but-uncommitted edits too, and
|
|
282
|
+
// before the push so a branch with nothing to submit never reaches the remote. A diff
|
|
283
|
+
// that cannot be computed lets the submit through: the list only feeds the PR body, and
|
|
284
|
+
// GitHub's own refusal of an empty branch is handled on both paths (api/github-sync.ts,
|
|
285
|
+
// worker/task-runner.ts).
|
|
286
|
+
let changedPaths;
|
|
287
|
+
try {
|
|
288
|
+
changedPaths = (await git.listChangedPathsSinceBase()).filter((p) => !isCanopyInternalPath(p));
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
console.warn(`CanopyCMS: Could not list the changes on ${options.context.branch.name} against its base; ` +
|
|
292
|
+
"the PR body lists only this submit's changes:", redactCredentials(getErrorMessage(err)));
|
|
293
|
+
}
|
|
294
|
+
if (changedPaths?.length === 0) {
|
|
295
|
+
if (committed)
|
|
296
|
+
await git.resetKeepingChanges(preCommitSha);
|
|
297
|
+
throw new NothingToSubmitError(options.context.branch.name, effectiveBase);
|
|
298
|
+
}
|
|
299
|
+
// A failure here leaves them uncommitted, so the next commit names them again.
|
|
300
|
+
if (committed && uncommitted.length > 0) {
|
|
301
|
+
try {
|
|
302
|
+
await getBranchMetadataFileManager(options.context.branchRoot, options.context.baseRoot).markEditorsCommitted(uncommitted);
|
|
303
|
+
}
|
|
304
|
+
catch (err) {
|
|
305
|
+
console.warn(`CanopyCMS: Could not clear the committed editors of ${options.context.branch.name}:`, getErrorMessage(err));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
197
308
|
if (committed || (await git.hasUnpushedCommits(options.context.branch.name))) {
|
|
198
309
|
await git.push(options.context.branch.name);
|
|
199
310
|
}
|
|
200
|
-
return status;
|
|
311
|
+
return changedPaths ?? status.files.map((f) => f.path).filter((p) => !isCanopyInternalPath(p));
|
|
201
312
|
});
|
|
202
|
-
//
|
|
203
|
-
// this
|
|
204
|
-
|
|
205
|
-
let changedPaths;
|
|
206
|
-
try {
|
|
207
|
-
changedPaths = await git.listChangedPathsSinceBase();
|
|
208
|
-
}
|
|
209
|
-
catch (err) {
|
|
210
|
-
console.warn(`CanopyCMS: Could not list the changes on ${options.context.branch.name} against its base; ` +
|
|
211
|
-
"the PR body lists only this submit's changes:", redactCredentials(getErrorMessage(err)));
|
|
212
|
-
changedPaths = submitted.files.map((f) => f.path);
|
|
213
|
-
}
|
|
313
|
+
// Re-read after the lock, so the PR body also names an editor recorded after the read above:
|
|
314
|
+
// one whose save this commit carries, or one whose save will reach the PR with a later push.
|
|
315
|
+
const editorIds = (await readRecorded())?.editors ?? recorded.editors ?? [];
|
|
214
316
|
return {
|
|
215
|
-
changedPaths:
|
|
317
|
+
changedPaths: submitted,
|
|
318
|
+
editors: await describeEditors(editorIds, lookupEditor),
|
|
319
|
+
stamped,
|
|
216
320
|
};
|
|
217
321
|
};
|
|
218
322
|
// Must be initialized before closures that reference it (commitToSettingsBranch)
|
|
@@ -328,6 +432,7 @@ async function _createCanopyServicesInternal(config, options) {
|
|
|
328
432
|
submitBranch,
|
|
329
433
|
commitToSettingsBranch,
|
|
330
434
|
getSettingsBranchRoot,
|
|
435
|
+
recordBranchEditor,
|
|
331
436
|
refreshActiveBranch: async () => {
|
|
332
437
|
if (services.config.mode !== 'dev')
|
|
333
438
|
return;
|
|
@@ -358,14 +463,27 @@ async function _createCanopyServicesInternal(config, options) {
|
|
|
358
463
|
changed = true;
|
|
359
464
|
}
|
|
360
465
|
if (changed) {
|
|
361
|
-
// The closures above
|
|
362
|
-
//
|
|
363
|
-
//
|
|
364
|
-
//
|
|
365
|
-
// values must read services.config.
|
|
466
|
+
// The closures above captured the original `config` local. Only branch
|
|
467
|
+
// identity changes here: git operations on existing branches use the
|
|
468
|
+
// fork point in branch metadata, and anything needing the fresh values
|
|
469
|
+
// reads services.config.
|
|
366
470
|
services.config = next;
|
|
367
471
|
}
|
|
368
472
|
},
|
|
473
|
+
resolvePendingBaseBranch: async () => {
|
|
474
|
+
if (services.config.defaultBaseBranch)
|
|
475
|
+
return;
|
|
476
|
+
// In-process and write-once in effect: concurrent requests each read the
|
|
477
|
+
// same remote HEAD and assign the same value, and nothing is written to
|
|
478
|
+
// disk, so no lock is needed. Later changes to that HEAD are not followed
|
|
479
|
+
// (configure defaultBaseBranch to move the base branch).
|
|
480
|
+
const detected = await GitManager.detectBaseBranch(services.config, 'throw');
|
|
481
|
+
services.config = {
|
|
482
|
+
...services.config,
|
|
483
|
+
defaultBaseBranch: detected,
|
|
484
|
+
defaultActiveBranch: services.config.defaultActiveBranch ?? detected,
|
|
485
|
+
};
|
|
486
|
+
},
|
|
369
487
|
};
|
|
370
488
|
return services;
|
|
371
489
|
}
|
|
@@ -8,8 +8,8 @@ import type { OperatingMode } from './operating-mode/index.js';
|
|
|
8
8
|
* its target, and `GitManager.initializeWorkspace` clones INTO the settings
|
|
9
9
|
* root, which `git clone` refuses if anything is already there. A dedicated
|
|
10
10
|
* dot-directory also keeps this marker out of `path.dirname(settingsRoot)`,
|
|
11
|
-
* where `ensureLocalSimulatedRemote` puts `.remote-init.lock` —
|
|
12
|
-
* calls into that while holding this lock, so separate directories make the
|
|
11
|
+
* where `ensureLocalSimulatedRemote` puts `.remote-init.lock` — an in-place
|
|
12
|
+
* settings re-init calls into that while holding this lock, so separate directories make the
|
|
13
13
|
* nesting obvious rather than incidental. For how a lock's anchor path is
|
|
14
14
|
* chosen, see utils/provisioning-lock.ts and docs/concurrency.md.
|
|
15
15
|
* @internal Exported for tests.
|
|
@@ -27,12 +27,32 @@ export interface EnsureSettingsWorkspaceOptions {
|
|
|
27
27
|
* BranchWorkspaceManager this writes no metadata files and never touches the
|
|
28
28
|
* branch registry.
|
|
29
29
|
*
|
|
30
|
+
* A first clone follows [PROV-1] (branch-provisioning.ts): it is built in a
|
|
31
|
+
* staging sibling and renamed into place, so a process killed mid-clone never
|
|
32
|
+
* leaves a half-made workspace at the settings root. Never sparse: the orphan
|
|
33
|
+
* init's `git rm -rf .` would leave out-of-cone base files in the tree.
|
|
34
|
+
*
|
|
30
35
|
* Two locking layers, mirroring BranchWorkspaceManager: an in-memory promise
|
|
31
36
|
* lock within the process, and `acquireProvisioningLock` (proper-lockfile)
|
|
32
|
-
* across processes and hosts.
|
|
37
|
+
* across processes and hosts around the publish and every in-place init.
|
|
33
38
|
*/
|
|
34
39
|
export declare class SettingsWorkspaceManager {
|
|
35
40
|
private readonly config;
|
|
36
41
|
constructor(config: CanopyConfig);
|
|
37
42
|
ensureGitWorkspace(options: EnsureSettingsWorkspaceOptions): Promise<void>;
|
|
43
|
+
private initOptions;
|
|
44
|
+
/**
|
|
45
|
+
* Layer 2 around the init itself (proper-lockfile: heartbeat-refreshed while the holder lives,
|
|
46
|
+
* so a slow EFS operation is not mistaken for a crash, and patient retries so a loser WAITS
|
|
47
|
+
* instead of racing into a concurrent init).
|
|
48
|
+
*/
|
|
49
|
+
private withInitLock;
|
|
50
|
+
/** Re-init an existing workspace where it is; false when, under the lock, there is none. */
|
|
51
|
+
private ensureInPlace;
|
|
52
|
+
/**
|
|
53
|
+
* Clone and set up the settings branch in a staging sibling, then publish it under the init
|
|
54
|
+
* lock, moving an interrupted first init aside to `.trash-settings-*`. A workspace someone
|
|
55
|
+
* else published meanwhile wins and the staging copy is dropped.
|
|
56
|
+
*/
|
|
57
|
+
private provisionStaged;
|
|
38
58
|
}
|