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
|
@@ -4,12 +4,19 @@ export interface UseReferenceResolutionOptions {
|
|
|
4
4
|
value: FormValue;
|
|
5
5
|
fields: EntrySchema;
|
|
6
6
|
branch: string;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
/** Identifies the open entry; when it changes every cached target is fetched again. */
|
|
8
|
+
entryKey?: string;
|
|
9
9
|
}
|
|
10
10
|
export interface UseReferenceResolutionResult {
|
|
11
|
+
/** The draft with every reference replaced by its target, or `null` until it has one. */
|
|
11
12
|
resolvedValue: FormValue;
|
|
13
|
+
/** `true` at each reference position still resolving; see `applyReferenceCache`. */
|
|
12
14
|
loadingState: FormValue;
|
|
13
15
|
}
|
|
14
|
-
|
|
16
|
+
/**
|
|
17
|
+
* The draft as live preview shows it. Computed during render from the cache, so the first value
|
|
18
|
+
* for a new entry or edit already has no bare ids; a debounced effect then fetches the ids the
|
|
19
|
+
* cache lacks, in batched requests, and re-renders when they arrive.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useReferenceResolution({ value, fields, branch, entryKey, }: UseReferenceResolutionOptions): UseReferenceResolutionResult;
|
|
15
22
|
export {};
|
|
@@ -1,189 +1,46 @@
|
|
|
1
1
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { flattenGroupFields } from '../../utils/flatten-group-fields.js';
|
|
2
|
+
import { applyReferenceCache, expireReferences, fetchReferences, idsToFetch, storeReferences, } from '../client-reference-resolver.js';
|
|
4
3
|
import { useOptionalApiClient } from '../context/index.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
/**
|
|
5
|
+
* The draft as live preview shows it. Computed during render from the cache, so the first value
|
|
6
|
+
* for a new entry or edit already has no bare ids; a debounced effect then fetches the ids the
|
|
7
|
+
* cache lacks, in batched requests, and re-renders when they arrive.
|
|
8
|
+
*/
|
|
9
|
+
export function useReferenceResolution({ value, fields, branch, entryKey, }) {
|
|
10
|
+
// The context client carries the deployment's basePath. `null` outside an ApiClientProvider
|
|
11
|
+
// (this hook's own unit tests); fetchReferences then falls back to a default client.
|
|
10
12
|
const apiClient = useOptionalApiClient();
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
const [
|
|
15
|
-
|
|
16
|
-
//
|
|
17
|
-
// that HASN'T fired yet; once the 300ms elapses and the async callback
|
|
18
|
-
// below starts awaiting `resolveChangedReferences`, clearTimeout can no
|
|
19
|
-
// longer stop it. The generation check after that await catches the case
|
|
20
|
-
// clearTimeout can't: a newer value/branch superseding this attempt, or
|
|
21
|
-
// the component unmounting, while the network call was in flight.
|
|
22
|
-
const resolveGenerationRef = useRef(0);
|
|
23
|
-
const referenceFieldNames = useMemo(() => {
|
|
24
|
-
const names = new Set();
|
|
25
|
-
for (const field of flattenGroupFields(fields)) {
|
|
26
|
-
if (field.type === 'reference') {
|
|
27
|
-
names.add(field.name);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return names;
|
|
31
|
-
}, [fields]);
|
|
32
|
-
/**
|
|
33
|
-
* PHASE 1: SYNCHRONOUS RESOLUTION
|
|
34
|
-
*
|
|
35
|
-
* Compute resolved value by applying cached reference data to form value.
|
|
36
|
-
* This runs synchronously during render (useMemo), so there are no async gaps.
|
|
37
|
-
*
|
|
38
|
-
* For each reference field:
|
|
39
|
-
* - If ID is in cache: substitute full object
|
|
40
|
-
* - If ID not in cache: keep the ID (loading state)
|
|
41
|
-
*
|
|
42
|
-
* Dependencies include resolutionTrigger, which is incremented when cache updates,
|
|
43
|
-
* forcing this to re-run and pick up newly-resolved data.
|
|
44
|
-
*/
|
|
45
|
-
const resolvedValue = useMemo(() => {
|
|
46
|
-
const result = { ...value };
|
|
47
|
-
for (const fieldName of referenceFieldNames) {
|
|
48
|
-
const fieldValue = value[fieldName];
|
|
49
|
-
if (fieldValue) {
|
|
50
|
-
if (Array.isArray(fieldValue)) {
|
|
51
|
-
result[fieldName] = fieldValue.map((id) => {
|
|
52
|
-
if (typeof id === 'string') {
|
|
53
|
-
const cached = resolvedCache.current.get(`${branch}:${id}`);
|
|
54
|
-
return cached || null;
|
|
55
|
-
}
|
|
56
|
-
return id;
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
else if (typeof fieldValue === 'string') {
|
|
60
|
-
const cached = resolvedCache.current.get(`${branch}:${fieldValue}`);
|
|
61
|
-
result[fieldName] = cached || null;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return result;
|
|
66
|
-
}, [value, branch, resolutionTrigger, referenceFieldNames]);
|
|
67
|
-
/**
|
|
68
|
-
* Compute loading state that mirrors the data structure.
|
|
69
|
-
* For each reference field, track if it's currently loading (not in cache).
|
|
70
|
-
*/
|
|
71
|
-
const loadingState = useMemo(() => {
|
|
72
|
-
const result = {};
|
|
73
|
-
for (const fieldName of referenceFieldNames) {
|
|
74
|
-
const fieldValue = value[fieldName];
|
|
75
|
-
if (fieldValue) {
|
|
76
|
-
if (Array.isArray(fieldValue)) {
|
|
77
|
-
result[fieldName] = fieldValue.map((id) => {
|
|
78
|
-
if (typeof id === 'string') {
|
|
79
|
-
return !resolvedCache.current.has(`${branch}:${id}`);
|
|
80
|
-
}
|
|
81
|
-
return false;
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
else if (typeof fieldValue === 'string') {
|
|
85
|
-
result[fieldName] = !resolvedCache.current.has(`${branch}:${fieldValue}`);
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
result[fieldName] = false;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
result[fieldName] = false;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return result;
|
|
96
|
-
}, [value, branch, resolutionTrigger, referenceFieldNames]);
|
|
97
|
-
/**
|
|
98
|
-
* PHASE 2: BACKGROUND ASYNC RESOLUTION
|
|
99
|
-
*
|
|
100
|
-
* Find reference IDs that aren't in cache yet and fetch them from the API.
|
|
101
|
-
*/
|
|
13
|
+
// One map per branch, so a request for a branch left behind stores into an orphaned map.
|
|
14
|
+
const cacheRef = useRef(new Map());
|
|
15
|
+
// The cache is a ref, so a fetch that fills it bumps this to recompute the memo below.
|
|
16
|
+
const [cacheVersion, setCacheVersion] = useState(0);
|
|
17
|
+
const { resolvedValue, loadingState } = useMemo(() => applyReferenceCache(fields, value, branch, cacheRef.current), [fields, value, branch, cacheVersion]);
|
|
18
|
+
// These two are declared before the fetch effect, so it sees their result in the same commit.
|
|
102
19
|
useEffect(() => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
if (uncachedIds.size === 0) {
|
|
116
|
-
prevValueRef.current = value;
|
|
20
|
+
cacheRef.current = new Map();
|
|
21
|
+
setCacheVersion((prev) => prev + 1);
|
|
22
|
+
}, [branch]);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
expireReferences(cacheRef.current);
|
|
25
|
+
}, [entryKey]);
|
|
26
|
+
// Asks for all the cache lacks, even ids still in flight; the next edit retries a failure.
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const cache = cacheRef.current;
|
|
29
|
+
const ids = idsToFetch(fields, value, branch, cache, Date.now());
|
|
30
|
+
if (ids.length === 0)
|
|
117
31
|
return;
|
|
118
|
-
}
|
|
119
|
-
// Claim a generation for this attempt before scheduling the debounce, so
|
|
120
|
-
// the check below always compares against the token captured at the
|
|
121
|
-
// moment THIS attempt was scheduled -- not whatever the ref happens to
|
|
122
|
-
// hold when the callback resumes after its await.
|
|
123
|
-
const generation = ++resolveGenerationRef.current;
|
|
124
32
|
const timeout = setTimeout(async () => {
|
|
125
33
|
try {
|
|
126
|
-
const
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return;
|
|
131
|
-
for (const [fieldName, resolvedFieldValue] of Object.entries(updates)) {
|
|
132
|
-
if (Array.isArray(resolvedFieldValue)) {
|
|
133
|
-
resolvedFieldValue.forEach((obj, idx) => {
|
|
134
|
-
const fieldValue = value[fieldName];
|
|
135
|
-
if (Array.isArray(fieldValue)) {
|
|
136
|
-
const id = fieldValue[idx];
|
|
137
|
-
if (typeof obj === 'object' && obj !== null && typeof id === 'string') {
|
|
138
|
-
resolvedCache.current.set(`${branch}:${id}`, obj);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
else if (typeof resolvedFieldValue === 'object' && resolvedFieldValue !== null) {
|
|
144
|
-
const id = value[fieldName];
|
|
145
|
-
if (typeof id === 'string') {
|
|
146
|
-
resolvedCache.current.set(`${branch}:${id}`, resolvedFieldValue);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
setResolutionTrigger((prev) => prev + 1);
|
|
151
|
-
prevValueRef.current = value;
|
|
34
|
+
const found = await fetchReferences(ids, branch, apiClient ?? undefined);
|
|
35
|
+
// Keyed by branch and id, a result stays valid however the draft changed meanwhile.
|
|
36
|
+
storeReferences(cache, branch, found, Date.now());
|
|
37
|
+
setCacheVersion((prev) => prev + 1);
|
|
152
38
|
}
|
|
153
39
|
catch (error) {
|
|
154
40
|
console.error('Reference resolution failed:', error);
|
|
155
41
|
}
|
|
156
|
-
}, 300);
|
|
157
|
-
return () =>
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// newer effect run claims the next one: cleanup is what fires on
|
|
161
|
-
// unmount, where there IS no next run to bump the counter otherwise.
|
|
162
|
-
++resolveGenerationRef.current;
|
|
163
|
-
};
|
|
164
|
-
}, [value, fields, branch, referenceFieldNames, apiClient]);
|
|
165
|
-
useEffect(() => {
|
|
166
|
-
resolvedCache.current.clear();
|
|
167
|
-
setResolutionTrigger((prev) => prev + 1);
|
|
168
|
-
}, [branch]);
|
|
169
|
-
// Notify parent of resolved value changes (with infinite loop prevention)
|
|
170
|
-
useEffect(() => {
|
|
171
|
-
const serialized = JSON.stringify(resolvedValue);
|
|
172
|
-
if (serialized !== lastNotifiedValueRef.current) {
|
|
173
|
-
lastNotifiedValueRef.current = serialized;
|
|
174
|
-
onResolvedValueChange?.(resolvedValue);
|
|
175
|
-
}
|
|
176
|
-
}, [resolvedValue, onResolvedValueChange]);
|
|
177
|
-
const lastNotifiedLoadingRef = useRef('');
|
|
178
|
-
useEffect(() => {
|
|
179
|
-
const serialized = JSON.stringify(loadingState);
|
|
180
|
-
if (serialized !== lastNotifiedLoadingRef.current) {
|
|
181
|
-
lastNotifiedLoadingRef.current = serialized;
|
|
182
|
-
onLoadingStateChange?.(loadingState);
|
|
183
|
-
}
|
|
184
|
-
}, [loadingState, onLoadingStateChange]);
|
|
185
|
-
return {
|
|
186
|
-
resolvedValue,
|
|
187
|
-
loadingState,
|
|
188
|
-
};
|
|
42
|
+
}, 300);
|
|
43
|
+
return () => clearTimeout(timeout);
|
|
44
|
+
}, [value, fields, branch, entryKey, apiClient]);
|
|
45
|
+
return { resolvedValue, loadingState };
|
|
189
46
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CreateCollectionInput, UpdateCollectionInput, CreateEntryTypeInput, UpdateEntryTypeInput } from '../../api/index.js';
|
|
2
|
+
import type { EntryReferencedBy } from '../../api/entries.js';
|
|
2
3
|
import type { LogicalPath, ContentId } from '../../paths/types.js';
|
|
3
4
|
export interface UseSchemaManagerOptions {
|
|
4
5
|
branchName: string;
|
|
@@ -15,9 +16,28 @@ export interface UseSchemaManagerOptions {
|
|
|
15
16
|
*/
|
|
16
17
|
export type SchemaOpResult = {
|
|
17
18
|
ok: true;
|
|
18
|
-
} |
|
|
19
|
+
} | SchemaOpFailure;
|
|
20
|
+
/**
|
|
21
|
+
* `unanswered`: the write timed out or got a gateway's 5xx page, so it may have landed
|
|
22
|
+
* (`editor/unanswered.ts`); `onSchemaChange` has been called so the content tree shows which.
|
|
23
|
+
*/
|
|
24
|
+
type SchemaOpFailure = {
|
|
25
|
+
ok: false;
|
|
26
|
+
error: string;
|
|
27
|
+
unanswered?: true;
|
|
28
|
+
};
|
|
29
|
+
/** Takes down a collection create's or details save's unknown-outcome toast, once it landed. */
|
|
30
|
+
export declare const hideCollectionOutcomeUnknown: () => void;
|
|
31
|
+
/** @internal Exported for tests. */
|
|
32
|
+
export declare const schemaChangeOutcomeUnknown: (action: string, check: string) => string;
|
|
33
|
+
/**
|
|
34
|
+
* {@link SchemaOpResult}, or a refusal because other entries reference the one being deleted.
|
|
35
|
+
* That refusal shows no toast: the caller asks the user, then retries with `confirmReferenced`.
|
|
36
|
+
*/
|
|
37
|
+
type DeleteEntryResult = SchemaOpResult | {
|
|
19
38
|
ok: false;
|
|
20
39
|
error: string;
|
|
40
|
+
referencedBy: EntryReferencedBy;
|
|
21
41
|
};
|
|
22
42
|
/** Same shape as {@link SchemaOpResult}, plus a payload on success. */
|
|
23
43
|
type CreateCollectionResult = {
|
|
@@ -26,10 +46,7 @@ type CreateCollectionResult = {
|
|
|
26
46
|
collectionPath: LogicalPath;
|
|
27
47
|
contentId: ContentId;
|
|
28
48
|
};
|
|
29
|
-
} |
|
|
30
|
-
ok: false;
|
|
31
|
-
error: string;
|
|
32
|
-
};
|
|
49
|
+
} | SchemaOpFailure;
|
|
33
50
|
export interface UseSchemaManagerReturn {
|
|
34
51
|
createCollection: (input: CreateCollectionInput) => Promise<CreateCollectionResult>;
|
|
35
52
|
updateCollection: (collectionPath: LogicalPath, updates: UpdateCollectionInput) => Promise<SchemaOpResult>;
|
|
@@ -38,7 +55,9 @@ export interface UseSchemaManagerReturn {
|
|
|
38
55
|
updateEntryType: (collectionPath: LogicalPath, entryTypeName: string, updates: UpdateEntryTypeInput) => Promise<SchemaOpResult>;
|
|
39
56
|
removeEntryType: (collectionPath: LogicalPath, entryTypeName: string) => Promise<SchemaOpResult>;
|
|
40
57
|
updateOrder: (collectionPath: LogicalPath, order: string[]) => Promise<SchemaOpResult>;
|
|
41
|
-
deleteEntry: (entryPath: LogicalPath
|
|
58
|
+
deleteEntry: (entryPath: LogicalPath, options?: {
|
|
59
|
+
confirmReferenced?: boolean;
|
|
60
|
+
}) => Promise<DeleteEntryResult>;
|
|
42
61
|
isLoading: boolean;
|
|
43
62
|
}
|
|
44
63
|
/**
|
|
@@ -2,6 +2,17 @@ import { useState, useCallback } from 'react';
|
|
|
2
2
|
import { notifications } from '@mantine/notifications';
|
|
3
3
|
import { useApiClient } from '../context/index.js';
|
|
4
4
|
import { getErrorMessage } from '../../utils/error.js';
|
|
5
|
+
import { isGatewayFailure, isUnanswered, UnansweredError } from '../unanswered.js';
|
|
6
|
+
const SCHEMA_OUTCOME_UNKNOWN_TOAST_ID = 'canopy-schema-outcome-unknown';
|
|
7
|
+
// A collection create or details save has its own, so settling one leaves another write's up.
|
|
8
|
+
const COLLECTION_OUTCOME_UNKNOWN_TOAST_ID = 'canopy-collection-outcome-unknown';
|
|
9
|
+
const CHECK_CONTENT_PANEL = 'Check the "Content" panel';
|
|
10
|
+
/** Takes down a collection create's or details save's unknown-outcome toast, once it landed. */
|
|
11
|
+
export const hideCollectionOutcomeUnknown = () => {
|
|
12
|
+
notifications.hide(COLLECTION_OUTCOME_UNKNOWN_TOAST_ID);
|
|
13
|
+
};
|
|
14
|
+
/** @internal Exported for tests. */
|
|
15
|
+
export const schemaChangeOutcomeUnknown = (action, check) => `${action} may have gone through even though the server didn't answer. ${check} before trying again.`;
|
|
5
16
|
/**
|
|
6
17
|
* Hook for managing schema operations (collections, entry types, ordering).
|
|
7
18
|
*
|
|
@@ -10,23 +21,50 @@ import { getErrorMessage } from '../../utils/error.js';
|
|
|
10
21
|
export function useSchemaManager(options) {
|
|
11
22
|
const apiClient = useApiClient();
|
|
12
23
|
const [isLoading, setIsLoading] = useState(false);
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
|
|
24
|
+
// Collection, order and entry operations toast each failure that reaches here
|
|
25
|
+
// (relied on by fire-and-forget callers that ignore the returned result).
|
|
26
|
+
// Entry-type operations pass `toast: false`: their only caller,
|
|
27
|
+
// CollectionEditor, shows each result inline. Both return the underlying
|
|
28
|
+
// message for callers that surface it themselves.
|
|
29
|
+
const handleError = useCallback((message, error, { toast = true } = {}) => {
|
|
17
30
|
console.error(message, error);
|
|
18
31
|
const errorMessage = getErrorMessage(error);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
32
|
+
if (toast) {
|
|
33
|
+
notifications.show({
|
|
34
|
+
title: 'Error',
|
|
35
|
+
message: `${message}: ${errorMessage}`,
|
|
36
|
+
color: 'red',
|
|
37
|
+
});
|
|
38
|
+
}
|
|
24
39
|
return errorMessage;
|
|
25
40
|
}, []);
|
|
41
|
+
/**
|
|
42
|
+
* The failure result for a write. An unanswered one may have landed, so the content tree
|
|
43
|
+
* reloads, and its toast (only with `unknown`) says to check rather than that it failed.
|
|
44
|
+
*/
|
|
45
|
+
const fail = useCallback((error, message, { toast = true, unknown, unknownId = SCHEMA_OUTCOME_UNKNOWN_TOAST_ID, } = {}) => {
|
|
46
|
+
if (!isUnanswered(error))
|
|
47
|
+
return { ok: false, error: handleError(message, error, { toast }) };
|
|
48
|
+
console.error(message, error);
|
|
49
|
+
void Promise.resolve(options.onSchemaChange?.()).catch(console.error);
|
|
50
|
+
if (unknown) {
|
|
51
|
+
notifications.hide(unknownId);
|
|
52
|
+
notifications.show({
|
|
53
|
+
id: unknownId,
|
|
54
|
+
message: unknown,
|
|
55
|
+
color: 'yellow',
|
|
56
|
+
autoClose: false,
|
|
57
|
+
withCloseButton: true,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return { ok: false, error: getErrorMessage(error), unanswered: true };
|
|
61
|
+
}, [options.onSchemaChange, handleError]);
|
|
26
62
|
const createCollection = useCallback(async (input) => {
|
|
27
63
|
setIsLoading(true);
|
|
28
64
|
try {
|
|
29
65
|
const result = await apiClient.schema.createCollection({ branch: options.branchName }, input);
|
|
66
|
+
if (isGatewayFailure(result))
|
|
67
|
+
throw new UnansweredError();
|
|
30
68
|
if (!result.ok || !result.data) {
|
|
31
69
|
throw new Error(result.error || 'Failed to create collection');
|
|
32
70
|
}
|
|
@@ -38,16 +76,21 @@ export function useSchemaManager(options) {
|
|
|
38
76
|
return { ok: true, data: result.data };
|
|
39
77
|
}
|
|
40
78
|
catch (error) {
|
|
41
|
-
return
|
|
79
|
+
return fail(error, 'Failed to create collection', {
|
|
80
|
+
unknown: schemaChangeOutcomeUnknown('Creating the collection', CHECK_CONTENT_PANEL),
|
|
81
|
+
unknownId: COLLECTION_OUTCOME_UNKNOWN_TOAST_ID,
|
|
82
|
+
});
|
|
42
83
|
}
|
|
43
84
|
finally {
|
|
44
85
|
setIsLoading(false);
|
|
45
86
|
}
|
|
46
|
-
}, [apiClient, options.branchName, options.onSchemaChange,
|
|
87
|
+
}, [apiClient, options.branchName, options.onSchemaChange, fail]);
|
|
47
88
|
const updateCollection = useCallback(async (collectionPath, updates) => {
|
|
48
89
|
setIsLoading(true);
|
|
49
90
|
try {
|
|
50
91
|
const result = await apiClient.schema.updateCollection({ branch: options.branchName, collectionPath }, updates);
|
|
92
|
+
if (isGatewayFailure(result))
|
|
93
|
+
throw new UnansweredError();
|
|
51
94
|
if (!result.ok) {
|
|
52
95
|
throw new Error(result.error || 'Failed to update collection');
|
|
53
96
|
}
|
|
@@ -55,16 +98,20 @@ export function useSchemaManager(options) {
|
|
|
55
98
|
message: 'Collection updated',
|
|
56
99
|
color: 'green',
|
|
57
100
|
});
|
|
58
|
-
|
|
101
|
+
// The write landed, so a failed refresh is logged rather than reported as its failure.
|
|
102
|
+
await Promise.resolve(options.onSchemaChange?.()).catch(console.error);
|
|
59
103
|
return { ok: true };
|
|
60
104
|
}
|
|
61
105
|
catch (error) {
|
|
62
|
-
return
|
|
106
|
+
return fail(error, 'Failed to update collection', {
|
|
107
|
+
unknown: schemaChangeOutcomeUnknown('Saving collection details', 'Reopen the collection to check'),
|
|
108
|
+
unknownId: COLLECTION_OUTCOME_UNKNOWN_TOAST_ID,
|
|
109
|
+
});
|
|
63
110
|
}
|
|
64
111
|
finally {
|
|
65
112
|
setIsLoading(false);
|
|
66
113
|
}
|
|
67
|
-
}, [apiClient, options.branchName, options.onSchemaChange,
|
|
114
|
+
}, [apiClient, options.branchName, options.onSchemaChange, fail]);
|
|
68
115
|
const deleteCollection = useCallback(async (collectionPath) => {
|
|
69
116
|
setIsLoading(true);
|
|
70
117
|
try {
|
|
@@ -72,6 +119,8 @@ export function useSchemaManager(options) {
|
|
|
72
119
|
branch: options.branchName,
|
|
73
120
|
collectionPath,
|
|
74
121
|
});
|
|
122
|
+
if (isGatewayFailure(result))
|
|
123
|
+
throw new UnansweredError();
|
|
75
124
|
if (!result.ok) {
|
|
76
125
|
throw new Error(result.error || 'Failed to delete collection');
|
|
77
126
|
}
|
|
@@ -83,54 +132,52 @@ export function useSchemaManager(options) {
|
|
|
83
132
|
return { ok: true };
|
|
84
133
|
}
|
|
85
134
|
catch (error) {
|
|
86
|
-
return
|
|
135
|
+
return fail(error, 'Failed to delete collection', {
|
|
136
|
+
unknown: schemaChangeOutcomeUnknown('Deleting the collection', CHECK_CONTENT_PANEL),
|
|
137
|
+
});
|
|
87
138
|
}
|
|
88
139
|
finally {
|
|
89
140
|
setIsLoading(false);
|
|
90
141
|
}
|
|
91
|
-
}, [apiClient, options.branchName, options.onSchemaChange,
|
|
142
|
+
}, [apiClient, options.branchName, options.onSchemaChange, fail]);
|
|
92
143
|
const addEntryType = useCallback(async (collectionPath, entryType) => {
|
|
93
144
|
setIsLoading(true);
|
|
94
145
|
try {
|
|
95
146
|
const result = await apiClient.schema.addEntryType({ branch: options.branchName, collectionPath }, entryType);
|
|
147
|
+
if (isGatewayFailure(result))
|
|
148
|
+
throw new UnansweredError();
|
|
96
149
|
if (!result.ok) {
|
|
97
150
|
throw new Error(result.error || 'Failed to add entry type');
|
|
98
151
|
}
|
|
99
|
-
notifications.show({
|
|
100
|
-
message: `Entry type "${entryType.name}" added`,
|
|
101
|
-
color: 'green',
|
|
102
|
-
});
|
|
103
152
|
options.onSchemaChange?.();
|
|
104
153
|
return { ok: true };
|
|
105
154
|
}
|
|
106
155
|
catch (error) {
|
|
107
|
-
return
|
|
156
|
+
return fail(error, 'Failed to add entry type', { toast: false });
|
|
108
157
|
}
|
|
109
158
|
finally {
|
|
110
159
|
setIsLoading(false);
|
|
111
160
|
}
|
|
112
|
-
}, [apiClient, options.branchName, options.onSchemaChange,
|
|
161
|
+
}, [apiClient, options.branchName, options.onSchemaChange, fail]);
|
|
113
162
|
const updateEntryType = useCallback(async (collectionPath, entryTypeName, updates) => {
|
|
114
163
|
setIsLoading(true);
|
|
115
164
|
try {
|
|
116
165
|
const result = await apiClient.schema.updateEntryType({ branch: options.branchName, collectionPath, entryTypeName }, updates);
|
|
166
|
+
if (isGatewayFailure(result))
|
|
167
|
+
throw new UnansweredError();
|
|
117
168
|
if (!result.ok) {
|
|
118
169
|
throw new Error(result.error || 'Failed to update entry type');
|
|
119
170
|
}
|
|
120
|
-
notifications.show({
|
|
121
|
-
message: 'Entry type updated',
|
|
122
|
-
color: 'green',
|
|
123
|
-
});
|
|
124
171
|
options.onSchemaChange?.();
|
|
125
172
|
return { ok: true };
|
|
126
173
|
}
|
|
127
174
|
catch (error) {
|
|
128
|
-
return
|
|
175
|
+
return fail(error, 'Failed to update entry type', { toast: false });
|
|
129
176
|
}
|
|
130
177
|
finally {
|
|
131
178
|
setIsLoading(false);
|
|
132
179
|
}
|
|
133
|
-
}, [apiClient, options.branchName, options.onSchemaChange,
|
|
180
|
+
}, [apiClient, options.branchName, options.onSchemaChange, fail]);
|
|
134
181
|
const removeEntryType = useCallback(async (collectionPath, entryTypeName) => {
|
|
135
182
|
setIsLoading(true);
|
|
136
183
|
try {
|
|
@@ -139,27 +186,27 @@ export function useSchemaManager(options) {
|
|
|
139
186
|
collectionPath,
|
|
140
187
|
entryTypeName,
|
|
141
188
|
});
|
|
189
|
+
if (isGatewayFailure(result))
|
|
190
|
+
throw new UnansweredError();
|
|
142
191
|
if (!result.ok) {
|
|
143
192
|
throw new Error(result.error || 'Failed to remove entry type');
|
|
144
193
|
}
|
|
145
|
-
notifications.show({
|
|
146
|
-
message: `Entry type "${entryTypeName}" removed`,
|
|
147
|
-
color: 'green',
|
|
148
|
-
});
|
|
149
194
|
options.onSchemaChange?.();
|
|
150
195
|
return { ok: true };
|
|
151
196
|
}
|
|
152
197
|
catch (error) {
|
|
153
|
-
return
|
|
198
|
+
return fail(error, 'Failed to remove entry type', { toast: false });
|
|
154
199
|
}
|
|
155
200
|
finally {
|
|
156
201
|
setIsLoading(false);
|
|
157
202
|
}
|
|
158
|
-
}, [apiClient, options.branchName, options.onSchemaChange,
|
|
203
|
+
}, [apiClient, options.branchName, options.onSchemaChange, fail]);
|
|
159
204
|
const updateOrder = useCallback(async (collectionPath, order) => {
|
|
160
205
|
setIsLoading(true);
|
|
161
206
|
try {
|
|
162
207
|
const result = await apiClient.schema.updateOrder({ branch: options.branchName, collectionPath }, { order });
|
|
208
|
+
if (isGatewayFailure(result))
|
|
209
|
+
throw new UnansweredError();
|
|
163
210
|
if (!result.ok) {
|
|
164
211
|
throw new Error(result.error || 'Failed to update order');
|
|
165
212
|
}
|
|
@@ -168,19 +215,28 @@ export function useSchemaManager(options) {
|
|
|
168
215
|
return { ok: true };
|
|
169
216
|
}
|
|
170
217
|
catch (error) {
|
|
171
|
-
return
|
|
218
|
+
return fail(error, 'Failed to update order', {
|
|
219
|
+
unknown: schemaChangeOutcomeUnknown('Reordering entries', CHECK_CONTENT_PANEL),
|
|
220
|
+
});
|
|
172
221
|
}
|
|
173
222
|
finally {
|
|
174
223
|
setIsLoading(false);
|
|
175
224
|
}
|
|
176
|
-
}, [apiClient, options.branchName, options.onSchemaChange,
|
|
177
|
-
const deleteEntry = useCallback(async (entryPath) => {
|
|
225
|
+
}, [apiClient, options.branchName, options.onSchemaChange, fail]);
|
|
226
|
+
const deleteEntry = useCallback(async (entryPath, deleteOptions) => {
|
|
178
227
|
setIsLoading(true);
|
|
179
228
|
try {
|
|
180
229
|
const result = await apiClient.entries.delete({
|
|
181
230
|
branch: options.branchName,
|
|
182
231
|
entryPath,
|
|
232
|
+
...(deleteOptions?.confirmReferenced ? { confirmReferenced: 'true' } : {}),
|
|
183
233
|
});
|
|
234
|
+
const referencedBy = result.data?.referencedBy;
|
|
235
|
+
if (!result.ok && referencedBy) {
|
|
236
|
+
return { ok: false, error: result.error ?? 'Entry is referenced', referencedBy };
|
|
237
|
+
}
|
|
238
|
+
if (isGatewayFailure(result))
|
|
239
|
+
throw new UnansweredError();
|
|
184
240
|
if (!result.ok) {
|
|
185
241
|
throw new Error(result.error || 'Failed to delete entry');
|
|
186
242
|
}
|
|
@@ -192,12 +248,14 @@ export function useSchemaManager(options) {
|
|
|
192
248
|
return { ok: true };
|
|
193
249
|
}
|
|
194
250
|
catch (error) {
|
|
195
|
-
return
|
|
251
|
+
return fail(error, 'Failed to delete entry', {
|
|
252
|
+
unknown: schemaChangeOutcomeUnknown('Deleting the entry', CHECK_CONTENT_PANEL),
|
|
253
|
+
});
|
|
196
254
|
}
|
|
197
255
|
finally {
|
|
198
256
|
setIsLoading(false);
|
|
199
257
|
}
|
|
200
|
-
}, [apiClient, options.branchName, options.onSchemaChange,
|
|
258
|
+
}, [apiClient, options.branchName, options.onSchemaChange, fail]);
|
|
201
259
|
return {
|
|
202
260
|
createCollection,
|
|
203
261
|
updateCollection,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Cache, type ScopedMutator } from 'swr';
|
|
2
|
+
import type { UserProfile, UserSearchResult } from '../../auth/types.js';
|
|
2
3
|
import type { CanopyUserId } from '../../types.js';
|
|
3
4
|
export interface UseUserMetadataResult {
|
|
4
5
|
userMetadata: UserSearchResult | null;
|
|
@@ -6,8 +7,17 @@ export interface UseUserMetadataResult {
|
|
|
6
7
|
error: Error | null;
|
|
7
8
|
}
|
|
8
9
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Caches profiles a response carried, keeping a cached record's email. A profile matching the
|
|
11
|
+
* cached record is not written: any write makes SWR discard a lookup in flight, email included. A
|
|
12
|
+
* user with no record, or whose written record still has no email, is refetched once the writes
|
|
13
|
+
* settle, since the seed may have discarded a lookup; that refetch is detached, so the caller
|
|
14
|
+
* never waits on the directory.
|
|
12
15
|
*/
|
|
16
|
+
export declare function seedUserProfiles(swr: {
|
|
17
|
+
cache: Cache;
|
|
18
|
+
mutate: ScopedMutator;
|
|
19
|
+
}, users: readonly UserProfile[]): Promise<void>;
|
|
20
|
+
/** Answers from the cache with no request and no email, for a reader who may not look users up. */
|
|
21
|
+
export declare function useSeededUserResolver(): (userId: string) => Promise<UserSearchResult | null>;
|
|
22
|
+
/** One user's metadata under a per-user SWR key, so every badge for that user shares a fetch. */
|
|
13
23
|
export declare function useUserMetadata(userId: CanopyUserId, getUserMetadata: (userId: string) => Promise<UserSearchResult | null>, cachedUser?: UserSearchResult): UseUserMetadataResult;
|