@useinsider/guido 3.17.0-beta.e39d9c6 → 3.17.0-beta.ea65303

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 CHANGED
@@ -162,6 +162,7 @@ const config: GuidoConfigInput = {
162
162
  liquidSyntax?: boolean, // Default: false - Enable Liquid template syntax
163
163
  autosave?: boolean, // Default: false - Show the Auto Save toggle in the header. See wiki/AUTOSAVE.md.
164
164
  allowlistEnabled?: boolean, // Default: false - Pre-save domain-allowlist check (opt-in). Guido self-serves the block toaster (role lookup, deep-link, copy from window.trans).
165
+ allowSaveWithErrors?: boolean, // Default: true - Allow the validation drawer's "Save and Continue" soft-save. Set false to hard-block invalid saves (transactional + unsubscribe pages).
165
166
  },
166
167
 
167
168
  // Optional: Callbacks
@@ -30,7 +30,7 @@ const p = {
30
30
  name: t(),
31
31
  /** Fallback font family (e.g., "serif" or "sans-serif") */
32
32
  family: t()
33
- }), M = a({
33
+ }), E = a({
34
34
  /** Partner/organization name (required) */
35
35
  name: m(
36
36
  t(),
@@ -54,7 +54,7 @@ const p = {
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(L)
57
- }), E = a({
57
+ }), M = a({
58
58
  /** Display text for the dynamic content */
59
59
  text: t(),
60
60
  /** Template variable value (e.g., {{username}}) */
@@ -76,10 +76,10 @@ const p = {
76
76
  children: e(c(S)),
77
77
  // eslint-disable-next-line camelcase -- backend field name
78
78
  select_items: e(c(S))
79
- })), N = y(
79
+ })), v = y(
80
80
  t(),
81
81
  R(c(S), [])
82
- ), P = g({
82
+ ), N = g({
83
83
  /** Block ID (matches the dictionary key and the legacy HTML element id) */
84
84
  id: e(n()),
85
85
  /** Decimal places for price display (legacy data may use string or number) */
@@ -124,7 +124,7 @@ const p = {
124
124
  isPriceMovedToNextLine: e(o()),
125
125
  /** Legacy "Hide if same as discounted" / delete-price-for-zero-sale toggle */
126
126
  isPriceDeletedForZeroSale: e(o())
127
- }), v = a({
127
+ }), P = a({
128
128
  /**
129
129
  * Legacy recommendation block configs keyed by block ID.
130
130
  * Pass this when loading a template authored with the v1
@@ -132,7 +132,7 @@ const p = {
132
132
  * strategy, currency, locale, and layout data.
133
133
  */
134
134
  recommendationConfigs: e(
135
- y(t(), P),
135
+ y(t(), N),
136
136
  {}
137
137
  )
138
138
  }), x = a({
@@ -142,7 +142,7 @@ const p = {
142
142
  css: e(t(), ""),
143
143
  /** Preselected dynamic content items */
144
144
  preselectedDynamicContent: e(
145
- c(E),
145
+ c(M),
146
146
  []
147
147
  ),
148
148
  /**
@@ -151,7 +151,7 @@ const p = {
151
151
  * (first) partner's leaf attributes into the label→token map that repairs
152
152
  * label-form placeholders (`{{ Phone Number }}`) in dropped saved modules.
153
153
  */
154
- dynamicContentList: e(N, {}),
154
+ dynamicContentList: e(v, {}),
155
155
  /** Valid custom field attribute names from the partner's categorized fields */
156
156
  customFieldAttributes: e(c(t()), []),
157
157
  /** Selected unsubscribe page IDs */
@@ -173,7 +173,7 @@ const p = {
173
173
  0
174
174
  ),
175
175
  /** Migration-only inputs (legacy block configs) */
176
- migration: e(v, {})
176
+ migration: e(P, {})
177
177
  }), D = a({
178
178
  /** Sender display name */
179
179
  senderName: e(t(), ""),
@@ -219,8 +219,10 @@ const p = {
219
219
  /** Enable pre-save domain-allowlist validation (opt-in; Guido self-serves the block toaster) */
220
220
  allowlistEnabled: e(o(), !1),
221
221
  /** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
222
- linkTrackingIds: e(o(), !1)
223
- }), B = i([
222
+ linkTrackingIds: e(o(), !1),
223
+ /** Allow persisting a template that still has validation errors (drawer "Save and Continue" soft-save). Host sets false for transactional + unsubscribe. */
224
+ allowSaveWithErrors: e(o(), !0)
225
+ }), w = i([
224
226
  "amp-accordion",
225
227
  "amp-carousel",
226
228
  "amp-form-controls",
@@ -234,7 +236,7 @@ const p = {
234
236
  "text-block",
235
237
  "timer-block",
236
238
  "video-block"
237
- ]), w = i([
239
+ ]), B = i([
238
240
  "dynamic-content",
239
241
  "checkbox-block",
240
242
  "radio-button-block",
@@ -245,12 +247,12 @@ const p = {
245
247
  ]), H = a({
246
248
  /** Default blocks to exclude from the editor */
247
249
  excludeDefaults: e(
248
- c(B),
250
+ c(w),
249
251
  []
250
252
  ),
251
253
  /** Custom blocks to include in the editor */
252
254
  includeCustoms: e(
253
- c(w),
255
+ c(B),
254
256
  []
255
257
  )
256
258
  }), d = a({
@@ -301,7 +303,7 @@ const p = {
301
303
  customRules: e(c(V), []),
302
304
  /** Skip default compiler rules */
303
305
  ignoreDefaultRules: e(o(), !1)
304
- }), Z = a({
306
+ }), W = a({
305
307
  /**
306
308
  * External validation handler called before save completes.
307
309
  * Return false to cancel the save operation.
@@ -312,12 +314,12 @@ const p = {
312
314
  "externalValidation must be a function"
313
315
  )
314
316
  )
315
- }), Q = a({
317
+ }), K = a({
316
318
  // Required sections
317
319
  /** Identity configuration (required) */
318
320
  identity: A,
319
321
  /** Partner configuration (required) */
320
- partner: M,
322
+ partner: E,
321
323
  // Optional sections (with defaults)
322
324
  /** Template content and presets */
323
325
  template: e(x, {}),
@@ -332,33 +334,33 @@ const p = {
332
334
  /** Compiler configuration */
333
335
  compiler: e(z, {}),
334
336
  /** Callbacks and event handlers */
335
- callbacks: e(Z, {})
337
+ callbacks: e(W, {})
336
338
  });
337
339
  export {
338
340
  H as BlocksSchema,
339
- Z as CallbacksSchema,
341
+ W as CallbacksSchema,
340
342
  V as CompilerRuleSchema,
341
343
  z as CompilerSchema,
342
- w as CustomBlockTypeSchema,
344
+ B as CustomBlockTypeSchema,
343
345
  G as CustomRuleSchema,
344
- B as DefaultBlockTypeSchema,
345
- N as DynamicContentListSchema,
346
+ w as DefaultBlockTypeSchema,
347
+ v as DynamicContentListSchema,
346
348
  S as DynamicContentNodeSchema,
347
- E as DynamicContentSchema,
349
+ M as DynamicContentSchema,
348
350
  O as EditorSchema,
349
351
  D as EmailHeaderSchema,
350
352
  L as FallbackFontSchema,
351
353
  U as FeaturesSchema,
352
- Q as GuidoConfigSchema,
354
+ K as GuidoConfigSchema,
353
355
  A as IdentitySchema,
354
- P as LegacyRecommendationConfigSchema,
356
+ N as LegacyRecommendationConfigSchema,
355
357
  p as MessageType,
356
- M as PartnerSchema,
358
+ E as PartnerSchema,
357
359
  l as ProductType,
358
360
  j as RegexRuleSchema,
359
361
  q as RemoveRuleSchema,
360
362
  _ as ReplaceRuleSchema,
361
- v as TemplateMigrationSchema,
363
+ P as TemplateMigrationSchema,
362
364
  x as TemplateSchema,
363
365
  F as UISchema
364
366
  };
@@ -15,7 +15,7 @@ var u = function() {
15
15
  p,
16
16
  !1,
17
17
  null,
18
- "44d8e7c8"
18
+ "eedf7416"
19
19
  );
20
20
  const v = c.exports;
21
21
  export {
@@ -4,14 +4,14 @@ import { useConfig as F } from "../../../composables/useConfig.js";
4
4
  import { useExport as z } from "../../../composables/useExport.js";
5
5
  import { useTestEmailClick as I } from "../../../composables/useGuidoActions.js";
6
6
  import { useHtmlCompiler as P } from "../../../composables/useHtmlCompiler.js";
7
- import { useSave as j } from "../../../composables/useSave.js";
8
- import { useSaveValidation as G } from "../../../composables/useSaveValidation.js";
9
- import { useSaveValidationRollout as J } from "../../../composables/useSaveValidationRollout.js";
10
- import { useToaster as K } from "../../../composables/useToaster.js";
11
- import { useTranslations as N } from "../../../composables/useTranslations.js";
12
- import { useVersionHistoryApi as Q } from "../../../composables/useVersionHistoryApi.js";
13
- import { useLiquidValidator as U } from "../../../composables/validators/useLiquidValidator.js";
14
- import { ToasterTypeOptions as W } from "../../../enums/toaster.js";
7
+ import { useSave as W } from "../../../composables/useSave.js";
8
+ import { useSaveValidation as j } from "../../../composables/useSaveValidation.js";
9
+ import { useSaveValidationRollout as G } from "../../../composables/useSaveValidationRollout.js";
10
+ import { useToaster as J } from "../../../composables/useToaster.js";
11
+ import { useTranslations as K } from "../../../composables/useTranslations.js";
12
+ import { useVersionHistoryApi as N } from "../../../composables/useVersionHistoryApi.js";
13
+ import { useLiquidValidator as Q } from "../../../composables/validators/useLiquidValidator.js";
14
+ import { ToasterTypeOptions as U } from "../../../enums/toaster.js";
15
15
  import { useConfigStore as X } from "../../../stores/config.js";
16
16
  import { useEditorStore as Y } from "../../../stores/editor.js";
17
17
  import { useSaveValidationStore as Z } from "../../../stores/save-validation.js";
@@ -23,7 +23,7 @@ import rt from "./MigrationConfirmModal.vue.js";
23
23
  const At = /* @__PURE__ */ R({
24
24
  __name: "EditorActions",
25
25
  setup(it, { expose: A }) {
26
- const { config: u, isFeatureEnabled: c } = F(), { exportHtml: f } = z(), { save: p } = j(), { validateCurrentTemplate: d } = G(), { isEnabled: i } = J(), { showToaster: v } = K(), { openVersionHistory: S, closeVersionHistory: y } = Q(), { getCompiledEmail: g } = D(), { compileHtml: h } = P(), { validateLiquidSyntax: T } = U(), V = X(), e = Y(), H = Z(), w = $(), { hasMigrations: E } = et(w), r = N(), O = l(() => i.value && !V.isTransactional ? r("email-editor.save-and-continue") : "Save"), s = m(!1), a = m(!1), x = m(), n = I(), M = () => {
26
+ const { config: u, isFeatureEnabled: c } = F(), { exportHtml: f } = z(), { save: p } = W(), { validateCurrentTemplate: d } = j(), { isEnabled: i } = G(), { showToaster: v } = J(), { openVersionHistory: S, closeVersionHistory: y } = N(), { getCompiledEmail: g } = D(), { compileHtml: h } = P(), { validateLiquidSyntax: V } = Q(), T = X(), e = Y(), w = Z(), H = $(), { hasMigrations: E } = et(H), r = K(), O = l(() => i.value && T.allowSaveWithErrors ? r("email-editor.save-and-continue") : "Save"), s = m(!1), a = m(!1), x = m(), n = I(), M = () => {
27
27
  if (e.isVersionHistoryOpen) {
28
28
  y();
29
29
  return;
@@ -62,11 +62,11 @@ const At = /* @__PURE__ */ R({
62
62
  }
63
63
  if (t.length) {
64
64
  v({
65
- type: W.Error,
65
+ type: U.Error,
66
66
  message: r("email-editor.validation-errors-found"),
67
67
  actionButton: {
68
68
  text: r("email-editor.check-errors"),
69
- onClick: () => H.open(t, "test")
69
+ onClick: () => w.open(t, "test")
70
70
  },
71
71
  autoHide: !1
72
72
  });
@@ -79,7 +79,7 @@ const At = /* @__PURE__ */ R({
79
79
  e.loadingStatus = !0;
80
80
  try {
81
81
  const { html: t } = await g({ minimize: !0, resetDataSavedFlag: !1 }), { compiledHtml: o } = h(t);
82
- if (!await T(o))
82
+ if (!await V(o))
83
83
  return;
84
84
  } finally {
85
85
  e.loadingStatus = !1;
@@ -89,7 +89,7 @@ const At = /* @__PURE__ */ R({
89
89
  };
90
90
  return A({
91
91
  handleSave: _
92
- }), { __sfc: !0, config: u, isFeatureEnabled: c, exportHtml: f, save: p, validateCurrentTemplate: d, isEnabled: i, showToaster: v, openVersionHistory: S, closeVersionHistory: y, getCompiledEmail: g, compileHtml: h, validateLiquidSyntax: T, configStore: V, editorStore: e, saveValidationStore: H, templateStore: w, hasMigrations: E, trans: r, saveLabel: O, isExporting: s, isSaving: a, migrationModalRef: x, testEmailClick: n, handleVersionHistory: M, handleExport: b, handleSaveAs: k, versionHistoryTooltipText: q, isVersionHistoryButtonVisible: B, executeSave: C, handleSave: _, handleTestEmail: L, getTooltipOptions: tt, InButtonV2: ot, MigrationConfirmModal: rt };
92
+ }), { __sfc: !0, config: u, isFeatureEnabled: c, exportHtml: f, save: p, validateCurrentTemplate: d, isEnabled: i, showToaster: v, openVersionHistory: S, closeVersionHistory: y, getCompiledEmail: g, compileHtml: h, validateLiquidSyntax: V, configStore: T, editorStore: e, saveValidationStore: w, templateStore: H, hasMigrations: E, trans: r, saveLabel: O, isExporting: s, isSaving: a, migrationModalRef: x, testEmailClick: n, handleVersionHistory: M, handleExport: b, handleSaveAs: k, versionHistoryTooltipText: q, isVersionHistoryButtonVisible: B, executeSave: C, handleSave: _, handleTestEmail: L, getTooltipOptions: tt, InButtonV2: ot, MigrationConfirmModal: rt };
93
93
  }
94
94
  });
95
95
  export {
@@ -1,18 +1,18 @@
1
- import n from "./ValidationErrorDrawer.vue2.js";
1
+ import a from "./ValidationErrorDrawer.vue2.js";
2
2
  /* empty css */
3
3
  import s from "../../../_virtual/_plugin-vue2_normalizer.js";
4
4
  var i = function() {
5
5
  var r = this, o = r._self._c, t = r._self._setupProxy;
6
- return o(t.WpDrawer, { attrs: { id: "guido__validation-error-drawer", size: "small", "footer-button-group-options": t.footerButtonGroupOptions, status: t.store.isDrawerOpen, "title-text": t.titleText }, on: { onCloseEvent: t.handleClose, primaryButtonEvent: t.handleClose, secondaryButtonEvent: t.handleSaveAndContinue } }, [o("div", { staticClass: "d-f f-d-c validation-error-list" }, r._l(t.rows, function(e, a) {
7
- return o("div", { key: a, staticClass: "d-f a-i-c validation-error-row" }, [o(t.InIcons, { staticClass: "validation-error-row__icon i-c-12", attrs: { name: "filled-caution-triangle" } }), o("span", { staticClass: "validation-error-row__text" }, [r._v(r._s(e))])], 1);
6
+ return o(t.WpDrawer, { attrs: { id: "guido__validation-error-drawer", size: "small", "footer-button-group-options": t.footerButtonGroupOptions, status: t.store.isDrawerOpen, "title-text": t.titleText }, on: { onCloseEvent: t.handleClose, primaryButtonEvent: t.handleClose, secondaryButtonEvent: t.handleSaveAndContinue } }, [o("div", { staticClass: "d-f f-d-c validation-error-list" }, r._l(t.rows, function(e, n) {
7
+ return o("div", { key: n, staticClass: "d-f a-i-c validation-error-row" }, [o(t.InIcons, { staticClass: "validation-error-row__icon i-c-12", attrs: { name: "filled-caution-triangle" } }), o("span", { staticClass: "validation-error-row__text" }, [r._v(r._s(e))])], 1);
8
8
  }), 0)]);
9
9
  }, l = [], _ = /* @__PURE__ */ s(
10
- n,
10
+ a,
11
11
  i,
12
12
  l,
13
13
  !1,
14
14
  null,
15
- "856367aa"
15
+ "30d2e1f9"
16
16
  );
17
17
  const p = _.exports;
18
18
  export {
@@ -4,12 +4,12 @@ import { useSave as S } from "../../../composables/useSave.js";
4
4
  import { useTranslations as v } from "../../../composables/useTranslations.js";
5
5
  import { useConfigStore as g } from "../../../stores/config.js";
6
6
  import { useEditorStore as y } from "../../../stores/editor.js";
7
- import { useSaveValidationStore as _ } from "../../../stores/save-validation.js";
8
- import { InIcons as h } from "@useinsider/design-system-vue";
9
- const O = /* @__PURE__ */ m({
7
+ import { useSaveValidationStore as h } from "../../../stores/save-validation.js";
8
+ import { InIcons as w } from "@useinsider/design-system-vue";
9
+ const I = /* @__PURE__ */ m({
10
10
  __name: "ValidationErrorDrawer",
11
- setup(w) {
12
- const r = v(), e = _(), n = y(), s = g(), { saveWithErrors: i } = S(), o = p(!1), l = a(() => `${r("email-editor.validation-errors")} (${e.errorCount})`), u = a(() => {
11
+ setup(_) {
12
+ const r = v(), e = h(), n = y(), s = g(), { saveWithErrors: i } = S(), o = p(!1), l = a(() => `${r("email-editor.validation-errors")} (${e.errorCount})`), u = a(() => {
13
13
  const t = {
14
14
  primaryButton: {
15
15
  styling: "solid",
@@ -17,7 +17,7 @@ const O = /* @__PURE__ */ m({
17
17
  labelText: r("email-editor.update-design")
18
18
  }
19
19
  };
20
- return !s.isTransactional && e.intent !== "test" && (t.secondaryButton = {
20
+ return s.allowSaveWithErrors && e.intent !== "test" && (t.secondaryButton = {
21
21
  styling: "solid",
22
22
  type: "subtle-primary",
23
23
  labelText: r("email-editor.save-and-continue"),
@@ -40,9 +40,9 @@ const O = /* @__PURE__ */ m({
40
40
  o.value = !1;
41
41
  }
42
42
  }
43
- }, WpDrawer: f, InIcons: h };
43
+ }, WpDrawer: f, InIcons: w };
44
44
  }
45
45
  });
46
46
  export {
47
- O as default
47
+ I as default
48
48
  };
@@ -1,10 +1,10 @@
1
- import { useActionsApi as h } from "./useActionsApi.js";
1
+ import { useActionsApi as U } from "./useActionsApi.js";
2
2
  import { useConfig as L } from "./useConfig.js";
3
3
  import { useSaveStart as A, useSaveComplete as q } from "./useGuidoActions.js";
4
4
  import { useSaveValidation as M } from "./useSaveValidation.js";
5
5
  import { useSaveValidationRollout as R } from "./useSaveValidationRollout.js";
6
- import { useSyncModuleExtractor as O } from "./useSyncModuleExtractor.js";
7
- import { ToasterTypeOptions as W } from "../enums/toaster.js";
6
+ import { useSyncModuleExtractor as W } from "./useSyncModuleExtractor.js";
7
+ import { ToasterTypeOptions as O } from "../enums/toaster.js";
8
8
  import { useStripoApi as D } from "../services/stripoApi.js";
9
9
  import { useConfigStore as F } from "../stores/config.js";
10
10
  import { useDynamicContentStore as j } from "../stores/dynamic-content.js";
@@ -16,8 +16,8 @@ import { useToaster as N } from "./useToaster.js";
16
16
  import { useCouponBlockValidator as Q } from "./validators/useCouponBlockValidator.js";
17
17
  import { useLiquidValidator as X } from "./validators/useLiquidValidator.js";
18
18
  import { useUnsubscribeBlockValidator as Y } from "./validators/useUnsubscribeBlockValidator.js";
19
- const bt = () => {
20
- const r = A(), u = q(), { validateHtml: d } = K(), { validateLiquidSyntax: f } = X(), { validateCouponBlockTags: p } = Q(), { validateUnsubscribeBlockUniqueness: v, validateUnsubscribeBlockHasTemplate: y } = Y(), { callbacks: a, isFeatureEnabled: c } = L(), { extractSyncModuleData: S } = O(), { setSyncModuleUnsubscriptionPages: b } = D(), { editorSave: g, getTemplateData: w } = h(), { showToaster: H } = N(), { getBlockedDomains: V, resolveToast: E } = J(), { prepareTemplateDetails: m } = G(), { collectSaveValidationErrors: C } = M(), { isEnabled: x } = R(), k = z(), T = j(), B = F(), n = async (t, e, o) => {
19
+ const wt = () => {
20
+ const r = A(), u = q(), { validateHtml: d } = K(), { validateLiquidSyntax: f } = X(), { validateCouponBlockTags: p } = Q(), { validateUnsubscribeBlockUniqueness: v, validateUnsubscribeBlockHasTemplate: S } = Y(), { callbacks: a, isFeatureEnabled: c } = L(), { extractSyncModuleData: y } = W(), { setSyncModuleUnsubscriptionPages: w } = D(), { editorSave: b, getTemplateData: g } = U(), { showToaster: H } = N(), { getBlockedDomains: V, resolveToast: E } = J(), { prepareTemplateDetails: m } = G(), { collectSaveValidationErrors: C } = M(), { isEnabled: x } = R(), k = z(), B = j(), T = F(), n = async (t, e, o) => {
21
21
  if (!c("allowlistEnabled"))
22
22
  return !1;
23
23
  const i = await V(t, e);
@@ -26,19 +26,19 @@ const bt = () => {
26
26
  if (!o) {
27
27
  const s = await E(i);
28
28
  s != null && s.message && H({
29
- type: W.Warning,
29
+ type: O.Warning,
30
30
  message: s.message,
31
31
  actionButton: s.actionButton
32
32
  });
33
33
  }
34
34
  return !0;
35
- }, P = async (t) => !p(t.compiledHtml) || !v(t.compiledHtml) || !y(t.compiledHtml) ? !1 : c("liquidSyntax") ? f(t.compiledHtml) : d(t.compiledHtml, t.dynamicContentList, !0), l = async (t, e) => {
36
- if (!await g())
35
+ }, P = async (t) => !p(t.compiledHtml) || !v(t.compiledHtml) || !S(t.compiledHtml) ? !1 : c("liquidSyntax") ? f(t.compiledHtml) : d(t.compiledHtml, t.dynamicContentList, !0), l = async (t, e) => {
36
+ if (!await b())
37
37
  return;
38
- const { unsubscribePayload: i, stripoModules: s } = S(t.rawHtml);
39
- if (await b(i), t.modules = s, !e.suppress) {
40
- const U = e.blankCompiled ? { compiledHtml: "", ampHtml: "" } : {};
41
- u({ ...t, ...U, silent: e.silent });
38
+ const { unsubscribePayload: i, stripoModules: s } = y(t.rawHtml);
39
+ if (await w(i), t.modules = s, !e.suppress) {
40
+ const h = e.blankCompiled ? { compiledHtml: "", ampHtml: "" } : {};
41
+ u({ ...t, ...h, silent: e.silent });
42
42
  }
43
43
  return t;
44
44
  };
@@ -61,7 +61,7 @@ const bt = () => {
61
61
  return l(o, { silent: e, suppress: t });
62
62
  }, saveWithErrors: async () => {
63
63
  var e;
64
- if (B.isTransactional)
64
+ if (!T.allowSaveWithErrors)
65
65
  return;
66
66
  r();
67
67
  const t = await m();
@@ -69,11 +69,11 @@ const bt = () => {
69
69
  return l(t, { silent: !1, blankCompiled: !0 });
70
70
  }, saveRawOnly: async () => {
71
71
  r();
72
- const { html: t, css: e } = await w();
72
+ const { html: t, css: e } = await g();
73
73
  if (await n(t, e, !0))
74
74
  return;
75
75
  const o = I(t), i = {
76
- dynamicContentList: T.getSelectedDynamicContentList,
76
+ dynamicContentList: B.getSelectedDynamicContentList,
77
77
  compiledHtml: "",
78
78
  rawHtml: t,
79
79
  css: e,
@@ -90,5 +90,5 @@ const bt = () => {
90
90
  } };
91
91
  };
92
92
  export {
93
- bt as useSave
93
+ wt as useSave
94
94
  };
package/dist/guido.css CHANGED
@@ -1 +1 @@
1
- .gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-b8f24f34] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-44d8e7c8]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.validation-error-list[data-v-856367aa]{gap:16px}.validation-error-row[data-v-856367aa]{gap:8px;padding:24px;border:1px solid #E1E1E1;border-radius:8px}.validation-error-row__icon[data-v-856367aa]{flex-shrink:0;font-size:24px;line-height:0}.validation-error-row__text[data-v-856367aa]{font-size:13px;line-height:16px;color:#292929;word-break:break-word}.guido-editor__wrapper[data-v-f02fdde0]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-f02fdde0]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-f02fdde0]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}
1
+ .gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-b8f24f34] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-eedf7416]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.validation-error-list[data-v-30d2e1f9]{gap:16px}.validation-error-row[data-v-30d2e1f9]{gap:8px;padding:24px;border:1px solid #E1E1E1;border-radius:8px}.validation-error-row__icon[data-v-30d2e1f9]{flex-shrink:0;font-size:24px;line-height:0}.validation-error-row__text[data-v-30d2e1f9]{font-size:13px;line-height:16px;color:#292929;word-break:break-word}.guido-editor__wrapper[data-v-f02fdde0]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-f02fdde0]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-f02fdde0]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}
@@ -395,6 +395,8 @@ export declare const FeaturesSchema: v.ObjectSchema<{
395
395
  readonly allowlistEnabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
396
396
  /** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
397
397
  readonly linkTrackingIds: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
398
+ /** Allow persisting a template that still has validation errors (drawer "Save and Continue" soft-save). Host sets false for transactional + unsubscribe. */
399
+ readonly allowSaveWithErrors: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
398
400
  }, undefined>;
399
401
  /**
400
402
  * Default block types available in Stripo
@@ -794,6 +796,8 @@ export declare const GuidoConfigSchema: v.ObjectSchema<{
794
796
  readonly allowlistEnabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
795
797
  /** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
796
798
  readonly linkTrackingIds: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
799
+ /** Allow persisting a template that still has validation errors (drawer "Save and Continue" soft-save). Host sets false for transactional + unsubscribe. */
800
+ readonly allowSaveWithErrors: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
797
801
  }, undefined>, {}>;
798
802
  /** Block configuration */
799
803
  readonly blocks: v.OptionalSchema<v.ObjectSchema<{
@@ -99,6 +99,7 @@ export declare const useConfig: () => {
99
99
  autosave: boolean;
100
100
  allowlistEnabled: boolean;
101
101
  linkTrackingIds: boolean;
102
+ allowSaveWithErrors: boolean;
102
103
  };
103
104
  blocks: {
104
105
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -233,6 +234,7 @@ export declare const useConfig: () => {
233
234
  autosave: boolean;
234
235
  allowlistEnabled: boolean;
235
236
  linkTrackingIds: boolean;
237
+ allowSaveWithErrors: boolean;
236
238
  } | null>;
237
239
  blocks: import("vue").ComputedRef<{
238
240
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -104,6 +104,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
104
104
  autosave: boolean;
105
105
  allowlistEnabled: boolean;
106
106
  linkTrackingIds: boolean;
107
+ allowSaveWithErrors: boolean;
107
108
  };
108
109
  blocks: {
109
110
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -244,6 +245,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
244
245
  autosave: boolean;
245
246
  allowlistEnabled: boolean;
246
247
  linkTrackingIds: boolean;
248
+ allowSaveWithErrors: boolean;
247
249
  };
248
250
  blocks: {
249
251
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -384,6 +386,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
384
386
  autosave: boolean;
385
387
  allowlistEnabled: boolean;
386
388
  linkTrackingIds: boolean;
389
+ allowSaveWithErrors: boolean;
387
390
  };
388
391
  blocks: {
389
392
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -524,6 +527,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
524
527
  autosave: boolean;
525
528
  allowlistEnabled: boolean;
526
529
  linkTrackingIds: boolean;
530
+ allowSaveWithErrors: boolean;
527
531
  };
528
532
  blocks: {
529
533
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -664,6 +668,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
664
668
  autosave: boolean;
665
669
  allowlistEnabled: boolean;
666
670
  linkTrackingIds: boolean;
671
+ allowSaveWithErrors: boolean;
667
672
  };
668
673
  blocks: {
669
674
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -804,6 +809,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
804
809
  autosave: boolean;
805
810
  allowlistEnabled: boolean;
806
811
  linkTrackingIds: boolean;
812
+ allowSaveWithErrors: boolean;
807
813
  };
808
814
  blocks: {
809
815
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -944,6 +950,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
944
950
  autosave: boolean;
945
951
  allowlistEnabled: boolean;
946
952
  linkTrackingIds: boolean;
953
+ allowSaveWithErrors: boolean;
947
954
  };
948
955
  blocks: {
949
956
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1084,6 +1091,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1084
1091
  autosave: boolean;
1085
1092
  allowlistEnabled: boolean;
1086
1093
  linkTrackingIds: boolean;
1094
+ allowSaveWithErrors: boolean;
1087
1095
  };
1088
1096
  blocks: {
1089
1097
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1224,6 +1232,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1224
1232
  autosave: boolean;
1225
1233
  allowlistEnabled: boolean;
1226
1234
  linkTrackingIds: boolean;
1235
+ allowSaveWithErrors: boolean;
1227
1236
  };
1228
1237
  blocks: {
1229
1238
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1364,6 +1373,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1364
1373
  autosave: boolean;
1365
1374
  allowlistEnabled: boolean;
1366
1375
  linkTrackingIds: boolean;
1376
+ allowSaveWithErrors: boolean;
1367
1377
  };
1368
1378
  blocks: {
1369
1379
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1504,6 +1514,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1504
1514
  autosave: boolean;
1505
1515
  allowlistEnabled: boolean;
1506
1516
  linkTrackingIds: boolean;
1517
+ allowSaveWithErrors: boolean;
1507
1518
  };
1508
1519
  blocks: {
1509
1520
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1644,6 +1655,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1644
1655
  autosave: boolean;
1645
1656
  allowlistEnabled: boolean;
1646
1657
  linkTrackingIds: boolean;
1658
+ allowSaveWithErrors: boolean;
1647
1659
  };
1648
1660
  blocks: {
1649
1661
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1784,6 +1796,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1784
1796
  autosave: boolean;
1785
1797
  allowlistEnabled: boolean;
1786
1798
  linkTrackingIds: boolean;
1799
+ allowSaveWithErrors: boolean;
1787
1800
  };
1788
1801
  blocks: {
1789
1802
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1924,6 +1937,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1924
1937
  autosave: boolean;
1925
1938
  allowlistEnabled: boolean;
1926
1939
  linkTrackingIds: boolean;
1940
+ allowSaveWithErrors: boolean;
1927
1941
  };
1928
1942
  blocks: {
1929
1943
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -2064,6 +2078,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2064
2078
  autosave: boolean;
2065
2079
  allowlistEnabled: boolean;
2066
2080
  linkTrackingIds: boolean;
2081
+ allowSaveWithErrors: boolean;
2067
2082
  };
2068
2083
  blocks: {
2069
2084
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -2111,6 +2126,13 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2111
2126
  * consumers stay safe in setup where a raw config read snapshots null (SD-147945).
2112
2127
  */
2113
2128
  isTransactional(): boolean;
2129
+ /**
2130
+ * Soft-save policy: may the editor persist a template with validation errors?
2131
+ * Default true (host sets features.allowSaveWithErrors=false for transactional +
2132
+ * unsub). Reactive getter defaulting true — reading via isFeatureEnabled would
2133
+ * floor to false pre-init and momentarily hide the soft-save option (SD-147430).
2134
+ */
2135
+ allowSaveWithErrors(): boolean;
2114
2136
  /**
2115
2137
  * Get the username
2116
2138
  */
@@ -2209,6 +2231,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2209
2231
  autosave: boolean;
2210
2232
  allowlistEnabled: boolean;
2211
2233
  linkTrackingIds: boolean;
2234
+ allowSaveWithErrors: boolean;
2212
2235
  };
2213
2236
  blocks: {
2214
2237
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -2349,6 +2372,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2349
2372
  autosave: boolean;
2350
2373
  allowlistEnabled: boolean;
2351
2374
  linkTrackingIds: boolean;
2375
+ allowSaveWithErrors: boolean;
2352
2376
  };
2353
2377
  blocks: {
2354
2378
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -2491,6 +2515,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2491
2515
  autosave: boolean;
2492
2516
  allowlistEnabled: boolean;
2493
2517
  linkTrackingIds: boolean;
2518
+ allowSaveWithErrors: boolean;
2494
2519
  };
2495
2520
  blocks: {
2496
2521
  excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
@@ -1,8 +1,8 @@
1
- import { MessageType as o } from "../@types/config/schemas.js";
1
+ import { MessageType as r } from "../@types/config/schemas.js";
2
2
  import "../@types/config/defaults.js";
3
- import { parseConfig as r } from "../@types/config/validator.js";
3
+ import { parseConfig as o } from "../@types/config/validator.js";
4
4
  import { defineStore as a } from "pinia";
5
- const g = a("guido-config", {
5
+ const u = a("guido-config", {
6
6
  state: () => ({
7
7
  initialized: !1,
8
8
  config: null
@@ -75,64 +75,74 @@ const g = a("guido-config", {
75
75
  * Get the template ID
76
76
  */
77
77
  templateId: (i) => {
78
- var e, n;
79
- return ((n = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : n.templateId) ?? "";
78
+ var e, t;
79
+ return ((t = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : t.templateId) ?? "";
80
80
  },
81
81
  /**
82
82
  * Get the user ID
83
83
  */
84
84
  userId: (i) => {
85
- var e, n;
86
- return ((n = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : n.userId) ?? "";
85
+ var e, t;
86
+ return ((t = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : t.userId) ?? "";
87
87
  },
88
88
  /**
89
89
  * Get the variation ID
90
90
  */
91
91
  variationId: (i) => {
92
- var e, n;
93
- return ((n = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : n.variationId) ?? "";
92
+ var e, t;
93
+ return ((t = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : t.variationId) ?? "";
94
94
  },
95
95
  /**
96
96
  * Get the partner name
97
97
  */
98
98
  partnerName: (i) => {
99
- var e, n;
100
- return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.name) ?? "";
99
+ var e, t;
100
+ return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.name) ?? "";
101
101
  },
102
102
  /**
103
103
  * Get the product type
104
104
  */
105
105
  productType: (i) => {
106
- var e, n;
107
- return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.productType) ?? 60;
106
+ var e, t;
107
+ return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.productType) ?? 60;
108
108
  },
109
109
  /**
110
110
  * Get the message type
111
111
  */
112
112
  messageType: (i) => {
113
- var e, n;
114
- return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.messageType) ?? 1;
113
+ var e, t;
114
+ return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.messageType) ?? 1;
115
115
  },
116
116
  /**
117
117
  * Transactional campaigns keep the hard save block. Reactive getter, so
118
118
  * consumers stay safe in setup where a raw config read snapshots null (SD-147945).
119
119
  */
120
120
  isTransactional() {
121
- return this.messageType === o.TRANSACTIONAL;
121
+ return this.messageType === r.TRANSACTIONAL;
122
+ },
123
+ /**
124
+ * Soft-save policy: may the editor persist a template with validation errors?
125
+ * Default true (host sets features.allowSaveWithErrors=false for transactional +
126
+ * unsub). Reactive getter defaulting true — reading via isFeatureEnabled would
127
+ * floor to false pre-init and momentarily hide the soft-save option (SD-147430).
128
+ */
129
+ allowSaveWithErrors() {
130
+ var i;
131
+ return ((i = this.features) == null ? void 0 : i.allowSaveWithErrors) ?? !0;
122
132
  },
123
133
  /**
124
134
  * Get the username
125
135
  */
126
136
  username: (i) => {
127
- var e, n;
128
- return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.username) ?? "Guido User";
137
+ var e, t;
138
+ return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.username) ?? "Guido User";
129
139
  },
130
140
  /**
131
141
  * Check if header should be shown
132
142
  */
133
143
  showHeader: (i) => {
134
- var e, n;
135
- return ((n = (e = i.config) == null ? void 0 : e.ui) == null ? void 0 : n.showHeader) ?? !0;
144
+ var e, t;
145
+ return ((t = (e = i.config) == null ? void 0 : e.ui) == null ? void 0 : t.showHeader) ?? !0;
136
146
  },
137
147
  /**
138
148
  * Check if a specific feature is enabled.
@@ -141,8 +151,8 @@ const g = a("guido-config", {
141
151
  */
142
152
  // eslint-disable-next-line @stylistic/max-len
143
153
  isFeatureEnabled: (i) => (e) => {
144
- var n, t;
145
- return ((t = (n = i.config) == null ? void 0 : n.features) == null ? void 0 : t[e]) ?? !1;
154
+ var t, n;
155
+ return ((n = (t = i.config) == null ? void 0 : t.features) == null ? void 0 : n[e]) ?? !1;
146
156
  }
147
157
  },
148
158
  actions: {
@@ -150,7 +160,7 @@ const g = a("guido-config", {
150
160
  * Initialize the config store with validated configuration
151
161
  */
152
162
  init(i) {
153
- const e = r(i);
163
+ const e = o(i);
154
164
  this.config = e, this.initialized = !0;
155
165
  },
156
166
  /**
@@ -162,5 +172,5 @@ const g = a("guido-config", {
162
172
  }
163
173
  });
164
174
  export {
165
- g as useConfigStore
175
+ u as useConfigStore
166
176
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.17.0-beta.e39d9c6",
3
+ "version": "3.17.0-beta.ea65303",
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",