@useinsider/guido 3.1.1-beta.6b60896 → 3.1.1-beta.7145c7d

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 (68) hide show
  1. package/README.md +1 -0
  2. package/dist/@types/config/schemas.js +69 -61
  3. package/dist/components/Guido.vue.js +4 -4
  4. package/dist/components/Guido.vue2.js +91 -81
  5. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue.js +7 -7
  6. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue2.js +12 -20
  7. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  8. package/dist/components/organisms/header/EditorActions.vue2.js +51 -36
  9. package/dist/components/organisms/header/RightSlot.vue.js +10 -10
  10. package/dist/components/organisms/header/RightSlot.vue2.js +16 -13
  11. package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +18 -17
  12. package/dist/composables/useHtmlCompiler.js +23 -21
  13. package/dist/composables/usePreviewMode.js +20 -16
  14. package/dist/composables/useSave.js +23 -15
  15. package/dist/composables/useStripo.js +44 -41
  16. package/dist/composables/validators/useLiquidValidator.js +42 -0
  17. package/dist/config/compiler/liquidCompilerRules.js +15 -0
  18. package/dist/config/compiler/recommendationCompilerRules.js +158 -44
  19. package/dist/config/compiler/utils/recommendationCompilerUtils.js +37 -36
  20. package/dist/config/migrator/checkboxMigrator.js +5 -3
  21. package/dist/config/migrator/radioButtonMigrator.js +14 -12
  22. package/dist/enums/extensions/recommendationBlock.js +14 -11
  23. package/dist/extensions/Blocks/CouponBlock/template.js +24 -13
  24. package/dist/extensions/Blocks/Recommendation/block.js +1 -1
  25. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +27 -11
  26. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +185 -172
  27. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +95 -93
  28. package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +75 -73
  29. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +7 -5
  30. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +30 -29
  31. package/dist/extensions/Blocks/Recommendation/templates/index.js +7 -7
  32. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +3 -1
  33. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +20 -20
  34. package/dist/extensions/Blocks/Recommendation/templates/utils.js +57 -50
  35. package/dist/extensions/Blocks/Recommendation/utils/tagName.js +6 -6
  36. package/dist/extensions/Blocks/Unsubscribe/settingsPanel.js +16 -17
  37. package/dist/extensions/DynamicContent/dynamic-content.js +17 -12
  38. package/dist/guido.css +1 -1
  39. package/dist/services/recommendationApi.js +15 -15
  40. package/dist/services/templateLibraryApi.js +48 -46
  41. package/dist/src/@types/config/index.d.ts +1 -1
  42. package/dist/src/@types/config/schemas.d.ts +20 -0
  43. package/dist/src/@types/config/types.d.ts +3 -1
  44. package/dist/src/@types/generic.d.ts +0 -1
  45. package/dist/src/@types/save-as-template.d.ts +1 -0
  46. package/dist/src/composables/useConfig.d.ts +8 -0
  47. package/dist/src/composables/validators/useLiquidValidator.d.ts +3 -0
  48. package/dist/src/config/compiler/liquidCompilerRules.d.ts +2 -0
  49. package/dist/src/enums/extensions/recommendationBlock.d.ts +3 -0
  50. package/dist/src/extensions/Blocks/CouponBlock/template.d.ts +2 -0
  51. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  52. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +5 -0
  53. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +5 -0
  54. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  55. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -3
  56. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +20 -3
  57. package/dist/src/services/templateLibraryApi.d.ts +1 -1
  58. package/dist/src/stores/config.d.ts +72 -0
  59. package/dist/src/stores/preview.d.ts +3 -0
  60. package/dist/src/utils/genericUtil.d.ts +1 -1
  61. package/dist/src/utils/htmlCompiler.d.ts +2 -1
  62. package/dist/static/styles/base.css.js +7 -2
  63. package/dist/stores/preview.js +4 -3
  64. package/dist/utils/genericUtil.js +42 -20
  65. package/dist/utils/htmlCompiler.js +48 -41
  66. package/dist/utils/templatePreparation.js +35 -26
  67. package/dist/utils/tooltipUtils.js +4 -5
  68. package/package.json +3 -2
@@ -3,6 +3,9 @@ import type { RecommendationFeedItem } from '@@/Types/recommendation';
3
3
  export declare const URLS: {
4
4
  RECOMMENDATION_API_URL: string;
5
5
  };
6
+ export declare const QUERY_PARAMS: {
7
+ CLIENT_ID: string;
8
+ };
6
9
  export declare const RecommendationFeedSourceMaps: RecommendationFeedItem[];
7
10
  export declare const PriceAttributes: string[];
8
11
  export declare const currencyLocationMaps: TextValueObject[];
@@ -1,3 +1,5 @@
1
+ export declare const COUPON_PLACEHOLDER_DEFAULT = "{@COUPON_CODE}";
2
+ export declare const COUPON_PLACEHOLDER_LIQUID = "{{ins_coupon_code}}";
1
3
  declare const migrationTemplate = "\n <td\n class=\"coupon-block coupon-block-v2 ins-coupon-code esd-block-text esd-extension-block\"\n esd-extension-block-id=\"coupon-block\"\n >\n <p class=\"ins-title\" contenteditable=\"false\">{@COUPON_CODE}</p>\n </td>\n";
2
4
  export declare function getDefaultTemplate(): string;
3
5
  export default migrationTemplate;
@@ -8,6 +8,6 @@
8
8
  */
9
9
  export { RecommendationBlockId } from './blockIds';
10
10
  export { RecommendationControlId } from './controlIds';
11
- export { BLOCK_ROOT_SELECTOR, CONTAINER_SELECTOR, DESKTOP_CONTAINER_SELECTOR, MOBILE_CONTAINER_SELECTOR, MOBILE_ROW_SELECTOR, CURRENCY_ATTR, ATTR_PRODUCT_IMAGE, ATTR_PRODUCT_NAME, ATTR_PRODUCT_PRICE, ATTR_PRODUCT_OLD_PRICE, ATTR_PRODUCT_OMNIBUS_PRICE, ATTR_PRODUCT_OMNIBUS_DISCOUNT, ATTR_PRODUCT_BUTTON, ATTR_CUSTOM_PREFIX, ATTR_DATA_CUSTOM_ATTRIBUTES, ATTR_PRODUCT_ATTR, } from './selectors';
11
+ export { BLOCK_ROOT_SELECTOR, CONTAINER_SELECTOR, DESKTOP_CONTAINER_SELECTOR, MOBILE_CONTAINER_SELECTOR, MOBILE_ROW_SELECTOR, CURRENCY_ATTR, ATTR_PRODUCT_IMAGE, ATTR_PRODUCT_NAME, ATTR_PRODUCT_PRICE, ATTR_PRODUCT_OLD_PRICE, ATTR_PRODUCT_OMNIBUS_PRICE, ATTR_PRODUCT_OMNIBUS_DISCOUNT, ATTR_PRODUCT_BUTTON, ATTR_CUSTOM_PREFIX, ATTR_DATA_CUSTOM_ATTRIBUTES, ATTR_PRODUCT_ATTR, BUILT_IN_DEFAULT_ATTRIBUTES, } from './selectors';
12
12
  export { LAYOUT_VALUES, LAYOUT_OPTIONS, DEFAULT_PRODUCTS_PER_ROW, DEFAULT_CARDS_IN_ROW, DEFAULT_MOBILE_CARDS_IN_ROW, MAX_PRODUCT_COUNT, MIN_PRODUCT_COUNT, MAX_PRODUCTS_PER_ROW, MIN_PRODUCTS_PER_ROW, MAX_MOBILE_PRODUCTS_PER_ROW, MIN_MOBILE_PRODUCTS_PER_ROW, DEFAULT_COLUMN_SPACING, DEFAULT_ROW_SPACING, DEFAULT_MOBILE_COLUMN_SPACING, DEFAULT_MOBILE_ROW_SPACING, MIN_SPACING, MAX_SPACING, SPACING_STEP, } from './layout';
13
13
  export { DEFAULT_NODE_CONFIG, DEFAULT_CURRENCY, DEFAULT_COMPOSITION, DEFAULT_VISIBILITY, CURRENT_CONFIG_VERSION, EXCLUDED_ALGORITHM_IDS, } from './defaultConfig';
@@ -50,3 +50,8 @@ export declare const ATTR_CUSTOM_PREFIX = "customAttr:";
50
50
  export declare const ATTR_DATA_CUSTOM_ATTRIBUTES = "data-custom-attributes";
51
51
  /** HTML attribute on <td> elements identifying the product attribute for compiler template variable generation */
52
52
  export declare const ATTR_PRODUCT_ATTR = "product-attr";
53
+ /**
54
+ * Default attribute names that are already represented by built-in composition toggle items.
55
+ * Used to exclude these from the custom attribute dropdown to prevent duplication with toggles.
56
+ */
57
+ export declare const BUILT_IN_DEFAULT_ATTRIBUTES: Set<string>;
@@ -170,6 +170,11 @@ export declare class RecommendationCardCompositionControl extends CommonControl
170
170
  * When filterList changes (e.g. after async fetch), re-renders dropdowns with new options.
171
171
  */
172
172
  private _subscribeToStoreChanges;
173
+ /**
174
+ * Returns filters eligible for the custom attribute dropdown,
175
+ * excluding default attributes already covered by built-in toggle items.
176
+ */
177
+ private _getAddableFilters;
173
178
  /**
174
179
  * Looks up the display name for an attribute from the store's filterList.
175
180
  * Falls back to Title Case conversion of the snake_case attribute name.
@@ -1,4 +1,4 @@
1
- import type { RecommendationProduct } from '@@/Types/recommendation';
1
+ import type { FiltersResponse, RecommendationProduct } from '@@/Types/recommendation';
2
2
  import { type ElementRenderer } from '../utils';
3
3
  /**
4
4
  * Generates attribute-aligned product rows for grid layout.
@@ -9,7 +9,7 @@ import { type ElementRenderer } from '../utils';
9
9
  * @param composition - Array defining order of card elements
10
10
  * @returns HTML string for attribute-aligned rows
11
11
  */
12
- export declare function prepareGridAttributeRows(products: RecommendationProduct[], productsPerRow: number, elementRenderer: ElementRenderer, composition?: string[]): string;
12
+ export declare function prepareGridAttributeRows(products: RecommendationProduct[], productsPerRow: number, elementRenderer: ElementRenderer, composition?: string[], filterList?: FiltersResponse): string;
13
13
  /**
14
14
  * Prepares grid product rows with attribute-aligned structure
15
15
  * Groups products into rows, then generates attribute-aligned HTML for each group
@@ -19,7 +19,7 @@ export declare function prepareGridAttributeRows(products: RecommendationProduct
19
19
  * @param composition - Array defining order of card elements
20
20
  * @returns HTML string for all product rows
21
21
  */
22
- export declare function prepareGridProductRows(products: RecommendationProduct[], productsPerRow: number, elementRenderer: ElementRenderer, composition?: string[]): string;
22
+ export declare function prepareGridProductRows(products: RecommendationProduct[], productsPerRow: number, elementRenderer: ElementRenderer, composition?: string[], filterList?: FiltersResponse): string;
23
23
  /**
24
24
  * Prepares grid product rows with attribute-aligned structure.
25
25
  * Uses row-based rendering where each attribute type forms a single row across all products.
@@ -28,6 +28,6 @@ export declare function prepareGridProductRows(products: RecommendationProduct[]
28
28
  * @param composition - Array defining element order
29
29
  * @returns HTML string for product rows
30
30
  */
31
- export declare function prepareProductRows(products: RecommendationProduct[], productsPerRow: number, composition?: string[]): string;
31
+ export declare function prepareProductRows(products: RecommendationProduct[], productsPerRow: number, composition?: string[], filterList?: FiltersResponse): string;
32
32
  export declare function getDefaultTemplate(recommendationId?: number): string;
33
33
  export declare function generateBlockTemplate(products: RecommendationProduct[], productsPerRow: number, title?: string, composition?: string[], mobileProductsPerRow?: number): string;
@@ -1,4 +1,4 @@
1
- import type { RecommendationProduct } from '@@/Types/recommendation';
1
+ import type { FiltersResponse, RecommendationProduct } from '@@/Types/recommendation';
2
2
  /**
3
3
  * Generates a list product card with 3-column layout
4
4
  * Uses buildElementRenderer to render Image, Info content, and Button
@@ -11,7 +11,7 @@ import type { RecommendationProduct } from '@@/Types/recommendation';
11
11
  * @param composition - Array defining order of card elements
12
12
  * @returns HTML string for a single product card row
13
13
  */
14
- export declare function getListProductCard(product: RecommendationProduct, composition?: string[]): string;
14
+ export declare function getListProductCard(product: RecommendationProduct, composition?: string[], filterList?: FiltersResponse): string;
15
15
  /**
16
16
  * Prepares list product rows
17
17
  * Each product is a full-width row with 3-column layout
@@ -19,6 +19,6 @@ export declare function getListProductCard(product: RecommendationProduct, compo
19
19
  * @param composition - Array defining order of card elements
20
20
  * @returns HTML string for product rows
21
21
  */
22
- export declare function prepareProductRows(products: RecommendationProduct[], composition?: string[]): string;
22
+ export declare function prepareProductRows(products: RecommendationProduct[], composition?: string[], filterList?: FiltersResponse): string;
23
23
  export declare function getDefaultTemplate(): string;
24
24
  export declare function generateBlockTemplate(products: RecommendationProduct[], title?: string, composition?: string[]): string;
@@ -1,15 +1,29 @@
1
- import type { RecommendationProduct } from '@@/Types/recommendation';
1
+ import type { FiltersResponse, RecommendationProduct } from '@@/Types/recommendation';
2
2
  import { ATTR_PRODUCT_IMAGE, ATTR_PRODUCT_NAME, ATTR_PRODUCT_PRICE, ATTR_PRODUCT_OLD_PRICE, ATTR_PRODUCT_OMNIBUS_PRICE, ATTR_PRODUCT_OMNIBUS_DISCOUNT, ATTR_PRODUCT_BUTTON } from '../constants';
3
3
  /**
4
4
  * Converts a snake_case attribute name to Title Case display name.
5
5
  * e.g., "rating_star" → "Rating Star"
6
6
  */
7
7
  export declare function toDisplayName(attrName: string): string;
8
+ /**
9
+ * Checks whether an attribute is a default (top-level) product attribute
10
+ * vs a custom product attribute (nested under `product_attributes`).
11
+ * Returns false when filterList is empty or the attribute is not found.
12
+ */
13
+ export declare function isDefaultAttribute(attrName: string, filterList: FiltersResponse): boolean;
14
+ /**
15
+ * Resolves the `product-attr` HTML attribute value based on attribute type from the filter list.
16
+ * - Default attributes → attribute name directly (e.g., "brand") → compiles to `{{1_0_brand}}`
17
+ * - Product attributes → "product_attribute.<name>" (e.g., "product_attribute.rating_star")
18
+ */
19
+ export declare function resolveProductAttrValue(attrName: string, filterList: FiltersResponse): string;
8
20
  /**
9
21
  * Callback that generates the cell HTML for a custom product attribute.
10
22
  * Layout-specific: grid returns `<td>…`, list returns `<tr><td>…</td></tr>`.
23
+ * @param productAttrValue - The resolved `product-attr` value (e.g., "brand" or "product_attribute.rating_star")
24
+ * @param content - The display content for the cell
11
25
  */
12
- export type CustomCellHtmlGetter = (attrName: string, content: string) => string;
26
+ export type CustomCellHtmlGetter = (productAttrValue: string, content: string) => string;
13
27
  /**
14
28
  * Symbol key for embedding custom attribute HTML in an ElementRenderer.
15
29
  * Grid and list renderers store their custom-attribute cell template under this key
@@ -28,8 +42,9 @@ export declare const CUSTOM_CELL_HTML: unique symbol;
28
42
  * alongside built-in ones, so template code can use a uniform lookup for all attributes.
29
43
  * @param baseRenderer - The built-in element renderer (grid or list), must include a [CUSTOM_CELL_HTML] entry
30
44
  * @param composition - Array of attribute keys including `customAttr:*` entries
45
+ * @param filterList - Filter list from the store, used to determine attribute type for correct product-attr resolution
31
46
  */
32
- export declare function buildElementRenderer(baseRenderer: ElementRenderer, composition: string[]): ElementRenderer;
47
+ export declare function buildElementRenderer(baseRenderer: ElementRenderer, composition: string[], filterList?: FiltersResponse): ElementRenderer;
33
48
  export type Orientation = 'list' | 'grid';
34
49
  /**
35
50
  * Options for prepareProductRows unified function
@@ -41,6 +56,8 @@ export interface PrepareProductRowsOptions {
41
56
  mobileProductsPerRow?: number;
42
57
  /** Array defining order of card elements */
43
58
  composition?: string[];
59
+ /** Filter list for attribute type resolution (default vs product attributes) */
60
+ filterList?: FiltersResponse;
44
61
  }
45
62
  /**
46
63
  * Element renderer interface for product card elements.
@@ -3,5 +3,5 @@ export declare const useTemplateLibraryApi: () => {
3
3
  getCategories: () => Promise<Category[]>;
4
4
  checkTemplateNameAvailability: (value: string) => Promise<boolean>;
5
5
  createCategory: (category: string) => Promise<string>;
6
- createTemplate: () => Promise<void>;
6
+ createTemplate: () => Promise<boolean>;
7
7
  };
@@ -22,6 +22,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
22
22
  productType: 60 | 49 | 97;
23
23
  messageType: 1 | 2;
24
24
  username: string;
25
+ fallbackFont?: {
26
+ name: string;
27
+ family: string;
28
+ } | undefined;
25
29
  };
26
30
  template: {
27
31
  html: string;
@@ -121,6 +125,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
121
125
  productType: 60 | 49 | 97;
122
126
  messageType: 1 | 2;
123
127
  username: string;
128
+ fallbackFont?: {
129
+ name: string;
130
+ family: string;
131
+ } | undefined;
124
132
  };
125
133
  template: {
126
134
  html: string;
@@ -220,6 +228,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
220
228
  productType: 60 | 49 | 97;
221
229
  messageType: 1 | 2;
222
230
  username: string;
231
+ fallbackFont?: {
232
+ name: string;
233
+ family: string;
234
+ } | undefined;
223
235
  };
224
236
  template: {
225
237
  html: string;
@@ -319,6 +331,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
319
331
  productType: 60 | 49 | 97;
320
332
  messageType: 1 | 2;
321
333
  username: string;
334
+ fallbackFont?: {
335
+ name: string;
336
+ family: string;
337
+ } | undefined;
322
338
  };
323
339
  template: {
324
340
  html: string;
@@ -418,6 +434,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
418
434
  productType: 60 | 49 | 97;
419
435
  messageType: 1 | 2;
420
436
  username: string;
437
+ fallbackFont?: {
438
+ name: string;
439
+ family: string;
440
+ } | undefined;
421
441
  };
422
442
  template: {
423
443
  html: string;
@@ -517,6 +537,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
517
537
  productType: 60 | 49 | 97;
518
538
  messageType: 1 | 2;
519
539
  username: string;
540
+ fallbackFont?: {
541
+ name: string;
542
+ family: string;
543
+ } | undefined;
520
544
  };
521
545
  template: {
522
546
  html: string;
@@ -616,6 +640,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
616
640
  productType: 60 | 49 | 97;
617
641
  messageType: 1 | 2;
618
642
  username: string;
643
+ fallbackFont?: {
644
+ name: string;
645
+ family: string;
646
+ } | undefined;
619
647
  };
620
648
  template: {
621
649
  html: string;
@@ -715,6 +743,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
715
743
  productType: 60 | 49 | 97;
716
744
  messageType: 1 | 2;
717
745
  username: string;
746
+ fallbackFont?: {
747
+ name: string;
748
+ family: string;
749
+ } | undefined;
718
750
  };
719
751
  template: {
720
752
  html: string;
@@ -814,6 +846,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
814
846
  productType: 60 | 49 | 97;
815
847
  messageType: 1 | 2;
816
848
  username: string;
849
+ fallbackFont?: {
850
+ name: string;
851
+ family: string;
852
+ } | undefined;
817
853
  };
818
854
  template: {
819
855
  html: string;
@@ -913,6 +949,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
913
949
  productType: 60 | 49 | 97;
914
950
  messageType: 1 | 2;
915
951
  username: string;
952
+ fallbackFont?: {
953
+ name: string;
954
+ family: string;
955
+ } | undefined;
916
956
  };
917
957
  template: {
918
958
  html: string;
@@ -1012,6 +1052,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1012
1052
  productType: 60 | 49 | 97;
1013
1053
  messageType: 1 | 2;
1014
1054
  username: string;
1055
+ fallbackFont?: {
1056
+ name: string;
1057
+ family: string;
1058
+ } | undefined;
1015
1059
  };
1016
1060
  template: {
1017
1061
  html: string;
@@ -1111,6 +1155,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1111
1155
  productType: 60 | 49 | 97;
1112
1156
  messageType: 1 | 2;
1113
1157
  username: string;
1158
+ fallbackFont?: {
1159
+ name: string;
1160
+ family: string;
1161
+ } | undefined;
1114
1162
  };
1115
1163
  template: {
1116
1164
  html: string;
@@ -1210,6 +1258,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1210
1258
  productType: 60 | 49 | 97;
1211
1259
  messageType: 1 | 2;
1212
1260
  username: string;
1261
+ fallbackFont?: {
1262
+ name: string;
1263
+ family: string;
1264
+ } | undefined;
1213
1265
  };
1214
1266
  template: {
1215
1267
  html: string;
@@ -1309,6 +1361,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1309
1361
  productType: 60 | 49 | 97;
1310
1362
  messageType: 1 | 2;
1311
1363
  username: string;
1364
+ fallbackFont?: {
1365
+ name: string;
1366
+ family: string;
1367
+ } | undefined;
1312
1368
  };
1313
1369
  template: {
1314
1370
  html: string;
@@ -1408,6 +1464,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1408
1464
  productType: 60 | 49 | 97;
1409
1465
  messageType: 1 | 2;
1410
1466
  username: string;
1467
+ fallbackFont?: {
1468
+ name: string;
1469
+ family: string;
1470
+ } | undefined;
1411
1471
  };
1412
1472
  template: {
1413
1473
  html: string;
@@ -1507,6 +1567,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1507
1567
  productType: 60 | 49 | 97;
1508
1568
  messageType: 1 | 2;
1509
1569
  username: string;
1570
+ fallbackFont?: {
1571
+ name: string;
1572
+ family: string;
1573
+ } | undefined;
1510
1574
  };
1511
1575
  template: {
1512
1576
  html: string;
@@ -1606,6 +1670,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1606
1670
  productType: 60 | 49 | 97;
1607
1671
  messageType: 1 | 2;
1608
1672
  username: string;
1673
+ fallbackFont?: {
1674
+ name: string;
1675
+ family: string;
1676
+ } | undefined;
1609
1677
  };
1610
1678
  template: {
1611
1679
  html: string;
@@ -1705,6 +1773,10 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1705
1773
  productType: 60 | 49 | 97;
1706
1774
  messageType: 1 | 2;
1707
1775
  username: string;
1776
+ fallbackFont?: {
1777
+ name: string;
1778
+ family: string;
1779
+ } | undefined;
1708
1780
  };
1709
1781
  template: {
1710
1782
  html: string;
@@ -7,6 +7,7 @@ export declare const usePreviewStore: import("pinia").StoreDefinition<"guidoPrev
7
7
  templateHtml: string;
8
8
  isLoaded: boolean;
9
9
  isAMPErrorModalVisible: boolean;
10
+ emailSizeKB: number;
10
11
  } & import("pinia").PiniaCustomStateProperties<PreviewState>) => boolean;
11
12
  previewHtml(): string;
12
13
  hasAMP: (state: {
@@ -16,6 +17,7 @@ export declare const usePreviewStore: import("pinia").StoreDefinition<"guidoPrev
16
17
  templateHtml: string;
17
18
  isLoaded: boolean;
18
19
  isAMPErrorModalVisible: boolean;
20
+ emailSizeKB: number;
19
21
  } & import("pinia").PiniaCustomStateProperties<PreviewState>) => boolean;
20
22
  hasAMPErrors: (state: {
21
23
  emailFormat: EmailFormat;
@@ -24,6 +26,7 @@ export declare const usePreviewStore: import("pinia").StoreDefinition<"guidoPrev
24
26
  templateHtml: string;
25
27
  isLoaded: boolean;
26
28
  isAMPErrorModalVisible: boolean;
29
+ emailSizeKB: number;
27
30
  } & import("pinia").PiniaCustomStateProperties<PreviewState>) => boolean;
28
31
  showAMPErrorButton(): boolean;
29
32
  isAMPResponsive(): boolean;
@@ -1,6 +1,6 @@
1
1
  import type { DynamicContent, MergeTag } from '@@/Types/generic';
2
2
  export declare const mergeTagToDynamicContent: (mergeTag: MergeTag) => DynamicContent;
3
- export declare const dynamicContentToMergeTags: (dynamicContentList: DynamicContent[]) => MergeTag[];
3
+ export declare const dynamicContentToMergeTags: (dynamicContentList: DynamicContent[], liquidSyntax?: boolean) => MergeTag[];
4
4
  export declare const getCsrfToken: () => string;
5
5
  /**
6
6
  * URL Parameter utilities
@@ -1,8 +1,9 @@
1
+ import type { FallbackFont } from '@@/Types/config';
1
2
  import type { CompilerRule, CompilationResult, HtmlCompiler } from '@@/Types/html-compiler';
2
3
  export declare class HtmlCompilerEngine implements HtmlCompiler {
3
4
  private rules;
4
5
  constructor(rules?: CompilerRule[]);
5
- compile(html: string, rules?: CompilerRule[]): CompilationResult;
6
+ compile(html: string, rules?: CompilerRule[], fallbackFont?: FallbackFont): CompilationResult;
6
7
  private applyRule;
7
8
  private applyReplaceRule;
8
9
  private applyRegexRule;
@@ -1,11 +1,16 @@
1
- const t = `.amp-input-list,
1
+ const n = `.amp-input-list,
2
2
  .button,
3
3
  .base-input,
4
4
  ue-stripe-thumb,
5
5
  .ue-stripe-thumb {
6
6
  transition: all .5s ease;
7
7
  }
8
+
9
+ :host {
10
+ height: 100% !important;
11
+ min-height: 0 !important;
12
+ }
8
13
  `;
9
14
  export {
10
- t as default
15
+ n as default
11
16
  };
@@ -1,13 +1,14 @@
1
1
  import { defineStore as e } from "pinia";
2
- const s = () => ({
2
+ const i = () => ({
3
3
  emailFormat: "html",
4
4
  ampHtml: "",
5
5
  ampErrors: [],
6
6
  templateHtml: "",
7
7
  isLoaded: !1,
8
- isAMPErrorModalVisible: !1
8
+ isAMPErrorModalVisible: !1,
9
+ emailSizeKB: 0
9
10
  }), a = e("guidoPreview", {
10
- state: () => s(),
11
+ state: () => i(),
11
12
  getters: {
12
13
  isAMPModeEnabled: (t) => t.emailFormat === "AMP",
13
14
  previewHtml() {
@@ -1,25 +1,47 @@
1
- const f = (t) => {
2
- const n = t.value.match(/\{\{([^}]+)\}\}/)[1].split("|").map((l) => l.trim()), [r] = n, e = {
3
- text: t.label,
4
- value: r || ""
1
+ const s = (e) => {
2
+ const a = e.value.match(/\{\{([^}]+)\}\}/)[1].split("|").map((l) => l.trim()), [n] = a, c = {
3
+ text: e.label,
4
+ value: n || ""
5
5
  };
6
- if (n.length >= 2) {
7
- const [, l, o] = n, c = l.includes("=") ? { key: l.split("=")[0].trim(), value: l.split("=")[1].trim() } : null;
8
- c ? e.format = c : o || (e.fallback = l), o && (e.fallback = o);
6
+ if (a.length >= 2) {
7
+ const [, l, r] = a;
8
+ if (l.startsWith("default:")) {
9
+ let t = l.slice(8).trim();
10
+ t.startsWith('"') && t.endsWith('"') && (t = t.slice(1, -1)), c.fallback = t;
11
+ } else {
12
+ const t = l.includes("=") ? { key: l.split("=")[0].trim(), value: l.split("=")[1].trim() } : null;
13
+ t ? c.format = t : r || (c.fallback = l), r && (c.fallback = r);
14
+ }
9
15
  }
10
- return e;
11
- }, s = (t) => t.map((a) => a.format ? {
12
- label: `${a.text} | ${a.format.key}=${a.format.value}`,
13
- value: `{{${a.value}|${a.format.key}=${a.format.value}}}`
14
- } : {
15
- label: a.fallback ? `${a.text} | ${a.fallback}` : a.text,
16
- value: a.fallback ? `{{${a.value}|${a.fallback}}}` : `{{${a.value}}}`
17
- }), u = () => {
18
- var t;
19
- return ((t = document.head.querySelector('meta[name="csrf-token"]')) == null ? void 0 : t.getAttribute("content")) ?? "";
16
+ return c;
17
+ }, u = (e, f = !1) => e.map((a) => {
18
+ if (a.format)
19
+ return {
20
+ label: `${a.text} | ${a.format.key}=${a.format.value}`,
21
+ value: `{{${a.value}|${a.format.key}=${a.format.value}}}`
22
+ };
23
+ if (f) {
24
+ if (!a.fallback)
25
+ return {
26
+ label: a.text,
27
+ value: `{{ ${a.value} }}`
28
+ };
29
+ const c = !Number.isNaN(Number(a.fallback)) && a.fallback.trim() !== "" ? a.fallback : `"${a.fallback}"`;
30
+ return {
31
+ label: `${a.text} | ${a.fallback}`,
32
+ value: `{{ ${a.value} | default: ${c} }}`
33
+ };
34
+ }
35
+ return {
36
+ label: a.fallback ? `${a.text} | ${a.fallback}` : a.text,
37
+ value: a.fallback ? `{{${a.value}|${a.fallback}}}` : `{{${a.value}}}`
38
+ };
39
+ }), o = () => {
40
+ var e;
41
+ return ((e = document.head.querySelector('meta[name="csrf-token"]')) == null ? void 0 : e.getAttribute("content")) ?? "";
20
42
  };
21
43
  export {
22
- s as dynamicContentToMergeTags,
23
- u as getCsrfToken,
24
- f as mergeTagToDynamicContent
44
+ u as dynamicContentToMergeTags,
45
+ o as getCsrfToken,
46
+ s as mergeTagToDynamicContent
25
47
  };
@@ -1,70 +1,77 @@
1
- var y = Object.defineProperty;
2
- var g = (p, e, r) => e in p ? y(p, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : p[e] = r;
3
- var u = (p, e, r) => g(p, typeof e != "symbol" ? e + "" : e, r);
4
- import { useToaster as m } from "../composables/useToaster.js";
5
- class d {
1
+ var h = Object.defineProperty;
2
+ var f = (o, e, t) => e in o ? h(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
+ var m = (o, e, t) => f(o, typeof e != "symbol" ? e + "" : e, t);
4
+ import { useToaster as x } from "../composables/useToaster.js";
5
+ const E = /font-family\s*:[^;}"']+/gi;
6
+ class T {
6
7
  constructor(e = []) {
7
- u(this, "rules");
8
+ m(this, "rules");
8
9
  this.rules = e;
9
10
  }
10
- compile(e, r) {
11
- const l = performance.now(), t = e, o = e.length;
11
+ compile(e, t, r) {
12
+ const n = performance.now(), l = e, c = e.length;
12
13
  let s = e;
13
- const a = [];
14
- (r || this.rules).sort((n, c) => n.priority - c.priority).forEach((n) => {
15
- const c = s.length;
16
- s = this.applyRule(s, n), s.length !== c && a.push(n.id);
14
+ const i = [];
15
+ (t || this.rules).sort((p, a) => p.priority - a.priority).forEach((p) => {
16
+ const a = s.length;
17
+ s = this.applyRule(s, p), s.length !== a && i.push(p.id);
17
18
  });
18
- const i = s.length, R = o > 0 ? (o - i) / o * 100 : 0;
19
+ const u = s.length, R = c > 0 ? (c - u) / c * 100 : 0, d = new TextEncoder().encode(s).byteLength;
20
+ let y = 0;
21
+ if (r && r.name && r.family) {
22
+ const p = (s.match(E) || []).length, a = `, ${r.name}, ${r.family}`;
23
+ y = p * new TextEncoder().encode(a).byteLength;
24
+ }
25
+ const g = Math.round((d + y) / 1024);
19
26
  return {
20
- originalHtml: t,
27
+ originalHtml: l,
21
28
  compiledHtml: s,
22
- appliedRules: a,
23
- // TODO: We can use stats for monitoring in the future
29
+ appliedRules: i,
30
+ estimatedSizeKB: g,
24
31
  stats: {
25
- originalSize: o,
26
- compiledSize: i,
32
+ originalSize: c,
33
+ compiledSize: u,
27
34
  reductionPercentage: R,
28
- executionTime: performance.now() - l
35
+ executionTime: performance.now() - n
29
36
  }
30
37
  };
31
38
  }
32
- applyRule(e, r) {
39
+ applyRule(e, t) {
33
40
  try {
34
- switch (r.type) {
41
+ switch (t.type) {
35
42
  case "replace":
36
- return this.applyReplaceRule(e, r);
43
+ return this.applyReplaceRule(e, t);
37
44
  case "regex":
38
- return this.applyRegexRule(e, r);
45
+ return this.applyRegexRule(e, t);
39
46
  case "remove":
40
- return this.applyRemoveRule(e, r);
47
+ return this.applyRemoveRule(e, t);
41
48
  case "custom":
42
- return this.applyCustomRule(e, r);
49
+ return this.applyCustomRule(e, t);
43
50
  default:
44
51
  return e;
45
52
  }
46
- } catch (l) {
47
- const { handleError: t } = m();
48
- return t(l, `Failed to apply rule ${r.id}:`), e;
53
+ } catch (r) {
54
+ const { handleError: n } = x();
55
+ return n(r, `Failed to apply rule ${t.id}:`), e;
49
56
  }
50
57
  }
51
- applyReplaceRule(e, r) {
52
- const { search: l, replacement: t, replaceAll: o = !0 } = r;
53
- return o ? e.replaceAll(l, t) : e.replace(l, t);
58
+ applyReplaceRule(e, t) {
59
+ const { search: r, replacement: n, replaceAll: l = !0 } = t;
60
+ return l ? e.replaceAll(r, n) : e.replace(r, n);
54
61
  }
55
- applyRegexRule(e, r) {
56
- const { pattern: l, replacement: t, flags: o = "g" } = r, s = new RegExp(l, o);
57
- return e.replace(s, t);
62
+ applyRegexRule(e, t) {
63
+ const { pattern: r, replacement: n, flags: l = "g" } = t, c = new RegExp(r, l);
64
+ return e.replace(c, n);
58
65
  }
59
- applyRemoveRule(e, r) {
60
- return r.targets.reduce((l, t) => t instanceof RegExp ? l.replace(t, "") : l.replaceAll(t, ""), e);
66
+ applyRemoveRule(e, t) {
67
+ return t.targets.reduce((r, n) => n instanceof RegExp ? r.replace(n, "") : r.replaceAll(n, ""), e);
61
68
  }
62
- applyCustomRule(e, r) {
63
- return r.processor(e);
69
+ applyCustomRule(e, t) {
70
+ return t.processor(e);
64
71
  }
65
72
  }
66
- const A = (p = []) => new d(p);
73
+ const H = (o = []) => new T(o);
67
74
  export {
68
- d as HtmlCompilerEngine,
69
- A as createHtmlCompiler
75
+ T as HtmlCompilerEngine,
76
+ H as createHtmlCompiler
70
77
  };