canopycms 0.0.67-int.89 → 0.0.67-int.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -3
- package/dist/ai/generate.js +1 -27
- package/dist/ai/handler.d.ts +0 -4
- package/dist/ai/handler.js +0 -11
- package/dist/ai/index.d.ts +1 -8
- package/dist/ai/index.js +1 -8
- package/dist/ai/json-to-markdown.js +15 -58
- package/dist/ai/resolve-branch.d.ts +2 -7
- package/dist/ai/resolve-branch.js +4 -10
- package/dist/ai/strip-mdx.d.ts +5 -13
- package/dist/ai/strip-mdx.js +5 -17
- package/dist/ai/to-plain-text.d.ts +10 -28
- package/dist/ai/to-plain-text.js +10 -28
- package/dist/ai/transform-components.d.ts +2 -4
- package/dist/ai/transform-components.js +8 -19
- package/dist/ai/types.d.ts +5 -10
- package/dist/api/admin-branch-health.d.ts +4 -12
- package/dist/api/admin-branch-health.js +26 -66
- package/dist/api/admin.d.ts +4 -12
- package/dist/api/admin.js +10 -26
- package/dist/api/assets.d.ts +0 -25
- package/dist/api/assets.js +50 -91
- package/dist/api/branch-merge.d.ts +1 -1
- package/dist/api/branch-merge.js +0 -2
- package/dist/api/branch-review.d.ts +0 -8
- package/dist/api/branch-review.js +0 -13
- package/dist/api/branch-status.d.ts +0 -3
- package/dist/api/branch-status.js +8 -33
- package/dist/api/branch-withdraw.d.ts +0 -1
- package/dist/api/branch-withdraw.js +6 -9
- package/dist/api/branch.d.ts +7 -12
- package/dist/api/branch.js +10 -46
- package/dist/api/client.d.ts +71 -224
- package/dist/api/client.js +82 -233
- package/dist/api/comments.d.ts +2 -4
- package/dist/api/comments.js +0 -17
- package/dist/api/content.d.ts +0 -6
- package/dist/api/content.js +66 -142
- package/dist/api/entries-constants.d.ts +5 -9
- package/dist/api/entries-constants.js +5 -9
- package/dist/api/entries.d.ts +8 -13
- package/dist/api/entries.js +20 -51
- package/dist/api/github-sync.d.ts +2 -4
- package/dist/api/github-sync.js +4 -8
- package/dist/api/groups.d.ts +3 -0
- package/dist/api/groups.js +8 -21
- package/dist/api/guards.d.ts +4 -16
- package/dist/api/guards.js +3 -22
- package/dist/api/index.d.ts +4 -4
- package/dist/api/permissions.d.ts +2 -0
- package/dist/api/permissions.js +18 -40
- package/dist/api/reference-options.d.ts +0 -1
- package/dist/api/reference-options.js +3 -11
- package/dist/api/request-body-hash.d.ts +12 -23
- package/dist/api/request-body-hash.js +12 -23
- package/dist/api/resolve-references.d.ts +0 -1
- package/dist/api/resolve-references.js +13 -28
- package/dist/api/route-builder.d.ts +3 -7
- package/dist/api/route-builder.js +1 -1
- package/dist/api/routes.d.ts +12 -0
- package/dist/api/routes.js +47 -0
- package/dist/api/schema.d.ts +23 -33
- package/dist/api/schema.js +20 -74
- package/dist/api/settings-helpers.js +4 -5
- package/dist/api/types.d.ts +0 -5
- package/dist/api/user.js +0 -5
- package/dist/api/validators.d.ts +14 -52
- package/dist/api/validators.js +14 -52
- package/dist/assets/asset-prefixes.d.ts +4 -8
- package/dist/assets/asset-prefixes.js +4 -8
- package/dist/assets/asset-src.d.ts +5 -22
- package/dist/assets/asset-src.js +5 -21
- package/dist/assets/factory.d.ts +1 -2
- package/dist/assets/factory.js +1 -2
- package/dist/assets/finalize.d.ts +3 -1
- package/dist/assets/finalize.js +3 -1
- package/dist/assets/index.d.ts +3 -3
- package/dist/assets/index.js +1 -1
- package/dist/assets/keys.d.ts +5 -3
- package/dist/assets/keys.js +6 -3
- package/dist/assets/pipeline.d.ts +7 -5
- package/dist/assets/pipeline.js +33 -71
- package/dist/assets/sharp-loader.d.ts +20 -0
- package/dist/assets/sharp-loader.js +36 -0
- package/dist/assets/store-local.d.ts +1 -2
- package/dist/assets/store-local.js +1 -2
- package/dist/assets/store-s3.d.ts +3 -4
- package/dist/assets/svg-sanitizer.d.ts +6 -14
- package/dist/assets/svg-sanitizer.js +6 -14
- package/dist/assets/transform-directives.d.ts +4 -5
- package/dist/assets/transform-directives.js +2 -2
- package/dist/assets/transform.d.ts +25 -24
- package/dist/assets/transform.js +33 -26
- package/dist/auth/cache.d.ts +2 -3
- package/dist/auth/cache.js +2 -3
- package/dist/auth/caching-auth-plugin.d.ts +11 -22
- package/dist/auth/caching-auth-plugin.js +12 -14
- package/dist/auth/context-helpers.d.ts +6 -20
- package/dist/auth/context-helpers.js +5 -17
- package/dist/auth/file-based-auth-cache.d.ts +10 -21
- package/dist/auth/file-based-auth-cache.js +23 -51
- package/dist/auth/plugin.d.ts +29 -61
- package/dist/auth/plugin.js +10 -14
- package/dist/auth/types.d.ts +11 -20
- package/dist/authorization/branch.d.ts +30 -49
- package/dist/authorization/branch.js +16 -42
- package/dist/authorization/content.d.ts +11 -40
- package/dist/authorization/content.js +13 -45
- package/dist/authorization/groups/index.d.ts +0 -3
- package/dist/authorization/groups/index.js +0 -3
- package/dist/authorization/groups/loader.d.ts +14 -28
- package/dist/authorization/groups/loader.js +14 -38
- package/dist/authorization/groups/schema.d.ts +0 -6
- package/dist/authorization/groups/schema.js +4 -7
- package/dist/authorization/helpers.d.ts +9 -28
- package/dist/authorization/helpers.js +9 -28
- package/dist/authorization/index.d.ts +3 -25
- package/dist/authorization/index.js +3 -35
- package/dist/authorization/path.d.ts +6 -13
- package/dist/authorization/path.js +8 -25
- package/dist/authorization/permissions/index.d.ts +0 -3
- package/dist/authorization/permissions/index.js +0 -3
- package/dist/authorization/permissions/loader.d.ts +14 -27
- package/dist/authorization/permissions/loader.js +14 -32
- package/dist/authorization/permissions/schema.d.ts +1 -6
- package/dist/authorization/permissions/schema.js +6 -13
- package/dist/authorization/protected-branch.d.ts +36 -65
- package/dist/authorization/protected-branch.js +29 -41
- package/dist/authorization/settings-file-store.d.ts +38 -81
- package/dist/authorization/settings-file-store.js +38 -79
- package/dist/authorization/types.d.ts +4 -26
- package/dist/authorization/types.js +0 -6
- package/dist/authorization/validation.d.ts +1 -23
- package/dist/authorization/validation.js +1 -24
- package/dist/branch-health.d.ts +39 -67
- package/dist/branch-health.js +27 -43
- package/dist/branch-metadata-file.d.ts +16 -32
- package/dist/branch-metadata-file.js +13 -26
- package/dist/branch-metadata.d.ts +49 -80
- package/dist/branch-metadata.js +57 -87
- package/dist/branch-registry.d.ts +26 -64
- package/dist/branch-registry.js +44 -93
- package/dist/branch-schema-cache.d.ts +34 -124
- package/dist/branch-schema-cache.js +49 -155
- package/dist/branch-workspace.d.ts +5 -3
- package/dist/branch-workspace.js +19 -17
- package/dist/build/generate-ai-content.d.ts +1 -0
- package/dist/build/generate-ai-content.js +12 -25
- package/dist/build-canopy.d.ts +17 -27
- package/dist/build-canopy.js +16 -23
- package/dist/build-mode.d.ts +35 -9
- package/dist/build-mode.js +35 -11
- package/dist/cli/cli.d.ts +19 -20
- package/dist/cli/cli.js +1697 -887
- package/dist/cli/generate-ai-content.js +356 -630
- package/dist/cli/github-app-manifest.d.ts +84 -0
- package/dist/cli/github-app-manifest.js +161 -0
- package/dist/cli/init-github-app.d.ts +185 -0
- package/dist/cli/init-github-app.js +1014 -0
- package/dist/cli/init.js +102 -80
- package/dist/cli/migrate.d.ts +13 -10
- package/dist/cli/migrate.js +22 -30
- package/dist/cli/project-detect.d.ts +17 -31
- package/dist/cli/project-detect.js +32 -35
- package/dist/cli/project-root.d.ts +4 -11
- package/dist/cli/project-root.js +4 -11
- package/dist/cli/prompt.d.ts +10 -0
- package/dist/cli/prompt.js +67 -0
- package/dist/cli/sync.d.ts +0 -8
- package/dist/cli/sync.js +8 -28
- package/dist/cli/template-files/Dockerfile.cms.template +22 -25
- package/dist/cli/template-files/canopycms.config.ts.template +8 -6
- package/dist/cli/template-files/cdk-app.ts.template +48 -1
- package/dist/cli/template-files/cdk-tsconfig.json.template +41 -0
- package/dist/cli/template-files/cms-stack.ts.template +82 -19
- package/dist/cli/template-files/deploy-cms.yml.template +81 -1
- package/dist/cli/template-files/dockerignore.template +6 -0
- package/dist/cli/template-files/middleware.ts.template +15 -25
- package/dist/cli/templates.d.ts +3 -12
- package/dist/cli/templates.js +12 -8
- package/dist/client.d.ts +1 -1
- package/dist/comment-store.d.ts +32 -53
- package/dist/comment-store.js +32 -52
- package/dist/config/flatten.d.ts +0 -3
- package/dist/config/flatten.js +2 -12
- package/dist/config/helpers.js +2 -2
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.js +1 -4
- package/dist/config/schemas/collection.d.ts +0 -8
- package/dist/config/schemas/collection.js +0 -10
- package/dist/config/schemas/config.d.ts +6 -78
- package/dist/config/schemas/config.js +38 -54
- package/dist/config/schemas/field.d.ts +2 -242
- package/dist/config/schemas/field.js +9 -20
- package/dist/config/schemas/media.js +1 -1
- package/dist/config/schemas/permissions.js +0 -2
- package/dist/config/schemas/url.d.ts +5 -6
- package/dist/config/schemas/url.js +5 -6
- package/dist/config/types.d.ts +45 -33
- package/dist/config/types.js +0 -1
- package/dist/config.d.ts +1 -8
- package/dist/config.js +1 -9
- package/dist/content-id-index.d.ts +76 -188
- package/dist/content-id-index.js +79 -230
- package/dist/content-index-generation.d.ts +27 -48
- package/dist/content-index-generation.js +35 -84
- package/dist/content-index-registry.d.ts +15 -24
- package/dist/content-index-registry.js +5 -9
- package/dist/content-listing.d.ts +64 -107
- package/dist/content-listing.js +68 -118
- package/dist/content-reader.d.ts +20 -29
- package/dist/content-reader.js +15 -22
- package/dist/content-store.d.ts +210 -336
- package/dist/content-store.js +413 -657
- package/dist/content-tree.d.ts +44 -86
- package/dist/content-tree.js +26 -54
- package/dist/context.d.ts +68 -95
- package/dist/context.js +53 -72
- package/dist/dev-content-watcher.d.ts +18 -18
- package/dist/dev-content-watcher.js +41 -44
- package/dist/editor/BranchManager.d.ts +3 -6
- package/dist/editor/BranchManager.js +24 -44
- package/dist/editor/CanopyEditor.js +5 -2
- package/dist/editor/CommentsPanel.js +0 -2
- package/dist/editor/Editor.js +19 -76
- package/dist/editor/EditorAuthGate.d.ts +27 -0
- package/dist/editor/EditorAuthGate.js +140 -0
- package/dist/editor/EntryNavigator.js +0 -20
- package/dist/editor/FormRenderer.d.ts +1 -2
- package/dist/editor/FormRenderer.js +8 -23
- package/dist/editor/admin/SystemHealthPanel.js +20 -37
- package/dist/editor/admin/useSystemHealth.d.ts +2 -3
- package/dist/editor/admin/useSystemHealth.js +10 -12
- package/dist/editor/client-reference-resolver.d.ts +2 -5
- package/dist/editor/client-reference-resolver.js +2 -19
- package/dist/editor/comments/BranchComments.js +0 -4
- package/dist/editor/comments/EntryComments.js +0 -4
- package/dist/editor/comments/FieldWrapper.js +0 -4
- package/dist/editor/comments/InlineCommentThread.js +0 -2
- package/dist/editor/comments/ThreadCarousel.d.ts +0 -58
- package/dist/editor/comments/ThreadCarousel.js +0 -12
- package/dist/editor/components/EditorFooter.d.ts +0 -8
- package/dist/editor/components/EditorFooter.js +0 -5
- package/dist/editor/components/EditorHeader.d.ts +0 -31
- package/dist/editor/components/EditorHeader.js +21 -71
- package/dist/editor/components/EditorSidebar.d.ts +0 -19
- package/dist/editor/components/EditorSidebar.js +0 -16
- package/dist/editor/components/EntryCreateModal.d.ts +4 -4
- package/dist/editor/components/EntryCreateModal.js +7 -22
- package/dist/editor/components/RenameEntryModal.js +0 -4
- package/dist/editor/components/UserBadge.js +0 -10
- package/dist/editor/components/index.js +0 -2
- package/dist/editor/context/ApiClientContext.d.ts +8 -7
- package/dist/editor/context/ApiClientContext.js +39 -11
- package/dist/editor/context/AssetContext.d.ts +7 -17
- package/dist/editor/context/AssetContext.js +7 -17
- package/dist/editor/context/EditorIdentityContext.d.ts +13 -0
- package/dist/editor/context/EditorIdentityContext.js +7 -0
- package/dist/editor/context/EditorStateContext.d.ts +10 -41
- package/dist/editor/context/EditorStateContext.js +7 -23
- package/dist/editor/context/SWRProvider.d.ts +3 -6
- package/dist/editor/context/index.d.ts +1 -20
- package/dist/editor/context/index.js +1 -20
- package/dist/editor/editor-utils.d.ts +8 -47
- package/dist/editor/editor-utils.js +19 -72
- package/dist/editor/fields/BlockField.d.ts +2 -2
- package/dist/editor/fields/BlockField.js +1 -2
- package/dist/editor/fields/CodeField.d.ts +0 -1
- package/dist/editor/fields/CodeField.js +0 -1
- package/dist/editor/fields/DateTimeField.d.ts +15 -22
- package/dist/editor/fields/DateTimeField.js +17 -26
- package/dist/editor/fields/ImageField.d.ts +2 -2
- package/dist/editor/fields/ImageField.js +8 -14
- package/dist/editor/fields/InlineGroupField.d.ts +0 -1
- package/dist/editor/fields/InlineGroupField.js +0 -1
- package/dist/editor/fields/MarkdownField.d.ts +0 -1
- package/dist/editor/fields/MarkdownField.js +6 -11
- package/dist/editor/fields/MdxImageDialog.d.ts +1 -1
- package/dist/editor/fields/MdxImageDialog.js +0 -1
- package/dist/editor/fields/NumberField.d.ts +9 -19
- package/dist/editor/fields/NumberField.js +11 -22
- package/dist/editor/fields/NumberListField.d.ts +7 -10
- package/dist/editor/fields/NumberListField.js +7 -10
- package/dist/editor/fields/ObjectField.d.ts +5 -8
- package/dist/editor/fields/ObjectField.js +0 -1
- package/dist/editor/fields/ReferenceField.d.ts +1 -1
- package/dist/editor/fields/ReferenceField.js +11 -16
- package/dist/editor/fields/SelectField.d.ts +2 -2
- package/dist/editor/fields/SelectField.js +0 -1
- package/dist/editor/fields/StringListField.d.ts +0 -4
- package/dist/editor/fields/StringListField.js +4 -9
- package/dist/editor/fields/TextField.d.ts +0 -1
- package/dist/editor/fields/TextField.js +0 -1
- package/dist/editor/fields/ToggleField.d.ts +0 -1
- package/dist/editor/fields/ToggleField.js +0 -1
- package/dist/editor/fields/entry-link/EntryLinkContext.js +2 -4
- package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +0 -3
- package/dist/editor/fields/entry-link/InsertEntryLink.js +0 -4
- package/dist/editor/group-manager/ExternalGroupsTab.d.ts +0 -3
- package/dist/editor/group-manager/ExternalGroupsTab.js +0 -1
- package/dist/editor/group-manager/GroupCard.d.ts +0 -3
- package/dist/editor/group-manager/GroupForm.d.ts +0 -3
- package/dist/editor/group-manager/InternalGroupsTab.d.ts +0 -3
- package/dist/editor/group-manager/InternalGroupsTab.js +0 -2
- package/dist/editor/group-manager/MemberList.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useExternalGroupSearch.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useExternalGroupSearch.js +0 -3
- package/dist/editor/group-manager/hooks/useGroupState.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useGroupState.js +0 -5
- package/dist/editor/group-manager/hooks/useUserSearch.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useUserSearch.js +0 -3
- package/dist/editor/group-manager/index.d.ts +0 -6
- package/dist/editor/group-manager/index.js +0 -10
- package/dist/editor/group-manager/types.d.ts +2 -5
- package/dist/editor/group-manager/types.js +0 -3
- package/dist/editor/hooks/index.d.ts +6 -11
- package/dist/editor/hooks/index.js +6 -12
- package/dist/editor/hooks/useBranchActions.d.ts +0 -14
- package/dist/editor/hooks/useBranchActions.js +0 -22
- package/dist/editor/hooks/useBranchManager.d.ts +2 -48
- package/dist/editor/hooks/useBranchManager.js +4 -64
- package/dist/editor/hooks/useBranchesData.d.ts +7 -6
- package/dist/editor/hooks/useBranchesData.js +7 -6
- package/dist/editor/hooks/useCommentSystem.d.ts +0 -49
- package/dist/editor/hooks/useCommentSystem.js +1 -36
- package/dist/editor/hooks/useDraftManager.d.ts +2 -35
- package/dist/editor/hooks/useDraftManager.js +23 -64
- package/dist/editor/hooks/useEditorLayout.d.ts +0 -20
- package/dist/editor/hooks/useEditorLayout.js +0 -23
- package/dist/editor/hooks/useEntriesData.d.ts +1 -0
- package/dist/editor/hooks/useEntriesData.js +2 -3
- package/dist/editor/hooks/useEntryLinkResolution.d.ts +2 -2
- package/dist/editor/hooks/useEntryLinkResolution.js +2 -2
- package/dist/editor/hooks/useEntryManager.d.ts +2 -27
- package/dist/editor/hooks/useEntryManager.js +29 -78
- package/dist/editor/hooks/useGroupManager.d.ts +0 -21
- package/dist/editor/hooks/useGroupManager.js +0 -21
- package/dist/editor/hooks/usePermissionManager.d.ts +0 -20
- package/dist/editor/hooks/usePermissionManager.js +0 -20
- package/dist/editor/hooks/useReferenceResolution.d.ts +2 -33
- package/dist/editor/hooks/useReferenceResolution.js +1 -48
- package/dist/editor/hooks/useSchemaManager.d.ts +8 -27
- package/dist/editor/hooks/useSchemaManager.js +0 -19
- package/dist/editor/hooks/useUserContext.d.ts +2 -9
- package/dist/editor/hooks/useUserContext.js +10 -10
- package/dist/editor/hooks/useUserMetadata.d.ts +0 -2
- package/dist/editor/hooks/useUserMetadata.js +0 -3
- package/dist/editor/media/AssetCard.d.ts +0 -1
- package/dist/editor/media/AssetCard.js +1 -2
- package/dist/editor/media/CropStep.d.ts +0 -1
- package/dist/editor/media/CropStep.js +0 -1
- package/dist/editor/media/MediaLibrary.d.ts +1 -2
- package/dist/editor/media/MediaLibrary.js +1 -2
- package/dist/editor/media/MediaLibraryBody.d.ts +0 -1
- package/dist/editor/media/MediaLibraryBody.js +0 -1
- package/dist/editor/media/crop-math.d.ts +1 -1
- package/dist/editor/media/crop-math.js +1 -1
- package/dist/editor/permission-manager/GroupSelector.d.ts +0 -3
- package/dist/editor/permission-manager/PermissionEditor.d.ts +0 -4
- package/dist/editor/permission-manager/PermissionEditor.js +0 -1
- package/dist/editor/permission-manager/PermissionLevelBadge.d.ts +0 -7
- package/dist/editor/permission-manager/PermissionLevelBadge.js +0 -4
- package/dist/editor/permission-manager/PermissionTree.d.ts +0 -4
- package/dist/editor/permission-manager/UserSelector.d.ts +0 -3
- package/dist/editor/permission-manager/constants.d.ts +0 -3
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts +0 -3
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js +0 -10
- package/dist/editor/permission-manager/hooks/usePermissionTree.d.ts +0 -14
- package/dist/editor/permission-manager/hooks/usePermissionTree.js +0 -11
- package/dist/editor/permission-manager/index.d.ts +0 -7
- package/dist/editor/permission-manager/index.js +0 -16
- package/dist/editor/permission-manager/types.d.ts +2 -12
- package/dist/editor/permission-manager/types.js +0 -3
- package/dist/editor/permission-manager/utils.d.ts +0 -28
- package/dist/editor/permission-manager/utils.js +9 -23
- package/dist/editor/preview-bridge.d.ts +5 -1
- package/dist/editor/preview-bridge.js +4 -4
- package/dist/editor/schema-editor/CollectionEditor.d.ts +0 -5
- package/dist/editor/schema-editor/CollectionEditor.js +9 -31
- package/dist/editor/schema-editor/EntryTypeEditor.d.ts +0 -6
- package/dist/editor/schema-editor/EntryTypeEditor.js +3 -24
- package/dist/editor/schema-editor/index.d.ts +0 -7
- package/dist/editor/schema-editor/index.js +0 -7
- package/dist/editor/utils/env.d.ts +3 -18
- package/dist/editor/utils/env.js +6 -25
- package/dist/entry-link-resolver.d.ts +13 -35
- package/dist/entry-link-resolver.js +20 -53
- package/dist/entry-schema-registry.d.ts +20 -60
- package/dist/entry-schema-registry.js +20 -69
- package/dist/entry-schema.d.ts +118 -223
- package/dist/entry-schema.js +46 -91
- package/dist/git-manager.d.ts +101 -200
- package/dist/git-manager.js +211 -384
- package/dist/github-service.d.ts +52 -55
- package/dist/github-service.js +42 -86
- package/dist/http/handler.d.ts +6 -37
- package/dist/http/handler.js +65 -120
- package/dist/http/router.d.ts +15 -32
- package/dist/http/router.js +34 -99
- package/dist/http/types.d.ts +15 -40
- package/dist/http/types.js +3 -7
- package/dist/id.d.ts +4 -10
- package/dist/id.js +4 -10
- package/dist/index.js +6 -9
- package/dist/operating-mode/client-safe-strategy.d.ts +7 -14
- package/dist/operating-mode/client-safe-strategy.js +8 -28
- package/dist/operating-mode/client-unsafe-strategy.d.ts +6 -16
- package/dist/operating-mode/client-unsafe-strategy.js +9 -34
- package/dist/operating-mode/client.d.ts +3 -10
- package/dist/operating-mode/client.js +3 -8
- package/dist/operating-mode/deployment-name-fixtures.d.ts +14 -18
- package/dist/operating-mode/deployment-name-fixtures.js +14 -18
- package/dist/operating-mode/deployment-name.d.ts +19 -29
- package/dist/operating-mode/deployment-name.js +29 -47
- package/dist/operating-mode/index.d.ts +4 -25
- package/dist/operating-mode/index.js +9 -31
- package/dist/operating-mode/mode-env.d.ts +32 -49
- package/dist/operating-mode/mode-env.js +36 -53
- package/dist/operating-mode/types.d.ts +24 -72
- package/dist/operating-mode/types.js +1 -7
- package/dist/paths/branch-name.d.ts +30 -40
- package/dist/paths/branch-name.js +30 -40
- package/dist/paths/branch.d.ts +4 -18
- package/dist/paths/branch.js +6 -22
- package/dist/paths/index.d.ts +2 -13
- package/dist/paths/index.js +3 -23
- package/dist/paths/normalize-server.d.ts +3 -15
- package/dist/paths/normalize-server.js +3 -15
- package/dist/paths/normalize.d.ts +13 -33
- package/dist/paths/normalize.js +13 -33
- package/dist/paths/resolve.d.ts +4 -17
- package/dist/paths/resolve.js +4 -22
- package/dist/paths/types.d.ts +12 -34
- package/dist/paths/types.js +5 -7
- package/dist/paths/validation.d.ts +22 -119
- package/dist/paths/validation.js +30 -148
- package/dist/reference-resolver.d.ts +0 -13
- package/dist/reference-resolver.js +0 -18
- package/dist/resolve-canopy-user.d.ts +16 -18
- package/dist/resolve-canopy-user.js +17 -26
- package/dist/resource-generation.d.ts +16 -25
- package/dist/resource-generation.js +34 -97
- package/dist/schema/meta-loader.d.ts +2 -14
- package/dist/schema/meta-loader.js +15 -64
- package/dist/schema/resolver.d.ts +1 -4
- package/dist/schema/resolver.js +1 -6
- package/dist/schema/schema-store-types.d.ts +0 -12
- package/dist/schema/schema-store.d.ts +61 -138
- package/dist/schema/schema-store.js +85 -282
- package/dist/schema/types.d.ts +0 -4
- package/dist/server.d.ts +62 -93
- package/dist/server.js +63 -94
- package/dist/services.d.ts +23 -47
- package/dist/services.js +61 -103
- package/dist/settings-workspace.d.ts +17 -30
- package/dist/settings-workspace.js +51 -81
- package/dist/static/index.d.ts +26 -52
- package/dist/static/index.js +33 -67
- package/dist/{worker/task-queue.d.ts → task-queue/cms-task-queue.d.ts} +7 -9
- package/dist/task-queue/cms-task-queue.js +13 -0
- package/dist/task-queue/task-queue-config.d.ts +3 -0
- package/dist/{worker → task-queue}/task-queue-config.js +1 -6
- package/dist/task-queue/task-queue.d.ts +16 -22
- package/dist/task-queue/task-queue.js +20 -44
- package/dist/task-queue/types.d.ts +0 -1
- package/dist/task-queue/worker-status.d.ts +35 -0
- package/dist/task-queue/worker-status.js +40 -0
- package/dist/types.d.ts +40 -51
- package/dist/url-collision.d.ts +26 -40
- package/dist/url-collision.js +47 -63
- package/dist/url-exclusivity-fixtures.d.ts +15 -20
- package/dist/url-exclusivity-fixtures.js +14 -19
- package/dist/url-path-resolver.d.ts +8 -16
- package/dist/url-path-resolver.js +19 -29
- package/dist/user.d.ts +8 -21
- package/dist/user.js +10 -19
- package/dist/utils/async-mutex.js +4 -6
- package/dist/utils/atomic-write.d.ts +2 -11
- package/dist/utils/atomic-write.js +2 -11
- package/dist/utils/body-field.d.ts +8 -15
- package/dist/utils/body-field.js +8 -15
- package/dist/utils/content-serialize.d.ts +18 -24
- package/dist/utils/content-serialize.js +109 -160
- package/dist/utils/content-write-lock.d.ts +51 -106
- package/dist/utils/content-write-lock.js +66 -111
- package/dist/utils/debug.d.ts +7 -23
- package/dist/utils/debug.js +7 -23
- package/dist/utils/entry-url.d.ts +11 -23
- package/dist/utils/entry-url.js +11 -26
- package/dist/utils/error.d.ts +25 -90
- package/dist/utils/error.js +66 -117
- package/dist/utils/flatten-group-fields.d.ts +5 -7
- package/dist/utils/flatten-group-fields.js +5 -7
- package/dist/utils/format.d.ts +1 -5
- package/dist/utils/format.js +1 -5
- package/dist/utils/fs.d.ts +3 -4
- package/dist/utils/fs.js +3 -4
- package/dist/utils/git.d.ts +52 -83
- package/dist/utils/git.js +79 -125
- package/dist/utils/logger.d.ts +35 -50
- package/dist/utils/logger.js +35 -52
- package/dist/utils/provisioning-lock.d.ts +23 -35
- package/dist/utils/provisioning-lock.js +49 -69
- package/dist/utils/sanitize-href.d.ts +5 -10
- package/dist/utils/sanitize-href.js +8 -18
- package/dist/utils/title-field.d.ts +17 -20
- package/dist/utils/title-field.js +18 -27
- package/dist/utils/typed-filename.d.ts +20 -48
- package/dist/utils/typed-filename.js +25 -61
- package/dist/utils/url-prefix.d.ts +3 -3
- package/dist/utils/url-prefix.js +3 -3
- package/dist/validation/block-structural-keys.d.ts +16 -31
- package/dist/validation/block-structural-keys.js +19 -29
- package/dist/validation/deletion-checker.d.ts +0 -34
- package/dist/validation/deletion-checker.js +1 -43
- package/dist/validation/entry-link-validator.d.ts +6 -13
- package/dist/validation/entry-link-validator.js +4 -13
- package/dist/validation/entry-type-reference-validator.d.ts +13 -18
- package/dist/validation/entry-type-reference-validator.js +13 -18
- package/dist/validation/entry-validator.d.ts +13 -25
- package/dist/validation/entry-validator.js +15 -32
- package/dist/validation/field-traversal.d.ts +3 -30
- package/dist/validation/field-traversal.js +1 -32
- package/dist/validation/reference-validator.d.ts +5 -24
- package/dist/validation/reference-validator.js +5 -30
- package/dist/worker/cms-worker.d.ts +225 -135
- package/dist/worker/cms-worker.js +356 -226
- package/dist/worker/git-sync.d.ts +32 -133
- package/dist/worker/git-sync.js +131 -187
- package/dist/worker/github-auth.d.ts +262 -0
- package/dist/worker/github-auth.js +407 -0
- package/dist/worker/history-rewrite.d.ts +53 -66
- package/dist/worker/history-rewrite.js +54 -60
- package/dist/worker/log.d.ts +24 -41
- package/dist/worker/log.js +25 -42
- package/dist/worker/rebase.d.ts +20 -110
- package/dist/worker/rebase.js +279 -354
- package/dist/worker/task-runner.d.ts +33 -60
- package/dist/worker/task-runner.js +137 -134
- package/dist/worker/worker-context.d.ts +47 -64
- package/package.json +5 -4
- package/dist/cli/template-files/middleware-clerk.ts.template +0 -20
- package/dist/worker/task-queue-config.d.ts +0 -8
- package/dist/worker/task-queue.js +0 -19
- package/dist/worker/worker-status.d.ts +0 -47
- package/dist/worker/worker-status.js +0 -52
package/README.md
CHANGED
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
CanopyCMS is a schema-driven, branch-aware CMS for websites that store their content in GitHub repositories.
|
|
4
4
|
|
|
5
|
+
## Which documentation matches this build
|
|
6
|
+
|
|
7
|
+
This package ships code, not documentation. The guides — `docs/adopter-migration.md`,
|
|
8
|
+
`docs/deploying-to-aws.md` and the project README — live in the repository and change
|
|
9
|
+
alongside the code, so read them at the ref **your installed version was built from**, not at
|
|
10
|
+
`main`. The npm provenance attestation records that ref exactly:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
V=$(node -p "require('./node_modules/canopycms/package.json').version")
|
|
14
|
+
curl -s "https://registry.npmjs.org/-/npm/v1/attestations/canopycms@$V" | node -e '
|
|
15
|
+
let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{
|
|
16
|
+
const a=JSON.parse(s).attestations.find(x=>x.predicateType==="https://slsa.dev/provenance/v1")
|
|
17
|
+
const b=JSON.parse(Buffer.from(a.bundle.dsseEnvelope.payload,"base64")).predicate.buildDefinition
|
|
18
|
+
console.log(b.externalParameters.workflow.ref, b.resolvedDependencies[0].digest.gitCommit)
|
|
19
|
+
})'
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Then browse `https://github.com/safeinsights/canopycms/tree/<commit>/docs`.
|
|
23
|
+
|
|
24
|
+
Check this whenever a documented behaviour does not match what you observe. It matters most on
|
|
25
|
+
the `int` channel: a version like `0.0.67-int.90` is published from an integration branch that
|
|
26
|
+
has **not** merged to `main`, so `main`'s guides describe the last stable release and simply do
|
|
27
|
+
not contain the sections covering your build. A missing section reads exactly like a behaviour
|
|
28
|
+
you misunderstood, which is why it is worth resolving the ref rather than guessing. Stable
|
|
29
|
+
`X.Y.Z` builds are on `main`, at tag `vX.Y.Z`.
|
|
30
|
+
|
|
5
31
|
## What it does for you
|
|
6
32
|
|
|
7
33
|
- Lets you keep your site code and content in one repo.
|
|
@@ -644,6 +670,7 @@ to enable the interactive crop step, or `altOptional: true` for decorative image
|
|
|
644
670
|
|
|
645
671
|
For deployment, the `canopycms-cdk` package ships an `AssetSupport` construct that provisions
|
|
646
672
|
the bucket, the transform Lambda and the CloudFront behaviors. Fuller documentation — every
|
|
647
|
-
config option, the transform directive syntax, and the AWS wiring — is in the
|
|
648
|
-
|
|
649
|
-
|
|
673
|
+
config option, the transform directive syntax, and the AWS wiring — is in the project README's
|
|
674
|
+
`#media-configuration` section and in `docs/deploying-to-aws.md`. Read both at the ref this
|
|
675
|
+
build came from, not at `main` — see
|
|
676
|
+
[Which documentation matches this build](#which-documentation-matches-this-build).
|
package/dist/ai/generate.js
CHANGED
|
@@ -24,9 +24,7 @@ import { resolveEntryLinksInText } from '../entry-link-resolver.js';
|
|
|
24
24
|
export async function generateAIContent(options) {
|
|
25
25
|
const { store, flatSchema, contentRoot, config, entryLinkUrl, generatedAt, buildId } = options;
|
|
26
26
|
const files = new Map();
|
|
27
|
-
// Build content ID index for entry link resolution
|
|
28
27
|
const idIndex = await store.idIndex();
|
|
29
|
-
// Build lookup maps from flat schema
|
|
30
28
|
const collections = flatSchema.filter((item) => item.type === 'collection');
|
|
31
29
|
// Track all entries for bundle filtering
|
|
32
30
|
const allEntries = [];
|
|
@@ -34,12 +32,10 @@ export async function generateAIContent(options) {
|
|
|
34
32
|
const manifestCollections = [];
|
|
35
33
|
// Track root-level entries (entries in the content root, not in a subcollection)
|
|
36
34
|
const rootEntries = [];
|
|
37
|
-
// Process each collection
|
|
38
35
|
for (const collection of collections) {
|
|
39
36
|
// Skip the content root itself — we process its children
|
|
40
37
|
if (collection.logicalPath === contentRoot)
|
|
41
38
|
continue;
|
|
42
|
-
// Check exclusion
|
|
43
39
|
if (isCollectionExcluded(collection.logicalPath, contentRoot, config))
|
|
44
40
|
continue;
|
|
45
41
|
// Only process top-level collections and direct subcollections here
|
|
@@ -63,7 +59,6 @@ export async function generateAIContent(options) {
|
|
|
63
59
|
}
|
|
64
60
|
rootEntries.push(...rootResult.manifestEntries);
|
|
65
61
|
}
|
|
66
|
-
// Process bundles
|
|
67
62
|
const manifestBundles = [];
|
|
68
63
|
if (config?.bundles) {
|
|
69
64
|
for (const bundle of config.bundles) {
|
|
@@ -87,8 +82,6 @@ export async function generateAIContent(options) {
|
|
|
87
82
|
}
|
|
88
83
|
}
|
|
89
84
|
}
|
|
90
|
-
// Build manifest.
|
|
91
|
-
//
|
|
92
85
|
// `generated` is emitted unless the caller named an artifact but no timestamp: a build id says
|
|
93
86
|
// "this content is identified by an artifact, not by when a runner happened to build it", and a
|
|
94
87
|
// wall clock alongside it would be a claim the artifact cannot support months later. Key order
|
|
@@ -108,7 +101,6 @@ async function processCollection(store, collection, flatSchema, contentRoot, con
|
|
|
108
101
|
const entries = [];
|
|
109
102
|
const cleanPath = stripContentRoot(collection.logicalPath, contentRoot);
|
|
110
103
|
const manifestEntries = [];
|
|
111
|
-
// Read entries directly in this collection (not subcollections)
|
|
112
104
|
const listed = await store.getCollectionEntryPaths(collection.logicalPath);
|
|
113
105
|
// Filter to only entries in this exact collection (not subcollections)
|
|
114
106
|
const directEntries = listed.filter((e) => e.collection === collection.logicalPath);
|
|
@@ -116,10 +108,8 @@ async function processCollection(store, collection, flatSchema, contentRoot, con
|
|
|
116
108
|
const entryTypeName = extractEntryTypeFromFilename(path.basename(listEntry.relativePath));
|
|
117
109
|
if (!entryTypeName)
|
|
118
110
|
continue;
|
|
119
|
-
// Check entry type exclusion
|
|
120
111
|
if (config?.exclude?.entryTypes?.includes(entryTypeName))
|
|
121
112
|
continue;
|
|
122
|
-
// Find the entry type config to get schema fields
|
|
123
113
|
const entryTypeConfig = findEntryType(collection, entryTypeName);
|
|
124
114
|
if (!entryTypeConfig)
|
|
125
115
|
continue;
|
|
@@ -128,17 +118,14 @@ async function processCollection(store, collection, flatSchema, contentRoot, con
|
|
|
128
118
|
resolveReferences: false,
|
|
129
119
|
});
|
|
130
120
|
const aiEntry = docToAIEntry(doc, listEntry.slug, entryTypeName, entryTypeConfig, cleanPath);
|
|
131
|
-
// Resolve entry:ID links in body content
|
|
132
121
|
if (aiEntry.body && idIndex) {
|
|
133
122
|
aiEntry.body = resolveEntryLinksInText(aiEntry.body, idIndex, contentRoot, entryLinkUrl);
|
|
134
123
|
}
|
|
135
|
-
// Check predicate exclusion
|
|
136
124
|
if (config?.exclude?.where?.(aiEntry))
|
|
137
125
|
continue;
|
|
138
126
|
// Fold in adopter-supplied markdown (e.g. a colocated sibling artifact), once per entry
|
|
139
127
|
await runEntryTransform(aiEntry, doc.absolutePath, extractIdFromFilename(path.basename(listEntry.relativePath)), config);
|
|
140
128
|
entries.push(aiEntry);
|
|
141
|
-
// Write individual entry file
|
|
142
129
|
const entryFilePath = `${cleanPath}/${listEntry.slug}.md`;
|
|
143
130
|
const entryMarkdown = entryToMarkdown(aiEntry, config);
|
|
144
131
|
files.set(entryFilePath, entryMarkdown);
|
|
@@ -153,7 +140,6 @@ async function processCollection(store, collection, flatSchema, contentRoot, con
|
|
|
153
140
|
continue;
|
|
154
141
|
}
|
|
155
142
|
}
|
|
156
|
-
// Process subcollections
|
|
157
143
|
const subcollections = flatSchema.filter((item) => item.type === 'collection' && item.parentPath === collection.logicalPath);
|
|
158
144
|
const manifestSubcollections = [];
|
|
159
145
|
for (const sub of subcollections) {
|
|
@@ -205,7 +191,6 @@ async function processRootEntries(store, rootCollection, contentRoot, config, id
|
|
|
205
191
|
resolveReferences: false,
|
|
206
192
|
});
|
|
207
193
|
const aiEntry = docToAIEntry(doc, listEntry.slug, entryTypeName, entryTypeConfig, '');
|
|
208
|
-
// Resolve entry:ID links in body content
|
|
209
194
|
if (aiEntry.body && idIndex) {
|
|
210
195
|
aiEntry.body = resolveEntryLinksInText(aiEntry.body, idIndex, contentRoot, entryLinkUrl);
|
|
211
196
|
}
|
|
@@ -230,17 +215,12 @@ async function processRootEntries(store, rootCollection, contentRoot, config, id
|
|
|
230
215
|
}
|
|
231
216
|
return { entries, files, manifestEntries };
|
|
232
217
|
}
|
|
233
|
-
// ---------------------------------------------------------------------------
|
|
234
|
-
// Helpers
|
|
235
|
-
// ---------------------------------------------------------------------------
|
|
236
|
-
/** Strip contentRoot prefix from a logical path */
|
|
237
218
|
function stripContentRoot(logicalPath, contentRoot) {
|
|
238
219
|
if (logicalPath.startsWith(contentRoot + '/')) {
|
|
239
220
|
return logicalPath.slice(contentRoot.length + 1);
|
|
240
221
|
}
|
|
241
222
|
return logicalPath;
|
|
242
223
|
}
|
|
243
|
-
/** Check if a collection is excluded by path */
|
|
244
224
|
function isCollectionExcluded(logicalPath, contentRoot, config) {
|
|
245
225
|
if (!config?.exclude?.collections)
|
|
246
226
|
return false;
|
|
@@ -249,11 +229,9 @@ function isCollectionExcluded(logicalPath, contentRoot, config) {
|
|
|
249
229
|
// Match against clean path or full logical path
|
|
250
230
|
minimatch(cleanPath, pattern) || minimatch(logicalPath, pattern));
|
|
251
231
|
}
|
|
252
|
-
/** Find an entry type config by name within a collection */
|
|
253
232
|
function findEntryType(collection, entryTypeName) {
|
|
254
233
|
return collection.entries?.find((e) => e.name === entryTypeName);
|
|
255
234
|
}
|
|
256
|
-
/** Convert a ContentDocument to an AIEntry */
|
|
257
235
|
function docToAIEntry(doc, slug, entryTypeName, entryTypeConfig, cleanCollectionPath) {
|
|
258
236
|
return {
|
|
259
237
|
slug,
|
|
@@ -326,9 +304,8 @@ async function runEntryTransform(entry, absolutePath, contentId, config) {
|
|
|
326
304
|
console.warn(`AI content: entry transform for "${entry.slug}" (${entry.entryType}) failed:`, getErrorMessage(err));
|
|
327
305
|
}
|
|
328
306
|
}
|
|
329
|
-
/**
|
|
307
|
+
/** Filters are AND'd: an entry must satisfy every filter field that's set. */
|
|
330
308
|
function matchesBundleFilter(entry, filter, contentRoot) {
|
|
331
|
-
// Collections filter
|
|
332
309
|
if (filter.collections) {
|
|
333
310
|
const matches = filter.collections.some((pattern) => {
|
|
334
311
|
const cleanPattern = stripContentRoot(pattern, contentRoot);
|
|
@@ -339,19 +316,16 @@ function matchesBundleFilter(entry, filter, contentRoot) {
|
|
|
339
316
|
if (!matches)
|
|
340
317
|
return false;
|
|
341
318
|
}
|
|
342
|
-
// Entry types filter
|
|
343
319
|
if (filter.entryTypes) {
|
|
344
320
|
if (!filter.entryTypes.includes(entry.entryType))
|
|
345
321
|
return false;
|
|
346
322
|
}
|
|
347
|
-
// Path glob filter
|
|
348
323
|
if (filter.paths) {
|
|
349
324
|
const entryPath = entry.collection ? `${entry.collection}/${entry.slug}` : entry.slug;
|
|
350
325
|
const matches = filter.paths.some((pattern) => minimatch(entryPath, pattern));
|
|
351
326
|
if (!matches)
|
|
352
327
|
return false;
|
|
353
328
|
}
|
|
354
|
-
// Predicate filter
|
|
355
329
|
if (filter.where) {
|
|
356
330
|
if (!filter.where(entry))
|
|
357
331
|
return false;
|
package/dist/ai/handler.d.ts
CHANGED
|
@@ -21,10 +21,6 @@ export interface AIContentHandlerOptions {
|
|
|
21
21
|
_testFlatSchema?: FlatSchemaItem[];
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* Create a Next.js GET handler for serving AI content.
|
|
25
|
-
*
|
|
26
|
-
* Returns a function compatible with Next.js route handlers.
|
|
27
|
-
*
|
|
28
24
|
* Caching strategy:
|
|
29
25
|
* - Dev mode: regenerates on every request (content changes without deploys)
|
|
30
26
|
* - Prod: generates once per process lifetime (Lambda instances are recycled on deploy,
|
package/dist/ai/handler.js
CHANGED
|
@@ -16,10 +16,6 @@ import { getErrorMessage } from '../utils/error.js';
|
|
|
16
16
|
import { generateAIContent } from './generate.js';
|
|
17
17
|
import { resolveBranchRoot } from './resolve-branch.js';
|
|
18
18
|
/**
|
|
19
|
-
* Create a Next.js GET handler for serving AI content.
|
|
20
|
-
*
|
|
21
|
-
* Returns a function compatible with Next.js route handlers.
|
|
22
|
-
*
|
|
23
19
|
* Caching strategy:
|
|
24
20
|
* - Dev mode: regenerates on every request (content changes without deploys)
|
|
25
21
|
* - Prod: generates once per process lifetime (Lambda instances are recycled on deploy,
|
|
@@ -30,19 +26,15 @@ export function createAIContentHandler(options) {
|
|
|
30
26
|
const schemaCache = new BranchSchemaCache(config.mode);
|
|
31
27
|
let cachedResult = null;
|
|
32
28
|
const generate = async () => {
|
|
33
|
-
// In dev mode, always regenerate (content changes without deploys)
|
|
34
29
|
if (config.mode !== 'prod') {
|
|
35
30
|
cachedResult = null;
|
|
36
31
|
}
|
|
37
32
|
if (cachedResult)
|
|
38
33
|
return cachedResult;
|
|
39
|
-
// Resolve branch root
|
|
40
34
|
const branchRoot = await resolveBranchRoot(config);
|
|
41
35
|
const contentRootName = config.contentRoot || 'content';
|
|
42
|
-
// Load schema (use test override if provided)
|
|
43
36
|
const flatSchema = _testFlatSchema ??
|
|
44
37
|
(await schemaCache.getSchema(branchRoot, entrySchemaRegistry, contentRootName)).flatSchema;
|
|
45
|
-
// Create store and generate
|
|
46
38
|
const store = new ContentStore(branchRoot, flatSchema, { contentRootName });
|
|
47
39
|
const result = await generateAIContent({
|
|
48
40
|
store,
|
|
@@ -58,9 +50,7 @@ export function createAIContentHandler(options) {
|
|
|
58
50
|
try {
|
|
59
51
|
const { path: pathSegments } = await ctx.params;
|
|
60
52
|
const result = await generate();
|
|
61
|
-
// Join path segments to get the file key
|
|
62
53
|
const requestPath = pathSegments.join('/');
|
|
63
|
-
// Check for manifest
|
|
64
54
|
if (requestPath === 'manifest.json') {
|
|
65
55
|
return new Response(result.files.get('manifest.json'), {
|
|
66
56
|
headers: {
|
|
@@ -69,7 +59,6 @@ export function createAIContentHandler(options) {
|
|
|
69
59
|
},
|
|
70
60
|
});
|
|
71
61
|
}
|
|
72
|
-
// Check for generated file
|
|
73
62
|
const content = result.files.get(requestPath);
|
|
74
63
|
if (content) {
|
|
75
64
|
return new Response(content, {
|
package/dist/ai/index.d.ts
CHANGED
|
@@ -7,14 +7,7 @@
|
|
|
7
7
|
export { defineAIContentConfig } from './types.js';
|
|
8
8
|
export { createAIContentHandler } from './handler.js';
|
|
9
9
|
export { generateAIContent } from './generate.js';
|
|
10
|
-
/**
|
|
11
|
-
* Convert MDX/Markdown body content to plain prose text (for a search index
|
|
12
|
-
* or any other "just the words" consumer). Distinct from the AI-content
|
|
13
|
-
* pipeline above: this strips markup down to human-readable text rather
|
|
14
|
-
* than preparing MDX for model consumption. See the source JSDoc for the
|
|
15
|
-
* full pipeline and why paired custom components keep their inner text
|
|
16
|
-
* while losing their tags.
|
|
17
|
-
*/
|
|
10
|
+
/** See `to-plain-text.ts`'s module doc for the pipeline and why it differs from the AI-content path above. */
|
|
18
11
|
export { toPlainText } from './to-plain-text.js';
|
|
19
12
|
export type { AIContentConfig, ExcludeConfig, BundleConfig, BundleFilter, FieldTransformFn, FieldTransforms, ComponentProps, ComponentTransformFn, ComponentTransforms, BodyTransformFn, BodyTransforms, EntryTransformFn, EntryTransforms, EntryTransformContext, AIManifest, AIManifestCollection, AIManifestEntry, AIManifestBundle, AIEntry, AIEntryMeta, } from './types.js';
|
|
20
13
|
export type { AIContentHandlerOptions } from './handler.js';
|
package/dist/ai/index.js
CHANGED
|
@@ -7,12 +7,5 @@
|
|
|
7
7
|
export { defineAIContentConfig } from './types.js';
|
|
8
8
|
export { createAIContentHandler } from './handler.js';
|
|
9
9
|
export { generateAIContent } from './generate.js';
|
|
10
|
-
/**
|
|
11
|
-
* Convert MDX/Markdown body content to plain prose text (for a search index
|
|
12
|
-
* or any other "just the words" consumer). Distinct from the AI-content
|
|
13
|
-
* pipeline above: this strips markup down to human-readable text rather
|
|
14
|
-
* than preparing MDX for model consumption. See the source JSDoc for the
|
|
15
|
-
* full pipeline and why paired custom components keep their inner text
|
|
16
|
-
* while losing their tags.
|
|
17
|
-
*/
|
|
10
|
+
/** See `to-plain-text.ts`'s module doc for the pipeline and why it differs from the AI-content path above. */
|
|
18
11
|
export { toPlainText } from './to-plain-text.js';
|
|
@@ -15,7 +15,6 @@ import { applyComponentTransforms } from './transform-components.js';
|
|
|
15
15
|
*/
|
|
16
16
|
export function entryToMarkdown(entry, config) {
|
|
17
17
|
const parts = [];
|
|
18
|
-
// Entry header with YAML-style frontmatter
|
|
19
18
|
parts.push('---');
|
|
20
19
|
if (entry.data.title) {
|
|
21
20
|
parts.push(`title: ${yamlValue(String(entry.data.title))}`);
|
|
@@ -30,11 +29,9 @@ export function entryToMarkdown(entry, config) {
|
|
|
30
29
|
if (entry.data.title)
|
|
31
30
|
skipFields.add('title');
|
|
32
31
|
if (entry.format === 'md' || entry.format === 'mdx') {
|
|
33
|
-
// For MD/MDX: render non-body fields as metadata, then body verbatim
|
|
34
32
|
parts.push(...renderMarkdownEntry(entry, config, skipFields));
|
|
35
33
|
}
|
|
36
34
|
else {
|
|
37
|
-
// For data-only formats (JSON/YAML): full schema-driven conversion
|
|
38
35
|
parts.push(...renderJsonEntry(entry, config, skipFields));
|
|
39
36
|
}
|
|
40
37
|
// Markdown appended by an entry transform (e.g. a folded-in sibling artifact). Computed once
|
|
@@ -57,21 +54,18 @@ function renderMarkdownEntry(entry, config, skipFields) {
|
|
|
57
54
|
const value = entry.data[field.name];
|
|
58
55
|
if (value === undefined || value === null)
|
|
59
56
|
continue;
|
|
60
|
-
// Check for field transform
|
|
61
57
|
const transformed = applyFieldTransform(entry, field, value, config);
|
|
62
58
|
if (transformed !== undefined) {
|
|
63
59
|
parts.push(transformed);
|
|
64
60
|
parts.push('');
|
|
65
61
|
continue;
|
|
66
62
|
}
|
|
67
|
-
// Simple inline rendering for metadata
|
|
68
63
|
const label = field.label || field.name;
|
|
69
64
|
parts.push(`**${label}:** ${formatInlineValue(field, value)}`);
|
|
70
65
|
}
|
|
71
66
|
if (parts.length > 0) {
|
|
72
67
|
parts.push('');
|
|
73
68
|
}
|
|
74
|
-
// Append body — pipeline: stripMdxImports → componentTransforms → bodyTransforms
|
|
75
69
|
if (entry.body) {
|
|
76
70
|
let body = entry.format === 'mdx' ? stripMdxImports(entry.body) : entry.body;
|
|
77
71
|
if (config?.componentTransforms && Object.keys(config.componentTransforms).length > 0) {
|
|
@@ -108,14 +102,9 @@ function renderJsonEntry(entry, config, skipFields) {
|
|
|
108
102
|
/**
|
|
109
103
|
* Render a single field to markdown.
|
|
110
104
|
*
|
|
111
|
-
* @param field - Field configuration from schema
|
|
112
|
-
* @param value - The field's value
|
|
113
105
|
* @param depth - Heading depth (2 = ##, 3 = ###, etc.)
|
|
114
|
-
* @param entry - The parent entry (for transform lookups)
|
|
115
|
-
* @param config - AI content config (for field transforms)
|
|
116
106
|
*/
|
|
117
107
|
function renderField(field, value, depth, entry, config) {
|
|
118
|
-
// Check for field transform override
|
|
119
108
|
const transformed = applyFieldTransform(entry, field, value, config);
|
|
120
109
|
if (transformed !== undefined) {
|
|
121
110
|
return transformed;
|
|
@@ -127,7 +116,6 @@ function renderField(field, value, depth, entry, config) {
|
|
|
127
116
|
// Adopters run this output through their own formatting, so emitting the form Prettier
|
|
128
117
|
// already agrees with is what keeps a regenerated bundle diff-free.
|
|
129
118
|
const descriptionLine = 'description' in field && field.description ? `\n\n_${field.description}_` : '';
|
|
130
|
-
// Handle list fields
|
|
131
119
|
if ('list' in field && field.list && Array.isArray(value)) {
|
|
132
120
|
return renderListField(field, value, depth, label, heading, descriptionLine, entry, config);
|
|
133
121
|
}
|
|
@@ -154,7 +142,6 @@ function renderField(field, value, depth, entry, config) {
|
|
|
154
142
|
case 'block':
|
|
155
143
|
return renderBlockField(field, value, depth, heading, label, descriptionLine, entry, config);
|
|
156
144
|
default:
|
|
157
|
-
// Custom or unknown field type — render as string
|
|
158
145
|
return `${heading} ${label}${descriptionLine}\n\n${String(value)}`;
|
|
159
146
|
}
|
|
160
147
|
}
|
|
@@ -173,7 +160,6 @@ function renderListField(field, values, depth, label, heading, descriptionLine,
|
|
|
173
160
|
}
|
|
174
161
|
const isComplex = field.type === 'object' || field.type === 'block';
|
|
175
162
|
if (isComplex) {
|
|
176
|
-
// For complex types, render each item as a subsection
|
|
177
163
|
const items = values
|
|
178
164
|
.map((item, i) => {
|
|
179
165
|
const itemLabel = `${label} ${i + 1}`;
|
|
@@ -195,7 +181,6 @@ function renderListField(field, values, depth, label, heading, descriptionLine,
|
|
|
195
181
|
.filter(Boolean);
|
|
196
182
|
return `${heading} ${label}${descriptionLine}\n\n${items.join('\n\n')}`;
|
|
197
183
|
}
|
|
198
|
-
// For primitive types, render as markdown list
|
|
199
184
|
const items = values.map((v) => `- ${formatInlineValue(field, v)}`).join('\n');
|
|
200
185
|
return `${heading} ${label}${descriptionLine}\n\n${items}`;
|
|
201
186
|
}
|
|
@@ -275,9 +260,6 @@ function escapeTableCell(value) {
|
|
|
275
260
|
.replace(/\r?\n+/g, ' ')
|
|
276
261
|
.trim();
|
|
277
262
|
}
|
|
278
|
-
/**
|
|
279
|
-
* Render a select field.
|
|
280
|
-
*/
|
|
281
263
|
function renderSelectField(field, value, heading, label, descriptionLine) {
|
|
282
264
|
if (Array.isArray(value)) {
|
|
283
265
|
return `${heading} ${label}${descriptionLine}\n\n${value.map((v) => resolveSelectLabel(field, v)).join(', ')}`;
|
|
@@ -301,9 +283,6 @@ function resolveSelectLabel(field, value) {
|
|
|
301
283
|
}
|
|
302
284
|
return strValue;
|
|
303
285
|
}
|
|
304
|
-
/**
|
|
305
|
-
* Render a reference field.
|
|
306
|
-
*/
|
|
307
286
|
function renderReferenceField(value, heading, label, descriptionLine) {
|
|
308
287
|
if (Array.isArray(value)) {
|
|
309
288
|
const items = value.map((v) => `- ${formatReference(v)}`).join('\n');
|
|
@@ -311,7 +290,6 @@ function renderReferenceField(value, heading, label, descriptionLine) {
|
|
|
311
290
|
}
|
|
312
291
|
return `${heading} ${label}${descriptionLine}\n\n${formatReference(value)}`;
|
|
313
292
|
}
|
|
314
|
-
/** True for a plain object (not null, not an array) with a string `src`. */
|
|
315
293
|
function isImageValueLike(value) {
|
|
316
294
|
return (typeof value === 'object' &&
|
|
317
295
|
value !== null &&
|
|
@@ -319,18 +297,11 @@ function isImageValueLike(value) {
|
|
|
319
297
|
typeof value.src === 'string');
|
|
320
298
|
}
|
|
321
299
|
/**
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
* backslash
|
|
327
|
-
* bracket from it is a non-issue, and stripping sidesteps a real composability
|
|
328
|
-
* bug backslash-escaping would have - `renderObjectListTable`'s
|
|
329
|
-
* `escapeTableCell` blindly DOUBLES every backslash in a cell's final text
|
|
330
|
-
* (to protect its own `|`-splitting), which would silently unescape a
|
|
331
|
-
* `\[`/`\]` produced here the moment this markdown lands in a table cell
|
|
332
|
-
* (formatCellValue's image case, below). Newlines collapse to spaces for the
|
|
333
|
-
* same "can't break out of the link-text span" reason.
|
|
300
|
+
* Sanitizes `alt` for the `[...]` span of ``: unescaped, a crafted alt like
|
|
301
|
+
* `x](/a) [pwn](https://evil.com)` injects a second attacker-chosen link/image. Strips
|
|
302
|
+
* (rather than escapes) `[`, `]`, backslash, and newlines — losing a stray bracket from
|
|
303
|
+
* descriptive text is harmless, and escaping would break under `escapeTableCell`'s blind
|
|
304
|
+
* backslash-doubling once this lands in a table cell (formatCellValue's image case).
|
|
334
305
|
*/
|
|
335
306
|
function sanitizeMarkdownAltText(text) {
|
|
336
307
|
return text
|
|
@@ -339,13 +310,11 @@ function sanitizeMarkdownAltText(text) {
|
|
|
339
310
|
.trim();
|
|
340
311
|
}
|
|
341
312
|
/**
|
|
342
|
-
* Percent-
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
* `sanitizeMarkdownAltText` above - it survives `escapeTableCell`'s blind
|
|
348
|
-
* backslash-doubling unchanged when this lands in a table cell.
|
|
313
|
+
* Percent-encodes the characters that would break a bare markdown link destination
|
|
314
|
+
* `(src)`: `)` closes it early, a space or `(` confuses where it ends. Percent-encoding
|
|
315
|
+
* (not `<...>` wrapping or backslash-escaping) introduces no backslash, so — like
|
|
316
|
+
* `sanitizeMarkdownAltText` above — it survives `escapeTableCell`'s blind backslash-doubling
|
|
317
|
+
* in a table cell.
|
|
349
318
|
*/
|
|
350
319
|
function encodeMarkdownLinkDestination(src) {
|
|
351
320
|
return src
|
|
@@ -355,14 +324,11 @@ function encodeMarkdownLinkDestination(src) {
|
|
|
355
324
|
.replace(/\)/g, '%29');
|
|
356
325
|
}
|
|
357
326
|
/**
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
* `
|
|
361
|
-
* `
|
|
362
|
-
*
|
|
363
|
-
* destination. Malformed values (not a `{ src, alt }`-shaped object — e.g. a
|
|
364
|
-
* legacy bare URL string) degrade to a plain string, matching how neighboring
|
|
365
|
-
* field serializers (e.g. renderObjectField, formatReference) handle
|
|
327
|
+
* Formats an `image` field as ``, using `value.alt` when non-empty else
|
|
328
|
+
* `altFallback`. Both are sanitized (see `sanitizeMarkdownAltText` /
|
|
329
|
+
* `encodeMarkdownLinkDestination`) since `alt` is free text and `src` may contain
|
|
330
|
+
* link-breaking characters. A malformed value (not `{ src, alt }`, e.g. a legacy bare URL
|
|
331
|
+
* string) degrades to a plain string, matching other field serializers' handling of
|
|
366
332
|
* unexpected shapes.
|
|
367
333
|
*/
|
|
368
334
|
function formatImageMarkdown(value, altFallback) {
|
|
@@ -373,7 +339,6 @@ function formatImageMarkdown(value, altFallback) {
|
|
|
373
339
|
return `})`;
|
|
374
340
|
}
|
|
375
341
|
/**
|
|
376
|
-
* Format a single reference value.
|
|
377
342
|
* References may be resolved (objects with data) or unresolved (string IDs).
|
|
378
343
|
*/
|
|
379
344
|
function formatReference(value) {
|
|
@@ -387,9 +352,6 @@ function formatReference(value) {
|
|
|
387
352
|
// Unresolved — raw ID or string
|
|
388
353
|
return String(value);
|
|
389
354
|
}
|
|
390
|
-
/**
|
|
391
|
-
* Render an object field with nested fields.
|
|
392
|
-
*/
|
|
393
355
|
function renderObjectField(field, value, depth, heading, label, descriptionLine, entry, config) {
|
|
394
356
|
if (typeof value !== 'object' || value === null) {
|
|
395
357
|
return `${heading} ${label}${descriptionLine}\n\n${String(value)}`;
|
|
@@ -444,10 +406,6 @@ function renderBlockField(field, value, depth, heading, label, descriptionLine,
|
|
|
444
406
|
return '';
|
|
445
407
|
return `${heading} ${label}${descriptionLine}\n\n${items.join('\n\n')}`;
|
|
446
408
|
}
|
|
447
|
-
/**
|
|
448
|
-
* Apply a field transform if one exists for this entry type + field name.
|
|
449
|
-
* Returns undefined if no transform applies.
|
|
450
|
-
*/
|
|
451
409
|
function applyFieldTransform(entry, field, value, config) {
|
|
452
410
|
if (!config?.fieldTransforms)
|
|
453
411
|
return undefined;
|
|
@@ -478,7 +436,6 @@ function formatInlineValue(field, value) {
|
|
|
478
436
|
return String(value);
|
|
479
437
|
}
|
|
480
438
|
/**
|
|
481
|
-
* Escape a value for YAML frontmatter.
|
|
482
439
|
* Wraps in quotes if value contains special characters.
|
|
483
440
|
*/
|
|
484
441
|
function yamlValue(value) {
|
|
@@ -6,12 +6,7 @@ import type { CanopyConfig } from '../config/index.js';
|
|
|
6
6
|
/**
|
|
7
7
|
* Resolve the branch root directory for reading content.
|
|
8
8
|
*
|
|
9
|
-
* -
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* Branch resolution priority (mirrors createActiveBranchDetector in services.ts):
|
|
13
|
-
* 1. Explicit `defaultActiveBranch` in config
|
|
14
|
-
* 2. In dev mode, auto-detect from git HEAD
|
|
15
|
-
* 3. Fall back to `defaultBaseBranch` or 'main'
|
|
9
|
+
* The active-branch priority below mirrors `createActiveBranchDetector` in services.ts —
|
|
10
|
+
* keep the two in sync if either changes.
|
|
16
11
|
*/
|
|
17
12
|
export declare function resolveBranchRoot(config: CanopyConfig): Promise<string>;
|
|
@@ -3,22 +3,16 @@
|
|
|
3
3
|
* Used by both the route handler and build utility.
|
|
4
4
|
*/
|
|
5
5
|
import { loadOrCreateBranchContext } from '../branch-workspace.js';
|
|
6
|
-
import {
|
|
6
|
+
import { readsFromCheckout } from '../build-mode.js';
|
|
7
7
|
import { detectHeadBranch } from '../utils/git.js';
|
|
8
8
|
/**
|
|
9
9
|
* Resolve the branch root directory for reading content.
|
|
10
10
|
*
|
|
11
|
-
* -
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* Branch resolution priority (mirrors createActiveBranchDetector in services.ts):
|
|
15
|
-
* 1. Explicit `defaultActiveBranch` in config
|
|
16
|
-
* 2. In dev mode, auto-detect from git HEAD
|
|
17
|
-
* 3. Fall back to `defaultBaseBranch` or 'main'
|
|
11
|
+
* The active-branch priority below mirrors `createActiveBranchDetector` in services.ts —
|
|
12
|
+
* keep the two in sync if either changes.
|
|
18
13
|
*/
|
|
19
14
|
export async function resolveBranchRoot(config) {
|
|
20
|
-
|
|
21
|
-
if (isDeployedStatic(config)) {
|
|
15
|
+
if (readsFromCheckout(config)) {
|
|
22
16
|
return process.cwd();
|
|
23
17
|
}
|
|
24
18
|
let activeBranch;
|
package/dist/ai/strip-mdx.d.ts
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Strip MDX-specific syntax from body content for AI consumption.
|
|
3
3
|
*
|
|
4
|
-
* Removes import/export statements (pure code, no content value)
|
|
5
|
-
* Leaves JSX components intact — many carry semantic data in props
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Handles:
|
|
10
|
-
* - Single-line and multi-line import/export statements (brace tracking)
|
|
11
|
-
* - Fenced code blocks (``` / ~~~) are preserved — imports/exports inside
|
|
12
|
-
* code blocks are not stripped
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Remove import/export statements and collapse resulting blank lines.
|
|
16
|
-
* Preserves content inside fenced code blocks.
|
|
4
|
+
* Removes import/export statements (pure code, no content value) and collapses the blank
|
|
5
|
+
* lines left behind. Leaves JSX components intact — many carry semantic data in props (e.g.,
|
|
6
|
+
* <MatrixRow label="..." matches="1, 3" />) that would be lost if stripped; AI models handle
|
|
7
|
+
* JSX props well for RAG. Handles both single-line and multi-line (brace-tracked) statements;
|
|
8
|
+
* fenced code blocks (``` / ~~~) are preserved untouched.
|
|
17
9
|
*/
|
|
18
10
|
export declare function stripMdxImports(body: string): string;
|
package/dist/ai/strip-mdx.js
CHANGED
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Strip MDX-specific syntax from body content for AI consumption.
|
|
3
3
|
*
|
|
4
|
-
* Removes import/export statements (pure code, no content value)
|
|
5
|
-
* Leaves JSX components intact — many carry semantic data in props
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Handles:
|
|
10
|
-
* - Single-line and multi-line import/export statements (brace tracking)
|
|
11
|
-
* - Fenced code blocks (``` / ~~~) are preserved — imports/exports inside
|
|
12
|
-
* code blocks are not stripped
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Remove import/export statements and collapse resulting blank lines.
|
|
16
|
-
* Preserves content inside fenced code blocks.
|
|
4
|
+
* Removes import/export statements (pure code, no content value) and collapses the blank
|
|
5
|
+
* lines left behind. Leaves JSX components intact — many carry semantic data in props (e.g.,
|
|
6
|
+
* <MatrixRow label="..." matches="1, 3" />) that would be lost if stripped; AI models handle
|
|
7
|
+
* JSX props well for RAG. Handles both single-line and multi-line (brace-tracked) statements;
|
|
8
|
+
* fenced code blocks (``` / ~~~) are preserved untouched.
|
|
17
9
|
*/
|
|
18
10
|
export function stripMdxImports(body) {
|
|
19
11
|
const lines = body.split('\n');
|
|
@@ -23,13 +15,11 @@ export function stripMdxImports(body) {
|
|
|
23
15
|
let depth = 0;
|
|
24
16
|
for (const line of lines) {
|
|
25
17
|
const trimmed = line.trim();
|
|
26
|
-
// Track fenced code blocks (``` or ~~~)
|
|
27
18
|
if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {
|
|
28
19
|
inCodeBlock = !inCodeBlock;
|
|
29
20
|
result.push(line);
|
|
30
21
|
continue;
|
|
31
22
|
}
|
|
32
|
-
// Inside code blocks: keep everything
|
|
33
23
|
if (inCodeBlock) {
|
|
34
24
|
result.push(line);
|
|
35
25
|
continue;
|
|
@@ -48,9 +38,7 @@ export function stripMdxImports(body) {
|
|
|
48
38
|
}
|
|
49
39
|
continue;
|
|
50
40
|
}
|
|
51
|
-
// Detect top-level import/export statements
|
|
52
41
|
if (/^import\s/.test(trimmed) || /^export\s/.test(trimmed)) {
|
|
53
|
-
// Count open/close braces to detect multi-line statements
|
|
54
42
|
depth = 0;
|
|
55
43
|
for (const ch of line) {
|
|
56
44
|
if (ch === '{' || ch === '(')
|