canopycms 0.0.67-int.90 → 0.0.67
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 +2 -8
- 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 +7 -44
- 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 +3 -2
- package/dist/assets/pipeline.js +22 -56
- package/dist/assets/sharp-loader.d.ts +2 -10
- package/dist/assets/sharp-loader.js +2 -10
- 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 +3 -4
- package/dist/assets/transform-directives.js +1 -1
- package/dist/assets/transform.d.ts +19 -30
- package/dist/assets/transform.js +18 -31
- 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 +9 -13
- 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 +4 -4
- package/dist/branch-workspace.js +15 -19
- 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 +25 -27
- package/dist/build-mode.js +25 -29
- package/dist/cli/cli.d.ts +15 -26
- package/dist/cli/cli.js +601 -978
- package/dist/cli/generate-ai-content.js +351 -628
- 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 +110 -444
- package/dist/cli/init-github-app.js +236 -773
- package/dist/cli/init.js +39 -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 +31 -42
- 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/middleware.ts.template +15 -29
- package/dist/cli/templates.d.ts +2 -12
- package/dist/cli/templates.js +4 -4
- 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 +10 -18
- 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 +67 -94
- 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 +34 -75
- package/dist/github-service.js +37 -91
- 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 -54
- package/dist/operating-mode/mode-env.js +36 -58
- 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 +55 -98
- 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 +60 -147
- 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 +172 -232
- package/dist/worker/cms-worker.js +241 -333
- package/dist/worker/git-sync.d.ts +32 -133
- package/dist/worker/git-sync.js +129 -191
- package/dist/worker/github-auth.d.ts +13 -19
- package/dist/worker/github-auth.js +13 -19
- 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 +32 -66
- package/dist/worker/task-runner.js +126 -162
- package/dist/worker/worker-context.d.ts +41 -81
- package/package.json +4 -4
- package/dist/cli/template-files/middleware-clerk.ts.template +0 -37
- 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
|
@@ -3,34 +3,23 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
/**
|
|
4
4
|
* EntryTypeEditor - Modal for creating/editing entry types within a collection.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* - format: Content format (md, mdx, json, yaml)
|
|
10
|
-
* - fields: Schema registry key for field definitions
|
|
11
|
-
* - default: Whether this is the default type for new items
|
|
12
|
-
* - maxItems: Optional limit on number of items (1 = singleton-like)
|
|
6
|
+
* An entry type has a name (machine-readable id), label, format (md/mdx/json/
|
|
7
|
+
* yaml), schema (registry key for field definitions), a default flag, and an
|
|
8
|
+
* optional maxItems limit (1 behaves like a singleton).
|
|
13
9
|
*/
|
|
14
10
|
import { useState, useCallback, useEffect } from 'react';
|
|
15
11
|
import { Modal, Stack, TextInput, Select, Switch, NumberInput, Group, Button, Text, Alert, Tooltip, } from '@mantine/core';
|
|
16
12
|
import { IconAlertCircle, IconLock } from '@tabler/icons-react';
|
|
17
|
-
// ============================================================================
|
|
18
|
-
// Constants
|
|
19
|
-
// ============================================================================
|
|
20
13
|
const FORMAT_OPTIONS = [
|
|
21
14
|
{ value: 'json', label: 'JSON' },
|
|
22
15
|
{ value: 'yaml', label: 'YAML' },
|
|
23
16
|
{ value: 'md', label: 'Markdown' },
|
|
24
17
|
{ value: 'mdx', label: 'MDX' },
|
|
25
18
|
];
|
|
26
|
-
// ============================================================================
|
|
27
|
-
// Component
|
|
28
|
-
// ============================================================================
|
|
29
19
|
export function EntryTypeEditor({ isOpen, editingEntryType, availableSchemas, existingEntryTypeNames = [], onSave, onClose, isSaving = false, error = null, }) {
|
|
30
20
|
const isEditMode = editingEntryType !== null;
|
|
31
21
|
const usageCount = editingEntryType?.usageCount ?? 0;
|
|
32
22
|
const isLocked = isEditMode && usageCount > 0;
|
|
33
|
-
// Form state
|
|
34
23
|
const [formData, setFormData] = useState({
|
|
35
24
|
name: '',
|
|
36
25
|
label: '',
|
|
@@ -39,9 +28,7 @@ export function EntryTypeEditor({ isOpen, editingEntryType, availableSchemas, ex
|
|
|
39
28
|
default: false,
|
|
40
29
|
maxItems: undefined,
|
|
41
30
|
});
|
|
42
|
-
// Local validation error
|
|
43
31
|
const [validationError, setValidationError] = useState(null);
|
|
44
|
-
// Reset form when modal opens or editing item changes
|
|
45
32
|
/* eslint-disable react-hooks/set-state-in-effect -- intentional: sync form state from props on open */
|
|
46
33
|
useEffect(() => {
|
|
47
34
|
if (isOpen) {
|
|
@@ -69,12 +56,10 @@ export function EntryTypeEditor({ isOpen, editingEntryType, availableSchemas, ex
|
|
|
69
56
|
}
|
|
70
57
|
}, [isOpen, editingEntryType, availableSchemas]);
|
|
71
58
|
/* eslint-enable react-hooks/set-state-in-effect */
|
|
72
|
-
// Update a form field
|
|
73
59
|
const updateField = useCallback((field, value) => {
|
|
74
60
|
setFormData((prev) => ({ ...prev, [field]: value }));
|
|
75
61
|
setValidationError(null);
|
|
76
62
|
}, []);
|
|
77
|
-
// Validate form
|
|
78
63
|
const validate = useCallback(() => {
|
|
79
64
|
if (!isEditMode && !formData.name.trim()) {
|
|
80
65
|
setValidationError('Name is required');
|
|
@@ -88,7 +73,6 @@ export function EntryTypeEditor({ isOpen, editingEntryType, availableSchemas, ex
|
|
|
88
73
|
setValidationError('Name must be 64 characters or less');
|
|
89
74
|
return false;
|
|
90
75
|
}
|
|
91
|
-
// Check for duplicate names (only in create mode)
|
|
92
76
|
if (!isEditMode && existingEntryTypeNames.includes(formData.name.trim())) {
|
|
93
77
|
setValidationError('Entry type with this name already exists in this collection');
|
|
94
78
|
return false;
|
|
@@ -99,12 +83,10 @@ export function EntryTypeEditor({ isOpen, editingEntryType, availableSchemas, ex
|
|
|
99
83
|
}
|
|
100
84
|
return true;
|
|
101
85
|
}, [formData, isEditMode, existingEntryTypeNames]);
|
|
102
|
-
// Handle save
|
|
103
86
|
const handleSave = useCallback(() => {
|
|
104
87
|
if (!validate())
|
|
105
88
|
return;
|
|
106
89
|
if (isEditMode) {
|
|
107
|
-
// Only include changed fields for update
|
|
108
90
|
const updates = {};
|
|
109
91
|
if (formData.label !== (editingEntryType?.label || '')) {
|
|
110
92
|
updates.label = formData.label || undefined;
|
|
@@ -124,7 +106,6 @@ export function EntryTypeEditor({ isOpen, editingEntryType, availableSchemas, ex
|
|
|
124
106
|
onSave(updates, false);
|
|
125
107
|
}
|
|
126
108
|
else {
|
|
127
|
-
// Create new entry type
|
|
128
109
|
const createData = {
|
|
129
110
|
name: formData.name.trim(),
|
|
130
111
|
format: formData.format,
|
|
@@ -142,7 +123,6 @@ export function EntryTypeEditor({ isOpen, editingEntryType, availableSchemas, ex
|
|
|
142
123
|
onSave(createData, true);
|
|
143
124
|
}
|
|
144
125
|
}, [formData, isEditMode, editingEntryType, validate, onSave]);
|
|
145
|
-
// Schema options for select
|
|
146
126
|
const schemaOptions = availableSchemas.map((key) => ({
|
|
147
127
|
value: key,
|
|
148
128
|
label: key,
|
|
@@ -158,4 +138,3 @@ export function EntryTypeEditor({ isOpen, editingEntryType, availableSchemas, ex
|
|
|
158
138
|
? `Locked (${usageCount} ${usageCount === 1 ? 'entry' : 'entries'} exist)`
|
|
159
139
|
: 'Field definitions for this entry type', data: schemaOptions, value: formData.schema, onChange: (value) => value && updateField('schema', value), searchable: true, required: true, placeholder: "Select a schema", disabled: isLocked, rightSection: isLocked ? _jsx(IconLock, { size: 14 }) : undefined }) }), _jsx(Switch, { label: "Default entry type", description: "Use this type when adding new items to the collection", checked: formData.default, onChange: (e) => updateField('default', e.currentTarget.checked) }), _jsx(NumberInput, { label: "Max Items", description: "Limit number of items (leave empty for unlimited, use 1 for singleton-like behavior)", placeholder: "Unlimited", value: formData.maxItems ?? '', onChange: (value) => updateField('maxItems', typeof value === 'number' ? value : undefined), min: 1, allowNegative: false, allowDecimal: false }), formData.maxItems === 1 && (_jsx(Text, { size: "xs", c: "dimmed", children: "With maxItems=1, this entry type behaves like a singleton (e.g., homepage, settings)" })), _jsxs(Group, { justify: "flex-end", gap: "sm", mt: "md", children: [_jsx(Button, { variant: "subtle", onClick: onClose, disabled: isSaving, children: "Cancel" }), _jsx(Button, { onClick: handleSave, loading: isSaving, children: isEditMode ? 'Save Changes' : 'Add Entry Type' })] })] }) }));
|
|
160
140
|
}
|
|
161
|
-
export default EntryTypeEditor;
|
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Schema Editor Components
|
|
3
|
-
*
|
|
4
|
-
* UI components for managing collection structure:
|
|
5
|
-
* - CollectionEditor: Create/edit collections and their entry types
|
|
6
|
-
* - EntryTypeEditor: Create/edit individual entry types
|
|
7
|
-
*/
|
|
8
1
|
export { CollectionEditor, type CollectionEditorProps, type ExistingCollection, type ExistingEntryType, } from './CollectionEditor.js';
|
|
9
2
|
export { EntryTypeEditor, type EntryTypeEditorProps, type EntryTypeFormData, } from './EntryTypeEditor.js';
|
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Schema Editor Components
|
|
3
|
-
*
|
|
4
|
-
* UI components for managing collection structure:
|
|
5
|
-
* - CollectionEditor: Create/edit collections and their entry types
|
|
6
|
-
* - EntryTypeEditor: Create/edit individual entry types
|
|
7
|
-
*/
|
|
8
1
|
export { CollectionEditor, } from './CollectionEditor.js';
|
|
9
2
|
export { EntryTypeEditor, } from './EntryTypeEditor.js';
|
|
@@ -1,22 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Playwright and other E2E frameworks often set specific globals.
|
|
4
|
-
*/
|
|
5
|
-
export declare function isTestEnvironment(): boolean;
|
|
6
|
-
/**
|
|
7
|
-
* Get notification duration based on environment.
|
|
8
|
-
* Tests get longer durations to be more reliable.
|
|
9
|
-
*
|
|
10
|
-
* @param defaultMs - Default duration in milliseconds for production (default: 4000)
|
|
11
|
-
* @returns Duration in milliseconds (15000ms for tests, defaultMs for production)
|
|
2
|
+
* Notification duration, longer in tests for reliability.
|
|
12
3
|
*
|
|
13
|
-
* @
|
|
14
|
-
*
|
|
15
|
-
* notifications.show({
|
|
16
|
-
* message: 'Saved',
|
|
17
|
-
* color: 'green',
|
|
18
|
-
* autoClose: getNotificationDuration(4000), // 4s in production, 15s in tests
|
|
19
|
-
* })
|
|
20
|
-
* ```
|
|
4
|
+
* @param defaultMs - Default in milliseconds for production (default: 4000)
|
|
5
|
+
* @returns 15000ms in tests, defaultMs otherwise
|
|
21
6
|
*/
|
|
22
7
|
export declare function getNotificationDuration(defaultMs?: number): number;
|
package/dist/editor/utils/env.js
CHANGED
|
@@ -1,36 +1,17 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
* Playwright and other E2E frameworks often set specific globals.
|
|
4
|
-
*/
|
|
5
|
-
export function isTestEnvironment() {
|
|
1
|
+
/** True when running in a test environment (Playwright, Cypress, or an E2E flag sets these globals). */
|
|
2
|
+
function isTestEnvironment() {
|
|
6
3
|
if (typeof window === 'undefined')
|
|
7
4
|
return false;
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
// Playwright sets window.playwright
|
|
11
|
-
'playwright' in window ||
|
|
12
|
-
// Cypress sets window.Cypress
|
|
5
|
+
return ('playwright' in window ||
|
|
13
6
|
'Cypress' in window ||
|
|
14
|
-
// Check if running in test mode via env variable (set by test runner)
|
|
15
7
|
window.__E2E_TEST__ === true ||
|
|
16
|
-
// Some test frameworks set navigator.webdriver
|
|
17
8
|
navigator.webdriver === true);
|
|
18
9
|
}
|
|
19
10
|
/**
|
|
20
|
-
*
|
|
21
|
-
* Tests get longer durations to be more reliable.
|
|
22
|
-
*
|
|
23
|
-
* @param defaultMs - Default duration in milliseconds for production (default: 4000)
|
|
24
|
-
* @returns Duration in milliseconds (15000ms for tests, defaultMs for production)
|
|
11
|
+
* Notification duration, longer in tests for reliability.
|
|
25
12
|
*
|
|
26
|
-
* @
|
|
27
|
-
*
|
|
28
|
-
* notifications.show({
|
|
29
|
-
* message: 'Saved',
|
|
30
|
-
* color: 'green',
|
|
31
|
-
* autoClose: getNotificationDuration(4000), // 4s in production, 15s in tests
|
|
32
|
-
* })
|
|
33
|
-
* ```
|
|
13
|
+
* @param defaultMs - Default in milliseconds for production (default: 4000)
|
|
14
|
+
* @returns 15000ms in tests, defaultMs otherwise
|
|
34
15
|
*/
|
|
35
16
|
export function getNotificationDuration(defaultMs = 4000) {
|
|
36
17
|
return isTestEnvironment() ? 15000 : defaultMs;
|
|
@@ -1,24 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Entry link resolution for body content
|
|
2
|
+
* Entry link resolution for body content: `entry:CONTENT_ID` tokens in markdown/MDX
|
|
3
|
+
* text resolve to URL paths, extending the reference-by-ID pattern from structured
|
|
4
|
+
* reference fields to inline body links.
|
|
3
5
|
*
|
|
4
|
-
* Resolves `entry:CONTENT_ID` patterns in markdown/MDX body text to actual URL paths.
|
|
5
|
-
* This extends the reference-by-ID pattern (already used for structured reference fields)
|
|
6
|
-
* to inline links in content bodies.
|
|
7
|
-
*
|
|
8
|
-
* Syntax:
|
|
9
6
|
* [Link text](entry:vh2WdhwAFiSL)
|
|
10
7
|
* [Link text](entry:vh2WdhwAFiSL#section-heading)
|
|
11
8
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* Fenced code blocks and inline code spans are skipped, so code examples are never
|
|
10
|
+
* rewritten.
|
|
14
11
|
*/
|
|
15
12
|
import type { ContentIdIndex, IdLocation } from './content-id-index.js';
|
|
16
|
-
/**
|
|
17
|
-
* Base58 alphabet pattern (matches content IDs).
|
|
18
|
-
* Excludes ambiguous characters: 0, O, I, l
|
|
19
|
-
*/
|
|
20
|
-
/** Base58 alphabet character class (excludes ambiguous: 0, O, I, l). */
|
|
21
|
-
export declare const BASE58_CHAR = "[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]";
|
|
22
13
|
/**
|
|
23
14
|
* Pattern matching `entry:CONTENT_ID` with optional anchor fragment.
|
|
24
15
|
* Uses the `g` flag — safe to share when used only with `.replace()`.
|
|
@@ -30,36 +21,23 @@ export type EntryLinkUrlResolver = (entry: {
|
|
|
30
21
|
slug: string;
|
|
31
22
|
id: string;
|
|
32
23
|
}) => string;
|
|
33
|
-
/**
|
|
34
|
-
* Compute a URL path from an entry's location in the content tree.
|
|
35
|
-
* Delegates to the shared `computeEntryUrl` utility.
|
|
36
|
-
*/
|
|
24
|
+
/** URL path for an entry's location in the content tree; delegates to `computeEntryUrl`. */
|
|
37
25
|
export declare function resolveEntryUrl(location: Pick<IdLocation, 'collection' | 'slug'>, contentRoot: string): string;
|
|
38
26
|
/**
|
|
39
|
-
* Replace `entry:CONTENT_ID`
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* code examples that mention the entry: syntax.
|
|
43
|
-
*
|
|
44
|
-
* Missing IDs are replaced with "#" (dead link) and logged as warnings.
|
|
45
|
-
* Anchor fragments are preserved: entry:ID#heading => /path#heading
|
|
27
|
+
* Replace `entry:CONTENT_ID` tokens with resolved URL paths, skipping code blocks and
|
|
28
|
+
* spans so examples mentioning the syntax survive. A missing ID becomes "#" (dead link)
|
|
29
|
+
* plus a warning; an anchor fragment is preserved (`entry:ID#heading` => `/path#heading`).
|
|
46
30
|
*/
|
|
47
31
|
export declare function resolveEntryLinksInText(text: string, idIndex: ContentIdIndex, contentRoot: string, customResolver?: EntryLinkUrlResolver): string;
|
|
48
32
|
/** Quick-check pattern for early bail-out (no `g` flag, safe for `.test()`). */
|
|
49
33
|
export declare const ENTRY_LINK_QUICK_CHECK: RegExp;
|
|
50
34
|
/**
|
|
51
|
-
* Recursively resolve entry:ID
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* JSON entries where markdown fields live inside nested objects (e.g., hero.body).
|
|
55
|
-
*
|
|
56
|
-
* Returns the same object reference if nothing changed (structural sharing).
|
|
35
|
+
* Recursively resolve `entry:ID` tokens in every string of a data structure — nested
|
|
36
|
+
* objects and arrays included, since JSON entries keep markdown fields inside nested
|
|
37
|
+
* objects (e.g. hero.body). Returns the same reference when nothing changed.
|
|
57
38
|
*/
|
|
58
39
|
export declare function resolveEntryLinksInData(data: unknown, idIndex: ContentIdIndex, contentRoot: string, customResolver?: EntryLinkUrlResolver): unknown;
|
|
59
|
-
/**
|
|
60
|
-
* Extract all entry link IDs from text (for validation, not resolution).
|
|
61
|
-
* Returns IDs found in entry:ID patterns, skipping code blocks.
|
|
62
|
-
*/
|
|
40
|
+
/** Every entry link ID in text, skipping code blocks — for validation, not resolution. */
|
|
63
41
|
export declare function extractEntryLinkIds(text: string): Array<{
|
|
64
42
|
id: string;
|
|
65
43
|
anchor?: string;
|
|
@@ -1,49 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Entry link resolution for body content
|
|
2
|
+
* Entry link resolution for body content: `entry:CONTENT_ID` tokens in markdown/MDX
|
|
3
|
+
* text resolve to URL paths, extending the reference-by-ID pattern from structured
|
|
4
|
+
* reference fields to inline body links.
|
|
3
5
|
*
|
|
4
|
-
* Resolves `entry:CONTENT_ID` patterns in markdown/MDX body text to actual URL paths.
|
|
5
|
-
* This extends the reference-by-ID pattern (already used for structured reference fields)
|
|
6
|
-
* to inline links in content bodies.
|
|
7
|
-
*
|
|
8
|
-
* Syntax:
|
|
9
6
|
* [Link text](entry:vh2WdhwAFiSL)
|
|
10
7
|
* [Link text](entry:vh2WdhwAFiSL#section-heading)
|
|
11
8
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* Fenced code blocks and inline code spans are skipped, so code examples are never
|
|
10
|
+
* rewritten.
|
|
14
11
|
*/
|
|
15
12
|
import { createDebugLogger } from './utils/debug.js';
|
|
16
13
|
import { computeEntryUrl } from './utils/entry-url.js';
|
|
17
14
|
const log = createDebugLogger({ prefix: 'EntryLinks' });
|
|
18
|
-
/**
|
|
19
|
-
* Base58 alphabet pattern (matches content IDs).
|
|
20
|
-
* Excludes ambiguous characters: 0, O, I, l
|
|
21
|
-
*/
|
|
22
15
|
/** Base58 alphabet character class (excludes ambiguous: 0, O, I, l). */
|
|
23
|
-
|
|
16
|
+
const BASE58_CHAR = '[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]';
|
|
24
17
|
/**
|
|
25
18
|
* Pattern matching `entry:CONTENT_ID` with optional anchor fragment.
|
|
26
19
|
* Uses the `g` flag — safe to share when used only with `.replace()`.
|
|
27
20
|
*/
|
|
28
21
|
export const ENTRY_LINK_PATTERN = new RegExp(`entry:(${BASE58_CHAR}{12})(#[^\\s)>"']*)?`, 'g');
|
|
29
|
-
/**
|
|
30
|
-
* Compute a URL path from an entry's location in the content tree.
|
|
31
|
-
* Delegates to the shared `computeEntryUrl` utility.
|
|
32
|
-
*/
|
|
22
|
+
/** URL path for an entry's location in the content tree; delegates to `computeEntryUrl`. */
|
|
33
23
|
export function resolveEntryUrl(location, contentRoot) {
|
|
34
24
|
return computeEntryUrl(location.collection ?? '', location.slug ?? '', contentRoot);
|
|
35
25
|
}
|
|
36
26
|
/**
|
|
37
|
-
* Replace `entry:CONTENT_ID`
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* code examples that mention the entry: syntax.
|
|
41
|
-
*
|
|
42
|
-
* Missing IDs are replaced with "#" (dead link) and logged as warnings.
|
|
43
|
-
* Anchor fragments are preserved: entry:ID#heading => /path#heading
|
|
27
|
+
* Replace `entry:CONTENT_ID` tokens with resolved URL paths, skipping code blocks and
|
|
28
|
+
* spans so examples mentioning the syntax survive. A missing ID becomes "#" (dead link)
|
|
29
|
+
* plus a warning; an anchor fragment is preserved (`entry:ID#heading` => `/path#heading`).
|
|
44
30
|
*/
|
|
45
31
|
export function resolveEntryLinksInText(text, idIndex, contentRoot, customResolver) {
|
|
46
|
-
// Split text into protected regions (code blocks/spans) and resolvable regions
|
|
47
32
|
const parts = splitByCodeRegions(text);
|
|
48
33
|
return parts
|
|
49
34
|
.map((part) => {
|
|
@@ -74,12 +59,9 @@ export function resolveEntryLinksInText(text, idIndex, contentRoot, customResolv
|
|
|
74
59
|
/** Quick-check pattern for early bail-out (no `g` flag, safe for `.test()`). */
|
|
75
60
|
export const ENTRY_LINK_QUICK_CHECK = /entry:[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{12}/;
|
|
76
61
|
/**
|
|
77
|
-
* Recursively resolve entry:ID
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* JSON entries where markdown fields live inside nested objects (e.g., hero.body).
|
|
81
|
-
*
|
|
82
|
-
* Returns the same object reference if nothing changed (structural sharing).
|
|
62
|
+
* Recursively resolve `entry:ID` tokens in every string of a data structure — nested
|
|
63
|
+
* objects and arrays included, since JSON entries keep markdown fields inside nested
|
|
64
|
+
* objects (e.g. hero.body). Returns the same reference when nothing changed.
|
|
83
65
|
*/
|
|
84
66
|
export function resolveEntryLinksInData(data, idIndex, contentRoot, customResolver) {
|
|
85
67
|
if (typeof data === 'string') {
|
|
@@ -110,20 +92,16 @@ export function resolveEntryLinksInData(data, idIndex, contentRoot, customResolv
|
|
|
110
92
|
}
|
|
111
93
|
return data;
|
|
112
94
|
}
|
|
113
|
-
/**
|
|
114
|
-
* Extract all entry link IDs from text (for validation, not resolution).
|
|
115
|
-
* Returns IDs found in entry:ID patterns, skipping code blocks.
|
|
116
|
-
*/
|
|
95
|
+
/** Every entry link ID in text, skipping code blocks — for validation, not resolution. */
|
|
117
96
|
export function extractEntryLinkIds(text) {
|
|
118
97
|
const parts = splitByCodeRegions(text);
|
|
119
98
|
const results = [];
|
|
120
99
|
for (const part of parts) {
|
|
121
100
|
if (part.isCode)
|
|
122
101
|
continue;
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
//
|
|
126
|
-
// ENTRY_LINK_PATTERN isn't mutated by this exec() loop.
|
|
102
|
+
// `ENTRY_LINK_PATTERN.source` is a fixed compile-time pattern, not attacker-controlled
|
|
103
|
+
// input. A fresh instance per part keeps this exec() loop from mutating the shared
|
|
104
|
+
// `g`-flagged pattern's `lastIndex`.
|
|
127
105
|
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
128
106
|
const regex = new RegExp(ENTRY_LINK_PATTERN.source, 'g');
|
|
129
107
|
let match;
|
|
@@ -137,30 +115,23 @@ export function extractEntryLinkIds(text) {
|
|
|
137
115
|
return results;
|
|
138
116
|
}
|
|
139
117
|
/**
|
|
140
|
-
* Split text into alternating code/non-code regions
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* - Fenced code blocks (``` or ~~~), including with language tags
|
|
144
|
-
* - Inline code spans (`code` and ``code``)
|
|
145
|
-
*
|
|
146
|
-
* This ensures entry:ID inside code is never resolved.
|
|
118
|
+
* Split text into alternating code/non-code regions — fenced blocks (``` or ~~~, language
|
|
119
|
+
* tags included) and inline spans (`code`, ``code``) — so `entry:ID` inside code is never
|
|
120
|
+
* resolved.
|
|
147
121
|
*/
|
|
148
122
|
function splitByCodeRegions(text) {
|
|
149
123
|
const parts = [];
|
|
150
124
|
let current = '';
|
|
151
125
|
let i = 0;
|
|
152
126
|
while (i < text.length) {
|
|
153
|
-
// Check for fenced code block (``` or ~~~)
|
|
154
127
|
if ((text[i] === '`' || text[i] === '~') &&
|
|
155
128
|
i + 2 < text.length &&
|
|
156
129
|
text[i + 1] === text[i] &&
|
|
157
130
|
text[i + 2] === text[i]) {
|
|
158
131
|
const fence = text[i];
|
|
159
|
-
// Count fence length (could be ``` or ```` etc.)
|
|
160
132
|
let fenceLen = 0;
|
|
161
133
|
while (i + fenceLen < text.length && text[i + fenceLen] === fence)
|
|
162
134
|
fenceLen++;
|
|
163
|
-
// Find end of opening fence line
|
|
164
135
|
const lineEnd = text.indexOf('\n', i + fenceLen);
|
|
165
136
|
if (lineEnd === -1) {
|
|
166
137
|
// No newline — rest of text is code block
|
|
@@ -169,7 +140,6 @@ function splitByCodeRegions(text) {
|
|
|
169
140
|
parts.push({ text: text.slice(i), isCode: true });
|
|
170
141
|
return parts;
|
|
171
142
|
}
|
|
172
|
-
// Find closing fence
|
|
173
143
|
const closingPattern = fence.repeat(fenceLen);
|
|
174
144
|
let closeStart = lineEnd + 1;
|
|
175
145
|
let found = false;
|
|
@@ -199,13 +169,10 @@ function splitByCodeRegions(text) {
|
|
|
199
169
|
}
|
|
200
170
|
continue;
|
|
201
171
|
}
|
|
202
|
-
// Check for inline code span (` or ``)
|
|
203
172
|
if (text[i] === '`') {
|
|
204
|
-
// Count opening backticks
|
|
205
173
|
let ticks = 0;
|
|
206
174
|
while (i + ticks < text.length && text[i + ticks] === '`')
|
|
207
175
|
ticks++;
|
|
208
|
-
// Find matching closing backticks
|
|
209
176
|
const closer = '`'.repeat(ticks);
|
|
210
177
|
const closeIdx = text.indexOf(closer, i + ticks);
|
|
211
178
|
if (closeIdx !== -1) {
|
|
@@ -3,78 +3,38 @@ import type { EntrySchemaRegistry } from './schema/types.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Create a type-safe entry schema registry with runtime validation.
|
|
5
5
|
*
|
|
6
|
-
* The KEYS
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
6
|
+
* The KEYS are the strings `.collection.json` files (and the editor wire format)
|
|
7
|
+
* use to look up each schema via the `entry.schema` property. Any string works,
|
|
8
|
+
* but **key by the entry-type name** — the filename token, the same string
|
|
9
|
+
* `meta.entryType` carries in `buildContentTree` callbacks — because then
|
|
10
|
+
* `EntryTypesFromRegistry<typeof yourRegistry>` derives the discriminated-union
|
|
11
|
+
* map for `buildContentTree`'s `TEntryTypes` parameter with no parallel
|
|
12
|
+
* interface to maintain. Keyed any other way, the derived map is keyed by that
|
|
13
|
+
* string instead and will not plug into `TEntryTypes`.
|
|
14
|
+
*
|
|
15
|
+
* Rejected at call time: an empty registry; a schema that is not a non-empty
|
|
16
|
+
* `EntrySchema` array; more than one `isTitle` per schema, or one on a non-string
|
|
17
|
+
* field or inside a list; more than one `isBody`, or one on a field that is not
|
|
18
|
+
* markdown/mdx or is named one of `RESOLVED_REFERENCE_KEYS`. This is also the one
|
|
19
|
+
* place the shared field-shape checks run: select fields must have options,
|
|
20
|
+
* reference fields must have `collections` or `entryTypes`, no inline groups
|
|
21
|
+
* inside object/block fields, no field-name collisions after group flattening.
|
|
14
22
|
*
|
|
15
23
|
* @example
|
|
16
|
-
* Recommended — keys are entry-type names:
|
|
17
24
|
* ```typescript
|
|
18
|
-
* import { createEntrySchemaRegistry } from 'canopycms/server'
|
|
19
|
-
* import { type EntryTypesFromRegistry, defineEntrySchema } from 'canopycms'
|
|
20
|
-
*
|
|
21
|
-
* export const partnerSchema = defineEntrySchema([
|
|
22
|
-
* { name: 'name', type: 'string', label: 'Name', isTitle: true },
|
|
23
|
-
* { name: 'isFictional', type: 'boolean', label: 'Fictional?' },
|
|
24
|
-
* ])
|
|
25
|
-
* export const docSchema = defineEntrySchema([
|
|
26
|
-
* { name: 'title', type: 'string', label: 'Title' },
|
|
27
|
-
* ])
|
|
28
|
-
*
|
|
29
25
|
* export const entrySchemaRegistry = createEntrySchemaRegistry({
|
|
30
|
-
* partner: partnerSchema,
|
|
26
|
+
* partner: partnerSchema, // .collection.json: { "name": "partner", "schema": "partner" }
|
|
31
27
|
* doc: docSchema,
|
|
32
28
|
* })
|
|
33
|
-
*
|
|
34
|
-
* // Then in .collection.json:
|
|
35
|
-
* // { "name": "partner", "format": "yaml", "schema": "partner" }
|
|
36
|
-
*
|
|
37
|
-
* // Derive entry-type map for typed narrowing:
|
|
38
29
|
* export type EntryTypes = EntryTypesFromRegistry<typeof entrySchemaRegistry>
|
|
39
|
-
*
|
|
40
|
-
* // Per-schema aliases stay one line each, anchored to the registry:
|
|
41
30
|
* export type PartnerContent = EntryTypes['partner']
|
|
42
31
|
* ```
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* Also valid — keys are schema-variable names (prior convention):
|
|
46
|
-
* ```typescript
|
|
47
|
-
* export const entrySchemaRegistry = createEntrySchemaRegistry({
|
|
48
|
-
* partnerSchema, // JS shorthand — key is the string "partnerSchema"
|
|
49
|
-
* docSchema,
|
|
50
|
-
* })
|
|
51
|
-
*
|
|
52
|
-
* // .collection.json must then say:
|
|
53
|
-
* // { "name": "partner", "schema": "partnerSchema" }
|
|
54
|
-
* //
|
|
55
|
-
* // EntryTypesFromRegistry produces a map keyed by "partnerSchema" rather than
|
|
56
|
-
* // by "partner", so it can't plug straight into buildContentTree's TEntryTypes.
|
|
57
|
-
* // Either rekey the registry to the recommended convention, or declare the
|
|
58
|
-
* // entry-type map manually using TypeFromEntrySchema<typeof partnerSchema>.
|
|
59
|
-
* ```
|
|
60
|
-
*
|
|
61
|
-
* Runtime validation: registry must be non-empty, each schema must be a
|
|
62
|
-
* non-empty `EntrySchema` array, at most one `isTitle` per schema (string
|
|
63
|
-
* fields only), at most one `isBody` per schema (markdown/mdx only). Field-
|
|
64
|
-
* shape checks: select fields must have options, reference fields must have
|
|
65
|
-
* `collections` or `entryTypes`, no inline groups inside object/block fields,
|
|
66
|
-
* no field-name collisions after group flattening.
|
|
67
32
|
*/
|
|
68
33
|
export declare function createEntrySchemaRegistry<T extends Record<string, EntrySchema>>(registry: T): T;
|
|
69
34
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* rather than at runtime on first request.
|
|
74
|
-
*
|
|
75
|
-
* @param entrySchemaRegistry - The entry schema registry mapping names to field definitions
|
|
76
|
-
* @param contentPath - Path to the content directory containing .collection.json files
|
|
77
|
-
* @returns Promise that resolves if validation passes, rejects with descriptive error if not
|
|
35
|
+
* Validate that every entry-schema reference in the `.collection.json` files under
|
|
36
|
+
* `contentPath` exists in the registry. Run it at build time so a stale reference fails
|
|
37
|
+
* there rather than at runtime on first request.
|
|
78
38
|
*
|
|
79
39
|
* @example
|
|
80
40
|
* ```typescript
|