@servicetitan/dte-unlayer 0.153.0 → 0.154.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/dist/index.d.ts CHANGED
@@ -3,8 +3,8 @@ export * from './tools';
3
3
  export * from './api-core';
4
4
  export * from './api-custom-tools';
5
5
  export * from './unlayer-interface';
6
- export { isUnlayerMergeTagGroup, scheduleUnlayerMergeTags, toUnlayerMergeTags } from './merge-tags';
7
- export type { ToUnlayerMergeTagsOptions, UnlayerMergeTagGroup, UnlayerMergeTagLeaf, UnlayerMergeTagsConfig, UnlayerMergeTagsEditor, } from './merge-tags';
6
+ export { isUnlayerMergeTagGroup, toUnlayerMergeTags } from './merge-tags';
7
+ export type { ToUnlayerMergeTagsOptions, UnlayerMergeTagGroup, UnlayerMergeTagLeaf, UnlayerMergeTagsConfig, } from './merge-tags';
8
8
  export * from './loadScript';
9
9
  export * from './shared/const';
10
10
  export * from './shared/forms';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACpG,YAAY,EACR,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACzB,MAAM,cAAc,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,cAAc,8CAA8C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC1E,YAAY,EACR,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,GACzB,MAAM,cAAc,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,cAAc,8CAA8C,CAAC"}
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ export * from './tools';
3
3
  export * from './api-core';
4
4
  export * from './api-custom-tools';
5
5
  export * from './unlayer-interface';
6
- export { isUnlayerMergeTagGroup, scheduleUnlayerMergeTags, toUnlayerMergeTags } from './merge-tags';
6
+ export { isUnlayerMergeTagGroup, toUnlayerMergeTags } from './merge-tags';
7
7
  export * from './loadScript';
8
8
  export * from './shared/const';
9
9
  export * from './shared/forms';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './editor';\nexport * from './tools';\nexport * from './api-core';\nexport * from './api-custom-tools';\nexport * from './unlayer-interface';\nexport { isUnlayerMergeTagGroup, scheduleUnlayerMergeTags, toUnlayerMergeTags } from './merge-tags';\nexport type {\n ToUnlayerMergeTagsOptions,\n UnlayerMergeTagGroup,\n UnlayerMergeTagLeaf,\n UnlayerMergeTagsConfig,\n UnlayerMergeTagsEditor,\n} from './merge-tags';\nexport * from './loadScript';\nexport * from './shared/const';\nexport * from './shared/forms';\nexport * from './shared/schema';\nexport * from './shared/tools';\nexport type { UnlayerDesignChangeInfo } from './store';\nexport { versions } from './unlayer';\nexport * from './shared/date-calc';\nexport { emptyArrayIfNull } from './shared/nunjucks-helpers';\nexport * from './display-conditions/lookupOptionsController';\n"],"names":["isUnlayerMergeTagGroup","scheduleUnlayerMergeTags","toUnlayerMergeTags","versions","emptyArrayIfNull"],"mappings":"AAAA,cAAc,WAAW;AACzB,cAAc,UAAU;AACxB,cAAc,aAAa;AAC3B,cAAc,qBAAqB;AACnC,cAAc,sBAAsB;AACpC,SAASA,sBAAsB,EAAEC,wBAAwB,EAAEC,kBAAkB,QAAQ,eAAe;AAQpG,cAAc,eAAe;AAC7B,cAAc,iBAAiB;AAC/B,cAAc,iBAAiB;AAC/B,cAAc,kBAAkB;AAChC,cAAc,iBAAiB;AAE/B,SAASC,QAAQ,QAAQ,YAAY;AACrC,cAAc,qBAAqB;AACnC,SAASC,gBAAgB,QAAQ,4BAA4B;AAC7D,cAAc,+CAA+C"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './editor';\nexport * from './tools';\nexport * from './api-core';\nexport * from './api-custom-tools';\nexport * from './unlayer-interface';\nexport { isUnlayerMergeTagGroup, toUnlayerMergeTags } from './merge-tags';\nexport type {\n ToUnlayerMergeTagsOptions,\n UnlayerMergeTagGroup,\n UnlayerMergeTagLeaf,\n UnlayerMergeTagsConfig,\n} from './merge-tags';\nexport * from './loadScript';\nexport * from './shared/const';\nexport * from './shared/forms';\nexport * from './shared/schema';\nexport * from './shared/tools';\nexport type { UnlayerDesignChangeInfo } from './store';\nexport { versions } from './unlayer';\nexport * from './shared/date-calc';\nexport { emptyArrayIfNull } from './shared/nunjucks-helpers';\nexport * from './display-conditions/lookupOptionsController';\n"],"names":["isUnlayerMergeTagGroup","toUnlayerMergeTags","versions","emptyArrayIfNull"],"mappings":"AAAA,cAAc,WAAW;AACzB,cAAc,UAAU;AACxB,cAAc,aAAa;AAC3B,cAAc,qBAAqB;AACnC,cAAc,sBAAsB;AACpC,SAASA,sBAAsB,EAAEC,kBAAkB,QAAQ,eAAe;AAO1E,cAAc,eAAe;AAC7B,cAAc,iBAAiB;AAC/B,cAAc,iBAAiB;AAC/B,cAAc,kBAAkB;AAChC,cAAc,iBAAiB;AAE/B,SAASC,QAAQ,QAAQ,YAAY;AACrC,cAAc,qBAAqB;AACnC,SAASC,gBAAgB,QAAQ,4BAA4B;AAC7D,cAAc,+CAA+C"}
@@ -5,7 +5,8 @@ export interface UnlayerMergeTagLeaf {
5
5
  }
6
6
  export interface UnlayerMergeTagGroup {
7
7
  name: string;
8
- mergeTags: Record<string, UnlayerMergeTagLeaf>;
8
+ /** Nested submenu: leaves and/or further groups (Unlayer supports arbitrary depth). */
9
+ mergeTags: UnlayerMergeTagsConfig;
9
10
  }
10
11
  export type UnlayerMergeTagsConfig = Record<string, UnlayerMergeTagLeaf | UnlayerMergeTagGroup>;
11
12
  export interface ToUnlayerMergeTagsOptions {
@@ -15,16 +16,11 @@ export interface ToUnlayerMergeTagsOptions {
15
16
  */
16
17
  groups?: boolean;
17
18
  }
18
- export interface UnlayerMergeTagsEditor {
19
- addEventListener(event: string, cb: (arg: any) => void): void;
20
- setMergeTags(tags: UnlayerMergeTagsConfig): void;
21
- }
22
19
  export declare function isUnlayerMergeTagGroup(entry: UnlayerMergeTagLeaf | UnlayerMergeTagGroup): entry is UnlayerMergeTagGroup;
23
- export declare const toUnlayerMergeTags: (tags: UnlayerEditorMergeTagInfo[] | undefined, options?: ToUnlayerMergeTagsOptions) => UnlayerMergeTagsConfig | undefined;
24
20
  /**
25
- * Nested Unlayer groups passed to createEditor prevent DTE custom tools from
26
- * loading in the host app. Apply the 0.151 flat shape at init, then upgrade to
27
- * grouped submenus once the editor (and customJS tools) are ready.
21
+ * Builds Unlayer's `mergeTags` config. With `groups` enabled (default) tags nest under the
22
+ * submenu path in `group`; `UnlayerStore` applies that shape once the editor is ready, since
23
+ * nested groups at `createEditor` time prevent DTE custom tools from loading.
28
24
  */
29
- export declare const scheduleUnlayerMergeTags: (editor: UnlayerMergeTagsEditor, tags: UnlayerEditorMergeTagInfo[] | undefined) => void;
25
+ export declare const toUnlayerMergeTags: (tags: UnlayerEditorMergeTagInfo[] | undefined, options?: ToUnlayerMergeTagsOptions) => UnlayerMergeTagsConfig | undefined;
30
26
  //# sourceMappingURL=merge-tags.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"merge-tags.d.ts","sourceRoot":"","sources":["../src/merge-tags.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAClD;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,GAAG,oBAAoB,CAAC,CAAC;AAEhG,MAAM,WAAW,yBAAyB;IACtC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACnC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IAC9D,YAAY,CAAC,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAC;CACpD;AAED,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,GAClD,KAAK,IAAI,oBAAoB,CAE/B;AAYD,eAAO,MAAM,kBAAkB,GAC3B,MAAM,yBAAyB,EAAE,GAAG,SAAS,EAC7C,UAAU,yBAAyB,uCAsCtC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACjC,QAAQ,sBAAsB,EAC9B,MAAM,yBAAyB,EAAE,GAAG,SAAS,SAwBhD,CAAC"}
1
+ {"version":3,"file":"merge-tags.d.ts","sourceRoot":"","sources":["../src/merge-tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,SAAS,EAAE,sBAAsB,CAAC;CACrC;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,GAAG,oBAAoB,CAAC,CAAC;AAEhG,MAAM,WAAW,yBAAyB;IACtC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,GAClD,KAAK,IAAI,oBAAoB,CAE/B;AA4CD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC3B,MAAM,yBAAyB,EAAE,GAAG,SAAS,EAC7C,UAAU,yBAAyB,uCAoBtC,CAAC"}
@@ -1,4 +1,3 @@
1
- import { logUnlayerError } from './log';
2
1
  export function isUnlayerMergeTagGroup(entry) {
3
2
  return 'mergeTags' in entry;
4
3
  }
@@ -6,61 +5,53 @@ const toMergeTagKey = (value)=>{
6
5
  const key = value.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).join('_');
7
6
  return key || value;
8
7
  };
9
- export const toUnlayerMergeTags = (tags, options)=>{
8
+ /**
9
+ * Normalizes the host `group` into the submenu path the tag belongs to:
10
+ * `'Custom Fields'` → `['Custom Fields']`, `['Forms', 'Intake']` → `['Forms', 'Intake']`.
11
+ * Blank segments are dropped; an empty result means the tag stays at the top level.
12
+ */ const toGroupPath = (group)=>{
13
+ const segments = Array.isArray(group) ? group : group === undefined ? [] : [
14
+ group
15
+ ];
16
+ return segments.map((segment)=>segment.trim()).filter(Boolean);
17
+ };
18
+ /** Returns the `mergeTags` record of the (possibly nested) group at `path`, creating groups on the way. */ const ensureGroup = (root, path)=>{
19
+ let current = root;
20
+ for (const groupName of path){
21
+ const groupKey = toMergeTagKey(groupName);
22
+ const existing = current[groupKey];
23
+ if (existing && isUnlayerMergeTagGroup(existing)) {
24
+ current = existing.mergeTags;
25
+ continue;
26
+ }
27
+ const created = {
28
+ name: groupName,
29
+ mergeTags: {}
30
+ };
31
+ current[groupKey] = created;
32
+ current = created.mergeTags;
33
+ }
34
+ return current;
35
+ };
36
+ /**
37
+ * Builds Unlayer's `mergeTags` config. With `groups` enabled (default) tags nest under the
38
+ * submenu path in `group`; `UnlayerStore` applies that shape once the editor is ready, since
39
+ * nested groups at `createEditor` time prevent DTE custom tools from loading.
40
+ */ export const toUnlayerMergeTags = (tags, options)=>{
10
41
  if (!(tags === null || tags === void 0 ? void 0 : tags.length)) {
11
42
  return undefined;
12
43
  }
13
44
  const groupsEnabled = (options === null || options === void 0 ? void 0 : options.groups) !== false;
14
45
  return tags.reduce((out, tag)=>{
15
- var _tag_group;
16
46
  const mergeTag = {
17
47
  name: tag.name,
18
48
  value: tag.propertyPath
19
49
  };
20
50
  const tagKey = toMergeTagKey(tag.id);
21
- const groupName = groupsEnabled ? (_tag_group = tag.group) === null || _tag_group === void 0 ? void 0 : _tag_group.trim() : undefined;
22
- if (!groupName) {
23
- out[tagKey] = mergeTag;
24
- return out;
25
- }
26
- const groupKey = toMergeTagKey(groupName);
27
- const existing = out[groupKey];
28
- if (existing && isUnlayerMergeTagGroup(existing)) {
29
- existing.mergeTags[tagKey] = mergeTag;
30
- return out;
31
- }
32
- out[groupKey] = {
33
- name: groupName,
34
- mergeTags: {
35
- [tagKey]: mergeTag
36
- }
37
- };
51
+ const groupPath = groupsEnabled ? toGroupPath(tag.group) : [];
52
+ ensureGroup(out, groupPath)[tagKey] = mergeTag;
38
53
  return out;
39
54
  }, {});
40
55
  };
41
- /**
42
- * Nested Unlayer groups passed to createEditor prevent DTE custom tools from
43
- * loading in the host app. Apply the 0.151 flat shape at init, then upgrade to
44
- * grouped submenus once the editor (and customJS tools) are ready.
45
- */ export const scheduleUnlayerMergeTags = (editor, tags)=>{
46
- const grouped = toUnlayerMergeTags(tags);
47
- if (!grouped) {
48
- return;
49
- }
50
- let isApplied = false;
51
- const apply = ()=>{
52
- if (isApplied) {
53
- return;
54
- }
55
- try {
56
- editor.setMergeTags(grouped);
57
- isApplied = true;
58
- } catch (error) {
59
- logUnlayerError('Failed to apply grouped merge tags', error);
60
- }
61
- };
62
- editor.addEventListener('editor:ready', apply);
63
- editor.addEventListener('design:loaded', apply);
64
- };
65
56
 
66
57
  //# sourceMappingURL=merge-tags.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/merge-tags.ts"],"sourcesContent":["import { logUnlayerError } from './log';\nimport { UnlayerEditorMergeTagInfo } from './unlayer-interface';\n\nexport interface UnlayerMergeTagLeaf {\n name: string;\n value: string;\n}\n\nexport interface UnlayerMergeTagGroup {\n name: string;\n mergeTags: Record<string, UnlayerMergeTagLeaf>;\n}\n\nexport type UnlayerMergeTagsConfig = Record<string, UnlayerMergeTagLeaf | UnlayerMergeTagGroup>;\n\nexport interface ToUnlayerMergeTagsOptions {\n /**\n * When false, ignore `group` and emit the flat 0.151 shape. Unlayer custom\n * tools fail to register if nested groups are present during createEditor.\n */\n groups?: boolean;\n}\n\nexport interface UnlayerMergeTagsEditor {\n addEventListener(event: string, cb: (arg: any) => void): void;\n setMergeTags(tags: UnlayerMergeTagsConfig): void;\n}\n\nexport function isUnlayerMergeTagGroup(\n entry: UnlayerMergeTagLeaf | UnlayerMergeTagGroup,\n): entry is UnlayerMergeTagGroup {\n return 'mergeTags' in entry;\n}\n\nconst toMergeTagKey = (value: string) => {\n const key = value\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter(Boolean)\n .join('_');\n\n return key || value;\n};\n\nexport const toUnlayerMergeTags = (\n tags: UnlayerEditorMergeTagInfo[] | undefined,\n options?: ToUnlayerMergeTagsOptions,\n) => {\n if (!tags?.length) {\n return undefined;\n }\n\n const groupsEnabled = options?.groups !== false;\n\n return tags.reduce<UnlayerMergeTagsConfig>((out, tag) => {\n const mergeTag: UnlayerMergeTagLeaf = {\n name: tag.name,\n value: tag.propertyPath,\n };\n const tagKey = toMergeTagKey(tag.id);\n const groupName = groupsEnabled ? tag.group?.trim() : undefined;\n\n if (!groupName) {\n out[tagKey] = mergeTag;\n return out;\n }\n\n const groupKey = toMergeTagKey(groupName);\n const existing = out[groupKey];\n\n if (existing && isUnlayerMergeTagGroup(existing)) {\n existing.mergeTags[tagKey] = mergeTag;\n return out;\n }\n\n out[groupKey] = {\n name: groupName,\n mergeTags: {\n [tagKey]: mergeTag,\n },\n };\n\n return out;\n }, {});\n};\n\n/**\n * Nested Unlayer groups passed to createEditor prevent DTE custom tools from\n * loading in the host app. Apply the 0.151 flat shape at init, then upgrade to\n * grouped submenus once the editor (and customJS tools) are ready.\n */\nexport const scheduleUnlayerMergeTags = (\n editor: UnlayerMergeTagsEditor,\n tags: UnlayerEditorMergeTagInfo[] | undefined,\n) => {\n const grouped = toUnlayerMergeTags(tags);\n\n if (!grouped) {\n return;\n }\n\n let isApplied = false;\n const apply = () => {\n if (isApplied) {\n return;\n }\n\n try {\n editor.setMergeTags(grouped);\n isApplied = true;\n } catch (error: unknown) {\n logUnlayerError('Failed to apply grouped merge tags', error);\n }\n };\n\n editor.addEventListener('editor:ready', apply);\n editor.addEventListener('design:loaded', apply);\n};\n"],"names":["logUnlayerError","isUnlayerMergeTagGroup","entry","toMergeTagKey","value","key","toLowerCase","split","filter","Boolean","join","toUnlayerMergeTags","tags","options","length","undefined","groupsEnabled","groups","reduce","out","tag","mergeTag","name","propertyPath","tagKey","id","groupName","group","trim","groupKey","existing","mergeTags","scheduleUnlayerMergeTags","editor","grouped","isApplied","apply","setMergeTags","error","addEventListener"],"mappings":"AAAA,SAASA,eAAe,QAAQ,QAAQ;AA4BxC,OAAO,SAASC,uBACZC,KAAiD;IAEjD,OAAO,eAAeA;AAC1B;AAEA,MAAMC,gBAAgB,CAACC;IACnB,MAAMC,MAAMD,MACPE,WAAW,GACXC,KAAK,CAAC,cACNC,MAAM,CAACC,SACPC,IAAI,CAAC;IAEV,OAAOL,OAAOD;AAClB;AAEA,OAAO,MAAMO,qBAAqB,CAC9BC,MACAC;IAEA,IAAI,EAACD,iBAAAA,2BAAAA,KAAME,MAAM,GAAE;QACf,OAAOC;IACX;IAEA,MAAMC,gBAAgBH,CAAAA,oBAAAA,8BAAAA,QAASI,MAAM,MAAK;IAE1C,OAAOL,KAAKM,MAAM,CAAyB,CAACC,KAAKC;YAMXA;QALlC,MAAMC,WAAgC;YAClCC,MAAMF,IAAIE,IAAI;YACdlB,OAAOgB,IAAIG,YAAY;QAC3B;QACA,MAAMC,SAASrB,cAAciB,IAAIK,EAAE;QACnC,MAAMC,YAAYV,iBAAgBI,aAAAA,IAAIO,KAAK,cAATP,iCAAAA,WAAWQ,IAAI,KAAKb;QAEtD,IAAI,CAACW,WAAW;YACZP,GAAG,CAACK,OAAO,GAAGH;YACd,OAAOF;QACX;QAEA,MAAMU,WAAW1B,cAAcuB;QAC/B,MAAMI,WAAWX,GAAG,CAACU,SAAS;QAE9B,IAAIC,YAAY7B,uBAAuB6B,WAAW;YAC9CA,SAASC,SAAS,CAACP,OAAO,GAAGH;YAC7B,OAAOF;QACX;QAEAA,GAAG,CAACU,SAAS,GAAG;YACZP,MAAMI;YACNK,WAAW;gBACP,CAACP,OAAO,EAAEH;YACd;QACJ;QAEA,OAAOF;IACX,GAAG,CAAC;AACR,EAAE;AAEF;;;;CAIC,GACD,OAAO,MAAMa,2BAA2B,CACpCC,QACArB;IAEA,MAAMsB,UAAUvB,mBAAmBC;IAEnC,IAAI,CAACsB,SAAS;QACV;IACJ;IAEA,IAAIC,YAAY;IAChB,MAAMC,QAAQ;QACV,IAAID,WAAW;YACX;QACJ;QAEA,IAAI;YACAF,OAAOI,YAAY,CAACH;YACpBC,YAAY;QAChB,EAAE,OAAOG,OAAgB;YACrBtC,gBAAgB,sCAAsCsC;QAC1D;IACJ;IAEAL,OAAOM,gBAAgB,CAAC,gBAAgBH;IACxCH,OAAOM,gBAAgB,CAAC,iBAAiBH;AAC7C,EAAE"}
1
+ {"version":3,"sources":["../src/merge-tags.ts"],"sourcesContent":["import { UnlayerEditorMergeTagInfo } from './unlayer-interface';\n\nexport interface UnlayerMergeTagLeaf {\n name: string;\n value: string;\n}\n\nexport interface UnlayerMergeTagGroup {\n name: string;\n /** Nested submenu: leaves and/or further groups (Unlayer supports arbitrary depth). */\n mergeTags: UnlayerMergeTagsConfig;\n}\n\nexport type UnlayerMergeTagsConfig = Record<string, UnlayerMergeTagLeaf | UnlayerMergeTagGroup>;\n\nexport interface ToUnlayerMergeTagsOptions {\n /**\n * When false, ignore `group` and emit the flat 0.151 shape. Unlayer custom\n * tools fail to register if nested groups are present during createEditor.\n */\n groups?: boolean;\n}\n\nexport function isUnlayerMergeTagGroup(\n entry: UnlayerMergeTagLeaf | UnlayerMergeTagGroup,\n): entry is UnlayerMergeTagGroup {\n return 'mergeTags' in entry;\n}\n\nconst toMergeTagKey = (value: string) => {\n const key = value\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter(Boolean)\n .join('_');\n\n return key || value;\n};\n\n/**\n * Normalizes the host `group` into the submenu path the tag belongs to:\n * `'Custom Fields'` → `['Custom Fields']`, `['Forms', 'Intake']` → `['Forms', 'Intake']`.\n * Blank segments are dropped; an empty result means the tag stays at the top level.\n */\nconst toGroupPath = (group: UnlayerEditorMergeTagInfo['group']): string[] => {\n const segments = Array.isArray(group) ? group : group === undefined ? [] : [group];\n\n return segments.map(segment => segment.trim()).filter(Boolean);\n};\n\n/** Returns the `mergeTags` record of the (possibly nested) group at `path`, creating groups on the way. */\nconst ensureGroup = (root: UnlayerMergeTagsConfig, path: string[]) => {\n let current = root;\n\n for (const groupName of path) {\n const groupKey = toMergeTagKey(groupName);\n const existing = current[groupKey];\n\n if (existing && isUnlayerMergeTagGroup(existing)) {\n current = existing.mergeTags;\n continue;\n }\n\n const created: UnlayerMergeTagGroup = { name: groupName, mergeTags: {} };\n current[groupKey] = created;\n current = created.mergeTags;\n }\n\n return current;\n};\n\n/**\n * Builds Unlayer's `mergeTags` config. With `groups` enabled (default) tags nest under the\n * submenu path in `group`; `UnlayerStore` applies that shape once the editor is ready, since\n * nested groups at `createEditor` time prevent DTE custom tools from loading.\n */\nexport const toUnlayerMergeTags = (\n tags: UnlayerEditorMergeTagInfo[] | undefined,\n options?: ToUnlayerMergeTagsOptions,\n) => {\n if (!tags?.length) {\n return undefined;\n }\n\n const groupsEnabled = options?.groups !== false;\n\n return tags.reduce<UnlayerMergeTagsConfig>((out, tag) => {\n const mergeTag: UnlayerMergeTagLeaf = {\n name: tag.name,\n value: tag.propertyPath,\n };\n const tagKey = toMergeTagKey(tag.id);\n const groupPath = groupsEnabled ? toGroupPath(tag.group) : [];\n\n ensureGroup(out, groupPath)[tagKey] = mergeTag;\n\n return out;\n }, {});\n};\n"],"names":["isUnlayerMergeTagGroup","entry","toMergeTagKey","value","key","toLowerCase","split","filter","Boolean","join","toGroupPath","group","segments","Array","isArray","undefined","map","segment","trim","ensureGroup","root","path","current","groupName","groupKey","existing","mergeTags","created","name","toUnlayerMergeTags","tags","options","length","groupsEnabled","groups","reduce","out","tag","mergeTag","propertyPath","tagKey","id","groupPath"],"mappings":"AAuBA,OAAO,SAASA,uBACZC,KAAiD;IAEjD,OAAO,eAAeA;AAC1B;AAEA,MAAMC,gBAAgB,CAACC;IACnB,MAAMC,MAAMD,MACPE,WAAW,GACXC,KAAK,CAAC,cACNC,MAAM,CAACC,SACPC,IAAI,CAAC;IAEV,OAAOL,OAAOD;AAClB;AAEA;;;;CAIC,GACD,MAAMO,cAAc,CAACC;IACjB,MAAMC,WAAWC,MAAMC,OAAO,CAACH,SAASA,QAAQA,UAAUI,YAAY,EAAE,GAAG;QAACJ;KAAM;IAElF,OAAOC,SAASI,GAAG,CAACC,CAAAA,UAAWA,QAAQC,IAAI,IAAIX,MAAM,CAACC;AAC1D;AAEA,yGAAyG,GACzG,MAAMW,cAAc,CAACC,MAA8BC;IAC/C,IAAIC,UAAUF;IAEd,KAAK,MAAMG,aAAaF,KAAM;QAC1B,MAAMG,WAAWtB,cAAcqB;QAC/B,MAAME,WAAWH,OAAO,CAACE,SAAS;QAElC,IAAIC,YAAYzB,uBAAuByB,WAAW;YAC9CH,UAAUG,SAASC,SAAS;YAC5B;QACJ;QAEA,MAAMC,UAAgC;YAAEC,MAAML;YAAWG,WAAW,CAAC;QAAE;QACvEJ,OAAO,CAACE,SAAS,GAAGG;QACpBL,UAAUK,QAAQD,SAAS;IAC/B;IAEA,OAAOJ;AACX;AAEA;;;;CAIC,GACD,OAAO,MAAMO,qBAAqB,CAC9BC,MACAC;IAEA,IAAI,EAACD,iBAAAA,2BAAAA,KAAME,MAAM,GAAE;QACf,OAAOjB;IACX;IAEA,MAAMkB,gBAAgBF,CAAAA,oBAAAA,8BAAAA,QAASG,MAAM,MAAK;IAE1C,OAAOJ,KAAKK,MAAM,CAAyB,CAACC,KAAKC;QAC7C,MAAMC,WAAgC;YAClCV,MAAMS,IAAIT,IAAI;YACdzB,OAAOkC,IAAIE,YAAY;QAC3B;QACA,MAAMC,SAAStC,cAAcmC,IAAII,EAAE;QACnC,MAAMC,YAAYT,gBAAgBvB,YAAY2B,IAAI1B,KAAK,IAAI,EAAE;QAE7DQ,YAAYiB,KAAKM,UAAU,CAACF,OAAO,GAAGF;QAEtC,OAAOF;IACX,GAAG,CAAC;AACR,EAAE"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Custom tools whose `values.id` is a per-instance GUID that must stay unique
3
+ * within a design. When such a tool is duplicated (content or row duplicate),
4
+ * Unlayer copies the values as-is, so the host regenerates the id of the copy.
5
+ */
6
+ export declare const INSTANCE_ID_TOOL_SLUGS: string[];
7
+ /**
8
+ * Generates an RFC 4122 v4 GUID (`3fa85f64-5717-4562-b3fc-2c963f66afa6`) with the
9
+ * platform `crypto.randomUUID()`. It is only exposed in secure contexts (https /
10
+ * localhost); when missing the error is logged and no id is produced.
11
+ */
12
+ export declare const generateInstanceId: () => string | undefined;
13
+ //# sourceMappingURL=instance-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-id.d.ts","sourceRoot":"","sources":["../../src/shared/instance-id.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,UAAqB,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,QAAO,MAAM,GAAG,SAU9C,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Custom tools whose `values.id` is a per-instance GUID that must stay unique
3
+ * within a design. When such a tool is duplicated (content or row duplicate),
4
+ * Unlayer copies the values as-is, so the host regenerates the id of the copy.
5
+ */ export const INSTANCE_ID_TOOL_SLUGS = [
6
+ 'embedded-image'
7
+ ];
8
+ /**
9
+ * Generates an RFC 4122 v4 GUID (`3fa85f64-5717-4562-b3fc-2c963f66afa6`) with the
10
+ * platform `crypto.randomUUID()`. It is only exposed in secure contexts (https /
11
+ * localhost); when missing the error is logged and no id is produced.
12
+ */ export const generateInstanceId = ()=>{
13
+ var _globalThis_crypto;
14
+ if (typeof ((_globalThis_crypto = globalThis.crypto) === null || _globalThis_crypto === void 0 ? void 0 : _globalThis_crypto.randomUUID) !== 'function') {
15
+ // eslint-disable-next-line no-console
16
+ console.error('crypto.randomUUID is not available (insecure context?), cannot generate an instance id');
17
+ return undefined;
18
+ }
19
+ return globalThis.crypto.randomUUID();
20
+ };
21
+
22
+ //# sourceMappingURL=instance-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/shared/instance-id.ts"],"sourcesContent":["/**\n * Custom tools whose `values.id` is a per-instance GUID that must stay unique\n * within a design. When such a tool is duplicated (content or row duplicate),\n * Unlayer copies the values as-is, so the host regenerates the id of the copy.\n */\nexport const INSTANCE_ID_TOOL_SLUGS = ['embedded-image'];\n\n/**\n * Generates an RFC 4122 v4 GUID (`3fa85f64-5717-4562-b3fc-2c963f66afa6`) with the\n * platform `crypto.randomUUID()`. It is only exposed in secure contexts (https /\n * localhost); when missing the error is logged and no id is produced.\n */\nexport const generateInstanceId = (): string | undefined => {\n if (typeof globalThis.crypto?.randomUUID !== 'function') {\n // eslint-disable-next-line no-console\n console.error(\n 'crypto.randomUUID is not available (insecure context?), cannot generate an instance id',\n );\n return undefined;\n }\n\n return globalThis.crypto.randomUUID();\n};\n"],"names":["INSTANCE_ID_TOOL_SLUGS","generateInstanceId","globalThis","crypto","randomUUID","console","error","undefined"],"mappings":"AAAA;;;;CAIC,GACD,OAAO,MAAMA,yBAAyB;IAAC;CAAiB,CAAC;AAEzD;;;;CAIC,GACD,OAAO,MAAMC,qBAAqB;QACnBC;IAAX,IAAI,SAAOA,qBAAAA,WAAWC,MAAM,cAAjBD,yCAAAA,mBAAmBE,UAAU,MAAK,YAAY;QACrD,sCAAsC;QACtCC,QAAQC,KAAK,CACT;QAEJ,OAAOC;IACX;IAEA,OAAOL,WAAWC,MAAM,CAACC,UAAU;AACvC,EAAE"}
package/dist/store.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { UnlayerEditorTwin } from './shared/const';
2
2
  import { FormFieldInfo, FormInfo } from './shared/forms';
3
- import { CreateUnlayerEditorProps, UnlayerDesignFormat, UnlayerRef } from './unlayer-interface';
3
+ import { CreateUnlayerEditorProps, UnlayerDesignFormat, UnlayerEditorMergeTagInfo, UnlayerRef } from './unlayer-interface';
4
4
  export interface UnlayerDesignChangeInfo {
5
5
  isToolsListChanged: boolean;
6
6
  }
@@ -18,6 +18,9 @@ export declare class UnlayerStore {
18
18
  private toolsReadyWatchdogId?;
19
19
  private formFieldsByFormId;
20
20
  private formFieldSamples;
21
+ private isEditorReady;
22
+ private isMergeTagsApplied;
23
+ private mergeTagsConfig?;
21
24
  private onMessageCB?;
22
25
  private onChangeCB?;
23
26
  private onSnapshotSaveCB?;
@@ -44,6 +47,16 @@ export declare class UnlayerStore {
44
47
  sendFormList: (forms: FormInfo[]) => void;
45
48
  sendFormFields: (formId: number, fields: FormFieldInfo[]) => void;
46
49
  sendCalcFieldLabels: (labels: Record<string, string>) => void;
50
+ /**
51
+ * Replaces the editor's merge tag menu. Nested groups passed to `createEditor` stop DTE
52
+ * custom tools from registering, so init only carries the flat shape and the grouped
53
+ * config is applied here once the editor is ready. A call before that (including the
54
+ * initial props) is parked; a later call replaces it. A failed apply is retried on the
55
+ * next `design:loaded`.
56
+ */
57
+ setMergeTags: (tags: UnlayerEditorMergeTagInfo[] | undefined) => void;
58
+ private applyMergeTags;
59
+ private onEditorReady;
47
60
  private onDesignLoaded;
48
61
  private onDesignUpdated;
49
62
  private onPostMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAA4C,MAAM,gBAAgB,CAAC;AAElG,OAAO,EACH,aAAa,EACb,QAAQ,EAGX,MAAM,gBAAgB,CAAC;AAUxB,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA0IhG,MAAM,WAAW,uBAAuB;IACpC,kBAAkB,EAAE,OAAO,CAAC;CAC/B;AAmBD,qBAAa,YAAY;IAyBT,QAAQ,CAAC,KAAK,EAAE,wBAAwB;IAxBpD,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;IAC1D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAc;IAElD,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAC,CAAoB;IACnC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,gBAAgB,CAA+B;IAEvD,OAAO,CAAC,WAAW,CAAC,CAAoC;IACxD,OAAO,CAAC,UAAU,CAAC,CAA0C;IAC7D,OAAO,CAAC,gBAAgB,CAAC,CAAwC;IACjE,OAAO,CAAC,SAAS,CAAC,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAC,CAA2C;IAC7D,OAAO,CAAC,SAAS,CAAC,CAAgD;IAClE,OAAO,CAAC,cAAc,CAAC,CAA2B;IAClD,OAAO,CAAC,iBAAiB,CAAC,CAAkC;IAC5D,OAAO,CAAC,mBAAmB,CAAC,CAAgC;gBAEvC,KAAK,EAAE,wBAAwB;IAqCpD,IAAI,GAAU,WAAW,cAAc,mBAkCrC;IAEF,OAAO,aAWL;IAEF,OAAO,GAAI,MAAM,iBAAiB,UAGhC;IAEF,SAAS,GAAI,SAAS,mBAAmB,UAUvC;IAEF,WAAW,GAAI,WAAW,YAAY,CAAC,YAAY,CAAC,UAElD;IAEF,iBAAiB,GAAI,iBAAiB,YAAY,CAAC,kBAAkB,CAAC,UAEpE;IAEF,UAAU,GAAI,UAAU,YAAY,CAAC,WAAW,CAAC,UAE/C;IAEF,UAAU,GAAI,UAAU,YAAY,CAAC,WAAW,CAAC,UAE/C;IAEF,UAAU,GAAI,UAAU,YAAY,CAAC,WAAW,CAAC,UAE/C;IAEF,YAAY,GAAI,YAAY,YAAY,CAAC,aAAa,CAAC,UAErD;IAEF,eAAe,GAAI,eAAe,YAAY,CAAC,gBAAgB,CAAC,UAE9D;IAEF,kBAAkB,GAAI,kBAAkB,YAAY,CAAC,mBAAmB,CAAC,UAEvE;IAEF,oBAAoB,GAAI,oBAAoB,YAAY,CAAC,qBAAqB,CAAC,UAE7E;IAEF,YAAY,GAAI,OAAO,QAAQ,EAAE,UAE/B;IAEF,cAAc,GAAI,QAAQ,MAAM,EAAE,QAAQ,aAAa,EAAE,UAIvD;IAEF,mBAAmB,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAEnD;IAEF,OAAO,CAAC,cAAc,CAQpB;IAEF,OAAO,CAAC,eAAe,CAmCrB;IAEF,OAAO,CAAC,aAAa,CA0EnB;IAEF,OAAO,CAAC,sBAAsB,CAgB5B;IAEF,OAAO,CAAC,0BAA0B,CAyBhC;IAEF,OAAO,CAAC,gBAAgB,CAqCtB;IAEF,OAAO,CAAC,4BAA4B,CAiBlC;IAEF,OAAO,CAAC,WAAW,CAUjB;IAEF,OAAO,CAAC,WAAW,CAuCjB;IAEF,OAAO,CAAC,uBAAuB,CAmB7B;IAEF,OAAO,CAAC,uBAAuB,CAO7B;IAEF,OAAO,CAAC,aAAa,CA+CnB;CACL"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/dist/store.js CHANGED
@@ -13,12 +13,13 @@ function _define_property(obj, key, value) {
13
13
  }
14
14
  import { loadScript } from './loadScript';
15
15
  import { logUnlayerError } from './log';
16
+ import { toUnlayerMergeTags } from './merge-tags';
16
17
  import { defaultImageValidation } from './shared/configs';
17
18
  import { unlayerSupportedFonts } from './shared/fonts';
18
19
  import { getFormFieldSampleValue, parseFormFieldKey } from './shared/forms';
19
20
  import { schemaBuildMap, schemaIsDate } from './shared/schema';
20
21
  import { unlayerToolsParseTwinKey } from './shared/tools';
21
- import { unlayerToolsIterate } from './tools';
22
+ import { unlayerToolsDedupeInstanceIds, unlayerToolsIterate } from './tools';
22
23
  import { createUnlayerEditor, DesignUpdatedEventType } from './unlayer';
23
24
  const defaultScriptUrl = 'https://editor.unlayer.com/embed.js?2';
24
25
  const UNLAYER_TOOLS_READY_TIMEOUT_MS = 30000;
@@ -159,6 +160,9 @@ export class UnlayerStore {
159
160
  _define_property(this, "toolsReadyWatchdogId", void 0);
160
161
  _define_property(this, "formFieldsByFormId", void 0);
161
162
  _define_property(this, "formFieldSamples", void 0);
163
+ _define_property(this, "isEditorReady", void 0);
164
+ _define_property(this, "isMergeTagsApplied", void 0);
165
+ _define_property(this, "mergeTagsConfig", void 0);
162
166
  _define_property(this, "onMessageCB", void 0);
163
167
  _define_property(this, "onChangeCB", void 0);
164
168
  _define_property(this, "onSnapshotSaveCB", void 0);
@@ -184,6 +188,15 @@ export class UnlayerStore {
184
188
  _define_property(this, "sendFormList", void 0);
185
189
  _define_property(this, "sendFormFields", void 0);
186
190
  _define_property(this, "sendCalcFieldLabels", void 0);
191
+ /**
192
+ * Replaces the editor's merge tag menu. Nested groups passed to `createEditor` stop DTE
193
+ * custom tools from registering, so init only carries the flat shape and the grouped
194
+ * config is applied here once the editor is ready. A call before that (including the
195
+ * initial props) is parked; a later call replaces it. A failed apply is retried on the
196
+ * next `design:loaded`.
197
+ */ _define_property(this, "setMergeTags", void 0);
198
+ _define_property(this, "applyMergeTags", void 0);
199
+ _define_property(this, "onEditorReady", void 0);
187
200
  _define_property(this, "onDesignLoaded", void 0);
188
201
  _define_property(this, "onDesignUpdated", void 0);
189
202
  _define_property(this, "onPostMessage", void 0);
@@ -203,19 +216,24 @@ export class UnlayerStore {
203
216
  this.hasToolsRegistered = false;
204
217
  this.formFieldsByFormId = {};
205
218
  this.formFieldSamples = {};
219
+ this.isEditorReady = false;
220
+ this.isMergeTagsApplied = false;
206
221
  this.init = async (container)=>{
207
222
  if (this.isInit) {
208
223
  return;
209
224
  }
210
225
  this.isInit = true;
211
226
  try {
212
- var _container_querySelector;
227
+ var // The host may already have pushed a newer set through `setMergeTags`; keep it.
228
+ _this_mergeTagsConfig, _container_querySelector;
213
229
  setTimeout(()=>window.addEventListener('message', this.onPostMessage));
214
230
  await loadScript(defaultScriptUrl);
215
231
  if (!window.unlayer) {
216
232
  throw new Error('Unlayer embed script loaded but window.unlayer is missing');
217
233
  }
218
234
  this.editor = createUnlayerEditor(container, this.props);
235
+ (_this_mergeTagsConfig = this.mergeTagsConfig) !== null && _this_mergeTagsConfig !== void 0 ? _this_mergeTagsConfig : this.mergeTagsConfig = toUnlayerMergeTags(this.props.mergeTags);
236
+ this.editor.addEventListener('editor:ready', this.onEditorReady);
219
237
  this.editor.addEventListener('design:loaded', this.onDesignLoaded);
220
238
  this.editor.addEventListener('design:updated', this.onDesignUpdated);
221
239
  this.editor.registerCallback('image', this.uploadImage);
@@ -235,6 +253,7 @@ export class UnlayerStore {
235
253
  this.clearToolsReadyWatchdog();
236
254
  window.removeEventListener('message', this.onPostMessage);
237
255
  if (this.editor) {
256
+ this.editor.removeEventListener('editor:ready', this.onEditorReady);
238
257
  this.editor.removeEventListener('design:loaded', this.onDesignLoaded);
239
258
  this.editor.removeEventListener('design:updated', this.onDesignUpdated);
240
259
  this.editor.unregisterCallback('image', this.uploadImage);
@@ -300,7 +319,29 @@ export class UnlayerStore {
300
319
  labels
301
320
  });
302
321
  };
322
+ this.setMergeTags = (tags)=>{
323
+ this.mergeTagsConfig = toUnlayerMergeTags(tags);
324
+ this.isMergeTagsApplied = false;
325
+ this.applyMergeTags();
326
+ };
327
+ this.applyMergeTags = ()=>{
328
+ if (!this.editor || !this.isEditorReady || this.isMergeTagsApplied || !this.mergeTagsConfig) {
329
+ return;
330
+ }
331
+ try {
332
+ this.editor.setMergeTags(this.mergeTagsConfig);
333
+ this.isMergeTagsApplied = true;
334
+ } catch (error) {
335
+ logUnlayerError('Failed to apply merge tags', error);
336
+ }
337
+ };
338
+ this.onEditorReady = ()=>{
339
+ this.isEditorReady = true;
340
+ this.applyMergeTags();
341
+ };
303
342
  this.onDesignLoaded = ()=>{
343
+ // A loaded design means the editor is up even if `editor:ready` never reached us.
344
+ this.onEditorReady();
304
345
  if (!this.hasDesign) {
305
346
  var _this_editor;
306
347
  this.hasDesign = true;
@@ -316,7 +357,7 @@ export class UnlayerStore {
316
357
  if (isToolAdded) {
317
358
  var _this_editor;
318
359
  (_this_editor = this.editor) === null || _this_editor === void 0 ? void 0 : _this_editor.exportHtml((data)=>{
319
- var _this_onChangeCB, _this;
360
+ var _event_item_values__meta, _event_item_values, _event_item, _this_onChangeCB, _this;
320
361
  let hasChanges = false;
321
362
  unlayerToolsIterate(data.design, (tool)=>{
322
363
  var _tool_slug;
@@ -331,6 +372,10 @@ export class UnlayerStore {
331
372
  tool.slug = realTool.slug;
332
373
  }
333
374
  });
375
+ // Duplicated contents/rows carry the original's instance GUIDs; give copies new ones.
376
+ if (unlayerToolsDedupeInstanceIds(data.design, (_event_item = event.item) === null || _event_item === void 0 ? void 0 : (_event_item_values = _event_item.values) === null || _event_item_values === void 0 ? void 0 : (_event_item_values__meta = _event_item_values._meta) === null || _event_item_values__meta === void 0 ? void 0 : _event_item_values__meta.htmlID)) {
377
+ hasChanges = true;
378
+ }
334
379
  if (hasChanges) {
335
380
  this.setDesign(data.design);
336
381
  }
@@ -642,6 +687,9 @@ export class UnlayerStore {
642
687
  },
643
688
  sendCalcFieldLabels: (labels)=>{
644
689
  this.sendCalcFieldLabels(labels);
690
+ },
691
+ setMergeTags: (tags)=>{
692
+ this.setMergeTags(tags);
645
693
  }
646
694
  };
647
695
  }