@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.
- package/lib/src/{CreatedOnBrandCrowd-de-de-CJZpKPNH.js → CreatedOnBrandCrowd-de-de-xmkupPus.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-DkIa7iEb.js → CreatedOnBrandCrowd-en-us-Ck7EdTtb.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-CE2p6XHz.js → CreatedOnBrandCrowd-es-es-BC8sJuDH.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-BBjOZS3M.js → CreatedOnBrandCrowd-fr-ca-CN-UBe1q.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-BBjOZS3M.js → CreatedOnBrandCrowd-fr-fr-CN-UBe1q.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-Dayzl4BZ.js → CreatedOnBrandCrowd-pt-br-CajQyNkx.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-Dayzl4BZ.js → CreatedOnBrandCrowd-pt-pt-CajQyNkx.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-CFzDqfCb.js → CreatedOnDcom-de-de-BRCNMmDq.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-C2jIPBDY.js → CreatedOnDcom-en-us-BzQDtZhc.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-qejpzqho.js → CreatedOnDcom-es-es-D-qAM4Cd.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-DMO9Ld7K.js → CreatedOnDcom-fr-ca-CZ1irFOc.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-BFWN9qTP.js → CreatedOnDcom-fr-fr-Gb5BCF0N.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-CneD3ghF.js → CreatedOnDcom-pt-br-CAQV0q6o.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-Cg1B7s0o.js → CreatedOnDcom-pt-pt-D6tQdQFh.js} +1 -1
- package/lib/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.js +2 -2
- package/lib/src/brand-page/models/brand-page-context.model.d.ts +0 -2
- package/lib/src/brand-page/models/brand-page-context.model.js +1 -11
- package/lib/src/brand-page/models/index.d.ts +1 -0
- package/lib/src/brand-page/models/index.js +1 -0
- package/lib/src/brand-page/utils/color.util.js +23 -3
- package/lib/src/brand-page/utils/raygun.util.d.ts +5 -1
- package/lib/src/brand-page/utils/raygun.util.js +7 -2
- package/lib/src/brand-page/utils/svg-color.util.js +1 -2
- package/lib/src/brand-page/utils/view-model.util.js +1 -1
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -31
- package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +0 -2
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +2 -31
- package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +0 -14
- package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +0 -28
- package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.d.ts +35 -0
- package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.js +108 -0
- package/lib/src/brand-page-maker/composables/ai-chat/{useAiChat.d.ts → types.d.ts} +5 -13
- package/lib/src/brand-page-maker/composables/ai-chat/types.js +1 -0
- package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +19 -0
- package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +1 -0
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +488 -82
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +5 -5
- package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +6 -16
- package/lib/src/brand-page-maker/composables/useEventTracker.js +19 -21
- package/lib/src/brand-page-maker/constants/sidebar-constant.d.ts +0 -1
- package/lib/src/brand-page-maker/constants/sidebar-constant.js +7 -15
- package/lib/src/brand-page-maker/convertors/image-aspect-ratio.convertor.js +2 -2
- package/lib/src/brand-page-maker/convertors/text-size-value.convertor.js +3 -1
- package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +30660 -0
- package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.js +34 -0
- package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +1 -1
- package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +0 -28
- package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +42 -2
- package/lib/src/brand-page-maker/stores/index.d.ts +1 -1
- package/lib/src/brand-page-maker/stores/index.js +1 -1
- package/lib/src/brand-page-maker/stores/user/user-store.js +0 -1
- package/lib/src/bundled-translations-CnareLWC.js +175 -0
- package/lib/src/bundled-translations.de-DE-2Ys7epLO.js +175 -0
- package/lib/src/bundled-translations.es-ES-Cjp-G8rT.js +175 -0
- package/lib/src/bundled-translations.fr-CA-CsaW4Oae.js +175 -0
- package/lib/src/bundled-translations.fr-FR-DIT2dd8J.js +175 -0
- package/lib/src/bundled-translations.pt-BR-BamoBpDW.js +175 -0
- package/lib/src/bundled-translations.pt-PT-C9A4hY_e.js +175 -0
- package/lib/src/bundles/bundled-translations.de-DE.json +1 -20
- package/lib/src/bundles/bundled-translations.es-ES.json +1 -20
- package/lib/src/bundles/bundled-translations.fr-CA.json +1 -20
- package/lib/src/bundles/bundled-translations.fr-FR.json +1 -20
- package/lib/src/bundles/bundled-translations.json +1 -20
- package/lib/src/bundles/bundled-translations.pt-BR.json +1 -20
- package/lib/src/bundles/bundled-translations.pt-PT.json +1 -20
- package/lib/src/clients/ai-assistant-client.d.ts +30 -29
- package/lib/src/clients/ai-assistant-client.js +16 -16
- package/lib/src/clients/design-template-client.d.ts +0 -2
- package/lib/src/clients/design-template-client.js +0 -38
- package/lib/src/clients/websocket-gateway-client.d.ts +9 -1
- package/lib/src/composables/useTranslate.d.ts +2 -1
- package/lib/src/composables/useTranslate.js +2 -1
- package/lib/src/constants/ui.d.ts +0 -1
- package/lib/src/css/library.brand-page-brandCrowd.min.css +225 -134
- package/lib/src/css/library.brand-page-brandPage.min.css +227 -121
- package/lib/src/css/library.brand-page-designCom.min.css +225 -134
- package/lib/src/css/library.brand-page-preview.min.css +225 -118
- package/lib/src/index.d.ts +1 -1
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-33w_DBny.js → lib-CSRUPpSo.js} +30887 -29395
- package/lib/src/metadata-builder/ai-metadata-executor.d.ts +21 -0
- package/lib/src/metadata-builder/ai-metadata-executor.js +56 -3
- package/lib/src/metadata-builder/builders/add-page-builder.d.ts +2 -4
- package/lib/src/metadata-builder/builders/add-page-builder.js +5 -8
- package/lib/src/metadata-builder/builders/footer-builder.d.ts +11 -0
- package/lib/src/metadata-builder/builders/footer-builder.js +151 -0
- package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +15 -0
- package/lib/src/metadata-builder/builders/global-styles-builder.js +129 -0
- package/lib/src/metadata-builder/builders/header-builder.d.ts +11 -0
- package/lib/src/metadata-builder/builders/header-builder.js +167 -0
- package/lib/src/metadata-builder/builders/rename-page-builder.d.ts +12 -0
- package/lib/src/metadata-builder/builders/rename-page-builder.js +49 -0
- package/lib/src/metadata-builder/builders/section-builders/about-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +44 -4
- package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +70 -6
- package/lib/src/metadata-builder/builders/section-builders/base-section-builder.d.ts +36 -4
- package/lib/src/metadata-builder/builders/section-builders/base-section-builder.js +102 -12
- package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.d.ts +8 -0
- package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +50 -0
- package/lib/src/metadata-builder/builders/section-builders/button-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/button-section-builder.js +5 -1
- package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +47 -3
- package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.d.ts +2 -1
- package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.js +5 -2
- package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.js +11 -1
- package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +52 -13
- package/lib/src/metadata-builder/builders/section-builders/images-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +47 -17
- package/lib/src/metadata-builder/builders/section-builders/index.d.ts +1 -0
- package/lib/src/metadata-builder/builders/section-builders/index.js +1 -0
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +20 -2
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +20 -2
- package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +36 -2
- package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +70 -27
- package/lib/src/metadata-builder/builders/section-builders/social-links-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +7 -2
- package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +91 -26
- package/lib/src/metadata-builder/builders/section-builders/text-section-builder.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +69 -31
- package/lib/src/metadata-builder/builders/section-content-factory.d.ts +2 -2
- package/lib/src/metadata-builder/builders/section-content-factory.js +8 -2
- package/lib/src/metadata-builder/builders/section-field-maps.js +30 -2
- package/lib/src/metadata-builder/builders/section-field-utils.d.ts +46 -7
- package/lib/src/metadata-builder/builders/section-field-utils.js +86 -62
- package/lib/src/metadata-builder/builders/section-rules/about-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/about-section.rules.js +20 -0
- package/lib/src/metadata-builder/builders/section-rules/add-page.rules.d.ts +7 -0
- package/lib/src/metadata-builder/builders/section-rules/add-page.rules.js +8 -0
- package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/banner-section.rules.js +27 -0
- package/lib/src/metadata-builder/builders/section-rules/booking-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/booking-section.rules.js +16 -0
- package/lib/src/metadata-builder/builders/section-rules/button-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/button-section.rules.js +13 -0
- package/lib/src/metadata-builder/builders/section-rules/contact-form.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/contact-form.rules.js +16 -0
- package/lib/src/metadata-builder/builders/section-rules/divider-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/divider-section.rules.js +7 -0
- package/lib/src/metadata-builder/builders/section-rules/footer.rules.d.ts +4 -0
- package/lib/src/metadata-builder/builders/section-rules/footer.rules.js +5 -0
- package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.d.ts +6 -0
- package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.js +26 -0
- package/lib/src/metadata-builder/builders/section-rules/header.rules.d.ts +4 -0
- package/lib/src/metadata-builder/builders/section-rules/header.rules.js +41 -0
- package/lib/src/metadata-builder/builders/section-rules/image-gallery.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/image-gallery.rules.js +10 -0
- package/lib/src/metadata-builder/builders/section-rules/images-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/images-section.rules.js +31 -0
- package/lib/src/metadata-builder/builders/section-rules/mailing-list.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/mailing-list.rules.js +11 -0
- package/lib/src/metadata-builder/builders/section-rules/profile.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/profile.rules.js +14 -0
- package/lib/src/metadata-builder/builders/section-rules/rename-page.rules.d.ts +7 -0
- package/lib/src/metadata-builder/builders/section-rules/rename-page.rules.js +8 -0
- package/lib/src/metadata-builder/builders/section-rules/shapes-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/shapes-section.rules.js +27 -0
- package/lib/src/metadata-builder/builders/section-rules/social-links.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/social-links.rules.js +9 -0
- package/lib/src/metadata-builder/builders/section-rules/testimonial-section.rules.d.ts +7 -0
- package/lib/src/metadata-builder/builders/section-rules/testimonial-section.rules.js +26 -0
- package/lib/src/metadata-builder/builders/section-rules/text-section.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/text-section.rules.js +14 -0
- package/lib/src/metadata-builder/builders/shape-color-utils.d.ts +26 -0
- package/lib/src/metadata-builder/builders/shape-color-utils.js +52 -0
- package/lib/src/metadata-builder/builders/undo-builder.d.ts +48 -0
- package/lib/src/metadata-builder/builders/undo-builder.js +58 -0
- package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +5 -1
- package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +15 -4
- package/lib/src/metadata-builder/helpers/rte.helpers.js +24 -10
- package/lib/src/metadata-builder/metadata-executor.d.ts +2 -1
- package/lib/src/metadata-builder/metadata-executor.js +32 -5
- package/lib/src/metadata-builder/models.d.ts +26 -1
- package/lib/src/metadata-builder/models.js +14 -1
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +144 -0
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +17 -0
- package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +113 -24
- package/lib/src/metadata-builder/parsers/section-tool-arguments.js +5 -1
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.d.ts +22 -0
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +84 -0
- package/lib/src/metadata-builder/sanitizers/sanitizer-rules.d.ts +47 -0
- package/lib/src/metadata-builder/sanitizers/sanitizer-rules.js +60 -0
- package/lib/src/metadata-builder/sanitizers/section-args-validator.d.ts +41 -0
- package/lib/src/metadata-builder/sanitizers/section-args-validator.js +274 -0
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +2 -1
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +2 -16
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.stories.js +0 -1
- package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +2 -1
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +2 -3
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +0 -4
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +6 -8
- package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +0 -28
- package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +2 -1
- package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +0 -28
- package/lib/src/shared/navigation-style-settings/store/index.js +1 -0
- package/lib/src/shared/page-navigation/store/page-navigation-store.js +1 -20
- package/lib/src/shared/page-navigation/utils/nav-order-utils.d.ts +3 -0
- package/lib/src/shared/page-navigation/utils/nav-order-utils.js +20 -0
- package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -30
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +0 -28
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +2 -43
- package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +0 -30
- package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +2 -3
- package/lib/src/shared/side-bar/store/side-bar-store.d.ts +0 -12
- package/lib/src/shared/side-bar/store/side-bar-store.js +0 -7
- package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +2 -29
- package/lib/src/shared/template-settings/components/TemplatesSettings.mixin.d.ts +2 -1
- package/lib/src/utils/build-asset-manifest.d.ts +26 -0
- package/lib/src/utils/build-asset-manifest.js +114 -0
- package/lib/src/utils/minify-brand-page-metadata.d.ts +49 -1
- package/lib/src/utils/minify-brand-page-metadata.js +216 -129
- package/package.json +1 -1
- package/src/brand-page/components/banner-section/BannerSection.vue +1 -1
- package/src/brand-page/components/contact-form/ContactForm.vue +29 -26
- package/src/brand-page/components/image-gallery/ImageGalleryModal.mixin.ts +6 -2
- package/src/brand-page/components/text-media-section/TextMediaSection.vue +1 -5
- package/src/brand-page/models/brand-page-context.model.ts +1 -25
- package/src/brand-page/models/index.ts +1 -0
- package/src/brand-page/utils/color.util.test.ts +48 -0
- package/src/brand-page/utils/color.util.ts +29 -4
- package/src/brand-page/utils/raygun.util.ts +11 -2
- package/src/brand-page/utils/svg-color.util.ts +1 -3
- package/src/brand-page/utils/view-model.util.ts +1 -4
- package/src/brand-page-maker/components/ai-text-edit/AiChatbox.vue +2 -2
- package/src/brand-page-maker/components/ai-text-edit/AiProgressFeed.vue +162 -0
- package/src/brand-page-maker/components/ai-text-edit/TextBubble.vue +57 -5
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.de-DE.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.es-ES.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.fr-CA.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.fr-FR.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.pt-BR.json +0 -20
- package/src/brand-page-maker/components/ai-text-edit/i18n/generate-ai.pt-PT.json +0 -20
- package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +1 -2
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.de-DE.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.es-ES.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.fr-CA.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.fr-FR.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.pt-BR.json +3 -0
- package/src/brand-page-maker/components/ai-website-builder/i18n/ai-website-builder.pt-PT.json +3 -0
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +3 -28
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -2
- package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.test.ts +229 -0
- package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.ts +164 -0
- package/src/brand-page-maker/composables/ai-chat/types.ts +49 -0
- package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +20 -0
- package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +651 -94
- package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +9 -9
- package/src/brand-page-maker/composables/useEventTracker.ts +31 -25
- package/src/brand-page-maker/constants/sidebar-constant.ts +7 -15
- package/src/brand-page-maker/convertors/image-aspect-ratio.convertor.ts +2 -2
- package/src/brand-page-maker/convertors/text-size-value.convertor.ts +3 -3
- package/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.ts +54 -0
- package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +76 -0
- package/src/brand-page-maker/stores/index.ts +1 -1
- package/src/brand-page-maker/stores/user/user-store.ts +0 -1
- package/src/bundles/bundled-translations.de-DE.json +1 -20
- package/src/bundles/bundled-translations.es-ES.json +1 -20
- package/src/bundles/bundled-translations.fr-CA.json +1 -20
- package/src/bundles/bundled-translations.fr-FR.json +1 -20
- package/src/bundles/bundled-translations.json +1 -20
- package/src/bundles/bundled-translations.pt-BR.json +1 -20
- package/src/bundles/bundled-translations.pt-PT.json +1 -20
- package/src/clients/ai-assistant-client.ts +59 -46
- package/src/clients/design-template-client.ts +0 -66
- package/src/clients/websocket-gateway-client.ts +17 -1
- package/src/composables/useTranslate.ts +3 -0
- package/src/constants/ui.ts +0 -1
- package/src/lib.ts +1 -0
- package/src/metadata-builder/ai-metadata-executor.ts +94 -1
- package/src/metadata-builder/builders/add-page-builder.ts +9 -13
- package/src/metadata-builder/builders/footer-builder.test.ts +76 -0
- package/src/metadata-builder/builders/footer-builder.ts +226 -0
- package/src/metadata-builder/builders/global-styles-builder.ts +187 -0
- package/src/metadata-builder/builders/header-builder.test.ts +106 -0
- package/src/metadata-builder/builders/header-builder.ts +254 -0
- package/src/metadata-builder/builders/rename-page-builder.ts +79 -0
- package/src/metadata-builder/builders/section-builders/about-section-builder.ts +73 -5
- package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +112 -7
- package/src/metadata-builder/builders/section-builders/base-section-builder.ts +149 -11
- package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +87 -0
- package/src/metadata-builder/builders/section-builders/button-section-builder.ts +6 -1
- package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +74 -4
- package/src/metadata-builder/builders/section-builders/delete-section-builder.ts +15 -1
- package/src/metadata-builder/builders/section-builders/divider-section-builder.ts +13 -1
- package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +91 -31
- package/src/metadata-builder/builders/section-builders/images-section-builder.ts +102 -48
- package/src/metadata-builder/builders/section-builders/index.ts +1 -0
- package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +38 -2
- package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +38 -2
- package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +55 -3
- package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +170 -77
- package/src/metadata-builder/builders/section-builders/social-links-builder.test.ts +119 -0
- package/src/metadata-builder/builders/section-builders/social-links-builder.ts +13 -2
- package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +178 -57
- package/src/metadata-builder/builders/section-builders/text-section-builder.ts +130 -30
- package/src/metadata-builder/builders/section-content-factory.ts +15 -2
- package/src/metadata-builder/builders/section-field-maps.ts +34 -1
- package/src/metadata-builder/builders/section-field-utils.ts +131 -72
- package/src/metadata-builder/builders/section-rules/about-section.rules.ts +38 -0
- package/src/metadata-builder/builders/section-rules/add-page.rules.ts +17 -0
- package/src/metadata-builder/builders/section-rules/banner-section.rules.ts +49 -0
- package/src/metadata-builder/builders/section-rules/booking-section.rules.ts +34 -0
- package/src/metadata-builder/builders/section-rules/button-section.rules.ts +22 -0
- package/src/metadata-builder/builders/section-rules/contact-form.rules.ts +30 -0
- package/src/metadata-builder/builders/section-rules/divider-section.rules.ts +17 -0
- package/src/metadata-builder/builders/section-rules/footer.rules.ts +21 -0
- package/src/metadata-builder/builders/section-rules/global-styles.rules.ts +44 -0
- package/src/metadata-builder/builders/section-rules/header.rules.ts +75 -0
- package/src/metadata-builder/builders/section-rules/image-gallery.rules.ts +22 -0
- package/src/metadata-builder/builders/section-rules/images-section.rules.ts +55 -0
- package/src/metadata-builder/builders/section-rules/mailing-list.rules.ts +21 -0
- package/src/metadata-builder/builders/section-rules/profile.rules.ts +27 -0
- package/src/metadata-builder/builders/section-rules/rename-page.rules.ts +17 -0
- package/src/metadata-builder/builders/section-rules/shapes-section.rules.ts +51 -0
- package/src/metadata-builder/builders/section-rules/social-links.rules.ts +27 -0
- package/src/metadata-builder/builders/section-rules/testimonial-section.rules.ts +48 -0
- package/src/metadata-builder/builders/section-rules/text-section.rules.ts +28 -0
- package/src/metadata-builder/builders/shape-color-utils.test.ts +115 -0
- package/src/metadata-builder/builders/shape-color-utils.ts +75 -0
- package/src/metadata-builder/builders/undo-builder.ts +105 -0
- package/src/metadata-builder/builders/update-content-text-style-builder.ts +4 -1
- package/src/metadata-builder/helpers/rte.helpers.ts +27 -13
- package/src/metadata-builder/metadata-executor.ts +42 -2
- package/src/metadata-builder/models.ts +39 -1
- package/src/metadata-builder/parsers/ai-toolcall-parser.ts +152 -0
- package/src/metadata-builder/parsers/section-tool-arguments.ts +138 -24
- package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +659 -0
- package/src/metadata-builder/sanitizers/rte-schema-check.ts +99 -0
- package/src/metadata-builder/sanitizers/sanitizer-rules.ts +97 -0
- package/src/metadata-builder/sanitizers/section-args-validator.ts +445 -0
- package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +10 -16
- package/src/shared/content-settings/components/content-settings/ContentSettings.stories.ts +0 -1
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +6 -10
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.vue +1 -23
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +0 -15
- package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +0 -15
- package/src/shared/navigation-style-settings/store/index.ts +5 -0
- package/src/shared/page-navigation/store/page-navigation-store.ts +4 -31
- package/src/shared/page-navigation/utils/nav-order-utils.ts +32 -0
- package/src/shared/side-bar/components/SideBar.vue +14 -1
- package/src/shared/side-bar/store/side-bar-store.ts +0 -20
- package/src/utils/build-asset-manifest.ts +153 -0
- package/src/utils/minify-brand-page-metadata.ts +362 -130
- package/lib/src/brand-page-maker/composables/ai-chat/useAiChat.js +0 -368
- package/lib/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.d.ts +0 -18
- package/lib/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.js +0 -144
- package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.d.ts +0 -155
- package/lib/src/brand-page-maker/stores/ai-thread/ai-thread-store.js +0 -25
- package/lib/src/brand-page-maker/utils/mixpanel.util.d.ts +0 -1
- package/lib/src/brand-page-maker/utils/mixpanel.util.js +0 -29
- package/lib/src/bundled-translations-CNK7l6_v.js +0 -173
- package/lib/src/bundled-translations.de-DE-BLE4_y0H.js +0 -173
- package/lib/src/bundled-translations.es-ES-thO9osbg.js +0 -173
- package/lib/src/bundled-translations.fr-CA-BZkhiNgU.js +0 -173
- package/lib/src/bundled-translations.fr-FR-bhDLPKgZ.js +0 -173
- package/lib/src/bundled-translations.pt-BR-CI9a5Bq1.js +0 -173
- package/lib/src/bundled-translations.pt-PT-DBoErBaq.js +0 -173
- package/src/brand-page-maker/components/ai-text-edit/AiTextEdit.vue +0 -154
- package/src/brand-page-maker/composables/ai-chat/useAiChat.ts +0 -562
- package/src/brand-page-maker/composables/ai-chat/useAiTextEditPrompts.ts +0 -196
- package/src/brand-page-maker/stores/ai-thread/ai-thread-store.ts +0 -31
- package/src/brand-page-maker/utils/mixpanel.util.ts +0 -42
- package/src/shared/content-settings/components/generate-ai-button/GenerateAiButton.vue +0 -114
- package/src/shared/content-settings/components/generate-ai-modal/GenerateAiModal.vue +0 -761
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { HEADER_DISPLAY_STYLE_CONFIGS } from '../../../brand-page/constants/sections/header-display.constants';
|
|
2
|
+
import type { UpdateHeaderArguments } from '../../parsers/ai-toolcall-parser';
|
|
3
|
+
import { validateLogoSize } from '../../sanitizers/section-args-validator';
|
|
4
|
+
import { PAGE_RULES, STYLE_RULES } from '../../sanitizers/sanitizer-rules';
|
|
5
|
+
|
|
6
|
+
type HeaderCheck = (args: UpdateHeaderArguments) => string | null;
|
|
7
|
+
|
|
8
|
+
export const HEADER_CHECKS: HeaderCheck[] = [
|
|
9
|
+
// Display style + nav type compatibility per viewport
|
|
10
|
+
...(['desktop', 'mobile'] as const).map(
|
|
11
|
+
(viewport): HeaderCheck =>
|
|
12
|
+
(args) => {
|
|
13
|
+
const overrides = args[viewport];
|
|
14
|
+
|
|
15
|
+
if (!overrides?.nav_display_type || !overrides?.display_style)
|
|
16
|
+
return null;
|
|
17
|
+
|
|
18
|
+
const compatible = HEADER_DISPLAY_STYLE_CONFIGS.some(
|
|
19
|
+
(c) =>
|
|
20
|
+
c.option.value === overrides.display_style &&
|
|
21
|
+
c.supportedNavTypes.includes(overrides.nav_display_type!),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return compatible
|
|
25
|
+
? null
|
|
26
|
+
: `Incompatible ${viewport} combination: display_style "${overrides.display_style}" is not compatible with nav_display_type "${overrides.nav_display_type}".`;
|
|
27
|
+
},
|
|
28
|
+
),
|
|
29
|
+
|
|
30
|
+
// Nav link font per viewport
|
|
31
|
+
...(['desktop', 'mobile'] as const).map(
|
|
32
|
+
(viewport): HeaderCheck =>
|
|
33
|
+
(args) => {
|
|
34
|
+
const font = args[viewport]?.link_text_font;
|
|
35
|
+
|
|
36
|
+
if (font == null) return null;
|
|
37
|
+
|
|
38
|
+
return !STYLE_RULES.fontFamilyNames.has(font)
|
|
39
|
+
? `"${viewport}.link_text_font" "${font}" is not a recognized font family`
|
|
40
|
+
: null;
|
|
41
|
+
},
|
|
42
|
+
),
|
|
43
|
+
|
|
44
|
+
// Logo sizes per viewport
|
|
45
|
+
...(['desktop', 'mobile'] as const).flatMap((viewport): HeaderCheck[] => [
|
|
46
|
+
(args) =>
|
|
47
|
+
validateLogoSize(
|
|
48
|
+
`${viewport}.logo_image_height`,
|
|
49
|
+
args[viewport]?.logo_image_height,
|
|
50
|
+
viewport,
|
|
51
|
+
),
|
|
52
|
+
(args) =>
|
|
53
|
+
validateLogoSize(
|
|
54
|
+
`${viewport}.logo_image_width`,
|
|
55
|
+
args[viewport]?.logo_image_width,
|
|
56
|
+
viewport,
|
|
57
|
+
),
|
|
58
|
+
]),
|
|
59
|
+
|
|
60
|
+
// Nav route display name length (returns first violation — retry loop handles the rest)
|
|
61
|
+
(args) => {
|
|
62
|
+
for (let i = 0; i < (args.nav_routes ?? []).length; i++) {
|
|
63
|
+
const displayName = args.nav_routes![i].display_name;
|
|
64
|
+
|
|
65
|
+
if (
|
|
66
|
+
displayName != null &&
|
|
67
|
+
displayName.length > PAGE_RULES.navDisplayName
|
|
68
|
+
) {
|
|
69
|
+
return `nav_routes[${i}].display_name exceeds the maximum length of ${PAGE_RULES.navDisplayName} characters (got ${displayName.length})`;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return null;
|
|
74
|
+
},
|
|
75
|
+
];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MAX_TITLE_LENGTH } from '../../../brand-page/constants/font.constants';
|
|
2
|
+
import {
|
|
3
|
+
enumCheck,
|
|
4
|
+
itemRteStyleCheck,
|
|
5
|
+
itemTextCheck,
|
|
6
|
+
runChecks,
|
|
7
|
+
type SectionCheck,
|
|
8
|
+
type ValidationContext,
|
|
9
|
+
} from '../../sanitizers/section-args-validator';
|
|
10
|
+
|
|
11
|
+
const CHECKS: SectionCheck[] = [
|
|
12
|
+
itemTextCheck('images', 'caption', MAX_TITLE_LENGTH),
|
|
13
|
+
itemRteStyleCheck('images', 'caption'),
|
|
14
|
+
enumCheck('gallery_type', ['grid', 'carousel', 'masonry'], 'image-gallery'),
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
export function validateImageGallery(
|
|
18
|
+
args: Record<string, unknown>,
|
|
19
|
+
ctx: ValidationContext,
|
|
20
|
+
): string[] {
|
|
21
|
+
return runChecks(CHECKS, args, ctx);
|
|
22
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_TITLE_LENGTH,
|
|
3
|
+
MAX_DESCRIPTION_LENGTH,
|
|
4
|
+
} from '../../../brand-page/constants/font.constants';
|
|
5
|
+
import { ASPECT_RATIOS } from '../../../brand-page/models';
|
|
6
|
+
import {
|
|
7
|
+
enumCheck,
|
|
8
|
+
itemCapCheck,
|
|
9
|
+
itemRteStyleCheck,
|
|
10
|
+
itemTextCheck,
|
|
11
|
+
runChecks,
|
|
12
|
+
styleCheck,
|
|
13
|
+
type SectionCheck,
|
|
14
|
+
type ValidationContext,
|
|
15
|
+
} from '../../sanitizers/section-args-validator';
|
|
16
|
+
import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
|
|
17
|
+
|
|
18
|
+
const CHECKS: SectionCheck[] = [
|
|
19
|
+
...textAndRteChecks('title', MAX_TITLE_LENGTH),
|
|
20
|
+
...textAndRteChecks('description', MAX_DESCRIPTION_LENGTH),
|
|
21
|
+
styleCheck('title_style'),
|
|
22
|
+
styleCheck('description_style'),
|
|
23
|
+
styleCheck('heading_style'),
|
|
24
|
+
styleCheck('paragraph_style'),
|
|
25
|
+
itemTextCheck('items', 'heading', MAX_TITLE_LENGTH),
|
|
26
|
+
itemRteStyleCheck('items', 'heading'),
|
|
27
|
+
itemTextCheck('items', 'text', MAX_DESCRIPTION_LENGTH),
|
|
28
|
+
itemRteStyleCheck('items', 'text'),
|
|
29
|
+
itemTextCheck('items', 'button_text', MAX_TITLE_LENGTH),
|
|
30
|
+
itemRteStyleCheck('items', 'button_text'),
|
|
31
|
+
enumCheck(
|
|
32
|
+
'display_style',
|
|
33
|
+
[
|
|
34
|
+
'left-aligned',
|
|
35
|
+
'right-aligned',
|
|
36
|
+
'centered',
|
|
37
|
+
'media-only',
|
|
38
|
+
'center-card-aligned-image',
|
|
39
|
+
'alternate-image',
|
|
40
|
+
],
|
|
41
|
+
'images-section',
|
|
42
|
+
),
|
|
43
|
+
enumCheck('aspect_ratio', Object.keys(ASPECT_RATIOS), 'images-section'),
|
|
44
|
+
itemCapCheck(
|
|
45
|
+
{ brandSite: 5, brandPage: 2, arrayField: 'items' },
|
|
46
|
+
'images-section',
|
|
47
|
+
),
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
export function validateImagesSection(
|
|
51
|
+
args: Record<string, unknown>,
|
|
52
|
+
ctx: ValidationContext,
|
|
53
|
+
): string[] {
|
|
54
|
+
return runChecks(CHECKS, args, ctx);
|
|
55
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { MAX_TITLE_LENGTH } from '../../../brand-page/constants/font.constants';
|
|
2
|
+
import {
|
|
3
|
+
enumCheck,
|
|
4
|
+
runChecks,
|
|
5
|
+
type SectionCheck,
|
|
6
|
+
type ValidationContext,
|
|
7
|
+
} from '../../sanitizers/section-args-validator';
|
|
8
|
+
import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
|
|
9
|
+
|
|
10
|
+
const CHECKS: SectionCheck[] = [
|
|
11
|
+
...textAndRteChecks('title', MAX_TITLE_LENGTH),
|
|
12
|
+
...textAndRteChecks('button_text', 25), // config-settings-constant.ts:1780 — field-specific limit
|
|
13
|
+
enumCheck('accepted_fields', ['emailOnly', 'nameAndEmail'], 'mailing-list'),
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export function validateMailingList(
|
|
17
|
+
args: Record<string, unknown>,
|
|
18
|
+
ctx: ValidationContext,
|
|
19
|
+
): string[] {
|
|
20
|
+
return runChecks(CHECKS, args, ctx);
|
|
21
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_TITLE_LENGTH,
|
|
3
|
+
MAX_DESCRIPTION_LENGTH,
|
|
4
|
+
} from '../../../brand-page/constants/font.constants';
|
|
5
|
+
import {
|
|
6
|
+
runChecks,
|
|
7
|
+
styleCheck,
|
|
8
|
+
type SectionCheck,
|
|
9
|
+
type ValidationContext,
|
|
10
|
+
} from '../../sanitizers/section-args-validator';
|
|
11
|
+
import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
|
|
12
|
+
|
|
13
|
+
const CHECKS: SectionCheck[] = [
|
|
14
|
+
...textAndRteChecks('name', MAX_TITLE_LENGTH),
|
|
15
|
+
...textAndRteChecks('title', MAX_TITLE_LENGTH),
|
|
16
|
+
...textAndRteChecks('description', MAX_DESCRIPTION_LENGTH),
|
|
17
|
+
styleCheck('name_style'),
|
|
18
|
+
styleCheck('title_style'),
|
|
19
|
+
styleCheck('description_style'),
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export function validateProfile(
|
|
23
|
+
args: Record<string, unknown>,
|
|
24
|
+
ctx: ValidationContext,
|
|
25
|
+
): string[] {
|
|
26
|
+
return runChecks(CHECKS, args, ctx);
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PAGE_RULES } from '../../sanitizers/sanitizer-rules';
|
|
2
|
+
|
|
3
|
+
export interface RenamePagePayload {
|
|
4
|
+
pageId: string;
|
|
5
|
+
pageName: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
type PageCheck = (payload: RenamePagePayload | undefined) => string | null;
|
|
9
|
+
|
|
10
|
+
export const RENAME_PAGE_CHECKS: PageCheck[] = [
|
|
11
|
+
(p) => (!p?.pageId ? 'page_id is required for rename_page' : null),
|
|
12
|
+
(p) => (!p?.pageName ? 'page_name is required for rename_page' : null),
|
|
13
|
+
(p) =>
|
|
14
|
+
p?.pageName && p.pageName.length > PAGE_RULES.pageName
|
|
15
|
+
? `page_name exceeds the maximum length of ${PAGE_RULES.pageName} characters (got ${p.pageName.length})`
|
|
16
|
+
: null,
|
|
17
|
+
];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_TITLE_LENGTH,
|
|
3
|
+
MAX_DESCRIPTION_LENGTH,
|
|
4
|
+
} from '../../../brand-page/constants/font.constants';
|
|
5
|
+
import {
|
|
6
|
+
enumCheck,
|
|
7
|
+
itemCapCheck,
|
|
8
|
+
itemRteStyleCheck,
|
|
9
|
+
itemTextCheck,
|
|
10
|
+
runChecks,
|
|
11
|
+
styleCheck,
|
|
12
|
+
type SectionCheck,
|
|
13
|
+
type ValidationContext,
|
|
14
|
+
} from '../../sanitizers/section-args-validator';
|
|
15
|
+
import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
|
|
16
|
+
|
|
17
|
+
const CHECKS: SectionCheck[] = [
|
|
18
|
+
...textAndRteChecks('title', MAX_TITLE_LENGTH),
|
|
19
|
+
...textAndRteChecks('description', MAX_DESCRIPTION_LENGTH),
|
|
20
|
+
styleCheck('title_style'),
|
|
21
|
+
styleCheck('description_style'),
|
|
22
|
+
styleCheck('heading_style'),
|
|
23
|
+
styleCheck('paragraph_style'),
|
|
24
|
+
itemTextCheck('items', 'heading', MAX_TITLE_LENGTH),
|
|
25
|
+
itemRteStyleCheck('items', 'heading'),
|
|
26
|
+
itemTextCheck('items', 'text', MAX_DESCRIPTION_LENGTH),
|
|
27
|
+
itemRteStyleCheck('items', 'text'),
|
|
28
|
+
enumCheck(
|
|
29
|
+
'display_style',
|
|
30
|
+
[
|
|
31
|
+
'left-aligned',
|
|
32
|
+
'right-aligned',
|
|
33
|
+
'centered',
|
|
34
|
+
'media-only',
|
|
35
|
+
'center-card-aligned-image',
|
|
36
|
+
'alternate-image',
|
|
37
|
+
],
|
|
38
|
+
'shapes-section',
|
|
39
|
+
),
|
|
40
|
+
itemCapCheck(
|
|
41
|
+
{ brandSite: 5, brandPage: 2, arrayField: 'items' },
|
|
42
|
+
'shapes-section',
|
|
43
|
+
),
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
export function validateShapesSection(
|
|
47
|
+
args: Record<string, unknown>,
|
|
48
|
+
ctx: ValidationContext,
|
|
49
|
+
): string[] {
|
|
50
|
+
return runChecks(CHECKS, args, ctx);
|
|
51
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SOCIAL_LINKS_ICON_DISPLAY_STYLES } from '../../../brand-page/models';
|
|
2
|
+
import {
|
|
3
|
+
enumCheck,
|
|
4
|
+
itemCapCheck,
|
|
5
|
+
runChecks,
|
|
6
|
+
type SectionCheck,
|
|
7
|
+
type ValidationContext,
|
|
8
|
+
} from '../../sanitizers/section-args-validator';
|
|
9
|
+
|
|
10
|
+
const CHECKS: SectionCheck[] = [
|
|
11
|
+
enumCheck(
|
|
12
|
+
'icon_style',
|
|
13
|
+
Object.keys(SOCIAL_LINKS_ICON_DISPLAY_STYLES),
|
|
14
|
+
'social-links',
|
|
15
|
+
),
|
|
16
|
+
itemCapCheck(
|
|
17
|
+
{ brandSite: 4, brandPage: 4, arrayField: 'links' },
|
|
18
|
+
'social-links',
|
|
19
|
+
),
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export function validateSocialLinks(
|
|
23
|
+
args: Record<string, unknown>,
|
|
24
|
+
ctx: ValidationContext,
|
|
25
|
+
): string[] {
|
|
26
|
+
return runChecks(CHECKS, args, ctx);
|
|
27
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_TITLE_LENGTH,
|
|
3
|
+
MAX_DESCRIPTION_LENGTH,
|
|
4
|
+
} from '../../../brand-page/constants/font.constants';
|
|
5
|
+
import {
|
|
6
|
+
enumCheck,
|
|
7
|
+
itemCapCheck,
|
|
8
|
+
itemRteStyleCheck,
|
|
9
|
+
itemTextCheck,
|
|
10
|
+
runChecks,
|
|
11
|
+
styleCheck,
|
|
12
|
+
type SectionCheck,
|
|
13
|
+
type ValidationContext,
|
|
14
|
+
} from '../../sanitizers/section-args-validator';
|
|
15
|
+
import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
|
|
16
|
+
|
|
17
|
+
export const TESTIMONIAL_ITEM_CAP = {
|
|
18
|
+
brandSite: 3,
|
|
19
|
+
brandPage: 3,
|
|
20
|
+
arrayField: 'items',
|
|
21
|
+
} as const;
|
|
22
|
+
|
|
23
|
+
const CHECKS: SectionCheck[] = [
|
|
24
|
+
...textAndRteChecks('title', MAX_TITLE_LENGTH),
|
|
25
|
+
styleCheck('title_style'),
|
|
26
|
+
styleCheck('testimonial_style'),
|
|
27
|
+
styleCheck('name_style'),
|
|
28
|
+
styleCheck('position_style'),
|
|
29
|
+
itemTextCheck('items', 'testimonial', MAX_DESCRIPTION_LENGTH),
|
|
30
|
+
itemRteStyleCheck('items', 'testimonial'),
|
|
31
|
+
itemTextCheck('items', 'name', MAX_TITLE_LENGTH),
|
|
32
|
+
itemRteStyleCheck('items', 'name'),
|
|
33
|
+
itemTextCheck('items', 'position', MAX_TITLE_LENGTH),
|
|
34
|
+
itemRteStyleCheck('items', 'position'),
|
|
35
|
+
enumCheck(
|
|
36
|
+
'display_style',
|
|
37
|
+
['centered', 'big-image', 'columns'],
|
|
38
|
+
'testimonial-section',
|
|
39
|
+
),
|
|
40
|
+
itemCapCheck(TESTIMONIAL_ITEM_CAP, 'testimonial-section'),
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
export function validateTestimonialSection(
|
|
44
|
+
args: Record<string, unknown>,
|
|
45
|
+
ctx: ValidationContext,
|
|
46
|
+
): string[] {
|
|
47
|
+
return runChecks(CHECKS, args, ctx);
|
|
48
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { MAX_TEXT_LENGTH } from '../../../brand-page/constants/font.constants';
|
|
2
|
+
import {
|
|
3
|
+
enumCheck,
|
|
4
|
+
itemRteStyleCheck,
|
|
5
|
+
itemStyleCheck,
|
|
6
|
+
itemTextCheck,
|
|
7
|
+
runChecks,
|
|
8
|
+
styleCheck,
|
|
9
|
+
type SectionCheck,
|
|
10
|
+
type ValidationContext,
|
|
11
|
+
} from '../../sanitizers/section-args-validator';
|
|
12
|
+
import { textAndRteChecks } from '../../sanitizers/rte-schema-check';
|
|
13
|
+
|
|
14
|
+
const CHECKS: SectionCheck[] = [
|
|
15
|
+
...textAndRteChecks('text', MAX_TEXT_LENGTH),
|
|
16
|
+
styleCheck('text_style'),
|
|
17
|
+
itemTextCheck('items', 'text', MAX_TEXT_LENGTH),
|
|
18
|
+
itemRteStyleCheck('items', 'text'),
|
|
19
|
+
itemStyleCheck('items', 'text_style'),
|
|
20
|
+
enumCheck('column_style', ['1', '2', '3', '4'], 'text'),
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export function validateTextSection(
|
|
24
|
+
args: Record<string, unknown>,
|
|
25
|
+
ctx: ValidationContext,
|
|
26
|
+
): string[] {
|
|
27
|
+
return runChecks(CHECKS, args, ctx);
|
|
28
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import type { ColorReplacement } from '../../brand-page/models';
|
|
3
|
+
import {
|
|
4
|
+
applyColorThemeToReplacements,
|
|
5
|
+
resolveShapeColorReplacementsAsync,
|
|
6
|
+
} from './shape-color-utils';
|
|
7
|
+
|
|
8
|
+
describe('shape-color-utils', () => {
|
|
9
|
+
describe('resolveShapeColorReplacementsAsync', () => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
vi.restoreAllMocks();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('returns [] for empty URL', async () => {
|
|
15
|
+
const result = await resolveShapeColorReplacementsAsync('');
|
|
16
|
+
|
|
17
|
+
expect(result).toEqual([]);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('returns [] for proxy URL without fetching', async () => {
|
|
21
|
+
const fetchSpy = vi.spyOn(global, 'fetch');
|
|
22
|
+
|
|
23
|
+
const result = await resolveShapeColorReplacementsAsync(
|
|
24
|
+
'https://example.com/asset/shape?id=123',
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
expect(result).toEqual([]);
|
|
28
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('fetches SVG and returns concrete identity-mapped entries per unique fill', async () => {
|
|
32
|
+
vi.spyOn(global, 'fetch').mockResolvedValueOnce({
|
|
33
|
+
ok: true,
|
|
34
|
+
text: async () => `<svg xmlns="http://www.w3.org/2000/svg">
|
|
35
|
+
<path style="fill: #111111" d="M10 10"/>
|
|
36
|
+
<path style="fill: #EEEEEE" d="M20 20"/>
|
|
37
|
+
</svg>`,
|
|
38
|
+
} as Response);
|
|
39
|
+
|
|
40
|
+
const result = await resolveShapeColorReplacementsAsync(
|
|
41
|
+
'https://shapes.com/icon.svg',
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const origs = result.map((r) => r.originalColor.toUpperCase());
|
|
45
|
+
|
|
46
|
+
expect(origs).toContain('#111111');
|
|
47
|
+
expect(origs).toContain('#EEEEEE');
|
|
48
|
+
// Identity-mapped: replacementColor equals originalColor (case-insensitive)
|
|
49
|
+
result.forEach((r) => {
|
|
50
|
+
expect(r.replacementColor.toLowerCase()).toBe(
|
|
51
|
+
r.originalColor.toLowerCase(),
|
|
52
|
+
);
|
|
53
|
+
expect(r.attribute).toBe('fill');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('throws on HTTP failure', async () => {
|
|
58
|
+
vi.spyOn(global, 'fetch').mockResolvedValueOnce({
|
|
59
|
+
ok: false,
|
|
60
|
+
status: 404,
|
|
61
|
+
} as Response);
|
|
62
|
+
|
|
63
|
+
await expect(
|
|
64
|
+
resolveShapeColorReplacementsAsync('https://shapes.com/missing.svg'),
|
|
65
|
+
).rejects.toThrow(/404/);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe('applyColorThemeToReplacements', () => {
|
|
70
|
+
it('returns [] for empty input', () => {
|
|
71
|
+
expect(applyColorThemeToReplacements([], '#1D4ED8')).toEqual([]);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('re-shades each entry preserving originalColor', () => {
|
|
75
|
+
const input: ColorReplacement[] = [
|
|
76
|
+
{
|
|
77
|
+
attribute: 'fill',
|
|
78
|
+
originalColor: '#808080',
|
|
79
|
+
replacementColor: '#808080',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
attribute: 'fill',
|
|
83
|
+
originalColor: '#333333',
|
|
84
|
+
replacementColor: '#333333',
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
const result = applyColorThemeToReplacements(input, '#1D4ED8');
|
|
89
|
+
|
|
90
|
+
expect(result).toHaveLength(2);
|
|
91
|
+
expect(result[0].originalColor).toBe('#808080');
|
|
92
|
+
expect(result[1].originalColor).toBe('#333333');
|
|
93
|
+
// replacementColor has been shifted — not equal to either original or raw theme
|
|
94
|
+
result.forEach((r, i) => {
|
|
95
|
+
expect(r.replacementColor).not.toBe(input[i].replacementColor);
|
|
96
|
+
expect(r.attribute).toBe('fill');
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('does not mutate the input array or its entries', () => {
|
|
101
|
+
const input: ColorReplacement[] = [
|
|
102
|
+
{
|
|
103
|
+
attribute: 'fill',
|
|
104
|
+
originalColor: '#808080',
|
|
105
|
+
replacementColor: '#808080',
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
const originalReplacement = input[0].replacementColor;
|
|
109
|
+
|
|
110
|
+
applyColorThemeToReplacements(input, '#1D4ED8');
|
|
111
|
+
|
|
112
|
+
expect(input[0].replacementColor).toBe(originalReplacement);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ColorReplacement } from '../../brand-page/models';
|
|
2
|
+
import { PROXY_SHAPE_URL_REGEX } from '../../brand-page/constants';
|
|
3
|
+
import { getNewColorBasedOnTargetColorTheme } from '../../brand-page/utils/color.util';
|
|
4
|
+
import { getColorReplacementsFromSvgStringServer } from '../../brand-page/utils/svg-color.util';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Fetch a shape's SVG and return concrete identity-mapped `ColorReplacement`
|
|
8
|
+
* entries, one per unique fill. Caller applies `color_theme` via
|
|
9
|
+
* `applyColorThemeToReplacements` as a second step when re-shading is needed.
|
|
10
|
+
*
|
|
11
|
+
* Returns `[]` for proxy URLs — those are served through `/asset/shape?...`
|
|
12
|
+
* and cannot be fetched for colour enumeration (render path renders them via
|
|
13
|
+
* `<object>` instead of downloading the SVG).
|
|
14
|
+
*
|
|
15
|
+
* Uses the svg-parser-based server variant (not DOMParser) so this works
|
|
16
|
+
* unchanged in both browser and SSR/test environments. For AI-authored shapes
|
|
17
|
+
* with style/class/direct fills, this covers every case; CSS computed-style
|
|
18
|
+
* only matters for shapes authored outside the AI flow.
|
|
19
|
+
*
|
|
20
|
+
* Throws on network or HTTP failure — no silent fallback.
|
|
21
|
+
*/
|
|
22
|
+
export const resolveShapeColorReplacementsAsync = async (
|
|
23
|
+
shapeUrl: string,
|
|
24
|
+
): Promise<ColorReplacement[]> => {
|
|
25
|
+
if (!shapeUrl || shapeUrl.match(PROXY_SHAPE_URL_REGEX)) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const response = await fetch(shapeUrl);
|
|
30
|
+
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Failed to fetch shape for colour enumeration (${response.status}): ${shapeUrl}`,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const svgText = await response.text();
|
|
38
|
+
|
|
39
|
+
const replacements = getColorReplacementsFromSvgStringServer(svgText);
|
|
40
|
+
|
|
41
|
+
// The server-side colour enumeration produces phantom #000000 entries from
|
|
42
|
+
// DEFAULT_FALLBACK_COLOR for elements whose class-based fill can't be
|
|
43
|
+
// resolved. Filter them out when real fill colours exist.
|
|
44
|
+
if (replacements.length > 1) {
|
|
45
|
+
const withoutPhantom = replacements.filter(
|
|
46
|
+
(r) => r.originalColor !== '#000000',
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
if (withoutPhantom.length > 0) return withoutPhantom;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return replacements;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Re-shade each entry's `replacementColor` to a luminance-preserving variant
|
|
57
|
+
* of `colorTheme`. Pure transformation over the existing array — no network.
|
|
58
|
+
*
|
|
59
|
+
* An empty input returns an empty array by design; the caller is expected to
|
|
60
|
+
* populate concrete entries via `resolveShapeColorReplacementsAsync` first.
|
|
61
|
+
*/
|
|
62
|
+
export const applyColorThemeToReplacements = (
|
|
63
|
+
replacements: ColorReplacement[],
|
|
64
|
+
colorTheme: string,
|
|
65
|
+
): ColorReplacement[] =>
|
|
66
|
+
replacements.map((r) => ({
|
|
67
|
+
...r,
|
|
68
|
+
replacementColor:
|
|
69
|
+
replacements.length === 1
|
|
70
|
+
? colorTheme
|
|
71
|
+
: getNewColorBasedOnTargetColorTheme(
|
|
72
|
+
r.originalColor,
|
|
73
|
+
colorTheme,
|
|
74
|
+
)?.toString() ?? colorTheme,
|
|
75
|
+
}));
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import cloneDeep from 'lodash.clonedeep';
|
|
2
|
+
import { type BrandPageModel } from '../../brand-page/models';
|
|
3
|
+
import {
|
|
4
|
+
BaseMetadataBuilder,
|
|
5
|
+
type BuilderResult,
|
|
6
|
+
type MetadataBuilderRequest,
|
|
7
|
+
} from '../models';
|
|
8
|
+
import type { Logger } from '../logger';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Resolver called at undo-execution time to fetch the snapshot to restore to.
|
|
12
|
+
*
|
|
13
|
+
* Returning `null` means there is no snapshot available (e.g. fresh session,
|
|
14
|
+
* or the website has never been modified). The UndoBuilder surfaces this as
|
|
15
|
+
* a validation error so the caller can show a meaningful message.
|
|
16
|
+
*
|
|
17
|
+
* Async supported: the handler may return a `Promise<BrandPageModel | null>`
|
|
18
|
+
* if resolution involves I/O (IndexedDB, remote store, etc.). Sync returns
|
|
19
|
+
* work too — `await` is a no-op on non-promises.
|
|
20
|
+
*/
|
|
21
|
+
export type UndoHandler = () =>
|
|
22
|
+
| BrandPageModel
|
|
23
|
+
| null
|
|
24
|
+
| Promise<BrandPageModel | null>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Payload for the UndoBuilder.
|
|
28
|
+
*
|
|
29
|
+
* The snapshot itself is not stored in the payload. Instead, the payload
|
|
30
|
+
* carries an {@link UndoHandler} callback that the builder invokes at
|
|
31
|
+
* execute time to lazily resolve the snapshot. This keeps the library
|
|
32
|
+
* agnostic about *how* snapshots are stored — the caller owns that concern.
|
|
33
|
+
*/
|
|
34
|
+
export interface UndoPayload {
|
|
35
|
+
undoHandler: UndoHandler;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* UndoBuilder — executes the `undo` tool call by invoking the caller-supplied
|
|
40
|
+
* {@link UndoHandler} callback to resolve the snapshot, then replaces the
|
|
41
|
+
* current model with that snapshot. Also sets
|
|
42
|
+
* {@link BuilderResult.undoRequested} on the returned result so the caller
|
|
43
|
+
* can observe that an undo was executed (useful for telemetry, UI messaging,
|
|
44
|
+
* and audit logs).
|
|
45
|
+
*
|
|
46
|
+
* Contract guarantee from the AI pipeline (Website Planner WL9): the `undo`
|
|
47
|
+
* tool call is exclusive — it never co-occurs with build/update/delete tool
|
|
48
|
+
* calls in the same response. If that contract is ever violated upstream,
|
|
49
|
+
* fix the planner — do not add defensive ordering here. The sequential
|
|
50
|
+
* MetadataExecutor will apply any subsequent builders on top of the restored
|
|
51
|
+
* snapshot, which is the semantically correct "undo-then-apply" ordering.
|
|
52
|
+
*/
|
|
53
|
+
export class UndoBuilder extends BaseMetadataBuilder<UndoPayload> {
|
|
54
|
+
constructor(request: MetadataBuilderRequest<UndoPayload>, logger?: Logger) {
|
|
55
|
+
super(request, logger);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async validateAsync(): Promise<{ errors: string[] }> {
|
|
59
|
+
const errors: string[] = [];
|
|
60
|
+
const payload = this.request.payload;
|
|
61
|
+
|
|
62
|
+
if (typeof payload?.undoHandler !== 'function') {
|
|
63
|
+
errors.push(
|
|
64
|
+
'undo requires an `undoHandler` callback in the payload — caller must supply a function that resolves the pre-prompt snapshot',
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return { errors };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
|
|
72
|
+
this.log('Build called');
|
|
73
|
+
|
|
74
|
+
const validation = await this.validateAsync();
|
|
75
|
+
|
|
76
|
+
if (validation.errors.length) {
|
|
77
|
+
return { request: this.request, model, errors: validation.errors };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const snapshot = await this.request.payload!.undoHandler();
|
|
81
|
+
|
|
82
|
+
if (!snapshot) {
|
|
83
|
+
return {
|
|
84
|
+
request: this.request,
|
|
85
|
+
model,
|
|
86
|
+
errors: ['There are no previous snapshots to restore.'],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Deep-clone the resolved snapshot so downstream builders (if any —
|
|
91
|
+
// exclusivity is enforced at the planner level but we don't rely on it
|
|
92
|
+
// here) mutate a fresh copy rather than the caller's stored snapshot.
|
|
93
|
+
const restored = cloneDeep(snapshot);
|
|
94
|
+
|
|
95
|
+
this.log({
|
|
96
|
+
message: 'Undo executed — model replaced with pre-prompt snapshot',
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
request: this.request,
|
|
101
|
+
model: restored,
|
|
102
|
+
undoRequested: true,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|