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/github-service.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export declare const shouldRetrySecondaryRateLimit: (retryAfter: number, retryCo
|
|
|
31
31
|
*
|
|
32
32
|
* A deployment using an App constructs the strategy and passes it through here
|
|
33
33
|
* — see `packages/canopycms-cdk/worker/github-app-auth.ts` and
|
|
34
|
-
* `
|
|
34
|
+
* `CHANGELOG.md` for a hand-written entrypoint.
|
|
35
35
|
*/
|
|
36
36
|
export interface OctokitAuthStrategyOptions {
|
|
37
37
|
/**
|
|
@@ -57,7 +57,23 @@ export type CanopyOctokitAuthOptions = {
|
|
|
57
57
|
* for the safety net this doesn't cover: exhausted plugin retries and
|
|
58
58
|
* errors the plugin never sees, like non-403 network failures).
|
|
59
59
|
*/
|
|
60
|
-
export declare function createCanopyOctokit(options: CanopyOctokitAuthOptions
|
|
60
|
+
export declare function createCanopyOctokit(options: CanopyOctokitAuthOptions,
|
|
61
|
+
/**
|
|
62
|
+
* Where Octokit's own log and the throttle's warnings go: the GitHub gateway passes its own,
|
|
63
|
+
* which scrubs and escapes. Without one, Octokit logs to the console as it does by default.
|
|
64
|
+
*/
|
|
65
|
+
logger?: {
|
|
66
|
+
warn: (...args: unknown[]) => void;
|
|
67
|
+
error: (...args: unknown[]) => void;
|
|
68
|
+
},
|
|
69
|
+
/**
|
|
70
|
+
* Told of every request's `authorization` header just before it is sent, which is the only
|
|
71
|
+
* place the FINAL header is visible: a token an auth strategy minted or rotated shows up here
|
|
72
|
+
* before anything has logged or thrown it. The GitHub gateway registers it for scrubbing.
|
|
73
|
+
*/
|
|
74
|
+
observe?: {
|
|
75
|
+
onAuthorization: (authorization: string) => void;
|
|
76
|
+
}): Octokit;
|
|
61
77
|
export interface GitHubServiceOptions {
|
|
62
78
|
token: string;
|
|
63
79
|
owner: string;
|
|
@@ -95,6 +111,8 @@ export interface CreateOrUpdatePullRequestParams {
|
|
|
95
111
|
mergeSectionIntoBody?: boolean;
|
|
96
112
|
/** Forwarded to all GitHub requests (worker task-timeout abort). */
|
|
97
113
|
signal?: AbortSignal;
|
|
114
|
+
/** Where its warnings go (default `canopyLogWarn`): the GitHub gateway passes its own. */
|
|
115
|
+
warn?: (...args: unknown[]) => void;
|
|
98
116
|
}
|
|
99
117
|
/**
|
|
100
118
|
* Create or update a pull request, idempotently: an open PR from head to base
|
|
@@ -112,6 +130,25 @@ export declare function createOrUpdatePullRequest(params: CreateOrUpdatePullRequ
|
|
|
112
130
|
url: string;
|
|
113
131
|
created: boolean;
|
|
114
132
|
}>;
|
|
133
|
+
/**
|
|
134
|
+
* Whether a `git.deleteRef` failure means the branch is already gone from GitHub, so the delete
|
|
135
|
+
* has nothing left to do. A missing ref is a 422 "Reference does not exist"; the message check
|
|
136
|
+
* matters because a 422 also refuses deleting the default branch. A 404 counts too, though it
|
|
137
|
+
* can also mean the repo is not visible to the credential.
|
|
138
|
+
*/
|
|
139
|
+
export declare function isRefAlreadyGoneError(err: unknown): boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Whether a PR create failed because the head branch has no commits its base lacks. GitHub
|
|
142
|
+
* answers 422 "Validation Failed" with the reason in `response.data.errors[].message`, which
|
|
143
|
+
* Octokit also folds into `err.message`. Other 422s (a duplicate PR, an unknown base) never match.
|
|
144
|
+
*/
|
|
145
|
+
export declare function isNoCommitsBetweenError(err: unknown): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* The `authorization` header of a request's headers: a plain object (lower-case keys, as Octokit
|
|
148
|
+
* sends them), a `Headers`, or a list of pairs.
|
|
149
|
+
* @internal Exported for tests.
|
|
150
|
+
*/
|
|
151
|
+
export declare function authorizationOf(headers: HeadersInit | undefined): string | undefined;
|
|
115
152
|
export declare class GitHubService {
|
|
116
153
|
private octokit;
|
|
117
154
|
private owner;
|
package/dist/github-service.js
CHANGED
|
@@ -8,6 +8,7 @@ import { getErrorMessage } from './utils/error.js';
|
|
|
8
8
|
// is plain console. See utils/logger.ts.
|
|
9
9
|
import { canopyLogWarn } from './utils/logger.js';
|
|
10
10
|
import { mergePrSection } from './submission-attribution.js';
|
|
11
|
+
import { baseBranchOf } from './utils/base-branch.js';
|
|
11
12
|
const ThrottledOctokit = Octokit.plugin(throttling);
|
|
12
13
|
/**
|
|
13
14
|
* Retry primary rate limits at most twice and only for short waits; beyond
|
|
@@ -30,25 +31,64 @@ export const shouldRetrySecondaryRateLimit = (retryAfter, retryCount) => retryCo
|
|
|
30
31
|
* for the safety net this doesn't cover: exhausted plugin retries and
|
|
31
32
|
* errors the plugin never sees, like non-403 network failures).
|
|
32
33
|
*/
|
|
33
|
-
export function createCanopyOctokit(options
|
|
34
|
+
export function createCanopyOctokit(options,
|
|
35
|
+
/**
|
|
36
|
+
* Where Octokit's own log and the throttle's warnings go: the GitHub gateway passes its own,
|
|
37
|
+
* which scrubs and escapes. Without one, Octokit logs to the console as it does by default.
|
|
38
|
+
*/
|
|
39
|
+
logger,
|
|
40
|
+
/**
|
|
41
|
+
* Told of every request's `authorization` header just before it is sent, which is the only
|
|
42
|
+
* place the FINAL header is visible: a token an auth strategy minted or rotated shows up here
|
|
43
|
+
* before anything has logged or thrown it. The GitHub gateway registers it for scrubbing.
|
|
44
|
+
*/
|
|
45
|
+
observe) {
|
|
46
|
+
const warn = logger?.warn ?? canopyLogWarn;
|
|
34
47
|
// Pick the two auth fields out EXPLICITLY, never spread: `baseUrl`,
|
|
35
48
|
// `request`, `log` and `userAgent` are all live `OctokitOptions`, and a
|
|
36
49
|
// non-literal argument slips past TypeScript's excess-property check. The
|
|
37
50
|
// contract is "our Octokit, authenticated the way you say", not "configured
|
|
38
|
-
// however you like".
|
|
51
|
+
// however you like". The one `request` we set is `observe`'s fetch: an auth
|
|
52
|
+
// strategy's hook is the innermost `request` wrap, so a hook added after
|
|
53
|
+
// construction runs before it sets the header. `@octokit/auth-app`'s hook
|
|
54
|
+
// mints through the `request` it wraps (`request.defaults`), so the JWT of a
|
|
55
|
+
// mint an Octokit request triggers passes the fetch too; a mint outside one
|
|
56
|
+
// (`mintInstallationToken`) uses auth-app's own `request`, and does not.
|
|
39
57
|
const auth = 'authStrategy' in options
|
|
40
58
|
? { authStrategy: options.authStrategy, auth: options.auth }
|
|
41
59
|
: { auth: options.auth };
|
|
42
60
|
return new ThrottledOctokit({
|
|
43
61
|
...auth,
|
|
62
|
+
...(observe === undefined
|
|
63
|
+
? {}
|
|
64
|
+
: {
|
|
65
|
+
request: {
|
|
66
|
+
fetch: (url, init) => {
|
|
67
|
+
const authorization = authorizationOf(init?.headers);
|
|
68
|
+
if (authorization !== undefined)
|
|
69
|
+
observe.onAuthorization(authorization);
|
|
70
|
+
return globalThis.fetch(url, init);
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
}),
|
|
74
|
+
...(logger === undefined
|
|
75
|
+
? {}
|
|
76
|
+
: {
|
|
77
|
+
log: {
|
|
78
|
+
debug: () => undefined,
|
|
79
|
+
info: () => undefined,
|
|
80
|
+
warn: logger.warn,
|
|
81
|
+
error: logger.error,
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
44
84
|
throttle: {
|
|
45
85
|
onRateLimit: (retryAfter, requestOptions, _octokit, retryCount) => {
|
|
46
|
-
|
|
86
|
+
warn(`CanopyCMS: GitHub primary rate limit hit for ${requestOptions.method} ${requestOptions.url} ` +
|
|
47
87
|
`(retryAfter=${retryAfter}s, retryCount=${retryCount})`);
|
|
48
88
|
return shouldRetryRateLimit(retryAfter, retryCount);
|
|
49
89
|
},
|
|
50
90
|
onSecondaryRateLimit: (retryAfter, requestOptions, _octokit, retryCount) => {
|
|
51
|
-
|
|
91
|
+
warn(`CanopyCMS: GitHub secondary rate limit hit for ${requestOptions.method} ${requestOptions.url} ` +
|
|
52
92
|
`(retryAfter=${retryAfter}s, retryCount=${retryCount})`);
|
|
53
93
|
return shouldRetrySecondaryRateLimit(retryAfter, retryCount);
|
|
54
94
|
},
|
|
@@ -68,6 +108,7 @@ export function createCanopyOctokit(options) {
|
|
|
68
108
|
*/
|
|
69
109
|
export async function createOrUpdatePullRequest(params) {
|
|
70
110
|
const { octokit, owner, repo, head, base, title, body, markReadyIfDraft, signal } = params;
|
|
111
|
+
const warn = params.warn ?? canopyLogWarn;
|
|
71
112
|
const mergeSection = params.mergeSectionIntoBody === true;
|
|
72
113
|
// CONDITIONAL spread: with no signal, the request objects below carry no
|
|
73
114
|
// `request` key at all (github-service.test.ts asserts on their exact shape).
|
|
@@ -87,7 +128,7 @@ export async function createOrUpdatePullRequest(params) {
|
|
|
87
128
|
let existing = existingPRs.data[0];
|
|
88
129
|
if (existingPRs.data.length > 1) {
|
|
89
130
|
existing = [...existingPRs.data].sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime())[0];
|
|
90
|
-
|
|
131
|
+
warn(`CanopyCMS: Found ${existingPRs.data.length} open PRs for ${head} -> ${base}; updating the most recently updated (#${existing.number})`);
|
|
91
132
|
}
|
|
92
133
|
await octokit.pulls.update({
|
|
93
134
|
owner,
|
|
@@ -126,7 +167,7 @@ export async function createOrUpdatePullRequest(params) {
|
|
|
126
167
|
});
|
|
127
168
|
}
|
|
128
169
|
catch (err) {
|
|
129
|
-
|
|
170
|
+
warn(`CanopyCMS: Failed to convert PR #${existing.number} to ready for review (the PR update itself succeeded; continuing):`, getErrorMessage(err));
|
|
130
171
|
}
|
|
131
172
|
}
|
|
132
173
|
return { number: existing.number, url: existing.html_url, created: false };
|
|
@@ -142,6 +183,59 @@ export async function createOrUpdatePullRequest(params) {
|
|
|
142
183
|
});
|
|
143
184
|
return { number: pr.data.number, url: pr.data.html_url, created: true };
|
|
144
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* Whether a `git.deleteRef` failure means the branch is already gone from GitHub, so the delete
|
|
188
|
+
* has nothing left to do. A missing ref is a 422 "Reference does not exist"; the message check
|
|
189
|
+
* matters because a 422 also refuses deleting the default branch. A 404 counts too, though it
|
|
190
|
+
* can also mean the repo is not visible to the credential.
|
|
191
|
+
*/
|
|
192
|
+
export function isRefAlreadyGoneError(err) {
|
|
193
|
+
if (!(err instanceof Error) || !('status' in err))
|
|
194
|
+
return false;
|
|
195
|
+
const { status } = err;
|
|
196
|
+
if (status === 404)
|
|
197
|
+
return true;
|
|
198
|
+
return status === 422 && /reference does not exist/i.test(err.message);
|
|
199
|
+
}
|
|
200
|
+
const NO_COMMITS_BETWEEN = /^No commits between /;
|
|
201
|
+
/**
|
|
202
|
+
* Whether a PR create failed because the head branch has no commits its base lacks. GitHub
|
|
203
|
+
* answers 422 "Validation Failed" with the reason in `response.data.errors[].message`, which
|
|
204
|
+
* Octokit also folds into `err.message`. Other 422s (a duplicate PR, an unknown base) never match.
|
|
205
|
+
*/
|
|
206
|
+
export function isNoCommitsBetweenError(err) {
|
|
207
|
+
if (!(err instanceof Error) || !('status' in err) || err.status !== 422)
|
|
208
|
+
return false;
|
|
209
|
+
const data = 'response' in err ? err.response?.data : null;
|
|
210
|
+
const errors = typeof data === 'object' && data !== null && 'errors' in data ? data.errors : undefined;
|
|
211
|
+
if (Array.isArray(errors)) {
|
|
212
|
+
return errors.some((e) => typeof e === 'object' &&
|
|
213
|
+
e !== null &&
|
|
214
|
+
'message' in e &&
|
|
215
|
+
typeof e.message === 'string' &&
|
|
216
|
+
NO_COMMITS_BETWEEN.test(e.message));
|
|
217
|
+
}
|
|
218
|
+
return /"message":"No commits between /.test(err.message);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* The `authorization` header of a request's headers: a plain object (lower-case keys, as Octokit
|
|
222
|
+
* sends them), a `Headers`, or a list of pairs.
|
|
223
|
+
* @internal Exported for tests.
|
|
224
|
+
*/
|
|
225
|
+
export function authorizationOf(headers) {
|
|
226
|
+
if (headers === undefined)
|
|
227
|
+
return undefined;
|
|
228
|
+
if (headers instanceof Headers)
|
|
229
|
+
return headers.get('authorization') ?? undefined;
|
|
230
|
+
if (Array.isArray(headers)) {
|
|
231
|
+
return headers.find(([name]) => name.toLowerCase() === 'authorization')?.[1];
|
|
232
|
+
}
|
|
233
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
234
|
+
if (name.toLowerCase() === 'authorization' && typeof value === 'string')
|
|
235
|
+
return value;
|
|
236
|
+
}
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
145
239
|
export class GitHubService {
|
|
146
240
|
constructor(options) {
|
|
147
241
|
this.octokit = createCanopyOctokit({ auth: options.token });
|
|
@@ -311,7 +405,7 @@ export const createGitHubService = (config, remoteUrl) => {
|
|
|
311
405
|
token,
|
|
312
406
|
owner,
|
|
313
407
|
repo,
|
|
314
|
-
baseBranch: config
|
|
408
|
+
baseBranch: baseBranchOf(config),
|
|
315
409
|
});
|
|
316
410
|
}
|
|
317
411
|
catch (err) {
|
package/dist/http/handler.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { jsonResponse, isCanopyBinaryResponse } from './types.js';
|
|
2
2
|
import { workerNotReadyResponse } from './worker-not-ready.js';
|
|
3
|
+
import { SchemaUnavailableError } from '../schema/schema-unavailable-error.js';
|
|
3
4
|
import { createCanopyRouter } from './router.js';
|
|
4
5
|
import { assertAuthPluginAllowedForMode } from '../auth/plugin.js';
|
|
5
6
|
import { createCanopyServices } from '../services.js';
|
|
7
|
+
import { recordConfiguredSparseCone } from '../branch-sparse.js';
|
|
8
|
+
import { recordServedSchemaRegistry } from '../schema-registry-record.js';
|
|
6
9
|
import { loadBranchContext, BranchWorkspaceManager } from '../branch-workspace.js';
|
|
7
10
|
import { BranchMetadataCorruptError } from '../branch-metadata.js';
|
|
11
|
+
import { BRANCH_METADATA_CORRUPT_MESSAGE } from '../branch-metadata-error.js';
|
|
8
12
|
import { resolveCanopyUser } from '../resolve-canopy-user.js';
|
|
9
13
|
import { authResultToCanopyUser } from '../user.js';
|
|
10
14
|
import { isAdmin } from '../authorization/index.js';
|
|
@@ -14,13 +18,18 @@ import { getErrorMessage, redactCredentials, sanitizeErrorMessage } from '../uti
|
|
|
14
18
|
// canopyLogError, not console.error: this is shared code and not guaranteed to
|
|
15
19
|
// stay out of the worker's runtime import closure, so new log lines here go
|
|
16
20
|
// through the indirection (utils/logger.ts).
|
|
17
|
-
import { canopyLogError } from '../utils/logger.js';
|
|
21
|
+
import { canopyLogError, canopyLogWarn } from '../utils/logger.js';
|
|
22
|
+
import { EDITOR_MODE_HEADER, EDITOR_MODE_MISMATCH_STATUS, editorModeMismatchMessage, parseEditorModeHeader, } from '../operating-mode/editor-mode-check.js';
|
|
18
23
|
import { runWithRequestTiming, setRequestTimingRoute, timeRequestPhase, } from '../utils/request-timing.js';
|
|
24
|
+
import { baseBranchOf } from '../utils/base-branch.js';
|
|
25
|
+
import { SYSTEM_USER_ID } from '../system-users.js';
|
|
19
26
|
const buildContext = async (options) => {
|
|
20
27
|
const services = options.services ?? (options.config ? await createCanopyServices(options.config) : undefined);
|
|
21
28
|
if (!services) {
|
|
22
29
|
throw new Error('CanopyCMS: config or services is required');
|
|
23
30
|
}
|
|
31
|
+
await recordConfiguredSparseCone(services.config);
|
|
32
|
+
await recordServedSchemaRegistry(services.config, services.entrySchemaRegistry);
|
|
24
33
|
const operatingMode = services.config.mode;
|
|
25
34
|
// Derived from the strategy, which resolves deploymentName; a literal here
|
|
26
35
|
// would miss a deployment-namespaced settings branch (say canopycms-settings-acme).
|
|
@@ -41,7 +50,7 @@ const buildContext = async (options) => {
|
|
|
41
50
|
}
|
|
42
51
|
// Read from services.config per-request, not a captured variable, so a
|
|
43
52
|
// refreshActiveBranch() update takes effect immediately.
|
|
44
|
-
const baseBranch = services.config
|
|
53
|
+
const baseBranch = baseBranchOf(services.config);
|
|
45
54
|
const activeBranch = services.config.defaultActiveBranch ?? baseBranch;
|
|
46
55
|
const shouldAutoCreate = clientOperatingStrategy(operatingMode).supportsBranching() &&
|
|
47
56
|
(branch === baseBranch || branch === activeBranch);
|
|
@@ -50,7 +59,7 @@ const buildContext = async (options) => {
|
|
|
50
59
|
const context = await manager.openOrCreateBranch({
|
|
51
60
|
branchName: branch,
|
|
52
61
|
mode: operatingMode,
|
|
53
|
-
createdBy:
|
|
62
|
+
createdBy: SYSTEM_USER_ID,
|
|
54
63
|
});
|
|
55
64
|
if (opts?.loadSchema && context) {
|
|
56
65
|
const contentRootName = services.config.contentRoot || 'content';
|
|
@@ -84,6 +93,11 @@ const parseQueryParams = (url) => {
|
|
|
84
93
|
return {};
|
|
85
94
|
}
|
|
86
95
|
};
|
|
96
|
+
/**
|
|
97
|
+
* The answer to a request with no accepted session. The body's `status: 401` is what the client
|
|
98
|
+
* detects sign-out from, so it stays 401 whatever HTTP status `unauthenticatedStatus` picks.
|
|
99
|
+
*/
|
|
100
|
+
const unauthenticatedResponse = (config, error) => jsonResponse({ ok: false, status: 401, error: error ?? 'Unauthorized' }, config.unauthenticatedStatus ?? 401);
|
|
87
101
|
/**
|
|
88
102
|
* The core handler behind every Canopy API request. A framework adapter
|
|
89
103
|
* (Next.js, Express, Hono) converts its request to a CanopyRequest, extracts
|
|
@@ -95,6 +109,26 @@ export function createCanopyRequestHandler(options) {
|
|
|
95
109
|
const mode = options.services?.config.mode ?? options.config?.mode;
|
|
96
110
|
assertAuthPluginAllowedForMode(options.authPlugin, mode);
|
|
97
111
|
const router = createCanopyRouter();
|
|
112
|
+
// Before auth, because a dev bundle against a prod server cannot authenticate: see
|
|
113
|
+
// editor-mode-check.ts.
|
|
114
|
+
let modeMismatchLogged = false;
|
|
115
|
+
const editorModeMismatchResponse = (req) => {
|
|
116
|
+
const editorMode = parseEditorModeHeader(req.header(EDITOR_MODE_HEADER));
|
|
117
|
+
if (!mode || !editorMode || editorMode === mode)
|
|
118
|
+
return null;
|
|
119
|
+
if (!modeMismatchLogged) {
|
|
120
|
+
modeMismatchLogged = true;
|
|
121
|
+
canopyLogWarn(`CanopyCMS: an editor built with NEXT_PUBLIC_CANOPY_MODE="${editorMode}" called this server, ` +
|
|
122
|
+
`which runs in "${mode}" mode. Its requests are refused with ${EDITOR_MODE_MISMATCH_STATUS} ` +
|
|
123
|
+
`until the editor is rebuilt with NEXT_PUBLIC_CANOPY_MODE=${mode}. Logged once per request handler.`);
|
|
124
|
+
}
|
|
125
|
+
return jsonResponse({
|
|
126
|
+
ok: false,
|
|
127
|
+
status: EDITOR_MODE_MISMATCH_STATUS,
|
|
128
|
+
code: 'EDITOR_MODE_MISMATCH',
|
|
129
|
+
error: editorModeMismatchMessage(editorMode),
|
|
130
|
+
}, EDITOR_MODE_MISMATCH_STATUS);
|
|
131
|
+
};
|
|
98
132
|
// Built once and reused across requests in the same warm container. On
|
|
99
133
|
// rejection (transient cold start, EFS not yet mounted) the cache is cleared
|
|
100
134
|
// (API-H3) so the NEXT request retries instead of replaying the rejection.
|
|
@@ -119,6 +153,9 @@ export function createCanopyRequestHandler(options) {
|
|
|
119
153
|
return jsonResponse({ ok: false, status: 404, error: 'Not found' }, 404);
|
|
120
154
|
}
|
|
121
155
|
setRequestTimingRoute(match.pattern.join('/') || '(malformed path)');
|
|
156
|
+
const modeMismatch = editorModeMismatchResponse(req);
|
|
157
|
+
if (modeMismatch)
|
|
158
|
+
return modeMismatch;
|
|
122
159
|
const apiCtx = await timeRequestPhase('context', getContext);
|
|
123
160
|
// In dev mode, re-check if the developer switched git branches
|
|
124
161
|
await timeRequestPhase('refreshBranch', () => apiCtx.services.refreshActiveBranch());
|
|
@@ -127,13 +164,30 @@ export function createCanopyRequestHandler(options) {
|
|
|
127
164
|
// any workspace provisioning below, so they can neither trigger expensive
|
|
128
165
|
// git operations nor read provisioning error details.
|
|
129
166
|
if (!authResult.success || !authResult.user) {
|
|
130
|
-
return
|
|
167
|
+
return unauthenticatedResponse(apiCtx.services.config, authResult.error);
|
|
168
|
+
}
|
|
169
|
+
// Whether a worker's recorded failure may be named in a not-ready 503: admins only, as in
|
|
170
|
+
// System health. With no remote there are no internal groups, so this is the bootstrap
|
|
171
|
+
// admins, and /admin is behind the same 503, so this answer is where they read it.
|
|
172
|
+
const mayReadWorkerFailure = () => isAdmin(authResultToCanopyUser(authResult, apiCtx.services.bootstrapAdminIds).groups);
|
|
173
|
+
// A prod base branch still pending since creation resolves here, once the
|
|
174
|
+
// worker has created the remote; until then this answers the not-ready 503.
|
|
175
|
+
try {
|
|
176
|
+
await timeRequestPhase('baseBranch', () => apiCtx.services.resolvePendingBaseBranch());
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
const notReady = workerNotReadyResponse(err, {
|
|
180
|
+
workerFailureDetail: mayReadWorkerFailure(),
|
|
181
|
+
});
|
|
182
|
+
if (notReady)
|
|
183
|
+
return notReady;
|
|
184
|
+
throw err;
|
|
131
185
|
}
|
|
132
186
|
// Provision the base/active branch workspace on first request, so the many
|
|
133
187
|
// endpoints that assume it exists (registry reads and the like) don't return
|
|
134
188
|
// confusing empty results on a cold start. A real provisioning error fails
|
|
135
189
|
// loudly here rather than surprising a later handler.
|
|
136
|
-
const baseBranch = apiCtx.services.config
|
|
190
|
+
const baseBranch = baseBranchOf(apiCtx.services.config);
|
|
137
191
|
try {
|
|
138
192
|
await apiCtx.getBranchContext(baseBranch);
|
|
139
193
|
}
|
|
@@ -151,7 +205,9 @@ export function createCanopyRequestHandler(options) {
|
|
|
151
205
|
// (authenticated) client. Credentials, which git errors can embed, are
|
|
152
206
|
// redacted even from the server logs.
|
|
153
207
|
console.error(`CanopyCMS: Failed to provision workspace for base branch '${baseBranch}': ${redactCredentials(message)}`);
|
|
154
|
-
const notReady = workerNotReadyResponse(err
|
|
208
|
+
const notReady = workerNotReadyResponse(err, {
|
|
209
|
+
workerFailureDetail: mayReadWorkerFailure(),
|
|
210
|
+
});
|
|
155
211
|
if (notReady)
|
|
156
212
|
return notReady;
|
|
157
213
|
return jsonResponse({
|
|
@@ -182,7 +238,9 @@ export function createCanopyRequestHandler(options) {
|
|
|
182
238
|
// No remote means no settings workspace, so /admin cannot load either:
|
|
183
239
|
// the worker has not created the remote yet, so every caller gets the
|
|
184
240
|
// not-ready 503, bootstrap admins included.
|
|
185
|
-
const notReady = workerNotReadyResponse(err
|
|
241
|
+
const notReady = workerNotReadyResponse(err, {
|
|
242
|
+
workerFailureDetail: mayReadWorkerFailure(),
|
|
243
|
+
});
|
|
186
244
|
if (notReady)
|
|
187
245
|
return notReady;
|
|
188
246
|
// Same trade as the base-branch degradation above: /admin is the recovery
|
|
@@ -220,7 +278,7 @@ export function createCanopyRequestHandler(options) {
|
|
|
220
278
|
}
|
|
221
279
|
}
|
|
222
280
|
if (user.type === 'anonymous') {
|
|
223
|
-
return
|
|
281
|
+
return unauthenticatedResponse(apiCtx.services.config, authResult.error);
|
|
224
282
|
}
|
|
225
283
|
const queryParams = parseQueryParams(req.url);
|
|
226
284
|
const mergedParams = { ...queryParams, ...match.params };
|
|
@@ -274,10 +332,17 @@ export function createCanopyRequestHandler(options) {
|
|
|
274
332
|
catch (err) {
|
|
275
333
|
// Last-resort boundary (API-C1): see handleRequest's doc comment above.
|
|
276
334
|
const message = getErrorMessage(err);
|
|
277
|
-
|
|
335
|
+
// Not per refused request: branch-schema-cache.ts logs each missing schema once per process.
|
|
336
|
+
if (!(err instanceof SchemaUnavailableError)) {
|
|
337
|
+
console.error('CanopyCMS: Unhandled error in API request handler:', message);
|
|
338
|
+
}
|
|
278
339
|
const notReady = workerNotReadyResponse(err);
|
|
279
340
|
if (notReady)
|
|
280
341
|
return notReady;
|
|
342
|
+
// Its message is a path and a parse error, neither of which helps an editor.
|
|
343
|
+
if (err instanceof BranchMetadataCorruptError) {
|
|
344
|
+
return jsonResponse({ ok: false, status: 500, error: BRANCH_METADATA_CORRUPT_MESSAGE }, 500);
|
|
345
|
+
}
|
|
281
346
|
return jsonResponse({ ok: false, status: 500, error: sanitizeErrorMessage(message) }, 500);
|
|
282
347
|
}
|
|
283
348
|
};
|
package/dist/http/types.d.ts
CHANGED
|
@@ -37,6 +37,8 @@ export interface CanopyBinaryResponse {
|
|
|
37
37
|
contentDisposition?: string;
|
|
38
38
|
cacheControl?: string;
|
|
39
39
|
etag?: string;
|
|
40
|
+
/** Redirect target, for a 3xx `status`; `body` is then empty. */
|
|
41
|
+
location?: string;
|
|
40
42
|
};
|
|
41
43
|
}
|
|
42
44
|
export declare function jsonResponse<T>(body: T, status?: number, headers?: Record<string, string>): CanopyResponse<T>;
|
|
@@ -2,8 +2,13 @@ import type { ApiResponse } from '../api/types.js';
|
|
|
2
2
|
import { type CanopyResponse } from './types.js';
|
|
3
3
|
export declare const WORKER_NOT_READY_MESSAGE = "CMS worker not ready \u2014 it may still be starting. Try again in a minute; if this persists, ask an admin to check the CMS worker.";
|
|
4
4
|
/**
|
|
5
|
-
* The 503 for a request that hit {@link RemoteNotReadyError},
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* The 503 for a request that hit {@link RemoteNotReadyError},
|
|
6
|
+
* {@link BranchProvisioningBusyError} or {@link SchemaUnavailableError}, or `undefined` for any
|
|
7
|
+
* other error. Retriable (with `Retry-After`) unless the worker recorded that its latest start
|
|
8
|
+
* failed; `workerFailureDetail` names that failure, for an authenticated admin only. The single
|
|
9
|
+
* mapping point for the core handler, the AI route and every framework adapter's backstop, so
|
|
10
|
+
* the message and `Retry-After` cannot diverge.
|
|
8
11
|
*/
|
|
9
|
-
export declare function workerNotReadyResponse(err: unknown
|
|
12
|
+
export declare function workerNotReadyResponse(err: unknown, options?: {
|
|
13
|
+
workerFailureDetail?: boolean;
|
|
14
|
+
}): CanopyResponse<ApiResponse> | undefined;
|
|
@@ -1,17 +1,70 @@
|
|
|
1
|
+
import { BranchProvisioningBusyError } from '../branch-provisioning.js';
|
|
1
2
|
import { RemoteNotReadyError } from '../git-manager.js';
|
|
3
|
+
import { sanitizeErrorMessage } from '../utils/error.js';
|
|
4
|
+
import { SchemaUnavailableError } from '../schema/schema-unavailable-error.js';
|
|
2
5
|
import { jsonResponse } from './types.js';
|
|
3
6
|
/** Seconds a client should wait before retrying while the worker boots. */
|
|
4
7
|
const RETRY_AFTER_SECONDS = '30';
|
|
8
|
+
/**
|
|
9
|
+
* Seconds before retrying an unavailable entry type. The editor's client never resends a 503
|
|
10
|
+
* (api/client.ts resends only a 429), so this informs other clients; the editor tells authors to
|
|
11
|
+
* reload.
|
|
12
|
+
*/
|
|
13
|
+
const SCHEMA_RETRY_AFTER_SECONDS = '60';
|
|
5
14
|
export const WORKER_NOT_READY_MESSAGE = 'CMS worker not ready — it may still be starting. Try again in a minute; if this persists, ask an admin to check the CMS worker.';
|
|
6
15
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
|
|
16
|
+
* An AWS account id, as twelve digits or the console's dddd-dddd-dddd. A secret's ARN in a
|
|
17
|
+
* worker error carries one; the region and names around it are what an admin needs.
|
|
18
|
+
*/
|
|
19
|
+
const ACCOUNT_ID = /(?<![0-9A-Za-z-])[0-9]{4}-[0-9]{4}-[0-9]{4}(?![0-9A-Za-z-])|(?<![0-9A-Za-z])[0-9]{12}(?![0-9A-Za-z])/g;
|
|
20
|
+
/**
|
|
21
|
+
* The 503 for a worker that recorded a startup failure. The worker's message, sanitized and with
|
|
22
|
+
* account ids masked, is included only with `detail`: it names secrets, paths and the repository,
|
|
23
|
+
* so it is for an admin the handler has authenticated, never anyone else.
|
|
24
|
+
*/
|
|
25
|
+
function workerFailureResponse(failure, detail) {
|
|
26
|
+
const named = detail
|
|
27
|
+
? ` (${failure.at}): ${sanitizeErrorMessage(failure.message).replace(ACCOUNT_ID, (id) => id.replace(/[0-9]/g, '*'))}`
|
|
28
|
+
: '.';
|
|
29
|
+
if (failure.current) {
|
|
30
|
+
return jsonResponse({
|
|
31
|
+
ok: false,
|
|
32
|
+
status: 503,
|
|
33
|
+
error: `The CMS worker failed to start${named} An admin needs to fix the worker; retrying will not help until then.`,
|
|
34
|
+
code: 'WORKER_FAILED',
|
|
35
|
+
}, 503);
|
|
36
|
+
}
|
|
37
|
+
return jsonResponse({
|
|
38
|
+
ok: false,
|
|
39
|
+
status: 503,
|
|
40
|
+
error: detail
|
|
41
|
+
? `CMS worker not ready — it is starting again after a failure${named} Try again in a minute; if this persists, ask an admin to check the CMS worker.`
|
|
42
|
+
: WORKER_NOT_READY_MESSAGE,
|
|
43
|
+
}, 503, { 'Retry-After': RETRY_AFTER_SECONDS });
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The 503 for a request that hit {@link RemoteNotReadyError},
|
|
47
|
+
* {@link BranchProvisioningBusyError} or {@link SchemaUnavailableError}, or `undefined` for any
|
|
48
|
+
* other error. Retriable (with `Retry-After`) unless the worker recorded that its latest start
|
|
49
|
+
* failed; `workerFailureDetail` names that failure, for an authenticated admin only. The single
|
|
50
|
+
* mapping point for the core handler, the AI route and every framework adapter's backstop, so
|
|
51
|
+
* the message and `Retry-After` cannot diverge.
|
|
10
52
|
*/
|
|
11
|
-
export function workerNotReadyResponse(err) {
|
|
12
|
-
if (
|
|
53
|
+
export function workerNotReadyResponse(err, options = {}) {
|
|
54
|
+
if (err instanceof SchemaUnavailableError) {
|
|
55
|
+
return jsonResponse({ ok: false, status: 503, error: err.message, code: 'SCHEMA_UNAVAILABLE' }, 503, { 'Retry-After': SCHEMA_RETRY_AFTER_SECONDS });
|
|
56
|
+
}
|
|
57
|
+
if (err instanceof RemoteNotReadyError && err.workerStartupFailure) {
|
|
58
|
+
return workerFailureResponse(err.workerStartupFailure, options.workerFailureDetail === true);
|
|
59
|
+
}
|
|
60
|
+
const message = err instanceof RemoteNotReadyError
|
|
61
|
+
? WORKER_NOT_READY_MESSAGE
|
|
62
|
+
: err instanceof BranchProvisioningBusyError
|
|
63
|
+
? err.message
|
|
64
|
+
: undefined;
|
|
65
|
+
if (message === undefined)
|
|
13
66
|
return undefined;
|
|
14
|
-
return jsonResponse({ ok: false, status: 503, error:
|
|
67
|
+
return jsonResponse({ ok: false, status: 503, error: message }, 503, {
|
|
15
68
|
'Retry-After': RETRY_AFTER_SECONDS,
|
|
16
69
|
});
|
|
17
70
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,3 +15,5 @@ export type { ListEntriesItem, ListEntriesOptions } from './content-listing.js';
|
|
|
15
15
|
export { assetUrl, assetSrcSet } from './assets/asset-url.js';
|
|
16
16
|
export type { AssetRef, AssetUrlOptions } from './assets/asset-url.js';
|
|
17
17
|
export type { OutputFormat, CropRect, TransformDirectives } from './assets/transform-directives.js';
|
|
18
|
+
export { fieldAttrs, scopeFieldProps } from './editor/field-props.js';
|
|
19
|
+
export type { FieldAttrs, FieldProps } from './editor/field-props.js';
|
package/dist/index.js
CHANGED
|
@@ -15,3 +15,6 @@ export { isCanopyRequest, isHeadersLike, extractHeaders, validateAuthContext, }
|
|
|
15
15
|
// Asset URL helpers — client-safe (no node: imports). Build/adjust transform URLs for <img>/srcset
|
|
16
16
|
// from stored asset refs without the server-only transform engine (assets/transform.ts, sharp).
|
|
17
17
|
export { assetUrl, assetSrcSet } from './assets/asset-url.js';
|
|
18
|
+
// Preview field marks — pure, so server components call them too (`canopycms/preview` is
|
|
19
|
+
// 'use client'); see editor/field-props.ts.
|
|
20
|
+
export { fieldAttrs, scopeFieldProps } from './editor/field-props.js';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BlockFieldConfig, FieldConfig, ObjectFieldConfig } from './config/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The key each object-list item and block carries in content, naming that item among its list's
|
|
4
|
+
* items for as long as it exists: a move or an edit keeps it, a copy gets a new one. Field comment
|
|
5
|
+
* threads name the items on their path by it (`CommentThread.itemKeys`). Beside `template` on a
|
|
6
|
+
* block, never inside its `value`; a schema may not define a field of this name.
|
|
7
|
+
*
|
|
8
|
+
* Dependency-free: the editor and the server both use this module.
|
|
9
|
+
*/
|
|
10
|
+
export declare const ITEM_KEY = "_key";
|
|
11
|
+
/** A usable item key: 1-64 letters, digits, `_` or `-`, starting with a letter or digit. */
|
|
12
|
+
export declare const isItemKey: (value: unknown) => value is string;
|
|
13
|
+
/** A new random item key: 12 Base58 characters. */
|
|
14
|
+
export declare function mintItemKey(): string;
|
|
15
|
+
/**
|
|
16
|
+
* How `withItemKeys` keys an item that lacks a usable key, or repeats one an earlier item of its
|
|
17
|
+
* list holds:
|
|
18
|
+
* - `content`: from a hash of the item, so every reader and writer of the same file names it
|
|
19
|
+
* alike before a save writes the key down, and an item added to the file later never inherits
|
|
20
|
+
* a key a removed one held unless it is the same content;
|
|
21
|
+
* - `random`: a fresh key;
|
|
22
|
+
* - `fresh`: a fresh key for EVERY item, keyed or not, as a copy needs.
|
|
23
|
+
*/
|
|
24
|
+
export type ItemKeyFill = 'content' | 'random' | 'fresh';
|
|
25
|
+
type ListField = ObjectFieldConfig | BlockFieldConfig;
|
|
26
|
+
/**
|
|
27
|
+
* `data` with every object-list item and block keyed, each unique in its list, nested lists
|
|
28
|
+
* included; the same object when nothing needed a key. A usable key is kept unless `fill` is
|
|
29
|
+
* `fresh`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function withItemKeys(fields: readonly FieldConfig[], data: Record<string, unknown>, fill: ItemKeyFill): Record<string, unknown>;
|
|
32
|
+
/** `item`, a copy about to join `field`'s list, with fresh keys for it and every item inside it. */
|
|
33
|
+
export declare function withFreshItemKeys<T>(field: ListField, item: T): T;
|
|
34
|
+
/**
|
|
35
|
+
* The keys of the list items on `canopyPath` in `value`, outermost first: what a new field thread
|
|
36
|
+
* stores to name them. Undefined when an item on the path has no usable key or the path isn't
|
|
37
|
+
* there.
|
|
38
|
+
*/
|
|
39
|
+
export declare function itemKeysOnPath(fields: readonly FieldConfig[], value: Record<string, unknown>, canopyPath: string): string[] | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Where a field thread made at `canopyPath` on the items named by `itemKeys` is in `value` now:
|
|
42
|
+
* its path with each index replaced by that item's current one, or `null` when one of the items
|
|
43
|
+
* is gone. A path with no keys (one through no list) is returned as it is.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveThreadPath(fields: readonly FieldConfig[], value: Record<string, unknown>, canopyPath: string, itemKeys: readonly string[] | undefined): string | null;
|
|
46
|
+
export {};
|