@designcrowd/library.brand-page 6.0.25 → 6.0.26-json-prereq-2
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-CS3ct0wa.js → CreatedOnBrandCrowd-de-de-CKBqjDH3.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-CmBcnDu6.js → CreatedOnBrandCrowd-en-us-CRXiimvT.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-BdTuJtqV.js → CreatedOnBrandCrowd-es-es-DCYdY6sj.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-Cx_H9X6l.js → CreatedOnBrandCrowd-fr-ca-Dk7LOhxE.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-Cx_H9X6l.js → CreatedOnBrandCrowd-fr-fr-Dk7LOhxE.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-BZZ9hjUi.js → CreatedOnBrandCrowd-pt-br-Cp4ufHJP.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-BZZ9hjUi.js → CreatedOnBrandCrowd-pt-pt-Cp4ufHJP.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-SbONDQN1.js → CreatedOnDcom-de-de-ZSLkWMwM.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-Beno1_gw.js → CreatedOnDcom-en-us-BgdIGfT3.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-BBE_zdRu.js → CreatedOnDcom-es-es-D0KemkCZ.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-C6pgDB5x.js → CreatedOnDcom-fr-ca-BuwNjNbC.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-FD1eqtg3.js → CreatedOnDcom-fr-fr-DCQcsFPf.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-BiSx3OwM.js → CreatedOnDcom-pt-br-DD-oLAS1.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-Dn4DmKGA.js → CreatedOnDcom-pt-pt-D8qLq2wW.js} +1 -1
- package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +5 -2
- package/lib/src/brand-page/models/index.d.ts +34 -26
- package/lib/src/brand-page/utils/migration/migration-20.d.ts +2 -0
- package/lib/src/brand-page/utils/migration/migration-20.js +66 -0
- package/lib/src/brand-page/utils/migration.util.js +11 -0
- package/lib/src/brand-page/utils/text.util.d.ts +1 -1
- package/lib/src/brand-page/utils/text.util.js +32 -0
- package/lib/src/brand-page/utils/vcard.util.js +4 -4
- package/lib/src/brand-page/utils/view-model.util.d.ts +1 -0
- package/lib/src/brand-page/utils/view-model.util.js +68 -20
- package/lib/src/brand-page/view-models.d.ts +3 -3
- package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.d.ts +22 -0
- package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.js +22 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -1
- package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +0 -1
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +21 -9
- package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.d.ts +2 -9
- package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.js +6 -10
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.d.ts +14 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.js +39 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +28 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.js +90 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +24 -103
- package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +8 -2
- package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.js +20 -0
- package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +7 -0
- package/lib/src/brand-page-maker/utils/index.d.ts +2 -0
- package/lib/src/brand-page-maker/utils/index.js +2 -0
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +28 -5
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +48 -5
- package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +63 -0
- package/lib/src/brand-page-maker/utils/rte-render.util.js +95 -0
- package/lib/src/brand-page-maker/utils/rte-sanitize.util.d.ts +6 -0
- package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +158 -0
- package/lib/src/brand-page-maker/validators/field.validator.js +10 -2
- package/lib/src/css/library.brand-page-brandCrowd.min.css +39 -39
- package/lib/src/css/library.brand-page-brandPage.min.css +39 -39
- package/lib/src/css/library.brand-page-designCom.min.css +39 -39
- package/lib/src/css/library.brand-page-preview.min.css +39 -39
- package/lib/src/index.d.ts +1 -0
- package/lib/src/index.mjs +143 -138
- package/lib/src/{lib-BVHFYSLL.js → lib-Db6j9fQZ.js} +56262 -52768
- package/lib/src/lib.js +2 -0
- package/lib/src/metadata-builder/ai-metadata-executor.d.ts +0 -1
- package/lib/src/metadata-builder/ai-metadata-executor.js +0 -19
- package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +2 -3
- package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +2 -3
- package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +2 -3
- package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +3 -4
- package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +2 -3
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +1 -2
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +1 -2
- package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +3 -4
- package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +2 -3
- package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +1 -2
- package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +15 -11
- package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +11 -13
- package/lib/src/metadata-builder/helpers/rte.helpers.js +14 -73
- package/lib/src/metadata-builder/metadata-executor.js +0 -4
- package/lib/src/metadata-builder/models.d.ts +0 -2
- package/lib/src/metadata-builder/models.js +0 -2
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +0 -19
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +0 -4
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.d.ts +7 -8
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +21 -52
- package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/GenericTextInput.mixin.js +14 -1
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +12 -3
- package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/radio-field/RadioField.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/slider-field/SliderField.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +3 -2
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.js +10 -3
- package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +2 -1
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +4 -1
- package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +2 -2
- package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +1 -1
- package/lib/src/utils/minify-brand-page-metadata.js +4 -1
- package/package.json +17 -15
- package/src/brand-page/components/contact-form/ContactForm.mixin.ts +5 -2
- package/src/brand-page/components/text-wrapper/TextWrapper.vue +17 -6
- package/src/brand-page/models/index.ts +35 -26
- package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -3
- package/src/brand-page/utils/migration/migration-20.server.test.ts +125 -0
- package/src/brand-page/utils/migration/migration-20.test.ts +72 -0
- package/src/brand-page/utils/migration/migration-20.ts +87 -0
- package/src/brand-page/utils/migration.util.ts +12 -0
- package/src/brand-page/utils/style.util.test.ts +51 -0
- package/src/brand-page/utils/text.util.test.ts +47 -0
- package/src/brand-page/utils/text.util.ts +43 -4
- package/src/brand-page/utils/vcard.util.ts +6 -4
- package/src/brand-page/utils/view-model.pageid-rte.test.ts +104 -0
- package/src/brand-page/utils/view-model.util.ts +94 -26
- package/src/brand-page/view-models.ts +3 -2
- package/src/brand-page-maker/__fixtures__/complex-rte.fixture.ts +23 -0
- package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +4 -3
- package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +0 -1
- package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +28 -9
- package/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.ts +6 -10
- package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +52 -0
- package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.ts +42 -0
- package/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.ts +137 -0
- package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +27 -111
- package/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.ts +23 -0
- package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +8 -0
- package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +202 -0
- package/src/brand-page-maker/utils/index.ts +2 -0
- package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +37 -3
- package/src/brand-page-maker/utils/rich-text-editor.util.ts +66 -11
- package/src/brand-page-maker/utils/rte-features.test.ts +351 -0
- package/src/brand-page-maker/utils/rte-render-parity.test.ts +157 -0
- package/src/brand-page-maker/utils/rte-render.util.ts +165 -0
- package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +158 -0
- package/src/brand-page-maker/utils/rte-sanitize.util.ts +195 -0
- package/src/brand-page-maker/validators/field.validator.test.ts +55 -0
- package/src/brand-page-maker/validators/field.validator.ts +10 -2
- package/src/lib.ts +9 -0
- package/src/metadata-builder/ai-metadata-executor.ts +0 -26
- package/src/metadata-builder/builders/section-builders/about-section-builder.ts +2 -3
- package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +2 -3
- package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +2 -5
- package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +3 -4
- package/src/metadata-builder/builders/section-builders/images-section-builder.ts +2 -3
- package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +1 -2
- package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +1 -2
- package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +3 -6
- package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +2 -3
- package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +1 -2
- package/src/metadata-builder/builders/section-builders/text-section-builder.ts +19 -13
- package/src/metadata-builder/helpers/rte.helpers.ts +15 -101
- package/src/metadata-builder/metadata-executor.ts +0 -5
- package/src/metadata-builder/models.ts +0 -3
- package/src/metadata-builder/parsers/ai-toolcall-parser.ts +0 -27
- package/src/metadata-builder/sanitizers/rte-schema-check.ts +24 -53
- package/src/shared/content-settings/components/GenericTextInput.mixin.ts +17 -1
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +16 -3
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.ts +13 -4
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +6 -4
- package/src/shared/content-settings/components/text-image-field/TextImageField.vue +6 -3
- package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +6 -1
- package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +1 -1
- package/src/utils/minify-brand-page-metadata.ts +4 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.d.ts +0 -20
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.js +0 -44
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.d.ts +0 -27
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.js +0 -44
- package/lib/src/metadata-builder/builders/update-content-text-builder.d.ts +0 -17
- package/lib/src/metadata-builder/builders/update-content-text-builder.js +0 -103
- package/lib/src/metadata-builder/builders/update-content-text-style-builder.d.ts +0 -16
- package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +0 -216
- package/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.ts +0 -73
- package/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.ts +0 -85
- package/src/metadata-builder/builders/update-content-text-builder.ts +0 -148
- package/src/metadata-builder/builders/update-content-text-style-builder.ts +0 -352
package/lib/src/lib.js
CHANGED
|
@@ -30,6 +30,8 @@ export { minifyBrandPageMetadata, } from './utils/minify-brand-page-metadata';
|
|
|
30
30
|
export * as brandPageUtils from './brand-page/utils';
|
|
31
31
|
export { getOptimalLogoSize, calculateOptimizedLogoDimensions, applyLogoImageBase64UrlToBrandPageTemplateModel, recalculateLogoContentDimensions, recalculateHeaderLogoSizes, } from './brand-page/utils/logo.util';
|
|
32
32
|
export { sanitizeRTEHtml } from './brand-page-maker/utils';
|
|
33
|
+
// BP-5787: RTE JSON storage boundary helpers (render/normalise/sanitise/extract).
|
|
34
|
+
export { renderRteToHtml, toRteJson, isTiptapDocument, sanitizeRteJson, getRteJsonPlainText, } from './brand-page-maker/utils';
|
|
33
35
|
export { getPageSlugFromPageTitle } from './brand-page-maker/utils/slug.util';
|
|
34
36
|
// AI-pipeline preview (longclaw per-turn snapshots): web-renderer's
|
|
35
37
|
// /preview/ai-pipeline render page + manifest server route apply the agent's
|
|
@@ -6,7 +6,6 @@ import { type MetadataExecutorResult } from './models';
|
|
|
6
6
|
import { type ParsedToolCall } from './parsers/ai-toolcall-parser';
|
|
7
7
|
export declare const executeToolCallsAsync: (metadata: BrandPageModel, toolcalls: ParsedToolCall[], options: {
|
|
8
8
|
logger?: Logger;
|
|
9
|
-
maxCharacters?: number;
|
|
10
9
|
/**
|
|
11
10
|
* Callback invoked by the UndoBuilder at execution time to resolve the
|
|
12
11
|
* pre-prompt snapshot to restore to. The library is agnostic about where
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import {} from '../brand-page/models';
|
|
2
|
-
import { buildUpdateTextRequest } from './builders/update-content-text-builder';
|
|
3
|
-
import { buildUpdateTextStyleRequest } from './builders/update-content-text-style-builder';
|
|
4
2
|
import { MetadataExecutor } from './metadata-executor';
|
|
5
3
|
import { BUILDER_TYPES, } from './models';
|
|
6
4
|
import { AI_ASSISTANT_TOOL_NAMES, SECTION_TOOL_MAP,
|
|
@@ -11,23 +9,6 @@ export const executeToolCallsAsync = async (metadata, toolcalls, options) => {
|
|
|
11
9
|
const requests = toolcalls
|
|
12
10
|
.map((toolcall) => {
|
|
13
11
|
switch (toolcall.function) {
|
|
14
|
-
case AI_ASSISTANT_TOOL_NAMES.UPDATE_TEXT: {
|
|
15
|
-
const arg = toolcall.arguments;
|
|
16
|
-
return buildUpdateTextRequest(toolcall.toolId, {
|
|
17
|
-
contentId: arg.contentId,
|
|
18
|
-
fieldName: arg.fieldName,
|
|
19
|
-
newText: arg.metadata.text,
|
|
20
|
-
maxCharacters: options.maxCharacters,
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
case AI_ASSISTANT_TOOL_NAMES.UPDATE_STYLE: {
|
|
24
|
-
const arg = toolcall.arguments;
|
|
25
|
-
return buildUpdateTextStyleRequest(toolcall.toolId, {
|
|
26
|
-
contentId: arg.contentId,
|
|
27
|
-
fieldName: arg.fieldName,
|
|
28
|
-
newStyles: arg.metadata.style,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
12
|
case AI_ASSISTANT_TOOL_NAMES.DELETE_SECTION: {
|
|
32
13
|
const arg = toolcall.arguments;
|
|
33
14
|
return {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyScalarFields, applyStyleFields, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { applyColorThemeToReplacements, resolveShapeColorReplacementsAsync, } from '../shape-color-utils';
|
|
@@ -24,7 +23,7 @@ export class AboutSectionBuilder extends BaseSectionBuilder {
|
|
|
24
23
|
const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
|
|
25
24
|
if (aboutArgs.title !== undefined) {
|
|
26
25
|
if (isTiptapDocument(aboutArgs.title)) {
|
|
27
|
-
resolved.content.title =
|
|
26
|
+
resolved.content.title = aboutArgs.title;
|
|
28
27
|
resolved.content.titleStyle = resolveGlobalPresetIntoStyle(resolved.content.titleStyle, textStyleOptions);
|
|
29
28
|
}
|
|
30
29
|
else {
|
|
@@ -33,7 +32,7 @@ export class AboutSectionBuilder extends BaseSectionBuilder {
|
|
|
33
32
|
}
|
|
34
33
|
if (aboutArgs.paragraph !== undefined) {
|
|
35
34
|
if (isTiptapDocument(aboutArgs.paragraph)) {
|
|
36
|
-
resolved.content.paragraph =
|
|
35
|
+
resolved.content.paragraph = aboutArgs.paragraph;
|
|
37
36
|
resolved.content.paragraphStyle = resolveGlobalPresetIntoStyle(resolved.content.paragraphStyle, textStyleOptions);
|
|
38
37
|
}
|
|
39
38
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyButtonLink, applyScalarFields, applyStyleFields, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { applyColorThemeToReplacements, resolveShapeColorReplacementsAsync, } from '../shape-color-utils';
|
|
@@ -44,7 +43,7 @@ export class BannerSectionBuilder extends BaseSectionBuilder {
|
|
|
44
43
|
const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
|
|
45
44
|
if (bannerArgs.title !== undefined) {
|
|
46
45
|
if (isTiptapDocument(bannerArgs.title)) {
|
|
47
|
-
resolved.content.title =
|
|
46
|
+
resolved.content.title = bannerArgs.title;
|
|
48
47
|
resolved.content.titleStyle = resolveGlobalPresetIntoStyle(resolved.content.titleStyle, textStyleOptions);
|
|
49
48
|
}
|
|
50
49
|
else {
|
|
@@ -53,7 +52,7 @@ export class BannerSectionBuilder extends BaseSectionBuilder {
|
|
|
53
52
|
}
|
|
54
53
|
if (bannerArgs.description !== undefined) {
|
|
55
54
|
if (isTiptapDocument(bannerArgs.description)) {
|
|
56
|
-
resolved.content.description =
|
|
55
|
+
resolved.content.description = bannerArgs.description;
|
|
57
56
|
resolved.content.descriptionStyle = resolveGlobalPresetIntoStyle(resolved.content.descriptionStyle, textStyleOptions);
|
|
58
57
|
}
|
|
59
58
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyButtonLink, applyScalarFields, applyStyleFields, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { BaseSectionBuilder } from './base-section-builder';
|
|
@@ -23,7 +22,7 @@ export class BookingSectionBuilder extends BaseSectionBuilder {
|
|
|
23
22
|
const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
|
|
24
23
|
if (bookingArgs.title !== undefined) {
|
|
25
24
|
if (isTiptapDocument(bookingArgs.title)) {
|
|
26
|
-
resolved.content.title =
|
|
25
|
+
resolved.content.title = bookingArgs.title;
|
|
27
26
|
resolved.content.titleStyle = resolveGlobalPresetIntoStyle(resolved.content.titleStyle, textStyleOptions);
|
|
28
27
|
}
|
|
29
28
|
else {
|
|
@@ -32,7 +31,7 @@ export class BookingSectionBuilder extends BaseSectionBuilder {
|
|
|
32
31
|
}
|
|
33
32
|
if (bookingArgs.description !== undefined) {
|
|
34
33
|
if (isTiptapDocument(bookingArgs.description)) {
|
|
35
|
-
resolved.content.description =
|
|
34
|
+
resolved.content.description = bookingArgs.description;
|
|
36
35
|
resolved.content.descriptionStyle = resolveGlobalPresetIntoStyle(resolved.content.descriptionStyle, textStyleOptions);
|
|
37
36
|
}
|
|
38
37
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyScalarFields, applyStyleFields, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { BaseSectionBuilder } from './base-section-builder';
|
|
@@ -23,7 +22,7 @@ export class ContactFormBuilder extends BaseSectionBuilder {
|
|
|
23
22
|
const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
|
|
24
23
|
if (args.title !== undefined) {
|
|
25
24
|
if (isTiptapDocument(args.title)) {
|
|
26
|
-
content.title =
|
|
25
|
+
content.title = args.title;
|
|
27
26
|
content.titleStyle = resolveGlobalPresetIntoStyle(content.titleStyle, textStyleOptions);
|
|
28
27
|
}
|
|
29
28
|
else {
|
|
@@ -32,7 +31,7 @@ export class ContactFormBuilder extends BaseSectionBuilder {
|
|
|
32
31
|
}
|
|
33
32
|
if (args.description !== undefined) {
|
|
34
33
|
if (isTiptapDocument(args.description)) {
|
|
35
|
-
content.description =
|
|
34
|
+
content.description = args.description;
|
|
36
35
|
content.descriptionStyle = resolveGlobalPresetIntoStyle(content.descriptionStyle, textStyleOptions);
|
|
37
36
|
}
|
|
38
37
|
else {
|
|
@@ -41,7 +40,7 @@ export class ContactFormBuilder extends BaseSectionBuilder {
|
|
|
41
40
|
}
|
|
42
41
|
if (args.success_message !== undefined) {
|
|
43
42
|
if (isTiptapDocument(args.success_message)) {
|
|
44
|
-
content.successMessage =
|
|
43
|
+
content.successMessage = args.success_message;
|
|
45
44
|
content.successMessageStyle = resolveGlobalPresetIntoStyle(content.successMessageStyle, textStyleOptions);
|
|
46
45
|
}
|
|
47
46
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyScalarFields, applyStyleFields, isValidUrl, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { BaseSectionBuilder } from './base-section-builder';
|
|
@@ -96,7 +95,7 @@ export class ImagesSectionBuilder extends BaseSectionBuilder {
|
|
|
96
95
|
const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
|
|
97
96
|
if (args.title !== undefined) {
|
|
98
97
|
if (isTiptapDocument(args.title)) {
|
|
99
|
-
content.title =
|
|
98
|
+
content.title = args.title;
|
|
100
99
|
content.titleStyle = resolveGlobalPresetIntoStyle(content.titleStyle, textStyleOptions);
|
|
101
100
|
}
|
|
102
101
|
else {
|
|
@@ -105,7 +104,7 @@ export class ImagesSectionBuilder extends BaseSectionBuilder {
|
|
|
105
104
|
}
|
|
106
105
|
if (args.description !== undefined) {
|
|
107
106
|
if (isTiptapDocument(args.description)) {
|
|
108
|
-
content.description =
|
|
107
|
+
content.description = args.description;
|
|
109
108
|
content.descriptionStyle = resolveGlobalPresetIntoStyle(content.descriptionStyle, textStyleOptions);
|
|
110
109
|
}
|
|
111
110
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyScalarFields, applyStyleFields, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { BaseSectionBuilder } from './base-section-builder';
|
|
@@ -23,7 +22,7 @@ export class MailingListBuilder extends BaseSectionBuilder {
|
|
|
23
22
|
const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
|
|
24
23
|
if (mailingListArgs.title !== undefined) {
|
|
25
24
|
if (isTiptapDocument(mailingListArgs.title)) {
|
|
26
|
-
content.title =
|
|
25
|
+
content.title = mailingListArgs.title;
|
|
27
26
|
content.titleStyle = resolveGlobalPresetIntoStyle(content.titleStyle, textStyleOptions);
|
|
28
27
|
}
|
|
29
28
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyScalarFields, applyStyleFields, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { BaseSectionBuilder } from './base-section-builder';
|
|
@@ -22,7 +21,7 @@ export class MailingListSectionBuilder extends BaseSectionBuilder {
|
|
|
22
21
|
const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
|
|
23
22
|
if (mailingListArgs.title !== undefined) {
|
|
24
23
|
if (isTiptapDocument(mailingListArgs.title)) {
|
|
25
|
-
resolved.content.title =
|
|
24
|
+
resolved.content.title = mailingListArgs.title;
|
|
26
25
|
resolved.content.titleStyle = resolveGlobalPresetIntoStyle(resolved.content.titleStyle, textStyleOptions);
|
|
27
26
|
}
|
|
28
27
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyScalarFields, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { BaseSectionBuilder } from './base-section-builder';
|
|
@@ -21,7 +20,7 @@ export class ProfileSectionBuilder extends BaseSectionBuilder {
|
|
|
21
20
|
const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
|
|
22
21
|
if (profileArgs.name !== undefined) {
|
|
23
22
|
if (isTiptapDocument(profileArgs.name)) {
|
|
24
|
-
resolved.content.name =
|
|
23
|
+
resolved.content.name = profileArgs.name;
|
|
25
24
|
resolved.content.nameStyle = resolveGlobalPresetIntoStyle(resolved.content.nameStyle, textStyleOptions);
|
|
26
25
|
}
|
|
27
26
|
else {
|
|
@@ -30,7 +29,7 @@ export class ProfileSectionBuilder extends BaseSectionBuilder {
|
|
|
30
29
|
}
|
|
31
30
|
if (profileArgs.title !== undefined) {
|
|
32
31
|
if (isTiptapDocument(profileArgs.title)) {
|
|
33
|
-
resolved.content.title =
|
|
32
|
+
resolved.content.title = profileArgs.title;
|
|
34
33
|
resolved.content.titleStyle = resolveGlobalPresetIntoStyle(resolved.content.titleStyle, textStyleOptions);
|
|
35
34
|
}
|
|
36
35
|
else {
|
|
@@ -39,7 +38,7 @@ export class ProfileSectionBuilder extends BaseSectionBuilder {
|
|
|
39
38
|
}
|
|
40
39
|
if (profileArgs.description !== undefined) {
|
|
41
40
|
if (isTiptapDocument(profileArgs.description)) {
|
|
42
|
-
resolved.content.description =
|
|
41
|
+
resolved.content.description = profileArgs.description;
|
|
43
42
|
resolved.content.descriptionStyle = resolveGlobalPresetIntoStyle(resolved.content.descriptionStyle, textStyleOptions);
|
|
44
43
|
}
|
|
45
44
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyScalarFields, applyStyleFields, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { applyColorThemeToReplacements, resolveShapeColorReplacementsAsync, } from '../shape-color-utils';
|
|
@@ -117,7 +116,7 @@ export class ShapesSectionBuilder extends BaseSectionBuilder {
|
|
|
117
116
|
const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
|
|
118
117
|
if (args.title !== undefined) {
|
|
119
118
|
if (isTiptapDocument(args.title)) {
|
|
120
|
-
content.title =
|
|
119
|
+
content.title = args.title;
|
|
121
120
|
content.titleStyle = resolveGlobalPresetIntoStyle(content.titleStyle, textStyleOptions);
|
|
122
121
|
}
|
|
123
122
|
else {
|
|
@@ -126,7 +125,7 @@ export class ShapesSectionBuilder extends BaseSectionBuilder {
|
|
|
126
125
|
}
|
|
127
126
|
if (args.description !== undefined) {
|
|
128
127
|
if (isTiptapDocument(args.description)) {
|
|
129
|
-
content.description =
|
|
128
|
+
content.description = args.description;
|
|
130
129
|
content.descriptionStyle = resolveGlobalPresetIntoStyle(content.descriptionStyle, textStyleOptions);
|
|
131
130
|
}
|
|
132
131
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyScalarFields, applyStyleFields, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { applyColorThemeToReplacements, resolveShapeColorReplacementsAsync, } from '../shape-color-utils';
|
|
@@ -103,7 +102,7 @@ export class TestimonialSectionBuilder extends BaseSectionBuilder {
|
|
|
103
102
|
const textStyleOptions = model.styles?.textStyles?.textStyleOptions;
|
|
104
103
|
if (args.title !== undefined) {
|
|
105
104
|
if (isTiptapDocument(args.title)) {
|
|
106
|
-
content.title =
|
|
105
|
+
content.title = args.title;
|
|
107
106
|
content.titleStyle = resolveGlobalPresetIntoStyle(content.titleStyle, textStyleOptions);
|
|
108
107
|
}
|
|
109
108
|
else {
|
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
2
1
|
import { isTiptapDocument, } from '../../parsers/section-tool-arguments';
|
|
3
2
|
import { applyScalarFields, applyStyleFields, resolveGlobalPresetIntoStyle, } from '../section-field-utils';
|
|
4
3
|
import { BaseSectionBuilder } from './base-section-builder';
|
|
5
4
|
import { validateTextSection } from '../section-rules/text-section.rules';
|
|
6
5
|
import { ensureItemIds, generateItemId, removeItemsByIds, repositionItemByAnchor, } from '../item-id-utils';
|
|
7
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a RichTextField to its stored RTE value. BP-5787: Tiptap JSON is
|
|
8
|
+
* stored as-is (no JSON→HTML round-trip — migration-20 is now a one-time
|
|
9
|
+
* legacy conversion), plain strings pass through. `wasTiptap` drives the
|
|
10
|
+
* text-style preset resolution for rich content.
|
|
11
|
+
*/
|
|
8
12
|
const resolveText = (value) => {
|
|
9
13
|
if (isTiptapDocument(value))
|
|
10
|
-
return {
|
|
11
|
-
return {
|
|
14
|
+
return { value, wasTiptap: true };
|
|
15
|
+
return { value: typeof value === 'string' ? value : '', wasTiptap: false };
|
|
12
16
|
};
|
|
13
17
|
const clearTextStyleTypeIfTiptap = (style, wasTiptap, textStyleOptions) => wasTiptap
|
|
14
18
|
? resolveGlobalPresetIntoStyle(style, textStyleOptions)
|
|
15
19
|
: style;
|
|
16
20
|
const createTextItem = (item, baseStyle, textStyleOptions) => {
|
|
17
21
|
const textStyle = (item.text_style ? { ...baseStyle, ...item.text_style } : { ...baseStyle });
|
|
18
|
-
const {
|
|
22
|
+
const { value, wasTiptap } = resolveText(item.text);
|
|
19
23
|
return {
|
|
20
24
|
id: item.item_id || generateItemId(),
|
|
21
|
-
text:
|
|
25
|
+
text: value,
|
|
22
26
|
textStyle: clearTextStyleTypeIfTiptap(textStyle, wasTiptap, textStyleOptions),
|
|
23
27
|
};
|
|
24
28
|
};
|
|
@@ -51,8 +55,8 @@ const mergeTextItems = (content, items, removeIds, textStyleOptions) => {
|
|
|
51
55
|
if (!existing)
|
|
52
56
|
continue;
|
|
53
57
|
if (item.text !== undefined) {
|
|
54
|
-
const {
|
|
55
|
-
existing.text =
|
|
58
|
+
const { value, wasTiptap } = resolveText(item.text);
|
|
59
|
+
existing.text = value;
|
|
56
60
|
existing.textStyle = clearTextStyleTypeIfTiptap(existing.textStyle || {}, wasTiptap, textStyleOptions);
|
|
57
61
|
}
|
|
58
62
|
if (item.text_style && typeof item.text_style === 'object') {
|
|
@@ -76,11 +80,11 @@ const mergeTextItems = (content, items, removeIds, textStyleOptions) => {
|
|
|
76
80
|
*/
|
|
77
81
|
const applySingleTextField = (content, args, textStyleOptions) => {
|
|
78
82
|
if (args.text !== undefined) {
|
|
79
|
-
const {
|
|
83
|
+
const { value, wasTiptap } = resolveText(args.text);
|
|
80
84
|
if (Array.isArray(content.textItems) && content.textItems.length > 0) {
|
|
81
85
|
content.textItems[0] = {
|
|
82
86
|
...content.textItems[0],
|
|
83
|
-
text:
|
|
87
|
+
text: value,
|
|
84
88
|
textStyle: clearTextStyleTypeIfTiptap(content.textItems[0].textStyle || {}, wasTiptap, textStyleOptions),
|
|
85
89
|
};
|
|
86
90
|
}
|
|
@@ -88,7 +92,7 @@ const applySingleTextField = (content, args, textStyleOptions) => {
|
|
|
88
92
|
content.textItems = [
|
|
89
93
|
{
|
|
90
94
|
id: generateItemId(),
|
|
91
|
-
text:
|
|
95
|
+
text: value,
|
|
92
96
|
textStyle: clearTextStyleTypeIfTiptap({ ...(content.textStyle || {}) }, wasTiptap, textStyleOptions),
|
|
93
97
|
},
|
|
94
98
|
];
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import type { TextStyleDeclaration } from '../../brand-page';
|
|
2
|
-
import type { Editor } from '@tiptap/vue-3';
|
|
3
|
-
export declare const applyStyleToRTEText: (externalEditor: Editor, contentText: string, newContentStyle: TextStyleDeclaration) => string;
|
|
4
1
|
/**
|
|
5
2
|
* Converts a Tiptap JSON document (ProseMirror document model) to an HTML
|
|
6
|
-
* string
|
|
3
|
+
* string via Tiptap's schema-driven static renderer (renderRteToHtml →
|
|
4
|
+
* renderToHTMLString). DOM-less and editor-free, so it runs on the server
|
|
5
|
+
* (Nitro/Node), not just the browser — unlike the previous headless-Editor
|
|
6
|
+
* implementation (BP-5787: the AI section builders no longer need a `document`).
|
|
7
7
|
*
|
|
8
8
|
* Returns the value unchanged if it is already a string.
|
|
9
|
-
* Returns an empty string for null/undefined.
|
|
9
|
+
* Returns an empty string for null/undefined or any non-Tiptap-document value.
|
|
10
10
|
*
|
|
11
|
-
* Note:
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* `
|
|
16
|
-
*
|
|
17
|
-
* `BuilderResult.errors`, which the AI-chat retry loop reads via
|
|
18
|
-
* `tool_result.errorMessage` and uses to re-emit a corrected payload.
|
|
11
|
+
* Note: to prevent saved copy being wiped (BP-5669), structural validity of any
|
|
12
|
+
* AI-emitted Tiptap doc is checked upstream by `rteSchemaCheck` in
|
|
13
|
+
* `section-args-validator.ts` against the editor's real ProseMirror schema. The
|
|
14
|
+
* validator surfaces a clear error into `BuilderResult.errors`, which the
|
|
15
|
+
* AI-chat retry loop reads via `tool_result.errorMessage` and uses to re-emit a
|
|
16
|
+
* corrected payload.
|
|
19
17
|
*/
|
|
20
18
|
export declare const tiptapJsonToHtml: (value: unknown) => string;
|
|
@@ -1,85 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { getRenderText } from '../../brand-page/utils';
|
|
4
|
-
import { ESCAPED_NEWLINE_CHARACTER } from '../../constants/ui';
|
|
5
|
-
import { isTiptapDocument, } from '../parsers/section-tool-arguments';
|
|
6
|
-
export const applyStyleToRTEText = (externalEditor, contentText, newContentStyle) => {
|
|
7
|
-
if (!contentText) {
|
|
8
|
-
return contentText;
|
|
9
|
-
}
|
|
10
|
-
const content = contentText.includes(ESCAPED_NEWLINE_CHARACTER)
|
|
11
|
-
? getRenderText(contentText)
|
|
12
|
-
: contentText;
|
|
13
|
-
externalEditor.commands.setContent(content);
|
|
14
|
-
let chain = externalEditor.chain().selectAll();
|
|
15
|
-
if (newContentStyle?.fontFamily) {
|
|
16
|
-
chain = chain.setFontFamily(newContentStyle.fontFamily);
|
|
17
|
-
}
|
|
18
|
-
if (newContentStyle?.fontSize) {
|
|
19
|
-
chain = chain.setFontSize(newContentStyle.fontSize);
|
|
20
|
-
}
|
|
21
|
-
if (newContentStyle?.letterSpacing) {
|
|
22
|
-
chain = chain.setLetterSpacing(newContentStyle.letterSpacing);
|
|
23
|
-
}
|
|
24
|
-
if (newContentStyle?.lineHeight) {
|
|
25
|
-
chain = chain.setLineHeight(newContentStyle.lineHeight);
|
|
26
|
-
}
|
|
27
|
-
if (newContentStyle?.color) {
|
|
28
|
-
chain = chain.setMark('textStyle', {
|
|
29
|
-
color: getRTEColor(newContentStyle.color, 'text'),
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
// Handle backgroundColor
|
|
33
|
-
if ('backgroundColor' in (newContentStyle || {})) {
|
|
34
|
-
chain = newContentStyle.backgroundColor
|
|
35
|
-
? chain.setMark('highlight', {
|
|
36
|
-
color: getRTEColor(newContentStyle.backgroundColor, 'background'),
|
|
37
|
-
})
|
|
38
|
-
: chain.unsetHighlight();
|
|
39
|
-
}
|
|
40
|
-
if (newContentStyle?.textAlign) {
|
|
41
|
-
chain = chain.setTextAlign(newContentStyle.textAlign);
|
|
42
|
-
}
|
|
43
|
-
const hasStrike = newContentStyle?.textDecoration?.includes('line-through');
|
|
44
|
-
const hasUnderline = newContentStyle?.textDecoration?.includes('underline');
|
|
45
|
-
chain = hasStrike ? chain.setStrike() : chain.unsetStrike();
|
|
46
|
-
chain = hasUnderline ? chain.setUnderline() : chain.unsetUnderline();
|
|
47
|
-
chain =
|
|
48
|
-
newContentStyle?.fontWeight === 'bold'
|
|
49
|
-
? chain.setBold()
|
|
50
|
-
: chain.unsetBold();
|
|
51
|
-
chain =
|
|
52
|
-
newContentStyle?.fontStyle === 'italic'
|
|
53
|
-
? chain.setItalic()
|
|
54
|
-
: chain.unsetItalic();
|
|
55
|
-
chain.run();
|
|
56
|
-
const html = externalEditor.getHTML();
|
|
57
|
-
return html;
|
|
58
|
-
};
|
|
1
|
+
import { renderRteToHtml } from '../../brand-page-maker/utils';
|
|
2
|
+
import { isTiptapDocument } from '../parsers/section-tool-arguments';
|
|
59
3
|
/**
|
|
60
4
|
* Converts a Tiptap JSON document (ProseMirror document model) to an HTML
|
|
61
|
-
* string
|
|
5
|
+
* string via Tiptap's schema-driven static renderer (renderRteToHtml →
|
|
6
|
+
* renderToHTMLString). DOM-less and editor-free, so it runs on the server
|
|
7
|
+
* (Nitro/Node), not just the browser — unlike the previous headless-Editor
|
|
8
|
+
* implementation (BP-5787: the AI section builders no longer need a `document`).
|
|
62
9
|
*
|
|
63
10
|
* Returns the value unchanged if it is already a string.
|
|
64
|
-
* Returns an empty string for null/undefined.
|
|
11
|
+
* Returns an empty string for null/undefined or any non-Tiptap-document value.
|
|
65
12
|
*
|
|
66
|
-
* Note:
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* `
|
|
71
|
-
*
|
|
72
|
-
* `BuilderResult.errors`, which the AI-chat retry loop reads via
|
|
73
|
-
* `tool_result.errorMessage` and uses to re-emit a corrected payload.
|
|
13
|
+
* Note: to prevent saved copy being wiped (BP-5669), structural validity of any
|
|
14
|
+
* AI-emitted Tiptap doc is checked upstream by `rteSchemaCheck` in
|
|
15
|
+
* `section-args-validator.ts` against the editor's real ProseMirror schema. The
|
|
16
|
+
* validator surfaces a clear error into `BuilderResult.errors`, which the
|
|
17
|
+
* AI-chat retry loop reads via `tool_result.errorMessage` and uses to re-emit a
|
|
18
|
+
* corrected payload.
|
|
74
19
|
*/
|
|
75
20
|
export const tiptapJsonToHtml = (value) => {
|
|
76
21
|
if (typeof value === 'string')
|
|
77
22
|
return value;
|
|
78
23
|
if (!isTiptapDocument(value))
|
|
79
24
|
return '';
|
|
80
|
-
|
|
81
|
-
externalEditor.commands.setContent(value);
|
|
82
|
-
const html = externalEditor.getHTML();
|
|
83
|
-
externalEditor.destroy();
|
|
84
|
-
return html;
|
|
25
|
+
return renderRteToHtml(value);
|
|
85
26
|
};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import cloneDeep from 'lodash.clonedeep';
|
|
2
2
|
import {} from '../brand-page/models';
|
|
3
3
|
import { BUILDER_TYPES, } from './models';
|
|
4
|
-
import { UpdateContentTextBuilder } from './builders/update-content-text-builder';
|
|
5
|
-
import { UpdateContentTextStyleBuilder } from './builders/update-content-text-style-builder';
|
|
6
4
|
import { BannerSectionBuilder, BookingSectionBuilder, AboutSectionBuilder, ContactFormBuilder, DividerSectionBuilder, TextSectionBuilder, TestimonialSectionBuilder, ImagesSectionBuilder, ShapesSectionBuilder, SocialLinksBuilder, ImageGalleryBuilder, ProfileSectionBuilder, MailingListSectionBuilder, ButtonSectionBuilder, DeleteSectionBuilder, MoveSectionBuilder, } from './builders/section-builders';
|
|
7
5
|
import { AddPageBuilder } from './builders/add-page-builder';
|
|
8
6
|
import { RemovePageBuilder } from './builders/remove-page-builder';
|
|
@@ -15,8 +13,6 @@ import { HeaderBuilder } from './builders/header-builder';
|
|
|
15
13
|
import { UndoBuilder } from './builders/undo-builder';
|
|
16
14
|
// Lazy initialization to avoid circular dependency issues
|
|
17
15
|
const getBuilderRegistry = () => ({
|
|
18
|
-
[BUILDER_TYPES.UPDATE_CONTENT_TEXT]: UpdateContentTextBuilder,
|
|
19
|
-
[BUILDER_TYPES.UPDATE_CONTENT_TEXT_STYLE]: UpdateContentTextStyleBuilder,
|
|
20
16
|
// Section builders (create)
|
|
21
17
|
[BUILDER_TYPES.CREATE_BANNER_SECTION]: BannerSectionBuilder,
|
|
22
18
|
[BUILDER_TYPES.CREATE_BOOKING_SECTION]: BookingSectionBuilder,
|
|
@@ -2,8 +2,6 @@ import { type BrandPageModel } from '../brand-page/models';
|
|
|
2
2
|
import type { EventTracker } from '../brand-page-maker/composables/useEventTracker';
|
|
3
3
|
import type { Logger } from './logger';
|
|
4
4
|
export declare const BUILDER_TYPES: {
|
|
5
|
-
readonly UPDATE_CONTENT_TEXT: "update-content-text";
|
|
6
|
-
readonly UPDATE_CONTENT_TEXT_STYLE: "update-content-text-style";
|
|
7
5
|
readonly CREATE_BANNER_SECTION: "create-banner-section";
|
|
8
6
|
readonly CREATE_ABOUT_SECTION: "create-about-section";
|
|
9
7
|
readonly CREATE_CONTACT_FORM: "create-contact-form";
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import {} from '../brand-page/models';
|
|
2
2
|
export const BUILDER_TYPES = {
|
|
3
|
-
UPDATE_CONTENT_TEXT: 'update-content-text',
|
|
4
|
-
UPDATE_CONTENT_TEXT_STYLE: 'update-content-text-style',
|
|
5
3
|
// Per-section builder types (create)
|
|
6
4
|
CREATE_BANNER_SECTION: 'create-banner-section',
|
|
7
5
|
CREATE_ABOUT_SECTION: 'create-about-section',
|
|
@@ -2,8 +2,6 @@ import type { AiAssistantToolCall } from '../../clients/ai-assistant-client';
|
|
|
2
2
|
import type { FooterDisplayStyle, HeaderDisplayStyle, NavigationDisplayType } from '../../brand-page/constants';
|
|
3
3
|
import type { SectionType, TextStyleArguments } from './section-tool-arguments';
|
|
4
4
|
export declare const AI_ASSISTANT_TOOL_NAMES: {
|
|
5
|
-
readonly UPDATE_TEXT: "updateText";
|
|
6
|
-
readonly UPDATE_STYLE: "updateStyle";
|
|
7
5
|
readonly BUILD_PROFILE_SECTION: "build_profile_section";
|
|
8
6
|
readonly BUILD_TEXT_SECTION: "build_text_section";
|
|
9
7
|
readonly BUILD_IMAGE_SECTION: "build_image_section";
|
|
@@ -49,23 +47,6 @@ export interface ParsedToolCall {
|
|
|
49
47
|
arguments: Record<string, unknown>;
|
|
50
48
|
usage_type?: 'free' | 'paid';
|
|
51
49
|
}
|
|
52
|
-
export interface BaseArguments {
|
|
53
|
-
message?: string;
|
|
54
|
-
}
|
|
55
|
-
export interface UpdateTextToolArguments extends BaseArguments {
|
|
56
|
-
contentId: string;
|
|
57
|
-
fieldName: string;
|
|
58
|
-
metadata: {
|
|
59
|
-
text: string;
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
export interface UpdateStyleToolArguments extends BaseArguments {
|
|
63
|
-
contentId: string;
|
|
64
|
-
fieldName: string;
|
|
65
|
-
metadata: {
|
|
66
|
-
style: BrandPageCssStyle;
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
50
|
export declare const SECTION_TOOL_MAP: Record<string, {
|
|
70
51
|
sectionType: SectionType;
|
|
71
52
|
}>;
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
// Tool names — must match the function names generated by the AI pipeline.
|
|
2
|
-
// Text element tools use camelCase names.
|
|
3
2
|
// Section tools follow the pattern: build_{sectionType}_section
|
|
4
3
|
// where sectionType matches the ContentType value (e.g. 'banner-section', 'profile').
|
|
5
4
|
// The mode ('create' | 'update') is a field in the tool arguments, not the tool name.
|
|
6
5
|
export const AI_ASSISTANT_TOOL_NAMES = {
|
|
7
|
-
// Text element agent tools
|
|
8
|
-
UPDATE_TEXT: 'updateText',
|
|
9
|
-
UPDATE_STYLE: 'updateStyle',
|
|
10
6
|
// Website builder agent tools — unified build
|
|
11
7
|
BUILD_PROFILE_SECTION: 'build_profile_section',
|
|
12
8
|
BUILD_TEXT_SECTION: 'build_text_section',
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { type SectionCheck } from './section-args-validator';
|
|
2
2
|
/**
|
|
3
|
-
* Validates a Tiptap doc against the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* the doc to `<p></p>` (BP-5669).
|
|
3
|
+
* Validates a Tiptap doc against the real ProseMirror schema
|
|
4
|
+
* (`schema.nodeFromJSON`). Catches malformed AI input — stray non-node children
|
|
5
|
+
* in `content`, unknown node types, malformed attrs — before the builder runs
|
|
6
|
+
* and the renderer's silent `setContent` drops the doc to `<p></p>` (BP-5669).
|
|
8
7
|
*
|
|
9
|
-
* Returns the field-prefixed error string so the AI's tool-call retry
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Returns the field-prefixed error string so the AI's tool-call retry loop reads
|
|
9
|
+
* it via `BuilderResult.errors` → `tool_result.errorMessage` and re-emits a
|
|
10
|
+
* corrected payload.
|
|
12
11
|
*/
|
|
13
12
|
export declare const rteSchemaCheck: (field: string) => SectionCheck;
|
|
14
13
|
/**
|