@designcrowd/library.brand-page 6.1.0-websitev2-dev-2 → 6.1.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.
Files changed (97) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-D_qQ0sPW.js → CreatedOnBrandCrowd-de-de-CW5bD06L.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-CNMxavFU.js → CreatedOnBrandCrowd-en-us-CofG4e3V.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-Cyaiw1-R.js → CreatedOnBrandCrowd-es-es-XpL0-LWx.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-DbniOtuE.js → CreatedOnBrandCrowd-fr-ca-dlVN3zaX.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-DbniOtuE.js → CreatedOnBrandCrowd-fr-fr-dlVN3zaX.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-DI3JfwR8.js → CreatedOnBrandCrowd-pt-br-98gqdDVF.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-DI3JfwR8.js → CreatedOnBrandCrowd-pt-pt-98gqdDVF.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-DqBzJ_O9.js → CreatedOnDcom-de-de-Dbmlc0i1.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-B8uZjYMi.js → CreatedOnDcom-en-us-Dy9z7h1o.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-BOLxcx3H.js → CreatedOnDcom-es-es-B3ksvNj9.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-CbGneDvu.js → CreatedOnDcom-fr-ca-CC9ieRzX.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-B-UwXpW3.js → CreatedOnDcom-fr-fr-BtnGJjF2.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-CRPrLx5_.js → CreatedOnDcom-pt-br-DT4doFYO.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-4p2rdAnc.js → CreatedOnDcom-pt-pt-CloXyOe6.js} +1 -1
  15. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +3 -5
  16. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.js +4 -6
  17. package/lib/src/brand-page/components/page-footer/PageFooter.mixin.d.ts +0 -1
  18. package/lib/src/brand-page/components/page-footer/PageFooter.mixin.js +1 -4
  19. package/lib/src/brand-page/components/payment/Payment.mixin.js +3 -4
  20. package/lib/src/brand-page/components/payment/__fixtures__/request-payment.d.ts +0 -1
  21. package/lib/src/brand-page/components/payment/__fixtures__/support-me.d.ts +0 -1
  22. package/lib/src/brand-page/components/payment/request-payment/RequestPayment.mixin.d.ts +0 -1
  23. package/lib/src/brand-page/components/payment/request-payment/RequestPayment.mixin.js +1 -4
  24. package/lib/src/brand-page/composables/consent.composable.d.ts +0 -2
  25. package/lib/src/brand-page/composables/consent.composable.js +3 -9
  26. package/lib/src/brand-page/models/brand-page-context.model.d.ts +0 -7
  27. package/lib/src/brand-page/utils/context.util.d.ts +0 -8
  28. package/lib/src/brand-page/utils/context.util.js +0 -8
  29. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +3 -7
  30. package/lib/src/clients/ai-assistant-client.d.ts +0 -1
  31. package/lib/src/clients/ai-assistant-client.js +0 -1
  32. package/lib/src/css/library.brand-page-brandCrowd.min.css +60 -60
  33. package/lib/src/css/library.brand-page-brandPage.min.css +60 -60
  34. package/lib/src/css/library.brand-page-designCom.min.css +60 -60
  35. package/lib/src/css/library.brand-page-preview.min.css +60 -60
  36. package/lib/src/index.d.ts +0 -1
  37. package/lib/src/index.mjs +217 -220
  38. package/lib/src/{lib-DhEJMZFn.js → lib-D7ubPlpu.js} +18168 -18341
  39. package/lib/src/lib.js +0 -1
  40. package/lib/src/metadata-builder/builders/global-styles-builder.js +0 -16
  41. package/lib/src/metadata-builder/builders/section-builders/index.d.ts +0 -1
  42. package/lib/src/metadata-builder/builders/section-builders/index.js +0 -1
  43. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +2 -5
  44. package/lib/src/metadata-builder/builders/section-field-maps.js +0 -15
  45. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +1 -6
  46. package/lib/src/metadata-builder/builders/section-field-utils.js +12 -48
  47. package/lib/src/metadata-builder/metadata-executor.js +1 -3
  48. package/lib/src/metadata-builder/models.d.ts +0 -2
  49. package/lib/src/metadata-builder/models.js +0 -2
  50. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +0 -1
  51. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +0 -4
  52. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +2 -14
  53. package/lib/src/utils/minify-brand-page-metadata.js +0 -7
  54. package/package.json +1 -1
  55. package/src/brand-page/components/contact-form/ContactForm.mixin.ts +2 -7
  56. package/src/brand-page/components/cookie-consent/CookieConsent.vue +0 -1
  57. package/src/brand-page/components/mailing-list/MailingList.mixin.ts +3 -8
  58. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.vue +1 -5
  59. package/src/brand-page/components/page-footer/PageFooter.mixin.ts +1 -4
  60. package/src/brand-page/components/page-footer/PageFooter.vue +1 -1
  61. package/src/brand-page/components/payment/Payment.mixin.ts +3 -4
  62. package/src/brand-page/components/payment/request-payment/RequestPayment.mixin.ts +1 -8
  63. package/src/brand-page/components/payment/request-payment/RequestPayment.vue +1 -1
  64. package/src/brand-page/components/save-contact/SaveContactWidget.vue +1 -2
  65. package/src/brand-page/components/shop/Shop.vue +3 -6
  66. package/src/brand-page/components/social-links/SocialLinks.vue +2 -5
  67. package/src/brand-page/composables/consent.composable.ts +4 -18
  68. package/src/brand-page/models/brand-page-context.model.ts +0 -7
  69. package/src/brand-page/utils/context.util.ts +0 -10
  70. package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +1 -1
  71. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +3 -7
  72. package/src/clients/ai-assistant-client.ts +0 -1
  73. package/src/lib.ts +0 -1
  74. package/src/metadata-builder/builders/global-styles-builder.ts +0 -21
  75. package/src/metadata-builder/builders/section-builders/index.ts +0 -1
  76. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +2 -5
  77. package/src/metadata-builder/builders/section-field-maps.ts +0 -18
  78. package/src/metadata-builder/builders/section-field-utils.ts +18 -69
  79. package/src/metadata-builder/metadata-executor.ts +0 -3
  80. package/src/metadata-builder/models.ts +0 -2
  81. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +0 -4
  82. package/src/metadata-builder/parsers/section-tool-arguments.ts +1 -14
  83. package/src/utils/minify-brand-page-metadata.ts +0 -8
  84. package/lib/src/metadata-builder/builders/global-font-propagation.d.ts +0 -28
  85. package/lib/src/metadata-builder/builders/global-font-propagation.js +0 -125
  86. package/lib/src/metadata-builder/builders/section-builders/support-me-builder.d.ts +0 -8
  87. package/lib/src/metadata-builder/builders/section-builders/support-me-builder.js +0 -25
  88. package/lib/src/metadata-builder/builders/section-rules/support-me.rules.d.ts +0 -2
  89. package/lib/src/metadata-builder/builders/section-rules/support-me.rules.js +0 -17
  90. package/src/brand-page/utils/context.util.test.ts +0 -43
  91. package/src/metadata-builder/builders/global-font-propagation.test.ts +0 -269
  92. package/src/metadata-builder/builders/global-font-propagation.ts +0 -205
  93. package/src/metadata-builder/builders/section-builders/support-me-builder.test.ts +0 -177
  94. package/src/metadata-builder/builders/section-builders/support-me-builder.ts +0 -43
  95. package/src/metadata-builder/builders/section-field-utils.test.ts +0 -83
  96. package/src/metadata-builder/builders/section-rules/support-me.rules.ts +0 -39
  97. package/src/utils/minify-brand-page-metadata.test.ts +0 -61
@@ -1,177 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import type {
3
- BrandPageModel,
4
- SupportMeContent,
5
- } from '../../../brand-page/models';
6
- import { BUILDER_TYPES } from '../../models';
7
- import type { SupportMeArguments } from '../../parsers/section-tool-arguments';
8
- import { SupportMeBuilder } from './support-me-builder';
9
-
10
- const makeModel = (contents: SupportMeContent[] = []): BrandPageModel =>
11
- ({
12
- brandPageType: 'brandSite',
13
- styles: { textStyles: { textStyleOptions: {} } },
14
- pages: [{ id: 'page-1', contents }],
15
- }) as unknown as BrandPageModel;
16
-
17
- const seedContent = (): SupportMeContent =>
18
- ({
19
- id: 'sm-1',
20
- type: 'support-me',
21
- title: 'Existing title',
22
- description: 'Existing description',
23
- successMessage: 'Existing success',
24
- displayStyle: 'preview',
25
- supportMeConfig: {
26
- paymentOptions: [{ amount: '0', id: 'po-1', name: 'Custom' }],
27
- isCustomerMessageEnabled: true,
28
- },
29
- titleStyle: {},
30
- headingStyle: {},
31
- descriptionStyle: {},
32
- buttonTextStyle: {},
33
- itemTextStyle: {},
34
- }) as unknown as SupportMeContent;
35
-
36
- const create = (args: SupportMeArguments, model: BrandPageModel) =>
37
- new SupportMeBuilder({
38
- id: 't-create',
39
- type: BUILDER_TYPES.CREATE_SUPPORT_ME,
40
- payload: { sectionType: 'support-me', arguments: args, pageId: 'page-1' },
41
- }).buildAsync(model);
42
-
43
- const update = (
44
- args: SupportMeArguments,
45
- model: BrandPageModel,
46
- contentId = 'sm-1',
47
- ) =>
48
- new SupportMeBuilder({
49
- id: 't-update',
50
- type: BUILDER_TYPES.UPDATE_SUPPORT_ME,
51
- payload: { sectionType: 'support-me', arguments: args, contentId },
52
- }).buildAsync(model);
53
-
54
- describe('SupportMeBuilder — create', () => {
55
- it('creates a support-me section with factory defaults', async () => {
56
- const model = makeModel();
57
-
58
- const { model: out, errors } = await create({}, model);
59
-
60
- expect(errors ?? []).toEqual([]);
61
-
62
- const created = out.pages[0].contents[0] as SupportMeContent;
63
-
64
- expect(created.type).toBe('support-me');
65
- // display style default comes from the factory
66
- expect(created.displayStyle).toBe('preview');
67
- // supportMeConfig (payment options) comes free from the factory, never the AI
68
- expect(created.supportMeConfig.paymentOptions.length).toBeGreaterThan(0);
69
- });
70
-
71
- it('applies AI-provided scalar fields over the defaults', async () => {
72
- const model = makeModel();
73
-
74
- const { model: out, errors } = await create(
75
- {
76
- title: 'Buy me a coffee',
77
- description: 'Support my work',
78
- success_message: 'Thanks!',
79
- display_style: 'collapsed',
80
- },
81
- model,
82
- );
83
-
84
- expect(errors ?? []).toEqual([]);
85
-
86
- const created = out.pages[0].contents[0] as SupportMeContent;
87
-
88
- expect(created.title).toBe('Buy me a coffee');
89
- expect(created.description).toBe('Support my work');
90
- expect(created.successMessage).toBe('Thanks!');
91
- expect(created.displayStyle).toBe('collapsed');
92
- });
93
- });
94
-
95
- describe('SupportMeBuilder — update', () => {
96
- it('updates scalar fields on an existing section', async () => {
97
- const model = makeModel([seedContent()]);
98
-
99
- const { model: out, errors } = await update(
100
- {
101
- title: 'New title',
102
- success_message: 'New success',
103
- display_style: 'collapsed',
104
- },
105
- model,
106
- );
107
-
108
- expect(errors ?? []).toEqual([]);
109
-
110
- const updated = out.pages[0].contents[0] as SupportMeContent;
111
-
112
- expect(updated.title).toBe('New title');
113
- expect(updated.successMessage).toBe('New success');
114
- expect(updated.displayStyle).toBe('collapsed');
115
- // untouched fields survive
116
- expect(updated.description).toBe('Existing description');
117
- // supportMeConfig is never AI-editable
118
- expect(updated.supportMeConfig.paymentOptions.length).toBe(1);
119
- });
120
-
121
- it('applies the five style fields to their model keys', async () => {
122
- const model = makeModel([seedContent()]);
123
-
124
- const { model: out, errors } = await update(
125
- {
126
- title_style: { textAlign: 'left' },
127
- heading_style: { textAlign: 'right' },
128
- description_style: { textAlign: 'center' },
129
- item_text_style: { textAlign: 'justify' },
130
- button_text_style: { color: '#123456' },
131
- },
132
- model,
133
- );
134
-
135
- expect(errors ?? []).toEqual([]);
136
-
137
- const updated = out.pages[0].contents[0] as SupportMeContent;
138
-
139
- expect(updated.titleStyle).toMatchObject({ textAlign: 'left' });
140
- expect(updated.headingStyle).toMatchObject({ textAlign: 'right' });
141
- expect(updated.descriptionStyle).toMatchObject({ textAlign: 'center' });
142
- expect(updated.itemTextStyle).toMatchObject({ textAlign: 'justify' });
143
- expect(updated.buttonTextStyle).toMatchObject({ color: '#123456' });
144
- });
145
- });
146
-
147
- describe('SupportMeBuilder — validation', () => {
148
- it('rejects an invalid display_style enum value', async () => {
149
- const model = makeModel([seedContent()]);
150
-
151
- const { errors } = await update({ display_style: 'fancy' as never }, model);
152
-
153
- expect(errors?.length).toBeGreaterThan(0);
154
- expect(errors!.join(' ')).toContain('display_style');
155
- });
156
-
157
- it('rejects an over-length title', async () => {
158
- const model = makeModel([seedContent()]);
159
-
160
- const { errors } = await update({ title: 'x'.repeat(201) }, model);
161
-
162
- expect(errors?.length).toBeGreaterThan(0);
163
- expect(errors!.join(' ')).toContain('title');
164
- });
165
-
166
- it('rejects an over-length success_message', async () => {
167
- const model = makeModel([seedContent()]);
168
-
169
- const { errors } = await update(
170
- { success_message: 'x'.repeat(1001) },
171
- model,
172
- );
173
-
174
- expect(errors?.length).toBeGreaterThan(0);
175
- expect(errors!.join(' ')).toContain('success_message');
176
- });
177
- });
@@ -1,43 +0,0 @@
1
- import type {
2
- BrandPageModel,
3
- SupportMeContent,
4
- } from '../../../brand-page/models';
5
- import type { BuilderResult } from '../../models';
6
- import { applyScalarFields, applyStyleFields } from '../section-field-utils';
7
- import { BaseSectionBuilder } from './base-section-builder';
8
- import { validateSupportMe } from '../section-rules/support-me.rules';
9
-
10
- export class SupportMeBuilder extends BaseSectionBuilder<SupportMeContent> {
11
- protected get sectionValidate() {
12
- return validateSupportMe;
13
- }
14
-
15
- async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
16
- this.log('Build called');
17
-
18
- const validation = await this.validateAsync();
19
-
20
- if (validation.errors.length) {
21
- return { request: this.request, model, errors: validation.errors };
22
- }
23
-
24
- const resolved = this.resolveAndRepositionContent(model);
25
-
26
- if ('error' in resolved) return resolved.error;
27
-
28
- const content = resolved.content;
29
-
30
- // title/description/success_message are plain-text fields (no RTE support),
31
- // so scalar application covers all content fields. supportMeConfig (payment
32
- // options) is intentionally not AI-editable — it comes from the factory.
33
- applyScalarFields(content, this.args, this.sectionType);
34
- applyStyleFields(
35
- content,
36
- this.args,
37
- this.sectionType,
38
- this.getGlobalTextStyles(model),
39
- );
40
-
41
- return { request: this.request, model };
42
- }
43
- }
@@ -1,83 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import type { Content } from '../../brand-page/models';
3
- import { applyStyleFields } from './section-field-utils';
4
-
5
- /**
6
- * Regression tests for the AI QA 2026-07-05 rerun P0: a colour-only *_style
7
- * patch left the field's existing inline textStyle marks (old colour) in
8
- * place — inline marks override the style layer at render, so recoloured
9
- * bands showed invisible old-colour text. applyStyleFields now propagates a
10
- * new style colour into the stored RTE HTML when the patch carries no new
11
- * text for that field.
12
- */
13
- describe('applyStyleFields inline-colour propagation', () => {
14
- const makeContent = (): Content =>
15
- ({
16
- type: 'about-section',
17
- title: '<h3><span style="color: #111111">Fine Grooming</span></h3>',
18
- titleStyle: { color: '#111111', fontSize: '2.188em' },
19
- paragraph: '<p><span style="color: #111111">Body copy</span></p>',
20
- paragraphStyle: { color: '#111111' },
21
- }) as unknown as Content;
22
-
23
- const recolour = (html: string, color: string): string =>
24
- html.replace(/color: #[0-9a-fA-F]{6}/g, `color: ${color}`);
25
-
26
- it('colour-only patch recolours the existing inline marks', () => {
27
- const content = makeContent();
28
-
29
- applyStyleFields(
30
- content,
31
- { title_style: { color: '#f8f2e9' } },
32
- 'about-section',
33
- undefined,
34
- recolour,
35
- );
36
-
37
- const record = content as unknown as Record<string, unknown>;
38
-
39
- expect(record.title).toContain('color: #f8f2e9');
40
- expect((record.titleStyle as Record<string, unknown>).color).toBe(
41
- '#f8f2e9',
42
- );
43
- // Untouched fields keep their marks.
44
- expect(record.paragraph).toContain('color: #111111');
45
- });
46
-
47
- it('does NOT rewrite marks when the patch also carries new text for the field', () => {
48
- const content = makeContent();
49
-
50
- applyStyleFields(
51
- content,
52
- {
53
- title: { type: 'doc', content: [] },
54
- title_style: { color: '#f8f2e9' },
55
- },
56
- 'about-section',
57
- undefined,
58
- recolour,
59
- );
60
-
61
- // The builder's own text path owns the rewrite — HTML left alone here.
62
- expect((content as unknown as Record<string, unknown>).title).toContain(
63
- 'color: #111111',
64
- );
65
- });
66
-
67
- it('merged style keeps non-colour properties from the current style', () => {
68
- const content = makeContent();
69
-
70
- applyStyleFields(
71
- content,
72
- { title_style: { color: '#f8f2e9' } },
73
- 'about-section',
74
- undefined,
75
- recolour,
76
- );
77
-
78
- const style = (content as unknown as Record<string, unknown>)
79
- .titleStyle as Record<string, unknown>;
80
-
81
- expect(style.fontSize).toBe('2.188em');
82
- });
83
- });
@@ -1,39 +0,0 @@
1
- import {
2
- MAX_TITLE_LENGTH,
3
- MAX_DESCRIPTION_LENGTH,
4
- } from '../../../brand-page/constants/font.constants';
5
- import {
6
- DISPLAY_STYLE_PREVIEW,
7
- DISPLAY_STYLE_COLLAPSED,
8
- } from '../../../brand-page/constants';
9
- import {
10
- enumCheck,
11
- runChecks,
12
- styleCheck,
13
- textCheck,
14
- type SectionCheck,
15
- type ValidationContext,
16
- } from '../../sanitizers/section-args-validator';
17
-
18
- const CHECKS: SectionCheck[] = [
19
- textCheck('title', MAX_TITLE_LENGTH),
20
- textCheck('description', MAX_DESCRIPTION_LENGTH),
21
- textCheck('success_message', MAX_DESCRIPTION_LENGTH),
22
- styleCheck('title_style'),
23
- styleCheck('heading_style'),
24
- styleCheck('description_style'),
25
- styleCheck('item_text_style'),
26
- styleCheck('button_text_style'),
27
- enumCheck(
28
- 'display_style',
29
- [DISPLAY_STYLE_PREVIEW, DISPLAY_STYLE_COLLAPSED],
30
- 'support-me',
31
- ),
32
- ];
33
-
34
- export function validateSupportMe(
35
- args: Record<string, unknown>,
36
- ctx: ValidationContext,
37
- ): string[] {
38
- return runChecks(CHECKS, args, ctx);
39
- }
@@ -1,61 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import type { BrandPageModel } from '../brand-page/models';
3
- import { minifyBrandPageMetadata } from './minify-brand-page-metadata';
4
-
5
- /**
6
- * The AI builder can now create/update `support-me` sections, so the minified
7
- * model it reads on update must surface the fields it can edit — otherwise it
8
- * can't see the current `displayStyle` / `successMessage` when deciding what to
9
- * change. `request-payment` (not AI-editable) must keep its original shape.
10
- */
11
-
12
- const makeModel = (contents: unknown[]): BrandPageModel =>
13
- ({
14
- brandPageType: 'brandSite',
15
- v: 1,
16
- styles: {},
17
- nav: { routes: [{ pageId: 'page-1', pageSlug: 'home' }] },
18
- pages: [{ id: 'page-1', title: 'Home', contents }],
19
- }) as unknown as BrandPageModel;
20
-
21
- const supportMe = {
22
- id: 'sm-1',
23
- type: 'support-me',
24
- title: 'Buy me a coffee',
25
- description: 'Support my work',
26
- successMessage: 'Thanks so much!',
27
- displayStyle: 'collapsed',
28
- };
29
-
30
- const requestPayment = {
31
- id: 'rp-1',
32
- type: 'request-payment',
33
- title: 'Pay now',
34
- description: 'Invoice',
35
- successMessage: 'Paid',
36
- displayStyle: 'preview',
37
- };
38
-
39
- describe('minifyBrandPageMetadata — support-me', () => {
40
- it('surfaces title, description, successMessage and displayStyle', () => {
41
- const out = minifyBrandPageMetadata(makeModel([supportMe]));
42
- const minified = out.pages[0].contents[0];
43
-
44
- expect(minified.type).toBe('support-me');
45
- expect(minified.title).toBe('Buy me a coffee');
46
- expect(minified.description).toBe('Support my work');
47
- expect(minified.successMessage).toBe('Thanks so much!');
48
- expect(minified.displayStyle).toBe('collapsed');
49
- });
50
-
51
- it('leaves request-payment shape unchanged (no successMessage / displayStyle)', () => {
52
- const out = minifyBrandPageMetadata(makeModel([requestPayment]));
53
- const minified = out.pages[0].contents[0];
54
-
55
- expect(minified.type).toBe('request-payment');
56
- expect(minified.title).toBe('Pay now');
57
- expect(minified.description).toBe('Invoice');
58
- expect(minified.successMessage).toBeUndefined();
59
- expect(minified.displayStyle).toBeUndefined();
60
- });
61
- });