canopycms 0.0.68-int.98 → 0.1.0
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/CHANGELOG.md +2131 -0
- package/README.md +47 -63
- package/dist/ai/generate.d.ts +5 -0
- package/dist/ai/generate.js +244 -115
- package/dist/ai/index.d.ts +1 -1
- package/dist/ai/json-to-markdown.d.ts +21 -1
- package/dist/ai/json-to-markdown.js +120 -57
- package/dist/ai/references.d.ts +72 -0
- package/dist/ai/references.js +223 -0
- package/dist/ai/resolve-branch.js +9 -2
- package/dist/ai/to-plain-text.d.ts +17 -8
- package/dist/ai/to-plain-text.js +18 -15
- package/dist/ai/types.d.ts +84 -3
- package/dist/api/admin-branch-health.d.ts +24 -1
- package/dist/api/admin-branch-health.js +52 -20
- package/dist/api/admin.d.ts +23 -5
- package/dist/api/admin.js +36 -1
- package/dist/api/assets.js +88 -78
- package/dist/api/branch-create-window.d.ts +12 -0
- package/dist/api/branch-create-window.js +13 -0
- package/dist/api/branch-merge.d.ts +1 -1
- package/dist/api/branch-merge.js +1 -1
- package/dist/api/branch-review.d.ts +3 -3
- package/dist/api/branch-review.js +16 -7
- package/dist/api/branch-status.d.ts +16 -6
- package/dist/api/branch-status.js +57 -12
- package/dist/api/branch-withdraw.d.ts +2 -2
- package/dist/api/branch-withdraw.js +8 -3
- package/dist/api/branch.d.ts +25 -12
- package/dist/api/branch.js +164 -103
- package/dist/api/client.d.ts +78 -58
- package/dist/api/client.js +150 -117
- package/dist/api/comments.d.ts +12 -3
- package/dist/api/comments.js +118 -9
- package/dist/api/content.d.ts +9 -9
- package/dist/api/content.js +131 -22
- package/dist/api/entries-constants.d.ts +14 -3
- package/dist/api/entries-constants.js +14 -3
- package/dist/api/entries.d.ts +40 -2
- package/dist/api/entries.js +102 -6
- package/dist/api/github-sync.d.ts +19 -0
- package/dist/api/github-sync.js +50 -3
- package/dist/api/groups.d.ts +4 -4
- package/dist/api/groups.js +2 -1
- package/dist/api/guards.js +23 -3
- package/dist/api/index.d.ts +3 -1
- package/dist/api/index.js +1 -0
- package/dist/api/permissions.d.ts +21 -2
- package/dist/api/permissions.js +50 -3
- package/dist/api/request-deadline.d.ts +59 -0
- package/dist/api/request-deadline.js +73 -0
- package/dist/api/resolve-references.js +8 -7
- package/dist/api/route-builder.d.ts +14 -0
- package/dist/api/route-builder.js +14 -1
- package/dist/api/schema.d.ts +11 -9
- package/dist/api/schema.js +2 -0
- package/dist/api/settings-helpers.d.ts +5 -1
- package/dist/api/settings-helpers.js +10 -2
- package/dist/api/types.d.ts +18 -0
- package/dist/api/users-constants.d.ts +6 -0
- package/dist/api/users-constants.js +6 -0
- package/dist/assets/asset-url.d.ts +28 -16
- package/dist/assets/asset-url.js +51 -25
- package/dist/assets/finalize.js +3 -0
- package/dist/assets/index.d.ts +1 -1
- package/dist/assets/materialize.d.ts +153 -0
- package/dist/assets/materialize.js +402 -0
- package/dist/assets/store-local.d.ts +19 -5
- package/dist/assets/store-local.js +69 -10
- package/dist/assets/store-s3.d.ts +38 -7
- package/dist/assets/store-s3.js +128 -22
- package/dist/assets/transform-directives.d.ts +52 -13
- package/dist/assets/transform-directives.js +87 -27
- package/dist/assets/transform.d.ts +3 -3
- package/dist/assets/transform.js +13 -8
- package/dist/assets/types.d.ts +31 -4
- package/dist/auth/cache.d.ts +1 -1
- package/dist/auth/cache.js +1 -1
- package/dist/auth/caching-auth-plugin.d.ts +2 -0
- package/dist/auth/caching-auth-plugin.js +12 -2
- package/dist/auth/file-based-auth-cache.d.ts +8 -0
- package/dist/auth/file-based-auth-cache.js +18 -8
- package/dist/auth/person-name.d.ts +5 -0
- package/dist/auth/person-name.js +8 -0
- package/dist/auth/plugin.d.ts +10 -1
- package/dist/auth/types.d.ts +2 -0
- package/dist/auth/user-metadata-lookup.d.ts +21 -0
- package/dist/auth/user-metadata-lookup.js +116 -0
- package/dist/authorization/branch.d.ts +1 -1
- package/dist/authorization/branch.js +12 -13
- package/dist/authorization/groups/schema.d.ts +4 -4
- package/dist/authorization/helpers.d.ts +8 -0
- package/dist/authorization/helpers.js +8 -0
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.js +1 -1
- package/dist/authorization/protected-branch.d.ts +5 -4
- package/dist/authorization/protected-branch.js +7 -5
- package/dist/branch-health.d.ts +35 -8
- package/dist/branch-health.js +54 -18
- package/dist/branch-metadata-error.d.ts +27 -0
- package/dist/branch-metadata-error.js +23 -0
- package/dist/branch-metadata-file.d.ts +205 -24
- package/dist/branch-metadata-file.js +126 -25
- package/dist/branch-metadata.d.ts +45 -6
- package/dist/branch-metadata.js +142 -50
- package/dist/branch-provisioning.d.ts +167 -0
- package/dist/branch-provisioning.js +501 -0
- package/dist/branch-registry.d.ts +8 -0
- package/dist/branch-registry.js +61 -9
- package/dist/branch-schema-cache.d.ts +29 -12
- package/dist/branch-schema-cache.js +64 -21
- package/dist/branch-sparse.d.ts +23 -0
- package/dist/branch-sparse.js +118 -0
- package/dist/branch-workspace.d.ts +42 -3
- package/dist/branch-workspace.js +239 -100
- package/dist/build/asset-refs.d.ts +94 -0
- package/dist/build/asset-refs.js +267 -0
- package/dist/build/generate-ai-content.js +5 -0
- package/dist/build/inline-flight.d.ts +37 -0
- package/dist/build/inline-flight.js +142 -0
- package/dist/cli/asset-refs.d.ts +52 -0
- package/dist/cli/asset-refs.js +194 -0
- package/dist/cli/cli.d.ts +15 -1
- package/dist/cli/cli.js +8543 -3193
- package/dist/cli/configured-asset-store.d.ts +12 -0
- package/dist/cli/configured-asset-store.js +46 -0
- package/dist/cli/generate-ai-content.js +4244 -1072
- package/dist/cli/init.js +217 -126
- package/dist/cli/project-detect.d.ts +2 -0
- package/dist/cli/project-detect.js +2 -0
- package/dist/cli/template-files/Dockerfile.cms.template +13 -5
- package/dist/cli/template-files/cms-stack.ts.template +16 -13
- package/dist/client.d.ts +1 -2
- package/dist/client.js +1 -2
- package/dist/comment-store.d.ts +25 -0
- package/dist/comment-store.js +43 -8
- package/dist/config/flatten.js +2 -0
- package/dist/config/helpers.js +2 -2
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schemas/config.d.ts +12 -29
- package/dist/config/schemas/config.js +9 -12
- package/dist/config/schemas/field.d.ts +3 -0
- package/dist/config/schemas/field.js +58 -4
- package/dist/config/schemas/media.d.ts +4 -13
- package/dist/config/schemas/media.js +5 -8
- package/dist/config/schemas/url.d.ts +2 -20
- package/dist/config/schemas/url.js +2 -25
- package/dist/config/types.d.ts +116 -22
- package/dist/config/types.js +3 -9
- package/dist/config/validation.d.ts +25 -4
- package/dist/config/validation.js +116 -3
- package/dist/content-id-index.js +2 -2
- package/dist/content-index-generation.d.ts +1 -1
- package/dist/content-index-generation.js +1 -1
- package/dist/content-listing.d.ts +10 -1
- package/dist/content-listing.js +22 -5
- package/dist/content-reader.d.ts +9 -0
- package/dist/content-reader.js +16 -11
- package/dist/content-store.d.ts +75 -12
- package/dist/content-store.js +249 -86
- package/dist/content-tree.js +2 -2
- package/dist/context.js +5 -2
- package/dist/dangling-reference-log.d.ts +17 -0
- package/dist/dangling-reference-log.js +29 -0
- package/dist/dev-content-watcher.d.ts +1 -1
- package/dist/dev-content-watcher.js +1 -1
- package/dist/editor/BranchManager.d.ts +23 -7
- package/dist/editor/BranchManager.js +119 -54
- package/dist/editor/CanopyEditor.d.ts +1 -1
- package/dist/editor/CanopyEditor.js +1 -2
- package/dist/editor/CommentsPanel.d.ts +14 -0
- package/dist/editor/CommentsPanel.js +68 -43
- package/dist/editor/Editor.d.ts +11 -5
- package/dist/editor/Editor.js +891 -218
- package/dist/editor/EditorAuthGate.d.ts +7 -1
- package/dist/editor/EditorAuthGate.js +41 -9
- package/dist/editor/EntryNavigator.d.ts +22 -0
- package/dist/editor/EntryNavigator.js +353 -105
- package/dist/editor/FormHeader.d.ts +25 -0
- package/dist/editor/FormHeader.js +82 -0
- package/dist/editor/FormRenderer.d.ts +27 -3
- package/dist/editor/FormRenderer.js +171 -76
- package/dist/editor/PreviewFrame.d.ts +40 -0
- package/dist/editor/PreviewFrame.js +215 -0
- package/dist/editor/PreviewPane.d.ts +47 -0
- package/dist/editor/PreviewPane.js +147 -0
- package/dist/editor/PreviewToolbarTools.d.ts +22 -0
- package/dist/editor/PreviewToolbarTools.js +73 -0
- package/dist/editor/admin/SystemHealthPanel.d.ts +2 -1
- package/dist/editor/admin/SystemHealthPanel.js +163 -33
- package/dist/editor/admin/useSystemHealth.d.ts +18 -0
- package/dist/editor/admin/useSystemHealth.js +70 -1
- package/dist/editor/branch-status.d.ts +17 -0
- package/dist/editor/branch-status.js +29 -0
- package/dist/editor/canopy-path.d.ts +9 -6
- package/dist/editor/canopy-path.js +8 -11
- package/dist/editor/client-reference-resolver.d.ts +43 -16
- package/dist/editor/client-reference-resolver.js +155 -64
- package/dist/editor/comments/BranchComments.d.ts +1 -1
- package/dist/editor/comments/BranchComments.js +2 -2
- package/dist/editor/comments/CloseRefusedNotice.d.ts +4 -0
- package/dist/editor/comments/CloseRefusedNotice.js +7 -0
- package/dist/editor/comments/CommentThreadsPopover.d.ts +47 -0
- package/dist/editor/comments/CommentThreadsPopover.js +274 -0
- package/dist/editor/comments/CommentWriteAlert.d.ts +11 -0
- package/dist/editor/comments/CommentWriteAlert.js +13 -0
- package/dist/editor/comments/EntryComments.d.ts +10 -4
- package/dist/editor/comments/EntryComments.js +14 -17
- package/dist/editor/comments/FieldWrapper.d.ts +18 -4
- package/dist/editor/comments/FieldWrapper.js +62 -28
- package/dist/editor/comments/InlineCommentThread.d.ts +9 -2
- package/dist/editor/comments/InlineCommentThread.js +11 -47
- package/dist/editor/comments/ThreadCarousel.d.ts +1 -1
- package/dist/editor/comments/ThreadCarousel.js +18 -21
- package/dist/editor/comments/ThreadReplyControls.d.ts +28 -0
- package/dist/editor/comments/ThreadReplyControls.js +92 -0
- package/dist/editor/comments/field-comment-context.d.ts +14 -0
- package/dist/editor/comments/field-comment-context.js +14 -0
- package/dist/editor/comments/form-comments.d.ts +48 -0
- package/dist/editor/comments/form-comments.js +178 -0
- package/dist/editor/comments/item-anchor-copy.d.ts +6 -0
- package/dist/editor/comments/item-anchor-copy.js +6 -0
- package/dist/editor/comments/move-focus-if-unmoved.d.ts +6 -0
- package/dist/editor/comments/move-focus-if-unmoved.js +11 -0
- package/dist/editor/comments/popover-placement.d.ts +18 -0
- package/dist/editor/comments/popover-placement.js +58 -0
- package/dist/editor/comments/use-tracked-writes.d.ts +16 -0
- package/dist/editor/comments/use-tracked-writes.js +53 -0
- package/dist/editor/components/BranchAccessList.d.ts +15 -0
- package/dist/editor/components/BranchAccessList.js +52 -0
- package/dist/editor/components/BranchLockBanner.d.ts +22 -0
- package/dist/editor/components/BranchLockBanner.js +39 -0
- package/dist/editor/components/BranchPill.d.ts +32 -0
- package/dist/editor/components/BranchPill.js +33 -0
- package/dist/editor/components/BranchesDrawer.d.ts +11 -0
- package/dist/editor/components/BranchesDrawer.js +5 -0
- package/dist/editor/components/ConfirmDeleteModal.d.ts +6 -1
- package/dist/editor/components/ConfirmDeleteModal.js +3 -2
- package/dist/editor/components/DestructiveMenuItem.d.ts +7 -0
- package/dist/editor/components/DestructiveMenuItem.js +8 -0
- package/dist/editor/components/EditorCrashScreen.d.ts +17 -0
- package/dist/editor/components/EditorCrashScreen.js +22 -0
- package/dist/editor/components/EditorErrorBoundary.d.ts +38 -0
- package/dist/editor/components/EditorErrorBoundary.js +40 -0
- package/dist/editor/components/EditorHeader.d.ts +56 -106
- package/dist/editor/components/EditorHeader.js +130 -131
- package/dist/editor/components/EditorRail.d.ts +49 -0
- package/dist/editor/components/EditorRail.js +65 -0
- package/dist/editor/components/EntryBreadcrumb.d.ts +33 -0
- package/dist/editor/components/EntryBreadcrumb.js +56 -0
- package/dist/editor/components/EntryCreateModal.d.ts +12 -7
- package/dist/editor/components/EntryCreateModal.js +51 -57
- package/dist/editor/components/NoEditPermissionNotice.d.ts +6 -5
- package/dist/editor/components/NoEditPermissionNotice.js +5 -4
- package/dist/editor/components/QuickOpenPalette.d.ts +22 -0
- package/dist/editor/components/QuickOpenPalette.js +66 -0
- package/dist/editor/components/ReadOnlyDraftNotice.d.ts +11 -0
- package/dist/editor/components/ReadOnlyDraftNotice.js +12 -0
- package/dist/editor/components/ReasonedMenuItem.d.ts +15 -0
- package/dist/editor/components/ReasonedMenuItem.js +15 -0
- package/dist/editor/components/ReferencedByList.d.ts +11 -0
- package/dist/editor/components/ReferencedByList.js +28 -0
- package/dist/editor/components/RelativeTime.d.ts +10 -0
- package/dist/editor/components/RelativeTime.js +10 -0
- package/dist/editor/components/RenameEntryModal.d.ts +9 -1
- package/dist/editor/components/RenameEntryModal.js +19 -31
- package/dist/editor/components/RetryToastMessage.d.ts +9 -0
- package/dist/editor/components/RetryToastMessage.js +6 -0
- package/dist/editor/components/SaveAllResult.d.ts +25 -0
- package/dist/editor/components/SaveAllResult.js +86 -0
- package/dist/editor/components/SaveSplitButton.d.ts +30 -0
- package/dist/editor/components/SaveSplitButton.js +108 -0
- package/dist/editor/components/StagedChangesDrawer.d.ts +39 -0
- package/dist/editor/components/StagedChangesDrawer.js +92 -0
- package/dist/editor/components/UnavailableEntryNotice.d.ts +6 -0
- package/dist/editor/components/UnavailableEntryNotice.js +9 -0
- package/dist/editor/components/UnavailableTypeMessage.d.ts +6 -0
- package/dist/editor/components/UnavailableTypeMessage.js +9 -0
- package/dist/editor/components/UndoToastMessage.d.ts +18 -0
- package/dist/editor/components/UndoToastMessage.js +10 -0
- package/dist/editor/components/UserBadge.d.ts +2 -5
- package/dist/editor/components/UserBadge.js +62 -33
- package/dist/editor/components/ValidationSummary.d.ts +14 -0
- package/dist/editor/components/ValidationSummary.js +24 -0
- package/dist/editor/components/index.d.ts +2 -2
- package/dist/editor/components/index.js +2 -2
- package/dist/editor/context/ApiClientContext.d.ts +8 -2
- package/dist/editor/context/ApiClientContext.js +19 -8
- package/dist/editor/context/AssetContext.d.ts +13 -35
- package/dist/editor/context/AssetContext.js +12 -31
- package/dist/editor/context/EditorStateContext.d.ts +4 -4
- package/dist/editor/context/EditorStateContext.js +4 -4
- package/dist/editor/context/SWRProvider.d.ts +3 -3
- package/dist/editor/context/SiteMdxAllowContext.d.ts +4 -0
- package/dist/editor/context/SiteMdxAllowContext.js +7 -0
- package/dist/editor/context/index.d.ts +2 -1
- package/dist/editor/context/index.js +2 -1
- package/dist/editor/contrast.d.ts +19 -0
- package/dist/editor/contrast.js +41 -0
- package/dist/editor/copy.d.ts +18 -0
- package/dist/editor/copy.js +18 -0
- package/dist/editor/editor-config.js +16 -0
- package/dist/editor/editor-utils.d.ts +34 -8
- package/dist/editor/editor-utils.js +42 -20
- package/dist/editor/entry-search.d.ts +20 -0
- package/dist/editor/entry-search.js +34 -0
- package/dist/editor/field-breadcrumb.d.ts +12 -0
- package/dist/editor/field-breadcrumb.js +85 -0
- package/dist/editor/field-props.d.ts +86 -0
- package/dist/editor/field-props.js +27 -0
- package/dist/editor/field-target.d.ts +30 -0
- package/dist/editor/field-target.js +77 -0
- package/dist/editor/fields/BlockField.d.ts +12 -0
- package/dist/editor/fields/BlockField.js +89 -73
- package/dist/editor/fields/CodeField.d.ts +2 -0
- package/dist/editor/fields/CodeField.js +6 -2
- package/dist/editor/fields/DateTimeField.d.ts +4 -29
- package/dist/editor/fields/DateTimeField.js +79 -41
- package/dist/editor/fields/ExpandAllButton.d.ts +6 -0
- package/dist/editor/fields/ExpandAllButton.js +4 -0
- package/dist/editor/fields/FieldCrashFallback.d.ts +17 -0
- package/dist/editor/fields/FieldCrashFallback.js +30 -0
- package/dist/editor/fields/FieldLabel.d.ts +37 -0
- package/dist/editor/fields/FieldLabel.js +19 -0
- package/dist/editor/fields/ImageField.d.ts +4 -0
- package/dist/editor/fields/ImageField.js +29 -14
- package/dist/editor/fields/InlineGroupField.js +4 -3
- package/dist/editor/fields/ItemList.d.ts +42 -0
- package/dist/editor/fields/ItemList.js +130 -0
- package/dist/editor/fields/MarkdownField.d.ts +32 -0
- package/dist/editor/fields/MarkdownField.js +223 -46
- package/dist/editor/fields/MdxImageDialog.js +1 -1
- package/dist/editor/fields/NumberField.d.ts +2 -0
- package/dist/editor/fields/NumberField.js +8 -5
- package/dist/editor/fields/NumberListField.d.ts +2 -0
- package/dist/editor/fields/NumberListField.js +19 -16
- package/dist/editor/fields/ObjectField.d.ts +2 -7
- package/dist/editor/fields/ObjectField.js +15 -5
- package/dist/editor/fields/ObjectListField.d.ts +29 -0
- package/dist/editor/fields/ObjectListField.js +57 -0
- package/dist/editor/fields/ReferenceField.d.ts +2 -0
- package/dist/editor/fields/ReferenceField.js +34 -9
- package/dist/editor/fields/SelectField.d.ts +2 -0
- package/dist/editor/fields/SelectField.js +11 -2
- package/dist/editor/fields/StringListField.d.ts +4 -1
- package/dist/editor/fields/StringListField.js +22 -8
- package/dist/editor/fields/TextField.d.ts +2 -0
- package/dist/editor/fields/TextField.js +6 -2
- package/dist/editor/fields/ToggleField.d.ts +2 -0
- package/dist/editor/fields/ToggleField.js +8 -3
- package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +1 -1
- package/dist/editor/fields/entry-link/InsertEntryLink.js +1 -1
- package/dist/editor/fields/form-expansion.d.ts +9 -0
- package/dist/editor/fields/form-expansion.js +2 -0
- package/dist/editor/fields/item-expansion.d.ts +15 -0
- package/dist/editor/fields/item-expansion.js +60 -0
- package/dist/editor/fields/list-item-keys.d.ts +8 -0
- package/dist/editor/fields/list-item-keys.js +50 -0
- package/dist/editor/fields/list-item-title.d.ts +20 -0
- package/dist/editor/fields/list-item-title.js +85 -0
- package/dist/editor/fields/markdown-export-options.d.ts +2 -0
- package/dist/editor/fields/markdown-export-options.js +8 -0
- package/dist/editor/fields/markdown-fidelity-visitors.d.ts +11 -0
- package/dist/editor/fields/markdown-fidelity-visitors.js +160 -0
- package/dist/editor/fields/mdx-jsx-support.d.ts +5 -1
- package/dist/editor/fields/mdx-jsx-support.js +157 -69
- package/dist/editor/fields/rich-text-failures.d.ts +5 -0
- package/dist/editor/fields/rich-text-failures.js +26 -0
- package/dist/editor/fields/toolbar-wrap.d.ts +7 -0
- package/dist/editor/fields/toolbar-wrap.js +35 -0
- package/dist/editor/form-outline.d.ts +13 -0
- package/dist/editor/form-outline.js +70 -0
- package/dist/editor/group-manager/GroupCard.d.ts +4 -1
- package/dist/editor/group-manager/GroupCard.js +12 -3
- package/dist/editor/group-manager/GroupForm.js +1 -1
- package/dist/editor/group-manager/InternalGroupsTab.d.ts +2 -1
- package/dist/editor/group-manager/InternalGroupsTab.js +4 -4
- package/dist/editor/group-manager/MemberList.d.ts +2 -1
- package/dist/editor/group-manager/MemberList.js +15 -4
- package/dist/editor/group-manager/hooks/useGroupState.d.ts +5 -0
- package/dist/editor/group-manager/hooks/useGroupState.js +30 -7
- package/dist/editor/group-manager/index.js +34 -5
- package/dist/editor/group-manager/types.d.ts +5 -2
- package/dist/editor/hooks/create-branch-request.d.ts +20 -0
- package/dist/editor/hooks/create-branch-request.js +54 -0
- package/dist/editor/hooks/save-all.d.ts +68 -0
- package/dist/editor/hooks/save-all.js +61 -0
- package/dist/editor/hooks/useBranchActions.d.ts +11 -1
- package/dist/editor/hooks/useBranchActions.js +42 -19
- package/dist/editor/hooks/useBranchManager.d.ts +21 -0
- package/dist/editor/hooks/useBranchManager.js +321 -125
- package/dist/editor/hooks/useBranchesData.d.ts +8 -4
- package/dist/editor/hooks/useBranchesData.js +9 -5
- package/dist/editor/hooks/useCommentSystem.d.ts +14 -2
- package/dist/editor/hooks/useCommentSystem.js +79 -55
- package/dist/editor/hooks/useCommentsData.d.ts +11 -7
- package/dist/editor/hooks/useCommentsData.js +20 -19
- package/dist/editor/hooks/useDraftManager.d.ts +77 -3
- package/dist/editor/hooks/useDraftManager.js +887 -94
- package/dist/editor/hooks/useEditorLayout.d.ts +53 -7
- package/dist/editor/hooks/useEditorLayout.js +98 -20
- package/dist/editor/hooks/useEntriesData.d.ts +2 -1
- package/dist/editor/hooks/useEntriesData.js +18 -4
- package/dist/editor/hooks/useEntryManager.d.ts +41 -2
- package/dist/editor/hooks/useEntryManager.js +227 -41
- package/dist/editor/hooks/useGroupManager.js +13 -16
- package/dist/editor/hooks/usePermissionManager.js +14 -6
- package/dist/editor/hooks/usePreviewMarks.d.ts +21 -0
- package/dist/editor/hooks/usePreviewMarks.js +33 -0
- package/dist/editor/hooks/useReferenceResolution.d.ts +10 -3
- package/dist/editor/hooks/useReferenceResolution.js +34 -177
- package/dist/editor/hooks/useSchemaManager.d.ts +25 -6
- package/dist/editor/hooks/useSchemaManager.js +97 -39
- package/dist/editor/hooks/useUserMetadata.d.ts +14 -4
- package/dist/editor/hooks/useUserMetadata.js +76 -47
- package/dist/editor/hooks/user-metadata-batcher.d.ts +8 -0
- package/dist/editor/hooks/user-metadata-batcher.js +33 -0
- package/dist/editor/media/AssetCard.d.ts +6 -7
- package/dist/editor/media/AssetCard.js +24 -31
- package/dist/editor/media/AssetListRow.d.ts +16 -0
- package/dist/editor/media/AssetListRow.js +41 -0
- package/dist/editor/media/CropStep.js +6 -1
- package/dist/editor/media/MediaLibrary.d.ts +4 -3
- package/dist/editor/media/MediaLibrary.js +11 -4
- package/dist/editor/media/MediaLibraryBody.d.ts +3 -3
- package/dist/editor/media/MediaLibraryBody.js +195 -80
- package/dist/editor/media/MediaLibrarySkeleton.d.ts +6 -0
- package/dist/editor/media/MediaLibrarySkeleton.js +14 -0
- package/dist/editor/media/crop-math.d.ts +3 -4
- package/dist/editor/media/crop-math.js +11 -22
- package/dist/editor/media/editor-image-src.d.ts +8 -0
- package/dist/editor/media/editor-image-src.js +10 -0
- package/dist/editor/media/format-bytes.d.ts +2 -0
- package/dist/editor/media/format-bytes.js +23 -0
- package/dist/editor/media/media-library-prefs.d.ts +23 -0
- package/dist/editor/media/media-library-prefs.js +49 -0
- package/dist/editor/media/media-library-view.d.ts +34 -0
- package/dist/editor/media/media-library-view.js +40 -0
- package/dist/editor/media/useAssetLibrary.d.ts +30 -0
- package/dist/editor/media/useAssetLibrary.js +126 -0
- package/dist/editor/media/useStableAssetOrder.d.ts +11 -0
- package/dist/editor/media/useStableAssetOrder.js +37 -0
- package/dist/editor/media/useThumbnailFailure.d.ts +6 -0
- package/dist/editor/media/useThumbnailFailure.js +16 -0
- package/dist/editor/permission-manager/GroupSelector.js +2 -2
- package/dist/editor/permission-manager/PermissionEditor.d.ts +1 -1
- package/dist/editor/permission-manager/PermissionEditor.js +15 -4
- package/dist/editor/permission-manager/PermissionLevelBadge.js +1 -1
- package/dist/editor/permission-manager/PermissionTree.d.ts +1 -1
- package/dist/editor/permission-manager/UserSelector.d.ts +1 -1
- package/dist/editor/permission-manager/UserSelector.js +3 -3
- package/dist/editor/permission-manager/index.js +12 -3
- package/dist/editor/permission-manager/types.d.ts +5 -2
- package/dist/editor/platform.d.ts +3 -0
- package/dist/editor/platform.js +9 -0
- package/dist/editor/preview-asset-base.d.ts +9 -0
- package/dist/editor/preview-asset-base.js +17 -0
- package/dist/editor/preview-bridge.d.ts +51 -27
- package/dist/editor/preview-bridge.js +103 -144
- package/dist/editor/preview-marks.d.ts +15 -0
- package/dist/editor/preview-marks.js +74 -0
- package/dist/editor/preview-path.d.ts +12 -0
- package/dist/editor/preview-path.js +45 -1
- package/dist/editor/preview-scale.d.ts +27 -0
- package/dist/editor/preview-scale.js +34 -0
- package/dist/editor/raw-asset-base.d.ts +5 -0
- package/dist/editor/raw-asset-base.js +14 -0
- package/dist/editor/relative-time.d.ts +4 -4
- package/dist/editor/relative-time.js +16 -8
- package/dist/editor/schema-editor/CollectionEditor.d.ts +20 -3
- package/dist/editor/schema-editor/CollectionEditor.js +361 -62
- package/dist/editor/schema-editor/EntryTypeEditor.d.ts +5 -1
- package/dist/editor/schema-editor/EntryTypeEditor.js +11 -6
- package/dist/editor/schema-editor/collection-draft.d.ts +22 -0
- package/dist/editor/schema-editor/collection-draft.js +40 -0
- package/dist/editor/schema-editor/index.d.ts +1 -1
- package/dist/editor/schema-label.d.ts +10 -0
- package/dist/editor/schema-label.js +17 -0
- package/dist/editor/settings-conflict.d.ts +5 -0
- package/dist/editor/settings-conflict.js +8 -0
- package/dist/editor/shell/ActivityRail.d.ts +37 -0
- package/dist/editor/shell/ActivityRail.js +91 -0
- package/dist/editor/shell/EditorShell.d.ts +17 -0
- package/dist/editor/shell/EditorShell.js +31 -0
- package/dist/editor/shell/PaneLayout.d.ts +28 -0
- package/dist/editor/shell/PaneLayout.js +116 -0
- package/dist/editor/shell/SidePanelHost.d.ts +35 -0
- package/dist/editor/shell/SidePanelHost.js +184 -0
- package/dist/editor/shell/TopBar.d.ts +12 -0
- package/dist/editor/shell/TopBar.js +14 -0
- package/dist/editor/shell/host-chrome.d.ts +16 -0
- package/dist/editor/shell/host-chrome.js +69 -0
- package/dist/editor/slug.d.ts +16 -0
- package/dist/editor/slug.js +43 -0
- package/dist/editor/theme.d.ts +2 -1
- package/dist/editor/theme.js +314 -13
- package/dist/editor/unanswered.d.ts +17 -0
- package/dist/editor/unanswered.js +26 -0
- package/dist/editor/unavailable-entry-type.d.ts +20 -0
- package/dist/editor/unavailable-entry-type.js +28 -0
- package/dist/editor/undo-removal.d.ts +57 -0
- package/dist/editor/undo-removal.js +163 -0
- package/dist/editor/user-display.d.ts +4 -0
- package/dist/editor/user-display.js +5 -0
- package/dist/editor/utils/confirm-modal.d.ts +8 -0
- package/dist/editor/utils/confirm-modal.js +12 -0
- package/dist/editor/utils/editor-errors.d.ts +19 -0
- package/dist/editor/utils/editor-errors.js +32 -0
- package/dist/editor/utils/focus-return.d.ts +56 -0
- package/dist/editor/utils/focus-return.js +106 -0
- package/dist/entry-link-resolver.d.ts +11 -1
- package/dist/entry-link-resolver.js +65 -5
- package/dist/entry-schema-registry.d.ts +3 -3
- package/dist/entry-schema-registry.js +7 -4
- package/dist/entry-schema.d.ts +49 -3
- package/dist/entry-schema.js +18 -0
- package/dist/git-manager.d.ts +172 -10
- package/dist/git-manager.js +449 -107
- package/dist/github-service.d.ts +39 -2
- package/dist/github-service.js +101 -7
- package/dist/http/handler.js +74 -9
- package/dist/http/types.d.ts +2 -0
- package/dist/http/worker-not-ready.d.ts +9 -4
- package/dist/http/worker-not-ready.js +59 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/item-keys.d.ts +46 -0
- package/dist/item-keys.js +235 -0
- package/dist/operating-mode/editor-mode-check.d.ts +15 -0
- package/dist/operating-mode/editor-mode-check.js +24 -0
- package/dist/operating-mode/mode-env.d.ts +13 -14
- package/dist/operating-mode/mode-env.js +13 -14
- package/dist/operating-mode/types.d.ts +2 -2
- package/dist/paths/branch.d.ts +0 -1
- package/dist/paths/branch.js +1 -8
- package/dist/paths/index.d.ts +1 -1
- package/dist/paths/index.js +1 -1
- package/dist/paths/validation.js +0 -2
- package/dist/preview.d.ts +8 -0
- package/dist/preview.js +7 -0
- package/dist/reference-resolver.js +1 -0
- package/dist/resolve-canopy-user.d.ts +1 -1
- package/dist/resolve-canopy-user.js +1 -1
- package/dist/schema/meta-loader.d.ts +18 -8
- package/dist/schema/meta-loader.js +42 -9
- package/dist/schema/registry-fingerprint.d.ts +14 -0
- package/dist/schema/registry-fingerprint.js +63 -0
- package/dist/schema/resolver.d.ts +7 -4
- package/dist/schema/resolver.js +7 -6
- package/dist/schema/schema-store.d.ts +7 -10
- package/dist/schema/schema-store.js +13 -11
- package/dist/schema/schema-unavailable-error.d.ts +11 -0
- package/dist/schema/schema-unavailable-error.js +15 -0
- package/dist/schema/types.d.ts +22 -0
- package/dist/schema-registry-record.d.ts +35 -0
- package/dist/schema-registry-record.js +134 -0
- package/dist/server.d.ts +79 -9
- package/dist/server.js +62 -8
- package/dist/services.d.ts +33 -5
- package/dist/services.js +155 -37
- package/dist/settings-workspace.d.ts +23 -3
- package/dist/settings-workspace.js +159 -45
- package/dist/stamp-on-publish.d.ts +36 -0
- package/dist/stamp-on-publish.js +71 -0
- package/dist/static/index.d.ts +58 -5
- package/dist/static/index.js +133 -3
- package/dist/static/seo.d.ts +5 -5
- package/dist/static/seo.js +5 -5
- package/dist/submission-attribution.d.ts +8 -0
- package/dist/submission-attribution.js +22 -0
- package/dist/system-users.d.ts +12 -0
- package/dist/system-users.js +12 -0
- package/dist/task-queue/cms-task-queue.d.ts +1 -1
- package/dist/task-queue/cms-task-queue.js +1 -1
- package/dist/task-queue/index.d.ts +1 -1
- package/dist/task-queue/index.js +1 -1
- package/dist/task-queue/task-queue.d.ts +6 -0
- package/dist/task-queue/task-queue.js +29 -0
- package/dist/task-queue/worker-status.d.ts +35 -9
- package/dist/task-queue/worker-status.js +84 -17
- package/dist/types.d.ts +90 -9
- package/dist/url-collision.js +3 -3
- package/dist/url-exclusivity-fixtures.d.ts +8 -1
- package/dist/url-exclusivity-fixtures.js +11 -1
- package/dist/user.js +2 -1
- package/dist/utils/atomic-write.js +2 -1
- package/dist/utils/base-branch.d.ts +13 -0
- package/dist/utils/base-branch.js +23 -0
- package/dist/utils/content-serialize.d.ts +15 -7
- package/dist/utils/content-serialize.js +353 -51
- package/dist/utils/content-write-lock.d.ts +6 -1
- package/dist/utils/content-write-lock.js +21 -6
- package/dist/utils/debug.d.ts +1 -1
- package/dist/utils/debug.js +5 -3
- package/dist/utils/error.js +13 -2
- package/dist/utils/escape-text.d.ts +7 -0
- package/dist/utils/escape-text.js +27 -0
- package/dist/utils/fs.d.ts +12 -4
- package/dist/utils/fs.js +18 -5
- package/dist/utils/git.d.ts +21 -1
- package/dist/utils/git.js +63 -8
- package/dist/utils/json-source-splice.d.ts +14 -0
- package/dist/utils/json-source-splice.js +120 -0
- package/dist/utils/markdown-body-splice.d.ts +39 -0
- package/dist/utils/markdown-body-splice.js +421 -0
- package/dist/utils/occ-json-write.js +18 -12
- package/dist/utils/provision-log.d.ts +25 -0
- package/dist/utils/provision-log.js +49 -0
- package/dist/utils/provisioning-lock.d.ts +32 -1
- package/dist/utils/provisioning-lock.js +78 -32
- package/dist/utils/sanitize-href.d.ts +9 -23
- package/dist/utils/sanitize-href.js +14 -28
- package/dist/utils/title-field.d.ts +10 -0
- package/dist/utils/title-field.js +47 -0
- package/dist/utils/yaml-source-splice.d.ts +58 -0
- package/dist/utils/yaml-source-splice.js +515 -0
- package/dist/validation/block-structural-keys.d.ts +1 -1
- package/dist/validation/block-structural-keys.js +1 -1
- package/dist/validation/deletion-checker.d.ts +21 -29
- package/dist/validation/deletion-checker.js +41 -117
- package/dist/validation/entry-validator.d.ts +6 -10
- package/dist/validation/entry-validator.js +19 -26
- package/dist/validation/field-traversal.d.ts +22 -0
- package/dist/validation/field-traversal.js +39 -8
- package/dist/validation/markdown-safety.d.ts +68 -0
- package/dist/validation/markdown-safety.js +596 -0
- package/dist/validation/mdx-allowlist.d.ts +55 -0
- package/dist/validation/mdx-allowlist.js +183 -0
- package/dist/validation/reference-validator.d.ts +2 -0
- package/dist/validation/reference-validator.js +3 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/branch-policy.d.ts +124 -0
- package/dist/worker/branch-policy.js +243 -0
- package/dist/worker/bundle-header.d.ts +117 -0
- package/dist/worker/bundle-header.js +253 -0
- package/dist/worker/cms-worker.d.ts +236 -142
- package/dist/worker/cms-worker.js +772 -285
- package/dist/worker/gateway-egress.d.ts +43 -0
- package/dist/worker/gateway-egress.js +209 -0
- package/dist/worker/gateway-instance.d.ts +42 -0
- package/dist/worker/gateway-instance.js +129 -0
- package/dist/worker/git-process.d.ts +81 -0
- package/dist/worker/git-process.js +234 -0
- package/dist/worker/git-sync.d.ts +34 -17
- package/dist/worker/git-sync.js +394 -131
- package/dist/worker/github-auth.d.ts +9 -9
- package/dist/worker/github-auth.js +13 -15
- package/dist/worker/github-gateway-http.d.ts +62 -0
- package/dist/worker/github-gateway-http.js +977 -0
- package/dist/worker/github-gateway-wire.d.ts +590 -0
- package/dist/worker/github-gateway-wire.js +488 -0
- package/dist/worker/github-gateway.d.ts +238 -0
- package/dist/worker/github-gateway.js +726 -0
- package/dist/worker/github-mirror-upkeep.d.ts +75 -0
- package/dist/worker/github-mirror-upkeep.js +266 -0
- package/dist/worker/github-mirror.d.ts +364 -0
- package/dist/worker/github-mirror.js +1030 -0
- package/dist/worker/github-transfer.d.ts +56 -0
- package/dist/worker/github-transfer.js +444 -0
- package/dist/worker/history-rewrite.d.ts +4 -5
- package/dist/worker/history-rewrite.js +12 -17
- package/dist/worker/provisioned-workspace.d.ts +5 -5
- package/dist/worker/provisioned-workspace.js +5 -5
- package/dist/worker/rebase.d.ts +1 -1
- package/dist/worker/rebase.js +58 -54
- package/dist/worker/remote-git-maintenance.d.ts +3 -0
- package/dist/worker/remote-git-maintenance.js +12 -0
- package/dist/worker/schema-gate.d.ts +49 -0
- package/dist/worker/schema-gate.js +226 -0
- package/dist/worker/self-checks.d.ts +107 -0
- package/dist/worker/self-checks.js +358 -0
- package/dist/worker/shared-repo-git.d.ts +96 -0
- package/dist/worker/shared-repo-git.js +459 -0
- package/dist/worker/sparse-cone.d.ts +20 -0
- package/dist/worker/sparse-cone.js +136 -0
- package/dist/worker/stale-mirror.d.ts +82 -0
- package/dist/worker/stale-mirror.js +130 -0
- package/dist/worker/task-runner.d.ts +5 -3
- package/dist/worker/task-runner.js +287 -186
- package/dist/worker/worker-context.d.ts +36 -37
- package/package.json +35 -7
- package/dist/editor/EditorPanes.d.ts +0 -10
- package/dist/editor/EditorPanes.js +0 -98
- package/dist/editor/components/EditorFooter.d.ts +0 -11
- package/dist/editor/components/EditorFooter.js +0 -9
- package/dist/editor/components/EditorSidebar.d.ts +0 -67
- package/dist/editor/components/EditorSidebar.js +0 -22
package/dist/ai/generate.js
CHANGED
|
@@ -12,26 +12,40 @@ import { isDataOnlyFormat } from '../utils/format.js';
|
|
|
12
12
|
import { extractEntryTypeFromFilename, extractIdFromFilename, } from '../content-id-index.js';
|
|
13
13
|
import { hasTraversalSequence } from '../paths/index.js';
|
|
14
14
|
import { getErrorMessage, isNodeError } from '../utils/error.js';
|
|
15
|
-
import {
|
|
15
|
+
import { buildResolvedReference } from '../entry-schema.js';
|
|
16
|
+
import { entryToMarkdown, frontmatterTitle } from './json-to-markdown.js';
|
|
17
|
+
import { createReferenceRendering, createReferenceTargetResolver, decideReferenceLinks, maskUnexportedTargets, resolveReferenceFields, } from './references.js';
|
|
16
18
|
import { resolveEntryLinksInText } from '../entry-link-resolver.js';
|
|
19
|
+
import { computeEntryUrl } from '../utils/entry-url.js';
|
|
20
|
+
import { DEFAULT_SEO_FIELD_NAMES, isNoindexEntry } from '../static/seo.js';
|
|
17
21
|
/**
|
|
18
22
|
* Generate all AI content from the content store.
|
|
19
23
|
*
|
|
20
24
|
* Walks the schema tree, reads entries, converts to markdown,
|
|
21
25
|
* and produces per-entry files, per-collection all.md files,
|
|
22
26
|
* bundle files, and a manifest.
|
|
27
|
+
*
|
|
28
|
+
* A reference or body `entry:` link may only show a target that is itself exported, so every
|
|
29
|
+
* entry is read and filtered first, which settles the exported set. Only then are body links
|
|
30
|
+
* resolved for output, references to anything outside the set masked, entry transforms run, and markdown
|
|
31
|
+
* rendered, in rounds that repeat while a render fails (see the loop below).
|
|
23
32
|
*/
|
|
24
33
|
export async function generateAIContent(options) {
|
|
25
34
|
const { store, flatSchema, contentRoot, config, entryLinkUrl, generatedAt, buildId } = options;
|
|
35
|
+
assertValidNoindexConfig(config);
|
|
36
|
+
assertValidReferenceLink(config);
|
|
26
37
|
const files = new Map();
|
|
27
38
|
const idIndex = await store.idIndex();
|
|
39
|
+
const read = {
|
|
40
|
+
store,
|
|
41
|
+
contentRoot,
|
|
42
|
+
config,
|
|
43
|
+
idIndex,
|
|
44
|
+
entryLinkUrl,
|
|
45
|
+
resolveTarget: createReferenceTargetResolver(store),
|
|
46
|
+
};
|
|
28
47
|
const collections = flatSchema.filter((item) => item.type === 'collection');
|
|
29
|
-
|
|
30
|
-
const allEntries = [];
|
|
31
|
-
// Track manifest collections (tree structure)
|
|
32
|
-
const manifestCollections = [];
|
|
33
|
-
// Track root-level entries (entries in the content root, not in a subcollection)
|
|
34
|
-
const rootEntries = [];
|
|
48
|
+
const collectionNodes = [];
|
|
35
49
|
for (const collection of collections) {
|
|
36
50
|
// Skip the content root itself — we process its children
|
|
37
51
|
if (collection.logicalPath === contentRoot)
|
|
@@ -42,23 +56,97 @@ export async function generateAIContent(options) {
|
|
|
42
56
|
// (subcollections are handled recursively via their parent)
|
|
43
57
|
if (collection.parentPath && collection.parentPath !== contentRoot)
|
|
44
58
|
continue;
|
|
45
|
-
|
|
46
|
-
allEntries.push(...collectionResult.entries);
|
|
47
|
-
for (const [filePath, content] of collectionResult.files) {
|
|
48
|
-
files.set(filePath, content);
|
|
49
|
-
}
|
|
50
|
-
manifestCollections.push(collectionResult.manifestCollection);
|
|
59
|
+
collectionNodes.push(await collectCollection(read, collection, flatSchema));
|
|
51
60
|
}
|
|
52
|
-
//
|
|
61
|
+
// Root-level entries (entries in content root, not in any subcollection)
|
|
53
62
|
const rootCollection = collections.find((c) => c.logicalPath === contentRoot);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
const rootEntries = rootCollection?.entries ? await collectEntries(read, rootCollection, '') : [];
|
|
64
|
+
// Collection entries first, then root entries: the order bundles list them in
|
|
65
|
+
const allPending = [...collectionNodes.flatMap(subtreeEntries), ...rootEntries];
|
|
66
|
+
// Content id -> output file of every exported entry: the export set, and where each
|
|
67
|
+
// reference's markdown copy lives
|
|
68
|
+
const exported = new Map();
|
|
69
|
+
for (const pending of allPending) {
|
|
70
|
+
if (pending.contentId !== null)
|
|
71
|
+
exported.set(pending.contentId, pending.filePath);
|
|
72
|
+
}
|
|
73
|
+
const pendingById = new Map();
|
|
74
|
+
for (const pending of allPending) {
|
|
75
|
+
if (pending.contentId !== null)
|
|
76
|
+
pendingById.set(pending.contentId, pending);
|
|
77
|
+
}
|
|
78
|
+
// The target as `resolveReferenceTarget` would give it, built from this export's own read, so
|
|
79
|
+
// an entry outside the export set is never offered and a target cannot change mid-run
|
|
80
|
+
const subjectOf = (id) => {
|
|
81
|
+
const pending = pendingById.get(id);
|
|
82
|
+
if (!pending || !exported.has(id))
|
|
83
|
+
return undefined;
|
|
84
|
+
const { slug } = pending.entry;
|
|
85
|
+
const target = buildResolvedReference(structuredClone(pending.storedData), {
|
|
86
|
+
id,
|
|
87
|
+
slug,
|
|
88
|
+
collection: pending.collectionPath,
|
|
89
|
+
urlPath: computeEntryUrl(pending.collectionPath, slug, contentRoot),
|
|
90
|
+
});
|
|
91
|
+
return { target, body: pending.body };
|
|
92
|
+
};
|
|
93
|
+
const linkFor = config?.referenceLink
|
|
94
|
+
? await decideReferenceLinks(config.referenceLink, allPending, subjectOf, entryLinkUrl)
|
|
95
|
+
: undefined;
|
|
96
|
+
// A body `entry:` link takes the same page URL a reference to its target renders with
|
|
97
|
+
const bodyLinkUrl = linkFor
|
|
98
|
+
? (location) => {
|
|
99
|
+
const decided = linkFor(location.id);
|
|
100
|
+
if (typeof decided === 'string')
|
|
101
|
+
return decided;
|
|
102
|
+
return entryLinkUrl
|
|
103
|
+
? entryLinkUrl(location)
|
|
104
|
+
: computeEntryUrl(location.collection, location.slug, contentRoot);
|
|
59
105
|
}
|
|
60
|
-
|
|
106
|
+
: entryLinkUrl;
|
|
107
|
+
const references = createReferenceRendering(idIndex, flatSchema, entryLinkUrl, { mountPath: config?.mountPath ?? '/ai', files: exported }, linkFor);
|
|
108
|
+
// An entry whose render throws is not in the export after all, so references and body links to
|
|
109
|
+
// it are withheld like any other left-out target, and the entries that changed run their
|
|
110
|
+
// transforms and render again. That can fail another entry, so this repeats until a round fails
|
|
111
|
+
// none; each round removes at least one entry, so it ends.
|
|
112
|
+
let round = allPending;
|
|
113
|
+
for (;;) {
|
|
114
|
+
for (const pending of round) {
|
|
115
|
+
if (pending.body !== undefined) {
|
|
116
|
+
const linked = new Set();
|
|
117
|
+
pending.entry.body = resolveEntryLinksInText(pending.body, idIndex, contentRoot, bodyLinkUrl, {
|
|
118
|
+
isLinkable: (id) => {
|
|
119
|
+
linked.add(id);
|
|
120
|
+
return exported.has(id) && linkFor?.(id) !== false;
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
pending.linkedIds = [...linked];
|
|
124
|
+
}
|
|
125
|
+
maskUnexportedTargets(pending.entry, exported);
|
|
126
|
+
// Fold in adopter-supplied markdown (e.g. a colocated sibling artifact), on data as masked
|
|
127
|
+
pending.entry.appendedSections = undefined;
|
|
128
|
+
await runEntryTransform(pending.entry, pending.absolutePath, pending.contentId, config);
|
|
129
|
+
}
|
|
130
|
+
const failed = renderAll(round, config, references);
|
|
131
|
+
if (failed.length === 0)
|
|
132
|
+
break;
|
|
133
|
+
const failedIds = new Set();
|
|
134
|
+
for (const pending of failed) {
|
|
135
|
+
if (pending.contentId === null)
|
|
136
|
+
continue;
|
|
137
|
+
exported.delete(pending.contentId);
|
|
138
|
+
failedIds.add(pending.contentId);
|
|
139
|
+
}
|
|
140
|
+
round = allPending.filter((pending) => {
|
|
141
|
+
if (!isRendered(pending))
|
|
142
|
+
return false;
|
|
143
|
+
const masked = maskUnexportedTargets(pending.entry, exported);
|
|
144
|
+
return masked || pending.linkedIds.some((id) => failedIds.has(id));
|
|
145
|
+
});
|
|
61
146
|
}
|
|
147
|
+
const manifestCollections = collectionNodes.map((node) => emitCollection(node, files));
|
|
148
|
+
const manifestRootEntries = emitEntries(rootEntries, files);
|
|
149
|
+
const allEntries = allPending.filter(isRendered);
|
|
62
150
|
const manifestBundles = [];
|
|
63
151
|
if (config?.bundles) {
|
|
64
152
|
for (const bundle of config.bundles) {
|
|
@@ -66,11 +154,9 @@ export async function generateAIContent(options) {
|
|
|
66
154
|
if (/[/\\]|\.\./.test(bundle.name)) {
|
|
67
155
|
throw new Error(`Invalid bundle name "${bundle.name}": must not contain slashes or ".."`);
|
|
68
156
|
}
|
|
69
|
-
const matchingEntries = allEntries.filter((
|
|
157
|
+
const matchingEntries = allEntries.filter((pending) => matchesBundleFilter(pending.entry, bundle.filter, contentRoot));
|
|
70
158
|
if (matchingEntries.length > 0) {
|
|
71
|
-
const bundleContent = matchingEntries
|
|
72
|
-
.map((e) => entryToMarkdown(e, config))
|
|
73
|
-
.join('\n---\n\n');
|
|
159
|
+
const bundleContent = matchingEntries.map((p) => p.markdown).join('\n---\n\n');
|
|
74
160
|
const bundlePath = `bundles/${bundle.name}.md`;
|
|
75
161
|
files.set(bundlePath, bundleContent);
|
|
76
162
|
manifestBundles.push({
|
|
@@ -89,18 +175,53 @@ export async function generateAIContent(options) {
|
|
|
89
175
|
const manifest = {
|
|
90
176
|
...(buildId ? { buildId } : {}),
|
|
91
177
|
...(generatedAt || !buildId ? { generated: generatedAt || new Date().toISOString() } : {}),
|
|
92
|
-
entries:
|
|
178
|
+
entries: manifestRootEntries,
|
|
93
179
|
collections: manifestCollections,
|
|
94
180
|
bundles: manifestBundles,
|
|
95
181
|
};
|
|
96
182
|
files.set('manifest.json', JSON.stringify(manifest, null, 2));
|
|
97
183
|
return { manifest, files };
|
|
98
184
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
|
|
185
|
+
/** Render each entry's markdown, returning those whose render threw (left without markdown). */
|
|
186
|
+
function renderAll(entries, config, references) {
|
|
187
|
+
const failed = [];
|
|
188
|
+
for (const pending of entries) {
|
|
189
|
+
try {
|
|
190
|
+
pending.markdown = entryToMarkdown(pending.entry, config, references);
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
pending.markdown = undefined;
|
|
194
|
+
failed.push(pending);
|
|
195
|
+
console.warn(`AI content: skipping entry "${pending.entry.slug}" in ${pending.collectionPath}:`, getErrorMessage(err));
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return failed;
|
|
199
|
+
}
|
|
200
|
+
function isRendered(pending) {
|
|
201
|
+
return pending.markdown !== undefined;
|
|
202
|
+
}
|
|
203
|
+
/** A collection's direct entries, then each subcollection's, in the order all.md lists them. */
|
|
204
|
+
function subtreeEntries(node) {
|
|
205
|
+
return [...node.entries, ...node.subcollections.flatMap(subtreeEntries)];
|
|
206
|
+
}
|
|
207
|
+
async function collectCollection(read, collection, flatSchema) {
|
|
208
|
+
const cleanPath = stripContentRoot(collection.logicalPath, read.contentRoot);
|
|
209
|
+
const entries = await collectEntries(read, collection, cleanPath);
|
|
210
|
+
const subcollections = [];
|
|
211
|
+
for (const sub of flatSchema) {
|
|
212
|
+
if (sub.type !== 'collection' || sub.parentPath !== collection.logicalPath)
|
|
213
|
+
continue;
|
|
214
|
+
if (isCollectionExcluded(sub.logicalPath, read.contentRoot, read.config))
|
|
215
|
+
continue;
|
|
216
|
+
subcollections.push(await collectCollection(read, sub, flatSchema));
|
|
217
|
+
}
|
|
218
|
+
return { collection, cleanPath, entries, subcollections };
|
|
219
|
+
}
|
|
220
|
+
/** Read, resolve and filter the entries directly in `collection` (not its subcollections). */
|
|
221
|
+
async function collectEntries(read, collection, cleanPath) {
|
|
222
|
+
const { store, contentRoot, config, idIndex, entryLinkUrl, resolveTarget } = read;
|
|
223
|
+
const skipNoindex = config?.exclude?.noindex !== false;
|
|
224
|
+
const pending = [];
|
|
104
225
|
const listed = await store.getCollectionEntryPaths(collection.logicalPath);
|
|
105
226
|
// Filter to only entries in this exact collection (not subcollections)
|
|
106
227
|
const directEntries = listed.filter((e) => e.collection === collection.logicalPath);
|
|
@@ -111,109 +232,116 @@ async function processCollection(store, collection, flatSchema, contentRoot, con
|
|
|
111
232
|
if (config?.exclude?.entryTypes?.includes(entryTypeName))
|
|
112
233
|
continue;
|
|
113
234
|
const entryTypeConfig = findEntryType(collection, entryTypeName);
|
|
114
|
-
if (!entryTypeConfig)
|
|
235
|
+
if (!entryTypeConfig || entryTypeConfig.unavailable)
|
|
115
236
|
continue;
|
|
116
237
|
try {
|
|
117
238
|
const doc = await store.read(listEntry.collection, listEntry.slug, {
|
|
118
239
|
resolveReferences: false,
|
|
119
240
|
});
|
|
241
|
+
// AI content advertises an entry, so `noindex` leaves it out here as it does the sitemap.
|
|
242
|
+
if (skipNoindex && isNoindexEntry(doc.data, config?.seo))
|
|
243
|
+
continue;
|
|
244
|
+
const storedData = doc.data;
|
|
245
|
+
doc.data = await resolveReferenceFields(doc.data, entryTypeConfig.schema, resolveTarget);
|
|
120
246
|
const aiEntry = docToAIEntry(doc, listEntry.slug, entryTypeName, entryTypeConfig, cleanPath);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
247
|
+
const body = aiEntry.body;
|
|
248
|
+
// `where` sees every link resolved; the export's own rendering re-resolves from `body`
|
|
249
|
+
if (body)
|
|
250
|
+
aiEntry.body = resolveEntryLinksInText(body, idIndex, contentRoot, entryLinkUrl);
|
|
124
251
|
if (config?.exclude?.where?.(aiEntry))
|
|
125
252
|
continue;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
file: entryFilePath,
|
|
253
|
+
pending.push({
|
|
254
|
+
entry: aiEntry,
|
|
255
|
+
body,
|
|
256
|
+
storedData,
|
|
257
|
+
linkedIds: [],
|
|
258
|
+
contentId: extractIdFromFilename(path.basename(listEntry.relativePath)),
|
|
259
|
+
absolutePath: doc.absolutePath,
|
|
260
|
+
collectionPath: collection.logicalPath,
|
|
261
|
+
filePath: cleanPath ? `${cleanPath}/${listEntry.slug}.md` : `${listEntry.slug}.md`,
|
|
136
262
|
});
|
|
137
263
|
}
|
|
138
264
|
catch (err) {
|
|
139
265
|
console.warn(`AI content: skipping entry "${listEntry.slug}" in ${collection.logicalPath}:`, getErrorMessage(err));
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
const subcollections = flatSchema.filter((item) => item.type === 'collection' && item.parentPath === collection.logicalPath);
|
|
144
|
-
const manifestSubcollections = [];
|
|
145
|
-
for (const sub of subcollections) {
|
|
146
|
-
if (isCollectionExcluded(sub.logicalPath, contentRoot, config))
|
|
147
|
-
continue;
|
|
148
|
-
const subResult = await processCollection(store, sub, flatSchema, contentRoot, config, idIndex, entryLinkUrl);
|
|
149
|
-
entries.push(...subResult.entries);
|
|
150
|
-
for (const [filePath, content] of subResult.files) {
|
|
151
|
-
files.set(filePath, content);
|
|
152
266
|
}
|
|
153
|
-
manifestSubcollections.push(subResult.manifestCollection);
|
|
154
267
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
268
|
+
return pending;
|
|
269
|
+
}
|
|
270
|
+
/** Write each rendered entry's file and return its manifest rows. */
|
|
271
|
+
function emitEntries(entries, files) {
|
|
272
|
+
return entries.filter(isRendered).map((pending) => {
|
|
273
|
+
files.set(pending.filePath, pending.markdown);
|
|
274
|
+
return {
|
|
275
|
+
slug: pending.entry.slug,
|
|
276
|
+
title: frontmatterTitle(pending.entry.data),
|
|
277
|
+
file: pending.filePath,
|
|
278
|
+
};
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
/** Write a collection's entry files and all.md, recursively, and return its manifest node. */
|
|
282
|
+
function emitCollection(node, files) {
|
|
283
|
+
const manifestEntries = emitEntries(node.entries, files);
|
|
284
|
+
const manifestSubcollections = node.subcollections.map((sub) => emitCollection(sub, files));
|
|
285
|
+
// all.md covers direct entries + subcollection entries
|
|
286
|
+
const rendered = subtreeEntries(node).filter(isRendered);
|
|
287
|
+
const allPath = `${node.cleanPath}/all.md`;
|
|
288
|
+
if (rendered.length > 0) {
|
|
289
|
+
files.set(allPath, rendered.map((p) => p.markdown).join('\n---\n\n'));
|
|
160
290
|
}
|
|
161
|
-
|
|
162
|
-
name: collection.name,
|
|
163
|
-
label: collection.label,
|
|
164
|
-
description: collection.description,
|
|
165
|
-
path: cleanPath,
|
|
166
|
-
allFile:
|
|
167
|
-
entryCount:
|
|
291
|
+
return {
|
|
292
|
+
name: node.collection.name,
|
|
293
|
+
label: node.collection.label,
|
|
294
|
+
description: node.collection.description,
|
|
295
|
+
path: node.cleanPath,
|
|
296
|
+
allFile: rendered.length > 0 ? allPath : undefined,
|
|
297
|
+
entryCount: rendered.length,
|
|
168
298
|
entries: manifestEntries,
|
|
169
299
|
subcollections: manifestSubcollections.length > 0 ? manifestSubcollections : undefined,
|
|
170
300
|
};
|
|
171
|
-
return { entries, files, manifestCollection };
|
|
172
301
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
302
|
+
/**
|
|
303
|
+
* Refuse a `referenceLink` that is not a function, which would otherwise fail every call and
|
|
304
|
+
* withhold every link it governs, one warning per target.
|
|
305
|
+
*/
|
|
306
|
+
function assertValidReferenceLink(config) {
|
|
307
|
+
const referenceLink = config?.referenceLink;
|
|
308
|
+
if (referenceLink !== undefined && typeof referenceLink !== 'function') {
|
|
309
|
+
throw new Error(`AI content config: referenceLink must be a function, got ${typeof referenceLink}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Refuse an `exclude.noindex` or `seo` the noindex gate would misread. A non-boolean
|
|
314
|
+
* `noindex: 'false'` would leave the gate on while the adopter believes it is off, and a
|
|
315
|
+
* misshapen `seo` reads the flag from a field no entry sets, so every noindex entry ships.
|
|
316
|
+
*/
|
|
317
|
+
function assertValidNoindexConfig(config) {
|
|
318
|
+
const noindex = config?.exclude?.noindex;
|
|
319
|
+
if (noindex !== undefined && typeof noindex !== 'boolean') {
|
|
320
|
+
throw new Error(`AI content config: exclude.noindex must be a boolean, got ${typeof noindex}`);
|
|
321
|
+
}
|
|
322
|
+
const seo = config?.seo;
|
|
323
|
+
if (seo === undefined)
|
|
324
|
+
return;
|
|
325
|
+
if (typeof seo !== 'object' || seo === null || Array.isArray(seo)) {
|
|
326
|
+
throw new Error('AI content config: seo must be an object of { group?, fields? }');
|
|
327
|
+
}
|
|
328
|
+
const { group, fields } = seo;
|
|
329
|
+
if (group !== undefined && typeof group !== 'string') {
|
|
330
|
+
throw new Error('AI content config: seo.group must be a string');
|
|
331
|
+
}
|
|
332
|
+
if (fields === undefined)
|
|
333
|
+
return;
|
|
334
|
+
if (typeof fields !== 'object' ||
|
|
335
|
+
fields === null ||
|
|
336
|
+
Array.isArray(fields) ||
|
|
337
|
+
Object.values(fields).some((name) => typeof name !== 'string')) {
|
|
338
|
+
throw new Error('AI content config: seo.fields must map SEO fields to field-name strings');
|
|
339
|
+
}
|
|
340
|
+
// An unknown key (`noIndex`) would leave the gate reading the default field name
|
|
341
|
+
const unknown = Object.keys(fields).filter((key) => !(key in DEFAULT_SEO_FIELD_NAMES));
|
|
342
|
+
if (unknown.length > 0) {
|
|
343
|
+
throw new Error(`AI content config: unknown seo.fields key(s): ${unknown.join(', ')}`);
|
|
215
344
|
}
|
|
216
|
-
return { entries, files, manifestEntries };
|
|
217
345
|
}
|
|
218
346
|
function stripContentRoot(logicalPath, contentRoot) {
|
|
219
347
|
if (logicalPath.startsWith(contentRoot + '/')) {
|
|
@@ -282,8 +410,9 @@ function makeReadSibling(dir) {
|
|
|
282
410
|
/**
|
|
283
411
|
* Run the configured entry transform (if any), caching its returned markdown on
|
|
284
412
|
* `entry.appendedSections`. The transform receives the entry's content ID and a directory-bound
|
|
285
|
-
* `readSibling`. Runs
|
|
286
|
-
*
|
|
413
|
+
* `readSibling`. Runs for every entry in the first round, then again in any later round whose
|
|
414
|
+
* masking changed the entry, always on the data as masked; the cached result is reused across the per-entry file, the collection `all.md`, and any bundle that
|
|
415
|
+
* includes this entry. A throwing transform is logged and
|
|
287
416
|
* skipped — the entry still renders without the appended section (distinct from an unreadable
|
|
288
417
|
* entry, which is skipped entirely upstream).
|
|
289
418
|
*/
|
package/dist/ai/index.d.ts
CHANGED
|
@@ -9,6 +9,6 @@ export { createAIContentHandler } from './handler.js';
|
|
|
9
9
|
export { generateAIContent } from './generate.js';
|
|
10
10
|
/** See `to-plain-text.ts`'s module doc for the pipeline and why it differs from the AI-content path above. */
|
|
11
11
|
export { toPlainText } from './to-plain-text.js';
|
|
12
|
-
export type { AIContentConfig, ExcludeConfig, BundleConfig, BundleFilter, FieldTransformFn, FieldTransforms, ComponentProps, ComponentTransformFn, ComponentTransforms, BodyTransformFn, BodyTransforms, EntryTransformFn, EntryTransforms, EntryTransformContext, AIManifest, AIManifestCollection, AIManifestEntry, AIManifestBundle, AIEntry, AIEntryMeta, } from './types.js';
|
|
12
|
+
export type { AIContentConfig, ExcludeConfig, BundleConfig, BundleFilter, FieldTransformFn, FieldTransforms, ComponentProps, ComponentTransformFn, ComponentTransforms, BodyTransformFn, BodyTransforms, EntryTransformFn, EntryTransforms, EntryTransformContext, AIManifest, AIManifestCollection, AIManifestEntry, AIManifestBundle, AIEntry, AIEntryMeta, AIExcludedReference, AIReferenceLinkContext, AIReferenceLinkFn, AIReferenceValue, AIResolvedReference, AIUnavailableReference, } from './types.js';
|
|
13
13
|
export type { AIContentHandlerOptions } from './handler.js';
|
|
14
14
|
export type { GenerateOptions, GenerateResult } from './generate.js';
|
|
@@ -5,10 +5,30 @@
|
|
|
5
5
|
* Handles all CanopyCMS field types including nested objects and blocks.
|
|
6
6
|
*/
|
|
7
7
|
import type { AIEntry, AIContentConfig } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* How a resolved reference becomes link text and a link target. generate.ts supplies one that
|
|
10
|
+
* knows every target's schema and the adopter's `entryLinkUrl`; the default needs neither.
|
|
11
|
+
*/
|
|
12
|
+
export interface ReferenceRendering {
|
|
13
|
+
/** Display title of a resolved target, used unless the field's `displayField` holds text. */
|
|
14
|
+
title(target: Record<string, unknown>): string;
|
|
15
|
+
/**
|
|
16
|
+
* Where the page link points: undefined renders the title as plain text, and `false` also
|
|
17
|
+
* drops the markdown copy, for a target the site says has no page.
|
|
18
|
+
*/
|
|
19
|
+
url(target: Record<string, unknown>): string | false | undefined;
|
|
20
|
+
/** URL of the target's own file in this export, linked after the page as its markdown copy. */
|
|
21
|
+
markdownUrl?(target: Record<string, unknown>): string | undefined;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The entry's `title` as frontmatter carries it. Only a scalar qualifies: a `reference` field
|
|
25
|
+
* named `title` holds an object and renders as a field instead.
|
|
26
|
+
*/
|
|
27
|
+
export declare function frontmatterTitle(data: Record<string, unknown>): string | undefined;
|
|
8
28
|
/**
|
|
9
29
|
* Convert an entry to clean markdown suitable for AI consumption.
|
|
10
30
|
*
|
|
11
31
|
* For MD/MDX entries: renders frontmatter fields as metadata, appends body verbatim.
|
|
12
32
|
* For JSON entries: full schema-driven conversion of all fields.
|
|
13
33
|
*/
|
|
14
|
-
export declare function entryToMarkdown(entry: AIEntry, config?: AIContentConfig): string;
|
|
34
|
+
export declare function entryToMarkdown(entry: AIEntry, config?: AIContentConfig, references?: ReferenceRendering): string;
|