canopycms 0.0.67-int.90 → 0.0.67
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/README.md +30 -3
- package/dist/ai/generate.js +1 -27
- package/dist/ai/handler.d.ts +0 -4
- package/dist/ai/handler.js +0 -11
- package/dist/ai/index.d.ts +1 -8
- package/dist/ai/index.js +1 -8
- package/dist/ai/json-to-markdown.js +15 -58
- package/dist/ai/resolve-branch.d.ts +2 -7
- package/dist/ai/resolve-branch.js +2 -8
- package/dist/ai/strip-mdx.d.ts +5 -13
- package/dist/ai/strip-mdx.js +5 -17
- package/dist/ai/to-plain-text.d.ts +10 -28
- package/dist/ai/to-plain-text.js +10 -28
- package/dist/ai/transform-components.d.ts +2 -4
- package/dist/ai/transform-components.js +8 -19
- package/dist/ai/types.d.ts +5 -10
- package/dist/api/admin-branch-health.d.ts +4 -12
- package/dist/api/admin-branch-health.js +26 -66
- package/dist/api/admin.d.ts +4 -12
- package/dist/api/admin.js +10 -26
- package/dist/api/assets.d.ts +0 -25
- package/dist/api/assets.js +50 -91
- package/dist/api/branch-merge.d.ts +1 -1
- package/dist/api/branch-merge.js +0 -2
- package/dist/api/branch-review.d.ts +0 -8
- package/dist/api/branch-review.js +0 -13
- package/dist/api/branch-status.d.ts +0 -3
- package/dist/api/branch-status.js +8 -33
- package/dist/api/branch-withdraw.d.ts +0 -1
- package/dist/api/branch-withdraw.js +6 -9
- package/dist/api/branch.d.ts +7 -12
- package/dist/api/branch.js +7 -44
- package/dist/api/client.d.ts +71 -224
- package/dist/api/client.js +82 -233
- package/dist/api/comments.d.ts +2 -4
- package/dist/api/comments.js +0 -17
- package/dist/api/content.d.ts +0 -6
- package/dist/api/content.js +66 -142
- package/dist/api/entries-constants.d.ts +5 -9
- package/dist/api/entries-constants.js +5 -9
- package/dist/api/entries.d.ts +8 -13
- package/dist/api/entries.js +20 -51
- package/dist/api/github-sync.d.ts +2 -4
- package/dist/api/github-sync.js +4 -8
- package/dist/api/groups.d.ts +3 -0
- package/dist/api/groups.js +8 -21
- package/dist/api/guards.d.ts +4 -16
- package/dist/api/guards.js +3 -22
- package/dist/api/index.d.ts +4 -4
- package/dist/api/permissions.d.ts +2 -0
- package/dist/api/permissions.js +18 -40
- package/dist/api/reference-options.d.ts +0 -1
- package/dist/api/reference-options.js +3 -11
- package/dist/api/request-body-hash.d.ts +12 -23
- package/dist/api/request-body-hash.js +12 -23
- package/dist/api/resolve-references.d.ts +0 -1
- package/dist/api/resolve-references.js +13 -28
- package/dist/api/route-builder.d.ts +3 -7
- package/dist/api/route-builder.js +1 -1
- package/dist/api/routes.d.ts +12 -0
- package/dist/api/routes.js +47 -0
- package/dist/api/schema.d.ts +23 -33
- package/dist/api/schema.js +20 -74
- package/dist/api/settings-helpers.js +4 -5
- package/dist/api/types.d.ts +0 -5
- package/dist/api/user.js +0 -5
- package/dist/api/validators.d.ts +14 -52
- package/dist/api/validators.js +14 -52
- package/dist/assets/asset-prefixes.d.ts +4 -8
- package/dist/assets/asset-prefixes.js +4 -8
- package/dist/assets/asset-src.d.ts +5 -22
- package/dist/assets/asset-src.js +5 -21
- package/dist/assets/factory.d.ts +1 -2
- package/dist/assets/factory.js +1 -2
- package/dist/assets/finalize.d.ts +3 -1
- package/dist/assets/finalize.js +3 -1
- package/dist/assets/index.d.ts +3 -3
- package/dist/assets/index.js +1 -1
- package/dist/assets/keys.d.ts +5 -3
- package/dist/assets/keys.js +6 -3
- package/dist/assets/pipeline.d.ts +3 -2
- package/dist/assets/pipeline.js +22 -56
- package/dist/assets/sharp-loader.d.ts +2 -10
- package/dist/assets/sharp-loader.js +2 -10
- package/dist/assets/store-local.d.ts +1 -2
- package/dist/assets/store-local.js +1 -2
- package/dist/assets/store-s3.d.ts +3 -4
- package/dist/assets/svg-sanitizer.d.ts +6 -14
- package/dist/assets/svg-sanitizer.js +6 -14
- package/dist/assets/transform-directives.d.ts +3 -4
- package/dist/assets/transform-directives.js +1 -1
- package/dist/assets/transform.d.ts +19 -30
- package/dist/assets/transform.js +18 -31
- package/dist/auth/cache.d.ts +2 -3
- package/dist/auth/cache.js +2 -3
- package/dist/auth/caching-auth-plugin.d.ts +11 -22
- package/dist/auth/caching-auth-plugin.js +12 -14
- package/dist/auth/context-helpers.d.ts +6 -20
- package/dist/auth/context-helpers.js +5 -17
- package/dist/auth/file-based-auth-cache.d.ts +10 -21
- package/dist/auth/file-based-auth-cache.js +23 -51
- package/dist/auth/plugin.d.ts +29 -61
- package/dist/auth/plugin.js +9 -13
- package/dist/auth/types.d.ts +11 -20
- package/dist/authorization/branch.d.ts +30 -49
- package/dist/authorization/branch.js +16 -42
- package/dist/authorization/content.d.ts +11 -40
- package/dist/authorization/content.js +13 -45
- package/dist/authorization/groups/index.d.ts +0 -3
- package/dist/authorization/groups/index.js +0 -3
- package/dist/authorization/groups/loader.d.ts +14 -28
- package/dist/authorization/groups/loader.js +14 -38
- package/dist/authorization/groups/schema.d.ts +0 -6
- package/dist/authorization/groups/schema.js +4 -7
- package/dist/authorization/helpers.d.ts +9 -28
- package/dist/authorization/helpers.js +9 -28
- package/dist/authorization/index.d.ts +3 -25
- package/dist/authorization/index.js +3 -35
- package/dist/authorization/path.d.ts +6 -13
- package/dist/authorization/path.js +8 -25
- package/dist/authorization/permissions/index.d.ts +0 -3
- package/dist/authorization/permissions/index.js +0 -3
- package/dist/authorization/permissions/loader.d.ts +14 -27
- package/dist/authorization/permissions/loader.js +14 -32
- package/dist/authorization/permissions/schema.d.ts +1 -6
- package/dist/authorization/permissions/schema.js +6 -13
- package/dist/authorization/protected-branch.d.ts +36 -65
- package/dist/authorization/protected-branch.js +29 -41
- package/dist/authorization/settings-file-store.d.ts +38 -81
- package/dist/authorization/settings-file-store.js +38 -79
- package/dist/authorization/types.d.ts +4 -26
- package/dist/authorization/types.js +0 -6
- package/dist/authorization/validation.d.ts +1 -23
- package/dist/authorization/validation.js +1 -24
- package/dist/branch-health.d.ts +39 -67
- package/dist/branch-health.js +27 -43
- package/dist/branch-metadata-file.d.ts +16 -32
- package/dist/branch-metadata-file.js +13 -26
- package/dist/branch-metadata.d.ts +49 -80
- package/dist/branch-metadata.js +57 -87
- package/dist/branch-registry.d.ts +26 -64
- package/dist/branch-registry.js +44 -93
- package/dist/branch-schema-cache.d.ts +34 -124
- package/dist/branch-schema-cache.js +49 -155
- package/dist/branch-workspace.d.ts +4 -4
- package/dist/branch-workspace.js +15 -19
- package/dist/build/generate-ai-content.d.ts +1 -0
- package/dist/build/generate-ai-content.js +12 -25
- package/dist/build-canopy.d.ts +17 -27
- package/dist/build-canopy.js +16 -23
- package/dist/build-mode.d.ts +25 -27
- package/dist/build-mode.js +25 -29
- package/dist/cli/cli.d.ts +15 -26
- package/dist/cli/cli.js +601 -978
- package/dist/cli/generate-ai-content.js +351 -628
- package/dist/cli/github-app-manifest.d.ts +84 -0
- package/dist/cli/github-app-manifest.js +161 -0
- package/dist/cli/init-github-app.d.ts +110 -444
- package/dist/cli/init-github-app.js +236 -773
- package/dist/cli/init.js +39 -80
- package/dist/cli/migrate.d.ts +13 -10
- package/dist/cli/migrate.js +22 -30
- package/dist/cli/project-detect.d.ts +17 -31
- package/dist/cli/project-detect.js +31 -42
- package/dist/cli/project-root.d.ts +4 -11
- package/dist/cli/project-root.js +4 -11
- package/dist/cli/prompt.d.ts +10 -0
- package/dist/cli/prompt.js +67 -0
- package/dist/cli/sync.d.ts +0 -8
- package/dist/cli/sync.js +8 -28
- package/dist/cli/template-files/middleware.ts.template +15 -29
- package/dist/cli/templates.d.ts +2 -12
- package/dist/cli/templates.js +4 -4
- package/dist/client.d.ts +1 -1
- package/dist/comment-store.d.ts +32 -53
- package/dist/comment-store.js +32 -52
- package/dist/config/flatten.d.ts +0 -3
- package/dist/config/flatten.js +2 -12
- package/dist/config/helpers.js +2 -2
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.js +1 -4
- package/dist/config/schemas/collection.d.ts +0 -8
- package/dist/config/schemas/collection.js +0 -10
- package/dist/config/schemas/config.d.ts +6 -78
- package/dist/config/schemas/config.js +38 -54
- package/dist/config/schemas/field.d.ts +2 -242
- package/dist/config/schemas/field.js +9 -20
- package/dist/config/schemas/media.js +1 -1
- package/dist/config/schemas/permissions.js +0 -2
- package/dist/config/schemas/url.d.ts +5 -6
- package/dist/config/schemas/url.js +5 -6
- package/dist/config/types.d.ts +45 -33
- package/dist/config/types.js +0 -1
- package/dist/config.d.ts +1 -8
- package/dist/config.js +1 -9
- package/dist/content-id-index.d.ts +76 -188
- package/dist/content-id-index.js +79 -230
- package/dist/content-index-generation.d.ts +27 -48
- package/dist/content-index-generation.js +35 -84
- package/dist/content-index-registry.d.ts +15 -24
- package/dist/content-index-registry.js +5 -9
- package/dist/content-listing.d.ts +64 -107
- package/dist/content-listing.js +68 -118
- package/dist/content-reader.d.ts +20 -29
- package/dist/content-reader.js +10 -18
- package/dist/content-store.d.ts +210 -336
- package/dist/content-store.js +413 -657
- package/dist/content-tree.d.ts +44 -86
- package/dist/content-tree.js +26 -54
- package/dist/context.d.ts +67 -94
- package/dist/context.js +53 -72
- package/dist/dev-content-watcher.d.ts +18 -18
- package/dist/dev-content-watcher.js +41 -44
- package/dist/editor/BranchManager.d.ts +3 -6
- package/dist/editor/BranchManager.js +24 -44
- package/dist/editor/CanopyEditor.js +5 -2
- package/dist/editor/CommentsPanel.js +0 -2
- package/dist/editor/Editor.js +19 -76
- package/dist/editor/EditorAuthGate.d.ts +27 -0
- package/dist/editor/EditorAuthGate.js +140 -0
- package/dist/editor/EntryNavigator.js +0 -20
- package/dist/editor/FormRenderer.d.ts +1 -2
- package/dist/editor/FormRenderer.js +8 -23
- package/dist/editor/admin/SystemHealthPanel.js +20 -37
- package/dist/editor/admin/useSystemHealth.d.ts +2 -3
- package/dist/editor/admin/useSystemHealth.js +10 -12
- package/dist/editor/client-reference-resolver.d.ts +2 -5
- package/dist/editor/client-reference-resolver.js +2 -19
- package/dist/editor/comments/BranchComments.js +0 -4
- package/dist/editor/comments/EntryComments.js +0 -4
- package/dist/editor/comments/FieldWrapper.js +0 -4
- package/dist/editor/comments/InlineCommentThread.js +0 -2
- package/dist/editor/comments/ThreadCarousel.d.ts +0 -58
- package/dist/editor/comments/ThreadCarousel.js +0 -12
- package/dist/editor/components/EditorFooter.d.ts +0 -8
- package/dist/editor/components/EditorFooter.js +0 -5
- package/dist/editor/components/EditorHeader.d.ts +0 -31
- package/dist/editor/components/EditorHeader.js +21 -71
- package/dist/editor/components/EditorSidebar.d.ts +0 -19
- package/dist/editor/components/EditorSidebar.js +0 -16
- package/dist/editor/components/EntryCreateModal.d.ts +4 -4
- package/dist/editor/components/EntryCreateModal.js +7 -22
- package/dist/editor/components/RenameEntryModal.js +0 -4
- package/dist/editor/components/UserBadge.js +0 -10
- package/dist/editor/components/index.js +0 -2
- package/dist/editor/context/ApiClientContext.d.ts +8 -7
- package/dist/editor/context/ApiClientContext.js +39 -11
- package/dist/editor/context/AssetContext.d.ts +7 -17
- package/dist/editor/context/AssetContext.js +7 -17
- package/dist/editor/context/EditorIdentityContext.d.ts +13 -0
- package/dist/editor/context/EditorIdentityContext.js +7 -0
- package/dist/editor/context/EditorStateContext.d.ts +10 -41
- package/dist/editor/context/EditorStateContext.js +7 -23
- package/dist/editor/context/SWRProvider.d.ts +3 -6
- package/dist/editor/context/index.d.ts +1 -20
- package/dist/editor/context/index.js +1 -20
- package/dist/editor/editor-utils.d.ts +8 -47
- package/dist/editor/editor-utils.js +19 -72
- package/dist/editor/fields/BlockField.d.ts +2 -2
- package/dist/editor/fields/BlockField.js +1 -2
- package/dist/editor/fields/CodeField.d.ts +0 -1
- package/dist/editor/fields/CodeField.js +0 -1
- package/dist/editor/fields/DateTimeField.d.ts +15 -22
- package/dist/editor/fields/DateTimeField.js +17 -26
- package/dist/editor/fields/ImageField.d.ts +2 -2
- package/dist/editor/fields/ImageField.js +8 -14
- package/dist/editor/fields/InlineGroupField.d.ts +0 -1
- package/dist/editor/fields/InlineGroupField.js +0 -1
- package/dist/editor/fields/MarkdownField.d.ts +0 -1
- package/dist/editor/fields/MarkdownField.js +6 -11
- package/dist/editor/fields/MdxImageDialog.d.ts +1 -1
- package/dist/editor/fields/MdxImageDialog.js +0 -1
- package/dist/editor/fields/NumberField.d.ts +9 -19
- package/dist/editor/fields/NumberField.js +11 -22
- package/dist/editor/fields/NumberListField.d.ts +7 -10
- package/dist/editor/fields/NumberListField.js +7 -10
- package/dist/editor/fields/ObjectField.d.ts +5 -8
- package/dist/editor/fields/ObjectField.js +0 -1
- package/dist/editor/fields/ReferenceField.d.ts +1 -1
- package/dist/editor/fields/ReferenceField.js +11 -16
- package/dist/editor/fields/SelectField.d.ts +2 -2
- package/dist/editor/fields/SelectField.js +0 -1
- package/dist/editor/fields/StringListField.d.ts +0 -4
- package/dist/editor/fields/StringListField.js +4 -9
- package/dist/editor/fields/TextField.d.ts +0 -1
- package/dist/editor/fields/TextField.js +0 -1
- package/dist/editor/fields/ToggleField.d.ts +0 -1
- package/dist/editor/fields/ToggleField.js +0 -1
- package/dist/editor/fields/entry-link/EntryLinkContext.js +2 -4
- package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +0 -3
- package/dist/editor/fields/entry-link/InsertEntryLink.js +0 -4
- package/dist/editor/group-manager/ExternalGroupsTab.d.ts +0 -3
- package/dist/editor/group-manager/ExternalGroupsTab.js +0 -1
- package/dist/editor/group-manager/GroupCard.d.ts +0 -3
- package/dist/editor/group-manager/GroupForm.d.ts +0 -3
- package/dist/editor/group-manager/InternalGroupsTab.d.ts +0 -3
- package/dist/editor/group-manager/InternalGroupsTab.js +0 -2
- package/dist/editor/group-manager/MemberList.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useExternalGroupSearch.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useExternalGroupSearch.js +0 -3
- package/dist/editor/group-manager/hooks/useGroupState.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useGroupState.js +0 -5
- package/dist/editor/group-manager/hooks/useUserSearch.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useUserSearch.js +0 -3
- package/dist/editor/group-manager/index.d.ts +0 -6
- package/dist/editor/group-manager/index.js +0 -10
- package/dist/editor/group-manager/types.d.ts +2 -5
- package/dist/editor/group-manager/types.js +0 -3
- package/dist/editor/hooks/index.d.ts +6 -11
- package/dist/editor/hooks/index.js +6 -12
- package/dist/editor/hooks/useBranchActions.d.ts +0 -14
- package/dist/editor/hooks/useBranchActions.js +0 -22
- package/dist/editor/hooks/useBranchManager.d.ts +2 -48
- package/dist/editor/hooks/useBranchManager.js +4 -64
- package/dist/editor/hooks/useBranchesData.d.ts +7 -6
- package/dist/editor/hooks/useBranchesData.js +7 -6
- package/dist/editor/hooks/useCommentSystem.d.ts +0 -49
- package/dist/editor/hooks/useCommentSystem.js +1 -36
- package/dist/editor/hooks/useDraftManager.d.ts +2 -35
- package/dist/editor/hooks/useDraftManager.js +23 -64
- package/dist/editor/hooks/useEditorLayout.d.ts +0 -20
- package/dist/editor/hooks/useEditorLayout.js +0 -23
- package/dist/editor/hooks/useEntriesData.d.ts +1 -0
- package/dist/editor/hooks/useEntriesData.js +2 -3
- package/dist/editor/hooks/useEntryLinkResolution.d.ts +2 -2
- package/dist/editor/hooks/useEntryLinkResolution.js +2 -2
- package/dist/editor/hooks/useEntryManager.d.ts +2 -27
- package/dist/editor/hooks/useEntryManager.js +29 -78
- package/dist/editor/hooks/useGroupManager.d.ts +0 -21
- package/dist/editor/hooks/useGroupManager.js +0 -21
- package/dist/editor/hooks/usePermissionManager.d.ts +0 -20
- package/dist/editor/hooks/usePermissionManager.js +0 -20
- package/dist/editor/hooks/useReferenceResolution.d.ts +2 -33
- package/dist/editor/hooks/useReferenceResolution.js +1 -48
- package/dist/editor/hooks/useSchemaManager.d.ts +8 -27
- package/dist/editor/hooks/useSchemaManager.js +0 -19
- package/dist/editor/hooks/useUserContext.d.ts +2 -9
- package/dist/editor/hooks/useUserContext.js +10 -10
- package/dist/editor/hooks/useUserMetadata.d.ts +0 -2
- package/dist/editor/hooks/useUserMetadata.js +0 -3
- package/dist/editor/media/AssetCard.d.ts +0 -1
- package/dist/editor/media/AssetCard.js +1 -2
- package/dist/editor/media/CropStep.d.ts +0 -1
- package/dist/editor/media/CropStep.js +0 -1
- package/dist/editor/media/MediaLibrary.d.ts +1 -2
- package/dist/editor/media/MediaLibrary.js +1 -2
- package/dist/editor/media/MediaLibraryBody.d.ts +0 -1
- package/dist/editor/media/MediaLibraryBody.js +0 -1
- package/dist/editor/media/crop-math.d.ts +1 -1
- package/dist/editor/media/crop-math.js +1 -1
- package/dist/editor/permission-manager/GroupSelector.d.ts +0 -3
- package/dist/editor/permission-manager/PermissionEditor.d.ts +0 -4
- package/dist/editor/permission-manager/PermissionEditor.js +0 -1
- package/dist/editor/permission-manager/PermissionLevelBadge.d.ts +0 -7
- package/dist/editor/permission-manager/PermissionLevelBadge.js +0 -4
- package/dist/editor/permission-manager/PermissionTree.d.ts +0 -4
- package/dist/editor/permission-manager/UserSelector.d.ts +0 -3
- package/dist/editor/permission-manager/constants.d.ts +0 -3
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts +0 -3
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js +0 -10
- package/dist/editor/permission-manager/hooks/usePermissionTree.d.ts +0 -14
- package/dist/editor/permission-manager/hooks/usePermissionTree.js +0 -11
- package/dist/editor/permission-manager/index.d.ts +0 -7
- package/dist/editor/permission-manager/index.js +0 -16
- package/dist/editor/permission-manager/types.d.ts +2 -12
- package/dist/editor/permission-manager/types.js +0 -3
- package/dist/editor/permission-manager/utils.d.ts +0 -28
- package/dist/editor/permission-manager/utils.js +9 -23
- package/dist/editor/preview-bridge.d.ts +5 -1
- package/dist/editor/preview-bridge.js +4 -4
- package/dist/editor/schema-editor/CollectionEditor.d.ts +0 -5
- package/dist/editor/schema-editor/CollectionEditor.js +9 -31
- package/dist/editor/schema-editor/EntryTypeEditor.d.ts +0 -6
- package/dist/editor/schema-editor/EntryTypeEditor.js +3 -24
- package/dist/editor/schema-editor/index.d.ts +0 -7
- package/dist/editor/schema-editor/index.js +0 -7
- package/dist/editor/utils/env.d.ts +3 -18
- package/dist/editor/utils/env.js +6 -25
- package/dist/entry-link-resolver.d.ts +13 -35
- package/dist/entry-link-resolver.js +20 -53
- package/dist/entry-schema-registry.d.ts +20 -60
- package/dist/entry-schema-registry.js +20 -69
- package/dist/entry-schema.d.ts +118 -223
- package/dist/entry-schema.js +46 -91
- package/dist/git-manager.d.ts +101 -200
- package/dist/git-manager.js +211 -384
- package/dist/github-service.d.ts +34 -75
- package/dist/github-service.js +37 -91
- package/dist/http/handler.d.ts +6 -37
- package/dist/http/handler.js +65 -120
- package/dist/http/router.d.ts +15 -32
- package/dist/http/router.js +34 -99
- package/dist/http/types.d.ts +15 -40
- package/dist/http/types.js +3 -7
- package/dist/id.d.ts +4 -10
- package/dist/id.js +4 -10
- package/dist/index.js +6 -9
- package/dist/operating-mode/client-safe-strategy.d.ts +7 -14
- package/dist/operating-mode/client-safe-strategy.js +8 -28
- package/dist/operating-mode/client-unsafe-strategy.d.ts +6 -16
- package/dist/operating-mode/client-unsafe-strategy.js +9 -34
- package/dist/operating-mode/client.d.ts +3 -10
- package/dist/operating-mode/client.js +3 -8
- package/dist/operating-mode/deployment-name-fixtures.d.ts +14 -18
- package/dist/operating-mode/deployment-name-fixtures.js +14 -18
- package/dist/operating-mode/deployment-name.d.ts +19 -29
- package/dist/operating-mode/deployment-name.js +29 -47
- package/dist/operating-mode/index.d.ts +4 -25
- package/dist/operating-mode/index.js +9 -31
- package/dist/operating-mode/mode-env.d.ts +32 -54
- package/dist/operating-mode/mode-env.js +36 -58
- package/dist/operating-mode/types.d.ts +24 -72
- package/dist/operating-mode/types.js +1 -7
- package/dist/paths/branch-name.d.ts +30 -40
- package/dist/paths/branch-name.js +30 -40
- package/dist/paths/branch.d.ts +4 -18
- package/dist/paths/branch.js +6 -22
- package/dist/paths/index.d.ts +2 -13
- package/dist/paths/index.js +3 -23
- package/dist/paths/normalize-server.d.ts +3 -15
- package/dist/paths/normalize-server.js +3 -15
- package/dist/paths/normalize.d.ts +13 -33
- package/dist/paths/normalize.js +13 -33
- package/dist/paths/resolve.d.ts +4 -17
- package/dist/paths/resolve.js +4 -22
- package/dist/paths/types.d.ts +12 -34
- package/dist/paths/types.js +5 -7
- package/dist/paths/validation.d.ts +22 -119
- package/dist/paths/validation.js +30 -148
- package/dist/reference-resolver.d.ts +0 -13
- package/dist/reference-resolver.js +0 -18
- package/dist/resolve-canopy-user.d.ts +16 -18
- package/dist/resolve-canopy-user.js +17 -26
- package/dist/resource-generation.d.ts +16 -25
- package/dist/resource-generation.js +34 -97
- package/dist/schema/meta-loader.d.ts +2 -14
- package/dist/schema/meta-loader.js +15 -64
- package/dist/schema/resolver.d.ts +1 -4
- package/dist/schema/resolver.js +1 -6
- package/dist/schema/schema-store-types.d.ts +0 -12
- package/dist/schema/schema-store.d.ts +61 -138
- package/dist/schema/schema-store.js +85 -282
- package/dist/schema/types.d.ts +0 -4
- package/dist/server.d.ts +62 -93
- package/dist/server.js +63 -94
- package/dist/services.d.ts +23 -47
- package/dist/services.js +55 -98
- package/dist/settings-workspace.d.ts +17 -30
- package/dist/settings-workspace.js +51 -81
- package/dist/static/index.d.ts +26 -52
- package/dist/static/index.js +33 -67
- package/dist/{worker/task-queue.d.ts → task-queue/cms-task-queue.d.ts} +7 -9
- package/dist/task-queue/cms-task-queue.js +13 -0
- package/dist/task-queue/task-queue-config.d.ts +3 -0
- package/dist/{worker → task-queue}/task-queue-config.js +1 -6
- package/dist/task-queue/task-queue.d.ts +16 -22
- package/dist/task-queue/task-queue.js +20 -44
- package/dist/task-queue/types.d.ts +0 -1
- package/dist/task-queue/worker-status.d.ts +35 -0
- package/dist/task-queue/worker-status.js +40 -0
- package/dist/types.d.ts +40 -51
- package/dist/url-collision.d.ts +26 -40
- package/dist/url-collision.js +47 -63
- package/dist/url-exclusivity-fixtures.d.ts +15 -20
- package/dist/url-exclusivity-fixtures.js +14 -19
- package/dist/url-path-resolver.d.ts +8 -16
- package/dist/url-path-resolver.js +19 -29
- package/dist/user.d.ts +8 -21
- package/dist/user.js +10 -19
- package/dist/utils/async-mutex.js +4 -6
- package/dist/utils/atomic-write.d.ts +2 -11
- package/dist/utils/atomic-write.js +2 -11
- package/dist/utils/body-field.d.ts +8 -15
- package/dist/utils/body-field.js +8 -15
- package/dist/utils/content-serialize.d.ts +18 -24
- package/dist/utils/content-serialize.js +109 -160
- package/dist/utils/content-write-lock.d.ts +51 -106
- package/dist/utils/content-write-lock.js +66 -111
- package/dist/utils/debug.d.ts +7 -23
- package/dist/utils/debug.js +7 -23
- package/dist/utils/entry-url.d.ts +11 -23
- package/dist/utils/entry-url.js +11 -26
- package/dist/utils/error.d.ts +25 -90
- package/dist/utils/error.js +60 -147
- package/dist/utils/flatten-group-fields.d.ts +5 -7
- package/dist/utils/flatten-group-fields.js +5 -7
- package/dist/utils/format.d.ts +1 -5
- package/dist/utils/format.js +1 -5
- package/dist/utils/fs.d.ts +3 -4
- package/dist/utils/fs.js +3 -4
- package/dist/utils/git.d.ts +52 -83
- package/dist/utils/git.js +79 -125
- package/dist/utils/logger.d.ts +35 -50
- package/dist/utils/logger.js +35 -52
- package/dist/utils/provisioning-lock.d.ts +23 -35
- package/dist/utils/provisioning-lock.js +49 -69
- package/dist/utils/sanitize-href.d.ts +5 -10
- package/dist/utils/sanitize-href.js +8 -18
- package/dist/utils/title-field.d.ts +17 -20
- package/dist/utils/title-field.js +18 -27
- package/dist/utils/typed-filename.d.ts +20 -48
- package/dist/utils/typed-filename.js +25 -61
- package/dist/utils/url-prefix.d.ts +3 -3
- package/dist/utils/url-prefix.js +3 -3
- package/dist/validation/block-structural-keys.d.ts +16 -31
- package/dist/validation/block-structural-keys.js +19 -29
- package/dist/validation/deletion-checker.d.ts +0 -34
- package/dist/validation/deletion-checker.js +1 -43
- package/dist/validation/entry-link-validator.d.ts +6 -13
- package/dist/validation/entry-link-validator.js +4 -13
- package/dist/validation/entry-type-reference-validator.d.ts +13 -18
- package/dist/validation/entry-type-reference-validator.js +13 -18
- package/dist/validation/entry-validator.d.ts +13 -25
- package/dist/validation/entry-validator.js +15 -32
- package/dist/validation/field-traversal.d.ts +3 -30
- package/dist/validation/field-traversal.js +1 -32
- package/dist/validation/reference-validator.d.ts +5 -24
- package/dist/validation/reference-validator.js +5 -30
- package/dist/worker/cms-worker.d.ts +172 -232
- package/dist/worker/cms-worker.js +241 -333
- package/dist/worker/git-sync.d.ts +32 -133
- package/dist/worker/git-sync.js +129 -191
- package/dist/worker/github-auth.d.ts +13 -19
- package/dist/worker/github-auth.js +13 -19
- package/dist/worker/history-rewrite.d.ts +53 -66
- package/dist/worker/history-rewrite.js +54 -60
- package/dist/worker/log.d.ts +24 -41
- package/dist/worker/log.js +25 -42
- package/dist/worker/rebase.d.ts +20 -110
- package/dist/worker/rebase.js +279 -354
- package/dist/worker/task-runner.d.ts +32 -66
- package/dist/worker/task-runner.js +126 -162
- package/dist/worker/worker-context.d.ts +41 -81
- package/package.json +4 -4
- package/dist/cli/template-files/middleware-clerk.ts.template +0 -37
- package/dist/worker/task-queue-config.d.ts +0 -8
- package/dist/worker/task-queue.js +0 -19
- package/dist/worker/worker-status.d.ts +0 -47
- package/dist/worker/worker-status.js +0 -52
|
@@ -7,31 +7,6 @@ import { resolveMessageOrigin } from '../preview-bridge.js';
|
|
|
7
7
|
import { commentsKey, fetchComments, useCommentsData } from './useCommentsData.js';
|
|
8
8
|
/**
|
|
9
9
|
* Custom hook for managing the comment system.
|
|
10
|
-
*
|
|
11
|
-
* Handles:
|
|
12
|
-
* - Loading comments from API
|
|
13
|
-
* - Adding comments to threads
|
|
14
|
-
* - Resolving comment threads
|
|
15
|
-
* - Field focus highlighting from preview frame
|
|
16
|
-
* - Active comment context tracking
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```tsx
|
|
20
|
-
* const {
|
|
21
|
-
* comments,
|
|
22
|
-
* activeThreads,
|
|
23
|
-
* handleAddComment,
|
|
24
|
-
* handleResolveThread,
|
|
25
|
-
* loadComments
|
|
26
|
-
* } = useCommentSystem({
|
|
27
|
-
* branchName,
|
|
28
|
-
* selectedPath,
|
|
29
|
-
* currentEntry,
|
|
30
|
-
* currentUser,
|
|
31
|
-
* canResolveComments,
|
|
32
|
-
* onReloadBranches
|
|
33
|
-
* })
|
|
34
|
-
* ```
|
|
35
10
|
*/
|
|
36
11
|
export function useCommentSystem(options) {
|
|
37
12
|
const apiClient = useApiClient();
|
|
@@ -44,7 +19,7 @@ export function useCommentSystem(options) {
|
|
|
44
19
|
// Automatic load, keyed per branch and deduped by SWR (e.g. React Strict
|
|
45
20
|
// Mode's double effect invoke collapses to a single request). Switching
|
|
46
21
|
// branches re-keys automatically, so no manual branch-change effect is
|
|
47
|
-
// needed
|
|
22
|
+
// needed.
|
|
48
23
|
const { data: commentsData } = useCommentsData(apiClient, options.branchName);
|
|
49
24
|
const comments = commentsData?.threads ?? [];
|
|
50
25
|
// Deliberately omits `options.onCommentsChange` from the deps: it's a
|
|
@@ -98,7 +73,6 @@ export function useCommentSystem(options) {
|
|
|
98
73
|
if (!result.ok)
|
|
99
74
|
throw new Error('Failed to resolve thread');
|
|
100
75
|
await loadComments(options.branchName);
|
|
101
|
-
// Branch summaries auto-update via useMemo watching comments
|
|
102
76
|
notifications.show({ message: 'Thread resolved', color: 'green' });
|
|
103
77
|
}
|
|
104
78
|
catch {
|
|
@@ -174,20 +148,15 @@ export function useCommentSystem(options) {
|
|
|
174
148
|
window.addEventListener('message', handleFocus);
|
|
175
149
|
return () => window.removeEventListener('message', handleFocus);
|
|
176
150
|
}, [options.currentEntry]);
|
|
177
|
-
// Jump-to handlers for navigating from CommentsPanel
|
|
178
151
|
const handleJumpToField = (entryPath, canopyPath, threadId) => {
|
|
179
|
-
// Switch to the correct entry if needed
|
|
180
152
|
if (entryPath !== options.selectedPath) {
|
|
181
153
|
options.setSelectedPath(entryPath);
|
|
182
154
|
}
|
|
183
|
-
// Wait for entry to load, then scroll and highlight
|
|
184
155
|
window.setTimeout(() => {
|
|
185
|
-
// Find and scroll to the field element
|
|
186
156
|
const fieldElement = document.querySelector(`[data-canopy-field="${canopyPath}"]`);
|
|
187
157
|
if (fieldElement) {
|
|
188
158
|
fieldElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
189
159
|
}
|
|
190
|
-
// Set focused field path and highlight thread
|
|
191
160
|
setFocusedFieldPath(canopyPath);
|
|
192
161
|
setHighlightThreadId(threadId);
|
|
193
162
|
window.setTimeout(() => {
|
|
@@ -197,18 +166,15 @@ export function useCommentSystem(options) {
|
|
|
197
166
|
}, entryPath !== options.selectedPath ? 300 : 0); // Delay if switching entries
|
|
198
167
|
};
|
|
199
168
|
const handleJumpToEntry = (entryPath, threadId) => {
|
|
200
|
-
// Switch to the correct entry if needed
|
|
201
169
|
if (entryPath !== options.selectedPath) {
|
|
202
170
|
options.setSelectedPath(entryPath);
|
|
203
171
|
}
|
|
204
|
-
// Wait for entry to load, then scroll and highlight
|
|
205
172
|
window.setTimeout(() => {
|
|
206
173
|
// Scroll to top of form (where EntryComments renders)
|
|
207
174
|
const formElement = document.querySelector('[data-form-renderer]');
|
|
208
175
|
if (formElement) {
|
|
209
176
|
formElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
210
177
|
}
|
|
211
|
-
// Set highlight thread
|
|
212
178
|
setHighlightThreadId(threadId);
|
|
213
179
|
window.setTimeout(() => {
|
|
214
180
|
setHighlightThreadId(undefined);
|
|
@@ -216,7 +182,6 @@ export function useCommentSystem(options) {
|
|
|
216
182
|
}, entryPath !== options.selectedPath ? 300 : 0); // Delay if switching entries
|
|
217
183
|
};
|
|
218
184
|
const handleJumpToBranch = (threadId) => {
|
|
219
|
-
// Open branch manager and highlight thread
|
|
220
185
|
options.setBranchManagerOpen(true);
|
|
221
186
|
setHighlightThreadId(threadId);
|
|
222
187
|
window.setTimeout(() => {
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import type { EditorEntry } from '../Editor.js';
|
|
2
2
|
import type { LogicalPath } from '../../paths/types.js';
|
|
3
3
|
import type { FormValue } from '../FormRenderer.js';
|
|
4
|
-
/**
|
|
5
|
-
* True when two field-error maps have the same keys and values (order
|
|
6
|
-
* independent). Used to bail out of a state update with the same object
|
|
7
|
-
* reference when a recompute produces an equal-but-newly-allocated map, so
|
|
8
|
-
* consumers that memo on `fieldErrors` identity don't churn.
|
|
9
|
-
*/
|
|
10
|
-
export declare const shallowEqualRecord: (a: Record<string, string>, b: Record<string, string>) => boolean;
|
|
11
4
|
export interface UseDraftManagerOptions {
|
|
12
5
|
branchName: string;
|
|
13
6
|
selectedPath: string;
|
|
@@ -18,8 +11,8 @@ export interface UseDraftManagerOptions {
|
|
|
18
11
|
saveEntry: (entry: EditorEntry, value: FormValue) => Promise<FormValue>;
|
|
19
12
|
/**
|
|
20
13
|
* The OCC version token currently held for an entry on the branch being
|
|
21
|
-
* shown (useEntryManager's `getEntryVersion`).
|
|
22
|
-
*
|
|
14
|
+
* shown (useEntryManager's `getEntryVersion`). Stamps each draft with the
|
|
15
|
+
* version it was based on, and detects at save time that the token has
|
|
23
16
|
* since moved on. Optional: without it no base versions are recorded and
|
|
24
17
|
* conflict detection falls back entirely to the server's 409.
|
|
25
18
|
*/
|
|
@@ -64,31 +57,5 @@ export interface UseDraftManagerReturn {
|
|
|
64
57
|
}
|
|
65
58
|
/**
|
|
66
59
|
* Custom hook for managing draft state (localStorage persistence, save/discard).
|
|
67
|
-
*
|
|
68
|
-
* Handles:
|
|
69
|
-
* - Draft state management
|
|
70
|
-
* - localStorage persistence (restore on mount, persist on change)
|
|
71
|
-
* - Save/discard operations
|
|
72
|
-
* - Reload from server
|
|
73
|
-
* - Computed values (selectedValue, effectiveValue, modifiedCount, editedFiles)
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
|
-
* ```tsx
|
|
77
|
-
* const {
|
|
78
|
-
* drafts,
|
|
79
|
-
* effectiveValue,
|
|
80
|
-
* modifiedCount,
|
|
81
|
-
* handleSave,
|
|
82
|
-
* handleDiscardDrafts
|
|
83
|
-
* } = useDraftManager({
|
|
84
|
-
* branchName,
|
|
85
|
-
* selectedPath,
|
|
86
|
-
* currentEntry,
|
|
87
|
-
* entries,
|
|
88
|
-
* loadEntry,
|
|
89
|
-
* saveEntry,
|
|
90
|
-
* setBusy
|
|
91
|
-
* })
|
|
92
|
-
* ```
|
|
93
60
|
*/
|
|
94
61
|
export declare function useDraftManager(options: UseDraftManagerOptions): UseDraftManagerReturn;
|
|
@@ -16,11 +16,11 @@ const toFieldErrorMap = (errors) => {
|
|
|
16
16
|
};
|
|
17
17
|
/**
|
|
18
18
|
* True when two field-error maps have the same keys and values (order
|
|
19
|
-
* independent).
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* independent). Bails a state update out with the same object reference
|
|
20
|
+
* when a recompute produces an equal-but-newly-allocated map, so consumers
|
|
21
|
+
* that memo on `fieldErrors` identity don't churn.
|
|
22
22
|
*/
|
|
23
|
-
|
|
23
|
+
const shallowEqualRecord = (a, b) => {
|
|
24
24
|
const aKeys = Object.keys(a);
|
|
25
25
|
const bKeys = Object.keys(b);
|
|
26
26
|
if (aKeys.length !== bKeys.length)
|
|
@@ -65,32 +65,6 @@ const parsePersistedDrafts = (raw) => {
|
|
|
65
65
|
};
|
|
66
66
|
/**
|
|
67
67
|
* Custom hook for managing draft state (localStorage persistence, save/discard).
|
|
68
|
-
*
|
|
69
|
-
* Handles:
|
|
70
|
-
* - Draft state management
|
|
71
|
-
* - localStorage persistence (restore on mount, persist on change)
|
|
72
|
-
* - Save/discard operations
|
|
73
|
-
* - Reload from server
|
|
74
|
-
* - Computed values (selectedValue, effectiveValue, modifiedCount, editedFiles)
|
|
75
|
-
*
|
|
76
|
-
* @example
|
|
77
|
-
* ```tsx
|
|
78
|
-
* const {
|
|
79
|
-
* drafts,
|
|
80
|
-
* effectiveValue,
|
|
81
|
-
* modifiedCount,
|
|
82
|
-
* handleSave,
|
|
83
|
-
* handleDiscardDrafts
|
|
84
|
-
* } = useDraftManager({
|
|
85
|
-
* branchName,
|
|
86
|
-
* selectedPath,
|
|
87
|
-
* currentEntry,
|
|
88
|
-
* entries,
|
|
89
|
-
* loadEntry,
|
|
90
|
-
* saveEntry,
|
|
91
|
-
* setBusy
|
|
92
|
-
* })
|
|
93
|
-
* ```
|
|
94
68
|
*/
|
|
95
69
|
export function useDraftManager(options) {
|
|
96
70
|
const [drafts, setDrafts] = useState(() => options.initialValues ?? {});
|
|
@@ -287,32 +261,27 @@ export function useDraftManager(options) {
|
|
|
287
261
|
console.warn('Failed to persist drafts', err);
|
|
288
262
|
}
|
|
289
263
|
}, [drafts, storageKey]);
|
|
290
|
-
//
|
|
291
|
-
//
|
|
292
|
-
//
|
|
293
|
-
//
|
|
294
|
-
//
|
|
295
|
-
//
|
|
296
|
-
//
|
|
297
|
-
// PR #106 review follow-up item 9:
|
|
264
|
+
// Recomputes field errors as the user edits, or as the selected entry's
|
|
265
|
+
// schema/format changes while it stays open, so each error clears when its
|
|
266
|
+
// field is fixed or no longer required. Errors for a different entry are
|
|
267
|
+
// simply not visible (see the `fieldErrors` derivation above), so this
|
|
268
|
+
// effect only needs to keep `errorState` itself correct. Server-only
|
|
269
|
+
// errors (e.g. reference existence) can't be recomputed client-side and
|
|
270
|
+
// clear on edit; the server re-reports them on save.
|
|
298
271
|
//
|
|
272
|
+
// Three things keep this from causing render loops/churn:
|
|
299
273
|
// 1. `options.currentEntry?.schema`/`.format` are in the deps (not just
|
|
300
|
-
// `effectiveValue`/`currentId`) so a schema change while the same
|
|
301
|
-
// stays open re-validates instead of leaving stale errors.
|
|
302
|
-
// 2. The updater is FUNCTIONAL (
|
|
303
|
-
// `errorState` itself
|
|
304
|
-
//
|
|
305
|
-
// 3. `shallowEqualRecord`
|
|
306
|
-
//
|
|
307
|
-
//
|
|
308
|
-
//
|
|
309
|
-
//
|
|
310
|
-
//
|
|
311
|
-
// errors object each time — churning any consumer that memoizes on
|
|
312
|
-
// `fieldErrors` identity.
|
|
313
|
-
//
|
|
314
|
-
// Note: server-only errors (e.g. reference existence) cannot be recomputed
|
|
315
|
-
// client-side and clear on edit; the server re-reports them on save.
|
|
274
|
+
// `effectiveValue`/`currentId`), so a schema change while the same
|
|
275
|
+
// entry stays open re-validates instead of leaving stale errors.
|
|
276
|
+
// 2. The updater is FUNCTIONAL (via the `prev` argument), keeping
|
|
277
|
+
// `errorState` itself out of the dep array -- depending on it would
|
|
278
|
+
// mean every write below re-triggers this effect.
|
|
279
|
+
// 3. `shallowEqualRecord` returns `prev` unchanged when the recomputed map
|
|
280
|
+
// is equal, which matters because `options.currentEntry` is a NEW
|
|
281
|
+
// reference on every entries refresh (`currentEntry` is a `useMemo`
|
|
282
|
+
// over `entriesState.find(...)`) -- without it, every refresh would
|
|
283
|
+
// allocate a new-but-equal errors object and churn any consumer
|
|
284
|
+
// memoizing on `fieldErrors` identity.
|
|
316
285
|
useEffect(() => {
|
|
317
286
|
const entry = options.currentEntry;
|
|
318
287
|
const value = effectiveValue;
|
|
@@ -361,13 +330,6 @@ export function useDraftManager(options) {
|
|
|
361
330
|
* One-time upgrade prompt for a draft carried across the pre-v2 -> v2
|
|
362
331
|
* storage change.
|
|
363
332
|
*
|
|
364
|
-
* `null` (unknown base) used to be treated exactly like a known-stale
|
|
365
|
-
* draft: blocked, with Reload and Discard the only exits -- both of which
|
|
366
|
-
* destroy the draft. And nothing ever re-stamped it, because the reconcile
|
|
367
|
-
* effect only fills ids NOT already in `bases` and `null` is present. So a
|
|
368
|
-
* legacy draft was visible, permanently unsaveable, and the only advice
|
|
369
|
-
* offered destroyed it: "kept" meant "kept and unusable".
|
|
370
|
-
*
|
|
371
333
|
* A bounded, one-time population deserves a decision, not a dead end. On
|
|
372
334
|
* confirm the base is re-stamped to the version currently held, so the
|
|
373
335
|
* draft rejoins the ordinary flow and this is never asked again -- and the
|
|
@@ -658,9 +620,7 @@ export function useDraftManager(options) {
|
|
|
658
620
|
},
|
|
659
621
|
});
|
|
660
622
|
};
|
|
661
|
-
// Compute dirty state for a given entry
|
|
662
623
|
const isDirtyForEntry = (entryPath) => {
|
|
663
|
-
// Find entry by path to get its content ID
|
|
664
624
|
const entry = options.entries.find((e) => e.path === entryPath);
|
|
665
625
|
if (!entry)
|
|
666
626
|
return false;
|
|
@@ -669,7 +629,6 @@ export function useDraftManager(options) {
|
|
|
669
629
|
return false;
|
|
670
630
|
return !loadedValues[id] || !equal(drafts[id], loadedValues[id]);
|
|
671
631
|
};
|
|
672
|
-
// Convenience helper for checking current selection
|
|
673
632
|
const isSelectedDirty = () => {
|
|
674
633
|
if (!currentId)
|
|
675
634
|
return false;
|
|
@@ -9,25 +9,5 @@ export interface UseEditorLayoutReturn {
|
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Custom hook for managing Editor layout state and measurements.
|
|
12
|
-
*
|
|
13
|
-
* Manages:
|
|
14
|
-
* - Pane layout (side-by-side or stacked)
|
|
15
|
-
* - Preview highlight toggle
|
|
16
|
-
* - Header height measurement via ResizeObserver
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```tsx
|
|
20
|
-
* const { layout, setLayout, highlightEnabled, setHighlightEnabled, headerRef, headerHeight } = useEditorLayout()
|
|
21
|
-
*
|
|
22
|
-
* // Toggle layout
|
|
23
|
-
* setLayout(layout === 'side' ? 'stacked' : 'side')
|
|
24
|
-
*
|
|
25
|
-
* // Toggle highlights
|
|
26
|
-
* setHighlightEnabled(!highlightEnabled)
|
|
27
|
-
*
|
|
28
|
-
* // Use header ref and height
|
|
29
|
-
* <Paper ref={headerRef}>...</Paper>
|
|
30
|
-
* <Box style={{ paddingTop: headerHeight }}>...</Box>
|
|
31
|
-
* ```
|
|
32
12
|
*/
|
|
33
13
|
export declare function useEditorLayout(): UseEditorLayoutReturn;
|
|
@@ -1,41 +1,18 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
/**
|
|
3
3
|
* Custom hook for managing Editor layout state and measurements.
|
|
4
|
-
*
|
|
5
|
-
* Manages:
|
|
6
|
-
* - Pane layout (side-by-side or stacked)
|
|
7
|
-
* - Preview highlight toggle
|
|
8
|
-
* - Header height measurement via ResizeObserver
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```tsx
|
|
12
|
-
* const { layout, setLayout, highlightEnabled, setHighlightEnabled, headerRef, headerHeight } = useEditorLayout()
|
|
13
|
-
*
|
|
14
|
-
* // Toggle layout
|
|
15
|
-
* setLayout(layout === 'side' ? 'stacked' : 'side')
|
|
16
|
-
*
|
|
17
|
-
* // Toggle highlights
|
|
18
|
-
* setHighlightEnabled(!highlightEnabled)
|
|
19
|
-
*
|
|
20
|
-
* // Use header ref and height
|
|
21
|
-
* <Paper ref={headerRef}>...</Paper>
|
|
22
|
-
* <Box style={{ paddingTop: headerHeight }}>...</Box>
|
|
23
|
-
* ```
|
|
24
4
|
*/
|
|
25
5
|
export function useEditorLayout() {
|
|
26
6
|
const [layout, setLayout] = useState('side');
|
|
27
7
|
const [highlightEnabled, setHighlightEnabled] = useState(false);
|
|
28
8
|
const [headerHeight, setHeaderHeight] = useState(80);
|
|
29
9
|
const headerRef = useRef(null);
|
|
30
|
-
// Measure header height using ResizeObserver
|
|
31
10
|
useEffect(() => {
|
|
32
11
|
if (!headerRef.current)
|
|
33
12
|
return;
|
|
34
13
|
const node = headerRef.current;
|
|
35
14
|
const updateHeight = () => setHeaderHeight(node.getBoundingClientRect().height || 80);
|
|
36
|
-
// Initial measurement
|
|
37
15
|
updateHeight();
|
|
38
|
-
// Watch for size changes
|
|
39
16
|
const observer = new ResizeObserver(updateHeight);
|
|
40
17
|
observer.observe(node);
|
|
41
18
|
return () => observer.disconnect();
|
|
@@ -18,6 +18,7 @@ export interface FetchEntriesParams {
|
|
|
18
18
|
* repeat across pages if content changes between requests.
|
|
19
19
|
*
|
|
20
20
|
* Exported for direct unit testing.
|
|
21
|
+
* @internal Exported for tests.
|
|
21
22
|
*/
|
|
22
23
|
export declare function listAllEntries(apiClient: {
|
|
23
24
|
entries: Pick<ApiClient['entries'], 'list'>;
|
|
@@ -11,9 +11,7 @@
|
|
|
11
11
|
* EditorCollection objects requires the hydrated flatSchema either way (see
|
|
12
12
|
* `fetchEntriesAndSchema`). This is also the single source of truth for
|
|
13
13
|
* `availableSchemas` (the entry-type schema names, keyed off the same
|
|
14
|
-
* schema response)
|
|
15
|
-
* own just to compute this list; it now reads it off useEntryManager's
|
|
16
|
-
* return value instead, eliminating that duplicate request.
|
|
14
|
+
* schema response).
|
|
17
15
|
*/
|
|
18
16
|
import { notifications } from '@mantine/notifications';
|
|
19
17
|
import { MAX_ENTRIES_PER_PAGE } from '../../api/entries-constants.js';
|
|
@@ -30,6 +28,7 @@ export const entriesKey = (branch) => `canopy:entries:${branch}`;
|
|
|
30
28
|
* repeat across pages if content changes between requests.
|
|
31
29
|
*
|
|
32
30
|
* Exported for direct unit testing.
|
|
31
|
+
* @internal Exported for tests.
|
|
33
32
|
*/
|
|
34
33
|
export async function listAllEntries(apiClient, branch) {
|
|
35
34
|
const byPath = new Map();
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Builds a Map<contentId, urlPath> from the loaded editor entries,
|
|
5
5
|
* then provides a function to resolve entry:ID patterns in text.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Transforms body content before it reaches the PreviewFrame, so the
|
|
7
|
+
* preview iframe receives fully-resolved URLs.
|
|
8
8
|
*/
|
|
9
9
|
import type { EditorEntry } from '../Editor.js';
|
|
10
10
|
import { type EntryLinkUrlResolver } from '../../entry-link-resolver.js';
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Builds a Map<contentId, urlPath> from the loaded editor entries,
|
|
5
5
|
* then provides a function to resolve entry:ID patterns in text.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Transforms body content before it reaches the PreviewFrame, so the
|
|
7
|
+
* preview iframe receives fully-resolved URLs.
|
|
8
8
|
*/
|
|
9
9
|
import { useMemo } from 'react';
|
|
10
10
|
import { computeEntryUrl } from '../../utils/entry-url.js';
|
|
@@ -2,6 +2,7 @@ import type { EditorEntry, EditorCollection } from '../Editor.js';
|
|
|
2
2
|
import type { LogicalPath } from '../../paths/types.js';
|
|
3
3
|
import type { FormValue } from '../FormRenderer.js';
|
|
4
4
|
import type { EntryFieldError } from '../../validation/entry-validator.js';
|
|
5
|
+
/** @internal Exported for tests. */
|
|
5
6
|
export { listAllEntries } from './useEntriesData.js';
|
|
6
7
|
/**
|
|
7
8
|
* Thrown by saveEntry when the API returns a non-200 response. Carries the
|
|
@@ -69,7 +70,7 @@ export interface UseEntryManagerReturn {
|
|
|
69
70
|
* Slugs already taken in `createModalCollection`, derived from the
|
|
70
71
|
* already-loaded `entries` list. Lets the create modal reject an obvious
|
|
71
72
|
* collision client-side with a clear message, before ever hitting the
|
|
72
|
-
* server's authoritative 409 guard
|
|
73
|
+
* server's authoritative 409 guard.
|
|
73
74
|
*/
|
|
74
75
|
createModalExistingSlugs: Set<string>;
|
|
75
76
|
handleCreateModalSubmit: (slug: string, entryTypeName: string) => Promise<void>;
|
|
@@ -77,31 +78,5 @@ export interface UseEntryManagerReturn {
|
|
|
77
78
|
}
|
|
78
79
|
/**
|
|
79
80
|
* Custom hook for managing editor entries (CRUD operations).
|
|
80
|
-
*
|
|
81
|
-
* Handles:
|
|
82
|
-
* - Entry selection and navigation
|
|
83
|
-
* - Loading and saving entry data
|
|
84
|
-
* - Refreshing entry list from API
|
|
85
|
-
* - Creating new entries
|
|
86
|
-
* - URL synchronization for selected entry
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```tsx
|
|
90
|
-
* const {
|
|
91
|
-
* selectedPath,
|
|
92
|
-
* entries,
|
|
93
|
-
* currentEntry,
|
|
94
|
-
* refreshEntries,
|
|
95
|
-
* handleCreateEntry,
|
|
96
|
-
* loadEntry,
|
|
97
|
-
* saveEntry
|
|
98
|
-
* } = useEntryManager({
|
|
99
|
-
* initialEntries: entries,
|
|
100
|
-
* branchName,
|
|
101
|
-
* collections,
|
|
102
|
-
* resolvePreviewSrc,
|
|
103
|
-
* setBusy
|
|
104
|
-
* })
|
|
105
|
-
* ```
|
|
106
81
|
*/
|
|
107
82
|
export declare function useEntryManager(options: UseEntryManagerOptions): UseEntryManagerReturn;
|
|
@@ -9,6 +9,7 @@ import { entriesKey, fetchEntriesAndSchema } from './useEntriesData.js';
|
|
|
9
9
|
// Re-exported so existing imports of `listAllEntries` from this module keep
|
|
10
10
|
// working -- the implementation lives in useEntriesData.ts alongside the
|
|
11
11
|
// other fetch/key/type pieces useEntryManager shares with the SWR layer.
|
|
12
|
+
/** @internal Exported for tests. */
|
|
12
13
|
export { listAllEntries } from './useEntriesData.js';
|
|
13
14
|
/**
|
|
14
15
|
* Thrown by saveEntry when the API returns a non-200 response. Carries the
|
|
@@ -33,32 +34,6 @@ const EMPTY_COLLECTIONS = [];
|
|
|
33
34
|
const EMPTY_SCHEMAS = [];
|
|
34
35
|
/**
|
|
35
36
|
* Custom hook for managing editor entries (CRUD operations).
|
|
36
|
-
*
|
|
37
|
-
* Handles:
|
|
38
|
-
* - Entry selection and navigation
|
|
39
|
-
* - Loading and saving entry data
|
|
40
|
-
* - Refreshing entry list from API
|
|
41
|
-
* - Creating new entries
|
|
42
|
-
* - URL synchronization for selected entry
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* ```tsx
|
|
46
|
-
* const {
|
|
47
|
-
* selectedPath,
|
|
48
|
-
* entries,
|
|
49
|
-
* currentEntry,
|
|
50
|
-
* refreshEntries,
|
|
51
|
-
* handleCreateEntry,
|
|
52
|
-
* loadEntry,
|
|
53
|
-
* saveEntry
|
|
54
|
-
* } = useEntryManager({
|
|
55
|
-
* initialEntries: entries,
|
|
56
|
-
* branchName,
|
|
57
|
-
* collections,
|
|
58
|
-
* resolvePreviewSrc,
|
|
59
|
-
* setBusy
|
|
60
|
-
* })
|
|
61
|
-
* ```
|
|
62
37
|
*/
|
|
63
38
|
export function useEntryManager(options) {
|
|
64
39
|
const apiClient = useApiClient();
|
|
@@ -115,45 +90,33 @@ export function useEntryManager(options) {
|
|
|
115
90
|
const versionKey = (branch, contentId) => `${branch}:${contentId}`;
|
|
116
91
|
// PER-BRANCH monotonic tokens guarding every commit of the fetched
|
|
117
92
|
// `BranchView` record above, shared by BOTH the automatic SWR-backed load
|
|
118
|
-
// (below) and explicit `refreshEntries()` calls.
|
|
93
|
+
// (below) and explicit `refreshEntries()` calls. `claimed` bumps the
|
|
94
|
+
// moment an attempt's request starts (baked into that attempt's result
|
|
95
|
+
// tag); `committed` is the tag seq currently reflected in state, per
|
|
96
|
+
// branch.
|
|
119
97
|
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
98
|
+
// Commit rule: `tag.seq >= committed(tag.branch)` -- never move a branch's
|
|
99
|
+
// view backwards -- NOT `tag.seq === claimed(tag.branch)` ("newest attempt
|
|
100
|
+
// wins"). Two reasons:
|
|
123
101
|
//
|
|
124
|
-
//
|
|
125
|
-
//
|
|
126
|
-
//
|
|
102
|
+
// 1. SWR replays a branch's cached tagged result on a switch back, and
|
|
103
|
+
// that tag carries the seq claimed when it was originally fetched --
|
|
104
|
+
// older than the newest claim by then. A newest-attempt rule would fail
|
|
105
|
+
// that valid cache hit and never commit it, and when the switch back
|
|
106
|
+
// also lands inside SWR's dedupingInterval no revalidation follows
|
|
107
|
+
// either, leaving the previous branch's entries on screen indefinitely.
|
|
108
|
+
// The committed-seq rule always accepts a replayed tag.
|
|
109
|
+
// 2. On remount these refs reset to empty maps while SWR's own cache
|
|
110
|
+
// (owned by the `SWRProvider` above this component) survives, so a
|
|
111
|
+
// replayed tag can carry a seq higher than anything this instance ever
|
|
112
|
+
// claimed, yet still be the newest data known for that branch.
|
|
127
113
|
//
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
// perfectly valid cache hit fail the check and never commit; when the
|
|
135
|
-
// switch back also landed inside SWR's dedupingInterval, no
|
|
136
|
-
// revalidation followed either, so the editor kept showing the
|
|
137
|
-
// PREVIOUS branch's entries under the new branch indefinitely. A
|
|
138
|
-
// replayed tag always passes the committed-seq rule (it was committed
|
|
139
|
-
// before, or is newer than what was).
|
|
140
|
-
// 2. On remount these refs reset to empty maps while SWR's cache (owned by
|
|
141
|
-
// the provider above this component) survives, so a replayed tag can
|
|
142
|
-
// carry a seq higher than anything this instance ever claimed -- still
|
|
143
|
-
// the newest data known for that branch, and still committable. Note the
|
|
144
|
-
// cache now belongs to `SWRProvider`'s own `provider` Map rather than
|
|
145
|
-
// SWR's module global, so "survives" means across remounts BELOW
|
|
146
|
-
// `CanopyEditor`; remounting `CanopyEditor` itself starts a fresh cache,
|
|
147
|
-
// which is the same empty-cache path as a first load.
|
|
148
|
-
//
|
|
149
|
-
// What the committed-seq rule gives up: when two same-branch attempts race
|
|
150
|
-
// and the OLDER response arrives second while the newer is still in
|
|
151
|
-
// flight, the older commits transiently and the newer overwrites it on
|
|
152
|
-
// settle (a sub-second flash of slightly-stale data, converging to the
|
|
153
|
-
// newest). A response older than what's already displayed is still
|
|
154
|
-
// rejected outright. Cross-branch bleed is prevented separately: every
|
|
155
|
-
// commit site checks the tag's branch against options.branchName at
|
|
156
|
-
// settle time.
|
|
114
|
+
// Trade-off: when two same-branch attempts race and the older response
|
|
115
|
+
// settles second, it commits transiently before the newer overwrites it on
|
|
116
|
+
// settle. An older response than what's already displayed is still
|
|
117
|
+
// rejected outright; every commit site also checks the tag's branch
|
|
118
|
+
// against options.branchName at settle time to keep cross-branch bleed
|
|
119
|
+
// out.
|
|
157
120
|
const refreshSeqRef = useRef({
|
|
158
121
|
claimed: new Map(),
|
|
159
122
|
committed: new Map(),
|
|
@@ -325,9 +288,6 @@ export function useEntryManager(options) {
|
|
|
325
288
|
}
|
|
326
289
|
return fetched.entries;
|
|
327
290
|
};
|
|
328
|
-
/**
|
|
329
|
-
* Open the create entry modal for the specified collection
|
|
330
|
-
*/
|
|
331
291
|
const handleCreateEntry = async (collectionPath, _) => {
|
|
332
292
|
const col = collectionByPath.get(collectionPath);
|
|
333
293
|
if (!col || col.type === 'entry') {
|
|
@@ -337,9 +297,6 @@ export function useEntryManager(options) {
|
|
|
337
297
|
setCreateModalError(null);
|
|
338
298
|
setCreateModalOpen(true);
|
|
339
299
|
};
|
|
340
|
-
/**
|
|
341
|
-
* Handle entry creation from the modal
|
|
342
|
-
*/
|
|
343
300
|
const handleCreateModalSubmit = async (slug, entryTypeName) => {
|
|
344
301
|
if (!createModalCollection)
|
|
345
302
|
return;
|
|
@@ -351,9 +308,9 @@ export function useEntryManager(options) {
|
|
|
351
308
|
// expectedVersion: null is the create-intent signal the server
|
|
352
309
|
// enforces authoritatively (see content-store.ts's write() OCC block
|
|
353
310
|
// and api/content.ts's writeContentHandler) -- "this slug must not
|
|
354
|
-
// already exist yet".
|
|
355
|
-
// blind update,
|
|
356
|
-
// overwrite existing content
|
|
311
|
+
// already exist yet". The client always sends create intent here,
|
|
312
|
+
// never a blind update, so a same-slug create cannot silently
|
|
313
|
+
// overwrite existing content.
|
|
357
314
|
const payload = isDataOnlyFormat(format)
|
|
358
315
|
? { format: format, data: {}, expectedVersion: null }
|
|
359
316
|
: { format, data: {}, body: '', expectedVersion: null };
|
|
@@ -394,18 +351,12 @@ export function useEntryManager(options) {
|
|
|
394
351
|
setCreateModalCreating(false);
|
|
395
352
|
}
|
|
396
353
|
};
|
|
397
|
-
/**
|
|
398
|
-
* Close the create entry modal
|
|
399
|
-
*/
|
|
400
354
|
const closeCreateModal = () => {
|
|
401
355
|
setCreateModalOpen(false);
|
|
402
356
|
setCreateModalCollection(null);
|
|
403
357
|
setCreateModalError(null);
|
|
404
358
|
setCreateModalCreating(false);
|
|
405
359
|
};
|
|
406
|
-
/**
|
|
407
|
-
* Rename an entry's slug
|
|
408
|
-
*/
|
|
409
360
|
const renameEntry = async (path, newSlug) => {
|
|
410
361
|
options.setBusy(true);
|
|
411
362
|
try {
|
|
@@ -483,7 +434,7 @@ export function useEntryManager(options) {
|
|
|
483
434
|
}).then((fetched) => ({ fetched, seq, branch }));
|
|
484
435
|
});
|
|
485
436
|
// Commit the current branch's tagged data -- both fresh settles AND SWR
|
|
486
|
-
// cache replays on a switch back to
|
|
437
|
+
// cache replays on a switch back to an earlier-visited branch (the
|
|
487
438
|
// effect re-runs on options.branchName so the replayed tag, whose object
|
|
488
439
|
// identity didn't change, still gets (re)committed). The seq comparison is
|
|
489
440
|
// the per-branch committed-seq rule -- see refreshSeqRef's doc comment for
|
|
@@ -2,7 +2,6 @@ import type { InternalGroup } from '../../authorization/index.js';
|
|
|
2
2
|
import type { UserSearchResult, GroupMetadata } from '../../auth/types.js';
|
|
3
3
|
export interface UseGroupManagerOptions {
|
|
4
4
|
/**
|
|
5
|
-
* Whether the group manager is currently open.
|
|
6
5
|
* Groups are loaded when this becomes true.
|
|
7
6
|
*/
|
|
8
7
|
isOpen: boolean;
|
|
@@ -18,25 +17,5 @@ export interface UseGroupManagerReturn {
|
|
|
18
17
|
}
|
|
19
18
|
/**
|
|
20
19
|
* Custom hook for managing internal groups (CRUD operations).
|
|
21
|
-
*
|
|
22
|
-
* Handles:
|
|
23
|
-
* - Loading groups from API
|
|
24
|
-
* - Saving groups to API
|
|
25
|
-
* - Searching for users to add to groups
|
|
26
|
-
* - Searching for external groups
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```tsx
|
|
30
|
-
* const { groupsData, groupsLoading, handleSaveGroups, handleSearchUsers } = useGroupManager({
|
|
31
|
-
* isOpen: groupManagerOpen
|
|
32
|
-
* })
|
|
33
|
-
*
|
|
34
|
-
* // Groups are automatically loaded when isOpen becomes true
|
|
35
|
-
* // Save groups
|
|
36
|
-
* await handleSaveGroups(updatedGroups)
|
|
37
|
-
*
|
|
38
|
-
* // Search users
|
|
39
|
-
* const users = await handleSearchUsers('john', 10)
|
|
40
|
-
* ```
|
|
41
20
|
*/
|
|
42
21
|
export declare function useGroupManager(options: UseGroupManagerOptions): UseGroupManagerReturn;
|