@xiwebdesign/xicms-core 4.17.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/XiCMSProvider.d.ts +7 -0
  2. package/dist/XiCMSProvider.js +32 -7
  3. package/dist/XiCMSProvider.js.map +1 -1
  4. package/dist/admin/blockEditors/GenericEditor.d.ts +22 -0
  5. package/dist/admin/blockEditors/GenericEditor.js +201 -0
  6. package/dist/admin/blockEditors/GenericEditor.js.map +1 -0
  7. package/dist/admin/blockEditors/SymbolRefEditor.d.ts +2 -0
  8. package/dist/admin/blockEditors/SymbolRefEditor.js +55 -0
  9. package/dist/admin/blockEditors/SymbolRefEditor.js.map +1 -0
  10. package/dist/admin/blockEditors/index.d.ts +11 -6
  11. package/dist/admin/blockEditors/index.js +49 -620
  12. package/dist/admin/blockEditors/index.js.map +1 -1
  13. package/dist/admin/customBlocks/CustomBlocksPanel.d.ts +3 -0
  14. package/dist/admin/customBlocks/CustomBlocksPanel.js +145 -0
  15. package/dist/admin/customBlocks/CustomBlocksPanel.js.map +1 -0
  16. package/dist/admin/lib/compressImage.d.ts +4 -2
  17. package/dist/admin/lib/compressImage.js +7 -5
  18. package/dist/admin/lib/compressImage.js.map +1 -1
  19. package/dist/admin/lib/mediaUsage.d.ts +4 -3
  20. package/dist/admin/lib/mediaUsage.js +21 -10
  21. package/dist/admin/lib/mediaUsage.js.map +1 -1
  22. package/dist/admin/lib/symbolsClient.d.ts +13 -0
  23. package/dist/admin/lib/symbolsClient.js +51 -0
  24. package/dist/admin/lib/symbolsClient.js.map +1 -0
  25. package/dist/admin/lib/upload.d.ts +4 -0
  26. package/dist/admin/lib/upload.js +26 -6
  27. package/dist/admin/lib/upload.js.map +1 -1
  28. package/dist/admin/lib/zodFields.d.ts +18 -0
  29. package/dist/admin/lib/zodFields.js +65 -2
  30. package/dist/admin/lib/zodFields.js.map +1 -1
  31. package/dist/admin/media/MediaManager.js +23 -7
  32. package/dist/admin/media/MediaManager.js.map +1 -1
  33. package/dist/admin/media/MediaPicker.js +12 -2
  34. package/dist/admin/media/MediaPicker.js.map +1 -1
  35. package/dist/admin/panelRegistry.js +3 -0
  36. package/dist/admin/panelRegistry.js.map +1 -1
  37. package/dist/admin/settings/SettingsPanel.js +6 -1
  38. package/dist/admin/settings/SettingsPanel.js.map +1 -1
  39. package/dist/admin/settings/SnapshotsCard.d.ts +3 -0
  40. package/dist/admin/settings/SnapshotsCard.js +98 -0
  41. package/dist/admin/settings/SnapshotsCard.js.map +1 -0
  42. package/dist/admin/visual/TranslationPanel.d.ts +13 -0
  43. package/dist/admin/visual/TranslationPanel.js +73 -0
  44. package/dist/admin/visual/TranslationPanel.js.map +1 -0
  45. package/dist/admin/visual/VisualEditor.js +146 -18
  46. package/dist/admin/visual/VisualEditor.js.map +1 -1
  47. package/dist/admin.css +1 -1
  48. package/dist/agentFiles/catalog.d.ts +21 -0
  49. package/dist/agentFiles/catalog.js +78 -0
  50. package/dist/agentFiles/catalog.js.map +1 -0
  51. package/dist/agentFiles/files.d.ts +59 -0
  52. package/dist/agentFiles/files.js +109 -0
  53. package/dist/agentFiles/files.js.map +1 -0
  54. package/dist/blocks/builtins/Agenda.d.ts +6 -0
  55. package/dist/blocks/builtins/Agenda.js +14 -6
  56. package/dist/blocks/builtins/Agenda.js.map +1 -1
  57. package/dist/blocks/builtins/BeforeAfter.js +1 -0
  58. package/dist/blocks/builtins/BeforeAfter.js.map +1 -1
  59. package/dist/blocks/builtins/Breadcrumbs.js +5 -1
  60. package/dist/blocks/builtins/Breadcrumbs.js.map +1 -1
  61. package/dist/blocks/builtins/Cards.js +4 -2
  62. package/dist/blocks/builtins/Cards.js.map +1 -1
  63. package/dist/blocks/builtins/Contact.js +2 -1
  64. package/dist/blocks/builtins/Contact.js.map +1 -1
  65. package/dist/blocks/builtins/Cta.js +1 -0
  66. package/dist/blocks/builtins/Cta.js.map +1 -1
  67. package/dist/blocks/builtins/Elements.js +1 -0
  68. package/dist/blocks/builtins/Elements.js.map +1 -1
  69. package/dist/blocks/builtins/Faq.js +5 -4
  70. package/dist/blocks/builtins/Faq.js.map +1 -1
  71. package/dist/blocks/builtins/Gallery.js +2 -2
  72. package/dist/blocks/builtins/Gallery.js.map +1 -1
  73. package/dist/blocks/builtins/Hero.js +2 -2
  74. package/dist/blocks/builtins/Hero.js.map +1 -1
  75. package/dist/blocks/builtins/Jobs.d.ts +8 -1
  76. package/dist/blocks/builtins/Jobs.js +38 -21
  77. package/dist/blocks/builtins/Jobs.js.map +1 -1
  78. package/dist/blocks/builtins/MapBlock.js +31 -4
  79. package/dist/blocks/builtins/MapBlock.js.map +1 -1
  80. package/dist/blocks/builtins/PdfBlock.js +2 -3
  81. package/dist/blocks/builtins/PdfBlock.js.map +1 -1
  82. package/dist/blocks/builtins/Portfolio.js +2 -2
  83. package/dist/blocks/builtins/Portfolio.js.map +1 -1
  84. package/dist/blocks/builtins/Pricing.d.ts +2 -0
  85. package/dist/blocks/builtins/Pricing.js +18 -10
  86. package/dist/blocks/builtins/Pricing.js.map +1 -1
  87. package/dist/blocks/builtins/Sections.js +4 -2
  88. package/dist/blocks/builtins/Sections.js.map +1 -1
  89. package/dist/blocks/builtins/Slider.js +21 -3
  90. package/dist/blocks/builtins/Slider.js.map +1 -1
  91. package/dist/blocks/builtins/SymbolRef.d.ts +2 -0
  92. package/dist/blocks/builtins/SymbolRef.js +61 -0
  93. package/dist/blocks/builtins/SymbolRef.js.map +1 -0
  94. package/dist/blocks/builtins/Testimonials.js +21 -18
  95. package/dist/blocks/builtins/Testimonials.js.map +1 -1
  96. package/dist/blocks/builtins/WhatsappChat.js +1 -1
  97. package/dist/blocks/builtins/WhatsappChat.js.map +1 -1
  98. package/dist/blocks/builtins/Widgets.js +2 -3
  99. package/dist/blocks/builtins/Widgets.js.map +1 -1
  100. package/dist/blocks/builtins/lib/ics.js +1 -1
  101. package/dist/blocks/builtins/lib/ics.js.map +1 -1
  102. package/dist/blocks/builtins/lib/openingHours.d.ts +4 -1
  103. package/dist/blocks/builtins/lib/openingHours.js +11 -5
  104. package/dist/blocks/builtins/lib/openingHours.js.map +1 -1
  105. package/dist/blocks/customTemplate/definition.d.ts +7 -0
  106. package/dist/blocks/customTemplate/definition.js +34 -0
  107. package/dist/blocks/customTemplate/definition.js.map +1 -0
  108. package/dist/blocks/customTemplate/interpret.d.ts +10 -0
  109. package/dist/blocks/customTemplate/interpret.js +136 -0
  110. package/dist/blocks/customTemplate/interpret.js.map +1 -0
  111. package/dist/blocks/registry.d.ts +8 -0
  112. package/dist/blocks/registry.js.map +1 -1
  113. package/dist/demo/demoStore.d.ts +11 -1
  114. package/dist/demo/demoStore.js +50 -0
  115. package/dist/demo/demoStore.js.map +1 -1
  116. package/dist/firebase/client.js +2 -1
  117. package/dist/firebase/client.js.map +1 -1
  118. package/dist/i18n/overlay.d.ts +61 -0
  119. package/dist/i18n/overlay.js +90 -0
  120. package/dist/i18n/overlay.js.map +1 -0
  121. package/dist/index.d.ts +11 -9
  122. package/dist/index.js +34 -9
  123. package/dist/index.js.map +1 -1
  124. package/dist/modules/builtins.js +3 -2
  125. package/dist/modules/builtins.js.map +1 -1
  126. package/dist/modules/consent/useConsent.js +15 -3
  127. package/dist/modules/consent/useConsent.js.map +1 -1
  128. package/dist/schema/blocks.d.ts +183 -3
  129. package/dist/schema/blocks.js +12 -1
  130. package/dist/schema/blocks.js.map +1 -1
  131. package/dist/schema/customBlocks.d.ts +47 -0
  132. package/dist/schema/customBlocks.js +32 -0
  133. package/dist/schema/customBlocks.js.map +1 -0
  134. package/dist/schema/fields.d.ts +122 -0
  135. package/dist/schema/fields.js +120 -0
  136. package/dist/schema/fields.js.map +1 -0
  137. package/dist/schema/forms.d.ts +6 -6
  138. package/dist/schema/pages.d.ts +15 -1
  139. package/dist/schema/pages.js +6 -2
  140. package/dist/schema/pages.js.map +1 -1
  141. package/dist/schema/siteConfig.d.ts +14 -8
  142. package/dist/schema/siteConfig.js +2 -1
  143. package/dist/schema/siteConfig.js.map +1 -1
  144. package/dist/schema/symbols.d.ts +205 -0
  145. package/dist/schema/symbols.js +18 -0
  146. package/dist/schema/symbols.js.map +1 -0
  147. package/dist/server/index.d.ts +2 -1
  148. package/dist/server/index.js +24 -0
  149. package/dist/server/index.js.map +1 -1
  150. package/dist/server/pages.d.ts +21 -0
  151. package/dist/server/pages.js +77 -0
  152. package/dist/server/pages.js.map +1 -1
  153. package/dist/server/seo.d.ts +12 -3
  154. package/dist/server/seo.js +23 -11
  155. package/dist/server/seo.js.map +1 -1
  156. package/dist/styles.css +62 -6
  157. package/package.json +1 -1
  158. package/dist/components/EditableImage.d.ts +0 -18
  159. package/dist/components/EditableImage.js +0 -62
  160. package/dist/components/EditableImage.js.map +0 -1
  161. package/dist/components/EditableRichText.d.ts +0 -14
  162. package/dist/components/EditableRichText.js +0 -26
  163. package/dist/components/EditableRichText.js.map +0 -1
  164. package/dist/components/EditableText.d.ts +0 -21
  165. package/dist/components/EditableText.js +0 -25
  166. package/dist/components/EditableText.js.map +0 -1
  167. package/dist/content/ContentProvider.d.ts +0 -23
  168. package/dist/content/ContentProvider.js +0 -86
  169. package/dist/content/ContentProvider.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/schema/fields.ts"],"sourcesContent":["/**\n * Field-IR (\"intermediate representation\") — het declaratieve veldmodel dat formulieren aandrijft.\n *\n * Geport concept + modelvorm uit primo (github.com/primocms/primo, MIT © Matthew Morris) — zie\n * THIRD_PARTY_LICENSES.md. Primo definieert velden als een Zod discriminated union met een\n * `config`-blob per type, nesting zonder recursieve schema's en conditionele velden (`Condition`).\n * XiCMS gebruikt dit model op twee plekken:\n *\n * 1. **Afgeleid**: `introspectToFields()` (admin/lib/zodFields.ts) leidt een Field-IR af uit de\n * bestaande Zod-block-schema's — de GenericEditor rendert die IR. De Zod-schema's blijven de\n * bron van waarheid; dit is puur de formulier-beschrijving.\n * 2. **Als data**: custom blocks (sites/{siteId}/customBlocks) slaan hun velddefinities als\n * Field-IR op in Firestore. `fieldsToZod()` genereert daaruit een echt Zod-schema zodat ook\n * runtime-gedefinieerde blokken de harde XiCMS-validatie houden.\n *\n * Server-safe (geen React). Nesting gaat via een `fields`-array in group/repeater — documentvorm,\n * geen aparte rows (Firestore-vriendelijk, en `z.lazy` dekt de recursie).\n */\nimport { z, type ZodTypeAny } from \"zod\";\n\n/** Conditioneel tonen: veld is zichtbaar als `field` (sibling-sleutel) matcht. */\nexport const ShowIfSchema = z.object({\n /** Sleutel van het veld (zelfde niveau) waarvan de waarde bepaalt of dit veld toont. */\n field: z.string().min(1),\n /** Toon alléén bij exact deze waarde. Weggelaten → toon bij een truthy waarde. */\n equals: z.union([z.string(), z.number(), z.boolean()]).optional(),\n});\nexport type ShowIf = z.infer<typeof ShowIfSchema>;\n\nconst base = {\n /** Sleutel in het waarden-object (dotted paths niet toegestaan; nesting via group/repeater). */\n key: z.string().min(1).regex(/^[a-zA-Z][a-zA-Z0-9]*$/, \"veldsleutel: letters/cijfers, begint met letter\"),\n /** Leesbaar label (NL). */\n label: z.string().default(\"\"),\n /** Optionele hint onder het veld. */\n hint: z.string().optional(),\n /** Conditioneel tonen (primo's Condition). */\n showIf: ShowIfSchema.optional(),\n};\n\n/** Selectie-optie voor `select`. */\nconst selectOption = z.object({ value: z.string(), label: z.string().default(\"\") });\n\n// ── Veldtypes (primo: Text, RichText, Number, Slider, Switch, Select, Date, Icon, Image, Url,\n// Link, Group, Repeater, Page, Info — hier op XiCMS-conventies gebracht) ──────────────────────\n\nexport type Field =\n | ({ type: \"text\"; maxLength?: number; placeholder?: string } & BaseShape)\n | ({ type: \"textarea\"; maxLength?: number; rows?: number } & BaseShape)\n | ({ type: \"richtext\" } & BaseShape)\n | ({ type: \"number\"; min?: number; max?: number; step?: number } & BaseShape)\n | ({ type: \"slider\"; min: number; max: number; step?: number } & BaseShape)\n | ({ type: \"switch\" } & BaseShape)\n | ({ type: \"select\"; options: { value: string; label: string }[] } & BaseShape)\n | ({ type: \"date\" } & BaseShape)\n | ({ type: \"icon\" } & BaseShape)\n | ({ type: \"image\" } & BaseShape)\n | ({ type: \"url\" } & BaseShape)\n | ({ type: \"link\" } & BaseShape)\n | ({ type: \"group\"; fields: Field[] } & BaseShape)\n | ({ type: \"repeater\"; fields: Field[]; max?: number; itemLabel?: string } & BaseShape)\n | ({ type: \"pageRef\" } & BaseShape)\n | ({ type: \"info\"; text: string } & BaseShape)\n | ({ type: \"json\" } & BaseShape);\n\ntype BaseShape = { key: string; label: string; hint?: string; showIf?: ShowIf };\n\n/** Zod-schema voor één veld-definitie (recursief via z.lazy voor group/repeater). */\nexport const FieldSchema: z.ZodType<Field> = z.lazy(() =>\n z.discriminatedUnion(\"type\", [\n z.object({ ...base, type: z.literal(\"text\"), maxLength: z.number().int().positive().optional(), placeholder: z.string().optional() }),\n z.object({ ...base, type: z.literal(\"textarea\"), maxLength: z.number().int().positive().optional(), rows: z.number().int().positive().optional() }),\n z.object({ ...base, type: z.literal(\"richtext\") }),\n z.object({ ...base, type: z.literal(\"number\"), min: z.number().optional(), max: z.number().optional(), step: z.number().optional() }),\n z.object({ ...base, type: z.literal(\"slider\"), min: z.number(), max: z.number(), step: z.number().optional() }),\n z.object({ ...base, type: z.literal(\"switch\") }),\n z.object({ ...base, type: z.literal(\"select\"), options: z.array(selectOption).min(1).max(50) }),\n z.object({ ...base, type: z.literal(\"date\") }),\n z.object({ ...base, type: z.literal(\"icon\") }),\n z.object({ ...base, type: z.literal(\"image\") }),\n z.object({ ...base, type: z.literal(\"url\") }),\n z.object({ ...base, type: z.literal(\"link\") }),\n z.object({ ...base, type: z.literal(\"group\"), fields: z.array(FieldSchema).max(30) }),\n z.object({ ...base, type: z.literal(\"repeater\"), fields: z.array(FieldSchema).max(30), max: z.number().int().positive().optional(), itemLabel: z.string().optional() }),\n z.object({ ...base, type: z.literal(\"pageRef\") }),\n z.object({ ...base, type: z.literal(\"info\"), text: z.string() }),\n z.object({ ...base, type: z.literal(\"json\") }),\n ]),\n) as z.ZodType<Field>;\n\n/** Een lijst velddefinities (bv. van een custom block). Unieke sleutels afgedwongen. */\nexport const FieldsSchema = z\n .array(FieldSchema)\n .max(40)\n .superRefine((fields, ctx) => {\n const seen = new Set<string>();\n for (const f of fields) {\n if (seen.has(f.key)) ctx.addIssue({ code: z.ZodIssueCode.custom, message: `dubbele veldsleutel \"${f.key}\"` });\n seen.add(f.key);\n }\n });\n\n/**\n * Rich-text-conventie (security): de sanitizer saneert alleen velden die `html` heten of op\n * `Html` eindigen. Een `richtext`-veld MOET dus zo'n sleutel hebben — afgedwongen waar Field-IR\n * als data binnenkomt (custom blocks), zodat er geen stored-XSS-gat ontstaat.\n */\nexport function isRichTextKey(key: string): boolean {\n return key === \"html\" || key.endsWith(\"Html\");\n}\n\n/** Waarde-sleutel van een link-veld: `{ label, href }`. */\nconst linkValue = z.object({ label: z.string().max(200).default(\"\"), href: z.string().max(2000).default(\"\") });\n\n/**\n * Genereert een Zod-waardenschema uit een Field-IR — de brug die runtime-gedefinieerde blokken\n * (custom blocks) dezelfde harde validatie geeft als code-gedefinieerde blokken. Alle velden\n * krijgen `.default()`/`.optional()` (update-veilig: bestaande content blijft geldig als er\n * velden bijkomen). `info`-velden zijn display-only en krijgen geen waarde.\n */\nexport function fieldsToZod(fields: Field[]): z.ZodObject<Record<string, ZodTypeAny>> {\n const shape: Record<string, ZodTypeAny> = {};\n for (const f of fields) {\n const s = fieldToZod(f);\n if (s) shape[f.key] = f.label ? s.describe(f.label) : s;\n }\n return z.object(shape);\n}\n\nfunction fieldToZod(f: Field): ZodTypeAny | null {\n switch (f.type) {\n case \"text\":\n return z.string().max(f.maxLength ?? 500).default(\"\");\n case \"textarea\":\n return z.string().max(f.maxLength ?? 5000).default(\"\");\n case \"richtext\":\n return z.string().max(50_000).default(\"\");\n case \"number\": {\n let n = z.number();\n if (f.min != null) n = n.min(f.min);\n if (f.max != null) n = n.max(f.max);\n return n.optional();\n }\n case \"slider\":\n return z.number().min(f.min).max(f.max).default(f.min);\n case \"switch\":\n return z.boolean().default(false);\n case \"select\": {\n const values = f.options.map((o) => o.value);\n return values.length > 0\n ? z.enum([values[0], ...values.slice(1)] as [string, ...string[]]).default(values[0])\n : z.string().default(\"\");\n }\n case \"date\":\n // ISO-datum (yyyy-mm-dd) of leeg.\n return z.string().regex(/^(\\d{4}-\\d{2}-\\d{2})?$/, \"datum als jjjj-mm-dd\").default(\"\");\n case \"icon\":\n return z.string().max(16).default(\"\");\n case \"image\":\n case \"url\":\n return z.string().max(2000).default(\"\");\n case \"link\":\n return linkValue.default({ label: \"\", href: \"\" });\n case \"group\":\n return fieldsToZod(f.fields).default({});\n case \"repeater\":\n return z.array(fieldsToZod(f.fields)).max(f.max ?? 100).default([]);\n case \"pageRef\":\n // Pad van een pagina binnen de site (\"/\", \"/contact\", …).\n return z.string().max(500).default(\"\");\n case \"info\":\n return null;\n case \"json\":\n return z.unknown().optional();\n }\n}\n\n/** Default-waarden voor een Field-IR (bv. een nieuw repeater-item). */\nexport function fieldsDefaults(fields: Field[]): Record<string, unknown> {\n return fieldsToZod(fields).parse({});\n}\n\n/**\n * Hints per veldsleutel (dotted path voor geneste velden, bv. \"items.date\") — verfijnt de uit een\n * Zod-schema afgeleide Field-IR. Gebruikt door `defineBlock({ fields })` + `introspectToFields`.\n */\nexport type FieldHints = Record<string, Partial<Field> & { type?: Field[\"type\"] }>;\n\n/** Evalueert `showIf` tegen de huidige waarden (zelfde niveau). Zonder showIf → altijd tonen. */\nexport function isFieldVisible(f: Field, values: Record<string, unknown>): boolean {\n if (!f.showIf) return true;\n const v = values[f.showIf.field];\n if (f.showIf.equals !== undefined) return v === f.showIf.equals;\n return Boolean(v);\n}\n"],"mappings":"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","names":[]}
@@ -11,14 +11,14 @@ export declare const FormFieldSchema: z.ZodObject<{
11
11
  /** Opties voor type "select" en "radio". */
12
12
  options: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
13
13
  }, "strip", z.ZodTypeAny, {
14
- type: "number" | "date" | "text" | "email" | "tel" | "textarea" | "select" | "checkbox" | "radio";
14
+ type: "number" | "date" | "text" | "email" | "textarea" | "select" | "tel" | "checkbox" | "radio";
15
15
  label: string;
16
16
  name: string;
17
17
  required: boolean;
18
18
  options?: string[] | undefined;
19
19
  placeholder?: string | undefined;
20
20
  }, {
21
- type: "number" | "date" | "text" | "email" | "tel" | "textarea" | "select" | "checkbox" | "radio";
21
+ type: "number" | "date" | "text" | "email" | "textarea" | "select" | "tel" | "checkbox" | "radio";
22
22
  label: string;
23
23
  name: string;
24
24
  options?: string[] | undefined;
@@ -39,14 +39,14 @@ export declare const FormSchema: z.ZodObject<{
39
39
  /** Opties voor type "select" en "radio". */
40
40
  options: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
41
41
  }, "strip", z.ZodTypeAny, {
42
- type: "number" | "date" | "text" | "email" | "tel" | "textarea" | "select" | "checkbox" | "radio";
42
+ type: "number" | "date" | "text" | "email" | "textarea" | "select" | "tel" | "checkbox" | "radio";
43
43
  label: string;
44
44
  name: string;
45
45
  required: boolean;
46
46
  options?: string[] | undefined;
47
47
  placeholder?: string | undefined;
48
48
  }, {
49
- type: "number" | "date" | "text" | "email" | "tel" | "textarea" | "select" | "checkbox" | "radio";
49
+ type: "number" | "date" | "text" | "email" | "textarea" | "select" | "tel" | "checkbox" | "radio";
50
50
  label: string;
51
51
  name: string;
52
52
  options?: string[] | undefined;
@@ -62,7 +62,7 @@ export declare const FormSchema: z.ZodObject<{
62
62
  }, "strip", z.ZodTypeAny, {
63
63
  name: string;
64
64
  fields: {
65
- type: "number" | "date" | "text" | "email" | "tel" | "textarea" | "select" | "checkbox" | "radio";
65
+ type: "number" | "date" | "text" | "email" | "textarea" | "select" | "tel" | "checkbox" | "radio";
66
66
  label: string;
67
67
  name: string;
68
68
  required: boolean;
@@ -76,7 +76,7 @@ export declare const FormSchema: z.ZodObject<{
76
76
  }, {
77
77
  name: string;
78
78
  fields: {
79
- type: "number" | "date" | "text" | "email" | "tel" | "textarea" | "select" | "checkbox" | "radio";
79
+ type: "number" | "date" | "text" | "email" | "textarea" | "select" | "tel" | "checkbox" | "radio";
80
80
  label: string;
81
81
  name: string;
82
82
  options?: string[] | undefined;
@@ -112,6 +112,8 @@ export declare const PageSchema: z.ZodObject<{
112
112
  animate?: "fade" | "up" | undefined;
113
113
  }>>;
114
114
  }, z.ZodTypeAny, "passthrough">>, "many">>;
115
+ /** Taal-overlay (5.0): per locale gepunte veldpaden → vertaalde tekst (zie i18n/overlay.ts). */
116
+ translations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodString>, Record<string, string>, Record<string, string>>>>;
115
117
  }, "strip", z.ZodTypeAny, {
116
118
  title: string;
117
119
  path: string;
@@ -153,6 +155,7 @@ export declare const PageSchema: z.ZodObject<{
153
155
  noindex?: boolean | undefined;
154
156
  jsonLdType?: string | undefined;
155
157
  } | undefined;
158
+ translations?: Record<string, Record<string, string>> | undefined;
156
159
  }, {
157
160
  title: string;
158
161
  path: string;
@@ -194,6 +197,7 @@ export declare const PageSchema: z.ZodObject<{
194
197
  noindex?: boolean | undefined;
195
198
  jsonLdType?: string | undefined;
196
199
  } | undefined;
200
+ translations?: Record<string, Record<string, string>> | undefined;
197
201
  }>;
198
202
  export type Page = z.infer<typeof PageSchema>;
199
203
  /** Invoer bij het aanmaken/bijwerken van een draft (geen serverside velden). */
@@ -304,7 +308,9 @@ export declare const PageDraftInputSchema: z.ZodObject<Pick<{
304
308
  animate?: "fade" | "up" | undefined;
305
309
  }>>;
306
310
  }, z.ZodTypeAny, "passthrough">>, "many">>;
307
- }, "title" | "path" | "blocks" | "slug" | "parentId" | "order" | "seo">, "strip", z.ZodTypeAny, {
311
+ /** Taal-overlay (5.0): per locale gepunte veldpaden → vertaalde tekst (zie i18n/overlay.ts). */
312
+ translations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodString>, Record<string, string>, Record<string, string>>>>;
313
+ }, "title" | "path" | "blocks" | "slug" | "parentId" | "order" | "seo" | "translations">, "strip", z.ZodTypeAny, {
308
314
  title: string;
309
315
  path: string;
310
316
  blocks: z.objectOutputType<{
@@ -344,6 +350,7 @@ export declare const PageDraftInputSchema: z.ZodObject<Pick<{
344
350
  noindex?: boolean | undefined;
345
351
  jsonLdType?: string | undefined;
346
352
  } | undefined;
353
+ translations?: Record<string, Record<string, string>> | undefined;
347
354
  }, {
348
355
  title: string;
349
356
  path: string;
@@ -384,6 +391,7 @@ export declare const PageDraftInputSchema: z.ZodObject<Pick<{
384
391
  noindex?: boolean | undefined;
385
392
  jsonLdType?: string | undefined;
386
393
  } | undefined;
394
+ translations?: Record<string, Record<string, string>> | undefined;
387
395
  }>;
388
396
  export type PageDraftInput = z.infer<typeof PageDraftInputSchema>;
389
397
  /** Een versie-snapshot (history). */
@@ -495,6 +503,8 @@ export declare const PageVersionSchema: z.ZodObject<{
495
503
  animate?: "fade" | "up" | undefined;
496
504
  }>>;
497
505
  }, z.ZodTypeAny, "passthrough">>, "many">>;
506
+ /** Taal-overlay (5.0): per locale gepunte veldpaden → vertaalde tekst (zie i18n/overlay.ts). */
507
+ translations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodString>, Record<string, string>, Record<string, string>>>>;
498
508
  }, "strip", z.ZodTypeAny, {
499
509
  title: string;
500
510
  path: string;
@@ -536,6 +546,7 @@ export declare const PageVersionSchema: z.ZodObject<{
536
546
  noindex?: boolean | undefined;
537
547
  jsonLdType?: string | undefined;
538
548
  } | undefined;
549
+ translations?: Record<string, Record<string, string>> | undefined;
539
550
  }, {
540
551
  title: string;
541
552
  path: string;
@@ -577,6 +588,7 @@ export declare const PageVersionSchema: z.ZodObject<{
577
588
  noindex?: boolean | undefined;
578
589
  jsonLdType?: string | undefined;
579
590
  } | undefined;
591
+ translations?: Record<string, Record<string, string>> | undefined;
580
592
  }>;
581
593
  kind: z.ZodEnum<["autosave", "publish", "manual"]>;
582
594
  label: z.ZodOptional<z.ZodString>;
@@ -622,6 +634,7 @@ export declare const PageVersionSchema: z.ZodObject<{
622
634
  noindex?: boolean | undefined;
623
635
  jsonLdType?: string | undefined;
624
636
  } | undefined;
637
+ translations?: Record<string, Record<string, string>> | undefined;
625
638
  };
626
639
  kind: "autosave" | "publish" | "manual";
627
640
  label?: string | undefined;
@@ -667,6 +680,7 @@ export declare const PageVersionSchema: z.ZodObject<{
667
680
  noindex?: boolean | undefined;
668
681
  jsonLdType?: string | undefined;
669
682
  } | undefined;
683
+ translations?: Record<string, Record<string, string>> | undefined;
670
684
  };
671
685
  kind: "autosave" | "publish" | "manual";
672
686
  label?: string | undefined;
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { SeoSchema } from "./seo";
3
3
  import { BlockBaseSchema } from "./blocks";
4
+ import { TranslationsSchema } from "../i18n/overlay";
4
5
  const PageStatusSchema = z.enum(["draft", "published"]);
5
6
  const PageSchema = z.object({
6
7
  /** URL-segment binnen de ouder, bv. "over-ons". */
@@ -12,7 +13,9 @@ const PageSchema = z.object({
12
13
  status: PageStatusSchema.default("draft"),
13
14
  title: z.string().min(1).max(200),
14
15
  seo: SeoSchema.optional(),
15
- blocks: z.array(BlockBaseSchema).max(200).default([])
16
+ blocks: z.array(BlockBaseSchema).max(200).default([]),
17
+ /** Taal-overlay (5.0): per locale gepunte veldpaden → vertaalde tekst (zie i18n/overlay.ts). */
18
+ translations: TranslationsSchema.optional()
16
19
  });
17
20
  const PageDraftInputSchema = PageSchema.pick({
18
21
  slug: true,
@@ -21,7 +24,8 @@ const PageDraftInputSchema = PageSchema.pick({
21
24
  order: true,
22
25
  title: true,
23
26
  seo: true,
24
- blocks: true
27
+ blocks: true,
28
+ translations: true
25
29
  });
26
30
  const PageVersionSchema = z.object({
27
31
  snapshot: PageSchema,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/schema/pages.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { SeoSchema } from \"./seo\";\nimport { BlockBaseSchema } from \"./blocks\";\n\nexport const PageStatusSchema = z.enum([\"draft\", \"published\"]);\nexport type PageStatus = z.infer<typeof PageStatusSchema>;\n\n/**\n * Een pagina: metadata + SEO + een lijst blocks. Blocks worden hier los (BlockBaseSchema)\n * gevalideerd; strikte per-type-validatie gebeurt via de registry (`validateBlocks`).\n */\nexport const PageSchema = z.object({\n /** URL-segment binnen de ouder, bv. \"over-ons\". */\n slug: z\n .string()\n .min(1)\n .max(120)\n .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, \"slug mag alleen kleine letters, cijfers en koppeltekens bevatten\"),\n /** Volledig pad vanaf de root, bv. \"/diensten/onderhoud\". */\n path: z.string().min(1).max(400),\n parentId: z.string().max(64).nullable().default(null),\n order: z.number().int().min(0).max(100_000).default(0),\n status: PageStatusSchema.default(\"draft\"),\n title: z.string().min(1).max(200),\n seo: SeoSchema.optional(),\n blocks: z.array(BlockBaseSchema).max(200).default([]),\n});\nexport type Page = z.infer<typeof PageSchema>;\n\n/** Invoer bij het aanmaken/bijwerken van een draft (geen serverside velden). */\nexport const PageDraftInputSchema = PageSchema.pick({\n slug: true,\n path: true,\n parentId: true,\n order: true,\n title: true,\n seo: true,\n blocks: true,\n});\nexport type PageDraftInput = z.infer<typeof PageDraftInputSchema>;\n\n/** Een versie-snapshot (history). */\nexport const PageVersionSchema = z.object({\n snapshot: PageSchema,\n kind: z.enum([\"autosave\", \"publish\", \"manual\"]),\n label: z.string().max(200).optional(),\n});\nexport type PageVersion = z.infer<typeof PageVersionSchema>;\n"],"mappings":"AAAA,SAAS,SAAS;AAClB,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAEzB,MAAM,mBAAmB,EAAE,KAAK,CAAC,SAAS,WAAW,CAAC;AAOtD,MAAM,aAAa,EAAE,OAAO;AAAA;AAAA,EAEjC,MAAM,EACH,OAAO,EACP,IAAI,CAAC,EACL,IAAI,GAAG,EACP,MAAM,8BAA8B,kEAAkE;AAAA;AAAA,EAEzG,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC/B,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,QAAQ,IAAI;AAAA,EACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAO,EAAE,QAAQ,CAAC;AAAA,EACrD,QAAQ,iBAAiB,QAAQ,OAAO;AAAA,EACxC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAChC,KAAK,UAAU,SAAS;AAAA,EACxB,QAAQ,EAAE,MAAM,eAAe,EAAE,IAAI,GAAG,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC;AAIM,MAAM,uBAAuB,WAAW,KAAK;AAAA,EAClD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AACV,CAAC;AAIM,MAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,UAAU;AAAA,EACV,MAAM,EAAE,KAAK,CAAC,YAAY,WAAW,QAAQ,CAAC;AAAA,EAC9C,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AACtC,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../src/schema/pages.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { SeoSchema } from \"./seo\";\nimport { BlockBaseSchema } from \"./blocks\";\nimport { TranslationsSchema } from \"../i18n/overlay\";\n\nexport const PageStatusSchema = z.enum([\"draft\", \"published\"]);\nexport type PageStatus = z.infer<typeof PageStatusSchema>;\n\n/**\n * Een pagina: metadata + SEO + een lijst blocks. Blocks worden hier los (BlockBaseSchema)\n * gevalideerd; strikte per-type-validatie gebeurt via de registry (`validateBlocks`).\n */\nexport const PageSchema = z.object({\n /** URL-segment binnen de ouder, bv. \"over-ons\". */\n slug: z\n .string()\n .min(1)\n .max(120)\n .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, \"slug mag alleen kleine letters, cijfers en koppeltekens bevatten\"),\n /** Volledig pad vanaf de root, bv. \"/diensten/onderhoud\". */\n path: z.string().min(1).max(400),\n parentId: z.string().max(64).nullable().default(null),\n order: z.number().int().min(0).max(100_000).default(0),\n status: PageStatusSchema.default(\"draft\"),\n title: z.string().min(1).max(200),\n seo: SeoSchema.optional(),\n blocks: z.array(BlockBaseSchema).max(200).default([]),\n /** Taal-overlay (5.0): per locale gepunte veldpaden → vertaalde tekst (zie i18n/overlay.ts). */\n translations: TranslationsSchema.optional(),\n});\nexport type Page = z.infer<typeof PageSchema>;\n\n/** Invoer bij het aanmaken/bijwerken van een draft (geen serverside velden). */\nexport const PageDraftInputSchema = PageSchema.pick({\n slug: true,\n path: true,\n parentId: true,\n order: true,\n title: true,\n seo: true,\n blocks: true,\n translations: true,\n});\nexport type PageDraftInput = z.infer<typeof PageDraftInputSchema>;\n\n/** Een versie-snapshot (history). */\nexport const PageVersionSchema = z.object({\n snapshot: PageSchema,\n kind: z.enum([\"autosave\", \"publish\", \"manual\"]),\n label: z.string().max(200).optional(),\n});\nexport type PageVersion = z.infer<typeof PageVersionSchema>;\n"],"mappings":"AAAA,SAAS,SAAS;AAClB,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AAE5B,MAAM,mBAAmB,EAAE,KAAK,CAAC,SAAS,WAAW,CAAC;AAOtD,MAAM,aAAa,EAAE,OAAO;AAAA;AAAA,EAEjC,MAAM,EACH,OAAO,EACP,IAAI,CAAC,EACL,IAAI,GAAG,EACP,MAAM,8BAA8B,kEAAkE;AAAA;AAAA,EAEzG,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC/B,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,QAAQ,IAAI;AAAA,EACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAO,EAAE,QAAQ,CAAC;AAAA,EACrD,QAAQ,iBAAiB,QAAQ,OAAO;AAAA,EACxC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAChC,KAAK,UAAU,SAAS;AAAA,EACxB,QAAQ,EAAE,MAAM,eAAe,EAAE,IAAI,GAAG,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAEpD,cAAc,mBAAmB,SAAS;AAC5C,CAAC;AAIM,MAAM,uBAAuB,WAAW,KAAK;AAAA,EAClD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,cAAc;AAChB,CAAC;AAIM,MAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,UAAU;AAAA,EACV,MAAM,EAAE,KAAK,CAAC,YAAY,WAAW,QAAQ,CAAC;AAAA,EAC9C,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AACtC,CAAC;","names":[]}
@@ -27,6 +27,14 @@ export interface SiteConfig {
27
27
  demoEditing?: boolean;
28
28
  /** Taalcode voor `<html lang>` en a11y (default "nl"). */
29
29
  lang?: string;
30
+ /**
31
+ * Extra talen naast de default (5.0), bv. `["de", "en"]`. Vertalingen leven als overlay op
32
+ * pagina's/symbolen; niet-default talen krijgen een URL-prefix (`/de/over-ons`). Weglaten =
33
+ * ééntalige site (geen overhead).
34
+ */
35
+ locales?: string[];
36
+ /** Default-taal van de canonieke content (default: `lang` ?? "nl"). */
37
+ defaultLocale?: string;
30
38
  /** Huisstijl. */
31
39
  theme: ThemeTokens;
32
40
  /** Hoofdnavigatie. */
@@ -37,11 +45,6 @@ export interface SiteConfig {
37
45
  seoDefaults?: Seo;
38
46
  /** Afzender-instelling voor formulier-e-mail (fallback voor settings/site). */
39
47
  forms?: FormsSender;
40
- /**
41
- * @deprecated Legacy standaardteksten per content-id (v1 plat model). Blijven werken via de
42
- * (eveneens deprecated) `Editable*`-componenten zolang er nog geen pagina-blocks zijn.
43
- */
44
- defaults?: Record<string, string>;
45
48
  /**
46
49
  * @deprecated Gebruik `modules` (XiCMS 3.0). Blijft werken als legacy-brug: `features[key] ===
47
50
  * false` zet de bijbehorende module uit. Aan/uit zetten van optionele beheer-panelen.
@@ -81,6 +84,8 @@ export declare const SiteConfigSchema: z.ZodObject<{
81
84
  mode: z.ZodEnum<["demo", "live"]>;
82
85
  demoEditing: z.ZodOptional<z.ZodBoolean>;
83
86
  lang: z.ZodOptional<z.ZodString>;
87
+ locales: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
88
+ defaultLocale: z.ZodOptional<z.ZodString>;
84
89
  theme: z.ZodObject<{
85
90
  primary: z.ZodString;
86
91
  accent: z.ZodOptional<z.ZodString>;
@@ -257,7 +262,6 @@ export declare const SiteConfigSchema: z.ZodObject<{
257
262
  fromName?: string | undefined;
258
263
  notifyTo?: string | undefined;
259
264
  }>>;
260
- defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
261
265
  features: z.ZodOptional<z.ZodObject<{
262
266
  pages: z.ZodOptional<z.ZodBoolean>;
263
267
  news: z.ZodOptional<z.ZodBoolean>;
@@ -294,6 +298,8 @@ export declare const SiteConfigSchema: z.ZodObject<{
294
298
  mode: z.ZodEnum<["demo", "live"]>;
295
299
  demoEditing: z.ZodOptional<z.ZodBoolean>;
296
300
  lang: z.ZodOptional<z.ZodString>;
301
+ locales: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
302
+ defaultLocale: z.ZodOptional<z.ZodString>;
297
303
  theme: z.ZodObject<{
298
304
  primary: z.ZodString;
299
305
  accent: z.ZodOptional<z.ZodString>;
@@ -470,7 +476,6 @@ export declare const SiteConfigSchema: z.ZodObject<{
470
476
  fromName?: string | undefined;
471
477
  notifyTo?: string | undefined;
472
478
  }>>;
473
- defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
474
479
  features: z.ZodOptional<z.ZodObject<{
475
480
  pages: z.ZodOptional<z.ZodBoolean>;
476
481
  news: z.ZodOptional<z.ZodBoolean>;
@@ -507,6 +512,8 @@ export declare const SiteConfigSchema: z.ZodObject<{
507
512
  mode: z.ZodEnum<["demo", "live"]>;
508
513
  demoEditing: z.ZodOptional<z.ZodBoolean>;
509
514
  lang: z.ZodOptional<z.ZodString>;
515
+ locales: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
516
+ defaultLocale: z.ZodOptional<z.ZodString>;
510
517
  theme: z.ZodObject<{
511
518
  primary: z.ZodString;
512
519
  accent: z.ZodOptional<z.ZodString>;
@@ -683,7 +690,6 @@ export declare const SiteConfigSchema: z.ZodObject<{
683
690
  fromName?: string | undefined;
684
691
  notifyTo?: string | undefined;
685
692
  }>>;
686
- defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
687
693
  features: z.ZodOptional<z.ZodObject<{
688
694
  pages: z.ZodOptional<z.ZodBoolean>;
689
695
  news: z.ZodOptional<z.ZodBoolean>;
@@ -11,12 +11,13 @@ const SiteConfigSchema = z.object({
11
11
  mode: z.enum(["demo", "live"]),
12
12
  demoEditing: z.boolean().optional(),
13
13
  lang: z.string().max(10).optional(),
14
+ locales: z.array(z.string().min(2).max(10)).max(10).optional(),
15
+ defaultLocale: z.string().min(2).max(10).optional(),
14
16
  theme: ThemeSchema,
15
17
  nav: z.array(NavItemSchema).max(50).optional(),
16
18
  contactEmail: z.string().email().optional(),
17
19
  seoDefaults: SeoSchema.optional(),
18
20
  forms: FormsSenderSchema.optional(),
19
- defaults: z.record(z.string(), z.string()).optional(),
20
21
  features: z.object({
21
22
  pages: z.boolean().optional(),
22
23
  news: z.boolean().optional(),
@@ -1 +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":[]}
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 /**\n * Extra talen naast de default (5.0), bv. `[\"de\", \"en\"]`. Vertalingen leven als overlay op\n * pagina's/symbolen; niet-default talen krijgen een URL-prefix (`/de/over-ons`). Weglaten =\n * ééntalige site (geen overhead).\n */\n locales?: string[];\n /** Default-taal van de canonieke content (default: `lang` ?? \"nl\"). */\n defaultLocale?: 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 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 locales: z.array(z.string().min(2).max(10)).max(10).optional(),\n defaultLocale: z.string().min(2).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 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;AAmE7B,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,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EAC7D,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EAClD,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,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,205 @@
1
+ /**
2
+ * Symbols (5.0, primo-concept): een symbol is een benoemde, gedeelde sectie — een compositie van
3
+ * gewone blokken — die op meerdere pagina's als **referentie** wordt ingevoegd (`symbolRef`-blok).
4
+ * Wijzig het symbol → alle pagina's die ernaar verwijzen bewegen mee (i.t.t. patterns, die bij
5
+ * invoegen worden gekloond). "Loskoppelen" in de editor zet een referentie om in een kloon.
6
+ *
7
+ * Opslag: `sites/{siteId}/symbols/{symbolId}` — publiek leesbaar (de live site leest ze bij het
8
+ * renderen), schrijven alleen via de `saveSymbol`-callable (sanitize + validatie + audit).
9
+ * Een symbol mag GEEN symbolRef bevatten (geen recursie) — afgedwongen in schema én callable.
10
+ */
11
+ import { z } from "zod";
12
+ export declare const SymbolSchema: z.ZodObject<{
13
+ name: z.ZodString;
14
+ /** De blok-compositie van het symbol (zelfde vorm als page.blocks). */
15
+ blocks: z.ZodEffects<z.ZodDefault<z.ZodArray<z.ZodObject<{
16
+ _type: z.ZodString;
17
+ _key: z.ZodString;
18
+ _style: z.ZodOptional<z.ZodObject<{
19
+ paddingY: z.ZodOptional<z.ZodEnum<["none", "sm", "md", "lg", "xl"]>>;
20
+ background: z.ZodOptional<z.ZodString>;
21
+ width: z.ZodOptional<z.ZodEnum<["container", "full", "narrow"]>>;
22
+ align: z.ZodOptional<z.ZodEnum<["left", "center", "right"]>>;
23
+ anchorId: z.ZodOptional<z.ZodString>;
24
+ animate: z.ZodOptional<z.ZodEnum<["fade", "up"]>>;
25
+ }, "strip", z.ZodTypeAny, {
26
+ background?: string | undefined;
27
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
28
+ width?: "container" | "full" | "narrow" | undefined;
29
+ align?: "left" | "center" | "right" | undefined;
30
+ anchorId?: string | undefined;
31
+ animate?: "fade" | "up" | undefined;
32
+ }, {
33
+ background?: string | undefined;
34
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
35
+ width?: "container" | "full" | "narrow" | undefined;
36
+ align?: "left" | "center" | "right" | undefined;
37
+ anchorId?: string | undefined;
38
+ animate?: "fade" | "up" | undefined;
39
+ }>>;
40
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
41
+ _type: z.ZodString;
42
+ _key: z.ZodString;
43
+ _style: z.ZodOptional<z.ZodObject<{
44
+ paddingY: z.ZodOptional<z.ZodEnum<["none", "sm", "md", "lg", "xl"]>>;
45
+ background: z.ZodOptional<z.ZodString>;
46
+ width: z.ZodOptional<z.ZodEnum<["container", "full", "narrow"]>>;
47
+ align: z.ZodOptional<z.ZodEnum<["left", "center", "right"]>>;
48
+ anchorId: z.ZodOptional<z.ZodString>;
49
+ animate: z.ZodOptional<z.ZodEnum<["fade", "up"]>>;
50
+ }, "strip", z.ZodTypeAny, {
51
+ background?: string | undefined;
52
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
53
+ width?: "container" | "full" | "narrow" | undefined;
54
+ align?: "left" | "center" | "right" | undefined;
55
+ anchorId?: string | undefined;
56
+ animate?: "fade" | "up" | undefined;
57
+ }, {
58
+ background?: string | undefined;
59
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
60
+ width?: "container" | "full" | "narrow" | undefined;
61
+ align?: "left" | "center" | "right" | undefined;
62
+ anchorId?: string | undefined;
63
+ animate?: "fade" | "up" | undefined;
64
+ }>>;
65
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
66
+ _type: z.ZodString;
67
+ _key: z.ZodString;
68
+ _style: z.ZodOptional<z.ZodObject<{
69
+ paddingY: z.ZodOptional<z.ZodEnum<["none", "sm", "md", "lg", "xl"]>>;
70
+ background: z.ZodOptional<z.ZodString>;
71
+ width: z.ZodOptional<z.ZodEnum<["container", "full", "narrow"]>>;
72
+ align: z.ZodOptional<z.ZodEnum<["left", "center", "right"]>>;
73
+ anchorId: z.ZodOptional<z.ZodString>;
74
+ animate: z.ZodOptional<z.ZodEnum<["fade", "up"]>>;
75
+ }, "strip", z.ZodTypeAny, {
76
+ background?: string | undefined;
77
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
78
+ width?: "container" | "full" | "narrow" | undefined;
79
+ align?: "left" | "center" | "right" | undefined;
80
+ anchorId?: string | undefined;
81
+ animate?: "fade" | "up" | undefined;
82
+ }, {
83
+ background?: string | undefined;
84
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
85
+ width?: "container" | "full" | "narrow" | undefined;
86
+ align?: "left" | "center" | "right" | undefined;
87
+ anchorId?: string | undefined;
88
+ animate?: "fade" | "up" | undefined;
89
+ }>>;
90
+ }, z.ZodTypeAny, "passthrough">>, "many">>, z.objectOutputType<{
91
+ _type: z.ZodString;
92
+ _key: z.ZodString;
93
+ _style: z.ZodOptional<z.ZodObject<{
94
+ paddingY: z.ZodOptional<z.ZodEnum<["none", "sm", "md", "lg", "xl"]>>;
95
+ background: z.ZodOptional<z.ZodString>;
96
+ width: z.ZodOptional<z.ZodEnum<["container", "full", "narrow"]>>;
97
+ align: z.ZodOptional<z.ZodEnum<["left", "center", "right"]>>;
98
+ anchorId: z.ZodOptional<z.ZodString>;
99
+ animate: z.ZodOptional<z.ZodEnum<["fade", "up"]>>;
100
+ }, "strip", z.ZodTypeAny, {
101
+ background?: string | undefined;
102
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
103
+ width?: "container" | "full" | "narrow" | undefined;
104
+ align?: "left" | "center" | "right" | undefined;
105
+ anchorId?: string | undefined;
106
+ animate?: "fade" | "up" | undefined;
107
+ }, {
108
+ background?: string | undefined;
109
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
110
+ width?: "container" | "full" | "narrow" | undefined;
111
+ align?: "left" | "center" | "right" | undefined;
112
+ anchorId?: string | undefined;
113
+ animate?: "fade" | "up" | undefined;
114
+ }>>;
115
+ }, z.ZodTypeAny, "passthrough">[], z.objectInputType<{
116
+ _type: z.ZodString;
117
+ _key: z.ZodString;
118
+ _style: z.ZodOptional<z.ZodObject<{
119
+ paddingY: z.ZodOptional<z.ZodEnum<["none", "sm", "md", "lg", "xl"]>>;
120
+ background: z.ZodOptional<z.ZodString>;
121
+ width: z.ZodOptional<z.ZodEnum<["container", "full", "narrow"]>>;
122
+ align: z.ZodOptional<z.ZodEnum<["left", "center", "right"]>>;
123
+ anchorId: z.ZodOptional<z.ZodString>;
124
+ animate: z.ZodOptional<z.ZodEnum<["fade", "up"]>>;
125
+ }, "strip", z.ZodTypeAny, {
126
+ background?: string | undefined;
127
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
128
+ width?: "container" | "full" | "narrow" | undefined;
129
+ align?: "left" | "center" | "right" | undefined;
130
+ anchorId?: string | undefined;
131
+ animate?: "fade" | "up" | undefined;
132
+ }, {
133
+ background?: string | undefined;
134
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
135
+ width?: "container" | "full" | "narrow" | undefined;
136
+ align?: "left" | "center" | "right" | undefined;
137
+ anchorId?: string | undefined;
138
+ animate?: "fade" | "up" | undefined;
139
+ }>>;
140
+ }, z.ZodTypeAny, "passthrough">[] | undefined>;
141
+ /** Taal-overlay (5.0): per locale gepunte veldpaden → vertaalde tekst (zie i18n/overlay.ts). */
142
+ translations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodString>, Record<string, string>, Record<string, string>>>>;
143
+ }, "strip", z.ZodTypeAny, {
144
+ name: string;
145
+ blocks: z.objectOutputType<{
146
+ _type: z.ZodString;
147
+ _key: z.ZodString;
148
+ _style: z.ZodOptional<z.ZodObject<{
149
+ paddingY: z.ZodOptional<z.ZodEnum<["none", "sm", "md", "lg", "xl"]>>;
150
+ background: z.ZodOptional<z.ZodString>;
151
+ width: z.ZodOptional<z.ZodEnum<["container", "full", "narrow"]>>;
152
+ align: z.ZodOptional<z.ZodEnum<["left", "center", "right"]>>;
153
+ anchorId: z.ZodOptional<z.ZodString>;
154
+ animate: z.ZodOptional<z.ZodEnum<["fade", "up"]>>;
155
+ }, "strip", z.ZodTypeAny, {
156
+ background?: string | undefined;
157
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
158
+ width?: "container" | "full" | "narrow" | undefined;
159
+ align?: "left" | "center" | "right" | undefined;
160
+ anchorId?: string | undefined;
161
+ animate?: "fade" | "up" | undefined;
162
+ }, {
163
+ background?: string | undefined;
164
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
165
+ width?: "container" | "full" | "narrow" | undefined;
166
+ align?: "left" | "center" | "right" | undefined;
167
+ anchorId?: string | undefined;
168
+ animate?: "fade" | "up" | undefined;
169
+ }>>;
170
+ }, z.ZodTypeAny, "passthrough">[];
171
+ translations?: Record<string, Record<string, string>> | undefined;
172
+ }, {
173
+ name: string;
174
+ blocks?: z.objectInputType<{
175
+ _type: z.ZodString;
176
+ _key: z.ZodString;
177
+ _style: z.ZodOptional<z.ZodObject<{
178
+ paddingY: z.ZodOptional<z.ZodEnum<["none", "sm", "md", "lg", "xl"]>>;
179
+ background: z.ZodOptional<z.ZodString>;
180
+ width: z.ZodOptional<z.ZodEnum<["container", "full", "narrow"]>>;
181
+ align: z.ZodOptional<z.ZodEnum<["left", "center", "right"]>>;
182
+ anchorId: z.ZodOptional<z.ZodString>;
183
+ animate: z.ZodOptional<z.ZodEnum<["fade", "up"]>>;
184
+ }, "strip", z.ZodTypeAny, {
185
+ background?: string | undefined;
186
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
187
+ width?: "container" | "full" | "narrow" | undefined;
188
+ align?: "left" | "center" | "right" | undefined;
189
+ anchorId?: string | undefined;
190
+ animate?: "fade" | "up" | undefined;
191
+ }, {
192
+ background?: string | undefined;
193
+ paddingY?: "sm" | "md" | "lg" | "xl" | "none" | undefined;
194
+ width?: "container" | "full" | "narrow" | undefined;
195
+ align?: "left" | "center" | "right" | undefined;
196
+ anchorId?: string | undefined;
197
+ animate?: "fade" | "up" | undefined;
198
+ }>>;
199
+ }, z.ZodTypeAny, "passthrough">[] | undefined;
200
+ translations?: Record<string, Record<string, string>> | undefined;
201
+ }>;
202
+ export type Symbol = z.infer<typeof SymbolSchema>;
203
+ export type StoredSymbol = Symbol & {
204
+ id: string;
205
+ };
@@ -0,0 +1,18 @@
1
+ import { z } from "zod";
2
+ import { BlockBaseSchema } from "./blocks";
3
+ import { TranslationsSchema } from "../i18n/overlay";
4
+ const SymbolSchema = z.object({
5
+ name: z.string().min(1).max(120).describe("Naam"),
6
+ /** De blok-compositie van het symbol (zelfde vorm als page.blocks). */
7
+ blocks: z.array(BlockBaseSchema).max(50).default([]).superRefine((blocks, ctx) => {
8
+ if (blocks.some((b) => b._type === "symbolRef")) {
9
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Een symbool kan geen ander symbool bevatten." });
10
+ }
11
+ }),
12
+ /** Taal-overlay (5.0): per locale gepunte veldpaden → vertaalde tekst (zie i18n/overlay.ts). */
13
+ translations: TranslationsSchema.optional()
14
+ });
15
+ export {
16
+ SymbolSchema
17
+ };
18
+ //# sourceMappingURL=symbols.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/schema/symbols.ts"],"sourcesContent":["/**\n * Symbols (5.0, primo-concept): een symbol is een benoemde, gedeelde sectie — een compositie van\n * gewone blokken — die op meerdere pagina's als **referentie** wordt ingevoegd (`symbolRef`-blok).\n * Wijzig het symbol → alle pagina's die ernaar verwijzen bewegen mee (i.t.t. patterns, die bij\n * invoegen worden gekloond). \"Loskoppelen\" in de editor zet een referentie om in een kloon.\n *\n * Opslag: `sites/{siteId}/symbols/{symbolId}` — publiek leesbaar (de live site leest ze bij het\n * renderen), schrijven alleen via de `saveSymbol`-callable (sanitize + validatie + audit).\n * Een symbol mag GEEN symbolRef bevatten (geen recursie) — afgedwongen in schema én callable.\n */\nimport { z } from \"zod\";\nimport { BlockBaseSchema } from \"./blocks\";\nimport { TranslationsSchema } from \"../i18n/overlay\";\n\nexport const SymbolSchema = z.object({\n name: z.string().min(1).max(120).describe(\"Naam\"),\n /** De blok-compositie van het symbol (zelfde vorm als page.blocks). */\n blocks: z\n .array(BlockBaseSchema)\n .max(50)\n .default([])\n .superRefine((blocks, ctx) => {\n if (blocks.some((b) => b._type === \"symbolRef\")) {\n ctx.addIssue({ code: z.ZodIssueCode.custom, message: \"Een symbool kan geen ander symbool bevatten.\" });\n }\n }),\n /** Taal-overlay (5.0): per locale gepunte veldpaden → vertaalde tekst (zie i18n/overlay.ts). */\n translations: TranslationsSchema.optional(),\n});\nexport type Symbol = z.infer<typeof SymbolSchema>;\nexport type StoredSymbol = Symbol & { id: string };\n"],"mappings":"AAUA,SAAS,SAAS;AAClB,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AAE5B,MAAM,eAAe,EAAE,OAAO;AAAA,EACnC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,MAAM;AAAA;AAAA,EAEhD,QAAQ,EACL,MAAM,eAAe,EACrB,IAAI,EAAE,EACN,QAAQ,CAAC,CAAC,EACV,YAAY,CAAC,QAAQ,QAAQ;AAC5B,QAAI,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,WAAW,GAAG;AAC/C,UAAI,SAAS,EAAE,MAAM,EAAE,aAAa,QAAQ,SAAS,+CAA+C,CAAC;AAAA,IACvG;AAAA,EACF,CAAC;AAAA;AAAA,EAEH,cAAc,mBAAmB,SAAS;AAC5C,CAAC;","names":[]}
@@ -7,4 +7,5 @@ export { getAdminApp, getAdminAuth, getAdminDb } from "../firebase/admin";
7
7
  export { sanitizeRichText } from "./sanitize";
8
8
  export { buildMetadata, buildJsonLd, buildSitemap, buildRobots, siteOrigin, businessJsonLd, breadcrumbListJsonLd, articleJsonLd, productJsonLd, openingHoursJsonLd, galleryJsonLd, videoObjectJsonLd, type BusinessInfo, } from "./seo";
9
9
  export { validateEnv, assertEnv, type EnvReport } from "./env";
10
- export { pathFromSlugs, listPublishedPages, getPublishedPageByPath, getDraftPageById, getDraftPageByPath, type StoredPage, } from "./pages";
10
+ export { pathFromSlugs, listPublishedPages, getPublishedPageByPath, getPublishedPageByPathExpanded, getSiteSymbols, expandSymbols, getSiteCustomBlocks, getDraftPageById, getDraftPageByPath, type StoredPage, } from "./pages";
11
+ export { siteLocales, parseLocaleSlugs, localizedPath, localizePage, localizeBlocks, pruneTranslations, TranslationsSchema, type Translations, type LocaleConfig, } from "../i18n/overlay";