@designcrowd/library.brand-page 6.0.1 → 6.0.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-BPP1Wtpt.js → CreatedOnBrandCrowd-de-de-Zptj2O2O.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-BlfpQiIg.js → CreatedOnBrandCrowd-en-us-Bxmo2Ps9.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-Tldy_pIo.js → CreatedOnBrandCrowd-es-es-uytkzFdZ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-CHmb3VQE.js → CreatedOnBrandCrowd-fr-ca-26tDXsvZ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-CHmb3VQE.js → CreatedOnBrandCrowd-fr-fr-26tDXsvZ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-XbU3eK3Z.js → CreatedOnBrandCrowd-pt-br-DuNRkCU5.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-XbU3eK3Z.js → CreatedOnBrandCrowd-pt-pt-DuNRkCU5.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-BVMFbVbI.js → CreatedOnDcom-de-de-D_aekURi.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us--kaKb1kI.js → CreatedOnDcom-en-us-CD3RyS8m.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-XXVLpF2I.js → CreatedOnDcom-es-es-BXCP18xT.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-D-7vtMZ5.js → CreatedOnDcom-fr-ca-BN04YN4o.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-CM9oQk77.js → CreatedOnDcom-fr-fr-B8-sowys.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-VVgu3BEa.js → CreatedOnDcom-pt-br-C0MTfZ_l.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-CWhA8Vla.js → CreatedOnDcom-pt-pt-BamTt9zq.js} +1 -1
- package/lib/src/brand-page-maker/components/admin-background-settings/ShapePositionSlider.mixin.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +2 -0
- package/lib/src/clients/ai-assistant-client.d.ts +7 -0
- package/lib/src/index.d.ts +4 -0
- package/lib/src/index.mjs +107 -104
- package/lib/src/{lib-yEV1yYI5.js → lib-dQieWjFg.js} +5484 -5470
- package/lib/src/lib.js +10 -0
- package/lib/src/metadata-builder/builders/reorder-pages-builder.d.ts +13 -0
- package/lib/src/metadata-builder/builders/reorder-pages-builder.js +49 -0
- package/lib/src/utils/build-asset-manifest.d.ts +4 -0
- package/lib/src/utils/build-asset-manifest.js +8 -0
- package/lib/src/utils/minify-brand-page-metadata.js +1 -9
- package/package.json +2 -2
- package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +2 -0
- package/src/clients/ai-assistant-client.ts +7 -0
- package/src/lib.ts +12 -0
- package/src/metadata-builder/builders/reorder-pages-builder.ts +80 -0
- package/src/utils/build-asset-manifest.ts +12 -0
- package/src/utils/minify-brand-page-metadata.ts +5 -13
package/lib/src/lib.js
CHANGED
|
@@ -31,6 +31,16 @@ 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
33
|
export { getPageSlugFromPageTitle } from './brand-page-maker/utils/slug.util';
|
|
34
|
+
// AI-pipeline preview (longclaw per-turn snapshots): web-renderer's
|
|
35
|
+
// /preview/ai-pipeline render page + manifest server route apply the agent's
|
|
36
|
+
// tool calls to a brand-page metadata snapshot server-side and resolve the
|
|
37
|
+
// target page by slug. These three symbols are otherwise internal to the
|
|
38
|
+
// metadata-builder / route utils.
|
|
39
|
+
export { executeToolCallsAsync } from './metadata-builder/ai-metadata-executor';
|
|
40
|
+
export { findNavItemByPageSlug } from './brand-page/utils/route.util';
|
|
41
|
+
// Tiptap-JSON RTE -> HTML (same converter the metadata builders use). Lets the
|
|
42
|
+
// preview render the agent's raw Tiptap fields, which the renderer expects as HTML.
|
|
43
|
+
export { tiptapJsonToHtml } from './metadata-builder/helpers/rte.helpers';
|
|
34
44
|
// stores
|
|
35
45
|
export { useBrandPageMakerStore, useBrandPageMakerUserStore, useUiStore, useBrandPageContainerStore, useEventManagerStore, useLocalisedRouteStore, useVideoStore, useRouteStore, } from './brand-page-maker/stores';
|
|
36
46
|
export { useShopConfigStore } from './shared/ecommerce-settings/store/shop-settings-store';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BrandPageModel } from '../../brand-page/models';
|
|
2
|
+
import { BaseMetadataBuilder, type BuilderResult, type MetadataBuilderRequest } from '../models';
|
|
3
|
+
import type { Logger } from '../logger';
|
|
4
|
+
export interface ReorderPagesPayload {
|
|
5
|
+
pageOrder: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare class ReorderPagesBuilder extends BaseMetadataBuilder<ReorderPagesPayload> {
|
|
8
|
+
constructor(request: MetadataBuilderRequest<ReorderPagesPayload>, logger?: Logger);
|
|
9
|
+
validateAsync(): Promise<{
|
|
10
|
+
errors: string[];
|
|
11
|
+
}>;
|
|
12
|
+
buildAsync(model: BrandPageModel): Promise<BuilderResult>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { BaseMetadataBuilder, } from '../models';
|
|
2
|
+
export class ReorderPagesBuilder extends BaseMetadataBuilder {
|
|
3
|
+
constructor(request, logger) {
|
|
4
|
+
super(request, logger);
|
|
5
|
+
}
|
|
6
|
+
async validateAsync() {
|
|
7
|
+
const errors = [];
|
|
8
|
+
const payload = this.request.payload;
|
|
9
|
+
if (!payload?.pageOrder?.length) {
|
|
10
|
+
errors.push('page_order is required for reorder_pages');
|
|
11
|
+
}
|
|
12
|
+
return { errors };
|
|
13
|
+
}
|
|
14
|
+
async buildAsync(model) {
|
|
15
|
+
this.log('Build called');
|
|
16
|
+
const validation = await this.validateAsync();
|
|
17
|
+
if (validation.errors.length) {
|
|
18
|
+
return { request: this.request, model, errors: validation.errors };
|
|
19
|
+
}
|
|
20
|
+
const { pageOrder } = this.request.payload;
|
|
21
|
+
// Build pageId → routeId lookup from nav.routes
|
|
22
|
+
const pageIdToRouteId = new Map();
|
|
23
|
+
for (const route of model.nav.routes) {
|
|
24
|
+
pageIdToRouteId.set(route.pageId, route.id);
|
|
25
|
+
}
|
|
26
|
+
// Build new nav.orders from the flat page_order (array of pageIds)
|
|
27
|
+
const newOrders = [];
|
|
28
|
+
const seenRouteIds = new Set();
|
|
29
|
+
for (const pageId of pageOrder) {
|
|
30
|
+
const routeId = pageIdToRouteId.get(pageId);
|
|
31
|
+
if (!routeId)
|
|
32
|
+
continue;
|
|
33
|
+
newOrders.push({ routeId, subRoutes: [] });
|
|
34
|
+
seenRouteIds.add(routeId);
|
|
35
|
+
}
|
|
36
|
+
// Safety: append any routes not mentioned (don't lose pages)
|
|
37
|
+
for (const route of model.nav.routes) {
|
|
38
|
+
const routeId = pageIdToRouteId.get(route.pageId);
|
|
39
|
+
if (routeId && !seenRouteIds.has(routeId)) {
|
|
40
|
+
newOrders.push({ routeId, subRoutes: [] });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
model.nav.orders = newOrders;
|
|
44
|
+
this.log({
|
|
45
|
+
message: `Reordered pages: ${pageOrder.join(', ')}`,
|
|
46
|
+
});
|
|
47
|
+
return { request: this.request, model };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -14,6 +14,10 @@ export interface AssetEntry {
|
|
|
14
14
|
* 2. Fall back to logoImageBase64Url if logoImage is unavailable.
|
|
15
15
|
*/
|
|
16
16
|
export declare function resolveLogoData(logoImage: LogoImageModel | undefined, logoImageBase64Url: string | undefined): string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Look up an asset key from the manifest by matching the data content.
|
|
19
|
+
*/
|
|
20
|
+
export declare function findAssetKey(assets: AssetEntry[] | undefined, data: string | undefined): string | undefined;
|
|
17
21
|
/**
|
|
18
22
|
* Build an asset manifest from the brand page model.
|
|
19
23
|
*
|
|
@@ -23,6 +23,14 @@ export function resolveLogoData(logoImage, logoImageBase64Url) {
|
|
|
23
23
|
// Fallback to base64 if available
|
|
24
24
|
return logoImageBase64Url || undefined;
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Look up an asset key from the manifest by matching the data content.
|
|
28
|
+
*/
|
|
29
|
+
export function findAssetKey(assets, data) {
|
|
30
|
+
if (!data || !assets)
|
|
31
|
+
return undefined;
|
|
32
|
+
return assets.find((a) => a.data === data)?.key;
|
|
33
|
+
}
|
|
26
34
|
/**
|
|
27
35
|
* Hash a string using SHA-256 and return the first 16 hex characters.
|
|
28
36
|
* Uses the Web Crypto API (available in browsers and modern runtimes).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BRAND_PAGE_TYPES, } from '../brand-page/models';
|
|
2
2
|
import { hasRTEContent } from '../brand-page-maker/utils';
|
|
3
3
|
import { useExternalRichTextEditor } from '../brand-page-maker/composables/rich-text-editor/useRichTextEditor';
|
|
4
|
-
import { resolveLogoData } from './build-asset-manifest';
|
|
4
|
+
import { findAssetKey, resolveLogoData, } from './build-asset-manifest';
|
|
5
5
|
const BUTTON_TYPES = [
|
|
6
6
|
'general-link',
|
|
7
7
|
'website',
|
|
@@ -78,14 +78,6 @@ const includeBackgroundStyle = (value) => {
|
|
|
78
78
|
return null;
|
|
79
79
|
return { backgroundStyle: { backgroundColor: bg } };
|
|
80
80
|
};
|
|
81
|
-
/**
|
|
82
|
-
* Look up an asset key from the manifest by matching the data content.
|
|
83
|
-
*/
|
|
84
|
-
const findAssetKey = (assets, data) => {
|
|
85
|
-
if (!data || !assets)
|
|
86
|
-
return undefined;
|
|
87
|
-
return assets.find((a) => a.data === data)?.key;
|
|
88
|
-
};
|
|
89
81
|
const minifyContent = (content, editor, assets) => {
|
|
90
82
|
const base = {
|
|
91
83
|
id: content.id,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@designcrowd/library.brand-page",
|
|
3
3
|
"description": "A collection of Maker/Designer applications",
|
|
4
|
-
"version": "6.0.
|
|
4
|
+
"version": "6.0.2",
|
|
5
5
|
"author": "Design.com Eng",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"type": "module",
|
|
@@ -248,4 +248,4 @@
|
|
|
248
248
|
"public"
|
|
249
249
|
]
|
|
250
250
|
}
|
|
251
|
-
}
|
|
251
|
+
}
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from '../../../clients/websocket-gateway-client';
|
|
20
20
|
import { minifyBrandPageMetadata } from '../../../utils/minify-brand-page-metadata';
|
|
21
21
|
import { buildAssetManifest } from '../../../utils/build-asset-manifest';
|
|
22
|
+
import cloneDeep from 'lodash.clonedeep';
|
|
22
23
|
import { usePageNavigationStore } from '../../../shared/page-navigation/store/page-navigation-store';
|
|
23
24
|
import { navigateToPageByPageId } from '../../routing';
|
|
24
25
|
import {
|
|
@@ -268,6 +269,7 @@ export function useAiWebsiteBuilderChat(): UseAiChatResult {
|
|
|
268
269
|
|
|
269
270
|
const websiteContext = {
|
|
270
271
|
metadata: minifyBrandPageMetadata(brandPageData, assets),
|
|
272
|
+
metadataFull: cloneDeep(brandPageData),
|
|
271
273
|
...(assets.length > 0 && { assets }),
|
|
272
274
|
websiteTemplateToken: containerStore.designTemplateToken,
|
|
273
275
|
...(containerStore.designDraftToken && {
|
|
@@ -2,6 +2,7 @@ import axios, { type AxiosError } from 'axios';
|
|
|
2
2
|
import { useBrandPageContainerStore } from '../brand-page-maker/stores/brandpage-container/brand-page-container-store';
|
|
3
3
|
import type { MinifiedBrandPageMetadata } from '../utils/minify-brand-page-metadata';
|
|
4
4
|
import type { AssetEntry } from '../utils/build-asset-manifest';
|
|
5
|
+
import type { BrandPageModel } from '../brand-page/models';
|
|
5
6
|
|
|
6
7
|
export interface ActiveContext {
|
|
7
8
|
currentPageId: string;
|
|
@@ -14,6 +15,12 @@ export interface LogoContext {
|
|
|
14
15
|
|
|
15
16
|
export interface WebsiteContext {
|
|
16
17
|
metadata: MinifiedBrandPageMetadata;
|
|
18
|
+
/**
|
|
19
|
+
* Full structural metadata (logos externalized to `logoAssetKey`, no base64,
|
|
20
|
+
* no field-stripping) — persisted for the preview render only. The LLM uses
|
|
21
|
+
* `metadata` (minified); the preview renderer uses this for full fidelity.
|
|
22
|
+
*/
|
|
23
|
+
metadataFull?: BrandPageModel;
|
|
17
24
|
assets?: AssetEntry[];
|
|
18
25
|
activeContext?: ActiveContext;
|
|
19
26
|
businessName?: string;
|
package/src/lib.ts
CHANGED
|
@@ -87,6 +87,18 @@ export {
|
|
|
87
87
|
export { sanitizeRTEHtml } from './brand-page-maker/utils';
|
|
88
88
|
export { getPageSlugFromPageTitle } from './brand-page-maker/utils/slug.util';
|
|
89
89
|
|
|
90
|
+
// AI-pipeline preview (longclaw per-turn snapshots): web-renderer's
|
|
91
|
+
// /preview/ai-pipeline render page + manifest server route apply the agent's
|
|
92
|
+
// tool calls to a brand-page metadata snapshot server-side and resolve the
|
|
93
|
+
// target page by slug. These three symbols are otherwise internal to the
|
|
94
|
+
// metadata-builder / route utils.
|
|
95
|
+
export { executeToolCallsAsync } from './metadata-builder/ai-metadata-executor';
|
|
96
|
+
export type { ParsedToolCall } from './metadata-builder/parsers/ai-toolcall-parser';
|
|
97
|
+
export { findNavItemByPageSlug } from './brand-page/utils/route.util';
|
|
98
|
+
// Tiptap-JSON RTE -> HTML (same converter the metadata builders use). Lets the
|
|
99
|
+
// preview render the agent's raw Tiptap fields, which the renderer expects as HTML.
|
|
100
|
+
export { tiptapJsonToHtml } from './metadata-builder/helpers/rte.helpers';
|
|
101
|
+
|
|
90
102
|
// stores
|
|
91
103
|
export {
|
|
92
104
|
useBrandPageMakerStore,
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { BrandPageModel, NavOrder } from '../../brand-page/models';
|
|
2
|
+
import {
|
|
3
|
+
BaseMetadataBuilder,
|
|
4
|
+
type BuilderResult,
|
|
5
|
+
type MetadataBuilderRequest,
|
|
6
|
+
} from '../models';
|
|
7
|
+
import type { Logger } from '../logger';
|
|
8
|
+
|
|
9
|
+
export interface ReorderPagesPayload {
|
|
10
|
+
pageOrder: string[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class ReorderPagesBuilder extends BaseMetadataBuilder<ReorderPagesPayload> {
|
|
14
|
+
constructor(
|
|
15
|
+
request: MetadataBuilderRequest<ReorderPagesPayload>,
|
|
16
|
+
logger?: Logger,
|
|
17
|
+
) {
|
|
18
|
+
super(request, logger);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async validateAsync(): Promise<{ errors: string[] }> {
|
|
22
|
+
const errors: string[] = [];
|
|
23
|
+
const payload = this.request.payload;
|
|
24
|
+
|
|
25
|
+
if (!payload?.pageOrder?.length) {
|
|
26
|
+
errors.push('page_order is required for reorder_pages');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return { errors };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
|
|
33
|
+
this.log('Build called');
|
|
34
|
+
|
|
35
|
+
const validation = await this.validateAsync();
|
|
36
|
+
|
|
37
|
+
if (validation.errors.length) {
|
|
38
|
+
return { request: this.request, model, errors: validation.errors };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const { pageOrder } = this.request.payload!;
|
|
42
|
+
|
|
43
|
+
// Build pageId → routeId lookup from nav.routes
|
|
44
|
+
const pageIdToRouteId = new Map<string, string>();
|
|
45
|
+
|
|
46
|
+
for (const route of model.nav.routes) {
|
|
47
|
+
pageIdToRouteId.set(route.pageId, route.id);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Build new nav.orders from the flat page_order (array of pageIds)
|
|
51
|
+
const newOrders: NavOrder[] = [];
|
|
52
|
+
const seenRouteIds = new Set<string>();
|
|
53
|
+
|
|
54
|
+
for (const pageId of pageOrder) {
|
|
55
|
+
const routeId = pageIdToRouteId.get(pageId);
|
|
56
|
+
|
|
57
|
+
if (!routeId) continue;
|
|
58
|
+
|
|
59
|
+
newOrders.push({ routeId, subRoutes: [] });
|
|
60
|
+
seenRouteIds.add(routeId);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Safety: append any routes not mentioned (don't lose pages)
|
|
64
|
+
for (const route of model.nav.routes) {
|
|
65
|
+
const routeId = pageIdToRouteId.get(route.pageId);
|
|
66
|
+
|
|
67
|
+
if (routeId && !seenRouteIds.has(routeId)) {
|
|
68
|
+
newOrders.push({ routeId, subRoutes: [] });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
model.nav.orders = newOrders;
|
|
73
|
+
|
|
74
|
+
this.log({
|
|
75
|
+
message: `Reordered pages: ${pageOrder.join(', ')}`,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return { request: this.request, model };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -41,6 +41,18 @@ export function resolveLogoData(
|
|
|
41
41
|
return logoImageBase64Url || undefined;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Look up an asset key from the manifest by matching the data content.
|
|
46
|
+
*/
|
|
47
|
+
export function findAssetKey(
|
|
48
|
+
assets: AssetEntry[] | undefined,
|
|
49
|
+
data: string | undefined,
|
|
50
|
+
): string | undefined {
|
|
51
|
+
if (!data || !assets) return undefined;
|
|
52
|
+
|
|
53
|
+
return assets.find((a) => a.data === data)?.key;
|
|
54
|
+
}
|
|
55
|
+
|
|
44
56
|
/**
|
|
45
57
|
* Hash a string using SHA-256 and return the first 16 hex characters.
|
|
46
58
|
* Uses the Web Crypto API (available in browsers and modern runtimes).
|
|
@@ -13,7 +13,11 @@ import type { TextStyleDeclaration } from '../brand-page/models/styles.model';
|
|
|
13
13
|
import { hasRTEContent } from '../brand-page-maker/utils';
|
|
14
14
|
import { useExternalRichTextEditor } from '../brand-page-maker/composables/rich-text-editor/useRichTextEditor';
|
|
15
15
|
import type { Editor, JSONContent } from '@tiptap/vue-3';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
type AssetEntry,
|
|
18
|
+
findAssetKey,
|
|
19
|
+
resolveLogoData,
|
|
20
|
+
} from './build-asset-manifest';
|
|
17
21
|
|
|
18
22
|
type MinifiedFooterSocialLink = { imageUrl: string; url: string };
|
|
19
23
|
|
|
@@ -188,18 +192,6 @@ const includeBackgroundStyle = (
|
|
|
188
192
|
return { backgroundStyle: { backgroundColor: bg } };
|
|
189
193
|
};
|
|
190
194
|
|
|
191
|
-
/**
|
|
192
|
-
* Look up an asset key from the manifest by matching the data content.
|
|
193
|
-
*/
|
|
194
|
-
const findAssetKey = (
|
|
195
|
-
assets: AssetEntry[] | undefined,
|
|
196
|
-
data: string | undefined,
|
|
197
|
-
): string | undefined => {
|
|
198
|
-
if (!data || !assets) return undefined;
|
|
199
|
-
|
|
200
|
-
return assets.find((a) => a.data === data)?.key;
|
|
201
|
-
};
|
|
202
|
-
|
|
203
195
|
const minifyContent = (
|
|
204
196
|
content: Content,
|
|
205
197
|
editor: Editor,
|