@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
|
@@ -1,25 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"aiModal": {
|
|
3
|
-
"generateTitle": "Gerar texto com IA",
|
|
4
|
-
"generateDescription": "O conteúdo é gerado por IA, pode precisar de alterações para melhorar a precisão",
|
|
5
|
-
"generatePlaceholder": "Descreva seu texto.",
|
|
6
|
-
"generationStopped": "A geração de texto parou. Inicie um novo prompt para continuar.",
|
|
7
|
-
"generateInputPlaceholder": "Digite o prompt para descrever o texto...",
|
|
8
|
-
"stopGeneration": "Parar de gerar",
|
|
9
|
-
"useText": "Usar texto",
|
|
10
|
-
"promptTooLong": "O prompt deve ter {{maxLength}} caracteres ou menos ({{currentLength}})",
|
|
11
|
-
"generateText": "Gerar {{ location }}",
|
|
12
|
-
"improveText": "Melhore meu texto",
|
|
13
|
-
"spellCheck": "Verificação Ortográfica",
|
|
14
|
-
"generateTextPrompt": "Escreva um {{fieldName}} cativante para {{businessName}}, uma empresa de {{industry}}. Torne-o amigável e convidativo.",
|
|
15
|
-
"generateTextPromptWithIndustry": "Crie um {{fieldName}} cativante para um negócio no setor de {{industry}}. O texto deve ser simpático e convidativo.",
|
|
16
|
-
"generateTextPromptWithBusinessName": "Crie um {{fieldName}} cativante para um {{businessName}}. O texto deve ser simpático e convidativo.",
|
|
17
|
-
"generateTextPromptSimple": "Crie um {{fieldName}} cativante. O texto deve ser simpático e convidativo.",
|
|
18
|
-
"improveTextPrompt": "Aprimore o texto do {{businessName}} para um negócio de {{industry}}. Ele deve soar natural, claro e profissional.",
|
|
19
|
-
"improveTextPromptWithIndustry": "Aprimore o texto para um negócio de {{industry}}. Ele deve soar natural, claro e profissional.",
|
|
20
|
-
"improveTextPromptWithBusinessName": "Aprimore o texto do {{businessName}}. Ele deve soar natural, claro e profissional.",
|
|
21
|
-
"improveTextPromptSimple": "Melhore este texto. Torne-o mais natural, claro e profissional.",
|
|
22
|
-
"spellCheckPrompt": "Verifique a ortografia e a gramática deste texto.",
|
|
23
3
|
"stop": "Parar",
|
|
24
4
|
"thinkingResponse": "Pensando em uma resposta..."
|
|
25
5
|
}
|
|
@@ -1,25 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"aiModal": {
|
|
3
|
-
"generateTitle": "Gerar Texto com IA",
|
|
4
|
-
"generateDescription": "O conteúdo é gerado por IA e pode precisar de edição para ser preciso",
|
|
5
|
-
"generatePlaceholder": "Descreva o seu texto.",
|
|
6
|
-
"generationStopped": "A geração de texto parou. Inicie um novo prompt para continuar.",
|
|
7
|
-
"generateInputPlaceholder": "Introduza o seu comando para descrever o texto...",
|
|
8
|
-
"stopGeneration": "Parar a geração",
|
|
9
|
-
"useText": "Utilizar texto",
|
|
10
|
-
"promptTooLong": "A mensagem tem de ter {{maxLength}} carateres ou menos ({{currentLength}})",
|
|
11
|
-
"generateText": "Gerar {{ location }}",
|
|
12
|
-
"improveText": "Melhore o seu texto",
|
|
13
|
-
"spellCheck": "Verificação Ortográfica",
|
|
14
|
-
"generateTextPrompt": "Escreva um {{fieldName}} cativante para {{businessName}}, uma empresa de {{industry}}. Escreva com um tom amigável e convidativo.",
|
|
15
|
-
"generateTextPromptWithIndustry": "Escreva um {{fieldName}} cativante para uma empresa na indústria de {{industry}}. Escreva com um tom amigável e convidativo.",
|
|
16
|
-
"generateTextPromptWithBusinessName": "Escreva um {{fieldName}} cativante para {{businessName}}. Escreva com um tom amigável e convidativo.",
|
|
17
|
-
"generateTextPromptSimple": "Escreva um {{fieldName}} cativante. Escreva com um tom amigável e convidativo.",
|
|
18
|
-
"improveTextPrompt": "Melhore este texto para {{businessName}}, uma empresa de {{industry}}. Faça com que soe mais natural, claro e profissional.",
|
|
19
|
-
"improveTextPromptWithIndustry": "Melhore este texto para uma empresa de {{industry}}. Faça com que soe mais natural, claro e profissional.",
|
|
20
|
-
"improveTextPromptWithBusinessName": "Melhore este texto para {{businessName}}. Faça com que soe mais natural, claro e profissional.",
|
|
21
|
-
"improveTextPromptSimple": "Melhore este texto. Faça com que soe mais natural, claro e profissional.",
|
|
22
|
-
"spellCheckPrompt": "Verifique a ortografia e a gramática deste texto.",
|
|
23
3
|
"stop": "Parar",
|
|
24
4
|
"thinkingResponse": "A pensar numa resposta..."
|
|
25
5
|
}
|
|
@@ -79,10 +79,7 @@
|
|
|
79
79
|
{{ commonTr('loadingText') }}
|
|
80
80
|
</p>
|
|
81
81
|
</div>
|
|
82
|
-
<AiActionButtons
|
|
83
|
-
:is-typing="true"
|
|
84
|
-
@stop-generation="onStopAiGeneration"
|
|
85
|
-
/>
|
|
82
|
+
<AiActionButtons :is-typing="true" />
|
|
86
83
|
</div>
|
|
87
84
|
</div>
|
|
88
85
|
|
|
@@ -179,10 +176,9 @@ import { VIEWPORTS, BRAND_PAGE_TYPES } from '@brand-page';
|
|
|
179
176
|
import { UI_DEVICE_MODES, UI_SCREENSIZE_MODES } from '@shared/models';
|
|
180
177
|
import { useLocalisedRouteStore } from '@brand-page-maker/stores/route/localised-route-store';
|
|
181
178
|
import { useBrandPageMakerStore } from '@brand-page-maker/stores/brandpage-maker/brandpage-maker-store';
|
|
182
|
-
import AiTextEdit from '../ai-text-edit/AiTextEdit.vue';
|
|
183
179
|
import AiWebsiteBuilder from '../ai-website-builder/AiWebsiteBuilder.vue';
|
|
184
180
|
import AiActionButtons from '../ai-text-edit/AiActionButtons.vue';
|
|
185
|
-
import {
|
|
181
|
+
import { useAiWebsiteBuilderThreadStore } from '../../stores';
|
|
186
182
|
import { useEventTracker } from '../../composables/useEventTracker';
|
|
187
183
|
|
|
188
184
|
export default {
|
|
@@ -191,7 +187,6 @@ export default {
|
|
|
191
187
|
Loader,
|
|
192
188
|
ActionBar,
|
|
193
189
|
AdminBackgroundSettings,
|
|
194
|
-
AiTextEdit,
|
|
195
190
|
AiWebsiteBuilder,
|
|
196
191
|
AiActionButtons,
|
|
197
192
|
BackgroundSettings: BrandPageBackgroundSettings,
|
|
@@ -223,18 +218,13 @@ export default {
|
|
|
223
218
|
setup(props, context) {
|
|
224
219
|
const localisedRouteStore = useLocalisedRouteStore();
|
|
225
220
|
const brandPageMakerStore = useBrandPageMakerStore();
|
|
226
|
-
const aiThreadStore = useAiThreadStore();
|
|
227
221
|
const aiWebsiteBuilderThreadStore = useAiWebsiteBuilderThreadStore();
|
|
228
222
|
const eventTracker = useEventTracker();
|
|
229
223
|
|
|
230
224
|
return {
|
|
231
225
|
...BrandPageMakerMixin.setup(props, context),
|
|
232
226
|
brandCrowdUrl: computed(() => localisedRouteStore.localisedBaseUrl),
|
|
233
|
-
isAiProcessing: computed(
|
|
234
|
-
() =>
|
|
235
|
-
aiThreadStore.isProcessing ||
|
|
236
|
-
aiWebsiteBuilderThreadStore.isProcessing,
|
|
237
|
-
),
|
|
227
|
+
isAiProcessing: computed(() => aiWebsiteBuilderThreadStore.isProcessing),
|
|
238
228
|
isBrandPageLoaded: computed(() => brandPageMakerStore.isBrandPageLoaded),
|
|
239
229
|
eventTracker,
|
|
240
230
|
};
|
|
@@ -248,21 +238,6 @@ export default {
|
|
|
248
238
|
UI_DEVICE_MODES,
|
|
249
239
|
};
|
|
250
240
|
},
|
|
251
|
-
methods: {
|
|
252
|
-
onStopAiGeneration() {
|
|
253
|
-
this.eventTracker.sendAiStopGenerationEvent('ai_processing_modal');
|
|
254
|
-
|
|
255
|
-
const aiThreadStore = useAiThreadStore();
|
|
256
|
-
if (aiThreadStore.stopGeneration) {
|
|
257
|
-
aiThreadStore.stopGeneration();
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const aiWebsiteBuilderThreadStore = useAiWebsiteBuilderThreadStore();
|
|
261
|
-
if (aiWebsiteBuilderThreadStore.stopGeneration) {
|
|
262
|
-
aiWebsiteBuilderThreadStore.stopGeneration();
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
241
|
};
|
|
267
242
|
</script>
|
|
268
243
|
<style scoped>
|
package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts
CHANGED
|
@@ -90,7 +90,6 @@ export const userFeatures: UserFeatures = {
|
|
|
90
90
|
canUseGettyVideos: false,
|
|
91
91
|
canUseGoogleAdsense: false,
|
|
92
92
|
googleAdsenseEnabled: false,
|
|
93
|
-
canUseAITextGenerator: true,
|
|
94
93
|
};
|
|
95
94
|
|
|
96
95
|
export const BRAND_PAGE: BrandPageData = {
|
|
@@ -2126,7 +2125,6 @@ export const USER_FEATURES: UIUserFeatures = Object.freeze({
|
|
|
2126
2125
|
canUseGettyVideos: true,
|
|
2127
2126
|
canUseGoogleAdsense: false,
|
|
2128
2127
|
googleAdsenseEnabled: true,
|
|
2129
|
-
canUseAITextGenerator: true,
|
|
2130
2128
|
} as UIUserFeatures);
|
|
2131
2129
|
|
|
2132
2130
|
export const INITIALISE_PAYLOAD: InitialisePayload = Object.freeze({
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
pickErrorMessage,
|
|
4
|
+
pickWsErrorMessage,
|
|
5
|
+
buildSubmitErrorReport,
|
|
6
|
+
GENERIC_ERROR_MESSAGE,
|
|
7
|
+
} from './aiErrorCopy';
|
|
8
|
+
|
|
9
|
+
describe('pickErrorMessage (HTTP errors)', () => {
|
|
10
|
+
it('returns the generic message whenever a backend code is present', () => {
|
|
11
|
+
const error = {
|
|
12
|
+
response: { data: { code: 'INVALID_REQUEST', message: 'raw' } },
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
expect(pickErrorMessage(error)).toBe(GENERIC_ERROR_MESSAGE);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('returns the generic message for any code, even unknown ones', () => {
|
|
19
|
+
const error = {
|
|
20
|
+
response: {
|
|
21
|
+
data: { code: 'UNKNOWN_CODE', message: 'specific server message' },
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
expect(pickErrorMessage(error)).toBe(GENERIC_ERROR_MESSAGE);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('falls back to message when no code is present', () => {
|
|
29
|
+
const error = {
|
|
30
|
+
response: { data: { message: 'specific server message' } },
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
expect(pickErrorMessage(error)).toBe('specific server message');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('falls back to legacy `error` field when code/message missing', () => {
|
|
37
|
+
const error = { response: { data: { error: 'legacy error string' } } };
|
|
38
|
+
|
|
39
|
+
expect(pickErrorMessage(error)).toBe('legacy error string');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('returns the generic message when nothing usable is present', () => {
|
|
43
|
+
expect(pickErrorMessage(null)).toBe(GENERIC_ERROR_MESSAGE);
|
|
44
|
+
expect(pickErrorMessage(undefined)).toBe(GENERIC_ERROR_MESSAGE);
|
|
45
|
+
expect(pickErrorMessage({})).toBe(GENERIC_ERROR_MESSAGE);
|
|
46
|
+
expect(pickErrorMessage({ response: {} })).toBe(GENERIC_ERROR_MESSAGE);
|
|
47
|
+
expect(pickErrorMessage({ response: { data: {} } })).toBe(
|
|
48
|
+
GENERIC_ERROR_MESSAGE,
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('ignores empty strings in message and error', () => {
|
|
53
|
+
const error = { response: { data: { message: '', error: '' } } };
|
|
54
|
+
|
|
55
|
+
expect(pickErrorMessage(error)).toBe(GENERIC_ERROR_MESSAGE);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('handles non-object inputs without throwing', () => {
|
|
59
|
+
expect(pickErrorMessage('string error')).toBe(GENERIC_ERROR_MESSAGE);
|
|
60
|
+
expect(pickErrorMessage(42)).toBe(GENERIC_ERROR_MESSAGE);
|
|
61
|
+
expect(pickErrorMessage(new Error('boom'))).toBe(GENERIC_ERROR_MESSAGE);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('pickWsErrorMessage (WebSocket build_error frames)', () => {
|
|
66
|
+
it('returns the generic message for BUILD_FAILED', () => {
|
|
67
|
+
const msg = {
|
|
68
|
+
type: 'build_error',
|
|
69
|
+
buildId: 'b1',
|
|
70
|
+
error: 'An unexpected error occurred during the build.',
|
|
71
|
+
code: 'BUILD_FAILED',
|
|
72
|
+
message: 'An unexpected error occurred during the build.',
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
expect(pickWsErrorMessage(msg)).toBe(GENERIC_ERROR_MESSAGE);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('returns the generic message for BUILD_TIMEOUT', () => {
|
|
79
|
+
const msg = { code: 'BUILD_TIMEOUT', message: 'timed out' };
|
|
80
|
+
|
|
81
|
+
expect(pickWsErrorMessage(msg)).toBe(GENERIC_ERROR_MESSAGE);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('returns the generic message for BUILD_CANCELLED', () => {
|
|
85
|
+
const msg = { code: 'BUILD_CANCELLED', error: 'restart' };
|
|
86
|
+
|
|
87
|
+
expect(pickWsErrorMessage(msg)).toBe(GENERIC_ERROR_MESSAGE);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('falls back to legacy `error` field for old backend payloads', () => {
|
|
91
|
+
const msg = {
|
|
92
|
+
type: 'build_error',
|
|
93
|
+
buildId: 'b1',
|
|
94
|
+
error: 'An unexpected error occurred during the build.',
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
expect(pickWsErrorMessage(msg)).toBe(
|
|
98
|
+
'An unexpected error occurred during the build.',
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('returns generic when nothing usable is present', () => {
|
|
103
|
+
expect(pickWsErrorMessage(null)).toBe(GENERIC_ERROR_MESSAGE);
|
|
104
|
+
expect(pickWsErrorMessage(undefined)).toBe(GENERIC_ERROR_MESSAGE);
|
|
105
|
+
expect(pickWsErrorMessage({})).toBe(GENERIC_ERROR_MESSAGE);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('buildSubmitErrorReport', () => {
|
|
110
|
+
it('classifies a network failure (no response)', () => {
|
|
111
|
+
const error = Object.assign(new Error('Network Error'), {
|
|
112
|
+
code: 'ERR_NETWORK',
|
|
113
|
+
});
|
|
114
|
+
const report = buildSubmitErrorReport(error, { stage: 'submit' });
|
|
115
|
+
|
|
116
|
+
expect(report?.tags).toContain('feature:ai-website-builder');
|
|
117
|
+
expect(report?.tags).toContain('failure:network');
|
|
118
|
+
expect(report?.tags).toContain('stage:submit');
|
|
119
|
+
expect(report?.customData.status_code).toBeNull();
|
|
120
|
+
expect(report?.customData.axios_code).toBe('ERR_NETWORK');
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('classifies a 502 from a brandcrowd.net proxy as failure:proxy', () => {
|
|
124
|
+
const error = {
|
|
125
|
+
message: 'Bad gateway',
|
|
126
|
+
response: { status: 502, data: { error: 'gateway' } },
|
|
127
|
+
config: {
|
|
128
|
+
url: '/api/ai/thread/build',
|
|
129
|
+
baseURL: 'https://www.brandcrowd.net',
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
const report = buildSubmitErrorReport(error, { stage: 'submit' });
|
|
133
|
+
|
|
134
|
+
expect(report?.tags).toContain('failure:proxy');
|
|
135
|
+
expect(report?.customData.status_code).toBe(502);
|
|
136
|
+
expect(report?.customData.host).toBe('www.brandcrowd.net');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('classifies a 502 from brandcrowd.net (no www) as failure:proxy', () => {
|
|
140
|
+
const error = {
|
|
141
|
+
message: 'Bad gateway',
|
|
142
|
+
response: { status: 502 },
|
|
143
|
+
config: {
|
|
144
|
+
url: '/api/ai/thread/build',
|
|
145
|
+
baseURL: 'https://brandcrowd.net',
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
const report = buildSubmitErrorReport(error, { stage: 'submit' });
|
|
149
|
+
|
|
150
|
+
expect(report?.tags).toContain('failure:proxy');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('does NOT misclassify look-alike hosts as proxies', () => {
|
|
154
|
+
// Earlier regex `/brand(crowd|page)/i.test(host)` would match these as
|
|
155
|
+
// substrings — tightened pattern now requires the brand domain at the
|
|
156
|
+
// start of the host with a literal `.` boundary.
|
|
157
|
+
const lookalikes = [
|
|
158
|
+
'https://mybrandcrowdtest.com',
|
|
159
|
+
'https://brandpage123.example.com',
|
|
160
|
+
'https://api.brandcrowd-attacker.com',
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
for (const baseURL of lookalikes) {
|
|
164
|
+
const error = {
|
|
165
|
+
message: 'Internal',
|
|
166
|
+
response: { status: 500 },
|
|
167
|
+
config: { url: '/x', baseURL },
|
|
168
|
+
};
|
|
169
|
+
const report = buildSubmitErrorReport(error, { stage: 'submit' });
|
|
170
|
+
|
|
171
|
+
expect(report?.tags, `host=${baseURL}`).not.toContain('failure:proxy');
|
|
172
|
+
expect(report?.tags, `host=${baseURL}`).toContain('failure:upstream');
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('classifies a 500 from ai-pipelines (non-proxy host) as failure:upstream', () => {
|
|
177
|
+
const error = {
|
|
178
|
+
message: 'Internal',
|
|
179
|
+
response: { status: 500 },
|
|
180
|
+
config: {
|
|
181
|
+
url: 'https://ai-pipelines-staging.designcrowd.ninja/api/assistant/thread/build',
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
const report = buildSubmitErrorReport(error, { stage: 'submit' });
|
|
185
|
+
|
|
186
|
+
expect(report?.tags).toContain('failure:upstream');
|
|
187
|
+
expect(report?.customData.status_code).toBe(500);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('classifies a 400 as failure:client', () => {
|
|
191
|
+
const error = {
|
|
192
|
+
message: 'Bad request',
|
|
193
|
+
response: { status: 400, data: { code: 'INVALID_REQUEST' } },
|
|
194
|
+
config: { url: '/api/ai/thread/build' },
|
|
195
|
+
};
|
|
196
|
+
const report = buildSubmitErrorReport(error, { stage: 'submit' });
|
|
197
|
+
|
|
198
|
+
expect(report?.tags).toContain('failure:client');
|
|
199
|
+
expect(report?.customData.status_code).toBe(400);
|
|
200
|
+
expect(report?.customData.response_data).toEqual({
|
|
201
|
+
code: 'INVALID_REQUEST',
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('respects the stage tag for continue calls', () => {
|
|
206
|
+
const error = {
|
|
207
|
+
message: 'x',
|
|
208
|
+
response: { status: 500 },
|
|
209
|
+
config: { url: '/x' },
|
|
210
|
+
};
|
|
211
|
+
const report = buildSubmitErrorReport(error, { stage: 'continue' });
|
|
212
|
+
|
|
213
|
+
expect(report?.tags).toContain('stage:continue');
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it('handles non-object errors without throwing', () => {
|
|
217
|
+
const report = buildSubmitErrorReport('string error', { stage: 'submit' });
|
|
218
|
+
|
|
219
|
+
expect(report?.tags).toContain('failure:unknown');
|
|
220
|
+
expect(report?.customData.raw).toBe('string error');
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('preserves the original Error instance when one is thrown', () => {
|
|
224
|
+
const original = new Error('original');
|
|
225
|
+
const report = buildSubmitErrorReport(original, { stage: 'submit' });
|
|
226
|
+
|
|
227
|
+
expect(report?.error).toBe(original);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// REL 1 Phase 1 / 1.5 — friendly chat copy keyed by the backend `code` field.
|
|
2
|
+
//
|
|
3
|
+
// Backend returns `{ error, code, message }` for known failure paths
|
|
4
|
+
// (both HTTP responses and WebSocket build_error / server_error frames).
|
|
5
|
+
// We look up the code first, then fall back to message → error → generic.
|
|
6
|
+
// English-only for now; Phase 2 promotes this to proper i18n keys.
|
|
7
|
+
|
|
8
|
+
export const GENERIC_ERROR_MESSAGE =
|
|
9
|
+
'Something went wrong while putting your website together. Could you try that again?';
|
|
10
|
+
|
|
11
|
+
interface ErrorPayload {
|
|
12
|
+
code?: unknown;
|
|
13
|
+
message?: unknown;
|
|
14
|
+
error?: unknown;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function pickFromPayload(data: ErrorPayload | undefined | null): string {
|
|
18
|
+
if (!data || typeof data !== 'object') return GENERIC_ERROR_MESSAGE;
|
|
19
|
+
|
|
20
|
+
if (typeof data.code === 'string') {
|
|
21
|
+
return GENERIC_ERROR_MESSAGE;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (typeof data.message === 'string' && data.message) {
|
|
25
|
+
return data.message;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (typeof data.error === 'string' && data.error) {
|
|
29
|
+
return data.error;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return GENERIC_ERROR_MESSAGE;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Pick a friendly chat message from a thrown HTTP error.
|
|
37
|
+
*
|
|
38
|
+
* Reads `error.response.data.{code, message, error}` — the shape returned by
|
|
39
|
+
* the ai-pipelines REST endpoints when a request fails synchronously.
|
|
40
|
+
*/
|
|
41
|
+
export function pickErrorMessage(error: unknown): string {
|
|
42
|
+
if (typeof error !== 'object' || error === null) return GENERIC_ERROR_MESSAGE;
|
|
43
|
+
|
|
44
|
+
const data = (error as { response?: { data?: ErrorPayload } }).response?.data;
|
|
45
|
+
|
|
46
|
+
return pickFromPayload(data);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Pick a friendly chat message from a WebSocket error frame.
|
|
51
|
+
*
|
|
52
|
+
* Reads `msg.{code, message, error}` directly — the shape pushed by the
|
|
53
|
+
* ai-pipelines build_error / server_error WebSocket frames.
|
|
54
|
+
*/
|
|
55
|
+
export function pickWsErrorMessage(
|
|
56
|
+
msg: ErrorPayload | undefined | null,
|
|
57
|
+
): string {
|
|
58
|
+
return pickFromPayload(msg);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Raygun reporting for the chat HTTP submit path
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
//
|
|
65
|
+
// REL 1 item (4): when the frontend POST to ai-pipelines fails — at the
|
|
66
|
+
// brandcrowd.net proxy, on the network, or inside ai-pipelines — we want
|
|
67
|
+
// it captured in Raygun so we can see request-path failures separately
|
|
68
|
+
// from pipeline failures.
|
|
69
|
+
//
|
|
70
|
+
// We classify the error by what happened so the Raygun tags tell a clear
|
|
71
|
+
// story:
|
|
72
|
+
// - `failure:network` → no response received (DNS, offline, CORS, abort)
|
|
73
|
+
// - `failure:proxy` → 5xx from a proxy (e.g. brandcrowd.net 502/504)
|
|
74
|
+
// - `failure:upstream` → 5xx from ai-pipelines itself
|
|
75
|
+
// - `failure:client` → 4xx (validation / bad request)
|
|
76
|
+
|
|
77
|
+
export interface RaygunReport {
|
|
78
|
+
error: Error;
|
|
79
|
+
tags: string[];
|
|
80
|
+
customData: Record<string, unknown>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface AxiosLikeError {
|
|
84
|
+
message?: string;
|
|
85
|
+
code?: string;
|
|
86
|
+
response?: { status?: number; data?: unknown };
|
|
87
|
+
config?: { url?: string; baseURL?: string };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const isObject = (v: unknown): v is Record<string, unknown> =>
|
|
91
|
+
typeof v === 'object' && v !== null;
|
|
92
|
+
|
|
93
|
+
// Match the proxy domains exactly at the start of the host (with optional
|
|
94
|
+
// `www.` prefix). The previous form `/brand(crowd|page)/i.test(host)` matched
|
|
95
|
+
// any substring, so unrelated hosts like ``mybrandcrowdtest.com`` or
|
|
96
|
+
// ``brandpage123.example.com`` would be misclassified as proxy failures.
|
|
97
|
+
const PROXY_HOST_PATTERN = /^(?:www\.)?(?:brandcrowd|brandpage)\./i;
|
|
98
|
+
|
|
99
|
+
const looksLikeProxy = (host: string | undefined): boolean => {
|
|
100
|
+
if (!host) return false;
|
|
101
|
+
|
|
102
|
+
return PROXY_HOST_PATTERN.test(host);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Build the Raygun payload for an error thrown during a chat submit POST.
|
|
107
|
+
*
|
|
108
|
+
* Returns null when the error is a normal cancellation (user clicked stop) —
|
|
109
|
+
* the caller must skip Raygun in that case.
|
|
110
|
+
*/
|
|
111
|
+
export function buildSubmitErrorReport(
|
|
112
|
+
error: unknown,
|
|
113
|
+
context: { stage: 'submit' | 'continue' },
|
|
114
|
+
): RaygunReport | null {
|
|
115
|
+
if (!isObject(error)) {
|
|
116
|
+
return {
|
|
117
|
+
error: new Error('AI submit failed: non-error thrown'),
|
|
118
|
+
tags: ['feature:ai-website-builder', 'failure:unknown'],
|
|
119
|
+
customData: { stage: context.stage, raw: String(error) },
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const e = error as AxiosLikeError;
|
|
124
|
+
const status = isObject(e.response) ? Number(e.response.status) : undefined;
|
|
125
|
+
const url = e.config?.url ?? '';
|
|
126
|
+
const baseURL = e.config?.baseURL ?? '';
|
|
127
|
+
const host = (() => {
|
|
128
|
+
try {
|
|
129
|
+
return new URL(url, baseURL || 'http://_').host;
|
|
130
|
+
} catch {
|
|
131
|
+
return baseURL || url;
|
|
132
|
+
}
|
|
133
|
+
})();
|
|
134
|
+
|
|
135
|
+
let failureTag = 'failure:unknown';
|
|
136
|
+
|
|
137
|
+
if (status === undefined) {
|
|
138
|
+
failureTag = 'failure:network';
|
|
139
|
+
} else if (status >= 500 && looksLikeProxy(host)) {
|
|
140
|
+
failureTag = 'failure:proxy';
|
|
141
|
+
} else if (status >= 500) {
|
|
142
|
+
failureTag = 'failure:upstream';
|
|
143
|
+
} else if (status >= 400) {
|
|
144
|
+
failureTag = 'failure:client';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const message =
|
|
148
|
+
e.message ||
|
|
149
|
+
`AI submit ${context.stage} failed (status=${status ?? 'none'})`;
|
|
150
|
+
const wrapped = error instanceof Error ? error : new Error(message);
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
error: wrapped,
|
|
154
|
+
tags: ['feature:ai-website-builder', failureTag, `stage:${context.stage}`],
|
|
155
|
+
customData: {
|
|
156
|
+
stage: context.stage,
|
|
157
|
+
status_code: status ?? null,
|
|
158
|
+
axios_code: e.code ?? null,
|
|
159
|
+
host: host || null,
|
|
160
|
+
url: url || null,
|
|
161
|
+
response_data: isObject(e.response) ? e.response.data : null,
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ComputedRef, Ref } from 'vue';
|
|
2
|
+
import { type PlanItem } from '../../../clients/websocket-gateway-client';
|
|
3
|
+
|
|
4
|
+
export interface BaseThreadMessage {
|
|
5
|
+
id: string;
|
|
6
|
+
role: 'user' | 'agent';
|
|
7
|
+
isTyping?: boolean;
|
|
8
|
+
isError?: boolean;
|
|
9
|
+
timestamp: Date;
|
|
10
|
+
langChainUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface TextThreadMessage extends BaseThreadMessage {
|
|
14
|
+
type: 'text';
|
|
15
|
+
text: string;
|
|
16
|
+
initialMessage?: string;
|
|
17
|
+
planItems?: PlanItem[];
|
|
18
|
+
completedItemIds?: string[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ImageThreadMessage extends BaseThreadMessage {
|
|
22
|
+
type: 'image';
|
|
23
|
+
images: { url: string; alt?: string }[];
|
|
24
|
+
text?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type ThreadMessage = TextThreadMessage | ImageThreadMessage;
|
|
28
|
+
|
|
29
|
+
export interface SendMessageOptions {
|
|
30
|
+
text?: string;
|
|
31
|
+
images?: { url: string; alt?: string }[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface UseAiChatResult {
|
|
35
|
+
threadItems: Ref<ThreadMessage[]>;
|
|
36
|
+
isProcessing: Ref<boolean>;
|
|
37
|
+
currentTypingMessageId: Ref<string | null>;
|
|
38
|
+
generatedText: Ref<string | null>;
|
|
39
|
+
generatedStyle: Ref<BrandPageCssStyle | null>;
|
|
40
|
+
sendMessageAsync: (options: SendMessageOptions) => Promise<void>;
|
|
41
|
+
deleteMessage: (messageId: string) => void;
|
|
42
|
+
stopGenerationAsync: () => Promise<void>;
|
|
43
|
+
formattedMessages: ComputedRef<
|
|
44
|
+
{
|
|
45
|
+
type: string;
|
|
46
|
+
props: Record<string, unknown>;
|
|
47
|
+
}[]
|
|
48
|
+
>;
|
|
49
|
+
}
|
|
@@ -4,14 +4,23 @@ import {
|
|
|
4
4
|
parseToolCalls,
|
|
5
5
|
type ParsedToolCall,
|
|
6
6
|
} from '../../../metadata-builder/parsers/ai-toolcall-parser';
|
|
7
|
+
import type { UndoHandler } from '../../../metadata-builder/builders/undo-builder';
|
|
7
8
|
import type { AiAssistantToolCall } from '../../../clients/ai-assistant-client';
|
|
8
9
|
import type { Logger } from '../../../metadata-builder/logger';
|
|
10
|
+
import type { EventTracker } from '../useEventTracker';
|
|
9
11
|
|
|
10
12
|
export interface AiMetadataBuilderResult {
|
|
11
13
|
model: BrandPageModel;
|
|
12
14
|
results: {
|
|
13
15
|
toolId: string;
|
|
14
16
|
errors?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* The frontend-assigned content id of the section this tool call
|
|
19
|
+
* created/updated, when the builder produced one. Used by the AI chat
|
|
20
|
+
* composable's vacant-slot tracker to anchor retried CREATE calls back
|
|
21
|
+
* to their planned slot via `move_before_content_id`.
|
|
22
|
+
*/
|
|
23
|
+
contentId?: string;
|
|
15
24
|
}[];
|
|
16
25
|
parsedToolCalls: ParsedToolCall[];
|
|
17
26
|
}
|
|
@@ -25,6 +34,16 @@ export function useAiMetadataBuilder(logger: Logger) {
|
|
|
25
34
|
aiAssistantToolCall: AiAssistantToolCall[],
|
|
26
35
|
options: {
|
|
27
36
|
maxCharacters?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Invoked by the UndoBuilder to resolve the pre-prompt snapshot.
|
|
39
|
+
* Required when the response includes an `undo` tool call.
|
|
40
|
+
*/
|
|
41
|
+
undoHandler?: UndoHandler;
|
|
42
|
+
/**
|
|
43
|
+
* Optional tracker for AI-prompt-originated content events.
|
|
44
|
+
* Forwarded to executeToolCallsAsync, then to section builders.
|
|
45
|
+
*/
|
|
46
|
+
eventTracker?: EventTracker;
|
|
28
47
|
} = {},
|
|
29
48
|
): Promise<AiMetadataBuilderResult> => {
|
|
30
49
|
try {
|
|
@@ -42,6 +61,7 @@ export function useAiMetadataBuilder(logger: Logger) {
|
|
|
42
61
|
return {
|
|
43
62
|
toolId: x.request.id,
|
|
44
63
|
errors: x.errors,
|
|
64
|
+
contentId: x.contentId,
|
|
45
65
|
};
|
|
46
66
|
}),
|
|
47
67
|
};
|