@xiwebdesign/xicms-core 4.17.1

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 (436) hide show
  1. package/dist/XiCMSProvider.d.ts +58 -0
  2. package/dist/XiCMSProvider.js +165 -0
  3. package/dist/XiCMSProvider.js.map +1 -0
  4. package/dist/admin/AdminApp.d.ts +4 -0
  5. package/dist/admin/AdminApp.js +62 -0
  6. package/dist/admin/AdminApp.js.map +1 -0
  7. package/dist/admin/AdminHelp.d.ts +2 -0
  8. package/dist/admin/AdminHelp.js +65 -0
  9. package/dist/admin/AdminHelp.js.map +1 -0
  10. package/dist/admin/NewsEditor.d.ts +2 -0
  11. package/dist/admin/NewsEditor.js +171 -0
  12. package/dist/admin/NewsEditor.js.map +1 -0
  13. package/dist/admin/SuperadminPanel.d.ts +4 -0
  14. package/dist/admin/SuperadminPanel.js +101 -0
  15. package/dist/admin/SuperadminPanel.js.map +1 -0
  16. package/dist/admin/blockEditors/StyleEditor.d.ts +10 -0
  17. package/dist/admin/blockEditors/StyleEditor.js +78 -0
  18. package/dist/admin/blockEditors/StyleEditor.js.map +1 -0
  19. package/dist/admin/blockEditors/index.d.ts +16 -0
  20. package/dist/admin/blockEditors/index.js +1602 -0
  21. package/dist/admin/blockEditors/index.js.map +1 -0
  22. package/dist/admin/editors/RichTextEditor.d.ts +10 -0
  23. package/dist/admin/editors/RichTextEditor.js +86 -0
  24. package/dist/admin/editors/RichTextEditor.js.map +1 -0
  25. package/dist/admin/forms/FormsPanel.d.ts +3 -0
  26. package/dist/admin/forms/FormsPanel.js +203 -0
  27. package/dist/admin/forms/FormsPanel.js.map +1 -0
  28. package/dist/admin/index.d.ts +21 -0
  29. package/dist/admin/index.js +38 -0
  30. package/dist/admin/index.js.map +1 -0
  31. package/dist/admin/lib/compressImage.d.ts +12 -0
  32. package/dist/admin/lib/compressImage.js +53 -0
  33. package/dist/admin/lib/compressImage.js.map +1 -0
  34. package/dist/admin/lib/mediaUsage.d.ts +9 -0
  35. package/dist/admin/lib/mediaUsage.js +25 -0
  36. package/dist/admin/lib/mediaUsage.js.map +1 -0
  37. package/dist/admin/lib/pagesClient.d.ts +38 -0
  38. package/dist/admin/lib/pagesClient.js +143 -0
  39. package/dist/admin/lib/pagesClient.js.map +1 -0
  40. package/dist/admin/lib/slugify.d.ts +2 -0
  41. package/dist/admin/lib/slugify.js +7 -0
  42. package/dist/admin/lib/slugify.js.map +1 -0
  43. package/dist/admin/lib/upload.d.ts +13 -0
  44. package/dist/admin/lib/upload.js +40 -0
  45. package/dist/admin/lib/upload.js.map +1 -0
  46. package/dist/admin/lib/zodFields.d.ts +27 -0
  47. package/dist/admin/lib/zodFields.js +48 -0
  48. package/dist/admin/lib/zodFields.js.map +1 -0
  49. package/dist/admin/media/MediaManager.d.ts +3 -0
  50. package/dist/admin/media/MediaManager.js +132 -0
  51. package/dist/admin/media/MediaManager.js.map +1 -0
  52. package/dist/admin/media/MediaPicker.d.ts +24 -0
  53. package/dist/admin/media/MediaPicker.js +93 -0
  54. package/dist/admin/media/MediaPicker.js.map +1 -0
  55. package/dist/admin/pages/PageEditor.d.ts +5 -0
  56. package/dist/admin/pages/PageEditor.js +239 -0
  57. package/dist/admin/pages/PageEditor.js.map +1 -0
  58. package/dist/admin/pages/PagesPanel.d.ts +3 -0
  59. package/dist/admin/pages/PagesPanel.js +92 -0
  60. package/dist/admin/pages/PagesPanel.js.map +1 -0
  61. package/dist/admin/panelRegistry.d.ts +20 -0
  62. package/dist/admin/panelRegistry.js +23 -0
  63. package/dist/admin/panelRegistry.js.map +1 -0
  64. package/dist/admin/patterns/PatternInserter.d.ts +10 -0
  65. package/dist/admin/patterns/PatternInserter.js +58 -0
  66. package/dist/admin/patterns/PatternInserter.js.map +1 -0
  67. package/dist/admin/settings/SettingsPanel.d.ts +3 -0
  68. package/dist/admin/settings/SettingsPanel.js +304 -0
  69. package/dist/admin/settings/SettingsPanel.js.map +1 -0
  70. package/dist/admin/settings/moduleSettingsForm.d.ts +12 -0
  71. package/dist/admin/settings/moduleSettingsForm.js +45 -0
  72. package/dist/admin/settings/moduleSettingsForm.js.map +1 -0
  73. package/dist/admin/stats/StatsPanel.d.ts +4 -0
  74. package/dist/admin/stats/StatsPanel.js +80 -0
  75. package/dist/admin/stats/StatsPanel.js.map +1 -0
  76. package/dist/admin/ui/ArrayEditor.d.ts +16 -0
  77. package/dist/admin/ui/ArrayEditor.js +38 -0
  78. package/dist/admin/ui/ArrayEditor.js.map +1 -0
  79. package/dist/admin/ui/ConfirmDialog.d.ts +22 -0
  80. package/dist/admin/ui/ConfirmDialog.js +47 -0
  81. package/dist/admin/ui/ConfirmDialog.js.map +1 -0
  82. package/dist/admin/ui/cn.d.ts +3 -0
  83. package/dist/admin/ui/cn.js +9 -0
  84. package/dist/admin/ui/cn.js.map +1 -0
  85. package/dist/admin/ui/dialog.d.ts +9 -0
  86. package/dist/admin/ui/dialog.js +47 -0
  87. package/dist/admin/ui/dialog.js.map +1 -0
  88. package/dist/admin/ui/index.d.ts +7 -0
  89. package/dist/admin/ui/index.js +29 -0
  90. package/dist/admin/ui/index.js.map +1 -0
  91. package/dist/admin/ui/primitives.d.ts +37 -0
  92. package/dist/admin/ui/primitives.js +137 -0
  93. package/dist/admin/ui/primitives.js.map +1 -0
  94. package/dist/admin/ui/select.d.ts +11 -0
  95. package/dist/admin/ui/select.js +27 -0
  96. package/dist/admin/ui/select.js.map +1 -0
  97. package/dist/admin/ui/switch.d.ts +6 -0
  98. package/dist/admin/ui/switch.js +22 -0
  99. package/dist/admin/ui/switch.js.map +1 -0
  100. package/dist/admin/ui/tabs.d.ts +5 -0
  101. package/dist/admin/ui/tabs.js +36 -0
  102. package/dist/admin/ui/tabs.js.map +1 -0
  103. package/dist/admin/ui/toast.d.ts +19 -0
  104. package/dist/admin/ui/toast.js +24 -0
  105. package/dist/admin/ui/toast.js.map +1 -0
  106. package/dist/admin/visual/VisualEditor.d.ts +10 -0
  107. package/dist/admin/visual/VisualEditor.js +597 -0
  108. package/dist/admin/visual/VisualEditor.js.map +1 -0
  109. package/dist/admin/visual/reorder.d.ts +6 -0
  110. package/dist/admin/visual/reorder.js +12 -0
  111. package/dist/admin/visual/reorder.js.map +1 -0
  112. package/dist/admin.css +1 -0
  113. package/dist/auth/AuthProvider.d.ts +30 -0
  114. package/dist/auth/AuthProvider.js +110 -0
  115. package/dist/auth/AuthProvider.js.map +1 -0
  116. package/dist/auth/LoginForm.d.ts +4 -0
  117. package/dist/auth/LoginForm.js +122 -0
  118. package/dist/auth/LoginForm.js.map +1 -0
  119. package/dist/auth/roles.d.ts +15 -0
  120. package/dist/auth/roles.js +21 -0
  121. package/dist/auth/roles.js.map +1 -0
  122. package/dist/blocks/BlockErrorBoundary.d.ts +32 -0
  123. package/dist/blocks/BlockErrorBoundary.js +39 -0
  124. package/dist/blocks/BlockErrorBoundary.js.map +1 -0
  125. package/dist/blocks/BlockRenderer.d.ts +15 -0
  126. package/dist/blocks/BlockRenderer.js +24 -0
  127. package/dist/blocks/BlockRenderer.js.map +1 -0
  128. package/dist/blocks/blockStyle.d.ts +14 -0
  129. package/dist/blocks/blockStyle.js +14 -0
  130. package/dist/blocks/blockStyle.js.map +1 -0
  131. package/dist/blocks/builtins/Accordion.d.ts +2 -0
  132. package/dist/blocks/builtins/Accordion.js +45 -0
  133. package/dist/blocks/builtins/Accordion.js.map +1 -0
  134. package/dist/blocks/builtins/Agenda.d.ts +23 -0
  135. package/dist/blocks/builtins/Agenda.js +102 -0
  136. package/dist/blocks/builtins/Agenda.js.map +1 -0
  137. package/dist/blocks/builtins/Banner.d.ts +2 -0
  138. package/dist/blocks/builtins/Banner.js +45 -0
  139. package/dist/blocks/builtins/Banner.js.map +1 -0
  140. package/dist/blocks/builtins/BeforeAfter.d.ts +2 -0
  141. package/dist/blocks/builtins/BeforeAfter.js +44 -0
  142. package/dist/blocks/builtins/BeforeAfter.js.map +1 -0
  143. package/dist/blocks/builtins/Booking.d.ts +2 -0
  144. package/dist/blocks/builtins/Booking.js +27 -0
  145. package/dist/blocks/builtins/Booking.js.map +1 -0
  146. package/dist/blocks/builtins/Breadcrumbs.d.ts +10 -0
  147. package/dist/blocks/builtins/Breadcrumbs.js +73 -0
  148. package/dist/blocks/builtins/Breadcrumbs.js.map +1 -0
  149. package/dist/blocks/builtins/Cards.d.ts +2 -0
  150. package/dist/blocks/builtins/Cards.js +94 -0
  151. package/dist/blocks/builtins/Cards.js.map +1 -0
  152. package/dist/blocks/builtins/Columns.d.ts +2 -0
  153. package/dist/blocks/builtins/Columns.js +22 -0
  154. package/dist/blocks/builtins/Columns.js.map +1 -0
  155. package/dist/blocks/builtins/Contact.d.ts +7 -0
  156. package/dist/blocks/builtins/Contact.js +121 -0
  157. package/dist/blocks/builtins/Contact.js.map +1 -0
  158. package/dist/blocks/builtins/Countdown.d.ts +18 -0
  159. package/dist/blocks/builtins/Countdown.js +65 -0
  160. package/dist/blocks/builtins/Countdown.js.map +1 -0
  161. package/dist/blocks/builtins/Cta.d.ts +2 -0
  162. package/dist/blocks/builtins/Cta.js +52 -0
  163. package/dist/blocks/builtins/Cta.js.map +1 -0
  164. package/dist/blocks/builtins/Downloads.d.ts +2 -0
  165. package/dist/blocks/builtins/Downloads.js +32 -0
  166. package/dist/blocks/builtins/Downloads.js.map +1 -0
  167. package/dist/blocks/builtins/Elements.d.ts +4 -0
  168. package/dist/blocks/builtins/Elements.js +64 -0
  169. package/dist/blocks/builtins/Elements.js.map +1 -0
  170. package/dist/blocks/builtins/Embed.d.ts +2 -0
  171. package/dist/blocks/builtins/Embed.js +30 -0
  172. package/dist/blocks/builtins/Embed.js.map +1 -0
  173. package/dist/blocks/builtins/Faq.d.ts +6 -0
  174. package/dist/blocks/builtins/Faq.js +110 -0
  175. package/dist/blocks/builtins/Faq.js.map +1 -0
  176. package/dist/blocks/builtins/FormBlock.d.ts +2 -0
  177. package/dist/blocks/builtins/FormBlock.js +221 -0
  178. package/dist/blocks/builtins/FormBlock.js.map +1 -0
  179. package/dist/blocks/builtins/Gallery.d.ts +23 -0
  180. package/dist/blocks/builtins/Gallery.js +177 -0
  181. package/dist/blocks/builtins/Gallery.js.map +1 -0
  182. package/dist/blocks/builtins/Hero.d.ts +2 -0
  183. package/dist/blocks/builtins/Hero.js +47 -0
  184. package/dist/blocks/builtins/Hero.js.map +1 -0
  185. package/dist/blocks/builtins/ImageBlock.d.ts +2 -0
  186. package/dist/blocks/builtins/ImageBlock.js +24 -0
  187. package/dist/blocks/builtins/ImageBlock.js.map +1 -0
  188. package/dist/blocks/builtins/Jobs.d.ts +8 -0
  189. package/dist/blocks/builtins/Jobs.js +65 -0
  190. package/dist/blocks/builtins/Jobs.js.map +1 -0
  191. package/dist/blocks/builtins/Layout.d.ts +3 -0
  192. package/dist/blocks/builtins/Layout.js +67 -0
  193. package/dist/blocks/builtins/Layout.js.map +1 -0
  194. package/dist/blocks/builtins/MapBlock.d.ts +2 -0
  195. package/dist/blocks/builtins/MapBlock.js +31 -0
  196. package/dist/blocks/builtins/MapBlock.js.map +1 -0
  197. package/dist/blocks/builtins/NewsListBlock.d.ts +2 -0
  198. package/dist/blocks/builtins/NewsListBlock.js +24 -0
  199. package/dist/blocks/builtins/NewsListBlock.js.map +1 -0
  200. package/dist/blocks/builtins/Newsletter.d.ts +2 -0
  201. package/dist/blocks/builtins/Newsletter.js +84 -0
  202. package/dist/blocks/builtins/Newsletter.js.map +1 -0
  203. package/dist/blocks/builtins/OpenNowBadge.d.ts +9 -0
  204. package/dist/blocks/builtins/OpenNowBadge.js +20 -0
  205. package/dist/blocks/builtins/OpenNowBadge.js.map +1 -0
  206. package/dist/blocks/builtins/OpeningHours.d.ts +2 -0
  207. package/dist/blocks/builtins/OpeningHours.js +47 -0
  208. package/dist/blocks/builtins/OpeningHours.js.map +1 -0
  209. package/dist/blocks/builtins/PdfBlock.d.ts +2 -0
  210. package/dist/blocks/builtins/PdfBlock.js +97 -0
  211. package/dist/blocks/builtins/PdfBlock.js.map +1 -0
  212. package/dist/blocks/builtins/Portfolio.d.ts +2 -0
  213. package/dist/blocks/builtins/Portfolio.js +94 -0
  214. package/dist/blocks/builtins/Portfolio.js.map +1 -0
  215. package/dist/blocks/builtins/Pricing.d.ts +6 -0
  216. package/dist/blocks/builtins/Pricing.js +77 -0
  217. package/dist/blocks/builtins/Pricing.js.map +1 -0
  218. package/dist/blocks/builtins/RichTextBlock.d.ts +2 -0
  219. package/dist/blocks/builtins/RichTextBlock.js +18 -0
  220. package/dist/blocks/builtins/RichTextBlock.js.map +1 -0
  221. package/dist/blocks/builtins/Search.d.ts +2 -0
  222. package/dist/blocks/builtins/Search.js +99 -0
  223. package/dist/blocks/builtins/Search.js.map +1 -0
  224. package/dist/blocks/builtins/Sections.d.ts +5 -0
  225. package/dist/blocks/builtins/Sections.js +183 -0
  226. package/dist/blocks/builtins/Sections.js.map +1 -0
  227. package/dist/blocks/builtins/Slider.d.ts +2 -0
  228. package/dist/blocks/builtins/Slider.js +131 -0
  229. package/dist/blocks/builtins/Slider.js.map +1 -0
  230. package/dist/blocks/builtins/Spacer.d.ts +2 -0
  231. package/dist/blocks/builtins/Spacer.js +19 -0
  232. package/dist/blocks/builtins/Spacer.js.map +1 -0
  233. package/dist/blocks/builtins/Team.d.ts +2 -0
  234. package/dist/blocks/builtins/Team.js +70 -0
  235. package/dist/blocks/builtins/Team.js.map +1 -0
  236. package/dist/blocks/builtins/Testimonials.d.ts +8 -0
  237. package/dist/blocks/builtins/Testimonials.js +82 -0
  238. package/dist/blocks/builtins/Testimonials.js.map +1 -0
  239. package/dist/blocks/builtins/Video.d.ts +9 -0
  240. package/dist/blocks/builtins/Video.js +77 -0
  241. package/dist/blocks/builtins/Video.js.map +1 -0
  242. package/dist/blocks/builtins/WhatsappChat.d.ts +8 -0
  243. package/dist/blocks/builtins/WhatsappChat.js +51 -0
  244. package/dist/blocks/builtins/WhatsappChat.js.map +1 -0
  245. package/dist/blocks/builtins/Widgets.d.ts +13 -0
  246. package/dist/blocks/builtins/Widgets.js +308 -0
  247. package/dist/blocks/builtins/Widgets.js.map +1 -0
  248. package/dist/blocks/builtins/consentEmbed.d.ts +17 -0
  249. package/dist/blocks/builtins/consentEmbed.js +31 -0
  250. package/dist/blocks/builtins/consentEmbed.js.map +1 -0
  251. package/dist/blocks/builtins/index.d.ts +46 -0
  252. package/dist/blocks/builtins/index.js +121 -0
  253. package/dist/blocks/builtins/index.js.map +1 -0
  254. package/dist/blocks/builtins/lib/bookingUrl.d.ts +8 -0
  255. package/dist/blocks/builtins/lib/bookingUrl.js +50 -0
  256. package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -0
  257. package/dist/blocks/builtins/lib/fileIcon.d.ts +2 -0
  258. package/dist/blocks/builtins/lib/fileIcon.js +45 -0
  259. package/dist/blocks/builtins/lib/fileIcon.js.map +1 -0
  260. package/dist/blocks/builtins/lib/ics.d.ts +17 -0
  261. package/dist/blocks/builtins/lib/ics.js +50 -0
  262. package/dist/blocks/builtins/lib/ics.js.map +1 -0
  263. package/dist/blocks/builtins/lib/openingHours.d.ts +20 -0
  264. package/dist/blocks/builtins/lib/openingHours.js +79 -0
  265. package/dist/blocks/builtins/lib/openingHours.js.map +1 -0
  266. package/dist/blocks/builtins/lib/searchRank.d.ts +22 -0
  267. package/dist/blocks/builtins/lib/searchRank.js +45 -0
  268. package/dist/blocks/builtins/lib/searchRank.js.map +1 -0
  269. package/dist/blocks/builtins/lib/submitForm.d.ts +6 -0
  270. package/dist/blocks/builtins/lib/submitForm.js +14 -0
  271. package/dist/blocks/builtins/lib/submitForm.js.map +1 -0
  272. package/dist/blocks/context.d.ts +8 -0
  273. package/dist/blocks/context.js +20 -0
  274. package/dist/blocks/context.js.map +1 -0
  275. package/dist/blocks/index.d.ts +9 -0
  276. package/dist/blocks/index.js +21 -0
  277. package/dist/blocks/index.js.map +1 -0
  278. package/dist/blocks/registry.d.ts +75 -0
  279. package/dist/blocks/registry.js +71 -0
  280. package/dist/blocks/registry.js.map +1 -0
  281. package/dist/blocks/ui/index.d.ts +35 -0
  282. package/dist/blocks/ui/index.js +48 -0
  283. package/dist/blocks/ui/index.js.map +1 -0
  284. package/dist/components/EditBar.d.ts +2 -0
  285. package/dist/components/EditBar.js +20 -0
  286. package/dist/components/EditBar.js.map +1 -0
  287. package/dist/components/EditableImage.d.ts +18 -0
  288. package/dist/components/EditableImage.js +62 -0
  289. package/dist/components/EditableImage.js.map +1 -0
  290. package/dist/components/EditableRichText.d.ts +14 -0
  291. package/dist/components/EditableRichText.js +26 -0
  292. package/dist/components/EditableRichText.js.map +1 -0
  293. package/dist/components/EditableText.d.ts +21 -0
  294. package/dist/components/EditableText.js +25 -0
  295. package/dist/components/EditableText.js.map +1 -0
  296. package/dist/components/News.d.ts +38 -0
  297. package/dist/components/News.js +128 -0
  298. package/dist/components/News.js.map +1 -0
  299. package/dist/components/PageView.d.ts +8 -0
  300. package/dist/components/PageView.js +28 -0
  301. package/dist/components/PageView.js.map +1 -0
  302. package/dist/components/ResponsiveImage.d.ts +16 -0
  303. package/dist/components/ResponsiveImage.js +39 -0
  304. package/dist/components/ResponsiveImage.js.map +1 -0
  305. package/dist/components/site/SiteFooter.d.ts +12 -0
  306. package/dist/components/site/SiteFooter.js +34 -0
  307. package/dist/components/site/SiteFooter.js.map +1 -0
  308. package/dist/config.d.ts +8 -0
  309. package/dist/config.js +17 -0
  310. package/dist/config.js.map +1 -0
  311. package/dist/content/ContentProvider.d.ts +23 -0
  312. package/dist/content/ContentProvider.js +86 -0
  313. package/dist/content/ContentProvider.js.map +1 -0
  314. package/dist/content/types.d.ts +41 -0
  315. package/dist/content/types.js +1 -0
  316. package/dist/content/types.js.map +1 -0
  317. package/dist/demo/DemoStudio.d.ts +7 -0
  318. package/dist/demo/DemoStudio.js +54 -0
  319. package/dist/demo/DemoStudio.js.map +1 -0
  320. package/dist/demo/demoStore.d.ts +26 -0
  321. package/dist/demo/demoStore.js +115 -0
  322. package/dist/demo/demoStore.js.map +1 -0
  323. package/dist/editor/EditorProvider.d.ts +12 -0
  324. package/dist/editor/EditorProvider.js +22 -0
  325. package/dist/editor/EditorProvider.js.map +1 -0
  326. package/dist/firebase/admin.d.ts +7 -0
  327. package/dist/firebase/admin.js +31 -0
  328. package/dist/firebase/admin.js.map +1 -0
  329. package/dist/firebase/appcheck.d.ts +6 -0
  330. package/dist/firebase/appcheck.js +23 -0
  331. package/dist/firebase/appcheck.js.map +1 -0
  332. package/dist/firebase/client.d.ts +9 -0
  333. package/dist/firebase/client.js +44 -0
  334. package/dist/firebase/client.js.map +1 -0
  335. package/dist/firebase/region.d.ts +5 -0
  336. package/dist/firebase/region.js +7 -0
  337. package/dist/firebase/region.js.map +1 -0
  338. package/dist/index.d.ts +54 -0
  339. package/dist/index.js +172 -0
  340. package/dist/index.js.map +1 -0
  341. package/dist/layers.css +13 -0
  342. package/dist/lock/DemoLock.d.ts +5 -0
  343. package/dist/lock/DemoLock.js +35 -0
  344. package/dist/lock/DemoLock.js.map +1 -0
  345. package/dist/media/ImageContext.d.ts +41 -0
  346. package/dist/media/ImageContext.js +74 -0
  347. package/dist/media/ImageContext.js.map +1 -0
  348. package/dist/modules/builtins.d.ts +46 -0
  349. package/dist/modules/builtins.js +462 -0
  350. package/dist/modules/builtins.js.map +1 -0
  351. package/dist/modules/consent/ConsentBanner.d.ts +42 -0
  352. package/dist/modules/consent/ConsentBanner.js +119 -0
  353. package/dist/modules/consent/ConsentBanner.js.map +1 -0
  354. package/dist/modules/consent/useConsent.d.ts +28 -0
  355. package/dist/modules/consent/useConsent.js +52 -0
  356. package/dist/modules/consent/useConsent.js.map +1 -0
  357. package/dist/modules/context.d.ts +20 -0
  358. package/dist/modules/context.js +31 -0
  359. package/dist/modules/context.js.map +1 -0
  360. package/dist/modules/contract.d.ts +9 -0
  361. package/dist/modules/contract.js +38 -0
  362. package/dist/modules/contract.js.map +1 -0
  363. package/dist/modules/defineModule.d.ts +11 -0
  364. package/dist/modules/defineModule.js +7 -0
  365. package/dist/modules/defineModule.js.map +1 -0
  366. package/dist/modules/index.d.ts +13 -0
  367. package/dist/modules/index.js +44 -0
  368. package/dist/modules/index.js.map +1 -0
  369. package/dist/modules/overrides.d.ts +17 -0
  370. package/dist/modules/overrides.js +25 -0
  371. package/dist/modules/overrides.js.map +1 -0
  372. package/dist/modules/registry.d.ts +40 -0
  373. package/dist/modules/registry.js +79 -0
  374. package/dist/modules/registry.js.map +1 -0
  375. package/dist/modules/types.d.ts +66 -0
  376. package/dist/modules/types.js +1 -0
  377. package/dist/modules/types.js.map +1 -0
  378. package/dist/patterns/builtins.d.ts +31 -0
  379. package/dist/patterns/builtins.js +415 -0
  380. package/dist/patterns/builtins.js.map +1 -0
  381. package/dist/patterns/index.d.ts +6 -0
  382. package/dist/patterns/index.js +9 -0
  383. package/dist/patterns/index.js.map +1 -0
  384. package/dist/patterns/patterns.d.ts +28 -0
  385. package/dist/patterns/patterns.js +53 -0
  386. package/dist/patterns/patterns.js.map +1 -0
  387. package/dist/render/PageRenderer.d.ts +13 -0
  388. package/dist/render/PageRenderer.js +14 -0
  389. package/dist/render/PageRenderer.js.map +1 -0
  390. package/dist/render/PublishedPage.d.ts +13 -0
  391. package/dist/render/PublishedPage.js +16 -0
  392. package/dist/render/PublishedPage.js.map +1 -0
  393. package/dist/schema/blocks.d.ts +15052 -0
  394. package/dist/schema/blocks.js +794 -0
  395. package/dist/schema/blocks.js.map +1 -0
  396. package/dist/schema/forms.d.ts +111 -0
  397. package/dist/schema/forms.js +47 -0
  398. package/dist/schema/forms.js.map +1 -0
  399. package/dist/schema/index.d.ts +11 -0
  400. package/dist/schema/index.js +16 -0
  401. package/dist/schema/index.js.map +1 -0
  402. package/dist/schema/pages.d.ts +674 -0
  403. package/dist/schema/pages.js +37 -0
  404. package/dist/schema/pages.js.map +1 -0
  405. package/dist/schema/seo.d.ts +29 -0
  406. package/dist/schema/seo.js +17 -0
  407. package/dist/schema/seo.js.map +1 -0
  408. package/dist/schema/settings.d.ts +1126 -0
  409. package/dist/schema/settings.js +128 -0
  410. package/dist/schema/settings.js.map +1 -0
  411. package/dist/schema/siteConfig.d.ts +722 -0
  412. package/dist/schema/siteConfig.js +39 -0
  413. package/dist/schema/siteConfig.js.map +1 -0
  414. package/dist/server/env.d.ts +10 -0
  415. package/dist/server/env.js +36 -0
  416. package/dist/server/env.js.map +1 -0
  417. package/dist/server/index.d.ts +10 -0
  418. package/dist/server/index.js +51 -0
  419. package/dist/server/index.js.map +1 -0
  420. package/dist/server/pages.d.ts +15 -0
  421. package/dist/server/pages.js +99 -0
  422. package/dist/server/pages.js.map +1 -0
  423. package/dist/server/sanitize.d.ts +2 -0
  424. package/dist/server/sanitize.js +55 -0
  425. package/dist/server/sanitize.js.map +1 -0
  426. package/dist/server/seo.d.ts +116 -0
  427. package/dist/server/seo.js +179 -0
  428. package/dist/server/seo.js.map +1 -0
  429. package/dist/settings/useSiteSettings.d.ts +25 -0
  430. package/dist/settings/useSiteSettings.js +68 -0
  431. package/dist/settings/useSiteSettings.js.map +1 -0
  432. package/dist/styles.css +2495 -0
  433. package/dist/theme/presets.d.ts +12 -0
  434. package/dist/theme/presets.js +147 -0
  435. package/dist/theme/presets.js.map +1 -0
  436. package/package.json +112 -0
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ import { NavItemSchema, ThemeSchema, FormsSenderSchema, ModulesSettingsSchema } from "./settings";
3
+ import { SeoSchema } from "./seo";
4
+ function defineSiteConfig(config) {
5
+ return config;
6
+ }
7
+ const SiteConfigSchema = z.object({
8
+ siteId: z.string().min(1).max(64).regex(/^[a-z0-9][a-z0-9-]*$/, "gebruik kleine letters/cijfers/koppeltekens (bv. 'bakkerij-jansen')"),
9
+ name: z.string().min(1).max(160),
10
+ domain: z.string().max(255).optional(),
11
+ mode: z.enum(["demo", "live"]),
12
+ demoEditing: z.boolean().optional(),
13
+ lang: z.string().max(10).optional(),
14
+ theme: ThemeSchema,
15
+ nav: z.array(NavItemSchema).max(50).optional(),
16
+ contactEmail: z.string().email().optional(),
17
+ seoDefaults: SeoSchema.optional(),
18
+ forms: FormsSenderSchema.optional(),
19
+ defaults: z.record(z.string(), z.string()).optional(),
20
+ features: z.object({
21
+ pages: z.boolean().optional(),
22
+ news: z.boolean().optional(),
23
+ media: z.boolean().optional(),
24
+ forms: z.boolean().optional(),
25
+ stats: z.boolean().optional()
26
+ }).optional(),
27
+ modules: ModulesSettingsSchema.optional()
28
+ }).passthrough();
29
+ function validateSiteConfig(config) {
30
+ const res = SiteConfigSchema.safeParse(config);
31
+ if (res.success) return [];
32
+ return res.error.issues.map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`);
33
+ }
34
+ export {
35
+ SiteConfigSchema,
36
+ defineSiteConfig,
37
+ validateSiteConfig
38
+ };
39
+ //# sourceMappingURL=siteConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/schema/siteConfig.ts"],"sourcesContent":["/**\n * SiteConfig — de statische basisconfig in een klantrepo (`content/site.config.ts`).\n * Dit is de fallback/identiteit van de site; bewerkbare instellingen kunnen in Firebase\n * (`sites/{siteId}/settings/site`) staan en deze waarden overschrijven.\n *\n * `@xiwebdesign/xicms-core` bevat hier nooit klantgegevens — die staan in de klantrepo.\n */\nimport { z } from \"zod\";\nimport { NavItemSchema, ThemeSchema, FormsSenderSchema, ModulesSettingsSchema, type NavItem, type ThemeTokens, type FormsSender } from \"./settings\";\nimport { SeoSchema, type Seo } from \"./seo\";\nimport type { ModulesSiteConfig } from \"../modules/types\";\n\nexport type SiteMode = \"demo\" | \"live\";\n\nexport interface SiteConfig {\n /** Uniek tenant-id; bepaalt het pad `sites/{siteId}/...` in Firebase. */\n siteId: string;\n /** Weergavenaam van het bedrijf. */\n name: string;\n /** Productiedomein, bv. \"www.bakkerijjansen.nl\". */\n domain?: string;\n /** \"demo\" toont de lock/CTA; \"live\" is de productiestand. */\n mode: SiteMode;\n /**\n * Demo-bewerkmodus: toont een pseudo-login zodat bezoekers het beheer (teksten + blokken) kunnen\n * uitproberen. Alle \"bewerkingen\" blijven UITSLUITEND lokaal in de browser (localStorage) — er gaat\n * niets naar Firebase. Alleen bedoeld voor een demo-site; laat dit `false`/weg op echte klantsites.\n */\n demoEditing?: boolean;\n /** Taalcode voor `<html lang>` en a11y (default \"nl\"). */\n lang?: string;\n /** Huisstijl. */\n theme: ThemeTokens;\n /** Hoofdnavigatie. */\n nav?: NavItem[];\n /** Contact-e-mailadres voor de demo-CTA en formulieren. */\n contactEmail?: string;\n /** Standaard-SEO als een pagina niets opgeeft. */\n seoDefaults?: Seo;\n /** Afzender-instelling voor formulier-e-mail (fallback voor settings/site). */\n forms?: FormsSender;\n /**\n * @deprecated Legacy standaardteksten per content-id (v1 plat model). Blijven werken via de\n * (eveneens deprecated) `Editable*`-componenten zolang er nog geen pagina-blocks zijn.\n */\n defaults?: Record<string, string>;\n /**\n * @deprecated Gebruik `modules` (XiCMS 3.0). Blijft werken als legacy-brug: `features[key] ===\n * false` zet de bijbehorende module uit. Aan/uit zetten van optionele beheer-panelen.\n */\n features?: {\n pages?: boolean;\n news?: boolean;\n media?: boolean;\n forms?: boolean;\n stats?: boolean;\n };\n /**\n * Modules per site aan/uit zetten en configureren (XiCMS 3.0). Een uitgezette module verbergt\n * zowel zijn blocks als zijn beheer-paneel. Per module kun je ook `config` meegeven (gevalideerd\n * tegen het `settingsSchema` van de module) zodat de agent gedrag instelt zonder core te forken:\n *\n * modules: {\n * gallery: { enabled: true, config: { lightbox: true, columns: 3 } },\n * stats: false,\n * }\n *\n * Afwezig = de standaard van de module (`defaultEnabled`, doorgaans aan).\n */\n modules?: ModulesSiteConfig;\n}\n\n/** Helper met type-inferentie voor `site.config.ts`. */\nexport function defineSiteConfig(config: SiteConfig): SiteConfig {\n return config;\n}\n\n/**\n * Runtime-spiegel van de `SiteConfig`-interface. TypeScript vangt fouten bij compileren, maar een\n * (agent-)geschreven `site.config.ts` kan alsnog ongeldige waarden bevatten (verkeerd siteId-formaat,\n * te lange strings, kapotte nav-items). `.passthrough()` zodat extra klant-velden nooit een fout zijn.\n */\nexport const SiteConfigSchema = z\n .object({\n siteId: z\n .string()\n .min(1)\n .max(64)\n .regex(/^[a-z0-9][a-z0-9-]*$/, \"gebruik kleine letters/cijfers/koppeltekens (bv. 'bakkerij-jansen')\"),\n name: z.string().min(1).max(160),\n domain: z.string().max(255).optional(),\n mode: z.enum([\"demo\", \"live\"]),\n demoEditing: z.boolean().optional(),\n lang: z.string().max(10).optional(),\n theme: ThemeSchema,\n nav: z.array(NavItemSchema).max(50).optional(),\n contactEmail: z.string().email().optional(),\n seoDefaults: SeoSchema.optional(),\n forms: FormsSenderSchema.optional(),\n defaults: z.record(z.string(), z.string()).optional(),\n features: z\n .object({\n pages: z.boolean().optional(),\n news: z.boolean().optional(),\n media: z.boolean().optional(),\n forms: z.boolean().optional(),\n stats: z.boolean().optional(),\n })\n .optional(),\n modules: ModulesSettingsSchema.optional(),\n })\n .passthrough();\n\n/**\n * Valideert een SiteConfig en geeft leesbare issues terug (leeg = geldig). Wordt in development\n * door de provider aangeroepen zodat een agent config-fouten direct in de console ziet, in plaats\n * van een subtiel kapotte site. Gooit bewust niet — een issue mag een site nooit platleggen.\n */\nexport function validateSiteConfig(config: unknown): string[] {\n const res = SiteConfigSchema.safeParse(config);\n if (res.success) return [];\n return res.error.issues.map((i) => `${i.path.join(\".\") || \"(root)\"}: ${i.message}`);\n}\n"],"mappings":"AAOA,SAAS,SAAS;AAClB,SAAS,eAAe,aAAa,mBAAmB,6BAA+E;AACvI,SAAS,iBAA2B;AAgE7B,SAAS,iBAAiB,QAAgC;AAC/D,SAAO;AACT;AAOO,MAAM,mBAAmB,EAC7B,OAAO;AAAA,EACN,QAAQ,EACL,OAAO,EACP,IAAI,CAAC,EACL,IAAI,EAAE,EACN,MAAM,wBAAwB,qEAAqE;AAAA,EACtG,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC/B,QAAQ,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACrC,MAAM,EAAE,KAAK,CAAC,QAAQ,MAAM,CAAC;AAAA,EAC7B,aAAa,EAAE,QAAQ,EAAE,SAAS;AAAA,EAClC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EAClC,OAAO;AAAA,EACP,KAAK,EAAE,MAAM,aAAa,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EAC7C,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS;AAAA,EAC1C,aAAa,UAAU,SAAS;AAAA,EAChC,OAAO,kBAAkB,SAAS;AAAA,EAClC,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACpD,UAAU,EACP,OAAO;AAAA,IACN,OAAO,EAAE,QAAQ,EAAE,SAAS;AAAA,IAC5B,MAAM,EAAE,QAAQ,EAAE,SAAS;AAAA,IAC3B,OAAO,EAAE,QAAQ,EAAE,SAAS;AAAA,IAC5B,OAAO,EAAE,QAAQ,EAAE,SAAS;AAAA,IAC5B,OAAO,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,CAAC,EACA,SAAS;AAAA,EACZ,SAAS,sBAAsB,SAAS;AAC1C,CAAC,EACA,YAAY;AAOR,SAAS,mBAAmB,QAA2B;AAC5D,QAAM,MAAM,iBAAiB,UAAU,MAAM;AAC7C,MAAI,IAAI,QAAS,QAAO,CAAC;AACzB,SAAO,IAAI,MAAM,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,KAAK,GAAG,KAAK,QAAQ,KAAK,EAAE,OAAO,EAAE;AACpF;","names":[]}
@@ -0,0 +1,10 @@
1
+ import "server-only";
2
+ export interface EnvReport {
3
+ ok: boolean;
4
+ /** Firebase volledig geconfigureerd (apiKey + projectId aanwezig). */
5
+ firebaseConfigured: boolean;
6
+ problems: string[];
7
+ }
8
+ export declare function validateEnv(env?: NodeJS.ProcessEnv): EnvReport;
9
+ /** Gooit als de env ongeldig is. Gebruik in build/serverstart om snel te falen. */
10
+ export declare function assertEnv(env?: NodeJS.ProcessEnv): void;
@@ -0,0 +1,36 @@
1
+ import "server-only";
2
+ import { z } from "zod";
3
+ const EnvSchema = z.object({
4
+ NEXT_PUBLIC_FIREBASE_API_KEY: z.string().min(1).optional(),
5
+ NEXT_PUBLIC_FIREBASE_PROJECT_ID: z.string().min(1).optional(),
6
+ NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: z.string().optional(),
7
+ NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET: z.string().optional(),
8
+ NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: z.string().optional(),
9
+ NEXT_PUBLIC_FIREBASE_APP_ID: z.string().optional(),
10
+ NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION: z.string().optional()
11
+ });
12
+ function validateEnv(env = process.env) {
13
+ const problems = [];
14
+ const parsed = EnvSchema.safeParse(env);
15
+ if (!parsed.success) {
16
+ for (const issue of parsed.error.issues) problems.push(`${issue.path.join(".")}: ${issue.message}`);
17
+ }
18
+ const apiKey = env.NEXT_PUBLIC_FIREBASE_API_KEY;
19
+ const projectId = env.NEXT_PUBLIC_FIREBASE_PROJECT_ID;
20
+ const firebaseConfigured = Boolean(apiKey && projectId);
21
+ if (apiKey && !projectId) problems.push("NEXT_PUBLIC_FIREBASE_PROJECT_ID ontbreekt (apiKey is w\xE9l gezet).");
22
+ if (!apiKey && projectId) problems.push("NEXT_PUBLIC_FIREBASE_API_KEY ontbreekt (projectId is w\xE9l gezet).");
23
+ return { ok: problems.length === 0, firebaseConfigured, problems };
24
+ }
25
+ function assertEnv(env = process.env) {
26
+ const report = validateEnv(env);
27
+ if (!report.ok) {
28
+ throw new Error(`XiCMS env-configuratie ongeldig:
29
+ - ${report.problems.join("\n- ")}`);
30
+ }
31
+ }
32
+ export {
33
+ assertEnv,
34
+ validateEnv
35
+ };
36
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/env.ts"],"sourcesContent":["import \"server-only\";\n\nimport { z } from \"zod\";\n\n/**\n * Env-validatie — vangt ontbrekende/foute Firebase-config vroeg (bij build/serverstart) i.p.v.\n * een cryptische runtime-fout later. Roep `validateEnv()` aan in een server-context (bv. de\n * sitemap-route of een instrumentation-hook). `assertEnv()` gooit; `validateEnv()` rapporteert.\n */\nconst EnvSchema = z.object({\n NEXT_PUBLIC_FIREBASE_API_KEY: z.string().min(1).optional(),\n NEXT_PUBLIC_FIREBASE_PROJECT_ID: z.string().min(1).optional(),\n NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: z.string().optional(),\n NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET: z.string().optional(),\n NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: z.string().optional(),\n NEXT_PUBLIC_FIREBASE_APP_ID: z.string().optional(),\n NEXT_PUBLIC_FIREBASE_FUNCTIONS_REGION: z.string().optional(),\n});\n\nexport interface EnvReport {\n ok: boolean;\n /** Firebase volledig geconfigureerd (apiKey + projectId aanwezig). */\n firebaseConfigured: boolean;\n problems: string[];\n}\n\nexport function validateEnv(env: NodeJS.ProcessEnv = process.env): EnvReport {\n const problems: string[] = [];\n const parsed = EnvSchema.safeParse(env);\n if (!parsed.success) {\n for (const issue of parsed.error.issues) problems.push(`${issue.path.join(\".\")}: ${issue.message}`);\n }\n const apiKey = env.NEXT_PUBLIC_FIREBASE_API_KEY;\n const projectId = env.NEXT_PUBLIC_FIREBASE_PROJECT_ID;\n const firebaseConfigured = Boolean(apiKey && projectId);\n\n // Half-geconfigureerd is een veelvoorkomende, lastig te debuggen fout: meld het expliciet.\n if (apiKey && !projectId) problems.push(\"NEXT_PUBLIC_FIREBASE_PROJECT_ID ontbreekt (apiKey is wél gezet).\");\n if (!apiKey && projectId) problems.push(\"NEXT_PUBLIC_FIREBASE_API_KEY ontbreekt (projectId is wél gezet).\");\n\n return { ok: problems.length === 0, firebaseConfigured, problems };\n}\n\n/** Gooit als de env ongeldig is. Gebruik in build/serverstart om snel te falen. */\nexport function assertEnv(env: NodeJS.ProcessEnv = process.env): void {\n const report = validateEnv(env);\n if (!report.ok) {\n throw new Error(`XiCMS env-configuratie ongeldig:\\n- ${report.problems.join(\"\\n- \")}`);\n }\n}\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,SAAS;AAOlB,MAAM,YAAY,EAAE,OAAO;AAAA,EACzB,8BAA8B,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACzD,iCAAiC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAC5D,kCAAkC,EAAE,OAAO,EAAE,SAAS;AAAA,EACtD,qCAAqC,EAAE,OAAO,EAAE,SAAS;AAAA,EACzD,0CAA0C,EAAE,OAAO,EAAE,SAAS;AAAA,EAC9D,6BAA6B,EAAE,OAAO,EAAE,SAAS;AAAA,EACjD,uCAAuC,EAAE,OAAO,EAAE,SAAS;AAC7D,CAAC;AASM,SAAS,YAAY,MAAyB,QAAQ,KAAgB;AAC3E,QAAM,WAAqB,CAAC;AAC5B,QAAM,SAAS,UAAU,UAAU,GAAG;AACtC,MAAI,CAAC,OAAO,SAAS;AACnB,eAAW,SAAS,OAAO,MAAM,OAAQ,UAAS,KAAK,GAAG,MAAM,KAAK,KAAK,GAAG,CAAC,KAAK,MAAM,OAAO,EAAE;AAAA,EACpG;AACA,QAAM,SAAS,IAAI;AACnB,QAAM,YAAY,IAAI;AACtB,QAAM,qBAAqB,QAAQ,UAAU,SAAS;AAGtD,MAAI,UAAU,CAAC,UAAW,UAAS,KAAK,qEAAkE;AAC1G,MAAI,CAAC,UAAU,UAAW,UAAS,KAAK,qEAAkE;AAE1G,SAAO,EAAE,IAAI,SAAS,WAAW,GAAG,oBAAoB,SAAS;AACnE;AAGO,SAAS,UAAU,MAAyB,QAAQ,KAAW;AACpE,QAAM,SAAS,YAAY,GAAG;AAC9B,MAAI,CAAC,OAAO,IAAI;AACd,UAAM,IAAI,MAAM;AAAA,IAAuC,OAAO,SAAS,KAAK,MAAM,CAAC,EAAE;AAAA,EACvF;AACF;","names":[]}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @xiwebdesign/xicms-core/server — server-only helpers (firebase-admin, sanitization, SEO,
3
+ * pagina-reads). NOOIT importeren in client-componenten.
4
+ */
5
+ import "server-only";
6
+ export { getAdminApp, getAdminAuth, getAdminDb } from "../firebase/admin";
7
+ export { sanitizeRichText } from "./sanitize";
8
+ export { buildMetadata, buildJsonLd, buildSitemap, buildRobots, siteOrigin, businessJsonLd, breadcrumbListJsonLd, articleJsonLd, productJsonLd, openingHoursJsonLd, galleryJsonLd, videoObjectJsonLd, type BusinessInfo, } from "./seo";
9
+ export { validateEnv, assertEnv, type EnvReport } from "./env";
10
+ export { pathFromSlugs, listPublishedPages, getPublishedPageByPath, getDraftPageById, getDraftPageByPath, type StoredPage, } from "./pages";
@@ -0,0 +1,51 @@
1
+ import "server-only";
2
+ import { getAdminApp, getAdminAuth, getAdminDb } from "../firebase/admin";
3
+ import { sanitizeRichText } from "./sanitize";
4
+ import {
5
+ buildMetadata,
6
+ buildJsonLd,
7
+ buildSitemap,
8
+ buildRobots,
9
+ siteOrigin,
10
+ businessJsonLd,
11
+ breadcrumbListJsonLd,
12
+ articleJsonLd,
13
+ productJsonLd,
14
+ openingHoursJsonLd,
15
+ galleryJsonLd,
16
+ videoObjectJsonLd
17
+ } from "./seo";
18
+ import { validateEnv, assertEnv } from "./env";
19
+ import {
20
+ pathFromSlugs,
21
+ listPublishedPages,
22
+ getPublishedPageByPath,
23
+ getDraftPageById,
24
+ getDraftPageByPath
25
+ } from "./pages";
26
+ export {
27
+ articleJsonLd,
28
+ assertEnv,
29
+ breadcrumbListJsonLd,
30
+ buildJsonLd,
31
+ buildMetadata,
32
+ buildRobots,
33
+ buildSitemap,
34
+ businessJsonLd,
35
+ galleryJsonLd,
36
+ getAdminApp,
37
+ getAdminAuth,
38
+ getAdminDb,
39
+ getDraftPageById,
40
+ getDraftPageByPath,
41
+ getPublishedPageByPath,
42
+ listPublishedPages,
43
+ openingHoursJsonLd,
44
+ pathFromSlugs,
45
+ productJsonLd,
46
+ sanitizeRichText,
47
+ siteOrigin,
48
+ validateEnv,
49
+ videoObjectJsonLd
50
+ };
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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\nexport { getAdminApp, getAdminAuth, getAdminDb } from \"../firebase/admin\";\nexport { sanitizeRichText } from \"./sanitize\";\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\";\nexport {\n pathFromSlugs,\n listPublishedPages,\n getPublishedPageByPath,\n getDraftPageById,\n getDraftPageByPath,\n type StoredPage,\n} from \"./pages\";\n"],"mappings":"AAIA,OAAO;AAEP,SAAS,aAAa,cAAc,kBAAkB;AACtD,SAAS,wBAAwB;AACjC;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;AACvD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;","names":[]}
@@ -0,0 +1,15 @@
1
+ import "server-only";
2
+ import { type Page } from "../schema/pages";
3
+ export type StoredPage = Page & {
4
+ id: string;
5
+ };
6
+ /** Pad uit Next catch-all params (`[[...slug]]`). "/" voor de root. */
7
+ export declare function pathFromSlugs(slugs: string[] | undefined): string;
8
+ /** Alle gepubliceerde pagina's (sitemap / generateStaticParams). Keyless via REST als geen Admin. */
9
+ export declare function listPublishedPages(siteId: string): Promise<StoredPage[]>;
10
+ /** Eén gepubliceerde pagina op pad. Keyless via REST als geen Admin. */
11
+ export declare function getPublishedPageByPath(siteId: string, path: string): Promise<StoredPage | null>;
12
+ /** Draft-versie (voor preview achter auth). */
13
+ export declare function getDraftPageById(siteId: string, pageId: string): Promise<StoredPage | null>;
14
+ /** Draft op pad (preview). */
15
+ export declare function getDraftPageByPath(siteId: string, path: string): Promise<StoredPage | null>;
@@ -0,0 +1,99 @@
1
+ import "server-only";
2
+ import { getAdminDb } from "../firebase/admin";
3
+ import { PageSchema } from "../schema/pages";
4
+ function toPath(slugs) {
5
+ const clean = (slugs ?? []).filter(Boolean);
6
+ return "/" + clean.join("/");
7
+ }
8
+ function pathFromSlugs(slugs) {
9
+ const p = toPath(slugs);
10
+ return p === "/" ? "/" : p.replace(/\/$/, "");
11
+ }
12
+ function parse(id, data) {
13
+ const res = PageSchema.safeParse(data);
14
+ if (!res.success) return null;
15
+ return { id, ...res.data };
16
+ }
17
+ function decode(v) {
18
+ if (v == null) return null;
19
+ if ("stringValue" in v) return v.stringValue;
20
+ if ("integerValue" in v) return Number(v.integerValue);
21
+ if ("doubleValue" in v) return v.doubleValue;
22
+ if ("booleanValue" in v) return v.booleanValue;
23
+ if ("nullValue" in v) return null;
24
+ if ("timestampValue" in v) return v.timestampValue;
25
+ if ("referenceValue" in v) return v.referenceValue;
26
+ if ("geoPointValue" in v) return v.geoPointValue;
27
+ if ("arrayValue" in v) return (v.arrayValue?.values ?? []).map(decode);
28
+ if ("mapValue" in v) return decodeFields(v.mapValue?.fields ?? {});
29
+ return null;
30
+ }
31
+ function decodeFields(fields) {
32
+ return Object.fromEntries(Object.entries(fields).map(([k, x]) => [k, decode(x)]));
33
+ }
34
+ function eq(fieldPath, value) {
35
+ return { fieldFilter: { field: { fieldPath }, op: "EQUAL", value: { stringValue: value } } };
36
+ }
37
+ async function restQuery(siteId, filters, limit) {
38
+ const apiKey = process.env.NEXT_PUBLIC_FIREBASE_API_KEY;
39
+ const projectId = process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID;
40
+ if (!apiKey || !projectId) return [];
41
+ const url = `https://firestore.googleapis.com/v1/projects/${projectId}/databases/(default)/documents/sites/${siteId}:runQuery?key=${apiKey}`;
42
+ const where = filters.length === 1 ? filters[0] : { compositeFilter: { op: "AND", filters } };
43
+ const structuredQuery = { from: [{ collectionId: "pages" }], where };
44
+ if (limit) structuredQuery.limit = limit;
45
+ try {
46
+ const res = await fetch(url, {
47
+ method: "POST",
48
+ headers: { "Content-Type": "application/json" },
49
+ body: JSON.stringify({ structuredQuery }),
50
+ // Pagina's zijn ISR-gecached; next-cache mag dit hergebruiken.
51
+ next: { revalidate: 300 }
52
+ });
53
+ if (!res.ok) return [];
54
+ const rows = await res.json();
55
+ return rows.filter((r) => r.document).map((r) => parse(r.document.name.split("/").pop(), decodeFields(r.document.fields))).filter((p) => p !== null);
56
+ } catch (err) {
57
+ console.error("[xicms] Firestore REST-query mislukt:", err);
58
+ return [];
59
+ }
60
+ }
61
+ async function listPublishedPages(siteId) {
62
+ const adb = getAdminDb();
63
+ if (adb) {
64
+ const snap = await adb.collection(`sites/${siteId}/pages`).where("status", "==", "published").get();
65
+ return snap.docs.map((d) => parse(d.id, d.data())).filter((p) => p !== null);
66
+ }
67
+ return restQuery(siteId, [eq("status", "published")]);
68
+ }
69
+ async function getPublishedPageByPath(siteId, path) {
70
+ const adb = getAdminDb();
71
+ if (adb) {
72
+ const snap = await adb.collection(`sites/${siteId}/pages`).where("status", "==", "published").where("path", "==", path).limit(1).get();
73
+ const d = snap.docs[0];
74
+ return d ? parse(d.id, d.data()) : null;
75
+ }
76
+ const rows = await restQuery(siteId, [eq("status", "published"), eq("path", path)], 1);
77
+ return rows[0] ?? null;
78
+ }
79
+ async function getDraftPageById(siteId, pageId) {
80
+ const db = getAdminDb();
81
+ if (!db) return null;
82
+ const d = await db.doc(`sites/${siteId}/drafts/${pageId}`).get();
83
+ return d.exists ? parse(d.id, d.data()) : null;
84
+ }
85
+ async function getDraftPageByPath(siteId, path) {
86
+ const db = getAdminDb();
87
+ if (!db) return null;
88
+ const snap = await db.collection(`sites/${siteId}/drafts`).where("path", "==", path).limit(1).get();
89
+ const d = snap.docs[0];
90
+ return d ? parse(d.id, d.data()) : null;
91
+ }
92
+ export {
93
+ getDraftPageById,
94
+ getDraftPageByPath,
95
+ getPublishedPageByPath,
96
+ listPublishedPages,
97
+ pathFromSlugs
98
+ };
99
+ //# sourceMappingURL=pages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/pages.ts"],"sourcesContent":["import \"server-only\";\n\nimport { getAdminDb } from \"../firebase/admin\";\nimport { PageSchema, type Page } from \"../schema/pages\";\n\nexport type StoredPage = Page & { id: string };\n\nfunction toPath(slugs: string[] | undefined): string {\n const clean = (slugs ?? []).filter(Boolean);\n return \"/\" + clean.join(\"/\");\n}\n\n/** Pad uit Next catch-all params (`[[...slug]]`). \"/\" voor de root. */\nexport function pathFromSlugs(slugs: string[] | undefined): string {\n const p = toPath(slugs);\n return p === \"/\" ? \"/\" : p.replace(/\\/$/, \"\");\n}\n\nfunction parse(id: string, data: unknown): StoredPage | null {\n const res = PageSchema.safeParse(data);\n if (!res.success) return null;\n return { id, ...res.data };\n}\n\n/* ---------------- keyless public reads via Firestore REST (alleen apiKey) ----------------\n * Gepubliceerde pagina's zijn publiek leesbaar (rules). De Firestore REST-API honoreert die\n * rules met enkel de web-apiKey (geen Admin-credentials, geen client-SDK), dus dit werkt\n * server-side op keyless deployments (org-policy zonder service-account-keys).\n */\ntype FsValue = Record<string, unknown>;\nfunction decode(v: FsValue): unknown {\n if (v == null) return null;\n if (\"stringValue\" in v) return v.stringValue;\n if (\"integerValue\" in v) return Number(v.integerValue);\n if (\"doubleValue\" in v) return v.doubleValue;\n if (\"booleanValue\" in v) return v.booleanValue;\n if (\"nullValue\" in v) return null;\n if (\"timestampValue\" in v) return v.timestampValue;\n if (\"referenceValue\" in v) return v.referenceValue;\n if (\"geoPointValue\" in v) return v.geoPointValue;\n if (\"arrayValue\" in v) return (((v.arrayValue as FsValue)?.values as FsValue[]) ?? []).map(decode);\n if (\"mapValue\" in v) return decodeFields(((v.mapValue as FsValue)?.fields as Record<string, FsValue>) ?? {});\n return null;\n}\nfunction decodeFields(fields: Record<string, FsValue>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(fields).map(([k, x]) => [k, decode(x)]));\n}\n\ninterface Filter { fieldFilter: { field: { fieldPath: string }; op: \"EQUAL\"; value: { stringValue: string } } }\nfunction eq(fieldPath: string, value: string): Filter {\n return { fieldFilter: { field: { fieldPath }, op: \"EQUAL\", value: { stringValue: value } } };\n}\n\nasync function restQuery(siteId: string, filters: Filter[], limit?: number): Promise<StoredPage[]> {\n const apiKey = process.env.NEXT_PUBLIC_FIREBASE_API_KEY;\n const projectId = process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID;\n if (!apiKey || !projectId) return [];\n const url = `https://firestore.googleapis.com/v1/projects/${projectId}/databases/(default)/documents/sites/${siteId}:runQuery?key=${apiKey}`;\n const where = filters.length === 1 ? filters[0] : { compositeFilter: { op: \"AND\", filters } };\n const structuredQuery: Record<string, unknown> = { from: [{ collectionId: \"pages\" }], where };\n if (limit) structuredQuery.limit = limit;\n // Netwerk-/parsefouten mogen een publieke pagina nooit laten crashen (500) — dan liever een\n // lege lijst (Next toont dan een 404 of de fallback, en de volgende revalidate probeert opnieuw).\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ structuredQuery }),\n // Pagina's zijn ISR-gecached; next-cache mag dit hergebruiken.\n next: { revalidate: 300 },\n });\n if (!res.ok) return [];\n const rows = (await res.json()) as { document?: { name: string; fields: Record<string, FsValue> } }[];\n return rows\n .filter((r) => r.document)\n .map((r) => parse(r.document!.name.split(\"/\").pop()!, decodeFields(r.document!.fields)))\n .filter((p): p is StoredPage => p !== null);\n } catch (err) {\n console.error(\"[xicms] Firestore REST-query mislukt:\", err);\n return [];\n }\n}\n\n/** Alle gepubliceerde pagina's (sitemap / generateStaticParams). Keyless via REST als geen Admin. */\nexport async function listPublishedPages(siteId: string): Promise<StoredPage[]> {\n const adb = getAdminDb();\n if (adb) {\n const snap = await adb.collection(`sites/${siteId}/pages`).where(\"status\", \"==\", \"published\").get();\n return snap.docs.map((d) => parse(d.id, d.data())).filter((p): p is StoredPage => p !== null);\n }\n return restQuery(siteId, [eq(\"status\", \"published\")]);\n}\n\n/** Eén gepubliceerde pagina op pad. Keyless via REST als geen Admin. */\nexport async function getPublishedPageByPath(siteId: string, path: string): Promise<StoredPage | null> {\n const adb = getAdminDb();\n if (adb) {\n const snap = await adb\n .collection(`sites/${siteId}/pages`)\n .where(\"status\", \"==\", \"published\")\n .where(\"path\", \"==\", path)\n .limit(1)\n .get();\n const d = snap.docs[0];\n return d ? parse(d.id, d.data()) : null;\n }\n const rows = await restQuery(siteId, [eq(\"status\", \"published\"), eq(\"path\", path)], 1);\n return rows[0] ?? null;\n}\n\n/** Draft-versie (voor preview achter auth). */\nexport async function getDraftPageById(siteId: string, pageId: string): Promise<StoredPage | null> {\n const db = getAdminDb();\n if (!db) return null;\n const d = await db.doc(`sites/${siteId}/drafts/${pageId}`).get();\n return d.exists ? parse(d.id, d.data()) : null;\n}\n\n/** Draft op pad (preview). */\nexport async function getDraftPageByPath(siteId: string, path: string): Promise<StoredPage | null> {\n const db = getAdminDb();\n if (!db) return null;\n const snap = await db.collection(`sites/${siteId}/drafts`).where(\"path\", \"==\", path).limit(1).get();\n const d = snap.docs[0];\n return d ? parse(d.id, d.data()) : null;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+ import "server-only";
2
+ export declare function sanitizeRichText(html: string): string;
@@ -0,0 +1,55 @@
1
+ import "server-only";
2
+ import sanitizeHtml from "sanitize-html";
3
+ const OPTIONS = {
4
+ allowedTags: [
5
+ "p",
6
+ "br",
7
+ "strong",
8
+ "b",
9
+ "em",
10
+ "i",
11
+ "u",
12
+ "s",
13
+ "a",
14
+ "img",
15
+ "ul",
16
+ "ol",
17
+ "li",
18
+ "blockquote",
19
+ "h2",
20
+ "h3",
21
+ "h4",
22
+ "code",
23
+ "pre",
24
+ "hr"
25
+ ],
26
+ allowedAttributes: {
27
+ a: ["href", "target", "rel"],
28
+ // Afbeeldingen in rich text (WYSIWYG): alleen veilige presentatie-attributen, geen on*-handlers.
29
+ img: ["src", "alt", "title", "width", "height", "loading", "decoding"]
30
+ },
31
+ // Geen data:-URI's voor afbeeldingen (alleen http/https + relatieve paden naar onze eigen Storage).
32
+ allowedSchemesByTag: { img: ["http", "https"] },
33
+ allowedSchemes: ["http", "https", "mailto", "tel"],
34
+ transformTags: {
35
+ // Externe links altijd veilig openen.
36
+ a: (tagName, attribs) => ({
37
+ tagName,
38
+ attribs: {
39
+ ...attribs,
40
+ rel: "noopener noreferrer nofollow",
41
+ ...attribs.target === "_blank" ? { target: "_blank" } : {}
42
+ }
43
+ }),
44
+ // Afbeeldingen lazy + async laten laden voor performance.
45
+ img: (tagName, attribs) => ({ tagName, attribs: { ...attribs, loading: "lazy", decoding: "async" } })
46
+ },
47
+ disallowedTagsMode: "discard"
48
+ };
49
+ function sanitizeRichText(html) {
50
+ return sanitizeHtml(html ?? "", OPTIONS);
51
+ }
52
+ export {
53
+ sanitizeRichText
54
+ };
55
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +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 */\nconst OPTIONS: sanitizeHtml.IOptions = {\n allowedTags: [\n \"p\", \"br\", \"strong\", \"b\", \"em\", \"i\", \"u\", \"s\", \"a\", \"img\",\n \"ul\", \"ol\", \"li\", \"blockquote\", \"h2\", \"h3\", \"h4\", \"code\", \"pre\", \"hr\",\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 },\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;AAOzB,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,IACpD;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAc;AAAA,IAAM;AAAA,IAAM;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAO;AAAA,EACnE;AAAA,EACA,mBAAmB;AAAA,IACjB,GAAG,CAAC,QAAQ,UAAU,KAAK;AAAA;AAAA,IAE3B,KAAK,CAAC,OAAO,OAAO,SAAS,SAAS,UAAU,WAAW,UAAU;AAAA,EACvE;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,EACA,oBAAoB;AACtB;AAEO,SAAS,iBAAiB,MAAsB;AACrD,SAAO,aAAa,QAAQ,IAAI,OAAO;AACzC;","names":[]}
@@ -0,0 +1,116 @@
1
+ import "server-only";
2
+ import type { Metadata, MetadataRoute } from "next";
3
+ import type { Seo } from "../schema/seo";
4
+ import type { Page } from "../schema/pages";
5
+ /** Absolute origin (https://domein) uit de site-config; "" als er geen domein is. */
6
+ export declare function siteOrigin(site: {
7
+ domain?: string;
8
+ }): string;
9
+ /**
10
+ * Bouwt een Next `sitemap.xml` uit een lijst pagina's. Gebruik in `app/sitemap.ts`:
11
+ * export default function sitemap() { return buildSitemap(pages, siteConfig); }
12
+ */
13
+ export declare function buildSitemap(pages: Array<{
14
+ path: string;
15
+ updatedAt?: string | number | Date;
16
+ seo?: {
17
+ noindex?: boolean;
18
+ };
19
+ }>, site: {
20
+ domain?: string;
21
+ }): MetadataRoute.Sitemap;
22
+ /**
23
+ * Bouwt een Next `robots.txt`. In `mode:"demo"` wordt de hele site op noindex gezet; anders alles
24
+ * toegestaan behalve de beheerpaden, met verwijzing naar de sitemap. Gebruik in `app/robots.ts`.
25
+ */
26
+ export declare function buildRobots(site: {
27
+ domain?: string;
28
+ mode?: string;
29
+ }, opts?: {
30
+ disallow?: string[];
31
+ }): MetadataRoute.Robots;
32
+ interface SeoSiteContext {
33
+ name: string;
34
+ domain?: string;
35
+ seoDefaults?: Seo;
36
+ }
37
+ /** Bouwt Next `Metadata` voor een pagina, met fallback op site-defaults. */
38
+ export declare function buildMetadata(page: Pick<Page, "title" | "path" | "seo">, site: SeoSiteContext): Metadata;
39
+ /** Bedrijfsgegevens voor gestructureerde data (schema.org LocalBusiness e.d.). */
40
+ export interface BusinessInfo {
41
+ /** schema.org-type, bv. "LocalBusiness", "LodgingBusiness", "Restaurant", "Store". */
42
+ type?: string;
43
+ name: string;
44
+ description?: string;
45
+ url?: string;
46
+ telephone?: string;
47
+ email?: string;
48
+ image?: string;
49
+ /** Indicatie prijsniveau, bv. "€€". */
50
+ priceRange?: string;
51
+ address?: {
52
+ street?: string;
53
+ locality?: string;
54
+ region?: string;
55
+ postalCode?: string;
56
+ country?: string;
57
+ };
58
+ geo?: {
59
+ lat: number;
60
+ lng: number;
61
+ };
62
+ /** schema.org openingHours, bv. ["Mo-Fr 09:00-17:00", "Sa 10:00-16:00"]. */
63
+ openingHours?: string[];
64
+ /** Externe profielen (social, etc.). */
65
+ sameAs?: string[];
66
+ }
67
+ /**
68
+ * Bouwt gestructureerde data voor een lokaal bedrijf (herbruikbaar per branche). Plaats het
69
+ * resultaat als JSON-LD in de layout: <script type="application/ld+json">JSON.stringify(...)</script>
70
+ */
71
+ export declare function businessJsonLd(info: BusinessInfo): Record<string, unknown>;
72
+ /** Breadcrumb-trail (schema.org BreadcrumbList) — voor genest navigeren + rich results. */
73
+ export declare function breadcrumbListJsonLd(items: {
74
+ name: string;
75
+ url: string;
76
+ }[]): Record<string, unknown>;
77
+ /** Article-JSON-LD voor nieuws/blog. */
78
+ export declare function articleJsonLd(a: {
79
+ title: string;
80
+ description?: string;
81
+ author?: string;
82
+ datePublished?: string;
83
+ image?: string;
84
+ url?: string;
85
+ }): Record<string, unknown>;
86
+ /** Product/Offer-JSON-LD. */
87
+ export declare function productJsonLd(p: {
88
+ name: string;
89
+ description?: string;
90
+ price?: string | number;
91
+ currency?: string;
92
+ image?: string;
93
+ availability?: string;
94
+ }): Record<string, unknown>;
95
+ /** OpeningHoursSpecification — bv. `[{ days:["Mo","Tu"], opens:"09:00", closes:"17:00" }]`. */
96
+ export declare function openingHoursJsonLd(spec: {
97
+ days: string[];
98
+ opens: string;
99
+ closes: string;
100
+ }[]): Record<string, unknown>[];
101
+ /** ImageGallery-JSON-LD voor een fotogalerij. */
102
+ export declare function galleryJsonLd(items: {
103
+ url: string;
104
+ caption?: string;
105
+ }[]): Record<string, unknown>;
106
+ /** VideoObject-JSON-LD. */
107
+ export declare function videoObjectJsonLd(v: {
108
+ name: string;
109
+ description?: string;
110
+ thumbnailUrl?: string;
111
+ contentUrl?: string;
112
+ uploadDate?: string;
113
+ }): Record<string, unknown>;
114
+ /** Bouwt een JSON-LD-object voor een pagina (schema.org). */
115
+ export declare function buildJsonLd(page: Pick<Page, "title" | "path" | "seo">, site: SeoSiteContext): Record<string, unknown>;
116
+ export {};