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/assets/factory.js
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* Instantiate the configured AssetStore from a site's `media` config.
|
|
3
3
|
*
|
|
4
4
|
* This is the one place that turns the (currently-unconsumed) `media` config
|
|
5
|
-
* into a real store — see .claude/future-tasks/assets-media-system.md
|
|
6
|
-
* this was previously dead configuration.
|
|
5
|
+
* into a real store — see .claude/future-tasks/resolved/assets-media-system.md.
|
|
7
6
|
*/
|
|
8
7
|
import { LocalAssetStore } from './store-local.js';
|
|
9
8
|
import { S3AssetStore } from './store-s3.js';
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { type FinalizeInput, type FinalizeRejection } from './pipeline.js';
|
|
7
7
|
import type { AssetMeta, AssetStore } from './types.js';
|
|
8
|
+
/** @internal Exported for tests. */
|
|
8
9
|
export declare function isValidStagingKey(key: string): boolean;
|
|
9
10
|
export type FinalizeAssetResult = {
|
|
10
11
|
ok: true;
|
|
@@ -20,10 +21,11 @@ export type FinalizeAssetResult = {
|
|
|
20
21
|
* point for an asset's existence, so a crash between `putOriginal` and here
|
|
21
22
|
* leaves only orphaned (harmless, content-addressed) blobs, never a meta
|
|
22
23
|
* record pointing at a missing blob.
|
|
24
|
+
* @internal Exported for tests.
|
|
23
25
|
*/
|
|
24
26
|
export declare function finalizeAsset(store: AssetStore, input: FinalizeInput): Promise<FinalizeAssetResult>;
|
|
25
27
|
/**
|
|
26
|
-
* Finalize a
|
|
28
|
+
* Finalize a staged upload: read the staged bytes, run
|
|
27
29
|
* `finalizeAsset`, and best-effort delete the staging object regardless of
|
|
28
30
|
* outcome (success OR pipeline rejection - a rejected upload's staged bytes
|
|
29
31
|
* are just as much litter as an accepted one's).
|
package/dist/assets/finalize.js
CHANGED
|
@@ -14,6 +14,7 @@ import { ASSET_PREFIXES } from './keys.js';
|
|
|
14
14
|
* prefixes must parameterize this check if that escape hatch is ever used.
|
|
15
15
|
*/
|
|
16
16
|
const STAGING_UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
17
|
+
/** @internal Exported for tests. */
|
|
17
18
|
export function isValidStagingKey(key) {
|
|
18
19
|
const prefix = `${ASSET_PREFIXES.staging}/`;
|
|
19
20
|
return key.startsWith(prefix) && STAGING_UUID_PATTERN.test(key.slice(prefix.length));
|
|
@@ -28,6 +29,7 @@ export function isValidStagingKey(key) {
|
|
|
28
29
|
* point for an asset's existence, so a crash between `putOriginal` and here
|
|
29
30
|
* leaves only orphaned (harmless, content-addressed) blobs, never a meta
|
|
30
31
|
* record pointing at a missing blob.
|
|
32
|
+
* @internal Exported for tests.
|
|
31
33
|
*/
|
|
32
34
|
export async function finalizeAsset(store, input) {
|
|
33
35
|
const result = await runFinalizePipeline(input);
|
|
@@ -52,7 +54,7 @@ export async function finalizeAsset(store, input) {
|
|
|
52
54
|
return { ok: true, meta };
|
|
53
55
|
}
|
|
54
56
|
/**
|
|
55
|
-
* Finalize a
|
|
57
|
+
* Finalize a staged upload: read the staged bytes, run
|
|
56
58
|
* `finalizeAsset`, and best-effort delete the staging object regardless of
|
|
57
59
|
* outcome (success OR pipeline rejection - a rejected upload's staged bytes
|
|
58
60
|
* are just as much litter as an accepted one's).
|
package/dist/assets/index.d.ts
CHANGED
|
@@ -10,10 +10,10 @@ export { ASSET_PREFIXES, createKeyBuilders, hashBytes, metaKey, metaPrefix, orig
|
|
|
10
10
|
export { LocalAssetStore, type LocalAssetStoreOptions } from './store-local.js';
|
|
11
11
|
export { S3AssetStore, type S3AssetStoreOptions } from './store-s3.js';
|
|
12
12
|
export { createAssetStore } from './factory.js';
|
|
13
|
-
export { ALLOWED_UPLOAD_CONTENT_TYPES, runFinalizePipeline, type FinalizeInput, type
|
|
13
|
+
export { ALLOWED_UPLOAD_CONTENT_TYPES, runFinalizePipeline, type FinalizeInput, type FinalizeResult, type FinalizeRejection, } from './pipeline.js';
|
|
14
14
|
export { finalizeAsset, finalizeStagedUpload, type FinalizeAssetResult } from './finalize.js';
|
|
15
15
|
export { sanitizeSvg } from './svg-sanitizer.js';
|
|
16
|
-
export { assetSrc
|
|
17
|
-
export { formatDirectives, isAllowedTransformWidth, isValidCropRect, parseTransformPath, type CropRect, type
|
|
16
|
+
export { assetSrc } from './asset-src.js';
|
|
17
|
+
export { formatDirectives, isAllowedTransformWidth, isValidCropRect, parseTransformPath, type CropRect, type OutputFormat, type ParsedTransformPath, type ParseTransformPathResult, type TransformDirectives, } from './transform-directives.js';
|
|
18
18
|
export { applyTransform, type ApplyTransformInput, type TransformResult } from './transform.js';
|
|
19
19
|
export { assetUrl, assetSrcSet, type AssetRef, type AssetUrlOptions } from './asset-url.js';
|
package/dist/assets/index.js
CHANGED
|
@@ -12,7 +12,7 @@ export { createAssetStore } from './factory.js';
|
|
|
12
12
|
export { ALLOWED_UPLOAD_CONTENT_TYPES, runFinalizePipeline, } from './pipeline.js';
|
|
13
13
|
export { finalizeAsset, finalizeStagedUpload } from './finalize.js';
|
|
14
14
|
export { sanitizeSvg } from './svg-sanitizer.js';
|
|
15
|
-
export { assetSrc
|
|
15
|
+
export { assetSrc } from './asset-src.js';
|
|
16
16
|
export { formatDirectives, isAllowedTransformWidth, isValidCropRect, parseTransformPath, } from './transform-directives.js';
|
|
17
17
|
export { applyTransform } from './transform.js';
|
|
18
18
|
export { assetUrl, assetSrcSet } from './asset-url.js';
|
package/dist/assets/keys.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* here — keeps this file trivially unit-testable and safe to reason about for
|
|
4
4
|
* path-traversal / header-injection concerns.
|
|
5
5
|
*
|
|
6
|
-
* Bucket-prefix layout (see .claude/future-tasks/assets-media-system.md):
|
|
6
|
+
* Bucket-prefix layout (see .claude/future-tasks/resolved/assets-media-system.md):
|
|
7
7
|
* asset-originals/{hash32}.{ext} private; full-fidelity originals
|
|
8
8
|
* asset-staging/{uuid} presigned-POST target
|
|
9
9
|
* asset-meta/{hash32}.json private; filename/uploader/dims/mime
|
|
@@ -45,11 +45,13 @@ export declare function slugifyFilename(name: string): {
|
|
|
45
45
|
*/
|
|
46
46
|
export declare function createKeyBuilders(prefixes?: AssetPrefixes): {
|
|
47
47
|
originalKey: (hash32: string, ext: string) => string;
|
|
48
|
-
/** Prefix
|
|
48
|
+
/** Prefix for looking up an original by hash32 alone (extension unknown ahead of time). */
|
|
49
49
|
originalPrefix: (hash32: string) => string;
|
|
50
50
|
stagingKey: (uuid: string) => string;
|
|
51
51
|
metaKey: (hash32: string) => string;
|
|
52
52
|
metaPrefix: () => string;
|
|
53
53
|
publicKey: (hash32: string, slug: string, ext: string) => string;
|
|
54
54
|
};
|
|
55
|
-
export declare const originalKey: (hash32: string, ext: string) => string,
|
|
55
|
+
export declare const originalKey: (hash32: string, ext: string) => string, stagingKey: (uuid: string) => string, metaKey: (hash32: string) => string, publicKey: (hash32: string, slug: string, ext: string) => string;
|
|
56
|
+
/** @internal Exported for tests. */
|
|
57
|
+
export declare const originalPrefix: (hash32: string) => string, metaPrefix: () => string;
|
package/dist/assets/keys.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* here — keeps this file trivially unit-testable and safe to reason about for
|
|
4
4
|
* path-traversal / header-injection concerns.
|
|
5
5
|
*
|
|
6
|
-
* Bucket-prefix layout (see .claude/future-tasks/assets-media-system.md):
|
|
6
|
+
* Bucket-prefix layout (see .claude/future-tasks/resolved/assets-media-system.md):
|
|
7
7
|
* asset-originals/{hash32}.{ext} private; full-fidelity originals
|
|
8
8
|
* asset-staging/{uuid} presigned-POST target
|
|
9
9
|
* asset-meta/{hash32}.json private; filename/uploader/dims/mime
|
|
@@ -76,7 +76,7 @@ export function slugifyFilename(name) {
|
|
|
76
76
|
export function createKeyBuilders(prefixes = ASSET_PREFIXES) {
|
|
77
77
|
return {
|
|
78
78
|
originalKey: (hash32, ext) => `${prefixes.originals}/${hash32}.${ext}`,
|
|
79
|
-
/** Prefix
|
|
79
|
+
/** Prefix for looking up an original by hash32 alone (extension unknown ahead of time). */
|
|
80
80
|
originalPrefix: (hash32) => `${prefixes.originals}/${hash32}.`,
|
|
81
81
|
stagingKey: (uuid) => `${prefixes.staging}/${uuid}`,
|
|
82
82
|
metaKey: (hash32) => `${prefixes.meta}/${hash32}.json`,
|
|
@@ -84,4 +84,7 @@ export function createKeyBuilders(prefixes = ASSET_PREFIXES) {
|
|
|
84
84
|
publicKey: (hash32, slug, ext) => `${prefixes.public}/${hash32}/${slug}.${ext}`,
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
const keyBuilders = createKeyBuilders();
|
|
88
|
+
export const { originalKey, stagingKey, metaKey, publicKey } = keyBuilders;
|
|
89
|
+
/** @internal Exported for tests. */
|
|
90
|
+
export const { originalPrefix, metaPrefix } = keyBuilders;
|
|
@@ -19,14 +19,14 @@ export interface FinalizeInput {
|
|
|
19
19
|
filename: string;
|
|
20
20
|
uploadedBy?: string;
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
interface FinalizePublicObject {
|
|
23
23
|
key: string;
|
|
24
24
|
data: Uint8Array;
|
|
25
25
|
contentType: string;
|
|
26
26
|
contentDisposition: string;
|
|
27
27
|
cacheControl: string;
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
interface FinalizeSuccess {
|
|
30
30
|
ok: true;
|
|
31
31
|
meta: AssetMeta;
|
|
32
32
|
/** Canonical bytes to persist as the original - sanitized bytes for svg, untouched otherwise. */
|
|
@@ -57,3 +57,4 @@ export type FinalizeResult = FinalizeSuccess | FinalizeRejection;
|
|
|
57
57
|
* stricter sanitizer version) cannot desync a stored hash from its content.
|
|
58
58
|
*/
|
|
59
59
|
export declare function runFinalizePipeline(input: FinalizeInput): Promise<FinalizeResult>;
|
|
60
|
+
export {};
|
package/dist/assets/pipeline.js
CHANGED
|
@@ -114,67 +114,33 @@ const DECODE_CHECK_SIZE = 8;
|
|
|
114
114
|
*/
|
|
115
115
|
const UNDECODABLE_RASTER_ERROR = 'This image could not be decoded - it may be corrupt or truncated. Try re-exporting it and uploading again.';
|
|
116
116
|
/**
|
|
117
|
-
* Force a
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* transform engine's real sharp/libvips decoder (transform.ts's
|
|
122
|
-
* `applyTransform`) later refuses - with a raw "vipspng: libpng read error"
|
|
123
|
-
* - by which point the asset has already "uploaded successfully" and renders
|
|
124
|
-
* broken everywhere it's shown. This makes finalize use the same decoder
|
|
125
|
-
* transform.ts does, before the bytes are ever persisted, instead of only
|
|
126
|
-
* discovering the mismatch at render time.
|
|
117
|
+
* Force a real pixel decode of a raster upload: `computeDimensions` above is header-only, so
|
|
118
|
+
* a corrupt PNG IDAT / truncated JPEG scan with a valid IHDR/SOF passes it, then fails at
|
|
119
|
+
* transform.ts's real sharp/libvips decode later - "uploads fine, renders broken". This runs
|
|
120
|
+
* the same decoder before the bytes are ever persisted, not just at render time.
|
|
127
121
|
*
|
|
128
|
-
* `.resize()` to a tiny output
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* this class of bug. libvips cannot compute a resized pixel buffer without
|
|
132
|
-
* fully decoding the source, so a corrupt IDAT/scan still throws here even
|
|
133
|
-
* though it would not throw from a header-only read. The output itself is
|
|
134
|
-
* immediately discarded - decode is the expensive, unavoidable part of this
|
|
135
|
-
* check; encoding an 8x8 buffer is not.
|
|
122
|
+
* `.resize()` to a tiny output, not `.metadata()`: libvips cannot compute a resized pixel
|
|
123
|
+
* buffer without fully decoding the source, so a corrupt IDAT/scan throws here even though a
|
|
124
|
+
* header-only read would not. The 8x8 output is discarded; decode is the expensive part.
|
|
136
125
|
*
|
|
137
|
-
* ANIMATION: sharp defaults to `pages: 1
|
|
138
|
-
*
|
|
139
|
-
* `min(totalPages, MAX_ANIMATED_FRAMES)`
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* count is probed and passed through, with the SAME cap constant transform.ts
|
|
145
|
-
* uses (both import it from transform-directives.ts) - which also means the
|
|
146
|
-
* two sides ignore the same frames past the cap, so a many-hundred-frame
|
|
147
|
-
* source cannot produce a disagreement either.
|
|
126
|
+
* ANIMATION: sharp defaults to `pages: 1` (frame 0 only), which is not enough to mirror
|
|
127
|
+
* `applyTransform`, so the real page count is probed first and read as
|
|
128
|
+
* `min(totalPages, MAX_ANIMATED_FRAMES)` - the SAME cap constant transform.ts uses (both
|
|
129
|
+
* import it from transform-directives.ts), so the two decoders never disagree on which
|
|
130
|
+
* frames past the cap they ignore. The probe is required, not optional: `pages` is a fixed
|
|
131
|
+
* request, not an upper bound, and a value exceeding the source's real page count makes sharp
|
|
132
|
+
* throw "bad page number" (transform.ts documents the same constraint at its call site).
|
|
148
133
|
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* costs effectively nothing - it is a header read, not a decode.
|
|
154
|
-
*
|
|
155
|
-
* `limitInputPixels: MAX_INPUT_PIXELS` reuses transform.ts's own
|
|
156
|
-
* decompression-bomb cap (imported above, not redefined) so this validation
|
|
157
|
-
* step cannot itself become a bomb vector on a header that lied about its
|
|
158
|
-
* dimensions - in practice the pixel-count check in the caller below already
|
|
159
|
-
* rejects those before this function is ever reached, but the cap is cheap
|
|
160
|
-
* insurance against relying on that ordering. Note the caller's check reads
|
|
161
|
-
* single-frame dimensions from `image-size`, so for animated sources it is
|
|
162
|
-
* `limitInputPixels` here (which sees the full multi-page strip) that bounds
|
|
163
|
-
* total decoded pixels - exactly as it does in transform.ts.
|
|
134
|
+
* `limitInputPixels: MAX_INPUT_PIXELS` reuses transform.ts's own decompression-bomb cap so
|
|
135
|
+
* this validation step cannot itself become a bomb vector. The caller's own pixel-count check
|
|
136
|
+
* (below) already rejects oversized single-frame dims from `image-size` before this runs, but
|
|
137
|
+
* for animated sources only this multi-page `limitInputPixels` bounds total decoded pixels.
|
|
164
138
|
*
|
|
165
139
|
* Fails OPEN vs. fails CLOSED, deliberately different failure modes:
|
|
166
|
-
* - sharp
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* unvalidated (the pre-fix behavior) rather than failing every raster
|
|
171
|
-
* upload because of a deployment issue.
|
|
172
|
-
* - sharp loads fine but its decoder REJECTS the bytes - that IS a fact
|
|
173
|
-
* about this specific file, and an actionable one. Return false so the
|
|
174
|
-
* caller rejects the upload. A throw from the page-count probe counts as
|
|
175
|
-
* this case, not the one above: the module loaded, so an unreadable header
|
|
176
|
-
* is again a fact about the file, and `applyTransform` would reject the
|
|
177
|
-
* same bytes from its own probe with the same 422.
|
|
140
|
+
* - sharp cannot be loaded at all (missing/wrong-arch native binary) - an environment
|
|
141
|
+
* problem, not a fact about the file. Log it and let the upload through unvalidated.
|
|
142
|
+
* - sharp loads but its decoder REJECTS the bytes (including a page-count-probe throw) -
|
|
143
|
+
* that IS a fact about this file. Return false so the caller rejects the upload.
|
|
178
144
|
*/
|
|
179
145
|
async function rasterIsDecodable(data) {
|
|
180
146
|
// `loadSharp()` has already logged the load failure once for the process;
|
|
@@ -6,16 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Why lazily. sharp is a native addon, and loading it dlopens libvips. A
|
|
8
8
|
* static `import sharp from 'sharp'` makes importing the MODULE GRAPH load
|
|
9
|
-
* libvips.
|
|
10
|
-
*
|
|
11
|
-
* evaluated (cms-image-build-epic.md in `.claude/future-tasks/`, "Every route
|
|
12
|
-
* loads sharp"). transform.ts is reachable from `canopycms/server` and, through
|
|
13
|
-
* api/assets.ts, from `canopycms/http` and so from `canopycms-next`, which a
|
|
14
|
-
* host app's root layout can import (that adopter's did). When the libvips
|
|
15
|
-
* `.so` was missing from its standalone output, that one static import turned
|
|
16
|
-
* it into a 500 on every on-demand route, 404s included, and defeated
|
|
17
|
-
* pipeline.ts's deliberate fail-open. Loaded on first use, a missing binary
|
|
18
|
-
* affects only the image operations that need it.
|
|
9
|
+
* libvips. Loaded on first use, a missing binary affects only the image
|
|
10
|
+
* operations that need it.
|
|
19
11
|
*
|
|
20
12
|
* Memoized INCLUDING a rejection: a failed dlopen does not heal inside a
|
|
21
13
|
* running process, so a retry would only pay for the failure again and log
|
|
@@ -6,16 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Why lazily. sharp is a native addon, and loading it dlopens libvips. A
|
|
8
8
|
* static `import sharp from 'sharp'` makes importing the MODULE GRAPH load
|
|
9
|
-
* libvips.
|
|
10
|
-
*
|
|
11
|
-
* evaluated (cms-image-build-epic.md in `.claude/future-tasks/`, "Every route
|
|
12
|
-
* loads sharp"). transform.ts is reachable from `canopycms/server` and, through
|
|
13
|
-
* api/assets.ts, from `canopycms/http` and so from `canopycms-next`, which a
|
|
14
|
-
* host app's root layout can import (that adopter's did). When the libvips
|
|
15
|
-
* `.so` was missing from its standalone output, that one static import turned
|
|
16
|
-
* it into a 500 on every on-demand route, 404s included, and defeated
|
|
17
|
-
* pipeline.ts's deliberate fail-open. Loaded on first use, a missing binary
|
|
18
|
-
* affects only the image operations that need it.
|
|
9
|
+
* libvips. Loaded on first use, a missing binary affects only the image
|
|
10
|
+
* operations that need it.
|
|
19
11
|
*
|
|
20
12
|
* Memoized INCLUDING a rejection: a failed dlopen does not heal inside a
|
|
21
13
|
* running process, so a retry would only pay for the failure again and log
|
|
@@ -17,8 +17,7 @@ export declare class LocalAssetStore implements AssetStore {
|
|
|
17
17
|
/**
|
|
18
18
|
* Resolve a store key to an absolute filesystem path, guarding against
|
|
19
19
|
* escape from the root. Keys are internally generated (never taken
|
|
20
|
-
* verbatim from user input), but this guard is kept as defense-in-depth
|
|
21
|
-
* (ported from the v1 LocalAssetStore).
|
|
20
|
+
* verbatim from user input), but this guard is kept as defense-in-depth.
|
|
22
21
|
*
|
|
23
22
|
* A naive `resolved.startsWith(root)` check would let a sibling directory
|
|
24
23
|
* that merely shares the root's name as a prefix (e.g. root `.../assets`,
|
|
@@ -21,8 +21,7 @@ export class LocalAssetStore {
|
|
|
21
21
|
/**
|
|
22
22
|
* Resolve a store key to an absolute filesystem path, guarding against
|
|
23
23
|
* escape from the root. Keys are internally generated (never taken
|
|
24
|
-
* verbatim from user input), but this guard is kept as defense-in-depth
|
|
25
|
-
* (ported from the v1 LocalAssetStore).
|
|
24
|
+
* verbatim from user input), but this guard is kept as defense-in-depth.
|
|
26
25
|
*
|
|
27
26
|
* A naive `resolved.startsWith(root)` check would let a sibling directory
|
|
28
27
|
* that merely shares the root's name as a prefix (e.g. root `.../assets`,
|
|
@@ -16,10 +16,9 @@ export interface S3AssetStoreOptions {
|
|
|
16
16
|
* returns. Absolute http(s) URL or a site-relative path. See `mediaSchema`'s s3 branch for
|
|
17
17
|
* what this is for; see `isHttpUrlOrSameOriginPath` for what is accepted.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* the client inside the presign response rather than in the client config.
|
|
19
|
+
* Not a public base URL: nothing is joined onto it and it is never rendered or stored -
|
|
20
|
+
* it is the endpoint the browser posts to, returned to the client inside the presign
|
|
21
|
+
* response rather than in the client config.
|
|
23
22
|
*/
|
|
24
23
|
uploadUrl?: string;
|
|
25
24
|
/** Override the default bucket-prefix layout (rarely needed). */
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SVG sanitization. Server-only - never import from client/editor code.
|
|
3
3
|
*
|
|
4
|
-
* Sanitizer choice:
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* UNCHANGED (a `<script>`, `onload=`, and `<foreignObject>` all survived), because
|
|
11
|
-
* linkedom's window has no `NodeFilter` global and DOMPurify silently no-ops when it
|
|
12
|
-
* doesn't recognize the environment as supported. That is a dangerous failure mode
|
|
13
|
-
* for a security boundary, so this module uses `sanitize-html` instead: it works
|
|
14
|
-
* directly on the parser tree (htmlparser2, no DOM shim to be incomplete), is
|
|
15
|
-
* actively maintained, and - verified empirically - correctly strips scripts, event
|
|
16
|
-
* handler attributes, and `foreignObject` while preserving a valid, still-parseable
|
|
17
|
-
* SVG document.
|
|
4
|
+
* Sanitizer choice: `dompurify` + a DOM shim (e.g. `linkedom`) is unsafe here - DOMPurify
|
|
5
|
+
* silently returns its input unchanged when the DOM shim lacks globals it expects (linkedom
|
|
6
|
+
* has no `NodeFilter`), producing an XSS hole with no error raised. This module uses
|
|
7
|
+
* `sanitize-html` instead: it works directly on the parser tree (htmlparser2, no DOM shim to
|
|
8
|
+
* be incomplete) and strips scripts, event handler attributes, and `foreignObject` while
|
|
9
|
+
* preserving a valid, still-parseable SVG document.
|
|
18
10
|
*
|
|
19
11
|
* Allowlist-based (not blocklist): only elements/attributes known to be safe survive.
|
|
20
12
|
* `href`/`xlink:href` are further restricted to local fragment references (`#...`) so
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SVG sanitization. Server-only - never import from client/editor code.
|
|
3
3
|
*
|
|
4
|
-
* Sanitizer choice:
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* UNCHANGED (a `<script>`, `onload=`, and `<foreignObject>` all survived), because
|
|
11
|
-
* linkedom's window has no `NodeFilter` global and DOMPurify silently no-ops when it
|
|
12
|
-
* doesn't recognize the environment as supported. That is a dangerous failure mode
|
|
13
|
-
* for a security boundary, so this module uses `sanitize-html` instead: it works
|
|
14
|
-
* directly on the parser tree (htmlparser2, no DOM shim to be incomplete), is
|
|
15
|
-
* actively maintained, and - verified empirically - correctly strips scripts, event
|
|
16
|
-
* handler attributes, and `foreignObject` while preserving a valid, still-parseable
|
|
17
|
-
* SVG document.
|
|
4
|
+
* Sanitizer choice: `dompurify` + a DOM shim (e.g. `linkedom`) is unsafe here - DOMPurify
|
|
5
|
+
* silently returns its input unchanged when the DOM shim lacks globals it expects (linkedom
|
|
6
|
+
* has no `NodeFilter`), producing an XSS hole with no error raised. This module uses
|
|
7
|
+
* `sanitize-html` instead: it works directly on the parser tree (htmlparser2, no DOM shim to
|
|
8
|
+
* be incomplete) and strips scripts, event handler attributes, and `foreignObject` while
|
|
9
|
+
* preserving a valid, still-parseable SVG document.
|
|
18
10
|
*
|
|
19
11
|
* Allowlist-based (not blocklist): only elements/attributes known to be safe survive.
|
|
20
12
|
* `href`/`xlink:href` are further restricted to local fragment references (`#...`) so
|
|
@@ -32,11 +32,11 @@ export interface CropRect {
|
|
|
32
32
|
readonly h: number;
|
|
33
33
|
}
|
|
34
34
|
/** Identity ('orig'): EXIF-strip only, no resize/format/quality change. */
|
|
35
|
-
|
|
35
|
+
interface IdentityDirectives {
|
|
36
36
|
readonly identity: true;
|
|
37
37
|
}
|
|
38
38
|
/** Non-identity directive set - every field optional, but at least one is present. */
|
|
39
|
-
|
|
39
|
+
interface ResizeDirectives {
|
|
40
40
|
readonly identity: false;
|
|
41
41
|
readonly width?: number;
|
|
42
42
|
readonly format?: OutputFormat;
|
|
@@ -89,8 +89,6 @@ export declare const MAX_INPUT_PIXELS: number;
|
|
|
89
89
|
export declare const MAX_ANIMATED_FRAMES = 60;
|
|
90
90
|
/** True if `width` is on the allowlist: a multiple of 160 in [160, 4096]. */
|
|
91
91
|
export declare function isAllowedTransformWidth(width: number): boolean;
|
|
92
|
-
/** True if `quality` is on the allowlist: a multiple of 5 in [30, 95]. */
|
|
93
|
-
export declare function isAllowedTransformQuality(quality: number): boolean;
|
|
94
92
|
/**
|
|
95
93
|
* True when x, y, w, h describe a valid normalized crop rect: all four values
|
|
96
94
|
* finite and in [0,1], w and h strictly positive, and the rect fits within
|
|
@@ -112,3 +110,4 @@ export declare function parseTransformPath(segments: readonly string[]): ParseTr
|
|
|
112
110
|
* cache key. Order is fixed alphabetically by key: c, f, q, w.
|
|
113
111
|
*/
|
|
114
112
|
export declare function formatDirectives(directives: TransformDirectives): string;
|
|
113
|
+
export {};
|
|
@@ -96,7 +96,7 @@ function parseWidth(value) {
|
|
|
96
96
|
return isAllowedTransformWidth(n) ? n : null;
|
|
97
97
|
}
|
|
98
98
|
/** True if `quality` is on the allowlist: a multiple of 5 in [30, 95]. */
|
|
99
|
-
|
|
99
|
+
function isAllowedTransformQuality(quality) {
|
|
100
100
|
return (Number.isInteger(quality) &&
|
|
101
101
|
quality >= MIN_QUALITY &&
|
|
102
102
|
quality <= MAX_QUALITY &&
|
|
@@ -1,38 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The shared transform engine: applies a parsed `TransformDirectives` to
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* transform Lambda (packages/canopycms-cdk/lambda/asset-transform).
|
|
2
|
+
* The shared transform engine: applies a parsed `TransformDirectives` to source image bytes
|
|
3
|
+
* with sharp. Server-only - never import this from client/editor code (kept in its own file,
|
|
4
|
+
* separate from the dependency-free transform-directives.ts). Used by the dev-mode lazy
|
|
5
|
+
* `/assets/t/*` emulation in api/assets.ts and, unchanged, by the prod transform Lambda
|
|
6
|
+
* (packages/canopycms-cdk/lambda/asset-transform).
|
|
8
7
|
*
|
|
9
|
-
* sharp is imported for its TYPES only and loaded on first use through
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `canopycms/server` and `canopycms/http`: see sharp-loader.ts for the
|
|
13
|
-
* adopter outage a static import caused, and eslint.config.mjs for the rule
|
|
14
|
-
* that keeps it from coming back.
|
|
8
|
+
* sharp is imported for its TYPES only and loaded on first use through `loadSharp()`
|
|
9
|
+
* (sharp-loader.ts), so importing this module never loads libvips - see sharp-loader.ts for
|
|
10
|
+
* why, and eslint.config.mjs for the rule that keeps a static import from coming back.
|
|
15
11
|
*
|
|
16
|
-
* Pipeline:
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* defense #2) without exceeding it and making sharp throw -> load for real
|
|
20
|
-
* with `{ pages: min(totalPages, MAX_ANIMATED_FRAMES), limitInputPixels }` ->
|
|
21
|
-
* `.rotate()` with no args (bakes EXIF orientation into pixels,
|
|
22
|
-
* dropping the orientation tag) -> optional crop via `.extract()` -> optional
|
|
23
|
-
* `.resize({ width, withoutEnlargement: true })` (never upscales) -> encode.
|
|
12
|
+
* Pipeline: metadata probe learns the page count (decompression-bomb defenses #1/#2) -> real
|
|
13
|
+
* load capped at `min(totalPages, MAX_ANIMATED_FRAMES)` -> `.rotate()` (bakes EXIF orientation
|
|
14
|
+
* into pixels) -> optional crop/resize (never upscales) -> encode.
|
|
24
15
|
*
|
|
25
|
-
* Identity (`orig`) and any request that omits an explicit `f=` format
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* (
|
|
29
|
-
* called here, which would undo that).
|
|
16
|
+
* Identity (`orig`) and any request that omits an explicit `f=` format re-encode through the
|
|
17
|
+
* SOURCE format rather than a fixed one: this is what guarantees EXIF/GPS gets stripped even
|
|
18
|
+
* when no other change is requested (sharp strips metadata by default on re-encode -
|
|
19
|
+
* `withMetadata()` is never called here, which would undo that).
|
|
30
20
|
*
|
|
31
|
-
* GIF has no EXIF segment (EXIF is a JPEG/TIFF APP1 marker
|
|
32
|
-
*
|
|
33
|
-
* re-encoded through sharp's `.gif()` (verified: current sharp bundles cgif
|
|
34
|
-
* and re-encodes multi-frame GIFs through the `{ animated: true }` input
|
|
35
|
-
* path with no extra native dependency) purely for pipeline uniformity, not
|
|
21
|
+
* GIF has no EXIF segment (EXIF is a JPEG/TIFF APP1 marker), so an identity GIF has nothing to
|
|
22
|
+
* strip - it is still re-encoded through sharp's `.gif()` purely for pipeline uniformity, not
|
|
36
23
|
* because GIF needs stripping.
|
|
37
24
|
*/
|
|
38
25
|
import { type TransformDirectives } from './transform-directives.js';
|
|
@@ -41,12 +28,14 @@ export interface ApplyTransformInput {
|
|
|
41
28
|
/** Source extension (lowercased file-type ext, e.g. 'png' | 'jpg' | 'webp' | 'gif'). */
|
|
42
29
|
ext: string;
|
|
43
30
|
}
|
|
31
|
+
/** @internal Exported for tests. */
|
|
44
32
|
export interface TransformSuccess {
|
|
45
33
|
ok: true;
|
|
46
34
|
data: Uint8Array;
|
|
47
35
|
contentType: string;
|
|
48
36
|
ext: string;
|
|
49
37
|
}
|
|
38
|
+
/** @internal Exported for tests. */
|
|
50
39
|
export interface TransformRejection {
|
|
51
40
|
ok: false;
|
|
52
41
|
/** 400: unsupported input; 413: output too large; 422: sharp failed to process the input. */
|
package/dist/assets/transform.js
CHANGED
|
@@ -1,38 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The shared transform engine: applies a parsed `TransformDirectives` to
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* transform Lambda (packages/canopycms-cdk/lambda/asset-transform).
|
|
2
|
+
* The shared transform engine: applies a parsed `TransformDirectives` to source image bytes
|
|
3
|
+
* with sharp. Server-only - never import this from client/editor code (kept in its own file,
|
|
4
|
+
* separate from the dependency-free transform-directives.ts). Used by the dev-mode lazy
|
|
5
|
+
* `/assets/t/*` emulation in api/assets.ts and, unchanged, by the prod transform Lambda
|
|
6
|
+
* (packages/canopycms-cdk/lambda/asset-transform).
|
|
8
7
|
*
|
|
9
|
-
* sharp is imported for its TYPES only and loaded on first use through
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `canopycms/server` and `canopycms/http`: see sharp-loader.ts for the
|
|
13
|
-
* adopter outage a static import caused, and eslint.config.mjs for the rule
|
|
14
|
-
* that keeps it from coming back.
|
|
8
|
+
* sharp is imported for its TYPES only and loaded on first use through `loadSharp()`
|
|
9
|
+
* (sharp-loader.ts), so importing this module never loads libvips - see sharp-loader.ts for
|
|
10
|
+
* why, and eslint.config.mjs for the rule that keeps a static import from coming back.
|
|
15
11
|
*
|
|
16
|
-
* Pipeline:
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* defense #2) without exceeding it and making sharp throw -> load for real
|
|
20
|
-
* with `{ pages: min(totalPages, MAX_ANIMATED_FRAMES), limitInputPixels }` ->
|
|
21
|
-
* `.rotate()` with no args (bakes EXIF orientation into pixels,
|
|
22
|
-
* dropping the orientation tag) -> optional crop via `.extract()` -> optional
|
|
23
|
-
* `.resize({ width, withoutEnlargement: true })` (never upscales) -> encode.
|
|
12
|
+
* Pipeline: metadata probe learns the page count (decompression-bomb defenses #1/#2) -> real
|
|
13
|
+
* load capped at `min(totalPages, MAX_ANIMATED_FRAMES)` -> `.rotate()` (bakes EXIF orientation
|
|
14
|
+
* into pixels) -> optional crop/resize (never upscales) -> encode.
|
|
24
15
|
*
|
|
25
|
-
* Identity (`orig`) and any request that omits an explicit `f=` format
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* (
|
|
29
|
-
* called here, which would undo that).
|
|
16
|
+
* Identity (`orig`) and any request that omits an explicit `f=` format re-encode through the
|
|
17
|
+
* SOURCE format rather than a fixed one: this is what guarantees EXIF/GPS gets stripped even
|
|
18
|
+
* when no other change is requested (sharp strips metadata by default on re-encode -
|
|
19
|
+
* `withMetadata()` is never called here, which would undo that).
|
|
30
20
|
*
|
|
31
|
-
* GIF has no EXIF segment (EXIF is a JPEG/TIFF APP1 marker
|
|
32
|
-
*
|
|
33
|
-
* re-encoded through sharp's `.gif()` (verified: current sharp bundles cgif
|
|
34
|
-
* and re-encodes multi-frame GIFs through the `{ animated: true }` input
|
|
35
|
-
* path with no extra native dependency) purely for pipeline uniformity, not
|
|
21
|
+
* GIF has no EXIF segment (EXIF is a JPEG/TIFF APP1 marker), so an identity GIF has nothing to
|
|
22
|
+
* strip - it is still re-encoded through sharp's `.gif()` purely for pipeline uniformity, not
|
|
36
23
|
* because GIF needs stripping.
|
|
37
24
|
*/
|
|
38
25
|
import { getErrorMessage } from '../utils/error.js';
|
|
@@ -109,7 +96,7 @@ function encode(pipeline, format, quality) {
|
|
|
109
96
|
}
|
|
110
97
|
/**
|
|
111
98
|
* Re-encode through the source container format - used for identity and for
|
|
112
|
-
* requests that omit `f=`. `quality`
|
|
99
|
+
* requests that omit `f=`. `quality` is honoured here exactly like
|
|
113
100
|
* `encode()` does for an explicit `f=`, so a `q=` directive without `f=` is
|
|
114
101
|
* never silently dropped - the cache key (`formatDirectives` in
|
|
115
102
|
* transform-directives.ts) already includes `q=` unconditionally, so the
|
package/dist/auth/cache.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Server-only
|
|
3
|
-
*
|
|
4
|
-
* Use 'canopycms/auth/cache' as the import path.
|
|
2
|
+
* Server-only: these use node:fs/promises and must NOT reach a client bundle.
|
|
3
|
+
* Import them as 'canopycms/auth/cache'.
|
|
5
4
|
*/
|
|
6
5
|
export { FileBasedAuthCache, writeAuthCacheSnapshot } from './file-based-auth-cache.js';
|
|
7
6
|
export { CachingAuthPlugin } from './caching-auth-plugin.js';
|
package/dist/auth/cache.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Server-only
|
|
3
|
-
*
|
|
4
|
-
* Use 'canopycms/auth/cache' as the import path.
|
|
2
|
+
* Server-only: these use node:fs/promises and must NOT reach a client bundle.
|
|
3
|
+
* Import them as 'canopycms/auth/cache'.
|
|
5
4
|
*/
|
|
6
5
|
export { FileBasedAuthCache, writeAuthCacheSnapshot } from './file-based-auth-cache.js';
|
|
7
6
|
export { CachingAuthPlugin } from './caching-auth-plugin.js';
|