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
package/dist/branch-registry.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
// The leaf, NOT './branch-metadata'
|
|
4
|
-
//
|
|
3
|
+
// The leaf, NOT './branch-metadata': that module imports this one back, so the
|
|
4
|
+
// pair would be a runtime import cycle. See branch-metadata-file.ts.
|
|
5
5
|
import { readBranchMetadataFile } from './branch-metadata-file.js';
|
|
6
6
|
import { isNotFoundError, getErrorMessage } from './utils/error.js';
|
|
7
7
|
import { createDebugLogger } from './utils/debug.js';
|
|
@@ -13,10 +13,8 @@ import { bumpResourceGeneration, readResourceGeneration, isGenerationCurrent, }
|
|
|
13
13
|
const log = createDebugLogger({ prefix: 'BranchRegistry' });
|
|
14
14
|
// Registry files are stored directly in the branches root (not in a subdirectory)
|
|
15
15
|
const REGISTRY_FILE = 'branches.json';
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
// process upgraded mid-flight may find one left over from before the deploy, so
|
|
19
|
-
// regenerate() opportunistically deletes it. Keep this name only for that cleanup.
|
|
16
|
+
// Retired stale-marker file, never written. Named only so regenerate() can
|
|
17
|
+
// delete one a mid-flight deploy left behind.
|
|
20
18
|
const REGISTRY_STALE_FILE = 'branches.stale.json';
|
|
21
19
|
const REGISTRY_TEMP_FILE = 'branches.tmp.json';
|
|
22
20
|
const REGISTRY_VERSION = 2;
|
|
@@ -25,50 +23,18 @@ const RESOURCE = 'branch-registry';
|
|
|
25
23
|
/** Throttle for the get() suspicious-miss backstop; mirrors content-store's FORCED_REFRESH_MIN_INTERVAL_MS. */
|
|
26
24
|
const GET_MISS_REFRESH_MIN_INTERVAL_MS = 5000;
|
|
27
25
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
26
|
+
* A read-only `branches.json` cache for fast branch listing; the individual
|
|
27
|
+
* branch.json files are the source of truth.
|
|
30
28
|
*
|
|
31
|
-
*
|
|
29
|
+
* Freshness follows the generation-marker protocol owned by
|
|
30
|
+
* resource-generation.ts. This is that protocol's durable-snapshot consumer, so
|
|
31
|
+
* it carries both mitigations: invalidate() eager-regenerates on the mutating
|
|
32
|
+
* host right after its own bump, and get() has a throttled suspicious-miss
|
|
33
|
+
* backstop bounding how long a bad snapshot can hide a real branch.
|
|
32
34
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* via the generic on-disk generation marker in resource-generation.ts: every
|
|
37
|
-
* snapshot embeds the marker token it was built against, and every read
|
|
38
|
-
* cheaply re-checks the live marker before trusting the cached snapshot. See
|
|
39
|
-
* that module's doc comment for the full protocol and residual staleness
|
|
40
|
-
* windows (A/B/C/E).
|
|
41
|
-
*
|
|
42
|
-
* BranchRegistry is exactly the "durable snapshot consumer" case called out
|
|
43
|
-
* there: a regeneration whose scan is served from stale NFS dentry/attribute
|
|
44
|
-
* caches can record a FRESH token over STALE data (window E), and because the
|
|
45
|
-
* result is written to `branches.json`, that staleness becomes durable and
|
|
46
|
-
* shared with every other host that reads the marker - not just one process's
|
|
47
|
-
* memory. Two mitigations close the practical gap:
|
|
48
|
-
*
|
|
49
|
-
* - invalidate() eager-regenerates immediately after its own bump. The
|
|
50
|
-
* mutating host's own scan is necessarily coherent with the mutation it just
|
|
51
|
-
* made (no NFS round trip was needed to observe its own write), so this
|
|
52
|
-
* closes window (E) for the common case without waiting for some other host
|
|
53
|
-
* to lazily pull the change.
|
|
54
|
-
* - get() implements a suspicious-miss backstop: a branch that "should" exist
|
|
55
|
-
* but is absent from the cached snapshot forces one fresh regeneration
|
|
56
|
-
* (throttled), bounding how long a bad snapshot can hide a real branch.
|
|
57
|
-
*
|
|
58
|
-
* regenerate() also skips persisting a snapshot when the marker read itself
|
|
59
|
-
* fails (`{ ok: false }`, e.g. unreadable for a non-ENOENT reason): a snapshot
|
|
60
|
-
* embedding a token we cannot attribute to "matches this scan" would be
|
|
61
|
-
* indistinguishable from a correctly-attributed one to every future reader, so
|
|
62
|
-
* the safer behavior is to serve the fresh scan without writing it durably and
|
|
63
|
-
* let the next read retry the marker.
|
|
64
|
-
*
|
|
65
|
-
* Design:
|
|
66
|
-
* - list() returns the cached snapshot if its embedded generation token still
|
|
67
|
-
* matches the live marker, regenerates from branch.json files otherwise
|
|
68
|
-
* - invalidate() bumps the marker (durable, cross-process) and eager-regenerates
|
|
69
|
-
* - Concurrent regeneration within one process is deduped to a single scan
|
|
70
|
-
* (regenInFlight); across processes, regeneration is still safe since all
|
|
71
|
-
* processes produce identical output from the same branch.json files
|
|
35
|
+
* Concurrent regeneration within one process is deduped to a single scan
|
|
36
|
+
* (regenInFlight); across processes it needs no coordination, since every
|
|
37
|
+
* process produces identical output from the same branch.json files.
|
|
72
38
|
*/
|
|
73
39
|
export class BranchRegistry {
|
|
74
40
|
constructor(root) {
|
|
@@ -97,10 +63,9 @@ export class BranchRegistry {
|
|
|
97
63
|
}
|
|
98
64
|
throw err;
|
|
99
65
|
}
|
|
100
|
-
// Strict version check: a
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
// token or explicit `null`, breaking the freshness comparison below.
|
|
66
|
+
// Strict version check, not truthiness: a snapshot from an older version
|
|
67
|
+
// left on EFS by a rolling deploy has no `generation` field, and an
|
|
68
|
+
// `undefined` token breaks the freshness comparison below.
|
|
104
69
|
if (parsed.version !== REGISTRY_VERSION || !Array.isArray(parsed.branches)) {
|
|
105
70
|
return await this.regenerate();
|
|
106
71
|
}
|
|
@@ -111,15 +76,12 @@ export class BranchRegistry {
|
|
|
111
76
|
return await this.regenerate();
|
|
112
77
|
}
|
|
113
78
|
/**
|
|
114
|
-
* Returns a single branch by name
|
|
79
|
+
* Returns a single branch by name, from the cached snapshot when it is fresh.
|
|
115
80
|
*
|
|
116
|
-
* Suspicious-miss backstop:
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* genuinely-absent branch costs at most one extra scan per throttle window.
|
|
121
|
-
* This bounds durable window-E staleness for the "branch exists but
|
|
122
|
-
* snapshot predates it" direction; see the class doc comment.
|
|
81
|
+
* Suspicious-miss backstop: a `name` missing from the list is the signal that
|
|
82
|
+
* the snapshot may predate a branch that now exists, so force one fresh
|
|
83
|
+
* regeneration and re-search before giving up. Throttled per instance, so a
|
|
84
|
+
* genuinely-absent branch costs at most one extra scan per window.
|
|
123
85
|
*/
|
|
124
86
|
async get(name) {
|
|
125
87
|
const branches = await this.list();
|
|
@@ -139,23 +101,19 @@ export class BranchRegistry {
|
|
|
139
101
|
return true;
|
|
140
102
|
}
|
|
141
103
|
/**
|
|
142
|
-
* Marks the cache
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* closing window (E) early - the bump alone already restored correctness
|
|
148
|
-
* for every future reader. A failed eager regen therefore must not fail the
|
|
149
|
-
* caller's save/delete.
|
|
104
|
+
* Marks the cache stale for every process sharing this root by bumping the
|
|
105
|
+
* marker, then eager-regenerates on this host. The bump must succeed —
|
|
106
|
+
* swallowing that failure leaves the registry stale indefinitely with no
|
|
107
|
+
* backstop. A failed eager regen must NOT fail the caller's save/delete: the
|
|
108
|
+
* bump alone already restored correctness for every future reader.
|
|
150
109
|
*/
|
|
151
110
|
async invalidate() {
|
|
152
111
|
await bumpResourceGeneration(this.root, RESOURCE, { mustSucceed: true });
|
|
153
112
|
try {
|
|
154
|
-
// A scan already in flight
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
// self-describes as stale either way — then run a fresh scan.
|
|
113
|
+
// A scan already in flight captured the PRE-bump token and possibly
|
|
114
|
+
// pre-mutation state; joining it via regenerate()'s dedup would skip the
|
|
115
|
+
// eager post-bump scan this method exists for. Let it drain — its
|
|
116
|
+
// snapshot self-describes as stale either way — then scan fresh.
|
|
159
117
|
if (this.regenInFlight)
|
|
160
118
|
await this.regenInFlight.catch(() => { });
|
|
161
119
|
await this.regenerate();
|
|
@@ -169,9 +127,8 @@ export class BranchRegistry {
|
|
|
169
127
|
/**
|
|
170
128
|
* Scans branch directories and rebuilds the cache, deduping concurrent
|
|
171
129
|
* callers on this instance to a single underlying scan. Never loops waiting
|
|
172
|
-
* for the
|
|
173
|
-
* storm
|
|
174
|
-
* after a concurrent bump should call list() again after this resolves.
|
|
130
|
+
* for the embedded token to match the marker — that livelocks under a bump
|
|
131
|
+
* storm; a caller wanting the very latest state calls list() again.
|
|
175
132
|
*/
|
|
176
133
|
async regenerate() {
|
|
177
134
|
if (this.regenInFlight)
|
|
@@ -191,16 +148,13 @@ export class BranchRegistry {
|
|
|
191
148
|
// next probe instead of silently resurrecting stale data.
|
|
192
149
|
const read = await readResourceGeneration(this.root, RESOURCE);
|
|
193
150
|
const branches = await this.scanBranchDirectories();
|
|
194
|
-
// Opportunistic cleanup of
|
|
195
|
-
// invalidation scheme (e.g. a process upgraded mid-flight). Not load-bearing.
|
|
151
|
+
// Opportunistic cleanup of the retired stale-marker file. Not load-bearing.
|
|
196
152
|
await fs.unlink(this.stalePath).catch(() => { });
|
|
197
153
|
if (!read.ok) {
|
|
198
|
-
// The marker
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
// the fresh scan result without persisting it; the next read retries
|
|
203
|
-
// the marker read and, on success, regenerates and persists normally.
|
|
154
|
+
// The marker read failed for a reason other than "never bumped", so no
|
|
155
|
+
// token can be attributed to this scan, and a snapshot stamped with an
|
|
156
|
+
// unattributable one would look correctly attributed to every future
|
|
157
|
+
// reader on any host. Serve the fresh scan without persisting it.
|
|
204
158
|
return branches;
|
|
205
159
|
}
|
|
206
160
|
const snapshot = {
|
|
@@ -208,8 +162,8 @@ export class BranchRegistry {
|
|
|
208
162
|
branches,
|
|
209
163
|
generation: read.token,
|
|
210
164
|
};
|
|
211
|
-
//
|
|
212
|
-
//
|
|
165
|
+
// Temp file then atomic rename; the random suffix keeps concurrent
|
|
166
|
+
// regenerations off each other's temp path.
|
|
213
167
|
const uniqueTempPath = `${this.tempPath}.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
214
168
|
await fs.mkdir(this.root, { recursive: true });
|
|
215
169
|
await fs.writeFile(uniqueTempPath, JSON.stringify(snapshot, null, 2) + '\n', 'utf8');
|
|
@@ -217,7 +171,6 @@ export class BranchRegistry {
|
|
|
217
171
|
await fs.rename(uniqueTempPath, this.registryPath);
|
|
218
172
|
}
|
|
219
173
|
catch (err) {
|
|
220
|
-
// Clean up temp file if rename fails
|
|
221
174
|
await fs.unlink(uniqueTempPath).catch(() => { });
|
|
222
175
|
throw err;
|
|
223
176
|
}
|
|
@@ -238,11 +191,10 @@ export class BranchRegistry {
|
|
|
238
191
|
continue;
|
|
239
192
|
}
|
|
240
193
|
const branchRoot = path.join(this.root, entry.name);
|
|
241
|
-
// Quarantine, don't propagate: one branch's corrupt
|
|
242
|
-
// branch.json must not take down the whole listing
|
|
243
|
-
// would 500 GET /branches for every branch). The broken branch
|
|
244
|
-
// drops out of the registry
|
|
245
|
-
// branch-health surface to report and repair.
|
|
194
|
+
// Quarantine, don't propagate: one branch's corrupt or unreadable
|
|
195
|
+
// branch.json must not take down the whole listing, which a rethrow
|
|
196
|
+
// would (500 on GET /branches, for every branch). The broken branch
|
|
197
|
+
// drops out of the registry and stays on disk for branch-health.
|
|
246
198
|
let meta;
|
|
247
199
|
try {
|
|
248
200
|
meta = await readBranchMetadataFile(branchRoot);
|
|
@@ -261,7 +213,6 @@ export class BranchRegistry {
|
|
|
261
213
|
}
|
|
262
214
|
}
|
|
263
215
|
catch (err) {
|
|
264
|
-
// If root doesn't exist yet, return empty list
|
|
265
216
|
if (isNotFoundError(err)) {
|
|
266
217
|
return [];
|
|
267
218
|
}
|
|
@@ -4,92 +4,32 @@ import type { OperatingMode } from './operating-mode/index.js';
|
|
|
4
4
|
import type { EntrySchemaRegistry, SchemaResolutionResult } from './schema/types.js';
|
|
5
5
|
/** resource-generation.ts resource key for the schema cache's marker. */
|
|
6
6
|
export declare const SCHEMA_GENERATION_RESOURCE = "schema";
|
|
7
|
-
/**
|
|
8
|
-
* Schema cache structure stored in {branchRoot}/.canopy-meta/schema-cache.json
|
|
9
|
-
*/
|
|
7
|
+
/** @internal Exported for tests. */
|
|
10
8
|
export interface BranchSchemaCacheEntry {
|
|
11
9
|
version: number;
|
|
12
10
|
schema: RootCollectionConfig;
|
|
13
11
|
flatSchema: FlatSchemaItem[];
|
|
14
12
|
cachedAt: string;
|
|
15
13
|
/**
|
|
16
|
-
* The
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* decide freshness. See the class doc comment.
|
|
14
|
+
* The marker token this snapshot was resolved against, or null when it was
|
|
15
|
+
* built before any bump on this root. Compared against the live marker (via
|
|
16
|
+
* isGenerationCurrent) to decide freshness.
|
|
20
17
|
*/
|
|
21
18
|
generation: string | null;
|
|
22
19
|
}
|
|
23
20
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* ## Cross-process freshness (resource-generation.ts marker protocol)
|
|
28
|
-
*
|
|
29
|
-
* Several warm Lambda containers plus the EC2 worker can share one
|
|
30
|
-
* branch-clone root over EFS, each with its own copy of
|
|
31
|
-
* `schema-cache.json`. There is no shared memory and no cross-host file
|
|
32
|
-
* watching, so freshness is coordinated via the generic on-disk generation
|
|
33
|
-
* marker in resource-generation.ts: every cached snapshot embeds the marker
|
|
34
|
-
* token it was resolved against, and every read cheaply re-checks the live
|
|
35
|
-
* marker before trusting the cache. See that module's doc comment for the
|
|
36
|
-
* full protocol and residual staleness windows (A/B/C/E).
|
|
37
|
-
*
|
|
38
|
-
* BranchSchemaCache is the "durable snapshot consumer" case called out there:
|
|
39
|
-
* a resolve whose scan is served from stale NFS dentry/attribute caches can
|
|
40
|
-
* record a FRESH token over STALE data (window E), and because the result is
|
|
41
|
-
* written to `schema-cache.json`, that staleness becomes durable and shared
|
|
42
|
-
* with every other host that reads the marker - not just one process's
|
|
43
|
-
* memory. `loadFromCacheOrResolve` mitigates this the same way
|
|
44
|
-
* BranchRegistry does:
|
|
45
|
-
*
|
|
46
|
-
* - The marker is captured strictly BEFORE `resolveFresh()` runs, and the
|
|
47
|
-
* captured token (not one read after resolving) is what gets embedded in
|
|
48
|
-
* the persisted snapshot. A bump landing mid-resolve therefore leaves the
|
|
49
|
-
* embedded token older than the live marker, forcing a re-resolve on the
|
|
50
|
-
* next read instead of silently resurrecting stale schema.
|
|
51
|
-
* - A snapshot is only persisted when the marker read itself succeeded
|
|
52
|
-
* (`{ ok: true }`). If the read fails for a reason other than "never
|
|
53
|
-
* bumped", we cannot attribute a token to this resolve, and stamping the
|
|
54
|
-
* snapshot with an unattributable token would make it indistinguishable
|
|
55
|
-
* from a correctly-attributed one to every future reader. The fresh result
|
|
56
|
-
* is still served to this caller; it just isn't written durably.
|
|
57
|
-
* - invalidate() bumps the marker with `mustSucceed: true`: an explicit
|
|
58
|
-
* invalidation (e.g. after a schema mutation) must not silently fail and
|
|
59
|
-
* leave every reader confidently stale with no bounding backstop.
|
|
60
|
-
* invalidate() itself does NOT eager-regenerate - it isn't given the
|
|
61
|
-
* entrySchemaRegistry/contentRootName that resolveSchema needs. The
|
|
62
|
-
* eager re-resolve (window-E mitigation, mirroring BranchRegistry's
|
|
63
|
-
* eager regen) lives one level up in SchemaOps.invalidateSchemaCache()
|
|
64
|
-
* (schema/schema-store.ts), which has those arguments and calls
|
|
65
|
-
* {@link resolveAndPersist} (NOT getSchema()) right after invalidating -
|
|
66
|
-
* so every SchemaOps mutation re-resolves on the mutating host via a scan
|
|
67
|
-
* that is GUARANTEED to run, not merely likely to run. getSchema() would
|
|
68
|
-
* be the wrong call here: its cache-read fast path can short-circuit
|
|
69
|
-
* through a snapshot a DIFFERENT concurrent host just wrote (see
|
|
70
|
-
* resolveAndPersist()'s doc comment for the exact race), silently
|
|
71
|
-
* skipping the one scan this eager re-resolve exists to guarantee. (The
|
|
72
|
-
* editor's follow-up schema GET is a separate Lambda invocation with no
|
|
73
|
-
* container affinity, so it could not serve this purpose either.)
|
|
74
|
-
* Callers of invalidate() that bypass SchemaOps (api/schema.ts's explicit
|
|
75
|
-
* invalidate endpoint; the bulk-mutation bump in
|
|
76
|
-
* invalidateBranchContentCaches) accept the lazy next-read regen.
|
|
77
|
-
*
|
|
78
|
-
* This is also why prod needs no mtime walk: the dev-only mtime check below
|
|
79
|
-
* exists solely to catch hand edits to .collection.json made outside the CMS
|
|
80
|
-
* (which bypass SchemaOps and therefore never bump the marker). Every
|
|
81
|
-
* mutation path that matters in prod - SchemaOps writes, git working-tree
|
|
82
|
-
* rewrites (checkout/merge/rebase/sync/migrate) - bumps the marker via
|
|
83
|
-
* SchemaOps.invalidateSchemaCache() or the combined
|
|
84
|
-
* invalidateBranchContentCaches() helper in content-index-generation.ts, so
|
|
85
|
-
* the marker alone is a sufficient prod backstop.
|
|
21
|
+
* Per-branch schema cache: a file at {branchRoot}/.canopy-meta/schema-cache.json
|
|
22
|
+
* with no in-memory layer, so it stays coherent across Lambda invocations.
|
|
86
23
|
*
|
|
87
|
-
*
|
|
88
|
-
* -
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
24
|
+
* Freshness follows the generation-marker protocol owned by
|
|
25
|
+
* resource-generation.ts, and this is one of that protocol's durable-snapshot
|
|
26
|
+
* consumers. Its eager re-resolve lives one level up, in
|
|
27
|
+
* `SchemaOps.invalidateSchemaCache()` (schema/schema-store.ts), because that is
|
|
28
|
+
* where the entrySchemaRegistry/contentRootName arguments {@link invalidate}
|
|
29
|
+
* lacks are available; it calls {@link resolveAndPersist}, never getSchema().
|
|
30
|
+
* Callers that bypass SchemaOps (api/schema.ts's invalidate endpoint, and the
|
|
31
|
+
* bulk git-op bump in invalidateBranchContentCaches) accept the lazy
|
|
32
|
+
* next-read regen instead.
|
|
93
33
|
*/
|
|
94
34
|
export declare class BranchSchemaCache {
|
|
95
35
|
/** Tracks when we last checked mtimes per contentRoot, to debounce rapid requests */
|
|
@@ -99,35 +39,23 @@ export declare class BranchSchemaCache {
|
|
|
99
39
|
/**
|
|
100
40
|
* Whether to skip the on-disk cache for this branchRoot.
|
|
101
41
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* the project root, regardless of which entrypoint produced the cwd branchRoot.
|
|
42
|
+
* Never write `.canopy-meta/` at the project root, whichever entrypoint
|
|
43
|
+
* produced the cwd branchRoot. branchRoot equals process.cwd() only in the
|
|
44
|
+
* synthetic contexts static deployments and build phases use; a real branch
|
|
45
|
+
* root is always nested under the workspace.
|
|
107
46
|
*/
|
|
108
47
|
private skipDiskCache;
|
|
109
|
-
/**
|
|
110
|
-
* Get schema for a branch (loads from cache or resolves fresh).
|
|
111
|
-
*
|
|
112
|
-
* @param branchRoot - Root directory of the branch (e.g., .canopy-dev/content-branches/main)
|
|
113
|
-
* @param entrySchemaRegistry - Map of schema names to field definitions
|
|
114
|
-
* @param contentRootName - Name of content directory (e.g., "content") from config
|
|
115
|
-
* @returns Resolved schema tree and flattened schema
|
|
116
|
-
*/
|
|
48
|
+
/** Get schema for a branch, from the cache when fresh, else resolved fresh. */
|
|
117
49
|
getSchema(branchRoot: string, entrySchemaRegistry: EntrySchemaRegistry, contentRootName?: string): Promise<{
|
|
118
50
|
schema: RootCollectionConfig;
|
|
119
51
|
flatSchema: FlatSchemaItem[];
|
|
120
52
|
}>;
|
|
121
53
|
/**
|
|
122
|
-
* Resolve the schema from disk.
|
|
123
|
-
*
|
|
124
|
-
* override with a deferred/blocking implementation to simulate cross-process
|
|
54
|
+
* Resolve the schema from disk. Protected rather than a direct resolveSchema
|
|
55
|
+
* call so tests can subclass and block it to simulate cross-process
|
|
125
56
|
* interleavings — mirrors BranchRegistry's scanBranchDirectories() hook.
|
|
126
57
|
*/
|
|
127
58
|
protected resolveFresh(contentRoot: string, entrySchemaRegistry: EntrySchemaRegistry): Promise<SchemaResolutionResult>;
|
|
128
|
-
/**
|
|
129
|
-
* Load schema from cache or resolve fresh if cache is missing or stale.
|
|
130
|
-
*/
|
|
131
59
|
private loadFromCacheOrResolve;
|
|
132
60
|
/**
|
|
133
61
|
* Resolve the schema fresh from disk and persist it (subject to the
|
|
@@ -137,43 +65,25 @@ export declare class BranchSchemaCache {
|
|
|
137
65
|
*/
|
|
138
66
|
private resolveFreshAndPersist;
|
|
139
67
|
/**
|
|
140
|
-
* Resolve
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* `getSchema()` call right after `invalidate()` is NOT that guarantee --
|
|
148
|
-
* `getSchema()`'s cache-read fast path (`loadFromCacheOrResolve`) can still
|
|
149
|
-
* return a snapshot written by a DIFFERENT, concurrent host: if that
|
|
150
|
-
* foreign host's own eager re-resolve raced this one and embedded the
|
|
151
|
-
* (now-current) marker token over ITS OWN stale-NFS-cache scan (the
|
|
152
|
-
* window-E case this class's doc comment describes), this host's
|
|
153
|
-
* `getSchema()` would happily accept that foreign snapshot as "current"
|
|
154
|
-
* and skip the one scan this call was specifically trying to guarantee.
|
|
155
|
-
* `resolveAndPersist()` never reads the cache file at all, so it cannot be
|
|
156
|
-
* short-circuited that way.
|
|
68
|
+
* Resolve fresh from disk and persist, SKIPPING the cache read entirely.
|
|
69
|
+
* That is what makes it, and not {@link getSchema}, the right call for the
|
|
70
|
+
* eager re-resolve in `SchemaOps.invalidateSchemaCache()` (its sole intended
|
|
71
|
+
* caller): an eager re-resolve exists to guarantee ONE scan coherent with the
|
|
72
|
+
* mutation this host just made, and getSchema()'s cache-read fast path can
|
|
73
|
+
* instead return a snapshot a concurrent host wrote — possibly one embedding
|
|
74
|
+
* the now-current token over ITS own stale-NFS scan — skipping that scan.
|
|
157
75
|
*/
|
|
158
76
|
resolveAndPersist(branchRoot: string, entrySchemaRegistry: EntrySchemaRegistry, contentRootName?: string): Promise<{
|
|
159
77
|
schema: RootCollectionConfig;
|
|
160
78
|
flatSchema: FlatSchemaItem[];
|
|
161
79
|
}>;
|
|
162
80
|
/**
|
|
163
|
-
* Invalidate
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
* The bump must succeed: a swallowed failure here would leave the schema
|
|
168
|
-
* cache stale indefinitely with no bounding backstop (unlike
|
|
169
|
-
* BranchRegistry, there is no get-miss backstop for a resolved schema).
|
|
170
|
-
*
|
|
171
|
-
* No eager regeneration here (unlike BranchRegistry.invalidate()): this
|
|
172
|
-
* method isn't given the entrySchemaRegistry/contentRootName resolveSchema
|
|
173
|
-
* needs. See the class doc comment for why the mutating request's own
|
|
174
|
-
* follow-up schema read closes the same window-E gap instead.
|
|
81
|
+
* Invalidate a branch's cache by bumping the marker; every process sharing
|
|
82
|
+
* this branchRoot re-resolves at its next read. The bump must succeed —
|
|
83
|
+
* swallowing that failure leaves the schema cache stale indefinitely, and
|
|
84
|
+
* unlike BranchRegistry there is no get-miss backstop for a resolved schema.
|
|
175
85
|
*
|
|
176
|
-
*
|
|
86
|
+
* No eager re-resolve here; it lives in SchemaOps (see the class doc).
|
|
177
87
|
*/
|
|
178
88
|
invalidate(branchRoot: string): Promise<void>;
|
|
179
89
|
}
|