@designcrowd/library.brand-page 5.17.6 → 5.17.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-BI2KuOEF.js → CreatedOnBrandCrowd-de-de-BUQFMhZb.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-BYLJCjLJ.js → CreatedOnBrandCrowd-en-us-QS-5r4XI.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-Y_D6cuGE.js → CreatedOnBrandCrowd-es-es-CP2iH-n0.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-CqCBRjYh.js → CreatedOnBrandCrowd-fr-ca-qfD4NmQZ.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-CqCBRjYh.js → CreatedOnBrandCrowd-fr-fr-qfD4NmQZ.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-Bt0YF6DA.js → CreatedOnBrandCrowd-pt-br-CfmaB7zE.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-Bt0YF6DA.js → CreatedOnBrandCrowd-pt-pt-CfmaB7zE.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-CEk8FBEG.js → CreatedOnDcom-de-de-BxSUWfGN.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-DWw4Tm2L.js → CreatedOnDcom-en-us-CSeUdR6v.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-DpG-8o98.js → CreatedOnDcom-es-es-g7rCfAtP.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-CEla7RmR.js → CreatedOnDcom-fr-ca-Bh_BTb-O.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-DRXeVTlV.js → CreatedOnDcom-fr-fr-Clgd_Ujm.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-Bzu_phZc.js → CreatedOnDcom-pt-br-Dlgk0myX.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-DWax8Er7.js → CreatedOnDcom-pt-pt-B14APfrn.js} +1 -1
  15. package/lib/src/brand-page/models/brand-page-context.model.d.ts +2 -1
  16. package/lib/src/brand-page/models/brand-page-context.model.js +5 -0
  17. package/lib/src/brand-page/models/index.d.ts +1 -0
  18. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +62 -2
  19. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +1 -0
  20. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +60 -2
  21. package/lib/src/brand-page-maker/components/preview/Preview.mixin.d.ts +30 -1
  22. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +60 -2
  23. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +60 -2
  24. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +60 -2
  25. package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +60 -2
  26. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +60 -2
  27. package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +60 -2
  28. package/lib/src/brand-page-maker/composables/ai-chat/useAiChat.js +3 -1
  29. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +1 -1
  30. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +6 -6
  31. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.d.ts +2 -0
  32. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +258 -0
  33. package/lib/src/brand-page-maker/constants/sidebar-constant.d.ts +1 -0
  34. package/lib/src/brand-page-maker/constants/sidebar-constant.js +8 -0
  35. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.d.ts +16 -0
  36. package/lib/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.js +14 -0
  37. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +62 -3
  38. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +2 -0
  39. package/lib/src/brand-page-maker/stores/index.d.ts +1 -0
  40. package/lib/src/brand-page-maker/stores/index.js +1 -0
  41. package/lib/src/brand-page-maker/stores/snapshot/snapshot-store.d.ts +2 -0
  42. package/lib/src/brand-page-maker/stores/snapshot/snapshot-store.js +9 -0
  43. package/lib/src/clients/ai-assistant-client.d.ts +8 -0
  44. package/lib/src/clients/ai-assistant-client.js +11 -1
  45. package/lib/src/composables/useSnapshot.js +33 -0
  46. package/lib/src/css/library.brand-page-brandCrowd.min.css +19 -6
  47. package/lib/src/css/library.brand-page-brandPage.min.css +19 -6
  48. package/lib/src/css/library.brand-page-designCom.min.css +19 -6
  49. package/lib/src/css/library.brand-page-preview.min.css +19 -6
  50. package/lib/src/index.d.ts +1 -0
  51. package/lib/src/index.mjs +42 -41
  52. package/lib/src/{lib-DODSa6QK.js → lib-pOkCQP0J.js} +28820 -26841
  53. package/lib/src/lib.js +1 -0
  54. package/lib/src/metadata-builder/ai-metadata-executor.d.ts +1 -1
  55. package/lib/src/metadata-builder/ai-metadata-executor.js +68 -7
  56. package/lib/src/metadata-builder/builders/add-page-builder.d.ts +14 -0
  57. package/lib/src/metadata-builder/builders/add-page-builder.js +66 -0
  58. package/lib/src/metadata-builder/builders/remove-page-builder.d.ts +13 -0
  59. package/lib/src/metadata-builder/builders/remove-page-builder.js +50 -0
  60. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.d.ts +6 -0
  61. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +17 -0
  62. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.d.ts +6 -0
  63. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +25 -0
  64. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.d.ts +40 -0
  65. package/lib/src/metadata-builder/builders/section-builders/base-section-builder.js +108 -0
  66. package/lib/src/metadata-builder/builders/section-builders/button-section-builder.d.ts +6 -0
  67. package/lib/src/metadata-builder/builders/section-builders/button-section-builder.js +16 -0
  68. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.d.ts +6 -0
  69. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +27 -0
  70. package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.d.ts +13 -0
  71. package/lib/src/metadata-builder/builders/section-builders/delete-section-builder.js +37 -0
  72. package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.d.ts +6 -0
  73. package/lib/src/metadata-builder/builders/section-builders/divider-section-builder.js +16 -0
  74. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.d.ts +6 -0
  75. package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +76 -0
  76. package/lib/src/metadata-builder/builders/section-builders/image-section-builder.d.ts +6 -0
  77. package/lib/src/metadata-builder/builders/section-builders/image-section-builder.js +16 -0
  78. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.d.ts +6 -0
  79. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +158 -0
  80. package/lib/src/metadata-builder/builders/section-builders/index.d.ts +17 -0
  81. package/lib/src/metadata-builder/builders/section-builders/index.js +17 -0
  82. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.d.ts +6 -0
  83. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +17 -0
  84. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.d.ts +6 -0
  85. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +16 -0
  86. package/lib/src/metadata-builder/builders/section-builders/move-section-builder.d.ts +15 -0
  87. package/lib/src/metadata-builder/builders/section-builders/move-section-builder.js +62 -0
  88. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.d.ts +6 -0
  89. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +16 -0
  90. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.d.ts +6 -0
  91. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +162 -0
  92. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.d.ts +6 -0
  93. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +50 -0
  94. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.d.ts +6 -0
  95. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +133 -0
  96. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.d.ts +6 -0
  97. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +154 -0
  98. package/lib/src/metadata-builder/builders/section-content-factory.d.ts +3 -0
  99. package/lib/src/metadata-builder/builders/section-content-factory.js +13 -0
  100. package/lib/src/metadata-builder/builders/section-field-maps.d.ts +12 -0
  101. package/lib/src/metadata-builder/builders/section-field-maps.js +180 -0
  102. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +11 -0
  103. package/lib/src/metadata-builder/builders/section-field-utils.js +109 -0
  104. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +6 -0
  105. package/lib/src/metadata-builder/helpers/rte.helpers.js +16 -1
  106. package/lib/src/metadata-builder/metadata-executor.js +71 -1
  107. package/lib/src/metadata-builder/models.d.ts +54 -0
  108. package/lib/src/metadata-builder/models.js +58 -0
  109. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +51 -3
  110. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +110 -13
  111. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +285 -0
  112. package/lib/src/metadata-builder/parsers/section-tool-arguments.js +7 -0
  113. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +60 -2
  114. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +60 -2
  115. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +60 -2
  116. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +60 -2
  117. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +90 -3
  118. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +61 -2
  119. package/lib/src/shared/side-bar/components/SideBar.mixin.js +6 -0
  120. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +60 -2
  121. package/lib/src/utils/minify-brand-page-metadata.d.ts +22 -0
  122. package/lib/src/utils/minify-brand-page-metadata.js +344 -0
  123. package/package.json +1 -1
  124. package/src/brand-page/models/brand-page-context.model.ts +12 -3
  125. package/src/brand-page/models/index.ts +1 -0
  126. package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +80 -0
  127. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +4 -0
  128. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +9 -2
  129. package/src/brand-page-maker/composables/ai-chat/useAiChat.ts +4 -1
  130. package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +6 -6
  131. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +363 -0
  132. package/src/brand-page-maker/constants/sidebar-constant.ts +8 -0
  133. package/src/brand-page-maker/stores/ai-thread/ai-website-builder-thread-store.ts +19 -0
  134. package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +3 -1
  135. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +4 -0
  136. package/src/brand-page-maker/stores/index.ts +1 -0
  137. package/src/brand-page-maker/stores/snapshot/snapshot-store.ts +12 -0
  138. package/src/clients/ai-assistant-client.ts +17 -1
  139. package/src/composables/useSnapshot.ts +47 -0
  140. package/src/lib.ts +4 -0
  141. package/src/metadata-builder/ai-metadata-executor.ts +116 -26
  142. package/src/metadata-builder/builders/add-page-builder.ts +98 -0
  143. package/src/metadata-builder/builders/remove-page-builder.ts +83 -0
  144. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +28 -0
  145. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +45 -0
  146. package/src/metadata-builder/builders/section-builders/base-section-builder.ts +160 -0
  147. package/src/metadata-builder/builders/section-builders/button-section-builder.ts +24 -0
  148. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +43 -0
  149. package/src/metadata-builder/builders/section-builders/delete-section-builder.ts +63 -0
  150. package/src/metadata-builder/builders/section-builders/divider-section-builder.ts +27 -0
  151. package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +111 -0
  152. package/src/metadata-builder/builders/section-builders/image-section-builder.ts +24 -0
  153. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +223 -0
  154. package/src/metadata-builder/builders/section-builders/index.ts +21 -0
  155. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +29 -0
  156. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +27 -0
  157. package/src/metadata-builder/builders/section-builders/move-section-builder.ts +100 -0
  158. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +27 -0
  159. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +231 -0
  160. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +79 -0
  161. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +194 -0
  162. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +234 -0
  163. package/src/metadata-builder/builders/section-content-factory.ts +20 -0
  164. package/src/metadata-builder/builders/section-field-maps.ts +235 -0
  165. package/src/metadata-builder/builders/section-field-utils.ts +157 -0
  166. package/src/metadata-builder/helpers/rte.helpers.ts +23 -1
  167. package/src/metadata-builder/metadata-executor.ts +96 -4
  168. package/src/metadata-builder/models.ts +62 -0
  169. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +141 -17
  170. package/src/metadata-builder/parsers/section-tool-arguments.ts +417 -0
  171. package/src/shared/side-bar/components/SideBar.mixin.ts +10 -0
  172. package/src/utils/minify-brand-page-metadata.ts +407 -0
@@ -0,0 +1,50 @@
1
+ import { applyScalarFields } from '../section-field-utils';
2
+ import { BaseSectionBuilder } from './base-section-builder';
3
+ const applySocialLinks = (content, links) => {
4
+ content.links = links.map((link) => ({
5
+ imageUrl: link.platform || '',
6
+ imageTitle: '',
7
+ width: 0,
8
+ height: 0,
9
+ imageLink: '',
10
+ url: link.url || '',
11
+ }));
12
+ };
13
+ const mergeSocialLinks = (content, links, replaceAll) => {
14
+ const updatedLinks = links.map((link, index) => {
15
+ const existing = content.links?.[index];
16
+ return {
17
+ ...(existing || {}),
18
+ imageUrl: link.platform ?? existing?.imageUrl ?? '',
19
+ url: link.url ?? existing?.url ?? '',
20
+ };
21
+ });
22
+ if (!replaceAll && content.links && content.links.length > links.length) {
23
+ updatedLinks.push(...content.links.slice(links.length));
24
+ }
25
+ content.links = updatedLinks;
26
+ };
27
+ export class SocialLinksBuilder extends BaseSectionBuilder {
28
+ async buildAsync(model) {
29
+ this.log('Build called');
30
+ const validation = await this.validateAsync();
31
+ if (validation.errors.length) {
32
+ return { request: this.request, model, errors: validation.errors };
33
+ }
34
+ const resolved = this.resolveContent(model);
35
+ if ('error' in resolved)
36
+ return resolved.error;
37
+ const content = resolved.content;
38
+ applyScalarFields(content, this.args, this.sectionType);
39
+ const args = this.args;
40
+ if (args.links && Array.isArray(args.links)) {
41
+ if (this.mode === 'create') {
42
+ applySocialLinks(content, args.links);
43
+ }
44
+ else {
45
+ mergeSocialLinks(content, args.links, !!args._replace_items);
46
+ }
47
+ }
48
+ return { request: this.request, model };
49
+ }
50
+ }
@@ -0,0 +1,6 @@
1
+ import type { TestimonialSectionContent, BrandPageModel } from '../../../brand-page/models';
2
+ import type { BuilderResult } from '../../models';
3
+ import { BaseSectionBuilder } from './base-section-builder';
4
+ export declare class TestimonialSectionBuilder extends BaseSectionBuilder<TestimonialSectionContent> {
5
+ buildAsync(model: BrandPageModel): Promise<BuilderResult>;
6
+ }
@@ -0,0 +1,133 @@
1
+ import { applyScalarFields, applyStyleFields } from '../section-field-utils';
2
+ import { BaseSectionBuilder } from './base-section-builder';
3
+ const applyTestimonialItems = (content, items) => {
4
+ content.items = items.map((item) => ({
5
+ imageUrl: item.avatar_image_url || '',
6
+ name: item.name || '',
7
+ position: item.position || '',
8
+ testimonials: item.testimonial || '',
9
+ colorReplacements: [],
10
+ mediaType: 'image',
11
+ }));
12
+ };
13
+ const mergeTestimonialItems = (content, items, replaceAll) => {
14
+ const hasIndexedItems = items.some((item) => item.item_index !== undefined);
15
+ if (hasIndexedItems) {
16
+ for (const item of items) {
17
+ const targetIndex = item.item_index;
18
+ if (targetIndex === undefined ||
19
+ targetIndex < 0 ||
20
+ !content.items?.[targetIndex])
21
+ continue;
22
+ const existing = content.items[targetIndex];
23
+ if (item.avatar_image_url !== undefined)
24
+ existing.imageUrl = item.avatar_image_url;
25
+ if (item.name !== undefined)
26
+ existing.name = item.name;
27
+ if (item.position !== undefined)
28
+ existing.position = item.position;
29
+ if (item.testimonial !== undefined)
30
+ existing.testimonials = item.testimonial;
31
+ }
32
+ return;
33
+ }
34
+ const updatedItems = items.map((item, index) => {
35
+ const existing = content.items?.[index];
36
+ return {
37
+ ...(existing || {}),
38
+ imageUrl: item.avatar_image_url ?? existing?.imageUrl ?? '',
39
+ name: item.name ?? existing?.name ?? '',
40
+ position: item.position ?? existing?.position ?? '',
41
+ testimonials: item.testimonial ?? existing?.testimonials ?? '',
42
+ colorReplacements: existing?.colorReplacements ?? [],
43
+ mediaType: existing?.mediaType ?? 'image',
44
+ };
45
+ });
46
+ if (!replaceAll && content.items && content.items.length > items.length) {
47
+ updatedItems.push(...content.items.slice(items.length));
48
+ }
49
+ content.items = updatedItems;
50
+ };
51
+ export class TestimonialSectionBuilder extends BaseSectionBuilder {
52
+ async buildAsync(model) {
53
+ this.log('Build called');
54
+ const validation = await this.validateAsync();
55
+ if (validation.errors.length) {
56
+ return { request: this.request, model, errors: validation.errors };
57
+ }
58
+ const resolved = this.resolveContent(model);
59
+ if ('error' in resolved)
60
+ return resolved.error;
61
+ const content = resolved.content;
62
+ applyScalarFields(content, this.args, this.sectionType);
63
+ applyStyleFields(content, this.args, this.sectionType);
64
+ const args = this.args;
65
+ if (args.background_style && typeof args.background_style === 'object') {
66
+ const existing = content.backgroundStyle || {};
67
+ content.backgroundStyle = {
68
+ ...existing,
69
+ ...Object.fromEntries(Object.entries(args.background_style).map(([k, v]) => [
70
+ k,
71
+ v === null ? '' : v,
72
+ ])),
73
+ };
74
+ }
75
+ if (args.card_style && typeof args.card_style === 'object') {
76
+ const existing = content.cardStyle || {};
77
+ content.cardStyle = {
78
+ ...existing,
79
+ ...Object.fromEntries(Object.entries(args.card_style).map(([k, v]) => [
80
+ k,
81
+ v === null ? '' : v,
82
+ ])),
83
+ };
84
+ }
85
+ if (args.items && Array.isArray(args.items)) {
86
+ if (this.mode === 'create') {
87
+ applyTestimonialItems(content, args.items);
88
+ }
89
+ else {
90
+ mergeTestimonialItems(content, args.items, !!args._replace_items);
91
+ }
92
+ }
93
+ // Phase 2: Item operations (remove, insert, reorder)
94
+ if (args._remove_item_indices?.length && content.items) {
95
+ const sorted = [...args._remove_item_indices].sort((a, b) => b - a);
96
+ for (const idx of sorted) {
97
+ if (idx >= 0 && idx < content.items.length) {
98
+ content.items.splice(idx, 1);
99
+ }
100
+ }
101
+ }
102
+ if (args.items && Array.isArray(args.items)) {
103
+ const insertItems = args.items.filter((item) => item.insert_at !== undefined && item.item_index === undefined);
104
+ const sortedInserts = [...insertItems].sort((a, b) => (b.insert_at ?? 0) - (a.insert_at ?? 0));
105
+ for (const item of sortedInserts) {
106
+ const pos = Math.max(0, Math.min(item.insert_at ?? 0, content.items?.length ?? 0));
107
+ const newItem = {
108
+ imageUrl: item.avatar_image_url ?? '',
109
+ name: item.name ?? '',
110
+ position: item.position ?? '',
111
+ testimonials: item.testimonial ?? '',
112
+ colorReplacements: [],
113
+ mediaType: 'image',
114
+ };
115
+ content.items = content.items ?? [];
116
+ content.items.splice(pos, 0, newItem);
117
+ }
118
+ }
119
+ if (args._reorder_items?.length && content.items) {
120
+ const newOrder = args._reorder_items;
121
+ const unique = new Set(newOrder);
122
+ if (unique.size === newOrder.length) {
123
+ const reordered = newOrder
124
+ .filter((idx) => idx >= 0 && idx < content.items.length)
125
+ .map((idx) => content.items[idx]);
126
+ if (reordered.length === content.items.length) {
127
+ content.items = reordered;
128
+ }
129
+ }
130
+ }
131
+ return { request: this.request, model };
132
+ }
133
+ }
@@ -0,0 +1,6 @@
1
+ import type { BuilderResult } from '../../models';
2
+ import type { TextContent, BrandPageModel } from '../../../brand-page/models';
3
+ import { BaseSectionBuilder } from './base-section-builder';
4
+ export declare class TextSectionBuilder extends BaseSectionBuilder<TextContent> {
5
+ buildAsync(model: BrandPageModel): Promise<BuilderResult>;
6
+ }
@@ -0,0 +1,154 @@
1
+ import { updateRTEText } from '../../helpers/rte.helpers';
2
+ import { applyScalarFields, applyStyleFields } from '../section-field-utils';
3
+ import { BaseSectionBuilder } from './base-section-builder';
4
+ const createTextItem = (item, baseStyle) => {
5
+ const textStyle = (item.text_style ? { ...baseStyle, ...item.text_style } : { ...baseStyle });
6
+ return {
7
+ text: item.text || '',
8
+ textStyle,
9
+ };
10
+ };
11
+ const applyTextItems = (content, items) => {
12
+ content.textItems = items.map((item) => createTextItem(item, content.textStyle || {}));
13
+ };
14
+ const mergeTextItems = (content, items, replaceAll) => {
15
+ const hasIndexedItems = items.some((item) => item.item_index !== undefined);
16
+ if (hasIndexedItems) {
17
+ for (const item of items) {
18
+ const targetIndex = item.item_index;
19
+ if (targetIndex === undefined ||
20
+ targetIndex < 0 ||
21
+ !content.textItems?.[targetIndex])
22
+ continue;
23
+ const existing = content.textItems[targetIndex];
24
+ if (item.text !== undefined)
25
+ existing.text = item.text;
26
+ if (item.text_style && typeof item.text_style === 'object') {
27
+ const mergedStyle = (item.text_style
28
+ ? { ...(existing.textStyle || {}), ...item.text_style }
29
+ : existing.textStyle || {});
30
+ existing.textStyle = mergedStyle;
31
+ existing.text = updateRTEText(existing.text, mergedStyle);
32
+ }
33
+ }
34
+ return;
35
+ }
36
+ const updatedItems = items.map((item, index) => {
37
+ const existing = content.textItems?.[index];
38
+ const baseStyle = existing?.textStyle || content.textStyle || {};
39
+ const mergedStyle = (item.text_style ? { ...baseStyle, ...item.text_style } : baseStyle);
40
+ const text = item.text ?? existing?.text ?? '';
41
+ return {
42
+ text: item.text_style ? updateRTEText(text, mergedStyle) : text,
43
+ textStyle: mergedStyle,
44
+ };
45
+ });
46
+ if (!replaceAll &&
47
+ content.textItems &&
48
+ content.textItems.length > items.length) {
49
+ updatedItems.push(...content.textItems.slice(items.length));
50
+ }
51
+ content.textItems = updatedItems;
52
+ };
53
+ /**
54
+ * Handles the single `text` + `text_style` fields (BrandPage/BrandContact
55
+ * or shorthand for the first item).
56
+ */
57
+ const applySingleTextField = (content, args) => {
58
+ if (typeof args.text === 'string') {
59
+ if (Array.isArray(content.textItems) && content.textItems.length > 0) {
60
+ content.textItems[0] = {
61
+ ...content.textItems[0],
62
+ text: args.text,
63
+ };
64
+ }
65
+ else {
66
+ content.textItems = [
67
+ {
68
+ text: args.text,
69
+ textStyle: { ...(content.textStyle || {}) },
70
+ },
71
+ ];
72
+ }
73
+ }
74
+ if (args.text_style &&
75
+ typeof args.text_style === 'object' &&
76
+ Array.isArray(content.textItems) &&
77
+ content.textItems.length > 0) {
78
+ const mergedStyle = {
79
+ ...(content.textItems[0].textStyle || {}),
80
+ ...(content.textStyle || {}),
81
+ };
82
+ content.textItems[0] = {
83
+ ...content.textItems[0],
84
+ textStyle: mergedStyle,
85
+ text: updateRTEText(content.textItems[0].text, mergedStyle),
86
+ };
87
+ }
88
+ };
89
+ export class TextSectionBuilder extends BaseSectionBuilder {
90
+ async buildAsync(model) {
91
+ this.log('Build called');
92
+ const validation = await this.validateAsync();
93
+ if (validation.errors.length) {
94
+ return { request: this.request, model, errors: validation.errors };
95
+ }
96
+ const resolved = this.resolveContent(model);
97
+ if ('error' in resolved)
98
+ return resolved.error;
99
+ const content = resolved.content;
100
+ applyScalarFields(content, this.args, this.sectionType);
101
+ applyStyleFields(content, this.args, this.sectionType);
102
+ const args = this.args;
103
+ if (args.items && Array.isArray(args.items)) {
104
+ if (this.mode === 'create') {
105
+ applyTextItems(content, args.items);
106
+ }
107
+ else {
108
+ mergeTextItems(content, args.items, !!args._replace_items);
109
+ }
110
+ }
111
+ else {
112
+ applySingleTextField(content, args);
113
+ }
114
+ // Phase 2: Item operations (remove, insert, reorder)
115
+ if (args._remove_item_indices?.length && content.textItems) {
116
+ const sorted = [...args._remove_item_indices].sort((a, b) => b - a);
117
+ for (const idx of sorted) {
118
+ if (idx >= 0 && idx < content.textItems.length) {
119
+ content.textItems.splice(idx, 1);
120
+ }
121
+ }
122
+ }
123
+ if (args.items && Array.isArray(args.items)) {
124
+ const insertItems = args.items.filter((item) => item.insert_at !== undefined && item.item_index === undefined);
125
+ const sortedInserts = [...insertItems].sort((a, b) => (b.insert_at ?? 0) - (a.insert_at ?? 0));
126
+ for (const item of sortedInserts) {
127
+ const pos = Math.max(0, Math.min(item.insert_at ?? 0, content.textItems?.length ?? 0));
128
+ const baseStyle = content.textStyle || {};
129
+ const textStyle = (item.text_style
130
+ ? { ...baseStyle, ...item.text_style }
131
+ : { ...baseStyle });
132
+ const newItem = {
133
+ text: item.text ?? '',
134
+ textStyle,
135
+ };
136
+ content.textItems = content.textItems ?? [];
137
+ content.textItems.splice(pos, 0, newItem);
138
+ }
139
+ }
140
+ if (args._reorder_items?.length && content.textItems) {
141
+ const newOrder = args._reorder_items;
142
+ const unique = new Set(newOrder);
143
+ if (unique.size === newOrder.length) {
144
+ const reordered = newOrder
145
+ .filter((idx) => idx >= 0 && idx < content.textItems.length)
146
+ .map((idx) => content.textItems[idx]);
147
+ if (reordered.length === content.textItems.length) {
148
+ content.textItems = reordered;
149
+ }
150
+ }
151
+ }
152
+ return { request: this.request, model };
153
+ }
154
+ }
@@ -0,0 +1,3 @@
1
+ import type { Content } from '../../brand-page/models';
2
+ import type { SectionType } from '../parsers/section-tool-arguments';
3
+ export declare const createDefaultSectionContent: (sectionType: SectionType) => Content | null;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Factory that creates default Content objects for each section type.
3
+ * Used by BaseSectionBuilder when adding a new section to a page.
4
+ */
5
+ import { CONTENT_SETTINGS_CONFIGS } from '../../brand-page-maker/constants/config-settings-constant';
6
+ export const createDefaultSectionContent = (sectionType) => {
7
+ const configs = CONTENT_SETTINGS_CONFIGS();
8
+ const config = configs[sectionType];
9
+ if (!config) {
10
+ return null;
11
+ }
12
+ return config.createInitialContent();
13
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Maps AI tool call argument names → BrandPageModel content field names
3
+ * per section type.
4
+ *
5
+ * Reference: service.ai-pipelines/src/agents/website/section_schemas.py
6
+ * Reference: library.brand-page/src/brand-page/models/index.ts
7
+ */
8
+ export type SectionFieldMap = Record<string, string>;
9
+ export declare const SECTION_FIELD_MAPS: Record<string, SectionFieldMap>;
10
+ export declare const getSectionFieldMap: (sectionType: string) => SectionFieldMap | undefined;
11
+ export declare const STYLE_FIELD_MAPS: Record<string, SectionFieldMap>;
12
+ export declare const getStyleFieldMap: (sectionType: string) => SectionFieldMap | undefined;
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Maps AI tool call argument names → BrandPageModel content field names
3
+ * per section type.
4
+ *
5
+ * Reference: service.ai-pipelines/src/agents/website/section_schemas.py
6
+ * Reference: library.brand-page/src/brand-page/models/index.ts
7
+ */
8
+ /**
9
+ * Identity function that validates field map values are actual properties
10
+ * of the given Content subtype at compile time.
11
+ */
12
+ function defineFieldMap(map) {
13
+ return map;
14
+ }
15
+ const bannerFields = defineFieldMap({
16
+ title: 'title',
17
+ description: 'description',
18
+ button_text: 'buttonText',
19
+ button_url: 'url',
20
+ background_image_url: 'imageUrl',
21
+ display_style: 'displayStyle',
22
+ });
23
+ const aboutFields = defineFieldMap({
24
+ title: 'title',
25
+ paragraph: 'paragraph',
26
+ about_image_url: 'imageUrl',
27
+ display_style: 'displayStyle',
28
+ });
29
+ const testimonialFields = defineFieldMap({
30
+ title: 'title',
31
+ display_style: 'displayStyle',
32
+ // items handled separately
33
+ });
34
+ const imagesSectionFields = defineFieldMap({
35
+ title: 'title',
36
+ description: 'description',
37
+ display_style: 'displayStyle',
38
+ aspect_ratio: 'aspectRatio',
39
+ are_images_full_width: 'areImagesFullWidth',
40
+ // items handled separately
41
+ });
42
+ const shapesSectionFields = defineFieldMap({
43
+ title: 'title',
44
+ description: 'description',
45
+ display_style: 'displayStyle',
46
+ size: 'size',
47
+ // items handled separately
48
+ });
49
+ const textFields = defineFieldMap({
50
+ text: 'text',
51
+ });
52
+ const profileFields = defineFieldMap({
53
+ name: 'name',
54
+ title: 'title',
55
+ description: 'description',
56
+ avatar_image_url: 'avatarImageUrl',
57
+ });
58
+ const contactFormFields = defineFieldMap({
59
+ title: 'title',
60
+ description: 'description',
61
+ button_text: 'buttonText',
62
+ success_message: 'successMessage',
63
+ response_email: 'responseEmail',
64
+ header_image_url: 'imageUrl',
65
+ display_style: 'displayStyle',
66
+ layout_style: 'layoutStyle',
67
+ });
68
+ const mailingListFields = defineFieldMap({
69
+ title: 'title',
70
+ button_text: 'buttonText',
71
+ });
72
+ const socialLinksFields = defineFieldMap({
73
+ title: 'title',
74
+ icon_style: 'iconDisplayStyle',
75
+ // links handled separately
76
+ });
77
+ const dividerFields = defineFieldMap({
78
+ divider_style: 'dividerStyle',
79
+ });
80
+ const imageFields = defineFieldMap({
81
+ image_url: 'imageUrl',
82
+ image_title: 'imageTitle',
83
+ });
84
+ const imageGalleryFields = defineFieldMap({
85
+ // images handled separately
86
+ });
87
+ const buttonWithIconFields = defineFieldMap({
88
+ title: 'title',
89
+ url: 'url',
90
+ icon_image_url: 'iconUrl',
91
+ });
92
+ const emailButtonFields = defineFieldMap({
93
+ title: 'title',
94
+ email: 'url',
95
+ icon_image_url: 'iconUrl',
96
+ });
97
+ const phoneButtonFields = defineFieldMap({
98
+ title: 'title',
99
+ phone_number: 'url',
100
+ icon_image_url: 'iconUrl',
101
+ });
102
+ const socialButtonFields = defineFieldMap({
103
+ title: 'title',
104
+ url: 'url',
105
+ });
106
+ export const SECTION_FIELD_MAPS = {
107
+ 'banner-section': bannerFields,
108
+ 'about-section': aboutFields,
109
+ 'testimonial-section': testimonialFields,
110
+ 'images-section': imagesSectionFields,
111
+ 'shapes-section': shapesSectionFields,
112
+ text: textFields,
113
+ profile: profileFields,
114
+ 'contact-form': contactFormFields,
115
+ 'mailing-list': mailingListFields,
116
+ 'social-links': socialLinksFields,
117
+ 'divider-section': dividerFields,
118
+ image: imageFields,
119
+ 'image-gallery': imageGalleryFields,
120
+ 'general-link': buttonWithIconFields,
121
+ website: buttonWithIconFields,
122
+ email: emailButtonFields,
123
+ phone: phoneButtonFields,
124
+ facebook: socialButtonFields,
125
+ x: socialButtonFields,
126
+ instagram: socialButtonFields,
127
+ youtube: socialButtonFields,
128
+ linkedin: socialButtonFields,
129
+ pinterest: socialButtonFields,
130
+ twitch: socialButtonFields,
131
+ tiktok: socialButtonFields,
132
+ };
133
+ export const getSectionFieldMap = (sectionType) => {
134
+ return SECTION_FIELD_MAPS[sectionType];
135
+ };
136
+ const bannerStyleFields = defineFieldMap({
137
+ title_style: 'titleStyle',
138
+ description_style: 'descriptionStyle',
139
+ button_text_style: 'buttonTextStyle',
140
+ });
141
+ const aboutStyleFields = defineFieldMap({
142
+ title_style: 'titleStyle',
143
+ paragraph_style: 'paragraphStyle',
144
+ });
145
+ const textStyleFields = defineFieldMap({
146
+ text_style: 'textStyle',
147
+ });
148
+ const testimonialStyleFields = defineFieldMap({
149
+ title_style: 'titleStyle',
150
+ testimonial_style: 'testimonialStyle',
151
+ name_style: 'nameStyle',
152
+ position_style: 'positionStyle',
153
+ });
154
+ const contactFormStyleFields = defineFieldMap({
155
+ title_style: 'titleStyle',
156
+ description_style: 'descriptionStyle',
157
+ button_text_style: 'buttonTextStyle',
158
+ });
159
+ const imagesSectionStyleFields = defineFieldMap({
160
+ title_style: 'titleStyle',
161
+ description_style: 'descriptionStyle',
162
+ heading_style: 'headingStyle',
163
+ paragraph_style: 'paragraphStyle',
164
+ });
165
+ const shapesSectionStyleFields = defineFieldMap({
166
+ title_style: 'titleStyle',
167
+ description_style: 'descriptionStyle',
168
+ heading_style: 'headingStyle',
169
+ paragraph_style: 'paragraphStyle',
170
+ });
171
+ export const STYLE_FIELD_MAPS = {
172
+ 'banner-section': bannerStyleFields,
173
+ 'about-section': aboutStyleFields,
174
+ text: textStyleFields,
175
+ 'testimonial-section': testimonialStyleFields,
176
+ 'contact-form': contactFormStyleFields,
177
+ 'images-section': imagesSectionStyleFields,
178
+ 'shapes-section': shapesSectionStyleFields,
179
+ };
180
+ export const getStyleFieldMap = (sectionType) => STYLE_FIELD_MAPS[sectionType];
@@ -0,0 +1,11 @@
1
+ import type { Content } from '../../brand-page/models';
2
+ import type { SectionToolArguments } from '../parsers/section-tool-arguments';
3
+ export declare const applyScalarFields: (content: Content, args: SectionToolArguments, sectionType: string) => void;
4
+ export declare const applyStyleFields: (content: Content, args: SectionToolArguments, sectionType: string) => void;
5
+ /**
6
+ * Re-applies merged styles to RTE content fields after applyStyleFields has
7
+ * updated the style objects. Only runs for section types that support RTE
8
+ * (defined by RTE_ALLOWED_SECTION_TYPES) and only touches fields in the
9
+ * RTE_ALLOWED_FIELDS list.
10
+ */
11
+ export declare const applyRTEStyles: (content: Content, args: SectionToolArguments, sectionType: string) => void;