canopycms 0.0.0 → 0.0.2
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/dist/auth/plugin.d.ts +8 -0
- package/dist/auth/plugin.d.ts.map +1 -1
- package/dist/build-mode.d.ts +15 -5
- package/dist/build-mode.d.ts.map +1 -1
- package/dist/build-mode.js +18 -8
- package/dist/build-mode.js.map +1 -1
- package/dist/cli/init.d.ts +2 -2
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +37 -36
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/template-files/ai-config.ts.template +21 -0
- package/dist/cli/template-files/ai-route.ts.template +10 -0
- package/dist/cli/template-files/canopy.ts.template +24 -0
- package/dist/cli/templates.d.ts +5 -1
- package/dist/cli/templates.d.ts.map +1 -1
- package/dist/cli/templates.js +9 -2
- package/dist/cli/templates.js.map +1 -1
- package/dist/config/schemas/config.d.ts +4 -0
- package/dist/config/schemas/config.d.ts.map +1 -1
- package/dist/config/schemas/config.js +2 -0
- package/dist/config/schemas/config.js.map +1 -1
- package/dist/config/types.d.ts +5 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/content-reader.js +2 -2
- package/dist/content-reader.js.map +1 -1
- package/dist/context.js +5 -5
- package/dist/context.js.map +1 -1
- package/dist/operating-mode/client-unsafe-strategy.d.ts.map +1 -1
- package/dist/operating-mode/client-unsafe-strategy.js +15 -18
- package/dist/operating-mode/client-unsafe-strategy.js.map +1 -1
- package/dist/operating-mode/types.d.ts +8 -0
- package/dist/operating-mode/types.d.ts.map +1 -1
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -1
- package/package.json +5 -4
- package/src/cli/init.ts +43 -38
- package/dist/__integration__/fixtures/content-seeds.d.ts +0 -43
- package/dist/__integration__/fixtures/content-seeds.d.ts.map +0 -1
- package/dist/__integration__/fixtures/content-seeds.js +0 -99
- package/dist/__integration__/fixtures/content-seeds.js.map +0 -1
- package/dist/__integration__/fixtures/schemas.d.ts +0 -12
- package/dist/__integration__/fixtures/schemas.d.ts.map +0 -1
- package/dist/__integration__/fixtures/schemas.js +0 -65
- package/dist/__integration__/fixtures/schemas.js.map +0 -1
- package/dist/__integration__/test-utils/api-client.d.ts +0 -123
- package/dist/__integration__/test-utils/api-client.d.ts.map +0 -1
- package/dist/__integration__/test-utils/api-client.js +0 -118
- package/dist/__integration__/test-utils/api-client.js.map +0 -1
- package/dist/__integration__/test-utils/multi-user.d.ts +0 -25
- package/dist/__integration__/test-utils/multi-user.d.ts.map +0 -1
- package/dist/__integration__/test-utils/multi-user.js +0 -105
- package/dist/__integration__/test-utils/multi-user.js.map +0 -1
- package/dist/__integration__/test-utils/test-workspace.d.ts +0 -25
- package/dist/__integration__/test-utils/test-workspace.d.ts.map +0 -1
- package/dist/__integration__/test-utils/test-workspace.js +0 -102
- package/dist/__integration__/test-utils/test-workspace.js.map +0 -1
- package/dist/editor/BranchManager.stories.d.ts +0 -8
- package/dist/editor/BranchManager.stories.d.ts.map +0 -1
- package/dist/editor/BranchManager.stories.js +0 -74
- package/dist/editor/BranchManager.stories.js.map +0 -1
- package/dist/editor/CanopyEditor.stories.d.ts +0 -7
- package/dist/editor/CanopyEditor.stories.d.ts.map +0 -1
- package/dist/editor/CanopyEditor.stories.js +0 -99
- package/dist/editor/CanopyEditor.stories.js.map +0 -1
- package/dist/editor/CommentsPanel.stories.d.ts +0 -10
- package/dist/editor/CommentsPanel.stories.d.ts.map +0 -1
- package/dist/editor/CommentsPanel.stories.js +0 -175
- package/dist/editor/CommentsPanel.stories.js.map +0 -1
- package/dist/editor/Editor.stories.d.ts +0 -7
- package/dist/editor/Editor.stories.d.ts.map +0 -1
- package/dist/editor/Editor.stories.js +0 -95
- package/dist/editor/Editor.stories.js.map +0 -1
- package/dist/editor/EditorPanes.stories.d.ts +0 -7
- package/dist/editor/EditorPanes.stories.d.ts.map +0 -1
- package/dist/editor/EditorPanes.stories.js +0 -116
- package/dist/editor/EditorPanes.stories.js.map +0 -1
- package/dist/editor/EntryNavigator.stories.d.ts +0 -8
- package/dist/editor/EntryNavigator.stories.d.ts.map +0 -1
- package/dist/editor/EntryNavigator.stories.js +0 -42
- package/dist/editor/EntryNavigator.stories.js.map +0 -1
- package/dist/editor/FormRenderer.stories.d.ts +0 -7
- package/dist/editor/FormRenderer.stories.d.ts.map +0 -1
- package/dist/editor/FormRenderer.stories.js +0 -115
- package/dist/editor/FormRenderer.stories.js.map +0 -1
- package/dist/editor/GroupManager.stories.d.ts +0 -19
- package/dist/editor/GroupManager.stories.d.ts.map +0 -1
- package/dist/editor/GroupManager.stories.js +0 -265
- package/dist/editor/GroupManager.stories.js.map +0 -1
- package/dist/editor/PermissionManager.stories.d.ts +0 -20
- package/dist/editor/PermissionManager.stories.d.ts.map +0 -1
- package/dist/editor/PermissionManager.stories.js +0 -506
- package/dist/editor/PermissionManager.stories.js.map +0 -1
- package/dist/editor/comments/FieldWrapper.stories.d.ts +0 -10
- package/dist/editor/comments/FieldWrapper.stories.d.ts.map +0 -1
- package/dist/editor/comments/FieldWrapper.stories.js +0 -173
- package/dist/editor/comments/FieldWrapper.stories.js.map +0 -1
- package/dist/editor/fields/BlockField.stories.d.ts +0 -7
- package/dist/editor/fields/BlockField.stories.d.ts.map +0 -1
- package/dist/editor/fields/BlockField.stories.js +0 -50
- package/dist/editor/fields/BlockField.stories.js.map +0 -1
- package/dist/editor/fields/fields.stories.d.ts +0 -8
- package/dist/editor/fields/fields.stories.d.ts.map +0 -1
- package/dist/editor/fields/fields.stories.js +0 -34
- package/dist/editor/fields/fields.stories.js.map +0 -1
- package/dist/test-utils/api-test-helpers.d.ts +0 -238
- package/dist/test-utils/api-test-helpers.d.ts.map +0 -1
- package/dist/test-utils/api-test-helpers.js +0 -347
- package/dist/test-utils/api-test-helpers.js.map +0 -1
- package/dist/test-utils/console-spy.d.ts +0 -56
- package/dist/test-utils/console-spy.d.ts.map +0 -1
- package/dist/test-utils/console-spy.js +0 -81
- package/dist/test-utils/console-spy.js.map +0 -1
- package/dist/test-utils/git-helpers.d.ts +0 -21
- package/dist/test-utils/git-helpers.d.ts.map +0 -1
- package/dist/test-utils/git-helpers.js +0 -23
- package/dist/test-utils/git-helpers.js.map +0 -1
- package/dist/test-utils/index.d.ts +0 -5
- package/dist/test-utils/index.d.ts.map +0 -1
- package/dist/test-utils/index.js +0 -4
- package/dist/test-utils/index.js.map +0 -1
- package/src/__integration__/errors/invalid-content.test.ts +0 -238
- package/src/__integration__/errors/permission-denied.test.ts +0 -220
- package/src/__integration__/fixtures/content-seeds.ts +0 -105
- package/src/__integration__/fixtures/schemas.ts +0 -67
- package/src/__integration__/initialization/prod-sim-init.test.ts +0 -139
- package/src/__integration__/permissions/path-permissions.test.ts +0 -314
- package/src/__integration__/permissions/role-permissions.test.ts +0 -354
- package/src/__integration__/permissions/settings-branch-isolation.test.ts +0 -317
- package/src/__integration__/settings/groups-api.test.ts +0 -403
- package/src/__integration__/test-utils/api-client.ts +0 -167
- package/src/__integration__/test-utils/multi-user.ts +0 -129
- package/src/__integration__/test-utils/test-workspace.ts +0 -130
- package/src/__integration__/user/user-context.test.ts +0 -174
- package/src/__integration__/validation/input-validation.test.ts +0 -166
- package/src/__integration__/workflows/api-editing-workflow.test.ts +0 -244
- package/src/__integration__/workflows/conflict-resolution.test.ts +0 -259
- package/src/__integration__/workflows/editing-workflow.test.ts +0 -205
- package/src/__integration__/workflows/review-workflow.test.ts +0 -260
- package/src/ai/__tests__/build.integration.test.ts +0 -224
- package/src/ai/__tests__/generate.integration.test.ts +0 -495
- package/src/ai/__tests__/handler.integration.test.ts +0 -212
- package/src/ai/__tests__/json-to-markdown.test.ts +0 -553
- package/src/ai/generate.ts +0 -410
- package/src/ai/handler.ts +0 -123
- package/src/ai/index.ts +0 -26
- package/src/ai/json-to-markdown.ts +0 -424
- package/src/ai/resolve-branch.ts +0 -34
- package/src/ai/types.ts +0 -160
- package/src/api/AGENTS.md +0 -81
- package/src/api/__test__/mock-client.ts +0 -404
- package/src/api/assets.test.ts +0 -140
- package/src/api/assets.ts +0 -154
- package/src/api/branch-merge.test.ts +0 -163
- package/src/api/branch-merge.ts +0 -113
- package/src/api/branch-review.test.ts +0 -297
- package/src/api/branch-review.ts +0 -136
- package/src/api/branch-status.test.ts +0 -85
- package/src/api/branch-status.ts +0 -153
- package/src/api/branch-withdraw.test.ts +0 -146
- package/src/api/branch-withdraw.ts +0 -81
- package/src/api/branch-workflow.integration.test.ts +0 -578
- package/src/api/branch.test.ts +0 -620
- package/src/api/branch.ts +0 -492
- package/src/api/client.test.ts +0 -349
- package/src/api/client.ts +0 -506
- package/src/api/comments.test.ts +0 -285
- package/src/api/comments.ts +0 -210
- package/src/api/content.test.ts +0 -345
- package/src/api/content.ts +0 -454
- package/src/api/entries.test.ts +0 -1339
- package/src/api/entries.ts +0 -650
- package/src/api/github-sync.ts +0 -144
- package/src/api/groups.test.ts +0 -1013
- package/src/api/groups.ts +0 -375
- package/src/api/guards.test.ts +0 -533
- package/src/api/guards.ts +0 -271
- package/src/api/index.ts +0 -87
- package/src/api/permissions.test.ts +0 -766
- package/src/api/permissions.ts +0 -334
- package/src/api/reference-options.ts +0 -118
- package/src/api/resolve-references.ts +0 -107
- package/src/api/route-builder.ts +0 -289
- package/src/api/schema.test.ts +0 -840
- package/src/api/schema.ts +0 -936
- package/src/api/security.test.ts +0 -233
- package/src/api/settings-helpers.ts +0 -84
- package/src/api/types.ts +0 -40
- package/src/api/user.test.ts +0 -127
- package/src/api/user.ts +0 -42
- package/src/api/validators.test.ts +0 -275
- package/src/api/validators.ts +0 -176
- package/src/asset-store.test.ts +0 -37
- package/src/asset-store.ts +0 -110
- package/src/auth/cache.ts +0 -7
- package/src/auth/caching-auth-plugin.test.ts +0 -154
- package/src/auth/caching-auth-plugin.ts +0 -109
- package/src/auth/context-helpers.ts +0 -75
- package/src/auth/file-based-auth-cache.test.ts +0 -257
- package/src/auth/file-based-auth-cache.ts +0 -279
- package/src/auth/index.ts +0 -12
- package/src/auth/plugin.ts +0 -51
- package/src/auth/types.ts +0 -38
- package/src/authorization/__tests__/branch.test.ts +0 -260
- package/src/authorization/__tests__/content.test.ts +0 -142
- package/src/authorization/__tests__/path.test.ts +0 -133
- package/src/authorization/__tests__/permissions-loader.test.ts +0 -200
- package/src/authorization/branch.ts +0 -94
- package/src/authorization/content.ts +0 -93
- package/src/authorization/groups/index.ts +0 -11
- package/src/authorization/groups/loader.ts +0 -127
- package/src/authorization/groups/schema.ts +0 -48
- package/src/authorization/helpers.ts +0 -48
- package/src/authorization/index.ts +0 -84
- package/src/authorization/path.ts +0 -112
- package/src/authorization/permissions/index.ts +0 -11
- package/src/authorization/permissions/loader.ts +0 -116
- package/src/authorization/permissions/schema.ts +0 -66
- package/src/authorization/test-utils.ts +0 -15
- package/src/authorization/types.ts +0 -66
- package/src/authorization/validation.test.ts +0 -100
- package/src/authorization/validation.ts +0 -62
- package/src/branch-metadata.test.ts +0 -168
- package/src/branch-metadata.ts +0 -166
- package/src/branch-registry.test.ts +0 -248
- package/src/branch-registry.ts +0 -152
- package/src/branch-schema-cache.test.ts +0 -275
- package/src/branch-schema-cache.ts +0 -189
- package/src/branch-workspace.test.ts +0 -183
- package/src/branch-workspace.ts +0 -124
- package/src/build/generate-ai-content.ts +0 -78
- package/src/build/index.ts +0 -8
- package/src/build-mode.ts +0 -27
- package/src/cli/generate-ai-content.ts +0 -100
- package/src/cli/init.test.ts +0 -240
- package/src/cli/templates/canopy.ts.template +0 -55
- package/src/cli/templates.ts +0 -47
- package/src/client.ts +0 -12
- package/src/comment-store.test.ts +0 -442
- package/src/comment-store.ts +0 -301
- package/src/config/__tests__/config.test.ts +0 -513
- package/src/config/flatten.ts +0 -174
- package/src/config/helpers.ts +0 -167
- package/src/config/index.ts +0 -86
- package/src/config/schemas/collection.ts +0 -67
- package/src/config/schemas/config.ts +0 -77
- package/src/config/schemas/field.ts +0 -108
- package/src/config/schemas/media.ts +0 -27
- package/src/config/schemas/permissions.ts +0 -21
- package/src/config/types.ts +0 -321
- package/src/config/validation.ts +0 -70
- package/src/config-test.ts +0 -65
- package/src/config.ts +0 -11
- package/src/content-id-index.test.ts +0 -512
- package/src/content-id-index.ts +0 -479
- package/src/content-reader.test.ts +0 -478
- package/src/content-reader.ts +0 -214
- package/src/content-store.test.ts +0 -1126
- package/src/content-store.ts +0 -793
- package/src/context.ts +0 -111
- package/src/editor/BranchManager.stories.tsx +0 -80
- package/src/editor/BranchManager.test.tsx +0 -324
- package/src/editor/BranchManager.tsx +0 -461
- package/src/editor/CanopyEditor.stories.tsx +0 -128
- package/src/editor/CanopyEditor.test.tsx +0 -81
- package/src/editor/CanopyEditor.tsx +0 -73
- package/src/editor/CanopyEditorPage.test.tsx +0 -59
- package/src/editor/CanopyEditorPage.tsx +0 -25
- package/src/editor/CommentsPanel.stories.tsx +0 -184
- package/src/editor/CommentsPanel.tsx +0 -338
- package/src/editor/Editor.integration.test.tsx +0 -227
- package/src/editor/Editor.stories.tsx +0 -119
- package/src/editor/Editor.tsx +0 -1221
- package/src/editor/EditorPanes.stories.tsx +0 -256
- package/src/editor/EditorPanes.test.tsx +0 -77
- package/src/editor/EditorPanes.tsx +0 -180
- package/src/editor/EntryNavigator.stories.tsx +0 -65
- package/src/editor/EntryNavigator.test.tsx +0 -598
- package/src/editor/EntryNavigator.tsx +0 -665
- package/src/editor/FormRenderer.stories.tsx +0 -212
- package/src/editor/FormRenderer.test.tsx +0 -194
- package/src/editor/FormRenderer.tsx +0 -432
- package/src/editor/GroupManager.stories.tsx +0 -301
- package/src/editor/GroupManager.test.tsx +0 -682
- package/src/editor/GroupManager.tsx +0 -9
- package/src/editor/PermissionManager.stories.tsx +0 -539
- package/src/editor/PermissionManager.test.tsx +0 -864
- package/src/editor/PermissionManager.tsx +0 -12
- package/src/editor/canopy-path.test.ts +0 -23
- package/src/editor/canopy-path.ts +0 -52
- package/src/editor/client-reference-resolver.ts +0 -118
- package/src/editor/comments/BranchComments.tsx +0 -93
- package/src/editor/comments/EntryComments.tsx +0 -94
- package/src/editor/comments/FieldWrapper.stories.tsx +0 -210
- package/src/editor/comments/FieldWrapper.tsx +0 -129
- package/src/editor/comments/InlineCommentThread.test.tsx +0 -384
- package/src/editor/comments/InlineCommentThread.tsx +0 -246
- package/src/editor/comments/ThreadCarousel.test.tsx +0 -393
- package/src/editor/comments/ThreadCarousel.tsx +0 -525
- package/src/editor/components/ConfirmDeleteModal.tsx +0 -49
- package/src/editor/components/EditorContext.tsx +0 -49
- package/src/editor/components/EditorFooter.tsx +0 -47
- package/src/editor/components/EditorHeader.tsx +0 -492
- package/src/editor/components/EditorSidebar.tsx +0 -193
- package/src/editor/components/EntryCreateModal.tsx +0 -193
- package/src/editor/components/RenameEntryModal.tsx +0 -152
- package/src/editor/components/UserBadge.test.tsx +0 -274
- package/src/editor/components/UserBadge.tsx +0 -240
- package/src/editor/components/index.ts +0 -6
- package/src/editor/context/ApiClientContext.tsx +0 -56
- package/src/editor/context/EditorStateContext.tsx +0 -221
- package/src/editor/context/index.ts +0 -40
- package/src/editor/editor-config.test.ts +0 -385
- package/src/editor/editor-config.ts +0 -94
- package/src/editor/editor-utils.test.ts +0 -772
- package/src/editor/editor-utils.ts +0 -303
- package/src/editor/env.ts +0 -4
- package/src/editor/fields/BlockField.stories.tsx +0 -79
- package/src/editor/fields/BlockField.tsx +0 -267
- package/src/editor/fields/CodeField.tsx +0 -41
- package/src/editor/fields/MarkdownField.tsx +0 -205
- package/src/editor/fields/ObjectField.tsx +0 -71
- package/src/editor/fields/ReferenceField.tsx +0 -138
- package/src/editor/fields/SelectField.tsx +0 -76
- package/src/editor/fields/TextField.tsx +0 -35
- package/src/editor/fields/ToggleField.tsx +0 -37
- package/src/editor/fields/fields.stories.tsx +0 -40
- package/src/editor/group-manager/ExternalGroupsTab.tsx +0 -114
- package/src/editor/group-manager/GroupCard.tsx +0 -102
- package/src/editor/group-manager/GroupForm.tsx +0 -66
- package/src/editor/group-manager/InternalGroupsTab.tsx +0 -147
- package/src/editor/group-manager/MemberList.tsx +0 -184
- package/src/editor/group-manager/hooks/useExternalGroupSearch.ts +0 -63
- package/src/editor/group-manager/hooks/useGroupState.ts +0 -134
- package/src/editor/group-manager/hooks/useUserSearch.ts +0 -84
- package/src/editor/group-manager/index.tsx +0 -210
- package/src/editor/group-manager/types.ts +0 -28
- package/src/editor/hooks/README.md +0 -26
- package/src/editor/hooks/__test__/test-utils.tsx +0 -183
- package/src/editor/hooks/index.ts +0 -23
- package/src/editor/hooks/useBranchActions.test.tsx +0 -267
- package/src/editor/hooks/useBranchActions.tsx +0 -121
- package/src/editor/hooks/useBranchManager.test.tsx +0 -391
- package/src/editor/hooks/useBranchManager.tsx +0 -326
- package/src/editor/hooks/useCommentSystem.test.ts +0 -615
- package/src/editor/hooks/useCommentSystem.ts +0 -347
- package/src/editor/hooks/useDraftManager.test.ts +0 -375
- package/src/editor/hooks/useDraftManager.ts +0 -259
- package/src/editor/hooks/useEditorLayout.test.ts +0 -147
- package/src/editor/hooks/useEditorLayout.ts +0 -67
- package/src/editor/hooks/useEntryManager.test.ts +0 -588
- package/src/editor/hooks/useEntryManager.ts +0 -387
- package/src/editor/hooks/useGroupManager.test.ts +0 -277
- package/src/editor/hooks/useGroupManager.ts +0 -139
- package/src/editor/hooks/usePermissionManager.test.ts +0 -211
- package/src/editor/hooks/usePermissionManager.ts +0 -113
- package/src/editor/hooks/useReferenceResolution.ts +0 -248
- package/src/editor/hooks/useSchemaManager.test.ts +0 -370
- package/src/editor/hooks/useSchemaManager.ts +0 -310
- package/src/editor/hooks/useUserContext.tsx +0 -57
- package/src/editor/hooks/useUserMetadata.test.ts +0 -191
- package/src/editor/hooks/useUserMetadata.ts +0 -71
- package/src/editor/permission-manager/GroupSelector.tsx +0 -73
- package/src/editor/permission-manager/PermissionEditor.tsx +0 -321
- package/src/editor/permission-manager/PermissionLevelBadge.tsx +0 -53
- package/src/editor/permission-manager/PermissionTree.tsx +0 -237
- package/src/editor/permission-manager/UserSelector.tsx +0 -95
- package/src/editor/permission-manager/constants.tsx +0 -18
- package/src/editor/permission-manager/hooks/useGroupsAndUsers.ts +0 -153
- package/src/editor/permission-manager/hooks/usePermissionTree.ts +0 -200
- package/src/editor/permission-manager/index.tsx +0 -294
- package/src/editor/permission-manager/types.ts +0 -58
- package/src/editor/permission-manager/utils.ts +0 -179
- package/src/editor/preview-bridge.test.tsx +0 -50
- package/src/editor/preview-bridge.tsx +0 -294
- package/src/editor/schema-editor/CollectionEditor.test.tsx +0 -238
- package/src/editor/schema-editor/CollectionEditor.tsx +0 -520
- package/src/editor/schema-editor/EntryTypeEditor.test.tsx +0 -215
- package/src/editor/schema-editor/EntryTypeEditor.tsx +0 -367
- package/src/editor/schema-editor/index.ts +0 -19
- package/src/editor/setup-test-dom.ts +0 -10
- package/src/editor/test-setup.ts +0 -33
- package/src/editor/theme.tsx +0 -119
- package/src/editor/utils/env.ts +0 -39
- package/src/entry-schema-registry.test.ts +0 -281
- package/src/entry-schema-registry.ts +0 -121
- package/src/entry-schema.ts +0 -84
- package/src/git-manager.test.ts +0 -552
- package/src/git-manager.ts +0 -667
- package/src/github-service.test.ts +0 -312
- package/src/github-service.ts +0 -295
- package/src/http/handler.test.ts +0 -275
- package/src/http/handler.ts +0 -280
- package/src/http/index.ts +0 -11
- package/src/http/router.ts +0 -164
- package/src/http/types.ts +0 -44
- package/src/id.test.ts +0 -48
- package/src/id.ts +0 -22
- package/src/index.ts +0 -26
- package/src/operating-mode/__tests__/strategies.test.ts +0 -511
- package/src/operating-mode/client-safe-strategy.ts +0 -184
- package/src/operating-mode/client-unsafe-strategy.ts +0 -303
- package/src/operating-mode/client.ts +0 -13
- package/src/operating-mode/index.ts +0 -34
- package/src/operating-mode/types.ts +0 -186
- package/src/paths/__tests__/branch.test.ts +0 -53
- package/src/paths/__tests__/normalize.test.ts +0 -141
- package/src/paths/__tests__/resolve.test.ts +0 -207
- package/src/paths/__tests__/validation.test.ts +0 -61
- package/src/paths/branch.ts +0 -115
- package/src/paths/index.ts +0 -73
- package/src/paths/normalize-server.ts +0 -40
- package/src/paths/normalize.ts +0 -107
- package/src/paths/resolve.ts +0 -61
- package/src/paths/test-utils.ts +0 -37
- package/src/paths/types.ts +0 -68
- package/src/paths/validation.test.ts +0 -480
- package/src/paths/validation.ts +0 -391
- package/src/reference-resolver.test.ts +0 -107
- package/src/reference-resolver.ts +0 -157
- package/src/schema/index.ts +0 -29
- package/src/schema/meta-loader.ts +0 -366
- package/src/schema/resolver.ts +0 -83
- package/src/schema/schema-store-types.ts +0 -56
- package/src/schema/schema-store.test.ts +0 -816
- package/src/schema/schema-store.ts +0 -795
- package/src/schema/types.ts +0 -33
- package/src/schema-meta-loader.test.ts +0 -447
- package/src/server.ts +0 -15
- package/src/services.test.ts +0 -559
- package/src/services.ts +0 -373
- package/src/settings-branch-utils.ts +0 -53
- package/src/settings-workspace.ts +0 -156
- package/src/task-queue/README.md +0 -144
- package/src/task-queue/index.ts +0 -14
- package/src/task-queue/task-queue.test.ts +0 -524
- package/src/task-queue/task-queue.ts +0 -514
- package/src/task-queue/types.ts +0 -41
- package/src/test-utils/api-test-helpers.ts +0 -445
- package/src/test-utils/console-spy.test.ts +0 -14
- package/src/test-utils/console-spy.ts +0 -125
- package/src/test-utils/git-helpers.ts +0 -31
- package/src/test-utils/index.ts +0 -4
- package/src/types.ts +0 -54
- package/src/user.ts +0 -118
- package/src/utils/debug.test.ts +0 -114
- package/src/utils/debug.ts +0 -127
- package/src/utils/error.test.ts +0 -92
- package/src/utils/error.ts +0 -83
- package/src/utils/format.ts +0 -12
- package/src/validation/__tests__/field-traversal.test.ts +0 -263
- package/src/validation/deletion-checker.ts +0 -234
- package/src/validation/field-traversal.ts +0 -146
- package/src/validation/reference-validator.ts +0 -168
- package/src/worker/cms-worker-rebase.test.ts +0 -473
- package/src/worker/cms-worker.ts +0 -777
- package/src/worker/integration.test.ts +0 -289
- package/src/worker/task-queue-config.ts +0 -25
- package/src/worker/task-queue.test.ts +0 -452
- package/src/worker/task-queue.ts +0 -58
- /package/{src/cli/templates → dist/cli/template-files}/Dockerfile.cms.template +0 -0
- /package/{src/cli/templates → dist/cli/template-files}/canopycms.config.ts.template +0 -0
- /package/{src/cli/templates → dist/cli/template-files}/deploy-cms.yml.template +0 -0
- /package/{src/cli/templates → dist/cli/template-files}/edit-page.tsx.template +0 -0
- /package/{src/cli/templates → dist/cli/template-files}/route.ts.template +0 -0
- /package/{src/cli/templates → dist/cli/template-files}/schemas.ts.template +0 -0
|
@@ -1,578 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration tests for the full GitHub PR workflow
|
|
3
|
-
* Tests the complete lifecycle: create → submit → withdraw → request changes → resubmit → merge
|
|
4
|
-
* Uses mocked Octokit to simulate GitHub API responses
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import fs from 'node:fs/promises'
|
|
8
|
-
import os from 'node:os'
|
|
9
|
-
import path from 'node:path'
|
|
10
|
-
|
|
11
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
12
|
-
import { simpleGit } from 'simple-git'
|
|
13
|
-
|
|
14
|
-
import { GitHubService } from '../github-service'
|
|
15
|
-
import { GitManager } from '../git-manager'
|
|
16
|
-
import { initBareRepo } from '../__integration__/test-utils/test-workspace'
|
|
17
|
-
import { BranchWorkspaceManager, loadBranchContext } from '../branch-workspace'
|
|
18
|
-
import { getBranchMetadataFileManager } from '../branch-metadata'
|
|
19
|
-
import { initTestRepo } from '../test-utils'
|
|
20
|
-
import { CommentStore } from '../comment-store'
|
|
21
|
-
import { defineCanopyTestConfig } from '../config-test'
|
|
22
|
-
|
|
23
|
-
// Mock Octokit
|
|
24
|
-
const mockOctokit = {
|
|
25
|
-
pulls: {
|
|
26
|
-
create: vi.fn(),
|
|
27
|
-
update: vi.fn(),
|
|
28
|
-
get: vi.fn(),
|
|
29
|
-
},
|
|
30
|
-
rest: {
|
|
31
|
-
pulls: {
|
|
32
|
-
updateBranch: vi.fn(),
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
graphql: vi.fn(),
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
vi.mock('@octokit/rest', () => ({
|
|
39
|
-
Octokit: vi.fn(() => mockOctokit),
|
|
40
|
-
}))
|
|
41
|
-
|
|
42
|
-
describe('PR Workflow Integration', () => {
|
|
43
|
-
let tmpRoot: string
|
|
44
|
-
let cwdSpy: any
|
|
45
|
-
let prNumber = 1
|
|
46
|
-
|
|
47
|
-
beforeEach(async () => {
|
|
48
|
-
// Create temp directory for test workspace
|
|
49
|
-
tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'canopycms-pr-workflow-'))
|
|
50
|
-
cwdSpy = vi.spyOn(process, 'cwd').mockReturnValue(tmpRoot)
|
|
51
|
-
|
|
52
|
-
// Reset PR counter
|
|
53
|
-
prNumber = 1
|
|
54
|
-
|
|
55
|
-
// Reset all mocks
|
|
56
|
-
mockOctokit.pulls.create.mockReset()
|
|
57
|
-
mockOctokit.pulls.update.mockReset()
|
|
58
|
-
mockOctokit.pulls.get.mockReset()
|
|
59
|
-
mockOctokit.rest.pulls.updateBranch.mockReset()
|
|
60
|
-
mockOctokit.graphql.mockReset()
|
|
61
|
-
|
|
62
|
-
// Setup default mock responses
|
|
63
|
-
mockOctokit.pulls.create.mockImplementation(async (opts: any) => {
|
|
64
|
-
const currentPR = prNumber++
|
|
65
|
-
return {
|
|
66
|
-
data: {
|
|
67
|
-
number: currentPR,
|
|
68
|
-
html_url: `https://github.com/${opts.owner}/${opts.repo}/pull/${currentPR}`,
|
|
69
|
-
state: 'open',
|
|
70
|
-
merged: false,
|
|
71
|
-
draft: opts.draft ?? false,
|
|
72
|
-
},
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
mockOctokit.pulls.get.mockImplementation(async (opts: any) => {
|
|
77
|
-
return {
|
|
78
|
-
data: {
|
|
79
|
-
number: opts.pull_number,
|
|
80
|
-
html_url: `https://github.com/testorg/testrepo/pull/${opts.pull_number}`,
|
|
81
|
-
state: 'open',
|
|
82
|
-
merged: false,
|
|
83
|
-
draft: false,
|
|
84
|
-
},
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
mockOctokit.pulls.update.mockImplementation(async (opts: any) => {
|
|
89
|
-
return {
|
|
90
|
-
data: {
|
|
91
|
-
number: opts.pull_number,
|
|
92
|
-
html_url: `https://github.com/testorg/testrepo/pull/${opts.pull_number}`,
|
|
93
|
-
state: 'open',
|
|
94
|
-
merged: false,
|
|
95
|
-
draft: false,
|
|
96
|
-
},
|
|
97
|
-
}
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
mockOctokit.graphql.mockResolvedValue({
|
|
101
|
-
markPullRequestReadyForReview: {
|
|
102
|
-
pullRequest: {
|
|
103
|
-
id: 'test-pr-id',
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
})
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
afterEach(async () => {
|
|
110
|
-
cwdSpy.mockRestore()
|
|
111
|
-
await fs.rm(tmpRoot, { recursive: true, force: true })
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it('completes full PR workflow: create → submit → withdraw → request changes → resubmit → merge', async () => {
|
|
115
|
-
const branchName = 'feature-pr-test'
|
|
116
|
-
const remotePath = path.join(tmpRoot, 'remote.git')
|
|
117
|
-
const seedPath = path.join(tmpRoot, 'seed')
|
|
118
|
-
const owner = 'testorg'
|
|
119
|
-
const repo = 'testrepo'
|
|
120
|
-
|
|
121
|
-
// ===== SETUP: Initialize bare remote and seed main branch =====
|
|
122
|
-
await initBareRepo(remotePath)
|
|
123
|
-
|
|
124
|
-
await fs.mkdir(seedPath, { recursive: true })
|
|
125
|
-
const seedGit = simpleGit({ baseDir: seedPath })
|
|
126
|
-
await seedGit.init()
|
|
127
|
-
await seedGit.raw(['branch', '-M', 'main'])
|
|
128
|
-
await fs.mkdir(path.join(seedPath, 'content'), { recursive: true })
|
|
129
|
-
await fs.writeFile(path.join(seedPath, 'README.md'), '# Test Repo\n', 'utf8')
|
|
130
|
-
await seedGit.add(['.'])
|
|
131
|
-
await seedGit.commit('Initial commit')
|
|
132
|
-
await seedGit.addRemote('origin', remotePath)
|
|
133
|
-
await seedGit.push('origin', 'main', { '--set-upstream': null })
|
|
134
|
-
|
|
135
|
-
// ===== SETUP: Create CanopyCMS config and services =====
|
|
136
|
-
const config = defineCanopyTestConfig({
|
|
137
|
-
mode: 'prod-sim',
|
|
138
|
-
defaultBranchAccess: 'allow',
|
|
139
|
-
defaultBaseBranch: 'main',
|
|
140
|
-
defaultRemoteName: 'origin',
|
|
141
|
-
defaultRemoteUrl: remotePath,
|
|
142
|
-
gitBotAuthorName: 'Test Bot',
|
|
143
|
-
gitBotAuthorEmail: 'bot@example.com',
|
|
144
|
-
schema: {
|
|
145
|
-
collections: [
|
|
146
|
-
{
|
|
147
|
-
name: 'posts',
|
|
148
|
-
path: 'posts',
|
|
149
|
-
entries: [
|
|
150
|
-
{
|
|
151
|
-
name: 'post',
|
|
152
|
-
format: 'json',
|
|
153
|
-
schema: [
|
|
154
|
-
{ name: 'title', type: 'string' },
|
|
155
|
-
{ name: 'content', type: 'markdown' },
|
|
156
|
-
],
|
|
157
|
-
},
|
|
158
|
-
],
|
|
159
|
-
},
|
|
160
|
-
],
|
|
161
|
-
},
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
const githubService = new GitHubService({
|
|
165
|
-
token: 'test-github-token',
|
|
166
|
-
owner,
|
|
167
|
-
repo,
|
|
168
|
-
baseBranch: 'main',
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
// ===== STEP 1: Create branch and workspace =====
|
|
172
|
-
const workspaceManager = new BranchWorkspaceManager(config)
|
|
173
|
-
const workspace = await workspaceManager.openOrCreateBranch({
|
|
174
|
-
branchName,
|
|
175
|
-
mode: config.mode,
|
|
176
|
-
title: 'Test PR Feature',
|
|
177
|
-
description: 'This is a test PR for the integration test',
|
|
178
|
-
createdBy: 'test-user',
|
|
179
|
-
remoteUrl: remotePath,
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
expect(workspace).toBeTruthy()
|
|
183
|
-
expect(workspace.branchRoot).toBeTruthy()
|
|
184
|
-
expect(workspace.branch.name).toBe(branchName)
|
|
185
|
-
expect(workspace.branch.status).toBe('editing')
|
|
186
|
-
expect(workspace.branch.pullRequestNumber).toBeUndefined()
|
|
187
|
-
|
|
188
|
-
// Configure git user for test commits
|
|
189
|
-
await initTestRepo(workspace.branchRoot)
|
|
190
|
-
const branchGit = simpleGit({ baseDir: workspace.branchRoot })
|
|
191
|
-
|
|
192
|
-
// ===== STEP 2: Make changes and create a commit =====
|
|
193
|
-
const contentDir = path.join(workspace.branchRoot, 'content', 'posts')
|
|
194
|
-
await fs.mkdir(contentDir, { recursive: true })
|
|
195
|
-
await fs.writeFile(
|
|
196
|
-
path.join(contentDir, 'first-post.json'),
|
|
197
|
-
JSON.stringify({
|
|
198
|
-
title: 'First Post',
|
|
199
|
-
content: 'This is my first post!',
|
|
200
|
-
}),
|
|
201
|
-
'utf8',
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
await branchGit.add(['.'])
|
|
205
|
-
await branchGit.commit('Add first post')
|
|
206
|
-
|
|
207
|
-
// ===== STEP 3: Submit branch for merge (creates PR) =====
|
|
208
|
-
const gitManager = new GitManager({
|
|
209
|
-
repoPath: workspace.branchRoot,
|
|
210
|
-
baseBranch: config.defaultBaseBranch ?? 'main',
|
|
211
|
-
remote: config.defaultRemoteName ?? 'origin',
|
|
212
|
-
})
|
|
213
|
-
await gitManager.add(['.'])
|
|
214
|
-
await gitManager.commit('Test commit before submit')
|
|
215
|
-
await gitManager.push(branchName)
|
|
216
|
-
|
|
217
|
-
// Create PR via GitHub service
|
|
218
|
-
const prResult = await githubService.createPullRequest({
|
|
219
|
-
branchName,
|
|
220
|
-
title: workspace.branch.title ?? 'Test PR',
|
|
221
|
-
body: workspace.branch.description ?? 'Test PR description',
|
|
222
|
-
draft: false,
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
expect(prResult.number).toBe(1)
|
|
226
|
-
expect(prResult.url).toContain('pull/1')
|
|
227
|
-
expect(mockOctokit.pulls.create).toHaveBeenCalledWith({
|
|
228
|
-
owner,
|
|
229
|
-
repo,
|
|
230
|
-
title: 'Test PR Feature',
|
|
231
|
-
body: 'This is a test PR for the integration test',
|
|
232
|
-
head: branchName,
|
|
233
|
-
base: 'main',
|
|
234
|
-
draft: false,
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
// Update branch metadata with PR info
|
|
238
|
-
const metadata = getBranchMetadataFileManager(workspace.branchRoot, workspace.baseRoot)
|
|
239
|
-
await metadata.save({
|
|
240
|
-
branch: {
|
|
241
|
-
status: 'submitted',
|
|
242
|
-
pullRequestNumber: prResult.number,
|
|
243
|
-
pullRequestUrl: prResult.url,
|
|
244
|
-
},
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
// Reload state and verify PR info
|
|
248
|
-
const submittedContext = await loadBranchContext({
|
|
249
|
-
branchName,
|
|
250
|
-
mode: config.mode,
|
|
251
|
-
})
|
|
252
|
-
expect(submittedContext?.branch.status).toBe('submitted')
|
|
253
|
-
expect(submittedContext?.branch.pullRequestNumber).toBe(1)
|
|
254
|
-
expect(submittedContext?.branch.pullRequestUrl).toContain('pull/1')
|
|
255
|
-
|
|
256
|
-
// ===== STEP 4: Withdraw submission (convert PR to draft) =====
|
|
257
|
-
await githubService.convertToDraft(prResult.number)
|
|
258
|
-
await metadata.save({ branch: { status: 'editing' } })
|
|
259
|
-
|
|
260
|
-
const withdrawnContext = await loadBranchContext({
|
|
261
|
-
branchName,
|
|
262
|
-
mode: config.mode,
|
|
263
|
-
})
|
|
264
|
-
expect(withdrawnContext?.branch.status).toBe('editing')
|
|
265
|
-
|
|
266
|
-
// Mock PR as draft for next get() call
|
|
267
|
-
mockOctokit.pulls.get.mockImplementationOnce(async (opts: any) => ({
|
|
268
|
-
data: {
|
|
269
|
-
number: opts.pull_number,
|
|
270
|
-
html_url: `https://github.com/testorg/testrepo/pull/${opts.pull_number}`,
|
|
271
|
-
state: 'open',
|
|
272
|
-
merged: false,
|
|
273
|
-
draft: true, // Now draft
|
|
274
|
-
},
|
|
275
|
-
}))
|
|
276
|
-
|
|
277
|
-
// Verify PR is draft
|
|
278
|
-
const prDetails = await githubService.getPullRequest(prResult.number)
|
|
279
|
-
expect(prDetails.draft).toBe(true)
|
|
280
|
-
|
|
281
|
-
// ===== STEP 5: Request changes (reviewer action) =====
|
|
282
|
-
await metadata.save({ branch: { status: 'editing' } })
|
|
283
|
-
|
|
284
|
-
const changesRequestedContext = await loadBranchContext({
|
|
285
|
-
branchName,
|
|
286
|
-
mode: config.mode,
|
|
287
|
-
})
|
|
288
|
-
expect(changesRequestedContext?.branch.status).toBe('editing')
|
|
289
|
-
|
|
290
|
-
// ===== STEP 6: Make additional changes and resubmit =====
|
|
291
|
-
await fs.writeFile(
|
|
292
|
-
path.join(contentDir, 'second-post.json'),
|
|
293
|
-
JSON.stringify({
|
|
294
|
-
title: 'Second Post',
|
|
295
|
-
content: 'Another post after changes requested',
|
|
296
|
-
}),
|
|
297
|
-
'utf8',
|
|
298
|
-
)
|
|
299
|
-
|
|
300
|
-
await branchGit.add(['.'])
|
|
301
|
-
await branchGit.commit('Add second post after review')
|
|
302
|
-
await branchGit.push('origin', branchName, { '--force': null })
|
|
303
|
-
|
|
304
|
-
// Update PR (not create new one)
|
|
305
|
-
await githubService.updatePullRequest(prResult.number, {
|
|
306
|
-
title: 'Updated: Test PR Feature',
|
|
307
|
-
body: 'Updated PR description after changes',
|
|
308
|
-
})
|
|
309
|
-
|
|
310
|
-
expect(mockOctokit.pulls.update).toHaveBeenCalledWith({
|
|
311
|
-
owner,
|
|
312
|
-
repo,
|
|
313
|
-
pull_number: 1,
|
|
314
|
-
title: 'Updated: Test PR Feature',
|
|
315
|
-
body: 'Updated PR description after changes',
|
|
316
|
-
})
|
|
317
|
-
|
|
318
|
-
// Convert from draft to ready
|
|
319
|
-
mockOctokit.pulls.get.mockImplementationOnce(async (opts: any) => ({
|
|
320
|
-
data: {
|
|
321
|
-
number: opts.pull_number,
|
|
322
|
-
html_url: `https://github.com/testorg/testrepo/pull/${opts.pull_number}`,
|
|
323
|
-
state: 'open',
|
|
324
|
-
merged: false,
|
|
325
|
-
draft: false, // Back to ready
|
|
326
|
-
},
|
|
327
|
-
}))
|
|
328
|
-
|
|
329
|
-
await githubService.convertToReady(prResult.number)
|
|
330
|
-
await metadata.save({ branch: { status: 'submitted' } })
|
|
331
|
-
|
|
332
|
-
const resubmittedContext = await loadBranchContext({
|
|
333
|
-
branchName,
|
|
334
|
-
mode: config.mode,
|
|
335
|
-
})
|
|
336
|
-
expect(resubmittedContext?.branch.status).toBe('submitted')
|
|
337
|
-
expect(resubmittedContext?.branch.pullRequestNumber).toBe(1) // Same PR number
|
|
338
|
-
|
|
339
|
-
// ===== STEP 7: Add and resolve comments =====
|
|
340
|
-
const commentStore = new CommentStore(workspace.branchRoot)
|
|
341
|
-
await commentStore.load()
|
|
342
|
-
|
|
343
|
-
// Add field comment
|
|
344
|
-
const fieldThread = await commentStore.addComment({
|
|
345
|
-
text: 'Please revise the title',
|
|
346
|
-
userId: 'reviewer1',
|
|
347
|
-
type: 'field',
|
|
348
|
-
entryPath: 'posts/first-post',
|
|
349
|
-
canopyPath: 'title',
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
// Add entry comment
|
|
353
|
-
await commentStore.addComment({
|
|
354
|
-
text: 'Overall structure looks good',
|
|
355
|
-
userId: 'reviewer1',
|
|
356
|
-
type: 'entry',
|
|
357
|
-
entryPath: 'posts/first-post',
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
// Add branch comment
|
|
361
|
-
await commentStore.addComment({
|
|
362
|
-
text: 'Great work on this feature!',
|
|
363
|
-
userId: 'reviewer1',
|
|
364
|
-
type: 'branch',
|
|
365
|
-
})
|
|
366
|
-
|
|
367
|
-
// Add reply to field comment
|
|
368
|
-
await commentStore.addComment({
|
|
369
|
-
text: 'Updated the title',
|
|
370
|
-
userId: 'author1',
|
|
371
|
-
threadId: fieldThread.threadId,
|
|
372
|
-
type: 'field',
|
|
373
|
-
entryPath: 'posts/first-post',
|
|
374
|
-
canopyPath: 'title',
|
|
375
|
-
})
|
|
376
|
-
|
|
377
|
-
// List all comments
|
|
378
|
-
await commentStore.load()
|
|
379
|
-
const allThreads = await commentStore.listThreads()
|
|
380
|
-
expect(allThreads).toHaveLength(3)
|
|
381
|
-
|
|
382
|
-
// Verify field comments
|
|
383
|
-
const fieldThreads = await commentStore.getThreadsForField('posts/first-post', 'title')
|
|
384
|
-
expect(fieldThreads).toHaveLength(1)
|
|
385
|
-
expect(fieldThreads[0].comments).toHaveLength(2) // Original + reply
|
|
386
|
-
|
|
387
|
-
// Verify entry comments
|
|
388
|
-
const entryThreads = await commentStore.getThreadsForEntry('posts/first-post')
|
|
389
|
-
expect(entryThreads).toHaveLength(1)
|
|
390
|
-
|
|
391
|
-
// Verify branch comments
|
|
392
|
-
const branchThreads = await commentStore.getBranchThreads()
|
|
393
|
-
expect(branchThreads).toHaveLength(1)
|
|
394
|
-
|
|
395
|
-
// Resolve field comment thread
|
|
396
|
-
await commentStore.resolveThread(fieldThread.threadId, 'reviewer1')
|
|
397
|
-
await commentStore.load()
|
|
398
|
-
const allThreadsAfterResolve = await commentStore.listThreads()
|
|
399
|
-
const resolvedThread = allThreadsAfterResolve.find((t) => t.id === fieldThread.threadId)
|
|
400
|
-
expect(resolvedThread?.resolved).toBe(true)
|
|
401
|
-
expect(resolvedThread?.resolvedBy).toBe('reviewer1')
|
|
402
|
-
|
|
403
|
-
// ===== STEP 8: Merge PR and mark as merged =====
|
|
404
|
-
// Mock PR as merged
|
|
405
|
-
mockOctokit.pulls.get.mockImplementationOnce(async (opts: any) => ({
|
|
406
|
-
data: {
|
|
407
|
-
number: opts.pull_number,
|
|
408
|
-
html_url: `https://github.com/testorg/testrepo/pull/${opts.pull_number}`,
|
|
409
|
-
state: 'closed',
|
|
410
|
-
merged: true,
|
|
411
|
-
draft: false,
|
|
412
|
-
},
|
|
413
|
-
}))
|
|
414
|
-
|
|
415
|
-
// Verify PR is merged
|
|
416
|
-
const mergedPR = await githubService.getPullRequest(prResult.number)
|
|
417
|
-
expect(mergedPR.merged).toBe(true)
|
|
418
|
-
expect(mergedPR.state).toBe('closed')
|
|
419
|
-
|
|
420
|
-
// Mark branch as merged in CanopyCMS
|
|
421
|
-
await metadata.save({ branch: { status: 'archived' } })
|
|
422
|
-
|
|
423
|
-
const archivedContext = await loadBranchContext({
|
|
424
|
-
branchName,
|
|
425
|
-
mode: config.mode,
|
|
426
|
-
})
|
|
427
|
-
expect(archivedContext?.branch.status).toBe('archived')
|
|
428
|
-
expect(archivedContext?.branch.pullRequestNumber).toBe(1)
|
|
429
|
-
|
|
430
|
-
// Verify comments are still accessible in archived branch
|
|
431
|
-
const archivedComments = new CommentStore(archivedContext!.branchRoot)
|
|
432
|
-
await archivedComments.load()
|
|
433
|
-
const archivedThreads = await archivedComments.listThreads()
|
|
434
|
-
expect(archivedThreads).toHaveLength(3) // All comments preserved
|
|
435
|
-
})
|
|
436
|
-
|
|
437
|
-
it('handles PR workflow with draft submissions', async () => {
|
|
438
|
-
const branchName = 'feature-draft-test'
|
|
439
|
-
const remotePath = path.join(tmpRoot, 'remote-draft.git')
|
|
440
|
-
const seedPath = path.join(tmpRoot, 'seed-draft')
|
|
441
|
-
const owner = 'testorg'
|
|
442
|
-
const repo = 'testrepo-draft'
|
|
443
|
-
|
|
444
|
-
// Setup remote and seed
|
|
445
|
-
await initBareRepo(remotePath)
|
|
446
|
-
await fs.mkdir(seedPath, { recursive: true })
|
|
447
|
-
const seedGit = simpleGit({ baseDir: seedPath })
|
|
448
|
-
await seedGit.init()
|
|
449
|
-
await seedGit.raw(['branch', '-M', 'main'])
|
|
450
|
-
await fs.writeFile(path.join(seedPath, 'README.md'), '# Draft Test\n', 'utf8')
|
|
451
|
-
await seedGit.add(['.'])
|
|
452
|
-
await seedGit.commit('Initial commit')
|
|
453
|
-
await seedGit.addRemote('origin', remotePath)
|
|
454
|
-
await seedGit.push('origin', 'main', { '--set-upstream': null })
|
|
455
|
-
|
|
456
|
-
const config = defineCanopyTestConfig({
|
|
457
|
-
mode: 'prod-sim',
|
|
458
|
-
defaultBranchAccess: 'allow',
|
|
459
|
-
defaultBaseBranch: 'main',
|
|
460
|
-
defaultRemoteUrl: remotePath,
|
|
461
|
-
gitBotAuthorName: 'Bot',
|
|
462
|
-
gitBotAuthorEmail: 'bot@test.com',
|
|
463
|
-
schema: {
|
|
464
|
-
collections: [
|
|
465
|
-
{
|
|
466
|
-
name: 'home',
|
|
467
|
-
path: 'home',
|
|
468
|
-
entries: [
|
|
469
|
-
{
|
|
470
|
-
name: 'entry',
|
|
471
|
-
format: 'json',
|
|
472
|
-
schema: [{ name: 'title', type: 'string' }],
|
|
473
|
-
},
|
|
474
|
-
],
|
|
475
|
-
},
|
|
476
|
-
],
|
|
477
|
-
},
|
|
478
|
-
})
|
|
479
|
-
|
|
480
|
-
const githubService = new GitHubService({
|
|
481
|
-
token: 'test-token',
|
|
482
|
-
owner,
|
|
483
|
-
repo,
|
|
484
|
-
baseBranch: 'main',
|
|
485
|
-
})
|
|
486
|
-
|
|
487
|
-
// Create branch
|
|
488
|
-
const workspaceManager = new BranchWorkspaceManager(config)
|
|
489
|
-
const workspace = await workspaceManager.openOrCreateBranch({
|
|
490
|
-
branchName,
|
|
491
|
-
mode: config.mode,
|
|
492
|
-
title: 'Draft PR Test',
|
|
493
|
-
createdBy: 'test-user',
|
|
494
|
-
remoteUrl: remotePath,
|
|
495
|
-
})
|
|
496
|
-
|
|
497
|
-
await initTestRepo(workspace.branchRoot)
|
|
498
|
-
const branchGit = simpleGit({ baseDir: workspace.branchRoot })
|
|
499
|
-
|
|
500
|
-
// Make changes
|
|
501
|
-
await fs.mkdir(path.join(workspace.branchRoot, 'content'), {
|
|
502
|
-
recursive: true,
|
|
503
|
-
})
|
|
504
|
-
await fs.writeFile(
|
|
505
|
-
path.join(workspace.branchRoot, 'content', 'home.json'),
|
|
506
|
-
JSON.stringify({ title: 'Home Page' }),
|
|
507
|
-
'utf8',
|
|
508
|
-
)
|
|
509
|
-
await branchGit.add(['.'])
|
|
510
|
-
await branchGit.commit('Update home page')
|
|
511
|
-
await branchGit.push('origin', branchName, { '--set-upstream': null })
|
|
512
|
-
|
|
513
|
-
// Submit as draft
|
|
514
|
-
const draftPR = await githubService.createPullRequest({
|
|
515
|
-
branchName,
|
|
516
|
-
title: 'Draft: Home Page Updates',
|
|
517
|
-
body: 'Work in progress',
|
|
518
|
-
draft: true,
|
|
519
|
-
})
|
|
520
|
-
|
|
521
|
-
expect(draftPR.number).toBeGreaterThan(0)
|
|
522
|
-
expect(mockOctokit.pulls.create).toHaveBeenCalledWith({
|
|
523
|
-
owner,
|
|
524
|
-
repo,
|
|
525
|
-
title: 'Draft: Home Page Updates',
|
|
526
|
-
body: 'Work in progress',
|
|
527
|
-
head: branchName,
|
|
528
|
-
base: 'main',
|
|
529
|
-
draft: true,
|
|
530
|
-
})
|
|
531
|
-
|
|
532
|
-
// Mock PR details as draft initially, then as ready
|
|
533
|
-
mockOctokit.pulls.get.mockImplementationOnce(async (opts: any) => ({
|
|
534
|
-
data: {
|
|
535
|
-
number: opts.pull_number,
|
|
536
|
-
html_url: `https://github.com/${owner}/${repo}/pull/${opts.pull_number}`,
|
|
537
|
-
state: 'open',
|
|
538
|
-
merged: false,
|
|
539
|
-
draft: true,
|
|
540
|
-
},
|
|
541
|
-
}))
|
|
542
|
-
|
|
543
|
-
// Verify PR is draft
|
|
544
|
-
const prDetails = await githubService.getPullRequest(draftPR.number)
|
|
545
|
-
expect(prDetails.draft).toBe(true)
|
|
546
|
-
|
|
547
|
-
// Mock ready state for next call
|
|
548
|
-
mockOctokit.pulls.get.mockImplementationOnce(async (opts: any) => ({
|
|
549
|
-
data: {
|
|
550
|
-
number: opts.pull_number,
|
|
551
|
-
html_url: `https://github.com/${owner}/${repo}/pull/${opts.pull_number}`,
|
|
552
|
-
state: 'open',
|
|
553
|
-
merged: false,
|
|
554
|
-
draft: false,
|
|
555
|
-
},
|
|
556
|
-
}))
|
|
557
|
-
|
|
558
|
-
// Convert to ready for review
|
|
559
|
-
await githubService.convertToReady(draftPR.number)
|
|
560
|
-
const readyPR = await githubService.getPullRequest(draftPR.number)
|
|
561
|
-
expect(readyPR.draft).toBe(false)
|
|
562
|
-
|
|
563
|
-
// Mock merged state
|
|
564
|
-
mockOctokit.pulls.get.mockImplementationOnce(async (opts: any) => ({
|
|
565
|
-
data: {
|
|
566
|
-
number: opts.pull_number,
|
|
567
|
-
html_url: `https://github.com/${owner}/${repo}/pull/${opts.pull_number}`,
|
|
568
|
-
state: 'closed',
|
|
569
|
-
merged: true,
|
|
570
|
-
draft: false,
|
|
571
|
-
},
|
|
572
|
-
}))
|
|
573
|
-
|
|
574
|
-
// Simulate merge
|
|
575
|
-
const mergedPR = await githubService.getPullRequest(draftPR.number)
|
|
576
|
-
expect(mergedPR.merged).toBe(true)
|
|
577
|
-
})
|
|
578
|
-
})
|