@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.
Files changed (482) hide show
  1. package/dist/XiCMSProvider.js +23 -7
  2. package/dist/XiCMSProvider.js.map +1 -1
  3. package/dist/admin/AdminApp.js +175 -93
  4. package/dist/admin/AdminApp.js.map +1 -1
  5. package/dist/admin/AdminHelp.d.ts +1 -1
  6. package/dist/admin/AdminHelp.js +44 -36
  7. package/dist/admin/AdminHelp.js.map +1 -1
  8. package/dist/admin/CoreVersion.d.ts +6 -3
  9. package/dist/admin/CoreVersion.js +60 -24
  10. package/dist/admin/CoreVersion.js.map +1 -1
  11. package/dist/admin/NewsEditor.d.ts +7 -0
  12. package/dist/admin/NewsEditor.js +117 -75
  13. package/dist/admin/NewsEditor.js.map +1 -1
  14. package/dist/admin/SuperadminPanel.js +1 -1
  15. package/dist/admin/SuperadminPanel.js.map +1 -1
  16. package/dist/admin/ZoekPalet.d.ts +15 -0
  17. package/dist/admin/ZoekPalet.js +123 -0
  18. package/dist/admin/ZoekPalet.js.map +1 -0
  19. package/dist/admin/blockEditors/GenericEditor.js +36 -18
  20. package/dist/admin/blockEditors/GenericEditor.js.map +1 -1
  21. package/dist/admin/blockEditors/StyleEditor.js +37 -3
  22. package/dist/admin/blockEditors/StyleEditor.js.map +1 -1
  23. package/dist/admin/blockEditors/SymbolRefEditor.js +44 -2
  24. package/dist/admin/blockEditors/SymbolRefEditor.js.map +1 -1
  25. package/dist/admin/blockEditors/index.js +154 -73
  26. package/dist/admin/blockEditors/index.js.map +1 -1
  27. package/dist/admin/customBlocks/CustomBlocksPanel.js +18 -7
  28. package/dist/admin/customBlocks/CustomBlocksPanel.js.map +1 -1
  29. package/dist/admin/dashboard/DashboardPanel.js +26 -16
  30. package/dist/admin/dashboard/DashboardPanel.js.map +1 -1
  31. package/dist/admin/editors/RichTextEditor.d.ts +4 -3
  32. package/dist/admin/editors/RichTextEditor.js +19 -60
  33. package/dist/admin/editors/RichTextEditor.js.map +1 -1
  34. package/dist/admin/editors/fontSizeExtension.js +7 -1
  35. package/dist/admin/editors/fontSizeExtension.js.map +1 -1
  36. package/dist/admin/editors/slashMenu.d.ts +18 -0
  37. package/dist/admin/editors/slashMenu.js +34 -0
  38. package/dist/admin/editors/slashMenu.js.map +1 -0
  39. package/dist/admin/editors/useRijkeTekst.d.ts +48 -0
  40. package/dist/admin/editors/useRijkeTekst.js +310 -0
  41. package/dist/admin/editors/useRijkeTekst.js.map +1 -0
  42. package/dist/admin/forms/FormsPanel.d.ts +11 -2
  43. package/dist/admin/forms/FormsPanel.js +218 -65
  44. package/dist/admin/forms/FormsPanel.js.map +1 -1
  45. package/dist/admin/lib/blokInfo.d.ts +17 -0
  46. package/dist/admin/lib/blokInfo.js +80 -0
  47. package/dist/admin/lib/blokInfo.js.map +1 -0
  48. package/dist/admin/lib/foutNaarMens.d.ts +1 -0
  49. package/dist/admin/lib/foutNaarMens.js +22 -0
  50. package/dist/admin/lib/foutNaarMens.js.map +1 -0
  51. package/dist/admin/lib/gewisteVelden.d.ts +13 -0
  52. package/dist/admin/lib/gewisteVelden.js +31 -0
  53. package/dist/admin/lib/gewisteVelden.js.map +1 -0
  54. package/dist/admin/lib/heroHulp.d.ts +11 -0
  55. package/dist/admin/lib/heroHulp.js +18 -0
  56. package/dist/admin/lib/heroHulp.js.map +1 -0
  57. package/dist/admin/lib/kleur.js +2 -3
  58. package/dist/admin/lib/kleur.js.map +1 -1
  59. package/dist/admin/lib/leesbaarheid.d.ts +34 -0
  60. package/dist/admin/lib/leesbaarheid.js +82 -0
  61. package/dist/admin/lib/leesbaarheid.js.map +1 -0
  62. package/dist/admin/lib/lengteAdvies.d.ts +1 -0
  63. package/dist/admin/lib/lengteAdvies.js +16 -0
  64. package/dist/admin/lib/lengteAdvies.js.map +1 -0
  65. package/dist/admin/lib/mediaLijst.d.ts +26 -0
  66. package/dist/admin/lib/mediaLijst.js +42 -0
  67. package/dist/admin/lib/mediaLijst.js.map +1 -0
  68. package/dist/admin/lib/mediaUsage.d.ts +12 -1
  69. package/dist/admin/lib/mediaUsage.js +43 -33
  70. package/dist/admin/lib/mediaUsage.js.map +1 -1
  71. package/dist/admin/lib/menuHulp.d.ts +16 -0
  72. package/dist/admin/lib/menuHulp.js +41 -0
  73. package/dist/admin/lib/menuHulp.js.map +1 -0
  74. package/dist/admin/lib/onopgeslagen.d.ts +10 -0
  75. package/dist/admin/lib/onopgeslagen.js +35 -0
  76. package/dist/admin/lib/onopgeslagen.js.map +1 -0
  77. package/dist/admin/lib/pagesClient.d.ts +55 -2
  78. package/dist/admin/lib/pagesClient.js +126 -28
  79. package/dist/admin/lib/pagesClient.js.map +1 -1
  80. package/dist/admin/lib/paginaGebruik.d.ts +56 -0
  81. package/dist/admin/lib/paginaGebruik.js +109 -0
  82. package/dist/admin/lib/paginaGebruik.js.map +1 -0
  83. package/dist/admin/lib/publicatieCheck.d.ts +25 -0
  84. package/dist/admin/lib/publicatieCheck.js +114 -0
  85. package/dist/admin/lib/publicatieCheck.js.map +1 -0
  86. package/dist/admin/lib/scrollNaarDetail.d.ts +6 -0
  87. package/dist/admin/lib/scrollNaarDetail.js +20 -0
  88. package/dist/admin/lib/scrollNaarDetail.js.map +1 -0
  89. package/dist/admin/lib/symbolsClient.d.ts +10 -0
  90. package/dist/admin/lib/symbolsClient.js +14 -1
  91. package/dist/admin/lib/symbolsClient.js.map +1 -1
  92. package/dist/admin/lib/tekstVeld.d.ts +8 -0
  93. package/dist/admin/lib/tekstVeld.js +10 -0
  94. package/dist/admin/lib/tekstVeld.js.map +1 -0
  95. package/dist/admin/lib/useIsSuperadmin.d.ts +2 -0
  96. package/dist/admin/lib/useIsSuperadmin.js +13 -0
  97. package/dist/admin/lib/useIsSuperadmin.js.map +1 -0
  98. package/dist/admin/lib/veldTaal.d.ts +14 -0
  99. package/dist/admin/lib/veldTaal.js +248 -0
  100. package/dist/admin/lib/veldTaal.js.map +1 -0
  101. package/dist/admin/lib/versieVergelijk.d.ts +17 -0
  102. package/dist/admin/lib/versieVergelijk.js +24 -0
  103. package/dist/admin/lib/versieVergelijk.js.map +1 -0
  104. package/dist/admin/lib/zodFields.js +22 -4
  105. package/dist/admin/lib/zodFields.js.map +1 -1
  106. package/dist/admin/lib/zodFout.d.ts +9 -0
  107. package/dist/admin/lib/zodFout.js +63 -0
  108. package/dist/admin/lib/zodFout.js.map +1 -0
  109. package/dist/admin/media/MediaManager.js +162 -32
  110. package/dist/admin/media/MediaManager.js.map +1 -1
  111. package/dist/admin/media/MediaPicker.d.ts +3 -0
  112. package/dist/admin/media/MediaPicker.js +84 -31
  113. package/dist/admin/media/MediaPicker.js.map +1 -1
  114. package/dist/admin/menu/MenuPanel.js +144 -83
  115. package/dist/admin/menu/MenuPanel.js.map +1 -1
  116. package/dist/admin/navContext.d.ts +3 -0
  117. package/dist/admin/navContext.js +13 -1
  118. package/dist/admin/navContext.js.map +1 -1
  119. package/dist/admin/pages/PageEditor.js +146 -30
  120. package/dist/admin/pages/PageEditor.js.map +1 -1
  121. package/dist/admin/pages/PagesPanel.js +215 -61
  122. package/dist/admin/pages/PagesPanel.js.map +1 -1
  123. package/dist/admin/pages/StarterKiezer.d.ts +12 -0
  124. package/dist/admin/pages/StarterKiezer.js +113 -0
  125. package/dist/admin/pages/StarterKiezer.js.map +1 -0
  126. package/dist/admin/panelRegistry.d.ts +1 -1
  127. package/dist/admin/panelRegistry.js +2 -1
  128. package/dist/admin/panelRegistry.js.map +1 -1
  129. package/dist/admin/patterns/PatternInserter.js +1 -1
  130. package/dist/admin/patterns/PatternInserter.js.map +1 -1
  131. package/dist/admin/settings/BedrijfInstellingen.d.ts +20 -0
  132. package/dist/admin/settings/BedrijfInstellingen.js +159 -0
  133. package/dist/admin/settings/BedrijfInstellingen.js.map +1 -0
  134. package/dist/admin/settings/MailTemplates.js +5 -4
  135. package/dist/admin/settings/MailTemplates.js.map +1 -1
  136. package/dist/admin/settings/SettingsPanel.js +120 -78
  137. package/dist/admin/settings/SettingsPanel.js.map +1 -1
  138. package/dist/admin/settings/SnapshotsCard.js +4 -4
  139. package/dist/admin/settings/SnapshotsCard.js.map +1 -1
  140. package/dist/admin/settings/VorigeTerugzetten.d.ts +15 -0
  141. package/dist/admin/settings/VorigeTerugzetten.js +89 -0
  142. package/dist/admin/settings/VorigeTerugzetten.js.map +1 -0
  143. package/dist/admin/shop/CategoriesTab.js +6 -4
  144. package/dist/admin/shop/CategoriesTab.js.map +1 -1
  145. package/dist/admin/shop/DiscountsTab.js +4 -2
  146. package/dist/admin/shop/DiscountsTab.js.map +1 -1
  147. package/dist/admin/shop/OrdersTab.js +57 -19
  148. package/dist/admin/shop/OrdersTab.js.map +1 -1
  149. package/dist/admin/shop/ProductPaneel.js +2 -1
  150. package/dist/admin/shop/ProductPaneel.js.map +1 -1
  151. package/dist/admin/shop/ProductsTab.js +40 -19
  152. package/dist/admin/shop/ProductsTab.js.map +1 -1
  153. package/dist/admin/shop/ShopPanel.js +13 -1
  154. package/dist/admin/shop/ShopPanel.js.map +1 -1
  155. package/dist/admin/shop/ShopSettingsTab.js +56 -17
  156. package/dist/admin/shop/ShopSettingsTab.js.map +1 -1
  157. package/dist/admin/shop/productClient.js +7 -3
  158. package/dist/admin/shop/productClient.js.map +1 -1
  159. package/dist/admin/stats/NietGevonden.d.ts +10 -0
  160. package/dist/admin/stats/NietGevonden.js +78 -0
  161. package/dist/admin/stats/NietGevonden.js.map +1 -0
  162. package/dist/admin/stats/StatsPanel.js +6 -1
  163. package/dist/admin/stats/StatsPanel.js.map +1 -1
  164. package/dist/admin/stats/lib.d.ts +2 -0
  165. package/dist/admin/stats/lib.js.map +1 -1
  166. package/dist/admin/ui/ConfirmDialog.js +10 -1
  167. package/dist/admin/ui/ConfirmDialog.js.map +1 -1
  168. package/dist/admin/ui/Icon.d.ts +34 -0
  169. package/dist/admin/ui/Icon.js +44 -0
  170. package/dist/admin/ui/Icon.js.map +1 -0
  171. package/dist/admin/ui/ImageField.d.ts +15 -0
  172. package/dist/admin/ui/ImageField.js +67 -0
  173. package/dist/admin/ui/ImageField.js.map +1 -0
  174. package/dist/admin/ui/KleurVeld.d.ts +25 -0
  175. package/dist/admin/ui/KleurVeld.js +76 -0
  176. package/dist/admin/ui/KleurVeld.js.map +1 -0
  177. package/dist/admin/ui/LaadStaat.d.ts +21 -0
  178. package/dist/admin/ui/LaadStaat.js +43 -0
  179. package/dist/admin/ui/LaadStaat.js.map +1 -0
  180. package/dist/admin/ui/LeesbaarheidPaneel.d.ts +10 -0
  181. package/dist/admin/ui/LeesbaarheidPaneel.js +68 -0
  182. package/dist/admin/ui/LeesbaarheidPaneel.js.map +1 -0
  183. package/dist/admin/ui/LinkDialog.d.ts +22 -0
  184. package/dist/admin/ui/LinkDialog.js +131 -0
  185. package/dist/admin/ui/LinkDialog.js.map +1 -0
  186. package/dist/admin/ui/LinkVeld.d.ts +14 -0
  187. package/dist/admin/ui/LinkVeld.js +49 -0
  188. package/dist/admin/ui/LinkVeld.js.map +1 -0
  189. package/dist/admin/ui/PreviewLinkResultaat.d.ts +14 -0
  190. package/dist/admin/ui/PreviewLinkResultaat.js +52 -0
  191. package/dist/admin/ui/PreviewLinkResultaat.js.map +1 -0
  192. package/dist/admin/ui/charts.js +5 -5
  193. package/dist/admin/ui/charts.js.map +1 -1
  194. package/dist/admin/ui/primitives.d.ts +16 -6
  195. package/dist/admin/ui/primitives.js +98 -26
  196. package/dist/admin/ui/primitives.js.map +1 -1
  197. package/dist/admin/ui/select.js +5 -2
  198. package/dist/admin/ui/select.js.map +1 -1
  199. package/dist/admin/ui/switch.d.ts +3 -1
  200. package/dist/admin/ui/switch.js +6 -3
  201. package/dist/admin/ui/switch.js.map +1 -1
  202. package/dist/admin/ui/toast.d.ts +2 -1
  203. package/dist/admin/ui/toast.js +17 -11
  204. package/dist/admin/ui/toast.js.map +1 -1
  205. package/dist/admin/visual/BlokKiezer.d.ts +34 -0
  206. package/dist/admin/visual/BlokKiezer.js +225 -0
  207. package/dist/admin/visual/BlokKiezer.js.map +1 -0
  208. package/dist/admin/visual/InlineGereedschap.d.ts +52 -0
  209. package/dist/admin/visual/InlineGereedschap.js +356 -0
  210. package/dist/admin/visual/InlineGereedschap.js.map +1 -0
  211. package/dist/admin/visual/InlineRijkeTekst.d.ts +23 -0
  212. package/dist/admin/visual/InlineRijkeTekst.js +152 -0
  213. package/dist/admin/visual/InlineRijkeTekst.js.map +1 -0
  214. package/dist/admin/visual/VisualEditor.js +273 -125
  215. package/dist/admin/visual/VisualEditor.js.map +1 -1
  216. package/dist/admin.css +1 -1
  217. package/dist/auth/AuthProvider.js +1 -0
  218. package/dist/auth/AuthProvider.js.map +1 -1
  219. package/dist/bedrijf/bedrijf.d.ts +44 -0
  220. package/dist/bedrijf/bedrijf.js +125 -0
  221. package/dist/bedrijf/bedrijf.js.map +1 -0
  222. package/dist/blocks/BlockRenderer.js +11 -1
  223. package/dist/blocks/BlockRenderer.js.map +1 -1
  224. package/dist/blocks/blockStyle.d.ts +7 -0
  225. package/dist/blocks/blockStyle.js +16 -3
  226. package/dist/blocks/blockStyle.js.map +1 -1
  227. package/dist/blocks/builtinSchemas.js +6 -0
  228. package/dist/blocks/builtinSchemas.js.map +1 -1
  229. package/dist/blocks/builtins/AgendaRender.d.ts +22 -0
  230. package/dist/blocks/builtins/AgendaRender.js +69 -9
  231. package/dist/blocks/builtins/AgendaRender.js.map +1 -1
  232. package/dist/blocks/builtins/Availability.d.ts +1 -0
  233. package/dist/blocks/builtins/Availability.js +23 -0
  234. package/dist/blocks/builtins/Availability.js.map +1 -0
  235. package/dist/blocks/builtins/AvailabilityRender.d.ts +12 -0
  236. package/dist/blocks/builtins/AvailabilityRender.js +105 -0
  237. package/dist/blocks/builtins/AvailabilityRender.js.map +1 -0
  238. package/dist/blocks/builtins/BeforeAfterRender.js +4 -3
  239. package/dist/blocks/builtins/BeforeAfterRender.js.map +1 -1
  240. package/dist/blocks/builtins/Booking.js +1 -1
  241. package/dist/blocks/builtins/Booking.js.map +1 -1
  242. package/dist/blocks/builtins/BreadcrumbsRender.d.ts +4 -3
  243. package/dist/blocks/builtins/BreadcrumbsRender.js +14 -8
  244. package/dist/blocks/builtins/BreadcrumbsRender.js.map +1 -1
  245. package/dist/blocks/builtins/ColumnsRender.d.ts +1 -1
  246. package/dist/blocks/builtins/ColumnsRender.js +3 -1
  247. package/dist/blocks/builtins/ColumnsRender.js.map +1 -1
  248. package/dist/blocks/builtins/Contact.js +1 -1
  249. package/dist/blocks/builtins/Contact.js.map +1 -1
  250. package/dist/blocks/builtins/ContactRender.d.ts +1 -1
  251. package/dist/blocks/builtins/ContactRender.js +37 -8
  252. package/dist/blocks/builtins/ContactRender.js.map +1 -1
  253. package/dist/blocks/builtins/Cta.js +1 -1
  254. package/dist/blocks/builtins/Cta.js.map +1 -1
  255. package/dist/blocks/builtins/CtaRender.d.ts +1 -1
  256. package/dist/blocks/builtins/CtaRender.js +5 -4
  257. package/dist/blocks/builtins/CtaRender.js.map +1 -1
  258. package/dist/blocks/builtins/Embed.js +1 -1
  259. package/dist/blocks/builtins/Embed.js.map +1 -1
  260. package/dist/blocks/builtins/FormBlock.js +1 -0
  261. package/dist/blocks/builtins/FormBlock.js.map +1 -1
  262. package/dist/blocks/builtins/FormBlockRender.d.ts +6 -0
  263. package/dist/blocks/builtins/FormBlockRender.js +88 -16
  264. package/dist/blocks/builtins/FormBlockRender.js.map +1 -1
  265. package/dist/blocks/builtins/GalleryRender.js +3 -2
  266. package/dist/blocks/builtins/GalleryRender.js.map +1 -1
  267. package/dist/blocks/builtins/Hero.js +1 -1
  268. package/dist/blocks/builtins/Hero.js.map +1 -1
  269. package/dist/blocks/builtins/HeroRender.js +7 -3
  270. package/dist/blocks/builtins/HeroRender.js.map +1 -1
  271. package/dist/blocks/builtins/OpenNowBadge.d.ts +4 -2
  272. package/dist/blocks/builtins/OpenNowBadge.js +6 -6
  273. package/dist/blocks/builtins/OpenNowBadge.js.map +1 -1
  274. package/dist/blocks/builtins/OpeningHoursRender.d.ts +8 -2
  275. package/dist/blocks/builtins/OpeningHoursRender.js +27 -6
  276. package/dist/blocks/builtins/OpeningHoursRender.js.map +1 -1
  277. package/dist/blocks/builtins/PriceList.d.ts +1 -0
  278. package/dist/blocks/builtins/PriceList.js +25 -0
  279. package/dist/blocks/builtins/PriceList.js.map +1 -0
  280. package/dist/blocks/builtins/PriceListRender.d.ts +17 -0
  281. package/dist/blocks/builtins/PriceListRender.js +87 -0
  282. package/dist/blocks/builtins/PriceListRender.js.map +1 -0
  283. package/dist/blocks/builtins/RichTextBlockRender.js +6 -1
  284. package/dist/blocks/builtins/RichTextBlockRender.js.map +1 -1
  285. package/dist/blocks/builtins/SectionHeading.d.ts +1 -0
  286. package/dist/blocks/builtins/SectionHeading.js +14 -0
  287. package/dist/blocks/builtins/SectionHeading.js.map +1 -0
  288. package/dist/blocks/builtins/SectionHeadingRender.d.ts +7 -0
  289. package/dist/blocks/builtins/SectionHeadingRender.js +14 -0
  290. package/dist/blocks/builtins/SectionHeadingRender.js.map +1 -0
  291. package/dist/blocks/builtins/SliderRender.js +3 -2
  292. package/dist/blocks/builtins/SliderRender.js.map +1 -1
  293. package/dist/blocks/builtins/SymbolRef.js +1 -1
  294. package/dist/blocks/builtins/SymbolRef.js.map +1 -1
  295. package/dist/blocks/builtins/TeamRender.js +6 -1
  296. package/dist/blocks/builtins/TeamRender.js.map +1 -1
  297. package/dist/blocks/builtins/Testimonials.js +3 -1
  298. package/dist/blocks/builtins/Testimonials.js.map +1 -1
  299. package/dist/blocks/builtins/TestimonialsRender.js +4 -0
  300. package/dist/blocks/builtins/TestimonialsRender.js.map +1 -1
  301. package/dist/blocks/builtins/WhatsappChatRender.d.ts +1 -1
  302. package/dist/blocks/builtins/WhatsappChatRender.js +3 -1
  303. package/dist/blocks/builtins/WhatsappChatRender.js.map +1 -1
  304. package/dist/blocks/builtins/Widgets.js +2 -2
  305. package/dist/blocks/builtins/Widgets.js.map +1 -1
  306. package/dist/blocks/builtins/WidgetsRender.js +3 -1
  307. package/dist/blocks/builtins/WidgetsRender.js.map +1 -1
  308. package/dist/blocks/builtins/consentEmbed.js +26 -9
  309. package/dist/blocks/builtins/consentEmbed.js.map +1 -1
  310. package/dist/blocks/builtins/index.d.ts +3 -0
  311. package/dist/blocks/builtins/index.js +6 -0
  312. package/dist/blocks/builtins/index.js.map +1 -1
  313. package/dist/blocks/builtins/lib/autoComplete.d.ts +7 -0
  314. package/dist/blocks/builtins/lib/autoComplete.js +20 -0
  315. package/dist/blocks/builtins/lib/autoComplete.js.map +1 -0
  316. package/dist/blocks/builtins/lib/bookingUrl.d.ts +2 -2
  317. package/dist/blocks/builtins/lib/bookingUrl.js +1 -1
  318. package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -1
  319. package/dist/blocks/builtins/lib/ical.d.ts +24 -0
  320. package/dist/blocks/builtins/lib/ical.js +82 -0
  321. package/dist/blocks/builtins/lib/ical.js.map +1 -0
  322. package/dist/blocks/builtins/lib/vandaag.d.ts +8 -0
  323. package/dist/blocks/builtins/lib/vandaag.js +22 -0
  324. package/dist/blocks/builtins/lib/vandaag.js.map +1 -0
  325. package/dist/blocks/registry.d.ts +6 -0
  326. package/dist/blocks/registry.js.map +1 -1
  327. package/dist/blocks/ui/index.js +1 -0
  328. package/dist/blocks/ui/index.js.map +1 -1
  329. package/dist/components/EditBar.js +2 -4
  330. package/dist/components/EditBar.js.map +1 -1
  331. package/dist/components/News.js +26 -18
  332. package/dist/components/News.js.map +1 -1
  333. package/dist/components/PageView.d.ts +7 -1
  334. package/dist/components/PageView.js +17 -0
  335. package/dist/components/PageView.js.map +1 -1
  336. package/dist/components/ResponsiveImage.js +18 -20
  337. package/dist/components/ResponsiveImage.js.map +1 -1
  338. package/dist/components/onderOffset.d.ts +13 -0
  339. package/dist/components/onderOffset.js +74 -0
  340. package/dist/components/onderOffset.js.map +1 -0
  341. package/dist/components/site/Bedrijfsnummers.d.ts +9 -0
  342. package/dist/components/site/Bedrijfsnummers.js +12 -0
  343. package/dist/components/site/Bedrijfsnummers.js.map +1 -0
  344. package/dist/components/site/SiteFooter.d.ts +6 -1
  345. package/dist/components/site/SiteFooter.js +62 -9
  346. package/dist/components/site/SiteFooter.js.map +1 -1
  347. package/dist/components/site/SiteHeader.d.ts +15 -0
  348. package/dist/components/site/SiteHeader.js +70 -0
  349. package/dist/components/site/SiteHeader.js.map +1 -0
  350. package/dist/components/site/SiteNav.d.ts +2 -0
  351. package/dist/components/site/SiteNav.js +29 -5
  352. package/dist/components/site/SiteNav.js.map +1 -1
  353. package/dist/demo/DemoStudio.js +2 -2
  354. package/dist/demo/DemoStudio.js.map +1 -1
  355. package/dist/demo/demoStore.d.ts +13 -0
  356. package/dist/demo/demoStore.js +36 -0
  357. package/dist/demo/demoStore.js.map +1 -1
  358. package/dist/editor/EditorProvider.js +15 -4
  359. package/dist/editor/EditorProvider.js.map +1 -1
  360. package/dist/firebase/functionsClient.js +5 -1
  361. package/dist/firebase/functionsClient.js.map +1 -1
  362. package/dist/index.d.ts +5 -1
  363. package/dist/index.js +20 -1
  364. package/dist/index.js.map +1 -1
  365. package/dist/media/ImageContext.d.ts +17 -0
  366. package/dist/media/ImageContext.js +65 -20
  367. package/dist/media/ImageContext.js.map +1 -1
  368. package/dist/media/altInHtml.d.ts +9 -0
  369. package/dist/media/altInHtml.js +17 -0
  370. package/dist/media/altInHtml.js.map +1 -0
  371. package/dist/media/srcset.d.ts +12 -0
  372. package/dist/media/srcset.js +13 -0
  373. package/dist/media/srcset.js.map +1 -0
  374. package/dist/modules/builtins.d.ts +1 -0
  375. package/dist/modules/builtins.js +22 -9
  376. package/dist/modules/builtins.js.map +1 -1
  377. package/dist/modules/consent/ConsentBanner.d.ts +5 -0
  378. package/dist/modules/consent/ConsentBanner.js +8 -7
  379. package/dist/modules/consent/ConsentBanner.js.map +1 -1
  380. package/dist/modules/consent/standaard.d.ts +12 -0
  381. package/dist/modules/consent/standaard.js +10 -0
  382. package/dist/modules/consent/standaard.js.map +1 -0
  383. package/dist/modules/consent/useConsent.d.ts +4 -0
  384. package/dist/modules/consent/useConsent.js +30 -1
  385. package/dist/modules/consent/useConsent.js.map +1 -1
  386. package/dist/modules/shop/blocks/Cart.js +5 -3
  387. package/dist/modules/shop/blocks/Cart.js.map +1 -1
  388. package/dist/modules/shop/blocks/Checkout.js +56 -35
  389. package/dist/modules/shop/blocks/Checkout.js.map +1 -1
  390. package/dist/modules/shop/blocks/Donation.js +4 -4
  391. package/dist/modules/shop/blocks/Donation.js.map +1 -1
  392. package/dist/modules/shop/blocks/ProductDetail.js +19 -3
  393. package/dist/modules/shop/blocks/ProductDetail.js.map +1 -1
  394. package/dist/modules/shop/blocks/ProductGrid.d.ts +3 -1
  395. package/dist/modules/shop/blocks/ProductGrid.js +8 -4
  396. package/dist/modules/shop/blocks/ProductGrid.js.map +1 -1
  397. package/dist/modules/shop/blocks/ShopCategories.js +4 -3
  398. package/dist/modules/shop/blocks/ShopCategories.js.map +1 -1
  399. package/dist/modules/shop/lib.d.ts +4 -0
  400. package/dist/modules/shop/lib.js +14 -0
  401. package/dist/modules/shop/lib.js.map +1 -1
  402. package/dist/modules/shop/settings.d.ts +3 -0
  403. package/dist/modules/shop/settings.js +14 -0
  404. package/dist/modules/shop/settings.js.map +1 -1
  405. package/dist/modules/shop/strings.d.ts +4 -0
  406. package/dist/modules/shop/strings.js +8 -0
  407. package/dist/modules/shop/strings.js.map +1 -1
  408. package/dist/next/envCheck.d.ts +42 -0
  409. package/dist/next/envCheck.js +106 -0
  410. package/dist/next/envCheck.js.map +1 -0
  411. package/dist/next/index.cjs +185 -2
  412. package/dist/next/index.d.ts +2 -0
  413. package/dist/next/index.js +8 -1
  414. package/dist/next/index.js.map +1 -1
  415. package/dist/next/securityHeaders.d.ts +36 -0
  416. package/dist/next/securityHeaders.js +74 -0
  417. package/dist/next/securityHeaders.js.map +1 -0
  418. package/dist/patterns/builtins.d.ts +7 -0
  419. package/dist/patterns/builtins.js +138 -3
  420. package/dist/patterns/builtins.js.map +1 -1
  421. package/dist/releaseNotes.js +148 -0
  422. package/dist/releaseNotes.js.map +1 -1
  423. package/dist/render/PublishedPage.d.ts +2 -1
  424. package/dist/render/PublishedPage.js +10 -4
  425. package/dist/render/PublishedPage.js.map +1 -1
  426. package/dist/schema/blocks.d.ts +473 -0
  427. package/dist/schema/blocks.js +105 -5
  428. package/dist/schema/blocks.js.map +1 -1
  429. package/dist/schema/business.d.ts +118 -0
  430. package/dist/schema/business.js +75 -0
  431. package/dist/schema/business.js.map +1 -0
  432. package/dist/schema/fields.d.ts +2 -1
  433. package/dist/schema/fields.js.map +1 -1
  434. package/dist/schema/forms.d.ts +18 -0
  435. package/dist/schema/forms.js +18 -3
  436. package/dist/schema/forms.js.map +1 -1
  437. package/dist/schema/mail.d.ts +10 -0
  438. package/dist/schema/mail.js +7 -0
  439. package/dist/schema/mail.js.map +1 -1
  440. package/dist/schema/settings.d.ts +103 -0
  441. package/dist/schema/settings.js +24 -3
  442. package/dist/schema/settings.js.map +1 -1
  443. package/dist/schema/shop.d.ts +2 -0
  444. package/dist/schema/shop.js +4 -0
  445. package/dist/schema/shop.js.map +1 -1
  446. package/dist/schema/shopGeld.d.ts +1 -0
  447. package/dist/schema/shopGeld.js +1 -0
  448. package/dist/schema/shopGeld.js.map +1 -1
  449. package/dist/schema/siteConfig.d.ts +69 -1
  450. package/dist/schema/siteConfig.js +7 -2
  451. package/dist/schema/siteConfig.js.map +1 -1
  452. package/dist/server/blockData.d.ts +1 -1
  453. package/dist/server/blockData.js +74 -18
  454. package/dist/server/blockData.js.map +1 -1
  455. package/dist/server/cspRapport.d.ts +20 -0
  456. package/dist/server/cspRapport.js +56 -0
  457. package/dist/server/cspRapport.js.map +1 -0
  458. package/dist/server/fonts.d.ts +3 -0
  459. package/dist/server/fonts.js +39 -0
  460. package/dist/server/fonts.js.map +1 -0
  461. package/dist/server/index.d.ts +3 -0
  462. package/dist/server/index.js +8 -0
  463. package/dist/server/index.js.map +1 -1
  464. package/dist/server/sanitize.js +2 -0
  465. package/dist/server/sanitize.js.map +1 -1
  466. package/dist/settings/useSiteSettings.js +4 -1
  467. package/dist/settings/useSiteSettings.js.map +1 -1
  468. package/dist/starters/starters.d.ts +69 -0
  469. package/dist/starters/starters.js +171 -0
  470. package/dist/starters/starters.js.map +1 -0
  471. package/dist/styles.css +1181 -212
  472. package/dist/theme/color.d.ts +10 -0
  473. package/dist/theme/color.js +17 -1
  474. package/dist/theme/color.js.map +1 -1
  475. package/dist/theme/fontFallback.d.ts +23 -0
  476. package/dist/theme/fontFallback.js +58 -0
  477. package/dist/theme/fontFallback.js.map +1 -0
  478. package/dist/theme/fonts.d.ts +11 -0
  479. package/dist/theme/fonts.js +16 -0
  480. package/dist/theme/fonts.js.map +1 -0
  481. package/dist/version.js +1 -1
  482. package/package.json +5 -4
@@ -0,0 +1,106 @@
1
+ const FIREBASE_PUBLIEK = [
2
+ "NEXT_PUBLIC_FIREBASE_API_KEY",
3
+ "NEXT_PUBLIC_FIREBASE_PROJECT_ID",
4
+ "NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET",
5
+ "NEXT_PUBLIC_FIREBASE_APP_ID"
6
+ ];
7
+ const FIREBASE_ADMIN = ["FIREBASE_PROJECT_ID", "FIREBASE_CLIENT_EMAIL", "FIREBASE_PRIVATE_KEY"];
8
+ const LEEG_UITLEG = "staat er wel, maar is leeg. Op Vercel betekent dat meestal dat hij Sensitive is (die komen bij `vercel pull` leeg binnen). Een NEXT_PUBLIC-waarde is publiek: maak hem opnieuw met `vercel env add <NAAM> production --no-sensitive --force`.";
9
+ function controleerSiteEnv(env, opties = {}) {
10
+ const m = [];
11
+ const heeft = (k) => typeof env[k] === "string" && env[k].trim() !== "";
12
+ const leeg = (k) => typeof env[k] === "string" && env[k].trim() === "";
13
+ const aanwezig = FIREBASE_PUBLIEK.filter(heeft);
14
+ if (aanwezig.length === 0 && !FIREBASE_PUBLIEK.some(leeg)) {
15
+ if (!opties.demo) {
16
+ m.push({
17
+ naam: "NEXT_PUBLIC_FIREBASE_*",
18
+ ernst: "fout",
19
+ tekst: "Geen Firebase-config. Zonder deze waarden werken inloggen, het beheer en formulieren niet. (Een demo-site zonder Firebase: `xicmsEnvCheck({ demo: true })`.)"
20
+ });
21
+ }
22
+ } else {
23
+ for (const k of FIREBASE_PUBLIEK) {
24
+ if (leeg(k)) m.push({ naam: k, ernst: "fout", tekst: `${k} ${LEEG_UITLEG}` });
25
+ else if (!heeft(k)) m.push({ naam: k, ernst: "fout", tekst: `${k} ontbreekt, terwijl de rest van de Firebase-config er w\xE9l is.` });
26
+ }
27
+ const sameOrigin = env.NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN === "1";
28
+ if (leeg("NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN") && !sameOrigin) {
29
+ m.push({ naam: "NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN", ernst: "fout", tekst: `NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN ${LEEG_UITLEG}` });
30
+ } else if (!heeft("NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN") && !sameOrigin) {
31
+ m.push({
32
+ naam: "NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN",
33
+ ernst: "waarschuwing",
34
+ tekst: "NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN ontbreekt en NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN staat niet op 1: inloggen met Google werkt dan niet."
35
+ });
36
+ }
37
+ }
38
+ for (const k of Object.keys(env)) {
39
+ if (k.startsWith("NEXT_PUBLIC_") && !k.startsWith("NEXT_PUBLIC_VERCEL_") && !FIREBASE_PUBLIEK.includes(k) && k !== "NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN" && leeg(k)) {
40
+ m.push({ naam: k, ernst: "waarschuwing", tekst: `${k} ${LEEG_UITLEG} (Is leeg hier bedoeld, haal hem dan weg.)` });
41
+ }
42
+ }
43
+ const so = env.NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN;
44
+ if (so !== void 0 && so !== "" && so !== "1" && so !== "0") {
45
+ m.push({ naam: "NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN", ernst: "waarschuwing", tekst: `NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN is "${so}"; alleen "1" zet hem aan.` });
46
+ }
47
+ const regio = env.NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION;
48
+ if (heeft("NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION") && !/^[a-z]+-[a-z]+\d$/.test(regio.trim())) {
49
+ m.push({ naam: "NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION", ernst: "waarschuwing", tekst: `NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION "${regio}" lijkt geen Google-regio (zoals europe-west1).` });
50
+ }
51
+ const admin = FIREBASE_ADMIN.filter(heeft);
52
+ if (admin.length > 0 && admin.length < FIREBASE_ADMIN.length) {
53
+ const mist = FIREBASE_ADMIN.filter((k) => !heeft(k));
54
+ m.push({ naam: mist.join(", "), ernst: "fout", tekst: `Firebase Admin is half ingesteld: ${mist.join(" en ")} ontbreekt. De server kan dan geen content lezen.` });
55
+ } else if (admin.length === 0 && !opties.demo && aanwezig.length > 0) {
56
+ m.push({
57
+ naam: "FIREBASE_*",
58
+ ernst: "waarschuwing",
59
+ tekst: "Geen Firebase Admin-sleutels (FIREBASE_PROJECT_ID/CLIENT_EMAIL/PRIVATE_KEY): de server leest dan alleen de gebundelde content, niet de live database."
60
+ });
61
+ }
62
+ if (heeft("FIREBASE_PRIVATE_KEY") && !env.FIREBASE_PRIVATE_KEY.includes("PRIVATE KEY")) {
63
+ m.push({ naam: "FIREBASE_PRIVATE_KEY", ernst: "fout", tekst: "FIREBASE_PRIVATE_KEY heeft niet de vorm van een sleutel (geen 'BEGIN PRIVATE KEY'). Plak de hele waarde uit het service-account-JSON, met de \\n's." });
64
+ }
65
+ if (heeft("FIREBASE_PROJECT_ID") && heeft("NEXT_PUBLIC_FIREBASE_PROJECT_ID") && env.FIREBASE_PROJECT_ID.trim() !== env.NEXT_PUBLIC_FIREBASE_PROJECT_ID.trim()) {
66
+ m.push({
67
+ naam: "FIREBASE_PROJECT_ID",
68
+ ernst: "fout",
69
+ tekst: `FIREBASE_PROJECT_ID (${env.FIREBASE_PROJECT_ID}) is een ander project dan NEXT_PUBLIC_FIREBASE_PROJECT_ID (${env.NEXT_PUBLIC_FIREBASE_PROJECT_ID}): de server en de browser zouden verschillende databases lezen.`
70
+ });
71
+ }
72
+ if (admin.length === FIREBASE_ADMIN.length && !heeft("XICMS_REVALIDATE_SECRET")) {
73
+ m.push({
74
+ naam: "XICMS_REVALIDATE_SECRET",
75
+ ernst: "waarschuwing",
76
+ tekst: "XICMS_REVALIDATE_SECRET ontbreekt: gepubliceerde wijzigingen verschijnen pas na het ISR-vangnet (tot een uur), niet binnen seconden."
77
+ });
78
+ }
79
+ return m;
80
+ }
81
+ function envIsStrikt(env) {
82
+ return env.XICMS_ENV_STRIKT === "1" || env.VERCEL_ENV === "production" && env.XICMS_ENV_STRIKT !== "0";
83
+ }
84
+ function xicmsEnvCheck(opties = {}) {
85
+ const env = process.env;
86
+ const meldingen = controleerSiteEnv(env, opties);
87
+ if (meldingen.length === 0) return meldingen;
88
+ const fouten = meldingen.filter((x) => x.ernst === "fout");
89
+ const regels = meldingen.map((x) => ` ${x.ernst === "fout" ? "\u2717" : "!"} ${x.tekst}`).join("\n");
90
+ const kop = `[xicms] Controle van de env-variabelen: ${fouten.length} fout(en), ${meldingen.length - fouten.length} waarschuwing(en)`;
91
+ if (fouten.length > 0 && envIsStrikt(env)) {
92
+ throw new Error(`${kop}
93
+ ${regels}
94
+
95
+ De build is gestopt zodat er geen kapotte site live gaat. Bewust negeren: XICMS_ENV_STRIKT=0.`);
96
+ }
97
+ console.warn(`${kop}
98
+ ${regels}`);
99
+ return meldingen;
100
+ }
101
+ export {
102
+ controleerSiteEnv,
103
+ envIsStrikt,
104
+ xicmsEnvCheck
105
+ };
106
+ //# sourceMappingURL=envCheck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/next/envCheck.ts"],"sourcesContent":["/**\n * Env-controle tijdens de BUILD (8.7) — naar het idee van Astro's `astro:env`-schema.\n *\n * Er bestond al een controle bij serverstart (`validateEnv` in `instrumentation.ts`), maar die\n * komt te laat voor `NEXT_PUBLIC_*`: die waarden worden tijdens `next build` letterlijk in de\n * JavaScript-bundel gezet. Een lege waarde zit er dan al in, en de site start gewoon — alleen\n * werkt inloggen of het beheer niet. Precies dat gebeurde in september 2026: `vercel pull` leverde\n * Sensitive-variabelen leeg af, en dat viel pas op in de live bundel.\n *\n * Gebruik bovenin `next.config.ts`:\n *\n * import { xicmsEnvCheck } from \"@xiwebdesign/xicms-core/next\";\n * xicmsEnvCheck();\n *\n * Een productie-build op Vercel (`VERCEL_ENV=production`) of met `XICMS_ENV_STRIKT=1` stopt bij een\n * fout; overal elders (lokaal, CI, previews) komen fouten en waarschuwingen alleen in de log.\n * Dit bestand draait in Node tijdens de build en mag niets uit de React-bundel importeren.\n */\n\nexport type EnvErnst = \"fout\" | \"waarschuwing\";\n\nexport interface EnvMelding {\n naam: string;\n ernst: EnvErnst;\n tekst: string;\n}\n\ntype Env = Record<string, string | undefined>;\n\n/** De publieke Firebase-config die de browser nodig heeft (gaat de bundel in). */\nconst FIREBASE_PUBLIEK = [\n \"NEXT_PUBLIC_FIREBASE_API_KEY\",\n \"NEXT_PUBLIC_FIREBASE_PROJECT_ID\",\n \"NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET\",\n \"NEXT_PUBLIC_FIREBASE_APP_ID\",\n] as const;\n\n/** Server-geheimen voor het lezen van content (Firebase Admin). Alles of niets. */\nconst FIREBASE_ADMIN = [\"FIREBASE_PROJECT_ID\", \"FIREBASE_CLIENT_EMAIL\", \"FIREBASE_PRIVATE_KEY\"] as const;\n\nconst LEEG_UITLEG =\n \"staat er wel, maar is leeg. Op Vercel betekent dat meestal dat hij Sensitive is (die komen bij \" +\n \"`vercel pull` leeg binnen). Een NEXT_PUBLIC-waarde is publiek: maak hem opnieuw met \" +\n \"`vercel env add <NAAM> production --no-sensitive --force`.\";\n\n/**\n * Puur en testbaar: welke problemen heeft deze env? `demo` = een site zonder eigen Firebase\n * (de demo-modus werkt lokaal), dan is ontbrekende Firebase-config geen fout.\n */\nexport function controleerSiteEnv(env: Env, opties: { demo?: boolean } = {}): EnvMelding[] {\n const m: EnvMelding[] = [];\n const heeft = (k: string) => typeof env[k] === \"string\" && env[k]!.trim() !== \"\";\n const leeg = (k: string) => typeof env[k] === \"string\" && env[k]!.trim() === \"\";\n\n // ── Publieke Firebase-config ────────────────────────────────────────────\n const aanwezig = FIREBASE_PUBLIEK.filter(heeft);\n if (aanwezig.length === 0 && !FIREBASE_PUBLIEK.some(leeg)) {\n if (!opties.demo) {\n m.push({\n naam: \"NEXT_PUBLIC_FIREBASE_*\",\n ernst: \"fout\",\n tekst: \"Geen Firebase-config. Zonder deze waarden werken inloggen, het beheer en formulieren niet. (Een demo-site zonder Firebase: `xicmsEnvCheck({ demo: true })`.)\",\n });\n }\n } else {\n for (const k of FIREBASE_PUBLIEK) {\n if (leeg(k)) m.push({ naam: k, ernst: \"fout\", tekst: `${k} ${LEEG_UITLEG}` });\n else if (!heeft(k)) m.push({ naam: k, ernst: \"fout\", tekst: `${k} ontbreekt, terwijl de rest van de Firebase-config er wél is.` });\n }\n const sameOrigin = env.NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN === \"1\";\n if (leeg(\"NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN\") && !sameOrigin) {\n m.push({ naam: \"NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN\", ernst: \"fout\", tekst: `NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN ${LEEG_UITLEG}` });\n } else if (!heeft(\"NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN\") && !sameOrigin) {\n m.push({\n naam: \"NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN\",\n ernst: \"waarschuwing\",\n tekst: \"NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN ontbreekt en NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN staat niet op 1: inloggen met Google werkt dan niet.\",\n });\n }\n }\n for (const k of Object.keys(env)) {\n // Andere publieke vars die leeg zijn (App Check, regio, …): ook die gaan zo de bundel in.\n // NEXT_PUBLIC_VERCEL_* zet Vercel zelf, en sommige zijn bewust leeg (geen PR → geen PR-id).\n if (k.startsWith(\"NEXT_PUBLIC_\") && !k.startsWith(\"NEXT_PUBLIC_VERCEL_\") && !(FIREBASE_PUBLIEK as readonly string[]).includes(k) && k !== \"NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN\" && leeg(k)) {\n m.push({ naam: k, ernst: \"waarschuwing\", tekst: `${k} ${LEEG_UITLEG} (Is leeg hier bedoeld, haal hem dan weg.)` });\n }\n }\n const so = env.NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN;\n if (so !== undefined && so !== \"\" && so !== \"1\" && so !== \"0\") {\n m.push({ naam: \"NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN\", ernst: \"waarschuwing\", tekst: `NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN is \"${so}\"; alleen \"1\" zet hem aan.` });\n }\n const regio = env.NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION;\n if (heeft(\"NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION\") && !/^[a-z]+-[a-z]+\\d$/.test(regio!.trim())) {\n m.push({ naam: \"NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION\", ernst: \"waarschuwing\", tekst: `NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION \"${regio}\" lijkt geen Google-regio (zoals europe-west1).` });\n }\n\n // ── Firebase Admin (server) ─────────────────────────────────────────────\n const admin = FIREBASE_ADMIN.filter(heeft);\n if (admin.length > 0 && admin.length < FIREBASE_ADMIN.length) {\n const mist = FIREBASE_ADMIN.filter((k) => !heeft(k));\n m.push({ naam: mist.join(\", \"), ernst: \"fout\", tekst: `Firebase Admin is half ingesteld: ${mist.join(\" en \")} ontbreekt. De server kan dan geen content lezen.` });\n } else if (admin.length === 0 && !opties.demo && aanwezig.length > 0) {\n m.push({\n naam: \"FIREBASE_*\",\n ernst: \"waarschuwing\",\n tekst: \"Geen Firebase Admin-sleutels (FIREBASE_PROJECT_ID/CLIENT_EMAIL/PRIVATE_KEY): de server leest dan alleen de gebundelde content, niet de live database.\",\n });\n }\n if (heeft(\"FIREBASE_PRIVATE_KEY\") && !env.FIREBASE_PRIVATE_KEY!.includes(\"PRIVATE KEY\")) {\n m.push({ naam: \"FIREBASE_PRIVATE_KEY\", ernst: \"fout\", tekst: \"FIREBASE_PRIVATE_KEY heeft niet de vorm van een sleutel (geen 'BEGIN PRIVATE KEY'). Plak de hele waarde uit het service-account-JSON, met de \\\\n's.\" });\n }\n if (heeft(\"FIREBASE_PROJECT_ID\") && heeft(\"NEXT_PUBLIC_FIREBASE_PROJECT_ID\") && env.FIREBASE_PROJECT_ID!.trim() !== env.NEXT_PUBLIC_FIREBASE_PROJECT_ID!.trim()) {\n m.push({\n naam: \"FIREBASE_PROJECT_ID\",\n ernst: \"fout\",\n tekst: `FIREBASE_PROJECT_ID (${env.FIREBASE_PROJECT_ID}) is een ander project dan NEXT_PUBLIC_FIREBASE_PROJECT_ID (${env.NEXT_PUBLIC_FIREBASE_PROJECT_ID}): de server en de browser zouden verschillende databases lezen.`,\n });\n }\n\n // ── Live zonder rebuild ─────────────────────────────────────────────────\n if (admin.length === FIREBASE_ADMIN.length && !heeft(\"XICMS_REVALIDATE_SECRET\")) {\n m.push({\n naam: \"XICMS_REVALIDATE_SECRET\",\n ernst: \"waarschuwing\",\n tekst: \"XICMS_REVALIDATE_SECRET ontbreekt: gepubliceerde wijzigingen verschijnen pas na het ISR-vangnet (tot een uur), niet binnen seconden.\",\n });\n }\n return m;\n}\n\n/** Moet een fout de build stoppen? Alleen bij een productie-build, of als je het expliciet vraagt. */\nexport function envIsStrikt(env: Env): boolean {\n return env.XICMS_ENV_STRIKT === \"1\" || (env.VERCEL_ENV === \"production\" && env.XICMS_ENV_STRIKT !== \"0\");\n}\n\n/**\n * Roep aan bovenin `next.config.ts`. Schrijft meldingen naar de log en gooit bij een fout als de\n * build strikt is (zie `envIsStrikt`).\n */\nexport function xicmsEnvCheck(opties: { demo?: boolean } = {}): EnvMelding[] {\n const env = process.env as Env;\n const meldingen = controleerSiteEnv(env, opties);\n if (meldingen.length === 0) return meldingen;\n const fouten = meldingen.filter((x) => x.ernst === \"fout\");\n const regels = meldingen.map((x) => ` ${x.ernst === \"fout\" ? \"✗\" : \"!\"} ${x.tekst}`).join(\"\\n\");\n const kop = `[xicms] Controle van de env-variabelen: ${fouten.length} fout(en), ${meldingen.length - fouten.length} waarschuwing(en)`;\n if (fouten.length > 0 && envIsStrikt(env)) {\n throw new Error(`${kop}\\n${regels}\\n\\nDe build is gestopt zodat er geen kapotte site live gaat. Bewust negeren: XICMS_ENV_STRIKT=0.`);\n }\n console.warn(`${kop}\\n${regels}`);\n return meldingen;\n}\n"],"mappings":"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","names":[]}
@@ -20,8 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/next/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ bouwCsp: () => bouwCsp,
24
+ controleerSiteEnv: () => controleerSiteEnv,
25
+ envIsStrikt: () => envIsStrikt,
23
26
  xicmsAuthHeaders: () => xicmsAuthHeaders,
24
- xicmsAuthRewrites: () => xicmsAuthRewrites
27
+ xicmsAuthRewrites: () => xicmsAuthRewrites,
28
+ xicmsEnvCheck: () => xicmsEnvCheck,
29
+ xicmsSecurityHeaders: () => xicmsSecurityHeaders
25
30
  });
26
31
  module.exports = __toCommonJS(index_exports);
27
32
 
@@ -52,8 +57,186 @@ function xicmsAuthRewrites() {
52
57
  { source: "/__/firebase/:path*", destination: `${doel}/__/firebase/:path*` }
53
58
  ];
54
59
  }
60
+
61
+ // src/next/envCheck.ts
62
+ var FIREBASE_PUBLIEK = [
63
+ "NEXT_PUBLIC_FIREBASE_API_KEY",
64
+ "NEXT_PUBLIC_FIREBASE_PROJECT_ID",
65
+ "NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET",
66
+ "NEXT_PUBLIC_FIREBASE_APP_ID"
67
+ ];
68
+ var FIREBASE_ADMIN = ["FIREBASE_PROJECT_ID", "FIREBASE_CLIENT_EMAIL", "FIREBASE_PRIVATE_KEY"];
69
+ var LEEG_UITLEG = "staat er wel, maar is leeg. Op Vercel betekent dat meestal dat hij Sensitive is (die komen bij `vercel pull` leeg binnen). Een NEXT_PUBLIC-waarde is publiek: maak hem opnieuw met `vercel env add <NAAM> production --no-sensitive --force`.";
70
+ function controleerSiteEnv(env, opties = {}) {
71
+ const m = [];
72
+ const heeft = (k) => typeof env[k] === "string" && env[k].trim() !== "";
73
+ const leeg = (k) => typeof env[k] === "string" && env[k].trim() === "";
74
+ const aanwezig = FIREBASE_PUBLIEK.filter(heeft);
75
+ if (aanwezig.length === 0 && !FIREBASE_PUBLIEK.some(leeg)) {
76
+ if (!opties.demo) {
77
+ m.push({
78
+ naam: "NEXT_PUBLIC_FIREBASE_*",
79
+ ernst: "fout",
80
+ tekst: "Geen Firebase-config. Zonder deze waarden werken inloggen, het beheer en formulieren niet. (Een demo-site zonder Firebase: `xicmsEnvCheck({ demo: true })`.)"
81
+ });
82
+ }
83
+ } else {
84
+ for (const k of FIREBASE_PUBLIEK) {
85
+ if (leeg(k)) m.push({ naam: k, ernst: "fout", tekst: `${k} ${LEEG_UITLEG}` });
86
+ else if (!heeft(k)) m.push({ naam: k, ernst: "fout", tekst: `${k} ontbreekt, terwijl de rest van de Firebase-config er w\xE9l is.` });
87
+ }
88
+ const sameOrigin = env.NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN === "1";
89
+ if (leeg("NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN") && !sameOrigin) {
90
+ m.push({ naam: "NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN", ernst: "fout", tekst: `NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN ${LEEG_UITLEG}` });
91
+ } else if (!heeft("NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN") && !sameOrigin) {
92
+ m.push({
93
+ naam: "NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN",
94
+ ernst: "waarschuwing",
95
+ tekst: "NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN ontbreekt en NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN staat niet op 1: inloggen met Google werkt dan niet."
96
+ });
97
+ }
98
+ }
99
+ for (const k of Object.keys(env)) {
100
+ if (k.startsWith("NEXT_PUBLIC_") && !k.startsWith("NEXT_PUBLIC_VERCEL_") && !FIREBASE_PUBLIEK.includes(k) && k !== "NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN" && leeg(k)) {
101
+ m.push({ naam: k, ernst: "waarschuwing", tekst: `${k} ${LEEG_UITLEG} (Is leeg hier bedoeld, haal hem dan weg.)` });
102
+ }
103
+ }
104
+ const so = env.NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN;
105
+ if (so !== void 0 && so !== "" && so !== "1" && so !== "0") {
106
+ m.push({ naam: "NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN", ernst: "waarschuwing", tekst: `NEXT_PUBLIC_FIREBASE_AUTH_SAME_ORIGIN is "${so}"; alleen "1" zet hem aan.` });
107
+ }
108
+ const regio = env.NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION;
109
+ if (heeft("NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION") && !/^[a-z]+-[a-z]+\d$/.test(regio.trim())) {
110
+ m.push({ naam: "NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION", ernst: "waarschuwing", tekst: `NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION "${regio}" lijkt geen Google-regio (zoals europe-west1).` });
111
+ }
112
+ const admin = FIREBASE_ADMIN.filter(heeft);
113
+ if (admin.length > 0 && admin.length < FIREBASE_ADMIN.length) {
114
+ const mist = FIREBASE_ADMIN.filter((k) => !heeft(k));
115
+ m.push({ naam: mist.join(", "), ernst: "fout", tekst: `Firebase Admin is half ingesteld: ${mist.join(" en ")} ontbreekt. De server kan dan geen content lezen.` });
116
+ } else if (admin.length === 0 && !opties.demo && aanwezig.length > 0) {
117
+ m.push({
118
+ naam: "FIREBASE_*",
119
+ ernst: "waarschuwing",
120
+ tekst: "Geen Firebase Admin-sleutels (FIREBASE_PROJECT_ID/CLIENT_EMAIL/PRIVATE_KEY): de server leest dan alleen de gebundelde content, niet de live database."
121
+ });
122
+ }
123
+ if (heeft("FIREBASE_PRIVATE_KEY") && !env.FIREBASE_PRIVATE_KEY.includes("PRIVATE KEY")) {
124
+ m.push({ naam: "FIREBASE_PRIVATE_KEY", ernst: "fout", tekst: "FIREBASE_PRIVATE_KEY heeft niet de vorm van een sleutel (geen 'BEGIN PRIVATE KEY'). Plak de hele waarde uit het service-account-JSON, met de \\n's." });
125
+ }
126
+ if (heeft("FIREBASE_PROJECT_ID") && heeft("NEXT_PUBLIC_FIREBASE_PROJECT_ID") && env.FIREBASE_PROJECT_ID.trim() !== env.NEXT_PUBLIC_FIREBASE_PROJECT_ID.trim()) {
127
+ m.push({
128
+ naam: "FIREBASE_PROJECT_ID",
129
+ ernst: "fout",
130
+ tekst: `FIREBASE_PROJECT_ID (${env.FIREBASE_PROJECT_ID}) is een ander project dan NEXT_PUBLIC_FIREBASE_PROJECT_ID (${env.NEXT_PUBLIC_FIREBASE_PROJECT_ID}): de server en de browser zouden verschillende databases lezen.`
131
+ });
132
+ }
133
+ if (admin.length === FIREBASE_ADMIN.length && !heeft("XICMS_REVALIDATE_SECRET")) {
134
+ m.push({
135
+ naam: "XICMS_REVALIDATE_SECRET",
136
+ ernst: "waarschuwing",
137
+ tekst: "XICMS_REVALIDATE_SECRET ontbreekt: gepubliceerde wijzigingen verschijnen pas na het ISR-vangnet (tot een uur), niet binnen seconden."
138
+ });
139
+ }
140
+ return m;
141
+ }
142
+ function envIsStrikt(env) {
143
+ return env.XICMS_ENV_STRIKT === "1" || env.VERCEL_ENV === "production" && env.XICMS_ENV_STRIKT !== "0";
144
+ }
145
+ function xicmsEnvCheck(opties = {}) {
146
+ const env = process.env;
147
+ const meldingen = controleerSiteEnv(env, opties);
148
+ if (meldingen.length === 0) return meldingen;
149
+ const fouten = meldingen.filter((x) => x.ernst === "fout");
150
+ const regels = meldingen.map((x) => ` ${x.ernst === "fout" ? "\u2717" : "!"} ${x.tekst}`).join("\n");
151
+ const kop = `[xicms] Controle van de env-variabelen: ${fouten.length} fout(en), ${meldingen.length - fouten.length} waarschuwing(en)`;
152
+ if (fouten.length > 0 && envIsStrikt(env)) {
153
+ throw new Error(`${kop}
154
+ ${regels}
155
+
156
+ De build is gestopt zodat er geen kapotte site live gaat. Bewust negeren: XICMS_ENV_STRIKT=0.`);
157
+ }
158
+ console.warn(`${kop}
159
+ ${regels}`);
160
+ return meldingen;
161
+ }
162
+
163
+ // src/next/securityHeaders.ts
164
+ function basis(dev) {
165
+ return {
166
+ "default-src": ["'self'"],
167
+ // reCAPTCHA v3 = App Check; apis.google.com laadt Firebase Auth voor de login-popup.
168
+ // vercel.live = de commentaar-toolbar die Vercel op preview-deploys invoegt.
169
+ "script-src": ["'self'", "'unsafe-inline'", "https://www.google.com/recaptcha/", "https://www.gstatic.com/recaptcha/", "https://apis.google.com", "https://vercel.live", ...dev ? ["'unsafe-eval'"] : []],
170
+ // Astryx en Next zetten inline stijlen; Google Fonts als de site niet zelf host.
171
+ "style-src": ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://vercel.live"],
172
+ "font-src": ["'self'", "data:", "https://fonts.gstatic.com", "https://vercel.live", "https://assets.vercel.com"],
173
+ // Foto's komen uit Storage, Unsplash, YouTube-thumbnails, … — beelden kunnen geen code draaien.
174
+ "img-src": ["'self'", "data:", "blob:", "https:"],
175
+ "media-src": ["'self'", "blob:", "https:"],
176
+ "connect-src": [
177
+ "'self'",
178
+ "https://*.googleapis.com",
179
+ "https://*.cloudfunctions.net",
180
+ "https://*.run.app",
181
+ "https://*.firebaseio.com",
182
+ "wss://*.firebaseio.com",
183
+ "https://*.firebaseapp.com",
184
+ "https://www.google.com",
185
+ // De engine-versie in /beheer komt rechtstreeks van npm (CoreVersion).
186
+ "https://registry.npmjs.org",
187
+ "https://vercel.live",
188
+ "wss://ws-us3.pusher.com",
189
+ ...dev ? ["ws:", "http://localhost:*", "http://127.0.0.1:*"] : []
190
+ ],
191
+ // Embeds (video, kaart, agenda, boekingswidgets) zijn iframes naar willekeurige diensten;
192
+ // die draaien in hun eigen origin. Ook de Firebase-login-handler en reCAPTCHA.
193
+ "frame-src": ["'self'", "https:"],
194
+ "worker-src": ["'self'", "blob:"],
195
+ // Het PDF-blok gebruikt bewust <object> (fallback met open-knop op mobiel). Browsers hebben geen
196
+ // plug-ins meer behalve de PDF-viewer, dus https: kost hier weinig; 'none' brak het PDF-blok.
197
+ "object-src": ["'self'", "https:"],
198
+ "base-uri": ["'self'"],
199
+ "form-action": ["'self'", "https:"],
200
+ // Niemand anders mag de site in een frame zetten (clickjacking).
201
+ "frame-ancestors": ["'self'"]
202
+ };
203
+ }
204
+ function bouwCsp(opties = {}) {
205
+ const dev = opties.dev ?? process.env.NODE_ENV !== "production";
206
+ const d = basis(dev);
207
+ for (const [k, bronnen] of Object.entries(opties.extra ?? {})) {
208
+ d[k] = [.../* @__PURE__ */ new Set([...d[k] ?? [], ...bronnen])];
209
+ }
210
+ const delen = Object.entries(d).map(([k, v]) => `${k} ${v.join(" ")}`);
211
+ if (opties.afdwingen && !dev) delen.push("upgrade-insecure-requests");
212
+ const pad = opties.rapportPad === void 0 ? "/api/csp-rapport" : opties.rapportPad;
213
+ if (pad) {
214
+ delen.push(`report-uri ${pad}`);
215
+ delen.push("report-to csp");
216
+ }
217
+ return delen.join("; ");
218
+ }
219
+ function xicmsSecurityHeaders(opties = {}) {
220
+ const pad = opties.rapportPad === void 0 ? "/api/csp-rapport" : opties.rapportPad;
221
+ const headers = [
222
+ { key: opties.afdwingen ? "Content-Security-Policy" : "Content-Security-Policy-Report-Only", value: bouwCsp(opties) },
223
+ // Geen MIME-gokken: een geüpload "plaatje" kan zo nooit als script draaien.
224
+ { key: "X-Content-Type-Options", value: "nosniff" },
225
+ // Externe sites zien alleen het domein, niet het volledige pad (privacy van bezoekers).
226
+ { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
227
+ // Een klantsite heeft geen camera, microfoon of betaal-API nodig. Locatie: alleen de site zelf.
228
+ { key: "Permissions-Policy", value: "camera=(), microphone=(), payment=(), usb=(), geolocation=(self)" }
229
+ ];
230
+ if (pad) headers.push({ key: "Reporting-Endpoints", value: `csp="${pad}"` });
231
+ return [{ source: "/:path*", headers }];
232
+ }
55
233
  // Annotate the CommonJS export names for ESM import in node:
56
234
  0 && (module.exports = {
235
+ bouwCsp,
236
+ controleerSiteEnv,
237
+ envIsStrikt,
57
238
  xicmsAuthHeaders,
58
- xicmsAuthRewrites
239
+ xicmsAuthRewrites,
240
+ xicmsEnvCheck,
241
+ xicmsSecurityHeaders
59
242
  });
@@ -3,3 +3,5 @@
3
3
  * niet in de browser, en mag dus niets uit de React-bundel meetrekken.
4
4
  */
5
5
  export { xicmsAuthRewrites, xicmsAuthHeaders, type XicmsRewrite, type XicmsHeader } from "./authRewrites.js";
6
+ export { xicmsEnvCheck, controleerSiteEnv, envIsStrikt, type EnvMelding, type EnvErnst } from "./envCheck.js";
7
+ export { xicmsSecurityHeaders, bouwCsp, type CspOpties, type CspDirective } from "./securityHeaders.js";
@@ -1,6 +1,13 @@
1
1
  import { xicmsAuthRewrites, xicmsAuthHeaders } from "./authRewrites.js";
2
+ import { xicmsEnvCheck, controleerSiteEnv, envIsStrikt } from "./envCheck.js";
3
+ import { xicmsSecurityHeaders, bouwCsp } from "./securityHeaders.js";
2
4
  export {
5
+ bouwCsp,
6
+ controleerSiteEnv,
7
+ envIsStrikt,
3
8
  xicmsAuthHeaders,
4
- xicmsAuthRewrites
9
+ xicmsAuthRewrites,
10
+ xicmsEnvCheck,
11
+ xicmsSecurityHeaders
5
12
  };
6
13
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/next/index.ts"],"sourcesContent":["/**\n * Helpers voor `next.config.ts`. Bewust een eigen ingang: dit draait in Node tijdens de build,\n * niet in de browser, en mag dus niets uit de React-bundel meetrekken.\n */\nexport { xicmsAuthRewrites, xicmsAuthHeaders, type XicmsRewrite, type XicmsHeader } from \"./authRewrites\";\n"],"mappings":"AAIA,SAAS,mBAAmB,wBAA6D;","names":[]}
1
+ {"version":3,"sources":["../../src/next/index.ts"],"sourcesContent":["/**\n * Helpers voor `next.config.ts`. Bewust een eigen ingang: dit draait in Node tijdens de build,\n * niet in de browser, en mag dus niets uit de React-bundel meetrekken.\n */\nexport { xicmsAuthRewrites, xicmsAuthHeaders, type XicmsRewrite, type XicmsHeader } from \"./authRewrites\";\nexport { xicmsEnvCheck, controleerSiteEnv, envIsStrikt, type EnvMelding, type EnvErnst } from \"./envCheck\";\nexport { xicmsSecurityHeaders, bouwCsp, type CspOpties, type CspDirective } from \"./securityHeaders\";\n"],"mappings":"AAIA,SAAS,mBAAmB,wBAA6D;AACzF,SAAS,eAAe,mBAAmB,mBAAmD;AAC9F,SAAS,sBAAsB,eAAkD;","names":[]}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Beveiligingsheaders met een Content Security Policy (8.7) — naar het idee van Astro's
3
+ * `security.csp`. Een CSP vertelt de browser welke bronnen een pagina mag laden. Komt er toch een
4
+ * vreemd script binnen (via geplakte HTML, een gehackte embed, een kwaadwillende extensie die de
5
+ * DOM aanpast), dan weigert de browser het.
6
+ *
7
+ * Standaard ALLEEN RAPPORTEREN (`Content-Security-Policy-Report-Only`): de browser blokkeert niets,
8
+ * maar meldt elke overtreding aan `/api/csp-rapport` (zie `cspRapportPOST`), zodat die in de
9
+ * Vercel-logs staan. Laat dat een week lopen, vul `extra` aan met wat legitiem bleek, en zet dan
10
+ * `afdwingen: true`.
11
+ *
12
+ * Waarom 'unsafe-inline' voor scripts: Next zet inline scripts in statisch gegenereerde pagina's.
13
+ * Nonces vragen een dynamische render per verzoek, en dat kost ons de SSG-snelheid. De rest van de
14
+ * policy (geen vreemde hosts, geen object/embed, geen framing door anderen, base-uri vast) blijft
15
+ * waardevol; Astro maakt dezelfde afweging niet omdat het de scripts kan hashen.
16
+ *
17
+ * Gebruik in next.config.ts:
18
+ *
19
+ * async headers() { return [...xicmsAuthHeaders(), ...xicmsSecurityHeaders()]; }
20
+ */
21
+ import type { XicmsHeader } from "./authRewrites.js";
22
+ export type CspDirective = "default-src" | "script-src" | "style-src" | "font-src" | "img-src" | "media-src" | "connect-src" | "frame-src" | "worker-src" | "object-src" | "base-uri" | "form-action" | "frame-ancestors";
23
+ export interface CspOpties {
24
+ /** true = blokkeren; standaard alleen rapporteren. */
25
+ afdwingen?: boolean;
26
+ /** Waar de browser overtredingen meldt; `false` = nergens (alleen de console). */
27
+ rapportPad?: string | false;
28
+ /** Extra bronnen per directive, bv. `{ "script-src": ["https://plausible.io"] }`. */
29
+ extra?: Partial<Record<CspDirective, string[]>>;
30
+ /** Ontwikkelmodus (HMR, eval, emulators). Standaard: NODE_ENV !== "production". */
31
+ dev?: boolean;
32
+ }
33
+ /** Bouwt de policy-string. Puur, voor tests en voor wie hem elders nodig heeft. */
34
+ export declare function bouwCsp(opties?: CspOpties): string;
35
+ /** Headers voor de hele site: CSP (rapport of afdwingen) plus een paar goedkope basisheaders. */
36
+ export declare function xicmsSecurityHeaders(opties?: CspOpties): XicmsHeader[];
@@ -0,0 +1,74 @@
1
+ function basis(dev) {
2
+ return {
3
+ "default-src": ["'self'"],
4
+ // reCAPTCHA v3 = App Check; apis.google.com laadt Firebase Auth voor de login-popup.
5
+ // vercel.live = de commentaar-toolbar die Vercel op preview-deploys invoegt.
6
+ "script-src": ["'self'", "'unsafe-inline'", "https://www.google.com/recaptcha/", "https://www.gstatic.com/recaptcha/", "https://apis.google.com", "https://vercel.live", ...dev ? ["'unsafe-eval'"] : []],
7
+ // Astryx en Next zetten inline stijlen; Google Fonts als de site niet zelf host.
8
+ "style-src": ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://vercel.live"],
9
+ "font-src": ["'self'", "data:", "https://fonts.gstatic.com", "https://vercel.live", "https://assets.vercel.com"],
10
+ // Foto's komen uit Storage, Unsplash, YouTube-thumbnails, … — beelden kunnen geen code draaien.
11
+ "img-src": ["'self'", "data:", "blob:", "https:"],
12
+ "media-src": ["'self'", "blob:", "https:"],
13
+ "connect-src": [
14
+ "'self'",
15
+ "https://*.googleapis.com",
16
+ "https://*.cloudfunctions.net",
17
+ "https://*.run.app",
18
+ "https://*.firebaseio.com",
19
+ "wss://*.firebaseio.com",
20
+ "https://*.firebaseapp.com",
21
+ "https://www.google.com",
22
+ // De engine-versie in /beheer komt rechtstreeks van npm (CoreVersion).
23
+ "https://registry.npmjs.org",
24
+ "https://vercel.live",
25
+ "wss://ws-us3.pusher.com",
26
+ ...dev ? ["ws:", "http://localhost:*", "http://127.0.0.1:*"] : []
27
+ ],
28
+ // Embeds (video, kaart, agenda, boekingswidgets) zijn iframes naar willekeurige diensten;
29
+ // die draaien in hun eigen origin. Ook de Firebase-login-handler en reCAPTCHA.
30
+ "frame-src": ["'self'", "https:"],
31
+ "worker-src": ["'self'", "blob:"],
32
+ // Het PDF-blok gebruikt bewust <object> (fallback met open-knop op mobiel). Browsers hebben geen
33
+ // plug-ins meer behalve de PDF-viewer, dus https: kost hier weinig; 'none' brak het PDF-blok.
34
+ "object-src": ["'self'", "https:"],
35
+ "base-uri": ["'self'"],
36
+ "form-action": ["'self'", "https:"],
37
+ // Niemand anders mag de site in een frame zetten (clickjacking).
38
+ "frame-ancestors": ["'self'"]
39
+ };
40
+ }
41
+ function bouwCsp(opties = {}) {
42
+ const dev = opties.dev ?? process.env.NODE_ENV !== "production";
43
+ const d = basis(dev);
44
+ for (const [k, bronnen] of Object.entries(opties.extra ?? {})) {
45
+ d[k] = [.../* @__PURE__ */ new Set([...d[k] ?? [], ...bronnen])];
46
+ }
47
+ const delen = Object.entries(d).map(([k, v]) => `${k} ${v.join(" ")}`);
48
+ if (opties.afdwingen && !dev) delen.push("upgrade-insecure-requests");
49
+ const pad = opties.rapportPad === void 0 ? "/api/csp-rapport" : opties.rapportPad;
50
+ if (pad) {
51
+ delen.push(`report-uri ${pad}`);
52
+ delen.push("report-to csp");
53
+ }
54
+ return delen.join("; ");
55
+ }
56
+ function xicmsSecurityHeaders(opties = {}) {
57
+ const pad = opties.rapportPad === void 0 ? "/api/csp-rapport" : opties.rapportPad;
58
+ const headers = [
59
+ { key: opties.afdwingen ? "Content-Security-Policy" : "Content-Security-Policy-Report-Only", value: bouwCsp(opties) },
60
+ // Geen MIME-gokken: een geüpload "plaatje" kan zo nooit als script draaien.
61
+ { key: "X-Content-Type-Options", value: "nosniff" },
62
+ // Externe sites zien alleen het domein, niet het volledige pad (privacy van bezoekers).
63
+ { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
64
+ // Een klantsite heeft geen camera, microfoon of betaal-API nodig. Locatie: alleen de site zelf.
65
+ { key: "Permissions-Policy", value: "camera=(), microphone=(), payment=(), usb=(), geolocation=(self)" }
66
+ ];
67
+ if (pad) headers.push({ key: "Reporting-Endpoints", value: `csp="${pad}"` });
68
+ return [{ source: "/:path*", headers }];
69
+ }
70
+ export {
71
+ bouwCsp,
72
+ xicmsSecurityHeaders
73
+ };
74
+ //# sourceMappingURL=securityHeaders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/next/securityHeaders.ts"],"sourcesContent":["/**\n * Beveiligingsheaders met een Content Security Policy (8.7) — naar het idee van Astro's\n * `security.csp`. Een CSP vertelt de browser welke bronnen een pagina mag laden. Komt er toch een\n * vreemd script binnen (via geplakte HTML, een gehackte embed, een kwaadwillende extensie die de\n * DOM aanpast), dan weigert de browser het.\n *\n * Standaard ALLEEN RAPPORTEREN (`Content-Security-Policy-Report-Only`): de browser blokkeert niets,\n * maar meldt elke overtreding aan `/api/csp-rapport` (zie `cspRapportPOST`), zodat die in de\n * Vercel-logs staan. Laat dat een week lopen, vul `extra` aan met wat legitiem bleek, en zet dan\n * `afdwingen: true`.\n *\n * Waarom 'unsafe-inline' voor scripts: Next zet inline scripts in statisch gegenereerde pagina's.\n * Nonces vragen een dynamische render per verzoek, en dat kost ons de SSG-snelheid. De rest van de\n * policy (geen vreemde hosts, geen object/embed, geen framing door anderen, base-uri vast) blijft\n * waardevol; Astro maakt dezelfde afweging niet omdat het de scripts kan hashen.\n *\n * Gebruik in next.config.ts:\n *\n * async headers() { return [...xicmsAuthHeaders(), ...xicmsSecurityHeaders()]; }\n */\nimport type { XicmsHeader } from \"./authRewrites\";\n\nexport type CspDirective =\n | \"default-src\"\n | \"script-src\"\n | \"style-src\"\n | \"font-src\"\n | \"img-src\"\n | \"media-src\"\n | \"connect-src\"\n | \"frame-src\"\n | \"worker-src\"\n | \"object-src\"\n | \"base-uri\"\n | \"form-action\"\n | \"frame-ancestors\";\n\nexport interface CspOpties {\n /** true = blokkeren; standaard alleen rapporteren. */\n afdwingen?: boolean;\n /** Waar de browser overtredingen meldt; `false` = nergens (alleen de console). */\n rapportPad?: string | false;\n /** Extra bronnen per directive, bv. `{ \"script-src\": [\"https://plausible.io\"] }`. */\n extra?: Partial<Record<CspDirective, string[]>>;\n /** Ontwikkelmodus (HMR, eval, emulators). Standaard: NODE_ENV !== \"production\". */\n dev?: boolean;\n}\n\n/** De basis: wat XiCMS zelf nodig heeft (Firebase, App Check, Google Fonts, embeds). */\nfunction basis(dev: boolean): Record<CspDirective, string[]> {\n return {\n \"default-src\": [\"'self'\"],\n // reCAPTCHA v3 = App Check; apis.google.com laadt Firebase Auth voor de login-popup.\n // vercel.live = de commentaar-toolbar die Vercel op preview-deploys invoegt.\n \"script-src\": [\"'self'\", \"'unsafe-inline'\", \"https://www.google.com/recaptcha/\", \"https://www.gstatic.com/recaptcha/\", \"https://apis.google.com\", \"https://vercel.live\", ...(dev ? [\"'unsafe-eval'\"] : [])],\n // Astryx en Next zetten inline stijlen; Google Fonts als de site niet zelf host.\n \"style-src\": [\"'self'\", \"'unsafe-inline'\", \"https://fonts.googleapis.com\", \"https://vercel.live\"],\n \"font-src\": [\"'self'\", \"data:\", \"https://fonts.gstatic.com\", \"https://vercel.live\", \"https://assets.vercel.com\"],\n // Foto's komen uit Storage, Unsplash, YouTube-thumbnails, … — beelden kunnen geen code draaien.\n \"img-src\": [\"'self'\", \"data:\", \"blob:\", \"https:\"],\n \"media-src\": [\"'self'\", \"blob:\", \"https:\"],\n \"connect-src\": [\n \"'self'\",\n \"https://*.googleapis.com\",\n \"https://*.cloudfunctions.net\",\n \"https://*.run.app\",\n \"https://*.firebaseio.com\",\n \"wss://*.firebaseio.com\",\n \"https://*.firebaseapp.com\",\n \"https://www.google.com\",\n // De engine-versie in /beheer komt rechtstreeks van npm (CoreVersion).\n \"https://registry.npmjs.org\",\n \"https://vercel.live\",\n \"wss://ws-us3.pusher.com\",\n ...(dev ? [\"ws:\", \"http://localhost:*\", \"http://127.0.0.1:*\"] : []),\n ],\n // Embeds (video, kaart, agenda, boekingswidgets) zijn iframes naar willekeurige diensten;\n // die draaien in hun eigen origin. Ook de Firebase-login-handler en reCAPTCHA.\n \"frame-src\": [\"'self'\", \"https:\"],\n \"worker-src\": [\"'self'\", \"blob:\"],\n // Het PDF-blok gebruikt bewust <object> (fallback met open-knop op mobiel). Browsers hebben geen\n // plug-ins meer behalve de PDF-viewer, dus https: kost hier weinig; 'none' brak het PDF-blok.\n \"object-src\": [\"'self'\", \"https:\"],\n \"base-uri\": [\"'self'\"],\n \"form-action\": [\"'self'\", \"https:\"],\n // Niemand anders mag de site in een frame zetten (clickjacking).\n \"frame-ancestors\": [\"'self'\"],\n };\n}\n\n/** Bouwt de policy-string. Puur, voor tests en voor wie hem elders nodig heeft. */\nexport function bouwCsp(opties: CspOpties = {}): string {\n const dev = opties.dev ?? process.env.NODE_ENV !== \"production\";\n const d = basis(dev);\n for (const [k, bronnen] of Object.entries(opties.extra ?? {}) as [CspDirective, string[]][]) {\n d[k] = [...new Set([...(d[k] ?? []), ...bronnen])];\n }\n const delen = Object.entries(d).map(([k, v]) => `${k} ${v.join(\" \")}`);\n // In report-only negeert de browser deze (met een waarschuwing), dus alleen bij afdwingen.\n if (opties.afdwingen && !dev) delen.push(\"upgrade-insecure-requests\");\n const pad = opties.rapportPad === undefined ? \"/api/csp-rapport\" : opties.rapportPad;\n if (pad) {\n delen.push(`report-uri ${pad}`);\n delen.push(\"report-to csp\");\n }\n return delen.join(\"; \");\n}\n\n/** Headers voor de hele site: CSP (rapport of afdwingen) plus een paar goedkope basisheaders. */\nexport function xicmsSecurityHeaders(opties: CspOpties = {}): XicmsHeader[] {\n const pad = opties.rapportPad === undefined ? \"/api/csp-rapport\" : opties.rapportPad;\n const headers = [\n { key: opties.afdwingen ? \"Content-Security-Policy\" : \"Content-Security-Policy-Report-Only\", value: bouwCsp(opties) },\n // Geen MIME-gokken: een geüpload \"plaatje\" kan zo nooit als script draaien.\n { key: \"X-Content-Type-Options\", value: \"nosniff\" },\n // Externe sites zien alleen het domein, niet het volledige pad (privacy van bezoekers).\n { key: \"Referrer-Policy\", value: \"strict-origin-when-cross-origin\" },\n // Een klantsite heeft geen camera, microfoon of betaal-API nodig. Locatie: alleen de site zelf.\n { key: \"Permissions-Policy\", value: \"camera=(), microphone=(), payment=(), usb=(), geolocation=(self)\" },\n ];\n if (pad) headers.push({ key: \"Reporting-Endpoints\", value: `csp=\"${pad}\"` });\n return [{ source: \"/:path*\", headers }];\n}\n"],"mappings":"AAiDA,SAAS,MAAM,KAA8C;AAC3D,SAAO;AAAA,IACL,eAAe,CAAC,QAAQ;AAAA;AAAA;AAAA,IAGxB,cAAc,CAAC,UAAU,mBAAmB,qCAAqC,sCAAsC,2BAA2B,uBAAuB,GAAI,MAAM,CAAC,eAAe,IAAI,CAAC,CAAE;AAAA;AAAA,IAE1M,aAAa,CAAC,UAAU,mBAAmB,gCAAgC,qBAAqB;AAAA,IAChG,YAAY,CAAC,UAAU,SAAS,6BAA6B,uBAAuB,2BAA2B;AAAA;AAAA,IAE/G,WAAW,CAAC,UAAU,SAAS,SAAS,QAAQ;AAAA,IAChD,aAAa,CAAC,UAAU,SAAS,QAAQ;AAAA,IACzC,eAAe;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,MAAM,CAAC,OAAO,sBAAsB,oBAAoB,IAAI,CAAC;AAAA,IACnE;AAAA;AAAA;AAAA,IAGA,aAAa,CAAC,UAAU,QAAQ;AAAA,IAChC,cAAc,CAAC,UAAU,OAAO;AAAA;AAAA;AAAA,IAGhC,cAAc,CAAC,UAAU,QAAQ;AAAA,IACjC,YAAY,CAAC,QAAQ;AAAA,IACrB,eAAe,CAAC,UAAU,QAAQ;AAAA;AAAA,IAElC,mBAAmB,CAAC,QAAQ;AAAA,EAC9B;AACF;AAGO,SAAS,QAAQ,SAAoB,CAAC,GAAW;AACtD,QAAM,MAAM,OAAO,OAAO,QAAQ,IAAI,aAAa;AACnD,QAAM,IAAI,MAAM,GAAG;AACnB,aAAW,CAAC,GAAG,OAAO,KAAK,OAAO,QAAQ,OAAO,SAAS,CAAC,CAAC,GAAiC;AAC3F,MAAE,CAAC,IAAI,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAI,EAAE,CAAC,KAAK,CAAC,GAAI,GAAG,OAAO,CAAC,CAAC;AAAA,EACnD;AACA,QAAM,QAAQ,OAAO,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE;AAErE,MAAI,OAAO,aAAa,CAAC,IAAK,OAAM,KAAK,2BAA2B;AACpE,QAAM,MAAM,OAAO,eAAe,SAAY,qBAAqB,OAAO;AAC1E,MAAI,KAAK;AACP,UAAM,KAAK,cAAc,GAAG,EAAE;AAC9B,UAAM,KAAK,eAAe;AAAA,EAC5B;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAGO,SAAS,qBAAqB,SAAoB,CAAC,GAAkB;AAC1E,QAAM,MAAM,OAAO,eAAe,SAAY,qBAAqB,OAAO;AAC1E,QAAM,UAAU;AAAA,IACd,EAAE,KAAK,OAAO,YAAY,4BAA4B,uCAAuC,OAAO,QAAQ,MAAM,EAAE;AAAA;AAAA,IAEpH,EAAE,KAAK,0BAA0B,OAAO,UAAU;AAAA;AAAA,IAElD,EAAE,KAAK,mBAAmB,OAAO,kCAAkC;AAAA;AAAA,IAEnE,EAAE,KAAK,sBAAsB,OAAO,mEAAmE;AAAA,EACzG;AACA,MAAI,IAAK,SAAQ,KAAK,EAAE,KAAK,uBAAuB,OAAO,QAAQ,GAAG,IAAI,CAAC;AAC3E,SAAO,CAAC,EAAE,QAAQ,WAAW,QAAQ,CAAC;AACxC;","names":[]}
@@ -27,5 +27,12 @@ export declare const pageLanding: Pattern;
27
27
  export declare const pageServices: Pattern;
28
28
  export declare const pageAbout: Pattern;
29
29
  export declare const pageContact: Pattern;
30
+ export declare const pageTarieven: Pattern;
31
+ export declare const pageMenukaart: Pattern;
32
+ export declare const pageReserveren: Pattern;
33
+ export declare const pageTeam: Pattern;
34
+ export declare const pageVerhuur: Pattern;
35
+ export declare const pagePortfolio: Pattern;
36
+ export declare const pageAgenda: Pattern;
30
37
  /** Alle ingebouwde patronen. */
31
38
  export declare const builtinPatterns: Pattern[];