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/api/permissions.js
CHANGED
|
@@ -2,6 +2,8 @@ import { z } from 'zod';
|
|
|
2
2
|
import { loadPermissionsFile, mutatePermissionsFile, loadGroupsFile, deriveInternalGroups, SettingsVersionConflictError, SettingsFileConflictError, } from '../authorization/index.js';
|
|
3
3
|
import { permissionPathSchema } from './validators.js';
|
|
4
4
|
import { MAX_ENTRIES_PER_PAGE } from './entries-constants.js';
|
|
5
|
+
import { MAX_USER_METADATA_BATCH } from './users-constants.js';
|
|
6
|
+
import { lookupUsersMetadata } from '../auth/user-metadata-lookup.js';
|
|
5
7
|
import { defineEndpoint } from './route-builder.js';
|
|
6
8
|
import { getSettingsBranchContext, commitSettings } from './settings-helpers.js';
|
|
7
9
|
import { getErrorMessage, sanitizeErrorMessage } from '../utils/error.js';
|
|
@@ -29,6 +31,10 @@ const searchUsersParamsSchema = z.object({
|
|
|
29
31
|
const getUserMetadataParamsSchema = z.object({
|
|
30
32
|
userId: z.string(),
|
|
31
33
|
});
|
|
34
|
+
const userIdSchema = z.string().min(1).max(256);
|
|
35
|
+
const batchGetUserMetadataBodySchema = z.object({
|
|
36
|
+
userIds: z.array(userIdSchema).min(1).max(MAX_USER_METADATA_BATCH),
|
|
37
|
+
});
|
|
32
38
|
const getPermissionsHandler = async (_gc, ctx, _req) => {
|
|
33
39
|
try {
|
|
34
40
|
const result = await getSettingsBranchContext(ctx);
|
|
@@ -82,6 +88,7 @@ const updatePermissionsHandler = async (_gc, ctx, req, body) => {
|
|
|
82
88
|
branchRoot: context.branchRoot,
|
|
83
89
|
fileName: 'permissions.json',
|
|
84
90
|
message: 'Update permissions',
|
|
91
|
+
actor: req.user,
|
|
85
92
|
mode,
|
|
86
93
|
});
|
|
87
94
|
if (!commitResult.pushed) {
|
|
@@ -95,7 +102,7 @@ const updatePermissionsHandler = async (_gc, ctx, req, body) => {
|
|
|
95
102
|
}
|
|
96
103
|
catch (error) {
|
|
97
104
|
if (error instanceof SettingsVersionConflictError) {
|
|
98
|
-
return { ok: false, status: 409, error: error.message };
|
|
105
|
+
return { ok: false, status: 409, error: error.message, code: 'SETTINGS_CHANGED' };
|
|
99
106
|
}
|
|
100
107
|
if (error instanceof SettingsFileConflictError) {
|
|
101
108
|
return { ok: false, status: 409, error: 'Settings are busy, please try again.' };
|
|
@@ -198,8 +205,29 @@ const getUserMetadataHandler = async (_gc, ctx, req, params) => {
|
|
|
198
205
|
return { ok: false, status: 501, error: 'Auth plugin not configured' };
|
|
199
206
|
}
|
|
200
207
|
try {
|
|
201
|
-
const
|
|
202
|
-
return { ok: true, status: 200, data: { user } };
|
|
208
|
+
const users = await lookupUsersMetadata(authPlugin, [params.userId]);
|
|
209
|
+
return { ok: true, status: 200, data: { user: users.get(params.userId) ?? null } };
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
return {
|
|
213
|
+
ok: false,
|
|
214
|
+
status: 500,
|
|
215
|
+
error: sanitizeErrorMessage(getErrorMessage(error)),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* Get metadata for many users at once (for UI display)
|
|
221
|
+
*/
|
|
222
|
+
const batchGetUserMetadataHandler = async (_gc, ctx, _req, body) => {
|
|
223
|
+
const authPlugin = ctx.authPlugin;
|
|
224
|
+
if (!authPlugin) {
|
|
225
|
+
return { ok: false, status: 501, error: 'Auth plugin not configured' };
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
const found = await lookupUsersMetadata(authPlugin, body.userIds);
|
|
229
|
+
const users = [...found.values()].filter((user) => user !== null);
|
|
230
|
+
return { ok: true, status: 200, data: { users } };
|
|
203
231
|
}
|
|
204
232
|
catch (error) {
|
|
205
233
|
return {
|
|
@@ -288,6 +316,24 @@ const getUserMetadata = defineEndpoint({
|
|
|
288
316
|
guards: ['privileged'],
|
|
289
317
|
handler: getUserMetadataHandler,
|
|
290
318
|
});
|
|
319
|
+
/**
|
|
320
|
+
* Get metadata for up to MAX_USER_METADATA_BATCH users (admin/reviewer only)
|
|
321
|
+
* POST /users/batch
|
|
322
|
+
*/
|
|
323
|
+
const batchGetUserMetadata = defineEndpoint({
|
|
324
|
+
namespace: 'permissions',
|
|
325
|
+
name: 'batchGetUserMetadata',
|
|
326
|
+
method: 'POST',
|
|
327
|
+
readOnly: true,
|
|
328
|
+
path: '/users/batch',
|
|
329
|
+
body: batchGetUserMetadataBodySchema,
|
|
330
|
+
bodyType: 'BatchGetUserMetadataBody',
|
|
331
|
+
responseType: 'BatchGetUserMetadataResponse',
|
|
332
|
+
response: {},
|
|
333
|
+
defaultMockData: { users: [] },
|
|
334
|
+
guards: ['privileged'],
|
|
335
|
+
handler: batchGetUserMetadataHandler,
|
|
336
|
+
});
|
|
291
337
|
/**
|
|
292
338
|
* Exported routes for router registration
|
|
293
339
|
*/
|
|
@@ -297,4 +343,5 @@ export const PERMISSION_ROUTES = {
|
|
|
297
343
|
searchUsers: searchUsers,
|
|
298
344
|
listGroups: listGroups,
|
|
299
345
|
getUserMetadata: getUserMetadata,
|
|
346
|
+
batchGetUserMetadata: batchGetUserMetadata,
|
|
300
347
|
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deadlines for the editor's API requests. A request that never answers (network drop, laptop
|
|
3
|
+
* sleep) must not hold a busy state open forever, so every client call runs under a deadline and,
|
|
4
|
+
* past it, rejects with {@link ApiTimeoutError}: a thrown error, as a network failure is, but
|
|
5
|
+
* distinguishable from one. HTTP error statuses stay `ok: false` responses.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* @internal Exported for tests.
|
|
9
|
+
*
|
|
10
|
+
* How long each class of request may take. `standard` is past the 60 s an API behind CloudFront
|
|
11
|
+
* gets (canopycms-cdk's `assertOriginReadTimeout`), so a server still working answers, or its
|
|
12
|
+
* proxy's 504 does, before the editor gives up; reads get it too, since any request may first
|
|
13
|
+
* provision the base branch's workspace (`http/handler.ts`). `long` is
|
|
14
|
+
* for the operations that legitimately run longer: branch create, submit, admin scans and
|
|
15
|
+
* repairs, and an upload without progress.
|
|
16
|
+
*/
|
|
17
|
+
export declare const REQUEST_TIMEOUT_MS: {
|
|
18
|
+
readonly standard: 75000;
|
|
19
|
+
readonly long: 180000;
|
|
20
|
+
};
|
|
21
|
+
/** An endpoint's timeout class; `none` waits as long as the browser does. */
|
|
22
|
+
export type RequestTimeoutClass = keyof typeof REQUEST_TIMEOUT_MS | 'none';
|
|
23
|
+
/** Per-call options every API client method accepts as its last argument. */
|
|
24
|
+
export interface RequestOptions {
|
|
25
|
+
/** Aborts the request; the call then rejects with the signal's `reason`. */
|
|
26
|
+
signal?: AbortSignal;
|
|
27
|
+
/** Replaces the endpoint's timeout, in ms; `null` waits as long as the browser does. */
|
|
28
|
+
timeoutMs?: number | null;
|
|
29
|
+
}
|
|
30
|
+
/** @internal Exported for tests. A timed-out read's message: retrying it is safe. */
|
|
31
|
+
export declare const REQUEST_TIMED_OUT_MESSAGE = "The server didn't answer in time. Check your connection and try again.";
|
|
32
|
+
/** @internal Exported for tests. A timed-out write's message: the server may have acted on it. */
|
|
33
|
+
export declare const WRITE_TIMED_OUT_MESSAGE = "The server didn't answer, so this may have gone through anyway. Check before trying again.";
|
|
34
|
+
/**
|
|
35
|
+
* A request ran past its deadline and was abandoned; the server may still have acted on it.
|
|
36
|
+
* `readOnly` defaults to GET; a body-taking lookup passes it (`EndpointConfigBase['readOnly']`).
|
|
37
|
+
*/
|
|
38
|
+
export declare class ApiTimeoutError extends Error {
|
|
39
|
+
readonly method: string;
|
|
40
|
+
readonly path: string;
|
|
41
|
+
readonly timeoutMs: number;
|
|
42
|
+
readonly name = "ApiTimeoutError";
|
|
43
|
+
constructor(method: string, path: string, timeoutMs: number, readOnly?: boolean);
|
|
44
|
+
}
|
|
45
|
+
export declare function isApiTimeoutError(err: unknown): err is ApiTimeoutError;
|
|
46
|
+
/** The timeout, in ms or `null` for none, that a call with `options` to a `timeout`-class endpoint gets. */
|
|
47
|
+
export declare function resolveTimeoutMs(timeout: RequestTimeoutClass, options: RequestOptions | undefined): number | null;
|
|
48
|
+
/**
|
|
49
|
+
* Run `run` with a signal that aborts at the deadline or when `options.signal` does, and settle
|
|
50
|
+
* then even if `run` ignores its signal (a custom `fetch` may). Past the deadline the call
|
|
51
|
+
* rejects with an {@link ApiTimeoutError}; on the caller's abort, with the caller's reason.
|
|
52
|
+
*/
|
|
53
|
+
export declare function runWithDeadline<T>(run: (signal: AbortSignal) => Promise<T>, request: {
|
|
54
|
+
method: string;
|
|
55
|
+
path: string;
|
|
56
|
+
timeoutMs: number | null;
|
|
57
|
+
signal?: AbortSignal;
|
|
58
|
+
readOnly?: boolean;
|
|
59
|
+
}): Promise<T>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deadlines for the editor's API requests. A request that never answers (network drop, laptop
|
|
3
|
+
* sleep) must not hold a busy state open forever, so every client call runs under a deadline and,
|
|
4
|
+
* past it, rejects with {@link ApiTimeoutError}: a thrown error, as a network failure is, but
|
|
5
|
+
* distinguishable from one. HTTP error statuses stay `ok: false` responses.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* @internal Exported for tests.
|
|
9
|
+
*
|
|
10
|
+
* How long each class of request may take. `standard` is past the 60 s an API behind CloudFront
|
|
11
|
+
* gets (canopycms-cdk's `assertOriginReadTimeout`), so a server still working answers, or its
|
|
12
|
+
* proxy's 504 does, before the editor gives up; reads get it too, since any request may first
|
|
13
|
+
* provision the base branch's workspace (`http/handler.ts`). `long` is
|
|
14
|
+
* for the operations that legitimately run longer: branch create, submit, admin scans and
|
|
15
|
+
* repairs, and an upload without progress.
|
|
16
|
+
*/
|
|
17
|
+
export const REQUEST_TIMEOUT_MS = {
|
|
18
|
+
standard: 75_000,
|
|
19
|
+
long: 180_000,
|
|
20
|
+
};
|
|
21
|
+
/** @internal Exported for tests. A timed-out read's message: retrying it is safe. */
|
|
22
|
+
export const REQUEST_TIMED_OUT_MESSAGE = "The server didn't answer in time. Check your connection and try again.";
|
|
23
|
+
/** @internal Exported for tests. A timed-out write's message: the server may have acted on it. */
|
|
24
|
+
export const WRITE_TIMED_OUT_MESSAGE = "The server didn't answer, so this may have gone through anyway. Check before trying again.";
|
|
25
|
+
/**
|
|
26
|
+
* A request ran past its deadline and was abandoned; the server may still have acted on it.
|
|
27
|
+
* `readOnly` defaults to GET; a body-taking lookup passes it (`EndpointConfigBase['readOnly']`).
|
|
28
|
+
*/
|
|
29
|
+
export class ApiTimeoutError extends Error {
|
|
30
|
+
constructor(method, path, timeoutMs, readOnly = method === 'GET') {
|
|
31
|
+
super(readOnly ? REQUEST_TIMED_OUT_MESSAGE : WRITE_TIMED_OUT_MESSAGE);
|
|
32
|
+
this.method = method;
|
|
33
|
+
this.path = path;
|
|
34
|
+
this.timeoutMs = timeoutMs;
|
|
35
|
+
this.name = 'ApiTimeoutError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function isApiTimeoutError(err) {
|
|
39
|
+
return err instanceof ApiTimeoutError;
|
|
40
|
+
}
|
|
41
|
+
/** The timeout, in ms or `null` for none, that a call with `options` to a `timeout`-class endpoint gets. */
|
|
42
|
+
export function resolveTimeoutMs(timeout, options) {
|
|
43
|
+
if (options?.timeoutMs !== undefined)
|
|
44
|
+
return options.timeoutMs;
|
|
45
|
+
return timeout === 'none' ? null : REQUEST_TIMEOUT_MS[timeout];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Run `run` with a signal that aborts at the deadline or when `options.signal` does, and settle
|
|
49
|
+
* then even if `run` ignores its signal (a custom `fetch` may). Past the deadline the call
|
|
50
|
+
* rejects with an {@link ApiTimeoutError}; on the caller's abort, with the caller's reason.
|
|
51
|
+
*/
|
|
52
|
+
export async function runWithDeadline(run, request) {
|
|
53
|
+
const { signal: callerSignal, timeoutMs } = request;
|
|
54
|
+
callerSignal?.throwIfAborted();
|
|
55
|
+
const controller = new AbortController();
|
|
56
|
+
const onCallerAbort = () => controller.abort(callerSignal?.reason);
|
|
57
|
+
callerSignal?.addEventListener('abort', onCallerAbort, { once: true });
|
|
58
|
+
const timer = timeoutMs === null
|
|
59
|
+
? undefined
|
|
60
|
+
: setTimeout(() => controller.abort(new ApiTimeoutError(request.method, request.path, timeoutMs, request.readOnly)), timeoutMs);
|
|
61
|
+
const aborted = new Promise((_, reject) => {
|
|
62
|
+
controller.signal.addEventListener('abort', () => reject(controller.signal.reason), {
|
|
63
|
+
once: true,
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
try {
|
|
67
|
+
return await Promise.race([run(controller.signal), aborted]);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
clearTimeout(timer);
|
|
71
|
+
callerSignal?.removeEventListener('abort', onCallerAbort);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -25,17 +25,16 @@ const resolveReferencesHandler = async (gc, ctx, req, params, body) => {
|
|
|
25
25
|
const checkAccess = await ctx.services.createContentAccessChecker(branchContext, branchContext.branchRoot, req.user);
|
|
26
26
|
const access = (logicalPath) => checkAccess(logicalPath, 'read').allowed;
|
|
27
27
|
// The resolution `read()` applies to a reference field, so live preview shows this user what
|
|
28
|
-
// `read()` would: the target's data,
|
|
29
|
-
//
|
|
28
|
+
// `read()` would: the target's data, a `RestrictedReference` for a target they may not read,
|
|
29
|
+
// or a `MissingReference` for an id naming no entry. The target's own references stay ids, as
|
|
30
|
+
// in `read()`.
|
|
30
31
|
const resolved = {};
|
|
31
32
|
for (const id of ids) {
|
|
32
33
|
try {
|
|
33
|
-
|
|
34
|
-
if (value)
|
|
35
|
-
resolved[id] = value;
|
|
34
|
+
resolved[id] = await store.resolveReferenceTarget(id, access);
|
|
36
35
|
}
|
|
37
36
|
catch (error) {
|
|
38
|
-
// An id
|
|
37
|
+
// An id whose lookup throws is omitted rather than failing the whole request.
|
|
39
38
|
console.error(`Failed to resolve reference ID ${id}:`, error);
|
|
40
39
|
}
|
|
41
40
|
}
|
|
@@ -47,7 +46,8 @@ const resolveReferencesHandler = async (gc, ctx, req, params, body) => {
|
|
|
47
46
|
};
|
|
48
47
|
/**
|
|
49
48
|
* Resolve reference IDs as a reference field would: full target data, or title + URL tagged
|
|
50
|
-
* `unavailable` for a target the user may not read
|
|
49
|
+
* `unavailable` for a target the user may not read, or `{ id, unavailable: true, reason: 'missing' }`
|
|
50
|
+
* for an id naming no entry.
|
|
51
51
|
* POST /:branch/resolve-references
|
|
52
52
|
* Body: { ids: string[] }
|
|
53
53
|
*/
|
|
@@ -55,6 +55,7 @@ const resolveReferences = defineEndpoint({
|
|
|
55
55
|
namespace: 'content',
|
|
56
56
|
name: 'resolveReferences',
|
|
57
57
|
method: 'POST',
|
|
58
|
+
readOnly: true,
|
|
58
59
|
path: '/:branch/resolve-references',
|
|
59
60
|
params: resolveReferencesParamsSchema,
|
|
60
61
|
body: resolveReferencesBodySchema,
|
|
@@ -34,6 +34,10 @@ export interface RouteMetadata {
|
|
|
34
34
|
defaultMockData?: unknown;
|
|
35
35
|
/** Casts to apply to mock data fields for branded types */
|
|
36
36
|
mockDataCasts?: MockDataCasts;
|
|
37
|
+
/** See `EndpointConfigBase['clientTimeout']`. */
|
|
38
|
+
clientTimeout?: 'long' | 'none';
|
|
39
|
+
/** See `EndpointConfigBase['readOnly']`. */
|
|
40
|
+
readOnly?: true;
|
|
37
41
|
}
|
|
38
42
|
/**
|
|
39
43
|
* Route definition created by defineEndpoint.
|
|
@@ -100,6 +104,16 @@ interface EndpointConfigBase<TParams extends z.ZodType | undefined, TBody extend
|
|
|
100
104
|
mockDataCasts?: MockDataCasts;
|
|
101
105
|
/** See `RouteDefinition['bodyFormat']` above. */
|
|
102
106
|
bodyFormat?: 'multipart';
|
|
107
|
+
/**
|
|
108
|
+
* The generated client's timeout for this endpoint, when not `standard`; see
|
|
109
|
+
* `REQUEST_TIMEOUT_MS` in request-deadline.ts.
|
|
110
|
+
*/
|
|
111
|
+
clientTimeout?: 'long' | 'none';
|
|
112
|
+
/**
|
|
113
|
+
* A non-GET endpoint that changes nothing, such as a lookup taking its input in a body. Its
|
|
114
|
+
* timeout then says to try again rather than that it may have gone through (`ApiTimeoutError`).
|
|
115
|
+
*/
|
|
116
|
+
readOnly?: true;
|
|
103
117
|
}
|
|
104
118
|
/** Config for an endpoint without guards */
|
|
105
119
|
interface UnguardedEndpointConfig<TParams extends z.ZodType | undefined, TBody extends z.ZodType | undefined, TResponse> extends EndpointConfigBase<TParams, TBody> {
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
* - Self-documents the API surface
|
|
10
10
|
*/
|
|
11
11
|
import { executeGuards } from './guards.js';
|
|
12
|
+
function isOkResponse(response) {
|
|
13
|
+
return (typeof response === 'object' && response !== null && 'ok' in response && response.ok === true);
|
|
14
|
+
}
|
|
12
15
|
/**
|
|
13
16
|
* Global registry - generator reads this
|
|
14
17
|
*/
|
|
@@ -28,6 +31,8 @@ export function defineEndpoint(config) {
|
|
|
28
31
|
responseTypeName: config.responseType,
|
|
29
32
|
defaultMockData: config.defaultMockData,
|
|
30
33
|
mockDataCasts: config.mockDataCasts,
|
|
34
|
+
clientTimeout: config.clientTimeout,
|
|
35
|
+
readOnly: config.readOnly,
|
|
31
36
|
});
|
|
32
37
|
// Convert path template to pattern array for router
|
|
33
38
|
const pattern = config.path.split('/').filter(Boolean);
|
|
@@ -71,6 +76,7 @@ export function defineEndpoint(config) {
|
|
|
71
76
|
if (config.guards && config.guards.length > 0) {
|
|
72
77
|
const guards = config.guards;
|
|
73
78
|
const guardedHandler = config.handler;
|
|
79
|
+
const recordsEditor = guards.includes('writableBranch');
|
|
74
80
|
handler = async (ctx, req, ...args) => {
|
|
75
81
|
// Extract params from args (first arg after ctx/req if present)
|
|
76
82
|
const params = args[0] ?? {};
|
|
@@ -79,7 +85,14 @@ export function defineEndpoint(config) {
|
|
|
79
85
|
return guardResult.response;
|
|
80
86
|
}
|
|
81
87
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
82
|
-
|
|
88
|
+
const response = await guardedHandler(guardResult.guardContext, ctx, req, ...args);
|
|
89
|
+
// Every 'writableBranch' endpoint changes the branch's working tree, so one that succeeds
|
|
90
|
+
// makes its user an editor of the branch.
|
|
91
|
+
if (recordsEditor && isOkResponse(response)) {
|
|
92
|
+
const { branchContext } = guardResult.guardContext;
|
|
93
|
+
await ctx.services.recordBranchEditor(branchContext, req.user);
|
|
94
|
+
}
|
|
95
|
+
return response;
|
|
83
96
|
};
|
|
84
97
|
}
|
|
85
98
|
else {
|
package/dist/api/schema.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import type { ApiResponse } from './types.js';
|
|
9
|
-
import type { ContentFormat, EntrySchema } from '../config/index.js';
|
|
9
|
+
import type { EntryTypeUnavailable, ContentFormat, EntrySchema } from '../config/index.js';
|
|
10
10
|
import { type LogicalPath, type ContentId } from '../paths/index.js';
|
|
11
11
|
/** Entry type in wire format: schemaRef instead of resolved schema */
|
|
12
12
|
interface WireEntryType {
|
|
@@ -16,6 +16,7 @@ interface WireEntryType {
|
|
|
16
16
|
readonly label?: string;
|
|
17
17
|
readonly default?: boolean;
|
|
18
18
|
readonly maxItems?: number;
|
|
19
|
+
readonly unavailable?: EntryTypeUnavailable;
|
|
19
20
|
}
|
|
20
21
|
/** Collection in wire format (entry types carry schemaRef, not resolved schema) */
|
|
21
22
|
interface WireCollectionConfig {
|
|
@@ -52,6 +53,7 @@ type WireFlatSchemaItem = {
|
|
|
52
53
|
schemaRef: string;
|
|
53
54
|
default?: boolean;
|
|
54
55
|
maxItems?: number;
|
|
56
|
+
unavailable?: EntryTypeUnavailable;
|
|
55
57
|
};
|
|
56
58
|
interface SchemaResponse {
|
|
57
59
|
flatSchema: WireFlatSchemaItem[];
|
|
@@ -339,18 +341,18 @@ export declare const updateEntryType: import("./route-builder.js").RouteDefiniti
|
|
|
339
341
|
branch: string & {
|
|
340
342
|
readonly __brand: "BranchName";
|
|
341
343
|
};
|
|
342
|
-
entryTypeName: string;
|
|
343
344
|
collectionPath: string & {
|
|
344
345
|
readonly __brand: "LogicalPath";
|
|
345
346
|
};
|
|
347
|
+
entryTypeName: string;
|
|
346
348
|
}, {
|
|
347
349
|
branch: string & {
|
|
348
350
|
readonly __brand: "BranchName";
|
|
349
351
|
};
|
|
350
|
-
entryTypeName: string;
|
|
351
352
|
collectionPath: string & {
|
|
352
353
|
readonly __brand: "LogicalPath";
|
|
353
354
|
};
|
|
355
|
+
entryTypeName: string;
|
|
354
356
|
}>, z.ZodObject<{
|
|
355
357
|
label: z.ZodOptional<z.ZodString>;
|
|
356
358
|
format: z.ZodOptional<z.ZodEnum<["md", "mdx", "json", "yaml"]>>;
|
|
@@ -383,18 +385,18 @@ export declare const removeEntryType: import("./route-builder.js").RouteDefiniti
|
|
|
383
385
|
branch: string & {
|
|
384
386
|
readonly __brand: "BranchName";
|
|
385
387
|
};
|
|
386
|
-
entryTypeName: string;
|
|
387
388
|
collectionPath: string & {
|
|
388
389
|
readonly __brand: "LogicalPath";
|
|
389
390
|
};
|
|
391
|
+
entryTypeName: string;
|
|
390
392
|
}, {
|
|
391
393
|
branch: string & {
|
|
392
394
|
readonly __brand: "BranchName";
|
|
393
395
|
};
|
|
394
|
-
entryTypeName: string;
|
|
395
396
|
collectionPath: string & {
|
|
396
397
|
readonly __brand: "LogicalPath";
|
|
397
398
|
};
|
|
399
|
+
entryTypeName: string;
|
|
398
400
|
}>, undefined, RemoveEntryTypeApiResponse>;
|
|
399
401
|
/**
|
|
400
402
|
* PATCH /:branch/schema/order/...collectionPath - Update item order
|
|
@@ -616,18 +618,18 @@ export declare const SCHEMA_ROUTES: {
|
|
|
616
618
|
branch: string & {
|
|
617
619
|
readonly __brand: "BranchName";
|
|
618
620
|
};
|
|
619
|
-
entryTypeName: string;
|
|
620
621
|
collectionPath: string & {
|
|
621
622
|
readonly __brand: "LogicalPath";
|
|
622
623
|
};
|
|
624
|
+
entryTypeName: string;
|
|
623
625
|
}, {
|
|
624
626
|
branch: string & {
|
|
625
627
|
readonly __brand: "BranchName";
|
|
626
628
|
};
|
|
627
|
-
entryTypeName: string;
|
|
628
629
|
collectionPath: string & {
|
|
629
630
|
readonly __brand: "LogicalPath";
|
|
630
631
|
};
|
|
632
|
+
entryTypeName: string;
|
|
631
633
|
}>, z.ZodObject<{
|
|
632
634
|
label: z.ZodOptional<z.ZodString>;
|
|
633
635
|
format: z.ZodOptional<z.ZodEnum<["md", "mdx", "json", "yaml"]>>;
|
|
@@ -655,18 +657,18 @@ export declare const SCHEMA_ROUTES: {
|
|
|
655
657
|
branch: string & {
|
|
656
658
|
readonly __brand: "BranchName";
|
|
657
659
|
};
|
|
658
|
-
entryTypeName: string;
|
|
659
660
|
collectionPath: string & {
|
|
660
661
|
readonly __brand: "LogicalPath";
|
|
661
662
|
};
|
|
663
|
+
entryTypeName: string;
|
|
662
664
|
}, {
|
|
663
665
|
branch: string & {
|
|
664
666
|
readonly __brand: "BranchName";
|
|
665
667
|
};
|
|
666
|
-
entryTypeName: string;
|
|
667
668
|
collectionPath: string & {
|
|
668
669
|
readonly __brand: "LogicalPath";
|
|
669
670
|
};
|
|
671
|
+
entryTypeName: string;
|
|
670
672
|
}>, undefined, RemoveEntryTypeApiResponse>;
|
|
671
673
|
readonly updateOrder: import("./route-builder.js").RouteDefinition<z.ZodObject<{
|
|
672
674
|
branch: z.ZodType<import("../paths/index.js").BranchName, z.ZodTypeDef, import("../paths/index.js").BranchName>;
|
package/dist/api/schema.js
CHANGED
|
@@ -57,6 +57,7 @@ function toWireEntryType(et, registry) {
|
|
|
57
57
|
...(et.label !== undefined && { label: et.label }),
|
|
58
58
|
...(et.default !== undefined && { default: et.default }),
|
|
59
59
|
...(et.maxItems !== undefined && { maxItems: et.maxItems }),
|
|
60
|
+
...(et.unavailable && { unavailable: et.unavailable }),
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
63
|
function toWireCollection(col, registry) {
|
|
@@ -99,6 +100,7 @@ function toWireFlatSchema(items, registry) {
|
|
|
99
100
|
schemaRef: resolveSchemaRef(item, registry),
|
|
100
101
|
...(item.default !== undefined && { default: item.default }),
|
|
101
102
|
...(item.maxItems !== undefined && { maxItems: item.maxItems }),
|
|
103
|
+
...(item.unavailable && { unavailable: item.unavailable }),
|
|
102
104
|
};
|
|
103
105
|
});
|
|
104
106
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ApiContext } from './types.js';
|
|
2
2
|
import type { OperatingMode } from '../operating-mode/index.js';
|
|
3
|
+
import type { CanopyUser } from '../user.js';
|
|
3
4
|
/**
|
|
4
5
|
* Get the appropriate root path for settings (permissions/groups).
|
|
5
6
|
* Returns the settings root managed by the settings workspace.
|
|
@@ -30,7 +31,8 @@ export interface CommitSettingsResult {
|
|
|
30
31
|
/**
|
|
31
32
|
* Commit and push settings changes based on the mode.
|
|
32
33
|
* Both prod and dev use commitToSettingsBranch.
|
|
33
|
-
* Settings changes are never reviewed through a PR (see commitToSettingsBranch)
|
|
34
|
+
* Settings changes are never reviewed through a PR (see commitToSettingsBranch), and the bot
|
|
35
|
+
* authors the commit, so its trailers, not its author line, name who made the change.
|
|
34
36
|
*/
|
|
35
37
|
export declare function commitSettings(ctx: ApiContext, options: {
|
|
36
38
|
context: {
|
|
@@ -39,5 +41,7 @@ export declare function commitSettings(ctx: ApiContext, options: {
|
|
|
39
41
|
branchRoot: string;
|
|
40
42
|
fileName: string;
|
|
41
43
|
message: string;
|
|
44
|
+
/** The user making the change, named in the commit's trailers as a submit names its editors. */
|
|
45
|
+
actor: CanopyUser;
|
|
42
46
|
mode: OperatingMode;
|
|
43
47
|
}): Promise<CommitSettingsResult>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { operatingStrategy } from '../operating-mode/index.js';
|
|
2
2
|
import { sanitizeErrorMessage } from '../utils/error.js';
|
|
3
|
+
import { appendTrailers, buildEditorTrailers, submissionEditorFromUser, } from '../submission-attribution.js';
|
|
3
4
|
/**
|
|
4
5
|
* Get the appropriate root path for settings (permissions/groups).
|
|
5
6
|
* Returns the settings root managed by the settings workspace.
|
|
@@ -23,7 +24,8 @@ export async function getSettingsBranchContext(ctx) {
|
|
|
23
24
|
/**
|
|
24
25
|
* Commit and push settings changes based on the mode.
|
|
25
26
|
* Both prod and dev use commitToSettingsBranch.
|
|
26
|
-
* Settings changes are never reviewed through a PR (see commitToSettingsBranch)
|
|
27
|
+
* Settings changes are never reviewed through a PR (see commitToSettingsBranch), and the bot
|
|
28
|
+
* authors the commit, so its trailers, not its author line, name who made the change.
|
|
27
29
|
*/
|
|
28
30
|
export async function commitSettings(ctx, options) {
|
|
29
31
|
const strategy = operatingStrategy(options.mode);
|
|
@@ -34,10 +36,16 @@ export async function commitSettings(ctx, options) {
|
|
|
34
36
|
}
|
|
35
37
|
// For modes that use separate settings branch, commit to settings branch
|
|
36
38
|
if (strategy.usesSeparateSettingsBranch()) {
|
|
39
|
+
const actor = submissionEditorFromUser(options.actor);
|
|
40
|
+
const { config } = ctx.services;
|
|
41
|
+
const trailers = buildEditorTrailers(actor ? [actor] : [], {
|
|
42
|
+
editedBy: config.gitEditedByTrailers ?? true,
|
|
43
|
+
coAuthoredBy: config.gitCoAuthoredByTrailers ?? false,
|
|
44
|
+
});
|
|
37
45
|
const result = await ctx.services.commitToSettingsBranch({
|
|
38
46
|
branchRoot: options.branchRoot,
|
|
39
47
|
files: options.fileName,
|
|
40
|
-
message: options.message,
|
|
48
|
+
message: appendTrailers(options.message, trailers),
|
|
41
49
|
});
|
|
42
50
|
if (!result.pushed) {
|
|
43
51
|
console.warn(`${options.message} committed but not pushed:`, result.error);
|
package/dist/api/types.d.ts
CHANGED
|
@@ -48,4 +48,22 @@ export interface ApiResponse<TData = unknown> {
|
|
|
48
48
|
fieldPath: string;
|
|
49
49
|
message: string;
|
|
50
50
|
}>;
|
|
51
|
+
/** A machine-readable reason for some failures; see {@link ApiErrorCode}. */
|
|
52
|
+
code?: ApiErrorCode;
|
|
51
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* `SCHEMA_UNAVAILABLE`: the entry's type names an entry schema the running code lacks (a 503,
|
|
56
|
+
* see `SchemaUnavailableError`). `WORKER_FAILED`: the CMS worker recorded that its latest start
|
|
57
|
+
* failed, so a retry will not help until an admin fixes it (a 503 with no `Retry-After`).
|
|
58
|
+
* `WRITE_OUTCOME_UNKNOWN`: an entry save ran but lost its branch lock mid-write, so it may have
|
|
59
|
+
* landed (a 409); the version the caller holds may be stale, so it must re-read before retrying.
|
|
60
|
+
* `ENTRY_GONE`: an entry update found no file, because the entry was deleted or moved since the
|
|
61
|
+
* caller read it (a 409); it was not saved, and only a create can bring the entry back.
|
|
62
|
+
* `EDITOR_MODE_MISMATCH`: the editor bundle was built for the other operating mode than the
|
|
63
|
+
* server runs (a 412, see operating-mode/editor-mode-check.ts); only a rebuild fixes it.
|
|
64
|
+
* `SETTINGS_CHANGED`: a groups or permissions save named a version the file has moved on from (a
|
|
65
|
+
* 409, see `SettingsVersionConflictError`); nothing was saved, and a reload shows the other edit.
|
|
66
|
+
* The other settings 409, a busy file lock, carries no code. `BRANCH_SYNCING`: an entry save was
|
|
67
|
+
* refused because the branch is mid-rebase (a 409); nothing was saved, and a retry soon can pass.
|
|
68
|
+
*/
|
|
69
|
+
export type ApiErrorCode = 'SCHEMA_UNAVAILABLE' | 'WORKER_FAILED' | 'WRITE_OUTCOME_UNKNOWN' | 'ENTRY_GONE' | 'EDITOR_MODE_MISMATCH' | 'SETTINGS_CHANGED' | 'BRANCH_SYNCING';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants the user endpoints share with the editor, kept dependency-free so the editor's
|
|
3
|
+
* browser bundle can import them without pulling in `permissions.ts` and its server-only deps.
|
|
4
|
+
*/
|
|
5
|
+
/** Most user ids one `POST /users/batch` request may carry; the editor splits larger sets. */
|
|
6
|
+
export declare const MAX_USER_METADATA_BATCH = 100;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants the user endpoints share with the editor, kept dependency-free so the editor's
|
|
3
|
+
* browser bundle can import them without pulling in `permissions.ts` and its server-only deps.
|
|
4
|
+
*/
|
|
5
|
+
/** Most user ids one `POST /users/batch` request may carry; the editor splits larger sets. */
|
|
6
|
+
export const MAX_USER_METADATA_BATCH = 100;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Build/adjust transform URLs for `<img>`/srcset without pulling in the
|
|
3
|
-
* server-only transform engine. Isomorphic -
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* import from client (editor) code as well as during static builds.
|
|
3
|
+
* server-only transform engine. Isomorphic - none of its imports reach a node
|
|
4
|
+
* builtin, so this is safe to import from client (editor) code as well as during
|
|
5
|
+
* static builds.
|
|
7
6
|
*/
|
|
8
7
|
import { type CropRect, type OutputFormat } from './transform-directives.js';
|
|
9
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* The minimal shape `assetUrl`/`assetSrcSet` need from a stored asset reference. An
|
|
10
|
+
* `ImageFieldValue` is one, so passing a field value renders the crop the editor stored.
|
|
11
|
+
*/
|
|
10
12
|
export interface AssetRef {
|
|
11
13
|
src: string;
|
|
14
|
+
crop?: CropRect;
|
|
12
15
|
}
|
|
13
16
|
export interface AssetUrlOptions {
|
|
14
17
|
width?: number;
|
|
@@ -23,16 +26,14 @@ export interface AssetUrlOptions {
|
|
|
23
26
|
* option beside it. Two shapes are legitimate, and they are alternatives, never composed:
|
|
24
27
|
*
|
|
25
28
|
* - An absolute origin (`https://assets.example.com`) — assets served from another origin.
|
|
26
|
-
* `media.publicBaseUrl` is one source of this, and is the source the editor uses; it is
|
|
27
|
-
* validated as an absolute URL, so it structurally cannot carry the second shape.
|
|
28
29
|
* - A same-origin path prefix (`/preview-123`) — the site is deployed under a Next `basePath`
|
|
29
30
|
* AND its assets are served by Next (`withCanopy`'s `/assets/:path*` rewrite, which Next
|
|
30
31
|
* auto-prefixes). NOT the right value on a CloudFront/CDK deployment, where the asset
|
|
31
32
|
* behaviors are anchored at the distribution root and a `basePath` does not move them —
|
|
32
33
|
* there the correct value is none at all. See the README's asset-mount table.
|
|
33
34
|
*
|
|
34
|
-
* It is a per-render option rather than a config field
|
|
35
|
-
*
|
|
35
|
+
* It is a per-render option rather than a config field because different renderers see the
|
|
36
|
+
* `/assets` space at different places.
|
|
36
37
|
*
|
|
37
38
|
* **Render-time only — never stored.** A stored `src` is always root-relative (see
|
|
38
39
|
* `assets/asset-src.ts`), because content moves between branches and environments. Nothing
|
|
@@ -41,16 +42,27 @@ export interface AssetUrlOptions {
|
|
|
41
42
|
baseUrl?: string;
|
|
42
43
|
}
|
|
43
44
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
|
|
45
|
+
* Whether `src` is in canopycms's own `/assets` URL space - a transform or static asset src the
|
|
46
|
+
* asset store serves. Every other src (a site's own static file, an off-site URL, a `data:` URI)
|
|
47
|
+
* is the host's, and the asset store never serves it.
|
|
48
|
+
*/
|
|
49
|
+
export declare function isAssetStoreSrc(src: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Build a transform URL, merging `opts` and `ref.crop` over the directives already present
|
|
52
|
+
* in `ref.src` (see `mergeDirectives` for precedence). For static srcs (svg/pdf under
|
|
53
|
+
* `/assets/{hash}/...`, or any src that isn't one of our own transform URLs) the src is
|
|
54
|
+
* returned unchanged and every directive is ignored - there is nothing to transform.
|
|
55
|
+
*
|
|
56
|
+
* In a live preview, a transform URL goes behind the editor's authenticated route
|
|
57
|
+
* (`editor/preview-asset-base.ts`) instead of `opts.baseUrl`: a draft's crop or width may exist
|
|
58
|
+
* nowhere a build put it. Static srcs keep `opts.baseUrl`, since finalize wrote them.
|
|
48
59
|
*/
|
|
49
60
|
export declare function assetUrl(ref: AssetRef, opts?: AssetUrlOptions): string;
|
|
50
61
|
/**
|
|
51
62
|
* Build a comma-joined `url w` srcset descriptor list. `widths` must all be
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
63
|
+
* integers in [1, 8192] (the `any` width policy) - this is developer-facing (a
|
|
64
|
+
* host app's own responsive-image markup), so an invalid width throws rather
|
|
65
|
+
* than silently dropping it. A site serving the opt-in lazy public path, which
|
|
66
|
+
* transforms only allowlisted widths, must pick widths from that allowlist.
|
|
55
67
|
*/
|
|
56
68
|
export declare function assetSrcSet(ref: AssetRef, widths: readonly number[], opts?: Omit<AssetUrlOptions, 'width'>): string;
|