@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
@@ -0,0 +1,31 @@
1
+ import { MAX_TITLE_LENGTH, MAX_DESCRIPTION_LENGTH, } from '../../../brand-page/constants/font.constants';
2
+ import { ASPECT_RATIOS } from '../../../brand-page/models';
3
+ import { enumCheck, itemCapCheck, itemRteStyleCheck, itemTextCheck, runChecks, styleCheck, } from '../../sanitizers/section-args-validator';
4
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
5
+ const CHECKS = [
6
+ ...textAndRteChecks('title', MAX_TITLE_LENGTH),
7
+ ...textAndRteChecks('description', MAX_DESCRIPTION_LENGTH),
8
+ styleCheck('title_style'),
9
+ styleCheck('description_style'),
10
+ styleCheck('heading_style'),
11
+ styleCheck('paragraph_style'),
12
+ itemTextCheck('items', 'heading', MAX_TITLE_LENGTH),
13
+ itemRteStyleCheck('items', 'heading'),
14
+ itemTextCheck('items', 'text', MAX_DESCRIPTION_LENGTH),
15
+ itemRteStyleCheck('items', 'text'),
16
+ itemTextCheck('items', 'button_text', MAX_TITLE_LENGTH),
17
+ itemRteStyleCheck('items', 'button_text'),
18
+ enumCheck('display_style', [
19
+ 'left-aligned',
20
+ 'right-aligned',
21
+ 'centered',
22
+ 'media-only',
23
+ 'center-card-aligned-image',
24
+ 'alternate-image',
25
+ ], 'images-section'),
26
+ enumCheck('aspect_ratio', Object.keys(ASPECT_RATIOS), 'images-section'),
27
+ itemCapCheck({ brandSite: 5, brandPage: 2, arrayField: 'items' }, 'images-section'),
28
+ ];
29
+ export function validateImagesSection(args, ctx) {
30
+ return runChecks(CHECKS, args, ctx);
31
+ }
@@ -0,0 +1,2 @@
1
+ import { type ValidationContext } from '../../sanitizers/section-args-validator';
2
+ export declare function validateMailingList(args: Record<string, unknown>, ctx: ValidationContext): string[];
@@ -0,0 +1,11 @@
1
+ import { MAX_TITLE_LENGTH } from '../../../brand-page/constants/font.constants';
2
+ import { enumCheck, runChecks, } from '../../sanitizers/section-args-validator';
3
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
4
+ const CHECKS = [
5
+ ...textAndRteChecks('title', MAX_TITLE_LENGTH),
6
+ ...textAndRteChecks('button_text', 25), // config-settings-constant.ts:1780 — field-specific limit
7
+ enumCheck('accepted_fields', ['emailOnly', 'nameAndEmail'], 'mailing-list'),
8
+ ];
9
+ export function validateMailingList(args, ctx) {
10
+ return runChecks(CHECKS, args, ctx);
11
+ }
@@ -0,0 +1,2 @@
1
+ import { type ValidationContext } from '../../sanitizers/section-args-validator';
2
+ export declare function validateProfile(args: Record<string, unknown>, ctx: ValidationContext): string[];
@@ -0,0 +1,14 @@
1
+ import { MAX_TITLE_LENGTH, MAX_DESCRIPTION_LENGTH, } from '../../../brand-page/constants/font.constants';
2
+ import { runChecks, styleCheck, } from '../../sanitizers/section-args-validator';
3
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
4
+ const CHECKS = [
5
+ ...textAndRteChecks('name', MAX_TITLE_LENGTH),
6
+ ...textAndRteChecks('title', MAX_TITLE_LENGTH),
7
+ ...textAndRteChecks('description', MAX_DESCRIPTION_LENGTH),
8
+ styleCheck('name_style'),
9
+ styleCheck('title_style'),
10
+ styleCheck('description_style'),
11
+ ];
12
+ export function validateProfile(args, ctx) {
13
+ return runChecks(CHECKS, args, ctx);
14
+ }
@@ -0,0 +1,7 @@
1
+ export interface RenamePagePayload {
2
+ pageId: string;
3
+ pageName: string;
4
+ }
5
+ type PageCheck = (payload: RenamePagePayload | undefined) => string | null;
6
+ export declare const RENAME_PAGE_CHECKS: PageCheck[];
7
+ export {};
@@ -0,0 +1,8 @@
1
+ import { PAGE_RULES } from '../../sanitizers/sanitizer-rules';
2
+ export const RENAME_PAGE_CHECKS = [
3
+ (p) => (!p?.pageId ? 'page_id is required for rename_page' : null),
4
+ (p) => (!p?.pageName ? 'page_name is required for rename_page' : null),
5
+ (p) => p?.pageName && p.pageName.length > PAGE_RULES.pageName
6
+ ? `page_name exceeds the maximum length of ${PAGE_RULES.pageName} characters (got ${p.pageName.length})`
7
+ : null,
8
+ ];
@@ -0,0 +1,2 @@
1
+ import { type ValidationContext } from '../../sanitizers/section-args-validator';
2
+ export declare function validateShapesSection(args: Record<string, unknown>, ctx: ValidationContext): string[];
@@ -0,0 +1,27 @@
1
+ import { MAX_TITLE_LENGTH, MAX_DESCRIPTION_LENGTH, } from '../../../brand-page/constants/font.constants';
2
+ import { enumCheck, itemCapCheck, itemRteStyleCheck, itemTextCheck, runChecks, styleCheck, } from '../../sanitizers/section-args-validator';
3
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
4
+ const CHECKS = [
5
+ ...textAndRteChecks('title', MAX_TITLE_LENGTH),
6
+ ...textAndRteChecks('description', MAX_DESCRIPTION_LENGTH),
7
+ styleCheck('title_style'),
8
+ styleCheck('description_style'),
9
+ styleCheck('heading_style'),
10
+ styleCheck('paragraph_style'),
11
+ itemTextCheck('items', 'heading', MAX_TITLE_LENGTH),
12
+ itemRteStyleCheck('items', 'heading'),
13
+ itemTextCheck('items', 'text', MAX_DESCRIPTION_LENGTH),
14
+ itemRteStyleCheck('items', 'text'),
15
+ enumCheck('display_style', [
16
+ 'left-aligned',
17
+ 'right-aligned',
18
+ 'centered',
19
+ 'media-only',
20
+ 'center-card-aligned-image',
21
+ 'alternate-image',
22
+ ], 'shapes-section'),
23
+ itemCapCheck({ brandSite: 5, brandPage: 2, arrayField: 'items' }, 'shapes-section'),
24
+ ];
25
+ export function validateShapesSection(args, ctx) {
26
+ return runChecks(CHECKS, args, ctx);
27
+ }
@@ -0,0 +1,2 @@
1
+ import { type ValidationContext } from '../../sanitizers/section-args-validator';
2
+ export declare function validateSocialLinks(args: Record<string, unknown>, ctx: ValidationContext): string[];
@@ -0,0 +1,9 @@
1
+ import { SOCIAL_LINKS_ICON_DISPLAY_STYLES } from '../../../brand-page/models';
2
+ import { enumCheck, itemCapCheck, runChecks, } from '../../sanitizers/section-args-validator';
3
+ const CHECKS = [
4
+ enumCheck('icon_style', Object.keys(SOCIAL_LINKS_ICON_DISPLAY_STYLES), 'social-links'),
5
+ itemCapCheck({ brandSite: 4, brandPage: 4, arrayField: 'links' }, 'social-links'),
6
+ ];
7
+ export function validateSocialLinks(args, ctx) {
8
+ return runChecks(CHECKS, args, ctx);
9
+ }
@@ -0,0 +1,7 @@
1
+ import { type ValidationContext } from '../../sanitizers/section-args-validator';
2
+ export declare const TESTIMONIAL_ITEM_CAP: {
3
+ readonly brandSite: 3;
4
+ readonly brandPage: 3;
5
+ readonly arrayField: "items";
6
+ };
7
+ export declare function validateTestimonialSection(args: Record<string, unknown>, ctx: ValidationContext): string[];
@@ -0,0 +1,26 @@
1
+ import { MAX_TITLE_LENGTH, MAX_DESCRIPTION_LENGTH, } from '../../../brand-page/constants/font.constants';
2
+ import { enumCheck, itemCapCheck, itemRteStyleCheck, itemTextCheck, runChecks, styleCheck, } from '../../sanitizers/section-args-validator';
3
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
4
+ export const TESTIMONIAL_ITEM_CAP = {
5
+ brandSite: 3,
6
+ brandPage: 3,
7
+ arrayField: 'items',
8
+ };
9
+ const CHECKS = [
10
+ ...textAndRteChecks('title', MAX_TITLE_LENGTH),
11
+ styleCheck('title_style'),
12
+ styleCheck('testimonial_style'),
13
+ styleCheck('name_style'),
14
+ styleCheck('position_style'),
15
+ itemTextCheck('items', 'testimonial', MAX_DESCRIPTION_LENGTH),
16
+ itemRteStyleCheck('items', 'testimonial'),
17
+ itemTextCheck('items', 'name', MAX_TITLE_LENGTH),
18
+ itemRteStyleCheck('items', 'name'),
19
+ itemTextCheck('items', 'position', MAX_TITLE_LENGTH),
20
+ itemRteStyleCheck('items', 'position'),
21
+ enumCheck('display_style', ['centered', 'big-image', 'columns'], 'testimonial-section'),
22
+ itemCapCheck(TESTIMONIAL_ITEM_CAP, 'testimonial-section'),
23
+ ];
24
+ export function validateTestimonialSection(args, ctx) {
25
+ return runChecks(CHECKS, args, ctx);
26
+ }
@@ -0,0 +1,2 @@
1
+ import { type ValidationContext } from '../../sanitizers/section-args-validator';
2
+ export declare function validateTextSection(args: Record<string, unknown>, ctx: ValidationContext): string[];
@@ -0,0 +1,14 @@
1
+ import { MAX_TEXT_LENGTH } from '../../../brand-page/constants/font.constants';
2
+ import { enumCheck, itemRteStyleCheck, itemStyleCheck, itemTextCheck, runChecks, styleCheck, } from '../../sanitizers/section-args-validator';
3
+ import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
4
+ const CHECKS = [
5
+ ...textAndRteChecks('text', MAX_TEXT_LENGTH),
6
+ styleCheck('text_style'),
7
+ itemTextCheck('items', 'text', MAX_TEXT_LENGTH),
8
+ itemRteStyleCheck('items', 'text'),
9
+ itemStyleCheck('items', 'text_style'),
10
+ enumCheck('column_style', ['1', '2', '3', '4'], 'text'),
11
+ ];
12
+ export function validateTextSection(args, ctx) {
13
+ return runChecks(CHECKS, args, ctx);
14
+ }
@@ -0,0 +1,26 @@
1
+ import type { ColorReplacement } from '../../brand-page/models';
2
+ /**
3
+ * Fetch a shape's SVG and return concrete identity-mapped `ColorReplacement`
4
+ * entries, one per unique fill. Caller applies `color_theme` via
5
+ * `applyColorThemeToReplacements` as a second step when re-shading is needed.
6
+ *
7
+ * Returns `[]` for proxy URLs — those are served through `/asset/shape?...`
8
+ * and cannot be fetched for colour enumeration (render path renders them via
9
+ * `<object>` instead of downloading the SVG).
10
+ *
11
+ * Uses the svg-parser-based server variant (not DOMParser) so this works
12
+ * unchanged in both browser and SSR/test environments. For AI-authored shapes
13
+ * with style/class/direct fills, this covers every case; CSS computed-style
14
+ * only matters for shapes authored outside the AI flow.
15
+ *
16
+ * Throws on network or HTTP failure — no silent fallback.
17
+ */
18
+ export declare const resolveShapeColorReplacementsAsync: (shapeUrl: string) => Promise<ColorReplacement[]>;
19
+ /**
20
+ * Re-shade each entry's `replacementColor` to a luminance-preserving variant
21
+ * of `colorTheme`. Pure transformation over the existing array — no network.
22
+ *
23
+ * An empty input returns an empty array by design; the caller is expected to
24
+ * populate concrete entries via `resolveShapeColorReplacementsAsync` first.
25
+ */
26
+ export declare const applyColorThemeToReplacements: (replacements: ColorReplacement[], colorTheme: string) => ColorReplacement[];
@@ -0,0 +1,52 @@
1
+ import { PROXY_SHAPE_URL_REGEX } from '../../brand-page/constants';
2
+ import { getNewColorBasedOnTargetColorTheme } from '../../brand-page/utils/color.util';
3
+ import { getColorReplacementsFromSvgStringServer } from '../../brand-page/utils/svg-color.util';
4
+ /**
5
+ * Fetch a shape's SVG and return concrete identity-mapped `ColorReplacement`
6
+ * entries, one per unique fill. Caller applies `color_theme` via
7
+ * `applyColorThemeToReplacements` as a second step when re-shading is needed.
8
+ *
9
+ * Returns `[]` for proxy URLs — those are served through `/asset/shape?...`
10
+ * and cannot be fetched for colour enumeration (render path renders them via
11
+ * `<object>` instead of downloading the SVG).
12
+ *
13
+ * Uses the svg-parser-based server variant (not DOMParser) so this works
14
+ * unchanged in both browser and SSR/test environments. For AI-authored shapes
15
+ * with style/class/direct fills, this covers every case; CSS computed-style
16
+ * only matters for shapes authored outside the AI flow.
17
+ *
18
+ * Throws on network or HTTP failure — no silent fallback.
19
+ */
20
+ export const resolveShapeColorReplacementsAsync = async (shapeUrl) => {
21
+ if (!shapeUrl || shapeUrl.match(PROXY_SHAPE_URL_REGEX)) {
22
+ return [];
23
+ }
24
+ const response = await fetch(shapeUrl);
25
+ if (!response.ok) {
26
+ throw new Error(`Failed to fetch shape for colour enumeration (${response.status}): ${shapeUrl}`);
27
+ }
28
+ const svgText = await response.text();
29
+ const replacements = getColorReplacementsFromSvgStringServer(svgText);
30
+ // The server-side colour enumeration produces phantom #000000 entries from
31
+ // DEFAULT_FALLBACK_COLOR for elements whose class-based fill can't be
32
+ // resolved. Filter them out when real fill colours exist.
33
+ if (replacements.length > 1) {
34
+ const withoutPhantom = replacements.filter((r) => r.originalColor !== '#000000');
35
+ if (withoutPhantom.length > 0)
36
+ return withoutPhantom;
37
+ }
38
+ return replacements;
39
+ };
40
+ /**
41
+ * Re-shade each entry's `replacementColor` to a luminance-preserving variant
42
+ * of `colorTheme`. Pure transformation over the existing array — no network.
43
+ *
44
+ * An empty input returns an empty array by design; the caller is expected to
45
+ * populate concrete entries via `resolveShapeColorReplacementsAsync` first.
46
+ */
47
+ export const applyColorThemeToReplacements = (replacements, colorTheme) => replacements.map((r) => ({
48
+ ...r,
49
+ replacementColor: replacements.length === 1
50
+ ? colorTheme
51
+ : getNewColorBasedOnTargetColorTheme(r.originalColor, colorTheme)?.toString() ?? colorTheme,
52
+ }));
@@ -0,0 +1,48 @@
1
+ import { type BrandPageModel } from '../../brand-page/models';
2
+ import { BaseMetadataBuilder, type BuilderResult, type MetadataBuilderRequest } from '../models';
3
+ import type { Logger } from '../logger';
4
+ /**
5
+ * Resolver called at undo-execution time to fetch the snapshot to restore to.
6
+ *
7
+ * Returning `null` means there is no snapshot available (e.g. fresh session,
8
+ * or the website has never been modified). The UndoBuilder surfaces this as
9
+ * a validation error so the caller can show a meaningful message.
10
+ *
11
+ * Async supported: the handler may return a `Promise<BrandPageModel | null>`
12
+ * if resolution involves I/O (IndexedDB, remote store, etc.). Sync returns
13
+ * work too — `await` is a no-op on non-promises.
14
+ */
15
+ export type UndoHandler = () => BrandPageModel | null | Promise<BrandPageModel | null>;
16
+ /**
17
+ * Payload for the UndoBuilder.
18
+ *
19
+ * The snapshot itself is not stored in the payload. Instead, the payload
20
+ * carries an {@link UndoHandler} callback that the builder invokes at
21
+ * execute time to lazily resolve the snapshot. This keeps the library
22
+ * agnostic about *how* snapshots are stored — the caller owns that concern.
23
+ */
24
+ export interface UndoPayload {
25
+ undoHandler: UndoHandler;
26
+ }
27
+ /**
28
+ * UndoBuilder — executes the `undo` tool call by invoking the caller-supplied
29
+ * {@link UndoHandler} callback to resolve the snapshot, then replaces the
30
+ * current model with that snapshot. Also sets
31
+ * {@link BuilderResult.undoRequested} on the returned result so the caller
32
+ * can observe that an undo was executed (useful for telemetry, UI messaging,
33
+ * and audit logs).
34
+ *
35
+ * Contract guarantee from the AI pipeline (Website Planner WL9): the `undo`
36
+ * tool call is exclusive — it never co-occurs with build/update/delete tool
37
+ * calls in the same response. If that contract is ever violated upstream,
38
+ * fix the planner — do not add defensive ordering here. The sequential
39
+ * MetadataExecutor will apply any subsequent builders on top of the restored
40
+ * snapshot, which is the semantically correct "undo-then-apply" ordering.
41
+ */
42
+ export declare class UndoBuilder extends BaseMetadataBuilder<UndoPayload> {
43
+ constructor(request: MetadataBuilderRequest<UndoPayload>, logger?: Logger);
44
+ validateAsync(): Promise<{
45
+ errors: string[];
46
+ }>;
47
+ buildAsync(model: BrandPageModel): Promise<BuilderResult>;
48
+ }
@@ -0,0 +1,58 @@
1
+ import cloneDeep from 'lodash.clonedeep';
2
+ import {} from '../../brand-page/models';
3
+ import { BaseMetadataBuilder, } from '../models';
4
+ /**
5
+ * UndoBuilder — executes the `undo` tool call by invoking the caller-supplied
6
+ * {@link UndoHandler} callback to resolve the snapshot, then replaces the
7
+ * current model with that snapshot. Also sets
8
+ * {@link BuilderResult.undoRequested} on the returned result so the caller
9
+ * can observe that an undo was executed (useful for telemetry, UI messaging,
10
+ * and audit logs).
11
+ *
12
+ * Contract guarantee from the AI pipeline (Website Planner WL9): the `undo`
13
+ * tool call is exclusive — it never co-occurs with build/update/delete tool
14
+ * calls in the same response. If that contract is ever violated upstream,
15
+ * fix the planner — do not add defensive ordering here. The sequential
16
+ * MetadataExecutor will apply any subsequent builders on top of the restored
17
+ * snapshot, which is the semantically correct "undo-then-apply" ordering.
18
+ */
19
+ export class UndoBuilder extends BaseMetadataBuilder {
20
+ constructor(request, logger) {
21
+ super(request, logger);
22
+ }
23
+ async validateAsync() {
24
+ const errors = [];
25
+ const payload = this.request.payload;
26
+ if (typeof payload?.undoHandler !== 'function') {
27
+ errors.push('undo requires an `undoHandler` callback in the payload — caller must supply a function that resolves the pre-prompt snapshot');
28
+ }
29
+ return { errors };
30
+ }
31
+ async buildAsync(model) {
32
+ this.log('Build called');
33
+ const validation = await this.validateAsync();
34
+ if (validation.errors.length) {
35
+ return { request: this.request, model, errors: validation.errors };
36
+ }
37
+ const snapshot = await this.request.payload.undoHandler();
38
+ if (!snapshot) {
39
+ return {
40
+ request: this.request,
41
+ model,
42
+ errors: ['There are no previous snapshots to restore.'],
43
+ };
44
+ }
45
+ // Deep-clone the resolved snapshot so downstream builders (if any —
46
+ // exclusivity is enforced at the planner level but we don't rely on it
47
+ // here) mutate a fresh copy rather than the caller's stored snapshot.
48
+ const restored = cloneDeep(snapshot);
49
+ this.log({
50
+ message: 'Undo executed — model replaced with pre-prompt snapshot',
51
+ });
52
+ return {
53
+ request: this.request,
54
+ model: restored,
55
+ undoRequested: true,
56
+ };
57
+ }
58
+ }
@@ -118,7 +118,7 @@ export class UpdateContentTextStyleBuilder extends BaseMetadataBuilder {
118
118
  validateAsync() {
119
119
  const { newStyles } = this.request.payload;
120
120
  const errors = [];
121
- // Validate lineHeight: must be between 0 and 2.5 inclusive
121
+ // Validate lineHeight: must be between 0 and 2.5 inclusive, snap to 0.1 step
122
122
  if (newStyles.lineHeight !== undefined && newStyles.lineHeight !== null) {
123
123
  const lineHeightValue = parseFloat(String(newStyles.lineHeight));
124
124
  if (isNaN(lineHeightValue) ||
@@ -126,6 +126,10 @@ export class UpdateContentTextStyleBuilder extends BaseMetadataBuilder {
126
126
  lineHeightValue > 2.5) {
127
127
  errors.push('Line height must be a value between 0 and 2.5 inclusive.');
128
128
  }
129
+ else {
130
+ // Snap to 0.1 increments to match the UI slider step
131
+ newStyles.lineHeight = String(Math.floor(lineHeightValue * 10) / 10);
132
+ }
129
133
  }
130
134
  // Validate and normalize letterSpacing: AI sends unitless 0-100, convert to em
131
135
  if (newStyles.letterSpacing !== undefined &&
@@ -2,8 +2,19 @@ import type { TextStyleDeclaration } from '../../brand-page';
2
2
  import type { Editor } from '@tiptap/vue-3';
3
3
  export declare const applyStyleToRTEText: (externalEditor: Editor, contentText: string, newContentStyle: TextStyleDeclaration) => string;
4
4
  /**
5
- * If `text` contains RTE markup, re-applies `style` to the RTE content
6
- * so inline formatting matches the updated TextStyleDeclaration.
7
- * Returns the original text unchanged when it has no RTE content.
5
+ * Converts a Tiptap JSON document (ProseMirror document model) to an HTML
6
+ * string using a headless Tiptap Editor instance.
7
+ *
8
+ * Returns the value unchanged if it is already a string.
9
+ * Returns an empty string for null/undefined.
10
+ *
11
+ * Note: Tiptap's `setContent` does NOT throw on malformed input — it
12
+ * silently drops content and returns `<p></p>`. To prevent saved copy
13
+ * being wiped (BP-5669), structural validity of any AI-emitted Tiptap
14
+ * doc is checked upstream by `rteSchemaCheck` in
15
+ * `section-args-validator.ts` using the editor's real ProseMirror
16
+ * schema. The validator surfaces a clear error into
17
+ * `BuilderResult.errors`, which the AI-chat retry loop reads via
18
+ * `tool_result.errorMessage` and uses to re-emit a corrected payload.
8
19
  */
9
- export declare const updateRTEText: (text: string, style: TextStyleDeclaration) => string;
20
+ export declare const tiptapJsonToHtml: (value: unknown) => string;
@@ -1,7 +1,8 @@
1
- import { getRTEColor, hasRTEContent } from '../../brand-page-maker/utils';
1
+ import { getRTEColor } from '../../brand-page-maker/utils';
2
2
  import { useExternalRichTextEditor } from '../../brand-page-maker/composables/rich-text-editor/useRichTextEditor';
3
3
  import { getRenderText } from '../../brand-page/utils';
4
4
  import { ESCAPED_NEWLINE_CHARACTER } from '../../constants/ui';
5
+ import { isTiptapDocument, } from '../parsers/section-tool-arguments';
5
6
  export const applyStyleToRTEText = (externalEditor, contentText, newContentStyle) => {
6
7
  if (!contentText) {
7
8
  return contentText;
@@ -56,16 +57,29 @@ export const applyStyleToRTEText = (externalEditor, contentText, newContentStyle
56
57
  return html;
57
58
  };
58
59
  /**
59
- * If `text` contains RTE markup, re-applies `style` to the RTE content
60
- * so inline formatting matches the updated TextStyleDeclaration.
61
- * Returns the original text unchanged when it has no RTE content.
60
+ * Converts a Tiptap JSON document (ProseMirror document model) to an HTML
61
+ * string using a headless Tiptap Editor instance.
62
+ *
63
+ * Returns the value unchanged if it is already a string.
64
+ * Returns an empty string for null/undefined.
65
+ *
66
+ * Note: Tiptap's `setContent` does NOT throw on malformed input — it
67
+ * silently drops content and returns `<p></p>`. To prevent saved copy
68
+ * being wiped (BP-5669), structural validity of any AI-emitted Tiptap
69
+ * doc is checked upstream by `rteSchemaCheck` in
70
+ * `section-args-validator.ts` using the editor's real ProseMirror
71
+ * schema. The validator surfaces a clear error into
72
+ * `BuilderResult.errors`, which the AI-chat retry loop reads via
73
+ * `tool_result.errorMessage` and uses to re-emit a corrected payload.
62
74
  */
63
- export const updateRTEText = (text, style) => {
64
- if (!text || typeof text !== 'string' || !hasRTEContent(text)) {
65
- return text;
66
- }
75
+ export const tiptapJsonToHtml = (value) => {
76
+ if (typeof value === 'string')
77
+ return value;
78
+ if (!isTiptapDocument(value))
79
+ return '';
67
80
  const { externalEditor } = useExternalRichTextEditor();
68
- const updatedText = applyStyleToRTEText(externalEditor, text, style);
81
+ externalEditor.commands.setContent(value);
82
+ const html = externalEditor.getHTML();
69
83
  externalEditor.destroy();
70
- return updatedText;
84
+ return html;
71
85
  };
@@ -1,6 +1,7 @@
1
1
  import { type BrandPageModel } from '../brand-page/models';
2
2
  import { type MetadataBuilderRequest, type MetadataExecutorResult } from './models';
3
+ import type { EventTracker } from '../brand-page-maker/composables/useEventTracker';
3
4
  import type { Logger } from './logger';
4
5
  export declare class MetadataExecutor {
5
- executeAsync(metadata: BrandPageModel, requests: MetadataBuilderRequest[], logger?: Logger): Promise<MetadataExecutorResult>;
6
+ executeAsync(metadata: BrandPageModel, requests: MetadataBuilderRequest[], logger?: Logger, eventTracker?: EventTracker): Promise<MetadataExecutorResult>;
6
7
  }
@@ -3,15 +3,21 @@ import {} from '../brand-page/models';
3
3
  import { BUILDER_TYPES, } from './models';
4
4
  import { UpdateContentTextBuilder } from './builders/update-content-text-builder';
5
5
  import { UpdateContentTextStyleBuilder } from './builders/update-content-text-style-builder';
6
- import { BannerSectionBuilder, AboutSectionBuilder, ContactFormBuilder, DividerSectionBuilder, TextSectionBuilder, TestimonialSectionBuilder, ImagesSectionBuilder, ShapesSectionBuilder, SocialLinksBuilder, ImageGalleryBuilder, ProfileSectionBuilder, MailingListSectionBuilder, ButtonSectionBuilder, DeleteSectionBuilder, MoveSectionBuilder, } from './builders/section-builders';
6
+ import { BannerSectionBuilder, BookingSectionBuilder, AboutSectionBuilder, ContactFormBuilder, DividerSectionBuilder, TextSectionBuilder, TestimonialSectionBuilder, ImagesSectionBuilder, ShapesSectionBuilder, SocialLinksBuilder, ImageGalleryBuilder, ProfileSectionBuilder, MailingListSectionBuilder, ButtonSectionBuilder, DeleteSectionBuilder, MoveSectionBuilder, } from './builders/section-builders';
7
7
  import { AddPageBuilder } from './builders/add-page-builder';
8
8
  import { RemovePageBuilder } from './builders/remove-page-builder';
9
+ import { RenamePageBuilder } from './builders/rename-page-builder';
10
+ import { FooterBuilder } from './builders/footer-builder';
11
+ import { GlobalStylesBuilder } from './builders/global-styles-builder';
12
+ import { HeaderBuilder } from './builders/header-builder';
13
+ import { UndoBuilder } from './builders/undo-builder';
9
14
  // Lazy initialization to avoid circular dependency issues
10
15
  const getBuilderRegistry = () => ({
11
16
  [BUILDER_TYPES.UPDATE_CONTENT_TEXT]: UpdateContentTextBuilder,
12
17
  [BUILDER_TYPES.UPDATE_CONTENT_TEXT_STYLE]: UpdateContentTextStyleBuilder,
13
18
  // Section builders (create)
14
19
  [BUILDER_TYPES.CREATE_BANNER_SECTION]: BannerSectionBuilder,
20
+ [BUILDER_TYPES.CREATE_BOOKING_SECTION]: BookingSectionBuilder,
15
21
  [BUILDER_TYPES.CREATE_ABOUT_SECTION]: AboutSectionBuilder,
16
22
  [BUILDER_TYPES.CREATE_CONTACT_FORM]: ContactFormBuilder,
17
23
  [BUILDER_TYPES.CREATE_DIVIDER_SECTION]: DividerSectionBuilder,
@@ -37,6 +43,7 @@ const getBuilderRegistry = () => ({
37
43
  [BUILDER_TYPES.CREATE_TIKTOK]: ButtonSectionBuilder,
38
44
  // Section builders (update)
39
45
  [BUILDER_TYPES.UPDATE_BANNER_SECTION]: BannerSectionBuilder,
46
+ [BUILDER_TYPES.UPDATE_BOOKING_SECTION]: BookingSectionBuilder,
40
47
  [BUILDER_TYPES.UPDATE_ABOUT_SECTION]: AboutSectionBuilder,
41
48
  [BUILDER_TYPES.UPDATE_CONTACT_FORM]: ContactFormBuilder,
42
49
  [BUILDER_TYPES.UPDATE_DIVIDER_SECTION]: DividerSectionBuilder,
@@ -66,9 +73,18 @@ const getBuilderRegistry = () => ({
66
73
  // Page-level operations
67
74
  [BUILDER_TYPES.ADD_PAGE]: AddPageBuilder,
68
75
  [BUILDER_TYPES.REMOVE_PAGE]: RemovePageBuilder,
76
+ [BUILDER_TYPES.RENAME_PAGE]: RenamePageBuilder,
77
+ // Footer operations
78
+ [BUILDER_TYPES.UPDATE_FOOTER]: FooterBuilder,
79
+ // Global styles operations
80
+ [BUILDER_TYPES.UPDATE_GLOBAL_STYLES]: GlobalStylesBuilder,
81
+ // Header operations
82
+ [BUILDER_TYPES.UPDATE_HEADER]: HeaderBuilder,
83
+ // Website-level operations
84
+ [BUILDER_TYPES.UNDO_WEBSITE]: UndoBuilder,
69
85
  });
70
86
  let builderRegistry = null;
71
- const resolveBuilder = (request, logger) => {
87
+ const resolveBuilder = (request, logger, eventTracker) => {
72
88
  if (!builderRegistry) {
73
89
  builderRegistry = getBuilderRegistry();
74
90
  }
@@ -77,14 +93,14 @@ const resolveBuilder = (request, logger) => {
77
93
  console.error(`No builder registered for request type: "${request.type}"`);
78
94
  return null;
79
95
  }
80
- return new BuilderClass(request, logger);
96
+ return new BuilderClass(request, logger, eventTracker);
81
97
  };
82
98
  export class MetadataExecutor {
83
- async executeAsync(metadata, requests, logger) {
99
+ async executeAsync(metadata, requests, logger, eventTracker) {
84
100
  let model = cloneDeep(metadata);
85
101
  const results = [];
86
102
  for (const request of requests) {
87
- const builder = resolveBuilder(request, logger);
103
+ const builder = resolveBuilder(request, logger, eventTracker);
88
104
  if (!builder) {
89
105
  results.push({
90
106
  request,
@@ -94,6 +110,17 @@ export class MetadataExecutor {
94
110
  continue;
95
111
  }
96
112
  const result = await builder.buildAsync(model);
113
+ // Surface the section's resolved content id on the result. The AI-chat
114
+ // retry path uses this to fill its vacant-slot tracker so a previously
115
+ // failed CREATE can re-enter its planned position on the page. Done at
116
+ // the executor level so individual builders don't have to remember to
117
+ // populate the field on every code path.
118
+ const resolveContentId = builder.getResolvedContentId?.bind(builder);
119
+ if (resolveContentId && !result.contentId) {
120
+ const cid = resolveContentId();
121
+ if (cid)
122
+ result.contentId = cid;
123
+ }
97
124
  results.push(result);
98
125
  model = result.model;
99
126
  }
@@ -1,4 +1,5 @@
1
1
  import { type BrandPageModel } from '../brand-page/models';
2
+ import type { EventTracker } from '../brand-page-maker/composables/useEventTracker';
2
3
  import type { Logger } from './logger';
3
4
  export declare const BUILDER_TYPES: {
4
5
  readonly UPDATE_CONTENT_TEXT: "update-content-text";
@@ -27,6 +28,7 @@ export declare const BUILDER_TYPES: {
27
28
  readonly CREATE_PINTEREST: "create-pinterest";
28
29
  readonly CREATE_TWITCH: "create-twitch";
29
30
  readonly CREATE_TIKTOK: "create-tiktok";
31
+ readonly CREATE_BOOKING_SECTION: "create-booking-section";
30
32
  readonly UPDATE_BANNER_SECTION: "update-banner-section";
31
33
  readonly UPDATE_ABOUT_SECTION: "update-about-section";
32
34
  readonly UPDATE_CONTACT_FORM: "update-contact-form";
@@ -51,10 +53,16 @@ export declare const BUILDER_TYPES: {
51
53
  readonly UPDATE_PINTEREST: "update-pinterest";
52
54
  readonly UPDATE_TWITCH: "update-twitch";
53
55
  readonly UPDATE_TIKTOK: "update-tiktok";
56
+ readonly UPDATE_BOOKING_SECTION: "update-booking-section";
54
57
  readonly DELETE_SECTION: "delete-section";
55
58
  readonly MOVE_SECTION: "move-section";
56
59
  readonly ADD_PAGE: "add-page";
57
60
  readonly REMOVE_PAGE: "remove-page";
61
+ readonly RENAME_PAGE: "rename-page";
62
+ readonly UPDATE_FOOTER: "update-footer";
63
+ readonly UPDATE_GLOBAL_STYLES: "update-global-styles";
64
+ readonly UPDATE_HEADER: "update-header";
65
+ readonly UNDO_WEBSITE: "undo-website";
58
66
  };
59
67
  export type BuilderType = (typeof BUILDER_TYPES)[keyof typeof BUILDER_TYPES];
60
68
  export interface MetadataBuilderRequest<T = unknown> {
@@ -74,11 +82,28 @@ export interface BuilderResult {
74
82
  request: MetadataBuilderRequest;
75
83
  model: BrandPageModel;
76
84
  errors?: string[];
85
+ /**
86
+ * Set by the UndoBuilder to signal that the caller should restore the
87
+ * website to the snapshot taken before the most recent change-producing
88
+ * prompt. The model returned alongside this flag is unchanged — the actual
89
+ * snapshot restore happens outside this library.
90
+ */
91
+ undoRequested?: boolean;
92
+ /**
93
+ * The frontend-assigned content ID of the section this builder created or
94
+ * updated. Populated for section CREATE flows so callers can anchor
95
+ * downstream operations (notably the AI retry path's vacant-slot tracking)
96
+ * to the resolved content. Undefined on failure, on non-section builders
97
+ * (page-level ops, undo), and on builders that don't touch a single
98
+ * content (e.g. global-styles).
99
+ */
100
+ contentId?: string;
77
101
  }
78
102
  export declare abstract class BaseMetadataBuilder<T = unknown> {
79
103
  protected request: MetadataBuilderRequest<T>;
80
104
  protected logger?: Logger;
81
- constructor(request: MetadataBuilderRequest<T>, logger?: Logger);
105
+ protected eventTracker?: EventTracker;
106
+ constructor(request: MetadataBuilderRequest<T>, logger?: Logger, eventTracker?: EventTracker);
82
107
  abstract validateAsync(): Promise<{
83
108
  errors: string[];
84
109
  }>;