@designcrowd/library.brand-page 6.0.5 → 6.0.6-ast-bugs

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 (395) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-DhzvKlTS.js → CreatedOnBrandCrowd-de-de-SHCspMwS.js} +3 -3
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DKH4lmNV.js → CreatedOnBrandCrowd-en-us-C6lITAAT.js} +3 -3
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-RloPCLuV.js → CreatedOnBrandCrowd-es-es-Uh69c4vZ.js} +3 -3
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-Cu9e2H0K.js → CreatedOnBrandCrowd-fr-ca-Bb0rp7BV.js} +3 -3
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-Cu9e2H0K.js → CreatedOnBrandCrowd-fr-fr-Bb0rp7BV.js} +3 -3
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-CiCnjxBZ.js → CreatedOnBrandCrowd-pt-br-DsrQHcjs.js} +3 -3
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-CiCnjxBZ.js → CreatedOnBrandCrowd-pt-pt-DsrQHcjs.js} +3 -3
  8. package/lib/src/{CreatedOnDcom-de-de-CwlnedFV.js → CreatedOnDcom-de-de-BshZYzSp.js} +3 -3
  9. package/lib/src/{CreatedOnDcom-en-us-DFHex61v.js → CreatedOnDcom-en-us-CLu8mKUW.js} +3 -3
  10. package/lib/src/{CreatedOnDcom-es-es-BTxH6I4V.js → CreatedOnDcom-es-es-BZYhkONd.js} +3 -3
  11. package/lib/src/{CreatedOnDcom-fr-ca-BVw0KYxu.js → CreatedOnDcom-fr-ca-CIaBEp_9.js} +3 -3
  12. package/lib/src/{CreatedOnDcom-fr-fr-DaqNz1Er.js → CreatedOnDcom-fr-fr-dyF7hioJ.js} +3 -3
  13. package/lib/src/{CreatedOnDcom-pt-br-B4KsMI8W.js → CreatedOnDcom-pt-br-CUHjk2du.js} +3 -3
  14. package/lib/src/{CreatedOnDcom-pt-pt-CWoHEtOZ.js → CreatedOnDcom-pt-pt-CWDvQidv.js} +3 -3
  15. package/lib/src/brand-page/clients/brand-page.client.d.ts +9 -9
  16. package/lib/src/brand-page/components/banner-section/BannerSection.mixin.d.ts +103 -0
  17. package/lib/src/brand-page/components/banner-section/BannerSection.mixin.js +178 -0
  18. package/lib/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.d.ts +1 -2
  19. package/lib/src/brand-page/components/navigation/hamburger/HamburgerNavigation.mixin.d.ts +4 -2
  20. package/lib/src/brand-page/components/navigation/hamburger/HamburgerNavigation.mixin.js +1 -0
  21. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.d.ts +4 -2
  22. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.js +11 -5
  23. package/lib/src/brand-page/components/page/Page.mixin.d.ts +1 -1
  24. package/lib/src/brand-page/components/page/PageComponent.mixin.d.ts +1 -1
  25. package/lib/src/brand-page/components/payment/Payment.mixin.d.ts +3 -3
  26. package/lib/src/brand-page/components/payment/__fixtures__/request-payment.d.ts +13 -13
  27. package/lib/src/brand-page/components/payment/__fixtures__/support-me.d.ts +13 -13
  28. package/lib/src/brand-page/constants/sections/footer-display.constants.js +1 -1
  29. package/lib/src/brand-page/models/index.d.ts +2 -13
  30. package/lib/src/brand-page/models/index.js +3 -0
  31. package/lib/src/brand-page/models/payment.model.d.ts +1 -1
  32. package/lib/src/brand-page/utils/personalisation.util.js +72 -14
  33. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +21 -19
  34. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.js +1 -0
  35. package/lib/src/brand-page-maker/components/admin-background-settings/AdminBackgroundSettings.mixin.d.ts +16 -10
  36. package/lib/src/brand-page-maker/components/admin-background-settings/ShapePositionSlider.mixin.d.ts +1 -1
  37. package/lib/src/brand-page-maker/components/admin-logo-settings/AdminLogoSettings.mixin.d.ts +3 -3
  38. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +181 -170
  39. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +3 -0
  40. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.js +1 -0
  41. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +12 -12
  42. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.stories.js +2 -2
  43. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-payment.js +0 -7
  44. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +148 -149
  45. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +21 -21
  46. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.js +1 -1
  47. package/lib/src/brand-page-maker/components/color-picker/components/ColorModeSelect.mixin.d.ts +4 -2
  48. package/lib/src/brand-page-maker/components/color-picker/components/ColorModeSelect.mixin.js +1 -0
  49. package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSlider.mixin.d.ts +4 -2
  50. package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSlider.mixin.js +1 -0
  51. package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSliderHandler.mixin.d.ts +5 -2
  52. package/lib/src/brand-page-maker/components/color-picker/components/GradientColorSliderHandler.mixin.js +1 -0
  53. package/lib/src/brand-page-maker/components/color-picker/components/GradientTypeSelector.mixin.d.ts +4 -2
  54. package/lib/src/brand-page-maker/components/color-picker/components/GradientTypeSelector.mixin.js +1 -0
  55. package/lib/src/brand-page-maker/components/device/Device.mixin.d.ts +4 -2
  56. package/lib/src/brand-page-maker/components/device/Device.mixin.js +1 -0
  57. package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.d.ts +4 -2
  58. package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.js +1 -0
  59. package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +3 -3
  60. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +11 -11
  61. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +27 -25
  62. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.js +1 -0
  63. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +27 -27
  64. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.js +1 -1
  65. package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +17 -12
  66. package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +12 -12
  67. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +30 -32
  68. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.js +16 -5
  69. package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +11 -11
  70. package/lib/src/brand-page-maker/composables/ai-chat/types.d.ts +3 -0
  71. package/lib/src/brand-page-maker/composables/ai-chat/ui-actions.d.ts +29 -0
  72. package/lib/src/brand-page-maker/composables/ai-chat/ui-actions.js +32 -0
  73. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +204 -177
  74. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +1 -1
  75. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +6 -6
  76. package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +3 -2
  77. package/lib/src/brand-page-maker/composables/useEventTracker.js +1 -0
  78. package/lib/src/brand-page-maker/constants/config-settings-constant.d.ts +6 -6
  79. package/lib/src/brand-page-maker/constants/config-settings-constant.js +3 -3
  80. package/lib/src/brand-page-maker/convertors/text-image-display-style.convertor.d.ts +1 -1
  81. package/lib/src/brand-page-maker/convertors/text-image-display-style.convertor.js +1 -1
  82. package/lib/src/brand-page-maker/models/content-settings.d.ts +1 -1
  83. package/lib/src/brand-page-maker/models/navigation-style-configs.js +1 -1
  84. package/lib/src/brand-page-maker/routing/brand-page-maker-router.d.ts +1 -2
  85. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +366 -378
  86. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +5 -4
  87. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.js +8 -5
  88. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +3 -1
  89. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +7 -3
  90. package/lib/src/brand-page-maker/stores/history/history-store.d.ts +15 -15
  91. package/lib/src/brand-page-maker/stores/ui/ui-store.d.ts +6 -0
  92. package/lib/src/brand-page-maker/stores/ui/ui-store.js +8 -0
  93. package/lib/src/brand-page-maker/utils/content-settings.util.js +1 -1
  94. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +1 -1
  95. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +4 -4
  96. package/lib/src/clients/ai-assistant-client.d.ts +7 -0
  97. package/lib/src/clients/brand-page-client.d.ts +16 -15
  98. package/lib/src/clients/design-template-client.d.ts +3 -0
  99. package/lib/src/clients/media-client.d.ts +2 -2
  100. package/lib/src/clients/models.d.ts +2 -0
  101. package/lib/src/composables/useSnapshot.js +18 -18
  102. package/lib/src/css/library.brand-page-brandCrowd.min.css +371 -344
  103. package/lib/src/css/library.brand-page-brandPage.min.css +649 -344
  104. package/lib/src/css/library.brand-page-designCom.min.css +371 -344
  105. package/lib/src/css/library.brand-page-preview.min.css +627 -344
  106. package/lib/src/index.d.ts +4 -0
  107. package/lib/src/index.mjs +107 -104
  108. package/lib/src/{lib-BPI8E2Ui.js → lib-COw-Rz05.js} +37005 -33761
  109. package/lib/src/lib.js +10 -0
  110. package/lib/src/metadata-builder/builders/footer-builder.js +105 -62
  111. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +68 -57
  112. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +93 -58
  113. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +99 -66
  114. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +17 -57
  115. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +85 -51
  116. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +74 -49
  117. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +7 -0
  118. package/lib/src/metadata-builder/builders/section-field-utils.js +1 -1
  119. package/lib/src/metadata-builder/builders/shape-color-utils.js +1 -1
  120. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +7 -16
  121. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +48 -66
  122. package/lib/src/plugins/google-maps-plugin/google-maps-plugin.d.ts +1 -1
  123. package/lib/src/plugins/google-maps-plugin/google-maps-plugin.js +8 -8
  124. package/lib/src/shared/background-settings/components/background-shapes/BackgroundShapeSettings.mixin.d.ts +13 -13
  125. package/lib/src/shared/background-settings/store/background-settings-store.d.ts +3 -3
  126. package/lib/src/shared/color-picker/components/ColorPicker.mixin.d.ts +4 -2
  127. package/lib/src/shared/color-picker/components/ColorPicker.mixin.js +2 -2
  128. package/lib/src/shared/color-picker/components/ColorPickerSwatch.mixin.d.ts +4 -2
  129. package/lib/src/shared/color-picker/components/ColorPickerSwatch.mixin.js +1 -0
  130. package/lib/src/shared/confirm-modal/ConfirmModal.mixin.d.ts +5 -2
  131. package/lib/src/shared/confirm-modal/ConfirmModal.mixin.js +1 -0
  132. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +0 -1
  133. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +131 -129
  134. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +2 -1
  135. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +111 -110
  136. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +84 -81
  137. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.js +5 -0
  138. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +117 -109
  139. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +1 -14
  140. package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +0 -1
  141. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +72 -70
  142. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +4 -3
  143. package/lib/src/shared/content-settings/components/form-fields-field/FormFieldsField.mixin.d.ts +4 -4
  144. package/lib/src/shared/content-settings/components/icon-library/IconLibrary.mixin.d.ts +3 -1
  145. package/lib/src/shared/content-settings/components/icon-library/IconLibrary.mixin.js +1 -0
  146. package/lib/src/shared/content-settings/components/images-field/ImagesField.mixin.d.ts +2 -2
  147. package/lib/src/shared/content-settings/components/items-field/ItemsField.mixin.d.ts +4 -3
  148. package/lib/src/shared/content-settings/components/items-field/ItemsField.mixin.js +1 -1
  149. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +40 -40
  150. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigOptionField.mixin.d.ts +5 -6
  151. package/lib/src/shared/content-settings/components/shape-field/ShapeField.mixin.d.ts +0 -1
  152. package/lib/src/shared/content-settings/components/slider-field/SliderField.mixin.d.ts +2 -2
  153. package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +0 -1
  154. package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +1 -2
  155. package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +0 -1
  156. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +1 -2
  157. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +1 -1
  158. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.d.ts +28 -28
  159. package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +0 -1
  160. package/lib/src/shared/content-settings/components/toggle-field/ToggleField.mixin.d.ts +2 -2
  161. package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +0 -1
  162. package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +0 -1
  163. package/lib/src/shared/content-settings/store/content-settings-store.d.ts +39 -39
  164. package/lib/src/shared/content-settings/utils.js +0 -1
  165. package/lib/src/shared/font-family-selector/FontFamilySelector.mixin.d.ts +6 -4
  166. package/lib/src/shared/font-family-selector/FontFamilySelector.mixin.js +1 -0
  167. package/lib/src/shared/image-gallery-style-settings/ImageGalleryStyleSettings.mixin.d.ts +4 -2
  168. package/lib/src/shared/image-gallery-style-settings/ImageGalleryStyleSettings.mixin.js +1 -0
  169. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +29 -21
  170. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.js +1 -1
  171. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +50 -51
  172. package/lib/src/shared/logo-settings/components/LogoSettingsHeader.mixin.d.ts +6 -4
  173. package/lib/src/shared/logo-settings/components/LogoSettingsHeader.mixin.js +1 -0
  174. package/lib/src/shared/logo-settings/store/editable-logo-store.js +1 -1
  175. package/lib/src/shared/logo-settings/store/logo-settings-store.d.ts +1 -1
  176. package/lib/src/shared/logo-versions/LogoVersions.mixin.d.ts +13 -5
  177. package/lib/src/shared/logo-versions/LogoVersions.mixin.js +1 -0
  178. package/lib/src/shared/models.d.ts +2 -0
  179. package/lib/src/shared/my-designs/MyDesigns.mixin.d.ts +14 -6
  180. package/lib/src/shared/my-designs/MyDesigns.mixin.js +1 -0
  181. package/lib/src/shared/my-uploads/MyMedia.mixin.d.ts +14 -5
  182. package/lib/src/shared/my-uploads/MyMedia.mixin.js +1 -0
  183. package/lib/src/shared/my-uploads/MyUploads.mixin.d.ts +14 -5
  184. package/lib/src/shared/my-uploads/MyUploads.mixin.js +1 -0
  185. package/lib/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.d.ts +5 -3
  186. package/lib/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.js +1 -0
  187. package/lib/src/shared/navigation-style-settings/store/index.d.ts +2 -2
  188. package/lib/src/shared/page-navigation/store/page-navigation-store.d.ts +2 -2
  189. package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.d.ts +27 -28
  190. package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.js +0 -2
  191. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +188 -179
  192. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +181 -177
  193. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.js +1 -1
  194. package/lib/src/shared/page-settings/store/page-settings-store.d.ts +9 -9
  195. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +39 -39
  196. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.js +0 -1
  197. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +18 -18
  198. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +6 -6
  199. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +66 -60
  200. package/lib/src/shared/style-settings/store/style-settings-store.d.ts +1 -1
  201. package/lib/src/shared/style-settings/store/style-settings-store.js +1 -1
  202. package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +20 -450
  203. package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.js +2 -2
  204. package/lib/src/shared/template-settings/models.d.ts +1 -0
  205. package/lib/src/shared/template-settings/store/template-settings-store.d.ts +4 -0
  206. package/lib/src/shared/template-settings/store/template-settings-store.js +79 -11
  207. package/lib/src/shared/unsplash-library/UnsplashLibrary.mixin.d.ts +9 -4
  208. package/lib/src/utils/build-asset-manifest.d.ts +4 -0
  209. package/lib/src/utils/build-asset-manifest.js +8 -0
  210. package/lib/src/utils/minify-brand-page-metadata.d.ts +0 -2
  211. package/lib/src/utils/minify-brand-page-metadata.js +2 -17
  212. package/package.json +60 -56
  213. package/src/brand-page/components/about-section/AboutSection.vue.test.ts +7 -5
  214. package/src/brand-page/components/banner-section/BannerSection.mixin.ts +210 -0
  215. package/src/brand-page/components/banner-section/BannerSection.vue +5 -1
  216. package/src/brand-page/components/brand-page-footer/BrandPageFooter.vue +1 -1
  217. package/src/brand-page/components/image/Image.mixin.ts +1 -1
  218. package/src/brand-page/components/image/Image.test.ts +1 -1
  219. package/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.ts +1 -2
  220. package/src/brand-page/components/images-section/ImagesSection.vue +0 -1
  221. package/src/brand-page/components/logo/LogoRender.vue +188 -188
  222. package/src/brand-page/components/navigation/hamburger/HamburgerNavigation.mixin.ts +1 -0
  223. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.ts +25 -8
  224. package/src/brand-page/components/page-footer/PageFooter.vue +1 -0
  225. package/src/brand-page/components/page-header/HeaderLayout.vue +12 -6
  226. package/src/brand-page/components/page-header/PageHeader.vue +1 -0
  227. package/src/brand-page/components/shapes-section/ShapesSection.vue +1 -1
  228. package/src/brand-page/components/shop/CartModal.vue +1 -3
  229. package/src/brand-page/components/shop/FeaturedDisplay.vue +2 -2
  230. package/src/brand-page/components/shop/PaymentModal.vue +1 -5
  231. package/src/brand-page/components/shop/ProductDetailModal.vue +1 -1
  232. package/src/brand-page/components/shop/Shop.vue +1 -5
  233. package/src/brand-page/components/shop/TextDisplay.vue +1 -1
  234. package/src/brand-page/components/shop/ThumbnailDisplay.vue +2 -2
  235. package/src/brand-page/components/testimonial-section/TestimonialSection.vue +3 -3
  236. package/src/brand-page/components/text-wrapper/TextWrapper.vue +3 -1
  237. package/src/brand-page/constants/sections/footer-display.constants.ts +1 -1
  238. package/src/brand-page/models/index.ts +4 -12
  239. package/src/brand-page/models/payment.model.ts +2 -1
  240. package/src/brand-page/models/shop.model.ts +0 -2
  241. package/src/brand-page/models/user-personalisation.model.ts +1 -2
  242. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -0
  243. package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +1 -0
  244. package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +2 -0
  245. package/src/brand-page/utils/migration/migration-01_1.ts +1 -1
  246. package/src/brand-page/utils/migration/migration-02.ts +0 -1
  247. package/src/brand-page/utils/migration/migration-03.ts +0 -1
  248. package/src/brand-page/utils/migration/migration-04.ts +0 -1
  249. package/src/brand-page/utils/migration/migration-05.ts +1 -5
  250. package/src/brand-page/utils/migration/migration-05_2.ts +1 -1
  251. package/src/brand-page/utils/migration/migration-08.test.ts +1 -1
  252. package/src/brand-page/utils/personalisation.util.test.ts +35 -0
  253. package/src/brand-page/utils/personalisation.util.ts +119 -23
  254. package/src/brand-page/view-models.ts +38 -56
  255. package/src/brand-page-maker/assessors/banner-section-description-visibility.assessor.ts +6 -6
  256. package/src/brand-page-maker/assessors/color-replacement-icon-visibility.assessor.ts +2 -2
  257. package/src/brand-page-maker/assessors/color-replacement-profile-visibility.assessor.ts +2 -2
  258. package/src/brand-page-maker/assessors/color-replacement-visibility.assessor.ts +2 -2
  259. package/src/brand-page-maker/assessors/contact-form-visibility.assessor.ts +14 -14
  260. package/src/brand-page-maker/components/action-bar/ActionBar.mixin.ts +1 -0
  261. package/src/brand-page-maker/components/ai-text-edit/AiActionButtons.vue +27 -12
  262. package/src/brand-page-maker/components/ai-text-edit/AiChatbox.vue +3 -2
  263. package/src/brand-page-maker/components/ai-text-edit/TextBubble.vue +8 -7
  264. package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +21 -1
  265. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +5 -1
  266. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.ts +1 -0
  267. package/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.stories.ts +2 -5
  268. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -5
  269. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-payment.ts +0 -8
  270. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-site-template.examples.ts +0 -2
  271. package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.vue +1 -0
  272. package/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.ts +1 -1
  273. package/src/brand-page-maker/components/color-palette/BpColorPalette.vue +1 -2
  274. package/src/brand-page-maker/components/color-picker/components/ColorModeSelect.mixin.ts +1 -0
  275. package/src/brand-page-maker/components/color-picker/components/GradientColorSlider.mixin.ts +1 -0
  276. package/src/brand-page-maker/components/color-picker/components/GradientColorSliderHandler.mixin.ts +1 -0
  277. package/src/brand-page-maker/components/color-picker/components/GradientTypeSelector.mixin.ts +1 -0
  278. package/src/brand-page-maker/components/device/Device.mixin.ts +1 -0
  279. package/src/brand-page-maker/components/navigation/Navigation.mixin.ts +1 -0
  280. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +3 -1
  281. package/src/brand-page-maker/components/sensitive-content/SensitiveContent.vue +1 -4
  282. package/src/brand-page-maker/components/seo-settings/DeleteDomainModal.vue +1 -1
  283. package/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.ts +1 -0
  284. package/src/brand-page-maker/components/seo-settings/SeoPageSettings.vue +1 -1
  285. package/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.ts +0 -1
  286. package/src/brand-page-maker/components/seo-settings/UrlSettings.vue +0 -1
  287. package/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.vue +1 -5
  288. package/src/brand-page-maker/components/shop/AddOrEditProductContainer.vue +1 -1
  289. package/src/brand-page-maker/components/shop/ReplaceImageSettingsForShop.vue +1 -1
  290. package/src/brand-page-maker/components/social-share/SocialShare.vue +1 -1
  291. package/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.ts +22 -8
  292. package/src/brand-page-maker/components/template-preview/TemplatePreview.vue +5 -10
  293. package/src/brand-page-maker/components/template-preview/TemplatePreviewAiBadge.vue +12 -0
  294. package/src/brand-page-maker/components/video-play/VideoPlayButton.vue +1 -1
  295. package/src/brand-page-maker/composables/ai-chat/types.ts +6 -0
  296. package/src/brand-page-maker/composables/ai-chat/ui-actions.test.ts +80 -0
  297. package/src/brand-page-maker/composables/ai-chat/ui-actions.ts +58 -0
  298. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +308 -262
  299. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +6 -6
  300. package/src/brand-page-maker/composables/useEventTracker.ts +1 -0
  301. package/src/brand-page-maker/constants/config-settings-constant.ts +5 -5
  302. package/src/brand-page-maker/convertors/text-image-display-style.convertor.ts +1 -1
  303. package/src/brand-page-maker/models/button-styles-config.ts +4 -2
  304. package/src/brand-page-maker/models/content-settings-configs.ts +4 -2
  305. package/src/brand-page-maker/models/navigation-style-configs.ts +5 -6
  306. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.ts +0 -1
  307. package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +8 -5
  308. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +1 -3
  309. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +12 -4
  310. package/src/brand-page-maker/stores/ui/ui-store.ts +16 -0
  311. package/src/brand-page-maker/utils/content-settings.util.ts +1 -1
  312. package/src/brand-page-maker/utils/rich-text-editor.util.ts +4 -4
  313. package/src/clients/ai-assistant-client.ts +7 -0
  314. package/src/clients/design-template-client.ts +3 -0
  315. package/src/clients/models.ts +2 -0
  316. package/src/composables/useSnapshot.ts +19 -22
  317. package/src/lib.ts +12 -0
  318. package/src/metadata-builder/builders/footer-builder.test.ts +130 -229
  319. package/src/metadata-builder/builders/footer-builder.ts +155 -90
  320. package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +88 -62
  321. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +129 -66
  322. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +160 -105
  323. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +20 -65
  324. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +146 -83
  325. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +122 -70
  326. package/src/metadata-builder/builders/section-field-utils.ts +1 -1
  327. package/src/metadata-builder/builders/shape-color-utils.ts +2 -2
  328. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +7 -16
  329. package/src/metadata-builder/parsers/section-tool-arguments.ts +48 -66
  330. package/src/plugins/google-maps-plugin/google-maps-plugin.ts +8 -8
  331. package/src/shared/background-settings/components/BackgroundSettings.vue +1 -1
  332. package/src/shared/background-settings/components/background-color/BackgroundColorSettings.vue +1 -1
  333. package/src/shared/color-picker/components/ColorPicker.mixin.ts +2 -7
  334. package/src/shared/color-picker/components/ColorPickerSwatch.mixin.ts +1 -0
  335. package/src/shared/common/NumberInput.vue +1 -0
  336. package/src/shared/common/SideBarSettingsHeader.vue +2 -2
  337. package/src/shared/confirm-modal/ConfirmModal.mixin.ts +1 -0
  338. package/src/shared/content-settings/components/booking-url-field/BookingUrlField.vue +1 -0
  339. package/src/shared/content-settings/components/button-configuration-field/ButtonConfigurationField.vue +1 -0
  340. package/src/shared/content-settings/components/color-field/ColorField.vue +3 -10
  341. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +1 -1
  342. package/src/shared/content-settings/components/content-settings/ContentSettingsLockedButton.vue +1 -0
  343. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.ts +5 -0
  344. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +1 -14
  345. package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +4 -6
  346. package/src/shared/content-settings/components/icon-library/IconLibrary.mixin.ts +1 -0
  347. package/src/shared/content-settings/components/items-field/ItemsField.mixin.ts +1 -1
  348. package/src/shared/content-settings/components/logo-selection-field/LogoSelectionField.vue +1 -1
  349. package/src/shared/content-settings/components/logo-size-field/LogoSizeSliderField.vue +1 -1
  350. package/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.vue +1 -1
  351. package/src/shared/content-settings/components/personalisation-role-field/PersonalisationRoleField.vue +4 -4
  352. package/src/shared/content-settings/components/text-image-field/TextImageField.vue +2 -8
  353. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +1 -1
  354. package/src/shared/content-settings/models.ts +3 -2
  355. package/src/shared/content-settings/utils.ts +0 -1
  356. package/src/shared/dropzone-image-uploader/components/DropzoneImageUploader.vue +1 -0
  357. package/src/shared/ecommerce-settings/store/cart-store.test.ts +1 -1
  358. package/src/shared/font-family-selector/FontFamilySelector.mixin.ts +1 -0
  359. package/src/shared/image-gallery-style-settings/ImageGalleryStyleSettings.mixin.ts +1 -0
  360. package/src/shared/logo-settings/components/EditLogoSettings.mixin.ts +1 -1
  361. package/src/shared/logo-settings/components/LogoSettings.mixin.ts +0 -1
  362. package/src/shared/logo-settings/components/LogoSettingsHeader.mixin.ts +1 -0
  363. package/src/shared/logo-settings/components/LogoStyleSettingsWithState.vue +2 -2
  364. package/src/shared/logo-settings/components/LogoTemplateSearch.vue +1 -1
  365. package/src/shared/logo-settings/store/editable-logo-store.ts +1 -1
  366. package/src/shared/logo-settings/store/logo-settings-store.test.ts +4 -4
  367. package/src/shared/logo-versions/LogoVersions.mixin.ts +1 -0
  368. package/src/shared/models.ts +6 -0
  369. package/src/shared/my-designs/MyDesigns.mixin.ts +1 -0
  370. package/src/shared/my-uploads/MyMedia.mixin.ts +1 -0
  371. package/src/shared/my-uploads/MyMediaSelectionItem.vue +2 -1
  372. package/src/shared/my-uploads/MyUploads.mixin.ts +1 -0
  373. package/src/shared/my-uploads/models.ts +1 -2
  374. package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.mixin.ts +1 -0
  375. package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.vue +1 -1
  376. package/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.ts +0 -3
  377. package/src/shared/page-settings/components/page-settings/NestedDraggable.vue +1 -1
  378. package/src/shared/page-settings/components/page-settings/PageSettings.vue +1 -2
  379. package/src/shared/page-settings/components/page-settings-section-styles/HeaderDisplayStyle.vue +1 -1
  380. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.ts +1 -1
  381. package/src/shared/page-settings/store/page-settings-store.test.ts +4 -8
  382. package/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.ts +0 -1
  383. package/src/shared/shape-library/ShapeLibrary.vue +2 -2
  384. package/src/shared/style-settings/store/style-settings-store.ts +1 -1
  385. package/src/shared/template-settings/components/TemplatesSettings.mixin.ts +2 -2
  386. package/src/shared/template-settings/models.ts +1 -0
  387. package/src/shared/template-settings/store/template-settings-store.ts +105 -18
  388. package/src/shared/unsplash-library/UnsplashLibrary.vue +2 -6
  389. package/src/shared/video-library/VideoLibrary.vue +1 -1
  390. package/src/utils/build-asset-manifest.ts +12 -0
  391. package/src/utils/minify-brand-page-metadata.ts +7 -27
  392. package/lib/src/metadata-builder/builders/item-id-utils.d.ts +0 -54
  393. package/lib/src/metadata-builder/builders/item-id-utils.js +0 -96
  394. package/src/metadata-builder/builders/item-id-utils.test.ts +0 -184
  395. package/src/metadata-builder/builders/item-id-utils.ts +0 -117
package/lib/src/lib.js CHANGED
@@ -31,6 +31,16 @@ export * as brandPageUtils from './brand-page/utils';
31
31
  export { getOptimalLogoSize, calculateOptimizedLogoDimensions, applyLogoImageBase64UrlToBrandPageTemplateModel, recalculateLogoContentDimensions, recalculateHeaderLogoSizes, } from './brand-page/utils/logo.util';
32
32
  export { sanitizeRTEHtml } from './brand-page-maker/utils';
33
33
  export { getPageSlugFromPageTitle } from './brand-page-maker/utils/slug.util';
34
+ // AI-pipeline preview (longclaw per-turn snapshots): web-renderer's
35
+ // /preview/ai-pipeline render page + manifest server route apply the agent's
36
+ // tool calls to a brand-page metadata snapshot server-side and resolve the
37
+ // target page by slug. These three symbols are otherwise internal to the
38
+ // metadata-builder / route utils.
39
+ export { executeToolCallsAsync } from './metadata-builder/ai-metadata-executor';
40
+ export { findNavItemByPageSlug } from './brand-page/utils/route.util';
41
+ // Tiptap-JSON RTE -> HTML (same converter the metadata builders use). Lets the
42
+ // preview render the agent's raw Tiptap fields, which the renderer expects as HTML.
43
+ export { tiptapJsonToHtml } from './metadata-builder/helpers/rte.helpers';
34
44
  // stores
35
45
  export { useBrandPageMakerStore, useBrandPageMakerUserStore, useUiStore, useBrandPageContainerStore, useEventManagerStore, useLocalisedRouteStore, useVideoStore, useRouteStore, } from './brand-page-maker/stores';
36
46
  export { useShopConfigStore } from './shared/ecommerce-settings/store/shop-settings-store';
@@ -1,8 +1,7 @@
1
1
  import {} from '../../brand-page/models';
2
2
  import { BaseMetadataBuilder, } from '../models';
3
3
  import { FOOTER_CHECKS } from './section-rules/footer.rules';
4
- import { applyDetachedStyleOverride } from './section-field-utils';
5
- import { ensureItemIds, generateItemId, removeItemsByIds, repositionItemByAnchor, } from './item-id-utils';
4
+ import { applyDetachedStyleOverride, normalizeStyleValue, } from './section-field-utils';
6
5
  const normaliseSocialUrl = (url) => {
7
6
  for (const prefix of ['mailto:', 'tel:']) {
8
7
  if (url.startsWith(prefix))
@@ -10,65 +9,101 @@ const normaliseSocialUrl = (url) => {
10
9
  }
11
10
  return url;
12
11
  };
13
- const applyGlobalFooterChanges = (footer, args, textStyleOptions) => {
14
- if (args.copyright_text !== undefined)
15
- footer.copyrightText = args.copyright_text;
16
- if (args.copyright_text_font_family !== undefined)
17
- footer.copyrightStyle = applyDetachedStyleOverride(footer.copyrightStyle, { fontFamily: args.copyright_text_font_family }, textStyleOptions);
18
- const links = args.social_links;
12
+ const makeSocialLink = (icon, url) => ({
13
+ imageUrl: icon || '',
14
+ url: normaliseSocialUrl(url || ''),
15
+ imageTitle: '',
16
+ width: 0,
17
+ height: 0,
18
+ imageLink: '',
19
+ });
20
+ const hasSocialLinkMutation = (args) => args._replace_social_links === true ||
21
+ (args._remove_social_link_indices?.length ?? 0) > 0 ||
22
+ (args._reorder_social_links?.length ?? 0) > 0 ||
23
+ (args.social_links?.length ?? 0) > 0;
24
+ /**
25
+ * Social links are a GLOBAL footer concern — one logical list that both
26
+ * viewports render identically. Derive the new list ONCE from the current one
27
+ * WITHOUT mutating the input, so the caller can assign an independent copy to
28
+ * each viewport.
29
+ *
30
+ * Why this can't mutate per-viewport in place: footers migrated from the legacy
31
+ * single `footerStyles` model (migration-01) share ONE `socialLinks` array
32
+ * reference across pageFooterDesktop and pageFooterMobile, and `cloneDeep`
33
+ * preserves that shared reference. Running an in-place `splice` once per
34
+ * viewport therefore applies it TWICE to the same array — e.g. one requested
35
+ * removal index drops two links. Compute-once + assign-fresh is correct for
36
+ * both shared (legacy) and independent (new-model) footers.
37
+ */
38
+ const computeSocialLinks = (current, args) => {
19
39
  // _replace_social_links: replace entire list (empty/absent social_links = clear all).
20
- // When replacing, all other social link mutations (remove, insert, reorder) are skipped —
21
- // they are superseded by the replacement and running them would cause duplicates.
40
+ // A replacement supersedes every other social link mutation.
22
41
  if (args._replace_social_links) {
23
- footer.socialLinks = (links ?? []).map((l) => ({
24
- id: generateItemId(),
25
- imageUrl: l.social_link_icon || '',
26
- url: normaliseSocialUrl(l.url || ''),
27
- imageTitle: '',
28
- width: 0,
29
- height: 0,
30
- imageLink: '',
31
- }));
42
+ return (args.social_links ?? []).map((l) => makeSocialLink(l.social_link_icon, l.url));
43
+ }
44
+ const links = [...(current ?? [])];
45
+ // item_index-based updates for existing links — replace the item reference
46
+ // (never mutate the original object, which may be shared across viewports).
47
+ for (const link of args.social_links ?? []) {
48
+ if (link.item_index === undefined)
49
+ continue;
50
+ const existing = links[link.item_index];
51
+ if (!existing)
52
+ continue;
53
+ links[link.item_index] = {
54
+ ...existing,
55
+ ...(link.social_link_icon !== undefined
56
+ ? { imageUrl: link.social_link_icon }
57
+ : {}),
58
+ ...(link.url !== undefined ? { url: normaliseSocialUrl(link.url) } : {}),
59
+ };
60
+ }
61
+ // Remove by index (descending order to preserve indices during splice).
62
+ if (args._remove_social_link_indices?.length) {
63
+ const sorted = [...args._remove_social_link_indices].sort((a, b) => b - a);
64
+ for (const idx of sorted) {
65
+ if (idx >= 0 && idx < links.length)
66
+ links.splice(idx, 1);
67
+ }
68
+ }
69
+ // Insert new links (descending insert_at order to preserve positions).
70
+ const insertLinks = (args.social_links ?? []).filter((l) => l.insert_at !== undefined && l.item_index === undefined);
71
+ const sortedInserts = [...insertLinks].sort((a, b) => b.insert_at - a.insert_at);
72
+ for (const link of sortedInserts) {
73
+ const pos = Math.max(0, Math.min(link.insert_at, links.length));
74
+ links.splice(pos, 0, makeSocialLink(link.social_link_icon, link.url));
32
75
  }
33
- else {
34
- // Targeted mutations — only run when NOT replacing the entire list.
35
- // BP-5603: id-based contract (item_id / move_before_item_id / _remove_social_link_ids).
36
- // Backfill ids on legacy links so they become referenceable after this call.
37
- ensureItemIds(footer.socialLinks);
38
- // Remove by id (order-independent — no index shifting needed).
39
- footer.socialLinks = removeItemsByIds(footer.socialLinks, args._remove_social_link_ids);
40
- // Update existing links (item_id present) or insert new links (no item_id).
41
- if (links?.length) {
42
- footer.socialLinks = footer.socialLinks ?? [];
43
- for (const link of links) {
44
- if (link.item_id) {
45
- // Update existing link in place; reposition if move_before_item_id set.
46
- const existing = footer.socialLinks.find((l) => l.id === link.item_id);
47
- // Unknown id — skip rather than guess at a position.
48
- if (!existing)
49
- continue;
50
- if (link.social_link_icon !== undefined)
51
- existing.imageUrl = link.social_link_icon;
52
- if (link.url !== undefined)
53
- existing.url = normaliseSocialUrl(link.url);
54
- repositionItemByAnchor(footer.socialLinks, existing, link.move_before_item_id);
55
- }
56
- else {
57
- // New link — assign a stable id and position via move_before_item_id.
58
- const newLink = {
59
- id: generateItemId(),
60
- imageUrl: link.social_link_icon || '',
61
- url: normaliseSocialUrl(link.url || ''),
62
- imageTitle: '',
63
- width: 0,
64
- height: 0,
65
- imageLink: '',
66
- };
67
- repositionItemByAnchor(footer.socialLinks, newLink, link.move_before_item_id);
68
- }
69
- }
76
+ // Reorder (requires ALL indices — partial reorder is not supported).
77
+ if (args._reorder_social_links?.length) {
78
+ const newOrder = args._reorder_social_links;
79
+ const unique = new Set(newOrder);
80
+ if (unique.size === newOrder.length &&
81
+ newOrder.every((idx) => idx >= 0 && idx < links.length)) {
82
+ const reordered = newOrder.map((idx) => links[idx]);
83
+ if (reordered.length === links.length)
84
+ return reordered;
70
85
  }
71
86
  }
87
+ return links;
88
+ };
89
+ const applyGlobalFooterChanges = (footer, args, textStyleOptions) => {
90
+ if (args.copyright_text !== undefined)
91
+ footer.copyrightText = args.copyright_text;
92
+ // copyright_text_style is the same text-style object sections use (typography
93
+ // + colour). Normalise each value the way section styles are normalised
94
+ // (letterSpacing int→em, lineHeight snap, null→''), then detach from the
95
+ // global preset via the override helper so a single call resolves the preset
96
+ // and clears textStyleType once — see resolveGlobalPresetIntoStyle (BP-5420).
97
+ if (args.copyright_text_style) {
98
+ const updates = {};
99
+ for (const [key, value] of Object.entries(args.copyright_text_style)) {
100
+ const normalized = normalizeStyleValue(key, value);
101
+ if (normalized !== undefined)
102
+ updates[key] = normalized;
103
+ }
104
+ if (Object.keys(updates).length > 0)
105
+ footer.copyrightStyle = applyDetachedStyleOverride(footer.copyrightStyle, updates, textStyleOptions);
106
+ }
72
107
  };
73
108
  const applyViewportFooterChanges = (footer, overrides) => {
74
109
  if (overrides.display_style !== undefined)
@@ -85,11 +120,6 @@ const applyViewportFooterChanges = (footer, overrides) => {
85
120
  color: overrides.icon_color,
86
121
  fill: overrides.icon_color,
87
122
  };
88
- if (overrides.copyright_text_color !== undefined)
89
- footer.copyrightStyle = {
90
- ...footer.copyrightStyle,
91
- color: overrides.copyright_text_color,
92
- };
93
123
  if (overrides.is_logo_visible !== undefined)
94
124
  footer.isLogoVisible = overrides.is_logo_visible;
95
125
  if (overrides.logo_image_height !== undefined)
@@ -126,11 +156,24 @@ export class FooterBuilder extends BaseMetadataBuilder {
126
156
  }
127
157
  const args = this.request.payload ?? {};
128
158
  const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
129
- // Global fields (copyright_text, social links) always apply to both viewports.
159
+ // Global scalar/style fields (copyright text + font) apply to both
160
+ // viewports. These are idempotent assignments, safe to run per-viewport.
130
161
  if (model.pageFooterDesktop)
131
162
  applyGlobalFooterChanges(model.pageFooterDesktop, args, textStyleOptions);
132
163
  if (model.pageFooterMobile)
133
164
  applyGlobalFooterChanges(model.pageFooterMobile, args, textStyleOptions);
165
+ // Social links are a single global list. Derive the new list ONCE, then
166
+ // assign an INDEPENDENT copy to each viewport — never mutate a (possibly
167
+ // shared) viewport array in place. See computeSocialLinks.
168
+ if (hasSocialLinkMutation(args)) {
169
+ const current = model.pageFooterDesktop?.socialLinks ??
170
+ model.pageFooterMobile?.socialLinks;
171
+ const updated = computeSocialLinks(current, args);
172
+ if (model.pageFooterDesktop)
173
+ model.pageFooterDesktop.socialLinks = updated.map((l) => ({ ...l }));
174
+ if (model.pageFooterMobile)
175
+ model.pageFooterMobile.socialLinks = updated.map((l) => ({ ...l }));
176
+ }
134
177
  // Viewport-specific styling via explicit sub-objects.
135
178
  if (args.desktop && model.pageFooterDesktop)
136
179
  applyViewportFooterChanges(model.pageFooterDesktop, args.desktop);
@@ -1,21 +1,14 @@
1
1
  import { applyScalarFields, isValidUrl } from '../section-field-utils';
2
2
  import { BaseSectionBuilder } from './base-section-builder';
3
3
  import { validateImageGallery } from '../section-rules/image-gallery.rules';
4
- import { ensureItemIds, generateItemId, removeItemsByIds, repositionItemByAnchor, } from '../item-id-utils';
5
4
  const applyGalleryType = (content, galleryType) => {
6
5
  content.galleryStyles = {
7
6
  ...(content.galleryStyles || {}),
8
7
  galleryType: galleryType,
9
8
  };
10
9
  };
11
- /**
12
- * Full rebuild: discard existing images and map the payload directly.
13
- * Used on create and when `_replace_items` is set. Each item gets a fresh id
14
- * (or keeps the caller-supplied `item_id` when provided).
15
- */
16
10
  const applyGalleryImages = (content, images) => {
17
11
  content.images = images.map((img) => ({
18
- id: img.item_id || generateItemId(),
19
12
  imageUrl: isValidUrl(img.image_url) ? img.image_url : '',
20
13
  imageTitle: img.caption || '',
21
14
  width: 0,
@@ -24,46 +17,59 @@ const applyGalleryImages = (content, images) => {
24
17
  imageLink: '',
25
18
  }));
26
19
  };
27
- /**
28
- * Id-based merge (BP-5603), mirroring testimonial-section-builder one level
29
- * deeper into `content.images`:
30
- * - `item_id` matches existing item → update in place; reposition if
31
- * `move_before_item_id` is set.
32
- * - no `item_id` → add new item, positioned by
33
- * `move_before_item_id`.
34
- * - `removeIds` → delete by id (order-independent).
35
- *
36
- * Existing items are id-backfilled first so legacy galleries become
37
- * referenceable as soon as the metadata builder touches them.
38
- */
39
- const mergeGalleryImages = (content, images, removeIds) => {
40
- ensureItemIds(content.images);
41
- content.images = removeItemsByIds(content.images, removeIds);
42
- for (const img of images) {
43
- if (img.item_id) {
44
- const existing = content.images.find((i) => i.id === img.item_id);
45
- // Unknown id — skip rather than guess at a position.
46
- if (!existing)
47
- continue;
48
- if (img.image_url !== undefined) {
49
- existing.imageUrl = isValidUrl(img.image_url) ? img.image_url : '';
50
- }
51
- if (img.caption !== undefined)
52
- existing.imageTitle = img.caption;
53
- repositionItemByAnchor(content.images, existing, img.move_before_item_id);
54
- }
55
- else {
56
- const newItem = {
57
- id: generateItemId(),
58
- imageUrl: isValidUrl(img.image_url) ? img.image_url : '',
59
- imageTitle: img.caption ?? '',
60
- width: 0,
61
- height: 0,
62
- mediaType: 'image',
63
- imageLink: '',
64
- };
65
- repositionItemByAnchor(content.images, newItem, img.move_before_item_id);
66
- }
20
+ const mergeGalleryImages = (content, images, replaceAll) => {
21
+ const itemsToMerge = images.filter((img) => img.insert_at === undefined);
22
+ const updatedImages = itemsToMerge.map((img, index) => {
23
+ const existing = content.images?.[index];
24
+ const imageUrl = isValidUrl(img.image_url)
25
+ ? img.image_url
26
+ : (existing?.imageUrl ?? '');
27
+ return {
28
+ ...(existing || {}),
29
+ imageUrl,
30
+ imageTitle: img.caption ?? existing?.imageTitle ?? '',
31
+ width: existing?.width ?? 0,
32
+ height: existing?.height ?? 0,
33
+ mediaType: existing?.mediaType ?? 'image',
34
+ imageLink: existing?.imageLink ?? '',
35
+ };
36
+ });
37
+ if (!replaceAll &&
38
+ content.images &&
39
+ content.images.length > itemsToMerge.length) {
40
+ const extras = content.images.slice(itemsToMerge.length).map((img) => ({
41
+ imageUrl: img.imageUrl ?? '',
42
+ imageTitle: img.imageTitle ?? '',
43
+ width: img.width ?? 0,
44
+ height: img.height ?? 0,
45
+ mediaType: img.mediaType ?? 'image',
46
+ imageLink: img.imageLink ?? '',
47
+ }));
48
+ updatedImages.push(...extras);
49
+ }
50
+ content.images = updatedImages;
51
+ };
52
+ const insertGalleryImages = (content, images) => {
53
+ const inserts = images.filter((img) => img.insert_at !== undefined);
54
+ if (!inserts.length)
55
+ return;
56
+ const sorted = [...inserts].sort((a, b) => (b.insert_at ?? 0) - (a.insert_at ?? 0));
57
+ for (const img of sorted) {
58
+ if (!isValidUrl(img.image_url))
59
+ continue;
60
+ if (content.images?.some((existing) => existing.imageUrl === img.image_url))
61
+ continue;
62
+ content.images = content.images ?? [];
63
+ const pos = Math.max(0, Math.min(img.insert_at ?? 0, content.images.length));
64
+ content.images.splice(pos, 0, {
65
+ imageUrl: img.image_url,
66
+ imageTitle: img.caption ?? '',
67
+ width: 0,
68
+ height: 0,
69
+ mediaType: 'image',
70
+ imageLink: '',
71
+ colorReplacements: [],
72
+ });
67
73
  }
68
74
  };
69
75
  export class ImageGalleryBuilder extends BaseSectionBuilder {
@@ -85,19 +91,24 @@ export class ImageGalleryBuilder extends BaseSectionBuilder {
85
91
  if (args.gallery_type) {
86
92
  applyGalleryType(content, args.gallery_type);
87
93
  }
88
- if (args._replace_items && args.images && Array.isArray(args.images)) {
89
- // Full replacement: discard existing images and rebuild from the payload.
90
- applyGalleryImages(content, args.images);
91
- }
92
- else if (this.mode === 'create') {
93
- if (args.images && Array.isArray(args.images)) {
94
+ if (args.images && Array.isArray(args.images)) {
95
+ if (this.mode === 'create') {
94
96
  applyGalleryImages(content, args.images);
95
97
  }
98
+ else {
99
+ mergeGalleryImages(content, args.images, !!args._replace_items);
100
+ }
101
+ }
102
+ if (args._remove_item_indices?.length && content.images) {
103
+ const sorted = [...args._remove_item_indices].sort((a, b) => b - a);
104
+ for (const idx of sorted) {
105
+ if (idx >= 0 && idx < content.images.length) {
106
+ content.images.splice(idx, 1);
107
+ }
108
+ }
96
109
  }
97
- else if ((args.images && Array.isArray(args.images)) ||
98
- args._remove_item_ids?.length) {
99
- // Update: id-based add / edit / move / remove in a single pass.
100
- mergeGalleryImages(content, args.images ?? [], args._remove_item_ids);
110
+ if (args.images && Array.isArray(args.images) && this.mode === 'update') {
111
+ insertGalleryImages(content, args.images);
101
112
  }
102
113
  return { request: this.request, model };
103
114
  }
@@ -3,15 +3,8 @@ import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
3
3
  import { applyScalarFields, applyStyleFields, isValidUrl, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
4
4
  import { BaseSectionBuilder } from './base-section-builder';
5
5
  import { validateImagesSection } from '../section-rules/images-section.rules';
6
- import { ensureItemIds, generateItemId, removeItemsByIds, repositionItemByAnchor, } from '../item-id-utils';
7
- /**
8
- * Full replacement: discard existing items and rebuild from the payload.
9
- * Assigns a stable `id` to each item; `itemsId` is set positionally here
10
- * but will be re-indexed at the end of buildAsync.
11
- */
12
6
  const applyImageItems = (content, items) => {
13
7
  content.items = items.map((item, index) => ({
14
- id: item.item_id || generateItemId(),
15
8
  imageUrl: isValidUrl(item.image_url) ? item.image_url : '',
16
9
  imageTitle: '',
17
10
  width: 0,
@@ -25,28 +18,16 @@ const applyImageItems = (content, items) => {
25
18
  colorReplacements: [],
26
19
  }));
27
20
  };
28
- /**
29
- * Apply a batch of item operations by id (BP-5603), mirroring the
30
- * section-level id-based contract one level deeper:
31
- * - item with `item_id` matching an existing item → update in place (and
32
- * reposition if `move_before_item_id` is set);
33
- * - item without `item_id` → add a new item,
34
- * positioned by `move_before_item_id`;
35
- * - `_remove_item_ids` → delete by id.
36
- *
37
- * Existing items are id-backfilled first so legacy sections become
38
- * referenceable the moment the metadata builder touches them.
39
- * Order-independent: there are no positional indices to shift between ops.
40
- */
41
- const mergeImageItems = (content, items, removeIds) => {
42
- ensureItemIds(content.items);
43
- content.items = removeItemsByIds(content.items, removeIds);
44
- for (const item of items) {
45
- if (item.item_id) {
46
- const existing = content.items.find((i) => i.id === item.item_id);
47
- // Unknown id — skip rather than guess at a position.
48
- if (!existing)
21
+ const mergeImageItems = (content, items, replaceAll) => {
22
+ const hasIndexedItems = items.some((item) => item.item_index !== undefined);
23
+ if (hasIndexedItems) {
24
+ for (const item of items) {
25
+ const targetIndex = item.item_index;
26
+ if (targetIndex === undefined ||
27
+ targetIndex < 0 ||
28
+ !content.items?.[targetIndex])
49
29
  continue;
30
+ const existing = content.items[targetIndex];
50
31
  if (isValidUrl(item.image_url))
51
32
  existing.imageUrl = item.image_url;
52
33
  if (item.heading !== undefined)
@@ -55,26 +36,36 @@ const mergeImageItems = (content, items, removeIds) => {
55
36
  existing.paragraph = item.text;
56
37
  if (item.button_text !== undefined)
57
38
  existing.buttonText = item.button_text || false;
58
- repositionItemByAnchor(content.items, existing, item.move_before_item_id);
59
- }
60
- else {
61
- const newItem = {
62
- id: generateItemId(),
63
- imageUrl: isValidUrl(item.image_url) ? item.image_url : '',
64
- imageTitle: '',
65
- width: 0,
66
- height: 0,
67
- mediaType: 'image',
68
- imageLink: '',
69
- title: item.heading ?? '',
70
- paragraph: item.text ?? '',
71
- buttonText: item.button_text || false,
72
- itemsId: 0, // re-indexed at the end of buildAsync
73
- colorReplacements: [],
74
- };
75
- repositionItemByAnchor(content.items, newItem, item.move_before_item_id);
76
39
  }
40
+ return;
41
+ }
42
+ const itemsToMerge = items.filter((item) => item.insert_at === undefined);
43
+ const updatedItems = itemsToMerge.map((item, index) => {
44
+ const existing = content.items?.[index];
45
+ return {
46
+ ...(existing || {}),
47
+ imageUrl: isValidUrl(item.image_url)
48
+ ? item.image_url
49
+ : (existing?.imageUrl ?? ''),
50
+ imageTitle: existing?.imageTitle ?? '',
51
+ width: existing?.width ?? 0,
52
+ height: existing?.height ?? 0,
53
+ mediaType: existing?.mediaType ?? 'image',
54
+ imageLink: existing?.imageLink ?? '',
55
+ title: item.heading ?? existing?.title ?? '',
56
+ paragraph: item.text ?? existing?.paragraph ?? '',
57
+ buttonText: item.button_text ?? existing?.buttonText ?? '',
58
+ itemsId: existing?.itemsId ?? index,
59
+ colorReplacements: existing?.colorReplacements ?? [],
60
+ };
61
+ });
62
+ if (!replaceAll &&
63
+ content.items &&
64
+ content.items.length > itemsToMerge.length) {
65
+ const remaining = content.items.slice(itemsToMerge.length);
66
+ updatedItems.push(...remaining);
77
67
  }
68
+ content.items = updatedItems;
78
69
  };
79
70
  export class ImagesSectionBuilder extends BaseSectionBuilder {
80
71
  get sectionValidate() {
@@ -132,22 +123,66 @@ export class ImagesSectionBuilder extends BaseSectionBuilder {
132
123
  ])),
133
124
  };
134
125
  }
135
- if (args._replace_items && args.items && Array.isArray(args.items)) {
136
- // Full replacement: discard existing items and rebuild from the payload.
137
- applyImageItems(content, args.items);
138
- }
139
- else if (this.mode === 'create') {
140
- if (args.items && Array.isArray(args.items)) {
126
+ if (args.items && Array.isArray(args.items)) {
127
+ if (this.mode === 'create') {
141
128
  applyImageItems(content, args.items);
142
129
  }
130
+ else {
131
+ mergeImageItems(content, args.items, !!args._replace_items);
132
+ }
143
133
  }
144
- else if ((args.items && Array.isArray(args.items)) ||
145
- args._remove_item_ids?.length) {
146
- // Update: id-based add / edit / move / remove in a single pass.
147
- mergeImageItems(content, args.items ?? [], args._remove_item_ids);
134
+ // Phase 2: Item operations (remove, insert, reorder)
135
+ if (args._remove_item_indices?.length && content.items) {
136
+ const sorted = [...args._remove_item_indices].sort((a, b) => b - a);
137
+ for (const idx of sorted) {
138
+ if (idx >= 0 && idx < content.items.length) {
139
+ content.items.splice(idx, 1);
140
+ }
141
+ }
142
+ }
143
+ if (args.items && Array.isArray(args.items)) {
144
+ const insertItems = args.items.filter((item) => item.insert_at !== undefined && item.item_index === undefined);
145
+ // Process inserts in reverse order of insert_at to preserve indices
146
+ const sortedInserts = [...insertItems].sort((a, b) => (b.insert_at ?? 0) - (a.insert_at ?? 0));
147
+ for (const item of sortedInserts) {
148
+ if (!isValidUrl(item.image_url))
149
+ continue;
150
+ // Skip if this image_url already exists — defensive against duplicate
151
+ // tool call application
152
+ if (content.items?.some((existing) => existing.imageUrl === item.image_url)) {
153
+ continue;
154
+ }
155
+ const pos = Math.max(0, Math.min(item.insert_at ?? 0, content.items?.length ?? 0));
156
+ const newItem = {
157
+ imageUrl: item.image_url,
158
+ imageTitle: '',
159
+ width: 0,
160
+ height: 0,
161
+ mediaType: 'image',
162
+ imageLink: '',
163
+ title: item.heading ?? '',
164
+ paragraph: item.text ?? '',
165
+ buttonText: item.button_text || '',
166
+ itemsId: pos,
167
+ colorReplacements: [],
168
+ };
169
+ content.items = content.items ?? [];
170
+ content.items.splice(pos, 0, newItem);
171
+ }
172
+ }
173
+ if (args._reorder_items?.length && content.items) {
174
+ const newOrder = args._reorder_items;
175
+ const unique = new Set(newOrder);
176
+ if (unique.size === newOrder.length) {
177
+ const reordered = newOrder
178
+ .filter((idx) => idx >= 0 && idx < content.items.length)
179
+ .map((idx) => content.items[idx]);
180
+ if (reordered.length === content.items.length) {
181
+ content.items = reordered;
182
+ }
183
+ }
148
184
  }
149
- // Re-index itemsId after all id-based item operations (render concern —
150
- // separate from the stable `id` used for targeting).
185
+ // Re-index itemsId after any item operations
151
186
  if (content.items) {
152
187
  content.items.forEach((item, i) => {
153
188
  item.itemsId = i;