@canvas-digital/blog-sdk 2.0.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/README.md +110 -0
- package/dist/BlogPlatform.d.ts +40 -0
- package/dist/BlogPlatform.d.ts.map +1 -0
- package/dist/BlogPlatform.js +38 -0
- package/dist/admin/components/BlogAdmin.d.ts +10 -0
- package/dist/admin/components/BlogAdmin.d.ts.map +1 -0
- package/dist/admin/components/BlogAdmin.js +36 -0
- package/dist/admin/components/CategoryManager.d.ts +5 -0
- package/dist/admin/components/CategoryManager.d.ts.map +1 -0
- package/dist/admin/components/CategoryManager.js +43 -0
- package/dist/admin/components/MediaManager.d.ts +7 -0
- package/dist/admin/components/MediaManager.d.ts.map +1 -0
- package/dist/admin/components/MediaManager.js +37 -0
- package/dist/admin/components/PostEditor.d.ts +7 -0
- package/dist/admin/components/PostEditor.d.ts.map +1 -0
- package/dist/admin/components/PostEditor.js +160 -0
- package/dist/admin/components/PostList.d.ts +8 -0
- package/dist/admin/components/PostList.d.ts.map +1 -0
- package/dist/admin/components/PostList.js +32 -0
- package/dist/admin/components/TagManager.d.ts +5 -0
- package/dist/admin/components/TagManager.d.ts.map +1 -0
- package/dist/admin/components/TagManager.js +41 -0
- package/dist/admin/components/editor/RichTextEditor.d.ts +8 -0
- package/dist/admin/components/editor/RichTextEditor.d.ts.map +1 -0
- package/dist/admin/components/editor/RichTextEditor.js +47 -0
- package/dist/admin/components/internal/States.d.ts +16 -0
- package/dist/admin/components/internal/States.d.ts.map +1 -0
- package/dist/admin/components/internal/States.js +15 -0
- package/dist/admin/hooks/useAsync.d.ts +23 -0
- package/dist/admin/hooks/useAsync.d.ts.map +1 -0
- package/dist/admin/hooks/useAsync.js +40 -0
- package/dist/admin/index.d.ts +10 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +9 -0
- package/dist/admin/theme.d.ts +6 -0
- package/dist/admin/theme.d.ts.map +1 -0
- package/dist/admin/theme.js +52 -0
- package/dist/admin/types.d.ts +27 -0
- package/dist/admin/types.d.ts.map +1 -0
- package/dist/admin/types.js +1 -0
- package/dist/blog-client.iife.js +1 -0
- package/dist/client/admin-client.d.ts +33 -0
- package/dist/client/admin-client.d.ts.map +1 -0
- package/dist/client/admin-client.js +153 -0
- package/dist/client/errors.d.ts +14 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +26 -0
- package/dist/client/http.d.ts +12 -0
- package/dist/client/http.d.ts.map +1 -0
- package/dist/client/http.js +135 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +6 -0
- package/dist/client/pagination.d.ts +4 -0
- package/dist/client/pagination.d.ts.map +1 -0
- package/dist/client/pagination.js +32 -0
- package/dist/client/public-client.d.ts +23 -0
- package/dist/client/public-client.d.ts.map +1 -0
- package/dist/client/public-client.js +94 -0
- package/dist/client/types.d.ts +115 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +1 -0
- package/dist/components/BlogUploader/BackButton.d.ts +5 -0
- package/dist/components/BlogUploader/BackButton.d.ts.map +1 -0
- package/dist/components/BlogUploader/BackButton.js +27 -0
- package/dist/components/BlogUploader/CommentSection.d.ts +12 -0
- package/dist/components/BlogUploader/CommentSection.d.ts.map +1 -0
- package/dist/components/BlogUploader/CommentSection.js +65 -0
- package/dist/components/BlogUploader/PostCard.d.ts +17 -0
- package/dist/components/BlogUploader/PostCard.d.ts.map +1 -0
- package/dist/components/BlogUploader/PostCard.js +42 -0
- package/dist/components/BlogUploader/PostFormatHero.d.ts +7 -0
- package/dist/components/BlogUploader/PostFormatHero.d.ts.map +1 -0
- package/dist/components/BlogUploader/PostFormatHero.js +47 -0
- package/dist/components/BlogUploader/ReadingProgress.d.ts +9 -0
- package/dist/components/BlogUploader/ReadingProgress.d.ts.map +1 -0
- package/dist/components/BlogUploader/ReadingProgress.js +28 -0
- package/dist/components/BlogUploader/RichText.d.ts +5 -0
- package/dist/components/BlogUploader/RichText.d.ts.map +1 -0
- package/dist/components/BlogUploader/RichText.js +59 -0
- package/dist/components/BlogUploader/ShareRow.d.ts +12 -0
- package/dist/components/BlogUploader/ShareRow.d.ts.map +1 -0
- package/dist/components/BlogUploader/ShareRow.js +13 -0
- package/dist/components/BlogUploader/ViewBeacon.d.ts +12 -0
- package/dist/components/BlogUploader/ViewBeacon.d.ts.map +1 -0
- package/dist/components/BlogUploader/ViewBeacon.js +37 -0
- package/dist/components/BlogUploader/dashboard/BrandSettings.d.ts +28 -0
- package/dist/components/BlogUploader/dashboard/BrandSettings.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/BrandSettings.js +60 -0
- package/dist/components/BlogUploader/dashboard/BrandSwitcher.d.ts +14 -0
- package/dist/components/BlogUploader/dashboard/BrandSwitcher.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/BrandSwitcher.js +25 -0
- package/dist/components/BlogUploader/dashboard/Chips.d.ts +15 -0
- package/dist/components/BlogUploader/dashboard/Chips.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/Chips.js +15 -0
- package/dist/components/BlogUploader/dashboard/CommentsManager.d.ts +19 -0
- package/dist/components/BlogUploader/dashboard/CommentsManager.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/CommentsManager.js +32 -0
- package/dist/components/BlogUploader/dashboard/LogOutButton.d.ts +4 -0
- package/dist/components/BlogUploader/dashboard/LogOutButton.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/LogOutButton.js +22 -0
- package/dist/components/BlogUploader/dashboard/MediaLibrary.d.ts +16 -0
- package/dist/components/BlogUploader/dashboard/MediaLibrary.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/MediaLibrary.js +124 -0
- package/dist/components/BlogUploader/dashboard/MediaPicker.d.ts +19 -0
- package/dist/components/BlogUploader/dashboard/MediaPicker.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/MediaPicker.js +99 -0
- package/dist/components/BlogUploader/dashboard/PostsTable.d.ts +46 -0
- package/dist/components/BlogUploader/dashboard/PostsTable.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/PostsTable.js +109 -0
- package/dist/components/BlogUploader/dashboard/Shell.d.ts +25 -0
- package/dist/components/BlogUploader/dashboard/Shell.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/Shell.js +128 -0
- package/dist/components/BlogUploader/dashboard/TermManager.d.ts +29 -0
- package/dist/components/BlogUploader/dashboard/TermManager.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/TermManager.js +96 -0
- package/dist/components/BlogUploader/dashboard/ToastProvider.d.ts +6 -0
- package/dist/components/BlogUploader/dashboard/ToastProvider.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/ToastProvider.js +5 -0
- package/dist/components/BlogUploader/dashboard/UsersManager.d.ts +32 -0
- package/dist/components/BlogUploader/dashboard/UsersManager.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/UsersManager.js +98 -0
- package/dist/components/BlogUploader/dashboard/charts.d.ts +22 -0
- package/dist/components/BlogUploader/dashboard/charts.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/charts.js +79 -0
- package/dist/components/BlogUploader/dashboard/editor/FormatContentPanel.d.ts +25 -0
- package/dist/components/BlogUploader/dashboard/editor/FormatContentPanel.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/FormatContentPanel.js +62 -0
- package/dist/components/BlogUploader/dashboard/editor/PostEditor.d.ts +95 -0
- package/dist/components/BlogUploader/dashboard/editor/PostEditor.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/PostEditor.js +649 -0
- package/dist/components/BlogUploader/dashboard/editor/RichTextEditor.d.ts +37 -0
- package/dist/components/BlogUploader/dashboard/editor/RichTextEditor.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/RichTextEditor.js +475 -0
- package/dist/components/BlogUploader/dashboard/editor/SeoAnalysisPanel.d.ts +11 -0
- package/dist/components/BlogUploader/dashboard/editor/SeoAnalysisPanel.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/SeoAnalysisPanel.js +31 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastCollapsible.d.ts +12 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastCollapsible.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastCollapsible.js +5 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastInsightsPanel.d.ts +4 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastInsightsPanel.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastInsightsPanel.js +31 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastInternalLinksPanel.d.ts +4 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastInternalLinksPanel.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastInternalLinksPanel.js +35 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastSeoAnalysisPanel.d.ts +11 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastSeoAnalysisPanel.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastSeoAnalysisPanel.js +23 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastSeoMetabox.d.ts +50 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastSeoMetabox.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastSeoMetabox.js +101 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastSnippetField.d.ts +22 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastSnippetField.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/YoastSnippetField.js +51 -0
- package/dist/components/BlogUploader/dashboard/editor/load.d.ts +10 -0
- package/dist/components/BlogUploader/dashboard/editor/load.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/editor/load.js +141 -0
- package/dist/components/BlogUploader/dashboard/loadTerms.d.ts +13 -0
- package/dist/components/BlogUploader/dashboard/loadTerms.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/loadTerms.js +41 -0
- package/dist/components/BlogUploader/dashboard/seo/BrandSeoActions.d.ts +8 -0
- package/dist/components/BlogUploader/dashboard/seo/BrandSeoActions.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/BrandSeoActions.js +35 -0
- package/dist/components/BlogUploader/dashboard/seo/Ga4Settings.d.ts +9 -0
- package/dist/components/BlogUploader/dashboard/seo/Ga4Settings.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/Ga4Settings.js +40 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectAnalyticsDashboard.d.ts +5 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectAnalyticsDashboard.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectAnalyticsDashboard.js +29 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectDetail.d.ts +10 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectDetail.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectDetail.js +31 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectForm.d.ts +27 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectForm.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectForm.js +79 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectList.d.ts +20 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectList.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/RedirectList.js +33 -0
- package/dist/components/BlogUploader/dashboard/seo/RobotsEditor.d.ts +11 -0
- package/dist/components/BlogUploader/dashboard/seo/RobotsEditor.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/RobotsEditor.js +54 -0
- package/dist/components/BlogUploader/dashboard/seo/SearchConsoleSettings.d.ts +9 -0
- package/dist/components/BlogUploader/dashboard/seo/SearchConsoleSettings.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/SearchConsoleSettings.js +38 -0
- package/dist/components/BlogUploader/dashboard/seo/SeoBrandList.d.ts +28 -0
- package/dist/components/BlogUploader/dashboard/seo/SeoBrandList.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/SeoBrandList.js +29 -0
- package/dist/components/BlogUploader/dashboard/seo/SeoBrandLists.d.ts +17 -0
- package/dist/components/BlogUploader/dashboard/seo/SeoBrandLists.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/SeoBrandLists.js +8 -0
- package/dist/components/BlogUploader/dashboard/seo/shared.d.ts +18 -0
- package/dist/components/BlogUploader/dashboard/seo/shared.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/seo/shared.js +6 -0
- package/dist/components/BlogUploader/dashboard/tools/ExportTool.d.ts +8 -0
- package/dist/components/BlogUploader/dashboard/tools/ExportTool.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/tools/ExportTool.js +78 -0
- package/dist/components/BlogUploader/dashboard/tools/ImportTool.d.ts +7 -0
- package/dist/components/BlogUploader/dashboard/tools/ImportTool.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/tools/ImportTool.js +70 -0
- package/dist/components/BlogUploader/dashboard/upload.d.ts +47 -0
- package/dist/components/BlogUploader/dashboard/upload.d.ts.map +1 -0
- package/dist/components/BlogUploader/dashboard/upload.js +68 -0
- package/dist/components/BlogUploader/site/ArticleDetailHero.d.ts +27 -0
- package/dist/components/BlogUploader/site/ArticleDetailHero.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/ArticleDetailHero.js +13 -0
- package/dist/components/BlogUploader/site/ArticleRailDetails.d.ts +27 -0
- package/dist/components/BlogUploader/site/ArticleRailDetails.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/ArticleRailDetails.js +17 -0
- package/dist/components/BlogUploader/site/BlogIndexView.d.ts +28 -0
- package/dist/components/BlogUploader/site/BlogIndexView.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/BlogIndexView.js +34 -0
- package/dist/components/BlogUploader/site/BrandTableOfContents.d.ts +18 -0
- package/dist/components/BlogUploader/site/BrandTableOfContents.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/BrandTableOfContents.js +15 -0
- package/dist/components/BlogUploader/site/HeroFadeSlide.d.ts +11 -0
- package/dist/components/BlogUploader/site/HeroFadeSlide.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/HeroFadeSlide.js +3 -0
- package/dist/components/BlogUploader/site/HeroMediaVisual.d.ts +23 -0
- package/dist/components/BlogUploader/site/HeroMediaVisual.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/HeroMediaVisual.js +50 -0
- package/dist/components/BlogUploader/site/IndexFeedSection.d.ts +14 -0
- package/dist/components/BlogUploader/site/IndexFeedSection.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/IndexFeedSection.js +12 -0
- package/dist/components/BlogUploader/site/InfinitePostFeed.d.ts +23 -0
- package/dist/components/BlogUploader/site/InfinitePostFeed.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/InfinitePostFeed.js +152 -0
- package/dist/components/BlogUploader/site/SiteMediaHero.d.ts +12 -0
- package/dist/components/BlogUploader/site/SiteMediaHero.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/SiteMediaHero.js +80 -0
- package/dist/components/BlogUploader/site/SiteMotion.d.ts +12 -0
- package/dist/components/BlogUploader/site/SiteMotion.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/SiteMotion.js +27 -0
- package/dist/components/BlogUploader/site/SiteNavAuth.d.ts +8 -0
- package/dist/components/BlogUploader/site/SiteNavAuth.d.ts.map +1 -0
- package/dist/components/BlogUploader/site/SiteNavAuth.js +36 -0
- package/dist/components/admin/AdminPostDetail.d.ts +7 -0
- package/dist/components/admin/AdminPostDetail.d.ts.map +1 -0
- package/dist/components/admin/AdminPostDetail.js +105 -0
- package/dist/components/admin/BrandSettings.d.ts +11 -0
- package/dist/components/admin/BrandSettings.d.ts.map +1 -0
- package/dist/components/admin/BrandSettings.js +71 -0
- package/dist/components/admin/BrandSwitcher.d.ts +3 -0
- package/dist/components/admin/BrandSwitcher.d.ts.map +1 -0
- package/dist/components/admin/BrandSwitcher.js +12 -0
- package/dist/components/admin/CategoryManager.d.ts +2 -0
- package/dist/components/admin/CategoryManager.d.ts.map +1 -0
- package/dist/components/admin/CategoryManager.js +1 -0
- package/dist/components/admin/Chips.d.ts +15 -0
- package/dist/components/admin/Chips.d.ts.map +1 -0
- package/dist/components/admin/Chips.js +15 -0
- package/dist/components/admin/CommentsManager.d.ts +6 -0
- package/dist/components/admin/CommentsManager.d.ts.map +1 -0
- package/dist/components/admin/CommentsManager.js +30 -0
- package/dist/components/admin/Dashboard.d.ts +3 -0
- package/dist/components/admin/Dashboard.d.ts.map +1 -0
- package/dist/components/admin/Dashboard.js +34 -0
- package/dist/components/admin/MediaLibrary.d.ts +4 -0
- package/dist/components/admin/MediaLibrary.d.ts.map +1 -0
- package/dist/components/admin/MediaLibrary.js +119 -0
- package/dist/components/admin/MediaManager.d.ts +2 -0
- package/dist/components/admin/MediaManager.d.ts.map +1 -0
- package/dist/components/admin/MediaManager.js +1 -0
- package/dist/components/admin/MediaPicker.d.ts +10 -0
- package/dist/components/admin/MediaPicker.d.ts.map +1 -0
- package/dist/components/admin/MediaPicker.js +86 -0
- package/dist/components/admin/PostEditor.d.ts +2 -0
- package/dist/components/admin/PostEditor.d.ts.map +1 -0
- package/dist/components/admin/PostEditor.js +1 -0
- package/dist/components/admin/PostList.d.ts +13 -0
- package/dist/components/admin/PostList.d.ts.map +1 -0
- package/dist/components/admin/PostList.js +93 -0
- package/dist/components/admin/PostsTable.d.ts +15 -0
- package/dist/components/admin/PostsTable.d.ts.map +1 -0
- package/dist/components/admin/PostsTable.js +106 -0
- package/dist/components/admin/Shell.d.ts +18 -0
- package/dist/components/admin/Shell.d.ts.map +1 -0
- package/dist/components/admin/Shell.js +99 -0
- package/dist/components/admin/TagManager.d.ts +2 -0
- package/dist/components/admin/TagManager.d.ts.map +1 -0
- package/dist/components/admin/TagManager.js +1 -0
- package/dist/components/admin/TermManager.d.ts +9 -0
- package/dist/components/admin/TermManager.d.ts.map +1 -0
- package/dist/components/admin/TermManager.js +105 -0
- package/dist/components/admin/UsersManager.d.ts +5 -0
- package/dist/components/admin/UsersManager.d.ts.map +1 -0
- package/dist/components/admin/UsersManager.js +96 -0
- package/dist/components/admin/api/mappers.d.ts +37 -0
- package/dist/components/admin/api/mappers.d.ts.map +1 -0
- package/dist/components/admin/api/mappers.js +174 -0
- package/dist/components/admin/charts.d.ts +30 -0
- package/dist/components/admin/charts.d.ts.map +1 -0
- package/dist/components/admin/charts.js +79 -0
- package/dist/components/admin/editor/FormatContentPanel.d.ts +25 -0
- package/dist/components/admin/editor/FormatContentPanel.d.ts.map +1 -0
- package/dist/components/admin/editor/FormatContentPanel.js +62 -0
- package/dist/components/admin/editor/PostEditor.d.ts +5 -0
- package/dist/components/admin/editor/PostEditor.d.ts.map +1 -0
- package/dist/components/admin/editor/PostEditor.js +404 -0
- package/dist/components/admin/editor/RichTextEditor.d.ts +42 -0
- package/dist/components/admin/editor/RichTextEditor.d.ts.map +1 -0
- package/dist/components/admin/editor/RichTextEditor.js +475 -0
- package/dist/components/admin/editor/SeoAnalysisPanel.d.ts +11 -0
- package/dist/components/admin/editor/SeoAnalysisPanel.d.ts.map +1 -0
- package/dist/components/admin/editor/SeoAnalysisPanel.js +31 -0
- package/dist/components/admin/editor/YoastCollapsible.d.ts +12 -0
- package/dist/components/admin/editor/YoastCollapsible.d.ts.map +1 -0
- package/dist/components/admin/editor/YoastCollapsible.js +5 -0
- package/dist/components/admin/editor/YoastInsightsPanel.d.ts +4 -0
- package/dist/components/admin/editor/YoastInsightsPanel.d.ts.map +1 -0
- package/dist/components/admin/editor/YoastInsightsPanel.js +31 -0
- package/dist/components/admin/editor/YoastInternalLinksPanel.d.ts +4 -0
- package/dist/components/admin/editor/YoastInternalLinksPanel.d.ts.map +1 -0
- package/dist/components/admin/editor/YoastInternalLinksPanel.js +35 -0
- package/dist/components/admin/editor/YoastSeoAnalysisPanel.d.ts +11 -0
- package/dist/components/admin/editor/YoastSeoAnalysisPanel.d.ts.map +1 -0
- package/dist/components/admin/editor/YoastSeoAnalysisPanel.js +23 -0
- package/dist/components/admin/editor/YoastSeoMetabox.d.ts +54 -0
- package/dist/components/admin/editor/YoastSeoMetabox.d.ts.map +1 -0
- package/dist/components/admin/editor/YoastSeoMetabox.js +101 -0
- package/dist/components/admin/editor/YoastSnippetField.d.ts +22 -0
- package/dist/components/admin/editor/YoastSnippetField.d.ts.map +1 -0
- package/dist/components/admin/editor/YoastSnippetField.js +51 -0
- package/dist/components/admin/editor/load.d.ts +10 -0
- package/dist/components/admin/editor/load.d.ts.map +1 -0
- package/dist/components/admin/editor/load.js +141 -0
- package/dist/components/admin/index.d.ts +28 -0
- package/dist/components/admin/index.d.ts.map +1 -0
- package/dist/components/admin/index.js +27 -0
- package/dist/components/admin/internal/States.d.ts +16 -0
- package/dist/components/admin/internal/States.d.ts.map +1 -0
- package/dist/components/admin/internal/States.js +15 -0
- package/dist/components/admin/lib/format.d.ts +7 -0
- package/dist/components/admin/lib/format.d.ts.map +1 -0
- package/dist/components/admin/lib/format.js +43 -0
- package/dist/components/admin/lib/publishing.d.ts +8 -0
- package/dist/components/admin/lib/publishing.d.ts.map +1 -0
- package/dist/components/admin/lib/publishing.js +10 -0
- package/dist/components/admin/lib/robots.d.ts +13 -0
- package/dist/components/admin/lib/robots.d.ts.map +1 -0
- package/dist/components/admin/lib/robots.js +22 -0
- package/dist/components/admin/mock/fixtures.d.ts +240 -0
- package/dist/components/admin/mock/fixtures.d.ts.map +1 -0
- package/dist/components/admin/mock/fixtures.js +546 -0
- package/dist/components/admin/mock/store.d.ts +139 -0
- package/dist/components/admin/mock/store.d.ts.map +1 -0
- package/dist/components/admin/mock/store.js +1067 -0
- package/dist/components/admin/seo/Ga4Settings.d.ts +34 -0
- package/dist/components/admin/seo/Ga4Settings.d.ts.map +1 -0
- package/dist/components/admin/seo/Ga4Settings.js +80 -0
- package/dist/components/admin/seo/RedirectAnalyticsDashboard.d.ts +5 -0
- package/dist/components/admin/seo/RedirectAnalyticsDashboard.d.ts.map +1 -0
- package/dist/components/admin/seo/RedirectAnalyticsDashboard.js +24 -0
- package/dist/components/admin/seo/RedirectDetail.d.ts +11 -0
- package/dist/components/admin/seo/RedirectDetail.d.ts.map +1 -0
- package/dist/components/admin/seo/RedirectDetail.js +30 -0
- package/dist/components/admin/seo/RedirectForm.d.ts +29 -0
- package/dist/components/admin/seo/RedirectForm.d.ts.map +1 -0
- package/dist/components/admin/seo/RedirectForm.js +89 -0
- package/dist/components/admin/seo/RedirectList.d.ts +10 -0
- package/dist/components/admin/seo/RedirectList.d.ts.map +1 -0
- package/dist/components/admin/seo/RedirectList.js +28 -0
- package/dist/components/admin/seo/RobotsEditor.d.ts +5 -0
- package/dist/components/admin/seo/RobotsEditor.d.ts.map +1 -0
- package/dist/components/admin/seo/RobotsEditor.js +50 -0
- package/dist/components/admin/seo/SearchConsoleSettings.d.ts +3 -0
- package/dist/components/admin/seo/SearchConsoleSettings.d.ts.map +1 -0
- package/dist/components/admin/seo/SearchConsoleSettings.js +1 -0
- package/dist/components/admin/seo/SeoBrandList.d.ts +3 -0
- package/dist/components/admin/seo/SeoBrandList.d.ts.map +1 -0
- package/dist/components/admin/seo/SeoBrandList.js +1 -0
- package/dist/components/admin/seo/shared.d.ts +17 -0
- package/dist/components/admin/seo/shared.d.ts.map +1 -0
- package/dist/components/admin/seo/shared.js +7 -0
- package/dist/components/admin/tools/ExportTool.d.ts +3 -0
- package/dist/components/admin/tools/ExportTool.d.ts.map +1 -0
- package/dist/components/admin/tools/ExportTool.js +1 -0
- package/dist/components/admin/tools/ImportTool.d.ts +3 -0
- package/dist/components/admin/tools/ImportTool.d.ts.map +1 -0
- package/dist/components/admin/tools/ImportTool.js +1 -0
- package/dist/components/admin/tools/ToolsHub.d.ts +10 -0
- package/dist/components/admin/tools/ToolsHub.d.ts.map +1 -0
- package/dist/components/admin/tools/ToolsHub.js +106 -0
- package/dist/components/admin/tools/index.d.ts +3 -0
- package/dist/components/admin/tools/index.d.ts.map +1 -0
- package/dist/components/admin/tools/index.js +1 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +2 -0
- package/dist/components/user/BlogCard.d.ts +20 -0
- package/dist/components/user/BlogCard.d.ts.map +1 -0
- package/dist/components/user/BlogCard.js +22 -0
- package/dist/components/user/BlogCategories.d.ts +6 -0
- package/dist/components/user/BlogCategories.d.ts.map +1 -0
- package/dist/components/user/BlogCategories.js +11 -0
- package/dist/components/user/BlogDetail.d.ts +25 -0
- package/dist/components/user/BlogDetail.d.ts.map +1 -0
- package/dist/components/user/BlogDetail.js +90 -0
- package/dist/components/user/BlogList.d.ts +20 -0
- package/dist/components/user/BlogList.d.ts.map +1 -0
- package/dist/components/user/BlogList.js +56 -0
- package/dist/components/user/BlogSearch.d.ts +8 -0
- package/dist/components/user/BlogSearch.d.ts.map +1 -0
- package/dist/components/user/BlogSearch.js +19 -0
- package/dist/components/user/BlogTags.d.ts +6 -0
- package/dist/components/user/BlogTags.d.ts.map +1 -0
- package/dist/components/user/BlogTags.js +11 -0
- package/dist/components/user/FeaturedBlogs.d.ts +8 -0
- package/dist/components/user/FeaturedBlogs.d.ts.map +1 -0
- package/dist/components/user/FeaturedBlogs.js +12 -0
- package/dist/components/user/RelatedBlogs.d.ts +9 -0
- package/dist/components/user/RelatedBlogs.d.ts.map +1 -0
- package/dist/components/user/RelatedBlogs.js +12 -0
- package/dist/components/user/SiteMediaHero.d.ts +14 -0
- package/dist/components/user/SiteMediaHero.d.ts.map +1 -0
- package/dist/components/user/SiteMediaHero.js +43 -0
- package/dist/components/user/detail/ArticleDetailHero.d.ts +30 -0
- package/dist/components/user/detail/ArticleDetailHero.d.ts.map +1 -0
- package/dist/components/user/detail/ArticleDetailHero.js +29 -0
- package/dist/components/user/detail/ArticleRailDetails.d.ts +24 -0
- package/dist/components/user/detail/ArticleRailDetails.d.ts.map +1 -0
- package/dist/components/user/detail/ArticleRailDetails.js +12 -0
- package/dist/components/user/detail/BackButton.d.ts +7 -0
- package/dist/components/user/detail/BackButton.d.ts.map +1 -0
- package/dist/components/user/detail/BackButton.js +18 -0
- package/dist/components/user/detail/CommentSection.d.ts +28 -0
- package/dist/components/user/detail/CommentSection.d.ts.map +1 -0
- package/dist/components/user/detail/CommentSection.js +68 -0
- package/dist/components/user/detail/HeroFadeSlide.d.ts +12 -0
- package/dist/components/user/detail/HeroFadeSlide.d.ts.map +1 -0
- package/dist/components/user/detail/HeroFadeSlide.js +5 -0
- package/dist/components/user/detail/ReadingProgress.d.ts +2 -0
- package/dist/components/user/detail/ReadingProgress.d.ts.map +1 -0
- package/dist/components/user/detail/ReadingProgress.js +20 -0
- package/dist/components/user/detail/ShareRow.d.ts +7 -0
- package/dist/components/user/detail/ShareRow.d.ts.map +1 -0
- package/dist/components/user/detail/ShareRow.js +7 -0
- package/dist/components/user/detail/toc.d.ts +14 -0
- package/dist/components/user/detail/toc.d.ts.map +1 -0
- package/dist/components/user/detail/toc.js +106 -0
- package/dist/components/user/index.d.ts +14 -0
- package/dist/components/user/index.d.ts.map +1 -0
- package/dist/components/user/index.js +13 -0
- package/dist/components/user/internal/States.d.ts +18 -0
- package/dist/components/user/internal/States.d.ts.map +1 -0
- package/dist/components/user/internal/States.js +21 -0
- package/dist/constants/index.d.ts +4 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +3 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useAsync.d.ts +23 -0
- package/dist/hooks/useAsync.d.ts.map +1 -0
- package/dist/hooks/useAsync.js +40 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/lib/access.d.ts +64 -0
- package/dist/lib/access.d.ts.map +1 -0
- package/dist/lib/access.js +127 -0
- package/dist/lib/canonical.d.ts +15 -0
- package/dist/lib/canonical.d.ts.map +1 -0
- package/dist/lib/canonical.js +34 -0
- package/dist/lib/comments.d.ts +9 -0
- package/dist/lib/comments.d.ts.map +1 -0
- package/dist/lib/comments.js +23 -0
- package/dist/lib/dashboard.d.ts +39 -0
- package/dist/lib/dashboard.d.ts.map +1 -0
- package/dist/lib/dashboard.js +157 -0
- package/dist/lib/data-transfer.d.ts +23 -0
- package/dist/lib/data-transfer.d.ts.map +1 -0
- package/dist/lib/data-transfer.js +436 -0
- package/dist/lib/default-author.d.ts +12 -0
- package/dist/lib/default-author.d.ts.map +1 -0
- package/dist/lib/default-author.js +57 -0
- package/dist/lib/format-media.d.ts +6 -0
- package/dist/lib/format-media.d.ts.map +1 -0
- package/dist/lib/format-media.js +18 -0
- package/dist/lib/format.d.ts +7 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +43 -0
- package/dist/lib/hero-post.d.ts +24 -0
- package/dist/lib/hero-post.d.ts.map +1 -0
- package/dist/lib/hero-post.js +95 -0
- package/dist/lib/lexical-build.d.ts +30 -0
- package/dist/lib/lexical-build.d.ts.map +1 -0
- package/dist/lib/lexical-build.js +57 -0
- package/dist/lib/lexical-doc.d.ts +88 -0
- package/dist/lib/lexical-doc.d.ts.map +1 -0
- package/dist/lib/lexical-doc.js +385 -0
- package/dist/lib/lexical-dom.d.ts +19 -0
- package/dist/lib/lexical-dom.d.ts.map +1 -0
- package/dist/lib/lexical-dom.js +181 -0
- package/dist/lib/lexical.d.ts +31 -0
- package/dist/lib/lexical.d.ts.map +1 -0
- package/dist/lib/lexical.js +59 -0
- package/dist/lib/post-categories.d.ts +11 -0
- package/dist/lib/post-categories.d.ts.map +1 -0
- package/dist/lib/post-categories.js +27 -0
- package/dist/lib/post-format.d.ts +39 -0
- package/dist/lib/post-format.d.ts.map +1 -0
- package/dist/lib/post-format.js +82 -0
- package/dist/lib/publishing.d.ts +3 -0
- package/dist/lib/publishing.d.ts.map +1 -0
- package/dist/lib/publishing.js +1 -0
- package/dist/lib/queries.d.ts +49 -0
- package/dist/lib/queries.d.ts.map +1 -0
- package/dist/lib/queries.js +340 -0
- package/dist/lib/redirect-analytics.d.ts +27 -0
- package/dist/lib/redirect-analytics.d.ts.map +1 -0
- package/dist/lib/redirect-analytics.js +147 -0
- package/dist/lib/redirects.d.ts +39 -0
- package/dist/lib/redirects.d.ts.map +1 -0
- package/dist/lib/redirects.js +96 -0
- package/dist/lib/revalidate.d.ts +30 -0
- package/dist/lib/revalidate.d.ts.map +1 -0
- package/dist/lib/revalidate.js +91 -0
- package/dist/lib/robots.d.ts +19 -0
- package/dist/lib/robots.d.ts.map +1 -0
- package/dist/lib/robots.js +38 -0
- package/dist/lib/seo-analysis.d.ts +28 -0
- package/dist/lib/seo-analysis.d.ts.map +1 -0
- package/dist/lib/seo-analysis.js +153 -0
- package/dist/lib/seo-limits.d.ts +19 -0
- package/dist/lib/seo-limits.d.ts.map +1 -0
- package/dist/lib/seo-limits.js +39 -0
- package/dist/lib/seo.d.ts +50 -0
- package/dist/lib/seo.d.ts.map +1 -0
- package/dist/lib/seo.js +238 -0
- package/dist/lib/slug.d.ts +3 -0
- package/dist/lib/slug.d.ts.map +1 -0
- package/dist/lib/slug.js +9 -0
- package/dist/lib/stats.d.ts +71 -0
- package/dist/lib/stats.d.ts.map +1 -0
- package/dist/lib/stats.js +207 -0
- package/dist/lib/tenant-host.d.ts +9 -0
- package/dist/lib/tenant-host.d.ts.map +1 -0
- package/dist/lib/tenant-host.js +15 -0
- package/dist/lib/tenant.d.ts +41 -0
- package/dist/lib/tenant.d.ts.map +1 -0
- package/dist/lib/tenant.js +140 -0
- package/dist/lib/toc.d.ts +16 -0
- package/dist/lib/toc.d.ts.map +1 -0
- package/dist/lib/toc.js +28 -0
- package/dist/lib/yoast-snippet.d.ts +25 -0
- package/dist/lib/yoast-snippet.d.ts.map +1 -0
- package/dist/lib/yoast-snippet.js +79 -0
- package/dist/pages/admin/BlogAdmin.d.ts +9 -0
- package/dist/pages/admin/BlogAdmin.d.ts.map +1 -0
- package/dist/pages/admin/BlogAdmin.js +234 -0
- package/dist/pages/admin/index.d.ts +2 -0
- package/dist/pages/admin/index.d.ts.map +1 -0
- package/dist/pages/admin/index.js +1 -0
- package/dist/pages/index.d.ts +3 -0
- package/dist/pages/index.d.ts.map +1 -0
- package/dist/pages/index.js +2 -0
- package/dist/pages/user/UserBlogPage.d.ts +10 -0
- package/dist/pages/user/UserBlogPage.d.ts.map +1 -0
- package/dist/pages/user/UserBlogPage.js +15 -0
- package/dist/pages/user/index.d.ts +2 -0
- package/dist/pages/user/index.d.ts.map +1 -0
- package/dist/pages/user/index.js +1 -0
- package/dist/services/admin-client.d.ts +33 -0
- package/dist/services/admin-client.d.ts.map +1 -0
- package/dist/services/admin-client.js +154 -0
- package/dist/services/admin-sdk-client.d.ts +285 -0
- package/dist/services/admin-sdk-client.d.ts.map +1 -0
- package/dist/services/admin-sdk-client.js +242 -0
- package/dist/services/errors.d.ts +14 -0
- package/dist/services/errors.d.ts.map +1 -0
- package/dist/services/errors.js +26 -0
- package/dist/services/http.d.ts +24 -0
- package/dist/services/http.d.ts.map +1 -0
- package/dist/services/http.js +159 -0
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +7 -0
- package/dist/services/pagination.d.ts +4 -0
- package/dist/services/pagination.d.ts.map +1 -0
- package/dist/services/pagination.js +32 -0
- package/dist/services/public-client.d.ts +23 -0
- package/dist/services/public-client.d.ts.map +1 -0
- package/dist/services/public-client.js +94 -0
- package/dist/services/types.d.ts +124 -0
- package/dist/services/types.d.ts.map +1 -0
- package/dist/services/types.js +1 -0
- package/dist/style.css +3105 -0
- package/dist/styles/adminTheme.d.ts +6 -0
- package/dist/styles/adminTheme.d.ts.map +1 -0
- package/dist/styles/adminTheme.js +52 -0
- package/dist/styles/index.d.ts +3 -0
- package/dist/styles/index.d.ts.map +1 -0
- package/dist/styles/index.js +2 -0
- package/dist/styles/userTheme.d.ts +8 -0
- package/dist/styles/userTheme.d.ts.map +1 -0
- package/dist/styles/userTheme.js +60 -0
- package/dist/types/admin.d.ts +28 -0
- package/dist/types/admin.d.ts.map +1 -0
- package/dist/types/admin.js +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/user.d.ts +41 -0
- package/dist/types/user.d.ts.map +1 -0
- package/dist/types/user.js +1 -0
- package/dist/user/components/BlogCard.d.ts +15 -0
- package/dist/user/components/BlogCard.d.ts.map +1 -0
- package/dist/user/components/BlogCard.js +31 -0
- package/dist/user/components/BlogCategories.d.ts +6 -0
- package/dist/user/components/BlogCategories.d.ts.map +1 -0
- package/dist/user/components/BlogCategories.js +11 -0
- package/dist/user/components/BlogDetail.d.ts +7 -0
- package/dist/user/components/BlogDetail.d.ts.map +1 -0
- package/dist/user/components/BlogDetail.js +19 -0
- package/dist/user/components/BlogList.d.ts +8 -0
- package/dist/user/components/BlogList.d.ts.map +1 -0
- package/dist/user/components/BlogList.js +18 -0
- package/dist/user/components/BlogSearch.d.ts +8 -0
- package/dist/user/components/BlogSearch.d.ts.map +1 -0
- package/dist/user/components/BlogSearch.js +19 -0
- package/dist/user/components/BlogTags.d.ts +6 -0
- package/dist/user/components/BlogTags.d.ts.map +1 -0
- package/dist/user/components/BlogTags.js +11 -0
- package/dist/user/components/FeaturedBlogs.d.ts +8 -0
- package/dist/user/components/FeaturedBlogs.d.ts.map +1 -0
- package/dist/user/components/FeaturedBlogs.js +12 -0
- package/dist/user/components/RelatedBlogs.d.ts +9 -0
- package/dist/user/components/RelatedBlogs.d.ts.map +1 -0
- package/dist/user/components/RelatedBlogs.js +12 -0
- package/dist/user/components/internal/States.d.ts +18 -0
- package/dist/user/components/internal/States.d.ts.map +1 -0
- package/dist/user/components/internal/States.js +16 -0
- package/dist/user/hooks/useAsync.d.ts +21 -0
- package/dist/user/hooks/useAsync.d.ts.map +1 -0
- package/dist/user/hooks/useAsync.js +40 -0
- package/dist/user/index.d.ts +11 -0
- package/dist/user/index.d.ts.map +1 -0
- package/dist/user/index.js +10 -0
- package/dist/user/sanitize.d.ts +2 -0
- package/dist/user/sanitize.d.ts.map +1 -0
- package/dist/user/sanitize.js +120 -0
- package/dist/user/theme.d.ts +8 -0
- package/dist/user/theme.d.ts.map +1 -0
- package/dist/user/theme.js +60 -0
- package/dist/user/types.d.ts +41 -0
- package/dist/user/types.d.ts.map +1 -0
- package/dist/user/types.js +1 -0
- package/dist/utils/env.d.ts +16 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +57 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/sanitize.d.ts +2 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +120 -0
- package/package.json +63 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { resolveFormatVideoSrc } from './format-media';
|
|
2
|
+
import { videoEmbedSrc } from './post-format';
|
|
3
|
+
import { mediaUrl } from './seo';
|
|
4
|
+
import { primaryCategoryName } from './post-categories';
|
|
5
|
+
const featuredAlt = (post) => {
|
|
6
|
+
const m = post.featuredImage;
|
|
7
|
+
if (typeof m === 'object' && m && 'alt' in m)
|
|
8
|
+
return String(m.alt ?? '');
|
|
9
|
+
return post.title;
|
|
10
|
+
};
|
|
11
|
+
const posterFor = (post) => mediaUrl(post.featuredImage, 'hero');
|
|
12
|
+
const resolveVideoHero = (post, poster, ambient) => {
|
|
13
|
+
const src = resolveFormatVideoSrc(post);
|
|
14
|
+
if (!src)
|
|
15
|
+
return null;
|
|
16
|
+
const embed = videoEmbedSrc(src);
|
|
17
|
+
if (!embed)
|
|
18
|
+
return null;
|
|
19
|
+
if (embed.includes('youtube.com/embed')) {
|
|
20
|
+
if (!ambient)
|
|
21
|
+
return { kind: 'video-embed', src: embed, poster };
|
|
22
|
+
const id = embed.split('/').pop()?.split('?')[0];
|
|
23
|
+
if (!id)
|
|
24
|
+
return null;
|
|
25
|
+
const params = new URLSearchParams({
|
|
26
|
+
autoplay: '1',
|
|
27
|
+
mute: '1',
|
|
28
|
+
loop: '1',
|
|
29
|
+
playlist: id,
|
|
30
|
+
controls: '0',
|
|
31
|
+
rel: '0',
|
|
32
|
+
modestbranding: '1',
|
|
33
|
+
playsinline: '1',
|
|
34
|
+
disablekb: '1',
|
|
35
|
+
iv_load_policy: '3',
|
|
36
|
+
});
|
|
37
|
+
return { kind: 'video-embed', src: `${embed}?${params}`, poster };
|
|
38
|
+
}
|
|
39
|
+
if (embed.includes('player.vimeo.com')) {
|
|
40
|
+
if (!ambient)
|
|
41
|
+
return { kind: 'video-embed', src: embed, poster };
|
|
42
|
+
const params = new URLSearchParams({
|
|
43
|
+
autoplay: '1',
|
|
44
|
+
muted: '1',
|
|
45
|
+
loop: '1',
|
|
46
|
+
background: '1',
|
|
47
|
+
autopause: '0',
|
|
48
|
+
});
|
|
49
|
+
return { kind: 'video-embed', src: `${embed}?${params}`, poster };
|
|
50
|
+
}
|
|
51
|
+
if (/\.(mp4|webm|ogg)(\?|$)/i.test(embed) || src.startsWith('/') || /^https?:\/\//i.test(src)) {
|
|
52
|
+
return { kind: 'video-file', src: embed || src, poster };
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
};
|
|
56
|
+
/** Resolve background media for a post hero (image, file video, or embed). */
|
|
57
|
+
export const resolveHeroMedia = (post) => {
|
|
58
|
+
const poster = posterFor(post);
|
|
59
|
+
if (post.postFormat === 'video') {
|
|
60
|
+
const video = resolveVideoHero(post, poster, true);
|
|
61
|
+
if (video)
|
|
62
|
+
return video;
|
|
63
|
+
}
|
|
64
|
+
const img = mediaUrl(post.featuredImage, 'hero');
|
|
65
|
+
if (img)
|
|
66
|
+
return { kind: 'image', src: img, alt: featuredAlt(post) };
|
|
67
|
+
return null;
|
|
68
|
+
};
|
|
69
|
+
/** First published post on the page that has a usable hero image or video. */
|
|
70
|
+
export const findHeroPost = (posts) => {
|
|
71
|
+
for (const post of posts) {
|
|
72
|
+
if (resolveHeroMedia(post))
|
|
73
|
+
return post;
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
};
|
|
77
|
+
/** Every post on the current page that can drive the media hero slider. */
|
|
78
|
+
export const findHeroPosts = (posts) => posts.filter((post) => Boolean(resolveHeroMedia(post)));
|
|
79
|
+
export const postCategoryName = (post) => primaryCategoryName(post);
|
|
80
|
+
/** Article detail hero — full-width media at social/OG 1200×630 without ambient autoplay. */
|
|
81
|
+
export const resolveArticleHeroMedia = (post) => {
|
|
82
|
+
const poster = mediaUrl(post.featuredImage, 'og') || mediaUrl(post.featuredImage, 'hero');
|
|
83
|
+
if (post.postFormat === 'video') {
|
|
84
|
+
const video = resolveVideoHero(post, poster, false);
|
|
85
|
+
if (video)
|
|
86
|
+
return video;
|
|
87
|
+
}
|
|
88
|
+
const format = post.postFormat || 'standard';
|
|
89
|
+
if (format !== 'standard' && format !== 'image' && format !== 'video')
|
|
90
|
+
return null;
|
|
91
|
+
const img = mediaUrl(post.featuredImage, 'og') || mediaUrl(post.featuredImage, 'hero');
|
|
92
|
+
if (img)
|
|
93
|
+
return { kind: 'image', src: img, alt: featuredAlt(post) };
|
|
94
|
+
return null;
|
|
95
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builders for Lexical editor state.
|
|
3
|
+
*
|
|
4
|
+
* Used by the seed and by the WordPress importer. Content is written as a node
|
|
5
|
+
* tree from the start — there is no HTML-to-anything step anywhere in the
|
|
6
|
+
* pipeline, which is what keeps the "no markup" guarantee true end to end.
|
|
7
|
+
*/
|
|
8
|
+
type Node = Record<string, unknown>;
|
|
9
|
+
export declare const p: (text: string) => Node;
|
|
10
|
+
export declare const h: (level: 2 | 3, text: string) => Node;
|
|
11
|
+
export declare const quote: (text: string) => Node;
|
|
12
|
+
export declare const ul: (items: string[]) => Node;
|
|
13
|
+
/**
|
|
14
|
+
* An internal link. Note it stores the target's *id*, not its URL — the path is
|
|
15
|
+
* resolved at render time, so this link keeps working after the target's slug
|
|
16
|
+
* changes.
|
|
17
|
+
*/
|
|
18
|
+
export declare const paragraphWithInternalLink: (before: string, linkText: string, targetId: string | number, after: string) => Node;
|
|
19
|
+
export declare const doc: (children: Node[]) => {
|
|
20
|
+
root: {
|
|
21
|
+
type: string;
|
|
22
|
+
format: string;
|
|
23
|
+
indent: number;
|
|
24
|
+
version: number;
|
|
25
|
+
direction: string;
|
|
26
|
+
children: Node[];
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=lexical-build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexical-build.d.ts","sourceRoot":"","sources":["../../app/lib/lexical-build.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAsBnC,eAAO,MAAM,CAAC,GAAI,MAAM,MAAM,KAAG,IAAmE,CAAA;AAEpG,eAAO,MAAM,CAAC,GAAI,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,KAAG,IACe,CAAA;AAE9D,eAAO,MAAM,KAAK,GAAI,MAAM,MAAM,KAAG,IAA4C,CAAA;AAEjF,eAAO,MAAM,EAAE,GAAI,OAAO,MAAM,EAAE,KAAG,IAOlC,CAAA;AAEH;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GACpC,QAAQ,MAAM,EACd,UAAU,MAAM,EAChB,UAAU,MAAM,GAAG,MAAM,EACzB,OAAO,MAAM,KACZ,IAqBA,CAAA;AAEH,eAAO,MAAM,GAAG,GAAI,UAAU,IAAI,EAAE;;;;;;;;;CASlC,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builders for Lexical editor state.
|
|
3
|
+
*
|
|
4
|
+
* Used by the seed and by the WordPress importer. Content is written as a node
|
|
5
|
+
* tree from the start — there is no HTML-to-anything step anywhere in the
|
|
6
|
+
* pipeline, which is what keeps the "no markup" guarantee true end to end.
|
|
7
|
+
*/
|
|
8
|
+
const textNode = (text, format = 0) => ({
|
|
9
|
+
type: 'text',
|
|
10
|
+
detail: 0,
|
|
11
|
+
format,
|
|
12
|
+
mode: 'normal',
|
|
13
|
+
style: '',
|
|
14
|
+
text,
|
|
15
|
+
version: 1,
|
|
16
|
+
});
|
|
17
|
+
const container = (type, children, extra = {}) => ({
|
|
18
|
+
type,
|
|
19
|
+
format: '',
|
|
20
|
+
indent: 0,
|
|
21
|
+
version: 1,
|
|
22
|
+
direction: 'ltr',
|
|
23
|
+
children,
|
|
24
|
+
...extra,
|
|
25
|
+
});
|
|
26
|
+
export const p = (text) => container('paragraph', [textNode(text)], { textFormat: 0 });
|
|
27
|
+
export const h = (level, text) => container('heading', [textNode(text)], { tag: `h${level}` });
|
|
28
|
+
export const quote = (text) => container('quote', [textNode(text)]);
|
|
29
|
+
export const ul = (items) => container('list', items.map((item, i) => container('listitem', [textNode(item)], { value: i + 1, checked: undefined })), { listType: 'bullet', start: 1, tag: 'ul' });
|
|
30
|
+
/**
|
|
31
|
+
* An internal link. Note it stores the target's *id*, not its URL — the path is
|
|
32
|
+
* resolved at render time, so this link keeps working after the target's slug
|
|
33
|
+
* changes.
|
|
34
|
+
*/
|
|
35
|
+
export const paragraphWithInternalLink = (before, linkText, targetId, after) => container('paragraph', [
|
|
36
|
+
textNode(before),
|
|
37
|
+
container('link', [textNode(linkText)], {
|
|
38
|
+
fields: {
|
|
39
|
+
linkType: 'internal',
|
|
40
|
+
doc: { relationTo: 'posts', value: targetId },
|
|
41
|
+
newTab: false,
|
|
42
|
+
rel: null,
|
|
43
|
+
},
|
|
44
|
+
id: `link-${targetId}`,
|
|
45
|
+
}),
|
|
46
|
+
textNode(after),
|
|
47
|
+
], { textFormat: 0 });
|
|
48
|
+
export const doc = (children) => ({
|
|
49
|
+
root: {
|
|
50
|
+
type: 'root',
|
|
51
|
+
format: '',
|
|
52
|
+
indent: 0,
|
|
53
|
+
version: 1,
|
|
54
|
+
direction: 'ltr',
|
|
55
|
+
children,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contract between the dashboard editor and the stored document.
|
|
3
|
+
*
|
|
4
|
+
* The editor is a contenteditable surface, so what it hands back is a DOM tree.
|
|
5
|
+
* That tree becomes a Lexical node tree in the browser (see lexical-dom.ts) and
|
|
6
|
+
* is then re-validated *here*, on the server, against a closed allowlist before
|
|
7
|
+
* it is written. Nothing a client sends reaches the database unexamined: an
|
|
8
|
+
* unknown node type is dropped, an unknown property is dropped, and a text node
|
|
9
|
+
* is reduced to a string plus an integer format mask.
|
|
10
|
+
*
|
|
11
|
+
* That is what keeps the "content is structured JSON, never markup" guarantee
|
|
12
|
+
* true now that a browser is producing the content. `lexicalToEditorHtml` does
|
|
13
|
+
* emit HTML, but only in one direction and only for the editing surface — it is
|
|
14
|
+
* generated from already-sanitised JSON, with every text run escaped, and it is
|
|
15
|
+
* never stored and never served to a reader.
|
|
16
|
+
*/
|
|
17
|
+
export type LexNode = {
|
|
18
|
+
type: string;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
};
|
|
21
|
+
export type LexDoc = {
|
|
22
|
+
root: {
|
|
23
|
+
type: 'root';
|
|
24
|
+
children: LexNode[];
|
|
25
|
+
direction: 'ltr' | null;
|
|
26
|
+
format: '';
|
|
27
|
+
indent: 0;
|
|
28
|
+
version: 1;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
/** Lexical's text format bitmask. These values are fixed by the format itself. */
|
|
32
|
+
export declare const FMT: {
|
|
33
|
+
readonly bold: 1;
|
|
34
|
+
readonly italic: 2;
|
|
35
|
+
readonly strikethrough: 4;
|
|
36
|
+
readonly underline: 8;
|
|
37
|
+
readonly code: 16;
|
|
38
|
+
};
|
|
39
|
+
/** Headings an editor may produce (classic WP editor parity includes H1). */
|
|
40
|
+
export declare const HEADING_TAGS: readonly ["h1", "h2", "h3", "h4"];
|
|
41
|
+
export type HeadingTag = (typeof HEADING_TAGS)[number];
|
|
42
|
+
/** Collections an internal link may point at — mirrors LinkFeature in payload.config.ts. */
|
|
43
|
+
declare const LINKABLE: readonly ["posts", "categories"];
|
|
44
|
+
export declare const emptyDoc: () => LexDoc;
|
|
45
|
+
export declare const text: (value: string, format?: number) => LexNode;
|
|
46
|
+
export declare const paragraph: (children: LexNode[]) => LexNode;
|
|
47
|
+
export declare const heading: (tag: HeadingTag, children: LexNode[]) => LexNode;
|
|
48
|
+
export declare const quote: (children: LexNode[]) => LexNode;
|
|
49
|
+
export declare const listItem: (children: LexNode[], value: number) => LexNode;
|
|
50
|
+
export declare const list: (tag: "ul" | "ol", items: LexNode[]) => LexNode;
|
|
51
|
+
export declare const horizontalRule: () => LexNode;
|
|
52
|
+
export declare const lineBreak: () => LexNode;
|
|
53
|
+
export declare const uploadNode: (mediaId: string, nodeId?: string) => LexNode;
|
|
54
|
+
export type LinkTarget = {
|
|
55
|
+
linkType: 'custom';
|
|
56
|
+
url: string;
|
|
57
|
+
newTab: boolean;
|
|
58
|
+
rel: string[] | null;
|
|
59
|
+
} | {
|
|
60
|
+
linkType: 'internal';
|
|
61
|
+
relationTo: (typeof LINKABLE)[number];
|
|
62
|
+
value: string;
|
|
63
|
+
newTab: boolean;
|
|
64
|
+
rel: string[] | null;
|
|
65
|
+
};
|
|
66
|
+
export declare const linkNode: (target: LinkTarget, children: LexNode[], id?: string) => LexNode;
|
|
67
|
+
/**
|
|
68
|
+
* External URLs are restricted to schemes that cannot execute. `javascript:` and
|
|
69
|
+
* `data:` in an href are the classic stored-XSS payload, and this is the point at
|
|
70
|
+
* which they are refused — before storage, not before rendering.
|
|
71
|
+
*/
|
|
72
|
+
export declare const safeHref: (raw: string) => string | null;
|
|
73
|
+
/**
|
|
74
|
+
* Validate an editor payload into something safe to persist.
|
|
75
|
+
*
|
|
76
|
+
* Returns `emptyDoc()` rather than throwing for unusable input: a save must not
|
|
77
|
+
* fail because of a stray node, and an empty body is a legitimate draft state.
|
|
78
|
+
*/
|
|
79
|
+
export declare const sanitizeLexical: (input: unknown) => LexDoc;
|
|
80
|
+
/** True when the document holds no words and no media — used for publish checks. */
|
|
81
|
+
export declare const isEmptyDoc: (doc: unknown) => boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Render a stored document as the HTML the contenteditable surface starts from.
|
|
84
|
+
* Pass content read at depth >= 1 so upload nodes carry their populated media.
|
|
85
|
+
*/
|
|
86
|
+
export declare const lexicalToEditorHtml: (doc: unknown) => string;
|
|
87
|
+
export {};
|
|
88
|
+
//# sourceMappingURL=lexical-doc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexical-doc.d.ts","sourceRoot":"","sources":["../../app/lib/lexical-doc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAA;AAE9D,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,OAAO,EAAE,CAAA;QACnB,SAAS,EAAE,KAAK,GAAG,IAAI,CAAA;QACvB,MAAM,EAAE,EAAE,CAAA;QACV,MAAM,EAAE,CAAC,CAAA;QACT,OAAO,EAAE,CAAC,CAAA;KACX,CAAA;CACF,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,GAAG;;;;;;CAMN,CAAA;AAIV,6EAA6E;AAC7E,eAAO,MAAM,YAAY,mCAAoC,CAAA;AAC7D,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtD,4FAA4F;AAC5F,QAAA,MAAM,QAAQ,kCAAmC,CAAA;AAIjD,eAAO,MAAM,QAAQ,QAAO,MAS1B,CAAA;AAgBF,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,EAAE,eAAU,KAAG,OAQ/C,CAAA;AAEF,eAAO,MAAM,SAAS,GAAI,UAAU,OAAO,EAAE,KAAG,OACgB,CAAA;AAEhE,eAAO,MAAM,OAAO,GAAI,KAAK,UAAU,EAAE,UAAU,OAAO,EAAE,KAAG,OAC1B,CAAA;AAErC,eAAO,MAAM,KAAK,GAAI,UAAU,OAAO,EAAE,KAAG,OAAmC,CAAA;AAE/E,eAAO,MAAM,QAAQ,GAAI,UAAU,OAAO,EAAE,EAAE,OAAO,MAAM,KAAG,OACF,CAAA;AAE5D,eAAO,MAAM,IAAI,GAAI,KAAK,IAAI,GAAG,IAAI,EAAE,OAAO,OAAO,EAAE,KAAG,OAKtD,CAAA;AAEJ,eAAO,MAAM,cAAc,QAAO,OAAmD,CAAA;AAErF,eAAO,MAAM,SAAS,QAAO,OAA8C,CAAA;AAE3E,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,EAAE,SAAS,MAAM,KAAG,OAQ5D,CAAA;AAEF,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,GAC1E;IACE,QAAQ,EAAE,UAAU,CAAA;IACpB,UAAU,EAAE,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAA;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CACrB,CAAA;AAEL,eAAO,MAAM,QAAQ,GAAI,QAAQ,UAAU,EAAE,UAAU,OAAO,EAAE,EAAE,KAAK,MAAM,KAAG,OAsB9E,CAAA;AAiBF;;;;GAIG;AACH,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAS/C,CAAA;AA8GD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,MAmBhD,CAAA;AAED,oFAAoF;AACpF,eAAO,MAAM,UAAU,GAAI,KAAK,OAAO,KAAG,OAWzC,CAAA;AAmHD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,OAAO,KAAG,MAIlD,CAAA"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contract between the dashboard editor and the stored document.
|
|
3
|
+
*
|
|
4
|
+
* The editor is a contenteditable surface, so what it hands back is a DOM tree.
|
|
5
|
+
* That tree becomes a Lexical node tree in the browser (see lexical-dom.ts) and
|
|
6
|
+
* is then re-validated *here*, on the server, against a closed allowlist before
|
|
7
|
+
* it is written. Nothing a client sends reaches the database unexamined: an
|
|
8
|
+
* unknown node type is dropped, an unknown property is dropped, and a text node
|
|
9
|
+
* is reduced to a string plus an integer format mask.
|
|
10
|
+
*
|
|
11
|
+
* That is what keeps the "content is structured JSON, never markup" guarantee
|
|
12
|
+
* true now that a browser is producing the content. `lexicalToEditorHtml` does
|
|
13
|
+
* emit HTML, but only in one direction and only for the editing surface — it is
|
|
14
|
+
* generated from already-sanitised JSON, with every text run escaped, and it is
|
|
15
|
+
* never stored and never served to a reader.
|
|
16
|
+
*/
|
|
17
|
+
/** Lexical's text format bitmask. These values are fixed by the format itself. */
|
|
18
|
+
export const FMT = {
|
|
19
|
+
bold: 1,
|
|
20
|
+
italic: 2,
|
|
21
|
+
strikethrough: 4,
|
|
22
|
+
underline: 8,
|
|
23
|
+
code: 16,
|
|
24
|
+
};
|
|
25
|
+
const ALL_FORMATS = FMT.bold | FMT.italic | FMT.strikethrough | FMT.underline | FMT.code;
|
|
26
|
+
/** Headings an editor may produce (classic WP editor parity includes H1). */
|
|
27
|
+
export const HEADING_TAGS = ['h1', 'h2', 'h3', 'h4'];
|
|
28
|
+
/** Collections an internal link may point at — mirrors LinkFeature in payload.config.ts. */
|
|
29
|
+
const LINKABLE = ['posts', 'categories'];
|
|
30
|
+
const REL_VALUES = ['noopener', 'noreferrer', 'nofollow', 'sponsored'];
|
|
31
|
+
export const emptyDoc = () => ({
|
|
32
|
+
root: {
|
|
33
|
+
type: 'root',
|
|
34
|
+
children: [paragraph([])],
|
|
35
|
+
direction: 'ltr',
|
|
36
|
+
format: '',
|
|
37
|
+
indent: 0,
|
|
38
|
+
version: 1,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
/* ------------------------------------------------------------------ */
|
|
42
|
+
/* builders — one place that knows each node's exact serialized shape */
|
|
43
|
+
/* ------------------------------------------------------------------ */
|
|
44
|
+
const block = (type, children, extra = {}) => ({
|
|
45
|
+
type,
|
|
46
|
+
children,
|
|
47
|
+
direction: 'ltr',
|
|
48
|
+
format: '',
|
|
49
|
+
indent: 0,
|
|
50
|
+
version: 1,
|
|
51
|
+
...extra,
|
|
52
|
+
});
|
|
53
|
+
export const text = (value, format = 0) => ({
|
|
54
|
+
type: 'text',
|
|
55
|
+
detail: 0,
|
|
56
|
+
format,
|
|
57
|
+
mode: 'normal',
|
|
58
|
+
style: '',
|
|
59
|
+
text: value,
|
|
60
|
+
version: 1,
|
|
61
|
+
});
|
|
62
|
+
export const paragraph = (children) => block('paragraph', children, { textFormat: 0, textStyle: '' });
|
|
63
|
+
export const heading = (tag, children) => block('heading', children, { tag });
|
|
64
|
+
export const quote = (children) => block('quote', children);
|
|
65
|
+
export const listItem = (children, value) => block('listitem', children, { value, checked: undefined });
|
|
66
|
+
export const list = (tag, items) => block('list', items, {
|
|
67
|
+
listType: tag === 'ol' ? 'number' : 'bullet',
|
|
68
|
+
start: 1,
|
|
69
|
+
tag,
|
|
70
|
+
});
|
|
71
|
+
export const horizontalRule = () => ({ type: 'horizontalrule', version: 1 });
|
|
72
|
+
export const lineBreak = () => ({ type: 'linebreak', version: 1 });
|
|
73
|
+
export const uploadNode = (mediaId, nodeId) => ({
|
|
74
|
+
type: 'upload',
|
|
75
|
+
relationTo: 'media',
|
|
76
|
+
value: mediaId,
|
|
77
|
+
fields: null,
|
|
78
|
+
format: '',
|
|
79
|
+
version: 3,
|
|
80
|
+
id: nodeId || `u-${mediaId}-${Math.random().toString(36).slice(2, 8)}`,
|
|
81
|
+
});
|
|
82
|
+
export const linkNode = (target, children, id) => ({
|
|
83
|
+
type: 'link',
|
|
84
|
+
children,
|
|
85
|
+
direction: 'ltr',
|
|
86
|
+
format: '',
|
|
87
|
+
indent: 0,
|
|
88
|
+
version: 3,
|
|
89
|
+
id: id || `l-${Math.random().toString(36).slice(2, 9)}`,
|
|
90
|
+
fields: target.linkType === 'internal'
|
|
91
|
+
? {
|
|
92
|
+
linkType: 'internal',
|
|
93
|
+
doc: { relationTo: target.relationTo, value: target.value },
|
|
94
|
+
newTab: target.newTab,
|
|
95
|
+
rel: target.rel,
|
|
96
|
+
}
|
|
97
|
+
: {
|
|
98
|
+
linkType: 'custom',
|
|
99
|
+
url: target.url,
|
|
100
|
+
newTab: target.newTab,
|
|
101
|
+
rel: target.rel,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
/* ------------------------------------------------------------------ */
|
|
105
|
+
/* sanitiser — the only door content comes through */
|
|
106
|
+
/* ------------------------------------------------------------------ */
|
|
107
|
+
const str = (v) => (typeof v === 'string' ? v : '');
|
|
108
|
+
const idOf = (v) => {
|
|
109
|
+
if (typeof v === 'string' || typeof v === 'number')
|
|
110
|
+
return String(v);
|
|
111
|
+
if (v && typeof v === 'object' && 'id' in v) {
|
|
112
|
+
const id = v.id;
|
|
113
|
+
if (typeof id === 'string' || typeof id === 'number')
|
|
114
|
+
return String(id);
|
|
115
|
+
}
|
|
116
|
+
return '';
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* External URLs are restricted to schemes that cannot execute. `javascript:` and
|
|
120
|
+
* `data:` in an href are the classic stored-XSS payload, and this is the point at
|
|
121
|
+
* which they are refused — before storage, not before rendering.
|
|
122
|
+
*/
|
|
123
|
+
export const safeHref = (raw) => {
|
|
124
|
+
const url = raw.trim();
|
|
125
|
+
if (!url)
|
|
126
|
+
return null;
|
|
127
|
+
if (/^(https?:\/\/|mailto:|tel:)/i.test(url))
|
|
128
|
+
return url;
|
|
129
|
+
if (url.startsWith('/') && !url.startsWith('//'))
|
|
130
|
+
return url;
|
|
131
|
+
if (url.startsWith('#'))
|
|
132
|
+
return url;
|
|
133
|
+
// Bare domains typed by a human ("example.com/x") are the common case.
|
|
134
|
+
if (/^[\w-]+(\.[\w-]+)+(\/|$)/.test(url))
|
|
135
|
+
return `https://${url}`;
|
|
136
|
+
return null;
|
|
137
|
+
};
|
|
138
|
+
const cleanRel = (v) => {
|
|
139
|
+
if (!Array.isArray(v))
|
|
140
|
+
return null;
|
|
141
|
+
const rels = v.filter((r) => typeof r === 'string' && REL_VALUES.includes(r));
|
|
142
|
+
return rels.length ? [...new Set(rels)] : null;
|
|
143
|
+
};
|
|
144
|
+
const sanitizeChildren = (v, inline) => {
|
|
145
|
+
if (!Array.isArray(v))
|
|
146
|
+
return [];
|
|
147
|
+
const out = [];
|
|
148
|
+
for (const child of v) {
|
|
149
|
+
const node = sanitizeNode(child, inline);
|
|
150
|
+
if (node)
|
|
151
|
+
out.push(node);
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
};
|
|
155
|
+
const sanitizeNode = (input, inline) => {
|
|
156
|
+
if (!input || typeof input !== 'object')
|
|
157
|
+
return null;
|
|
158
|
+
const n = input;
|
|
159
|
+
switch (n.type) {
|
|
160
|
+
case 'text': {
|
|
161
|
+
const value = str(n.text);
|
|
162
|
+
if (!value)
|
|
163
|
+
return null;
|
|
164
|
+
const format = typeof n.format === 'number' ? n.format & ALL_FORMATS : 0;
|
|
165
|
+
return text(value, format);
|
|
166
|
+
}
|
|
167
|
+
case 'linebreak':
|
|
168
|
+
return lineBreak();
|
|
169
|
+
case 'link':
|
|
170
|
+
case 'autolink': {
|
|
171
|
+
const children = sanitizeChildren(n.children, true);
|
|
172
|
+
if (!children.length)
|
|
173
|
+
return null;
|
|
174
|
+
const fields = (n.fields ?? {});
|
|
175
|
+
const newTab = Boolean(fields.newTab);
|
|
176
|
+
const rel = cleanRel(fields.rel);
|
|
177
|
+
if (fields.linkType === 'internal') {
|
|
178
|
+
const doc = (fields.doc ?? {});
|
|
179
|
+
const relationTo = LINKABLE.includes(doc.relationTo)
|
|
180
|
+
? doc.relationTo
|
|
181
|
+
: null;
|
|
182
|
+
const value = idOf(doc.value);
|
|
183
|
+
if (!relationTo || !value)
|
|
184
|
+
return null;
|
|
185
|
+
return linkNode({ linkType: 'internal', relationTo, value, newTab, rel }, children, str(n.id));
|
|
186
|
+
}
|
|
187
|
+
const url = safeHref(str(fields.url));
|
|
188
|
+
if (!url) {
|
|
189
|
+
// A refused URL must not silently drop the words it was wrapped around.
|
|
190
|
+
return children.length === 1 ? children[0] : paragraph(children);
|
|
191
|
+
}
|
|
192
|
+
return linkNode({ linkType: 'custom', url, newTab, rel }, children, str(n.id));
|
|
193
|
+
}
|
|
194
|
+
default:
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
// Anything below here is block level and cannot appear inside a paragraph.
|
|
198
|
+
if (inline)
|
|
199
|
+
return null;
|
|
200
|
+
switch (n.type) {
|
|
201
|
+
case 'paragraph':
|
|
202
|
+
return paragraph(sanitizeChildren(n.children, true));
|
|
203
|
+
case 'heading': {
|
|
204
|
+
const tag = HEADING_TAGS.includes(n.tag) ? n.tag : 'h2';
|
|
205
|
+
const children = sanitizeChildren(n.children, true);
|
|
206
|
+
return children.length ? heading(tag, children) : null;
|
|
207
|
+
}
|
|
208
|
+
case 'quote': {
|
|
209
|
+
const children = sanitizeChildren(n.children, true);
|
|
210
|
+
return children.length ? quote(children) : null;
|
|
211
|
+
}
|
|
212
|
+
case 'list': {
|
|
213
|
+
const tag = n.tag === 'ol' || n.listType === 'number' ? 'ol' : 'ul';
|
|
214
|
+
const items = [];
|
|
215
|
+
if (Array.isArray(n.children)) {
|
|
216
|
+
for (const raw of n.children) {
|
|
217
|
+
if (!raw || typeof raw !== 'object')
|
|
218
|
+
continue;
|
|
219
|
+
const item = raw;
|
|
220
|
+
if (item.type !== 'listitem')
|
|
221
|
+
continue;
|
|
222
|
+
const children = sanitizeChildren(item.children, true);
|
|
223
|
+
if (children.length)
|
|
224
|
+
items.push(listItem(children, items.length + 1));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return items.length ? list(tag, items) : null;
|
|
228
|
+
}
|
|
229
|
+
case 'horizontalrule':
|
|
230
|
+
return horizontalRule();
|
|
231
|
+
case 'upload': {
|
|
232
|
+
const mediaId = idOf(n.value);
|
|
233
|
+
if (!mediaId || n.relationTo !== 'media')
|
|
234
|
+
return null;
|
|
235
|
+
return uploadNode(mediaId, str(n.id));
|
|
236
|
+
}
|
|
237
|
+
default:
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Validate an editor payload into something safe to persist.
|
|
243
|
+
*
|
|
244
|
+
* Returns `emptyDoc()` rather than throwing for unusable input: a save must not
|
|
245
|
+
* fail because of a stray node, and an empty body is a legitimate draft state.
|
|
246
|
+
*/
|
|
247
|
+
export const sanitizeLexical = (input) => {
|
|
248
|
+
const root = input && typeof input === 'object' && 'root' in input
|
|
249
|
+
? input.root
|
|
250
|
+
: null;
|
|
251
|
+
const children = sanitizeChildren(root?.children, false);
|
|
252
|
+
if (!children.length)
|
|
253
|
+
return emptyDoc();
|
|
254
|
+
return {
|
|
255
|
+
root: {
|
|
256
|
+
type: 'root',
|
|
257
|
+
children,
|
|
258
|
+
direction: 'ltr',
|
|
259
|
+
format: '',
|
|
260
|
+
indent: 0,
|
|
261
|
+
version: 1,
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
/** True when the document holds no words and no media — used for publish checks. */
|
|
266
|
+
export const isEmptyDoc = (doc) => {
|
|
267
|
+
let found = false;
|
|
268
|
+
const walk = (node) => {
|
|
269
|
+
if (found || !node || typeof node !== 'object')
|
|
270
|
+
return;
|
|
271
|
+
const n = node;
|
|
272
|
+
if (n.type === 'upload' || n.type === 'horizontalrule')
|
|
273
|
+
found = true;
|
|
274
|
+
if (typeof n.text === 'string' && n.text.trim())
|
|
275
|
+
found = true;
|
|
276
|
+
if (Array.isArray(n.children))
|
|
277
|
+
n.children.forEach(walk);
|
|
278
|
+
};
|
|
279
|
+
walk(doc?.root);
|
|
280
|
+
return !found;
|
|
281
|
+
};
|
|
282
|
+
/* ------------------------------------------------------------------ */
|
|
283
|
+
/* JSON -> editor HTML (one direction, editing surface only) */
|
|
284
|
+
/* ------------------------------------------------------------------ */
|
|
285
|
+
const escapeHtml = (value) => value
|
|
286
|
+
.replace(/&/g, '&')
|
|
287
|
+
.replace(/</g, '<')
|
|
288
|
+
.replace(/>/g, '>')
|
|
289
|
+
.replace(/"/g, '"')
|
|
290
|
+
.replace(/'/g, ''');
|
|
291
|
+
const FORMAT_TAGS = [
|
|
292
|
+
[FMT.code, 'code'],
|
|
293
|
+
[FMT.strikethrough, 's'],
|
|
294
|
+
[FMT.underline, 'u'],
|
|
295
|
+
[FMT.italic, 'em'],
|
|
296
|
+
[FMT.bold, 'strong'],
|
|
297
|
+
];
|
|
298
|
+
const textToHtml = (node) => {
|
|
299
|
+
const format = typeof node.format === 'number' ? node.format : 0;
|
|
300
|
+
let html = escapeHtml(str(node.text)).replace(/\n/g, '<br>');
|
|
301
|
+
for (const [bit, tag] of FORMAT_TAGS) {
|
|
302
|
+
if (format & bit)
|
|
303
|
+
html = `<${tag}>${html}</${tag}>`;
|
|
304
|
+
}
|
|
305
|
+
return html;
|
|
306
|
+
};
|
|
307
|
+
const mediaFromNode = (value) => {
|
|
308
|
+
const id = idOf(value);
|
|
309
|
+
if (!id)
|
|
310
|
+
return null;
|
|
311
|
+
const doc = value && typeof value === 'object' ? value : {};
|
|
312
|
+
const sizes = (doc.sizes ?? {});
|
|
313
|
+
const url = str(sizes.card?.url) || str(doc.url);
|
|
314
|
+
return { id, url, alt: str(doc.alt) };
|
|
315
|
+
};
|
|
316
|
+
const childrenToHtml = (node) => Array.isArray(node.children) ? node.children.map(nodeToHtml).join('') : '';
|
|
317
|
+
const nodeToHtml = (node) => {
|
|
318
|
+
switch (node.type) {
|
|
319
|
+
case 'text':
|
|
320
|
+
return textToHtml(node);
|
|
321
|
+
case 'linebreak':
|
|
322
|
+
return '<br>';
|
|
323
|
+
case 'link':
|
|
324
|
+
case 'autolink': {
|
|
325
|
+
const fields = (node.fields ?? {});
|
|
326
|
+
const inner = childrenToHtml(node);
|
|
327
|
+
const newTab = fields.newTab ? ' data-new-tab="1"' : '';
|
|
328
|
+
if (fields.linkType === 'internal') {
|
|
329
|
+
const doc = (fields.doc ?? {});
|
|
330
|
+
const target = doc.value;
|
|
331
|
+
const slug = target && typeof target === 'object' ? escapeHtml(str(target.slug)) : '';
|
|
332
|
+
const collection = escapeHtml(str(doc.relationTo) || 'posts');
|
|
333
|
+
const label = collection === 'categories' ? 'category' : 'post';
|
|
334
|
+
return `<a href="#" data-link-type="internal" data-doc-collection="${collection}" data-doc-id="${escapeHtml(idOf(doc.value))}" data-doc-label="${label}: ${slug}"${newTab}>${inner}</a>`;
|
|
335
|
+
}
|
|
336
|
+
const href = safeHref(str(fields.url));
|
|
337
|
+
if (!href)
|
|
338
|
+
return inner;
|
|
339
|
+
return `<a href="${escapeHtml(href)}" data-link-type="custom"${newTab}>${inner}</a>`;
|
|
340
|
+
}
|
|
341
|
+
case 'paragraph': {
|
|
342
|
+
const inner = childrenToHtml(node);
|
|
343
|
+
return `<p>${inner || '<br>'}</p>`;
|
|
344
|
+
}
|
|
345
|
+
case 'heading': {
|
|
346
|
+
const tag = HEADING_TAGS.includes(node.tag) ? node.tag : 'h2';
|
|
347
|
+
return `<${tag}>${childrenToHtml(node)}</${tag}>`;
|
|
348
|
+
}
|
|
349
|
+
case 'quote':
|
|
350
|
+
return `<blockquote>${childrenToHtml(node)}</blockquote>`;
|
|
351
|
+
case 'list': {
|
|
352
|
+
const tag = node.tag === 'ol' || node.listType === 'number' ? 'ol' : 'ul';
|
|
353
|
+
const items = Array.isArray(node.children)
|
|
354
|
+
? node.children
|
|
355
|
+
.map((item) => `<li>${childrenToHtml(item)}</li>`)
|
|
356
|
+
.join('')
|
|
357
|
+
: '';
|
|
358
|
+
return `<${tag}>${items}</${tag}>`;
|
|
359
|
+
}
|
|
360
|
+
case 'horizontalrule':
|
|
361
|
+
return '<hr>';
|
|
362
|
+
case 'upload': {
|
|
363
|
+
const media = mediaFromNode(node.value);
|
|
364
|
+
if (!media)
|
|
365
|
+
return '';
|
|
366
|
+
return (`<figure class="ed-figure" contenteditable="false" data-media-id="${escapeHtml(media.id)}"` +
|
|
367
|
+
` data-node-id="${escapeHtml(str(node.id))}">` +
|
|
368
|
+
`<img src="${escapeHtml(media.url)}" alt="${escapeHtml(media.alt)}">` +
|
|
369
|
+
`<figcaption>${escapeHtml(media.alt || 'Image')}</figcaption>` +
|
|
370
|
+
`</figure>`);
|
|
371
|
+
}
|
|
372
|
+
default:
|
|
373
|
+
return '';
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
/**
|
|
377
|
+
* Render a stored document as the HTML the contenteditable surface starts from.
|
|
378
|
+
* Pass content read at depth >= 1 so upload nodes carry their populated media.
|
|
379
|
+
*/
|
|
380
|
+
export const lexicalToEditorHtml = (doc) => {
|
|
381
|
+
const root = doc?.root;
|
|
382
|
+
if (!root || !Array.isArray(root.children))
|
|
383
|
+
return '';
|
|
384
|
+
return root.children.map(nodeToHtml).join('');
|
|
385
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser side of the editor contract: the contenteditable DOM read back as a
|
|
3
|
+
* Lexical node tree.
|
|
4
|
+
*
|
|
5
|
+
* We walk the live DOM rather than serialising to an HTML string and parsing it
|
|
6
|
+
* again — there is no intermediate markup to get wrong, and anything the browser
|
|
7
|
+
* invented while the user typed (a stray <span style>, a pasted <font>) simply
|
|
8
|
+
* has no case here and disappears. The server re-validates the result anyway
|
|
9
|
+
* (see sanitizeLexical), so this file is a translator, not a security boundary.
|
|
10
|
+
*/
|
|
11
|
+
import { type LexDoc } from './lexical-doc';
|
|
12
|
+
/**
|
|
13
|
+
* Read the editing surface as a document.
|
|
14
|
+
*
|
|
15
|
+
* Loose text typed straight into the root (which browsers do on the first
|
|
16
|
+
* keystroke of an empty editor) is gathered into a paragraph rather than lost.
|
|
17
|
+
*/
|
|
18
|
+
export declare const domToLexical: (root: HTMLElement) => LexDoc;
|
|
19
|
+
//# sourceMappingURL=lexical-dom.d.ts.map
|