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,244 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API-level integration tests for editing workflows.
|
|
3
|
-
* These tests go through the HTTP API layer, not calling core code directly.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
|
7
|
-
|
|
8
|
-
import { createTestWorkspace, type TestWorkspace } from '../test-utils/test-workspace'
|
|
9
|
-
import { createMockAuthPlugin } from '../test-utils/multi-user'
|
|
10
|
-
import { createApiClient } from '../test-utils/api-client'
|
|
11
|
-
import { BLOG_SCHEMA } from '../fixtures/schemas'
|
|
12
|
-
import type { BranchResponse, BranchListResponse } from '../../api/branch'
|
|
13
|
-
import type { EntriesResponse } from '../../api/entries'
|
|
14
|
-
import type { ApiResponse } from '../../api/types'
|
|
15
|
-
|
|
16
|
-
describe('API Editing Workflow Integration', () => {
|
|
17
|
-
let workspace: TestWorkspace
|
|
18
|
-
let adminClient: Awaited<ReturnType<typeof createApiClient>>
|
|
19
|
-
let editorClient: Awaited<ReturnType<typeof createApiClient>>
|
|
20
|
-
|
|
21
|
-
beforeEach(async () => {
|
|
22
|
-
workspace = await createTestWorkspace({
|
|
23
|
-
schema: BLOG_SCHEMA,
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
// Create API clients for different users
|
|
27
|
-
adminClient = await createApiClient({
|
|
28
|
-
config: workspace.config,
|
|
29
|
-
authPlugin: createMockAuthPlugin('admin'),
|
|
30
|
-
schema: BLOG_SCHEMA,
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
editorClient = await createApiClient({
|
|
34
|
-
config: workspace.config,
|
|
35
|
-
authPlugin: createMockAuthPlugin('editor'),
|
|
36
|
-
schema: BLOG_SCHEMA,
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
afterEach(async () => {
|
|
41
|
-
await workspace.cleanup()
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('completes full editing cycle through API: create → edit → save', async () => {
|
|
45
|
-
// STEP 1: Create branch via API
|
|
46
|
-
const createResponse = await editorClient.post('/api/canopycms/branches', {
|
|
47
|
-
branch: 'feature/new-post',
|
|
48
|
-
title: 'Add new blog post',
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
expect(createResponse.status).toBe(200)
|
|
52
|
-
expect(createResponse.ok).toBe(true)
|
|
53
|
-
const createData = await createResponse.json<BranchResponse>()
|
|
54
|
-
expect(createData.data?.branch.name).toBe('feature-new-post')
|
|
55
|
-
expect(createData.data?.branch.status).toBe('editing')
|
|
56
|
-
|
|
57
|
-
// STEP 2: Write content via API (path-based routing)
|
|
58
|
-
const writeResponse = await editorClient.put(
|
|
59
|
-
'/api/canopycms/feature-new-post/content/posts/hello-world',
|
|
60
|
-
{
|
|
61
|
-
format: 'mdx',
|
|
62
|
-
data: {
|
|
63
|
-
title: 'Hello World',
|
|
64
|
-
author: 'Test Author',
|
|
65
|
-
date: '2024-01-01T00:00:00Z',
|
|
66
|
-
tags: ['intro', 'test'],
|
|
67
|
-
},
|
|
68
|
-
body: 'This is my first post!',
|
|
69
|
-
},
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
if (writeResponse.status !== 200) {
|
|
73
|
-
console.error('Write content failed:', await writeResponse.json())
|
|
74
|
-
}
|
|
75
|
-
expect(writeResponse.status).toBe(200)
|
|
76
|
-
expect(writeResponse.ok).toBe(true)
|
|
77
|
-
|
|
78
|
-
// STEP 3: Read content back via API to verify
|
|
79
|
-
const readResponse = await editorClient.get(
|
|
80
|
-
'/api/canopycms/feature-new-post/content/posts/hello-world',
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
if (readResponse.status !== 200) {
|
|
84
|
-
console.error('Read content failed:', await readResponse.json())
|
|
85
|
-
}
|
|
86
|
-
expect(readResponse.status).toBe(200)
|
|
87
|
-
expect(readResponse.ok).toBe(true)
|
|
88
|
-
const content = await readResponse.json<
|
|
89
|
-
ApiResponse<{
|
|
90
|
-
format: string
|
|
91
|
-
data: Record<string, unknown>
|
|
92
|
-
body?: string
|
|
93
|
-
}>
|
|
94
|
-
>()
|
|
95
|
-
// content.data is the ContentDocument: { format, data: {...frontmatter}, body, ... }
|
|
96
|
-
expect(content.data?.data.title).toBe('Hello World')
|
|
97
|
-
expect(content.data?.body?.trim()).toBe('This is my first post!')
|
|
98
|
-
|
|
99
|
-
// STEP 4: List entries via API
|
|
100
|
-
const entriesResponse = await editorClient.get('/api/canopycms/feature-new-post/entries')
|
|
101
|
-
|
|
102
|
-
expect(entriesResponse.status).toBe(200)
|
|
103
|
-
const entries = await entriesResponse.json<EntriesResponse>()
|
|
104
|
-
expect(entries.data?.entries).toBeDefined()
|
|
105
|
-
expect(entries.data?.entries.length).toBeGreaterThan(0)
|
|
106
|
-
|
|
107
|
-
// STEP 5: Get branch status via API
|
|
108
|
-
const statusResponse = await editorClient.get('/api/canopycms/feature-new-post/status')
|
|
109
|
-
|
|
110
|
-
expect(statusResponse.status).toBe(200)
|
|
111
|
-
const status = await statusResponse.json<BranchResponse>()
|
|
112
|
-
expect(status.data?.branch.status).toBe('editing')
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
it('enforces permissions at API level', async () => {
|
|
116
|
-
// STEP 1: Admin creates a branch
|
|
117
|
-
const createResponse = await adminClient.post('/api/canopycms/branches', {
|
|
118
|
-
branch: 'admin-only-branch',
|
|
119
|
-
title: 'Admin Only',
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
expect(createResponse.status).toBe(200)
|
|
123
|
-
|
|
124
|
-
// STEP 2: Admin restricts branch access
|
|
125
|
-
const patchResponse = await adminClient.patch('/api/canopycms/admin-only-branch/access', {
|
|
126
|
-
allowedUsers: ['test-admin'],
|
|
127
|
-
allowedGroups: [],
|
|
128
|
-
managerOrAdminAllowed: true,
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
expect(patchResponse.status).toBe(200)
|
|
132
|
-
|
|
133
|
-
// STEP 3: Regular editor tries to access - should be denied
|
|
134
|
-
const editorAccessResponse = await editorClient.get('/api/canopycms/admin-only-branch/status')
|
|
135
|
-
|
|
136
|
-
expect(editorAccessResponse.status).toBe(403)
|
|
137
|
-
expect(editorAccessResponse.ok).toBe(false)
|
|
138
|
-
|
|
139
|
-
// STEP 4: Admin can still access
|
|
140
|
-
const adminAccessResponse = await adminClient.get('/api/canopycms/admin-only-branch/status')
|
|
141
|
-
|
|
142
|
-
expect(adminAccessResponse.status).toBe(200)
|
|
143
|
-
expect(adminAccessResponse.ok).toBe(true)
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
it('handles concurrent API requests from different users', async () => {
|
|
147
|
-
// Both users create branches simultaneously
|
|
148
|
-
const [adminBranchResponse, editorBranchResponse] = await Promise.all([
|
|
149
|
-
adminClient.post('/api/canopycms/branches', {
|
|
150
|
-
branch: 'admin-feature',
|
|
151
|
-
title: 'Admin Feature',
|
|
152
|
-
}),
|
|
153
|
-
editorClient.post('/api/canopycms/branches', {
|
|
154
|
-
branch: 'editor-feature',
|
|
155
|
-
title: 'Editor Feature',
|
|
156
|
-
}),
|
|
157
|
-
])
|
|
158
|
-
|
|
159
|
-
expect(adminBranchResponse.status).toBe(200)
|
|
160
|
-
expect(editorBranchResponse.status).toBe(200)
|
|
161
|
-
|
|
162
|
-
// Both users write content to their own branches (path-based routing)
|
|
163
|
-
const [adminWriteResponse, editorWriteResponse] = await Promise.all([
|
|
164
|
-
adminClient.put('/api/canopycms/admin-feature/content/posts/admin-post', {
|
|
165
|
-
format: 'mdx',
|
|
166
|
-
data: {
|
|
167
|
-
title: 'Admin Post',
|
|
168
|
-
author: 'Admin',
|
|
169
|
-
date: '2024-01-01',
|
|
170
|
-
tags: ['admin'],
|
|
171
|
-
},
|
|
172
|
-
body: 'Admin content',
|
|
173
|
-
}),
|
|
174
|
-
editorClient.put('/api/canopycms/editor-feature/content/posts/editor-post', {
|
|
175
|
-
format: 'mdx',
|
|
176
|
-
data: {
|
|
177
|
-
title: 'Editor Post',
|
|
178
|
-
author: 'Editor',
|
|
179
|
-
date: '2024-01-01',
|
|
180
|
-
tags: ['editor'],
|
|
181
|
-
},
|
|
182
|
-
body: 'Editor content',
|
|
183
|
-
}),
|
|
184
|
-
])
|
|
185
|
-
|
|
186
|
-
expect(adminWriteResponse.status).toBe(200)
|
|
187
|
-
expect(editorWriteResponse.status).toBe(200)
|
|
188
|
-
|
|
189
|
-
// Verify each user can read their own content
|
|
190
|
-
const adminReadResponse = await adminClient.get(
|
|
191
|
-
'/api/canopycms/admin-feature/content/posts/admin-post',
|
|
192
|
-
)
|
|
193
|
-
expect(adminReadResponse.status).toBe(200)
|
|
194
|
-
|
|
195
|
-
const editorReadResponse = await editorClient.get(
|
|
196
|
-
'/api/canopycms/editor-feature/content/posts/editor-post',
|
|
197
|
-
)
|
|
198
|
-
expect(editorReadResponse.status).toBe(200)
|
|
199
|
-
|
|
200
|
-
// Admin restricts their branch to admin-only
|
|
201
|
-
const restrictResponse = await adminClient.patch('/api/canopycms/admin-feature/access', {
|
|
202
|
-
allowedUsers: ['test-admin'],
|
|
203
|
-
allowedGroups: [],
|
|
204
|
-
managerOrAdminAllowed: true,
|
|
205
|
-
})
|
|
206
|
-
expect(restrictResponse.status).toBe(200)
|
|
207
|
-
|
|
208
|
-
// Cross-branch access with ACL
|
|
209
|
-
const adminReadEditorResponse = await adminClient.get(
|
|
210
|
-
'/api/canopycms/editor-feature/content/posts/editor-post',
|
|
211
|
-
)
|
|
212
|
-
expect(adminReadEditorResponse.status).toBe(200) // Admin can access everything
|
|
213
|
-
|
|
214
|
-
const editorReadAdminResponse = await editorClient.get(
|
|
215
|
-
'/api/canopycms/admin-feature/content/posts/admin-post',
|
|
216
|
-
)
|
|
217
|
-
expect(editorReadAdminResponse.status).toBe(403) // Editor cannot access restricted admin branch
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
it('lists branches via API with proper filtering', async () => {
|
|
221
|
-
// Create multiple branches
|
|
222
|
-
await adminClient.post('/api/canopycms/branches', {
|
|
223
|
-
branch: 'public-branch',
|
|
224
|
-
title: 'Public Branch',
|
|
225
|
-
})
|
|
226
|
-
|
|
227
|
-
await editorClient.post('/api/canopycms/branches', {
|
|
228
|
-
branch: 'editor-branch',
|
|
229
|
-
title: 'Editor Branch',
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
// List branches as admin - should see all
|
|
233
|
-
const adminListResponse = await adminClient.get('/api/canopycms/branches')
|
|
234
|
-
expect(adminListResponse.status).toBe(200)
|
|
235
|
-
const adminBranches = await adminListResponse.json<BranchListResponse>()
|
|
236
|
-
expect(adminBranches.data?.branches.length).toBeGreaterThanOrEqual(2)
|
|
237
|
-
|
|
238
|
-
// List branches as editor - should see their own + public
|
|
239
|
-
const editorListResponse = await editorClient.get('/api/canopycms/branches')
|
|
240
|
-
expect(editorListResponse.status).toBe(200)
|
|
241
|
-
const editorBranches = await editorListResponse.json<BranchListResponse>()
|
|
242
|
-
expect(editorBranches.data?.branches.some((b) => b.name === 'editor-branch')).toBe(true)
|
|
243
|
-
})
|
|
244
|
-
})
|
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration tests for conflict resolution workflows.
|
|
3
|
-
* Tests merge conflicts, git errors, and recovery scenarios.
|
|
4
|
-
* Tests go through the HTTP API layer.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
|
8
|
-
|
|
9
|
-
import { createTestWorkspace, type TestWorkspace } from '../test-utils/test-workspace'
|
|
10
|
-
import { createMockAuthPlugin } from '../test-utils/multi-user'
|
|
11
|
-
import { createApiClient } from '../test-utils/api-client'
|
|
12
|
-
import { BLOG_SCHEMA } from '../fixtures/schemas'
|
|
13
|
-
import type { BranchResponse } from '../../api/branch'
|
|
14
|
-
import type { ApiResponse } from '../../api/types'
|
|
15
|
-
|
|
16
|
-
describe('Conflict Resolution Integration', () => {
|
|
17
|
-
let workspace: TestWorkspace
|
|
18
|
-
let editor1Client: Awaited<ReturnType<typeof createApiClient>>
|
|
19
|
-
let editor2Client: Awaited<ReturnType<typeof createApiClient>>
|
|
20
|
-
|
|
21
|
-
beforeEach(async () => {
|
|
22
|
-
workspace = await createTestWorkspace({
|
|
23
|
-
schema: BLOG_SCHEMA,
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
editor1Client = await createApiClient({
|
|
27
|
-
config: workspace.config,
|
|
28
|
-
authPlugin: createMockAuthPlugin('editor'),
|
|
29
|
-
schema: BLOG_SCHEMA,
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
editor2Client = await createApiClient({
|
|
33
|
-
config: workspace.config,
|
|
34
|
-
authPlugin: createMockAuthPlugin('admin'),
|
|
35
|
-
schema: BLOG_SCHEMA,
|
|
36
|
-
})
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
afterEach(async () => {
|
|
40
|
-
await workspace.cleanup()
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('detects conflicts when two editors modify the same content', async () => {
|
|
44
|
-
// Editor 1 creates a branch and writes content
|
|
45
|
-
await editor1Client.post('/api/canopycms/branches', {
|
|
46
|
-
branch: 'feature/conflict-test',
|
|
47
|
-
title: 'Conflict Test',
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
await editor1Client.put('/api/canopycms/feature-conflict-test/content/posts/shared-post', {
|
|
51
|
-
format: 'mdx',
|
|
52
|
-
data: {
|
|
53
|
-
title: 'Shared Post',
|
|
54
|
-
author: 'Editor 1',
|
|
55
|
-
date: '2024-01-01',
|
|
56
|
-
tags: ['test'],
|
|
57
|
-
},
|
|
58
|
-
body: 'Original content from Editor 1',
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
// Editor 2 creates a different branch from same base
|
|
62
|
-
await editor2Client.post('/api/canopycms/branches', {
|
|
63
|
-
branch: 'feature/conflict-test-2',
|
|
64
|
-
title: 'Conflict Test 2',
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
await editor2Client.put('/api/canopycms/feature-conflict-test-2/content/posts/shared-post', {
|
|
68
|
-
format: 'mdx',
|
|
69
|
-
data: {
|
|
70
|
-
title: 'Shared Post',
|
|
71
|
-
author: 'Editor 2',
|
|
72
|
-
date: '2024-01-01',
|
|
73
|
-
tags: ['test'],
|
|
74
|
-
},
|
|
75
|
-
body: 'Different content from Editor 2',
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
// Both approve and publish
|
|
79
|
-
// When merging, there should be a conflict
|
|
80
|
-
// TODO: Once merge API is implemented, test conflict detection
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('handles concurrent modifications to different files', async () => {
|
|
84
|
-
// Create branch
|
|
85
|
-
await editor1Client.post('/api/canopycms/branches', {
|
|
86
|
-
branch: 'feature/concurrent-edits',
|
|
87
|
-
title: 'Concurrent Edits',
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
// Two editors write different files simultaneously
|
|
91
|
-
const [response1, response2] = await Promise.all([
|
|
92
|
-
editor1Client.put('/api/canopycms/feature-concurrent-edits/content/posts/post-1', {
|
|
93
|
-
format: 'mdx',
|
|
94
|
-
data: {
|
|
95
|
-
title: 'Post 1',
|
|
96
|
-
author: 'Editor 1',
|
|
97
|
-
date: '2024-01-01',
|
|
98
|
-
tags: ['test'],
|
|
99
|
-
},
|
|
100
|
-
body: 'Content 1',
|
|
101
|
-
}),
|
|
102
|
-
editor1Client.put('/api/canopycms/feature-concurrent-edits/content/posts/post-2', {
|
|
103
|
-
format: 'mdx',
|
|
104
|
-
data: {
|
|
105
|
-
title: 'Post 2',
|
|
106
|
-
author: 'Editor 2',
|
|
107
|
-
date: '2024-01-02',
|
|
108
|
-
tags: ['test'],
|
|
109
|
-
},
|
|
110
|
-
body: 'Content 2',
|
|
111
|
-
}),
|
|
112
|
-
])
|
|
113
|
-
|
|
114
|
-
expect(response1.status).toBe(200)
|
|
115
|
-
expect(response2.status).toBe(200)
|
|
116
|
-
|
|
117
|
-
// Both files should exist
|
|
118
|
-
const read1 = await editor1Client.get(
|
|
119
|
-
'/api/canopycms/feature-concurrent-edits/content/posts/post-1',
|
|
120
|
-
)
|
|
121
|
-
const read2 = await editor1Client.get(
|
|
122
|
-
'/api/canopycms/feature-concurrent-edits/content/posts/post-2',
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
expect(read1.status).toBe(200)
|
|
126
|
-
expect(read2.status).toBe(200)
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
it('prevents overwriting uncommitted changes', async () => {
|
|
130
|
-
// Create branch and write content
|
|
131
|
-
await editor1Client.post('/api/canopycms/branches', {
|
|
132
|
-
branch: 'feature/uncommitted-test',
|
|
133
|
-
title: 'Uncommitted Test',
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
const write1 = await editor1Client.put(
|
|
137
|
-
'/api/canopycms/feature-uncommitted-test/content/posts/test-post',
|
|
138
|
-
{
|
|
139
|
-
format: 'mdx',
|
|
140
|
-
data: {
|
|
141
|
-
title: 'Test Post',
|
|
142
|
-
author: 'Editor 1',
|
|
143
|
-
date: '2024-01-01',
|
|
144
|
-
tags: ['test'],
|
|
145
|
-
},
|
|
146
|
-
body: 'First version',
|
|
147
|
-
},
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
expect(write1.status).toBe(200)
|
|
151
|
-
|
|
152
|
-
// Write again to same file (should succeed with overwrite)
|
|
153
|
-
const write2 = await editor1Client.put(
|
|
154
|
-
'/api/canopycms/feature-uncommitted-test/content/posts/test-post',
|
|
155
|
-
{
|
|
156
|
-
format: 'mdx',
|
|
157
|
-
data: {
|
|
158
|
-
title: 'Test Post Updated',
|
|
159
|
-
author: 'Editor 1',
|
|
160
|
-
date: '2024-01-01',
|
|
161
|
-
tags: ['test', 'updated'],
|
|
162
|
-
},
|
|
163
|
-
body: 'Second version',
|
|
164
|
-
},
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
expect(write2.status).toBe(200)
|
|
168
|
-
|
|
169
|
-
// Verify second version is persisted
|
|
170
|
-
const read = await editor1Client.get(
|
|
171
|
-
'/api/canopycms/feature-uncommitted-test/content/posts/test-post',
|
|
172
|
-
)
|
|
173
|
-
expect(read.status).toBe(200)
|
|
174
|
-
const content = await read.json<
|
|
175
|
-
ApiResponse<{
|
|
176
|
-
format: string
|
|
177
|
-
data: Record<string, unknown>
|
|
178
|
-
body?: string
|
|
179
|
-
}>
|
|
180
|
-
>()
|
|
181
|
-
expect(content.data?.data.title).toBe('Test Post Updated')
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
it('recovers from git errors gracefully', async () => {
|
|
185
|
-
// Create branch
|
|
186
|
-
await editor1Client.post('/api/canopycms/branches', {
|
|
187
|
-
branch: 'feature/git-error-test',
|
|
188
|
-
title: 'Git Error Test',
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
// Write valid content
|
|
192
|
-
const writeResponse = await editor1Client.put(
|
|
193
|
-
'/api/canopycms/feature-git-error-test/content/posts/test-post',
|
|
194
|
-
{
|
|
195
|
-
format: 'mdx',
|
|
196
|
-
data: {
|
|
197
|
-
title: 'Test Post',
|
|
198
|
-
author: 'Editor',
|
|
199
|
-
date: '2024-01-01',
|
|
200
|
-
tags: ['test'],
|
|
201
|
-
},
|
|
202
|
-
body: 'Test content',
|
|
203
|
-
},
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
expect(writeResponse.status).toBe(200)
|
|
207
|
-
|
|
208
|
-
// Try to write to invalid collection (should fail gracefully)
|
|
209
|
-
const invalidWrite = await editor1Client.put(
|
|
210
|
-
'/api/canopycms/feature-git-error-test/content/invalid-collection/test',
|
|
211
|
-
{
|
|
212
|
-
collection: 'invalid-collection',
|
|
213
|
-
slug: 'test',
|
|
214
|
-
format: 'mdx',
|
|
215
|
-
data: {
|
|
216
|
-
title: 'Test',
|
|
217
|
-
},
|
|
218
|
-
body: 'Should fail',
|
|
219
|
-
},
|
|
220
|
-
)
|
|
221
|
-
|
|
222
|
-
// Should get error, not crash
|
|
223
|
-
expect(invalidWrite.status).toBeGreaterThanOrEqual(400)
|
|
224
|
-
|
|
225
|
-
// Original content should still be accessible
|
|
226
|
-
const read = await editor1Client.get(
|
|
227
|
-
'/api/canopycms/feature-git-error-test/content/posts/test-post',
|
|
228
|
-
)
|
|
229
|
-
expect(read.status).toBe(200)
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
it('handles stale branch state after remote updates', async () => {
|
|
233
|
-
// Create branch
|
|
234
|
-
await editor1Client.post('/api/canopycms/branches', {
|
|
235
|
-
branch: 'feature/stale-state',
|
|
236
|
-
title: 'Stale State Test',
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
// Write content
|
|
240
|
-
await editor1Client.put('/api/canopycms/feature-stale-state/content/posts/test-post', {
|
|
241
|
-
format: 'mdx',
|
|
242
|
-
data: {
|
|
243
|
-
title: 'Test Post',
|
|
244
|
-
author: 'Editor',
|
|
245
|
-
date: '2024-01-01',
|
|
246
|
-
tags: ['test'],
|
|
247
|
-
},
|
|
248
|
-
body: 'Original content',
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
// Get branch status
|
|
252
|
-
const statusResponse = await editor1Client.get('/api/canopycms/feature-stale-state/status')
|
|
253
|
-
expect(statusResponse.status).toBe(200)
|
|
254
|
-
const status = await statusResponse.json<BranchResponse>()
|
|
255
|
-
|
|
256
|
-
// Branch should be in editing state
|
|
257
|
-
expect(status.data?.branch?.status).toBeDefined()
|
|
258
|
-
})
|
|
259
|
-
})
|