@useinsider/guido 3.11.0 → 3.12.0-beta.1b68f97
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/README.md +33 -0
- package/dist/@types/config/schemas.js +131 -98
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
- package/dist/components/organisms/header/EditorActions.vue.js +1 -1
- package/dist/components/organisms/header/HeaderWrapper.vue.js +3 -3
- package/dist/components/organisms/header/HeaderWrapper.vue2.js +2 -0
- package/dist/components/organisms/header/version-history/VersionHistory.vue.js +1 -1
- package/dist/components/organisms/onboarding/AMPOnboarding.vue.js +11 -10
- package/dist/components/organisms/onboarding/GenericOnboarding.vue.js +1 -1
- package/dist/components/organisms/onboarding/ItemsOnboarding.vue.js +6 -6
- package/dist/components/organisms/onboarding/NewVersionPopup.vue2.js +20 -23
- package/dist/components/organisms/onboarding/TextBlockOnboarding.vue.js +3 -3
- package/dist/components/organisms/onboarding/VersionHistoryOnboarding.vue.js +8 -7
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +5 -5
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +2 -2
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue.js +3 -3
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue2.js +9 -9
- package/dist/composables/useModuleDynamicContentRepair.js +37 -0
- package/dist/composables/usePreviewInteractionGuard.js +36 -11
- package/dist/composables/useRecommendationPreview.js +61 -60
- package/dist/composables/useSave.js +43 -24
- package/dist/composables/useStripo.js +70 -67
- package/dist/composables/validators/useAllowlistValidator.js +31 -0
- package/dist/config/migrator/index.js +7 -6
- package/dist/config/migrator/socialIconMigrator.js +29 -0
- package/dist/enums/academy.js +1 -1
- package/dist/enums/date.js +3 -4
- package/dist/extensions/Blocks/Items/controls/price/formattedPrice.js +43 -41
- package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
- package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
- package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
- package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
- package/dist/extensions/Blocks/controlFactories.js +125 -75
- package/dist/guido.css +1 -1
- package/dist/node_modules/valibot/dist/index.js +148 -112
- package/dist/src/@types/config/schemas.d.ts +59 -0
- package/dist/src/@types/generic.d.ts +18 -0
- package/dist/src/composables/useConfig.d.ts +10 -0
- package/dist/src/composables/useModuleDynamicContentRepair.d.ts +18 -0
- package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
- package/dist/src/composables/validators/useAllowlistValidator.d.ts +9 -0
- package/dist/src/config/migrator/socialIconMigrator.d.ts +1 -0
- package/dist/src/enums/academy.d.ts +3 -3
- package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
- package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
- package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
- package/dist/src/library.d.ts +1 -1
- package/dist/src/stores/config.d.ts +90 -0
- package/dist/src/utils/dynamicContentConverter.d.ts +27 -0
- package/dist/src/utils/environmentUtil.d.ts +5 -2
- package/dist/src/utils/genericUtil.d.ts +18 -1
- package/dist/src/utils/urlSchemes.d.ts +6 -0
- package/dist/utils/dateUtil.js +10 -23
- package/dist/utils/dynamicContentConverter.js +31 -0
- package/dist/utils/environmentUtil.js +3 -2
- package/dist/utils/genericUtil.js +42 -21
- package/dist/utils/urlSchemes.js +4 -0
- package/package.json +10 -1
- package/dist/src/composables/useHtmlValidator.test.d.ts +0 -1
- package/dist/src/config/compiler/utils/recommendationIgnoreUtils.test.d.ts +0 -1
package/README.md
CHANGED
|
@@ -113,6 +113,14 @@ const config: GuidoConfigInput = {
|
|
|
113
113
|
html?: string,
|
|
114
114
|
css?: string,
|
|
115
115
|
preselectedDynamicContent?: DynamicContent[],
|
|
116
|
+
// Partner-keyed catalog of the account's dynamic-content attributes, e.g.
|
|
117
|
+
// { [partnerName]: [{ text, value, children }] } (architect is multi-partner).
|
|
118
|
+
// Guido flattens the active (first) partner's leaf attributes and uses them to
|
|
119
|
+
// repair label-form tokens (`{{ Phone Number }}` -> `{{phone_number}}`) in
|
|
120
|
+
// dropped saved modules; an unresolvable token raises a single warning toaster
|
|
121
|
+
// (translation key `dynamic-content.unresolved-attributes-on-drop`, registered
|
|
122
|
+
// host-side). Omit it and the repair is a silent no-op. Default: {}.
|
|
123
|
+
dynamicContentList?: DynamicContentList,
|
|
116
124
|
selectedUnsubscribePages?: number[],
|
|
117
125
|
forceRecreate?: boolean, // Default: false - Force recreate template in Stripo storage
|
|
118
126
|
migration?: {
|
|
@@ -153,11 +161,15 @@ const config: GuidoConfigInput = {
|
|
|
153
161
|
modulesDisabled?: boolean, // Default: false - Disable modules panel
|
|
154
162
|
liquidSyntax?: boolean, // Default: false - Enable Liquid template syntax
|
|
155
163
|
autosave?: boolean, // Default: false - Show the Auto Save toggle in the header. See wiki/AUTOSAVE.md.
|
|
164
|
+
allowlistEnabled?: boolean, // Default: false - Pre-save domain-allowlist check (opt-in). Pair with callbacks.resolveAllowlistToast.
|
|
156
165
|
},
|
|
157
166
|
|
|
158
167
|
// Optional: Callbacks
|
|
159
168
|
callbacks?: {
|
|
160
169
|
externalValidation?: (data: SavedTemplateDetails) => Promise<boolean>, // Return false to cancel save
|
|
170
|
+
// Supplies the block toaster when features.allowlistEnabled blocks a save on a non-allowlisted domain.
|
|
171
|
+
// The host owns role-gating, the settings deep-link, and copy; Guido renders the result. Return null/void to block silently.
|
|
172
|
+
resolveAllowlistToast?: (blockedDomains: string[]) => { message: string, actionButton?: { text: string, onClick: () => void } } | null | void,
|
|
161
173
|
},
|
|
162
174
|
|
|
163
175
|
// Optional: Block configuration
|
|
@@ -520,6 +532,8 @@ import type {
|
|
|
520
532
|
BlocksConfig,
|
|
521
533
|
CompilerConfig,
|
|
522
534
|
DynamicContent,
|
|
535
|
+
DynamicContentList,
|
|
536
|
+
DynamicContentNode,
|
|
523
537
|
DefaultBlockType,
|
|
524
538
|
CustomBlockType,
|
|
525
539
|
} from '@useinsider/guido';
|
|
@@ -584,6 +598,25 @@ const closeModal = () => {
|
|
|
584
598
|
</script>
|
|
585
599
|
```
|
|
586
600
|
|
|
601
|
+
### Saved-module token repair
|
|
602
|
+
|
|
603
|
+
Legacy **saved modules** may serialize their merge-tag chips by display label
|
|
604
|
+
(`{{ Phone Number }}`) instead of the canonical token (`{{phone_number}}`), which the
|
|
605
|
+
backend can't resolve. When such a module is dropped or copied into the editor, Guido
|
|
606
|
+
repairs these automatically using the `template.dynamicContentList` catalog (see
|
|
607
|
+
[Configuration](#configuration)):
|
|
608
|
+
|
|
609
|
+
- **Label match** → canonical value: `{{ Phone Number }}` → `{{phone_number}}` (any author `| default:` / format tail is preserved).
|
|
610
|
+
- Already-canonical values, Liquid nested tokens (`coupon.code`), recommendation-block variables (`123_0_price`), allowed system tokens, and `data-*` product tags are left untouched.
|
|
611
|
+
- An **unresolvable** token is left in place and raises a single **warning toaster** (translation key `dynamic-content.unresolved-attributes-on-drop`; register the copy host-side).
|
|
612
|
+
|
|
613
|
+
Pass `template.dynamicContentList` as a **partner-keyed** tree
|
|
614
|
+
(`{ [partnerName]: DynamicContentNode[] }`, where a node is `{ text, value, children? }`).
|
|
615
|
+
Guido flattens the **active (first) partner's** leaf attributes. Products that manage
|
|
616
|
+
multiple partners (e.g. architect) should key by partner and place the active partner
|
|
617
|
+
first. Omit the prop and the repair is a safe no-op — nothing is rewritten and no
|
|
618
|
+
toaster fires (useful before the host has wired the catalog).
|
|
619
|
+
|
|
587
620
|
---
|
|
588
621
|
|
|
589
622
|
## Development
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ModuleFolderDefaults as
|
|
2
|
-
import { object as a, number as
|
|
1
|
+
import { ModuleFolderDefaults as y } from "../../enums/defaults.js";
|
|
2
|
+
import { object as a, number as n, optional as e, string as t, picklist as i, pipe as p, minLength as b, custom as S, boolean as o, array as c, record as k, fallback as C, literal as m, looseObject as g, variant as R, union as h, unknown as l, lazy as T } 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
|
-
},
|
|
15
|
+
}, A = 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
|
+
}), I = 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
|
+
}), v = a({
|
|
34
34
|
/** Partner/organization name (required) */
|
|
35
35
|
name: p(
|
|
36
36
|
t(),
|
|
@@ -38,7 +38,7 @@ const d = {
|
|
|
38
38
|
),
|
|
39
39
|
/** Product type identifier */
|
|
40
40
|
productType: e(
|
|
41
|
-
|
|
41
|
+
i([
|
|
42
42
|
r.EMAIL,
|
|
43
43
|
r.ARCHITECT,
|
|
44
44
|
r.UNSUBSCRIBE_PAGES
|
|
@@ -47,14 +47,14 @@ const d = {
|
|
|
47
47
|
),
|
|
48
48
|
/** Message type (promotional or transactional) */
|
|
49
49
|
messageType: e(
|
|
50
|
-
|
|
50
|
+
i([d.PROMOTIONAL, d.TRANSACTIONAL]),
|
|
51
51
|
d.PROMOTIONAL
|
|
52
52
|
),
|
|
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
|
-
}),
|
|
56
|
+
fallbackFont: e(I)
|
|
57
|
+
}), L = a({
|
|
58
58
|
/** Display text for the dynamic content */
|
|
59
59
|
text: t(),
|
|
60
60
|
/** Template variable value (e.g., {{username}}) */
|
|
@@ -68,35 +68,46 @@ const d = {
|
|
|
68
68
|
value: t()
|
|
69
69
|
})
|
|
70
70
|
)
|
|
71
|
-
}),
|
|
71
|
+
}), f = T(() => g({
|
|
72
|
+
text: e(t()),
|
|
73
|
+
// eslint-disable-next-line camelcase -- backend field name
|
|
74
|
+
tag_text: e(t()),
|
|
75
|
+
value: e(t()),
|
|
76
|
+
children: e(c(f)),
|
|
77
|
+
// eslint-disable-next-line camelcase -- backend field name
|
|
78
|
+
select_items: e(c(f))
|
|
79
|
+
})), E = k(
|
|
80
|
+
t(),
|
|
81
|
+
C(c(f), [])
|
|
82
|
+
), P = g({
|
|
72
83
|
/** Block ID (matches the dictionary key and the legacy HTML element id) */
|
|
73
|
-
id: e(
|
|
84
|
+
id: e(n()),
|
|
74
85
|
/** Decimal places for price display (legacy data may use string or number) */
|
|
75
|
-
decimalCount: e(
|
|
86
|
+
decimalCount: e(h([t(), n()])),
|
|
76
87
|
/** Pinned product IDs (empty array when filter-driven) */
|
|
77
|
-
productIds: e(c(
|
|
88
|
+
productIds: e(c(l())),
|
|
78
89
|
/** Whether the block requested live products at send time */
|
|
79
90
|
sendProductRequestFlag: e(o()),
|
|
80
91
|
/** Whether to randomize product order */
|
|
81
92
|
shuffleProducts: e(o()),
|
|
82
93
|
/** Filter rules driving product selection */
|
|
83
|
-
filters: e(c(
|
|
94
|
+
filters: e(c(l())),
|
|
84
95
|
/** Currency code (e.g. 'EUR') — sometimes absent in legacy data */
|
|
85
96
|
currency: e(t()),
|
|
86
97
|
/** Currency display settings (separators, alignment, decimals) */
|
|
87
|
-
currencySettings: e(
|
|
98
|
+
currencySettings: e(l()),
|
|
88
99
|
/** Locale (e.g. 'nl_NL') */
|
|
89
100
|
language: e(t()),
|
|
90
101
|
/** Recommendation strategy key (e.g. 'newArrivals') */
|
|
91
102
|
strategy: e(t()),
|
|
92
103
|
/** Snapshot of products as rendered by the legacy block */
|
|
93
|
-
recommendedProducts: e(c(
|
|
104
|
+
recommendedProducts: e(c(l())),
|
|
94
105
|
/** Number of product cards per row */
|
|
95
|
-
cardsInRow: e(
|
|
106
|
+
cardsInRow: e(n()),
|
|
96
107
|
/** Mobile-only padding (right) */
|
|
97
|
-
mobileRightPadding: e(
|
|
108
|
+
mobileRightPadding: e(n()),
|
|
98
109
|
/** Mobile-only padding (left) */
|
|
99
|
-
mobileLeftPadding: e(
|
|
110
|
+
mobileLeftPadding: e(n()),
|
|
100
111
|
/** Disable responsive scaling */
|
|
101
112
|
unresponsive: e(o()),
|
|
102
113
|
/** Layout orientation ('vertical' | 'horizontal') */
|
|
@@ -106,14 +117,14 @@ const d = {
|
|
|
106
117
|
/** Block type marker used by some legacy variants */
|
|
107
118
|
blockType: e(t()),
|
|
108
119
|
/** Size variant marker (legacy data may use string or number) */
|
|
109
|
-
size: e(
|
|
120
|
+
size: e(h([t(), n()])),
|
|
110
121
|
/** Vertical responsiveness flag (legacy size=1 variants) */
|
|
111
122
|
verticalResponsiveness: e(o()),
|
|
112
123
|
/** Legacy "Move to next line" price placement toggle (cardPricePlacement.js) */
|
|
113
124
|
isPriceMovedToNextLine: e(o()),
|
|
114
125
|
/** Legacy "Hide if same as discounted" / delete-price-for-zero-sale toggle */
|
|
115
126
|
isPriceDeletedForZeroSale: e(o())
|
|
116
|
-
}),
|
|
127
|
+
}), D = a({
|
|
117
128
|
/**
|
|
118
129
|
* Legacy recommendation block configs keyed by block ID.
|
|
119
130
|
* Pass this when loading a template authored with the v1
|
|
@@ -121,51 +132,58 @@ const d = {
|
|
|
121
132
|
* strategy, currency, locale, and layout data.
|
|
122
133
|
*/
|
|
123
134
|
recommendationConfigs: e(
|
|
124
|
-
k(t(),
|
|
135
|
+
k(t(), P),
|
|
125
136
|
{}
|
|
126
137
|
)
|
|
127
|
-
}),
|
|
138
|
+
}), M = a({
|
|
128
139
|
/** Initial HTML content */
|
|
129
140
|
html: e(t(), ""),
|
|
130
141
|
/** Initial CSS content */
|
|
131
142
|
css: e(t(), ""),
|
|
132
143
|
/** Preselected dynamic content items */
|
|
133
144
|
preselectedDynamicContent: e(
|
|
134
|
-
c(
|
|
145
|
+
c(L),
|
|
135
146
|
[]
|
|
136
147
|
),
|
|
148
|
+
/**
|
|
149
|
+
* Partner-keyed set of dynamic-content items the account offers, e.g.
|
|
150
|
+
* `{ [partnerName]: [{ text, value, children }] }`. Guido flattens the active
|
|
151
|
+
* (first) partner's leaf attributes into the label→token map that repairs
|
|
152
|
+
* label-form placeholders (`{{ Phone Number }}`) in dropped saved modules.
|
|
153
|
+
*/
|
|
154
|
+
dynamicContentList: e(E, {}),
|
|
137
155
|
/** Valid custom field attribute names from the partner's categorized fields */
|
|
138
156
|
customFieldAttributes: e(c(t()), []),
|
|
139
157
|
/** Selected unsubscribe page IDs */
|
|
140
|
-
selectedUnsubscribePages: e(c(
|
|
158
|
+
selectedUnsubscribePages: e(c(n()), []),
|
|
141
159
|
/** Force recreate template in Stripo storage (use true when updating externally modified templates) */
|
|
142
160
|
forceRecreate: e(o(), !1),
|
|
143
161
|
/** Migration-only inputs (legacy block configs) */
|
|
144
|
-
migration: e(
|
|
145
|
-
}),
|
|
162
|
+
migration: e(D, {})
|
|
163
|
+
}), N = a({
|
|
146
164
|
/** Sender display name */
|
|
147
165
|
senderName: e(t(), ""),
|
|
148
166
|
/** Email subject line */
|
|
149
167
|
subject: e(t(), "")
|
|
150
|
-
}),
|
|
168
|
+
}), O = a({
|
|
151
169
|
/** Locale for the editor UI */
|
|
152
170
|
locale: e(t(), "en"),
|
|
153
171
|
/** Path to translations object */
|
|
154
172
|
translationsPath: e(t(), "window.trans[Object.keys(window.trans)[0]]"),
|
|
155
173
|
/** Migration date for template compatibility */
|
|
156
|
-
migrationDate: e(
|
|
174
|
+
migrationDate: e(n(), 1759696858),
|
|
157
175
|
/** Email header settings */
|
|
158
|
-
emailHeader: e(
|
|
176
|
+
emailHeader: e(N, { senderName: "", subject: "" }),
|
|
159
177
|
/** Folder name for user-saved modules (used by Stripo plugin panel for path construction) */
|
|
160
|
-
savedModulesFolderName: e(t(),
|
|
178
|
+
savedModulesFolderName: e(t(), y.SAVED_MODULES),
|
|
161
179
|
/** Folder name for default/prebuilt modules (used by Stripo plugin panel for path construction) */
|
|
162
|
-
defaultModulesFolderName: e(t(),
|
|
163
|
-
}),
|
|
180
|
+
defaultModulesFolderName: e(t(), y.DEFAULT_MODULES)
|
|
181
|
+
}), x = a({
|
|
164
182
|
/** Whether to show the header bar */
|
|
165
183
|
showHeader: e(o(), !0),
|
|
166
184
|
/** Custom label for back button (if shown) */
|
|
167
185
|
backButtonLabel: e(t())
|
|
168
|
-
}),
|
|
186
|
+
}), F = a({
|
|
169
187
|
/** Enable dynamic content insertion */
|
|
170
188
|
dynamicContent: e(o(), !0),
|
|
171
189
|
/** Enable save as template functionality */
|
|
@@ -183,8 +201,10 @@ const d = {
|
|
|
183
201
|
/** Enable Liquid template syntax */
|
|
184
202
|
liquidSyntax: e(o(), !1),
|
|
185
203
|
/** Enable autosave (3-min interval + tab-hide). User toggles on/off from the header. */
|
|
186
|
-
autosave: e(o(), !1)
|
|
187
|
-
|
|
204
|
+
autosave: e(o(), !1),
|
|
205
|
+
/** Enable pre-save domain-allowlist validation (opt-in; host supplies the block toaster via callbacks.resolveAllowlistToast) */
|
|
206
|
+
allowlistEnabled: e(o(), !1)
|
|
207
|
+
}), w = i([
|
|
188
208
|
"amp-accordion",
|
|
189
209
|
"amp-carousel",
|
|
190
210
|
"amp-form-controls",
|
|
@@ -198,7 +218,7 @@ const d = {
|
|
|
198
218
|
"text-block",
|
|
199
219
|
"timer-block",
|
|
200
220
|
"video-block"
|
|
201
|
-
]),
|
|
221
|
+
]), U = i([
|
|
202
222
|
"dynamic-content",
|
|
203
223
|
"checkbox-block",
|
|
204
224
|
"radio-button-block",
|
|
@@ -206,121 +226,134 @@ const d = {
|
|
|
206
226
|
"unsubscribe-block",
|
|
207
227
|
"coupon-block",
|
|
208
228
|
"items-block"
|
|
209
|
-
]),
|
|
229
|
+
]), B = a({
|
|
210
230
|
/** Default blocks to exclude from the editor */
|
|
211
231
|
excludeDefaults: e(
|
|
212
|
-
c(
|
|
232
|
+
c(w),
|
|
213
233
|
[]
|
|
214
234
|
),
|
|
215
235
|
/** Custom blocks to include in the editor */
|
|
216
236
|
includeCustoms: e(
|
|
217
|
-
c(
|
|
237
|
+
c(U),
|
|
218
238
|
[]
|
|
219
239
|
)
|
|
220
|
-
}),
|
|
240
|
+
}), u = a({
|
|
221
241
|
/** Unique identifier for the rule */
|
|
222
242
|
id: t(),
|
|
223
243
|
/** Human-readable description */
|
|
224
244
|
description: e(t()),
|
|
225
245
|
/** Priority for rule ordering (lower = earlier) */
|
|
226
|
-
priority:
|
|
227
|
-
}),
|
|
228
|
-
...
|
|
229
|
-
type:
|
|
246
|
+
priority: n()
|
|
247
|
+
}), H = a({
|
|
248
|
+
...u.entries,
|
|
249
|
+
type: m("replace"),
|
|
230
250
|
/** String to search for */
|
|
231
251
|
search: t(),
|
|
232
252
|
/** Replacement string */
|
|
233
253
|
replacement: t(),
|
|
234
254
|
/** Replace all occurrences (default: false) */
|
|
235
255
|
replaceAll: e(o())
|
|
236
|
-
}),
|
|
237
|
-
...
|
|
238
|
-
type:
|
|
256
|
+
}), _ = a({
|
|
257
|
+
...u.entries,
|
|
258
|
+
type: m("regex"),
|
|
239
259
|
/** Regex pattern string */
|
|
240
260
|
pattern: t(),
|
|
241
261
|
/** Replacement string (supports $1, $2, etc.) */
|
|
242
262
|
replacement: t(),
|
|
243
263
|
/** Regex flags (e.g., 'gi') */
|
|
244
264
|
flags: e(t())
|
|
245
|
-
}),
|
|
246
|
-
...
|
|
247
|
-
type:
|
|
265
|
+
}), j = a({
|
|
266
|
+
...u.entries,
|
|
267
|
+
type: m("remove"),
|
|
248
268
|
/** Strings or patterns to remove */
|
|
249
269
|
targets: c(t())
|
|
250
|
-
}),
|
|
251
|
-
...
|
|
252
|
-
type:
|
|
270
|
+
}), q = a({
|
|
271
|
+
...u.entries,
|
|
272
|
+
type: m("custom"),
|
|
253
273
|
/** Custom processor function */
|
|
254
|
-
processor:
|
|
255
|
-
(
|
|
274
|
+
processor: S(
|
|
275
|
+
(s) => typeof s == "function",
|
|
256
276
|
"processor must be a function"
|
|
257
277
|
)
|
|
258
|
-
}),
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
]),
|
|
278
|
+
}), G = R("type", [
|
|
279
|
+
H,
|
|
280
|
+
_,
|
|
281
|
+
j,
|
|
282
|
+
q
|
|
283
|
+
]), V = a({
|
|
264
284
|
/** Custom compiler rules to apply */
|
|
265
|
-
customRules: e(c(
|
|
285
|
+
customRules: e(c(G), []),
|
|
266
286
|
/** Skip default compiler rules */
|
|
267
287
|
ignoreDefaultRules: e(o(), !1)
|
|
268
|
-
}),
|
|
288
|
+
}), z = a({
|
|
269
289
|
/**
|
|
270
290
|
* External validation handler called before save completes.
|
|
271
291
|
* Return false to cancel the save operation.
|
|
272
292
|
*/
|
|
273
293
|
externalValidation: e(
|
|
274
|
-
|
|
275
|
-
(
|
|
294
|
+
S(
|
|
295
|
+
(s) => typeof s == "function",
|
|
276
296
|
"externalValidation must be a function"
|
|
277
297
|
)
|
|
298
|
+
),
|
|
299
|
+
/**
|
|
300
|
+
* Resolves the block toaster's content when the domain-allowlist check (features.allowlistEnabled)
|
|
301
|
+
* blocks a save. Host-supplied so role-gating, the settings deep-link, and copy stay host-side.
|
|
302
|
+
* Returning null/void blocks the save with no toaster.
|
|
303
|
+
*/
|
|
304
|
+
resolveAllowlistToast: e(
|
|
305
|
+
S(
|
|
306
|
+
(s) => typeof s == "function",
|
|
307
|
+
"resolveAllowlistToast must be a function"
|
|
308
|
+
)
|
|
278
309
|
)
|
|
279
|
-
}),
|
|
310
|
+
}), K = a({
|
|
280
311
|
// Required sections
|
|
281
312
|
/** Identity configuration (required) */
|
|
282
|
-
identity:
|
|
313
|
+
identity: A,
|
|
283
314
|
/** Partner configuration (required) */
|
|
284
|
-
partner:
|
|
315
|
+
partner: v,
|
|
285
316
|
// Optional sections (with defaults)
|
|
286
317
|
/** Template content and presets */
|
|
287
|
-
template: e(
|
|
318
|
+
template: e(M, {}),
|
|
288
319
|
/** Editor settings */
|
|
289
|
-
editor: e(
|
|
320
|
+
editor: e(O, {}),
|
|
290
321
|
/** UI configuration */
|
|
291
|
-
ui: e(
|
|
322
|
+
ui: e(x, {}),
|
|
292
323
|
/** Feature toggles */
|
|
293
|
-
features: e(
|
|
324
|
+
features: e(F, {}),
|
|
294
325
|
/** Block configuration */
|
|
295
|
-
blocks: e(
|
|
326
|
+
blocks: e(B, {}),
|
|
296
327
|
/** Compiler configuration */
|
|
297
|
-
compiler: e(
|
|
328
|
+
compiler: e(V, {}),
|
|
298
329
|
/** Callbacks and event handlers */
|
|
299
|
-
callbacks: e(
|
|
330
|
+
callbacks: e(z, {})
|
|
300
331
|
});
|
|
301
332
|
export {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
333
|
+
B as BlocksSchema,
|
|
334
|
+
z as CallbacksSchema,
|
|
335
|
+
G as CompilerRuleSchema,
|
|
336
|
+
V as CompilerSchema,
|
|
337
|
+
U as CustomBlockTypeSchema,
|
|
338
|
+
q as CustomRuleSchema,
|
|
339
|
+
w as DefaultBlockTypeSchema,
|
|
340
|
+
E as DynamicContentListSchema,
|
|
341
|
+
f as DynamicContentNodeSchema,
|
|
342
|
+
L as DynamicContentSchema,
|
|
343
|
+
O as EditorSchema,
|
|
344
|
+
N as EmailHeaderSchema,
|
|
345
|
+
I as FallbackFontSchema,
|
|
346
|
+
F as FeaturesSchema,
|
|
347
|
+
K as GuidoConfigSchema,
|
|
348
|
+
A as IdentitySchema,
|
|
349
|
+
P as LegacyRecommendationConfigSchema,
|
|
317
350
|
d as MessageType,
|
|
318
|
-
|
|
351
|
+
v as PartnerSchema,
|
|
319
352
|
r as ProductType,
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
353
|
+
_ as RegexRuleSchema,
|
|
354
|
+
j as RemoveRuleSchema,
|
|
355
|
+
H as ReplaceRuleSchema,
|
|
356
|
+
D as TemplateMigrationSchema,
|
|
357
|
+
M as TemplateSchema,
|
|
358
|
+
x as UISchema
|
|
326
359
|
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { defineComponent as u, ref as a, onMounted as p, onBeforeUnmount as l, nextTick as
|
|
2
|
-
import { usePreviewInteractionGuard as
|
|
1
|
+
import { defineComponent as u, ref as a, onMounted as p, onBeforeUnmount as l, nextTick as d } from "vue";
|
|
2
|
+
import { usePreviewInteractionGuard as v } from "../../../../composables/usePreviewInteractionGuard.js";
|
|
3
3
|
import { useTranslations as _ } from "../../../../composables/useTranslations.js";
|
|
4
4
|
import { usePreviewStore as w } from "../../../../stores/preview.js";
|
|
5
5
|
import I from "./DesktopBrowserHeader.vue.js";
|
|
6
6
|
const C = /* @__PURE__ */ u({
|
|
7
7
|
__name: "DesktopPreview",
|
|
8
|
-
setup(
|
|
9
|
-
const i = _(), {
|
|
8
|
+
setup(P) {
|
|
9
|
+
const i = _(), { guardPreviewInteractions: t } = v(), o = a(), r = a(!1), c = w();
|
|
10
10
|
let e = null;
|
|
11
11
|
const f = (m) => {
|
|
12
12
|
t(m.target);
|
|
13
|
-
},
|
|
13
|
+
}, n = () => {
|
|
14
14
|
o.value && (e = new ResizeObserver(() => {
|
|
15
|
-
}), e.observe(o.value),
|
|
16
|
-
|
|
15
|
+
}), e.observe(o.value), d(() => {
|
|
16
|
+
r.value = !0;
|
|
17
17
|
}));
|
|
18
18
|
}, s = () => {
|
|
19
19
|
e == null || e.disconnect();
|
|
20
20
|
};
|
|
21
|
-
return p(
|
|
21
|
+
return p(n), l(s), { __sfc: !0, trans: i, guardPreviewInteractions: t, containerRef: o, isContainerReady: r, previewStore: c, resizeObserver: e, onIframeLoad: f, initIframe: n, cleanIframe: s, DesktopBrowserHeader: I };
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
export {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import e from "./ContentView.vue2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import n from "../../../../_virtual/_plugin-vue2_normalizer.js";
|
|
4
|
-
var
|
|
4
|
+
var o = function() {
|
|
5
5
|
var t = this, s = t._self._c, a = t._self._setupProxy;
|
|
6
6
|
return s("div", { staticClass: "w-1 h-1 b-c-4 d-f f-d-c" }, [s("div", { staticClass: "d-f j-c-s-b a-i-c p-2 h-6-s" }, [s("div", { staticClass: "d-f a-i-c cur-p", on: { click: function(l) {
|
|
7
7
|
return t.$emit("back-to-inbox");
|
|
8
8
|
} } }, [s(a.InIcons, { staticClass: "f-s-3 i-c-7", attrs: { name: "line-chevron-left" } }), s("span", { staticClass: "ml-2 f-s-1 f-w-400 l-h-1 t-c-7" }, [t._v(t._s(a.trans("newsletter.inbox")))])], 1), s("div", { staticClass: "d-f a-i-c" }, [s(a.InIcons, { staticClass: "i-c-52", attrs: { name: "line-chevron-down" } }), s(a.InIcons, { staticClass: "ml-1 i-c-52", attrs: { name: "line-chevron-up" } })], 1)]), s("div", { staticClass: "iframe-wrapper f-g-1 o-h" }, [s("iframe", { ref: "iframeRef", staticClass: "iframe-scaled d-b b-c-4 bor-s-n", attrs: { sandbox: "allow-same-origin allow-popups allow-forms allow-scripts allow-popups-to-escape-sandbox", srcdoc: a.previewStore.previewHtml }, on: { load: a.onLoad } })])]);
|
|
9
|
-
},
|
|
9
|
+
}, i = [], r = /* @__PURE__ */ n(
|
|
10
10
|
e,
|
|
11
|
-
c,
|
|
12
11
|
o,
|
|
12
|
+
i,
|
|
13
13
|
!1,
|
|
14
14
|
null,
|
|
15
|
-
"
|
|
15
|
+
"f255b2bb"
|
|
16
16
|
);
|
|
17
|
-
const d =
|
|
17
|
+
const d = r.exports;
|
|
18
18
|
export {
|
|
19
19
|
d as default
|
|
20
20
|
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { defineComponent as
|
|
1
|
+
import { defineComponent as c, ref as a } from "vue";
|
|
2
2
|
import { usePreviewInteractionGuard as f } from "../../../../composables/usePreviewInteractionGuard.js";
|
|
3
3
|
import { useResponsivePreview as p } from "../../../../composables/useResponsivePreview.js";
|
|
4
4
|
import { useTranslations as u } from "../../../../composables/useTranslations.js";
|
|
5
5
|
import { usePreviewStore as v } from "../../../../stores/preview.js";
|
|
6
|
-
import { InIcons as
|
|
7
|
-
const
|
|
6
|
+
import { InIcons as d } from "@useinsider/design-system-vue";
|
|
7
|
+
const b = /* @__PURE__ */ c({
|
|
8
8
|
__name: "ContentView",
|
|
9
9
|
emits: ["back-to-inbox"],
|
|
10
|
-
setup(
|
|
11
|
-
const
|
|
10
|
+
setup(P) {
|
|
11
|
+
const m = u(), r = v(), t = a(), { setupResponsivePreview: n } = p(), { guardPreviewInteractions: s } = f(), i = (e) => {
|
|
12
12
|
["transform", "transform-origin", "height"].forEach((o) => {
|
|
13
13
|
e.documentElement.style.removeProperty(o);
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
|
-
return { __sfc: !0, trans:
|
|
17
|
-
const e =
|
|
18
|
-
o && (n(e), s(e),
|
|
19
|
-
}, InIcons:
|
|
16
|
+
return { __sfc: !0, trans: m, previewStore: r, iframeRef: t, setupResponsivePreview: n, guardPreviewInteractions: s, clearAMPTransforms: i, onLoad: () => {
|
|
17
|
+
const e = t.value, o = e == null ? void 0 : e.contentDocument;
|
|
18
|
+
o && (n(e), s(e), r.isAMPResponsive && i(o));
|
|
19
|
+
}, InIcons: d };
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
export {
|
|
23
|
-
|
|
23
|
+
b as default
|
|
24
24
|
};
|
|
@@ -8,6 +8,8 @@ const c = /* @__PURE__ */ n({
|
|
|
8
8
|
setup(l, { expose: r }) {
|
|
9
9
|
const e = m(null);
|
|
10
10
|
return r({
|
|
11
|
+
// Stryker disable next-line OptionalChaining: RightSlot is always rendered (no
|
|
12
|
+
// v-if), so rightSlotRef.value is never null and `?.` cannot short-circuit.
|
|
11
13
|
handleSave: (t) => {
|
|
12
14
|
var o;
|
|
13
15
|
return (o = e.value) == null ? void 0 : o.handleSave(t);
|