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
package/src/api/permissions.ts
DELETED
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
|
|
3
|
-
import type { ApiContext, ApiRequest, ApiResponse } from './types'
|
|
4
|
-
import type { PathPermission } from '../config'
|
|
5
|
-
import type { UserSearchResult, GroupMetadata } from '../auth/types'
|
|
6
|
-
import { loadPathPermissions, savePathPermissions, loadPermissionsFile } from '../authorization'
|
|
7
|
-
import { permissionPathSchema } from './validators'
|
|
8
|
-
import { defineEndpoint } from './route-builder'
|
|
9
|
-
import { getSettingsBranchContext, commitSettings } from './settings-helpers'
|
|
10
|
-
|
|
11
|
-
/** Response type for getting permissions */
|
|
12
|
-
export type PermissionsResponse = ApiResponse<{ permissions: PathPermission[] }>
|
|
13
|
-
|
|
14
|
-
/** Response type for user search */
|
|
15
|
-
export type SearchUsersResponse = ApiResponse<{ users: UserSearchResult[] }>
|
|
16
|
-
|
|
17
|
-
/** Response type for list groups */
|
|
18
|
-
export type ListGroupsResponse = ApiResponse<{ groups: GroupMetadata[] }>
|
|
19
|
-
|
|
20
|
-
/** Response type for get user metadata */
|
|
21
|
-
export type GetUserMetadataResponse = ApiResponse<{
|
|
22
|
-
user: UserSearchResult | null
|
|
23
|
-
}>
|
|
24
|
-
|
|
25
|
-
// ============================================================================
|
|
26
|
-
// Zod Schemas for Validation
|
|
27
|
-
// ============================================================================
|
|
28
|
-
|
|
29
|
-
const permissionTargetSchema = z.object({
|
|
30
|
-
allowedUsers: z.array(z.string()).optional(),
|
|
31
|
-
allowedGroups: z.array(z.string()).optional(),
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
const pathPermissionSchema = z.object({
|
|
35
|
-
path: permissionPathSchema,
|
|
36
|
-
read: permissionTargetSchema.optional(),
|
|
37
|
-
edit: permissionTargetSchema.optional(),
|
|
38
|
-
review: permissionTargetSchema.optional(),
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
const updatePermissionsBodySchema = z.object({
|
|
42
|
-
permissions: z.array(pathPermissionSchema),
|
|
43
|
-
expectedContentVersion: z.number().optional(),
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
const searchUsersParamsSchema = z.object({
|
|
47
|
-
q: z.string(),
|
|
48
|
-
limit: z.string().optional(),
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
const getUserMetadataParamsSchema = z.object({
|
|
52
|
-
userId: z.string(),
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
export type UpdatePermissionsBody = z.infer<typeof updatePermissionsBodySchema>
|
|
56
|
-
export type SearchUsersParams = z.infer<typeof searchUsersParamsSchema>
|
|
57
|
-
export type GetUserMetadataParams = z.infer<typeof getUserMetadataParamsSchema>
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Get current permissions (admin only)
|
|
61
|
-
*/
|
|
62
|
-
const getPermissionsHandler = async (
|
|
63
|
-
_gc: Record<string, never>,
|
|
64
|
-
ctx: ApiContext,
|
|
65
|
-
_req: ApiRequest,
|
|
66
|
-
): Promise<PermissionsResponse> => {
|
|
67
|
-
try {
|
|
68
|
-
const result = await getSettingsBranchContext(ctx)
|
|
69
|
-
if ('error' in result) {
|
|
70
|
-
return { ok: false, status: result.status, error: result.error }
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const { context, mode } = result
|
|
74
|
-
const permissions = await loadPathPermissions(context.branchRoot, mode)
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
ok: true,
|
|
78
|
-
status: 200,
|
|
79
|
-
data: { permissions },
|
|
80
|
-
}
|
|
81
|
-
} catch (error) {
|
|
82
|
-
return {
|
|
83
|
-
ok: false,
|
|
84
|
-
status: 500,
|
|
85
|
-
error: error instanceof Error ? error.message : 'Failed to load permissions',
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Update permissions (admin only)
|
|
92
|
-
*/
|
|
93
|
-
const updatePermissionsHandler = async (
|
|
94
|
-
_gc: Record<string, never>,
|
|
95
|
-
ctx: ApiContext,
|
|
96
|
-
req: ApiRequest,
|
|
97
|
-
body: z.infer<typeof updatePermissionsBodySchema>,
|
|
98
|
-
): Promise<ApiResponse> => {
|
|
99
|
-
if (!body?.permissions) {
|
|
100
|
-
return { ok: false, status: 400, error: 'permissions array required' }
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
try {
|
|
104
|
-
const result = await getSettingsBranchContext(ctx)
|
|
105
|
-
if ('error' in result) {
|
|
106
|
-
return { ok: false, status: result.status, error: result.error }
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const { context, mode } = result
|
|
110
|
-
|
|
111
|
-
// Load current file to check version (optimistic locking)
|
|
112
|
-
const currentFile = await loadPermissionsFile(context.branchRoot, mode)
|
|
113
|
-
|
|
114
|
-
// Check for version conflict if client sent expected version
|
|
115
|
-
if (body.expectedContentVersion !== undefined) {
|
|
116
|
-
const currentVersion = currentFile?.contentVersion ?? 0
|
|
117
|
-
if (currentVersion !== body.expectedContentVersion) {
|
|
118
|
-
return {
|
|
119
|
-
ok: false,
|
|
120
|
-
status: 409,
|
|
121
|
-
error: 'Permissions were modified by another user. Please reload and try again.',
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Increment version when saving
|
|
127
|
-
const newContentVersion = (currentFile?.contentVersion ?? 0) + 1
|
|
128
|
-
|
|
129
|
-
// Save file (uses mode-aware file path)
|
|
130
|
-
await savePathPermissions(
|
|
131
|
-
context.branchRoot,
|
|
132
|
-
body.permissions,
|
|
133
|
-
req.user.userId,
|
|
134
|
-
mode,
|
|
135
|
-
newContentVersion,
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
// Commit and push (mode-aware)
|
|
139
|
-
await commitSettings(ctx, {
|
|
140
|
-
context,
|
|
141
|
-
branchRoot: context.branchRoot,
|
|
142
|
-
fileName: 'permissions.json',
|
|
143
|
-
message: 'Update permissions',
|
|
144
|
-
mode,
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
return { ok: true, status: 200 }
|
|
148
|
-
} catch (error) {
|
|
149
|
-
return {
|
|
150
|
-
ok: false,
|
|
151
|
-
status: 500,
|
|
152
|
-
error: error instanceof Error ? error.message : 'Failed to save permissions',
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Search users (for permission UI)
|
|
159
|
-
*/
|
|
160
|
-
const searchUsersHandler = async (
|
|
161
|
-
_gc: Record<string, never>,
|
|
162
|
-
ctx: ApiContext,
|
|
163
|
-
req: ApiRequest,
|
|
164
|
-
params: z.infer<typeof searchUsersParamsSchema>,
|
|
165
|
-
): Promise<SearchUsersResponse> => {
|
|
166
|
-
const authPlugin = ctx.authPlugin
|
|
167
|
-
if (!authPlugin) {
|
|
168
|
-
return { ok: false, status: 501, error: 'Auth plugin not configured' }
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const query = params.q
|
|
172
|
-
const limit = params.limit ? parseInt(params.limit, 10) : undefined
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
const users = await authPlugin.searchUsers(query, limit)
|
|
176
|
-
return { ok: true, status: 200, data: { users } }
|
|
177
|
-
} catch (error) {
|
|
178
|
-
return {
|
|
179
|
-
ok: false,
|
|
180
|
-
status: 500,
|
|
181
|
-
error: error instanceof Error ? error.message : 'User search failed',
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* List groups (for permission UI)
|
|
188
|
-
*/
|
|
189
|
-
const listGroupsHandler = async (
|
|
190
|
-
_gc: Record<string, never>,
|
|
191
|
-
ctx: ApiContext,
|
|
192
|
-
_req: ApiRequest,
|
|
193
|
-
): Promise<ListGroupsResponse> => {
|
|
194
|
-
const authPlugin = ctx.authPlugin
|
|
195
|
-
if (!authPlugin) {
|
|
196
|
-
return { ok: false, status: 501, error: 'Auth plugin not configured' }
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
try {
|
|
200
|
-
const groups = await authPlugin.listGroups()
|
|
201
|
-
return { ok: true, status: 200, data: { groups } }
|
|
202
|
-
} catch (error) {
|
|
203
|
-
return {
|
|
204
|
-
ok: false,
|
|
205
|
-
status: 500,
|
|
206
|
-
error: error instanceof Error ? error.message : 'Group list failed',
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Get user metadata by ID (for UI display)
|
|
213
|
-
*/
|
|
214
|
-
const getUserMetadataHandler = async (
|
|
215
|
-
_gc: Record<string, never>,
|
|
216
|
-
ctx: ApiContext,
|
|
217
|
-
req: ApiRequest,
|
|
218
|
-
params: z.infer<typeof getUserMetadataParamsSchema>,
|
|
219
|
-
): Promise<GetUserMetadataResponse> => {
|
|
220
|
-
const authPlugin = ctx.authPlugin
|
|
221
|
-
if (!authPlugin) {
|
|
222
|
-
return { ok: false, status: 501, error: 'Auth plugin not configured' }
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
try {
|
|
226
|
-
const user = await authPlugin.getUserMetadata(params.userId)
|
|
227
|
-
return { ok: true, status: 200, data: { user } }
|
|
228
|
-
} catch (error) {
|
|
229
|
-
return {
|
|
230
|
-
ok: false,
|
|
231
|
-
status: 500,
|
|
232
|
-
error: error instanceof Error ? error.message : 'Failed to get user metadata',
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// ============================================================================
|
|
238
|
-
// Route Definitions with defineEndpoint
|
|
239
|
-
// ============================================================================
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Get current permissions (admin only)
|
|
243
|
-
* GET /permissions
|
|
244
|
-
*/
|
|
245
|
-
const getPermissions = defineEndpoint({
|
|
246
|
-
namespace: 'permissions',
|
|
247
|
-
name: 'get',
|
|
248
|
-
method: 'GET',
|
|
249
|
-
path: '/permissions',
|
|
250
|
-
responseType: 'PermissionsResponse',
|
|
251
|
-
response: {} as PermissionsResponse,
|
|
252
|
-
defaultMockData: { permissions: [] },
|
|
253
|
-
guards: ['admin'] as const,
|
|
254
|
-
handler: getPermissionsHandler,
|
|
255
|
-
})
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Update permissions (admin only)
|
|
259
|
-
* PUT /permissions
|
|
260
|
-
*/
|
|
261
|
-
const updatePermissions = defineEndpoint({
|
|
262
|
-
namespace: 'permissions',
|
|
263
|
-
name: 'update',
|
|
264
|
-
method: 'PUT',
|
|
265
|
-
path: '/permissions',
|
|
266
|
-
body: updatePermissionsBodySchema,
|
|
267
|
-
bodyType: 'UpdatePermissionsBody',
|
|
268
|
-
responseType: 'PermissionsResponse',
|
|
269
|
-
response: {} as PermissionsResponse,
|
|
270
|
-
defaultMockData: { permissions: [] },
|
|
271
|
-
guards: ['admin'] as const,
|
|
272
|
-
handler: updatePermissionsHandler,
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Search for users (admin/reviewer only)
|
|
277
|
-
* GET /users/search?q=...
|
|
278
|
-
*/
|
|
279
|
-
const searchUsers = defineEndpoint({
|
|
280
|
-
namespace: 'permissions',
|
|
281
|
-
name: 'searchUsers',
|
|
282
|
-
method: 'GET',
|
|
283
|
-
path: '/users/search',
|
|
284
|
-
params: searchUsersParamsSchema,
|
|
285
|
-
responseType: 'SearchUsersResponse',
|
|
286
|
-
response: {} as SearchUsersResponse,
|
|
287
|
-
defaultMockData: { users: [] },
|
|
288
|
-
guards: ['privileged'] as const,
|
|
289
|
-
handler: searchUsersHandler,
|
|
290
|
-
})
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* List groups (admin/reviewer only)
|
|
294
|
-
* GET /groups
|
|
295
|
-
*/
|
|
296
|
-
const listGroups = defineEndpoint({
|
|
297
|
-
namespace: 'permissions',
|
|
298
|
-
name: 'listGroups',
|
|
299
|
-
method: 'GET',
|
|
300
|
-
path: '/groups',
|
|
301
|
-
responseType: 'ListGroupsResponse',
|
|
302
|
-
response: {} as ListGroupsResponse,
|
|
303
|
-
defaultMockData: { groups: [] },
|
|
304
|
-
guards: ['privileged'] as const,
|
|
305
|
-
handler: listGroupsHandler,
|
|
306
|
-
})
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Get user metadata by ID (admin/reviewer only)
|
|
310
|
-
* GET /users/:userId
|
|
311
|
-
*/
|
|
312
|
-
const getUserMetadata = defineEndpoint({
|
|
313
|
-
namespace: 'permissions',
|
|
314
|
-
name: 'getUserMetadata',
|
|
315
|
-
method: 'GET',
|
|
316
|
-
path: '/users/:userId',
|
|
317
|
-
params: getUserMetadataParamsSchema,
|
|
318
|
-
responseType: 'GetUserMetadataResponse',
|
|
319
|
-
response: {} as GetUserMetadataResponse,
|
|
320
|
-
defaultMockData: { user: null },
|
|
321
|
-
guards: ['privileged'] as const,
|
|
322
|
-
handler: getUserMetadataHandler,
|
|
323
|
-
})
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Exported routes for router registration
|
|
327
|
-
*/
|
|
328
|
-
export const PERMISSION_ROUTES = {
|
|
329
|
-
get: getPermissions,
|
|
330
|
-
update: updatePermissions,
|
|
331
|
-
searchUsers: searchUsers,
|
|
332
|
-
listGroups: listGroups,
|
|
333
|
-
getUserMetadata: getUserMetadata,
|
|
334
|
-
} as const
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
|
|
3
|
-
import type { ApiContext, ApiRequest, ApiResponse } from './types'
|
|
4
|
-
import type { BranchContextWithSchema } from '../types'
|
|
5
|
-
import { ContentStore } from '../content-store'
|
|
6
|
-
import { defineEndpoint } from './route-builder'
|
|
7
|
-
import { ReferenceResolver } from '../reference-resolver'
|
|
8
|
-
import { parseLogicalPath } from '../paths'
|
|
9
|
-
import type { LogicalPath } from '../paths/types'
|
|
10
|
-
import { branchNameSchema } from './validators'
|
|
11
|
-
|
|
12
|
-
/** Response type for reference options */
|
|
13
|
-
export type ReferenceOptionsResponse = ApiResponse<{
|
|
14
|
-
options: Array<{
|
|
15
|
-
id: string
|
|
16
|
-
label: string
|
|
17
|
-
collection: string
|
|
18
|
-
}>
|
|
19
|
-
}>
|
|
20
|
-
|
|
21
|
-
// ============================================================================
|
|
22
|
-
// Zod Schemas for Validation
|
|
23
|
-
// ============================================================================
|
|
24
|
-
|
|
25
|
-
const getReferenceOptionsParamsSchema = z.object({
|
|
26
|
-
branch: branchNameSchema,
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
const getReferenceOptionsHandler = async (
|
|
30
|
-
gc: { branchContext: BranchContextWithSchema },
|
|
31
|
-
ctx: ApiContext,
|
|
32
|
-
req: ApiRequest,
|
|
33
|
-
_params: z.infer<typeof getReferenceOptionsParamsSchema>,
|
|
34
|
-
): Promise<ReferenceOptionsResponse> => {
|
|
35
|
-
const { branchContext } = gc
|
|
36
|
-
|
|
37
|
-
// Query parameter validation
|
|
38
|
-
const querySchema = z.object({
|
|
39
|
-
collections: z.string().min(1),
|
|
40
|
-
displayField: z.string().optional(),
|
|
41
|
-
search: z.string().optional(),
|
|
42
|
-
})
|
|
43
|
-
const queryResult = querySchema.safeParse(req.query ?? {})
|
|
44
|
-
if (!queryResult.success) {
|
|
45
|
-
return {
|
|
46
|
-
ok: false,
|
|
47
|
-
status: 400,
|
|
48
|
-
error: 'Query parameter "collections" is required',
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const collectionsParam = queryResult.data.collections
|
|
53
|
-
const displayField = queryResult.data.displayField || 'title'
|
|
54
|
-
const search = queryResult.data.search
|
|
55
|
-
|
|
56
|
-
const flatSchema = branchContext.flatSchema
|
|
57
|
-
const store = new ContentStore(branchContext.branchRoot, flatSchema)
|
|
58
|
-
|
|
59
|
-
// Get ID index (automatically loads if needed)
|
|
60
|
-
const idIndex = await store.idIndex()
|
|
61
|
-
|
|
62
|
-
// Parse and validate collections from query params
|
|
63
|
-
const rawCollections = collectionsParam
|
|
64
|
-
.split(',')
|
|
65
|
-
.map((c) => c.trim())
|
|
66
|
-
.filter(Boolean)
|
|
67
|
-
const collections: LogicalPath[] = []
|
|
68
|
-
for (const raw of rawCollections) {
|
|
69
|
-
const result = parseLogicalPath(raw)
|
|
70
|
-
if (!result.ok) {
|
|
71
|
-
return {
|
|
72
|
-
ok: false,
|
|
73
|
-
status: 400,
|
|
74
|
-
error: `Invalid collection path "${raw}": ${result.error}`,
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
collections.push(result.path)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Load reference options
|
|
81
|
-
const resolver = new ReferenceResolver(store, idIndex)
|
|
82
|
-
const options = await resolver.loadReferenceOptions(collections, displayField, search)
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
ok: true,
|
|
86
|
-
status: 200,
|
|
87
|
-
data: { options },
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// ============================================================================
|
|
92
|
-
// Route Definitions
|
|
93
|
-
// ============================================================================
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Get reference options for a field
|
|
97
|
-
* GET /:branch/reference-options
|
|
98
|
-
* Query params: collections (comma-separated), displayField, search
|
|
99
|
-
*/
|
|
100
|
-
const getReferenceOptions = defineEndpoint({
|
|
101
|
-
namespace: 'content',
|
|
102
|
-
name: 'getReferenceOptions',
|
|
103
|
-
method: 'GET',
|
|
104
|
-
path: '/:branch/reference-options',
|
|
105
|
-
params: getReferenceOptionsParamsSchema,
|
|
106
|
-
responseType: 'ReferenceOptionsResponse',
|
|
107
|
-
response: {} as ReferenceOptionsResponse,
|
|
108
|
-
defaultMockData: { options: [] },
|
|
109
|
-
guards: ['branchAccessWithSchema'] as const,
|
|
110
|
-
handler: getReferenceOptionsHandler,
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Exported routes for router registration
|
|
115
|
-
*/
|
|
116
|
-
export const REFERENCE_OPTIONS_ROUTES = {
|
|
117
|
-
get: getReferenceOptions,
|
|
118
|
-
} as const
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
|
|
3
|
-
import type { ApiContext, ApiRequest, ApiResponse } from './types'
|
|
4
|
-
import type { BranchContextWithSchema } from '../types'
|
|
5
|
-
import { ContentStore } from '../content-store'
|
|
6
|
-
import { defineEndpoint } from './route-builder'
|
|
7
|
-
import { ReferenceResolver } from '../reference-resolver'
|
|
8
|
-
import { branchNameSchema, contentIdSchema } from './validators'
|
|
9
|
-
|
|
10
|
-
export interface ResolveReferencesBody {
|
|
11
|
-
ids: string[] // ContentId strings at runtime
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/** Response type for resolved references */
|
|
15
|
-
export type ResolveReferencesResponse = ApiResponse<{
|
|
16
|
-
resolved: Record<string, unknown>
|
|
17
|
-
}>
|
|
18
|
-
|
|
19
|
-
// ============================================================================
|
|
20
|
-
// Zod Schemas for Validation
|
|
21
|
-
// ============================================================================
|
|
22
|
-
|
|
23
|
-
const resolveReferencesParamsSchema = z.object({
|
|
24
|
-
branch: branchNameSchema,
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
const resolveReferencesBodySchema = z.object({
|
|
28
|
-
ids: z.array(contentIdSchema).min(1),
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
const resolveReferencesHandler = async (
|
|
32
|
-
gc: { branchContext: BranchContextWithSchema },
|
|
33
|
-
ctx: ApiContext,
|
|
34
|
-
req: ApiRequest,
|
|
35
|
-
params: z.infer<typeof resolveReferencesParamsSchema>,
|
|
36
|
-
body: z.infer<typeof resolveReferencesBodySchema>,
|
|
37
|
-
): Promise<ResolveReferencesResponse> => {
|
|
38
|
-
const { branchContext } = gc
|
|
39
|
-
|
|
40
|
-
const { ids } = body
|
|
41
|
-
|
|
42
|
-
const flatSchema = branchContext.flatSchema
|
|
43
|
-
const store = new ContentStore(branchContext.branchRoot, flatSchema)
|
|
44
|
-
|
|
45
|
-
// Get ID index (automatically loads if needed)
|
|
46
|
-
const idIndex = await store.idIndex()
|
|
47
|
-
|
|
48
|
-
// Resolve each ID to full document
|
|
49
|
-
const resolver = new ReferenceResolver(store, idIndex)
|
|
50
|
-
|
|
51
|
-
const resolved: Record<string, unknown> = {}
|
|
52
|
-
|
|
53
|
-
for (const id of ids) {
|
|
54
|
-
try {
|
|
55
|
-
const result = await resolver.resolve(id)
|
|
56
|
-
if (result && result.exists && result.collection && result.slug) {
|
|
57
|
-
const doc = await store.read(result.collection, result.slug)
|
|
58
|
-
if (doc && doc.data) {
|
|
59
|
-
resolved[id] = {
|
|
60
|
-
id,
|
|
61
|
-
...doc.data,
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
} catch (error) {
|
|
66
|
-
// Skip failed resolutions, don't block entire request
|
|
67
|
-
console.error(`Failed to resolve reference ID ${id}:`, error)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
ok: true,
|
|
73
|
-
status: 200,
|
|
74
|
-
data: { resolved },
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// ============================================================================
|
|
79
|
-
// Route Definitions
|
|
80
|
-
// ============================================================================
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Resolve reference IDs to full document objects
|
|
84
|
-
* POST /:branch/resolve-references
|
|
85
|
-
* Body: { ids: string[] }
|
|
86
|
-
*/
|
|
87
|
-
const resolveReferences = defineEndpoint({
|
|
88
|
-
namespace: 'content',
|
|
89
|
-
name: 'resolveReferences',
|
|
90
|
-
method: 'POST',
|
|
91
|
-
path: '/:branch/resolve-references',
|
|
92
|
-
params: resolveReferencesParamsSchema,
|
|
93
|
-
body: resolveReferencesBodySchema,
|
|
94
|
-
bodyType: 'ResolveReferencesBody',
|
|
95
|
-
responseType: 'ResolveReferencesResponse',
|
|
96
|
-
response: {} as ResolveReferencesResponse,
|
|
97
|
-
defaultMockData: { resolved: {} },
|
|
98
|
-
guards: ['branchAccessWithSchema'] as const,
|
|
99
|
-
handler: resolveReferencesHandler,
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Exported routes for router registration
|
|
104
|
-
*/
|
|
105
|
-
export const RESOLVE_REFERENCES_ROUTES = {
|
|
106
|
-
post: resolveReferences,
|
|
107
|
-
} as const
|