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
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hook for managing groups and user search state
|
|
3
|
-
*/
|
|
4
1
|
import { useState, useEffect, useMemo, useCallback } from 'react';
|
|
5
2
|
export function useGroupsAndUsers({ onListGroups, onSearchUsers, canEdit, }) {
|
|
6
|
-
// Groups state
|
|
7
3
|
const [groups, setGroups] = useState([]);
|
|
8
4
|
const [isLoadingGroups, setIsLoadingGroups] = useState(false);
|
|
9
5
|
const [groupLoadError, setGroupLoadError] = useState(null);
|
|
10
6
|
const [groupSearchQuery, setGroupSearchQuery] = useState('');
|
|
11
7
|
const [showGroupSearch, setShowGroupSearch] = useState(false);
|
|
12
|
-
// User search state
|
|
13
8
|
const [userSearchResults, setUserSearchResults] = useState([]);
|
|
14
9
|
const [isSearchingUsers, setIsSearchingUsers] = useState(false);
|
|
15
10
|
const [userSearchQuery, setUserSearchQuery] = useState('');
|
|
16
11
|
const [showUserSearch, setShowUserSearch] = useState(false);
|
|
17
12
|
const [userSearchError, setUserSearchError] = useState(null);
|
|
18
|
-
// Load groups on mount
|
|
19
13
|
useEffect(() => {
|
|
20
14
|
if (onListGroups && canEdit) {
|
|
21
15
|
setIsLoadingGroups(true);
|
|
@@ -31,13 +25,11 @@ export function useGroupsAndUsers({ onListGroups, onSearchUsers, canEdit, }) {
|
|
|
31
25
|
.finally(() => setIsLoadingGroups(false));
|
|
32
26
|
}
|
|
33
27
|
}, [onListGroups, canEdit]);
|
|
34
|
-
// Transform groups to select data format
|
|
35
28
|
const groupSelectData = useMemo(() => groups.map((g) => ({
|
|
36
29
|
value: g.id,
|
|
37
30
|
label: g.name,
|
|
38
31
|
source: g.source,
|
|
39
32
|
})), [groups]);
|
|
40
|
-
// Filter groups based on search query
|
|
41
33
|
const filteredGroups = useMemo(() => {
|
|
42
34
|
const query = groupSearchQuery.toLowerCase().trim();
|
|
43
35
|
if (!query)
|
|
@@ -79,7 +71,6 @@ export function useGroupsAndUsers({ onListGroups, onSearchUsers, canEdit, }) {
|
|
|
79
71
|
setGroupLoadError(null);
|
|
80
72
|
}, []);
|
|
81
73
|
return {
|
|
82
|
-
// Groups
|
|
83
74
|
groups,
|
|
84
75
|
groupSelectData,
|
|
85
76
|
filteredGroups,
|
|
@@ -90,7 +81,6 @@ export function useGroupsAndUsers({ onListGroups, onSearchUsers, canEdit, }) {
|
|
|
90
81
|
setGroupSearchQuery,
|
|
91
82
|
setShowGroupSearch,
|
|
92
83
|
clearGroupLoadError,
|
|
93
|
-
// Users
|
|
94
84
|
userSearchResults,
|
|
95
85
|
isSearchingUsers,
|
|
96
86
|
userSearchQuery,
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hook for managing permission tree state and operations
|
|
3
|
-
*/
|
|
4
1
|
import type { TreeNode, ContentNode, PathPermission, PermissionLevel, PermissionTarget } from '../types.js';
|
|
5
2
|
import type { EditorCollection } from '../../Editor.js';
|
|
6
3
|
export interface UsePermissionTreeOptions {
|
|
@@ -10,29 +7,18 @@ export interface UsePermissionTreeOptions {
|
|
|
10
7
|
contentTree?: ContentNode;
|
|
11
8
|
}
|
|
12
9
|
export interface UsePermissionTreeResult {
|
|
13
|
-
/** The annotated tree with permissions */
|
|
14
10
|
annotatedTree: TreeNode;
|
|
15
|
-
/** Expanded node paths */
|
|
16
11
|
expandedNodes: Set<string>;
|
|
17
|
-
/** Currently selected node path */
|
|
18
12
|
selectedNode: string | null;
|
|
19
13
|
/** Local permission state (may differ from saved) */
|
|
20
14
|
localPermissions: PathPermission[];
|
|
21
|
-
/** Whether there are unsaved changes */
|
|
22
15
|
isDirty: boolean;
|
|
23
|
-
/** Toggle a node's expanded state */
|
|
24
16
|
toggleNode: (path: string) => void;
|
|
25
|
-
/** Expand all nodes */
|
|
26
17
|
expandAll: () => void;
|
|
27
|
-
/** Collapse all nodes */
|
|
28
18
|
collapseAll: () => void;
|
|
29
|
-
/** Select a node */
|
|
30
19
|
selectNode: (path: string | null) => void;
|
|
31
|
-
/** Update permission for a node */
|
|
32
20
|
updateNodePermission: (nodePath: string, level: PermissionLevel, updates: Partial<PermissionTarget>) => void;
|
|
33
|
-
/** Reset local permissions to saved state */
|
|
34
21
|
resetPermissions: () => void;
|
|
35
|
-
/** Set dirty state */
|
|
36
22
|
setIsDirty: (dirty: boolean) => void;
|
|
37
23
|
/** Set local permissions directly (for after save) */
|
|
38
24
|
setLocalPermissions: React.Dispatch<React.SetStateAction<PathPermission[]>>;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hook for managing permission tree state and operations
|
|
3
|
-
*/
|
|
4
1
|
import { useState, useMemo, useEffect, useCallback } from 'react';
|
|
5
2
|
import { buildTree, annotateTreeWithPermissions, findTreeNode } from '../utils.js';
|
|
6
3
|
import { parsePermissionPath } from '../../../authorization/validation.js';
|
|
@@ -9,11 +6,8 @@ export function usePermissionTree({ collections, contentRoot = 'content', permis
|
|
|
9
6
|
const [selectedNode, setSelectedNode] = useState(null);
|
|
10
7
|
const [localPermissions, setLocalPermissions] = useState(permissions);
|
|
11
8
|
const [isDirty, setIsDirty] = useState(false);
|
|
12
|
-
// Build tree from collections + contentTree
|
|
13
9
|
const tree = useMemo(() => buildTree(contentTree, contentRoot, collections), [collections, contentTree, contentRoot]);
|
|
14
|
-
// Annotate tree with permissions
|
|
15
10
|
const annotatedTree = useMemo(() => annotateTreeWithPermissions(tree, localPermissions), [tree, localPermissions]);
|
|
16
|
-
// Reset local state when permissions change externally
|
|
17
11
|
useEffect(() => {
|
|
18
12
|
setLocalPermissions(permissions);
|
|
19
13
|
setIsDirty(false);
|
|
@@ -61,18 +55,15 @@ export function usePermissionTree({ collections, contentRoot = 'content', permis
|
|
|
61
55
|
const permissionPath = parsed.path;
|
|
62
56
|
const existingIndex = newPermissions.findIndex((p) => p.path === permissionPath);
|
|
63
57
|
if (existingIndex >= 0) {
|
|
64
|
-
// Update existing permission for this level
|
|
65
58
|
const existing = newPermissions[existingIndex];
|
|
66
59
|
const updatedLevel = {
|
|
67
60
|
...existing[level],
|
|
68
61
|
...updates,
|
|
69
62
|
};
|
|
70
|
-
// Clean up empty arrays
|
|
71
63
|
if (updatedLevel.allowedUsers?.length === 0)
|
|
72
64
|
delete updatedLevel.allowedUsers;
|
|
73
65
|
if (updatedLevel.allowedGroups?.length === 0)
|
|
74
66
|
delete updatedLevel.allowedGroups;
|
|
75
|
-
// If level target is empty, remove it
|
|
76
67
|
if (!updatedLevel.allowedUsers && !updatedLevel.allowedGroups) {
|
|
77
68
|
newPermissions[existingIndex] = { ...existing, [level]: undefined };
|
|
78
69
|
}
|
|
@@ -82,14 +73,12 @@ export function usePermissionTree({ collections, contentRoot = 'content', permis
|
|
|
82
73
|
[level]: updatedLevel,
|
|
83
74
|
};
|
|
84
75
|
}
|
|
85
|
-
// If all levels are empty, remove the permission entirely
|
|
86
76
|
const perm = newPermissions[existingIndex];
|
|
87
77
|
if (!perm.read && !perm.edit && !perm.review) {
|
|
88
78
|
newPermissions.splice(existingIndex, 1);
|
|
89
79
|
}
|
|
90
80
|
}
|
|
91
81
|
else {
|
|
92
|
-
// Add new permission
|
|
93
82
|
if (updates.allowedUsers?.length || updates.allowedGroups?.length) {
|
|
94
83
|
newPermissions.push({
|
|
95
84
|
path: permissionPath,
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PermissionManager - Main component for managing path-based permissions.
|
|
3
|
-
*
|
|
4
|
-
* This component provides a tree-based UI for configuring read/edit/review
|
|
5
|
-
* permissions on content paths. Supports both schema-based and collection-based
|
|
6
|
-
* tree building.
|
|
7
|
-
*/
|
|
8
1
|
import React from 'react';
|
|
9
2
|
import type { PermissionManagerProps } from './types.js';
|
|
10
3
|
export declare const PermissionManager: React.FC<PermissionManagerProps>;
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
/**
|
|
4
|
-
* PermissionManager - Main component for managing path-based permissions.
|
|
5
|
-
*
|
|
6
|
-
* This component provides a tree-based UI for configuring read/edit/review
|
|
7
|
-
* permissions on content paths. Supports both schema-based and collection-based
|
|
8
|
-
* tree building.
|
|
9
|
-
*/
|
|
10
3
|
import { useState, useCallback } from 'react';
|
|
11
4
|
import { Alert, Button, Group, Loader, ScrollArea, Stack, Text } from '@mantine/core';
|
|
12
5
|
import { IconAlertCircle } from '@tabler/icons-react';
|
|
@@ -18,20 +11,17 @@ export const PermissionManager = ({ collections, contentRoot = 'content', permis
|
|
|
18
11
|
const [isSaving, setIsSaving] = useState(false);
|
|
19
12
|
const [error, setError] = useState(null);
|
|
20
13
|
const [activeLevel, setActiveLevel] = useState('read');
|
|
21
|
-
// Tree state management
|
|
22
14
|
const { annotatedTree, expandedNodes, selectedNode, localPermissions, isDirty, toggleNode, expandAll, collapseAll, selectNode, updateNodePermission, resetPermissions, setIsDirty, } = usePermissionTree({
|
|
23
15
|
collections,
|
|
24
16
|
contentRoot,
|
|
25
17
|
permissions,
|
|
26
18
|
contentTree,
|
|
27
19
|
});
|
|
28
|
-
// Groups and user search
|
|
29
20
|
const { groupSelectData, filteredGroups, groupLoadError, groupSearchQuery, showGroupSearch, setGroupSearchQuery, setShowGroupSearch, clearGroupLoadError, userSearchResults, isSearchingUsers, userSearchQuery, showUserSearch, userSearchError, setUserSearchQuery, toggleUserSearch, } = useGroupsAndUsers({
|
|
30
21
|
onListGroups,
|
|
31
22
|
onSearchUsers,
|
|
32
23
|
canEdit,
|
|
33
24
|
});
|
|
34
|
-
// Save handler
|
|
35
25
|
const handleSave = useCallback(async () => {
|
|
36
26
|
if (!onSave)
|
|
37
27
|
return;
|
|
@@ -48,12 +38,10 @@ export const PermissionManager = ({ collections, contentRoot = 'content', permis
|
|
|
48
38
|
setIsSaving(false);
|
|
49
39
|
}
|
|
50
40
|
}, [onSave, localPermissions, setIsDirty]);
|
|
51
|
-
// Discard handler
|
|
52
41
|
const handleDiscard = useCallback(() => {
|
|
53
42
|
resetPermissions();
|
|
54
43
|
setError(null);
|
|
55
44
|
}, [resetPermissions]);
|
|
56
|
-
// User add handler with search state cleanup
|
|
57
45
|
const handleAddUser = useCallback((nodePath, level, userId) => {
|
|
58
46
|
const treeNode = findTreeNode(annotatedTree, nodePath);
|
|
59
47
|
const permissionPath = treeNode?.type === 'folder' ? `${nodePath}/**` : nodePath;
|
|
@@ -66,11 +54,9 @@ export const PermissionManager = ({ collections, contentRoot = 'content', permis
|
|
|
66
54
|
allowedGroups: currentTarget?.allowedGroups,
|
|
67
55
|
});
|
|
68
56
|
}
|
|
69
|
-
// Clear search state
|
|
70
57
|
setUserSearchQuery('');
|
|
71
58
|
toggleUserSearch(false);
|
|
72
59
|
}, [annotatedTree, localPermissions, updateNodePermission, setUserSearchQuery, toggleUserSearch]);
|
|
73
|
-
// User remove handler
|
|
74
60
|
const handleRemoveUser = useCallback((nodePath, level, userId) => {
|
|
75
61
|
const treeNode = findTreeNode(annotatedTree, nodePath);
|
|
76
62
|
const permissionPath = treeNode?.type === 'folder' ? `${nodePath}/**` : nodePath;
|
|
@@ -83,7 +69,6 @@ export const PermissionManager = ({ collections, contentRoot = 'content', permis
|
|
|
83
69
|
allowedGroups: currentTarget.allowedGroups,
|
|
84
70
|
});
|
|
85
71
|
}, [annotatedTree, localPermissions, updateNodePermission]);
|
|
86
|
-
// Group add handler
|
|
87
72
|
const handleAddGroup = useCallback((nodePath, level, groupId) => {
|
|
88
73
|
const treeNode = findTreeNode(annotatedTree, nodePath);
|
|
89
74
|
const permissionPath = treeNode?.type === 'folder' ? `${nodePath}/**` : nodePath;
|
|
@@ -105,7 +90,6 @@ export const PermissionManager = ({ collections, contentRoot = 'content', permis
|
|
|
105
90
|
setGroupSearchQuery,
|
|
106
91
|
setShowGroupSearch,
|
|
107
92
|
]);
|
|
108
|
-
// Group remove handler
|
|
109
93
|
const handleRemoveGroup = useCallback((nodePath, level, groupId) => {
|
|
110
94
|
const treeNode = findTreeNode(annotatedTree, nodePath);
|
|
111
95
|
const permissionPath = treeNode?.type === 'folder' ? `${nodePath}/**` : nodePath;
|
|
@@ -1,29 +1,20 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Types for PermissionManager component
|
|
3
|
-
*/
|
|
4
1
|
import type { PathPermission, PermissionLevel, PermissionTarget } from '../../config/index.js';
|
|
5
|
-
import type { UserSearchResult,
|
|
2
|
+
import type { UserSearchResult, GroupSource, PermissionGroupOption } from '../../auth/types.js';
|
|
6
3
|
import type { EditorCollection } from '../Editor.js';
|
|
7
4
|
export interface PermissionManagerProps {
|
|
8
5
|
/** Collections from API */
|
|
9
6
|
collections?: EditorCollection[];
|
|
10
7
|
/** Content root path (default: 'content') */
|
|
11
8
|
contentRoot?: string;
|
|
12
|
-
/** Current permissions */
|
|
13
9
|
permissions: PathPermission[];
|
|
14
10
|
/** Whether user can edit permissions (admin only) */
|
|
15
11
|
canEdit: boolean;
|
|
16
|
-
/** Handler to save updated permissions */
|
|
17
12
|
onSave?: (permissions: PathPermission[]) => Promise<void>;
|
|
18
|
-
/** Handler to search users */
|
|
19
13
|
onSearchUsers?: (query: string, limit?: number) => Promise<UserSearchResult[]>;
|
|
20
|
-
/** Handler to get user metadata by ID */
|
|
21
14
|
onGetUserMetadata?: (userId: string) => Promise<UserSearchResult | null>;
|
|
22
15
|
/** Handler to list groups (internal + external, tagged by `source`) */
|
|
23
16
|
onListGroups?: () => Promise<PermissionGroupOption[]>;
|
|
24
|
-
/** Close handler */
|
|
25
17
|
onClose?: () => void;
|
|
26
|
-
/** Loading state */
|
|
27
18
|
loading?: boolean;
|
|
28
19
|
/** Optional: actual filesystem content tree (for entries not in schema) */
|
|
29
20
|
contentTree?: ContentNode;
|
|
@@ -50,5 +41,4 @@ export interface GroupSelectItem {
|
|
|
50
41
|
/** Which universe this option came from; shown as a tag in the picker. */
|
|
51
42
|
source: GroupSource;
|
|
52
43
|
}
|
|
53
|
-
|
|
54
|
-
export type { PathPermission, PermissionLevel, PermissionTarget, UserSearchResult, GroupMetadata, GroupSource, PermissionGroupOption, };
|
|
44
|
+
export type { PathPermission, PermissionLevel, PermissionTarget, UserSearchResult, GroupSource, PermissionGroupOption, };
|
|
@@ -1,41 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility functions for PermissionManager
|
|
3
|
-
*/
|
|
4
1
|
import type { TreeNode, ContentNode, PathPermission } from './types.js';
|
|
5
2
|
import type { EditorCollection } from '../Editor.js';
|
|
6
3
|
/**
|
|
7
4
|
* Search utility: Find a tree node by exact path match (recursive search).
|
|
8
|
-
* Used to locate nodes when updating permissions.
|
|
9
5
|
*
|
|
10
6
|
* @param node - Root node to start searching from
|
|
11
7
|
* @param path - The exact path to search for
|
|
12
8
|
* @returns The matching TreeNode or null if not found
|
|
13
9
|
*/
|
|
14
10
|
export declare function findTreeNode(node: TreeNode, path: string): TreeNode | null;
|
|
15
|
-
/**
|
|
16
|
-
* Transforms API/editor collections into permission tree nodes.
|
|
17
|
-
*
|
|
18
|
-
* Handles the case where buildEditorCollections returns a structure with the content root
|
|
19
|
-
* as a top-level collection. Avoids double-wrapping by detecting when a collection IS the
|
|
20
|
-
* content root itself and processing its children directly.
|
|
21
|
-
*
|
|
22
|
-
* @param collections - Array of EditorCollection from API or buildEditorCollections
|
|
23
|
-
* @param contentRoot - The content root path (e.g., "content")
|
|
24
|
-
* @param parentPath - Optional parent path for recursive calls
|
|
25
|
-
* @returns Array of TreeNode for the permission tree
|
|
26
|
-
*/
|
|
27
|
-
export declare function convertCollectionsToTreeNodes(collections: EditorCollection[], contentRoot: string, parentPath?: string): TreeNode[];
|
|
28
|
-
/**
|
|
29
|
-
* Merges filesystem content into schema tree for files not defined in the schema.
|
|
30
|
-
*
|
|
31
|
-
* Used to add files that exist in the filesystem but aren't explicitly defined in
|
|
32
|
-
* the schema (e.g., entries created manually via the filesystem). Only adds files,
|
|
33
|
-
* not folders - folders are expected to come from the schema.
|
|
34
|
-
*
|
|
35
|
-
* @param schemaNode - TreeNode from schema to merge into (mutated)
|
|
36
|
-
* @param contentNode - Actual filesystem content tree from API
|
|
37
|
-
*/
|
|
38
|
-
export declare function mergeContentTree(schemaNode: TreeNode, contentNode: ContentNode): void;
|
|
39
11
|
/**
|
|
40
12
|
* Build tree structure from EditorCollections.
|
|
41
13
|
*
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility functions for PermissionManager
|
|
3
|
-
*/
|
|
4
1
|
/**
|
|
5
2
|
* Search utility: Find a tree node by exact path match (recursive search).
|
|
6
|
-
* Used to locate nodes when updating permissions.
|
|
7
3
|
*
|
|
8
4
|
* @param node - Root node to start searching from
|
|
9
5
|
* @param path - The exact path to search for
|
|
@@ -22,19 +18,16 @@ export function findTreeNode(node, path) {
|
|
|
22
18
|
/**
|
|
23
19
|
* Transforms API/editor collections into permission tree nodes.
|
|
24
20
|
*
|
|
25
|
-
*
|
|
26
|
-
* as
|
|
27
|
-
*
|
|
21
|
+
* Skips wrapping when `collections` is a single item that IS the content root
|
|
22
|
+
* itself (as `buildEditorCollections` returns), processing its children
|
|
23
|
+
* directly instead of double-nesting.
|
|
28
24
|
*
|
|
29
25
|
* @param collections - Array of EditorCollection from API or buildEditorCollections
|
|
30
26
|
* @param contentRoot - The content root path (e.g., "content")
|
|
31
27
|
* @param parentPath - Optional parent path for recursive calls
|
|
32
28
|
* @returns Array of TreeNode for the permission tree
|
|
33
29
|
*/
|
|
34
|
-
|
|
35
|
-
// Special case: If we're at the top level (no parentPath) and the collections array
|
|
36
|
-
// contains exactly one item that IS the content root itself, skip creating a duplicate
|
|
37
|
-
// node for it and just process its children directly.
|
|
30
|
+
function convertCollectionsToTreeNodes(collections, contentRoot, parentPath) {
|
|
38
31
|
if (!parentPath && collections.length === 1 && collections[0].path === contentRoot) {
|
|
39
32
|
const rootCollection = collections[0];
|
|
40
33
|
return rootCollection.children
|
|
@@ -52,7 +45,6 @@ export function convertCollectionsToTreeNodes(collections, contentRoot, parentPa
|
|
|
52
45
|
type: collection.type === 'collection' ? 'folder' : 'file',
|
|
53
46
|
children: [],
|
|
54
47
|
};
|
|
55
|
-
// Recursively process nested collections
|
|
56
48
|
if (collection.children) {
|
|
57
49
|
node.children = convertCollectionsToTreeNodes(collection.children, contentRoot, logicalPath);
|
|
58
50
|
}
|
|
@@ -61,26 +53,24 @@ export function convertCollectionsToTreeNodes(collections, contentRoot, parentPa
|
|
|
61
53
|
return nodes;
|
|
62
54
|
}
|
|
63
55
|
/**
|
|
64
|
-
* Merges filesystem content into schema tree
|
|
56
|
+
* Merges filesystem content into the schema tree.
|
|
65
57
|
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
58
|
+
* Adds files that exist in the filesystem but aren't defined in the schema
|
|
59
|
+
* (e.g., entries created manually), never folders — folders are expected to
|
|
60
|
+
* come from the schema.
|
|
69
61
|
*
|
|
70
62
|
* @param schemaNode - TreeNode from schema to merge into (mutated)
|
|
71
63
|
* @param contentNode - Actual filesystem content tree from API
|
|
72
64
|
*/
|
|
73
|
-
|
|
65
|
+
function mergeContentTree(schemaNode, contentNode) {
|
|
74
66
|
contentNode.children?.forEach((child) => {
|
|
75
67
|
const existing = schemaNode.children.find((n) => n.name === child.name);
|
|
76
68
|
if (existing) {
|
|
77
|
-
// If this is a folder/collection that exists in schema, recursively merge its children
|
|
78
69
|
if (child.type === 'folder' && child.children) {
|
|
79
70
|
mergeContentTree(existing, child);
|
|
80
71
|
}
|
|
81
72
|
}
|
|
82
73
|
else if (child.type === 'file') {
|
|
83
|
-
// Add file not in schema (e.g., entry created via filesystem)
|
|
84
74
|
schemaNode.children.push({
|
|
85
75
|
path: child.path,
|
|
86
76
|
name: child.name,
|
|
@@ -105,10 +95,8 @@ export function buildTree(contentTree, contentRoot = 'content', collections) {
|
|
|
105
95
|
type: 'folder',
|
|
106
96
|
children: [],
|
|
107
97
|
};
|
|
108
|
-
// Build from collections if provided
|
|
109
98
|
if (collections && collections.length > 0) {
|
|
110
99
|
root.children = convertCollectionsToTreeNodes(collections, contentRoot);
|
|
111
|
-
// Merge contentTree if provided
|
|
112
100
|
if (contentTree) {
|
|
113
101
|
mergeContentTree(root, contentTree);
|
|
114
102
|
}
|
|
@@ -128,9 +116,7 @@ export function buildTree(contentTree, contentRoot = 'content', collections) {
|
|
|
128
116
|
*/
|
|
129
117
|
export function annotateTreeWithPermissions(node, permissions) {
|
|
130
118
|
const folderPath = node.type === 'folder' ? `${node.path}/**` : node.path;
|
|
131
|
-
// Find direct permission
|
|
132
119
|
const directPerm = permissions.find((p) => p.path === folderPath || p.path === node.path);
|
|
133
|
-
// Find inherited permission from parent
|
|
134
120
|
let inheritedPerm;
|
|
135
121
|
const pathParts = node.path.split('/');
|
|
136
122
|
for (let i = pathParts.length - 1; i >= 0; i--) {
|
|
@@ -40,7 +40,7 @@ export interface HighlightMessage {
|
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
42
|
* Preview → editor report that the current draft fails to compile/render
|
|
43
|
-
* (e.g. malformed MDX). `message: null` clears
|
|
43
|
+
* (e.g. malformed MDX). `message: null` clears an earlier error.
|
|
44
44
|
*/
|
|
45
45
|
export interface PreviewErrorMessage {
|
|
46
46
|
type: typeof CANOPY_PREVIEW_ERROR;
|
|
@@ -48,6 +48,10 @@ export interface PreviewErrorMessage {
|
|
|
48
48
|
message: string | null;
|
|
49
49
|
fieldPath?: string;
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Convenience hook that wires draft updates, focus emitter, and highlight toggling together.
|
|
53
|
+
* Returns live data plus helpers for setting data-canopy-path attributes.
|
|
54
|
+
*/
|
|
51
55
|
export declare const useCanopyPreview: <T>(opts: {
|
|
52
56
|
path?: string;
|
|
53
57
|
initialData: T;
|
|
@@ -57,10 +57,6 @@ export const sendDraftUpdate = (iframe, message, targetOrigin) => {
|
|
|
57
57
|
return;
|
|
58
58
|
iframe.contentWindow.postMessage(message, target);
|
|
59
59
|
};
|
|
60
|
-
/**
|
|
61
|
-
* Convenience hook that wires draft updates, focus emitter, and highlight toggling together.
|
|
62
|
-
* Returns live data plus helpers for setting data-canopy-path attributes.
|
|
63
|
-
*/
|
|
64
60
|
const resolvePreviewPath = (explicit) => {
|
|
65
61
|
if (explicit)
|
|
66
62
|
return explicit;
|
|
@@ -68,6 +64,10 @@ const resolvePreviewPath = (explicit) => {
|
|
|
68
64
|
return '';
|
|
69
65
|
return `${window.location.pathname}${window.location.search}`;
|
|
70
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* Convenience hook that wires draft updates, focus emitter, and highlight toggling together.
|
|
69
|
+
* Returns live data plus helpers for setting data-canopy-path attributes.
|
|
70
|
+
*/
|
|
71
71
|
export const useCanopyPreview = (opts) => {
|
|
72
72
|
const resolvedPath = resolvePreviewPath(opts.path);
|
|
73
73
|
const editorOrigin = opts.editorOrigin;
|
|
@@ -26,7 +26,6 @@ export interface ExistingCollection {
|
|
|
26
26
|
entries: ExistingEntryType[];
|
|
27
27
|
}
|
|
28
28
|
export interface CollectionEditorProps {
|
|
29
|
-
/** Whether the modal is open */
|
|
30
29
|
isOpen: boolean;
|
|
31
30
|
/** Collection being edited (null for create mode) */
|
|
32
31
|
editingCollection: ExistingCollection | null;
|
|
@@ -42,12 +41,8 @@ export interface CollectionEditorProps {
|
|
|
42
41
|
onUpdateEntryType?: (collectionPath: LogicalPath, entryTypeName: string, updates: Partial<CreateEntryTypeInput>) => Promise<SchemaOpResult>;
|
|
43
42
|
/** Called when an entry type is removed (edit mode only) */
|
|
44
43
|
onRemoveEntryType?: (collectionPath: LogicalPath, entryTypeName: string) => Promise<SchemaOpResult> | void;
|
|
45
|
-
/** Called when modal is closed */
|
|
46
44
|
onClose: () => void;
|
|
47
|
-
/** Whether a save operation is in progress */
|
|
48
45
|
isSaving?: boolean;
|
|
49
|
-
/** Error message to display */
|
|
50
46
|
error?: string | null;
|
|
51
47
|
}
|
|
52
48
|
export declare function CollectionEditor({ isOpen, editingCollection, parentPath, availableSchemas, onSave, onAddEntryType, onUpdateEntryType, onRemoveEntryType, onClose, isSaving, error, }: CollectionEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
53
|
-
export default CollectionEditor;
|
|
@@ -3,13 +3,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
/**
|
|
4
4
|
* CollectionEditor - Modal for creating/editing collections.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* When creating a collection, at least one entry type is required.
|
|
12
|
-
* When editing, only name and label can be changed (entry types are managed separately).
|
|
6
|
+
* A collection has a name (machine-readable id), label (display name), and
|
|
7
|
+
* entries (entry types defining what content can be created). Create mode
|
|
8
|
+
* requires at least one entry type; edit mode only allows changing name and
|
|
9
|
+
* label (entry types are managed separately).
|
|
13
10
|
*/
|
|
14
11
|
import { useState, useCallback, useEffect } from 'react';
|
|
15
12
|
import { Modal, Stack, TextInput, Group, Button, Alert, Text, Paper, ActionIcon, Menu, Divider, Badge, } from '@mantine/core';
|
|
@@ -17,12 +14,8 @@ import { IconAlertCircle, IconPlus, IconDotsVertical, IconTrash, IconEdit, IconS
|
|
|
17
14
|
import { EntryTypeEditor } from './EntryTypeEditor.js';
|
|
18
15
|
import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal.js';
|
|
19
16
|
import { getErrorMessage } from '../../utils/error.js';
|
|
20
|
-
// ============================================================================
|
|
21
|
-
// Component
|
|
22
|
-
// ============================================================================
|
|
23
17
|
export function CollectionEditor({ isOpen, editingCollection, parentPath, availableSchemas, onSave, onAddEntryType, onUpdateEntryType, onRemoveEntryType, onClose, isSaving = false, error = null, }) {
|
|
24
18
|
const isEditMode = editingCollection !== null;
|
|
25
|
-
// Form state
|
|
26
19
|
const [formData, setFormData] = useState({
|
|
27
20
|
name: '',
|
|
28
21
|
label: '',
|
|
@@ -30,18 +23,14 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
30
23
|
});
|
|
31
24
|
// Slug field state (edit mode only)
|
|
32
25
|
const [slug, setSlug] = useState('');
|
|
33
|
-
// Local validation error
|
|
34
26
|
const [validationError, setValidationError] = useState(null);
|
|
35
|
-
// Entry type editor state
|
|
36
27
|
const [entryTypeEditorOpen, setEntryTypeEditorOpen] = useState(false);
|
|
37
28
|
const [editingEntryType, setEditingEntryType] = useState(null);
|
|
38
29
|
const [editingEntryTypeIndex, setEditingEntryTypeIndex] = useState(null);
|
|
39
30
|
const [entryTypeSaving, setEntryTypeSaving] = useState(false);
|
|
40
31
|
const [entryTypeError, setEntryTypeError] = useState(null);
|
|
41
|
-
// Delete entry type confirmation state
|
|
42
32
|
const [deleteEntryTypeModalOpen, setDeleteEntryTypeModalOpen] = useState(false);
|
|
43
33
|
const [deletingEntryType, setDeletingEntryType] = useState(null);
|
|
44
|
-
// Reset form when modal opens or editing item changes
|
|
45
34
|
useEffect(() => {
|
|
46
35
|
if (isOpen) {
|
|
47
36
|
if (editingCollection) {
|
|
@@ -50,7 +39,7 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
50
39
|
label: editingCollection.label || '',
|
|
51
40
|
entries: [], // Entry types are managed separately in edit mode
|
|
52
41
|
});
|
|
53
|
-
//
|
|
42
|
+
// Slug is the logical path's last segment before its embedded id (e.g. "posts.abc123" -> "posts").
|
|
54
43
|
const pathParts = editingCollection.logicalPath.split('/');
|
|
55
44
|
const lastPart = pathParts[pathParts.length - 1];
|
|
56
45
|
const slugPart = lastPart?.split('.')[0] || '';
|
|
@@ -67,19 +56,17 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
67
56
|
setValidationError(null);
|
|
68
57
|
}
|
|
69
58
|
}, [isOpen, editingCollection]);
|
|
70
|
-
// Update a form field
|
|
71
59
|
const updateField = useCallback((field, value) => {
|
|
72
60
|
setFormData((prev) => ({ ...prev, [field]: value }));
|
|
73
61
|
setValidationError(null);
|
|
74
62
|
}, []);
|
|
75
|
-
// Validate form
|
|
76
63
|
const validate = useCallback(() => {
|
|
77
64
|
if (!formData.name.trim()) {
|
|
78
65
|
setValidationError('Name is required');
|
|
79
66
|
return false;
|
|
80
67
|
}
|
|
81
|
-
// Enforced in both create and edit mode
|
|
82
|
-
//
|
|
68
|
+
// Enforced in both create and edit mode: the server rejects unsafe
|
|
69
|
+
// names too, but this validates for immediate feedback.
|
|
83
70
|
if (!/^[a-z][a-z0-9-]*$/.test(formData.name)) {
|
|
84
71
|
setValidationError('Name must start with a letter and contain only lowercase letters, numbers, and hyphens');
|
|
85
72
|
return false;
|
|
@@ -94,12 +81,10 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
94
81
|
}
|
|
95
82
|
return true;
|
|
96
83
|
}, [formData, isEditMode]);
|
|
97
|
-
// Handle save
|
|
98
84
|
const handleSave = useCallback(() => {
|
|
99
85
|
if (!validate())
|
|
100
86
|
return;
|
|
101
87
|
if (isEditMode) {
|
|
102
|
-
// Only include changed fields for update
|
|
103
88
|
const updates = {};
|
|
104
89
|
if (formData.name !== (editingCollection?.name || '')) {
|
|
105
90
|
updates.name = formData.name.trim() || undefined;
|
|
@@ -107,7 +92,6 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
107
92
|
if (formData.label !== (editingCollection?.label || '')) {
|
|
108
93
|
updates.label = formData.label || undefined;
|
|
109
94
|
}
|
|
110
|
-
// Include slug if changed
|
|
111
95
|
const pathParts = editingCollection?.logicalPath.split('/') || [];
|
|
112
96
|
const lastPart = pathParts[pathParts.length - 1];
|
|
113
97
|
const currentSlug = lastPart?.split('.')[0] || '';
|
|
@@ -117,7 +101,6 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
117
101
|
onSave(updates, false);
|
|
118
102
|
}
|
|
119
103
|
else {
|
|
120
|
-
// Create new collection
|
|
121
104
|
const createData = {
|
|
122
105
|
name: formData.name.trim(),
|
|
123
106
|
entries: formData.entries,
|
|
@@ -131,7 +114,6 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
131
114
|
onSave(createData, true);
|
|
132
115
|
}
|
|
133
116
|
}, [formData, slug, isEditMode, editingCollection, parentPath, validate, onSave]);
|
|
134
|
-
// Entry type management (create mode)
|
|
135
117
|
const handleOpenAddEntryType = useCallback(() => {
|
|
136
118
|
setEditingEntryType(null);
|
|
137
119
|
setEditingEntryTypeIndex(null);
|
|
@@ -146,7 +128,6 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
146
128
|
}, []);
|
|
147
129
|
const handleEntryTypeSave = useCallback(async (data, isNew) => {
|
|
148
130
|
if (isEditMode && editingCollection) {
|
|
149
|
-
// In edit mode, delegate to parent handlers
|
|
150
131
|
setEntryTypeSaving(true);
|
|
151
132
|
setEntryTypeError(null);
|
|
152
133
|
try {
|
|
@@ -163,9 +144,8 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
163
144
|
}
|
|
164
145
|
}
|
|
165
146
|
catch (err) {
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
// in case a caller violates that contract.
|
|
147
|
+
// Last resort: onAddEntryType/onUpdateEntryType return result objects
|
|
148
|
+
// by contract and aren't expected to throw; guards a caller violating it.
|
|
169
149
|
setEntryTypeError(getErrorMessage(err));
|
|
170
150
|
return;
|
|
171
151
|
}
|
|
@@ -219,7 +199,6 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
219
199
|
setDeleteEntryTypeModalOpen(false);
|
|
220
200
|
setDeletingEntryType(null);
|
|
221
201
|
}, [deletingEntryType, isEditMode, editingCollection, onRemoveEntryType]);
|
|
222
|
-
// Get entry types to display
|
|
223
202
|
const displayEntryTypes = isEditMode
|
|
224
203
|
? editingCollection?.entries || []
|
|
225
204
|
: formData.entries;
|
|
@@ -241,4 +220,3 @@ export function CollectionEditor({ isOpen, editingCollection, parentPath, availa
|
|
|
241
220
|
setDeletingEntryType(null);
|
|
242
221
|
} })] }));
|
|
243
222
|
}
|
|
244
|
-
export default CollectionEditor;
|
|
@@ -9,7 +9,6 @@ export interface EntryTypeFormData {
|
|
|
9
9
|
maxItems: number | undefined;
|
|
10
10
|
}
|
|
11
11
|
export interface EntryTypeEditorProps {
|
|
12
|
-
/** Whether the modal is open */
|
|
13
12
|
isOpen: boolean;
|
|
14
13
|
/** Entry type being edited (null for create mode) */
|
|
15
14
|
editingEntryType: {
|
|
@@ -25,14 +24,9 @@ export interface EntryTypeEditorProps {
|
|
|
25
24
|
availableSchemas: string[];
|
|
26
25
|
/** Existing entry type names in the collection (for duplicate validation) */
|
|
27
26
|
existingEntryTypeNames?: string[];
|
|
28
|
-
/** Called when save is clicked */
|
|
29
27
|
onSave: (data: CreateEntryTypeInput | UpdateEntryTypeInput, isNew: boolean) => void;
|
|
30
|
-
/** Called when modal is closed */
|
|
31
28
|
onClose: () => void;
|
|
32
|
-
/** Whether a save operation is in progress */
|
|
33
29
|
isSaving?: boolean;
|
|
34
|
-
/** Error message to display */
|
|
35
30
|
error?: string | null;
|
|
36
31
|
}
|
|
37
32
|
export declare function EntryTypeEditor({ isOpen, editingEntryType, availableSchemas, existingEntryTypeNames, onSave, onClose, isSaving, error, }: EntryTypeEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
-
export default EntryTypeEditor;
|