@useinsider/guido 3.21.2-beta.45bb425 → 3.21.2-beta.4b0fed7
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/dist/composables/useSave.js +68 -75
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +22 -22
- package/dist/config/migrator/recommendation/compositionMapper.js +56 -49
- package/dist/config/migrator/recommendation/extractors.js +68 -29
- package/dist/config/migrator/recommendation/htmlBuilder.js +283 -200
- package/dist/config/migrator/recommendation/settingsMapper.js +35 -32
- package/dist/config/migrator/recommendationMigrator.js +32 -29
- package/dist/extensions/Blocks/Recommendation/block.js +33 -24
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +146 -162
- package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMap.js +1 -2
- package/dist/services/templateLibraryApi.js +31 -36
- package/dist/src/config/migrator/recommendation/compositionMapper.d.ts +3 -1
- package/dist/src/config/migrator/recommendation/extractors.d.ts +20 -0
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +2 -8
- package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.d.ts +3 -2
- package/dist/src/utils/templatePreparation.d.ts +1 -2
- package/dist/utils/templatePreparation.js +30 -30
- package/package.json +1 -1
- package/dist/composables/validators/useHtmlDocumentCountValidator.js +0 -22
- package/dist/src/composables/validators/useHtmlDocumentCountValidator.d.ts +0 -3
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LegacyVariable } from './types';
|
|
1
2
|
export declare function extractTitleText(block: Element): string;
|
|
2
3
|
/**
|
|
3
4
|
* Fallback for legacy configs that carry no `p_recommendation_title` variable:
|
|
@@ -7,6 +8,25 @@ export declare function extractTitleText(block: Element): string;
|
|
|
7
8
|
* @returns True when the legacy block renders a visible title
|
|
8
9
|
*/
|
|
9
10
|
export declare function hasVisibleTitle(block: Element): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* A rendered title container with no text showed the user no title, whatever the config's `hidden` flag says.
|
|
13
|
+
* @param block - The legacy recommendation block element
|
|
14
|
+
* @returns True when the legacy block renders an empty title container
|
|
15
|
+
*/
|
|
16
|
+
export declare function hasEmptyTitle(block: Element): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Reads which price the legacy card renders first. Prices sharing a `positionIdx` are ordered by this.
|
|
19
|
+
* @param block - The legacy recommendation block element
|
|
20
|
+
* @returns True only when both prices render and the original price comes first
|
|
21
|
+
*/
|
|
22
|
+
export declare function isOldPriceFirst(block: Element): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Legacy keeps the text color and the name's trim toggle in the rendered `<p>`, not in the config theme.
|
|
25
|
+
* @param variables - The legacy composition variables
|
|
26
|
+
* @param block - The legacy recommendation block element
|
|
27
|
+
* @returns The variables, with `textColor` / `textTrimming` filled from the rendered HTML where the theme lacks them
|
|
28
|
+
*/
|
|
29
|
+
export declare function withRenderedTextTheme(variables: LegacyVariable[] | undefined, block: Element): LegacyVariable[] | undefined;
|
|
10
30
|
/**
|
|
11
31
|
* Card background lives on either the block (`bgcolor`/`style`) or per-card
|
|
12
32
|
* cells (`.product-card`). Returns empty string when no background is set —
|
|
@@ -65,6 +65,7 @@ export declare class RecommendationBlock extends Block {
|
|
|
65
65
|
*/
|
|
66
66
|
onDelete(node: ImmutableHtmlNode): void;
|
|
67
67
|
private _ensureMobileFitRule;
|
|
68
|
+
private _ensureTextTrimCss;
|
|
68
69
|
private _syncHeightBound;
|
|
69
70
|
/**
|
|
70
71
|
* Warns (dark advisory toaster) when the design holds more than one live
|
|
@@ -121,14 +121,8 @@ export declare class RecommendationBlockControl extends CommonControl {
|
|
|
121
121
|
private _fetchBlockData;
|
|
122
122
|
private _isPanelOn;
|
|
123
123
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* For new blocks (config still matches hardcoded defaults), validates that
|
|
127
|
-
* the default currency and algorithm are available from the API response.
|
|
128
|
-
* If not, falls back to the first available option.
|
|
129
|
-
*
|
|
130
|
-
* Saved templates with user-customized config are left unchanged because
|
|
131
|
-
* their values won't match the hardcoded defaults.
|
|
124
|
+
* Falls back to the first available option when the block's currency or locale is not offered (a new block on
|
|
125
|
+
* the hard-coded default, or a block copied from another account). The algorithm falls back only on new blocks.
|
|
132
126
|
*/
|
|
133
127
|
private _applySmartDefaults;
|
|
134
128
|
/**
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* Maps legacy algorithm strategy keys (used by templates authored against the
|
|
3
3
|
* old recommendation system) to the new keys used by `RecommendationFeedSourceMaps`.
|
|
4
4
|
*
|
|
5
|
+
* `viewedTogether` and `purchasedTogether` map to `mostPopular`: their feed sources (ids 11, 12) need a
|
|
6
|
+
* product id and are excluded from the algorithm dropdown (`EXCLUDED_ALGORITHM_IDS`).
|
|
7
|
+
*
|
|
5
8
|
* Renames are matched by feed-source id:
|
|
6
|
-
* - `viewedTogether` → `similarViewed` (id 11, path `viewed-together`)
|
|
7
|
-
* - `purchasedTogether` → `similarBought` (id 12, path `purchased-together`)
|
|
8
9
|
* - `trending` → `trendingProducts` (id 40, path `trending`)
|
|
9
10
|
* - `mostValuable` → `mostValuableOfPartner` (id 46, path `most-valuable`)
|
|
10
11
|
* - `topSellers` → `mostPurchased` (id 62, path `top-sellers`)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { TemplateData } from '@@/Types/actions-api';
|
|
2
1
|
import type { SavedTemplateDetails } from '@@/Types/stripo';
|
|
3
2
|
/**
|
|
4
3
|
* Collects every unsubscribe page id referenced by the unsubscribe blocks
|
|
@@ -45,7 +44,7 @@ export declare function getHtmlReferencedUnsubscribePages(html: string): number[
|
|
|
45
44
|
*/
|
|
46
45
|
declare function hydrateRecommendationStoreFromRawHtml(rawHtml: string): Promise<void>;
|
|
47
46
|
export declare const useTemplatePreparation: () => {
|
|
48
|
-
prepareTemplateDetails: (
|
|
47
|
+
prepareTemplateDetails: () => Promise<Omit<SavedTemplateDetails, "metadata">>;
|
|
49
48
|
hydrateRecommendationStore: typeof hydrateRecommendationStoreFromRawHtml;
|
|
50
49
|
};
|
|
51
50
|
export {};
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
2
|
-
import { useConfig as
|
|
3
|
-
import { useHtmlCompiler as
|
|
1
|
+
import { useActionsApi as D } from "../composables/useActionsApi.js";
|
|
2
|
+
import { useConfig as E } from "../composables/useConfig.js";
|
|
3
|
+
import { useHtmlCompiler as F } from "../composables/useHtmlCompiler.js";
|
|
4
4
|
import { useRecommendationExtensionStore as b } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
5
|
-
import { toBlockUrlConfig as
|
|
5
|
+
import { toBlockUrlConfig as I } from "../extensions/Blocks/Recommendation/utils/blockUrlConfig.js";
|
|
6
6
|
import { DATA_ATTRIBUTES as g } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
|
|
7
|
-
import { parsePageList as
|
|
8
|
-
import { useDynamicContentStore as
|
|
9
|
-
import { useEditorStore as
|
|
10
|
-
import { useUnsubscribeStore as
|
|
11
|
-
import { isPlainObject as
|
|
12
|
-
import { assignTrackingIds as
|
|
13
|
-
function
|
|
7
|
+
import { parsePageList as R } from "../extensions/Blocks/Unsubscribe/utils/utils.js";
|
|
8
|
+
import { useDynamicContentStore as U } from "../stores/dynamic-content.js";
|
|
9
|
+
import { useEditorStore as L } from "../stores/editor.js";
|
|
10
|
+
import { useUnsubscribeStore as N } from "../stores/unsubscribe.js";
|
|
11
|
+
import { isPlainObject as v } from "./genericUtil.js";
|
|
12
|
+
import { assignTrackingIds as z } from "./linkTrackingIds.js";
|
|
13
|
+
function M(n) {
|
|
14
14
|
const r = new DOMParser().parseFromString(n, "text/html").querySelectorAll(`[${g.PAGE_LIST}]`), e = [];
|
|
15
15
|
return r.forEach((i) => {
|
|
16
16
|
const t = i.getAttribute(g.PAGE_LIST);
|
|
17
|
-
t && e.push(...
|
|
17
|
+
t && e.push(...R(t));
|
|
18
18
|
}), [...new Set(e)];
|
|
19
19
|
}
|
|
20
20
|
async function S(n) {
|
|
@@ -35,7 +35,7 @@ async function S(n) {
|
|
|
35
35
|
} catch {
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
v(a) && r.seedBlockUrlConfig(t, I(a));
|
|
39
39
|
});
|
|
40
40
|
try {
|
|
41
41
|
await r.fetchRecommendationCreateData();
|
|
@@ -46,40 +46,40 @@ async function S(n) {
|
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
const
|
|
50
|
-
const n =
|
|
49
|
+
const Y = () => {
|
|
50
|
+
const n = U(), c = L(), o = N(), { getCompiledEmail: r, getTemplateData: e, updateHtmlAndCss: i } = D(), { compileHtml: t, compileAmpHtml: m } = F(), { isFeatureEnabled: a } = E();
|
|
51
51
|
return {
|
|
52
|
-
prepareTemplateDetails: async (
|
|
53
|
-
let { html: s, css: u, syncModulesIds:
|
|
52
|
+
prepareTemplateDetails: async () => {
|
|
53
|
+
let { html: s, css: u, syncModulesIds: h = [] } = await e();
|
|
54
54
|
if (a("linkTrackingIds"))
|
|
55
55
|
try {
|
|
56
|
-
const { html: d, changed:
|
|
57
|
-
c.trackIdSessionFloor =
|
|
56
|
+
const { html: d, changed: P, nextSeq: x } = z(s, c.trackIdSessionFloor);
|
|
57
|
+
c.trackIdSessionFloor = x, P && (s = d, await i(d, u));
|
|
58
58
|
} catch (d) {
|
|
59
59
|
console.error("Tracking-id step failed, saving anyway:", d);
|
|
60
60
|
}
|
|
61
|
-
const { html:
|
|
61
|
+
const { html: y, ampHtml: p = "", ampErrors: T = [] } = await r({
|
|
62
62
|
minimize: !0,
|
|
63
63
|
resetDataSavedFlag: !1
|
|
64
64
|
});
|
|
65
65
|
o.selectedUnsubscribePages.length && await o.fetchTemplates(), await S(s);
|
|
66
|
-
const { compiledHtml:
|
|
66
|
+
const { compiledHtml: A, stats: l, appliedRules: w } = t(y), C = p && m(p).compiledHtml, H = n.getSelectedDynamicContentList, k = b(), f = M(s);
|
|
67
67
|
return console.debug("HTML Compilation Stats:", {
|
|
68
68
|
originalSize: l.originalSize,
|
|
69
69
|
compiledSize: l.compiledSize,
|
|
70
70
|
reduction: `${l.reductionPercentage.toFixed(2)}%`,
|
|
71
|
-
appliedRules:
|
|
71
|
+
appliedRules: w,
|
|
72
72
|
executionTime: `${l.executionTime.toFixed(2)}ms`
|
|
73
73
|
}), {
|
|
74
|
-
dynamicContentList:
|
|
75
|
-
compiledHtml:
|
|
74
|
+
dynamicContentList: H,
|
|
75
|
+
compiledHtml: A,
|
|
76
76
|
rawHtml: s,
|
|
77
77
|
css: u,
|
|
78
|
-
ampHtml:
|
|
79
|
-
ampErrors:
|
|
80
|
-
modules:
|
|
78
|
+
ampHtml: C,
|
|
79
|
+
ampErrors: T,
|
|
80
|
+
modules: h.map(Number),
|
|
81
81
|
recommendation: {
|
|
82
|
-
campaignUrls:
|
|
82
|
+
campaignUrls: k.recommendationCampaignUrls,
|
|
83
83
|
configs: {}
|
|
84
84
|
},
|
|
85
85
|
unsubscribe: {
|
|
@@ -94,6 +94,6 @@ const Z = () => {
|
|
|
94
94
|
};
|
|
95
95
|
};
|
|
96
96
|
export {
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
M as getHtmlReferencedUnsubscribePages,
|
|
98
|
+
Y as useTemplatePreparation
|
|
99
99
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.21.2-beta.
|
|
3
|
+
"version": "3.21.2-beta.4b0fed7",
|
|
4
4
|
"description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
|
|
5
5
|
"main": "./dist/guido.umd.cjs",
|
|
6
6
|
"module": "./dist/library.js",
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { useToaster as i } from "../useToaster.js";
|
|
2
|
-
import { useTranslations as m } from "../useTranslations.js";
|
|
3
|
-
import { ToasterTypeOptions as c } from "../../enums/toaster.js";
|
|
4
|
-
const u = "newsletter.multiple-html-designs-detected", r = `(?:[^>"']|"[^"]*"|'[^']*')*`, a = "style|script|noscript|xmp|iframe|noembed|noframes|textarea|title", T = /<html(?=[\s>/])/gi, A = new RegExp(
|
|
5
|
-
`<!--[\\s\\S]*?-->|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|<(${a})(?=[\\s/>])${r}>[\\s\\S]*?</\\1\\s*>|<([a-zA-Z][\\w:-]*)${r}>`,
|
|
6
|
-
"gi"
|
|
7
|
-
), p = (e) => Array.from(e.matchAll(A)).filter(([, , t]) => (t == null ? void 0 : t.toLowerCase()) === "html").length, g = () => {
|
|
8
|
-
const { showToaster: e } = i(), t = m();
|
|
9
|
-
return { validateSingleHtmlDocument: (o, l = !1) => {
|
|
10
|
-
var n;
|
|
11
|
-
if ((((n = o.match(T)) == null ? void 0 : n.length) ?? 0) < 2)
|
|
12
|
-
return !0;
|
|
13
|
-
const s = p(o);
|
|
14
|
-
return s <= 1 ? !0 : (console.debug("guido:save:blocked", { reason: "multiple-html-documents", htmlRootCount: s }), l || e({
|
|
15
|
-
type: c.Warning,
|
|
16
|
-
message: t(u)
|
|
17
|
-
}), !1);
|
|
18
|
-
} };
|
|
19
|
-
};
|
|
20
|
-
export {
|
|
21
|
-
g as useHtmlDocumentCountValidator
|
|
22
|
-
};
|