@useinsider/guido 3.7.0-beta.2037cb1 → 3.7.0-beta.24bdfa3
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/@types/config/schemas.js +70 -66
- package/dist/composables/usePreviewMode.js +15 -14
- package/dist/composables/useRecommendationPreview.js +100 -0
- package/dist/composables/useStripo.js +39 -44
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +90 -82
- package/dist/config/migrator/recommendation/htmlBuilder.js +59 -58
- package/dist/config/migrator/recommendation/settingsMapper.js +38 -33
- package/dist/extensions/Blocks/Recommendation/block.js +58 -39
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +41 -32
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +369 -288
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +84 -72
- package/dist/extensions/Blocks/Recommendation/controls/main/pricePlacement.js +133 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +68 -66
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +21 -7
- package/dist/extensions/Blocks/Recommendation/recommendation.css.js +64 -4
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +7 -5
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +101 -72
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +31 -30
- package/dist/extensions/Blocks/Recommendation/templates/index.js +9 -7
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +74 -59
- package/dist/extensions/Blocks/Recommendation/templates/list/template.js +21 -21
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +88 -57
- package/dist/src/@types/config/schemas.d.ts +16 -0
- package/dist/src/composables/useConfig.d.ts +4 -0
- package/dist/src/composables/useRecommendationPreview.d.ts +10 -0
- package/dist/src/composables/useRecommendationPreview.test.d.ts +1 -0
- package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +29 -3
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +3 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/pricePlacement.d.ts +59 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/elementRenderer.d.ts +16 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
- package/dist/src/extensions/Blocks/Recommendation/templates/list/elementRenderer.d.ts +13 -0
- package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -2
- package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +33 -1
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +15 -0
- package/dist/src/stores/config.d.ts +36 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ModuleFolderDefaults as S } from "../../enums/defaults.js";
|
|
2
|
-
import { object as
|
|
2
|
+
import { object as a, number as s, optional as e, string as t, picklist as l, pipe as p, minLength as b, custom as h, boolean as o, array as c, record as k, literal as i, looseObject as y, variant as g, union as f, unknown as n } from "../../node_modules/valibot/dist/index.js";
|
|
3
3
|
const d = {
|
|
4
4
|
/** Promotional/marketing emails */
|
|
5
5
|
PROMOTIONAL: 1,
|
|
@@ -12,7 +12,7 @@ const d = {
|
|
|
12
12
|
ARCHITECT: 49,
|
|
13
13
|
/** Unsubscribe page builder */
|
|
14
14
|
UNSUBSCRIBE_PAGES: 97
|
|
15
|
-
}, R =
|
|
15
|
+
}, R = a({
|
|
16
16
|
/** Unique identifier for the template being edited */
|
|
17
17
|
templateId: p(
|
|
18
18
|
t(),
|
|
@@ -25,12 +25,12 @@ const d = {
|
|
|
25
25
|
),
|
|
26
26
|
/** Optional variation ID for A/B testing */
|
|
27
27
|
variationId: e(t())
|
|
28
|
-
}),
|
|
28
|
+
}), T = a({
|
|
29
29
|
/** Fallback font name (e.g., "Georgia") */
|
|
30
30
|
name: t(),
|
|
31
31
|
/** Fallback font family (e.g., "serif" or "sans-serif") */
|
|
32
32
|
family: t()
|
|
33
|
-
}),
|
|
33
|
+
}), C = a({
|
|
34
34
|
/** Partner/organization name (required) */
|
|
35
35
|
name: p(
|
|
36
36
|
t(),
|
|
@@ -53,8 +53,8 @@ const d = {
|
|
|
53
53
|
/** Display name for the current user */
|
|
54
54
|
username: e(t(), "Guido User"),
|
|
55
55
|
/** Fallback font settings from partner settings — used to match backend size calculation */
|
|
56
|
-
fallbackFont: e(
|
|
57
|
-
}), A =
|
|
56
|
+
fallbackFont: e(T)
|
|
57
|
+
}), A = a({
|
|
58
58
|
/** Display text for the dynamic content */
|
|
59
59
|
text: t(),
|
|
60
60
|
/** Template variable value (e.g., {{username}}) */
|
|
@@ -63,53 +63,57 @@ const d = {
|
|
|
63
63
|
fallback: e(t()),
|
|
64
64
|
/** Optional formatting options */
|
|
65
65
|
format: e(
|
|
66
|
-
|
|
66
|
+
a({
|
|
67
67
|
key: t(),
|
|
68
68
|
value: t()
|
|
69
69
|
})
|
|
70
70
|
)
|
|
71
71
|
}), I = y({
|
|
72
72
|
/** Block ID (matches the dictionary key and the legacy HTML element id) */
|
|
73
|
-
id: e(
|
|
73
|
+
id: e(s()),
|
|
74
74
|
/** Decimal places for price display (legacy data may use string or number) */
|
|
75
|
-
decimalCount: e(f([t(),
|
|
75
|
+
decimalCount: e(f([t(), s()])),
|
|
76
76
|
/** Pinned product IDs (empty array when filter-driven) */
|
|
77
|
-
productIds: e(c(
|
|
77
|
+
productIds: e(c(n())),
|
|
78
78
|
/** Whether the block requested live products at send time */
|
|
79
|
-
sendProductRequestFlag: e(
|
|
79
|
+
sendProductRequestFlag: e(o()),
|
|
80
80
|
/** Whether to randomize product order */
|
|
81
|
-
shuffleProducts: e(
|
|
81
|
+
shuffleProducts: e(o()),
|
|
82
82
|
/** Filter rules driving product selection */
|
|
83
|
-
filters: e(c(
|
|
83
|
+
filters: e(c(n())),
|
|
84
84
|
/** Currency code (e.g. 'EUR') — sometimes absent in legacy data */
|
|
85
85
|
currency: e(t()),
|
|
86
86
|
/** Currency display settings (separators, alignment, decimals) */
|
|
87
|
-
currencySettings: e(
|
|
87
|
+
currencySettings: e(n()),
|
|
88
88
|
/** Locale (e.g. 'nl_NL') */
|
|
89
89
|
language: e(t()),
|
|
90
90
|
/** Recommendation strategy key (e.g. 'newArrivals') */
|
|
91
91
|
strategy: e(t()),
|
|
92
92
|
/** Snapshot of products as rendered by the legacy block */
|
|
93
|
-
recommendedProducts: e(c(
|
|
93
|
+
recommendedProducts: e(c(n())),
|
|
94
94
|
/** Number of product cards per row */
|
|
95
|
-
cardsInRow: e(
|
|
95
|
+
cardsInRow: e(s()),
|
|
96
96
|
/** Mobile-only padding (right) */
|
|
97
|
-
mobileRightPadding: e(
|
|
97
|
+
mobileRightPadding: e(s()),
|
|
98
98
|
/** Mobile-only padding (left) */
|
|
99
|
-
mobileLeftPadding: e(
|
|
99
|
+
mobileLeftPadding: e(s()),
|
|
100
100
|
/** Disable responsive scaling */
|
|
101
|
-
unresponsive: e(
|
|
101
|
+
unresponsive: e(o()),
|
|
102
102
|
/** Layout orientation ('vertical' | 'horizontal') */
|
|
103
103
|
orientation: e(t()),
|
|
104
104
|
/** Whether long text is trimmed */
|
|
105
|
-
textTrimming: e(
|
|
105
|
+
textTrimming: e(o()),
|
|
106
106
|
/** Block type marker used by some legacy variants */
|
|
107
107
|
blockType: e(t()),
|
|
108
108
|
/** Size variant marker (legacy data may use string or number) */
|
|
109
|
-
size: e(f([t(),
|
|
109
|
+
size: e(f([t(), s()])),
|
|
110
110
|
/** Vertical responsiveness flag (legacy size=1 variants) */
|
|
111
|
-
verticalResponsiveness: e(
|
|
112
|
-
|
|
111
|
+
verticalResponsiveness: e(o()),
|
|
112
|
+
/** Legacy "Move to next line" price placement toggle (cardPricePlacement.js) */
|
|
113
|
+
isPriceMovedToNextLine: e(o()),
|
|
114
|
+
/** Legacy "Hide if same as discounted" / delete-price-for-zero-sale toggle */
|
|
115
|
+
isPriceDeletedForZeroSale: e(o())
|
|
116
|
+
}), L = a({
|
|
113
117
|
/**
|
|
114
118
|
* Legacy recommendation block configs keyed by block ID.
|
|
115
119
|
* Pass this when loading a template authored with the v1
|
|
@@ -120,7 +124,7 @@ const d = {
|
|
|
120
124
|
k(t(), I),
|
|
121
125
|
{}
|
|
122
126
|
)
|
|
123
|
-
}),
|
|
127
|
+
}), P = a({
|
|
124
128
|
/** Initial HTML content */
|
|
125
129
|
html: e(t(), ""),
|
|
126
130
|
/** Initial CSS content */
|
|
@@ -133,53 +137,53 @@ const d = {
|
|
|
133
137
|
/** Valid custom field attribute names from the partner's categorized fields */
|
|
134
138
|
customFieldAttributes: e(c(t()), []),
|
|
135
139
|
/** Selected unsubscribe page IDs */
|
|
136
|
-
selectedUnsubscribePages: e(c(
|
|
140
|
+
selectedUnsubscribePages: e(c(s()), []),
|
|
137
141
|
/** Force recreate template in Stripo storage (use true when updating externally modified templates) */
|
|
138
|
-
forceRecreate: e(
|
|
142
|
+
forceRecreate: e(o(), !1),
|
|
139
143
|
/** Migration-only inputs (legacy block configs) */
|
|
140
|
-
migration: e(
|
|
141
|
-
}),
|
|
144
|
+
migration: e(L, {})
|
|
145
|
+
}), v = a({
|
|
142
146
|
/** Sender display name */
|
|
143
147
|
senderName: e(t(), ""),
|
|
144
148
|
/** Email subject line */
|
|
145
149
|
subject: e(t(), "")
|
|
146
|
-
}),
|
|
150
|
+
}), E = a({
|
|
147
151
|
/** Locale for the editor UI */
|
|
148
152
|
locale: e(t(), "en"),
|
|
149
153
|
/** Path to translations object */
|
|
150
154
|
translationsPath: e(t(), "window.trans[Object.keys(window.trans)[0]]"),
|
|
151
155
|
/** Migration date for template compatibility */
|
|
152
|
-
migrationDate: e(
|
|
156
|
+
migrationDate: e(s(), 1759696858),
|
|
153
157
|
/** Email header settings */
|
|
154
|
-
emailHeader: e(
|
|
158
|
+
emailHeader: e(v, { senderName: "", subject: "" }),
|
|
155
159
|
/** Folder name for user-saved modules (used by Stripo plugin panel for path construction) */
|
|
156
160
|
savedModulesFolderName: e(t(), S.SAVED_MODULES),
|
|
157
161
|
/** Folder name for default/prebuilt modules (used by Stripo plugin panel for path construction) */
|
|
158
162
|
defaultModulesFolderName: e(t(), S.DEFAULT_MODULES)
|
|
159
|
-
}), M =
|
|
163
|
+
}), M = a({
|
|
160
164
|
/** Whether to show the header bar */
|
|
161
|
-
showHeader: e(
|
|
165
|
+
showHeader: e(o(), !0),
|
|
162
166
|
/** Custom label for back button (if shown) */
|
|
163
167
|
backButtonLabel: e(t())
|
|
164
|
-
}),
|
|
168
|
+
}), O = a({
|
|
165
169
|
/** Enable dynamic content insertion */
|
|
166
|
-
dynamicContent: e(
|
|
170
|
+
dynamicContent: e(o(), !0),
|
|
167
171
|
/** Enable save as template functionality */
|
|
168
|
-
saveAsTemplate: e(
|
|
172
|
+
saveAsTemplate: e(o(), !0),
|
|
169
173
|
/** Enable version history */
|
|
170
|
-
versionHistory: e(
|
|
174
|
+
versionHistory: e(o(), !0),
|
|
171
175
|
/** Enable test message sending */
|
|
172
|
-
testMessage: e(
|
|
176
|
+
testMessage: e(o(), !0),
|
|
173
177
|
/** Enable display conditions */
|
|
174
|
-
displayConditions: e(
|
|
178
|
+
displayConditions: e(o(), !0),
|
|
175
179
|
/** Enable unsubscribe block */
|
|
176
|
-
unsubscribe: e(
|
|
180
|
+
unsubscribe: e(o(), !0),
|
|
177
181
|
/** Disable modules panel in the editor */
|
|
178
|
-
modulesDisabled: e(
|
|
182
|
+
modulesDisabled: e(o(), !1),
|
|
179
183
|
/** Enable Liquid template syntax */
|
|
180
|
-
liquidSyntax: e(
|
|
184
|
+
liquidSyntax: e(o(), !1),
|
|
181
185
|
/** Enable autosave (3-min interval + tab-hide). User toggles on/off from the header. */
|
|
182
|
-
autosave: e(
|
|
186
|
+
autosave: e(o(), !1)
|
|
183
187
|
}), N = l([
|
|
184
188
|
"amp-accordion",
|
|
185
189
|
"amp-carousel",
|
|
@@ -202,7 +206,7 @@ const d = {
|
|
|
202
206
|
"unsubscribe-block",
|
|
203
207
|
"coupon-block",
|
|
204
208
|
"items-block"
|
|
205
|
-
]), x =
|
|
209
|
+
]), x = a({
|
|
206
210
|
/** Default blocks to exclude from the editor */
|
|
207
211
|
excludeDefaults: e(
|
|
208
212
|
c(N),
|
|
@@ -213,14 +217,14 @@ const d = {
|
|
|
213
217
|
c(D),
|
|
214
218
|
[]
|
|
215
219
|
)
|
|
216
|
-
}), m =
|
|
220
|
+
}), m = a({
|
|
217
221
|
/** Unique identifier for the rule */
|
|
218
222
|
id: t(),
|
|
219
223
|
/** Human-readable description */
|
|
220
224
|
description: e(t()),
|
|
221
225
|
/** Priority for rule ordering (lower = earlier) */
|
|
222
|
-
priority:
|
|
223
|
-
}), F =
|
|
226
|
+
priority: s()
|
|
227
|
+
}), F = a({
|
|
224
228
|
...m.entries,
|
|
225
229
|
type: i("replace"),
|
|
226
230
|
/** String to search for */
|
|
@@ -228,8 +232,8 @@ const d = {
|
|
|
228
232
|
/** Replacement string */
|
|
229
233
|
replacement: t(),
|
|
230
234
|
/** Replace all occurrences (default: false) */
|
|
231
|
-
replaceAll: e(
|
|
232
|
-
}), U =
|
|
235
|
+
replaceAll: e(o())
|
|
236
|
+
}), U = a({
|
|
233
237
|
...m.entries,
|
|
234
238
|
type: i("regex"),
|
|
235
239
|
/** Regex pattern string */
|
|
@@ -238,12 +242,12 @@ const d = {
|
|
|
238
242
|
replacement: t(),
|
|
239
243
|
/** Regex flags (e.g., 'gi') */
|
|
240
244
|
flags: e(t())
|
|
241
|
-
}), B =
|
|
245
|
+
}), B = a({
|
|
242
246
|
...m.entries,
|
|
243
247
|
type: i("remove"),
|
|
244
248
|
/** Strings or patterns to remove */
|
|
245
249
|
targets: c(t())
|
|
246
|
-
}), w =
|
|
250
|
+
}), w = a({
|
|
247
251
|
...m.entries,
|
|
248
252
|
type: i("custom"),
|
|
249
253
|
/** Custom processor function */
|
|
@@ -256,12 +260,12 @@ const d = {
|
|
|
256
260
|
U,
|
|
257
261
|
B,
|
|
258
262
|
w
|
|
259
|
-
]), j =
|
|
263
|
+
]), j = a({
|
|
260
264
|
/** Custom compiler rules to apply */
|
|
261
265
|
customRules: e(c(H), []),
|
|
262
266
|
/** Skip default compiler rules */
|
|
263
|
-
ignoreDefaultRules: e(
|
|
264
|
-
}), q =
|
|
267
|
+
ignoreDefaultRules: e(o(), !1)
|
|
268
|
+
}), q = a({
|
|
265
269
|
/**
|
|
266
270
|
* External validation handler called before save completes.
|
|
267
271
|
* Return false to cancel the save operation.
|
|
@@ -272,21 +276,21 @@ const d = {
|
|
|
272
276
|
"externalValidation must be a function"
|
|
273
277
|
)
|
|
274
278
|
)
|
|
275
|
-
}), V =
|
|
279
|
+
}), V = a({
|
|
276
280
|
// Required sections
|
|
277
281
|
/** Identity configuration (required) */
|
|
278
282
|
identity: R,
|
|
279
283
|
/** Partner configuration (required) */
|
|
280
|
-
partner:
|
|
284
|
+
partner: C,
|
|
281
285
|
// Optional sections (with defaults)
|
|
282
286
|
/** Template content and presets */
|
|
283
|
-
template: e(
|
|
287
|
+
template: e(P, {}),
|
|
284
288
|
/** Editor settings */
|
|
285
|
-
editor: e(
|
|
289
|
+
editor: e(E, {}),
|
|
286
290
|
/** UI configuration */
|
|
287
291
|
ui: e(M, {}),
|
|
288
292
|
/** Feature toggles */
|
|
289
|
-
features: e(
|
|
293
|
+
features: e(O, {}),
|
|
290
294
|
/** Block configuration */
|
|
291
295
|
blocks: e(x, {}),
|
|
292
296
|
/** Compiler configuration */
|
|
@@ -303,20 +307,20 @@ export {
|
|
|
303
307
|
w as CustomRuleSchema,
|
|
304
308
|
N as DefaultBlockTypeSchema,
|
|
305
309
|
A as DynamicContentSchema,
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
+
E as EditorSchema,
|
|
311
|
+
v as EmailHeaderSchema,
|
|
312
|
+
T as FallbackFontSchema,
|
|
313
|
+
O as FeaturesSchema,
|
|
310
314
|
V as GuidoConfigSchema,
|
|
311
315
|
R as IdentitySchema,
|
|
312
316
|
I as LegacyRecommendationConfigSchema,
|
|
313
317
|
d as MessageType,
|
|
314
|
-
|
|
318
|
+
C as PartnerSchema,
|
|
315
319
|
r as ProductType,
|
|
316
320
|
U as RegexRuleSchema,
|
|
317
321
|
B as RemoveRuleSchema,
|
|
318
322
|
F as ReplaceRuleSchema,
|
|
319
|
-
|
|
320
|
-
|
|
323
|
+
L as TemplateMigrationSchema,
|
|
324
|
+
P as TemplateSchema,
|
|
321
325
|
M as UISchema
|
|
322
326
|
};
|
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
import { useEditorStore as
|
|
2
|
-
import { usePreviewStore as
|
|
3
|
-
import { useActionsApi as
|
|
4
|
-
import { useCodeEditorApi as
|
|
5
|
-
import { useHtmlCompiler as
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { useEditorStore as n } from "../stores/editor.js";
|
|
2
|
+
import { usePreviewStore as p } from "../stores/preview.js";
|
|
3
|
+
import { useActionsApi as c } from "./useActionsApi.js";
|
|
4
|
+
import { useCodeEditorApi as u } from "./useCodeEditorApi.js";
|
|
5
|
+
import { useHtmlCompiler as v } from "./useHtmlCompiler.js";
|
|
6
|
+
import { useRecommendationPreview as w } from "./useRecommendationPreview.js";
|
|
7
|
+
const C = () => {
|
|
8
|
+
const t = n(), e = p(), { closeCodeEditor: a } = u(), { getPreviewData: m, getCompiledEmail: s } = c(), { compileHtml: l } = v(), { substituteRecommendationPreview: r } = w(), i = () => {
|
|
8
9
|
t.isPreviewModeOpen = !1, e.$reset();
|
|
9
10
|
};
|
|
10
11
|
return {
|
|
11
|
-
closePreviewMode:
|
|
12
|
+
closePreviewMode: i,
|
|
12
13
|
openPreviewMode: () => {
|
|
13
|
-
t.isCodeEditorOpen &&
|
|
14
|
+
t.isCodeEditorOpen && a(), t.isPreviewModeOpen = !0;
|
|
14
15
|
},
|
|
15
16
|
loadPreviewData: async () => {
|
|
16
17
|
if (!(t.loadingStatus || e.isLoaded)) {
|
|
17
18
|
t.loadingStatus = !0;
|
|
18
19
|
try {
|
|
19
|
-
const [o,
|
|
20
|
-
|
|
20
|
+
const [o, d] = await Promise.all([
|
|
21
|
+
m(),
|
|
21
22
|
s({ minimize: !0, resetDataSavedFlag: !1 })
|
|
22
23
|
]);
|
|
23
|
-
e.templateHtml = o.html || "", e.ampHtml = o.ampHtml || "", e.ampErrors = o.ampErrors || [], e.setEmailFormat(o.ampHtml ? "AMP" : "html"), e.emailSizeKB =
|
|
24
|
+
e.templateHtml = r(o.html || ""), e.ampHtml = r(o.ampHtml || ""), e.ampErrors = o.ampErrors || [], e.setEmailFormat(o.ampHtml ? "AMP" : "html"), e.emailSizeKB = l(d.html).estimatedSizeKB, e.isLoaded = !0;
|
|
24
25
|
} catch (o) {
|
|
25
|
-
console.error("Failed to load preview data:", o),
|
|
26
|
+
console.error("Failed to load preview data:", o), i();
|
|
26
27
|
} finally {
|
|
27
28
|
t.loadingStatus = !1;
|
|
28
29
|
}
|
|
@@ -31,5 +32,5 @@ const g = () => {
|
|
|
31
32
|
};
|
|
32
33
|
};
|
|
33
34
|
export {
|
|
34
|
-
|
|
35
|
+
C as usePreviewMode
|
|
35
36
|
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { BLOCK_ROOT_SELECTOR as S, CURRENCY_ATTR as d, CONTAINER_SELECTOR as f } from "../extensions/Blocks/Recommendation/constants/selectors.js";
|
|
2
|
+
import { useRecommendationExtensionStore as O } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
3
|
+
import { formatPrice as g } from "../extensions/Blocks/Recommendation/utils/priceFormatter.js";
|
|
4
|
+
const p = `${S}[recommendation-id]`, R = ".product-old-price", C = /\{\{(?:reco_)?(\d+_\d+_[a-zA-Z0-9_.]+)\}\}/g, h = new RegExp(
|
|
5
|
+
"\\{%\\s*if\\s+([\\s\\S]+?)\\s*%\\}([\\s\\S]*?)(?:\\{%\\s*else\\s*%\\}([\\s\\S]*?))?\\{%\\s*endif\\s*%\\}",
|
|
6
|
+
"g"
|
|
7
|
+
);
|
|
8
|
+
function T(e) {
|
|
9
|
+
const t = e.getAttribute(d.CURRENCY) || "USD", i = e.getAttribute(d.DECIMAL_SEPARATOR) || ".", s = e.getAttribute(d.THOUSAND_SEPARATOR) || ",";
|
|
10
|
+
return {
|
|
11
|
+
code: t,
|
|
12
|
+
symbol: e.getAttribute(d.SYMBOL) || t,
|
|
13
|
+
alignment: e.getAttribute(d.ALIGNMENT) === "0" ? "before" : "after",
|
|
14
|
+
decimalCount: parseInt(e.getAttribute(d.DECIMAL_COUNT) || "2") || 2,
|
|
15
|
+
decimalSeparator: i,
|
|
16
|
+
thousandSeparator: s
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function _(e, t) {
|
|
20
|
+
return (e == null ? void 0 : e[t]) ?? Object.values(e ?? {})[0] ?? 0;
|
|
21
|
+
}
|
|
22
|
+
function b(e, t) {
|
|
23
|
+
const i = _(e.original_price, t), s = _(e.price, t), n = i > 0 ? Math.round((i - s) / i * 100) : 0;
|
|
24
|
+
return n > 0 ? `${n}%` : "0%";
|
|
25
|
+
}
|
|
26
|
+
function N(e, t, i, s, n, a) {
|
|
27
|
+
s.forEach((o, c) => {
|
|
28
|
+
const r = (m) => `${i}_${c}_${m}`, u = g({ price: _(o.price, n.code), currency: n }), l = g({ price: _(o.original_price, n.code), currency: n }), A = b(o, n.code);
|
|
29
|
+
e.set(r("name"), o.name ?? ""), e.set(r("image_url"), o.image_url ?? ""), e.set(r("url"), o.url ?? ""), e.set(r("item_id"), o.item_id ?? ""), e.set(r("currency"), ""), e.set(r("price"), u), e.set(r("original_price"), l), e.set(r("discount"), A), e.set(r("omnibus_price"), l), e.set(r("omnibus_discount"), A), a && u === l && t.add(`${i}_${c}`), Object.entries(o.product_attributes ?? {}).forEach(([m, E]) => {
|
|
30
|
+
e.set(r(`product_attribute.${m}`), String(E)), e.set(r(m), String(E));
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function L(e, t) {
|
|
35
|
+
const i = e.match(/^(.+?)\s*(!=|==)\s*"([^"]*)"$/);
|
|
36
|
+
if (!i)
|
|
37
|
+
return !0;
|
|
38
|
+
const [, s, n, a] = i, o = t.get(s.trim()) ?? "";
|
|
39
|
+
return n === "!=" ? o !== a : o === a;
|
|
40
|
+
}
|
|
41
|
+
function P(e, t) {
|
|
42
|
+
return e.replace(
|
|
43
|
+
h,
|
|
44
|
+
(i, s, n, a) => s.split(/\s+and\s+/).every((c) => L(c.trim(), t)) ? n : a ?? ""
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
function $(e) {
|
|
48
|
+
let t = e;
|
|
49
|
+
for (; t.children.length === 1; )
|
|
50
|
+
[t] = t.children;
|
|
51
|
+
return t;
|
|
52
|
+
}
|
|
53
|
+
function D(e, t) {
|
|
54
|
+
var o;
|
|
55
|
+
if (!t.size)
|
|
56
|
+
return e;
|
|
57
|
+
const i = e.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), s = new DOMParser().parseFromString(i, "text/html");
|
|
58
|
+
s.querySelectorAll(p).forEach((c) => {
|
|
59
|
+
const r = Number(c.getAttribute("recommendation-id"));
|
|
60
|
+
if (!Number.isFinite(r))
|
|
61
|
+
return;
|
|
62
|
+
const u = c.querySelectorAll(f);
|
|
63
|
+
(u.length ? Array.from(u) : [c]).forEach((A) => {
|
|
64
|
+
A.querySelectorAll(R).forEach((m, E) => {
|
|
65
|
+
t.has(`${r}_${E}`) && ($(m).textContent = "");
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
const n = (o = e.match(/<!DOCTYPE[^>]*>/i)) == null ? void 0 : o[0];
|
|
70
|
+
return ((n ? `${n}
|
|
71
|
+
` : "") + s.documentElement.outerHTML).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}");
|
|
72
|
+
}
|
|
73
|
+
function I(e) {
|
|
74
|
+
if (!e || !e.includes("recommendation-block-v2"))
|
|
75
|
+
return e;
|
|
76
|
+
const t = O(), i = new DOMParser().parseFromString(e, "text/html"), s = Array.from(i.querySelectorAll(p)), n = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set();
|
|
77
|
+
if (s.forEach((c) => {
|
|
78
|
+
var l;
|
|
79
|
+
const r = Number(c.getAttribute("recommendation-id"));
|
|
80
|
+
if (!Number.isFinite(r))
|
|
81
|
+
return;
|
|
82
|
+
const u = ((l = t.blockStates[r]) == null ? void 0 : l.recommendationProducts) ?? [];
|
|
83
|
+
u.length && N(
|
|
84
|
+
n,
|
|
85
|
+
a,
|
|
86
|
+
r,
|
|
87
|
+
u,
|
|
88
|
+
T(c),
|
|
89
|
+
c.getAttribute("hide-price") === "true"
|
|
90
|
+
);
|
|
91
|
+
}), !n.size)
|
|
92
|
+
return e;
|
|
93
|
+
let o = D(e, a);
|
|
94
|
+
return o = o.replace(C, (c, r) => n.has(r) ? n.get(r) : c), o = P(o, n), o;
|
|
95
|
+
}
|
|
96
|
+
const x = () => ({ substituteRecommendationPreview: I });
|
|
97
|
+
export {
|
|
98
|
+
I as substituteRecommendationPreview,
|
|
99
|
+
x as useRecommendationPreview
|
|
100
|
+
};
|
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
import { useActionsApi as D } from "./useActionsApi.js";
|
|
2
|
-
import { useBlocksConfig as
|
|
3
|
-
import { useConfig as
|
|
2
|
+
import { useBlocksConfig as I } from "./useBlocksConfig.js";
|
|
3
|
+
import { useConfig as P } from "./useConfig.js";
|
|
4
4
|
import { useCustomInterfaceAppearance as U } from "./useCustomInterfaceAppearance.js";
|
|
5
5
|
import { useFullStoryBridge as R } from "./useFullStoryBridge.js";
|
|
6
6
|
import { useStripoEventHandler as q } from "./useStripoEventHandler.js";
|
|
7
7
|
import { useToaster as x } from "./useToaster.js";
|
|
8
8
|
import { localePatch as H } from "../config/i18n/index.js";
|
|
9
9
|
import { useStripoApi as O } from "../services/stripoApi.js";
|
|
10
|
-
import
|
|
11
|
-
import { useEditorStore as
|
|
12
|
-
import { dynamicContentToMergeTags as
|
|
13
|
-
import
|
|
14
|
-
const se = (
|
|
15
|
-
const { features:
|
|
10
|
+
import j from "../static/styles/customEditorStyle.css.js";
|
|
11
|
+
import { useEditorStore as E } from "../stores/editor.js";
|
|
12
|
+
import { dynamicContentToMergeTags as z } from "../utils/genericUtil.js";
|
|
13
|
+
import L from "../package.json.js";
|
|
14
|
+
const se = (C, l) => {
|
|
15
|
+
const { features: c, template: h, isFeatureEnabled: u } = P(), { handleError: m } = x(), { getToken: w, getCustomFonts: b, getSyncModulesStatus: k } = O(), { handleEvent: F } = q(), { getStripoBlocksConfig: B } = I(), T = async (i, r = [], s = !1) => {
|
|
16
16
|
var g, S, y;
|
|
17
|
-
const e =
|
|
17
|
+
const e = E(), { html: p, css: a } = i, { baseBlocks: o, extensions: d } = await B(), f = ((g = c.value) == null ? void 0 : g.displayConditions) ?? !0, _ = ((S = c.value) == null ? void 0 : S.modulesDisabled) ?? !1, v = ((y = h.value) == null ? void 0 : y.forceRecreate) ?? !1;
|
|
18
18
|
window.UIEditor.initEditor(
|
|
19
19
|
document.querySelector("#guido-editor"),
|
|
20
20
|
{
|
|
21
|
-
metadata:
|
|
21
|
+
metadata: C,
|
|
22
22
|
html: p,
|
|
23
23
|
css: a,
|
|
24
|
-
forceRecreate:
|
|
24
|
+
forceRecreate: v,
|
|
25
25
|
locale: "en",
|
|
26
26
|
undoButtonSelector: "#guido__undo-button",
|
|
27
27
|
redoButtonSelector: "#guido__redo-button",
|
|
28
28
|
mobileViewButtonSelector: ".guido__view-option-selection-mobile",
|
|
29
29
|
desktopViewButtonSelector: ".guido__view-option-selection-desktop",
|
|
30
30
|
codeEditorButtonSelector: "#guido__code-button",
|
|
31
|
-
customAppearanceMergetags: !
|
|
31
|
+
customAppearanceMergetags: !u("liquidSyntax"),
|
|
32
32
|
customAppearanceMergetagsBorderColor: "#f1f3fe",
|
|
33
33
|
customAppearanceMergetagsBackgroundColor: "#f1f3fe",
|
|
34
|
-
customViewStyles:
|
|
34
|
+
customViewStyles: j,
|
|
35
35
|
conditionsEnabled: f,
|
|
36
36
|
customConditionsEnabled: f,
|
|
37
37
|
enableXSSSecurity: !0,
|
|
38
|
-
modulesDisabled:
|
|
39
|
-
syncModulesEnabled:
|
|
38
|
+
modulesDisabled: _,
|
|
39
|
+
syncModulesEnabled: s,
|
|
40
40
|
messageSettingsEnabled: !0,
|
|
41
41
|
displayGmailAnnotations: !0,
|
|
42
42
|
displayHiddenPreheader: !1,
|
|
@@ -45,7 +45,7 @@ const se = (E, c) => {
|
|
|
45
45
|
selectElementAfterDrop: !0,
|
|
46
46
|
sameFontSizeForOutlook: !0,
|
|
47
47
|
allowedScriptSourceDomains: "https://email-static.useinsider.com https://edge.fullstory.com https://rs.fullstory.com",
|
|
48
|
-
...
|
|
48
|
+
...o ? { baseBlocks: o } : {},
|
|
49
49
|
editorFonts: {
|
|
50
50
|
showDefaultStandardFonts: !0,
|
|
51
51
|
showDefaultNotStandardFonts: !0,
|
|
@@ -53,9 +53,9 @@ const se = (E, c) => {
|
|
|
53
53
|
},
|
|
54
54
|
mergeTags: [
|
|
55
55
|
{
|
|
56
|
-
entries:
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
entries: z(
|
|
57
|
+
l.preselectedDynamicContentList,
|
|
58
|
+
u("liquidSyntax")
|
|
59
59
|
)
|
|
60
60
|
}
|
|
61
61
|
],
|
|
@@ -64,17 +64,17 @@ const se = (E, c) => {
|
|
|
64
64
|
const n = await w();
|
|
65
65
|
t(n);
|
|
66
66
|
} catch (n) {
|
|
67
|
-
|
|
67
|
+
m(n, "Failed to refresh token");
|
|
68
68
|
}
|
|
69
69
|
},
|
|
70
70
|
onTemplateLoaded() {
|
|
71
71
|
try {
|
|
72
72
|
const { importCss: t } = U(), { activateCustomViewStyles: n, updateTimerInClonedTemplate: M } = D(), { injectFullStory: A } = R();
|
|
73
|
-
t(), n(), A(), M(),
|
|
73
|
+
t(), n(), A(), M(), l.onReady(), e.isStripoInitialized = !0, e.loadingStatus = !1, setTimeout(() => {
|
|
74
74
|
e.hasChanges = !1;
|
|
75
75
|
}, 1e3);
|
|
76
76
|
} catch (t) {
|
|
77
|
-
|
|
77
|
+
m(t, "Failed to load custom interface appearance");
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
onCodeEditorVisibilityChanged(t) {
|
|
@@ -89,7 +89,7 @@ const se = (E, c) => {
|
|
|
89
89
|
onDataChanged() {
|
|
90
90
|
e.hasChanges = !0;
|
|
91
91
|
},
|
|
92
|
-
onEvent:
|
|
92
|
+
onEvent: F,
|
|
93
93
|
ignoreClickOutsideSelectors: [
|
|
94
94
|
"#guido-dynamic-content-modal",
|
|
95
95
|
".in-on-board-wrapper",
|
|
@@ -99,32 +99,27 @@ const se = (E, c) => {
|
|
|
99
99
|
localePatch: H
|
|
100
100
|
}
|
|
101
101
|
);
|
|
102
|
-
},
|
|
102
|
+
}, V = (i) => new Promise((r, s) => {
|
|
103
103
|
var d;
|
|
104
104
|
if (document.getElementById("UiEditorScript")) {
|
|
105
|
-
|
|
105
|
+
i(), r();
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
108
|
-
const e =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
}, document.body.appendChild(
|
|
108
|
+
const e = L.guido, a = `https://email-static.useinsider.com/guido/${(d = e == null ? void 0 : e.stripo) == null ? void 0 : d.version}/UIEditor.js`, o = document.createElement("script");
|
|
109
|
+
o.id = "UiEditorScript", o.type = "module", o.src = a, o.onload = () => {
|
|
110
|
+
i(), r();
|
|
111
|
+
}, o.onerror = () => {
|
|
112
|
+
s(new Error(`Failed to load Stripo UIEditor script from S3: ${a}`));
|
|
113
|
+
}, document.body.appendChild(o);
|
|
114
114
|
});
|
|
115
|
-
return { initPlugin: async (
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
r.syncModulesEnabled = e, await B(s, o, e);
|
|
124
|
-
});
|
|
125
|
-
} catch (o) {
|
|
126
|
-
r.loadingStatus = !1, l(o, "Failed to load the editor");
|
|
127
|
-
}
|
|
115
|
+
return { initPlugin: async (i) => {
|
|
116
|
+
await V(async () => {
|
|
117
|
+
const r = E(), [s, e] = await Promise.all([
|
|
118
|
+
b(),
|
|
119
|
+
k()
|
|
120
|
+
]);
|
|
121
|
+
r.syncModulesEnabled = e, await T(i, s, e);
|
|
122
|
+
});
|
|
128
123
|
} };
|
|
129
124
|
};
|
|
130
125
|
export {
|