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
package/dist/api/assets.d.ts
CHANGED
|
@@ -48,31 +48,6 @@ declare const finalizeAssetBodySchema: z.ZodObject<{
|
|
|
48
48
|
stagingKey: string;
|
|
49
49
|
}>;
|
|
50
50
|
export type FinalizeAssetBody = z.infer<typeof finalizeAssetBodySchema>;
|
|
51
|
-
/**
|
|
52
|
-
* Declared as `params` (not just parsed ad hoc from req.query) so the client
|
|
53
|
-
* generator (scripts/generate-client.ts) sees a paramsSchema and emits a
|
|
54
|
-
* method that accepts and forwards `cursor`/`limit` (API-H4) instead of a
|
|
55
|
-
* no-arg `assets.list()` that can never pass them.
|
|
56
|
-
*/
|
|
57
|
-
declare const listAssetsParamsSchema: z.ZodObject<{
|
|
58
|
-
cursor: z.ZodOptional<z.ZodString>;
|
|
59
|
-
limit: z.ZodOptional<z.ZodNumber>;
|
|
60
|
-
}, "strip", z.ZodTypeAny, {
|
|
61
|
-
cursor?: string | undefined;
|
|
62
|
-
limit?: number | undefined;
|
|
63
|
-
}, {
|
|
64
|
-
cursor?: string | undefined;
|
|
65
|
-
limit?: number | undefined;
|
|
66
|
-
}>;
|
|
67
|
-
export type ListAssetsParams = z.infer<typeof listAssetsParamsSchema>;
|
|
68
|
-
declare const deleteAssetParamsSchema: z.ZodObject<{
|
|
69
|
-
key: z.ZodString;
|
|
70
|
-
}, "strip", z.ZodTypeAny, {
|
|
71
|
-
key: string;
|
|
72
|
-
}, {
|
|
73
|
-
key: string;
|
|
74
|
-
}>;
|
|
75
|
-
export type DeleteAssetParams = z.infer<typeof deleteAssetParamsSchema>;
|
|
76
51
|
/**
|
|
77
52
|
* Exported routes for router registration and client codegen.
|
|
78
53
|
*/
|
package/dist/api/assets.js
CHANGED
|
@@ -23,9 +23,6 @@ const MOCK_ASSET_RECORD = {
|
|
|
23
23
|
uploadedAt: '2024-01-01T00:00:00.000Z',
|
|
24
24
|
src: '/assets/t/orig/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/sample.png',
|
|
25
25
|
};
|
|
26
|
-
// ============================================================================
|
|
27
|
-
// Zod Schemas for Validation
|
|
28
|
-
// ============================================================================
|
|
29
26
|
const filenameSchema = z.string().min(1).max(255);
|
|
30
27
|
const presignAssetBodySchema = z.object({
|
|
31
28
|
filename: filenameSchema,
|
|
@@ -51,13 +48,10 @@ const hash32Schema = z
|
|
|
51
48
|
.string()
|
|
52
49
|
.regex(/^[a-f0-9]{32}$/, 'key must be a 32-character lowercase hex string');
|
|
53
50
|
const deleteAssetParamsSchema = z.object({ key: hash32Schema });
|
|
54
|
-
// ============================================================================
|
|
55
|
-
// Handlers
|
|
56
|
-
// ============================================================================
|
|
57
51
|
/**
|
|
58
52
|
* Presign a direct (or proxied) upload target. Any authenticated user - there
|
|
59
53
|
* is no finer "editor" role, and upload needs to work for every non-admin
|
|
60
|
-
* user too (see guard semantics in .claude/future-tasks/assets-media-system.md).
|
|
54
|
+
* user too (see guard semantics in .claude/future-tasks/resolved/assets-media-system.md).
|
|
61
55
|
*/
|
|
62
56
|
const presignAssetHandler = async (ctx, _req, body) => {
|
|
63
57
|
if (!ctx.assetStore)
|
|
@@ -93,13 +87,11 @@ const finalizeAssetHandler = async (ctx, req, body) => {
|
|
|
93
87
|
return { ok: true, status: 200, data: { asset: toAssetRecord(result.meta) } };
|
|
94
88
|
};
|
|
95
89
|
/**
|
|
96
|
-
* Proxied upload for stores that don't support direct-to-storage presigning
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* once (see http/handler.ts). Any authenticated user (same rationale as
|
|
102
|
-
* presign/finalize).
|
|
90
|
+
* Proxied upload for stores that don't support direct-to-storage presigning (LocalAssetStore in
|
|
91
|
+
* dev). Reads multipart/form-data (a `file` part, optional `filename` override) instead of JSON;
|
|
92
|
+
* this route sets `bodyFormat: 'multipart'` so the core handler skips its default `req.json()`
|
|
93
|
+
* parse, since the body stream can only be read once (see http/handler.ts). Any authenticated
|
|
94
|
+
* user (same rationale as presign/finalize).
|
|
103
95
|
*/
|
|
104
96
|
const uploadProxiedHandler = async (ctx, req) => {
|
|
105
97
|
if (!ctx.assetStore)
|
|
@@ -118,15 +110,11 @@ const uploadProxiedHandler = async (ctx, req) => {
|
|
|
118
110
|
error: 'This server adapter does not support multipart form-data uploads',
|
|
119
111
|
};
|
|
120
112
|
}
|
|
121
|
-
// Early size guard from
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
//
|
|
126
|
-
// to learn "the store's max" (mirrors presignAssetHandler's own use of it)
|
|
127
|
-
// - filename/contentType are placeholders here since only `.maxBytes` is
|
|
128
|
-
// read; the real `beginUpload()` call below (with the actual filename)
|
|
129
|
-
// still runs after the body is read to build the real staging target.
|
|
113
|
+
// Early size guard from Content-Length, before the multipart body is read - `formData()`/
|
|
114
|
+
// `arrayBuffer()` below fully buffer the upload into memory, so without this an over-cap
|
|
115
|
+
// request still pays the full read cost before the post-read check further down rejects it.
|
|
116
|
+
// `beginUpload()` is the store-agnostic way to learn the store's max; filename/contentType here
|
|
117
|
+
// are placeholders since only `.maxBytes` is read.
|
|
130
118
|
const contentLengthHeader = req.rawRequest.header('content-length');
|
|
131
119
|
if (contentLengthHeader !== null) {
|
|
132
120
|
const contentLength = Number(contentLengthHeader);
|
|
@@ -179,7 +167,7 @@ const uploadProxiedHandler = async (ctx, req) => {
|
|
|
179
167
|
};
|
|
180
168
|
/**
|
|
181
169
|
* List assets - any authenticated user can list assets (key enumeration is
|
|
182
|
-
* accepted: unlisted != private, see assets-media-system.md).
|
|
170
|
+
* accepted: unlisted != private, see .claude/future-tasks/resolved/assets-media-system.md).
|
|
183
171
|
*/
|
|
184
172
|
const listAssetsHandler = async (ctx, _req, params) => {
|
|
185
173
|
if (!ctx.assetStore)
|
|
@@ -191,31 +179,26 @@ const listAssetsHandler = async (ctx, _req, params) => {
|
|
|
191
179
|
return { ok: true, status: 200, data: { assets: items.map(toAssetRecord), nextCursor } };
|
|
192
180
|
};
|
|
193
181
|
/**
|
|
194
|
-
* Delete asset - an Admin may delete any asset; anyone else may delete only an
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
* a future GC worker task (see assets-media-system.md).
|
|
182
|
+
* Delete asset - an Admin may delete any asset; anyone else may delete only an asset whose
|
|
183
|
+
* recorded `uploadedBy` is them. `key` (hash32) is pre-validated by `deleteAssetParamsSchema`.
|
|
184
|
+
* Deletes the meta sidecar only - blobs are immortal until a future GC worker task (see
|
|
185
|
+
* .claude/future-tasks/resolved/assets-media-system.md).
|
|
199
186
|
*
|
|
200
|
-
* The ownership check lives here
|
|
201
|
-
*
|
|
187
|
+
* The ownership check lives here, not in a declarative guard, because it needs the asset's meta,
|
|
188
|
+
* which guards can't read. Two fail-closed choices:
|
|
189
|
+
* - Meta with no `uploadedBy` (the field is optional) is admin-only — defaulting to "anyone may
|
|
190
|
+
* delete" would open every legacy asset to everyone.
|
|
191
|
+
* - A missing asset returns the same 403 as an unowned one for non-admins, so the endpoint isn't
|
|
192
|
+
* an existence oracle over a content-addressed keyspace.
|
|
202
193
|
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
* -
|
|
207
|
-
* the endpoint isn't an existence oracle over a content-addressed keyspace.
|
|
194
|
+
* `uploadedBy` records the FIRST uploader only: finalizeAsset dedups on content hash, so a second
|
|
195
|
+
* person uploading an identical file gains no delete rights over it — benign (a 403 where they
|
|
196
|
+
* expected success, never the reverse; see
|
|
197
|
+
* .claude/future-tasks/asset-listing-cross-branch-exposure.md).
|
|
208
198
|
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
* expected success, never the reverse) - see
|
|
213
|
-
* .claude/future-tasks/asset-listing-cross-branch-exposure.md.
|
|
214
|
-
*
|
|
215
|
-
* COUPLED to the blob-GC follow-up in asset-review-followups.md: this
|
|
216
|
-
* permission is safe because delete is a de-list, not a destroy - nothing that
|
|
217
|
-
* another branch references breaks. If GC ever makes delete destroy the
|
|
218
|
-
* underlying blob, revisit this (it would then need a reference check).
|
|
199
|
+
* Coupled to the blob-GC follow-up in asset-review-followups.md: this permission is safe because
|
|
200
|
+
* delete is a de-list, not a destroy — nothing another branch references breaks. If GC ever makes
|
|
201
|
+
* delete destroy the blob, this needs a reference check too.
|
|
219
202
|
*/
|
|
220
203
|
const deleteAssetHandler = async (ctx, req, params) => {
|
|
221
204
|
if (!ctx.assetStore)
|
|
@@ -232,16 +215,13 @@ const deleteAssetHandler = async (ctx, req, params) => {
|
|
|
232
215
|
/** Cache-Control applied to every transform output this route writes/serves - matches finalize.ts's PUBLIC_CACHE_CONTROL for static public objects. */
|
|
233
216
|
const TRANSFORM_CACHE_CONTROL = 'public, max-age=31536000, immutable';
|
|
234
217
|
/**
|
|
235
|
-
* Lazy dev-mode emulation of the prod transform Lambda (
|
|
236
|
-
* `
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
* dedupes with any equivalent request), then serve the bytes just computed
|
|
240
|
-
* (no re-read from the store).
|
|
218
|
+
* Lazy dev-mode emulation of the prod transform Lambda (reuses `parseTransformPath`/
|
|
219
|
+
* `formatDirectives`/`applyTransform` unchanged): parse, load the original, transform, write the
|
|
220
|
+
* result back under its CANONICAL key (so a non-canonically-ordered directive string still
|
|
221
|
+
* dedupes with any equivalent request), then serve the bytes just computed.
|
|
241
222
|
*
|
|
242
|
-
* `key` here
|
|
243
|
-
* `
|
|
244
|
-
* check in `rawAssetHandler`.
|
|
223
|
+
* `key` here already starts with `assets/t/` and already missed `rawAssetHandler`'s cache-hit
|
|
224
|
+
* `readPublicObject` check.
|
|
245
225
|
*/
|
|
246
226
|
async function serveLazyTransform(assetStore, key) {
|
|
247
227
|
const rest = key.slice(ASSET_PREFIXES.transform.length + 1);
|
|
@@ -256,12 +236,10 @@ async function serveLazyTransform(assetStore, key) {
|
|
|
256
236
|
if (meta.kind !== 'raster') {
|
|
257
237
|
return { ok: false, status: 400, error: 'Not a raster asset - svg/pdf are served statically' };
|
|
258
238
|
}
|
|
259
|
-
// The slug is decorative in the URL but load-bearing in the stored key, so
|
|
260
|
-
//
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
// `meta.slug` (assets/asset-url.ts). Mirrors the prod transform Lambda's
|
|
264
|
-
// handler.ts check - the two paths must agree, or dev accepts URLs prod 404s.
|
|
239
|
+
// The slug is decorative in the URL but load-bearing in the stored key, so it must equal the
|
|
240
|
+
// asset's real slug — the parser only enforces `[a-z0-9-]+`, and any other string that passes
|
|
241
|
+
// it aliases the same image into a new cache key. Mirrors the prod transform Lambda's check
|
|
242
|
+
// (assets/asset-url.ts); the two paths must agree, or dev accepts URLs prod 404s.
|
|
265
243
|
if (parsed.slug !== meta.slug) {
|
|
266
244
|
return { ok: false, status: 404, error: 'Not found' };
|
|
267
245
|
}
|
|
@@ -279,11 +257,9 @@ async function serveLazyTransform(assetStore, key) {
|
|
|
279
257
|
}
|
|
280
258
|
const transformed = await applyTransform({ data: original.data, ext: original.ext }, parsed.directives);
|
|
281
259
|
if (!transformed.ok) {
|
|
282
|
-
// Pass the real status through
|
|
283
|
-
//
|
|
284
|
-
//
|
|
285
|
-
// failure (422), none of which are "this server failed" (502). Mirrors
|
|
286
|
-
// the prod transform Lambda's own handler.ts, which makes the same fix.
|
|
260
|
+
// Pass the real status through instead of flattening every rejection to 502:
|
|
261
|
+
// `applyTransform` already distinguishes client-input errors (400/413) from a genuine decode
|
|
262
|
+
// failure (422), none of which are "this server failed." Mirrors the prod transform Lambda.
|
|
287
263
|
return { ok: false, status: transformed.status, error: transformed.error };
|
|
288
264
|
}
|
|
289
265
|
const canonicalKey = `${ASSET_PREFIXES.transform}/${formatDirectives(parsed.directives)}/${parsed.hash32}/${parsed.slug}.${parsed.ext}`;
|
|
@@ -301,19 +277,15 @@ async function serveLazyTransform(assetStore, key) {
|
|
|
301
277
|
};
|
|
302
278
|
}
|
|
303
279
|
/**
|
|
304
|
-
* Serve a public asset object (sanitized svg/pdf finalize wrote, or a
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
* `
|
|
308
|
-
* (
|
|
309
|
-
* method that calls `response.json()` would be actively wrong. Consumers hit
|
|
310
|
-
* this route directly (an `<img>`/`<a>` src, or a framework rewrite), never
|
|
311
|
-
* through `client.ts`.
|
|
280
|
+
* Serve a public asset object (sanitized svg/pdf finalize wrote, or a cached transform output)
|
|
281
|
+
* for dev-mode `/assets/*` rewrites. Hand-built (not `defineEndpoint`), not registered in
|
|
282
|
+
* `ASSET_ROUTES`/the client generator: this returns raw bytes (`CanopyBinaryResponse`), not a
|
|
283
|
+
* JSON envelope, so a generated `response.json()` client method would be wrong. Consumers hit
|
|
284
|
+
* this route directly (`<img>`/`<a>` src, or a framework rewrite), never through `client.ts`.
|
|
312
285
|
*
|
|
313
|
-
* Transform outputs (`assets/t/...`) are cache-checked
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
* mirrors the prod design (CloudFront origin-group -> S3 -> Lambda on miss).
|
|
286
|
+
* Transform outputs (`assets/t/...`) are cache-checked like any other public object first — only
|
|
287
|
+
* a MISS under `assets/t/` falls through to `serveLazyTransform`. Mirrors prod (CloudFront
|
|
288
|
+
* origin-group -> S3 -> Lambda on miss).
|
|
317
289
|
*/
|
|
318
290
|
const rawAssetHandler = async (ctx, _req, params) => {
|
|
319
291
|
if (!ctx.assetStore)
|
|
@@ -346,16 +318,9 @@ const rawAssetHandler = async (ctx, _req, params) => {
|
|
|
346
318
|
}
|
|
347
319
|
return serveLazyTransform(ctx.assetStore, key);
|
|
348
320
|
};
|
|
349
|
-
// ============================================================================
|
|
350
|
-
// Route Definitions with defineEndpoint
|
|
351
|
-
// ============================================================================
|
|
352
|
-
//
|
|
353
321
|
// Deliberately no 'writableBranch' guard on any endpoint below: none take a
|
|
354
322
|
// :branch param -- the asset store is branch-agnostic (a single global store,
|
|
355
323
|
// see assets/factory.ts), so the protected-base-branch predicate doesn't apply.
|
|
356
|
-
/**
|
|
357
|
-
* POST /assets/presign
|
|
358
|
-
*/
|
|
359
324
|
const presignAsset = defineEndpoint({
|
|
360
325
|
namespace: 'assets',
|
|
361
326
|
name: 'presign',
|
|
@@ -370,9 +335,6 @@ const presignAsset = defineEndpoint({
|
|
|
370
335
|
},
|
|
371
336
|
handler: presignAssetHandler,
|
|
372
337
|
});
|
|
373
|
-
/**
|
|
374
|
-
* POST /assets/finalize
|
|
375
|
-
*/
|
|
376
338
|
const finalizeAsset = defineEndpoint({
|
|
377
339
|
namespace: 'assets',
|
|
378
340
|
name: 'finalize',
|
|
@@ -399,9 +361,6 @@ const uploadProxied = defineEndpoint({
|
|
|
399
361
|
defaultMockData: { asset: MOCK_ASSET_RECORD },
|
|
400
362
|
handler: uploadProxiedHandler,
|
|
401
363
|
});
|
|
402
|
-
/**
|
|
403
|
-
* GET /assets
|
|
404
|
-
*/
|
|
405
364
|
const listAssets = defineEndpoint({
|
|
406
365
|
namespace: 'assets',
|
|
407
366
|
name: 'list',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { ApiResponse } from './types.js';
|
|
3
|
+
/** @internal No importer; deletion candidate in knip-no-importer-deletion-candidates.md. */
|
|
3
4
|
export interface MarkAsMergedParams {
|
|
4
5
|
branch: string;
|
|
5
6
|
}
|
|
@@ -12,7 +13,6 @@ export type BranchMergeResponse = ApiResponse<{
|
|
|
12
13
|
}>;
|
|
13
14
|
/**
|
|
14
15
|
* Mark a branch as merged and archived after PR is merged on GitHub
|
|
15
|
-
* POST /:branch/mark-merged
|
|
16
16
|
*
|
|
17
17
|
* Deliberately no 'submittableBranch' guard: needs no new guard because the
|
|
18
18
|
* handler above already requires status === 'submitted' AND a recorded
|
package/dist/api/branch-merge.js
CHANGED
|
@@ -27,7 +27,6 @@ const markAsMergedHandler = async (gc, ctx, _req, params) => {
|
|
|
27
27
|
error: 'Cannot mark as merged: no pull request associated with this branch',
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
|
-
// Optionally verify PR is actually merged via GitHub API
|
|
31
30
|
if (ctx.services.githubService) {
|
|
32
31
|
try {
|
|
33
32
|
const pr = await ctx.services.githubService.getPullRequest(branchContext.branch.pullRequestNumber);
|
|
@@ -70,7 +69,6 @@ const markAsMergedHandler = async (gc, ctx, _req, params) => {
|
|
|
70
69
|
};
|
|
71
70
|
/**
|
|
72
71
|
* Mark a branch as merged and archived after PR is merged on GitHub
|
|
73
|
-
* POST /:branch/mark-merged
|
|
74
72
|
*
|
|
75
73
|
* Deliberately no 'submittableBranch' guard: needs no new guard because the
|
|
76
74
|
* handler above already requires status === 'submitted' AND a recorded
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { BranchResponse } from './branch.js';
|
|
3
|
-
/**
|
|
4
|
-
* Request changes on a submitted branch (reviewer action)
|
|
5
|
-
* POST /:branch/request-changes
|
|
6
|
-
*/
|
|
7
3
|
export declare const requestChanges: import("./route-builder.js").RouteDefinition<z.ZodObject<{
|
|
8
4
|
branch: z.ZodType<import("../paths/index.js").BranchName, z.ZodTypeDef, import("../paths/index.js").BranchName>;
|
|
9
5
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -15,10 +11,6 @@ export declare const requestChanges: import("./route-builder.js").RouteDefinitio
|
|
|
15
11
|
readonly __brand: "BranchName";
|
|
16
12
|
};
|
|
17
13
|
}>, undefined, BranchResponse>;
|
|
18
|
-
/**
|
|
19
|
-
* Approve a branch (optional for v1)
|
|
20
|
-
* POST /:branch/approve
|
|
21
|
-
*/
|
|
22
14
|
export declare const approveBranch: import("./route-builder.js").RouteDefinition<z.ZodObject<{
|
|
23
15
|
branch: z.ZodType<import("../paths/index.js").BranchName, z.ZodTypeDef, import("../paths/index.js").BranchName>;
|
|
24
16
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -4,7 +4,6 @@ import { defineEndpoint } from './route-builder.js';
|
|
|
4
4
|
import { syncConvertToDraft } from './github-sync.js';
|
|
5
5
|
const requestChangesHandler = async (gc, ctx, _req, _params) => {
|
|
6
6
|
const { branchContext } = gc;
|
|
7
|
-
// Verify branch is submitted
|
|
8
7
|
if (branchContext.branch.status !== 'submitted') {
|
|
9
8
|
return {
|
|
10
9
|
ok: false,
|
|
@@ -12,9 +11,7 @@ const requestChangesHandler = async (gc, ctx, _req, _params) => {
|
|
|
12
11
|
error: `Cannot request changes on branch with status '${branchContext.branch.status}'. Only 'submitted' branches can have changes requested.`,
|
|
13
12
|
};
|
|
14
13
|
}
|
|
15
|
-
// Convert PR to draft (sync via githubService, or async via task queue)
|
|
16
14
|
await syncConvertToDraft(ctx, branchContext);
|
|
17
|
-
// Update branch status to 'editing'
|
|
18
15
|
const meta = getBranchMetadataFileManager(branchContext.branchRoot, branchContext.baseRoot);
|
|
19
16
|
const updated = await meta.save({
|
|
20
17
|
branch: { name: branchContext.branch.name, status: 'editing' },
|
|
@@ -24,7 +21,6 @@ const requestChangesHandler = async (gc, ctx, _req, _params) => {
|
|
|
24
21
|
};
|
|
25
22
|
const approveBranchHandler = async (gc, _ctx, _req, _params) => {
|
|
26
23
|
const { branchContext } = gc;
|
|
27
|
-
// Verify branch is submitted
|
|
28
24
|
if (branchContext.branch.status !== 'submitted') {
|
|
29
25
|
return {
|
|
30
26
|
ok: false,
|
|
@@ -32,7 +28,6 @@ const approveBranchHandler = async (gc, _ctx, _req, _params) => {
|
|
|
32
28
|
error: `Cannot approve branch with status '${branchContext.branch.status}'. Only 'submitted' branches can be approved.`,
|
|
33
29
|
};
|
|
34
30
|
}
|
|
35
|
-
// Update branch status to 'approved'
|
|
36
31
|
const meta = getBranchMetadataFileManager(branchContext.branchRoot, branchContext.baseRoot);
|
|
37
32
|
const updated = await meta.save({
|
|
38
33
|
branch: { name: branchContext.branch.name, status: 'approved' },
|
|
@@ -40,10 +35,6 @@ const approveBranchHandler = async (gc, _ctx, _req, _params) => {
|
|
|
40
35
|
// TODO: Optionally call githubService.approvePullRequest() when GitHub integration is needed
|
|
41
36
|
return { ok: true, status: 200, data: { branch: updated.branch } };
|
|
42
37
|
};
|
|
43
|
-
/**
|
|
44
|
-
* Request changes on a submitted branch (reviewer action)
|
|
45
|
-
* POST /:branch/request-changes
|
|
46
|
-
*/
|
|
47
38
|
export const requestChanges = defineEndpoint({
|
|
48
39
|
namespace: 'workflow',
|
|
49
40
|
name: 'requestChanges',
|
|
@@ -67,10 +58,6 @@ export const requestChanges = defineEndpoint({
|
|
|
67
58
|
guards: ['reviewer', 'branch'],
|
|
68
59
|
handler: requestChangesHandler,
|
|
69
60
|
});
|
|
70
|
-
/**
|
|
71
|
-
* Approve a branch (optional for v1)
|
|
72
|
-
* POST /:branch/approve
|
|
73
|
-
*/
|
|
74
61
|
export const approveBranch = defineEndpoint({
|
|
75
62
|
namespace: 'workflow',
|
|
76
63
|
name: 'approve',
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { BranchResponse } from './branch.js';
|
|
3
3
|
export type { BranchMergeResponse } from './branch-merge.js';
|
|
4
|
-
/**
|
|
5
|
-
* Exported routes for router registration
|
|
6
|
-
*/
|
|
7
4
|
export declare const WORKFLOW_ROUTES: {
|
|
8
5
|
readonly getStatus: import("./route-builder.js").RouteDefinition<z.ZodObject<{
|
|
9
6
|
branch: z.ZodType<import("../paths/index.js").BranchName, z.ZodTypeDef, import("../paths/index.js").BranchName>;
|
|
@@ -29,26 +29,15 @@ const submitBranchForMergeHandler = async (gc, ctx, req, _params) => {
|
|
|
29
29
|
error: 'Only the branch creator or users with explicit branch access can submit this branch',
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
// Only an 'editing' branch may be submitted
|
|
33
|
-
// getBranchWriteProtection's
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
32
|
+
// Only an 'editing' branch may be submitted, mirroring
|
|
33
|
+
// getBranchWriteProtection's status gate exactly so "can I edit this?" and
|
|
34
|
+
// "can I submit this?" stay one question. Without this, an archived
|
|
35
|
+
// (merged) branch could be re-submitted by its creator, re-stamping it
|
|
36
|
+
// 'submitted' and overwriting the merged PR's title/body.
|
|
37
37
|
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
// request-changes, which have always had one. An archived (merged) branch
|
|
42
|
-
// could therefore be re-submitted by its creator: the working tree is clean so
|
|
43
|
-
// nothing is committed, but it re-stamped the branch 'submitted', overwrote
|
|
44
|
-
// the merged PR's title/body via syncSubmitPr's update path, and in prod (no
|
|
45
|
-
// direct githubService) enqueued a worker task that 422s on pulls.create,
|
|
46
|
-
// since createOrUpdatePullRequest finds no OPEN PR to update.
|
|
47
|
-
//
|
|
48
|
-
// Fails closed on a missing status: branch.json is read with a bare
|
|
49
|
-
// JSON.parse (branch-metadata.ts) with no schema validation, so a damaged or
|
|
50
|
-
// hand-repaired file can yield `undefined` at runtime. Same reasoning, and
|
|
51
|
-
// same wording, as runWritableBranchGuard's unreadable-status arm.
|
|
38
|
+
// Fails closed on a missing status (branch.json is read with a bare
|
|
39
|
+
// JSON.parse, no schema validation, so a damaged file can yield
|
|
40
|
+
// `undefined`) -- same as runWritableBranchGuard's unreadable-status arm.
|
|
52
41
|
const status = branchContext.branch.status;
|
|
53
42
|
if (status !== 'editing') {
|
|
54
43
|
return {
|
|
@@ -120,13 +109,6 @@ const submitBranchForMergeHandler = async (gc, ctx, req, _params) => {
|
|
|
120
109
|
});
|
|
121
110
|
return { ok: true, status: 200, data: { branch: updated.branch } };
|
|
122
111
|
};
|
|
123
|
-
// ============================================================================
|
|
124
|
-
// Route Definitions with defineEndpoint
|
|
125
|
-
// ============================================================================
|
|
126
|
-
/**
|
|
127
|
-
* Get branch status
|
|
128
|
-
* GET /:branch/status
|
|
129
|
-
*/
|
|
130
112
|
const getBranchStatus = defineEndpoint({
|
|
131
113
|
namespace: 'workflow',
|
|
132
114
|
name: 'getStatus',
|
|
@@ -148,10 +130,6 @@ const getBranchStatus = defineEndpoint({
|
|
|
148
130
|
guards: ['branchAccess'],
|
|
149
131
|
handler: getBranchStatusHandler,
|
|
150
132
|
});
|
|
151
|
-
/**
|
|
152
|
-
* Submit branch for merge/review
|
|
153
|
-
* POST /:branch/submit
|
|
154
|
-
*/
|
|
155
133
|
const submitBranchForMerge = defineEndpoint({
|
|
156
134
|
namespace: 'workflow',
|
|
157
135
|
name: 'submit',
|
|
@@ -176,9 +154,6 @@ const submitBranchForMerge = defineEndpoint({
|
|
|
176
154
|
guards: ['branch', 'submittableBranch'],
|
|
177
155
|
handler: submitBranchForMergeHandler,
|
|
178
156
|
});
|
|
179
|
-
/**
|
|
180
|
-
* Exported routes for router registration
|
|
181
|
-
*/
|
|
182
157
|
export const WORKFLOW_ROUTES = {
|
|
183
158
|
getStatus: getBranchStatus,
|
|
184
159
|
submit: submitBranchForMerge,
|
|
@@ -2,7 +2,6 @@ import { z } from 'zod';
|
|
|
2
2
|
import type { BranchResponse } from './branch.js';
|
|
3
3
|
/**
|
|
4
4
|
* Withdraw a submitted branch, converting the PR to draft and unlocking editing
|
|
5
|
-
* POST /:branch/withdraw
|
|
6
5
|
*
|
|
7
6
|
* Deliberately no 'submittableBranch' guard: withdraw is the only self-serve
|
|
8
7
|
* recovery path for a base branch wrongly stuck in 'submitted' (e.g. a failed
|
|
@@ -21,8 +21,6 @@ const withdrawBranchHandler = async (gc, ctx, req, _params) => {
|
|
|
21
21
|
error: 'Only the branch creator or users with explicit branch access can withdraw this branch',
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
// Verify branch is in a withdrawable status.
|
|
25
|
-
//
|
|
26
24
|
// 'approved' is accepted alongside 'submitted' because withdraw is its only
|
|
27
25
|
// non-destructive exit. Every non-'editing' status blocks content writes, and
|
|
28
26
|
// request-changes requires 'submitted' -- so before this, an approved branch
|
|
@@ -40,16 +38,16 @@ const withdrawBranchHandler = async (gc, ctx, req, _params) => {
|
|
|
40
38
|
error: `Cannot withdraw branch with status '${status}'. Only 'submitted' or 'approved' branches can be withdrawn.`,
|
|
41
39
|
};
|
|
42
40
|
}
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
//
|
|
41
|
+
// syncConvertToDraft converts the PR to draft, but a PR closed on GitHub
|
|
42
|
+
// without merging can't be converted. Withdraw (back to 'editing') is the
|
|
43
|
+
// deliberate recovery path for a closed-unmerged PR; a later resubmit
|
|
44
|
+
// opens a fresh PR via createOrUpdatePullRequest, so skip the conversion
|
|
45
|
+
// in that case.
|
|
48
46
|
const wasClosed = branchContext.branch.pullRequestState === 'closed';
|
|
49
47
|
if (!wasClosed) {
|
|
50
48
|
await syncConvertToDraft(ctx, branchContext);
|
|
51
49
|
}
|
|
52
|
-
//
|
|
50
|
+
// A closed PR is dead after withdraw
|
|
53
51
|
// (resubmit opens a fresh one), so drop its metadata rather than leaving a
|
|
54
52
|
// stale PR chip on an editing branch; a drafted PR is still live, so keep it.
|
|
55
53
|
const meta = getBranchMetadataFileManager(branchContext.branchRoot, branchContext.baseRoot);
|
|
@@ -66,7 +64,6 @@ const withdrawBranchHandler = async (gc, ctx, req, _params) => {
|
|
|
66
64
|
};
|
|
67
65
|
/**
|
|
68
66
|
* Withdraw a submitted branch, converting the PR to draft and unlocking editing
|
|
69
|
-
* POST /:branch/withdraw
|
|
70
67
|
*
|
|
71
68
|
* Deliberately no 'submittableBranch' guard: withdraw is the only self-serve
|
|
72
69
|
* recovery path for a base branch wrongly stuck in 'submitted' (e.g. a failed
|
package/dist/api/branch.d.ts
CHANGED
|
@@ -113,11 +113,11 @@ declare const updateBranchAccessBodySchema: z.ZodObject<{
|
|
|
113
113
|
import type { PathPermission } from '../config/index.js';
|
|
114
114
|
import type { CanopyUser } from '../user.js';
|
|
115
115
|
/**
|
|
116
|
-
* Check if a user can create branches.
|
|
117
116
|
* Returns true if:
|
|
118
117
|
* - User is Admin or Reviewer (privileged)
|
|
119
118
|
* - User has edit access to at least one path via pathPermissions rules
|
|
120
119
|
* - No path permissions are defined (open access)
|
|
120
|
+
* @internal Exported for tests.
|
|
121
121
|
*/
|
|
122
122
|
export declare const canCreateBranch: (user: CanopyUser, pathPermissions: PathPermission[]) => {
|
|
123
123
|
allowed: boolean;
|
|
@@ -129,33 +129,28 @@ export interface CreateBranchBody {
|
|
|
129
129
|
description?: string;
|
|
130
130
|
access?: BranchMetadata['access'];
|
|
131
131
|
}
|
|
132
|
+
/** @internal Exported for tests. */
|
|
132
133
|
export declare const createBranchHandler: (ctx: ApiContext, req: ApiRequest, body: z.infer<typeof createBranchBodySchema>) => Promise<BranchResponse>;
|
|
134
|
+
/** @internal Exported for tests. */
|
|
133
135
|
export declare const listBranchesHandler: (ctx: ApiContext, req: ApiRequest) => Promise<BranchListResponse>;
|
|
134
|
-
/**
|
|
135
|
-
* Check if a user can delete a specific branch.
|
|
136
|
-
* Returns true if user is Admin or the branch creator.
|
|
137
|
-
*/
|
|
136
|
+
/** @internal Exported for tests. */
|
|
138
137
|
export declare const canDeleteBranch: (user: CanopyUser, branchContext: BranchContext) => {
|
|
139
138
|
allowed: boolean;
|
|
140
139
|
reason: string;
|
|
141
140
|
};
|
|
141
|
+
/** @internal Exported for tests. */
|
|
142
142
|
export declare const deleteBranchHandler: (ctx: ApiContext, req: ApiRequest, params: z.infer<typeof branchParamSchema>) => Promise<BranchDeleteResponse>;
|
|
143
143
|
export interface UpdateBranchAccessBody {
|
|
144
144
|
allowedUsers?: string[];
|
|
145
145
|
allowedGroups?: string[];
|
|
146
146
|
}
|
|
147
|
-
/**
|
|
148
|
-
* Check if a user can modify branch access.
|
|
149
|
-
* Returns true if user is Admin or the branch creator.
|
|
150
|
-
*/
|
|
147
|
+
/** @internal Exported for tests. */
|
|
151
148
|
export declare const canModifyBranchAccess: (user: CanopyUser, branchContext: BranchContext) => {
|
|
152
149
|
allowed: boolean;
|
|
153
150
|
reason: string;
|
|
154
151
|
};
|
|
152
|
+
/** @internal Exported for tests. */
|
|
155
153
|
export declare const updateBranchAccessHandler: (ctx: ApiContext, req: ApiRequest, params: z.infer<typeof branchParamSchema>, body: z.infer<typeof updateBranchAccessBodySchema>) => Promise<BranchResponse>;
|
|
156
|
-
/**
|
|
157
|
-
* Exported routes for router registration
|
|
158
|
-
*/
|
|
159
154
|
export declare const BRANCH_ROUTES: {
|
|
160
155
|
readonly list: import("./route-builder.js").RouteDefinition<undefined, undefined, BranchListResponse>;
|
|
161
156
|
readonly create: import("./route-builder.js").RouteDefinition<undefined, z.ZodObject<{
|