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
|
@@ -2,10 +2,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useId } from 'react';
|
|
3
3
|
import { Input } from '@mantine/core';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* into the
|
|
7
|
-
* (`YYYY-MM-DDTHH:mm:ss`, no timezone). Returns '' for '' or an unparsable
|
|
8
|
-
*
|
|
5
|
+
* Converts a stored value (ISO 8601 UTC, e.g. `YYYY-MM-DDTHH:mm:ss.sssZ`)
|
|
6
|
+
* into the local wall-clock string a `datetime-local` input expects
|
|
7
|
+
* (`YYYY-MM-DDTHH:mm:ss`, no timezone). Returns '' for '' or an unparsable value.
|
|
8
|
+
* @internal Exported for tests.
|
|
9
9
|
*/
|
|
10
10
|
export function isoToDatetimeLocalValue(iso) {
|
|
11
11
|
if (!iso)
|
|
@@ -16,15 +16,14 @@ export function isoToDatetimeLocalValue(iso) {
|
|
|
16
16
|
const pad = (n) => String(n).padStart(2, '0');
|
|
17
17
|
const base = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` +
|
|
18
18
|
`T${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
// input.value getter does the same), so the value we set and what the
|
|
22
|
-
// control reports back agree exactly.
|
|
19
|
+
// Seconds are included only when non-zero, matching a real browser's own
|
|
20
|
+
// `datetime-local` serialization, so the value we set agrees with what the control reports back.
|
|
23
21
|
return date.getSeconds() === 0 ? base : `${base}:${pad(date.getSeconds())}`;
|
|
24
22
|
}
|
|
25
23
|
/**
|
|
26
24
|
* Convert a `datetime-local` input's local wall-clock string back into the
|
|
27
25
|
* ISO 8601 UTC storage format. Returns '' for '' or an unparsable value.
|
|
26
|
+
* @internal Exported for tests.
|
|
28
27
|
*/
|
|
29
28
|
export function datetimeLocalValueToIso(local) {
|
|
30
29
|
if (!local)
|
|
@@ -37,29 +36,21 @@ export function datetimeLocalValueToIso(local) {
|
|
|
37
36
|
/**
|
|
38
37
|
* Editor for `type: 'datetime'` fields.
|
|
39
38
|
*
|
|
40
|
-
* Storage format: ISO 8601 UTC string (e.g.
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* Empty string means "not set" (matches entry-validator's empty-string
|
|
44
|
-
* check for required fields).
|
|
39
|
+
* Storage format: ISO 8601 UTC string (e.g. `YYYY-MM-DDTHH:mm:ss.sssZ`) — what
|
|
40
|
+
* `Date.prototype.toISOString()` produces and `validation/entry-validator.ts`'s
|
|
41
|
+
* datetime check (`Date.parse`) accepts. Empty string means "not set".
|
|
45
42
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* type="datetime-local">` wrapped in Mantine's `Input`/`Input.Wrapper`
|
|
49
|
-
* gives a real date+time picker with zero new dependencies.
|
|
43
|
+
* Uses a native `datetime-local` input in Mantine's `Input.Wrapper` rather than
|
|
44
|
+
* `@mantine/dates` (not a dependency here) — a real picker with zero new deps.
|
|
50
45
|
*
|
|
51
|
-
* `datetime-local` has no timezone
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* precision in the source data is not preserved (`datetime-local` has no
|
|
57
|
-
* milliseconds field), so a stored value with non-zero milliseconds will
|
|
58
|
-
* have them zeroed out once resaved.
|
|
46
|
+
* `datetime-local` has no timezone: converts UTC ISO -> local for display and
|
|
47
|
+
* back on change, so an unedited load-then-save round-trips exactly instead of
|
|
48
|
+
* drifting by the browser's offset. `step={1}` preserves seconds in that
|
|
49
|
+
* round-trip; sub-second precision is not preserved (no milliseconds field),
|
|
50
|
+
* so a value with non-zero milliseconds is zeroed out once resaved.
|
|
59
51
|
*/
|
|
60
52
|
export const DateTimeField = ({ id, label, value, onChange, dataCanopyField, }) => {
|
|
61
53
|
const generatedId = useId();
|
|
62
54
|
const inputId = id ?? generatedId;
|
|
63
55
|
return (_jsx(Input.Wrapper, { id: inputId, label: label, size: "sm", children: _jsx(Input, { type: "datetime-local", step: 1, size: "sm", value: isoToDatetimeLocalValue(value), onChange: (e) => onChange(datetimeLocalValueToIso(e.currentTarget.value)), "data-canopy-field": dataCanopyField }) }));
|
|
64
56
|
};
|
|
65
|
-
export default DateTimeField;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { ImageFieldValue } from '../../config/index.js';
|
|
3
|
-
|
|
3
|
+
interface ImageFieldErrors {
|
|
4
4
|
src?: string;
|
|
5
5
|
alt?: string;
|
|
6
6
|
crop?: string;
|
|
@@ -18,4 +18,4 @@ export interface ImageFieldProps {
|
|
|
18
18
|
errors?: ImageFieldErrors;
|
|
19
19
|
}
|
|
20
20
|
export declare const ImageField: React.FC<ImageFieldProps>;
|
|
21
|
-
export
|
|
21
|
+
export {};
|
|
@@ -20,8 +20,7 @@ export const ImageField = ({ id, label, value, onChange, aspect, altOptional, da
|
|
|
20
20
|
const [pickerOpen, setPickerOpen] = useState(false);
|
|
21
21
|
const [cropRequest, setCropRequest] = useState(null);
|
|
22
22
|
// Dropzone-level rejections (wrong type/too large) never reach useAssetUpload
|
|
23
|
-
// (
|
|
24
|
-
// error slot rather than piggybacking on upload.error.
|
|
23
|
+
// (filtered before onDrop fires), so they need their own error slot.
|
|
25
24
|
const [dropError, setDropError] = useState(null);
|
|
26
25
|
const altInputRef = useRef(null);
|
|
27
26
|
const justCommittedRef = useRef(false);
|
|
@@ -30,20 +29,17 @@ export const ImageField = ({ id, label, value, onChange, aspect, altOptional, da
|
|
|
30
29
|
const previewSrc = value
|
|
31
30
|
? assetUrl({ src: value.src }, { width: PREVIEW_WIDTH, crop: value.crop, baseUrl })
|
|
32
31
|
: undefined;
|
|
33
|
-
// Broken-preview fallback,
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
// both an asset that was broken at upload time (pre-existing content) and
|
|
37
|
-
// a transform that fails for some other reason at render time.
|
|
32
|
+
// Broken-preview fallback, mirroring AssetCard.tsx's thumbnail fallback (same
|
|
33
|
+
// icon/copy, same reset-during-render pattern). Covers both an asset broken
|
|
34
|
+
// at upload time and a transform failing at render time.
|
|
38
35
|
const [previewFailed, setPreviewFailed] = useState(false);
|
|
39
36
|
const [prevPreviewSrc, setPrevPreviewSrc] = useState(previewSrc);
|
|
40
37
|
if (previewSrc !== prevPreviewSrc) {
|
|
41
38
|
setPrevPreviewSrc(previewSrc);
|
|
42
39
|
setPreviewFailed(false);
|
|
43
40
|
}
|
|
44
|
-
//
|
|
45
|
-
// so the
|
|
46
|
-
// to need attention.
|
|
41
|
+
// Focuses the alt input right after a new image commits (pick or upload),
|
|
42
|
+
// so the next keystroke lands in the field most likely to need attention.
|
|
47
43
|
useEffect(() => {
|
|
48
44
|
if (justCommittedRef.current) {
|
|
49
45
|
justCommittedRef.current = false;
|
|
@@ -54,9 +50,8 @@ export const ImageField = ({ id, label, value, onChange, aspect, altOptional, da
|
|
|
54
50
|
justCommittedRef.current = true;
|
|
55
51
|
onChange({
|
|
56
52
|
src: asset.src,
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
// Selecting into an empty field has no prior alt, so it stays ''.
|
|
53
|
+
// Preserves the current alt text on replace (it often still fits); an
|
|
54
|
+
// empty field has no prior alt, so it stays ''.
|
|
60
55
|
alt: value?.alt ?? '',
|
|
61
56
|
...(asset.width !== undefined ? { width: asset.width } : {}),
|
|
62
57
|
...(asset.height !== undefined ? { height: asset.height } : {}),
|
|
@@ -123,4 +118,3 @@ export const ImageField = ({ id, label, value, onChange, aspect, altOptional, da
|
|
|
123
118
|
display: 'block',
|
|
124
119
|
}, onError: () => setPreviewFailed(true) })), errors?.src && (_jsx(Text, { size: "xs", c: "red", children: errors.src })), _jsx(TextInput, { id: inputId, ref: altInputRef, label: "Alt text", required: !altOptional, value: value.alt, onChange: (event) => handleAltChange(event.currentTarget.value), error: errors?.alt, size: "sm", "data-testid": `image-field-alt-${dataCanopyField}` }), _jsxs(Group, { gap: "xs", children: [_jsx(Button, { variant: "light", size: "xs", onClick: () => setPickerOpen(true), "data-testid": `image-field-replace-${dataCanopyField}`, children: "Replace" }), aspectRatio !== undefined && (_jsx(Button, { variant: "light", size: "xs", onClick: () => setCropRequest({ kind: 'existing' }), "data-testid": `image-field-crop-${dataCanopyField}`, children: "Crop" })), _jsx(Button, { variant: "subtle", color: "red", size: "xs", onClick: handleRemove, "data-testid": `image-field-remove-${dataCanopyField}`, children: "Remove" })] }), errors?.crop && (_jsx(Text, { size: "xs", c: "red", children: errors.crop }))] })), _jsx(MediaLibrary, { opened: pickerOpen, onClose: () => setPickerOpen(false), mode: "picker", onSelect: handleAssetReady }), aspectRatio !== undefined && (_jsx(CropStep, { opened: cropRequest !== null, onClose: () => setCropRequest(null), imageSrc: cropImageSrc, aspect: aspectRatio, initialCrop: cropInitial, onConfirm: handleCropConfirm }))] }));
|
|
125
120
|
};
|
|
126
|
-
export default ImageField;
|
|
@@ -12,4 +12,3 @@ export const InlineGroupField = ({ label, description, fields, value, onChange,
|
|
|
12
12
|
return (_jsx("div", { children: renderField(field, value[field.name], (next) => onChange({ ...value, [field.name]: next }), fieldPath) }, formatCanopyPath(fieldPath)));
|
|
13
13
|
}) })] }) }));
|
|
14
14
|
};
|
|
15
|
-
export default InlineGroupField;
|
|
@@ -8,15 +8,14 @@ import { useApiClient } from '../context/index.js';
|
|
|
8
8
|
import { uploadAsset } from '../media/upload-asset.js';
|
|
9
9
|
const MDXEditorLazy = React.lazy(async () => {
|
|
10
10
|
const [{ MDXEditor }, { headingsPlugin, listsPlugin, quotePlugin, thematicBreakPlugin, markdownShortcutPlugin, linkPlugin, linkDialogPlugin, imagePlugin, tablePlugin, toolbarPlugin, codeBlockPlugin, codeMirrorPlugin, BoldItalicUnderlineToggles, BlockTypeSelect, ListsToggle, CreateLink, InsertImage, InsertTable, InsertThematicBreak, CodeToggle, InsertCodeBlock, UndoRedo, Separator, insertMarkdown$, usePublisher, useCellValues, saveImage$, closeImageDialog$, imageDialogState$, },] = await Promise.all([import('@mdxeditor/editor'), import('@mdxeditor/editor')]);
|
|
11
|
-
/** Toolbar wrapper that provides insertMarkdown to InsertEntryLink */
|
|
12
11
|
const EntryLinkToolbarButton = () => {
|
|
13
12
|
const insertMarkdown = usePublisher(insertMarkdown$);
|
|
14
13
|
return _jsx(InsertEntryLink, { onInsert: insertMarkdown });
|
|
15
14
|
};
|
|
16
15
|
/**
|
|
17
|
-
* Bridges mdxeditor's realm cells (only
|
|
16
|
+
* Bridges mdxeditor's realm cells (reachable only once this lazy chunk has
|
|
18
17
|
* loaded) into MdxImageDialog's plain-props interface, so that component
|
|
19
|
-
*
|
|
18
|
+
* never imports `@mdxeditor/editor` at runtime — same pattern as
|
|
20
19
|
* `EntryLinkToolbarButton` above.
|
|
21
20
|
*/
|
|
22
21
|
const MdxImageDialogBridge = () => {
|
|
@@ -60,7 +59,6 @@ const MDXEditorLazy = React.lazy(async () => {
|
|
|
60
59
|
};
|
|
61
60
|
return { default: WrappedEditor };
|
|
62
61
|
});
|
|
63
|
-
/** Style the editor wrapper with a white background and border so it's visually distinct from the form background. */
|
|
64
62
|
const editorWrapperStyle = {
|
|
65
63
|
background: '#fff',
|
|
66
64
|
border: '1px solid var(--mantine-color-gray-4, #ced4da)',
|
|
@@ -102,12 +100,10 @@ export const MarkdownField = ({ id, label, value, onChange, dataCanopyField, })
|
|
|
102
100
|
const editorRef = useRef(null);
|
|
103
101
|
const lastExternalValue = useRef(value);
|
|
104
102
|
const apiClient = useApiClient();
|
|
105
|
-
// Drives both MDXEditor's
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
// client, which ApiClientProvider itself memoizes) so MDXEditor's plugin
|
|
110
|
-
// list doesn't churn on every keystroke.
|
|
103
|
+
// Drives both MDXEditor's drag/drop/paste upload and the custom image
|
|
104
|
+
// dialog's Upload tab via the same presign/finalize-or-proxied pipeline
|
|
105
|
+
// (media/upload-asset.ts). Memoized on the API client (itself memoized by
|
|
106
|
+
// ApiClientProvider) so MDXEditor's plugin list doesn't churn per keystroke.
|
|
111
107
|
const imageUploadHandler = useCallback(async (file) => {
|
|
112
108
|
const asset = await uploadAsset(apiClient, file);
|
|
113
109
|
return asset.src;
|
|
@@ -125,4 +121,3 @@ export const MarkdownField = ({ id, label, value, onChange, dataCanopyField, })
|
|
|
125
121
|
}, [onChange]);
|
|
126
122
|
return (_jsxs("div", { id: inputId, "data-canopy-field": dataCanopyField, className: "canopy-markdown-field", children: [label && (_jsx(Text, { size: "sm", fw: 500, mb: 4, children: label })), _jsx(EditorContentStyles, {}), _jsx("div", { style: editorWrapperStyle, children: _jsx(Suspense, { fallback: _jsx(FallbackTextarea, { value: value, onChange: onChange }), children: _jsx(MDXEditorLazy, { markdown: value, onChange: handleChange, editorRef: editorRef, imageUploadHandler: imageUploadHandler }) }) })] }));
|
|
127
123
|
};
|
|
128
|
-
export default MarkdownField;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { EditingImageDialogState, InactiveImageDialogState, NewImageDialogState, SaveImageParameters } from '@mdxeditor/editor';
|
|
3
|
+
/** @internal Exported for tests. */
|
|
3
4
|
export type MdxImageDialogState = InactiveImageDialogState | NewImageDialogState | EditingImageDialogState;
|
|
4
5
|
export interface MdxImageDialogProps {
|
|
5
6
|
state: MdxImageDialogState;
|
|
@@ -12,4 +13,3 @@ export interface MdxImageDialogProps {
|
|
|
12
13
|
* in MarkdownField.tsx.
|
|
13
14
|
*/
|
|
14
15
|
export declare const MdxImageDialog: React.FC<MdxImageDialogProps>;
|
|
15
|
-
export default MdxImageDialog;
|
|
@@ -69,4 +69,3 @@ export const MdxImageDialog = ({ state, onSave, onClose }) => {
|
|
|
69
69
|
}, children: [_jsxs(Tabs.List, { children: [_jsx(Tabs.Tab, { value: "upload", "data-testid": "mdx-image-dialog-tab-upload", children: "Upload" }), _jsx(Tabs.Tab, { value: "library", "data-testid": "mdx-image-dialog-tab-library", children: "From library" }), _jsx(Tabs.Tab, { value: "url", "data-testid": "mdx-image-dialog-tab-url", children: "By URL" })] }), _jsx(Tabs.Panel, { value: "upload", pt: "sm", children: _jsxs(Stack, { gap: "xs", children: [_jsx(Dropzone, { onDrop: (files) => void handleDrop(files), onReject: handleReject, maxSize: MAX_UPLOAD_BYTES, accept: ACCEPTED_IMAGE_MIME_TYPES, loading: upload.uploading, multiple: false, "data-testid": "mdx-image-dialog-dropzone", children: _jsxs(Group, { justify: "center", gap: "xs", py: "sm", style: { pointerEvents: 'none' }, children: [_jsx(IconUpload, { size: 20 }), _jsx(Text, { size: "sm", children: "Drop an image here, or click to browse" })] }) }), upload.uploading &&
|
|
70
70
|
(upload.progress !== null ? (_jsx(Progress, { value: upload.progress * 100, size: "sm" })) : (_jsx(Progress, { value: 100, size: "sm", animated: true }))), (upload.error || dropError) && (_jsx(Alert, { icon: _jsx(IconAlertCircle, { size: 16 }), color: "red", children: upload.error || dropError }))] }) }), _jsx(Tabs.Panel, { value: "library", pt: "sm", children: _jsx("div", { style: { height: LIBRARY_PANEL_HEIGHT }, children: _jsx(MediaLibraryBody, { opened: tab === 'library', mode: "picker", onSelect: handlePickFromLibrary }) }) }), _jsx(Tabs.Panel, { value: "url", pt: "sm", children: _jsxs(Stack, { gap: "xs", children: [_jsx(TextInput, { label: "Image URL", placeholder: "https://example.com/image.png", value: urlValue, onChange: (event) => setUrlValue(event.currentTarget.value), "data-testid": "mdx-image-dialog-url" }), _jsx(Group, { justify: "flex-end", children: _jsx(Button, { onClick: handleUrlSubmit, disabled: !urlValue.trim(), "data-testid": "mdx-image-dialog-url-submit", children: "Insert" }) })] }) })] }), _jsx(Group, { justify: "flex-end", children: _jsx(Button, { variant: "default", onClick: onClose, children: "Cancel" }) })] }) }));
|
|
71
71
|
};
|
|
72
|
-
export default MdxImageDialog;
|
|
@@ -9,25 +9,15 @@ export interface NumberFieldProps {
|
|
|
9
9
|
/**
|
|
10
10
|
* Editor for `type: 'number'` fields.
|
|
11
11
|
*
|
|
12
|
-
* `undefined` means "not filled in"
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* looks fine), and `0` must not be mistaken for "absent". Mantine's
|
|
16
|
-
* `NumberInput` reports an empty input as `''`; we translate that to
|
|
17
|
-
* `undefined` so `validation/entry-validator.ts`'s required check (which
|
|
18
|
-
* treats only `undefined`/`null` as empty for numbers) agrees with what the
|
|
19
|
-
* form displays.
|
|
12
|
+
* `undefined` (not `0`) means "not filled in": Mantine's `NumberInput` reports
|
|
13
|
+
* an empty input as `''`, which this field translates to `undefined` so
|
|
14
|
+
* `validation/entry-validator.ts`'s required check agrees with the form.
|
|
20
15
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* `
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* minus after the second keystroke and the `.5` appended to a POSITIVE
|
|
28
|
-
* zero: the user typed `-0.5` and `0.5` was stored, silently. Keeping the
|
|
29
|
-
* text Mantine itself reported keeps the sign on screen until the entry is
|
|
30
|
-
* a complete number. See NumberField.test.tsx's keystroke matrix.
|
|
16
|
+
* The in-progress TEXT is mirrored back, not the parsed number. Mantine
|
|
17
|
+
* reports the entry as a string exactly when text and numeric value disagree
|
|
18
|
+
* (`'-0'`, `'0.'`, leading zeros); re-rendering from `String(parsedNumber)`
|
|
19
|
+
* instead loses that distinction — `String(-0)` is `'0'`, so typing `-0.5`
|
|
20
|
+
* would silently store `0.5` after the second keystroke. See
|
|
21
|
+
* NumberField.test.tsx's keystroke matrix.
|
|
31
22
|
*/
|
|
32
23
|
export declare const NumberField: React.FC<NumberFieldProps>;
|
|
33
|
-
export default NumberField;
|
|
@@ -16,37 +16,26 @@ const toNumericValue = (raw) => {
|
|
|
16
16
|
/**
|
|
17
17
|
* Editor for `type: 'number'` fields.
|
|
18
18
|
*
|
|
19
|
-
* `undefined` means "not filled in"
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* looks fine), and `0` must not be mistaken for "absent". Mantine's
|
|
23
|
-
* `NumberInput` reports an empty input as `''`; we translate that to
|
|
24
|
-
* `undefined` so `validation/entry-validator.ts`'s required check (which
|
|
25
|
-
* treats only `undefined`/`null` as empty for numbers) agrees with what the
|
|
26
|
-
* form displays.
|
|
19
|
+
* `undefined` (not `0`) means "not filled in": Mantine's `NumberInput` reports
|
|
20
|
+
* an empty input as `''`, which this field translates to `undefined` so
|
|
21
|
+
* `validation/entry-validator.ts`'s required check agrees with the form.
|
|
27
22
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* `
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* minus after the second keystroke and the `.5` appended to a POSITIVE
|
|
35
|
-
* zero: the user typed `-0.5` and `0.5` was stored, silently. Keeping the
|
|
36
|
-
* text Mantine itself reported keeps the sign on screen until the entry is
|
|
37
|
-
* a complete number. See NumberField.test.tsx's keystroke matrix.
|
|
23
|
+
* The in-progress TEXT is mirrored back, not the parsed number. Mantine
|
|
24
|
+
* reports the entry as a string exactly when text and numeric value disagree
|
|
25
|
+
* (`'-0'`, `'0.'`, leading zeros); re-rendering from `String(parsedNumber)`
|
|
26
|
+
* instead loses that distinction — `String(-0)` is `'0'`, so typing `-0.5`
|
|
27
|
+
* would silently store `0.5` after the second keystroke. See
|
|
28
|
+
* NumberField.test.tsx's keystroke matrix.
|
|
38
29
|
*/
|
|
39
30
|
export const NumberField = ({ id, label, value, onChange, dataCanopyField, }) => {
|
|
40
31
|
const generatedId = useId();
|
|
41
32
|
const inputId = id ?? generatedId;
|
|
42
33
|
const [inputValue, setInputValue] = useState(value ?? '');
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
// "Reload File"), that value wins and the stale text is dropped.
|
|
34
|
+
// Shows the in-progress text only while it still matches the parent's
|
|
35
|
+
// value; once the parent's value diverges (load, discard, reload), that value wins.
|
|
46
36
|
const displayValue = toNumericValue(inputValue) === value ? inputValue : (value ?? '');
|
|
47
37
|
return (_jsx(NumberInput, { id: inputId, label: label, value: displayValue, size: "sm", onChange: (next) => {
|
|
48
38
|
setInputValue(next);
|
|
49
39
|
onChange(toNumericValue(next));
|
|
50
40
|
}, "data-canopy-field": dataCanopyField }));
|
|
51
41
|
};
|
|
52
|
-
export default NumberField;
|
|
@@ -9,16 +9,13 @@ export interface NumberListFieldProps {
|
|
|
9
9
|
/**
|
|
10
10
|
* Editor for `type: 'number', list: true` fields.
|
|
11
11
|
*
|
|
12
|
-
* Mirrors `StringListField`'s approach (
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* would be `NaN`, or a spurious `0` for a blank one).
|
|
12
|
+
* Mirrors `StringListField`'s `TagsInput` approach (type + Enter adds an
|
|
13
|
+
* item, Backspace on empty removes the last) since Mantine has no numeric
|
|
14
|
+
* equivalent. A tag that doesn't parse to a finite number is dropped rather
|
|
15
|
+
* than stored as `NaN`.
|
|
17
16
|
*
|
|
18
|
-
* A
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* doesn't work" - so the rejected text is named in the field's error slot.
|
|
17
|
+
* A dropped tag is reported, not silently swallowed — otherwise it vanished
|
|
18
|
+
* on Enter indistinguishably from being accepted, with nothing to tell a
|
|
19
|
+
* typo from a broken field — so rejected text is named in the error slot.
|
|
22
20
|
*/
|
|
23
21
|
export declare const NumberListField: React.FC<NumberListFieldProps>;
|
|
24
|
-
export default NumberListField;
|
|
@@ -18,16 +18,14 @@ const parseTag = (tag) => {
|
|
|
18
18
|
/**
|
|
19
19
|
* Editor for `type: 'number', list: true` fields.
|
|
20
20
|
*
|
|
21
|
-
* Mirrors `StringListField`'s approach (
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* would be `NaN`, or a spurious `0` for a blank one).
|
|
21
|
+
* Mirrors `StringListField`'s `TagsInput` approach (type + Enter adds an
|
|
22
|
+
* item, Backspace on empty removes the last) since Mantine has no numeric
|
|
23
|
+
* equivalent. A tag that doesn't parse to a finite number is dropped rather
|
|
24
|
+
* than stored as `NaN`.
|
|
26
25
|
*
|
|
27
|
-
* A
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* doesn't work" - so the rejected text is named in the field's error slot.
|
|
26
|
+
* A dropped tag is reported, not silently swallowed — otherwise it vanished
|
|
27
|
+
* on Enter indistinguishably from being accepted, with nothing to tell a
|
|
28
|
+
* typo from a broken field — so rejected text is named in the error slot.
|
|
31
29
|
*/
|
|
32
30
|
export const NumberListField = ({ id, label, value, onChange, dataCanopyField, }) => {
|
|
33
31
|
const generatedId = useId();
|
|
@@ -49,4 +47,3 @@ export const NumberListField = ({ id, label, value, onChange, dataCanopyField, }
|
|
|
49
47
|
onChange(parsed);
|
|
50
48
|
}, splitChars: [], allowDuplicates: true, "data-canopy-field": dataCanopyField }));
|
|
51
49
|
};
|
|
52
|
-
export default NumberListField;
|
|
@@ -10,15 +10,12 @@ export interface ObjectFieldProps {
|
|
|
10
10
|
path: Array<string | number>;
|
|
11
11
|
dataCanopyField?: string;
|
|
12
12
|
/**
|
|
13
|
-
* When
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* for object-list items, which are removed via the list's own per-item
|
|
19
|
-
* Remove button instead.
|
|
13
|
+
* When set, shows a "Clear" affordance that resets this field to unset
|
|
14
|
+
* (`undefined`) — used by `FormRenderer.tsx`'s non-list `case 'object'` so
|
|
15
|
+
* a required child can't strand the field present-but-invalid with no way
|
|
16
|
+
* back to "not filled in". Omitted for object-list items, which remove via
|
|
17
|
+
* the list's own per-item button.
|
|
20
18
|
*/
|
|
21
19
|
onRemove?: () => void;
|
|
22
20
|
}
|
|
23
21
|
export declare const ObjectField: React.FC<ObjectFieldProps>;
|
|
24
|
-
export default ObjectField;
|
|
@@ -8,4 +8,3 @@ export const ObjectField = ({ label, fields, value, onChange, renderField, path,
|
|
|
8
8
|
return (_jsx("div", { children: renderField(field, current[field.name], (next) => onChange({ ...current, [field.name]: next }), fieldPath) }, formatCanopyPath(fieldPath)));
|
|
9
9
|
}) })] }) }));
|
|
10
10
|
};
|
|
11
|
-
export default ObjectField;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/** @internal Exported for tests. */
|
|
2
3
|
export interface ReferenceOption {
|
|
3
4
|
value: string;
|
|
4
5
|
label: string;
|
|
@@ -17,4 +18,3 @@ export interface ReferenceFieldProps {
|
|
|
17
18
|
dataCanopyField?: string;
|
|
18
19
|
}
|
|
19
20
|
export declare const ReferenceField: React.FC<ReferenceFieldProps>;
|
|
20
|
-
export default ReferenceField;
|
|
@@ -7,10 +7,10 @@ import { createApiClient } from '../../api/client.js';
|
|
|
7
7
|
import { useOptionalApiClient } from '../context/index.js';
|
|
8
8
|
import { getErrorMessage } from '../../utils/error.js';
|
|
9
9
|
export const ReferenceField = ({ id, label, options: staticOptions, collections, entryTypes, displayField = 'title', branch = 'main', value, onChange, multiple, dataCanopyField, }) => {
|
|
10
|
-
//
|
|
11
|
-
// ApiClientProvider
|
|
12
|
-
// FormRenderer.stories.tsx
|
|
13
|
-
//
|
|
10
|
+
// Configured with the deployment's basePath when rendered inside an
|
|
11
|
+
// ApiClientProvider (always true in the real Editor tree); `null` outside one
|
|
12
|
+
// (e.g. FormRenderer.stories.tsx), so the fetch effect falls back to a
|
|
13
|
+
// default-configured client.
|
|
14
14
|
const contextApiClient = useOptionalApiClient();
|
|
15
15
|
const hasCollections = !!collections && collections.length > 0;
|
|
16
16
|
const hasEntryTypes = !!entryTypes && entryTypes.length > 0;
|
|
@@ -19,7 +19,6 @@ export const ReferenceField = ({ id, label, options: staticOptions, collections,
|
|
|
19
19
|
const [loading, setLoading] = useState(needsFetch);
|
|
20
20
|
const [error, setError] = useState(null);
|
|
21
21
|
const [retryCount, setRetryCount] = useState(0);
|
|
22
|
-
// Extract ID from value - handle both string IDs and resolved objects
|
|
23
22
|
const extractId = (val) => {
|
|
24
23
|
if (typeof val === 'string')
|
|
25
24
|
return val;
|
|
@@ -46,17 +45,14 @@ export const ReferenceField = ({ id, label, options: staticOptions, collections,
|
|
|
46
45
|
setError(null);
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
|
-
//
|
|
48
|
+
// Keyed on the derived `fetchKey`, not the raw `collections`/`entryTypes`
|
|
49
|
+
// arrays: the parent rebuilds those on every render (including every
|
|
50
|
+
// `refreshEntries()` after a save), so depending on them directly fired
|
|
51
|
+
// this fetch far more often than the inputs actually changed.
|
|
50
52
|
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
// fired this fetch far more often than the inputs actually changed.
|
|
55
|
-
//
|
|
56
|
-
// `active` guards against a stale response: if the key changes again (or
|
|
57
|
-
// the field unmounts) before this request settles, the loser's `.then`/
|
|
58
|
-
// `.catch`/`.finally` must not overwrite state a newer request already
|
|
59
|
-
// owns.
|
|
53
|
+
// `active` guards against a stale response: if the key changes again or the
|
|
54
|
+
// field unmounts before this request settles, the loser's `.then`/`.catch`/
|
|
55
|
+
// `.finally` must not overwrite state a newer request already owns.
|
|
60
56
|
useEffect(() => {
|
|
61
57
|
if (!needsFetch)
|
|
62
58
|
return;
|
|
@@ -112,4 +108,3 @@ export const ReferenceField = ({ id, label, options: staticOptions, collections,
|
|
|
112
108
|
}
|
|
113
109
|
return (_jsx(Stack, { gap: 4, "data-canopy-field": dataCanopyField, "data-testid": `reference-field-${dataCanopyField}`, children: multiple ? (_jsx(MultiSelect, { id: inputId, label: label, data: options, value: normalizedValue, onChange: (next) => onChange(next), searchable: true, placeholder: "Select reference\u2026", size: "sm" })) : (_jsx(Select, { id: inputId, label: label, data: options, value: normalizedValue, onChange: (next) => onChange(next ?? ''), searchable: true, clearable: true, placeholder: "Select reference\u2026", size: "sm" })) }));
|
|
114
110
|
};
|
|
115
|
-
export default ReferenceField;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
interface SelectOption {
|
|
3
3
|
label: string;
|
|
4
4
|
value: string;
|
|
5
5
|
}
|
|
@@ -14,4 +14,4 @@ export interface SelectFieldProps {
|
|
|
14
14
|
dataCanopyField?: string;
|
|
15
15
|
}
|
|
16
16
|
export declare const SelectField: React.FC<SelectFieldProps>;
|
|
17
|
-
export
|
|
17
|
+
export {};
|
|
@@ -13,4 +13,3 @@ export const SelectField = ({ id, label, options, value, onChange, multiple, pla
|
|
|
13
13
|
const inputId = id ?? generatedId;
|
|
14
14
|
return (_jsxs(Stack, { gap: 4, "data-canopy-field": dataCanopyField, children: [multiple ? (_jsx(MultiSelect, { id: inputId, label: label, data: options, value: normalizedValue, onChange: (next) => onChange(next), searchable: true, placeholder: placeholder, size: "sm" })) : (_jsx(Select, { id: inputId, label: label, data: options, value: normalizedValue, onChange: (next) => onChange(next ?? ''), searchable: true, clearable: true, placeholder: placeholder, size: "sm" })), multiple && (_jsx(Text, { size: "xs", c: "dimmed", children: "Searchable multi-select; start typing to filter." }))] }));
|
|
15
15
|
};
|
|
16
|
-
export default SelectField;
|
|
@@ -11,9 +11,5 @@ export interface StringListFieldProps {
|
|
|
11
11
|
*
|
|
12
12
|
* Uses Mantine's TagsInput: type + Enter adds an item, each item renders as a
|
|
13
13
|
* removable pill, and Backspace on an empty input removes the last item.
|
|
14
|
-
* (Before this component existed, string-list fields fell through to the
|
|
15
|
-
* single-value TextField, which coerced the array to a comma-joined string —
|
|
16
|
-
* effectively unsupported.)
|
|
17
14
|
*/
|
|
18
15
|
export declare const StringListField: React.FC<StringListFieldProps>;
|
|
19
|
-
export default StringListField;
|
|
@@ -6,19 +6,14 @@ import { TagsInput } from '@mantine/core';
|
|
|
6
6
|
*
|
|
7
7
|
* Uses Mantine's TagsInput: type + Enter adds an item, each item renders as a
|
|
8
8
|
* removable pill, and Backspace on an empty input removes the last item.
|
|
9
|
-
* (Before this component existed, string-list fields fell through to the
|
|
10
|
-
* single-value TextField, which coerced the array to a comma-joined string —
|
|
11
|
-
* effectively unsupported.)
|
|
12
9
|
*/
|
|
13
10
|
export const StringListField = ({ id, label, value, onChange, dataCanopyField, }) => {
|
|
14
11
|
const generatedId = useId();
|
|
15
12
|
const inputId = id ?? generatedId;
|
|
16
13
|
return (_jsx(TagsInput, { id: inputId, label: label, value: value, size: "sm", onChange: onChange,
|
|
17
|
-
// Faithful generic-list semantics, not tag ergonomics: no comma
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
// couldn't round-trip).
|
|
14
|
+
// Faithful generic-list semantics, not tag ergonomics: no comma-splitting
|
|
15
|
+
// ("New York, NY" stays one item) and duplicates are legitimate list
|
|
16
|
+
// data — TagsInput's defaults would break both, so existing file data
|
|
17
|
+
// couldn't round-trip.
|
|
22
18
|
splitChars: [], allowDuplicates: true, "data-canopy-field": dataCanopyField }));
|
|
23
19
|
};
|
|
24
|
-
export default StringListField;
|
|
@@ -6,4 +6,3 @@ export const TextField = ({ id, label, value, onChange, dataCanopyField, }) => {
|
|
|
6
6
|
const inputId = id ?? generatedId;
|
|
7
7
|
return (_jsx(TextInput, { id: inputId, label: label, value: value, size: "sm", onChange: (e) => onChange(e.currentTarget.value), "data-canopy-field": dataCanopyField }));
|
|
8
8
|
};
|
|
9
|
-
export default TextField;
|
|
@@ -6,4 +6,3 @@ export const ToggleField = ({ id, label, value, onChange, dataCanopyField, testI
|
|
|
6
6
|
const inputId = id ?? generatedId;
|
|
7
7
|
return (_jsx(Switch, { id: inputId, label: label, checked: value, onChange: (e) => onChange(e.currentTarget.checked), size: "md", "data-canopy-field": dataCanopyField, wrapperProps: testId ? { 'data-testid': testId } : undefined }));
|
|
8
8
|
};
|
|
9
|
-
export default ToggleField;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* The MarkdownField is lazy-loaded and its toolbar components don't have direct
|
|
6
|
-
* access to the editor's entry list. This context bridges that gap.
|
|
3
|
+
* Bridges entry data to MarkdownField's lazy-loaded toolbar components (e.g.
|
|
4
|
+
* InsertEntryLink), which have no direct access to the editor's entry list.
|
|
7
5
|
*/
|
|
8
6
|
import { createContext, useContext } from 'react';
|
|
9
7
|
export const EntryLinkContext = createContext({ entries: [] });
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MDXEditor toolbar button for inserting entry links.
|
|
3
3
|
*
|
|
4
|
-
* Opens a modal with a searchable list of entries. When the user selects
|
|
5
|
-
* an entry, inserts [Entry Title](entry:CONTENT_ID) into the editor.
|
|
6
|
-
*
|
|
7
4
|
* Must be rendered inside an MDXEditor toolbar (uses usePublisher from gurx).
|
|
8
5
|
*/
|
|
9
6
|
import React from 'react';
|
|
@@ -3,9 +3,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
/**
|
|
4
4
|
* MDXEditor toolbar button for inserting entry links.
|
|
5
5
|
*
|
|
6
|
-
* Opens a modal with a searchable list of entries. When the user selects
|
|
7
|
-
* an entry, inserts [Entry Title](entry:CONTENT_ID) into the editor.
|
|
8
|
-
*
|
|
9
6
|
* Must be rendered inside an MDXEditor toolbar (uses usePublisher from gurx).
|
|
10
7
|
*/
|
|
11
8
|
import { useState, useMemo } from 'react';
|
|
@@ -27,7 +24,6 @@ export const InsertEntryLink = ({ onInsert }) => {
|
|
|
27
24
|
e.slug?.toLowerCase().includes(lower) ||
|
|
28
25
|
e.collectionName?.toLowerCase().includes(lower));
|
|
29
26
|
}, [entries, search]);
|
|
30
|
-
// Group entries by collection
|
|
31
27
|
const grouped = useMemo(() => {
|
|
32
28
|
const groups = new Map();
|
|
33
29
|
for (const entry of filtered) {
|