@useinsider/guido 3.19.0-beta.892c3ca → 3.19.0-beta.9fe04f1

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 (78) hide show
  1. package/README.md +0 -1
  2. package/dist/@types/config/schemas.js +118 -107
  3. package/dist/components/Guido.vue.js +9 -9
  4. package/dist/components/Guido.vue2.js +77 -69
  5. package/dist/components/organisms/AutoSaveController.vue2.js +8 -9
  6. package/dist/components/organisms/base/AuthErrorModal.vue.js +18 -0
  7. package/dist/components/organisms/base/AuthErrorModal.vue2.js +42 -0
  8. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  9. package/dist/components/organisms/header/EditorActions.vue2.js +55 -90
  10. package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
  11. package/dist/components/organisms/header/LeftSlot.vue2.js +12 -16
  12. package/dist/components/wrappers/WpDrawer.vue.js +7 -9
  13. package/dist/components/wrappers/WpDrawer.vue2.js +1 -1
  14. package/dist/components/wrappers/WpModal.vue.js +1 -1
  15. package/dist/components/wrappers/WpModal.vue2.js +4 -3
  16. package/dist/composables/useAuthError.js +52 -0
  17. package/dist/composables/useCortexBlueprintBridge.js +122 -54
  18. package/dist/composables/useEmailTemplateApplier.js +106 -50
  19. package/dist/composables/useHtmlCompiler.js +26 -37
  20. package/dist/composables/useHtmlValidator.js +0 -2
  21. package/dist/composables/useHttp.js +64 -54
  22. package/dist/composables/useLegacyStrategyConversion.js +23 -19
  23. package/dist/composables/useSave.js +45 -90
  24. package/dist/composables/useStripo.js +24 -20
  25. package/dist/composables/useToaster.js +17 -15
  26. package/dist/composables/validators/useCouponBlockValidator.js +21 -24
  27. package/dist/composables/validators/useLiquidValidator.js +15 -15
  28. package/dist/composables/validators/useUnsubscribeBlockValidator.js +27 -34
  29. package/dist/config/migrator/index.js +14 -13
  30. package/dist/config/migrator/recommendationPartnerMigrator.js +50 -0
  31. package/dist/enums/extensions/recommendationBlock.js +30 -29
  32. package/dist/extensions/Blocks/Recommendation/block.js +15 -14
  33. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +45 -38
  34. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +72 -49
  35. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +30 -29
  36. package/dist/extensions/Blocks/Recommendation/utils/partnerScope.js +25 -0
  37. package/dist/guido.css +1 -1
  38. package/dist/src/@types/config/schemas.d.ts +16 -4
  39. package/dist/src/components/Guido.vue.d.ts +1 -17
  40. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -17
  41. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -17
  42. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -17
  43. package/dist/src/components/wrappers/WpDrawer.vue.d.ts +3 -4
  44. package/dist/src/components/wrappers/WpModal.vue.d.ts +5 -1
  45. package/dist/src/composables/useAuthError.d.ts +12 -0
  46. package/dist/src/composables/useConfig.d.ts +2 -2
  47. package/dist/src/composables/useCortexBlueprintBridge.d.ts +2 -3
  48. package/dist/src/composables/useEmailTemplateApplier.d.ts +18 -5
  49. package/dist/src/composables/useHtmlValidator.d.ts +0 -21
  50. package/dist/src/composables/useHttp.d.ts +2 -0
  51. package/dist/src/composables/useSave.d.ts +1 -6
  52. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +0 -3
  53. package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +0 -10
  54. package/dist/src/config/migrator/index.d.ts +2 -1
  55. package/dist/src/config/migrator/recommendationPartnerMigrator.d.ts +19 -0
  56. package/dist/src/enums/extensions/recommendationBlock.d.ts +1 -1
  57. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +6 -0
  58. package/dist/src/extensions/Blocks/Recommendation/utils/partnerScope.d.ts +33 -0
  59. package/dist/src/stores/config.d.ts +20 -32
  60. package/dist/src/stores/guido-email-editor.d.ts +20 -10
  61. package/dist/src/utils/templatePreparation.d.ts +0 -30
  62. package/dist/static/styles/components/recommendation-strategy.css.js +9 -0
  63. package/dist/stores/config.js +67 -84
  64. package/dist/stores/guido-email-editor.js +3 -1
  65. package/dist/utils/templatePreparation.js +36 -39
  66. package/package.json +1 -1
  67. package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +0 -20
  68. package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +0 -49
  69. package/dist/composables/useSaveValidation.js +0 -282
  70. package/dist/composables/useSaveValidationRollout.js +0 -9
  71. package/dist/enums/save-validation.js +0 -4
  72. package/dist/src/@types/save-validation.d.ts +0 -19
  73. package/dist/src/composables/useSaveValidation.d.ts +0 -6
  74. package/dist/src/composables/useSaveValidationRollout.d.ts +0 -3
  75. package/dist/src/enums/save-validation.d.ts +0 -27
  76. package/dist/src/stores/save-validation.d.ts +0 -22
  77. package/dist/stores/save-validation.js +0 -30
  78. /package/dist/src/components/organisms/{validation/ValidationErrorDrawer.vue.d.ts → base/AuthErrorModal.vue.d.ts} +0 -0
@@ -3,6 +3,7 @@ type __VLS_Props = {
3
3
  id: string;
4
4
  title: string;
5
5
  description?: string;
6
+ state?: 'default' | 'primary' | 'warning' | 'danger';
6
7
  size?: 'X-small' | 'small' | 'medium' | 'large';
7
8
  footerButtonOptions?: FooterButtonGroup;
8
9
  closeButtonStatus?: boolean;
@@ -15,6 +16,7 @@ type __VLS_Slots = {} & {
15
16
  };
16
17
  declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
17
18
  description: string;
19
+ state: string;
18
20
  size: string;
19
21
  footerButtonOptions: undefined;
20
22
  closeButtonStatus: boolean;
@@ -26,6 +28,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<
26
28
  "secondary-action": () => void;
27
29
  }, string, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
28
30
  description: string;
31
+ state: string;
29
32
  size: string;
30
33
  footerButtonOptions: undefined;
31
34
  closeButtonStatus: boolean;
@@ -34,9 +37,10 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<
34
37
  }>>>, {
35
38
  size: "X-small" | "small" | "medium" | "large";
36
39
  description: string;
37
- closeOnOutsideClick: boolean;
40
+ state: "default" | "primary" | "warning" | "danger";
38
41
  footerButtonOptions: FooterButtonGroup;
39
42
  closeButtonStatus: boolean;
43
+ closeOnOutsideClick: boolean;
40
44
  footerStatus: boolean;
41
45
  }>;
42
46
  declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
@@ -0,0 +1,12 @@
1
+ export interface AuthErrorState {
2
+ status: number;
3
+ data: Record<string, unknown> | null;
4
+ }
5
+ export declare const isPanelOrigin: (url: string) => boolean;
6
+ export declare const reportAuthError: (status: number, body: string, url: string) => void;
7
+ export declare const useAuthError: () => {
8
+ authError: import("vue").Ref<{
9
+ status: number;
10
+ data: Record<string, unknown> | null;
11
+ } | null>;
12
+ };
@@ -43,6 +43,7 @@ export declare const useConfig: () => {
43
43
  selectedUnsubscribePages: number[];
44
44
  forceRecreate: boolean;
45
45
  trackIdCounter: number;
46
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
46
47
  migration: {
47
48
  recommendationConfigs: {
48
49
  [x: string]: {
@@ -101,7 +102,6 @@ export declare const useConfig: () => {
101
102
  autosave: boolean;
102
103
  allowlistEnabled: boolean;
103
104
  linkTrackingIds: boolean;
104
- allowSaveWithErrors: boolean;
105
105
  reusableRecommendationStrategy: boolean;
106
106
  };
107
107
  blocks: {
@@ -181,6 +181,7 @@ export declare const useConfig: () => {
181
181
  selectedUnsubscribePages: number[];
182
182
  forceRecreate: boolean;
183
183
  trackIdCounter: number;
184
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
184
185
  migration: {
185
186
  recommendationConfigs: {
186
187
  [x: string]: {
@@ -239,7 +240,6 @@ export declare const useConfig: () => {
239
240
  autosave: boolean;
240
241
  allowlistEnabled: boolean;
241
242
  linkTrackingIds: boolean;
242
- allowSaveWithErrors: boolean;
243
243
  reusableRecommendationStrategy: boolean;
244
244
  } | null>;
245
245
  blocks: import("vue").ComputedRef<{
@@ -17,12 +17,11 @@
17
17
  * - `error` segments (and message-level `isError` / `isCancelled`) trigger
18
18
  * a localized toaster.
19
19
  *
20
+ * Every apply settles into a terminal `applyAcks` entry, so cortex moves its button on the write, not the click.
21
+ *
20
22
  * In dev (`import.meta.env.DEV`) every observed segment + message-level flag
21
23
  * change is also `console.debug`-logged with the prefix `[guido:cortex]` so a
22
24
  * developer can watch the agent stream in real time. In production this is
23
25
  * gated behind `localStorage.guido:debug:ai === '1'`.
24
- *
25
- * If cortex-fe isn't loaded the chat store is undefined and the bridge is a
26
- * no-op (intentional — Guido must still work standalone).
27
26
  */
28
27
  export declare const useCortexBlueprintBridge: () => void;
@@ -1,4 +1,16 @@
1
1
  type ApplyStatus = 'pending' | 'applying' | 'applied' | 'failed';
2
+ /**
3
+ * Terminal outcome of an apply; every promise here settles with one, since the bridge acks on it.
4
+ * `superseded`: a newer payload for the same key replaced this one and owns the ack.
5
+ */
6
+ export type ApplyOutcome = {
7
+ status: 'applied';
8
+ } | {
9
+ status: 'failed';
10
+ error: unknown;
11
+ } | {
12
+ status: 'superseded';
13
+ };
2
14
  /**
3
15
  * Applies email_template blueprints from the chat agent to the Stripo editor.
4
16
  *
@@ -9,18 +21,19 @@ type ApplyStatus = 'pending' | 'applying' | 'applied' | 'failed';
9
21
  * - manual Apply click (first apply): immediate.
10
22
  * - blueprint_update after the user has applied once: debounced 250 ms trailing
11
23
  * so rapid mid-stream updates don't thrash updateHtmlAndCss.
24
+ * - a click before Stripo is ready is queued and flushed when `isStripoInitialized` flips.
12
25
  */
13
26
  export declare const useEmailTemplateApplier: () => {
14
27
  applyStatus: import("vue").Ref<Record<string, ApplyStatus>>;
15
- markPending: (blueprintId: string) => void;
16
- applyTemplate: (blueprintId: string, data: {
28
+ markPending: (key: string) => void;
29
+ applyTemplate: (key: string, data: {
17
30
  html?: string;
18
31
  css?: string;
19
- }) => void;
20
- applyTemplateDebounced: (blueprintId: string, data: {
32
+ }) => Promise<ApplyOutcome>;
33
+ applyTemplateDebounced: (key: string, data: {
21
34
  html?: string;
22
35
  css?: string;
23
- }) => void;
36
+ }) => Promise<ApplyOutcome>;
24
37
  };
25
38
  export declare const resetEmailTemplateApplier: () => void;
26
39
  export {};
@@ -1,12 +1,5 @@
1
1
  import type { DynamicContent } from '@@/Types/generic';
2
2
  import type { FiltersResponse } from '@@/Types/recommendation';
3
- /**
4
- * Extracts recommendation block IDs directly from the HTML by parsing
5
- * the recommendation-id attribute on block elements.
6
- * This avoids depending on store state which may not be populated
7
- * when the settings panel hasn't been opened yet (e.g., saved templates).
8
- */
9
- export declare function getRecommendationBlockIds(html: string): string[];
10
3
  /**
11
4
  * Parses a `{{recoId_index_attributeName}}` variable (already stripped of the
12
5
  * braces/whitespace) into its recommendation id and attribute name. Returns
@@ -34,20 +27,6 @@ export declare function buildPartnerAttributeNameSet(filterList: FiltersResponse
34
27
  * before, so flagging it would false-positive on merge tags like `{{user.name}}`.
35
28
  */
36
29
  export declare function findInvalidCustomFields(html: string, validCustomFields: string[], recommendationBlockIds: string[], ignoredIds: Set<string>, ignoredAttributeNames: Set<string> | null): string[];
37
- /**
38
- * Returns the invalid `{{ ... }}` dynamic-content tags found in the HTML.
39
- *
40
- * A tag's variable name is the part before the first `|` (everything after it is the fallback).
41
- * Surrounding whitespace is always allowed (trimmed). A tag is valid only when the variable name
42
- * is an allowed system token, or it is a clean identifier (`[A-Za-z0-9_.]`) and — when a `|` is
43
- * present — the fallback after it is not empty. Otherwise the tag is invalid (e.g.
44
- * `{{Api Response: OA1 Main Item Url}}` — spaces/`:` — or `{{bounce|}}` — empty fallback).
45
- *
46
- * `data-*` block-config attribute values are excluded from the scan: blocks such as Items/cart
47
- * store product merge tags (`data-product_button_link="{{Abandoned Cart Item (1) Url}}"`) that the
48
- * backend resolves through its own pipeline, so they must not be treated as user-authored tags.
49
- */
50
- export declare function getInvalidDynamicContentTags(html: string): string[];
51
30
  export declare const useHtmlValidator: () => {
52
31
  validateHtml: (html: string, customFields: DynamicContent[], isOnSaveValidation?: boolean) => Promise<boolean>;
53
32
  };
@@ -16,6 +16,7 @@ export interface HttpError {
16
16
  status?: number;
17
17
  statusText?: string;
18
18
  response?: Response;
19
+ authReported?: boolean;
19
20
  }
20
21
  export declare const useHttp: (defaultOptions?: HttpOptions) => {
21
22
  loading: import("vue").ComputedRef<boolean>;
@@ -65,6 +66,7 @@ export declare const useHttp: (defaultOptions?: HttpOptions) => {
65
66
  json: () => Promise<any>;
66
67
  text: () => Promise<string>;
67
68
  } | undefined;
69
+ authReported?: boolean | undefined;
68
70
  } | null>;
69
71
  hasError: import("vue").ComputedRef<boolean>;
70
72
  request: <T = unknown>(method: HttpMethod, url: string, data?: unknown, options?: HttpOptions) => Promise<HttpResponse<T>>;
@@ -1,9 +1,4 @@
1
1
  import type { SavedTemplateDetails } from '@@/Types/stripo';
2
- type SaveDetails = Omit<SavedTemplateDetails, 'metadata' | 'silent'>;
3
- type SaveResult = SaveDetails | undefined;
4
2
  export declare const useSave: () => {
5
- save: (suppressEmit?: boolean, silent?: boolean) => Promise<SaveResult>;
6
- saveWithErrors: () => Promise<SaveResult>;
7
- saveRawOnly: () => Promise<SaveResult>;
3
+ save: (suppressEmit?: boolean, silent?: boolean) => Promise<Omit<SavedTemplateDetails, "metadata" | "silent"> | undefined>;
8
4
  };
9
- export {};
@@ -1,6 +1,3 @@
1
- export declare const COUPON_TAG_MODIFIED_KEY = "newsletter.coupon-tag-modified";
2
- /** Pure core: the tag text of every coupon block whose code was modified. */
3
- export declare function findInvalidCouponBlocks(html: string): string[];
4
1
  export declare const useCouponBlockValidator: () => {
5
2
  validateCouponBlockTags: (html: string) => boolean;
6
3
  };
@@ -1,14 +1,4 @@
1
- declare const SINGLETON_BLOCK_RULES: {
2
- pageType: number;
3
- messageKey: string;
4
- }[];
5
- export declare const EMPTY_BLOCK_KEY = "unsubscription-preference.select-page-to-continue";
6
- /** Pure core: the singleton rules whose page type appears more than once. */
7
- export declare function findDuplicateUnsubPageTypes(html: string): typeof SINGLETON_BLOCK_RULES;
8
- /** Pure core: count of unsubscribe blocks with no page type or page list chosen. */
9
- export declare function countUnsubBlocksWithoutPage(html: string): number;
10
1
  export declare const useUnsubscribeBlockValidator: () => {
11
2
  validateUnsubscribeBlockUniqueness: (html: string) => boolean;
12
3
  validateUnsubscribeBlockHasTemplate: (html: string) => boolean;
13
4
  };
14
- export {};
@@ -1,2 +1,3 @@
1
1
  import type { LegacyRecommendationConfig } from '@@/Types/config';
2
- export declare const migrate: (html: string, recommendationConfigs?: Record<string, LegacyRecommendationConfig>) => Promise<string>;
2
+ import { type PartnerScopeMigrationOptions } from './recommendationPartnerMigrator';
3
+ export declare const migrate: (html: string, recommendationConfigs?: Record<string, LegacyRecommendationConfig>, partnerScope?: PartnerScopeMigrationOptions) => Promise<string>;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Empties recommendation blocks copied in from another account and stamps the
3
+ * current one, before the editor ever sees the template (SD-151945).
4
+ *
5
+ * Runs at load rather than on document change: the stamp makes it a one-time
6
+ * pass per template, the campaign-URL rule only ever applies to the loaded HTML,
7
+ * and Stripo takes the result as the original document, so nothing is dirtied.
8
+ */
9
+ export interface PartnerScopeMigrationOptions {
10
+ partnerName: string;
11
+ /** `undefined` when the host does not pass the map — the unstamped check is then off. */
12
+ campaignUrls?: Record<string, unknown>;
13
+ rrsEnabled: boolean;
14
+ }
15
+ /**
16
+ * @param html Template HTML, already normalized by `migrateRecommendation`.
17
+ * @returns Migrated HTML, or the original when no block needed a reset or a stamp.
18
+ */
19
+ export declare function migrateRecommendationPartnerScope(html: string, { partnerName, campaignUrls, rrsEnabled }: PartnerScopeMigrationOptions): string;
@@ -8,8 +8,8 @@ export declare const URLS: {
8
8
  NEWSLETTER_RECOMMENDATIONS_PATH: string;
9
9
  MIGRATE_STRATEGIES_PATH: string;
10
10
  TEMPLATE_MIGRATE_STRATEGIES_PATH: string;
11
- RECOMMENDATION_STRATEGY_CREATE_PATH: string;
12
11
  };
12
+ export declare const strategyCreatePath: () => string;
13
13
  export declare const strategyEditPath: (strategyId: string | number) => string;
14
14
  export declare const MIGRATION_PATHS: Record<RrsMigrationTarget['scope'], string>;
15
15
  export declare const QUERY_PARAMS: {
@@ -83,6 +83,12 @@ export interface RecommendationNodeConfig {
83
83
  */
84
84
  filters: Filter[];
85
85
  strategyId: string;
86
+ /**
87
+ * Account (`config.partner.name`) that last wrote the strategy config. Strategy ids and
88
+ * attribute types are account-scoped, so a block opened under another account is reset.
89
+ * Absent on blocks saved before SD-151945.
90
+ */
91
+ partnerName?: string;
86
92
  /**
87
93
  * Layout orientation
88
94
  * - 'grid': Products in a grid, attributes aligned across products
@@ -0,0 +1,33 @@
1
+ import type { RecommendationNodeConfig } from '../types/nodeConfig';
2
+ /**
3
+ * Mirrors the backend's `RecommendationCampaignUrls::isDefined`: a legacy feed URL
4
+ * string or an entry that names a strategy.
5
+ */
6
+ export declare function isDefinedCampaignUrl(value: unknown): boolean;
7
+ export interface PartnerScopeInputs {
8
+ config: Pick<RecommendationNodeConfig, 'strategyId' | 'partnerName'>;
9
+ blockId: number;
10
+ partnerName: string;
11
+ /** `undefined` when the host does not pass the map — the unstamped check is then off. */
12
+ campaignUrls: Record<string, unknown> | undefined;
13
+ /** With RRS off `buildCampaignUrl` drops the block's map entry, so the map says nothing. */
14
+ rrsEnabled: boolean;
15
+ }
16
+ /**
17
+ * Whether a block carries another account's strategy config (SD-151945).
18
+ *
19
+ * A stamped block is judged by its stamp. An unstamped one predates the stamp, so it
20
+ * falls back to the backend's own signal: a cross-account duplicate drops the block's
21
+ * strategy entry from the campaign URL map but leaves the HTML untouched. That signal
22
+ * only holds while RRS is on, and only for the HTML the host loaded — which is what
23
+ * the caller, a load-time migrator, runs on.
24
+ */
25
+ export declare function carriesForeignPartnerConfig({ config, blockId, partnerName, campaignUrls, rrsEnabled }: PartnerScopeInputs): boolean;
26
+ /**
27
+ * Whether an unstamped block's ownership can be decided at all. `carriesForeignPartnerConfig`
28
+ * answers `false` both for "clean" and for "cannot tell", and stamping on the latter would
29
+ * record a foreign block as this account's and silence every later check. A block with no
30
+ * strategy reference has nothing foreign to carry, so it is always decidable.
31
+ */
32
+ export declare function canJudgeUnstampedBlock({ config, campaignUrls, rrsEnabled }: Pick<PartnerScopeInputs, 'config' | 'campaignUrls' | 'rrsEnabled'>): boolean;
33
+ export declare function withoutCustomAttributes(composition: string[]): string[];
@@ -48,6 +48,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
48
48
  selectedUnsubscribePages: number[];
49
49
  forceRecreate: boolean;
50
50
  trackIdCounter: number;
51
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
51
52
  migration: {
52
53
  recommendationConfigs: {
53
54
  [x: string]: {
@@ -106,7 +107,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
106
107
  autosave: boolean;
107
108
  allowlistEnabled: boolean;
108
109
  linkTrackingIds: boolean;
109
- allowSaveWithErrors: boolean;
110
110
  reusableRecommendationStrategy: boolean;
111
111
  };
112
112
  blocks: {
@@ -192,6 +192,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
192
192
  selectedUnsubscribePages: number[];
193
193
  forceRecreate: boolean;
194
194
  trackIdCounter: number;
195
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
195
196
  migration: {
196
197
  recommendationConfigs: {
197
198
  [x: string]: {
@@ -250,7 +251,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
250
251
  autosave: boolean;
251
252
  allowlistEnabled: boolean;
252
253
  linkTrackingIds: boolean;
253
- allowSaveWithErrors: boolean;
254
254
  reusableRecommendationStrategy: boolean;
255
255
  };
256
256
  blocks: {
@@ -336,6 +336,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
336
336
  selectedUnsubscribePages: number[];
337
337
  forceRecreate: boolean;
338
338
  trackIdCounter: number;
339
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
339
340
  migration: {
340
341
  recommendationConfigs: {
341
342
  [x: string]: {
@@ -394,7 +395,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
394
395
  autosave: boolean;
395
396
  allowlistEnabled: boolean;
396
397
  linkTrackingIds: boolean;
397
- allowSaveWithErrors: boolean;
398
398
  reusableRecommendationStrategy: boolean;
399
399
  };
400
400
  blocks: {
@@ -480,6 +480,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
480
480
  selectedUnsubscribePages: number[];
481
481
  forceRecreate: boolean;
482
482
  trackIdCounter: number;
483
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
483
484
  migration: {
484
485
  recommendationConfigs: {
485
486
  [x: string]: {
@@ -538,7 +539,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
538
539
  autosave: boolean;
539
540
  allowlistEnabled: boolean;
540
541
  linkTrackingIds: boolean;
541
- allowSaveWithErrors: boolean;
542
542
  reusableRecommendationStrategy: boolean;
543
543
  };
544
544
  blocks: {
@@ -624,6 +624,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
624
624
  selectedUnsubscribePages: number[];
625
625
  forceRecreate: boolean;
626
626
  trackIdCounter: number;
627
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
627
628
  migration: {
628
629
  recommendationConfigs: {
629
630
  [x: string]: {
@@ -682,7 +683,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
682
683
  autosave: boolean;
683
684
  allowlistEnabled: boolean;
684
685
  linkTrackingIds: boolean;
685
- allowSaveWithErrors: boolean;
686
686
  reusableRecommendationStrategy: boolean;
687
687
  };
688
688
  blocks: {
@@ -768,6 +768,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
768
768
  selectedUnsubscribePages: number[];
769
769
  forceRecreate: boolean;
770
770
  trackIdCounter: number;
771
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
771
772
  migration: {
772
773
  recommendationConfigs: {
773
774
  [x: string]: {
@@ -826,7 +827,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
826
827
  autosave: boolean;
827
828
  allowlistEnabled: boolean;
828
829
  linkTrackingIds: boolean;
829
- allowSaveWithErrors: boolean;
830
830
  reusableRecommendationStrategy: boolean;
831
831
  };
832
832
  blocks: {
@@ -912,6 +912,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
912
912
  selectedUnsubscribePages: number[];
913
913
  forceRecreate: boolean;
914
914
  trackIdCounter: number;
915
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
915
916
  migration: {
916
917
  recommendationConfigs: {
917
918
  [x: string]: {
@@ -970,7 +971,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
970
971
  autosave: boolean;
971
972
  allowlistEnabled: boolean;
972
973
  linkTrackingIds: boolean;
973
- allowSaveWithErrors: boolean;
974
974
  reusableRecommendationStrategy: boolean;
975
975
  };
976
976
  blocks: {
@@ -1056,6 +1056,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1056
1056
  selectedUnsubscribePages: number[];
1057
1057
  forceRecreate: boolean;
1058
1058
  trackIdCounter: number;
1059
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
1059
1060
  migration: {
1060
1061
  recommendationConfigs: {
1061
1062
  [x: string]: {
@@ -1114,7 +1115,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1114
1115
  autosave: boolean;
1115
1116
  allowlistEnabled: boolean;
1116
1117
  linkTrackingIds: boolean;
1117
- allowSaveWithErrors: boolean;
1118
1118
  reusableRecommendationStrategy: boolean;
1119
1119
  };
1120
1120
  blocks: {
@@ -1200,6 +1200,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1200
1200
  selectedUnsubscribePages: number[];
1201
1201
  forceRecreate: boolean;
1202
1202
  trackIdCounter: number;
1203
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
1203
1204
  migration: {
1204
1205
  recommendationConfigs: {
1205
1206
  [x: string]: {
@@ -1258,7 +1259,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1258
1259
  autosave: boolean;
1259
1260
  allowlistEnabled: boolean;
1260
1261
  linkTrackingIds: boolean;
1261
- allowSaveWithErrors: boolean;
1262
1262
  reusableRecommendationStrategy: boolean;
1263
1263
  };
1264
1264
  blocks: {
@@ -1344,6 +1344,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1344
1344
  selectedUnsubscribePages: number[];
1345
1345
  forceRecreate: boolean;
1346
1346
  trackIdCounter: number;
1347
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
1347
1348
  migration: {
1348
1349
  recommendationConfigs: {
1349
1350
  [x: string]: {
@@ -1402,7 +1403,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1402
1403
  autosave: boolean;
1403
1404
  allowlistEnabled: boolean;
1404
1405
  linkTrackingIds: boolean;
1405
- allowSaveWithErrors: boolean;
1406
1406
  reusableRecommendationStrategy: boolean;
1407
1407
  };
1408
1408
  blocks: {
@@ -1488,6 +1488,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1488
1488
  selectedUnsubscribePages: number[];
1489
1489
  forceRecreate: boolean;
1490
1490
  trackIdCounter: number;
1491
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
1491
1492
  migration: {
1492
1493
  recommendationConfigs: {
1493
1494
  [x: string]: {
@@ -1546,7 +1547,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1546
1547
  autosave: boolean;
1547
1548
  allowlistEnabled: boolean;
1548
1549
  linkTrackingIds: boolean;
1549
- allowSaveWithErrors: boolean;
1550
1550
  reusableRecommendationStrategy: boolean;
1551
1551
  };
1552
1552
  blocks: {
@@ -1632,6 +1632,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1632
1632
  selectedUnsubscribePages: number[];
1633
1633
  forceRecreate: boolean;
1634
1634
  trackIdCounter: number;
1635
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
1635
1636
  migration: {
1636
1637
  recommendationConfigs: {
1637
1638
  [x: string]: {
@@ -1690,7 +1691,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1690
1691
  autosave: boolean;
1691
1692
  allowlistEnabled: boolean;
1692
1693
  linkTrackingIds: boolean;
1693
- allowSaveWithErrors: boolean;
1694
1694
  reusableRecommendationStrategy: boolean;
1695
1695
  };
1696
1696
  blocks: {
@@ -1776,6 +1776,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1776
1776
  selectedUnsubscribePages: number[];
1777
1777
  forceRecreate: boolean;
1778
1778
  trackIdCounter: number;
1779
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
1779
1780
  migration: {
1780
1781
  recommendationConfigs: {
1781
1782
  [x: string]: {
@@ -1834,7 +1835,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1834
1835
  autosave: boolean;
1835
1836
  allowlistEnabled: boolean;
1836
1837
  linkTrackingIds: boolean;
1837
- allowSaveWithErrors: boolean;
1838
1838
  reusableRecommendationStrategy: boolean;
1839
1839
  };
1840
1840
  blocks: {
@@ -1920,6 +1920,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1920
1920
  selectedUnsubscribePages: number[];
1921
1921
  forceRecreate: boolean;
1922
1922
  trackIdCounter: number;
1923
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
1923
1924
  migration: {
1924
1925
  recommendationConfigs: {
1925
1926
  [x: string]: {
@@ -1978,7 +1979,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1978
1979
  autosave: boolean;
1979
1980
  allowlistEnabled: boolean;
1980
1981
  linkTrackingIds: boolean;
1981
- allowSaveWithErrors: boolean;
1982
1982
  reusableRecommendationStrategy: boolean;
1983
1983
  };
1984
1984
  blocks: {
@@ -2064,6 +2064,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2064
2064
  selectedUnsubscribePages: number[];
2065
2065
  forceRecreate: boolean;
2066
2066
  trackIdCounter: number;
2067
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
2067
2068
  migration: {
2068
2069
  recommendationConfigs: {
2069
2070
  [x: string]: {
@@ -2122,7 +2123,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2122
2123
  autosave: boolean;
2123
2124
  allowlistEnabled: boolean;
2124
2125
  linkTrackingIds: boolean;
2125
- allowSaveWithErrors: boolean;
2126
2126
  reusableRecommendationStrategy: boolean;
2127
2127
  };
2128
2128
  blocks: {
@@ -2208,6 +2208,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2208
2208
  selectedUnsubscribePages: number[];
2209
2209
  forceRecreate: boolean;
2210
2210
  trackIdCounter: number;
2211
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
2211
2212
  migration: {
2212
2213
  recommendationConfigs: {
2213
2214
  [x: string]: {
@@ -2266,7 +2267,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2266
2267
  autosave: boolean;
2267
2268
  allowlistEnabled: boolean;
2268
2269
  linkTrackingIds: boolean;
2269
- allowSaveWithErrors: boolean;
2270
2270
  reusableRecommendationStrategy: boolean;
2271
2271
  };
2272
2272
  blocks: {
@@ -2352,6 +2352,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2352
2352
  selectedUnsubscribePages: number[];
2353
2353
  forceRecreate: boolean;
2354
2354
  trackIdCounter: number;
2355
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
2355
2356
  migration: {
2356
2357
  recommendationConfigs: {
2357
2358
  [x: string]: {
@@ -2410,7 +2411,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2410
2411
  autosave: boolean;
2411
2412
  allowlistEnabled: boolean;
2412
2413
  linkTrackingIds: boolean;
2413
- allowSaveWithErrors: boolean;
2414
2414
  reusableRecommendationStrategy: boolean;
2415
2415
  };
2416
2416
  blocks: {
@@ -2454,18 +2454,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2454
2454
  };
2455
2455
  } | null;
2456
2456
  } & import("pinia").PiniaCustomStateProperties<ConfigStoreState>) => number;
2457
- /**
2458
- * Transactional campaigns keep the hard save block. Reactive getter, so
2459
- * consumers stay safe in setup where a raw config read snapshots null (SD-147945).
2460
- */
2461
- isTransactional(): boolean;
2462
- /**
2463
- * Soft-save policy: may the editor persist a template with validation errors?
2464
- * Default true (host sets features.allowSaveWithErrors=false for transactional +
2465
- * unsub). Reactive getter defaulting true — reading via isFeatureEnabled would
2466
- * floor to false pre-init and momentarily hide the soft-save option (SD-147430).
2467
- */
2468
- allowSaveWithErrors(): boolean;
2469
2457
  /**
2470
2458
  * Get the username
2471
2459
  */
@@ -2508,6 +2496,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2508
2496
  selectedUnsubscribePages: number[];
2509
2497
  forceRecreate: boolean;
2510
2498
  trackIdCounter: number;
2499
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
2511
2500
  migration: {
2512
2501
  recommendationConfigs: {
2513
2502
  [x: string]: {
@@ -2566,7 +2555,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2566
2555
  autosave: boolean;
2567
2556
  allowlistEnabled: boolean;
2568
2557
  linkTrackingIds: boolean;
2569
- allowSaveWithErrors: boolean;
2570
2558
  reusableRecommendationStrategy: boolean;
2571
2559
  };
2572
2560
  blocks: {
@@ -2652,6 +2640,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2652
2640
  selectedUnsubscribePages: number[];
2653
2641
  forceRecreate: boolean;
2654
2642
  trackIdCounter: number;
2643
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
2655
2644
  migration: {
2656
2645
  recommendationConfigs: {
2657
2646
  [x: string]: {
@@ -2710,7 +2699,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2710
2699
  autosave: boolean;
2711
2700
  allowlistEnabled: boolean;
2712
2701
  linkTrackingIds: boolean;
2713
- allowSaveWithErrors: boolean;
2714
2702
  reusableRecommendationStrategy: boolean;
2715
2703
  };
2716
2704
  blocks: {
@@ -2798,6 +2786,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2798
2786
  selectedUnsubscribePages: number[];
2799
2787
  forceRecreate: boolean;
2800
2788
  trackIdCounter: number;
2789
+ recommendationCampaignUrls?: Record<string, unknown> | undefined;
2801
2790
  migration: {
2802
2791
  recommendationConfigs: {
2803
2792
  [x: string]: {
@@ -2856,7 +2845,6 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2856
2845
  autosave: boolean;
2857
2846
  allowlistEnabled: boolean;
2858
2847
  linkTrackingIds: boolean;
2859
- allowSaveWithErrors: boolean;
2860
2848
  reusableRecommendationStrategy: boolean;
2861
2849
  };
2862
2850
  blocks: {