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
|
@@ -1,82 +1,46 @@
|
|
|
1
1
|
import { isValidId } from '../id.js';
|
|
2
|
-
// Lives here rather than in content-listing.ts
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// re-exports this and `canopycms/server` re-exports it from there, so the public surface is
|
|
6
|
-
// unchanged.
|
|
2
|
+
// Lives here rather than in content-listing.ts so dependency-light modules can use it:
|
|
3
|
+
// content-listing imports ContentStore, so url-collision.ts (which content-store imports) cannot
|
|
4
|
+
// reach back into it without a cycle. content-listing and `canopycms/server` re-export it.
|
|
7
5
|
/**
|
|
8
6
|
* Parse a Canopy content filename into its `{type}.{slug}.{id}.{ext}` parts.
|
|
9
7
|
*
|
|
10
|
-
*
|
|
8
|
+
* The slug may itself contain dots (`getting.started.guide`), so type and ID anchor the split:
|
|
9
|
+
* the ID is the second-to-last dot-separated segment, the slug is everything between the type and
|
|
10
|
+
* it (lowercased), and the extension is stripped. The ID is a 12-character Base58 content ID, and
|
|
11
|
+
* a would-be ID segment that fails `isValidId` rejects the whole parse.
|
|
11
12
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* everything between the type and the ID. The returned `slug` is
|
|
18
|
-
* lowercased.
|
|
19
|
-
* - `id` — a 12-character Base58 content ID (`generateId()`/`isValidId()`).
|
|
20
|
-
* Base58 excludes the ambiguous characters `0`, `O`, `I`, `l` so IDs are
|
|
21
|
-
* unambiguous when read aloud or hand-transcribed. A filename whose
|
|
22
|
-
* would-be ID segment doesn't pass `isValidId` is rejected — the whole
|
|
23
|
-
* parse returns `null`, even if the rest of the shape looks right.
|
|
24
|
-
* - `ext` — the format extension (`.md`, `.mdx`, `.json`, `.yaml`), stripped
|
|
25
|
-
* before parsing and not part of the returned result.
|
|
13
|
+
* `filename` must be a bare filename, and **that precondition is not enforced**: the parser splits
|
|
14
|
+
* purely on `.`, so a `/` or `\` is neither rejected nor treated as special and becomes part of
|
|
15
|
+
* whichever segment it falls in (`'foo/bar.slug.<validId>.md'` gives `type: 'foo/bar'`). Strip the
|
|
16
|
+
* directory component yourself (`path.basename`) — every internal caller does. A leading-dot
|
|
17
|
+
* filename is always rejected, matching `extractEntryTypeFromFilename` in `content-id-index.ts`.
|
|
26
18
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* for adopter code that needs to recover `{type, slug, id}` from a
|
|
39
|
-
* filename without having a schema/entry-types list on hand (e.g. a
|
|
40
|
-
* filesystem walk over content for tooling or diagnostics). Even without
|
|
41
|
-
* `entryTypes`, a leading-dot filename (dotfile, editor swap/backup file)
|
|
42
|
-
* is always rejected — an empty string is never a legal type, matching the
|
|
43
|
-
* `filename.startsWith('.')` guard `extractEntryTypeFromFilename` in
|
|
44
|
-
* `content-id-index.ts` already applies.
|
|
45
|
-
* @returns `{ type, slug, id }`, or `null` if `filename` doesn't match the
|
|
46
|
-
* `{type}.{slug}.{id}.{ext}` shape (too few segments, no extension, a
|
|
47
|
-
* leading dot, an invalid ID, or — when `entryTypes` is given — an
|
|
48
|
-
* unrecognized type). `id` is validated (`isValidId`) and safe to trust. **`slug` is
|
|
49
|
-
* not** — it is the raw dot-joined middle segment(s), lowercased, cast to the branded
|
|
50
|
-
* `Slug` type without running `parseSlug`'s validation. A filename with an
|
|
51
|
-
* unconventional slug segment (e.g. containing a space, or a dot) still parses and still
|
|
52
|
-
* receives the `Slug` brand. Callers that need a validated slug must run the result
|
|
53
|
-
* through `parseSlug` themselves; this function's contract is "split the filename
|
|
54
|
-
* grammar apart," not "validate every part." `listCollectionEntries` (content-listing.ts)
|
|
55
|
-
* is exactly such a caller that does NOT re-validate — it lists the file and computes a
|
|
56
|
-
* `urlPath` for it regardless — so a dotted slug listed this way builds and gets
|
|
57
|
-
* advertised (sitemap, `generateStaticParams`) but can never be read back through
|
|
58
|
-
* `readByUrlPath`, which does run every URL-resolution candidate through `parseSlug`.
|
|
59
|
-
* `static/index.ts`'s `assertRoutableSlugs` is the build-time guard that catches this.
|
|
19
|
+
* `entryTypes`, when given, restricts the `type` segment to those entry types — how
|
|
20
|
+
* `listCollectionEntries` filters out files that do not belong to the collection. Omit it to
|
|
21
|
+
* parse structurally, for adopter code recovering `{type, slug, id}` with no schema on hand.
|
|
22
|
+
*
|
|
23
|
+
* `id` is validated and safe to trust. **`slug` is not** — it is the raw dot-joined middle,
|
|
24
|
+
* lowercased and cast to the branded `Slug` without `parseSlug`'s validation, so a slug holding a
|
|
25
|
+
* space or a dot still parses and still carries the brand. Callers needing a validated slug run
|
|
26
|
+
* `parseSlug` themselves. `listCollectionEntries` does NOT, so a dotted slug is listed and
|
|
27
|
+
* advertised (sitemap, `generateStaticParams`) yet can never be read back through `readByUrlPath`,
|
|
28
|
+
* which runs every candidate through `parseSlug`; `static/index.ts`'s `assertRoutableSlugs` is the
|
|
29
|
+
* build-time guard for that.
|
|
60
30
|
*/
|
|
61
31
|
export const parseTypedFilename = (filename, entryTypes) => {
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
// is exactly the shape of the files a structural (no-entryTypes) parse would
|
|
65
|
-
// otherwise misparse -- e.g. '.hidden.file.aB3cD4eF5gH6.md' -> potentialType ''.
|
|
32
|
+
// A leading dot can never be a legal entry type, and a dotfile is exactly what a structural
|
|
33
|
+
// (no-entryTypes) parse would otherwise misparse: '.hidden.file.aB3cD4eF5gH6.md' -> type ''.
|
|
66
34
|
if (filename.startsWith('.'))
|
|
67
35
|
return null;
|
|
68
|
-
// Remove extension
|
|
69
36
|
const lastDot = filename.lastIndexOf('.');
|
|
70
37
|
if (lastDot === -1)
|
|
71
38
|
return null;
|
|
72
39
|
const nameWithoutExt = filename.slice(0, lastDot);
|
|
73
|
-
// Parse: {type}.{slug}.{id}
|
|
74
40
|
const parts = nameWithoutExt.split('.');
|
|
75
41
|
if (parts.length < 3)
|
|
76
42
|
return null;
|
|
77
43
|
const potentialType = parts[0];
|
|
78
|
-
// When a known-types list is supplied, the first segment must match one of
|
|
79
|
-
// them. Without it, any non-empty first segment is accepted as the type.
|
|
80
44
|
if (entryTypes && !entryTypes.some((e) => e.name === potentialType)) {
|
|
81
45
|
return null;
|
|
82
46
|
}
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
* Whether `url` is a DECLARED off-site pointer - a scheme-qualified absolute URL
|
|
22
22
|
* (`https://example.com/x`) or a literal protocol-relative one (`//cdn.example.com/x`).
|
|
23
23
|
*
|
|
24
|
-
* Deliberately narrower than "resolves off-origin": a
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* Deliberately narrower than "resolves off-origin": a backslash-equivalent spelling (see
|
|
25
|
+
* `utils/sanitize-href.ts`'s `declaresScheme` and `isImplicitlyOffOrigin`)
|
|
26
|
+
* also resolves off-origin in a browser, but is NOT recognized here as
|
|
27
27
|
* an intentional off-site pointer the way a literal `//cdn…` is. Callers handle that case
|
|
28
28
|
* separately, by neutralizing (`neutralizeImplicitOffOrigin`) rather than passing through: a
|
|
29
29
|
* `false` result here isn't a guarantee the value is a safe site-relative path on its own, only
|
package/dist/utils/url-prefix.js
CHANGED
|
@@ -22,9 +22,9 @@ import { declaresScheme, neutralizeImplicitOffOrigin } from './sanitize-href.js'
|
|
|
22
22
|
* Whether `url` is a DECLARED off-site pointer - a scheme-qualified absolute URL
|
|
23
23
|
* (`https://example.com/x`) or a literal protocol-relative one (`//cdn.example.com/x`).
|
|
24
24
|
*
|
|
25
|
-
* Deliberately narrower than "resolves off-origin": a
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* Deliberately narrower than "resolves off-origin": a backslash-equivalent spelling (see
|
|
26
|
+
* `utils/sanitize-href.ts`'s `declaresScheme` and `isImplicitlyOffOrigin`)
|
|
27
|
+
* also resolves off-origin in a browser, but is NOT recognized here as
|
|
28
28
|
* an intentional off-site pointer the way a literal `//cdn…` is. Callers handle that case
|
|
29
29
|
* separately, by neutralizing (`neutralizeImplicitOffOrigin`) rather than passing through: a
|
|
30
30
|
* `false` result here isn't a guarantee the value is a safe site-relative path on its own, only
|
|
@@ -1,41 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The keys a block item carries that are STRUCTURE rather than content
|
|
2
|
+
* The keys a block item carries that are STRUCTURE rather than content: the
|
|
3
|
+
* discriminator naming the block's TEMPLATE — a category label shared by every
|
|
4
|
+
* block of that kind, not an identifier for this one — present in either on-disk
|
|
5
|
+
* shape: canonical `{ template: 'hero', value: {...} }` or the defensive inline
|
|
6
|
+
* `{ _type: 'hero', ...fields }` (see `resolveBlockItem` in `./field-traversal`).
|
|
3
7
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
8
|
+
* The list lives here, not in either caller, so the two below can't drift apart:
|
|
9
|
+
* - `findUnknownKeys` (./entry-validator) must not report the discriminator as a
|
|
10
|
+
* stale key — it isn't a schema field, but is supposed to be there.
|
|
11
|
+
* - `looksLikeSameItem` (../utils/content-serialize) must not accept it as evidence
|
|
12
|
+
* two list items are the same item — every `hero` shares `template: hero`, so
|
|
13
|
+
* counting it would migrate an editorial comment off a deleted block onto an
|
|
14
|
+
* unrelated survivor.
|
|
9
15
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* - `findUnknownKeys` (./entry-validator) must not report the discriminator as a stale key: it
|
|
14
|
-
* is not a schema field, but it is supposed to be there.
|
|
15
|
-
* - `looksLikeSameItem` (../utils/content-serialize) must not accept the discriminator as
|
|
16
|
-
* evidence that two list items are the same item: two `hero` blocks share `template: hero`,
|
|
17
|
-
* so counting it migrated an editorial comment off a deleted block onto an unrelated
|
|
18
|
-
* survivor.
|
|
19
|
-
*
|
|
20
|
-
* A single list keeps those two from drifting apart — a third discriminator added for one of
|
|
21
|
-
* them but not the other would resurrect exactly one of those bugs.
|
|
22
|
-
*
|
|
23
|
-
* Note that two other readers deliberately still spell the keys out themselves, because they
|
|
24
|
-
* READ the discriminator's value positionally rather than testing membership, and they do not
|
|
25
|
-
* agree on precedence: `resolveBlockItem` prefers `template`, while `ai/json-to-markdown.ts`
|
|
26
|
-
* prefers `_type`. Reconciling that is a behaviour question, not a refactor — see
|
|
16
|
+
* Two other readers still spell the keys out themselves — they read the value
|
|
17
|
+
* positionally and disagree on precedence (`resolveBlockItem` prefers `template`,
|
|
18
|
+
* `ai/json-to-markdown.ts` prefers `_type`) — see
|
|
27
19
|
* `.claude/future-tasks/block-discriminator-precedence-disagreement.md`.
|
|
28
20
|
*
|
|
29
|
-
* Dependency-free on purpose: both importers
|
|
21
|
+
* Dependency-free on purpose: both importers reach contexts that must not pull in
|
|
30
22
|
* schema types or node built-ins.
|
|
31
23
|
*/
|
|
32
|
-
/**
|
|
33
|
-
* The discriminator keys, in the precedence `resolveBlockItem` reads them.
|
|
34
|
-
*
|
|
35
|
-
* Ordered (rather than a bare Set) so a caller that needs the VALUE can iterate it, and so the
|
|
36
|
-
* canonical shape's key stays visibly first.
|
|
37
|
-
*/
|
|
38
|
-
export declare const BLOCK_DISCRIMINATOR_KEYS: readonly ["template", "_type"];
|
|
39
24
|
/** Membership form of {@link BLOCK_DISCRIMINATOR_KEYS}, for the two set-test callers. */
|
|
40
25
|
export declare const BLOCK_STRUCTURAL_KEYS: ReadonlySet<string>;
|
|
41
26
|
/** True for a key that names a block's template rather than holding any of its content. */
|
|
@@ -1,41 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The keys a block item carries that are STRUCTURE rather than content
|
|
2
|
+
* The keys a block item carries that are STRUCTURE rather than content: the
|
|
3
|
+
* discriminator naming the block's TEMPLATE — a category label shared by every
|
|
4
|
+
* block of that kind, not an identifier for this one — present in either on-disk
|
|
5
|
+
* shape: canonical `{ template: 'hero', value: {...} }` or the defensive inline
|
|
6
|
+
* `{ _type: 'hero', ...fields }` (see `resolveBlockItem` in `./field-traversal`).
|
|
3
7
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
8
|
+
* The list lives here, not in either caller, so the two below can't drift apart:
|
|
9
|
+
* - `findUnknownKeys` (./entry-validator) must not report the discriminator as a
|
|
10
|
+
* stale key — it isn't a schema field, but is supposed to be there.
|
|
11
|
+
* - `looksLikeSameItem` (../utils/content-serialize) must not accept it as evidence
|
|
12
|
+
* two list items are the same item — every `hero` shares `template: hero`, so
|
|
13
|
+
* counting it would migrate an editorial comment off a deleted block onto an
|
|
14
|
+
* unrelated survivor.
|
|
9
15
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* - `findUnknownKeys` (./entry-validator) must not report the discriminator as a stale key: it
|
|
14
|
-
* is not a schema field, but it is supposed to be there.
|
|
15
|
-
* - `looksLikeSameItem` (../utils/content-serialize) must not accept the discriminator as
|
|
16
|
-
* evidence that two list items are the same item: two `hero` blocks share `template: hero`,
|
|
17
|
-
* so counting it migrated an editorial comment off a deleted block onto an unrelated
|
|
18
|
-
* survivor.
|
|
19
|
-
*
|
|
20
|
-
* A single list keeps those two from drifting apart — a third discriminator added for one of
|
|
21
|
-
* them but not the other would resurrect exactly one of those bugs.
|
|
22
|
-
*
|
|
23
|
-
* Note that two other readers deliberately still spell the keys out themselves, because they
|
|
24
|
-
* READ the discriminator's value positionally rather than testing membership, and they do not
|
|
25
|
-
* agree on precedence: `resolveBlockItem` prefers `template`, while `ai/json-to-markdown.ts`
|
|
26
|
-
* prefers `_type`. Reconciling that is a behaviour question, not a refactor — see
|
|
16
|
+
* Two other readers still spell the keys out themselves — they read the value
|
|
17
|
+
* positionally and disagree on precedence (`resolveBlockItem` prefers `template`,
|
|
18
|
+
* `ai/json-to-markdown.ts` prefers `_type`) — see
|
|
27
19
|
* `.claude/future-tasks/block-discriminator-precedence-disagreement.md`.
|
|
28
20
|
*
|
|
29
|
-
* Dependency-free on purpose: both importers
|
|
21
|
+
* Dependency-free on purpose: both importers reach contexts that must not pull in
|
|
30
22
|
* schema types or node built-ins.
|
|
31
23
|
*/
|
|
32
24
|
/**
|
|
33
|
-
* The discriminator keys, in the precedence `resolveBlockItem` reads them.
|
|
34
|
-
*
|
|
35
|
-
* Ordered (rather than a bare Set) so a caller that needs the VALUE can iterate it, and so the
|
|
36
|
-
* canonical shape's key stays visibly first.
|
|
25
|
+
* The discriminator keys, in the precedence `resolveBlockItem` reads them. Ordered (not a
|
|
26
|
+
* bare Set) so a caller needing the VALUE can iterate, and the canonical key stays first.
|
|
37
27
|
*/
|
|
38
|
-
|
|
28
|
+
const BLOCK_DISCRIMINATOR_KEYS = ['template', '_type'];
|
|
39
29
|
/** Membership form of {@link BLOCK_DISCRIMINATOR_KEYS}, for the two set-test callers. */
|
|
40
30
|
export const BLOCK_STRUCTURAL_KEYS = new Set(BLOCK_DISCRIMINATOR_KEYS);
|
|
41
31
|
/** True for a key that names a block's template rather than holding any of its content. */
|
|
@@ -15,18 +15,6 @@ export interface DeletionCheckResult {
|
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* DeletionChecker finds all references to an entry before deletion.
|
|
18
|
-
*
|
|
19
|
-
* This class provides referential integrity checking by:
|
|
20
|
-
* - Scanning all entries for references to a target ID
|
|
21
|
-
* - Identifying which entries and fields reference the target
|
|
22
|
-
* - Preventing deletion of entries that are still referenced
|
|
23
|
-
*
|
|
24
|
-
* Usage:
|
|
25
|
-
* const checker = new DeletionChecker(store, idIndex, schema)
|
|
26
|
-
* const result = await checker.canDelete(targetId)
|
|
27
|
-
* if (!result.canDelete) {
|
|
28
|
-
* console.log('Cannot delete:', result.referencedBy)
|
|
29
|
-
* }
|
|
30
18
|
*/
|
|
31
19
|
export declare class DeletionChecker {
|
|
32
20
|
private store;
|
|
@@ -35,31 +23,9 @@ export declare class DeletionChecker {
|
|
|
35
23
|
constructor(store: ContentStore, idIndex: ContentIdIndex, collections: Map<LogicalPath, {
|
|
36
24
|
fields: FieldConfig[];
|
|
37
25
|
}>);
|
|
38
|
-
/**
|
|
39
|
-
* Check if an entry can be safely deleted.
|
|
40
|
-
*
|
|
41
|
-
* @param id - The content ID to check
|
|
42
|
-
* @returns Result indicating if deletion is safe and what references exist
|
|
43
|
-
*/
|
|
44
26
|
canDelete(id: string): Promise<DeletionCheckResult>;
|
|
45
|
-
/**
|
|
46
|
-
* Find all entries that reference the target ID.
|
|
47
|
-
*
|
|
48
|
-
* @param targetId - The content ID to search for
|
|
49
|
-
* @returns Array of reference info for each referencing entry
|
|
50
|
-
*/
|
|
51
27
|
findReferences(targetId: string): Promise<ReferenceInfo[]>;
|
|
52
|
-
/**
|
|
53
|
-
* Scan a single collection for references to the target ID.
|
|
54
|
-
*/
|
|
55
28
|
private scanCollection;
|
|
56
|
-
/**
|
|
57
|
-
* Find all occurrences of target ID in entry data.
|
|
58
|
-
* Returns field paths where the ID was found.
|
|
59
|
-
*/
|
|
60
29
|
private findIdInData;
|
|
61
|
-
/**
|
|
62
|
-
* Helper to list all entries in a collection from the ID index.
|
|
63
|
-
*/
|
|
64
30
|
private listEntriesInCollection;
|
|
65
31
|
}
|
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
import { resolveBlockItem } from './field-traversal.js';
|
|
2
2
|
/**
|
|
3
3
|
* DeletionChecker finds all references to an entry before deletion.
|
|
4
|
-
*
|
|
5
|
-
* This class provides referential integrity checking by:
|
|
6
|
-
* - Scanning all entries for references to a target ID
|
|
7
|
-
* - Identifying which entries and fields reference the target
|
|
8
|
-
* - Preventing deletion of entries that are still referenced
|
|
9
|
-
*
|
|
10
|
-
* Usage:
|
|
11
|
-
* const checker = new DeletionChecker(store, idIndex, schema)
|
|
12
|
-
* const result = await checker.canDelete(targetId)
|
|
13
|
-
* if (!result.canDelete) {
|
|
14
|
-
* console.log('Cannot delete:', result.referencedBy)
|
|
15
|
-
* }
|
|
16
4
|
*/
|
|
17
5
|
export class DeletionChecker {
|
|
18
6
|
constructor(store, idIndex, collections) {
|
|
@@ -20,12 +8,6 @@ export class DeletionChecker {
|
|
|
20
8
|
this.idIndex = idIndex;
|
|
21
9
|
this.collections = collections;
|
|
22
10
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Check if an entry can be safely deleted.
|
|
25
|
-
*
|
|
26
|
-
* @param id - The content ID to check
|
|
27
|
-
* @returns Result indicating if deletion is safe and what references exist
|
|
28
|
-
*/
|
|
29
11
|
async canDelete(id) {
|
|
30
12
|
const referencedBy = await this.findReferences(id);
|
|
31
13
|
return {
|
|
@@ -33,27 +15,16 @@ export class DeletionChecker {
|
|
|
33
15
|
referencedBy,
|
|
34
16
|
};
|
|
35
17
|
}
|
|
36
|
-
/**
|
|
37
|
-
* Find all entries that reference the target ID.
|
|
38
|
-
*
|
|
39
|
-
* @param targetId - The content ID to search for
|
|
40
|
-
* @returns Array of reference info for each referencing entry
|
|
41
|
-
*/
|
|
42
18
|
async findReferences(targetId) {
|
|
43
19
|
const references = [];
|
|
44
|
-
// Scan all collections for references
|
|
45
20
|
for (const [collectionPath, collectionDef] of this.collections.entries()) {
|
|
46
21
|
const refs = await this.scanCollection(collectionPath, collectionDef.fields, targetId);
|
|
47
22
|
references.push(...refs);
|
|
48
23
|
}
|
|
49
24
|
return references;
|
|
50
25
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Scan a single collection for references to the target ID.
|
|
53
|
-
*/
|
|
54
26
|
async scanCollection(collectionPath, fields, targetId) {
|
|
55
27
|
const references = [];
|
|
56
|
-
// Get all entries in this collection from the ID index
|
|
57
28
|
const entries = this.listEntriesInCollection(collectionPath);
|
|
58
29
|
for (const entry of entries) {
|
|
59
30
|
try {
|
|
@@ -71,20 +42,15 @@ export class DeletionChecker {
|
|
|
71
42
|
}
|
|
72
43
|
}
|
|
73
44
|
catch {
|
|
74
|
-
// Skip entries that can't be read
|
|
75
45
|
continue;
|
|
76
46
|
}
|
|
77
47
|
}
|
|
78
48
|
return references;
|
|
79
49
|
}
|
|
80
|
-
/**
|
|
81
|
-
* Find all occurrences of target ID in entry data.
|
|
82
|
-
* Returns field paths where the ID was found.
|
|
83
|
-
*/
|
|
84
50
|
findIdInData(data, targetId, schema, pathPrefix = '') {
|
|
85
51
|
const found = [];
|
|
86
52
|
for (const field of schema) {
|
|
87
|
-
// Inline groups are transparent — recurse
|
|
53
|
+
// Inline groups are transparent (walkFields, ./field-traversal) — recurse at the same level.
|
|
88
54
|
if (field.type === 'group') {
|
|
89
55
|
found.push(...this.findIdInData(data, targetId, field.fields, pathPrefix));
|
|
90
56
|
continue;
|
|
@@ -94,7 +60,6 @@ export class DeletionChecker {
|
|
|
94
60
|
if (value === undefined || value === null)
|
|
95
61
|
continue;
|
|
96
62
|
if (field.type === 'reference') {
|
|
97
|
-
// Check if this reference field contains the target ID
|
|
98
63
|
if (Array.isArray(value)) {
|
|
99
64
|
if (value.includes(targetId)) {
|
|
100
65
|
found.push(fieldPath);
|
|
@@ -122,8 +87,6 @@ export class DeletionChecker {
|
|
|
122
87
|
}
|
|
123
88
|
}
|
|
124
89
|
else if (field.type === 'block') {
|
|
125
|
-
// Handle block fields — real block items are { template, value }, with
|
|
126
|
-
// nested field values under `value` (resolved by resolveBlockItem)
|
|
127
90
|
const blockField = field;
|
|
128
91
|
if (Array.isArray(value)) {
|
|
129
92
|
value.forEach((item, index) => {
|
|
@@ -139,16 +102,11 @@ export class DeletionChecker {
|
|
|
139
102
|
}
|
|
140
103
|
return found;
|
|
141
104
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Helper to list all entries in a collection from the ID index.
|
|
144
|
-
*/
|
|
145
105
|
listEntriesInCollection(collectionPath) {
|
|
146
106
|
const entries = [];
|
|
147
|
-
// Get all locations from the index
|
|
148
107
|
const allLocations = this.idIndex.getAllLocations();
|
|
149
108
|
for (const location of allLocations) {
|
|
150
109
|
if (location.type === 'entry') {
|
|
151
|
-
// Check if this entry is in the target collection
|
|
152
110
|
if (location.collection === collectionPath ||
|
|
153
111
|
location.collection?.startsWith(collectionPath + '/')) {
|
|
154
112
|
entries.push({
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* This parallels ReferenceValidator but operates on inline links in text content
|
|
7
|
-
* rather than structured reference fields.
|
|
2
|
+
* Scans body/markdown/mdx fields for `entry:ID` links and checks that each ID
|
|
3
|
+
* resolves to an existing entry. Warns rather than blocks — a save is never
|
|
4
|
+
* rejected over a broken entry link. Parallels `ReferenceValidator`, but for
|
|
5
|
+
* inline links in text rather than structured reference fields.
|
|
8
6
|
*/
|
|
9
7
|
import type { ContentIdIndex } from '../content-id-index.js';
|
|
10
8
|
import type { FieldConfig } from '../config/index.js';
|
|
11
|
-
|
|
9
|
+
interface EntryLinkWarning {
|
|
12
10
|
field: string;
|
|
13
11
|
fieldPath: string;
|
|
14
12
|
id: string;
|
|
@@ -17,10 +15,5 @@ export interface EntryLinkWarning {
|
|
|
17
15
|
export interface EntryLinkValidationResult {
|
|
18
16
|
warnings: EntryLinkWarning[];
|
|
19
17
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Validate entry links in body/markdown/mdx fields of the provided data.
|
|
22
|
-
*
|
|
23
|
-
* Scans all markdown and mdx fields for entry:ID patterns
|
|
24
|
-
* and checks that each referenced ID exists in the content index.
|
|
25
|
-
*/
|
|
26
18
|
export declare function validateEntryLinks(data: Record<string, unknown>, schema: readonly FieldConfig[], idIndex: ContentIdIndex, bodyContent?: string): EntryLinkValidationResult;
|
|
19
|
+
export {};
|
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* This parallels ReferenceValidator but operates on inline links in text content
|
|
7
|
-
* rather than structured reference fields.
|
|
2
|
+
* Scans body/markdown/mdx fields for `entry:ID` links and checks that each ID
|
|
3
|
+
* resolves to an existing entry. Warns rather than blocks — a save is never
|
|
4
|
+
* rejected over a broken entry link. Parallels `ReferenceValidator`, but for
|
|
5
|
+
* inline links in text rather than structured reference fields.
|
|
8
6
|
*/
|
|
9
7
|
import { extractEntryLinkIds } from '../entry-link-resolver.js';
|
|
10
8
|
import { findFieldsByType } from './field-traversal.js';
|
|
11
|
-
/**
|
|
12
|
-
* Validate entry links in body/markdown/mdx fields of the provided data.
|
|
13
|
-
*
|
|
14
|
-
* Scans all markdown and mdx fields for entry:ID patterns
|
|
15
|
-
* and checks that each referenced ID exists in the content index.
|
|
16
|
-
*/
|
|
17
9
|
export function validateEntryLinks(data, schema, idIndex, bodyContent) {
|
|
18
10
|
const warnings = [];
|
|
19
11
|
// Check body content (for md/mdx entries, body is separate from data)
|
|
20
12
|
if (bodyContent) {
|
|
21
13
|
checkText(bodyContent, 'body', 'body', idIndex, warnings);
|
|
22
14
|
}
|
|
23
|
-
// Check markdown/mdx fields in structured data
|
|
24
15
|
const markdownTypes = ['markdown', 'mdx'];
|
|
25
16
|
for (const fieldType of markdownTypes) {
|
|
26
17
|
const contexts = findFieldsByType(schema, data, fieldType);
|
|
@@ -1,27 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Validates that every reference field's `entryTypes` names an entry type that
|
|
3
|
-
* actually exists in the resolved schema
|
|
3
|
+
* actually exists in the resolved schema — without this, a typo like
|
|
4
|
+
* `entryTypes: ['parter']` is accepted silently and surfaces later as a
|
|
5
|
+
* reference picker returning zero results, with nothing pointing at the cause.
|
|
4
6
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* purpose: entry types are declared per-collection in `.collection.json` files
|
|
11
|
-
* on disk, so the set of valid names only exists once a branch's schema has
|
|
12
|
-
* been resolved. `config/validation.ts`'s `ensureReferenceFieldsHaveScope` runs
|
|
13
|
-
* at entry-schema *registration* (entry-schema-registry.ts), before any branch
|
|
14
|
-
* schema exists, and so cannot perform this check.
|
|
7
|
+
* Runs after schema resolution, not at config-validation time: entry types are
|
|
8
|
+
* declared per-collection in `.collection.json` files on disk, so the valid-name
|
|
9
|
+
* set only exists once a branch's schema is resolved. `config/validation.ts`'s
|
|
10
|
+
* `ensureReferenceFieldsHaveScope` runs at entry-schema registration
|
|
11
|
+
* (entry-schema-registry.ts), before any branch schema exists, so it can't.
|
|
15
12
|
*/
|
|
16
13
|
import type { RootCollectionConfig } from '../config/index.js';
|
|
17
14
|
/**
|
|
18
|
-
* Collect every entry type name defined anywhere in the schema
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* (see reference-resolver.ts, which filters resolved entries by entry type name
|
|
24
|
-
* without regard to which collection defined it).
|
|
15
|
+
* Collect every entry type name defined anywhere in the schema, as a flat set:
|
|
16
|
+
* a reference field's `entryTypes` matches entries across ALL collections, since
|
|
17
|
+
* the same type name may legitimately appear in more than one (see
|
|
18
|
+
* reference-resolver.ts, which filters by type name regardless of collection).
|
|
19
|
+
* @internal Exported for tests.
|
|
25
20
|
*/
|
|
26
21
|
export declare const collectEntryTypeNames: (schema: RootCollectionConfig) => Set<string>;
|
|
27
22
|
/**
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Validates that every reference field's `entryTypes` names an entry type that
|
|
3
|
-
* actually exists in the resolved schema
|
|
3
|
+
* actually exists in the resolved schema — without this, a typo like
|
|
4
|
+
* `entryTypes: ['parter']` is accepted silently and surfaces later as a
|
|
5
|
+
* reference picker returning zero results, with nothing pointing at the cause.
|
|
4
6
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* purpose: entry types are declared per-collection in `.collection.json` files
|
|
11
|
-
* on disk, so the set of valid names only exists once a branch's schema has
|
|
12
|
-
* been resolved. `config/validation.ts`'s `ensureReferenceFieldsHaveScope` runs
|
|
13
|
-
* at entry-schema *registration* (entry-schema-registry.ts), before any branch
|
|
14
|
-
* schema exists, and so cannot perform this check.
|
|
7
|
+
* Runs after schema resolution, not at config-validation time: entry types are
|
|
8
|
+
* declared per-collection in `.collection.json` files on disk, so the valid-name
|
|
9
|
+
* set only exists once a branch's schema is resolved. `config/validation.ts`'s
|
|
10
|
+
* `ensureReferenceFieldsHaveScope` runs at entry-schema registration
|
|
11
|
+
* (entry-schema-registry.ts), before any branch schema exists, so it can't.
|
|
15
12
|
*/
|
|
16
13
|
import { forEachReferenceField } from '../config/validation.js';
|
|
17
14
|
/**
|
|
@@ -59,13 +56,11 @@ const forEachEntryType = (schema, visit) => {
|
|
|
59
56
|
walk(schema, '');
|
|
60
57
|
};
|
|
61
58
|
/**
|
|
62
|
-
* Collect every entry type name defined anywhere in the schema
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* (see reference-resolver.ts, which filters resolved entries by entry type name
|
|
68
|
-
* without regard to which collection defined it).
|
|
59
|
+
* Collect every entry type name defined anywhere in the schema, as a flat set:
|
|
60
|
+
* a reference field's `entryTypes` matches entries across ALL collections, since
|
|
61
|
+
* the same type name may legitimately appear in more than one (see
|
|
62
|
+
* reference-resolver.ts, which filters by type name regardless of collection).
|
|
63
|
+
* @internal Exported for tests.
|
|
69
64
|
*/
|
|
70
65
|
export const collectEntryTypeNames = (schema) => {
|
|
71
66
|
const names = new Set();
|