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,511 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Operating Mode Strategy Pattern Tests
|
|
3
|
-
*
|
|
4
|
-
* Tests for both client-safe and client-unsafe strategies
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, it, expect, afterEach } from 'vitest'
|
|
8
|
-
import {
|
|
9
|
-
clientOperatingStrategy,
|
|
10
|
-
clearClientStrategyCache,
|
|
11
|
-
operatingStrategy,
|
|
12
|
-
clearStrategyCache,
|
|
13
|
-
} from '../index'
|
|
14
|
-
import type { OperatingMode } from '..'
|
|
15
|
-
|
|
16
|
-
describe('Operating Mode Strategies', () => {
|
|
17
|
-
// Clean up caches after each test
|
|
18
|
-
afterEach(() => {
|
|
19
|
-
clearClientStrategyCache()
|
|
20
|
-
clearStrategyCache()
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
describe('Client-Safe Strategies', () => {
|
|
24
|
-
describe('Production Mode', () => {
|
|
25
|
-
const mode: OperatingMode = 'prod'
|
|
26
|
-
|
|
27
|
-
it('should have correct mode identifier', () => {
|
|
28
|
-
const strategy = clientOperatingStrategy(mode)
|
|
29
|
-
expect(strategy.mode).toBe('prod')
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('should support branching', () => {
|
|
33
|
-
const strategy = clientOperatingStrategy(mode)
|
|
34
|
-
expect(strategy.supportsBranching()).toBe(true)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('should support status badge', () => {
|
|
38
|
-
const strategy = clientOperatingStrategy(mode)
|
|
39
|
-
expect(strategy.supportsStatusBadge()).toBe(true)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('should support comments', () => {
|
|
43
|
-
const strategy = clientOperatingStrategy(mode)
|
|
44
|
-
expect(strategy.supportsComments()).toBe(true)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('should support pull requests', () => {
|
|
48
|
-
const strategy = clientOperatingStrategy(mode)
|
|
49
|
-
expect(strategy.supportsPullRequests()).toBe(true)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('should use standard permissions file name', () => {
|
|
53
|
-
const strategy = clientOperatingStrategy(mode)
|
|
54
|
-
expect(strategy.getPermissionsFileName()).toBe('permissions.json')
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
it('should use standard groups file name', () => {
|
|
58
|
-
const strategy = clientOperatingStrategy(mode)
|
|
59
|
-
expect(strategy.getGroupsFileName()).toBe('groups.json')
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
it('should commit changes', () => {
|
|
63
|
-
const strategy = clientOperatingStrategy(mode)
|
|
64
|
-
expect(strategy.shouldCommit()).toBe(true)
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it('should push changes', () => {
|
|
68
|
-
const strategy = clientOperatingStrategy(mode)
|
|
69
|
-
expect(strategy.shouldPush()).toBe(true)
|
|
70
|
-
})
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
describe('Local Production Simulation Mode', () => {
|
|
74
|
-
const mode: OperatingMode = 'prod-sim'
|
|
75
|
-
|
|
76
|
-
it('should have correct mode identifier', () => {
|
|
77
|
-
const strategy = clientOperatingStrategy(mode)
|
|
78
|
-
expect(strategy.mode).toBe('prod-sim')
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it('should support branching', () => {
|
|
82
|
-
const strategy = clientOperatingStrategy(mode)
|
|
83
|
-
expect(strategy.supportsBranching()).toBe(true)
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
it('should support status badge', () => {
|
|
87
|
-
const strategy = clientOperatingStrategy(mode)
|
|
88
|
-
expect(strategy.supportsStatusBadge()).toBe(true)
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it('should support comments', () => {
|
|
92
|
-
const strategy = clientOperatingStrategy(mode)
|
|
93
|
-
expect(strategy.supportsComments()).toBe(true)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it('should NOT support pull requests', () => {
|
|
97
|
-
const strategy = clientOperatingStrategy(mode)
|
|
98
|
-
expect(strategy.supportsPullRequests()).toBe(false)
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it('should use standard permissions file name', () => {
|
|
102
|
-
const strategy = clientOperatingStrategy(mode)
|
|
103
|
-
expect(strategy.getPermissionsFileName()).toBe('permissions.json')
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
it('should use standard groups file name', () => {
|
|
107
|
-
const strategy = clientOperatingStrategy(mode)
|
|
108
|
-
expect(strategy.getGroupsFileName()).toBe('groups.json')
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
it('should commit changes', () => {
|
|
112
|
-
const strategy = clientOperatingStrategy(mode)
|
|
113
|
-
expect(strategy.shouldCommit()).toBe(true)
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
it('should push changes', () => {
|
|
117
|
-
const strategy = clientOperatingStrategy(mode)
|
|
118
|
-
expect(strategy.shouldPush()).toBe(true)
|
|
119
|
-
})
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
describe('Local Simple Mode', () => {
|
|
123
|
-
const mode: OperatingMode = 'dev'
|
|
124
|
-
|
|
125
|
-
it('should have correct mode identifier', () => {
|
|
126
|
-
const strategy = clientOperatingStrategy(mode)
|
|
127
|
-
expect(strategy.mode).toBe('dev')
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
it('should NOT support branching', () => {
|
|
131
|
-
const strategy = clientOperatingStrategy(mode)
|
|
132
|
-
expect(strategy.supportsBranching()).toBe(false)
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
it('should NOT support status badge', () => {
|
|
136
|
-
const strategy = clientOperatingStrategy(mode)
|
|
137
|
-
expect(strategy.supportsStatusBadge()).toBe(false)
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
it('should NOT support comments', () => {
|
|
141
|
-
const strategy = clientOperatingStrategy(mode)
|
|
142
|
-
expect(strategy.supportsComments()).toBe(false)
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
it('should NOT support pull requests', () => {
|
|
146
|
-
const strategy = clientOperatingStrategy(mode)
|
|
147
|
-
expect(strategy.supportsPullRequests()).toBe(false)
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
it('should use standard permissions file name', () => {
|
|
151
|
-
const strategy = clientOperatingStrategy(mode)
|
|
152
|
-
expect(strategy.getPermissionsFileName()).toBe('permissions.json')
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
it('should use standard groups file name', () => {
|
|
156
|
-
const strategy = clientOperatingStrategy(mode)
|
|
157
|
-
expect(strategy.getGroupsFileName()).toBe('groups.json')
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
it('should NOT commit changes', () => {
|
|
161
|
-
const strategy = clientOperatingStrategy(mode)
|
|
162
|
-
expect(strategy.shouldCommit()).toBe(false)
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
it('should NOT push changes', () => {
|
|
166
|
-
const strategy = clientOperatingStrategy(mode)
|
|
167
|
-
expect(strategy.shouldPush()).toBe(false)
|
|
168
|
-
})
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
describe('Memoization', () => {
|
|
172
|
-
it('should return same instance for same mode', () => {
|
|
173
|
-
const strategy1 = clientOperatingStrategy('prod')
|
|
174
|
-
const strategy2 = clientOperatingStrategy('prod')
|
|
175
|
-
expect(strategy1).toBe(strategy2)
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
it('should return different instances for different modes', () => {
|
|
179
|
-
const prodStrategy = clientOperatingStrategy('prod')
|
|
180
|
-
const localStrategy = clientOperatingStrategy('dev')
|
|
181
|
-
expect(prodStrategy).not.toBe(localStrategy)
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
it('should create new instance after cache clear', () => {
|
|
185
|
-
const strategy1 = clientOperatingStrategy('prod')
|
|
186
|
-
clearClientStrategyCache()
|
|
187
|
-
const strategy2 = clientOperatingStrategy('prod')
|
|
188
|
-
expect(strategy1).not.toBe(strategy2)
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
describe('Client-Unsafe Strategies', () => {
|
|
194
|
-
describe('Production Mode', () => {
|
|
195
|
-
const mode: OperatingMode = 'prod'
|
|
196
|
-
const originalEnv = process.env.CANOPYCMS_WORKSPACE_ROOT
|
|
197
|
-
|
|
198
|
-
afterEach(() => {
|
|
199
|
-
// Restore original env
|
|
200
|
-
if (originalEnv) {
|
|
201
|
-
process.env.CANOPYCMS_WORKSPACE_ROOT = originalEnv
|
|
202
|
-
} else {
|
|
203
|
-
delete process.env.CANOPYCMS_WORKSPACE_ROOT
|
|
204
|
-
}
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
it('should inherit all client-safe methods', () => {
|
|
208
|
-
const strategy = operatingStrategy(mode)
|
|
209
|
-
expect(strategy.mode).toBe('prod')
|
|
210
|
-
expect(strategy.supportsBranching()).toBe(true)
|
|
211
|
-
expect(strategy.shouldCommit()).toBe(true)
|
|
212
|
-
expect(strategy.getPermissionsFileName()).toBe('permissions.json')
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
it('should use default content branches root', () => {
|
|
216
|
-
delete process.env.CANOPYCMS_WORKSPACE_ROOT
|
|
217
|
-
const strategy = operatingStrategy(mode)
|
|
218
|
-
const branchesRoot = strategy.getContentBranchesRoot()
|
|
219
|
-
expect(branchesRoot).toContain('/mnt/efs/workspace/content-branches')
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
it('should use env variable for content branches root', () => {
|
|
223
|
-
process.env.CANOPYCMS_WORKSPACE_ROOT = '/custom/path'
|
|
224
|
-
const strategy = operatingStrategy(mode)
|
|
225
|
-
const branchesRoot = strategy.getContentBranchesRoot()
|
|
226
|
-
expect(branchesRoot).toContain('/custom/path/content-branches')
|
|
227
|
-
})
|
|
228
|
-
|
|
229
|
-
it('should get content root', () => {
|
|
230
|
-
const strategy = operatingStrategy(mode)
|
|
231
|
-
const contentRoot = strategy.getContentRoot()
|
|
232
|
-
expect(contentRoot).toContain('content')
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
it('should create branch subdirectories', () => {
|
|
236
|
-
const strategy = operatingStrategy(mode)
|
|
237
|
-
const branchRoot = strategy.getContentBranchRoot('feature-branch')
|
|
238
|
-
expect(branchRoot).toContain('feature-branch')
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
it('should construct permissions file path', () => {
|
|
242
|
-
const strategy = operatingStrategy(mode)
|
|
243
|
-
const path = strategy.getPermissionsFilePath('/root')
|
|
244
|
-
expect(path).toContain('/root')
|
|
245
|
-
expect(path).toContain('permissions.json')
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
it('should construct groups file path', () => {
|
|
249
|
-
const strategy = operatingStrategy(mode)
|
|
250
|
-
const path = strategy.getGroupsFilePath('/root')
|
|
251
|
-
expect(path).toContain('/root')
|
|
252
|
-
expect(path).toContain('groups.json')
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
it('should NOT require existing repo', () => {
|
|
256
|
-
const strategy = operatingStrategy(mode)
|
|
257
|
-
expect(strategy.requiresExistingRepo()).toBe(false)
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
it('should use canopycms-settings-prod branch by default', () => {
|
|
261
|
-
const strategy = operatingStrategy(mode)
|
|
262
|
-
const branchName = strategy.getSettingsBranchName({})
|
|
263
|
-
expect(branchName).toBe('canopycms-settings-prod')
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
it('should use deploymentName for settings branch', () => {
|
|
267
|
-
const strategy = operatingStrategy(mode)
|
|
268
|
-
const branchName = strategy.getSettingsBranchName({
|
|
269
|
-
deploymentName: 'staging',
|
|
270
|
-
})
|
|
271
|
-
expect(branchName).toBe('canopycms-settings-staging')
|
|
272
|
-
})
|
|
273
|
-
|
|
274
|
-
it('should respect custom settings branch', () => {
|
|
275
|
-
const strategy = operatingStrategy(mode)
|
|
276
|
-
const branchName = strategy.getSettingsBranchName({
|
|
277
|
-
settingsBranch: 'custom-settings',
|
|
278
|
-
})
|
|
279
|
-
expect(branchName).toBe('custom-settings')
|
|
280
|
-
})
|
|
281
|
-
|
|
282
|
-
it('should use separate settings branch', () => {
|
|
283
|
-
const strategy = operatingStrategy(mode)
|
|
284
|
-
expect(strategy.usesSeparateSettingsBranch()).toBe(true)
|
|
285
|
-
})
|
|
286
|
-
|
|
287
|
-
it('should validate config requires git bot info', () => {
|
|
288
|
-
const strategy = operatingStrategy(mode)
|
|
289
|
-
expect(() => {
|
|
290
|
-
strategy.validateConfig({})
|
|
291
|
-
}).toThrow('gitBotAuthorName and gitBotAuthorEmail')
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
it('should allow valid config', () => {
|
|
295
|
-
const strategy = operatingStrategy(mode)
|
|
296
|
-
expect(() => {
|
|
297
|
-
strategy.validateConfig({
|
|
298
|
-
gitBotAuthorName: 'Bot',
|
|
299
|
-
gitBotAuthorEmail: 'bot@example.com',
|
|
300
|
-
})
|
|
301
|
-
}).not.toThrow()
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
it('should create permissions PR by default', () => {
|
|
305
|
-
const strategy = operatingStrategy(mode)
|
|
306
|
-
expect(strategy.shouldCreateSettingsPR({})).toBe(true)
|
|
307
|
-
})
|
|
308
|
-
|
|
309
|
-
it('should respect autoCreatePermissionsPR config', () => {
|
|
310
|
-
const strategy = operatingStrategy(mode)
|
|
311
|
-
expect(strategy.shouldCreateSettingsPR({ autoCreateSettingsPR: false })).toBe(false)
|
|
312
|
-
})
|
|
313
|
-
|
|
314
|
-
it('should return git exclude pattern', () => {
|
|
315
|
-
const strategy = operatingStrategy(mode)
|
|
316
|
-
expect(strategy.getGitExcludePattern()).toBe('.canopy-meta/')
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
it('should have autoDetectRemotePath pointing to remote.git at workspace root', () => {
|
|
320
|
-
delete process.env.CANOPYCMS_WORKSPACE_ROOT
|
|
321
|
-
clearStrategyCache()
|
|
322
|
-
const strategy = operatingStrategy(mode)
|
|
323
|
-
const config = strategy.getRemoteUrlConfig()
|
|
324
|
-
expect(config.shouldAutoInitLocal).toBe(false)
|
|
325
|
-
expect(config.autoDetectRemotePath).toContain('/mnt/efs/workspace/remote.git')
|
|
326
|
-
})
|
|
327
|
-
|
|
328
|
-
it('should use custom workspace root in autoDetectRemotePath', () => {
|
|
329
|
-
process.env.CANOPYCMS_WORKSPACE_ROOT = '/custom/workspace'
|
|
330
|
-
clearStrategyCache()
|
|
331
|
-
const strategy = operatingStrategy(mode)
|
|
332
|
-
const config = strategy.getRemoteUrlConfig()
|
|
333
|
-
expect(config.autoDetectRemotePath).toContain('/custom/workspace/remote.git')
|
|
334
|
-
})
|
|
335
|
-
})
|
|
336
|
-
|
|
337
|
-
describe('Local Production Simulation Mode', () => {
|
|
338
|
-
const mode: OperatingMode = 'prod-sim'
|
|
339
|
-
|
|
340
|
-
it('should inherit all client-safe methods', () => {
|
|
341
|
-
const strategy = operatingStrategy(mode)
|
|
342
|
-
expect(strategy.mode).toBe('prod-sim')
|
|
343
|
-
expect(strategy.supportsBranching()).toBe(true)
|
|
344
|
-
expect(strategy.shouldCommit()).toBe(true)
|
|
345
|
-
expect(strategy.supportsPullRequests()).toBe(false)
|
|
346
|
-
})
|
|
347
|
-
|
|
348
|
-
it('should use .canopy-prod-sim/content-branches as branches root', () => {
|
|
349
|
-
const strategy = operatingStrategy(mode)
|
|
350
|
-
const branchesRoot = strategy.getContentBranchesRoot()
|
|
351
|
-
expect(branchesRoot).toContain('.canopy-prod-sim/content-branches')
|
|
352
|
-
})
|
|
353
|
-
|
|
354
|
-
it('should create branch subdirectories', () => {
|
|
355
|
-
const strategy = operatingStrategy(mode)
|
|
356
|
-
const branchRoot = strategy.getContentBranchRoot('feature-branch')
|
|
357
|
-
expect(branchRoot).toContain('feature-branch')
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
it('should NOT require existing repo', () => {
|
|
361
|
-
const strategy = operatingStrategy(mode)
|
|
362
|
-
expect(strategy.requiresExistingRepo()).toBe(false)
|
|
363
|
-
})
|
|
364
|
-
|
|
365
|
-
it('should use separate settings branch', () => {
|
|
366
|
-
const strategy = operatingStrategy(mode)
|
|
367
|
-
expect(strategy.usesSeparateSettingsBranch()).toBe(true)
|
|
368
|
-
})
|
|
369
|
-
|
|
370
|
-
it('should NOT create permissions PR', () => {
|
|
371
|
-
const strategy = operatingStrategy(mode)
|
|
372
|
-
expect(strategy.shouldCreateSettingsPR({})).toBe(false)
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
it('should return git exclude pattern', () => {
|
|
376
|
-
const strategy = operatingStrategy(mode)
|
|
377
|
-
expect(strategy.getGitExcludePattern()).toBe('.canopy-meta/')
|
|
378
|
-
})
|
|
379
|
-
})
|
|
380
|
-
|
|
381
|
-
describe('Local Simple Mode', () => {
|
|
382
|
-
const mode: OperatingMode = 'dev'
|
|
383
|
-
|
|
384
|
-
it('should inherit all client-safe methods', () => {
|
|
385
|
-
const strategy = operatingStrategy(mode)
|
|
386
|
-
expect(strategy.mode).toBe('dev')
|
|
387
|
-
expect(strategy.supportsBranching()).toBe(false)
|
|
388
|
-
expect(strategy.shouldCommit()).toBe(false)
|
|
389
|
-
expect(strategy.getPermissionsFileName()).toBe('permissions.json')
|
|
390
|
-
})
|
|
391
|
-
|
|
392
|
-
it('should get content root', () => {
|
|
393
|
-
const strategy = operatingStrategy(mode)
|
|
394
|
-
const contentRoot = strategy.getContentRoot()
|
|
395
|
-
expect(contentRoot).toContain('content')
|
|
396
|
-
})
|
|
397
|
-
|
|
398
|
-
it('should throw error when getting content branches root', () => {
|
|
399
|
-
const strategy = operatingStrategy(mode)
|
|
400
|
-
expect(() => strategy.getContentBranchesRoot()).toThrow('No branching in dev mode')
|
|
401
|
-
})
|
|
402
|
-
|
|
403
|
-
it('should throw error when getting content branch root', () => {
|
|
404
|
-
const strategy = operatingStrategy(mode)
|
|
405
|
-
expect(() => strategy.getContentBranchRoot('feature-branch')).toThrow(
|
|
406
|
-
'No branching in dev mode',
|
|
407
|
-
)
|
|
408
|
-
})
|
|
409
|
-
|
|
410
|
-
it('should construct permissions file path in .canopy-dev', () => {
|
|
411
|
-
const strategy = operatingStrategy(mode)
|
|
412
|
-
const path = strategy.getPermissionsFilePath('/root')
|
|
413
|
-
expect(path).toContain('.canopy-dev')
|
|
414
|
-
expect(path).toContain('permissions.json')
|
|
415
|
-
})
|
|
416
|
-
|
|
417
|
-
it('should require existing repo', () => {
|
|
418
|
-
const strategy = operatingStrategy(mode)
|
|
419
|
-
expect(strategy.requiresExistingRepo()).toBe(true)
|
|
420
|
-
})
|
|
421
|
-
|
|
422
|
-
it('should use main branch for settings by default', () => {
|
|
423
|
-
const strategy = operatingStrategy(mode)
|
|
424
|
-
const branchName = strategy.getSettingsBranchName({})
|
|
425
|
-
expect(branchName).toBe('main')
|
|
426
|
-
})
|
|
427
|
-
|
|
428
|
-
it('should respect custom default base branch', () => {
|
|
429
|
-
const strategy = operatingStrategy(mode)
|
|
430
|
-
const branchName = strategy.getSettingsBranchName({
|
|
431
|
-
defaultBaseBranch: 'master',
|
|
432
|
-
})
|
|
433
|
-
expect(branchName).toBe('master')
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
it('should NOT use separate settings branch', () => {
|
|
437
|
-
const strategy = operatingStrategy(mode)
|
|
438
|
-
expect(strategy.usesSeparateSettingsBranch()).toBe(false)
|
|
439
|
-
})
|
|
440
|
-
|
|
441
|
-
it('should NOT validate config', () => {
|
|
442
|
-
const strategy = operatingStrategy(mode)
|
|
443
|
-
expect(() => {
|
|
444
|
-
strategy.validateConfig({})
|
|
445
|
-
}).not.toThrow()
|
|
446
|
-
})
|
|
447
|
-
|
|
448
|
-
it('should NOT create permissions PR', () => {
|
|
449
|
-
const strategy = operatingStrategy(mode)
|
|
450
|
-
expect(strategy.shouldCreateSettingsPR({})).toBe(false)
|
|
451
|
-
})
|
|
452
|
-
|
|
453
|
-
it('should not auto-init local remote', () => {
|
|
454
|
-
const strategy = operatingStrategy(mode)
|
|
455
|
-
const config = strategy.getRemoteUrlConfig()
|
|
456
|
-
expect(config.shouldAutoInitLocal).toBe(false)
|
|
457
|
-
expect(config.envVarName).toBe('CANOPYCMS_REMOTE_URL')
|
|
458
|
-
})
|
|
459
|
-
|
|
460
|
-
it('should return git exclude pattern', () => {
|
|
461
|
-
const strategy = operatingStrategy(mode)
|
|
462
|
-
expect(strategy.getGitExcludePattern()).toBe('.canopy-meta/')
|
|
463
|
-
})
|
|
464
|
-
})
|
|
465
|
-
|
|
466
|
-
describe('Memoization', () => {
|
|
467
|
-
it('should return same instance for same mode', () => {
|
|
468
|
-
const strategy1 = operatingStrategy('prod')
|
|
469
|
-
const strategy2 = operatingStrategy('prod')
|
|
470
|
-
expect(strategy1).toBe(strategy2)
|
|
471
|
-
})
|
|
472
|
-
|
|
473
|
-
it('should return different instances for different modes', () => {
|
|
474
|
-
const prodStrategy = operatingStrategy('prod')
|
|
475
|
-
const localStrategy = operatingStrategy('dev')
|
|
476
|
-
expect(prodStrategy).not.toBe(localStrategy)
|
|
477
|
-
})
|
|
478
|
-
|
|
479
|
-
it('should create new instance after cache clear', () => {
|
|
480
|
-
const strategy1 = operatingStrategy('prod')
|
|
481
|
-
clearStrategyCache()
|
|
482
|
-
const strategy2 = operatingStrategy('prod')
|
|
483
|
-
expect(strategy1).not.toBe(strategy2)
|
|
484
|
-
})
|
|
485
|
-
})
|
|
486
|
-
|
|
487
|
-
describe('Integration with Client-Safe Strategies', () => {
|
|
488
|
-
it('should have separate caches', () => {
|
|
489
|
-
const clientStrategy = clientOperatingStrategy('prod')
|
|
490
|
-
const fullStrategy = operatingStrategy('prod')
|
|
491
|
-
// They should not be the same instance
|
|
492
|
-
expect(clientStrategy).not.toBe(fullStrategy)
|
|
493
|
-
})
|
|
494
|
-
|
|
495
|
-
it('should have same mode values', () => {
|
|
496
|
-
const clientStrategy = clientOperatingStrategy('prod')
|
|
497
|
-
const fullStrategy = operatingStrategy('prod')
|
|
498
|
-
expect(clientStrategy.mode).toBe(fullStrategy.mode)
|
|
499
|
-
})
|
|
500
|
-
|
|
501
|
-
it('should have same client-safe method results', () => {
|
|
502
|
-
const clientStrategy = clientOperatingStrategy('prod')
|
|
503
|
-
const fullStrategy = operatingStrategy('prod')
|
|
504
|
-
|
|
505
|
-
expect(clientStrategy.supportsBranching()).toBe(fullStrategy.supportsBranching())
|
|
506
|
-
expect(clientStrategy.shouldCommit()).toBe(fullStrategy.shouldCommit())
|
|
507
|
-
expect(clientStrategy.getPermissionsFileName()).toBe(fullStrategy.getPermissionsFileName())
|
|
508
|
-
})
|
|
509
|
-
})
|
|
510
|
-
})
|
|
511
|
-
})
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client-Safe Operating Mode Strategies
|
|
3
|
-
*
|
|
4
|
-
* Base strategy classes that are safe to import in 'use client' React components.
|
|
5
|
-
* NO Node.js imports (fs, path, process, etc.) - only pure logic and simple data.
|
|
6
|
-
*
|
|
7
|
-
* These classes are extended by client-unsafe strategies to add Node.js functionality.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import type { OperatingMode, ClientSafeStrategy } from './types'
|
|
11
|
-
|
|
12
|
-
// ============================================================================
|
|
13
|
-
// Production Mode - Client-Safe Strategy
|
|
14
|
-
// ============================================================================
|
|
15
|
-
|
|
16
|
-
export class ProdClientSafeStrategy implements ClientSafeStrategy {
|
|
17
|
-
readonly mode: OperatingMode = 'prod'
|
|
18
|
-
|
|
19
|
-
// UI Feature Flags
|
|
20
|
-
supportsBranching(): boolean {
|
|
21
|
-
return true
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
supportsStatusBadge(): boolean {
|
|
25
|
-
return true
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
supportsComments(): boolean {
|
|
29
|
-
return true
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
supportsPullRequests(): boolean {
|
|
33
|
-
return true
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Simple Data
|
|
37
|
-
getPermissionsFileName(): string {
|
|
38
|
-
return 'permissions.json'
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
getGroupsFileName(): string {
|
|
42
|
-
return 'groups.json'
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
shouldCommit(): boolean {
|
|
46
|
-
return true
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
shouldPush(): boolean {
|
|
50
|
-
return true
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// ============================================================================
|
|
55
|
-
// Local Production Simulation - Client-Safe Strategy
|
|
56
|
-
// ============================================================================
|
|
57
|
-
|
|
58
|
-
export class LocalProdSimClientSafeStrategy implements ClientSafeStrategy {
|
|
59
|
-
readonly mode: OperatingMode = 'prod-sim'
|
|
60
|
-
|
|
61
|
-
// UI Feature Flags
|
|
62
|
-
supportsBranching(): boolean {
|
|
63
|
-
return true
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
supportsStatusBadge(): boolean {
|
|
67
|
-
return true
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
supportsComments(): boolean {
|
|
71
|
-
return true
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
supportsPullRequests(): boolean {
|
|
75
|
-
return false // No real GitHub in simulation
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Simple Data
|
|
79
|
-
getPermissionsFileName(): string {
|
|
80
|
-
return 'permissions.json'
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
getGroupsFileName(): string {
|
|
84
|
-
return 'groups.json'
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
shouldCommit(): boolean {
|
|
88
|
-
return true
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
shouldPush(): boolean {
|
|
92
|
-
return true
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// ============================================================================
|
|
97
|
-
// Local Simple Mode - Client-Safe Strategy
|
|
98
|
-
// ============================================================================
|
|
99
|
-
|
|
100
|
-
export class LocalSimpleClientSafeStrategy implements ClientSafeStrategy {
|
|
101
|
-
readonly mode: OperatingMode = 'dev'
|
|
102
|
-
|
|
103
|
-
// UI Feature Flags
|
|
104
|
-
supportsBranching(): boolean {
|
|
105
|
-
return false
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
supportsStatusBadge(): boolean {
|
|
109
|
-
return false
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
supportsComments(): boolean {
|
|
113
|
-
return false
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
supportsPullRequests(): boolean {
|
|
117
|
-
return false
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Simple Data
|
|
121
|
-
getPermissionsFileName(): string {
|
|
122
|
-
return 'permissions.json'
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
getGroupsFileName(): string {
|
|
126
|
-
return 'groups.json'
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
shouldCommit(): boolean {
|
|
130
|
-
return false
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
shouldPush(): boolean {
|
|
134
|
-
return false
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// ============================================================================
|
|
139
|
-
// Factory with Memoization
|
|
140
|
-
// ============================================================================
|
|
141
|
-
|
|
142
|
-
const clientStrategyCache = new Map<OperatingMode, ClientSafeStrategy>()
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Get the client-safe strategy for an operating mode.
|
|
146
|
-
*
|
|
147
|
-
* Strategies are memoized - one instance per mode for the entire process lifetime.
|
|
148
|
-
* Safe to call inline: clientOperatingStrategy(mode).supportsBranching()
|
|
149
|
-
*
|
|
150
|
-
* @param mode - The operating mode
|
|
151
|
-
* @returns Client-safe strategy instance
|
|
152
|
-
*/
|
|
153
|
-
export function clientOperatingStrategy(mode: OperatingMode): ClientSafeStrategy {
|
|
154
|
-
const cached = clientStrategyCache.get(mode)
|
|
155
|
-
if (cached) return cached
|
|
156
|
-
|
|
157
|
-
let strategy: ClientSafeStrategy
|
|
158
|
-
switch (mode) {
|
|
159
|
-
case 'prod':
|
|
160
|
-
strategy = new ProdClientSafeStrategy()
|
|
161
|
-
break
|
|
162
|
-
case 'prod-sim':
|
|
163
|
-
strategy = new LocalProdSimClientSafeStrategy()
|
|
164
|
-
break
|
|
165
|
-
case 'dev':
|
|
166
|
-
strategy = new LocalSimpleClientSafeStrategy()
|
|
167
|
-
break
|
|
168
|
-
default: {
|
|
169
|
-
// Exhaustiveness check - TypeScript will error if a mode is not handled
|
|
170
|
-
const _exhaustive: never = mode
|
|
171
|
-
throw new Error(`Unknown operating mode: ${_exhaustive}`)
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
clientStrategyCache.set(mode, strategy)
|
|
176
|
-
return strategy
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Clear the client strategy cache (mainly for testing)
|
|
181
|
-
*/
|
|
182
|
-
export function clearClientStrategyCache(): void {
|
|
183
|
-
clientStrategyCache.clear()
|
|
184
|
-
}
|