@useinsider/guido 3.11.0-beta.17c184c → 3.11.0-beta.1fde696

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 (28) hide show
  1. package/dist/@types/config/schemas.js +110 -114
  2. package/dist/components/organisms/header/EditorActions.vue.js +1 -1
  3. package/dist/components/organisms/header/HeaderWrapper.vue.js +3 -3
  4. package/dist/components/organisms/header/HeaderWrapper.vue2.js +0 -2
  5. package/dist/components/organisms/header/version-history/VersionHistory.vue.js +1 -1
  6. package/dist/composables/useModuleDynamicContentRepair.js +36 -0
  7. package/dist/composables/useStripo.js +62 -59
  8. package/dist/enums/unsubscribe.js +31 -35
  9. package/dist/guido.css +1 -1
  10. package/dist/src/@types/config/defaults.d.ts +1 -5
  11. package/dist/src/@types/config/index.d.ts +3 -3
  12. package/dist/src/@types/config/schemas.d.ts +36 -21
  13. package/dist/src/@types/config/types.d.ts +1 -5
  14. package/dist/src/composables/useConfig.d.ts +18 -3
  15. package/dist/src/composables/useHtmlValidator.test.d.ts +1 -0
  16. package/dist/src/composables/useModuleDynamicContentRepair.d.ts +18 -0
  17. package/dist/src/config/compiler/utils/recommendationIgnoreUtils.test.d.ts +1 -0
  18. package/dist/src/enums/unsubscribe.d.ts +2 -2
  19. package/dist/src/library.d.ts +1 -1
  20. package/dist/src/stores/config.d.ts +156 -185
  21. package/dist/src/utils/dynamicContentConverter.d.ts +31 -0
  22. package/dist/src/utils/environmentUtil.d.ts +2 -5
  23. package/dist/src/utils/genericUtil.d.ts +7 -0
  24. package/dist/stores/config.js +20 -27
  25. package/dist/utils/dynamicContentConverter.js +33 -0
  26. package/dist/utils/environmentUtil.js +2 -8
  27. package/dist/utils/genericUtil.js +26 -19
  28. package/package.json +1 -5
@@ -1,6 +1,6 @@
1
1
  import { ModuleFolderDefaults as S } from "../../enums/defaults.js";
2
- import { object as o, number as c, optional as e, string as t, picklist as i, pipe as l, minLength as m, custom as h, boolean as a, array as n, record as y, literal as u, looseObject as k, variant as g, union as f, unknown as s } from "../../node_modules/valibot/dist/index.js";
3
- const b = {
2
+ import { object as a, number as n, 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 g, variant as R, union as f, unknown as s } from "../../node_modules/valibot/dist/index.js";
3
+ const d = {
4
4
  /** Promotional/marketing emails */
5
5
  PROMOTIONAL: 1,
6
6
  /** Transactional/system emails */
@@ -12,33 +12,33 @@ const b = {
12
12
  ARCHITECT: 49,
13
13
  /** Unsubscribe page builder */
14
14
  UNSUBSCRIBE_PAGES: 97
15
- }, R = o({
15
+ }, C = a({
16
16
  /** Unique identifier for the template being edited */
17
- templateId: l(
17
+ templateId: p(
18
18
  t(),
19
- m(1, "templateId is required")
19
+ b(1, "templateId is required")
20
20
  ),
21
21
  /** Unique identifier for the user editing the template */
22
- userId: l(
22
+ userId: p(
23
23
  t(),
24
- m(1, "userId is required")
24
+ b(1, "userId is required")
25
25
  ),
26
26
  /** Optional variation ID for A/B testing */
27
27
  variationId: e(t())
28
- }), T = o({
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
- }), C = o({
33
+ }), A = a({
34
34
  /** Partner/organization name (required) */
35
- name: l(
35
+ name: p(
36
36
  t(),
37
- m(1, "partner.name is required")
37
+ b(1, "partner.name is required")
38
38
  ),
39
39
  /** Product type identifier */
40
40
  productType: e(
41
- i([
41
+ l([
42
42
  r.EMAIL,
43
43
  r.ARCHITECT,
44
44
  r.UNSUBSCRIBE_PAGES
@@ -47,14 +47,14 @@ const b = {
47
47
  ),
48
48
  /** Message type (promotional or transactional) */
49
49
  messageType: e(
50
- i([b.PROMOTIONAL, b.TRANSACTIONAL]),
51
- b.PROMOTIONAL
50
+ l([d.PROMOTIONAL, d.TRANSACTIONAL]),
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
56
  fallbackFont: e(T)
57
- }), A = o({
57
+ }), y = a({
58
58
  /** Display text for the dynamic content */
59
59
  text: t(),
60
60
  /** Template variable value (e.g., {{username}}) */
@@ -63,24 +63,24 @@ const b = {
63
63
  fallback: e(t()),
64
64
  /** Optional formatting options */
65
65
  format: e(
66
- o({
66
+ a({
67
67
  key: t(),
68
68
  value: t()
69
69
  })
70
70
  )
71
- }), I = k({
71
+ }), I = g({
72
72
  /** Block ID (matches the dictionary key and the legacy HTML element id) */
73
- id: e(c()),
73
+ id: e(n()),
74
74
  /** Decimal places for price display (legacy data may use string or number) */
75
- decimalCount: e(f([t(), c()])),
75
+ decimalCount: e(f([t(), n()])),
76
76
  /** Pinned product IDs (empty array when filter-driven) */
77
- productIds: e(n(s())),
77
+ productIds: e(c(s())),
78
78
  /** Whether the block requested live products at send time */
79
- sendProductRequestFlag: e(a()),
79
+ sendProductRequestFlag: e(o()),
80
80
  /** Whether to randomize product order */
81
- shuffleProducts: e(a()),
81
+ shuffleProducts: e(o()),
82
82
  /** Filter rules driving product selection */
83
- filters: e(n(s())),
83
+ filters: e(c(s())),
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) */
@@ -90,30 +90,30 @@ const b = {
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(n(s())),
93
+ recommendedProducts: e(c(s())),
94
94
  /** Number of product cards per row */
95
- cardsInRow: e(c()),
95
+ cardsInRow: e(n()),
96
96
  /** Mobile-only padding (right) */
97
- mobileRightPadding: e(c()),
97
+ mobileRightPadding: e(n()),
98
98
  /** Mobile-only padding (left) */
99
- mobileLeftPadding: e(c()),
99
+ mobileLeftPadding: e(n()),
100
100
  /** Disable responsive scaling */
101
- unresponsive: e(a()),
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(a()),
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(), c()])),
109
+ size: e(f([t(), n()])),
110
110
  /** Vertical responsiveness flag (legacy size=1 variants) */
111
- verticalResponsiveness: e(a()),
111
+ verticalResponsiveness: e(o()),
112
112
  /** Legacy "Move to next line" price placement toggle (cardPricePlacement.js) */
113
- isPriceMovedToNextLine: e(a()),
113
+ isPriceMovedToNextLine: e(o()),
114
114
  /** Legacy "Hide if same as discounted" / delete-price-for-zero-sale toggle */
115
- isPriceDeletedForZeroSale: e(a())
116
- }), v = o({
115
+ isPriceDeletedForZeroSale: e(o())
116
+ }), v = a({
117
117
  /**
118
118
  * Legacy recommendation block configs keyed by block ID.
119
119
  * Pass this when loading a template authored with the v1
@@ -121,70 +121,79 @@ const b = {
121
121
  * strategy, currency, locale, and layout data.
122
122
  */
123
123
  recommendationConfigs: e(
124
- y(t(), I),
124
+ k(t(), I),
125
125
  {}
126
126
  )
127
- }), E = o({
127
+ }), L = a({
128
128
  /** Initial HTML content */
129
129
  html: e(t(), ""),
130
130
  /** Initial CSS content */
131
131
  css: e(t(), ""),
132
132
  /** Preselected dynamic content items */
133
133
  preselectedDynamicContent: e(
134
- n(A),
134
+ c(y),
135
+ []
136
+ ),
137
+ /**
138
+ * Full set of dynamic-content items the account offers (label + token).
139
+ * Used as the label→token map that repairs label-form placeholders
140
+ * (e.g. `{{ Phone Number }}`) in dropped saved modules.
141
+ */
142
+ availableDynamicContent: e(
143
+ c(y),
135
144
  []
136
145
  ),
137
146
  /** Valid custom field attribute names from the partner's categorized fields */
138
- customFieldAttributes: e(n(t()), []),
147
+ customFieldAttributes: e(c(t()), []),
139
148
  /** Selected unsubscribe page IDs */
140
- selectedUnsubscribePages: e(n(c()), []),
149
+ selectedUnsubscribePages: e(c(n()), []),
141
150
  /** Force recreate template in Stripo storage (use true when updating externally modified templates) */
142
- forceRecreate: e(a(), !1),
151
+ forceRecreate: e(o(), !1),
143
152
  /** Migration-only inputs (legacy block configs) */
144
153
  migration: e(v, {})
145
- }), L = o({
154
+ }), P = a({
146
155
  /** Sender display name */
147
156
  senderName: e(t(), ""),
148
157
  /** Email subject line */
149
158
  subject: e(t(), "")
150
- }), P = o({
159
+ }), E = a({
151
160
  /** Locale for the editor UI */
152
161
  locale: e(t(), "en"),
153
162
  /** Path to translations object */
154
163
  translationsPath: e(t(), "window.trans[Object.keys(window.trans)[0]]"),
155
164
  /** Migration date for template compatibility */
156
- migrationDate: e(c(), 1759696858),
165
+ migrationDate: e(n(), 1759696858),
157
166
  /** Email header settings */
158
- emailHeader: e(L, { senderName: "", subject: "" }),
167
+ emailHeader: e(P, { senderName: "", subject: "" }),
159
168
  /** Folder name for user-saved modules (used by Stripo plugin panel for path construction) */
160
169
  savedModulesFolderName: e(t(), S.SAVED_MODULES),
161
170
  /** Folder name for default/prebuilt modules (used by Stripo plugin panel for path construction) */
162
171
  defaultModulesFolderName: e(t(), S.DEFAULT_MODULES)
163
- }), M = o({
172
+ }), M = a({
164
173
  /** Whether to show the header bar */
165
- showHeader: e(a(), !0),
174
+ showHeader: e(o(), !0),
166
175
  /** Custom label for back button (if shown) */
167
176
  backButtonLabel: e(t())
168
- }), O = o({
177
+ }), O = a({
169
178
  /** Enable dynamic content insertion */
170
- dynamicContent: e(a(), !0),
179
+ dynamicContent: e(o(), !0),
171
180
  /** Enable save as template functionality */
172
- saveAsTemplate: e(a(), !0),
181
+ saveAsTemplate: e(o(), !0),
173
182
  /** Enable version history */
174
- versionHistory: e(a(), !0),
183
+ versionHistory: e(o(), !0),
175
184
  /** Enable test message sending */
176
- testMessage: e(a(), !0),
185
+ testMessage: e(o(), !0),
177
186
  /** Enable display conditions */
178
- displayConditions: e(a(), !0),
187
+ displayConditions: e(o(), !0),
179
188
  /** Enable unsubscribe block */
180
- unsubscribe: e(a(), !0),
189
+ unsubscribe: e(o(), !0),
181
190
  /** Disable modules panel in the editor */
182
- modulesDisabled: e(a(), !1),
191
+ modulesDisabled: e(o(), !1),
183
192
  /** Enable Liquid template syntax */
184
- liquidSyntax: e(a(), !1),
193
+ liquidSyntax: e(o(), !1),
185
194
  /** Enable autosave (3-min interval + tab-hide). User toggles on/off from the header. */
186
- autosave: e(a(), !1)
187
- }), x = i([
195
+ autosave: e(o(), !1)
196
+ }), D = l([
188
197
  "amp-accordion",
189
198
  "amp-carousel",
190
199
  "amp-form-controls",
@@ -198,7 +207,7 @@ const b = {
198
207
  "text-block",
199
208
  "timer-block",
200
209
  "video-block"
201
- ]), N = i([
210
+ ]), N = l([
202
211
  "dynamic-content",
203
212
  "checkbox-block",
204
213
  "radio-button-block",
@@ -206,134 +215,121 @@ const b = {
206
215
  "unsubscribe-block",
207
216
  "coupon-block",
208
217
  "items-block"
209
- ]), D = o({
218
+ ]), x = a({
210
219
  /** Default blocks to exclude from the editor */
211
220
  excludeDefaults: e(
212
- n(x),
221
+ c(D),
213
222
  []
214
223
  ),
215
224
  /** Custom blocks to include in the editor */
216
225
  includeCustoms: e(
217
- n(N),
226
+ c(N),
218
227
  []
219
228
  )
220
- }), d = o({
229
+ }), m = a({
221
230
  /** Unique identifier for the rule */
222
231
  id: t(),
223
232
  /** Human-readable description */
224
233
  description: e(t()),
225
234
  /** Priority for rule ordering (lower = earlier) */
226
- priority: c()
227
- }), F = o({
228
- ...d.entries,
229
- type: u("replace"),
235
+ priority: n()
236
+ }), F = a({
237
+ ...m.entries,
238
+ type: i("replace"),
230
239
  /** String to search for */
231
240
  search: t(),
232
241
  /** Replacement string */
233
242
  replacement: t(),
234
243
  /** Replace all occurrences (default: false) */
235
- replaceAll: e(a())
236
- }), U = o({
237
- ...d.entries,
238
- type: u("regex"),
244
+ replaceAll: e(o())
245
+ }), U = a({
246
+ ...m.entries,
247
+ type: i("regex"),
239
248
  /** Regex pattern string */
240
249
  pattern: t(),
241
250
  /** Replacement string (supports $1, $2, etc.) */
242
251
  replacement: t(),
243
252
  /** Regex flags (e.g., 'gi') */
244
253
  flags: e(t())
245
- }), B = o({
246
- ...d.entries,
247
- type: u("remove"),
254
+ }), B = a({
255
+ ...m.entries,
256
+ type: i("remove"),
248
257
  /** Strings or patterns to remove */
249
- targets: n(t())
250
- }), w = o({
251
- ...d.entries,
252
- type: u("custom"),
258
+ targets: c(t())
259
+ }), w = a({
260
+ ...m.entries,
261
+ type: i("custom"),
253
262
  /** Custom processor function */
254
263
  processor: h(
255
- (p) => typeof p == "function",
264
+ (u) => typeof u == "function",
256
265
  "processor must be a function"
257
266
  )
258
- }), H = g("type", [
267
+ }), H = R("type", [
259
268
  F,
260
269
  U,
261
270
  B,
262
271
  w
263
- ]), j = o({
272
+ ]), j = a({
264
273
  /** Custom compiler rules to apply */
265
- customRules: e(n(H), []),
274
+ customRules: e(c(H), []),
266
275
  /** Skip default compiler rules */
267
- ignoreDefaultRules: e(a(), !1)
268
- }), q = o({
276
+ ignoreDefaultRules: e(o(), !1)
277
+ }), q = a({
269
278
  /**
270
279
  * External validation handler called before save completes.
271
280
  * Return false to cancel the save operation.
272
281
  */
273
282
  externalValidation: e(
274
283
  h(
275
- (p) => typeof p == "function",
284
+ (u) => typeof u == "function",
276
285
  "externalValidation must be a function"
277
286
  )
278
287
  )
279
- }), G = o({
280
- /**
281
- * Environment prefix for runtime-built hosts (unsubscribe / preference-center
282
- * links compile to `https://mail.<prefix>.com/...`). When omitted, the prefix
283
- * is derived from the hostname with a safe production fallback (SD-145225).
284
- */
285
- prefix: e(l(
286
- t(),
287
- m(1, "environment.prefix cannot be empty")
288
- ))
289
- }), z = o({
288
+ }), V = a({
290
289
  // Required sections
291
290
  /** Identity configuration (required) */
292
- identity: R,
291
+ identity: C,
293
292
  /** Partner configuration (required) */
294
- partner: C,
293
+ partner: A,
295
294
  // Optional sections (with defaults)
296
295
  /** Template content and presets */
297
- template: e(E, {}),
296
+ template: e(L, {}),
298
297
  /** Editor settings */
299
- editor: e(P, {}),
298
+ editor: e(E, {}),
300
299
  /** UI configuration */
301
300
  ui: e(M, {}),
302
301
  /** Feature toggles */
303
302
  features: e(O, {}),
304
303
  /** Block configuration */
305
- blocks: e(D, {}),
304
+ blocks: e(x, {}),
306
305
  /** Compiler configuration */
307
306
  compiler: e(j, {}),
308
307
  /** Callbacks and event handlers */
309
- callbacks: e(q, {}),
310
- /** Deployment environment context */
311
- environment: e(G, {})
308
+ callbacks: e(q, {})
312
309
  });
313
310
  export {
314
- D as BlocksSchema,
311
+ x as BlocksSchema,
315
312
  q as CallbacksSchema,
316
313
  H as CompilerRuleSchema,
317
314
  j as CompilerSchema,
318
315
  N as CustomBlockTypeSchema,
319
316
  w as CustomRuleSchema,
320
- x as DefaultBlockTypeSchema,
321
- A as DynamicContentSchema,
322
- P as EditorSchema,
323
- L as EmailHeaderSchema,
324
- G as EnvironmentSchema,
317
+ D as DefaultBlockTypeSchema,
318
+ y as DynamicContentSchema,
319
+ E as EditorSchema,
320
+ P as EmailHeaderSchema,
325
321
  T as FallbackFontSchema,
326
322
  O as FeaturesSchema,
327
- z as GuidoConfigSchema,
328
- R as IdentitySchema,
323
+ V as GuidoConfigSchema,
324
+ C as IdentitySchema,
329
325
  I as LegacyRecommendationConfigSchema,
330
- b as MessageType,
331
- C as PartnerSchema,
326
+ d as MessageType,
327
+ A as PartnerSchema,
332
328
  r as ProductType,
333
329
  U as RegexRuleSchema,
334
330
  B as RemoveRuleSchema,
335
331
  F as ReplaceRuleSchema,
336
332
  v as TemplateMigrationSchema,
337
- E as TemplateSchema,
333
+ L as TemplateSchema,
338
334
  M as UISchema
339
335
  };
@@ -15,7 +15,7 @@ var u = function() {
15
15
  p,
16
16
  !1,
17
17
  null,
18
- "6e711fd7"
18
+ "82128f7d"
19
19
  );
20
20
  const v = c.exports;
21
21
  export {
@@ -10,9 +10,9 @@ var s = function() {
10
10
  d,
11
11
  !1,
12
12
  null,
13
- "d11dd577"
13
+ "5c02dcc7"
14
14
  );
15
- const c = i.exports;
15
+ const p = i.exports;
16
16
  export {
17
- c as default
17
+ p as default
18
18
  };
@@ -8,8 +8,6 @@ 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.
13
11
  handleSave: (t) => {
14
12
  var o;
15
13
  return (o = e.value) == null ? void 0 : o.handleSave(t);
@@ -14,7 +14,7 @@ var n = function() {
14
14
  a,
15
15
  !1,
16
16
  null,
17
- "fad98586"
17
+ "64c52560"
18
18
  );
19
19
  const _ = c.exports;
20
20
  export {
@@ -0,0 +1,36 @@
1
+ import { useConfig as D } from "./useConfig.js";
2
+ import { useToaster as T } from "./useToaster.js";
3
+ import { useTranslations as g } from "./useTranslations.js";
4
+ import { ToasterTypeOptions as C } from "../enums/toaster.js";
5
+ import { buildDynamicContentLookup as h, convertModuleDynamicContent as O } from "../utils/dynamicContentConverter.js";
6
+ const M = "dynamic-content.unresolved-attributes-on-drop", A = () => {
7
+ const { template: i, isFeatureEnabled: p } = D(), { showToaster: a } = T(), m = g();
8
+ return { handleModuleAdd: (n, e) => {
9
+ var s, c, l;
10
+ try {
11
+ if ((n == null ? void 0 : n.action) !== "ADD" && (n == null ? void 0 : n.action) !== "COPY")
12
+ return;
13
+ const o = h(((s = i.value) == null ? void 0 : s.availableDynamicContent) ?? []);
14
+ if (o.size === 0)
15
+ return;
16
+ const t = (c = e == null ? void 0 : e.getTargetNode) == null ? void 0 : c.call(e), r = (l = t == null ? void 0 : t.getOuterHTML) == null ? void 0 : l.call(t);
17
+ if (!t || typeof r != "string")
18
+ return;
19
+ const { html: u, unresolved: y } = O(
20
+ r,
21
+ o,
22
+ p("liquidSyntax")
23
+ );
24
+ u !== r && e.modifyHtml(t).replaceWith(u), y.length > 0 && a({
25
+ type: C.Warning,
26
+ message: m(M)
27
+ });
28
+ } catch (o) {
29
+ console.error("Failed to repair dynamic content on module add:", o);
30
+ }
31
+ } };
32
+ };
33
+ export {
34
+ M as UNRESOLVED_DYNAMIC_CONTENT_ON_DROP_KEY,
35
+ A as useModuleDynamicContentRepair
36
+ };