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
|
@@ -6,11 +6,15 @@
|
|
|
6
6
|
* the same checks. Exported so the test suite can exercise them directly.
|
|
7
7
|
*/
|
|
8
8
|
import { CanopyConfigSchema } from './schemas/config.js';
|
|
9
|
+
import { mdxAllowlistSchema } from './schemas/field.js';
|
|
10
|
+
import { isMarkdownField, markdownFieldOptionsError } from '../validation/mdx-allowlist.js';
|
|
9
11
|
import { normalizePathValue } from './flatten.js';
|
|
10
12
|
// Leaf module, NOT the `operating-mode` barrel: the barrel re-exports the
|
|
11
13
|
// client-unsafe strategy (node:fs/node:path) and this file is reachable from
|
|
12
14
|
// `canopycms/client` (the generated editor page imports the adopter's config).
|
|
13
15
|
import { resolveOperatingMode } from '../operating-mode/mode-env.js';
|
|
16
|
+
import { isPathFieldName } from '../editor/canopy-path.js';
|
|
17
|
+
import { ITEM_KEY } from '../item-keys.js';
|
|
14
18
|
/**
|
|
15
19
|
* Recursively check that all select fields have options defined.
|
|
16
20
|
* Throws an error if a select field is missing options.
|
|
@@ -37,6 +41,33 @@ export const ensureSelectFieldsHaveOptions = (fields) => {
|
|
|
37
41
|
}
|
|
38
42
|
}
|
|
39
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Check that every data field's name can be spelled as a field path segment (`isPathFieldName`):
|
|
46
|
+
* the form, the preview's marks, validation errors and comment threads all name a field by its
|
|
47
|
+
* path. An inline group's own name is not part of any path, so only its children are checked.
|
|
48
|
+
* `ITEM_KEY` is reserved too, since every list item and block carries it.
|
|
49
|
+
*/
|
|
50
|
+
export const ensureFieldNamesSpellInPaths = (fields) => {
|
|
51
|
+
if (!Array.isArray(fields))
|
|
52
|
+
return;
|
|
53
|
+
for (const field of fields) {
|
|
54
|
+
const f = field;
|
|
55
|
+
if (f?.type !== 'group' && typeof f?.name === 'string' && !isPathFieldName(f.name)) {
|
|
56
|
+
throw new Error(`Field "${f.name}": field names can't be empty, all digits, or contain '.', '[' or ']'; they're used in field paths`);
|
|
57
|
+
}
|
|
58
|
+
if (f?.type !== 'group' && f?.name === ITEM_KEY) {
|
|
59
|
+
throw new Error(`Field "${ITEM_KEY}": the name is reserved for the key CanopyCMS gives each list item and block. Rename the field, and the key in your content files with it.`);
|
|
60
|
+
}
|
|
61
|
+
if (f?.type === 'group' || f?.type === 'object') {
|
|
62
|
+
ensureFieldNamesSpellInPaths(f.fields);
|
|
63
|
+
}
|
|
64
|
+
if (f?.type === 'block' && Array.isArray(f.templates)) {
|
|
65
|
+
for (const template of f.templates) {
|
|
66
|
+
ensureFieldNamesSpellInPaths(template.fields);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
40
71
|
/**
|
|
41
72
|
* Recursively check that all reference fields have at least one of `collections` or `entryTypes`.
|
|
42
73
|
* Throws an error if a reference field has neither.
|
|
@@ -78,9 +109,11 @@ export const forEachReferenceField = (fields, visit) => {
|
|
|
78
109
|
}
|
|
79
110
|
};
|
|
80
111
|
/**
|
|
81
|
-
* Check that every `
|
|
82
|
-
*
|
|
83
|
-
*
|
|
112
|
+
* Check that every `itemLabel` is non-blank text and, like every `itemTitleField`, sits on a
|
|
113
|
+
* `list: true` object, and that every `itemTitleField` names a direct child of type `string` or
|
|
114
|
+
* `number`, the only values the card heading shows as typed (a reference would show its raw id, a
|
|
115
|
+
* select its stored value). Throws an error when it does not. Entry schemas reach the editor
|
|
116
|
+
* through these checks, not the zod field schema.
|
|
84
117
|
*/
|
|
85
118
|
export const ensureItemTitleFieldsExist = (fields) => {
|
|
86
119
|
if (!Array.isArray(fields))
|
|
@@ -89,6 +122,15 @@ export const ensureItemTitleFieldsExist = (fields) => {
|
|
|
89
122
|
const f = field;
|
|
90
123
|
if (f?.type === 'object') {
|
|
91
124
|
const children = Array.isArray(f.fields) ? f.fields : [];
|
|
125
|
+
if (f.itemLabel !== undefined) {
|
|
126
|
+
const label = `Object field "${f.name ?? 'unknown'}" has itemLabel`;
|
|
127
|
+
if (f.list !== true) {
|
|
128
|
+
throw new Error(`${label}, but itemLabel applies only to list: true objects`);
|
|
129
|
+
}
|
|
130
|
+
if (typeof f.itemLabel !== 'string' || f.itemLabel.trim() === '') {
|
|
131
|
+
throw new Error(`${label}, which must be non-blank text`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
92
134
|
if (f.itemTitleField !== undefined) {
|
|
93
135
|
const label = `Object field "${f.name ?? 'unknown'}" has itemTitleField "${String(f.itemTitleField)}"`;
|
|
94
136
|
if (f.list !== true) {
|
|
@@ -210,6 +252,77 @@ export const ensureNoGroupsInsideComplexFields = (fields) => {
|
|
|
210
252
|
};
|
|
211
253
|
checkFields(Array.isArray(fields) ? fields : undefined);
|
|
212
254
|
};
|
|
255
|
+
/**
|
|
256
|
+
* Check that `stampOnPublish` sits only on an entry's own top-level `datetime` field (an inline
|
|
257
|
+
* group's members count, since groups carry no data) that is neither `list: true` nor
|
|
258
|
+
* `required: true`. The submit that stamps sets one top-level value, and a required field can
|
|
259
|
+
* never be saved empty, so it would never be stamped. Throws on the first problem.
|
|
260
|
+
*/
|
|
261
|
+
export const ensureStampOnPublishPlacement = (fields, scopeLabel = 'entry schema') => {
|
|
262
|
+
const refuse = (f, why) => {
|
|
263
|
+
throw new Error(`${scopeLabel}: field "${f.name ?? 'unknown'}" has stampOnPublish, ${why}`);
|
|
264
|
+
};
|
|
265
|
+
const check = (scopeFields, nestedIn) => {
|
|
266
|
+
if (!Array.isArray(scopeFields))
|
|
267
|
+
return;
|
|
268
|
+
for (const field of scopeFields) {
|
|
269
|
+
const f = field;
|
|
270
|
+
if (f?.stampOnPublish !== undefined && typeof f.stampOnPublish !== 'boolean') {
|
|
271
|
+
refuse(f, 'which must be true or false');
|
|
272
|
+
}
|
|
273
|
+
if (f?.stampOnPublish === true) {
|
|
274
|
+
if (nestedIn)
|
|
275
|
+
refuse(f, `but it is inside ${nestedIn}; only a top-level field is stamped`);
|
|
276
|
+
if (f.type !== 'datetime')
|
|
277
|
+
refuse(f, `but it is type "${String(f.type)}", not "datetime"`);
|
|
278
|
+
if (f.list === true)
|
|
279
|
+
refuse(f, 'but it is list: true; only a single date is stamped');
|
|
280
|
+
if (f.required === true) {
|
|
281
|
+
refuse(f, 'but it is required: true, so it can never be saved empty to be stamped');
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (f?.type === 'group')
|
|
285
|
+
check(f.fields, nestedIn);
|
|
286
|
+
if (f?.type === 'object')
|
|
287
|
+
check(f.fields, `object field "${String(f.name)}"`);
|
|
288
|
+
if (f?.type === 'block' && Array.isArray(f.templates)) {
|
|
289
|
+
for (const template of f.templates) {
|
|
290
|
+
check(template.fields, `block field "${String(f.name)}"`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
check(fields, undefined);
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
298
|
+
* Check every markdown and mdx field's `mdxAllow` against its schema and its `renderAs`,
|
|
299
|
+
* `mdxAllow` and `executable` against each other. Throws on the first problem.
|
|
300
|
+
*/
|
|
301
|
+
export const ensureMarkdownFieldOptions = (fields) => {
|
|
302
|
+
for (const field of fields) {
|
|
303
|
+
if (isMarkdownField(field)) {
|
|
304
|
+
if (field.mdxAllow !== undefined) {
|
|
305
|
+
const parsed = mdxAllowlistSchema.safeParse(field.mdxAllow);
|
|
306
|
+
if (!parsed.success) {
|
|
307
|
+
const [first] = parsed.error.issues;
|
|
308
|
+
const where = first?.path.join('.') ?? '';
|
|
309
|
+
throw new Error(`Field "${field.name}": mdxAllow${where === '' ? '' : `.${where}`} ${first?.message ?? 'is invalid'}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const message = markdownFieldOptionsError(field);
|
|
313
|
+
if (message !== undefined)
|
|
314
|
+
throw new Error(message);
|
|
315
|
+
}
|
|
316
|
+
if (field.type === 'group' || field.type === 'object') {
|
|
317
|
+
if ('fields' in field && Array.isArray(field.fields))
|
|
318
|
+
ensureMarkdownFieldOptions(field.fields);
|
|
319
|
+
}
|
|
320
|
+
if (field.type === 'block' && 'templates' in field && Array.isArray(field.templates)) {
|
|
321
|
+
for (const template of field.templates)
|
|
322
|
+
ensureMarkdownFieldOptions(template.fields);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
};
|
|
213
326
|
/**
|
|
214
327
|
* Validate and normalize a CanopyConfig object.
|
|
215
328
|
* Performs Zod validation and normalizes paths. Field-shape validation for
|
package/dist/content-id-index.js
CHANGED
|
@@ -165,8 +165,8 @@ export class ContentIdIndex {
|
|
|
165
165
|
`embed this ID. Keeping "${kept}" for ID-based lookups (reads, references, ` +
|
|
166
166
|
`listings); "${dropped}" is excluded from those lookups for now but has NOT ` +
|
|
167
167
|
`been deleted -- it is still on disk at that path, and saves addressed to it are ` +
|
|
168
|
-
`refused until this is resolved. An admin can resolve this
|
|
169
|
-
`
|
|
168
|
+
`refused until this is resolved. An admin can resolve this in System health ` +
|
|
169
|
+
`(Branches tab), whose repair-content-duplicates action archives ` +
|
|
170
170
|
`"${dropped}" with a dot-prefixed name so future scans stop flagging it. ` +
|
|
171
171
|
`Root: ${this.root}`);
|
|
172
172
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Absolute path of the generation marker for a branch-clone root.
|
|
3
|
-
* @internal No importer; deletion candidate in
|
|
3
|
+
* @internal No importer; deletion candidate in safeinsights/canopycms#725.
|
|
4
4
|
*/
|
|
5
5
|
export declare function contentIndexGenerationPath(root: string): string;
|
|
6
6
|
/**
|
|
@@ -20,7 +20,7 @@ import { SCHEMA_GENERATION_RESOURCE } from './branch-schema-cache.js';
|
|
|
20
20
|
const RESOURCE = 'content-index';
|
|
21
21
|
/**
|
|
22
22
|
* Absolute path of the generation marker for a branch-clone root.
|
|
23
|
-
* @internal No importer; deletion candidate in
|
|
23
|
+
* @internal No importer; deletion candidate in safeinsights/canopycms#725.
|
|
24
24
|
*/
|
|
25
25
|
export function contentIndexGenerationPath(root) {
|
|
26
26
|
return resourceGenerationPath(root, RESOURCE);
|
|
@@ -152,6 +152,12 @@ export interface ListingReferenceResolver {
|
|
|
152
152
|
cache: ReferenceResolveCache;
|
|
153
153
|
access: ReferenceTargetAccess | undefined;
|
|
154
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* A collection's listed entries minus those of an `unavailable` entry type, for the listings
|
|
157
|
+
* adopter pages render: data whose shape the running code does not know renders wrong rather
|
|
158
|
+
* than failing. The editor's own listing keeps them, so it can say why they cannot be opened.
|
|
159
|
+
*/
|
|
160
|
+
export declare const withoutUnavailableEntries: (items: CollectionListItem[], collection: CollectionSchemaItem) => CollectionListItem[];
|
|
155
161
|
/**
|
|
156
162
|
* Resolve `reference` fields in a collection's listed entries, in place of their raw data.
|
|
157
163
|
*
|
|
@@ -203,5 +209,8 @@ export interface SkippedListingFile {
|
|
|
203
209
|
* -- a `README.md`, a colocated sibling artifact -- is always dropped with a debug-gated
|
|
204
210
|
* `log.warn` and never passed to `onSkip`. Optional and purely diagnostic: `listEntries` uses
|
|
205
211
|
* it to turn the skip into a hard build-time failure instead of a silent one.
|
|
212
|
+
*
|
|
213
|
+
* `readsId`, when given, leaves out every entry whose ContentId it rejects before its file is
|
|
214
|
+
* read, so a caller wanting a few entries does not pay for the rest.
|
|
206
215
|
*/
|
|
207
|
-
export declare const listCollectionEntries: (root: string, collection: FlatSchemaItem, onSkip?: (file: SkippedListingFile) => void) => Promise<CollectionListItem[]>;
|
|
216
|
+
export declare const listCollectionEntries: (root: string, collection: FlatSchemaItem, onSkip?: (file: SkippedListingFile) => void, readsId?: (id: ContentId) => boolean) => Promise<CollectionListItem[]>;
|
package/dist/content-listing.js
CHANGED
|
@@ -14,6 +14,7 @@ import { isNotFoundError, getErrorMessage } from './utils/error.js';
|
|
|
14
14
|
import { createDebugLogger } from './utils/debug.js';
|
|
15
15
|
import { ContentStore, ContentStoreError, createReferenceResolveCache, } from './content-store.js';
|
|
16
16
|
import { isBuildMode } from './build-mode.js';
|
|
17
|
+
import { withItemKeys } from './item-keys.js';
|
|
17
18
|
const log = createDebugLogger({ prefix: 'ContentListing' });
|
|
18
19
|
/** Validate and normalize `target` under `root`; throws ContentStoreError on a traversal. */
|
|
19
20
|
const normalizePath = (root, target) => {
|
|
@@ -89,6 +90,15 @@ export const createReferenceResolver = (branchRoot, flatSchema, contentRootName,
|
|
|
89
90
|
// row would have hidden.
|
|
90
91
|
access: visibility?.shouldInclude,
|
|
91
92
|
});
|
|
93
|
+
/**
|
|
94
|
+
* A collection's listed entries minus those of an `unavailable` entry type, for the listings
|
|
95
|
+
* adopter pages render: data whose shape the running code does not know renders wrong rather
|
|
96
|
+
* than failing. The editor's own listing keeps them, so it can say why they cannot be opened.
|
|
97
|
+
*/
|
|
98
|
+
export const withoutUnavailableEntries = (items, collection) => {
|
|
99
|
+
const unavailable = new Set(collection.entries?.filter((e) => e.unavailable).map((e) => e.name) ?? []);
|
|
100
|
+
return unavailable.size > 0 ? items.filter((item) => !unavailable.has(item.entryType)) : items;
|
|
101
|
+
};
|
|
92
102
|
/**
|
|
93
103
|
* Resolve `reference` fields in a collection's listed entries, in place of their raw data.
|
|
94
104
|
*
|
|
@@ -103,7 +113,7 @@ export const resolveCollectionItemReferences = async (items, collection, resolve
|
|
|
103
113
|
return item;
|
|
104
114
|
return {
|
|
105
115
|
...item,
|
|
106
|
-
data: await resolver.store.resolveReferences(item.data, fields, resolver.cache, resolver.access),
|
|
116
|
+
data: await resolver.store.resolveReferences(item.data, fields, resolver.cache, resolver.access, item.logicalPath),
|
|
107
117
|
};
|
|
108
118
|
}));
|
|
109
119
|
/**
|
|
@@ -142,7 +152,7 @@ export async function listEntries(branchRoot, flatSchema, contentRootName, optio
|
|
|
142
152
|
? createReferenceResolver(branchRoot, flatSchema, contentRootName, visibility)
|
|
143
153
|
: null;
|
|
144
154
|
const collectionResults = await Promise.all(collections.map(async (collection) => {
|
|
145
|
-
const entries = await listCollectionEntries(branchRoot, collection, (file) => skippedFiles.push(file));
|
|
155
|
+
const entries = withoutUnavailableEntries(await listCollectionEntries(branchRoot, collection, (file) => skippedFiles.push(file)), collection);
|
|
146
156
|
const visible = shouldInclude ? entries.filter((e) => shouldInclude(e.logicalPath)) : entries;
|
|
147
157
|
// Resolve AFTER the visibility filter (a denied entry is never resolved, so its
|
|
148
158
|
// references cost nothing and leak nothing) and BEFORE the mapping below, so
|
|
@@ -183,7 +193,7 @@ export async function listEntries(branchRoot, flatSchema, contentRootName, optio
|
|
|
183
193
|
// One deliberate copy of the rule remains: `content-tree.ts`'s `defaultBuildPath`,
|
|
184
194
|
// exported for adopters to extend and also handling the collection case
|
|
185
195
|
// `computeEntryUrl` does not model. Folding it in is tracked in
|
|
186
|
-
//
|
|
196
|
+
// safeinsights/canopycms#646.
|
|
187
197
|
const urlPath = computeEntryUrl(entry.collectionPath, entry.slug, contentRootName);
|
|
188
198
|
const raw = entry.data;
|
|
189
199
|
const meta = {
|
|
@@ -281,8 +291,11 @@ const looksLikeMalformedEntry = (filename, entryTypes) => {
|
|
|
281
291
|
* -- a `README.md`, a colocated sibling artifact -- is always dropped with a debug-gated
|
|
282
292
|
* `log.warn` and never passed to `onSkip`. Optional and purely diagnostic: `listEntries` uses
|
|
283
293
|
* it to turn the skip into a hard build-time failure instead of a silent one.
|
|
294
|
+
*
|
|
295
|
+
* `readsId`, when given, leaves out every entry whose ContentId it rejects before its file is
|
|
296
|
+
* read, so a caller wanting a few entries does not pay for the rest.
|
|
284
297
|
*/
|
|
285
|
-
export const listCollectionEntries = async (root, collection, onSkip) => {
|
|
298
|
+
export const listCollectionEntries = async (root, collection, onSkip, readsId) => {
|
|
286
299
|
if (collection.type !== 'collection' || !collection.entries) {
|
|
287
300
|
return [];
|
|
288
301
|
}
|
|
@@ -326,13 +339,17 @@ export const listCollectionEntries = async (root, collection, onSkip) => {
|
|
|
326
339
|
return null;
|
|
327
340
|
}
|
|
328
341
|
const { type: entryTypeName, slug, id: contentId } = parsed;
|
|
342
|
+
if (readsId && !readsId(contentId))
|
|
343
|
+
return null;
|
|
329
344
|
const entryType = entryTypes.find((e) => e.name === entryTypeName);
|
|
330
345
|
const format = entryType?.format || 'json';
|
|
331
346
|
const bodyField = entryType?.schema ? findBodyFieldName(entryType.schema) : 'body';
|
|
332
|
-
const [stats,
|
|
347
|
+
const [stats, rawData] = await Promise.all([
|
|
333
348
|
fs.stat(absolutePath),
|
|
334
349
|
readEntryData(absolutePath, format, bodyField),
|
|
335
350
|
]);
|
|
351
|
+
// Keyed as `ContentStore.read` keys it, so every reader names an item alike.
|
|
352
|
+
const data = withItemKeys(entryType?.schema ?? [], rawData, 'content');
|
|
336
353
|
const item = {
|
|
337
354
|
logicalPath: entryLogicalPath(collection.logicalPath, slug),
|
|
338
355
|
contentId,
|
package/dist/content-reader.d.ts
CHANGED
|
@@ -84,10 +84,19 @@ export interface ContentReadMeta {
|
|
|
84
84
|
* `{type}.{slug}.{id}.{ext}`) -- see the `entryType` caveat above for what that implies.
|
|
85
85
|
*/
|
|
86
86
|
entryId?: ContentId;
|
|
87
|
+
/** The entry's slug within its collection, by the rule `listEntries` uses. */
|
|
88
|
+
slug: Slug;
|
|
89
|
+
/** The entry's URL path with no query, by the rule `listEntries` uses. */
|
|
90
|
+
urlPath: string;
|
|
87
91
|
}
|
|
88
92
|
export interface ContentReader {
|
|
89
93
|
read: <T = unknown>(input: ReadContentInput, message?: string) => Promise<{
|
|
90
94
|
data: T;
|
|
95
|
+
/**
|
|
96
|
+
* The requested `entryPath` and slug as a percent-encoded URL path, plus `?branch=<name>`.
|
|
97
|
+
* Through an entry-type `entryPath` it is not the entry's URL. Compare entries by
|
|
98
|
+
* `meta.urlPath`.
|
|
99
|
+
*/
|
|
91
100
|
path: string;
|
|
92
101
|
meta: ContentReadMeta;
|
|
93
102
|
}>;
|
package/dist/content-reader.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { loadBranchContext, loadOrCreateBranchContext } from './branch-workspace.js';
|
|
2
|
+
import { SchemaUnavailableError } from './schema/schema-unavailable-error.js';
|
|
2
3
|
import { ContentStore, ContentStoreError } from './content-store.js';
|
|
3
4
|
import { namesNoWorkspace, resolveBranchPaths, } from './paths/index.js';
|
|
4
5
|
import { trimSlashes } from './paths/normalize.js';
|
|
5
|
-
import { isIndexSlug } from './utils/entry-url.js';
|
|
6
|
+
import { computeEntryUrl, isIndexSlug } from './utils/entry-url.js';
|
|
6
7
|
import { isDeployedStatic, isBuildMode, readsFromCheckout } from './build-mode.js';
|
|
7
8
|
import { isNotFoundError } from './utils/error.js';
|
|
8
9
|
import { resolveEntryLinksInData } from './entry-link-resolver.js';
|
|
10
|
+
import { baseBranchOf } from './utils/base-branch.js';
|
|
11
|
+
import { CONTENT_READER_USER_ID } from './system-users.js';
|
|
9
12
|
/**
|
|
10
13
|
* Server-side helper to read content directly from a branch workspace. A branch with no workspace
|
|
11
14
|
* reads as NOT_FOUND unless `allowCreateBranch` or a `getBranchContext` resolver says otherwise.
|
|
@@ -14,12 +17,9 @@ export const createContentReader = (options) => {
|
|
|
14
17
|
const services = options.services;
|
|
15
18
|
const operatingMode = services.config.mode;
|
|
16
19
|
const basePathOverride = options.basePathOverride;
|
|
17
|
-
const defaultBranch = options.defaultBranch ??
|
|
18
|
-
services.config.defaultActiveBranch ??
|
|
19
|
-
services.config.defaultBaseBranch ??
|
|
20
|
-
'main';
|
|
20
|
+
const defaultBranch = options.defaultBranch ?? services.config.defaultActiveBranch ?? baseBranchOf(services.config);
|
|
21
21
|
const allowCreateBranch = options.allowCreateBranch ?? false;
|
|
22
|
-
const createdBy = options.createdBy ??
|
|
22
|
+
const createdBy = options.createdBy ?? CONTENT_READER_USER_ID;
|
|
23
23
|
const resolveBranchContext = async (branchName) => {
|
|
24
24
|
// Static deployments and builds read from the checkout: loadOrCreateBranchContext
|
|
25
25
|
// returns a synthetic cwd context without git ops, regardless of allowCreateBranch
|
|
@@ -115,7 +115,7 @@ export const createContentReader = (options) => {
|
|
|
115
115
|
// deliberately does not resolve the former, so a caller linking `path` linked to a 404.
|
|
116
116
|
// Same index decision as computeEntryUrl/listEntries/buildPreviewSrc, through the same
|
|
117
117
|
// predicate. NOTE this builder still keeps its own content-root strip and its own encoding
|
|
118
|
-
// rather than delegating wholesale -- see
|
|
118
|
+
// rather than delegating wholesale -- see safeinsights/canopycms#646.
|
|
119
119
|
const encodedSlug = isIndexSlug(opts.slug) ? '' : encodeSlug(opts.slug);
|
|
120
120
|
const url = encodedSlug ? `${trimmed}/${encodedSlug}` : trimmed || '/';
|
|
121
121
|
return appendBranch(url);
|
|
@@ -141,6 +141,8 @@ export const createContentReader = (options) => {
|
|
|
141
141
|
// key by them without a separate listEntries lookup or filename parse.
|
|
142
142
|
let entryType;
|
|
143
143
|
let entryId;
|
|
144
|
+
let urlPath;
|
|
145
|
+
let resolvedSlug;
|
|
144
146
|
try {
|
|
145
147
|
const resolved = await store.resolveDocumentPath(entryPath, slug ?? '');
|
|
146
148
|
logicalPath = resolved.logicalPath;
|
|
@@ -150,6 +152,8 @@ export const createContentReader = (options) => {
|
|
|
150
152
|
// absent, for legacy entry files without an embedded ID (see ContentReadMeta).
|
|
151
153
|
entryType = resolved.entryTypeName;
|
|
152
154
|
entryId = resolved.id;
|
|
155
|
+
resolvedSlug = resolved.slug;
|
|
156
|
+
urlPath = computeEntryUrl(resolved.collectionPath, resolved.slug, contentRoot);
|
|
153
157
|
}
|
|
154
158
|
catch (err) {
|
|
155
159
|
const message = err instanceof ContentStoreError ? err.message : 'Invalid content request';
|
|
@@ -196,10 +200,11 @@ export const createContentReader = (options) => {
|
|
|
196
200
|
resolveReferences: input.resolveReferences ?? true,
|
|
197
201
|
referenceAccess,
|
|
198
202
|
});
|
|
199
|
-
return { doc, store, physicalPath, entryType, entryId };
|
|
203
|
+
return { doc, store, physicalPath, entryType, entryId, slug: resolvedSlug, urlPath };
|
|
200
204
|
}
|
|
201
205
|
catch (err) {
|
|
202
|
-
|
|
206
|
+
// An entry of an unavailable type reads as absent, as adopter listings leave it out.
|
|
207
|
+
if (isNotFoundError(err) || err instanceof SchemaUnavailableError)
|
|
203
208
|
return null;
|
|
204
209
|
throw err;
|
|
205
210
|
}
|
|
@@ -211,7 +216,7 @@ export const createContentReader = (options) => {
|
|
|
211
216
|
const defaultMessage = `Content not found for ${entryPath}${slug ? `/${slug}` : ''} on branch ${branchName}`;
|
|
212
217
|
throw new ContentStoreError(message ?? defaultMessage, 'NOT_FOUND');
|
|
213
218
|
}
|
|
214
|
-
const { doc, store, physicalPath, entryType, entryId } = result;
|
|
219
|
+
const { doc, store, physicalPath, entryType, entryId, slug: entrySlug, urlPath } = result;
|
|
215
220
|
// For md/mdx format, merge the body into the data so callers get a complete object.
|
|
216
221
|
// The field name comes from the schema's isBody flag (defaults to 'body').
|
|
217
222
|
const docRecord = doc;
|
|
@@ -228,7 +233,7 @@ export const createContentReader = (options) => {
|
|
|
228
233
|
slug,
|
|
229
234
|
branch: branchName,
|
|
230
235
|
});
|
|
231
|
-
return { data, path, meta: { physicalPath, entryType, entryId } };
|
|
236
|
+
return { data, path, meta: { physicalPath, entryType, entryId, slug: entrySlug, urlPath } };
|
|
232
237
|
};
|
|
233
238
|
return { read };
|
|
234
239
|
};
|
package/dist/content-store.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntrySchema, FlatSchemaItem, EntryTypeConfig } from './config/index.js';
|
|
1
|
+
import type { ContentFormat, EntrySchema, FlatSchemaItem, EntryTypeConfig } from './config/index.js';
|
|
2
2
|
import { ContentIdIndex } from './content-id-index.js';
|
|
3
3
|
import { type LogicalPath, type PhysicalPath, type Slug, type ContentId } from './paths/index.js';
|
|
4
4
|
export type MarkdownDocument = {
|
|
@@ -50,6 +50,19 @@ export declare class ContentStoreError extends Error {
|
|
|
50
50
|
export declare class ContentConflictError extends Error {
|
|
51
51
|
constructor(message?: string);
|
|
52
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Thrown when a write carrying a numeric `expectedVersion` finds no file: the entry was deleted
|
|
55
|
+
* or moved since that version was read. A missing file is a change since the read, so the write
|
|
56
|
+
* is refused rather than re-creating the entry; re-creating it is a create (`expectedVersion:
|
|
57
|
+
* null`) the caller makes deliberately.
|
|
58
|
+
*
|
|
59
|
+
* A `ContentConflictError` subclass so every 409 mapping keeps working; the distinct type lets
|
|
60
|
+
* the API tell the editor the entry is gone, where "reload to see the latest version" has
|
|
61
|
+
* nothing to reload.
|
|
62
|
+
*/
|
|
63
|
+
export declare class EntryGoneError extends ContentConflictError {
|
|
64
|
+
constructor();
|
|
65
|
+
}
|
|
53
66
|
/**
|
|
54
67
|
* [SYNC-C1] Thrown when a mutation could not take the branch's cross-host
|
|
55
68
|
* content-write lock within its bounded wait (utils/content-write-lock.ts) --
|
|
@@ -61,7 +74,11 @@ export declare class ContentConflictError extends Error {
|
|
|
61
74
|
* instead of the misleading generic "modified by another editor".
|
|
62
75
|
*/
|
|
63
76
|
export declare class BranchSyncingError extends ContentConflictError {
|
|
64
|
-
|
|
77
|
+
/** As on `ContentWriteLockBusyError`: `'unknown'` means the write ran and may have landed. */
|
|
78
|
+
readonly outcome: 'not-run' | 'unknown';
|
|
79
|
+
constructor(message: string,
|
|
80
|
+
/** As on `ContentWriteLockBusyError`: `'unknown'` means the write ran and may have landed. */
|
|
81
|
+
outcome?: 'not-run' | 'unknown');
|
|
65
82
|
}
|
|
66
83
|
/**
|
|
67
84
|
* [F1] Thrown when a save's content ID is carried by MORE THAN ONE file in the branch's
|
|
@@ -152,10 +169,11 @@ export interface ContentStoreOptions {
|
|
|
152
169
|
* cache must never be shared by two readers.
|
|
153
170
|
*
|
|
154
171
|
* Misses are memoized alongside hits so one batch stays internally coherent: a shared block
|
|
155
|
-
* resolving to data on page 1 and `
|
|
156
|
-
* consistent answer. Each DISTINCT id still gets its full self-healing retry, inside the
|
|
172
|
+
* resolving to data on page 1 and a `MissingReference` on page 40 of one sitemap is worse than
|
|
173
|
+
* either consistent answer. Each DISTINCT id still gets its full self-healing retry, inside the
|
|
174
|
+
* memo.
|
|
157
175
|
*/
|
|
158
|
-
export type ReferenceResolveCache = Map<string, Promise<Record<string, unknown
|
|
176
|
+
export type ReferenceResolveCache = Map<string, Promise<Record<string, unknown>>>;
|
|
159
177
|
/** Create a cache for one batch of reference resolution. See {@link ReferenceResolveCache}. */
|
|
160
178
|
export declare const createReferenceResolveCache: () => ReferenceResolveCache;
|
|
161
179
|
/**
|
|
@@ -172,6 +190,13 @@ export interface ReadOptions {
|
|
|
172
190
|
resolveReferences?: boolean;
|
|
173
191
|
/** See {@link ReferenceTargetAccess}. */
|
|
174
192
|
referenceAccess?: ReferenceTargetAccess;
|
|
193
|
+
/**
|
|
194
|
+
* Read an entry of an `unavailable` entry type as raw data instead of throwing
|
|
195
|
+
* {@link SchemaUnavailableError}: for reads of it as another entry's reference target
|
|
196
|
+
* (resolution embeds that raw data; the picker takes a label from it), never for one an
|
|
197
|
+
* author edits.
|
|
198
|
+
*/
|
|
199
|
+
allowUnavailableEntryType?: boolean;
|
|
175
200
|
}
|
|
176
201
|
export declare class ContentStore {
|
|
177
202
|
private readonly root;
|
|
@@ -365,6 +390,10 @@ export declare class ContentStore {
|
|
|
365
390
|
relativePath: PhysicalPath;
|
|
366
391
|
/** The entry's logical path, the form path-permission rules match (`entryLogicalPath`). */
|
|
367
392
|
logicalPath: LogicalPath;
|
|
393
|
+
/** The collection the entry file lives in: the parent, when an entry-type item delegated. */
|
|
394
|
+
collectionPath: LogicalPath;
|
|
395
|
+
/** The entry's slug within that collection, lowercased as listings report it. */
|
|
396
|
+
slug: Slug;
|
|
368
397
|
id?: string;
|
|
369
398
|
/**
|
|
370
399
|
* Always populated for a valid schema item: the collection branch below resolves a name
|
|
@@ -387,6 +416,21 @@ export declare class ContentStore {
|
|
|
387
416
|
*/
|
|
388
417
|
read(collectionPath: LogicalPath, slug?: Slug | '', options?: ReadOptions): Promise<ContentDocument>;
|
|
389
418
|
write(collectionPath: LogicalPath, slug: (Slug | "") | undefined, input: WriteInput, entryTypeName?: string, existingId?: ContentId): Promise<ContentDocument>;
|
|
419
|
+
/**
|
|
420
|
+
* Set top-level `field` of the entry file at `physicalPath` to the string `value` when the
|
|
421
|
+
* file holds it empty (absent, null or ''), keeping every other byte. Resolves to the file's
|
|
422
|
+
* version (the mtime `read()` reports) before and after the write, or undefined when it left
|
|
423
|
+
* the file alone.
|
|
424
|
+
*
|
|
425
|
+
* PRECONDITION: the caller already holds this branch's content-write lock, which makes the
|
|
426
|
+
* read and the write one critical section; a call outside it throws. This takes no lock
|
|
427
|
+
* itself, since a nested acquisition fails busy and is why nothing holding that lock may call
|
|
428
|
+
* `write()` (docs/concurrency.md, "Lock acquisition order").
|
|
429
|
+
*/
|
|
430
|
+
fillEmptyFieldWhileHoldingWriteLock(physicalPath: PhysicalPath, format: ContentFormat, field: string, value: string): Promise<{
|
|
431
|
+
previousVersion: number;
|
|
432
|
+
version: number;
|
|
433
|
+
} | undefined>;
|
|
390
434
|
/**
|
|
391
435
|
* Read an entry by its ID (UUID).
|
|
392
436
|
* Returns null if the ID doesn't exist or points to a collection.
|
|
@@ -478,14 +522,21 @@ export declare class ContentStore {
|
|
|
478
522
|
* unmemoized behavior.
|
|
479
523
|
*
|
|
480
524
|
* `access` applies to every target exactly as in `read()`; see {@link ReferenceTargetAccess}.
|
|
525
|
+
* `origin`, the referring entry's logical path, names it in the dangling-reference warning.
|
|
526
|
+
*/
|
|
527
|
+
resolveReferences(data: Record<string, unknown>, fields: EntrySchema, cache?: ReferenceResolveCache, access?: ReferenceTargetAccess, origin?: string): Promise<Record<string, unknown>>;
|
|
528
|
+
/**
|
|
529
|
+
* Resolve one reference id the way a reference field resolves it, for callers with ids but no
|
|
530
|
+
* field to walk: the editor's live-preview endpoint (api/resolve-references.ts) and the AI
|
|
531
|
+
* export (ai/references.ts). An id
|
|
532
|
+
* naming no readable entry resolves to a `MissingReference`, as in `read()`. No body is
|
|
533
|
+
* embedded, since there is no field to ask for one.
|
|
481
534
|
*/
|
|
482
|
-
|
|
535
|
+
resolveReferenceTarget(id: string, access?: ReferenceTargetAccess): Promise<Record<string, unknown>>;
|
|
483
536
|
/**
|
|
484
|
-
*
|
|
485
|
-
*
|
|
486
|
-
* when the id names no entry. No body is embedded, since there is no field to ask for one.
|
|
537
|
+
* `trail` names where `data` sits, for the dangling-reference warning: the referring entry and
|
|
538
|
+
* the field path so far, in `traverseFields`' format (`blocks[2].author`, `reviewers[1]`).
|
|
487
539
|
*/
|
|
488
|
-
resolveReferenceTarget(id: string, access?: ReferenceTargetAccess): Promise<Record<string, unknown> | null>;
|
|
489
540
|
private resolveReferencesInData;
|
|
490
541
|
/**
|
|
491
542
|
* Resolve a single reference ID to full entry data, memoized when a batch cache is supplied.
|
|
@@ -501,7 +552,7 @@ export declare class ContentStore {
|
|
|
501
552
|
* `data` from a process-global content-keyed cache, so `resolveSingleReferenceOnce`'s
|
|
502
553
|
* top-level spread severs exactly one level and NESTED frontmatter objects alias across
|
|
503
554
|
* occurrences, calls and requests. Pre-existing `read()` behavior, deliberately out of scope
|
|
504
|
-
* here; see
|
|
555
|
+
* here; see safeinsights/canopycms#708.
|
|
505
556
|
*
|
|
506
557
|
* Measured (2000 occurrences of one target, local disk, the friendliest case for NOT
|
|
507
558
|
* caching): cloning a snippet-sized target is ~63x cheaper than re-reading and parsing it, a
|
|
@@ -513,7 +564,8 @@ export declare class ContentStore {
|
|
|
513
564
|
*/
|
|
514
565
|
private resolveSingleReference;
|
|
515
566
|
/**
|
|
516
|
-
*
|
|
567
|
+
* The target's data with its reference metadata, a `RestrictedReference` for a denied target,
|
|
568
|
+
* or a `MissingReference` when the id names no readable entry.
|
|
517
569
|
*
|
|
518
570
|
* A suspicious result (ID missing from the index, or an index hit whose file is gone)
|
|
519
571
|
* triggers one forced index refresh and a retry — self-healing for mutations by other
|
|
@@ -526,6 +578,17 @@ export declare class ContentStore {
|
|
|
526
578
|
* still runs the full refresh-and-retry; a cache only makes repeats of the SAME id share it.
|
|
527
579
|
*/
|
|
528
580
|
private resolveSingleReferenceUncached;
|
|
581
|
+
/**
|
|
582
|
+
* Throw {@link SchemaUnavailableError} when an entry exists at `slug` and is of an
|
|
583
|
+
* `unavailable` entry type, for a handler to refuse before any other check answers first.
|
|
584
|
+
*/
|
|
585
|
+
assertEntryAvailable(collectionPath: LogicalPath, slug?: Slug | ''): Promise<void>;
|
|
586
|
+
/**
|
|
587
|
+
* Throw {@link SchemaUnavailableError} when the entry type an entry is read or written as --
|
|
588
|
+
* `entryTypeName`, else the collection's default -- is `unavailable`. A name the collection
|
|
589
|
+
* does not declare is never charged to the default type, which it was not written as.
|
|
590
|
+
*/
|
|
591
|
+
private assertEntryTypeAvailable;
|
|
529
592
|
/**
|
|
530
593
|
* The entry type an entry file was written as, by its filename's type token, falling back to
|
|
531
594
|
* the collection's default the way `read()` does for a legacy untyped file.
|