@designcrowd/library.brand-page 5.17.28 → 5.18.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 (380) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-CJZpKPNH.js → CreatedOnBrandCrowd-de-de-xmkupPus.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DkIa7iEb.js → CreatedOnBrandCrowd-en-us-Ck7EdTtb.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-CE2p6XHz.js → CreatedOnBrandCrowd-es-es-BC8sJuDH.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-BBjOZS3M.js → CreatedOnBrandCrowd-fr-ca-CN-UBe1q.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-BBjOZS3M.js → CreatedOnBrandCrowd-fr-fr-CN-UBe1q.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-Dayzl4BZ.js → CreatedOnBrandCrowd-pt-br-CajQyNkx.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-Dayzl4BZ.js → CreatedOnBrandCrowd-pt-pt-CajQyNkx.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-CFzDqfCb.js → CreatedOnDcom-de-de-BRCNMmDq.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-C2jIPBDY.js → CreatedOnDcom-en-us-BzQDtZhc.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-qejpzqho.js → CreatedOnDcom-es-es-D-qAM4Cd.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-DMO9Ld7K.js → CreatedOnDcom-fr-ca-CZ1irFOc.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-BFWN9qTP.js → CreatedOnDcom-fr-fr-Gb5BCF0N.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-CneD3ghF.js → CreatedOnDcom-pt-br-CAQV0q6o.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-Cg1B7s0o.js → CreatedOnDcom-pt-pt-D6tQdQFh.js} +1 -1
  15. package/lib/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.js +2 -2
  16. package/lib/src/brand-page/models/brand-page-context.model.d.ts +0 -2
  17. package/lib/src/brand-page/models/brand-page-context.model.js +1 -11
  18. package/lib/src/brand-page/models/index.d.ts +1 -0
  19. package/lib/src/brand-page/models/index.js +1 -0
  20. package/lib/src/brand-page/utils/color.util.js +23 -3
  21. package/lib/src/brand-page/utils/raygun.util.d.ts +5 -1
  22. package/lib/src/brand-page/utils/raygun.util.js +7 -2
  23. package/lib/src/brand-page/utils/svg-color.util.js +1 -2
  24. package/lib/src/brand-page/utils/view-model.util.js +1 -1
  25. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -31
  26. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +0 -2
  27. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +2 -31
  28. package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +0 -14
  29. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +0 -28
  30. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +0 -28
  31. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +0 -28
  32. package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +0 -28
  33. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +0 -28
  34. package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +0 -28
  35. package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.d.ts +35 -0
  36. package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.js +108 -0
  37. package/lib/src/brand-page-maker/composables/ai-chat/{useAiChat.d.ts → types.d.ts} +5 -13
  38. package/lib/src/brand-page-maker/composables/ai-chat/types.js +1 -0
  39. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +19 -0
  40. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +1 -0
  41. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.d.ts +1 -1
  42. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +488 -82
  43. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +5 -5
  44. package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +6 -16
  45. package/lib/src/brand-page-maker/composables/useEventTracker.js +19 -21
  46. package/lib/src/brand-page-maker/constants/sidebar-constant.d.ts +0 -1
  47. package/lib/src/brand-page-maker/constants/sidebar-constant.js +7 -15
  48. package/lib/src/brand-page-maker/convertors/image-aspect-ratio.convertor.js +2 -2
  49. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.js +3 -1
  50. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +30660 -0
  51. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.js +34 -0
  52. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +1 -1
  53. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +0 -28
  54. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +42 -2
  55. package/lib/src/brand-page-maker/stores/index.d.ts +1 -1
  56. package/lib/src/brand-page-maker/stores/index.js +1 -1
  57. package/lib/src/brand-page-maker/stores/user/user-store.js +0 -1
  58. package/lib/src/bundled-translations-CnareLWC.js +175 -0
  59. package/lib/src/bundled-translations.de-DE-2Ys7epLO.js +175 -0
  60. package/lib/src/bundled-translations.es-ES-Cjp-G8rT.js +175 -0
  61. package/lib/src/bundled-translations.fr-CA-CsaW4Oae.js +175 -0
  62. package/lib/src/bundled-translations.fr-FR-DIT2dd8J.js +175 -0
  63. package/lib/src/bundled-translations.pt-BR-BamoBpDW.js +175 -0
  64. package/lib/src/bundled-translations.pt-PT-C9A4hY_e.js +175 -0
  65. package/lib/src/bundles/bundled-translations.de-DE.json +1 -20
  66. package/lib/src/bundles/bundled-translations.es-ES.json +1 -20
  67. package/lib/src/bundles/bundled-translations.fr-CA.json +1 -20
  68. package/lib/src/bundles/bundled-translations.fr-FR.json +1 -20
  69. package/lib/src/bundles/bundled-translations.json +1 -20
  70. package/lib/src/bundles/bundled-translations.pt-BR.json +1 -20
  71. package/lib/src/bundles/bundled-translations.pt-PT.json +1 -20
  72. package/lib/src/clients/ai-assistant-client.d.ts +30 -29
  73. package/lib/src/clients/ai-assistant-client.js +16 -16
  74. package/lib/src/clients/design-template-client.d.ts +0 -2
  75. package/lib/src/clients/design-template-client.js +0 -38
  76. package/lib/src/clients/websocket-gateway-client.d.ts +9 -1
  77. package/lib/src/composables/useTranslate.d.ts +2 -1
  78. package/lib/src/composables/useTranslate.js +2 -1
  79. package/lib/src/constants/ui.d.ts +0 -1
  80. package/lib/src/css/library.brand-page-brandCrowd.min.css +225 -134
  81. package/lib/src/css/library.brand-page-brandPage.min.css +227 -121
  82. package/lib/src/css/library.brand-page-designCom.min.css +225 -134
  83. package/lib/src/css/library.brand-page-preview.min.css +225 -118
  84. package/lib/src/index.d.ts +1 -1
  85. package/lib/src/index.mjs +1 -1
  86. package/lib/src/{lib-33w_DBny.js → lib-CSRUPpSo.js} +30887 -29395
  87. package/lib/src/metadata-builder/ai-metadata-executor.d.ts +21 -0
  88. package/lib/src/metadata-builder/ai-metadata-executor.js +56 -3
  89. package/lib/src/metadata-builder/builders/add-page-builder.d.ts +2 -4
  90. package/lib/src/metadata-builder/builders/add-page-builder.js +5 -8
  91. package/lib/src/metadata-builder/builders/footer-builder.d.ts +11 -0
  92. package/lib/src/metadata-builder/builders/footer-builder.js +151 -0
  93. package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +15 -0
  94. package/lib/src/metadata-builder/builders/global-styles-builder.js +129 -0
  95. package/lib/src/metadata-builder/builders/header-builder.d.ts +11 -0
  96. package/lib/src/metadata-builder/builders/header-builder.js +167 -0
  97. package/lib/src/metadata-builder/builders/rename-page-builder.d.ts +12 -0
  98. package/lib/src/metadata-builder/builders/rename-page-builder.js +49 -0
  99. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.d.ts +2 -0
  100. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +44 -4
  101. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.d.ts +2 -0
  102. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +70 -6
  103. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.d.ts +36 -4
  104. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.js +102 -12
  105. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.d.ts +8 -0
  106. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +50 -0
  107. package/lib/src/metadata-builder/builders/section-builders/button-section-builder.d.ts +2 -0
  108. package/lib/src/metadata-builder/builders/section-builders/button-section-builder.js +5 -1
  109. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.d.ts +2 -0
  110. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +47 -3
  111. package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.d.ts +2 -1
  112. package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.js +5 -2
  113. package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.d.ts +2 -0
  114. package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.js +11 -1
  115. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.d.ts +2 -0
  116. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +52 -13
  117. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.d.ts +2 -0
  118. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +47 -17
  119. package/lib/src/metadata-builder/builders/section-builders/index.d.ts +1 -0
  120. package/lib/src/metadata-builder/builders/section-builders/index.js +1 -0
  121. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.d.ts +2 -0
  122. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +20 -2
  123. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.d.ts +2 -0
  124. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +20 -2
  125. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.d.ts +2 -0
  126. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +36 -2
  127. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.d.ts +2 -0
  128. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +70 -27
  129. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.d.ts +2 -0
  130. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +7 -2
  131. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.d.ts +2 -0
  132. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +91 -26
  133. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.d.ts +2 -0
  134. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +69 -31
  135. package/lib/src/metadata-builder/builders/section-content-factory.d.ts +2 -2
  136. package/lib/src/metadata-builder/builders/section-content-factory.js +8 -2
  137. package/lib/src/metadata-builder/builders/section-field-maps.js +30 -2
  138. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +46 -7
  139. package/lib/src/metadata-builder/builders/section-field-utils.js +86 -62
  140. package/lib/src/metadata-builder/builders/section-rules/about-section.rules.d.ts +2 -0
  141. package/lib/src/metadata-builder/builders/section-rules/about-section.rules.js +20 -0
  142. package/lib/src/metadata-builder/builders/section-rules/add-page.rules.d.ts +7 -0
  143. package/lib/src/metadata-builder/builders/section-rules/add-page.rules.js +8 -0
  144. package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.d.ts +2 -0
  145. package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.js +27 -0
  146. package/lib/src/metadata-builder/builders/section-rules/booking-section.rules.d.ts +2 -0
  147. package/lib/src/metadata-builder/builders/section-rules/booking-section.rules.js +16 -0
  148. package/lib/src/metadata-builder/builders/section-rules/button-section.rules.d.ts +2 -0
  149. package/lib/src/metadata-builder/builders/section-rules/button-section.rules.js +13 -0
  150. package/lib/src/metadata-builder/builders/section-rules/contact-form.rules.d.ts +2 -0
  151. package/lib/src/metadata-builder/builders/section-rules/contact-form.rules.js +16 -0
  152. package/lib/src/metadata-builder/builders/section-rules/divider-section.rules.d.ts +2 -0
  153. package/lib/src/metadata-builder/builders/section-rules/divider-section.rules.js +7 -0
  154. package/lib/src/metadata-builder/builders/section-rules/footer.rules.d.ts +4 -0
  155. package/lib/src/metadata-builder/builders/section-rules/footer.rules.js +5 -0
  156. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.d.ts +6 -0
  157. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.js +26 -0
  158. package/lib/src/metadata-builder/builders/section-rules/header.rules.d.ts +4 -0
  159. package/lib/src/metadata-builder/builders/section-rules/header.rules.js +41 -0
  160. package/lib/src/metadata-builder/builders/section-rules/image-gallery.rules.d.ts +2 -0
  161. package/lib/src/metadata-builder/builders/section-rules/image-gallery.rules.js +10 -0
  162. package/lib/src/metadata-builder/builders/section-rules/images-section.rules.d.ts +2 -0
  163. package/lib/src/metadata-builder/builders/section-rules/images-section.rules.js +31 -0
  164. package/lib/src/metadata-builder/builders/section-rules/mailing-list.rules.d.ts +2 -0
  165. package/lib/src/metadata-builder/builders/section-rules/mailing-list.rules.js +11 -0
  166. package/lib/src/metadata-builder/builders/section-rules/profile.rules.d.ts +2 -0
  167. package/lib/src/metadata-builder/builders/section-rules/profile.rules.js +14 -0
  168. package/lib/src/metadata-builder/builders/section-rules/rename-page.rules.d.ts +7 -0
  169. package/lib/src/metadata-builder/builders/section-rules/rename-page.rules.js +8 -0
  170. package/lib/src/metadata-builder/builders/section-rules/shapes-section.rules.d.ts +2 -0
  171. package/lib/src/metadata-builder/builders/section-rules/shapes-section.rules.js +27 -0
  172. package/lib/src/metadata-builder/builders/section-rules/social-links.rules.d.ts +2 -0
  173. package/lib/src/metadata-builder/builders/section-rules/social-links.rules.js +9 -0
  174. package/lib/src/metadata-builder/builders/section-rules/testimonial-section.rules.d.ts +7 -0
  175. package/lib/src/metadata-builder/builders/section-rules/testimonial-section.rules.js +26 -0
  176. package/lib/src/metadata-builder/builders/section-rules/text-section.rules.d.ts +2 -0
  177. package/lib/src/metadata-builder/builders/section-rules/text-section.rules.js +14 -0
  178. package/lib/src/metadata-builder/builders/shape-color-utils.d.ts +26 -0
  179. package/lib/src/metadata-builder/builders/shape-color-utils.js +52 -0
  180. package/lib/src/metadata-builder/builders/undo-builder.d.ts +48 -0
  181. package/lib/src/metadata-builder/builders/undo-builder.js +58 -0
  182. package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +5 -1
  183. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +15 -4
  184. package/lib/src/metadata-builder/helpers/rte.helpers.js +24 -10
  185. package/lib/src/metadata-builder/metadata-executor.d.ts +2 -1
  186. package/lib/src/metadata-builder/metadata-executor.js +32 -5
  187. package/lib/src/metadata-builder/models.d.ts +26 -1
  188. package/lib/src/metadata-builder/models.js +14 -1
  189. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +144 -0
  190. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +17 -0
  191. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +113 -24
  192. package/lib/src/metadata-builder/parsers/section-tool-arguments.js +5 -1
  193. package/lib/src/metadata-builder/sanitizers/rte-schema-check.d.ts +22 -0
  194. package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +84 -0
  195. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.d.ts +47 -0
  196. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.js +60 -0
  197. package/lib/src/metadata-builder/sanitizers/section-args-validator.d.ts +41 -0
  198. package/lib/src/metadata-builder/sanitizers/section-args-validator.js +274 -0
  199. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +2 -1
  200. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +2 -16
  201. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.stories.js +0 -1
  202. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +2 -1
  203. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +2 -3
  204. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +0 -4
  205. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +6 -8
  206. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +0 -28
  207. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +2 -1
  208. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +0 -28
  209. package/lib/src/shared/navigation-style-settings/store/index.js +1 -0
  210. package/lib/src/shared/page-navigation/store/page-navigation-store.js +1 -20
  211. package/lib/src/shared/page-navigation/utils/nav-order-utils.d.ts +3 -0
  212. package/lib/src/shared/page-navigation/utils/nav-order-utils.js +20 -0
  213. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -30
  214. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +0 -28
  215. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +2 -43
  216. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +0 -30
  217. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +2 -3
  218. package/lib/src/shared/side-bar/store/side-bar-store.d.ts +0 -12
  219. package/lib/src/shared/side-bar/store/side-bar-store.js +0 -7
  220. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +2 -29
  221. package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +2 -1
  222. package/lib/src/utils/build-asset-manifest.d.ts +26 -0
  223. package/lib/src/utils/build-asset-manifest.js +114 -0
  224. package/lib/src/utils/minify-brand-page-metadata.d.ts +49 -1
  225. package/lib/src/utils/minify-brand-page-metadata.js +216 -129
  226. package/package.json +1 -1
  227. package/src/brand-page/components/banner-section/BannerSection.vue +1 -1
  228. package/src/brand-page/components/contact-form/ContactForm.vue +29 -26
  229. package/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.ts +6 -2
  230. package/src/brand-page/components/text-media-section/TextMediaSection.vue +1 -5
  231. package/src/brand-page/models/brand-page-context.model.ts +1 -25
  232. package/src/brand-page/models/index.ts +1 -0
  233. package/src/brand-page/utils/color.util.test.ts +48 -0
  234. package/src/brand-page/utils/color.util.ts +29 -4
  235. package/src/brand-page/utils/raygun.util.ts +11 -2
  236. package/src/brand-page/utils/svg-color.util.ts +1 -3
  237. package/src/brand-page/utils/view-model.util.ts +1 -4
  238. package/src/brand-page-maker/components/ai-text-edit/AiChatbox.vue +2 -2
  239. package/src/brand-page-maker/components/ai-text-edit/AiProgressFeed.vue +162 -0
  240. package/src/brand-page-maker/components/ai-text-edit/TextBubble.vue +57 -5
  241. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.de-DE.json +0 -20
  242. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.es-ES.json +0 -20
  243. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.fr-CA.json +0 -20
  244. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.fr-FR.json +0 -20
  245. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.json +0 -20
  246. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.pt-BR.json +0 -20
  247. package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.pt-PT.json +0 -20
  248. package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +1 -2
  249. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.de-DE.json +3 -0
  250. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.es-ES.json +3 -0
  251. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.fr-CA.json +3 -0
  252. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.fr-FR.json +3 -0
  253. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.json +3 -0
  254. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.pt-BR.json +3 -0
  255. package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.pt-PT.json +3 -0
  256. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +3 -28
  257. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -2
  258. package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.test.ts +229 -0
  259. package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.ts +164 -0
  260. package/src/brand-page-maker/composables/ai-chat/types.ts +49 -0
  261. package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +20 -0
  262. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +651 -94
  263. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +9 -9
  264. package/src/brand-page-maker/composables/useEventTracker.ts +31 -25
  265. package/src/brand-page-maker/constants/sidebar-constant.ts +7 -15
  266. package/src/brand-page-maker/convertors/image-aspect-ratio.convertor.ts +2 -2
  267. package/src/brand-page-maker/convertors/text-size-value.convertor.ts +3 -3
  268. package/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.ts +54 -0
  269. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +76 -0
  270. package/src/brand-page-maker/stores/index.ts +1 -1
  271. package/src/brand-page-maker/stores/user/user-store.ts +0 -1
  272. package/src/bundles/bundled-translations.de-DE.json +1 -20
  273. package/src/bundles/bundled-translations.es-ES.json +1 -20
  274. package/src/bundles/bundled-translations.fr-CA.json +1 -20
  275. package/src/bundles/bundled-translations.fr-FR.json +1 -20
  276. package/src/bundles/bundled-translations.json +1 -20
  277. package/src/bundles/bundled-translations.pt-BR.json +1 -20
  278. package/src/bundles/bundled-translations.pt-PT.json +1 -20
  279. package/src/clients/ai-assistant-client.ts +59 -46
  280. package/src/clients/design-template-client.ts +0 -66
  281. package/src/clients/websocket-gateway-client.ts +17 -1
  282. package/src/composables/useTranslate.ts +3 -0
  283. package/src/constants/ui.ts +0 -1
  284. package/src/lib.ts +1 -0
  285. package/src/metadata-builder/ai-metadata-executor.ts +94 -1
  286. package/src/metadata-builder/builders/add-page-builder.ts +9 -13
  287. package/src/metadata-builder/builders/footer-builder.test.ts +76 -0
  288. package/src/metadata-builder/builders/footer-builder.ts +226 -0
  289. package/src/metadata-builder/builders/global-styles-builder.ts +187 -0
  290. package/src/metadata-builder/builders/header-builder.test.ts +106 -0
  291. package/src/metadata-builder/builders/header-builder.ts +254 -0
  292. package/src/metadata-builder/builders/rename-page-builder.ts +79 -0
  293. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +73 -5
  294. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +112 -7
  295. package/src/metadata-builder/builders/section-builders/base-section-builder.ts +149 -11
  296. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +87 -0
  297. package/src/metadata-builder/builders/section-builders/button-section-builder.ts +6 -1
  298. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +74 -4
  299. package/src/metadata-builder/builders/section-builders/delete-section-builder.ts +15 -1
  300. package/src/metadata-builder/builders/section-builders/divider-section-builder.ts +13 -1
  301. package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +91 -31
  302. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +102 -48
  303. package/src/metadata-builder/builders/section-builders/index.ts +1 -0
  304. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +38 -2
  305. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +38 -2
  306. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +55 -3
  307. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +170 -77
  308. package/src/metadata-builder/builders/section-builders/social-links-builder.test.ts +119 -0
  309. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +13 -2
  310. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +178 -57
  311. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +130 -30
  312. package/src/metadata-builder/builders/section-content-factory.ts +15 -2
  313. package/src/metadata-builder/builders/section-field-maps.ts +34 -1
  314. package/src/metadata-builder/builders/section-field-utils.ts +131 -72
  315. package/src/metadata-builder/builders/section-rules/about-section.rules.ts +38 -0
  316. package/src/metadata-builder/builders/section-rules/add-page.rules.ts +17 -0
  317. package/src/metadata-builder/builders/section-rules/banner-section.rules.ts +49 -0
  318. package/src/metadata-builder/builders/section-rules/booking-section.rules.ts +34 -0
  319. package/src/metadata-builder/builders/section-rules/button-section.rules.ts +22 -0
  320. package/src/metadata-builder/builders/section-rules/contact-form.rules.ts +30 -0
  321. package/src/metadata-builder/builders/section-rules/divider-section.rules.ts +17 -0
  322. package/src/metadata-builder/builders/section-rules/footer.rules.ts +21 -0
  323. package/src/metadata-builder/builders/section-rules/global-styles.rules.ts +44 -0
  324. package/src/metadata-builder/builders/section-rules/header.rules.ts +75 -0
  325. package/src/metadata-builder/builders/section-rules/image-gallery.rules.ts +22 -0
  326. package/src/metadata-builder/builders/section-rules/images-section.rules.ts +55 -0
  327. package/src/metadata-builder/builders/section-rules/mailing-list.rules.ts +21 -0
  328. package/src/metadata-builder/builders/section-rules/profile.rules.ts +27 -0
  329. package/src/metadata-builder/builders/section-rules/rename-page.rules.ts +17 -0
  330. package/src/metadata-builder/builders/section-rules/shapes-section.rules.ts +51 -0
  331. package/src/metadata-builder/builders/section-rules/social-links.rules.ts +27 -0
  332. package/src/metadata-builder/builders/section-rules/testimonial-section.rules.ts +48 -0
  333. package/src/metadata-builder/builders/section-rules/text-section.rules.ts +28 -0
  334. package/src/metadata-builder/builders/shape-color-utils.test.ts +115 -0
  335. package/src/metadata-builder/builders/shape-color-utils.ts +75 -0
  336. package/src/metadata-builder/builders/undo-builder.ts +105 -0
  337. package/src/metadata-builder/builders/update-content-text-style-builder.ts +4 -1
  338. package/src/metadata-builder/helpers/rte.helpers.ts +27 -13
  339. package/src/metadata-builder/metadata-executor.ts +42 -2
  340. package/src/metadata-builder/models.ts +39 -1
  341. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +152 -0
  342. package/src/metadata-builder/parsers/section-tool-arguments.ts +138 -24
  343. package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +659 -0
  344. package/src/metadata-builder/sanitizers/rte-schema-check.ts +99 -0
  345. package/src/metadata-builder/sanitizers/sanitizer-rules.ts +97 -0
  346. package/src/metadata-builder/sanitizers/section-args-validator.ts +445 -0
  347. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +10 -16
  348. package/src/shared/content-settings/components/content-settings/ContentSettings.stories.ts +0 -1
  349. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +6 -10
  350. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.vue +1 -23
  351. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +0 -15
  352. package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +0 -15
  353. package/src/shared/navigation-style-settings/store/index.ts +5 -0
  354. package/src/shared/page-navigation/store/page-navigation-store.ts +4 -31
  355. package/src/shared/page-navigation/utils/nav-order-utils.ts +32 -0
  356. package/src/shared/side-bar/components/SideBar.vue +14 -1
  357. package/src/shared/side-bar/store/side-bar-store.ts +0 -20
  358. package/src/utils/build-asset-manifest.ts +153 -0
  359. package/src/utils/minify-brand-page-metadata.ts +362 -130
  360. package/lib/src/brand-page-maker/composables/ai-chat/useAiChat.js +0 -368
  361. package/lib/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.d.ts +0 -18
  362. package/lib/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.js +0 -144
  363. package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.d.ts +0 -155
  364. package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.js +0 -25
  365. package/lib/src/brand-page-maker/utils/mixpanel.util.d.ts +0 -1
  366. package/lib/src/brand-page-maker/utils/mixpanel.util.js +0 -29
  367. package/lib/src/bundled-translations-CNK7l6_v.js +0 -173
  368. package/lib/src/bundled-translations.de-DE-BLE4_y0H.js +0 -173
  369. package/lib/src/bundled-translations.es-ES-thO9osbg.js +0 -173
  370. package/lib/src/bundled-translations.fr-CA-BZkhiNgU.js +0 -173
  371. package/lib/src/bundled-translations.fr-FR-bhDLPKgZ.js +0 -173
  372. package/lib/src/bundled-translations.pt-BR-CI9a5Bq1.js +0 -173
  373. package/lib/src/bundled-translations.pt-PT-DBoErBaq.js +0 -173
  374. package/src/brand-page-maker/components/ai-text-edit/AiTextEdit.vue +0 -154
  375. package/src/brand-page-maker/composables/ai-chat/useAiChat.ts +0 -562
  376. package/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.ts +0 -196
  377. package/src/brand-page-maker/stores/ai-thread/ai-thread-store.ts +0 -31
  378. package/src/brand-page-maker/utils/mixpanel.util.ts +0 -42
  379. package/src/shared/content-settings/components/generate-ai-button/GenerateAiButton.vue +0 -114
  380. package/src/shared/content-settings/components/generate-ai-modal/GenerateAiModal.vue +0 -761
@@ -9,6 +9,7 @@
9
9
  import type {
10
10
  Content,
11
11
  BannerSectionContent,
12
+ BookingSectionContent,
12
13
  AboutSectionContent,
13
14
  TestimonialSectionContent,
14
15
  ImagesSectionContent,
@@ -42,13 +43,22 @@ const bannerFields = defineFieldMap<BannerSectionContent>({
42
43
  button_text: 'buttonText',
43
44
  button_url: 'url',
44
45
  background_image_url: 'imageUrl',
46
+ background_shape_url: 'imageUrl',
45
47
  display_style: 'displayStyle',
46
48
  });
47
49
 
50
+ const bookingFields = defineFieldMap<BookingSectionContent>({
51
+ title: 'title',
52
+ description: 'description',
53
+ button_text: 'buttonText',
54
+ button_url: 'url',
55
+ });
56
+
48
57
  const aboutFields = defineFieldMap<AboutSectionContent>({
49
58
  title: 'title',
50
59
  paragraph: 'paragraph',
51
60
  about_image_url: 'imageUrl',
61
+ about_shape_url: 'imageUrl',
52
62
  display_style: 'displayStyle',
53
63
  });
54
64
 
@@ -99,8 +109,8 @@ const contactFormFields = defineFieldMap<ContactFormContent>({
99
109
  });
100
110
 
101
111
  const mailingListFields = defineFieldMap<MailingListContent>({
102
- title: 'title',
103
112
  button_text: 'buttonText',
113
+ accepted_fields: 'acceptedFields',
104
114
  });
105
115
 
106
116
  const socialLinksFields = defineFieldMap<SocialLinksContent>({
@@ -111,6 +121,7 @@ const socialLinksFields = defineFieldMap<SocialLinksContent>({
111
121
 
112
122
  const dividerFields = defineFieldMap<DividerSectionContent>({
113
123
  divider_style: 'dividerStyle',
124
+ padding: 'paddingStyle',
114
125
  });
115
126
 
116
127
  const imageFields = defineFieldMap<ImageContent>({
@@ -119,6 +130,7 @@ const imageFields = defineFieldMap<ImageContent>({
119
130
  });
120
131
 
121
132
  const imageGalleryFields = defineFieldMap<ImageGalleryContent>({
133
+ is_full_width: 'isFullWidth',
122
134
  // images handled separately
123
135
  });
124
136
 
@@ -147,6 +159,7 @@ const socialButtonFields = defineFieldMap<ButtonContent>({
147
159
 
148
160
  export const SECTION_FIELD_MAPS: Record<string, SectionFieldMap> = {
149
161
  'banner-section': bannerFields,
162
+ 'booking-section': bookingFields,
150
163
  'about-section': aboutFields,
151
164
  'testimonial-section': testimonialFields,
152
165
  'images-section': imagesSectionFields,
@@ -213,6 +226,7 @@ const imagesSectionStyleFields = defineFieldMap<ImagesSectionContent>({
213
226
  description_style: 'descriptionStyle',
214
227
  heading_style: 'headingStyle',
215
228
  paragraph_style: 'paragraphStyle',
229
+ button_text_style: 'buttonTextStyle',
216
230
  });
217
231
 
218
232
  const shapesSectionStyleFields = defineFieldMap<ShapesSectionContent>({
@@ -222,14 +236,33 @@ const shapesSectionStyleFields = defineFieldMap<ShapesSectionContent>({
222
236
  paragraph_style: 'paragraphStyle',
223
237
  });
224
238
 
239
+ const bookingStyleFields = defineFieldMap<BookingSectionContent>({
240
+ title_style: 'titleStyle',
241
+ description_style: 'descriptionStyle',
242
+ button_text_style: 'buttonTextStyle',
243
+ });
244
+
245
+ const mailingListStyleFields = defineFieldMap<MailingListContent>({
246
+ title_style: 'titleStyle',
247
+ button_text_style: 'buttonTextStyle',
248
+ });
249
+
250
+ const socialLinksStyleFields = defineFieldMap<SocialLinksContent>({
251
+ icon_fill_style: 'iconFillStyles',
252
+ icon_background_style: 'iconBackgroundStyles',
253
+ });
254
+
225
255
  export const STYLE_FIELD_MAPS: Record<string, SectionFieldMap> = {
226
256
  'banner-section': bannerStyleFields,
257
+ 'booking-section': bookingStyleFields,
227
258
  'about-section': aboutStyleFields,
228
259
  text: textStyleFields,
229
260
  'testimonial-section': testimonialStyleFields,
230
261
  'contact-form': contactFormStyleFields,
231
262
  'images-section': imagesSectionStyleFields,
232
263
  'shapes-section': shapesSectionStyleFields,
264
+ 'mailing-list': mailingListStyleFields,
265
+ 'social-links': socialLinksStyleFields,
233
266
  };
234
267
 
235
268
  export const getStyleFieldMap = (
@@ -1,7 +1,14 @@
1
- import type { Content, TextStyleDeclaration } from '../../brand-page/models';
2
- import { RTE_ALLOWED_SECTION_TYPES } from '../../brand-page-maker/utils';
3
- import { updateRTEText } from '../helpers/rte.helpers';
4
- import type { SectionToolArguments } from '../parsers/section-tool-arguments';
1
+ import type { Content } from '../../brand-page/models';
2
+ import { BUTTON_LINK_TYPE } from '../../brand-page/models';
3
+ import type { ButtonLinkType } from '../../brand-page/models';
4
+ import type {
5
+ TextStyleOptions,
6
+ TextStyleType,
7
+ } from '../../brand-page/models/styles.model';
8
+ import {
9
+ isTiptapDocument,
10
+ type SectionToolArguments,
11
+ } from '../parsers/section-tool-arguments';
5
12
  import { getSectionFieldMap, getStyleFieldMap } from './section-field-maps';
6
13
 
7
14
  /**
@@ -18,7 +25,7 @@ type IndexableContent = Content & Record<string, unknown>;
18
25
 
19
26
  const isUrlField = (aiKey: string): boolean => aiKey.endsWith('_url');
20
27
 
21
- const isValidUrl = (value: unknown): boolean => {
28
+ export const isValidUrl = (value: unknown): boolean => {
22
29
  if (typeof value !== 'string' || !value) return false;
23
30
 
24
31
  try {
@@ -30,6 +37,46 @@ const isValidUrl = (value: unknown): boolean => {
30
37
  }
31
38
  };
32
39
 
40
+ interface ButtonLinkContent {
41
+ url: string;
42
+ email?: string;
43
+ tel?: string;
44
+ buttonPageId: string;
45
+ buttonLinkType: ButtonLinkType;
46
+ }
47
+
48
+ interface ButtonLinkArgs {
49
+ button_link_type?: 'url' | 'page' | 'mailTo' | 'tel';
50
+ button_url?: string;
51
+ }
52
+
53
+ /**
54
+ * Sets buttonLinkType and the corresponding link value field (url/email/tel/buttonPageId)
55
+ * on any section content that supports multiple button link types.
56
+ * Must be called after applyScalarFields() since that sets content.url as a baseline.
57
+ */
58
+ export const applyButtonLink = (
59
+ content: ButtonLinkContent,
60
+ args: ButtonLinkArgs,
61
+ ): void => {
62
+ const { button_link_type: linkType, button_url: buttonUrl } = args;
63
+
64
+ if (!linkType || !buttonUrl) return;
65
+
66
+ content.buttonLinkType = linkType;
67
+
68
+ switch (linkType) {
69
+ case BUTTON_LINK_TYPE.url:
70
+ case BUTTON_LINK_TYPE.mailTo:
71
+ case BUTTON_LINK_TYPE.tel:
72
+ content.url = buttonUrl;
73
+ break;
74
+ case BUTTON_LINK_TYPE.page:
75
+ content.buttonPageId = buttonUrl.replace('pageid:', '');
76
+ break;
77
+ }
78
+ };
79
+
33
80
  export const applyScalarFields = (
34
81
  content: Content,
35
82
  args: SectionToolArguments,
@@ -43,10 +90,15 @@ export const applyScalarFields = (
43
90
 
44
91
  for (const [aiKey, modelKey] of Object.entries(fieldMap)) {
45
92
  if (aiKey in args) {
93
+ const value = args[aiKey];
94
+
46
95
  // Skip invalid URLs — don't overwrite model with malformed values
47
- if (isUrlField(aiKey) && !isValidUrl(args[aiKey])) continue;
96
+ if (isUrlField(aiKey) && !isValidUrl(value)) continue;
97
+
98
+ // Skip Tiptap JSON documents — each builder handles its own RTE fields
99
+ if (isTiptapDocument(value)) continue;
48
100
 
49
- record[modelKey] = args[aiKey];
101
+ record[modelKey] = value;
50
102
  }
51
103
  }
52
104
  };
@@ -66,97 +118,104 @@ const normalizeStyleValue = (key: string, value: unknown): unknown => {
66
118
  return `${value / 100}em`;
67
119
  }
68
120
 
69
- if (key === 'lineHeight' && typeof value === 'number') {
70
- return String(value);
121
+ if (key === 'lineHeight') {
122
+ // Snap to 0.1 increments to match the UI slider step
123
+ const num = typeof value === 'number' ? value : parseFloat(String(value));
124
+
125
+ if (!isNaN(num)) return String(Math.floor(num * 10) / 10);
71
126
  }
72
127
 
73
128
  return value;
74
129
  };
75
130
 
76
- export const applyStyleFields = (
77
- content: Content,
78
- args: SectionToolArguments,
79
- sectionType: string,
80
- ): void => {
81
- const styleMap = getStyleFieldMap(sectionType);
82
-
83
- if (!styleMap) return;
84
-
85
- const record = content as IndexableContent;
131
+ /**
132
+ * When an executor is about to mark a content-level text style "custom" by
133
+ * clearing `textStyleType`, the resolved preset values (font, size, spacing,
134
+ * etc.) must first be copied onto the style — otherwise the renderer falls
135
+ * back to browser defaults because `textStyleType` no longer points at a
136
+ * preset.
137
+ *
138
+ * The category is read from the existing `style.textStyleType`, which is the
139
+ * authoritative per-section + per-field reference set by the content factory.
140
+ * Existing style values win over preset defaults (the content may already
141
+ * carry user overrides on top of the preset).
142
+ */
143
+ export const resolveGlobalPresetIntoStyle = (
144
+ style: object | undefined,
145
+ textStyleOptions: TextStyleOptions | undefined,
146
+ ): Record<string, unknown> => {
147
+ const base = { ...((style as Record<string, unknown>) ?? {}) };
148
+ const currentTextStyleType = base.textStyleType as TextStyleType | undefined;
86
149
 
87
- for (const [aiKey, modelKey] of Object.entries(styleMap)) {
88
- if (aiKey in args && args[aiKey] && typeof args[aiKey] === 'object') {
89
- const existing = (content[modelKey] as Record<string, unknown>) || {};
90
- const aiStyle = args[aiKey] as Record<string, unknown>;
150
+ if (!currentTextStyleType || !textStyleOptions?.[currentTextStyleType]) {
151
+ base.textStyleType = undefined;
91
152
 
92
- const filtered: Record<string, unknown> = {};
153
+ return base;
154
+ }
93
155
 
94
- for (const [k, v] of Object.entries(aiStyle)) {
95
- const normalized = normalizeStyleValue(k, v);
156
+ const presetStyle = textStyleOptions[currentTextStyleType].style;
157
+ const presetDefaults: Record<string, unknown> = {};
96
158
 
97
- if (normalized !== undefined) filtered[k] = normalized;
98
- }
159
+ for (const [k, v] of Object.entries(presetStyle)) {
160
+ if (k === 'textStyleType' || v === undefined) continue;
99
161
 
100
- record[modelKey] = {
101
- ...existing,
102
- ...filtered,
103
- textStyleType: undefined,
104
- };
105
- }
162
+ presetDefaults[k] = v;
106
163
  }
164
+
165
+ return { ...presetDefaults, ...base, textStyleType: undefined };
107
166
  };
108
167
 
109
168
  /**
110
- * RTE field → style field pairs for fields that support rich text editing.
111
- * Matches the RTE_ALLOWED_FIELDS constant from rich-text-editor.util.ts:
112
- * ['title', 'description', 'text', 'textItems']
169
+ * Applies per-element style overrides while detaching the element from any
170
+ * global text-style preset. When a style is bound to a `textStyleType` preset,
171
+ * the renderer (`getCopyrightTextStyle` / `getTextStyleByContentTextStyle`)
172
+ * replaces the whole style with that preset and discards per-element values such
173
+ * as `fontFamily`. Resolving the preset in and clearing `textStyleType` makes the
174
+ * override stick — the same disconnect rule section content follows.
113
175
  *
114
- * textItems is excluded here because it requires per-item handling
115
- * (each TextItem has its own textStyle) — handled by TextSectionBuilder.
176
+ * Idempotent: once `textStyleType` is cleared, subsequent calls just merge the
177
+ * updates without re-resolving a preset.
116
178
  */
117
- const RTE_FIELD_STYLE_PAIRS: {
118
- textField: string;
119
- styleField: string;
120
- argKey: string;
121
- }[] = [
122
- { textField: 'title', styleField: 'titleStyle', argKey: 'title_style' },
123
- {
124
- textField: 'description',
125
- styleField: 'descriptionStyle',
126
- argKey: 'description_style',
127
- },
128
- { textField: 'text', styleField: 'textStyle', argKey: 'text_style' },
129
- {
130
- textField: 'paragraph',
131
- styleField: 'paragraphStyle',
132
- argKey: 'paragraph_style',
133
- },
134
- ];
179
+ export const applyDetachedStyleOverride = <T extends object>(
180
+ current: T | undefined,
181
+ updates: Partial<T>,
182
+ textStyleOptions: TextStyleOptions | undefined,
183
+ ): T =>
184
+ ({
185
+ ...resolveGlobalPresetIntoStyle(current, textStyleOptions),
186
+ ...updates,
187
+ }) as T;
135
188
 
136
- /**
137
- * Re-applies merged styles to RTE content fields after applyStyleFields has
138
- * updated the style objects. Only runs for section types that support RTE
139
- * (defined by RTE_ALLOWED_SECTION_TYPES) and only touches fields in the
140
- * RTE_ALLOWED_FIELDS list.
141
- */
142
- export const applyRTEStyles = (
189
+ export const applyStyleFields = (
143
190
  content: Content,
144
191
  args: SectionToolArguments,
145
192
  sectionType: string,
193
+ textStyleOptions?: TextStyleOptions,
146
194
  ): void => {
147
- if (!RTE_ALLOWED_SECTION_TYPES.includes(sectionType)) return;
195
+ const styleMap = getStyleFieldMap(sectionType);
196
+
197
+ if (!styleMap) return;
148
198
 
149
199
  const record = content as IndexableContent;
150
- const argsRecord = args as Record<string, unknown>;
151
200
 
152
- for (const { textField, styleField, argKey } of RTE_FIELD_STYLE_PAIRS) {
153
- if (!argsRecord[argKey]) continue;
201
+ for (const [aiKey, modelKey] of Object.entries(styleMap)) {
202
+ if (!(aiKey in args) || !args[aiKey] || typeof args[aiKey] !== 'object')
203
+ continue;
204
+
205
+ const aiStyle = args[aiKey] as Record<string, unknown>;
206
+ const filtered: Record<string, unknown> = {};
154
207
 
155
- const text = record[textField];
156
- const style = record[styleField];
208
+ for (const [k, v] of Object.entries(aiStyle)) {
209
+ const normalized = normalizeStyleValue(k, v);
157
210
 
158
- if (typeof text === 'string' && style) {
159
- record[textField] = updateRTEText(text, style as TextStyleDeclaration);
211
+ if (normalized !== undefined) filtered[k] = normalized;
160
212
  }
213
+
214
+ const resolved = resolveGlobalPresetIntoStyle(
215
+ content[modelKey] as object,
216
+ textStyleOptions,
217
+ );
218
+
219
+ record[modelKey] = { ...resolved, ...filtered, textStyleType: undefined };
161
220
  }
162
221
  };
@@ -0,0 +1,38 @@
1
+ import {
2
+ MAX_TITLE_LENGTH,
3
+ MAX_DESCRIPTION_LENGTH,
4
+ } from '../../../brand-page/constants/font.constants';
5
+ import {
6
+ enumCheck,
7
+ runChecks,
8
+ styleCheck,
9
+ type SectionCheck,
10
+ type ValidationContext,
11
+ } from '../../sanitizers/section-args-validator';
12
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
13
+
14
+ const CHECKS: SectionCheck[] = [
15
+ ...textAndRteChecks('title', MAX_TITLE_LENGTH),
16
+ ...textAndRteChecks('paragraph', MAX_DESCRIPTION_LENGTH),
17
+ styleCheck('title_style'),
18
+ styleCheck('paragraph_style'),
19
+ enumCheck(
20
+ 'display_style',
21
+ [
22
+ 'left-aligned',
23
+ 'right-aligned',
24
+ 'centered',
25
+ 'text-only',
26
+ 'left-aligned-full-image',
27
+ 'right-aligned-full-image',
28
+ ],
29
+ 'about-section',
30
+ ),
31
+ ];
32
+
33
+ export function validateAboutSection(
34
+ args: Record<string, unknown>,
35
+ ctx: ValidationContext,
36
+ ): string[] {
37
+ return runChecks(CHECKS, args, ctx);
38
+ }
@@ -0,0 +1,17 @@
1
+ import { PAGE_RULES } from '../../sanitizers/sanitizer-rules';
2
+
3
+ export interface AddPagePayload {
4
+ pageId: string;
5
+ pageName: string;
6
+ }
7
+
8
+ type PageCheck = (payload: AddPagePayload | undefined) => string | null;
9
+
10
+ export const ADD_PAGE_CHECKS: PageCheck[] = [
11
+ (p) => (!p?.pageId ? 'page_id is required for add_page' : null),
12
+ (p) => (!p?.pageName ? 'page_name is required for add_page' : null),
13
+ (p) =>
14
+ p?.pageName && p.pageName.length > PAGE_RULES.pageName
15
+ ? `page_name exceeds the maximum length of ${PAGE_RULES.pageName} characters (got ${p.pageName.length})`
16
+ : null,
17
+ ];
@@ -0,0 +1,49 @@
1
+ import {
2
+ MAX_TITLE_LENGTH,
3
+ MAX_DESCRIPTION_LENGTH,
4
+ } from '../../../brand-page/constants/font.constants';
5
+ import { BUTTON_LINK_TYPE } from '../../../brand-page/models';
6
+ import {
7
+ enumCheck,
8
+ runChecks,
9
+ styleCheck,
10
+ type SectionCheck,
11
+ type ValidationContext,
12
+ } from '../../sanitizers/section-args-validator';
13
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
14
+
15
+ const CHECKS: SectionCheck[] = [
16
+ ...textAndRteChecks('title', MAX_TITLE_LENGTH),
17
+ ...textAndRteChecks('description', MAX_DESCRIPTION_LENGTH),
18
+ ...textAndRteChecks('button_text', MAX_TITLE_LENGTH),
19
+ styleCheck('title_style'),
20
+ styleCheck('description_style'),
21
+ styleCheck('button_text_style'),
22
+ enumCheck(
23
+ 'display_style',
24
+ [
25
+ 'left-aligned',
26
+ 'right-aligned',
27
+ 'centered',
28
+ 'big-image',
29
+ 'left-aligned-big-image',
30
+ 'right-aligned-full-image',
31
+ 'left-aligned-full-image',
32
+ 'center-card-aligned-image',
33
+ 'left-card-aligned-image',
34
+ ],
35
+ 'banner-section',
36
+ ),
37
+ enumCheck(
38
+ 'button_link_type',
39
+ Object.keys(BUTTON_LINK_TYPE),
40
+ 'banner-section',
41
+ ),
42
+ ];
43
+
44
+ export function validateBannerSection(
45
+ args: Record<string, unknown>,
46
+ ctx: ValidationContext,
47
+ ): string[] {
48
+ return runChecks(CHECKS, args, ctx);
49
+ }
@@ -0,0 +1,34 @@
1
+ import {
2
+ MAX_TITLE_LENGTH,
3
+ MAX_DESCRIPTION_LENGTH,
4
+ } from '../../../brand-page/constants/font.constants';
5
+ import { BUTTON_LINK_TYPE } from '../../../brand-page/models';
6
+ import {
7
+ enumCheck,
8
+ runChecks,
9
+ styleCheck,
10
+ type SectionCheck,
11
+ type ValidationContext,
12
+ } from '../../sanitizers/section-args-validator';
13
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
14
+
15
+ const CHECKS: SectionCheck[] = [
16
+ ...textAndRteChecks('title', MAX_TITLE_LENGTH),
17
+ ...textAndRteChecks('description', MAX_DESCRIPTION_LENGTH),
18
+ ...textAndRteChecks('button_text', MAX_TITLE_LENGTH),
19
+ styleCheck('title_style'),
20
+ styleCheck('description_style'),
21
+ styleCheck('button_text_style'),
22
+ enumCheck(
23
+ 'button_link_type',
24
+ Object.keys(BUTTON_LINK_TYPE),
25
+ 'booking-section',
26
+ ),
27
+ ];
28
+
29
+ export function validateBookingSection(
30
+ args: Record<string, unknown>,
31
+ ctx: ValidationContext,
32
+ ): string[] {
33
+ return runChecks(CHECKS, args, ctx);
34
+ }
@@ -0,0 +1,22 @@
1
+ import { MAX_TITLE_LENGTH } from '../../../brand-page/constants/font.constants';
2
+ import {
3
+ runChecks,
4
+ type SectionCheck,
5
+ type ValidationContext,
6
+ } from '../../sanitizers/section-args-validator';
7
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
8
+
9
+ /**
10
+ * Shared validation for all link/button section types:
11
+ * website, email, phone, general-link, facebook, x, instagram,
12
+ * youtube, linkedin, pinterest, twitch, tiktok.
13
+ * All use ButtonSectionBuilder and share the same title constraint.
14
+ */
15
+ const CHECKS: SectionCheck[] = [...textAndRteChecks('title', MAX_TITLE_LENGTH)];
16
+
17
+ export function validateButtonSection(
18
+ args: Record<string, unknown>,
19
+ ctx: ValidationContext,
20
+ ): string[] {
21
+ return runChecks(CHECKS, args, ctx);
22
+ }
@@ -0,0 +1,30 @@
1
+ import {
2
+ MAX_TITLE_LENGTH,
3
+ MAX_DESCRIPTION_LENGTH,
4
+ } from '../../../brand-page/constants/font.constants';
5
+ import {
6
+ enumCheck,
7
+ runChecks,
8
+ styleCheck,
9
+ type SectionCheck,
10
+ type ValidationContext,
11
+ } from '../../sanitizers/section-args-validator';
12
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
13
+
14
+ const CHECKS: SectionCheck[] = [
15
+ ...textAndRteChecks('title', MAX_TITLE_LENGTH),
16
+ ...textAndRteChecks('description', MAX_DESCRIPTION_LENGTH),
17
+ ...textAndRteChecks('button_text', MAX_TITLE_LENGTH),
18
+ ...textAndRteChecks('success_message', MAX_TITLE_LENGTH),
19
+ styleCheck('title_style'),
20
+ styleCheck('description_style'),
21
+ styleCheck('button_text_style'),
22
+ enumCheck('display_style', ['preview', 'collapsed'], 'contact-form'),
23
+ ];
24
+
25
+ export function validateContactForm(
26
+ args: Record<string, unknown>,
27
+ ctx: ValidationContext,
28
+ ): string[] {
29
+ return runChecks(CHECKS, args, ctx);
30
+ }
@@ -0,0 +1,17 @@
1
+ import {
2
+ enumCheck,
3
+ runChecks,
4
+ type SectionCheck,
5
+ type ValidationContext,
6
+ } from '../../sanitizers/section-args-validator';
7
+
8
+ const CHECKS: SectionCheck[] = [
9
+ enumCheck('divider_style', ['none', 'thin', 'thick'], 'divider-section'),
10
+ ];
11
+
12
+ export function validateDividerSection(
13
+ args: Record<string, unknown>,
14
+ ctx: ValidationContext,
15
+ ): string[] {
16
+ return runChecks(CHECKS, args, ctx);
17
+ }
@@ -0,0 +1,21 @@
1
+ import type { UpdateFooterArguments } from '../../parsers/ai-toolcall-parser';
2
+ import { validateLogoSize } from '../../sanitizers/section-args-validator';
3
+
4
+ type FooterCheck = (args: UpdateFooterArguments) => string | null;
5
+
6
+ export const FOOTER_CHECKS: FooterCheck[] = (
7
+ ['desktop', 'mobile'] as const
8
+ ).flatMap((viewport) => [
9
+ (args: UpdateFooterArguments) =>
10
+ validateLogoSize(
11
+ `${viewport}.logo_image_height`,
12
+ args[viewport]?.logo_image_height,
13
+ viewport,
14
+ ),
15
+ (args: UpdateFooterArguments) =>
16
+ validateLogoSize(
17
+ `${viewport}.logo_image_width`,
18
+ args[viewport]?.logo_image_width,
19
+ viewport,
20
+ ),
21
+ ]);
@@ -0,0 +1,44 @@
1
+ import type {
2
+ UpdateGlobalStylesArguments,
3
+ TextStyleOptionStyle,
4
+ } from '../../parsers/ai-toolcall-parser';
5
+ import type { TextStyleType } from '../../../brand-page/models/styles.model';
6
+ import { STYLE_RULES } from '../../sanitizers/sanitizer-rules';
7
+ import { validateStringStyleAttrs } from '../../sanitizers/section-args-validator';
8
+
9
+ export const TEXT_STYLE_OPTION_KEYS: TextStyleType[] = [
10
+ 'titles',
11
+ 'headings',
12
+ 'paragraphs',
13
+ 'buttons',
14
+ ];
15
+
16
+ type GlobalStyleCheck = (args: UpdateGlobalStylesArguments) => string | null;
17
+
18
+ export const GLOBAL_STYLE_CHECKS: GlobalStyleCheck[] = [
19
+ // textFontFamily: must be a recognized camelCase font key (e.g. 'playfairDisplay')
20
+ (args) => {
21
+ const font = args.textStyles?.textFontFamily;
22
+
23
+ if (font == null) return null;
24
+
25
+ return !STYLE_RULES.fontFamilyKeys.has(font)
26
+ ? `"textFontFamily" "${font}" is not a recognized font family key`
27
+ : null;
28
+ },
29
+
30
+ // textStyleOptions[category].style — fontSize, fontFamily, lineHeight, letterSpacing
31
+ ...TEXT_STYLE_OPTION_KEYS.map(
32
+ (category): GlobalStyleCheck =>
33
+ (args) => {
34
+ const style = args.textStyles?.textStyleOptions?.[category]?.style;
35
+
36
+ if (!style) return null;
37
+
38
+ return validateStringStyleAttrs(
39
+ `textStyleOptions.${category}.style`,
40
+ style as TextStyleOptionStyle,
41
+ );
42
+ },
43
+ ),
44
+ ];