@useinsider/guido 3.12.0-beta.3450e5f → 3.12.0
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 +29 -0
- package/dist/@types/config/schemas.js +104 -84
- package/dist/components/organisms/onboarding/AMPOnboarding.vue.js +11 -10
- package/dist/components/organisms/onboarding/GenericOnboarding.vue.js +1 -1
- package/dist/components/organisms/onboarding/ItemsOnboarding.vue.js +6 -6
- package/dist/components/organisms/onboarding/NewVersionPopup.vue2.js +20 -23
- package/dist/components/organisms/onboarding/TextBlockOnboarding.vue.js +3 -3
- package/dist/components/organisms/onboarding/VersionHistoryOnboarding.vue.js +8 -7
- package/dist/composables/useModuleDynamicContentRepair.js +37 -0
- package/dist/composables/useStripo.js +70 -67
- package/dist/config/migrator/index.js +7 -6
- package/dist/config/migrator/socialIconMigrator.js +29 -0
- package/dist/enums/academy.js +1 -1
- package/dist/enums/date.js +3 -4
- package/dist/extensions/Blocks/Items/controls/price/formattedPrice.js +43 -41
- package/dist/guido.css +1 -1
- package/dist/node_modules/valibot/dist/index.js +148 -112
- package/dist/src/@types/config/schemas.d.ts +30 -0
- package/dist/src/@types/generic.d.ts +18 -0
- package/dist/src/composables/useConfig.d.ts +6 -0
- package/dist/src/composables/useModuleDynamicContentRepair.d.ts +18 -0
- package/dist/src/config/migrator/socialIconMigrator.d.ts +1 -0
- package/dist/src/enums/academy.d.ts +3 -3
- package/dist/src/library.d.ts +1 -1
- package/dist/src/stores/config.d.ts +54 -0
- package/dist/src/utils/dynamicContentConverter.d.ts +27 -0
- package/dist/src/utils/environmentUtil.d.ts +5 -2
- package/dist/src/utils/genericUtil.d.ts +18 -1
- package/dist/utils/dateUtil.js +10 -23
- package/dist/utils/dynamicContentConverter.js +31 -0
- package/dist/utils/environmentUtil.js +3 -2
- package/dist/utils/genericUtil.js +42 -21
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* All types are inferred from these schemas to ensure single source of truth.
|
|
6
6
|
* @module @types/config/schemas
|
|
7
7
|
*/
|
|
8
|
+
import type { DynamicContentNode } from '../generic';
|
|
8
9
|
import type { SavedTemplateDetails } from '../stripo';
|
|
9
10
|
import * as v from 'valibot';
|
|
10
11
|
/**
|
|
@@ -86,6 +87,21 @@ export declare const DynamicContentSchema: v.ObjectSchema<{
|
|
|
86
87
|
readonly value: v.StringSchema<undefined>;
|
|
87
88
|
}, undefined>, undefined>;
|
|
88
89
|
}, undefined>;
|
|
90
|
+
/**
|
|
91
|
+
* A node in the partner-keyed dynamic-content tree (backend categorized-fields
|
|
92
|
+
* shape). Loose so the many extra backend fields pass through untouched; Guido
|
|
93
|
+
* only reads text/tag_text/value and recurses children/select_items.
|
|
94
|
+
*/
|
|
95
|
+
export declare const DynamicContentNodeSchema: v.GenericSchema<DynamicContentNode>;
|
|
96
|
+
/**
|
|
97
|
+
* Partner-keyed dynamic-content list: `{ [partnerName]: DynamicContentNode[] }`.
|
|
98
|
+
* Architect is multi-partner, so the raw structure is keyed by partner name.
|
|
99
|
+
*
|
|
100
|
+
* Per-entry `fallback`: the raw backend payload may carry non-array metadata
|
|
101
|
+
* keys, so a value that is not a node array degrades to `[]` instead of failing
|
|
102
|
+
* the whole config validation (the repair feature is fail-open).
|
|
103
|
+
*/
|
|
104
|
+
export declare const DynamicContentListSchema: v.RecordSchema<v.StringSchema<undefined>, v.SchemaWithFallback<v.ArraySchema<v.GenericSchema<DynamicContentNode>, undefined>, readonly []>, undefined>;
|
|
89
105
|
/**
|
|
90
106
|
* Legacy recommendation block config (v1 format) keyed by block ID.
|
|
91
107
|
*
|
|
@@ -227,6 +243,13 @@ export declare const TemplateSchema: v.ObjectSchema<{
|
|
|
227
243
|
readonly value: v.StringSchema<undefined>;
|
|
228
244
|
}, undefined>, undefined>;
|
|
229
245
|
}, undefined>, undefined>, readonly []>;
|
|
246
|
+
/**
|
|
247
|
+
* Partner-keyed set of dynamic-content items the account offers, e.g.
|
|
248
|
+
* `{ [partnerName]: [{ text, value, children }] }`. Guido flattens the active
|
|
249
|
+
* (first) partner's leaf attributes into the label→token map that repairs
|
|
250
|
+
* label-form placeholders (`{{ Phone Number }}`) in dropped saved modules.
|
|
251
|
+
*/
|
|
252
|
+
readonly dynamicContentList: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.SchemaWithFallback<v.ArraySchema<v.GenericSchema<DynamicContentNode>, undefined>, readonly []>, undefined>, {}>;
|
|
230
253
|
/** Valid custom field attribute names from the partner's categorized fields */
|
|
231
254
|
readonly customFieldAttributes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, readonly []>;
|
|
232
255
|
/** Selected unsubscribe page IDs */
|
|
@@ -622,6 +645,13 @@ export declare const GuidoConfigSchema: v.ObjectSchema<{
|
|
|
622
645
|
readonly value: v.StringSchema<undefined>;
|
|
623
646
|
}, undefined>, undefined>;
|
|
624
647
|
}, undefined>, undefined>, readonly []>;
|
|
648
|
+
/**
|
|
649
|
+
* Partner-keyed set of dynamic-content items the account offers, e.g.
|
|
650
|
+
* `{ [partnerName]: [{ text, value, children }] }`. Guido flattens the active
|
|
651
|
+
* (first) partner's leaf attributes into the label→token map that repairs
|
|
652
|
+
* label-form placeholders (`{{ Phone Number }}`) in dropped saved modules.
|
|
653
|
+
*/
|
|
654
|
+
readonly dynamicContentList: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.SchemaWithFallback<v.ArraySchema<v.GenericSchema<DynamicContentNode>, undefined>, readonly []>, undefined>, {}>;
|
|
625
655
|
/** Valid custom field attribute names from the partner's categorized fields */
|
|
626
656
|
readonly customFieldAttributes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, readonly []>;
|
|
627
657
|
/** Selected unsubscribe page IDs */
|
|
@@ -13,6 +13,24 @@ export type BaseDynamicContent = {
|
|
|
13
13
|
export type DynamicContent = BaseDynamicContent & {
|
|
14
14
|
text: string;
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* A node in the partner-keyed dynamic-content tree (backend categorized-fields
|
|
18
|
+
* shape). Category nodes carry `children`/`select_items`; leaf nodes are the
|
|
19
|
+
* real attributes. Extra backend fields are allowed and ignored.
|
|
20
|
+
*/
|
|
21
|
+
export type DynamicContentNode = {
|
|
22
|
+
text?: string;
|
|
23
|
+
tag_text?: string;
|
|
24
|
+
value?: string;
|
|
25
|
+
children?: DynamicContentNode[];
|
|
26
|
+
select_items?: DynamicContentNode[];
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Partner-keyed dynamic-content list. Architect is multi-partner, so the map is
|
|
30
|
+
* keyed by partner name; each entry is that partner's category tree. Guido
|
|
31
|
+
* flattens the active (first) partner's leaf attributes into a `DynamicContent[]`.
|
|
32
|
+
*/
|
|
33
|
+
export type DynamicContentList = Record<string, DynamicContentNode[]>;
|
|
16
34
|
export type MergeTag = BaseDynamicContent & {
|
|
17
35
|
label: string;
|
|
18
36
|
selStart?: number;
|
|
@@ -34,6 +34,9 @@ export declare const useConfig: () => {
|
|
|
34
34
|
value: string;
|
|
35
35
|
} | undefined;
|
|
36
36
|
}[];
|
|
37
|
+
dynamicContentList: {
|
|
38
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
39
|
+
};
|
|
37
40
|
customFieldAttributes: string[];
|
|
38
41
|
selectedUnsubscribePages: number[];
|
|
39
42
|
forceRecreate: boolean;
|
|
@@ -162,6 +165,9 @@ export declare const useConfig: () => {
|
|
|
162
165
|
value: string;
|
|
163
166
|
} | undefined;
|
|
164
167
|
}[];
|
|
168
|
+
dynamicContentList: {
|
|
169
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
170
|
+
};
|
|
165
171
|
customFieldAttributes: string[];
|
|
166
172
|
selectedUnsubscribePages: number[];
|
|
167
173
|
forceRecreate: boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ModuleAddData, ModuleModifier } from '@@/Types/stripo';
|
|
2
|
+
/**
|
|
3
|
+
* Host-registered translation key for the "some attributes could not be
|
|
4
|
+
* converted" toaster. Guido resolves it against the host's `window.trans.en`;
|
|
5
|
+
* the copy is registered host-side.
|
|
6
|
+
*/
|
|
7
|
+
export declare const UNRESOLVED_DYNAMIC_CONTENT_ON_DROP_KEY = "dynamic-content.unresolved-attributes-on-drop";
|
|
8
|
+
/**
|
|
9
|
+
* Repairs label-form dynamic-content tokens in saved modules as they are dropped
|
|
10
|
+
* or copied into the editor. Saved modules serialize merge-tag chips by their
|
|
11
|
+
* display label (`{{ Phone Number }}`); this maps them back to their canonical
|
|
12
|
+
* token (`{{phone_number}}`) using the account's dynamic-content list.
|
|
13
|
+
*
|
|
14
|
+
* Wired into Stripo via the `onModuleAdd` init callback (see `useStripo`).
|
|
15
|
+
*/
|
|
16
|
+
export declare const useModuleDynamicContentRepair: () => {
|
|
17
|
+
handleModuleAdd: (data: ModuleAddData, modifier: ModuleModifier) => void;
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function migrateSocialIcons(html: string): string;
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* for easy maintenance and domain migration.
|
|
6
6
|
*/
|
|
7
7
|
export declare const ACADEMY_LINKS: {
|
|
8
|
-
readonly EMAIL_EDITOR: "https://academy.insiderone.com
|
|
9
|
-
readonly GLOBAL_UNSUBSCRIBE: "https://academy.insiderone.com
|
|
10
|
-
readonly AMP_FOR_EMAILS: "https://academy.insiderone.com
|
|
8
|
+
readonly EMAIL_EDITOR: "https://academy.insiderone.com/docs/email-drag-and-drop-editor";
|
|
9
|
+
readonly GLOBAL_UNSUBSCRIBE: "https://academy.insiderone.com/docs/global-unsubscribe-preference-center";
|
|
10
|
+
readonly AMP_FOR_EMAILS: "https://academy.insiderone.com/docs/amp-for-emails";
|
|
11
11
|
};
|
|
12
12
|
export type AcademyLinkKey = keyof typeof ACADEMY_LINKS;
|
package/dist/src/library.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export { default as Guido } from './components/Guido.vue';
|
|
|
2
2
|
export type { GuidoConfig, GuidoConfigInput, IdentityConfig, PartnerConfig, TemplateConfig, TemplateMigrationConfig, LegacyRecommendationConfig, EditorConfig, UIConfig, FeaturesConfig, BlocksConfig, CompilerConfig, DynamicContent, EmailHeader, DefaultBlockType, CustomBlockType, ValidationResult, ValidationError, } from './@types/config';
|
|
3
3
|
export { validateConfig, parseConfig, parseConfigSafe, isValidConfig, getValidationErrors, MessageType, ProductType, } from './@types/config';
|
|
4
4
|
export type { StripoEventType } from './@types/events';
|
|
5
|
-
export type { PositionData, DynamicContentEvent, MergeTagClickEvent, MergeTag, BaseDynamicContent, TooltipOptions, TextValueObject, L10n, } from './@types/generic';
|
|
5
|
+
export type { PositionData, DynamicContentEvent, MergeTagClickEvent, MergeTag, BaseDynamicContent, DynamicContentNode, DynamicContentList, TooltipOptions, TextValueObject, L10n, } from './@types/generic';
|
|
@@ -39,6 +39,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
39
39
|
value: string;
|
|
40
40
|
} | undefined;
|
|
41
41
|
}[];
|
|
42
|
+
dynamicContentList: {
|
|
43
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
44
|
+
};
|
|
42
45
|
customFieldAttributes: string[];
|
|
43
46
|
selectedUnsubscribePages: number[];
|
|
44
47
|
forceRecreate: boolean;
|
|
@@ -173,6 +176,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
173
176
|
value: string;
|
|
174
177
|
} | undefined;
|
|
175
178
|
}[];
|
|
179
|
+
dynamicContentList: {
|
|
180
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
181
|
+
};
|
|
176
182
|
customFieldAttributes: string[];
|
|
177
183
|
selectedUnsubscribePages: number[];
|
|
178
184
|
forceRecreate: boolean;
|
|
@@ -307,6 +313,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
307
313
|
value: string;
|
|
308
314
|
} | undefined;
|
|
309
315
|
}[];
|
|
316
|
+
dynamicContentList: {
|
|
317
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
318
|
+
};
|
|
310
319
|
customFieldAttributes: string[];
|
|
311
320
|
selectedUnsubscribePages: number[];
|
|
312
321
|
forceRecreate: boolean;
|
|
@@ -441,6 +450,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
441
450
|
value: string;
|
|
442
451
|
} | undefined;
|
|
443
452
|
}[];
|
|
453
|
+
dynamicContentList: {
|
|
454
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
455
|
+
};
|
|
444
456
|
customFieldAttributes: string[];
|
|
445
457
|
selectedUnsubscribePages: number[];
|
|
446
458
|
forceRecreate: boolean;
|
|
@@ -575,6 +587,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
575
587
|
value: string;
|
|
576
588
|
} | undefined;
|
|
577
589
|
}[];
|
|
590
|
+
dynamicContentList: {
|
|
591
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
592
|
+
};
|
|
578
593
|
customFieldAttributes: string[];
|
|
579
594
|
selectedUnsubscribePages: number[];
|
|
580
595
|
forceRecreate: boolean;
|
|
@@ -709,6 +724,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
709
724
|
value: string;
|
|
710
725
|
} | undefined;
|
|
711
726
|
}[];
|
|
727
|
+
dynamicContentList: {
|
|
728
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
729
|
+
};
|
|
712
730
|
customFieldAttributes: string[];
|
|
713
731
|
selectedUnsubscribePages: number[];
|
|
714
732
|
forceRecreate: boolean;
|
|
@@ -843,6 +861,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
843
861
|
value: string;
|
|
844
862
|
} | undefined;
|
|
845
863
|
}[];
|
|
864
|
+
dynamicContentList: {
|
|
865
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
866
|
+
};
|
|
846
867
|
customFieldAttributes: string[];
|
|
847
868
|
selectedUnsubscribePages: number[];
|
|
848
869
|
forceRecreate: boolean;
|
|
@@ -977,6 +998,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
977
998
|
value: string;
|
|
978
999
|
} | undefined;
|
|
979
1000
|
}[];
|
|
1001
|
+
dynamicContentList: {
|
|
1002
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
1003
|
+
};
|
|
980
1004
|
customFieldAttributes: string[];
|
|
981
1005
|
selectedUnsubscribePages: number[];
|
|
982
1006
|
forceRecreate: boolean;
|
|
@@ -1111,6 +1135,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1111
1135
|
value: string;
|
|
1112
1136
|
} | undefined;
|
|
1113
1137
|
}[];
|
|
1138
|
+
dynamicContentList: {
|
|
1139
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
1140
|
+
};
|
|
1114
1141
|
customFieldAttributes: string[];
|
|
1115
1142
|
selectedUnsubscribePages: number[];
|
|
1116
1143
|
forceRecreate: boolean;
|
|
@@ -1245,6 +1272,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1245
1272
|
value: string;
|
|
1246
1273
|
} | undefined;
|
|
1247
1274
|
}[];
|
|
1275
|
+
dynamicContentList: {
|
|
1276
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
1277
|
+
};
|
|
1248
1278
|
customFieldAttributes: string[];
|
|
1249
1279
|
selectedUnsubscribePages: number[];
|
|
1250
1280
|
forceRecreate: boolean;
|
|
@@ -1379,6 +1409,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1379
1409
|
value: string;
|
|
1380
1410
|
} | undefined;
|
|
1381
1411
|
}[];
|
|
1412
|
+
dynamicContentList: {
|
|
1413
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
1414
|
+
};
|
|
1382
1415
|
customFieldAttributes: string[];
|
|
1383
1416
|
selectedUnsubscribePages: number[];
|
|
1384
1417
|
forceRecreate: boolean;
|
|
@@ -1513,6 +1546,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1513
1546
|
value: string;
|
|
1514
1547
|
} | undefined;
|
|
1515
1548
|
}[];
|
|
1549
|
+
dynamicContentList: {
|
|
1550
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
1551
|
+
};
|
|
1516
1552
|
customFieldAttributes: string[];
|
|
1517
1553
|
selectedUnsubscribePages: number[];
|
|
1518
1554
|
forceRecreate: boolean;
|
|
@@ -1647,6 +1683,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1647
1683
|
value: string;
|
|
1648
1684
|
} | undefined;
|
|
1649
1685
|
}[];
|
|
1686
|
+
dynamicContentList: {
|
|
1687
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
1688
|
+
};
|
|
1650
1689
|
customFieldAttributes: string[];
|
|
1651
1690
|
selectedUnsubscribePages: number[];
|
|
1652
1691
|
forceRecreate: boolean;
|
|
@@ -1781,6 +1820,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1781
1820
|
value: string;
|
|
1782
1821
|
} | undefined;
|
|
1783
1822
|
}[];
|
|
1823
|
+
dynamicContentList: {
|
|
1824
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
1825
|
+
};
|
|
1784
1826
|
customFieldAttributes: string[];
|
|
1785
1827
|
selectedUnsubscribePages: number[];
|
|
1786
1828
|
forceRecreate: boolean;
|
|
@@ -1915,6 +1957,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1915
1957
|
value: string;
|
|
1916
1958
|
} | undefined;
|
|
1917
1959
|
}[];
|
|
1960
|
+
dynamicContentList: {
|
|
1961
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
1962
|
+
};
|
|
1918
1963
|
customFieldAttributes: string[];
|
|
1919
1964
|
selectedUnsubscribePages: number[];
|
|
1920
1965
|
forceRecreate: boolean;
|
|
@@ -2049,6 +2094,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2049
2094
|
value: string;
|
|
2050
2095
|
} | undefined;
|
|
2051
2096
|
}[];
|
|
2097
|
+
dynamicContentList: {
|
|
2098
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
2099
|
+
};
|
|
2052
2100
|
customFieldAttributes: string[];
|
|
2053
2101
|
selectedUnsubscribePages: number[];
|
|
2054
2102
|
forceRecreate: boolean;
|
|
@@ -2183,6 +2231,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2183
2231
|
value: string;
|
|
2184
2232
|
} | undefined;
|
|
2185
2233
|
}[];
|
|
2234
|
+
dynamicContentList: {
|
|
2235
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
2236
|
+
};
|
|
2186
2237
|
customFieldAttributes: string[];
|
|
2187
2238
|
selectedUnsubscribePages: number[];
|
|
2188
2239
|
forceRecreate: boolean;
|
|
@@ -2317,6 +2368,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2317
2368
|
value: string;
|
|
2318
2369
|
} | undefined;
|
|
2319
2370
|
}[];
|
|
2371
|
+
dynamicContentList: {
|
|
2372
|
+
[x: string]: import("../library").DynamicContentNode[];
|
|
2373
|
+
};
|
|
2320
2374
|
customFieldAttributes: string[];
|
|
2321
2375
|
selectedUnsubscribePages: number[];
|
|
2322
2376
|
forceRecreate: boolean;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { DynamicContent } from '@@/Types/generic';
|
|
2
|
+
export interface DynamicContentConversionResult {
|
|
3
|
+
html: string;
|
|
4
|
+
/** Distinct tokens that matched neither a known value nor a known label (reported to the user). */
|
|
5
|
+
unresolved: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Builds a label→item lookup from one or more dynamic-content lists, keyed by
|
|
9
|
+
* normalized label (trimmed, lowercased). When lists overlap, a later list wins
|
|
10
|
+
* for a shared key.
|
|
11
|
+
*/
|
|
12
|
+
export declare const buildDynamicContentLookup: (...lists: DynamicContent[][]) => Map<string, DynamicContent>;
|
|
13
|
+
/**
|
|
14
|
+
* Repairs dynamic-content tokens in a dropped module's HTML, using `lookup`
|
|
15
|
+
* (label→item) built from the account's full dynamic-content list. Returns the
|
|
16
|
+
* rewritten HTML plus the tokens it could not resolve.
|
|
17
|
+
*
|
|
18
|
+
* A token is rewritten to its canonical `{{value}}` form when its name matches a
|
|
19
|
+
* display label (`{{ Phone Number }}` → `{{phone_number}}`). Left untouched: an
|
|
20
|
+
* exact canonical value (already correct — this also stops a valid token being
|
|
21
|
+
* rewritten just because it coincides with an unrelated label), Liquid nested
|
|
22
|
+
* tokens (dotted, e.g. `coupon.code`), recommendation-block variables
|
|
23
|
+
* (`123_0_attr`), allowed system tokens, and `data-*` product tags. The account
|
|
24
|
+
* list is exhaustive, so any remaining token matching neither a value nor a label
|
|
25
|
+
* is reported in `unresolved`; the text itself is always left in place.
|
|
26
|
+
*/
|
|
27
|
+
export declare const convertModuleDynamicContent: (html: string, lookup: Map<string, DynamicContent>, liquidSyntax: boolean) => DynamicContentConversionResult;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
/** Production default — pony-express builds unsubscribe links on mail.useinsider.com. */
|
|
2
|
+
export declare const DEFAULT_ENVIRONMENT_PREFIX = "useinsider";
|
|
1
3
|
/**
|
|
2
|
-
* Gets the
|
|
3
|
-
*
|
|
4
|
+
* Gets the environment prefix by parsing the current hostname (third segment),
|
|
5
|
+
* falling back to the production default when that segment is absent or empty —
|
|
6
|
+
* so unsubscribe links never compile to `https://mail.undefined.com/...` (SD-145225).
|
|
4
7
|
*/
|
|
5
8
|
export declare const getEnvironmentPrefix: () => string;
|
|
@@ -1,6 +1,23 @@
|
|
|
1
|
-
import type { DynamicContent, MergeTag } from '@@/Types/generic';
|
|
1
|
+
import type { DynamicContent, DynamicContentList, MergeTag } from '@@/Types/generic';
|
|
2
2
|
export declare const mergeTagToDynamicContent: (mergeTag: MergeTag) => DynamicContent;
|
|
3
3
|
export declare const dynamicContentToMergeTags: (dynamicContentList: DynamicContent[], liquidSyntax?: boolean) => MergeTag[];
|
|
4
|
+
/**
|
|
5
|
+
* Flattens the partner-keyed dynamic-content tree into a deduped flat list of the
|
|
6
|
+
* ACTIVE partner's leaf attributes. A single editor session targets one partner,
|
|
7
|
+
* so only the FIRST partner entry is used (the sole entry for a single-partner
|
|
8
|
+
* host like email-fe; merging all partners would risk cross-partner label
|
|
9
|
+
* collisions). A node carrying `children`/`select_items` is a category grouping:
|
|
10
|
+
* recursed into but never collected itself — only real leaf attributes
|
|
11
|
+
* (`text`/`tag_text` + `value`) become `{ text, value }` pairs.
|
|
12
|
+
*/
|
|
13
|
+
export declare const flattenDynamicContentList: (list: DynamicContentList | undefined | null) => DynamicContent[];
|
|
14
|
+
/**
|
|
15
|
+
* Builds the editor merge-tag entries from the template's preselected list plus
|
|
16
|
+
* the account's full available list, deduped by token value (preselected wins so
|
|
17
|
+
* its fallback/format is kept). Registering the full list lets every recognized
|
|
18
|
+
* token — including ones repaired on module drop — render as a chip.
|
|
19
|
+
*/
|
|
20
|
+
export declare const buildMergeTagEntries: (preselected: DynamicContent[], available: DynamicContent[], liquidSyntax?: boolean) => MergeTag[];
|
|
4
21
|
export declare const getCsrfToken: () => string;
|
|
5
22
|
/**
|
|
6
23
|
* URL Parameter utilities
|
package/dist/utils/dateUtil.js
CHANGED
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
import { DEFAULT_LOCALE as r, DEFAULT as
|
|
2
|
-
const
|
|
1
|
+
import { DEFAULT_LOCALE as r, DEFAULT as o } from "../enums/date.js";
|
|
2
|
+
const c = () => {
|
|
3
3
|
const t = window.l10n;
|
|
4
|
-
return (t == null ? void 0 : t.locale) ===
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}, D = (t, e = s(), n = f()) => {
|
|
9
|
-
const o = {
|
|
10
|
-
year: "numeric",
|
|
11
|
-
month: "2-digit",
|
|
12
|
-
day: "2-digit",
|
|
13
|
-
timeZone: n
|
|
14
|
-
}, i = m(t);
|
|
15
|
-
return new Intl.DateTimeFormat(e, o).format(i);
|
|
16
|
-
}, T = (t) => {
|
|
4
|
+
return (t == null ? void 0 : t.locale) === o ? r : (t == null ? void 0 : t.locale) || r;
|
|
5
|
+
};
|
|
6
|
+
new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
7
|
+
const i = (t) => {
|
|
17
8
|
if (!t)
|
|
18
9
|
return "";
|
|
19
10
|
const e = new Date(t);
|
|
@@ -25,13 +16,9 @@ const m = (t) => t ? t instanceof Date ? t : typeof t == "string" ? t.length ===
|
|
|
25
16
|
second: "2-digit",
|
|
26
17
|
hour12: !1
|
|
27
18
|
}).format(e);
|
|
28
|
-
},
|
|
19
|
+
}, m = (t) => t ? Math.floor(Date.now() / 1e3) >= t : !1;
|
|
29
20
|
export {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
h as isAfterDate,
|
|
34
|
-
u as localTz,
|
|
35
|
-
s as locale,
|
|
36
|
-
f as timezone
|
|
21
|
+
i as formatPatchDate,
|
|
22
|
+
m as isAfterDate,
|
|
23
|
+
c as locale
|
|
37
24
|
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DATA_ATTRIBUTE_REGEX as A, DYNAMIC_CONTENT_TAG_REGEX as m, ALLOWED_DYNAMIC_SYSTEM_TOKENS as D } from "../enums/html-validator.js";
|
|
2
|
+
import { dynamicContentToMergeTags as T } from "./genericUtil.js";
|
|
3
|
+
const p = "guidoDataMask", M = "EndDataMask", f = /guidoDataMask(\d+)EndDataMask/g, h = /^\d+_\d+_.+$/, E = (o) => o.trim().toLowerCase(), I = (...o) => {
|
|
4
|
+
const r = /* @__PURE__ */ new Map();
|
|
5
|
+
return o.forEach((i) => {
|
|
6
|
+
i.forEach((s) => {
|
|
7
|
+
const a = E(s.text);
|
|
8
|
+
a && r.set(a, s);
|
|
9
|
+
});
|
|
10
|
+
}), r;
|
|
11
|
+
}, w = (o, r, i) => {
|
|
12
|
+
const s = /* @__PURE__ */ new Set(), a = new Set([...r.values()].map((e) => e.value)), u = [];
|
|
13
|
+
return { html: o.replace(A, (e) => (u.push(e), `${p}${u.length - 1}${M}`)).replace(m, (e) => {
|
|
14
|
+
const n = e.slice(2, -2), c = n.indexOf("|"), l = c === -1 ? n : n.slice(0, c), t = l.trim();
|
|
15
|
+
if (t === "" || D.includes(t) || t.includes(".") || h.test(t) || a.has(t))
|
|
16
|
+
return e;
|
|
17
|
+
const d = r.get(E(t));
|
|
18
|
+
if (d) {
|
|
19
|
+
if (c !== -1) {
|
|
20
|
+
const _ = n.slice(c);
|
|
21
|
+
return `{{${l.replace(t, () => d.value)}${_}}}`;
|
|
22
|
+
}
|
|
23
|
+
return T([d], i)[0].value;
|
|
24
|
+
}
|
|
25
|
+
return s.add(t), e;
|
|
26
|
+
}).replace(f, (e, n) => u[Number(n)]), unresolved: [...s] };
|
|
27
|
+
};
|
|
28
|
+
export {
|
|
29
|
+
I as buildDynamicContentLookup,
|
|
30
|
+
w as convertModuleDynamicContent
|
|
31
|
+
};
|
|
@@ -1,47 +1,68 @@
|
|
|
1
|
-
const
|
|
2
|
-
const a =
|
|
3
|
-
text:
|
|
4
|
-
value:
|
|
1
|
+
const o = (l) => {
|
|
2
|
+
const a = l.value.match(/\{\{([^}]+)\}\}/)[1].split("|").map((t) => t.trim()), [c] = a, r = {
|
|
3
|
+
text: l.label,
|
|
4
|
+
value: c || ""
|
|
5
5
|
};
|
|
6
6
|
if (a.length >= 2) {
|
|
7
|
-
const [,
|
|
8
|
-
if (
|
|
9
|
-
let
|
|
10
|
-
|
|
7
|
+
const [, t, e] = a;
|
|
8
|
+
if (t.startsWith("default:")) {
|
|
9
|
+
let n = t.slice(8).trim();
|
|
10
|
+
n.startsWith('"') && n.endsWith('"') && (n = n.slice(1, -1)), r.fallback = n;
|
|
11
11
|
} else {
|
|
12
|
-
const
|
|
13
|
-
|
|
12
|
+
const n = t.includes("=") ? { key: t.split("=")[0].trim(), value: t.split("=")[1].trim() } : null;
|
|
13
|
+
n ? r.format = n : e || (r.fallback = t), e && (r.fallback = e);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
return
|
|
17
|
-
},
|
|
16
|
+
return r;
|
|
17
|
+
}, f = (l, s = !1) => l.map((a) => {
|
|
18
18
|
if (a.format)
|
|
19
19
|
return {
|
|
20
20
|
label: `${a.text} | ${a.format.key}=${a.format.value}`,
|
|
21
21
|
value: `{{${a.value}|${a.format.key}=${a.format.value}}}`
|
|
22
22
|
};
|
|
23
|
-
if (
|
|
23
|
+
if (s) {
|
|
24
24
|
if (!a.fallback)
|
|
25
25
|
return {
|
|
26
26
|
label: a.text,
|
|
27
27
|
value: `{{ ${a.value} }}`
|
|
28
28
|
};
|
|
29
|
-
const
|
|
29
|
+
const r = !Number.isNaN(Number(a.fallback)) && a.fallback.trim() !== "" ? a.fallback : `"${a.fallback}"`;
|
|
30
30
|
return {
|
|
31
31
|
label: `${a.text} | ${a.fallback}`,
|
|
32
|
-
value: `{{ ${a.value} | default: ${
|
|
32
|
+
value: `{{ ${a.value} | default: ${r} }}`
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
return {
|
|
36
36
|
label: a.fallback ? `${a.text} | ${a.fallback}` : a.text,
|
|
37
37
|
value: a.fallback ? `{{${a.value}|${a.fallback}}}` : `{{${a.value}}}`
|
|
38
38
|
};
|
|
39
|
-
}),
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
}), b = (l) => {
|
|
40
|
+
const s = [], a = /* @__PURE__ */ new Set(), c = (t) => {
|
|
41
|
+
Array.isArray(t) && t.forEach((e) => {
|
|
42
|
+
const n = [...e.children ?? [], ...e.select_items ?? []];
|
|
43
|
+
if (n.length > 0) {
|
|
44
|
+
c(n);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const u = e.text || e.tag_text;
|
|
48
|
+
u && e.value && !a.has(e.value) && (a.add(e.value), s.push({ text: u, value: e.value }));
|
|
49
|
+
});
|
|
50
|
+
}, [r] = Object.values(l ?? {});
|
|
51
|
+
return c(r), s;
|
|
52
|
+
}, v = (l, s, a = !1) => {
|
|
53
|
+
const c = new Set(l.map((t) => t.value)), r = s.filter((t) => c.has(t.value) ? !1 : (c.add(t.value), !0));
|
|
54
|
+
return [
|
|
55
|
+
...f(l, a),
|
|
56
|
+
...f(r, a)
|
|
57
|
+
];
|
|
58
|
+
}, i = () => {
|
|
59
|
+
var l;
|
|
60
|
+
return ((l = document.head.querySelector('meta[name="csrf-token"]')) == null ? void 0 : l.getAttribute("content")) ?? "";
|
|
42
61
|
};
|
|
43
62
|
export {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
63
|
+
v as buildMergeTagEntries,
|
|
64
|
+
f as dynamicContentToMergeTags,
|
|
65
|
+
b as flattenDynamicContentList,
|
|
66
|
+
i as getCsrfToken,
|
|
67
|
+
o as mergeTagToDynamicContent
|
|
47
68
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.12.0
|
|
3
|
+
"version": "3.12.0",
|
|
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",
|