@xiwebdesign/xicms-core 7.31.0 → 8.16.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/dist/XiCMSProvider.js +23 -7
- package/dist/XiCMSProvider.js.map +1 -1
- package/dist/admin/AdminApp.js +175 -93
- package/dist/admin/AdminApp.js.map +1 -1
- package/dist/admin/AdminHelp.d.ts +1 -1
- package/dist/admin/AdminHelp.js +44 -36
- package/dist/admin/AdminHelp.js.map +1 -1
- package/dist/admin/CoreVersion.d.ts +6 -3
- package/dist/admin/CoreVersion.js +60 -24
- package/dist/admin/CoreVersion.js.map +1 -1
- package/dist/admin/NewsEditor.d.ts +7 -0
- package/dist/admin/NewsEditor.js +117 -75
- package/dist/admin/NewsEditor.js.map +1 -1
- package/dist/admin/SuperadminPanel.js +1 -1
- package/dist/admin/SuperadminPanel.js.map +1 -1
- package/dist/admin/ZoekPalet.d.ts +15 -0
- package/dist/admin/ZoekPalet.js +123 -0
- package/dist/admin/ZoekPalet.js.map +1 -0
- package/dist/admin/blockEditors/GenericEditor.js +36 -18
- package/dist/admin/blockEditors/GenericEditor.js.map +1 -1
- package/dist/admin/blockEditors/StyleEditor.js +37 -3
- package/dist/admin/blockEditors/StyleEditor.js.map +1 -1
- package/dist/admin/blockEditors/SymbolRefEditor.js +44 -2
- package/dist/admin/blockEditors/SymbolRefEditor.js.map +1 -1
- package/dist/admin/blockEditors/index.js +154 -73
- package/dist/admin/blockEditors/index.js.map +1 -1
- package/dist/admin/customBlocks/CustomBlocksPanel.js +18 -7
- package/dist/admin/customBlocks/CustomBlocksPanel.js.map +1 -1
- package/dist/admin/dashboard/DashboardPanel.js +26 -16
- package/dist/admin/dashboard/DashboardPanel.js.map +1 -1
- package/dist/admin/editors/RichTextEditor.d.ts +4 -3
- package/dist/admin/editors/RichTextEditor.js +19 -60
- package/dist/admin/editors/RichTextEditor.js.map +1 -1
- package/dist/admin/editors/fontSizeExtension.js +7 -1
- package/dist/admin/editors/fontSizeExtension.js.map +1 -1
- package/dist/admin/editors/slashMenu.d.ts +18 -0
- package/dist/admin/editors/slashMenu.js +34 -0
- package/dist/admin/editors/slashMenu.js.map +1 -0
- package/dist/admin/editors/useRijkeTekst.d.ts +48 -0
- package/dist/admin/editors/useRijkeTekst.js +310 -0
- package/dist/admin/editors/useRijkeTekst.js.map +1 -0
- package/dist/admin/forms/FormsPanel.d.ts +11 -2
- package/dist/admin/forms/FormsPanel.js +218 -65
- package/dist/admin/forms/FormsPanel.js.map +1 -1
- package/dist/admin/lib/blokInfo.d.ts +17 -0
- package/dist/admin/lib/blokInfo.js +80 -0
- package/dist/admin/lib/blokInfo.js.map +1 -0
- package/dist/admin/lib/foutNaarMens.d.ts +1 -0
- package/dist/admin/lib/foutNaarMens.js +22 -0
- package/dist/admin/lib/foutNaarMens.js.map +1 -0
- package/dist/admin/lib/gewisteVelden.d.ts +13 -0
- package/dist/admin/lib/gewisteVelden.js +31 -0
- package/dist/admin/lib/gewisteVelden.js.map +1 -0
- package/dist/admin/lib/heroHulp.d.ts +11 -0
- package/dist/admin/lib/heroHulp.js +18 -0
- package/dist/admin/lib/heroHulp.js.map +1 -0
- package/dist/admin/lib/kleur.js +2 -3
- package/dist/admin/lib/kleur.js.map +1 -1
- package/dist/admin/lib/leesbaarheid.d.ts +34 -0
- package/dist/admin/lib/leesbaarheid.js +82 -0
- package/dist/admin/lib/leesbaarheid.js.map +1 -0
- package/dist/admin/lib/lengteAdvies.d.ts +1 -0
- package/dist/admin/lib/lengteAdvies.js +16 -0
- package/dist/admin/lib/lengteAdvies.js.map +1 -0
- package/dist/admin/lib/mediaLijst.d.ts +26 -0
- package/dist/admin/lib/mediaLijst.js +42 -0
- package/dist/admin/lib/mediaLijst.js.map +1 -0
- package/dist/admin/lib/mediaUsage.d.ts +12 -1
- package/dist/admin/lib/mediaUsage.js +43 -33
- package/dist/admin/lib/mediaUsage.js.map +1 -1
- package/dist/admin/lib/menuHulp.d.ts +16 -0
- package/dist/admin/lib/menuHulp.js +41 -0
- package/dist/admin/lib/menuHulp.js.map +1 -0
- package/dist/admin/lib/onopgeslagen.d.ts +10 -0
- package/dist/admin/lib/onopgeslagen.js +35 -0
- package/dist/admin/lib/onopgeslagen.js.map +1 -0
- package/dist/admin/lib/pagesClient.d.ts +55 -2
- package/dist/admin/lib/pagesClient.js +126 -28
- package/dist/admin/lib/pagesClient.js.map +1 -1
- package/dist/admin/lib/paginaGebruik.d.ts +56 -0
- package/dist/admin/lib/paginaGebruik.js +109 -0
- package/dist/admin/lib/paginaGebruik.js.map +1 -0
- package/dist/admin/lib/publicatieCheck.d.ts +25 -0
- package/dist/admin/lib/publicatieCheck.js +114 -0
- package/dist/admin/lib/publicatieCheck.js.map +1 -0
- package/dist/admin/lib/scrollNaarDetail.d.ts +6 -0
- package/dist/admin/lib/scrollNaarDetail.js +20 -0
- package/dist/admin/lib/scrollNaarDetail.js.map +1 -0
- package/dist/admin/lib/symbolsClient.d.ts +10 -0
- package/dist/admin/lib/symbolsClient.js +14 -1
- package/dist/admin/lib/symbolsClient.js.map +1 -1
- package/dist/admin/lib/tekstVeld.d.ts +8 -0
- package/dist/admin/lib/tekstVeld.js +10 -0
- package/dist/admin/lib/tekstVeld.js.map +1 -0
- package/dist/admin/lib/useIsSuperadmin.d.ts +2 -0
- package/dist/admin/lib/useIsSuperadmin.js +13 -0
- package/dist/admin/lib/useIsSuperadmin.js.map +1 -0
- package/dist/admin/lib/veldTaal.d.ts +14 -0
- package/dist/admin/lib/veldTaal.js +248 -0
- package/dist/admin/lib/veldTaal.js.map +1 -0
- package/dist/admin/lib/versieVergelijk.d.ts +17 -0
- package/dist/admin/lib/versieVergelijk.js +24 -0
- package/dist/admin/lib/versieVergelijk.js.map +1 -0
- package/dist/admin/lib/zodFields.js +22 -4
- package/dist/admin/lib/zodFields.js.map +1 -1
- package/dist/admin/lib/zodFout.d.ts +9 -0
- package/dist/admin/lib/zodFout.js +63 -0
- package/dist/admin/lib/zodFout.js.map +1 -0
- package/dist/admin/media/MediaManager.js +162 -32
- package/dist/admin/media/MediaManager.js.map +1 -1
- package/dist/admin/media/MediaPicker.d.ts +3 -0
- package/dist/admin/media/MediaPicker.js +84 -31
- package/dist/admin/media/MediaPicker.js.map +1 -1
- package/dist/admin/menu/MenuPanel.js +144 -83
- package/dist/admin/menu/MenuPanel.js.map +1 -1
- package/dist/admin/navContext.d.ts +3 -0
- package/dist/admin/navContext.js +13 -1
- package/dist/admin/navContext.js.map +1 -1
- package/dist/admin/pages/PageEditor.js +146 -30
- package/dist/admin/pages/PageEditor.js.map +1 -1
- package/dist/admin/pages/PagesPanel.js +215 -61
- package/dist/admin/pages/PagesPanel.js.map +1 -1
- package/dist/admin/pages/StarterKiezer.d.ts +12 -0
- package/dist/admin/pages/StarterKiezer.js +113 -0
- package/dist/admin/pages/StarterKiezer.js.map +1 -0
- package/dist/admin/panelRegistry.d.ts +1 -1
- package/dist/admin/panelRegistry.js +2 -1
- package/dist/admin/panelRegistry.js.map +1 -1
- package/dist/admin/patterns/PatternInserter.js +1 -1
- package/dist/admin/patterns/PatternInserter.js.map +1 -1
- package/dist/admin/settings/BedrijfInstellingen.d.ts +20 -0
- package/dist/admin/settings/BedrijfInstellingen.js +159 -0
- package/dist/admin/settings/BedrijfInstellingen.js.map +1 -0
- package/dist/admin/settings/MailTemplates.js +5 -4
- package/dist/admin/settings/MailTemplates.js.map +1 -1
- package/dist/admin/settings/SettingsPanel.js +120 -78
- package/dist/admin/settings/SettingsPanel.js.map +1 -1
- package/dist/admin/settings/SnapshotsCard.js +4 -4
- package/dist/admin/settings/SnapshotsCard.js.map +1 -1
- package/dist/admin/settings/VorigeTerugzetten.d.ts +15 -0
- package/dist/admin/settings/VorigeTerugzetten.js +89 -0
- package/dist/admin/settings/VorigeTerugzetten.js.map +1 -0
- package/dist/admin/shop/CategoriesTab.js +6 -4
- package/dist/admin/shop/CategoriesTab.js.map +1 -1
- package/dist/admin/shop/DiscountsTab.js +4 -2
- package/dist/admin/shop/DiscountsTab.js.map +1 -1
- package/dist/admin/shop/OrdersTab.js +57 -19
- package/dist/admin/shop/OrdersTab.js.map +1 -1
- package/dist/admin/shop/ProductPaneel.js +2 -1
- package/dist/admin/shop/ProductPaneel.js.map +1 -1
- package/dist/admin/shop/ProductsTab.js +40 -19
- package/dist/admin/shop/ProductsTab.js.map +1 -1
- package/dist/admin/shop/ShopPanel.js +13 -1
- package/dist/admin/shop/ShopPanel.js.map +1 -1
- package/dist/admin/shop/ShopSettingsTab.js +56 -17
- package/dist/admin/shop/ShopSettingsTab.js.map +1 -1
- package/dist/admin/shop/productClient.js +7 -3
- package/dist/admin/shop/productClient.js.map +1 -1
- package/dist/admin/stats/NietGevonden.d.ts +10 -0
- package/dist/admin/stats/NietGevonden.js +78 -0
- package/dist/admin/stats/NietGevonden.js.map +1 -0
- package/dist/admin/stats/StatsPanel.js +6 -1
- package/dist/admin/stats/StatsPanel.js.map +1 -1
- package/dist/admin/stats/lib.d.ts +2 -0
- package/dist/admin/stats/lib.js.map +1 -1
- package/dist/admin/ui/ConfirmDialog.js +10 -1
- package/dist/admin/ui/ConfirmDialog.js.map +1 -1
- package/dist/admin/ui/Icon.d.ts +34 -0
- package/dist/admin/ui/Icon.js +44 -0
- package/dist/admin/ui/Icon.js.map +1 -0
- package/dist/admin/ui/ImageField.d.ts +15 -0
- package/dist/admin/ui/ImageField.js +67 -0
- package/dist/admin/ui/ImageField.js.map +1 -0
- package/dist/admin/ui/KleurVeld.d.ts +25 -0
- package/dist/admin/ui/KleurVeld.js +76 -0
- package/dist/admin/ui/KleurVeld.js.map +1 -0
- package/dist/admin/ui/LaadStaat.d.ts +21 -0
- package/dist/admin/ui/LaadStaat.js +43 -0
- package/dist/admin/ui/LaadStaat.js.map +1 -0
- package/dist/admin/ui/LeesbaarheidPaneel.d.ts +10 -0
- package/dist/admin/ui/LeesbaarheidPaneel.js +68 -0
- package/dist/admin/ui/LeesbaarheidPaneel.js.map +1 -0
- package/dist/admin/ui/LinkDialog.d.ts +22 -0
- package/dist/admin/ui/LinkDialog.js +131 -0
- package/dist/admin/ui/LinkDialog.js.map +1 -0
- package/dist/admin/ui/LinkVeld.d.ts +14 -0
- package/dist/admin/ui/LinkVeld.js +49 -0
- package/dist/admin/ui/LinkVeld.js.map +1 -0
- package/dist/admin/ui/PreviewLinkResultaat.d.ts +14 -0
- package/dist/admin/ui/PreviewLinkResultaat.js +52 -0
- package/dist/admin/ui/PreviewLinkResultaat.js.map +1 -0
- package/dist/admin/ui/charts.js +5 -5
- package/dist/admin/ui/charts.js.map +1 -1
- package/dist/admin/ui/primitives.d.ts +16 -6
- package/dist/admin/ui/primitives.js +98 -26
- package/dist/admin/ui/primitives.js.map +1 -1
- package/dist/admin/ui/select.js +5 -2
- package/dist/admin/ui/select.js.map +1 -1
- package/dist/admin/ui/switch.d.ts +3 -1
- package/dist/admin/ui/switch.js +6 -3
- package/dist/admin/ui/switch.js.map +1 -1
- package/dist/admin/ui/toast.d.ts +2 -1
- package/dist/admin/ui/toast.js +17 -11
- package/dist/admin/ui/toast.js.map +1 -1
- package/dist/admin/visual/BlokKiezer.d.ts +34 -0
- package/dist/admin/visual/BlokKiezer.js +225 -0
- package/dist/admin/visual/BlokKiezer.js.map +1 -0
- package/dist/admin/visual/InlineGereedschap.d.ts +52 -0
- package/dist/admin/visual/InlineGereedschap.js +356 -0
- package/dist/admin/visual/InlineGereedschap.js.map +1 -0
- package/dist/admin/visual/InlineRijkeTekst.d.ts +23 -0
- package/dist/admin/visual/InlineRijkeTekst.js +152 -0
- package/dist/admin/visual/InlineRijkeTekst.js.map +1 -0
- package/dist/admin/visual/VisualEditor.js +273 -125
- package/dist/admin/visual/VisualEditor.js.map +1 -1
- package/dist/admin.css +1 -1
- package/dist/auth/AuthProvider.js +1 -0
- package/dist/auth/AuthProvider.js.map +1 -1
- package/dist/bedrijf/bedrijf.d.ts +44 -0
- package/dist/bedrijf/bedrijf.js +125 -0
- package/dist/bedrijf/bedrijf.js.map +1 -0
- package/dist/blocks/BlockRenderer.js +11 -1
- package/dist/blocks/BlockRenderer.js.map +1 -1
- package/dist/blocks/blockStyle.d.ts +7 -0
- package/dist/blocks/blockStyle.js +16 -3
- package/dist/blocks/blockStyle.js.map +1 -1
- package/dist/blocks/builtinSchemas.js +6 -0
- package/dist/blocks/builtinSchemas.js.map +1 -1
- package/dist/blocks/builtins/AgendaRender.d.ts +22 -0
- package/dist/blocks/builtins/AgendaRender.js +69 -9
- package/dist/blocks/builtins/AgendaRender.js.map +1 -1
- package/dist/blocks/builtins/Availability.d.ts +1 -0
- package/dist/blocks/builtins/Availability.js +23 -0
- package/dist/blocks/builtins/Availability.js.map +1 -0
- package/dist/blocks/builtins/AvailabilityRender.d.ts +12 -0
- package/dist/blocks/builtins/AvailabilityRender.js +105 -0
- package/dist/blocks/builtins/AvailabilityRender.js.map +1 -0
- package/dist/blocks/builtins/BeforeAfterRender.js +4 -3
- package/dist/blocks/builtins/BeforeAfterRender.js.map +1 -1
- package/dist/blocks/builtins/Booking.js +1 -1
- package/dist/blocks/builtins/Booking.js.map +1 -1
- package/dist/blocks/builtins/BreadcrumbsRender.d.ts +4 -3
- package/dist/blocks/builtins/BreadcrumbsRender.js +14 -8
- package/dist/blocks/builtins/BreadcrumbsRender.js.map +1 -1
- package/dist/blocks/builtins/ColumnsRender.d.ts +1 -1
- package/dist/blocks/builtins/ColumnsRender.js +3 -1
- package/dist/blocks/builtins/ColumnsRender.js.map +1 -1
- package/dist/blocks/builtins/Contact.js +1 -1
- package/dist/blocks/builtins/Contact.js.map +1 -1
- package/dist/blocks/builtins/ContactRender.d.ts +1 -1
- package/dist/blocks/builtins/ContactRender.js +37 -8
- package/dist/blocks/builtins/ContactRender.js.map +1 -1
- package/dist/blocks/builtins/Cta.js +1 -1
- package/dist/blocks/builtins/Cta.js.map +1 -1
- package/dist/blocks/builtins/CtaRender.d.ts +1 -1
- package/dist/blocks/builtins/CtaRender.js +5 -4
- package/dist/blocks/builtins/CtaRender.js.map +1 -1
- package/dist/blocks/builtins/Embed.js +1 -1
- package/dist/blocks/builtins/Embed.js.map +1 -1
- package/dist/blocks/builtins/FormBlock.js +1 -0
- package/dist/blocks/builtins/FormBlock.js.map +1 -1
- package/dist/blocks/builtins/FormBlockRender.d.ts +6 -0
- package/dist/blocks/builtins/FormBlockRender.js +88 -16
- package/dist/blocks/builtins/FormBlockRender.js.map +1 -1
- package/dist/blocks/builtins/GalleryRender.js +3 -2
- package/dist/blocks/builtins/GalleryRender.js.map +1 -1
- package/dist/blocks/builtins/Hero.js +1 -1
- package/dist/blocks/builtins/Hero.js.map +1 -1
- package/dist/blocks/builtins/HeroRender.js +7 -3
- package/dist/blocks/builtins/HeroRender.js.map +1 -1
- package/dist/blocks/builtins/OpenNowBadge.d.ts +4 -2
- package/dist/blocks/builtins/OpenNowBadge.js +6 -6
- package/dist/blocks/builtins/OpenNowBadge.js.map +1 -1
- package/dist/blocks/builtins/OpeningHoursRender.d.ts +8 -2
- package/dist/blocks/builtins/OpeningHoursRender.js +27 -6
- package/dist/blocks/builtins/OpeningHoursRender.js.map +1 -1
- package/dist/blocks/builtins/PriceList.d.ts +1 -0
- package/dist/blocks/builtins/PriceList.js +25 -0
- package/dist/blocks/builtins/PriceList.js.map +1 -0
- package/dist/blocks/builtins/PriceListRender.d.ts +17 -0
- package/dist/blocks/builtins/PriceListRender.js +87 -0
- package/dist/blocks/builtins/PriceListRender.js.map +1 -0
- package/dist/blocks/builtins/RichTextBlockRender.js +6 -1
- package/dist/blocks/builtins/RichTextBlockRender.js.map +1 -1
- package/dist/blocks/builtins/SectionHeading.d.ts +1 -0
- package/dist/blocks/builtins/SectionHeading.js +14 -0
- package/dist/blocks/builtins/SectionHeading.js.map +1 -0
- package/dist/blocks/builtins/SectionHeadingRender.d.ts +7 -0
- package/dist/blocks/builtins/SectionHeadingRender.js +14 -0
- package/dist/blocks/builtins/SectionHeadingRender.js.map +1 -0
- package/dist/blocks/builtins/SliderRender.js +3 -2
- package/dist/blocks/builtins/SliderRender.js.map +1 -1
- package/dist/blocks/builtins/SymbolRef.js +1 -1
- package/dist/blocks/builtins/SymbolRef.js.map +1 -1
- package/dist/blocks/builtins/TeamRender.js +6 -1
- package/dist/blocks/builtins/TeamRender.js.map +1 -1
- package/dist/blocks/builtins/Testimonials.js +3 -1
- package/dist/blocks/builtins/Testimonials.js.map +1 -1
- package/dist/blocks/builtins/TestimonialsRender.js +4 -0
- package/dist/blocks/builtins/TestimonialsRender.js.map +1 -1
- package/dist/blocks/builtins/WhatsappChatRender.d.ts +1 -1
- package/dist/blocks/builtins/WhatsappChatRender.js +3 -1
- package/dist/blocks/builtins/WhatsappChatRender.js.map +1 -1
- package/dist/blocks/builtins/Widgets.js +2 -2
- package/dist/blocks/builtins/Widgets.js.map +1 -1
- package/dist/blocks/builtins/WidgetsRender.js +3 -1
- package/dist/blocks/builtins/WidgetsRender.js.map +1 -1
- package/dist/blocks/builtins/consentEmbed.js +26 -9
- package/dist/blocks/builtins/consentEmbed.js.map +1 -1
- package/dist/blocks/builtins/index.d.ts +3 -0
- package/dist/blocks/builtins/index.js +6 -0
- package/dist/blocks/builtins/index.js.map +1 -1
- package/dist/blocks/builtins/lib/autoComplete.d.ts +7 -0
- package/dist/blocks/builtins/lib/autoComplete.js +20 -0
- package/dist/blocks/builtins/lib/autoComplete.js.map +1 -0
- package/dist/blocks/builtins/lib/bookingUrl.d.ts +2 -2
- package/dist/blocks/builtins/lib/bookingUrl.js +1 -1
- package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -1
- package/dist/blocks/builtins/lib/ical.d.ts +24 -0
- package/dist/blocks/builtins/lib/ical.js +82 -0
- package/dist/blocks/builtins/lib/ical.js.map +1 -0
- package/dist/blocks/builtins/lib/vandaag.d.ts +8 -0
- package/dist/blocks/builtins/lib/vandaag.js +22 -0
- package/dist/blocks/builtins/lib/vandaag.js.map +1 -0
- package/dist/blocks/registry.d.ts +6 -0
- package/dist/blocks/registry.js.map +1 -1
- package/dist/blocks/ui/index.js +1 -0
- package/dist/blocks/ui/index.js.map +1 -1
- package/dist/components/EditBar.js +2 -4
- package/dist/components/EditBar.js.map +1 -1
- package/dist/components/News.js +26 -18
- package/dist/components/News.js.map +1 -1
- package/dist/components/PageView.d.ts +7 -1
- package/dist/components/PageView.js +17 -0
- package/dist/components/PageView.js.map +1 -1
- package/dist/components/ResponsiveImage.js +18 -20
- package/dist/components/ResponsiveImage.js.map +1 -1
- package/dist/components/onderOffset.d.ts +13 -0
- package/dist/components/onderOffset.js +74 -0
- package/dist/components/onderOffset.js.map +1 -0
- package/dist/components/site/Bedrijfsnummers.d.ts +9 -0
- package/dist/components/site/Bedrijfsnummers.js +12 -0
- package/dist/components/site/Bedrijfsnummers.js.map +1 -0
- package/dist/components/site/SiteFooter.d.ts +6 -1
- package/dist/components/site/SiteFooter.js +62 -9
- package/dist/components/site/SiteFooter.js.map +1 -1
- package/dist/components/site/SiteHeader.d.ts +15 -0
- package/dist/components/site/SiteHeader.js +70 -0
- package/dist/components/site/SiteHeader.js.map +1 -0
- package/dist/components/site/SiteNav.d.ts +2 -0
- package/dist/components/site/SiteNav.js +29 -5
- package/dist/components/site/SiteNav.js.map +1 -1
- package/dist/demo/DemoStudio.js +2 -2
- package/dist/demo/DemoStudio.js.map +1 -1
- package/dist/demo/demoStore.d.ts +13 -0
- package/dist/demo/demoStore.js +36 -0
- package/dist/demo/demoStore.js.map +1 -1
- package/dist/editor/EditorProvider.js +15 -4
- package/dist/editor/EditorProvider.js.map +1 -1
- package/dist/firebase/functionsClient.js +5 -1
- package/dist/firebase/functionsClient.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +20 -1
- package/dist/index.js.map +1 -1
- package/dist/media/ImageContext.d.ts +17 -0
- package/dist/media/ImageContext.js +65 -20
- package/dist/media/ImageContext.js.map +1 -1
- package/dist/media/altInHtml.d.ts +9 -0
- package/dist/media/altInHtml.js +17 -0
- package/dist/media/altInHtml.js.map +1 -0
- package/dist/media/srcset.d.ts +12 -0
- package/dist/media/srcset.js +13 -0
- package/dist/media/srcset.js.map +1 -0
- package/dist/modules/builtins.d.ts +1 -0
- package/dist/modules/builtins.js +22 -9
- package/dist/modules/builtins.js.map +1 -1
- package/dist/modules/consent/ConsentBanner.d.ts +5 -0
- package/dist/modules/consent/ConsentBanner.js +8 -7
- package/dist/modules/consent/ConsentBanner.js.map +1 -1
- package/dist/modules/consent/standaard.d.ts +12 -0
- package/dist/modules/consent/standaard.js +10 -0
- package/dist/modules/consent/standaard.js.map +1 -0
- package/dist/modules/consent/useConsent.d.ts +4 -0
- package/dist/modules/consent/useConsent.js +30 -1
- package/dist/modules/consent/useConsent.js.map +1 -1
- package/dist/modules/shop/blocks/Cart.js +5 -3
- package/dist/modules/shop/blocks/Cart.js.map +1 -1
- package/dist/modules/shop/blocks/Checkout.js +56 -35
- package/dist/modules/shop/blocks/Checkout.js.map +1 -1
- package/dist/modules/shop/blocks/Donation.js +4 -4
- package/dist/modules/shop/blocks/Donation.js.map +1 -1
- package/dist/modules/shop/blocks/ProductDetail.js +19 -3
- package/dist/modules/shop/blocks/ProductDetail.js.map +1 -1
- package/dist/modules/shop/blocks/ProductGrid.d.ts +3 -1
- package/dist/modules/shop/blocks/ProductGrid.js +8 -4
- package/dist/modules/shop/blocks/ProductGrid.js.map +1 -1
- package/dist/modules/shop/blocks/ShopCategories.js +4 -3
- package/dist/modules/shop/blocks/ShopCategories.js.map +1 -1
- package/dist/modules/shop/lib.d.ts +4 -0
- package/dist/modules/shop/lib.js +14 -0
- package/dist/modules/shop/lib.js.map +1 -1
- package/dist/modules/shop/settings.d.ts +3 -0
- package/dist/modules/shop/settings.js +14 -0
- package/dist/modules/shop/settings.js.map +1 -1
- package/dist/modules/shop/strings.d.ts +4 -0
- package/dist/modules/shop/strings.js +8 -0
- package/dist/modules/shop/strings.js.map +1 -1
- package/dist/next/envCheck.d.ts +42 -0
- package/dist/next/envCheck.js +106 -0
- package/dist/next/envCheck.js.map +1 -0
- package/dist/next/index.cjs +185 -2
- package/dist/next/index.d.ts +2 -0
- package/dist/next/index.js +8 -1
- package/dist/next/index.js.map +1 -1
- package/dist/next/securityHeaders.d.ts +36 -0
- package/dist/next/securityHeaders.js +74 -0
- package/dist/next/securityHeaders.js.map +1 -0
- package/dist/patterns/builtins.d.ts +7 -0
- package/dist/patterns/builtins.js +138 -3
- package/dist/patterns/builtins.js.map +1 -1
- package/dist/releaseNotes.js +148 -0
- package/dist/releaseNotes.js.map +1 -1
- package/dist/render/PublishedPage.d.ts +2 -1
- package/dist/render/PublishedPage.js +10 -4
- package/dist/render/PublishedPage.js.map +1 -1
- package/dist/schema/blocks.d.ts +473 -0
- package/dist/schema/blocks.js +105 -5
- package/dist/schema/blocks.js.map +1 -1
- package/dist/schema/business.d.ts +118 -0
- package/dist/schema/business.js +75 -0
- package/dist/schema/business.js.map +1 -0
- package/dist/schema/fields.d.ts +2 -1
- package/dist/schema/fields.js.map +1 -1
- package/dist/schema/forms.d.ts +18 -0
- package/dist/schema/forms.js +18 -3
- package/dist/schema/forms.js.map +1 -1
- package/dist/schema/mail.d.ts +10 -0
- package/dist/schema/mail.js +7 -0
- package/dist/schema/mail.js.map +1 -1
- package/dist/schema/settings.d.ts +103 -0
- package/dist/schema/settings.js +24 -3
- package/dist/schema/settings.js.map +1 -1
- package/dist/schema/shop.d.ts +2 -0
- package/dist/schema/shop.js +4 -0
- package/dist/schema/shop.js.map +1 -1
- package/dist/schema/shopGeld.d.ts +1 -0
- package/dist/schema/shopGeld.js +1 -0
- package/dist/schema/shopGeld.js.map +1 -1
- package/dist/schema/siteConfig.d.ts +69 -1
- package/dist/schema/siteConfig.js +7 -2
- package/dist/schema/siteConfig.js.map +1 -1
- package/dist/server/blockData.d.ts +1 -1
- package/dist/server/blockData.js +74 -18
- package/dist/server/blockData.js.map +1 -1
- package/dist/server/cspRapport.d.ts +20 -0
- package/dist/server/cspRapport.js +56 -0
- package/dist/server/cspRapport.js.map +1 -0
- package/dist/server/fonts.d.ts +3 -0
- package/dist/server/fonts.js +39 -0
- package/dist/server/fonts.js.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +8 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/sanitize.js +2 -0
- package/dist/server/sanitize.js.map +1 -1
- package/dist/settings/useSiteSettings.js +4 -1
- package/dist/settings/useSiteSettings.js.map +1 -1
- package/dist/starters/starters.d.ts +69 -0
- package/dist/starters/starters.js +171 -0
- package/dist/starters/starters.js.map +1 -0
- package/dist/styles.css +1181 -212
- package/dist/theme/color.d.ts +10 -0
- package/dist/theme/color.js +17 -1
- package/dist/theme/color.js.map +1 -1
- package/dist/theme/fontFallback.d.ts +23 -0
- package/dist/theme/fontFallback.js +58 -0
- package/dist/theme/fontFallback.js.map +1 -0
- package/dist/theme/fonts.d.ts +11 -0
- package/dist/theme/fonts.js +16 -0
- package/dist/theme/fonts.js.map +1 -0
- package/dist/version.js +1 -1
- package/package.json +5 -4
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/index.ts"],"sourcesContent":["/**\n * @xiwebdesign/xicms-core/server — server-only helpers (firebase-admin, sanitization, SEO,\n * pagina-reads). NOOIT importeren in client-componenten.\n */\nimport \"server-only\";\n\n// `getAdminAuth` zit BEWUST niet hier maar achter de subpath `@xiwebdesign/xicms-core/server/auth`\n// (zie ./auth.ts): firebase-admin/auth sloopt via jwks-rsa/jose élke server-render op Vercel, en\n// hoort dus niet in de bundel van sites die alleen pagina's lezen.\nexport { getAdminApp, getAdminDb } from \"../firebase/admin\";\nexport { sanitizeRichText } from \"./sanitize\";\n// Veilige JSON-LD-serialisatie voor <script type=\"application/ld+json\"> in consumer-routes\n// (escapet `<` zodat klant-tekst met </script> de pagina niet kan breken).\nexport { jsonLdHtml } from \"../blocks/builtins/jsonld\";\nexport {\n buildMetadata,\n buildJsonLd,\n buildSitemap,\n buildRobots,\n siteOrigin,\n businessJsonLd,\n breadcrumbListJsonLd,\n articleJsonLd,\n productJsonLd,\n openingHoursJsonLd,\n galleryJsonLd,\n videoObjectJsonLd,\n type BusinessInfo,\n} from \"./seo\";\nexport { validateEnv, assertEnv, type EnvReport } from \"./env\";\n// On-demand revalidation (6.5): POST-handler voor `app/api/revalidate/route.ts` in de klantsite.\n// De backend roept die route na een publicatie aan → wijziging binnen seconden live, zonder rebuild.\n// SSR-seeds (7.12): verzamelt server-side de blockData die de blokken van déze pagina nodig\n// hebben (shop, nieuws, formulieren, zoekindex) — één aanroep in de catch-all, en geen enkel blok\n// hoeft meer per bezoeker uit Firestore te lezen.\nexport { getPageBlockData, type PageBlockDataOptions } from \"./blockData\";\nexport { listFormDefinitions, listSiteMedia } from \"./pages\";\nexport { revalidatePOST } from \"./revalidate\";\n// Preview (Draft Mode): POST-handler voor `app/api/draft/route.ts` in de klantsite. Zet de\n// bypass-cookie zodat een ingelogde editor de content-bundel + ISR-cache overslaat, terwijl de\n// pagina-route voor publiek statisch blijft.\nexport { draftPOST, maakDraftGET } from \"./draft\";\nexport { signPreviewToken, verifyPreviewToken, type PreviewClaims } from \"./previewToken\";\n// Doorverwijzingen (7.24): `resolveRedirect(siteId, path)` in de catch-all vlak vóór notFound().\nexport { resolveRedirect } from \"./redirects\";\n// Versie-endpoint: GET-handler voor `app/api/version/route.ts`, zodat het superbeheer kan zien op\n// welke engine een DEPLOYMENT draait (en niet alleen wanneer er voor het laatst is ingelogd).\nexport { versionGET } from \"./version\";\n// Shop-SSR (6.0): opt-in via subpath `@xiwebdesign/xicms-core/server/shop` (readers + product-SEO).\n// Niet meer onvoorwaardelijk her-geëxporteerd, zodat shop-servercode niet in elke site landt.\nexport {\n pathFromSlugs,\n listPublishedPages,\n listPublishedNews,\n getPublishedPageByPath,\n getPublishedPageByPathExpanded,\n getSiteSymbols,\n expandSymbols,\n getSiteCustomBlocks,\n getPublicSiteSettings,\n getDraftPageById,\n getDraftPageByPath,\n type StoredPage,\n} from \"./pages\";\n// Content-bundle (5.7): build-time reader van `content/published.bundle.json`. De pagina-/settings-/\n// symbol-/customBlock-readers hierboven zijn al bundle-first; deze exports zijn voor directe\n// consumptie (bv. nieuws-blockData in de klant-routes).\nexport {\n getBundle,\n getBundlePage,\n getBundleNews,\n getNewsPageData,\n type PublishedBundle,\n type BundleItem,\n} from \"./bundle\";\n// Localisatie (5.0) — server-safe overlay-helpers, ook bruikbaar in route-handlers/layouts.\nexport {\n siteLocales,\n parseLocaleSlugs,\n localizedPath,\n localizePage,\n localizeBlocks,\n pruneTranslations,\n TranslationsSchema,\n type Translations,\n type LocaleConfig,\n} from \"../i18n/overlay\";\n"],"mappings":"AAIA,OAAO;AAKP,SAAS,aAAa,kBAAkB;AACxC,SAAS,wBAAwB;AAGjC,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,aAAa,iBAAiC;AAMvD,SAAS,wBAAmD;AAC5D,SAAS,qBAAqB,qBAAqB;AACnD,SAAS,sBAAsB;AAI/B,SAAS,WAAW,oBAAoB;AACxC,SAAS,kBAAkB,0BAA8C;AAEzE,SAAS,uBAAuB;AAGhC,SAAS,kBAAkB;
|
|
1
|
+
{"version":3,"sources":["../../src/server/index.ts"],"sourcesContent":["/**\n * @xiwebdesign/xicms-core/server — server-only helpers (firebase-admin, sanitization, SEO,\n * pagina-reads). NOOIT importeren in client-componenten.\n */\nimport \"server-only\";\n\n// `getAdminAuth` zit BEWUST niet hier maar achter de subpath `@xiwebdesign/xicms-core/server/auth`\n// (zie ./auth.ts): firebase-admin/auth sloopt via jwks-rsa/jose élke server-render op Vercel, en\n// hoort dus niet in de bundel van sites die alleen pagina's lezen.\nexport { getAdminApp, getAdminDb } from \"../firebase/admin\";\nexport { sanitizeRichText } from \"./sanitize\";\n// Veilige JSON-LD-serialisatie voor <script type=\"application/ld+json\"> in consumer-routes\n// (escapet `<` zodat klant-tekst met </script> de pagina niet kan breken).\nexport { jsonLdHtml } from \"../blocks/builtins/jsonld\";\nexport {\n buildMetadata,\n buildJsonLd,\n buildSitemap,\n buildRobots,\n siteOrigin,\n businessJsonLd,\n breadcrumbListJsonLd,\n articleJsonLd,\n productJsonLd,\n openingHoursJsonLd,\n galleryJsonLd,\n videoObjectJsonLd,\n type BusinessInfo,\n} from \"./seo\";\nexport { validateEnv, assertEnv, type EnvReport } from \"./env\";\n// On-demand revalidation (6.5): POST-handler voor `app/api/revalidate/route.ts` in de klantsite.\n// De backend roept die route na een publicatie aan → wijziging binnen seconden live, zonder rebuild.\n// SSR-seeds (7.12): verzamelt server-side de blockData die de blokken van déze pagina nodig\n// hebben (shop, nieuws, formulieren, zoekindex) — één aanroep in de catch-all, en geen enkel blok\n// hoeft meer per bezoeker uit Firestore te lezen.\nexport { getPageBlockData, type PageBlockDataOptions } from \"./blockData\";\nexport { listFormDefinitions, listSiteMedia } from \"./pages\";\nexport { revalidatePOST } from \"./revalidate\";\n// Preview (Draft Mode): POST-handler voor `app/api/draft/route.ts` in de klantsite. Zet de\n// bypass-cookie zodat een ingelogde editor de content-bundel + ISR-cache overslaat, terwijl de\n// pagina-route voor publiek statisch blijft.\nexport { draftPOST, maakDraftGET } from \"./draft\";\nexport { signPreviewToken, verifyPreviewToken, type PreviewClaims } from \"./previewToken\";\n// Doorverwijzingen (7.24): `resolveRedirect(siteId, path)` in de catch-all vlak vóór notFound().\nexport { resolveRedirect } from \"./redirects\";\n// Versie-endpoint: GET-handler voor `app/api/version/route.ts`, zodat het superbeheer kan zien op\n// welke engine een DEPLOYMENT draait (en niet alleen wanneer er voor het laatst is ingelogd).\nexport { versionGET } from \"./version\";\n// 8.3: Google Fonts via de eigen site (geen verbinding met Google vanaf de bezoeker).\nexport { fontsGET, herschrijfFontCss } from \"./fonts\";\n// 8.7: CSP-overtredingen van browsers naar de serverlog (zie xicmsSecurityHeaders in /next).\nexport { cspRapportPOST, leesCspRapport, type CspOvertreding } from \"./cspRapport\";\n// Shop-SSR (6.0): opt-in via subpath `@xiwebdesign/xicms-core/server/shop` (readers + product-SEO).\n// Niet meer onvoorwaardelijk her-geëxporteerd, zodat shop-servercode niet in elke site landt.\nexport {\n pathFromSlugs,\n listPublishedPages,\n listPublishedNews,\n getPublishedPageByPath,\n getPublishedPageByPathExpanded,\n getSiteSymbols,\n expandSymbols,\n getSiteCustomBlocks,\n getPublicSiteSettings,\n getDraftPageById,\n getDraftPageByPath,\n type StoredPage,\n} from \"./pages\";\n// Content-bundle (5.7): build-time reader van `content/published.bundle.json`. De pagina-/settings-/\n// symbol-/customBlock-readers hierboven zijn al bundle-first; deze exports zijn voor directe\n// consumptie (bv. nieuws-blockData in de klant-routes).\nexport {\n getBundle,\n getBundlePage,\n getBundleNews,\n getNewsPageData,\n type PublishedBundle,\n type BundleItem,\n} from \"./bundle\";\n// Localisatie (5.0) — server-safe overlay-helpers, ook bruikbaar in route-handlers/layouts.\nexport {\n siteLocales,\n parseLocaleSlugs,\n localizedPath,\n localizePage,\n localizeBlocks,\n pruneTranslations,\n TranslationsSchema,\n type Translations,\n type LocaleConfig,\n} from \"../i18n/overlay\";\n\n// 8.13: LocalBusiness-JSON-LD uit het bedrijfsprofiel (Instellingen → Bedrijf).\nexport { bedrijfJsonLd } from \"../bedrijf/bedrijf\";\n"],"mappings":"AAIA,OAAO;AAKP,SAAS,aAAa,kBAAkB;AACxC,SAAS,wBAAwB;AAGjC,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,aAAa,iBAAiC;AAMvD,SAAS,wBAAmD;AAC5D,SAAS,qBAAqB,qBAAqB;AACnD,SAAS,sBAAsB;AAI/B,SAAS,WAAW,oBAAoB;AACxC,SAAS,kBAAkB,0BAA8C;AAEzE,SAAS,uBAAuB;AAGhC,SAAS,kBAAkB;AAE3B,SAAS,UAAU,yBAAyB;AAE5C,SAAS,gBAAgB,sBAA2C;AAGpE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAIP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAGP,SAAS,qBAAqB;","names":[]}
|
package/dist/server/sanitize.js
CHANGED
|
@@ -63,6 +63,8 @@ const OPTIONS = {
|
|
|
63
63
|
// Afbeeldingen lazy + async laten laden voor performance.
|
|
64
64
|
img: (tagName, attribs) => ({ tagName, attribs: { ...attribs, loading: "lazy", decoding: "async" } })
|
|
65
65
|
},
|
|
66
|
+
// 8.10: lege koppen weg (zie de spiegel in functions/src/lib/sanitize.ts).
|
|
67
|
+
exclusiveFilter: (frame) => /^h[2-4]$/.test(frame.tag) && !frame.text.trim() && !frame.mediaChildren?.length,
|
|
66
68
|
disallowedTagsMode: "discard"
|
|
67
69
|
};
|
|
68
70
|
function sanitizeRichText(html) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/sanitize.ts"],"sourcesContent":["import \"server-only\";\n\nimport sanitizeHtml from \"sanitize-html\";\n\n/**\n * Server-side sanitization van rich text (TipTap-output) met een strikte allowlist.\n * Dit draait bij elke write/publish, zodat opgeslagen HTML gegarandeerd veilig te renderen is\n * (de RichText-block rendert met dangerouslySetInnerHTML). Nooit op vertrouwen van de client.\n */\n// Lettergrootte (RichTextEditor.tsx, FONT_SIZES): vaste preset-waarden, geen vrij invoerveld — de\n// regex staat UITSLUITEND deze exacte strings toe (geen url()/expression()/willekeurige CSS).\nconst ALLOWED_FONT_SIZES = /^(0\\.85|1\\.25|1\\.5)rem$/;\n\nconst OPTIONS: sanitizeHtml.IOptions = {\n allowedTags: [\n \"p\", \"br\", \"strong\", \"b\", \"em\", \"i\", \"u\", \"s\", \"a\", \"img\", \"span\",\n \"ul\", \"ol\", \"li\", \"blockquote\", \"h2\", \"h3\", \"h4\", \"code\", \"pre\", \"hr\",\n \"table\", \"thead\", \"tbody\", \"tfoot\", \"tr\", \"th\", \"td\", \"caption\",\n ],\n allowedAttributes: {\n a: [\"href\", \"target\", \"rel\"],\n // Afbeeldingen in rich text (WYSIWYG): alleen veilige presentatie-attributen, geen on*-handlers.\n img: [\"src\", \"alt\", \"title\", \"width\", \"height\", \"loading\", \"decoding\"],\n // `span` mag uitsluitend `style` dragen — en zelfs dat alleen voor de font-size-preset (zie\n // `allowedStyles` hieronder). Geen andere attributen (geen class/id/data-*).\n span: [\"style\"],\n // Tabellen: alleen celspanning, geen style/class (opmaak komt uit .xicms-richtext in styles.css).\n th: [\"colspan\", \"rowspan\"],\n td: [\"colspan\", \"rowspan\"],\n },\n allowedStyles: {\n span: { \"font-size\": [ALLOWED_FONT_SIZES] },\n },\n // Geen data:-URI's voor afbeeldingen (alleen http/https + relatieve paden naar onze eigen Storage).\n allowedSchemesByTag: { img: [\"http\", \"https\"] },\n allowedSchemes: [\"http\", \"https\", \"mailto\", \"tel\"],\n transformTags: {\n // Externe links altijd veilig openen.\n a: (tagName, attribs) => ({\n tagName,\n attribs: {\n ...attribs,\n rel: \"noopener noreferrer nofollow\",\n ...(attribs.target === \"_blank\" ? { target: \"_blank\" } : {}),\n },\n }),\n // Afbeeldingen lazy + async laten laden voor performance.\n img: (tagName, attribs) => ({ tagName, attribs: { ...attribs, loading: \"lazy\", decoding: \"async\" } }),\n },\n disallowedTagsMode: \"discard\",\n};\n\nexport function sanitizeRichText(html: string): string {\n return sanitizeHtml(html ?? \"\", OPTIONS);\n}\n"],"mappings":"AAAA,OAAO;AAEP,OAAO,kBAAkB;AASzB,MAAM,qBAAqB;AAE3B,MAAM,UAAiC;AAAA,EACrC,aAAa;AAAA,IACX;AAAA,IAAK;AAAA,IAAM;AAAA,IAAU;AAAA,IAAK;AAAA,IAAM;AAAA,IAAK;AAAA,IAAK;AAAA,IAAK;AAAA,IAAK;AAAA,IAAO;AAAA,IAC3D;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAc;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAO;AAAA,IACjE;AAAA,IAAS;AAAA,IAAS;AAAA,IAAS;AAAA,IAAS;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,EACxD;AAAA,EACA,mBAAmB;AAAA,IACjB,GAAG,CAAC,QAAQ,UAAU,KAAK;AAAA;AAAA,IAE3B,KAAK,CAAC,OAAO,OAAO,SAAS,SAAS,UAAU,WAAW,UAAU;AAAA;AAAA;AAAA,IAGrE,MAAM,CAAC,OAAO;AAAA;AAAA,IAEd,IAAI,CAAC,WAAW,SAAS;AAAA,IACzB,IAAI,CAAC,WAAW,SAAS;AAAA,EAC3B;AAAA,EACA,eAAe;AAAA,IACb,MAAM,EAAE,aAAa,CAAC,kBAAkB,EAAE;AAAA,EAC5C;AAAA;AAAA,EAEA,qBAAqB,EAAE,KAAK,CAAC,QAAQ,OAAO,EAAE;AAAA,EAC9C,gBAAgB,CAAC,QAAQ,SAAS,UAAU,KAAK;AAAA,EACjD,eAAe;AAAA;AAAA,IAEb,GAAG,CAAC,SAAS,aAAa;AAAA,MACxB;AAAA,MACA,SAAS;AAAA,QACP,GAAG;AAAA,QACH,KAAK;AAAA,QACL,GAAI,QAAQ,WAAW,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,MAC5D;AAAA,IACF;AAAA;AAAA,IAEA,KAAK,CAAC,SAAS,aAAa,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,SAAS,QAAQ,UAAU,QAAQ,EAAE;AAAA,EACrG;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../src/server/sanitize.ts"],"sourcesContent":["import \"server-only\";\n\nimport sanitizeHtml from \"sanitize-html\";\n\n/**\n * Server-side sanitization van rich text (TipTap-output) met een strikte allowlist.\n * Dit draait bij elke write/publish, zodat opgeslagen HTML gegarandeerd veilig te renderen is\n * (de RichText-block rendert met dangerouslySetInnerHTML). Nooit op vertrouwen van de client.\n */\n// Lettergrootte (RichTextEditor.tsx, FONT_SIZES): vaste preset-waarden, geen vrij invoerveld — de\n// regex staat UITSLUITEND deze exacte strings toe (geen url()/expression()/willekeurige CSS).\nconst ALLOWED_FONT_SIZES = /^(0\\.85|1\\.25|1\\.5)rem$/;\n\nconst OPTIONS: sanitizeHtml.IOptions = {\n allowedTags: [\n \"p\", \"br\", \"strong\", \"b\", \"em\", \"i\", \"u\", \"s\", \"a\", \"img\", \"span\",\n \"ul\", \"ol\", \"li\", \"blockquote\", \"h2\", \"h3\", \"h4\", \"code\", \"pre\", \"hr\",\n \"table\", \"thead\", \"tbody\", \"tfoot\", \"tr\", \"th\", \"td\", \"caption\",\n ],\n allowedAttributes: {\n a: [\"href\", \"target\", \"rel\"],\n // Afbeeldingen in rich text (WYSIWYG): alleen veilige presentatie-attributen, geen on*-handlers.\n img: [\"src\", \"alt\", \"title\", \"width\", \"height\", \"loading\", \"decoding\"],\n // `span` mag uitsluitend `style` dragen — en zelfs dat alleen voor de font-size-preset (zie\n // `allowedStyles` hieronder). Geen andere attributen (geen class/id/data-*).\n span: [\"style\"],\n // Tabellen: alleen celspanning, geen style/class (opmaak komt uit .xicms-richtext in styles.css).\n th: [\"colspan\", \"rowspan\"],\n td: [\"colspan\", \"rowspan\"],\n },\n allowedStyles: {\n span: { \"font-size\": [ALLOWED_FONT_SIZES] },\n },\n // Geen data:-URI's voor afbeeldingen (alleen http/https + relatieve paden naar onze eigen Storage).\n allowedSchemesByTag: { img: [\"http\", \"https\"] },\n allowedSchemes: [\"http\", \"https\", \"mailto\", \"tel\"],\n transformTags: {\n // Externe links altijd veilig openen.\n a: (tagName, attribs) => ({\n tagName,\n attribs: {\n ...attribs,\n rel: \"noopener noreferrer nofollow\",\n ...(attribs.target === \"_blank\" ? { target: \"_blank\" } : {}),\n },\n }),\n // Afbeeldingen lazy + async laten laden voor performance.\n img: (tagName, attribs) => ({ tagName, attribs: { ...attribs, loading: \"lazy\", decoding: \"async\" } }),\n },\n // 8.10: lege koppen weg (zie de spiegel in functions/src/lib/sanitize.ts).\n exclusiveFilter: (frame) => /^h[2-4]$/.test(frame.tag) && !frame.text.trim() && !frame.mediaChildren?.length,\n disallowedTagsMode: \"discard\",\n};\n\nexport function sanitizeRichText(html: string): string {\n return sanitizeHtml(html ?? \"\", OPTIONS);\n}\n"],"mappings":"AAAA,OAAO;AAEP,OAAO,kBAAkB;AASzB,MAAM,qBAAqB;AAE3B,MAAM,UAAiC;AAAA,EACrC,aAAa;AAAA,IACX;AAAA,IAAK;AAAA,IAAM;AAAA,IAAU;AAAA,IAAK;AAAA,IAAM;AAAA,IAAK;AAAA,IAAK;AAAA,IAAK;AAAA,IAAK;AAAA,IAAO;AAAA,IAC3D;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAc;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAO;AAAA,IACjE;AAAA,IAAS;AAAA,IAAS;AAAA,IAAS;AAAA,IAAS;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,EACxD;AAAA,EACA,mBAAmB;AAAA,IACjB,GAAG,CAAC,QAAQ,UAAU,KAAK;AAAA;AAAA,IAE3B,KAAK,CAAC,OAAO,OAAO,SAAS,SAAS,UAAU,WAAW,UAAU;AAAA;AAAA;AAAA,IAGrE,MAAM,CAAC,OAAO;AAAA;AAAA,IAEd,IAAI,CAAC,WAAW,SAAS;AAAA,IACzB,IAAI,CAAC,WAAW,SAAS;AAAA,EAC3B;AAAA,EACA,eAAe;AAAA,IACb,MAAM,EAAE,aAAa,CAAC,kBAAkB,EAAE;AAAA,EAC5C;AAAA;AAAA,EAEA,qBAAqB,EAAE,KAAK,CAAC,QAAQ,OAAO,EAAE;AAAA,EAC9C,gBAAgB,CAAC,QAAQ,SAAS,UAAU,KAAK;AAAA,EACjD,eAAe;AAAA;AAAA,IAEb,GAAG,CAAC,SAAS,aAAa;AAAA,MACxB;AAAA,MACA,SAAS;AAAA,QACP,GAAG;AAAA,QACH,KAAK;AAAA,QACL,GAAI,QAAQ,WAAW,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,MAC5D;AAAA,IACF;AAAA;AAAA,IAEA,KAAK,CAAC,SAAS,aAAa,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,SAAS,QAAQ,UAAU,QAAQ,EAAE;AAAA,EACrG;AAAA;AAAA,EAEA,iBAAiB,CAAC,UAAU,WAAW,KAAK,MAAM,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,KAAK,CAAC,MAAM,eAAe;AAAA,EACtG,oBAAoB;AACtB;AAEO,SAAS,iBAAiB,MAAsB;AACrD,SAAO,aAAa,QAAQ,IAAI,OAAO;AACzC;","names":[]}
|
|
@@ -96,7 +96,10 @@ function useMergedSiteConfig() {
|
|
|
96
96
|
name: settings.name ?? base.name,
|
|
97
97
|
nav,
|
|
98
98
|
theme: mergeThemeTokens(base.theme, settings.theme),
|
|
99
|
-
seoDefaults: settings.seoDefaults ?? base.seoDefaults
|
|
99
|
+
seoDefaults: settings.seoDefaults ?? base.seoDefaults,
|
|
100
|
+
// 8.13: het profiel uit /beheer wint; de site-config is de startwaarde.
|
|
101
|
+
business: settings.business ?? base.business,
|
|
102
|
+
header: settings.header ?? base.header
|
|
100
103
|
};
|
|
101
104
|
}, [base, settings]);
|
|
102
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/settings/useSiteSettings.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport { useSiteConfig } from \"../config\";\nimport {\n PublicSiteSettingsSchema,\n mergeThemeTokens,\n type PublicSiteSettings,\n} from \"../schema/settings\";\nimport type { SiteConfig } from \"../schema/siteConfig\";\n\n/**\n * Live, publiek-veilige site-instellingen (`sites/{siteId}/settings/public`) zodat dingen die de\n * klant in /beheer wijzigt (footer, nav, thema, module-instellingen) direct op de site verschijnen.\n *\n * - Met SSR-seed (`initial`, via XiCMSProvider `settingsData`): géén client-read voor publiek —\n * de settings zitten al in de server-HTML (geen theme-flits) en verversen via ISR.\n * - Zonder seed (publiek): één `getDoc` (geen per-bezoeker listener).\n * - Editors: `useSiteSettingsLiveSync` (onSnapshot) zodat /beheer-wijzigingen meteen zichtbaar zijn.\n * Zonder Firebase of zonder doc valt alles terug op de statische `SiteConfig` (identiek aan vroeger).\n */\ninterface Ctx {\n settings: PublicSiteSettings;\n loaded: boolean;\n /** Interne setter voor de editor-live-sync (useSiteSettingsLiveSync). */\n _set?: (s: PublicSiteSettings) => void;\n}\nconst SettingsContext = createContext<Ctx>({ settings: {}, loaded: false });\n\nexport function SiteSettingsProvider({\n siteId,\n live = false,\n initial,\n children,\n}: {\n siteId: string;\n live?: boolean;\n /** SSR-startset (server-side gelezen via `getPublicSiteSettings`); slaat de client-read over. */\n initial?: PublicSiteSettings;\n children: ReactNode;\n}) {\n const hasInitial = initial !== undefined;\n const [settings, setSettings] = useState<PublicSiteSettings>(initial ?? {});\n const [loaded, setLoaded] = useState(hasInitial);\n\n useEffect(() => {\n // Met een SSR-seed doet de publieke site géén client-read meer: de layout-route is ISR-gecached\n // en levert verse settings per revalidate; editors krijgen apart een live sync.\n if (hasInitial && !live) return;\n const apply = (data: unknown) => {\n const res = PublicSiteSettingsSchema.safeParse(data ?? {});\n if (res.success) setSettings(res.data);\n setLoaded(true);\n };\n // Firestore DYNAMISCH: met een SSR-seed komt de publieke site hier niet eens, en een bezoeker\n // hoort de SDK nooit te downloaden. Statisch importeren zette hem in de bundel van elke pagina.\n let cancelled = false;\n let unsub: (() => void) | undefined;\n void (async () => {\n const [{ getDb }, { doc, getDoc, onSnapshot }] = await Promise.all([\n import(\"../firebase/client\"),\n import(\"firebase/firestore\"),\n ]);\n const db = getDb();\n if (!db || cancelled) {\n setLoaded(true);\n return;\n }\n const ref = doc(db, \"sites\", siteId, \"settings\", \"public\");\n if (live) {\n unsub = onSnapshot(ref, (snap) => apply(snap.exists() ? snap.data() : {}), () => setLoaded(true));\n return;\n }\n try {\n const snap = await getDoc(ref);\n if (!cancelled) apply(snap.exists() ? snap.data() : {});\n } catch {\n if (!cancelled) setLoaded(true);\n }\n })();\n return () => {\n cancelled = true;\n unsub?.();\n };\n }, [siteId, live, hasInitial]);\n\n const value = useMemo<Ctx>(() => ({ settings, loaded, _set: setSettings }), [settings, loaded]);\n return <SettingsContext.Provider value={value}>{children}</SettingsContext.Provider>;\n}\n\n/** Ruwe publieke settings + laadstatus. */\nexport function useSiteSettings(): Ctx {\n return useContext(SettingsContext);\n}\n\n/**\n * Editor-live-sync: onSnapshot op `settings/public` zolang `enabled` (ingelogde editor). Aparte\n * hook (i.p.v. `live` op de provider) zodat publiek nooit een listener krijgt — zelfde patroon\n * als CustomBlocksSync in XiCMSProvider. Een leesfout laat de bestaande settings staan.\n */\nexport function useSiteSettingsLiveSync(siteId: string, enabled: boolean) {\n const { _set } = useContext(SettingsContext);\n useEffect(() => {\n // Alleen editors (enabled) krijgen een listener, en pas dán laadt de SDK.\n if (!enabled || !_set) return;\n let unsub: (() => void) | undefined;\n let afgebroken = false;\n void (async () => {\n const [{ getDb }, { doc, onSnapshot }] = await Promise.all([\n import(\"../firebase/client\"),\n import(\"firebase/firestore\"),\n ]);\n const db = getDb();\n if (!db || afgebroken) return;\n unsub = onSnapshot(\n doc(db, \"sites\", siteId, \"settings\", \"public\"),\n (snap) => {\n const res = PublicSiteSettingsSchema.safeParse(snap.exists() ? snap.data() : {});\n if (res.success) _set(res.data);\n },\n () => undefined,\n );\n })();\n return () => {\n afgebroken = true;\n unsub?.();\n };\n }, [enabled, siteId, _set]);\n}\n\n/** SiteConfig met de live Firestore-settings eroverheen (Firestore wint waar gezet). */\nexport function useMergedSiteConfig(): SiteConfig {\n const base = useSiteConfig();\n const { settings } = useSiteSettings();\n return useMemo(() => {\n // AANWEZIG wint, ook als de lijst leeg is. Dat was `length > 0`, en dan kon je het menu niet\n // leegmaken: sla je een leeg menu op, dan kwam de nav uit `site.config.ts` gewoon terug. Het\n // verschil dat telt is \"heeft iemand hier een keuze gemaakt\", niet \"staat er iets in\".\n const nav = settings.nav ?? base.nav;\n return {\n ...base,\n name: settings.name ?? base.name,\n nav,\n theme: mergeThemeTokens(base.theme, settings.theme),\n seoDefaults: settings.seoDefaults ?? base.seoDefaults,\n };\n }, [base, settings]);\n}\n"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../../src/settings/useSiteSettings.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport { useSiteConfig } from \"../config\";\nimport {\n PublicSiteSettingsSchema,\n mergeThemeTokens,\n type PublicSiteSettings,\n} from \"../schema/settings\";\nimport type { SiteConfig } from \"../schema/siteConfig\";\n\n/**\n * Live, publiek-veilige site-instellingen (`sites/{siteId}/settings/public`) zodat dingen die de\n * klant in /beheer wijzigt (footer, nav, thema, module-instellingen) direct op de site verschijnen.\n *\n * - Met SSR-seed (`initial`, via XiCMSProvider `settingsData`): géén client-read voor publiek —\n * de settings zitten al in de server-HTML (geen theme-flits) en verversen via ISR.\n * - Zonder seed (publiek): één `getDoc` (geen per-bezoeker listener).\n * - Editors: `useSiteSettingsLiveSync` (onSnapshot) zodat /beheer-wijzigingen meteen zichtbaar zijn.\n * Zonder Firebase of zonder doc valt alles terug op de statische `SiteConfig` (identiek aan vroeger).\n */\ninterface Ctx {\n settings: PublicSiteSettings;\n loaded: boolean;\n /** Interne setter voor de editor-live-sync (useSiteSettingsLiveSync). */\n _set?: (s: PublicSiteSettings) => void;\n}\nconst SettingsContext = createContext<Ctx>({ settings: {}, loaded: false });\n\nexport function SiteSettingsProvider({\n siteId,\n live = false,\n initial,\n children,\n}: {\n siteId: string;\n live?: boolean;\n /** SSR-startset (server-side gelezen via `getPublicSiteSettings`); slaat de client-read over. */\n initial?: PublicSiteSettings;\n children: ReactNode;\n}) {\n const hasInitial = initial !== undefined;\n const [settings, setSettings] = useState<PublicSiteSettings>(initial ?? {});\n const [loaded, setLoaded] = useState(hasInitial);\n\n useEffect(() => {\n // Met een SSR-seed doet de publieke site géén client-read meer: de layout-route is ISR-gecached\n // en levert verse settings per revalidate; editors krijgen apart een live sync.\n if (hasInitial && !live) return;\n const apply = (data: unknown) => {\n const res = PublicSiteSettingsSchema.safeParse(data ?? {});\n if (res.success) setSettings(res.data);\n setLoaded(true);\n };\n // Firestore DYNAMISCH: met een SSR-seed komt de publieke site hier niet eens, en een bezoeker\n // hoort de SDK nooit te downloaden. Statisch importeren zette hem in de bundel van elke pagina.\n let cancelled = false;\n let unsub: (() => void) | undefined;\n void (async () => {\n const [{ getDb }, { doc, getDoc, onSnapshot }] = await Promise.all([\n import(\"../firebase/client\"),\n import(\"firebase/firestore\"),\n ]);\n const db = getDb();\n if (!db || cancelled) {\n setLoaded(true);\n return;\n }\n const ref = doc(db, \"sites\", siteId, \"settings\", \"public\");\n if (live) {\n unsub = onSnapshot(ref, (snap) => apply(snap.exists() ? snap.data() : {}), () => setLoaded(true));\n return;\n }\n try {\n const snap = await getDoc(ref);\n if (!cancelled) apply(snap.exists() ? snap.data() : {});\n } catch {\n if (!cancelled) setLoaded(true);\n }\n })();\n return () => {\n cancelled = true;\n unsub?.();\n };\n }, [siteId, live, hasInitial]);\n\n const value = useMemo<Ctx>(() => ({ settings, loaded, _set: setSettings }), [settings, loaded]);\n return <SettingsContext.Provider value={value}>{children}</SettingsContext.Provider>;\n}\n\n/** Ruwe publieke settings + laadstatus. */\nexport function useSiteSettings(): Ctx {\n return useContext(SettingsContext);\n}\n\n/**\n * Editor-live-sync: onSnapshot op `settings/public` zolang `enabled` (ingelogde editor). Aparte\n * hook (i.p.v. `live` op de provider) zodat publiek nooit een listener krijgt — zelfde patroon\n * als CustomBlocksSync in XiCMSProvider. Een leesfout laat de bestaande settings staan.\n */\nexport function useSiteSettingsLiveSync(siteId: string, enabled: boolean) {\n const { _set } = useContext(SettingsContext);\n useEffect(() => {\n // Alleen editors (enabled) krijgen een listener, en pas dán laadt de SDK.\n if (!enabled || !_set) return;\n let unsub: (() => void) | undefined;\n let afgebroken = false;\n void (async () => {\n const [{ getDb }, { doc, onSnapshot }] = await Promise.all([\n import(\"../firebase/client\"),\n import(\"firebase/firestore\"),\n ]);\n const db = getDb();\n if (!db || afgebroken) return;\n unsub = onSnapshot(\n doc(db, \"sites\", siteId, \"settings\", \"public\"),\n (snap) => {\n const res = PublicSiteSettingsSchema.safeParse(snap.exists() ? snap.data() : {});\n if (res.success) _set(res.data);\n },\n () => undefined,\n );\n })();\n return () => {\n afgebroken = true;\n unsub?.();\n };\n }, [enabled, siteId, _set]);\n}\n\n/** SiteConfig met de live Firestore-settings eroverheen (Firestore wint waar gezet). */\nexport function useMergedSiteConfig(): SiteConfig {\n const base = useSiteConfig();\n const { settings } = useSiteSettings();\n return useMemo(() => {\n // AANWEZIG wint, ook als de lijst leeg is. Dat was `length > 0`, en dan kon je het menu niet\n // leegmaken: sla je een leeg menu op, dan kwam de nav uit `site.config.ts` gewoon terug. Het\n // verschil dat telt is \"heeft iemand hier een keuze gemaakt\", niet \"staat er iets in\".\n const nav = settings.nav ?? base.nav;\n return {\n ...base,\n name: settings.name ?? base.name,\n nav,\n theme: mergeThemeTokens(base.theme, settings.theme),\n seoDefaults: settings.seoDefaults ?? base.seoDefaults,\n // 8.13: het profiel uit /beheer wint; de site-config is de startwaarde.\n business: settings.business ?? base.business,\n header: settings.header ?? base.header,\n };\n }, [base, settings]);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type Pattern } from "../patterns/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Branchestarters (8.14): een complete beginsite per soort bedrijf.
|
|
4
|
+
*
|
|
5
|
+
* Een nieuwe site begon leeg — "Welkom bij X" en een link naar /beheer — en elke klant kreeg
|
|
6
|
+
* daarmee hetzelfde lege vel, of het nu een kapper, een restaurant of een vakantiehuis was. Een
|
|
7
|
+
* starter zet in één keer: een passende huisstijl-preset, het soort bedrijf (voor Google), de
|
|
8
|
+
* modules die dat type nodig heeft, en vier tot zes pagina's met de juiste blokken, als werkversie
|
|
9
|
+
* om in te vullen. Gebruikt door `create-site --type` en door de knop "Start met een kant-en-klare
|
|
10
|
+
* opzet" in /beheer → Pagina's (alleen bij een site zonder pagina's).
|
|
11
|
+
*
|
|
12
|
+
* De pagina's zijn patronen (`patterns/builtins.ts`, categorie "Pagina's"), zodat dezelfde opzet
|
|
13
|
+
* ook los te kiezen is bij "Nieuwe pagina".
|
|
14
|
+
*/
|
|
15
|
+
export interface StarterPagina {
|
|
16
|
+
title: string;
|
|
17
|
+
path: string;
|
|
18
|
+
/** Id van een paginapatroon. */
|
|
19
|
+
patroon: string;
|
|
20
|
+
/** Staat de pagina in het menu? (standaard ja) */
|
|
21
|
+
inMenu?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface Starter {
|
|
24
|
+
id: string;
|
|
25
|
+
label: string;
|
|
26
|
+
/** Voor wie, in één zin. */
|
|
27
|
+
voor: string;
|
|
28
|
+
icoon: string;
|
|
29
|
+
/** Id uit `theme/presets.ts`. */
|
|
30
|
+
preset: string;
|
|
31
|
+
/** schema.org-type voor het bedrijfsprofiel. */
|
|
32
|
+
bedrijfstype: string;
|
|
33
|
+
/** Modules die aan moeten (naast de standaard-aan modules). */
|
|
34
|
+
modules: string[];
|
|
35
|
+
paginas: StarterPagina[];
|
|
36
|
+
/** De knop rechtsboven in de kop. */
|
|
37
|
+
cta: {
|
|
38
|
+
label: string;
|
|
39
|
+
href: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export declare const STARTERS: Starter[];
|
|
43
|
+
export declare function vindStarter(id: string): Starter | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* De pagina's van een starter, klaar om op te slaan (verse blok-sleutels). Een patroon dat niet
|
|
46
|
+
* bestaat (oude starter, nieuwe core) wordt overgeslagen in plaats van een lege pagina te maken.
|
|
47
|
+
*/
|
|
48
|
+
export declare function starterPaginas(starter: Starter, patronen?: Pattern[]): {
|
|
49
|
+
title: string;
|
|
50
|
+
slug: string;
|
|
51
|
+
path: string;
|
|
52
|
+
inMenu: boolean;
|
|
53
|
+
blocks: Array<Record<string, unknown>>;
|
|
54
|
+
}[];
|
|
55
|
+
/** Alle bloktypes die de pagina's van een starter gebruiken (ook genest in kolommen). */
|
|
56
|
+
export declare function starterBloktypes(starter: Starter, patronen?: Pattern[]): Set<string>;
|
|
57
|
+
/**
|
|
58
|
+
* Welke modules moeten aan: die de starter noemt, plus elke module die een gebruikt blok levert
|
|
59
|
+
* (anders staat er op een startpagina een blok dat de site niet kent). Standaard-aan en kern-
|
|
60
|
+
* modules hoeven niet in de lijst.
|
|
61
|
+
*/
|
|
62
|
+
export declare function starterModules(starter: Starter, modules: {
|
|
63
|
+
id: string;
|
|
64
|
+
blocks?: {
|
|
65
|
+
type: string;
|
|
66
|
+
}[];
|
|
67
|
+
core?: boolean;
|
|
68
|
+
defaultEnabled?: boolean;
|
|
69
|
+
}[], patronen?: Pattern[]): string[];
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { builtinPatterns, collectPatternTypes, instantiatePattern } from "../patterns/index.js";
|
|
2
|
+
const STARTERS = [
|
|
3
|
+
{
|
|
4
|
+
id: "dienstverlener",
|
|
5
|
+
label: "Dienstverlener",
|
|
6
|
+
voor: "Hovenier, klusbedrijf, schilder, installateur, coach \u2014 diensten en een offerte-aanvraag.",
|
|
7
|
+
icoon: "\u{1F6E0}\uFE0F",
|
|
8
|
+
preset: "natuurlijk-groen",
|
|
9
|
+
bedrijfstype: "HomeAndConstructionBusiness",
|
|
10
|
+
modules: ["testimonials", "portfolio"],
|
|
11
|
+
cta: { label: "Offerte aanvragen", href: "/contact" },
|
|
12
|
+
paginas: [
|
|
13
|
+
{ title: "Home", path: "/", patroon: "page-landing" },
|
|
14
|
+
{ title: "Diensten", path: "/diensten", patroon: "page-services" },
|
|
15
|
+
{ title: "Werk", path: "/werk", patroon: "page-portfolio" },
|
|
16
|
+
{ title: "Over ons", path: "/over-ons", patroon: "page-about" },
|
|
17
|
+
{ title: "Contact", path: "/contact", patroon: "page-contact" }
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "salon",
|
|
22
|
+
label: "Kapper, barbier of salon",
|
|
23
|
+
voor: "Kapper, barbier, schoonheids- of nagelsalon \u2014 tarieven, team en online afspraken.",
|
|
24
|
+
icoon: "\u2702\uFE0F",
|
|
25
|
+
preset: "luxe-donker",
|
|
26
|
+
bedrijfstype: "HairSalon",
|
|
27
|
+
modules: ["testimonials", "team", "booking"],
|
|
28
|
+
cta: { label: "Afspraak maken", href: "/afspraak" },
|
|
29
|
+
paginas: [
|
|
30
|
+
{ title: "Home", path: "/", patroon: "page-landing" },
|
|
31
|
+
{ title: "Tarieven", path: "/tarieven", patroon: "page-tarieven" },
|
|
32
|
+
{ title: "Team", path: "/team", patroon: "page-team" },
|
|
33
|
+
{ title: "Afspraak maken", path: "/afspraak", patroon: "page-reserveren" },
|
|
34
|
+
{ title: "Contact", path: "/contact", patroon: "page-contact" }
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: "horeca",
|
|
39
|
+
label: "Restaurant of caf\xE9",
|
|
40
|
+
voor: "Restaurant, caf\xE9, lunchroom, bakkerij \u2014 menukaart, openingstijden en reserveren.",
|
|
41
|
+
icoon: "\u{1F37D}\uFE0F",
|
|
42
|
+
preset: "warm-uitnodigend",
|
|
43
|
+
bedrijfstype: "Restaurant",
|
|
44
|
+
modules: ["testimonials", "booking", "agenda"],
|
|
45
|
+
cta: { label: "Reserveren", href: "/reserveren" },
|
|
46
|
+
paginas: [
|
|
47
|
+
{ title: "Home", path: "/", patroon: "page-landing" },
|
|
48
|
+
{ title: "Menukaart", path: "/menukaart", patroon: "page-menukaart" },
|
|
49
|
+
{ title: "Reserveren", path: "/reserveren", patroon: "page-reserveren" },
|
|
50
|
+
{ title: "Over ons", path: "/over-ons", patroon: "page-about" },
|
|
51
|
+
{ title: "Contact", path: "/contact", patroon: "page-contact" }
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "winkel",
|
|
56
|
+
label: "Webwinkel",
|
|
57
|
+
voor: "Producten online verkopen, met afrekenen, verzenden of afhalen.",
|
|
58
|
+
icoon: "\u{1F6CD}\uFE0F",
|
|
59
|
+
preset: "modern-fris",
|
|
60
|
+
bedrijfstype: "Store",
|
|
61
|
+
modules: ["shop", "testimonials"],
|
|
62
|
+
cta: { label: "Bekijk de winkel", href: "/winkel" },
|
|
63
|
+
paginas: [
|
|
64
|
+
{ title: "Home", path: "/", patroon: "page-landing" },
|
|
65
|
+
{ title: "Over ons", path: "/over-ons", patroon: "page-about" },
|
|
66
|
+
{ title: "Contact", path: "/contact", patroon: "page-contact" }
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "verhuur",
|
|
71
|
+
label: "Vakantiehuis of B&B",
|
|
72
|
+
voor: "Vakantiewoning, B&B, camping, groepsaccommodatie \u2014 foto's, prijzen en boeken.",
|
|
73
|
+
icoon: "\u{1F3E1}",
|
|
74
|
+
preset: "elegant-klassiek",
|
|
75
|
+
bedrijfstype: "LodgingBusiness",
|
|
76
|
+
modules: ["testimonials", "booking"],
|
|
77
|
+
cta: { label: "Beschikbaarheid", href: "/verblijf" },
|
|
78
|
+
paginas: [
|
|
79
|
+
{ title: "Home", path: "/", patroon: "page-landing" },
|
|
80
|
+
{ title: "Het verblijf", path: "/verblijf", patroon: "page-verhuur" },
|
|
81
|
+
{ title: "Omgeving", path: "/omgeving", patroon: "page-about" },
|
|
82
|
+
{ title: "Contact", path: "/contact", patroon: "page-contact" }
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: "vereniging",
|
|
87
|
+
label: "Vereniging, kerk of stichting",
|
|
88
|
+
voor: "Vereniging, kerk, stichting, school \u2014 agenda, nieuws, wie we zijn en contact.",
|
|
89
|
+
icoon: "\u{1F91D}",
|
|
90
|
+
preset: "vriendelijk-afgerond",
|
|
91
|
+
bedrijfstype: "NGO",
|
|
92
|
+
modules: ["agenda", "team", "newsletter"],
|
|
93
|
+
cta: { label: "Word lid", href: "/contact" },
|
|
94
|
+
paginas: [
|
|
95
|
+
{ title: "Home", path: "/", patroon: "page-landing" },
|
|
96
|
+
{ title: "Agenda", path: "/agenda", patroon: "page-agenda" },
|
|
97
|
+
{ title: "Wie we zijn", path: "/wie-we-zijn", patroon: "page-team" },
|
|
98
|
+
{ title: "Contact", path: "/contact", patroon: "page-contact" }
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: "praktijk",
|
|
103
|
+
label: "Praktijk",
|
|
104
|
+
voor: "Fysiotherapie, huisarts, psycholoog, tandarts \u2014 behandelingen, team en afspraken.",
|
|
105
|
+
icoon: "\u{1FA7A}",
|
|
106
|
+
preset: "strak-zakelijk",
|
|
107
|
+
bedrijfstype: "MedicalBusiness",
|
|
108
|
+
modules: ["team", "booking", "testimonials"],
|
|
109
|
+
cta: { label: "Afspraak maken", href: "/afspraak" },
|
|
110
|
+
paginas: [
|
|
111
|
+
{ title: "Home", path: "/", patroon: "page-landing" },
|
|
112
|
+
{ title: "Behandelingen", path: "/behandelingen", patroon: "page-services" },
|
|
113
|
+
{ title: "Tarieven", path: "/tarieven", patroon: "page-tarieven" },
|
|
114
|
+
{ title: "Team", path: "/team", patroon: "page-team" },
|
|
115
|
+
{ title: "Afspraak maken", path: "/afspraak", patroon: "page-reserveren" },
|
|
116
|
+
{ title: "Contact", path: "/contact", patroon: "page-contact" }
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: "creatief",
|
|
121
|
+
label: "Fotograaf of creatief",
|
|
122
|
+
voor: "Fotograaf, ontwerper, architect, kunstenaar \u2014 werk tonen en opdrachten krijgen.",
|
|
123
|
+
icoon: "\u{1F4F7}",
|
|
124
|
+
preset: "minimalistisch",
|
|
125
|
+
bedrijfstype: "ProfessionalService",
|
|
126
|
+
modules: ["portfolio", "testimonials"],
|
|
127
|
+
cta: { label: "Neem contact op", href: "/contact" },
|
|
128
|
+
paginas: [
|
|
129
|
+
{ title: "Home", path: "/", patroon: "page-landing" },
|
|
130
|
+
{ title: "Werk", path: "/werk", patroon: "page-portfolio" },
|
|
131
|
+
{ title: "Over mij", path: "/over-mij", patroon: "page-about" },
|
|
132
|
+
{ title: "Contact", path: "/contact", patroon: "page-contact" }
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
];
|
|
136
|
+
function vindStarter(id) {
|
|
137
|
+
return STARTERS.find((s) => s.id === id);
|
|
138
|
+
}
|
|
139
|
+
function starterPaginas(starter, patronen = builtinPatterns) {
|
|
140
|
+
return starter.paginas.flatMap((p) => {
|
|
141
|
+
const patroon = patronen.find((x) => x.id === p.patroon);
|
|
142
|
+
if (!patroon) return [];
|
|
143
|
+
const slug = p.path === "/" ? "home" : p.path.split("/").pop() ?? "pagina";
|
|
144
|
+
return [{ title: p.title, slug, path: p.path, inMenu: p.inMenu !== false, blocks: instantiatePattern(patroon) }];
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function starterBloktypes(starter, patronen = builtinPatterns) {
|
|
148
|
+
const types = /* @__PURE__ */ new Set();
|
|
149
|
+
for (const p of starter.paginas) {
|
|
150
|
+
const patroon = patronen.find((x) => x.id === p.patroon);
|
|
151
|
+
if (patroon) for (const t of collectPatternTypes(patroon)) types.add(t);
|
|
152
|
+
}
|
|
153
|
+
return types;
|
|
154
|
+
}
|
|
155
|
+
function starterModules(starter, modules, patronen = builtinPatterns) {
|
|
156
|
+
const nodig = new Set(starter.modules);
|
|
157
|
+
const types = starterBloktypes(starter, patronen);
|
|
158
|
+
for (const m of modules) {
|
|
159
|
+
if (m.core || m.defaultEnabled !== false) continue;
|
|
160
|
+
if ((m.blocks ?? []).some((b) => types.has(b.type))) nodig.add(m.id);
|
|
161
|
+
}
|
|
162
|
+
return [...nodig].sort();
|
|
163
|
+
}
|
|
164
|
+
export {
|
|
165
|
+
STARTERS,
|
|
166
|
+
starterBloktypes,
|
|
167
|
+
starterModules,
|
|
168
|
+
starterPaginas,
|
|
169
|
+
vindStarter
|
|
170
|
+
};
|
|
171
|
+
//# sourceMappingURL=starters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/starters/starters.ts"],"sourcesContent":["import { builtinPatterns, collectPatternTypes, instantiatePattern, type Pattern } from \"../patterns\";\n\n/**\n * Branchestarters (8.14): een complete beginsite per soort bedrijf.\n *\n * Een nieuwe site begon leeg — \"Welkom bij X\" en een link naar /beheer — en elke klant kreeg\n * daarmee hetzelfde lege vel, of het nu een kapper, een restaurant of een vakantiehuis was. Een\n * starter zet in één keer: een passende huisstijl-preset, het soort bedrijf (voor Google), de\n * modules die dat type nodig heeft, en vier tot zes pagina's met de juiste blokken, als werkversie\n * om in te vullen. Gebruikt door `create-site --type` en door de knop \"Start met een kant-en-klare\n * opzet\" in /beheer → Pagina's (alleen bij een site zonder pagina's).\n *\n * De pagina's zijn patronen (`patterns/builtins.ts`, categorie \"Pagina's\"), zodat dezelfde opzet\n * ook los te kiezen is bij \"Nieuwe pagina\".\n */\nexport interface StarterPagina {\n title: string;\n path: string;\n /** Id van een paginapatroon. */\n patroon: string;\n /** Staat de pagina in het menu? (standaard ja) */\n inMenu?: boolean;\n}\n\nexport interface Starter {\n id: string;\n label: string;\n /** Voor wie, in één zin. */\n voor: string;\n icoon: string;\n /** Id uit `theme/presets.ts`. */\n preset: string;\n /** schema.org-type voor het bedrijfsprofiel. */\n bedrijfstype: string;\n /** Modules die aan moeten (naast de standaard-aan modules). */\n modules: string[];\n paginas: StarterPagina[];\n /** De knop rechtsboven in de kop. */\n cta: { label: string; href: string };\n}\n\nexport const STARTERS: Starter[] = [\n {\n id: \"dienstverlener\",\n label: \"Dienstverlener\",\n voor: \"Hovenier, klusbedrijf, schilder, installateur, coach — diensten en een offerte-aanvraag.\",\n icoon: \"🛠️\",\n preset: \"natuurlijk-groen\",\n bedrijfstype: \"HomeAndConstructionBusiness\",\n modules: [\"testimonials\", \"portfolio\"],\n cta: { label: \"Offerte aanvragen\", href: \"/contact\" },\n paginas: [\n { title: \"Home\", path: \"/\", patroon: \"page-landing\" },\n { title: \"Diensten\", path: \"/diensten\", patroon: \"page-services\" },\n { title: \"Werk\", path: \"/werk\", patroon: \"page-portfolio\" },\n { title: \"Over ons\", path: \"/over-ons\", patroon: \"page-about\" },\n { title: \"Contact\", path: \"/contact\", patroon: \"page-contact\" },\n ],\n },\n {\n id: \"salon\",\n label: \"Kapper, barbier of salon\",\n voor: \"Kapper, barbier, schoonheids- of nagelsalon — tarieven, team en online afspraken.\",\n icoon: \"✂️\",\n preset: \"luxe-donker\",\n bedrijfstype: \"HairSalon\",\n modules: [\"testimonials\", \"team\", \"booking\"],\n cta: { label: \"Afspraak maken\", href: \"/afspraak\" },\n paginas: [\n { title: \"Home\", path: \"/\", patroon: \"page-landing\" },\n { title: \"Tarieven\", path: \"/tarieven\", patroon: \"page-tarieven\" },\n { title: \"Team\", path: \"/team\", patroon: \"page-team\" },\n { title: \"Afspraak maken\", path: \"/afspraak\", patroon: \"page-reserveren\" },\n { title: \"Contact\", path: \"/contact\", patroon: \"page-contact\" },\n ],\n },\n {\n id: \"horeca\",\n label: \"Restaurant of café\",\n voor: \"Restaurant, café, lunchroom, bakkerij — menukaart, openingstijden en reserveren.\",\n icoon: \"🍽️\",\n preset: \"warm-uitnodigend\",\n bedrijfstype: \"Restaurant\",\n modules: [\"testimonials\", \"booking\", \"agenda\"],\n cta: { label: \"Reserveren\", href: \"/reserveren\" },\n paginas: [\n { title: \"Home\", path: \"/\", patroon: \"page-landing\" },\n { title: \"Menukaart\", path: \"/menukaart\", patroon: \"page-menukaart\" },\n { title: \"Reserveren\", path: \"/reserveren\", patroon: \"page-reserveren\" },\n { title: \"Over ons\", path: \"/over-ons\", patroon: \"page-about\" },\n { title: \"Contact\", path: \"/contact\", patroon: \"page-contact\" },\n ],\n },\n {\n id: \"winkel\",\n label: \"Webwinkel\",\n voor: \"Producten online verkopen, met afrekenen, verzenden of afhalen.\",\n icoon: \"🛍️\",\n preset: \"modern-fris\",\n bedrijfstype: \"Store\",\n modules: [\"shop\", \"testimonials\"],\n cta: { label: \"Bekijk de winkel\", href: \"/winkel\" },\n paginas: [\n { title: \"Home\", path: \"/\", patroon: \"page-landing\" },\n { title: \"Over ons\", path: \"/over-ons\", patroon: \"page-about\" },\n { title: \"Contact\", path: \"/contact\", patroon: \"page-contact\" },\n ],\n },\n {\n id: \"verhuur\",\n label: \"Vakantiehuis of B&B\",\n voor: \"Vakantiewoning, B&B, camping, groepsaccommodatie — foto's, prijzen en boeken.\",\n icoon: \"🏡\",\n preset: \"elegant-klassiek\",\n bedrijfstype: \"LodgingBusiness\",\n modules: [\"testimonials\", \"booking\"],\n cta: { label: \"Beschikbaarheid\", href: \"/verblijf\" },\n paginas: [\n { title: \"Home\", path: \"/\", patroon: \"page-landing\" },\n { title: \"Het verblijf\", path: \"/verblijf\", patroon: \"page-verhuur\" },\n { title: \"Omgeving\", path: \"/omgeving\", patroon: \"page-about\" },\n { title: \"Contact\", path: \"/contact\", patroon: \"page-contact\" },\n ],\n },\n {\n id: \"vereniging\",\n label: \"Vereniging, kerk of stichting\",\n voor: \"Vereniging, kerk, stichting, school — agenda, nieuws, wie we zijn en contact.\",\n icoon: \"🤝\",\n preset: \"vriendelijk-afgerond\",\n bedrijfstype: \"NGO\",\n modules: [\"agenda\", \"team\", \"newsletter\"],\n cta: { label: \"Word lid\", href: \"/contact\" },\n paginas: [\n { title: \"Home\", path: \"/\", patroon: \"page-landing\" },\n { title: \"Agenda\", path: \"/agenda\", patroon: \"page-agenda\" },\n { title: \"Wie we zijn\", path: \"/wie-we-zijn\", patroon: \"page-team\" },\n { title: \"Contact\", path: \"/contact\", patroon: \"page-contact\" },\n ],\n },\n {\n id: \"praktijk\",\n label: \"Praktijk\",\n voor: \"Fysiotherapie, huisarts, psycholoog, tandarts — behandelingen, team en afspraken.\",\n icoon: \"🩺\",\n preset: \"strak-zakelijk\",\n bedrijfstype: \"MedicalBusiness\",\n modules: [\"team\", \"booking\", \"testimonials\"],\n cta: { label: \"Afspraak maken\", href: \"/afspraak\" },\n paginas: [\n { title: \"Home\", path: \"/\", patroon: \"page-landing\" },\n { title: \"Behandelingen\", path: \"/behandelingen\", patroon: \"page-services\" },\n { title: \"Tarieven\", path: \"/tarieven\", patroon: \"page-tarieven\" },\n { title: \"Team\", path: \"/team\", patroon: \"page-team\" },\n { title: \"Afspraak maken\", path: \"/afspraak\", patroon: \"page-reserveren\" },\n { title: \"Contact\", path: \"/contact\", patroon: \"page-contact\" },\n ],\n },\n {\n id: \"creatief\",\n label: \"Fotograaf of creatief\",\n voor: \"Fotograaf, ontwerper, architect, kunstenaar — werk tonen en opdrachten krijgen.\",\n icoon: \"📷\",\n preset: \"minimalistisch\",\n bedrijfstype: \"ProfessionalService\",\n modules: [\"portfolio\", \"testimonials\"],\n cta: { label: \"Neem contact op\", href: \"/contact\" },\n paginas: [\n { title: \"Home\", path: \"/\", patroon: \"page-landing\" },\n { title: \"Werk\", path: \"/werk\", patroon: \"page-portfolio\" },\n { title: \"Over mij\", path: \"/over-mij\", patroon: \"page-about\" },\n { title: \"Contact\", path: \"/contact\", patroon: \"page-contact\" },\n ],\n },\n];\n\nexport function vindStarter(id: string): Starter | undefined {\n return STARTERS.find((s) => s.id === id);\n}\n\n/**\n * De pagina's van een starter, klaar om op te slaan (verse blok-sleutels). Een patroon dat niet\n * bestaat (oude starter, nieuwe core) wordt overgeslagen in plaats van een lege pagina te maken.\n */\nexport function starterPaginas(\n starter: Starter,\n patronen: Pattern[] = builtinPatterns,\n): { title: string; slug: string; path: string; inMenu: boolean; blocks: Array<Record<string, unknown>> }[] {\n return starter.paginas.flatMap((p) => {\n const patroon = patronen.find((x) => x.id === p.patroon);\n if (!patroon) return [];\n const slug = p.path === \"/\" ? \"home\" : (p.path.split(\"/\").pop() ?? \"pagina\");\n return [{ title: p.title, slug, path: p.path, inMenu: p.inMenu !== false, blocks: instantiatePattern(patroon) }];\n });\n}\n\n/** Alle bloktypes die de pagina's van een starter gebruiken (ook genest in kolommen). */\nexport function starterBloktypes(starter: Starter, patronen: Pattern[] = builtinPatterns): Set<string> {\n const types = new Set<string>();\n for (const p of starter.paginas) {\n const patroon = patronen.find((x) => x.id === p.patroon);\n if (patroon) for (const t of collectPatternTypes(patroon)) types.add(t);\n }\n return types;\n}\n\n/**\n * Welke modules moeten aan: die de starter noemt, plus elke module die een gebruikt blok levert\n * (anders staat er op een startpagina een blok dat de site niet kent). Standaard-aan en kern-\n * modules hoeven niet in de lijst.\n */\nexport function starterModules(\n starter: Starter,\n modules: { id: string; blocks?: { type: string }[]; core?: boolean; defaultEnabled?: boolean }[],\n patronen: Pattern[] = builtinPatterns,\n): string[] {\n const nodig = new Set(starter.modules);\n const types = starterBloktypes(starter, patronen);\n for (const m of modules) {\n if (m.core || m.defaultEnabled !== false) continue;\n if ((m.blocks ?? []).some((b) => types.has(b.type))) nodig.add(m.id);\n }\n return [...nodig].sort();\n}\n"],"mappings":"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","names":[]}
|