@templatical/types 0.0.1 → 0.0.3

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.cjs CHANGED
@@ -26,16 +26,18 @@ __export(index_exports, {
26
26
  DEFAULT_TEMPLATE_DEFAULTS: () => DEFAULT_TEMPLATE_DEFAULTS,
27
27
  DIVIDER_BLOCK_DEFAULTS: () => DIVIDER_BLOCK_DEFAULTS,
28
28
  EventEmitter: () => EventEmitter,
29
+ HEADING_LEVEL_FONT_SIZE: () => HEADING_LEVEL_FONT_SIZE,
29
30
  HTML_BLOCK_DEFAULTS: () => HTML_BLOCK_DEFAULTS,
30
31
  IMAGE_BLOCK_DEFAULTS: () => IMAGE_BLOCK_DEFAULTS,
31
32
  MENU_BLOCK_DEFAULTS: () => MENU_BLOCK_DEFAULTS,
33
+ PARAGRAPH_BLOCK_DEFAULTS: () => PARAGRAPH_BLOCK_DEFAULTS,
32
34
  SECTION_BLOCK_DEFAULTS: () => SECTION_BLOCK_DEFAULTS,
33
35
  SOCIAL_ICONS_BLOCK_DEFAULTS: () => SOCIAL_ICONS_BLOCK_DEFAULTS,
34
36
  SPACER_BLOCK_DEFAULTS: () => SPACER_BLOCK_DEFAULTS,
35
37
  SYNTAX_PRESETS: () => SYNTAX_PRESETS,
36
38
  SdkError: () => SdkError,
37
39
  TABLE_BLOCK_DEFAULTS: () => TABLE_BLOCK_DEFAULTS,
38
- TEXT_BLOCK_DEFAULTS: () => TEXT_BLOCK_DEFAULTS,
40
+ TITLE_BLOCK_DEFAULTS: () => TITLE_BLOCK_DEFAULTS,
39
41
  VIDEO_BLOCK_DEFAULTS: () => VIDEO_BLOCK_DEFAULTS,
40
42
  cloneBlock: () => cloneBlock,
41
43
  containsMergeTag: () => containsMergeTag,
@@ -48,11 +50,12 @@ __export(index_exports, {
48
50
  createHtmlBlock: () => createHtmlBlock,
49
51
  createImageBlock: () => createImageBlock,
50
52
  createMenuBlock: () => createMenuBlock,
53
+ createParagraphBlock: () => createParagraphBlock,
51
54
  createSectionBlock: () => createSectionBlock,
52
55
  createSocialIconsBlock: () => createSocialIconsBlock,
53
56
  createSpacerBlock: () => createSpacerBlock,
54
57
  createTableBlock: () => createTableBlock,
55
- createTextBlock: () => createTextBlock,
58
+ createTitleBlock: () => createTitleBlock,
56
59
  createVideoBlock: () => createVideoBlock,
57
60
  deepMergeDefaults: () => deepMergeDefaults,
58
61
  generateId: () => generateId,
@@ -67,11 +70,12 @@ __export(index_exports, {
67
70
  isLogicMergeTagValue: () => isLogicMergeTagValue,
68
71
  isMenu: () => isMenu,
69
72
  isMergeTagValue: () => isMergeTagValue,
73
+ isParagraph: () => isParagraph,
70
74
  isSection: () => isSection,
71
75
  isSocialIcons: () => isSocialIcons,
72
76
  isSpacer: () => isSpacer,
73
77
  isTable: () => isTable,
74
- isText: () => isText,
78
+ isTitle: () => isTitle,
75
79
  isVideo: () => isVideo,
76
80
  resolveHtmlLogicMergeTagLabels: () => resolveHtmlLogicMergeTagLabels,
77
81
  resolveHtmlMergeTagLabels: () => resolveHtmlMergeTagLabels,
@@ -80,12 +84,23 @@ __export(index_exports, {
80
84
  });
81
85
  module.exports = __toCommonJS(index_exports);
82
86
 
87
+ // src/blocks.ts
88
+ var HEADING_LEVEL_FONT_SIZE = {
89
+ 1: 36,
90
+ 2: 28,
91
+ 3: 22,
92
+ 4: 18
93
+ };
94
+
83
95
  // src/guards.ts
84
96
  function isSection(block) {
85
97
  return block.type === "section";
86
98
  }
87
- function isText(block) {
88
- return block.type === "text";
99
+ function isTitle(block) {
100
+ return block.type === "title";
101
+ }
102
+ function isParagraph(block) {
103
+ return block.type === "paragraph";
89
104
  }
90
105
  function isImage(block) {
91
106
  return block.type === "image";
@@ -122,12 +137,14 @@ function isCustomBlock(block) {
122
137
  }
123
138
 
124
139
  // src/defaults.ts
125
- var TEXT_BLOCK_DEFAULTS = {
126
- content: "<p>Enter your text here</p>",
127
- fontSize: 16,
140
+ var TITLE_BLOCK_DEFAULTS = {
141
+ content: "<p>Enter your title</p>",
142
+ level: 2,
128
143
  color: "#1a1a1a",
129
- textAlign: "left",
130
- fontWeight: "normal"
144
+ textAlign: "left"
145
+ };
146
+ var PARAGRAPH_BLOCK_DEFAULTS = {
147
+ content: "<p>Enter your text here</p>"
131
148
  };
132
149
  var IMAGE_BLOCK_DEFAULTS = {
133
150
  src: "",
@@ -211,7 +228,8 @@ var COUNTDOWN_BLOCK_DEFAULTS = {
211
228
  hideOnExpiry: false
212
229
  };
213
230
  var DEFAULT_BLOCK_DEFAULTS = {
214
- text: TEXT_BLOCK_DEFAULTS,
231
+ title: TITLE_BLOCK_DEFAULTS,
232
+ paragraph: PARAGRAPH_BLOCK_DEFAULTS,
215
233
  image: IMAGE_BLOCK_DEFAULTS,
216
234
  button: BUTTON_BLOCK_DEFAULTS,
217
235
  divider: DIVIDER_BLOCK_DEFAULTS,
@@ -227,7 +245,7 @@ var DEFAULT_BLOCK_DEFAULTS = {
227
245
  var DEFAULT_TEMPLATE_DEFAULTS = {
228
246
  width: 600,
229
247
  backgroundColor: "#ffffff",
230
- fontFamily: "Arial, sans-serif"
248
+ fontFamily: "Arial"
231
249
  };
232
250
  function isPlainObject(value) {
233
251
  return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
@@ -253,7 +271,7 @@ function deepMergeDefaults(base, overrides) {
253
271
  }
254
272
 
255
273
  // src/template.ts
256
- function createDefaultTemplateContent(defaultFontFamily = "Arial, sans-serif", templateDefaults) {
274
+ function createDefaultTemplateContent(defaultFontFamily = "Arial", templateDefaults) {
257
275
  return {
258
276
  blocks: [],
259
277
  settings: {
@@ -267,10 +285,7 @@ function createDefaultTemplateContent(defaultFontFamily = "Arial, sans-serif", t
267
285
  // src/factory.ts
268
286
  function applyDefaults(base, partial) {
269
287
  if (!partial || Object.keys(partial).length === 0) return base;
270
- return deepMergeDefaults(
271
- base,
272
- partial
273
- );
288
+ return deepMergeDefaults(base, partial);
274
289
  }
275
290
  function generateId() {
276
291
  return crypto.randomUUID();
@@ -284,11 +299,20 @@ function createDefaultStyles(padding = 10) {
284
299
  margin: createDefaultSpacing(0)
285
300
  };
286
301
  }
287
- function createTextBlock(partial = {}) {
302
+ function createTitleBlock(partial = {}) {
288
303
  const base = {
289
304
  id: generateId(),
290
- type: "text",
291
- ...TEXT_BLOCK_DEFAULTS,
305
+ type: "title",
306
+ ...TITLE_BLOCK_DEFAULTS,
307
+ styles: createDefaultStyles()
308
+ };
309
+ return applyDefaults(base, partial);
310
+ }
311
+ function createParagraphBlock(partial = {}) {
312
+ const base = {
313
+ id: generateId(),
314
+ type: "paragraph",
315
+ ...PARAGRAPH_BLOCK_DEFAULTS,
292
316
  styles: createDefaultStyles()
293
317
  };
294
318
  return applyDefaults(base, partial);
@@ -438,8 +462,10 @@ function createBlock(type, blockDefaults) {
438
462
  switch (type) {
439
463
  case "section":
440
464
  return createSectionBlock(blockDefaults?.section);
441
- case "text":
442
- return createTextBlock(blockDefaults?.text);
465
+ case "title":
466
+ return createTitleBlock(blockDefaults?.title);
467
+ case "paragraph":
468
+ return createParagraphBlock(blockDefaults?.paragraph);
443
469
  case "image":
444
470
  return createImageBlock(blockDefaults?.image);
445
471
  case "button":
@@ -477,9 +503,7 @@ function cloneBlock(block) {
477
503
 
478
504
  // src/events.ts
479
505
  var EventEmitter = class {
480
- constructor() {
481
- this.handlers = /* @__PURE__ */ new Map();
482
- }
506
+ handlers = /* @__PURE__ */ new Map();
483
507
  on(event, handler) {
484
508
  if (!this.handlers.has(event)) {
485
509
  this.handlers.set(event, /* @__PURE__ */ new Set());
@@ -642,16 +666,18 @@ var SdkError = class extends Error {
642
666
  DEFAULT_TEMPLATE_DEFAULTS,
643
667
  DIVIDER_BLOCK_DEFAULTS,
644
668
  EventEmitter,
669
+ HEADING_LEVEL_FONT_SIZE,
645
670
  HTML_BLOCK_DEFAULTS,
646
671
  IMAGE_BLOCK_DEFAULTS,
647
672
  MENU_BLOCK_DEFAULTS,
673
+ PARAGRAPH_BLOCK_DEFAULTS,
648
674
  SECTION_BLOCK_DEFAULTS,
649
675
  SOCIAL_ICONS_BLOCK_DEFAULTS,
650
676
  SPACER_BLOCK_DEFAULTS,
651
677
  SYNTAX_PRESETS,
652
678
  SdkError,
653
679
  TABLE_BLOCK_DEFAULTS,
654
- TEXT_BLOCK_DEFAULTS,
680
+ TITLE_BLOCK_DEFAULTS,
655
681
  VIDEO_BLOCK_DEFAULTS,
656
682
  cloneBlock,
657
683
  containsMergeTag,
@@ -664,11 +690,12 @@ var SdkError = class extends Error {
664
690
  createHtmlBlock,
665
691
  createImageBlock,
666
692
  createMenuBlock,
693
+ createParagraphBlock,
667
694
  createSectionBlock,
668
695
  createSocialIconsBlock,
669
696
  createSpacerBlock,
670
697
  createTableBlock,
671
- createTextBlock,
698
+ createTitleBlock,
672
699
  createVideoBlock,
673
700
  deepMergeDefaults,
674
701
  generateId,
@@ -683,11 +710,12 @@ var SdkError = class extends Error {
683
710
  isLogicMergeTagValue,
684
711
  isMenu,
685
712
  isMergeTagValue,
713
+ isParagraph,
686
714
  isSection,
687
715
  isSocialIcons,
688
716
  isSpacer,
689
717
  isTable,
690
- isText,
718
+ isTitle,
691
719
  isVideo,
692
720
  resolveHtmlLogicMergeTagLabels,
693
721
  resolveHtmlMergeTagLabels,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/guards.ts","../src/defaults.ts","../src/template.ts","../src/factory.ts","../src/events.ts","../src/merge-tags.ts","../src/config.ts"],"sourcesContent":["// Blocks\nexport type {\n BaseBlock,\n Block,\n BlockStyles,\n BlockType,\n BlockVisibility,\n ButtonBlock,\n ColumnLayout,\n CountdownBlock,\n CustomBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n MenuItemData,\n ResponsiveStyles,\n SectionBlock,\n SocialIcon,\n SocialIconSize,\n SocialIconStyle,\n SocialIconsBlock,\n SocialPlatform,\n SpacerBlock,\n SpacingValue,\n TableBlock,\n TableCellData,\n TableRowData,\n TextBlock,\n VideoBlock,\n} from \"./blocks\";\n\n// Type guards\nexport {\n isButton,\n isCountdown,\n isCustomBlock,\n isDivider,\n isHtml,\n isImage,\n isMenu,\n isSection,\n isSocialIcons,\n isSpacer,\n isTable,\n isText,\n isVideo,\n} from \"./guards\";\n\n// Template\nexport type { TemplateContent, TemplateSettings } from \"./template\";\nexport { createDefaultTemplateContent } from \"./template\";\n\n// Defaults\nexport type { BlockDefaults, TemplateDefaults } from \"./defaults\";\nexport {\n deepMergeDefaults,\n DEFAULT_BLOCK_DEFAULTS,\n DEFAULT_TEMPLATE_DEFAULTS,\n TEXT_BLOCK_DEFAULTS,\n IMAGE_BLOCK_DEFAULTS,\n BUTTON_BLOCK_DEFAULTS,\n DIVIDER_BLOCK_DEFAULTS,\n SECTION_BLOCK_DEFAULTS,\n VIDEO_BLOCK_DEFAULTS,\n SOCIAL_ICONS_BLOCK_DEFAULTS,\n SPACER_BLOCK_DEFAULTS,\n HTML_BLOCK_DEFAULTS,\n MENU_BLOCK_DEFAULTS,\n TABLE_BLOCK_DEFAULTS,\n COUNTDOWN_BLOCK_DEFAULTS,\n} from \"./defaults\";\n\n// Custom blocks\nexport type {\n CustomBlockBooleanField,\n CustomBlockColorField,\n CustomBlockDefinition,\n CustomBlockField,\n CustomBlockFieldBase,\n CustomBlockFieldType,\n CustomBlockImageField,\n CustomBlockNumberField,\n CustomBlockRepeatableField,\n CustomBlockSelectField,\n CustomBlockTextField,\n CustomBlockTextareaField,\n DataSourceConfig,\n DataSourceFetchContext,\n SelectOption,\n} from \"./custom-blocks\";\n\n// Block factory\nexport {\n cloneBlock,\n createBlock,\n createButtonBlock,\n createCountdownBlock,\n createCustomBlock,\n createDividerBlock,\n createHtmlBlock,\n createImageBlock,\n createMenuBlock,\n createSectionBlock,\n createSocialIconsBlock,\n createSpacerBlock,\n createTableBlock,\n createTextBlock,\n createVideoBlock,\n generateId,\n} from \"./factory\";\n\n// Event emitter\nexport { EventEmitter } from \"./events\";\n\n// Merge tags\nexport type { SyntaxPreset, SyntaxPresetName } from \"./merge-tags\";\nexport {\n containsMergeTag,\n getLogicMergeTagKeyword,\n getMergeTagLabel,\n isLogicMergeTagValue,\n isMergeTagValue,\n resolveHtmlLogicMergeTagLabels,\n resolveHtmlMergeTagLabels,\n resolveSyntax,\n restoreMergeTagMarkup,\n SYNTAX_PRESETS,\n} from \"./merge-tags\";\n\n// Config\nexport type {\n CustomFont,\n DisplayCondition,\n DisplayConditionsConfig,\n ExportResult,\n FontsConfig,\n MediaResult,\n MergeTag,\n MergeTagsConfig,\n ThemeOverrides,\n ViewportSize,\n} from \"./config\";\nexport { SdkError } from \"./config\";\n\n// Cloud types (zero runtime cost — all type-only except re-exported ViewportSize/SyntaxPreset)\nexport type {\n AiChatMessage,\n AiConfig,\n AiGenerateOptions,\n AiScoreOptions,\n AiStreamEvent,\n ApiError,\n ApiResponse,\n AuthConfig,\n AuthRequestOptions,\n CategoryScore,\n Collaborator,\n CollaborationConfig,\n Comment,\n CommentEvent,\n CommentEventType,\n CommentThread,\n CreateCommentData,\n DirectAuthConfig,\n EditorState,\n FindingSeverity,\n SdkAuthConfig,\n HealthCheckResult,\n McpConfig,\n McpOperation,\n McpOperationPayload,\n PlanConfig,\n PlanFeatures,\n PlanLimits,\n ProxyAuthConfig,\n RewriteData,\n SavedModule,\n SaveResult,\n ScoringCategory,\n ScoringFinding,\n ScoringResult,\n Template,\n TemplaticalConfig,\n TemplaticalInstance,\n TemplateSnapshot,\n TestEmailConfig,\n TokenData,\n UpdateCommentData,\n UserConfig,\n WebSocketServerConfig,\n} from \"./cloud\";\n","import type {\n Block,\n ButtonBlock,\n CountdownBlock,\n CustomBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n TableBlock,\n TextBlock,\n VideoBlock,\n} from \"./blocks\";\n\nexport function isSection(block: Block): block is SectionBlock {\n return block.type === \"section\";\n}\n\nexport function isText(block: Block): block is TextBlock {\n return block.type === \"text\";\n}\n\nexport function isImage(block: Block): block is ImageBlock {\n return block.type === \"image\";\n}\n\nexport function isButton(block: Block): block is ButtonBlock {\n return block.type === \"button\";\n}\n\nexport function isDivider(block: Block): block is DividerBlock {\n return block.type === \"divider\";\n}\n\nexport function isVideo(block: Block): block is VideoBlock {\n return block.type === \"video\";\n}\n\nexport function isSocialIcons(block: Block): block is SocialIconsBlock {\n return block.type === \"social\";\n}\n\nexport function isSpacer(block: Block): block is SpacerBlock {\n return block.type === \"spacer\";\n}\n\nexport function isHtml(block: Block): block is HtmlBlock {\n return block.type === \"html\";\n}\n\nexport function isMenu(block: Block): block is MenuBlock {\n return block.type === \"menu\";\n}\n\nexport function isTable(block: Block): block is TableBlock {\n return block.type === \"table\";\n}\n\nexport function isCountdown(block: Block): block is CountdownBlock {\n return block.type === \"countdown\";\n}\n\nexport function isCustomBlock(block: Block): block is CustomBlock {\n return block.type === \"custom\";\n}\n","import type {\n ButtonBlock,\n CountdownBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n TableBlock,\n TextBlock,\n VideoBlock,\n} from \"./blocks\";\nimport type { TemplateSettings } from \"./template\";\n\ntype BlockDefaultsFor<T> = Partial<Omit<T, \"id\" | \"type\">>;\n\nexport interface BlockDefaults {\n text?: BlockDefaultsFor<TextBlock>;\n image?: BlockDefaultsFor<ImageBlock>;\n button?: BlockDefaultsFor<ButtonBlock>;\n divider?: BlockDefaultsFor<DividerBlock>;\n section?: BlockDefaultsFor<SectionBlock>;\n video?: BlockDefaultsFor<VideoBlock>;\n social?: BlockDefaultsFor<SocialIconsBlock>;\n spacer?: BlockDefaultsFor<SpacerBlock>;\n html?: BlockDefaultsFor<HtmlBlock>;\n menu?: BlockDefaultsFor<MenuBlock>;\n table?: BlockDefaultsFor<TableBlock>;\n countdown?: BlockDefaultsFor<CountdownBlock>;\n}\n\nexport type TemplateDefaults = Partial<TemplateSettings>;\n\n// ---------------------------------------------------------------------------\n// Built-in default values — single source of truth for factories & consumers\n// ---------------------------------------------------------------------------\n\nexport const TEXT_BLOCK_DEFAULTS: BlockDefaultsFor<TextBlock> = {\n content: \"<p>Enter your text here</p>\",\n fontSize: 16,\n color: \"#1a1a1a\",\n textAlign: \"left\",\n fontWeight: \"normal\",\n};\n\nexport const IMAGE_BLOCK_DEFAULTS: BlockDefaultsFor<ImageBlock> = {\n src: \"\",\n alt: \"\",\n width: \"full\",\n align: \"center\",\n};\n\nexport const BUTTON_BLOCK_DEFAULTS: BlockDefaultsFor<ButtonBlock> = {\n text: \"Click Here\",\n url: \"\",\n backgroundColor: \"#333333\",\n textColor: \"#ffffff\",\n borderRadius: 6,\n fontSize: 15,\n buttonPadding: { top: 12, right: 24, bottom: 12, left: 24 },\n};\n\nexport const DIVIDER_BLOCK_DEFAULTS: BlockDefaultsFor<DividerBlock> = {\n lineStyle: \"solid\",\n color: \"#e0e0e0\",\n thickness: 1,\n width: \"full\",\n};\n\nexport const SECTION_BLOCK_DEFAULTS: BlockDefaultsFor<SectionBlock> = {\n columns: \"1\",\n};\n\nexport const VIDEO_BLOCK_DEFAULTS: BlockDefaultsFor<VideoBlock> = {\n url: \"\",\n thumbnailUrl: \"\",\n alt: \"Video\",\n width: \"full\",\n align: \"center\",\n};\n\nexport const SOCIAL_ICONS_BLOCK_DEFAULTS: BlockDefaultsFor<SocialIconsBlock> = {\n iconStyle: \"solid\",\n iconSize: \"medium\",\n spacing: 10,\n align: \"center\",\n};\n\nexport const SPACER_BLOCK_DEFAULTS: BlockDefaultsFor<SpacerBlock> = {\n height: 24,\n};\n\nexport const HTML_BLOCK_DEFAULTS: BlockDefaultsFor<HtmlBlock> = {\n content: \"\",\n};\n\nexport const MENU_BLOCK_DEFAULTS: BlockDefaultsFor<MenuBlock> = {\n fontSize: 15,\n color: \"#1a1a1a\",\n textAlign: \"center\",\n separator: \"|\",\n separatorColor: \"#e0e0e0\",\n spacing: 10,\n};\n\nexport const TABLE_BLOCK_DEFAULTS: BlockDefaultsFor<TableBlock> = {\n hasHeaderRow: true,\n borderColor: \"#e0e0e0\",\n borderWidth: 1,\n cellPadding: 8,\n fontSize: 15,\n color: \"#1a1a1a\",\n textAlign: \"left\",\n};\n\nexport const COUNTDOWN_BLOCK_DEFAULTS: BlockDefaultsFor<CountdownBlock> = {\n targetDate: \"\",\n timezone: \"UTC\",\n showDays: true,\n showHours: true,\n showMinutes: true,\n showSeconds: true,\n separator: \":\",\n digitFontSize: 32,\n digitColor: \"#1a1a1a\",\n labelColor: \"#6b7280\",\n labelFontSize: 12,\n backgroundColor: \"#ffffff\",\n labelDays: \"Days\",\n labelHours: \"Hours\",\n labelMinutes: \"Minutes\",\n labelSeconds: \"Seconds\",\n expiredMessage: \"This offer has expired\",\n expiredImageUrl: \"\",\n hideOnExpiry: false,\n};\n\nexport const DEFAULT_BLOCK_DEFAULTS: Required<BlockDefaults> = {\n text: TEXT_BLOCK_DEFAULTS,\n image: IMAGE_BLOCK_DEFAULTS,\n button: BUTTON_BLOCK_DEFAULTS,\n divider: DIVIDER_BLOCK_DEFAULTS,\n section: SECTION_BLOCK_DEFAULTS,\n video: VIDEO_BLOCK_DEFAULTS,\n social: SOCIAL_ICONS_BLOCK_DEFAULTS,\n spacer: SPACER_BLOCK_DEFAULTS,\n html: HTML_BLOCK_DEFAULTS,\n menu: MENU_BLOCK_DEFAULTS,\n table: TABLE_BLOCK_DEFAULTS,\n countdown: COUNTDOWN_BLOCK_DEFAULTS,\n};\n\nexport const DEFAULT_TEMPLATE_DEFAULTS: TemplateDefaults = {\n width: 600,\n backgroundColor: \"#ffffff\",\n fontFamily: \"Arial, sans-serif\",\n};\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.getPrototypeOf(value) === Object.prototype\n );\n}\n\nexport function deepMergeDefaults<T extends Record<string, unknown>>(\n base: T,\n overrides: Partial<T>,\n): T {\n const result = { ...base };\n\n for (const key of Object.keys(overrides) as Array<keyof T>) {\n const baseVal = base[key];\n const overrideVal = overrides[key];\n\n if (overrideVal === undefined) {\n continue;\n }\n\n if (isPlainObject(baseVal) && isPlainObject(overrideVal)) {\n result[key] = deepMergeDefaults(\n baseVal as Record<string, unknown>,\n overrideVal as Record<string, unknown>,\n ) as T[keyof T];\n } else {\n result[key] = overrideVal as T[keyof T];\n }\n }\n\n return result;\n}\n","import type { Block } from \"./blocks\";\nimport { DEFAULT_TEMPLATE_DEFAULTS } from \"./defaults\";\nimport type { TemplateDefaults } from \"./defaults\";\n\nexport interface TemplateSettings {\n width: number;\n backgroundColor: string;\n fontFamily: string;\n preheaderText?: string;\n}\n\nexport interface TemplateContent {\n blocks: Block[];\n settings: TemplateSettings;\n}\n\nexport function createDefaultTemplateContent(\n defaultFontFamily = \"Arial, sans-serif\",\n templateDefaults?: TemplateDefaults,\n): TemplateContent {\n return {\n blocks: [],\n settings: {\n ...DEFAULT_TEMPLATE_DEFAULTS,\n fontFamily: defaultFontFamily,\n ...templateDefaults,\n } as TemplateSettings,\n };\n}\n","import type {\n Block,\n BlockStyles,\n BlockType,\n ButtonBlock,\n CountdownBlock,\n CustomBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n SpacingValue,\n TableBlock,\n TableCellData,\n TableRowData,\n TextBlock,\n VideoBlock,\n} from \"./blocks\";\nimport type { CustomBlockDefinition, CustomBlockField } from \"./custom-blocks\";\nimport type { BlockDefaults } from \"./defaults\";\nimport {\n BUTTON_BLOCK_DEFAULTS,\n COUNTDOWN_BLOCK_DEFAULTS,\n deepMergeDefaults,\n DIVIDER_BLOCK_DEFAULTS,\n HTML_BLOCK_DEFAULTS,\n IMAGE_BLOCK_DEFAULTS,\n MENU_BLOCK_DEFAULTS,\n SECTION_BLOCK_DEFAULTS,\n SOCIAL_ICONS_BLOCK_DEFAULTS,\n SPACER_BLOCK_DEFAULTS,\n TABLE_BLOCK_DEFAULTS,\n TEXT_BLOCK_DEFAULTS,\n VIDEO_BLOCK_DEFAULTS,\n} from \"./defaults\";\n\nfunction applyDefaults<T>(base: T, partial: Partial<T> | undefined): T {\n if (!partial || Object.keys(partial).length === 0) return base;\n return deepMergeDefaults(\n base as unknown as Record<string, unknown>,\n partial as unknown as Record<string, unknown>,\n ) as unknown as T;\n}\n\nexport function generateId(): string {\n return crypto.randomUUID();\n}\n\nfunction createDefaultSpacing(value = 0): SpacingValue {\n return { top: value, right: value, bottom: value, left: value };\n}\n\nfunction createDefaultStyles(padding = 10): BlockStyles {\n return {\n padding: createDefaultSpacing(padding),\n margin: createDefaultSpacing(0),\n };\n}\n\nexport function createTextBlock(partial: Partial<TextBlock> = {}): TextBlock {\n const base: TextBlock = {\n id: generateId(),\n type: \"text\",\n ...TEXT_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as TextBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createImageBlock(\n partial: Partial<ImageBlock> = {},\n): ImageBlock {\n const base: ImageBlock = {\n id: generateId(),\n type: \"image\",\n ...IMAGE_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as ImageBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createButtonBlock(\n partial: Partial<ButtonBlock> = {},\n): ButtonBlock {\n const base: ButtonBlock = {\n id: generateId(),\n type: \"button\",\n ...BUTTON_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as ButtonBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createDividerBlock(\n partial: Partial<DividerBlock> = {},\n): DividerBlock {\n const base: DividerBlock = {\n id: generateId(),\n type: \"divider\",\n ...DIVIDER_BLOCK_DEFAULTS,\n styles: createDefaultStyles(20),\n } as DividerBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSectionBlock(\n partial: Partial<SectionBlock> = {},\n): SectionBlock {\n const base: SectionBlock = {\n id: generateId(),\n type: \"section\",\n ...SECTION_BLOCK_DEFAULTS,\n children: [[]],\n styles: createDefaultStyles(20),\n } as SectionBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createVideoBlock(\n partial: Partial<VideoBlock> = {},\n): VideoBlock {\n const base: VideoBlock = {\n id: generateId(),\n type: \"video\",\n ...VIDEO_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as VideoBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSocialIconsBlock(\n partial: Partial<SocialIconsBlock> = {},\n): SocialIconsBlock {\n const base: SocialIconsBlock = {\n id: generateId(),\n type: \"social\",\n icons: [],\n ...SOCIAL_ICONS_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as SocialIconsBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSpacerBlock(\n partial: Partial<SpacerBlock> = {},\n): SpacerBlock {\n const base: SpacerBlock = {\n id: generateId(),\n type: \"spacer\",\n ...SPACER_BLOCK_DEFAULTS,\n styles: createDefaultStyles(0),\n } as SpacerBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createHtmlBlock(partial: Partial<HtmlBlock> = {}): HtmlBlock {\n const base: HtmlBlock = {\n id: generateId(),\n type: \"html\",\n ...HTML_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as HtmlBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createMenuBlock(partial: Partial<MenuBlock> = {}): MenuBlock {\n const base: MenuBlock = {\n id: generateId(),\n type: \"menu\",\n items: [],\n ...MENU_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as MenuBlock;\n return applyDefaults(base, partial);\n}\n\nfunction createDefaultTableRows(columns: number, rows: number): TableRowData[] {\n return Array.from({ length: rows }, () => ({\n id: generateId(),\n cells: Array.from(\n { length: columns },\n (): TableCellData => ({\n id: generateId(),\n content: \"\",\n }),\n ),\n }));\n}\n\nexport function createTableBlock(\n partial: Partial<TableBlock> = {},\n): TableBlock {\n const base: TableBlock = {\n id: generateId(),\n type: \"table\",\n rows: createDefaultTableRows(3, 3),\n ...TABLE_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as TableBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createCountdownBlock(\n partial: Partial<CountdownBlock> = {},\n): CountdownBlock {\n const base: CountdownBlock = {\n id: generateId(),\n type: \"countdown\",\n ...COUNTDOWN_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as CountdownBlock;\n return applyDefaults(base, partial);\n}\n\nfunction getFieldDefault(field: CustomBlockField): unknown {\n if (field.type === \"repeatable\") {\n return field.default ?? [];\n }\n if (field.type === \"boolean\") {\n return field.default ?? false;\n }\n if (field.type === \"number\") {\n return field.default ?? 0;\n }\n\n return field.default ?? \"\";\n}\n\nexport function createCustomBlock(\n definition: CustomBlockDefinition,\n): CustomBlock {\n const fieldValues: Record<string, unknown> = {};\n\n for (const field of definition.fields) {\n fieldValues[field.key] = getFieldDefault(field);\n }\n\n return {\n id: generateId(),\n type: \"custom\",\n customType: definition.type,\n fieldValues,\n styles: createDefaultStyles(),\n ...(definition.dataSource ? { dataSourceFetched: false } : {}),\n };\n}\n\nexport function createBlock(\n type: BlockType,\n blockDefaults?: BlockDefaults,\n): Block {\n switch (type) {\n case \"section\":\n return createSectionBlock(blockDefaults?.section);\n case \"text\":\n return createTextBlock(blockDefaults?.text);\n case \"image\":\n return createImageBlock(blockDefaults?.image);\n case \"button\":\n return createButtonBlock(blockDefaults?.button);\n case \"divider\":\n return createDividerBlock(blockDefaults?.divider);\n case \"video\":\n return createVideoBlock(blockDefaults?.video);\n case \"social\":\n return createSocialIconsBlock(blockDefaults?.social);\n case \"spacer\":\n return createSpacerBlock(blockDefaults?.spacer);\n case \"html\":\n return createHtmlBlock(blockDefaults?.html);\n case \"menu\":\n return createMenuBlock(blockDefaults?.menu);\n case \"table\":\n return createTableBlock(blockDefaults?.table);\n case \"countdown\":\n return createCountdownBlock(blockDefaults?.countdown);\n default:\n throw new Error(`Unknown block type: ${type}`);\n }\n}\n\nexport function cloneBlock(block: Block): Block {\n const cloned = JSON.parse(JSON.stringify(block)) as Block;\n cloned.id = generateId();\n\n if (cloned.type === \"section\") {\n cloned.children = cloned.children.map((column) =>\n column.map((child) => cloneBlock(child)),\n );\n }\n\n return cloned;\n}\n","export class EventEmitter<\n TEvents extends Record<string, unknown> = Record<string, unknown>,\n> {\n private handlers = new Map<keyof TEvents, Set<(data: never) => void>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: (data: TEvents[K]) => void,\n ): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n\n const set = this.handlers.get(event)!;\n set.add(handler as (data: never) => void);\n\n return () => {\n set.delete(handler as (data: never) => void);\n if (set.size === 0) {\n this.handlers.delete(event);\n }\n };\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: (data: TEvents[K]) => void,\n ): void {\n const set = this.handlers.get(event);\n if (!set) {\n return;\n }\n\n set.delete(handler as (data: never) => void);\n if (set.size === 0) {\n this.handlers.delete(event);\n }\n }\n\n emit<K extends keyof TEvents>(event: K, data: TEvents[K]): void {\n const set = this.handlers.get(event);\n if (!set) {\n return;\n }\n\n // Copy to avoid issues with handlers modifying the set during iteration\n for (const handler of [...set]) {\n handler(data as never);\n }\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.handlers.delete(event);\n } else {\n this.handlers.clear();\n }\n }\n\n listenerCount(event: keyof TEvents): number {\n return this.handlers.get(event)?.size ?? 0;\n }\n}\n","import type { MergeTag } from \"./config\";\n\n// --- Syntax Presets ---\n\nexport interface SyntaxPreset {\n value: RegExp;\n logic: RegExp;\n}\n\nexport type SyntaxPresetName =\n | \"liquid\"\n | \"handlebars\"\n | \"mailchimp\"\n | \"ampscript\";\n\nexport const SYNTAX_PRESETS: Record<SyntaxPresetName, SyntaxPreset> = {\n liquid: { value: /\\{\\{.+?\\}\\}/g, logic: /\\{%-?\\s*(\\w+).*?-?%\\}/g },\n handlebars: {\n value: /\\{\\{\\{?.+?\\}?\\}\\}/g,\n logic: /\\{\\{[#/](\\w+).*?\\}\\}/g,\n },\n mailchimp: { value: /\\*\\|\\w+\\|\\*/g, logic: /\\*\\|(\\w+)[:|].*?\\|\\*/g },\n ampscript: { value: /%%=.+?=%%/g, logic: /%%\\[\\s*(\\w+).*?\\]%%/g },\n};\n\nexport function resolveSyntax(\n syntax?: SyntaxPresetName | SyntaxPreset,\n): SyntaxPreset {\n if (!syntax) {\n return SYNTAX_PRESETS.liquid;\n }\n\n if (typeof syntax === \"string\") {\n return SYNTAX_PRESETS[syntax];\n }\n\n return syntax;\n}\n\n// --- Merge Tag Utilities ---\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction anchoredRegex(pattern: RegExp): RegExp {\n const source = pattern.source;\n const flags = pattern.flags.replace(\"g\", \"\");\n return new RegExp(`^${source}$`, flags);\n}\n\nexport function isMergeTagValue(value: string, syntax: SyntaxPreset): boolean {\n return anchoredRegex(syntax.value).test(value?.trim() || \"\");\n}\n\nexport function getMergeTagLabel(value: string, mergeTags: MergeTag[]): string {\n const found = mergeTags.find((p) => p.value === value);\n if (found) {\n return found.label;\n }\n return value;\n}\n\nexport function resolveHtmlMergeTagLabels(\n html: string,\n mergeTags: MergeTag[],\n): string {\n return html.replace(\n /(<span[^>]*\\sdata-merge-tag=\"([^\"]*)\"[^>]*>)(.*?)(<\\/span>)/g,\n (_match, openTag, value, _oldLabel, closeTag) => {\n const label = getMergeTagLabel(value, mergeTags);\n return `${openTag}${label}${closeTag}`;\n },\n );\n}\n\nexport function containsMergeTag(value: string, syntax: SyntaxPreset): boolean {\n if (!value) return false;\n\n const valueRegex = new RegExp(syntax.value.source, syntax.value.flags);\n const logicRegex = new RegExp(syntax.logic.source, syntax.logic.flags);\n\n return valueRegex.test(value) || logicRegex.test(value);\n}\n\nexport function restoreMergeTagMarkup(\n html: string,\n mergeTags: MergeTag[],\n syntax: SyntaxPreset,\n): string {\n let result = html;\n\n for (const tag of mergeTags) {\n const escaped = escapeRegExp(tag.value);\n const pattern = new RegExp(`(?<!data-merge-tag=\")${escaped}`, \"g\");\n result = result.replace(pattern, (match) => {\n const label = getMergeTagLabel(match, mergeTags);\n return `<span data-merge-tag=\"${match}\">${label}</span>`;\n });\n }\n\n const logicRegex = new RegExp(\n `(?<!data-logic-merge-tag=\")${syntax.logic.source}`,\n syntax.logic.flags,\n );\n result = result.replace(logicRegex, (match) => {\n const keyword = getLogicMergeTagKeyword(match, syntax);\n return `<span data-logic-merge-tag=\"${match}\">${keyword}</span>`;\n });\n\n return result;\n}\n\nexport function isLogicMergeTagValue(\n value: string,\n syntax: SyntaxPreset,\n): boolean {\n return anchoredRegex(syntax.logic).test(value?.trim() || \"\");\n}\n\nexport function getLogicMergeTagKeyword(\n value: string,\n syntax: SyntaxPreset,\n): string {\n const regex = new RegExp(\n syntax.logic.source,\n syntax.logic.flags.replace(\"g\", \"\"),\n );\n const match = value.match(regex);\n return match && match[1] ? match[1].toUpperCase() : value;\n}\n\nexport function resolveHtmlLogicMergeTagLabels(\n html: string,\n syntax: SyntaxPreset,\n): string {\n return html.replace(\n /(<span[^>]*\\sdata-logic-merge-tag=\"([^\"]*)\"[^>]*>)(.*?)(<\\/span>)/g,\n (_match, openTag, value, _oldLabel, closeTag) => {\n const keyword = getLogicMergeTagKeyword(value, syntax);\n return `${openTag}${keyword}${closeTag}`;\n },\n );\n}\n","import type { SyntaxPreset, SyntaxPresetName } from \"./merge-tags\";\n\nexport type ViewportSize = \"desktop\" | \"tablet\" | \"mobile\";\n\nexport interface CustomFont {\n name: string;\n url: string;\n fallback?: string;\n}\n\nexport interface FontsConfig {\n defaultFallback?: string;\n defaultFont?: string;\n customFonts?: CustomFont[];\n}\n\nexport interface ExportResult {\n html: string;\n mjml: string;\n}\n\nexport interface MergeTag {\n label: string;\n value: string;\n}\n\nexport interface MediaResult {\n url: string;\n alt?: string;\n}\n\nexport interface MergeTagsConfig {\n syntax?: SyntaxPresetName | SyntaxPreset;\n tags?: MergeTag[];\n onRequest?: () => Promise<MergeTag | null>;\n}\n\nexport interface DisplayCondition {\n label: string;\n before: string;\n after: string;\n group?: string;\n description?: string;\n}\n\nexport interface DisplayConditionsConfig {\n conditions: DisplayCondition[];\n allowCustom?: boolean;\n}\n\nexport interface ThemeOverrides {\n bg?: string;\n bgElevated?: string;\n bgHover?: string;\n bgActive?: string;\n border?: string;\n borderLight?: string;\n text?: string;\n textMuted?: string;\n textDim?: string;\n primary?: string;\n primaryHover?: string;\n primaryLight?: string;\n secondary?: string;\n secondaryHover?: string;\n secondaryLight?: string;\n success?: string;\n successLight?: string;\n warning?: string;\n warningLight?: string;\n danger?: string;\n dangerLight?: string;\n canvasBg?: string;\n}\n\nexport class SdkError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"SdkError\";\n }\n\n get isNotFound(): boolean {\n return this.statusCode === 404;\n }\n\n get isUnauthorized(): boolean {\n return this.statusCode === 401;\n }\n\n get isServerError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 500;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/blocks.ts","../src/guards.ts","../src/defaults.ts","../src/template.ts","../src/factory.ts","../src/events.ts","../src/merge-tags.ts","../src/config.ts"],"sourcesContent":["// Blocks\nexport type {\n BaseBlock,\n Block,\n BlockStyles,\n BlockType,\n BlockVisibility,\n ButtonBlock,\n ColumnLayout,\n CountdownBlock,\n CustomBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n MenuItemData,\n ResponsiveStyles,\n SectionBlock,\n SocialIcon,\n SocialIconSize,\n SocialIconStyle,\n SocialIconsBlock,\n SocialPlatform,\n SpacerBlock,\n SpacingValue,\n TableBlock,\n TableCellData,\n TableRowData,\n TitleBlock,\n ParagraphBlock,\n HeadingLevel,\n VideoBlock,\n} from \"./blocks\";\nexport { HEADING_LEVEL_FONT_SIZE } from \"./blocks\";\n\n// Type guards\nexport {\n isButton,\n isCountdown,\n isCustomBlock,\n isDivider,\n isHtml,\n isImage,\n isMenu,\n isSection,\n isSocialIcons,\n isSpacer,\n isTable,\n isTitle,\n isParagraph,\n isVideo,\n} from \"./guards\";\n\n// Template\nexport type { TemplateContent, TemplateSettings } from \"./template\";\nexport { createDefaultTemplateContent } from \"./template\";\n\n// Defaults\nexport type { BlockDefaults, TemplateDefaults } from \"./defaults\";\nexport {\n deepMergeDefaults,\n DEFAULT_BLOCK_DEFAULTS,\n DEFAULT_TEMPLATE_DEFAULTS,\n TITLE_BLOCK_DEFAULTS,\n PARAGRAPH_BLOCK_DEFAULTS,\n IMAGE_BLOCK_DEFAULTS,\n BUTTON_BLOCK_DEFAULTS,\n DIVIDER_BLOCK_DEFAULTS,\n SECTION_BLOCK_DEFAULTS,\n VIDEO_BLOCK_DEFAULTS,\n SOCIAL_ICONS_BLOCK_DEFAULTS,\n SPACER_BLOCK_DEFAULTS,\n HTML_BLOCK_DEFAULTS,\n MENU_BLOCK_DEFAULTS,\n TABLE_BLOCK_DEFAULTS,\n COUNTDOWN_BLOCK_DEFAULTS,\n} from \"./defaults\";\n\n// Custom blocks\nexport type {\n CustomBlockBooleanField,\n CustomBlockColorField,\n CustomBlockDefinition,\n CustomBlockField,\n CustomBlockFieldBase,\n CustomBlockFieldType,\n CustomBlockImageField,\n CustomBlockNumberField,\n CustomBlockRepeatableField,\n CustomBlockSelectField,\n CustomBlockTextField,\n CustomBlockTextareaField,\n DataSourceConfig,\n DataSourceFetchContext,\n SelectOption,\n} from \"./custom-blocks\";\n\n// Block factory\nexport {\n cloneBlock,\n createBlock,\n createButtonBlock,\n createCountdownBlock,\n createCustomBlock,\n createDividerBlock,\n createHtmlBlock,\n createImageBlock,\n createMenuBlock,\n createSectionBlock,\n createSocialIconsBlock,\n createSpacerBlock,\n createTableBlock,\n createTitleBlock,\n createParagraphBlock,\n createVideoBlock,\n generateId,\n} from \"./factory\";\n\n// Event emitter\nexport { EventEmitter } from \"./events\";\n\n// Merge tags\nexport type { SyntaxPreset, SyntaxPresetName } from \"./merge-tags\";\nexport {\n containsMergeTag,\n getLogicMergeTagKeyword,\n getMergeTagLabel,\n isLogicMergeTagValue,\n isMergeTagValue,\n resolveHtmlLogicMergeTagLabels,\n resolveHtmlMergeTagLabels,\n resolveSyntax,\n restoreMergeTagMarkup,\n SYNTAX_PRESETS,\n} from \"./merge-tags\";\n\n// Config\nexport type {\n CustomFont,\n DisplayCondition,\n DisplayConditionsConfig,\n ExportResult,\n FontsConfig,\n MediaResult,\n MergeTag,\n MergeTagsConfig,\n ThemeOverrides,\n UiTheme,\n ViewportSize,\n} from \"./config\";\nexport { SdkError } from \"./config\";\n\n// Cloud types (zero runtime cost — all type-only except re-exported ViewportSize/SyntaxPreset)\nexport type {\n AiChatMessage,\n AiConfig,\n AiGenerateOptions,\n AiScoreOptions,\n AiStreamEvent,\n ApiError,\n ApiResponse,\n AuthConfig,\n AuthRequestOptions,\n CategoryScore,\n Collaborator,\n CollaborationConfig,\n Comment,\n CommentEvent,\n CommentEventType,\n CommentThread,\n CreateCommentData,\n DirectAuthConfig,\n EditorState,\n FindingSeverity,\n SdkAuthConfig,\n HealthCheckResult,\n McpConfig,\n McpOperation,\n McpOperationPayload,\n PlanConfig,\n PlanFeatures,\n PlanLimits,\n ProxyAuthConfig,\n RewriteData,\n SavedModule,\n SaveResult,\n ScoringCategory,\n ScoringFinding,\n ScoringResult,\n Template,\n TemplaticalConfig,\n TemplaticalInstance,\n TemplateSnapshot,\n TestEmailConfig,\n TokenData,\n UpdateCommentData,\n UserConfig,\n WebSocketServerConfig,\n} from \"./cloud\";\n","export interface SpacingValue {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\nexport interface ResponsiveStyles {\n tablet?: Partial<BlockStyles>;\n mobile?: Partial<BlockStyles>;\n}\n\nexport interface BlockStyles {\n padding: SpacingValue;\n margin: SpacingValue;\n backgroundColor?: string;\n responsive?: ResponsiveStyles;\n}\n\nexport interface BlockVisibility {\n desktop: boolean;\n tablet: boolean;\n mobile: boolean;\n}\n\nexport interface BaseBlock {\n id: string;\n type: string;\n styles: BlockStyles;\n customCss?: string;\n visibility?: BlockVisibility;\n displayCondition?: {\n label: string;\n before: string;\n after: string;\n group?: string;\n description?: string;\n };\n}\n\nexport type ColumnLayout = \"1\" | \"2\" | \"3\" | \"2-1\" | \"1-2\";\n\nexport interface SectionBlock extends BaseBlock {\n type: \"section\";\n columns: ColumnLayout;\n children: Block[][];\n}\n\nexport type HeadingLevel = 1 | 2 | 3 | 4;\n\nexport const HEADING_LEVEL_FONT_SIZE: Record<HeadingLevel, number> = {\n 1: 36,\n 2: 28,\n 3: 22,\n 4: 18,\n};\n\nexport interface TitleBlock extends BaseBlock {\n type: \"title\";\n content: string;\n level: HeadingLevel;\n color: string;\n textAlign: \"left\" | \"center\" | \"right\";\n fontFamily?: string;\n}\n\nexport interface ParagraphBlock extends BaseBlock {\n type: \"paragraph\";\n content: string;\n}\n\nexport interface ImageBlock extends BaseBlock {\n type: \"image\";\n src: string;\n alt: string;\n width: number | \"full\";\n align: \"left\" | \"center\" | \"right\";\n linkUrl?: string;\n linkOpenInNewTab?: boolean;\n placeholderUrl?: string;\n}\n\nexport interface ButtonBlock extends BaseBlock {\n type: \"button\";\n text: string;\n url: string;\n openInNewTab?: boolean;\n backgroundColor: string;\n textColor: string;\n borderRadius: number;\n fontSize: number;\n buttonPadding: SpacingValue;\n fontFamily?: string;\n}\n\nexport interface DividerBlock extends BaseBlock {\n type: \"divider\";\n lineStyle: \"solid\" | \"dashed\" | \"dotted\";\n color: string;\n thickness: number;\n width: number | \"full\";\n}\n\nexport interface VideoBlock extends BaseBlock {\n type: \"video\";\n url: string;\n openInNewTab?: boolean;\n thumbnailUrl: string;\n alt: string;\n width: number | \"full\";\n align: \"left\" | \"center\" | \"right\";\n placeholderUrl?: string;\n}\n\nexport type SocialPlatform =\n | \"facebook\"\n | \"twitter\"\n | \"instagram\"\n | \"linkedin\"\n | \"youtube\"\n | \"tiktok\"\n | \"pinterest\"\n | \"email\"\n | \"whatsapp\"\n | \"telegram\"\n | \"discord\"\n | \"snapchat\"\n | \"reddit\"\n | \"github\"\n | \"dribbble\"\n | \"behance\";\n\nexport type SocialIconStyle =\n | \"solid\"\n | \"outlined\"\n | \"rounded\"\n | \"square\"\n | \"circle\";\n\nexport type SocialIconSize = \"small\" | \"medium\" | \"large\";\n\nexport interface SocialIcon {\n id: string;\n platform: SocialPlatform;\n url: string;\n}\n\nexport interface SocialIconsBlock extends BaseBlock {\n type: \"social\";\n icons: SocialIcon[];\n iconStyle: SocialIconStyle;\n iconSize: SocialIconSize;\n spacing: number;\n align: \"left\" | \"center\" | \"right\";\n}\n\nexport interface SpacerBlock extends BaseBlock {\n type: \"spacer\";\n height: number;\n}\n\nexport interface HtmlBlock extends BaseBlock {\n type: \"html\";\n content: string;\n}\n\nexport interface MenuItemData {\n id: string;\n text: string;\n url: string;\n openInNewTab: boolean;\n bold: boolean;\n underline: boolean;\n color?: string;\n}\n\nexport interface MenuBlock extends BaseBlock {\n type: \"menu\";\n items: MenuItemData[];\n fontSize: number;\n fontFamily?: string;\n color: string;\n linkColor?: string;\n textAlign: \"left\" | \"center\" | \"right\";\n separator: string;\n separatorColor: string;\n spacing: number;\n}\n\nexport interface TableCellData {\n id: string;\n content: string;\n}\n\nexport interface TableRowData {\n id: string;\n cells: TableCellData[];\n}\n\nexport interface TableBlock extends BaseBlock {\n type: \"table\";\n rows: TableRowData[];\n hasHeaderRow: boolean;\n headerBackgroundColor?: string;\n borderColor: string;\n borderWidth: number;\n cellPadding: number;\n fontSize: number;\n fontFamily?: string;\n color: string;\n textAlign: \"left\" | \"center\" | \"right\";\n}\n\nexport interface CountdownBlock extends BaseBlock {\n type: \"countdown\";\n targetDate: string;\n timezone: string;\n showDays: boolean;\n showHours: boolean;\n showMinutes: boolean;\n showSeconds: boolean;\n separator: \":\" | \"-\" | \" \";\n digitFontSize: number;\n digitColor: string;\n labelColor: string;\n labelFontSize: number;\n backgroundColor: string;\n fontFamily?: string;\n labelDays: string;\n labelHours: string;\n labelMinutes: string;\n labelSeconds: string;\n expiredMessage: string;\n expiredImageUrl: string;\n hideOnExpiry: boolean;\n}\n\nexport interface CustomBlock extends BaseBlock {\n type: \"custom\";\n customType: string;\n fieldValues: Record<string, unknown>;\n renderedHtml?: string;\n dataSourceFetched?: boolean;\n}\n\nexport type Block =\n | SectionBlock\n | TitleBlock\n | ParagraphBlock\n | ImageBlock\n | ButtonBlock\n | DividerBlock\n | VideoBlock\n | SocialIconsBlock\n | SpacerBlock\n | HtmlBlock\n | MenuBlock\n | TableBlock\n | CountdownBlock\n | CustomBlock;\n\nexport type BlockType = Block[\"type\"];\n","import type {\n Block,\n ButtonBlock,\n CountdownBlock,\n CustomBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n ParagraphBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n TableBlock,\n TitleBlock,\n VideoBlock,\n} from \"./blocks\";\n\nexport function isSection(block: Block): block is SectionBlock {\n return block.type === \"section\";\n}\n\nexport function isTitle(block: Block): block is TitleBlock {\n return block.type === \"title\";\n}\n\nexport function isParagraph(block: Block): block is ParagraphBlock {\n return block.type === \"paragraph\";\n}\n\nexport function isImage(block: Block): block is ImageBlock {\n return block.type === \"image\";\n}\n\nexport function isButton(block: Block): block is ButtonBlock {\n return block.type === \"button\";\n}\n\nexport function isDivider(block: Block): block is DividerBlock {\n return block.type === \"divider\";\n}\n\nexport function isVideo(block: Block): block is VideoBlock {\n return block.type === \"video\";\n}\n\nexport function isSocialIcons(block: Block): block is SocialIconsBlock {\n return block.type === \"social\";\n}\n\nexport function isSpacer(block: Block): block is SpacerBlock {\n return block.type === \"spacer\";\n}\n\nexport function isHtml(block: Block): block is HtmlBlock {\n return block.type === \"html\";\n}\n\nexport function isMenu(block: Block): block is MenuBlock {\n return block.type === \"menu\";\n}\n\nexport function isTable(block: Block): block is TableBlock {\n return block.type === \"table\";\n}\n\nexport function isCountdown(block: Block): block is CountdownBlock {\n return block.type === \"countdown\";\n}\n\nexport function isCustomBlock(block: Block): block is CustomBlock {\n return block.type === \"custom\";\n}\n","import type {\n ButtonBlock,\n CountdownBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n ParagraphBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n TableBlock,\n TitleBlock,\n VideoBlock,\n} from \"./blocks\";\nimport type { TemplateSettings } from \"./template\";\n\ntype BlockDefaultsFor<T> = Partial<Omit<T, \"id\" | \"type\">>;\n\nexport interface BlockDefaults {\n title?: BlockDefaultsFor<TitleBlock>;\n paragraph?: BlockDefaultsFor<ParagraphBlock>;\n image?: BlockDefaultsFor<ImageBlock>;\n button?: BlockDefaultsFor<ButtonBlock>;\n divider?: BlockDefaultsFor<DividerBlock>;\n section?: BlockDefaultsFor<SectionBlock>;\n video?: BlockDefaultsFor<VideoBlock>;\n social?: BlockDefaultsFor<SocialIconsBlock>;\n spacer?: BlockDefaultsFor<SpacerBlock>;\n html?: BlockDefaultsFor<HtmlBlock>;\n menu?: BlockDefaultsFor<MenuBlock>;\n table?: BlockDefaultsFor<TableBlock>;\n countdown?: BlockDefaultsFor<CountdownBlock>;\n}\n\nexport type TemplateDefaults = Partial<TemplateSettings>;\n\n// ---------------------------------------------------------------------------\n// Built-in default values — single source of truth for factories & consumers\n// ---------------------------------------------------------------------------\n\nexport const TITLE_BLOCK_DEFAULTS: BlockDefaultsFor<TitleBlock> = {\n content: \"<p>Enter your title</p>\",\n level: 2,\n color: \"#1a1a1a\",\n textAlign: \"left\",\n};\n\nexport const PARAGRAPH_BLOCK_DEFAULTS: BlockDefaultsFor<ParagraphBlock> = {\n content: \"<p>Enter your text here</p>\",\n};\n\nexport const IMAGE_BLOCK_DEFAULTS: BlockDefaultsFor<ImageBlock> = {\n src: \"\",\n alt: \"\",\n width: \"full\",\n align: \"center\",\n};\n\nexport const BUTTON_BLOCK_DEFAULTS: BlockDefaultsFor<ButtonBlock> = {\n text: \"Click Here\",\n url: \"\",\n backgroundColor: \"#333333\",\n textColor: \"#ffffff\",\n borderRadius: 6,\n fontSize: 15,\n buttonPadding: { top: 12, right: 24, bottom: 12, left: 24 },\n};\n\nexport const DIVIDER_BLOCK_DEFAULTS: BlockDefaultsFor<DividerBlock> = {\n lineStyle: \"solid\",\n color: \"#e0e0e0\",\n thickness: 1,\n width: \"full\",\n};\n\nexport const SECTION_BLOCK_DEFAULTS: BlockDefaultsFor<SectionBlock> = {\n columns: \"1\",\n};\n\nexport const VIDEO_BLOCK_DEFAULTS: BlockDefaultsFor<VideoBlock> = {\n url: \"\",\n thumbnailUrl: \"\",\n alt: \"Video\",\n width: \"full\",\n align: \"center\",\n};\n\nexport const SOCIAL_ICONS_BLOCK_DEFAULTS: BlockDefaultsFor<SocialIconsBlock> = {\n iconStyle: \"solid\",\n iconSize: \"medium\",\n spacing: 10,\n align: \"center\",\n};\n\nexport const SPACER_BLOCK_DEFAULTS: BlockDefaultsFor<SpacerBlock> = {\n height: 24,\n};\n\nexport const HTML_BLOCK_DEFAULTS: BlockDefaultsFor<HtmlBlock> = {\n content: \"\",\n};\n\nexport const MENU_BLOCK_DEFAULTS: BlockDefaultsFor<MenuBlock> = {\n fontSize: 15,\n color: \"#1a1a1a\",\n textAlign: \"center\",\n separator: \"|\",\n separatorColor: \"#e0e0e0\",\n spacing: 10,\n};\n\nexport const TABLE_BLOCK_DEFAULTS: BlockDefaultsFor<TableBlock> = {\n hasHeaderRow: true,\n borderColor: \"#e0e0e0\",\n borderWidth: 1,\n cellPadding: 8,\n fontSize: 15,\n color: \"#1a1a1a\",\n textAlign: \"left\",\n};\n\nexport const COUNTDOWN_BLOCK_DEFAULTS: BlockDefaultsFor<CountdownBlock> = {\n targetDate: \"\",\n timezone: \"UTC\",\n showDays: true,\n showHours: true,\n showMinutes: true,\n showSeconds: true,\n separator: \":\",\n digitFontSize: 32,\n digitColor: \"#1a1a1a\",\n labelColor: \"#6b7280\",\n labelFontSize: 12,\n backgroundColor: \"#ffffff\",\n labelDays: \"Days\",\n labelHours: \"Hours\",\n labelMinutes: \"Minutes\",\n labelSeconds: \"Seconds\",\n expiredMessage: \"This offer has expired\",\n expiredImageUrl: \"\",\n hideOnExpiry: false,\n};\n\nexport const DEFAULT_BLOCK_DEFAULTS: Required<BlockDefaults> = {\n title: TITLE_BLOCK_DEFAULTS,\n paragraph: PARAGRAPH_BLOCK_DEFAULTS,\n image: IMAGE_BLOCK_DEFAULTS,\n button: BUTTON_BLOCK_DEFAULTS,\n divider: DIVIDER_BLOCK_DEFAULTS,\n section: SECTION_BLOCK_DEFAULTS,\n video: VIDEO_BLOCK_DEFAULTS,\n social: SOCIAL_ICONS_BLOCK_DEFAULTS,\n spacer: SPACER_BLOCK_DEFAULTS,\n html: HTML_BLOCK_DEFAULTS,\n menu: MENU_BLOCK_DEFAULTS,\n table: TABLE_BLOCK_DEFAULTS,\n countdown: COUNTDOWN_BLOCK_DEFAULTS,\n};\n\nexport const DEFAULT_TEMPLATE_DEFAULTS: TemplateDefaults = {\n width: 600,\n backgroundColor: \"#ffffff\",\n fontFamily: \"Arial\",\n};\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.getPrototypeOf(value) === Object.prototype\n );\n}\n\nexport function deepMergeDefaults<T extends object>(\n base: T,\n overrides: Partial<T>,\n): T {\n const result = { ...base };\n\n for (const key of Object.keys(overrides) as Array<keyof T>) {\n const baseVal = base[key];\n const overrideVal = overrides[key];\n\n if (overrideVal === undefined) {\n continue;\n }\n\n if (isPlainObject(baseVal) && isPlainObject(overrideVal)) {\n result[key] = deepMergeDefaults(\n baseVal,\n overrideVal as Partial<typeof baseVal>,\n ) as T[keyof T];\n } else {\n result[key] = overrideVal as T[keyof T];\n }\n }\n\n return result;\n}\n","import type { Block } from \"./blocks\";\nimport { DEFAULT_TEMPLATE_DEFAULTS } from \"./defaults\";\nimport type { TemplateDefaults } from \"./defaults\";\n\nexport interface TemplateSettings {\n width: number;\n backgroundColor: string;\n fontFamily: string;\n preheaderText?: string;\n}\n\nexport interface TemplateContent {\n blocks: Block[];\n settings: TemplateSettings;\n}\n\nexport function createDefaultTemplateContent(\n defaultFontFamily = \"Arial\",\n templateDefaults?: TemplateDefaults,\n): TemplateContent {\n return {\n blocks: [],\n settings: {\n ...DEFAULT_TEMPLATE_DEFAULTS,\n fontFamily: defaultFontFamily,\n ...templateDefaults,\n } as TemplateSettings,\n };\n}\n","import type {\n Block,\n BlockStyles,\n BlockType,\n ButtonBlock,\n CountdownBlock,\n CustomBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n ParagraphBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n SpacingValue,\n TableBlock,\n TableCellData,\n TableRowData,\n TitleBlock,\n VideoBlock,\n} from \"./blocks\";\nimport type { CustomBlockDefinition, CustomBlockField } from \"./custom-blocks\";\nimport type { BlockDefaults } from \"./defaults\";\nimport {\n BUTTON_BLOCK_DEFAULTS,\n COUNTDOWN_BLOCK_DEFAULTS,\n deepMergeDefaults,\n DIVIDER_BLOCK_DEFAULTS,\n HTML_BLOCK_DEFAULTS,\n IMAGE_BLOCK_DEFAULTS,\n MENU_BLOCK_DEFAULTS,\n PARAGRAPH_BLOCK_DEFAULTS,\n SECTION_BLOCK_DEFAULTS,\n SOCIAL_ICONS_BLOCK_DEFAULTS,\n SPACER_BLOCK_DEFAULTS,\n TABLE_BLOCK_DEFAULTS,\n TITLE_BLOCK_DEFAULTS,\n VIDEO_BLOCK_DEFAULTS,\n} from \"./defaults\";\n\nfunction applyDefaults<T extends object>(\n base: T,\n partial: Partial<T> | undefined,\n): T {\n if (!partial || Object.keys(partial).length === 0) return base;\n return deepMergeDefaults(base, partial);\n}\n\nexport function generateId(): string {\n return crypto.randomUUID();\n}\n\nfunction createDefaultSpacing(value = 0): SpacingValue {\n return { top: value, right: value, bottom: value, left: value };\n}\n\nfunction createDefaultStyles(padding = 10): BlockStyles {\n return {\n padding: createDefaultSpacing(padding),\n margin: createDefaultSpacing(0),\n };\n}\n\nexport function createTitleBlock(\n partial: Partial<TitleBlock> = {},\n): TitleBlock {\n const base: TitleBlock = {\n id: generateId(),\n type: \"title\",\n ...TITLE_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as TitleBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createParagraphBlock(\n partial: Partial<ParagraphBlock> = {},\n): ParagraphBlock {\n const base: ParagraphBlock = {\n id: generateId(),\n type: \"paragraph\",\n ...PARAGRAPH_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as ParagraphBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createImageBlock(\n partial: Partial<ImageBlock> = {},\n): ImageBlock {\n const base: ImageBlock = {\n id: generateId(),\n type: \"image\",\n ...IMAGE_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as ImageBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createButtonBlock(\n partial: Partial<ButtonBlock> = {},\n): ButtonBlock {\n const base: ButtonBlock = {\n id: generateId(),\n type: \"button\",\n ...BUTTON_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as ButtonBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createDividerBlock(\n partial: Partial<DividerBlock> = {},\n): DividerBlock {\n const base: DividerBlock = {\n id: generateId(),\n type: \"divider\",\n ...DIVIDER_BLOCK_DEFAULTS,\n styles: createDefaultStyles(20),\n } as DividerBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSectionBlock(\n partial: Partial<SectionBlock> = {},\n): SectionBlock {\n const base: SectionBlock = {\n id: generateId(),\n type: \"section\",\n ...SECTION_BLOCK_DEFAULTS,\n children: [[]],\n styles: createDefaultStyles(20),\n } as SectionBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createVideoBlock(\n partial: Partial<VideoBlock> = {},\n): VideoBlock {\n const base: VideoBlock = {\n id: generateId(),\n type: \"video\",\n ...VIDEO_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as VideoBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSocialIconsBlock(\n partial: Partial<SocialIconsBlock> = {},\n): SocialIconsBlock {\n const base: SocialIconsBlock = {\n id: generateId(),\n type: \"social\",\n icons: [],\n ...SOCIAL_ICONS_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as SocialIconsBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSpacerBlock(\n partial: Partial<SpacerBlock> = {},\n): SpacerBlock {\n const base: SpacerBlock = {\n id: generateId(),\n type: \"spacer\",\n ...SPACER_BLOCK_DEFAULTS,\n styles: createDefaultStyles(0),\n } as SpacerBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createHtmlBlock(partial: Partial<HtmlBlock> = {}): HtmlBlock {\n const base: HtmlBlock = {\n id: generateId(),\n type: \"html\",\n ...HTML_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as HtmlBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createMenuBlock(partial: Partial<MenuBlock> = {}): MenuBlock {\n const base: MenuBlock = {\n id: generateId(),\n type: \"menu\",\n items: [],\n ...MENU_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as MenuBlock;\n return applyDefaults(base, partial);\n}\n\nfunction createDefaultTableRows(columns: number, rows: number): TableRowData[] {\n return Array.from({ length: rows }, () => ({\n id: generateId(),\n cells: Array.from(\n { length: columns },\n (): TableCellData => ({\n id: generateId(),\n content: \"\",\n }),\n ),\n }));\n}\n\nexport function createTableBlock(\n partial: Partial<TableBlock> = {},\n): TableBlock {\n const base: TableBlock = {\n id: generateId(),\n type: \"table\",\n rows: createDefaultTableRows(3, 3),\n ...TABLE_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as TableBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createCountdownBlock(\n partial: Partial<CountdownBlock> = {},\n): CountdownBlock {\n const base: CountdownBlock = {\n id: generateId(),\n type: \"countdown\",\n ...COUNTDOWN_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as CountdownBlock;\n return applyDefaults(base, partial);\n}\n\nfunction getFieldDefault(field: CustomBlockField): unknown {\n if (field.type === \"repeatable\") {\n return field.default ?? [];\n }\n if (field.type === \"boolean\") {\n return field.default ?? false;\n }\n if (field.type === \"number\") {\n return field.default ?? 0;\n }\n\n return field.default ?? \"\";\n}\n\nexport function createCustomBlock(\n definition: CustomBlockDefinition,\n): CustomBlock {\n const fieldValues: Record<string, unknown> = {};\n\n for (const field of definition.fields) {\n fieldValues[field.key] = getFieldDefault(field);\n }\n\n return {\n id: generateId(),\n type: \"custom\",\n customType: definition.type,\n fieldValues,\n styles: createDefaultStyles(),\n ...(definition.dataSource ? { dataSourceFetched: false } : {}),\n };\n}\n\nexport function createBlock(\n type: BlockType,\n blockDefaults?: BlockDefaults,\n): Block {\n switch (type) {\n case \"section\":\n return createSectionBlock(blockDefaults?.section);\n case \"title\":\n return createTitleBlock(blockDefaults?.title);\n case \"paragraph\":\n return createParagraphBlock(blockDefaults?.paragraph);\n case \"image\":\n return createImageBlock(blockDefaults?.image);\n case \"button\":\n return createButtonBlock(blockDefaults?.button);\n case \"divider\":\n return createDividerBlock(blockDefaults?.divider);\n case \"video\":\n return createVideoBlock(blockDefaults?.video);\n case \"social\":\n return createSocialIconsBlock(blockDefaults?.social);\n case \"spacer\":\n return createSpacerBlock(blockDefaults?.spacer);\n case \"html\":\n return createHtmlBlock(blockDefaults?.html);\n case \"menu\":\n return createMenuBlock(blockDefaults?.menu);\n case \"table\":\n return createTableBlock(blockDefaults?.table);\n case \"countdown\":\n return createCountdownBlock(blockDefaults?.countdown);\n default:\n throw new Error(`Unknown block type: ${type}`);\n }\n}\n\nexport function cloneBlock(block: Block): Block {\n const cloned = JSON.parse(JSON.stringify(block)) as Block;\n cloned.id = generateId();\n\n if (cloned.type === \"section\") {\n cloned.children = cloned.children.map((column) =>\n column.map((child) => cloneBlock(child)),\n );\n }\n\n return cloned;\n}\n","export class EventEmitter<\n TEvents extends Record<string, unknown> = Record<string, unknown>,\n> {\n private handlers = new Map<keyof TEvents, Set<(data: never) => void>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: (data: TEvents[K]) => void,\n ): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n\n const set = this.handlers.get(event)!;\n set.add(handler as (data: never) => void);\n\n return () => {\n set.delete(handler as (data: never) => void);\n if (set.size === 0) {\n this.handlers.delete(event);\n }\n };\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: (data: TEvents[K]) => void,\n ): void {\n const set = this.handlers.get(event);\n if (!set) {\n return;\n }\n\n set.delete(handler as (data: never) => void);\n if (set.size === 0) {\n this.handlers.delete(event);\n }\n }\n\n emit<K extends keyof TEvents>(event: K, data: TEvents[K]): void {\n const set = this.handlers.get(event);\n if (!set) {\n return;\n }\n\n // Copy to avoid issues with handlers modifying the set during iteration\n for (const handler of [...set]) {\n handler(data as never);\n }\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.handlers.delete(event);\n } else {\n this.handlers.clear();\n }\n }\n\n listenerCount(event: keyof TEvents): number {\n return this.handlers.get(event)?.size ?? 0;\n }\n}\n","import type { MergeTag } from \"./config\";\n\n// --- Syntax Presets ---\n\nexport interface SyntaxPreset {\n value: RegExp;\n logic: RegExp;\n}\n\nexport type SyntaxPresetName =\n | \"liquid\"\n | \"handlebars\"\n | \"mailchimp\"\n | \"ampscript\";\n\nexport const SYNTAX_PRESETS: Record<SyntaxPresetName, SyntaxPreset> = {\n liquid: { value: /\\{\\{.+?\\}\\}/g, logic: /\\{%-?\\s*(\\w+).*?-?%\\}/g },\n handlebars: {\n value: /\\{\\{\\{?.+?\\}?\\}\\}/g,\n logic: /\\{\\{[#/](\\w+).*?\\}\\}/g,\n },\n mailchimp: { value: /\\*\\|\\w+\\|\\*/g, logic: /\\*\\|(\\w+)[:|].*?\\|\\*/g },\n ampscript: { value: /%%=.+?=%%/g, logic: /%%\\[\\s*(\\w+).*?\\]%%/g },\n};\n\nexport function resolveSyntax(\n syntax?: SyntaxPresetName | SyntaxPreset,\n): SyntaxPreset {\n if (!syntax) {\n return SYNTAX_PRESETS.liquid;\n }\n\n if (typeof syntax === \"string\") {\n return SYNTAX_PRESETS[syntax];\n }\n\n return syntax;\n}\n\n// --- Merge Tag Utilities ---\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction anchoredRegex(pattern: RegExp): RegExp {\n const source = pattern.source;\n const flags = pattern.flags.replace(\"g\", \"\");\n return new RegExp(`^${source}$`, flags);\n}\n\nexport function isMergeTagValue(value: string, syntax: SyntaxPreset): boolean {\n return anchoredRegex(syntax.value).test(value?.trim() || \"\");\n}\n\nexport function getMergeTagLabel(value: string, mergeTags: MergeTag[]): string {\n const found = mergeTags.find((p) => p.value === value);\n if (found) {\n return found.label;\n }\n return value;\n}\n\nexport function resolveHtmlMergeTagLabels(\n html: string,\n mergeTags: MergeTag[],\n): string {\n return html.replace(\n /(<span[^>]*\\sdata-merge-tag=\"([^\"]*)\"[^>]*>)(.*?)(<\\/span>)/g,\n (_match, openTag, value, _oldLabel, closeTag) => {\n const label = getMergeTagLabel(value, mergeTags);\n return `${openTag}${label}${closeTag}`;\n },\n );\n}\n\nexport function containsMergeTag(value: string, syntax: SyntaxPreset): boolean {\n if (!value) return false;\n\n const valueRegex = new RegExp(syntax.value.source, syntax.value.flags);\n const logicRegex = new RegExp(syntax.logic.source, syntax.logic.flags);\n\n return valueRegex.test(value) || logicRegex.test(value);\n}\n\nexport function restoreMergeTagMarkup(\n html: string,\n mergeTags: MergeTag[],\n syntax: SyntaxPreset,\n): string {\n let result = html;\n\n for (const tag of mergeTags) {\n const escaped = escapeRegExp(tag.value);\n const pattern = new RegExp(`(?<!data-merge-tag=\")${escaped}`, \"g\");\n result = result.replace(pattern, (match) => {\n const label = getMergeTagLabel(match, mergeTags);\n return `<span data-merge-tag=\"${match}\">${label}</span>`;\n });\n }\n\n const logicRegex = new RegExp(\n `(?<!data-logic-merge-tag=\")${syntax.logic.source}`,\n syntax.logic.flags,\n );\n result = result.replace(logicRegex, (match) => {\n const keyword = getLogicMergeTagKeyword(match, syntax);\n return `<span data-logic-merge-tag=\"${match}\">${keyword}</span>`;\n });\n\n return result;\n}\n\nexport function isLogicMergeTagValue(\n value: string,\n syntax: SyntaxPreset,\n): boolean {\n return anchoredRegex(syntax.logic).test(value?.trim() || \"\");\n}\n\nexport function getLogicMergeTagKeyword(\n value: string,\n syntax: SyntaxPreset,\n): string {\n const regex = new RegExp(\n syntax.logic.source,\n syntax.logic.flags.replace(\"g\", \"\"),\n );\n const match = value.match(regex);\n return match && match[1] ? match[1].toUpperCase() : value;\n}\n\nexport function resolveHtmlLogicMergeTagLabels(\n html: string,\n syntax: SyntaxPreset,\n): string {\n return html.replace(\n /(<span[^>]*\\sdata-logic-merge-tag=\"([^\"]*)\"[^>]*>)(.*?)(<\\/span>)/g,\n (_match, openTag, value, _oldLabel, closeTag) => {\n const keyword = getLogicMergeTagKeyword(value, syntax);\n return `${openTag}${keyword}${closeTag}`;\n },\n );\n}\n","import type { SyntaxPreset, SyntaxPresetName } from \"./merge-tags\";\n\nexport type ViewportSize = \"desktop\" | \"tablet\" | \"mobile\";\n\nexport type UiTheme = \"light\" | \"dark\" | \"auto\";\n\nexport interface CustomFont {\n name: string;\n url: string;\n fallback?: string;\n}\n\nexport interface FontsConfig {\n defaultFallback?: string;\n defaultFont?: string;\n customFonts?: CustomFont[];\n}\n\nexport interface ExportResult {\n html: string;\n mjml: string;\n}\n\nexport interface MergeTag {\n label: string;\n value: string;\n}\n\nexport interface MediaResult {\n url: string;\n alt?: string;\n}\n\nexport interface MergeTagsConfig {\n syntax?: SyntaxPresetName | SyntaxPreset;\n tags?: MergeTag[];\n onRequest?: () => Promise<MergeTag | null>;\n}\n\nexport interface DisplayCondition {\n label: string;\n before: string;\n after: string;\n group?: string;\n description?: string;\n}\n\nexport interface DisplayConditionsConfig {\n conditions: DisplayCondition[];\n allowCustom?: boolean;\n}\n\nexport interface ThemeOverrides {\n bg?: string;\n bgElevated?: string;\n bgHover?: string;\n bgActive?: string;\n border?: string;\n borderLight?: string;\n text?: string;\n textMuted?: string;\n textDim?: string;\n primary?: string;\n primaryHover?: string;\n primaryLight?: string;\n secondary?: string;\n secondaryHover?: string;\n secondaryLight?: string;\n success?: string;\n successLight?: string;\n warning?: string;\n warningLight?: string;\n danger?: string;\n dangerLight?: string;\n canvasBg?: string;\n dark?: Omit<ThemeOverrides, \"dark\">;\n}\n\nexport class SdkError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"SdkError\";\n }\n\n get isNotFound(): boolean {\n return this.statusCode === 404;\n }\n\n get isUnauthorized(): boolean {\n return this.statusCode === 401;\n }\n\n get isServerError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 500;\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -39,15 +39,20 @@ interface SectionBlock extends BaseBlock {
39
39
  columns: ColumnLayout;
40
40
  children: Block[][];
41
41
  }
42
- interface TextBlock extends BaseBlock {
43
- type: "text";
42
+ type HeadingLevel = 1 | 2 | 3 | 4;
43
+ declare const HEADING_LEVEL_FONT_SIZE: Record<HeadingLevel, number>;
44
+ interface TitleBlock extends BaseBlock {
45
+ type: "title";
44
46
  content: string;
45
- fontSize: number;
47
+ level: HeadingLevel;
46
48
  color: string;
47
49
  textAlign: "left" | "center" | "right";
48
- fontWeight: "normal" | "bold";
49
50
  fontFamily?: string;
50
51
  }
52
+ interface ParagraphBlock extends BaseBlock {
53
+ type: "paragraph";
54
+ content: string;
55
+ }
51
56
  interface ImageBlock extends BaseBlock {
52
57
  type: "image";
53
58
  src: string;
@@ -183,11 +188,12 @@ interface CustomBlock extends BaseBlock {
183
188
  renderedHtml?: string;
184
189
  dataSourceFetched?: boolean;
185
190
  }
186
- type Block = SectionBlock | TextBlock | ImageBlock | ButtonBlock | DividerBlock | VideoBlock | SocialIconsBlock | SpacerBlock | HtmlBlock | MenuBlock | TableBlock | CountdownBlock | CustomBlock;
191
+ type Block = SectionBlock | TitleBlock | ParagraphBlock | ImageBlock | ButtonBlock | DividerBlock | VideoBlock | SocialIconsBlock | SpacerBlock | HtmlBlock | MenuBlock | TableBlock | CountdownBlock | CustomBlock;
187
192
  type BlockType = Block["type"];
188
193
 
189
194
  declare function isSection(block: Block): block is SectionBlock;
190
- declare function isText(block: Block): block is TextBlock;
195
+ declare function isTitle(block: Block): block is TitleBlock;
196
+ declare function isParagraph(block: Block): block is ParagraphBlock;
191
197
  declare function isImage(block: Block): block is ImageBlock;
192
198
  declare function isButton(block: Block): block is ButtonBlock;
193
199
  declare function isDivider(block: Block): block is DividerBlock;
@@ -202,7 +208,8 @@ declare function isCustomBlock(block: Block): block is CustomBlock;
202
208
 
203
209
  type BlockDefaultsFor<T> = Partial<Omit<T, "id" | "type">>;
204
210
  interface BlockDefaults {
205
- text?: BlockDefaultsFor<TextBlock>;
211
+ title?: BlockDefaultsFor<TitleBlock>;
212
+ paragraph?: BlockDefaultsFor<ParagraphBlock>;
206
213
  image?: BlockDefaultsFor<ImageBlock>;
207
214
  button?: BlockDefaultsFor<ButtonBlock>;
208
215
  divider?: BlockDefaultsFor<DividerBlock>;
@@ -216,7 +223,8 @@ interface BlockDefaults {
216
223
  countdown?: BlockDefaultsFor<CountdownBlock>;
217
224
  }
218
225
  type TemplateDefaults = Partial<TemplateSettings>;
219
- declare const TEXT_BLOCK_DEFAULTS: BlockDefaultsFor<TextBlock>;
226
+ declare const TITLE_BLOCK_DEFAULTS: BlockDefaultsFor<TitleBlock>;
227
+ declare const PARAGRAPH_BLOCK_DEFAULTS: BlockDefaultsFor<ParagraphBlock>;
220
228
  declare const IMAGE_BLOCK_DEFAULTS: BlockDefaultsFor<ImageBlock>;
221
229
  declare const BUTTON_BLOCK_DEFAULTS: BlockDefaultsFor<ButtonBlock>;
222
230
  declare const DIVIDER_BLOCK_DEFAULTS: BlockDefaultsFor<DividerBlock>;
@@ -230,7 +238,7 @@ declare const TABLE_BLOCK_DEFAULTS: BlockDefaultsFor<TableBlock>;
230
238
  declare const COUNTDOWN_BLOCK_DEFAULTS: BlockDefaultsFor<CountdownBlock>;
231
239
  declare const DEFAULT_BLOCK_DEFAULTS: Required<BlockDefaults>;
232
240
  declare const DEFAULT_TEMPLATE_DEFAULTS: TemplateDefaults;
233
- declare function deepMergeDefaults<T extends Record<string, unknown>>(base: T, overrides: Partial<T>): T;
241
+ declare function deepMergeDefaults<T extends object>(base: T, overrides: Partial<T>): T;
234
242
 
235
243
  interface TemplateSettings {
236
244
  width: number;
@@ -316,7 +324,8 @@ interface DataSourceConfig {
316
324
  }
317
325
 
318
326
  declare function generateId(): string;
319
- declare function createTextBlock(partial?: Partial<TextBlock>): TextBlock;
327
+ declare function createTitleBlock(partial?: Partial<TitleBlock>): TitleBlock;
328
+ declare function createParagraphBlock(partial?: Partial<ParagraphBlock>): ParagraphBlock;
320
329
  declare function createImageBlock(partial?: Partial<ImageBlock>): ImageBlock;
321
330
  declare function createButtonBlock(partial?: Partial<ButtonBlock>): ButtonBlock;
322
331
  declare function createDividerBlock(partial?: Partial<DividerBlock>): DividerBlock;
@@ -342,6 +351,7 @@ declare class EventEmitter<TEvents extends Record<string, unknown> = Record<stri
342
351
  }
343
352
 
344
353
  type ViewportSize = "desktop" | "tablet" | "mobile";
354
+ type UiTheme = "light" | "dark" | "auto";
345
355
  interface CustomFont {
346
356
  name: string;
347
357
  url: string;
@@ -403,6 +413,7 @@ interface ThemeOverrides {
403
413
  danger?: string;
404
414
  dangerLight?: string;
405
415
  canvasBg?: string;
416
+ dark?: Omit<ThemeOverrides, "dark">;
406
417
  }
407
418
  declare class SdkError extends Error {
408
419
  readonly statusCode?: number | undefined;
@@ -674,6 +685,7 @@ interface EditorState {
674
685
  isDirty: boolean;
675
686
  isSaving: boolean;
676
687
  isLoading: boolean;
688
+ uiTheme: UiTheme;
677
689
  }
678
690
  interface ApiResponse<T> {
679
691
  data: T;
@@ -750,4 +762,4 @@ interface AiScoreOptions {
750
762
  fixFindingId?: string;
751
763
  }
752
764
 
753
- export { type AiChatMessage, type AiConfig, type AiGenerateOptions, type AiScoreOptions, type AiStreamEvent, type ApiError, type ApiResponse, type AuthConfig, type AuthRequestOptions, BUTTON_BLOCK_DEFAULTS, type BaseBlock, type Block, type BlockDefaults, type BlockStyles, type BlockType, type BlockVisibility, type ButtonBlock, COUNTDOWN_BLOCK_DEFAULTS, type CategoryScore, type CollaborationConfig, type Collaborator, type ColumnLayout, type Comment, type CommentEvent, type CommentEventType, type CommentThread, type CountdownBlock, type CreateCommentData, type CustomBlock, type CustomBlockBooleanField, type CustomBlockColorField, type CustomBlockDefinition, type CustomBlockField, type CustomBlockFieldBase, type CustomBlockFieldType, type CustomBlockImageField, type CustomBlockNumberField, type CustomBlockRepeatableField, type CustomBlockSelectField, type CustomBlockTextField, type CustomBlockTextareaField, type CustomFont, DEFAULT_BLOCK_DEFAULTS, DEFAULT_TEMPLATE_DEFAULTS, DIVIDER_BLOCK_DEFAULTS, type DataSourceConfig, type DataSourceFetchContext, type DirectAuthConfig, type DisplayCondition, type DisplayConditionsConfig, type DividerBlock, type EditorState, EventEmitter, type ExportResult, type FindingSeverity, type FontsConfig, HTML_BLOCK_DEFAULTS, type HealthCheckResult, type HtmlBlock, IMAGE_BLOCK_DEFAULTS, type ImageBlock, MENU_BLOCK_DEFAULTS, type McpConfig, type McpOperation, type McpOperationPayload, type MediaResult, type MenuBlock, type MenuItemData, type MergeTag, type MergeTagsConfig, type PlanConfig, type PlanFeatures, type PlanLimits, type ProxyAuthConfig, type ResponsiveStyles, type RewriteData, SECTION_BLOCK_DEFAULTS, SOCIAL_ICONS_BLOCK_DEFAULTS, SPACER_BLOCK_DEFAULTS, SYNTAX_PRESETS, type SaveResult, type SavedModule, type ScoringCategory, type ScoringFinding, type ScoringResult, type SdkAuthConfig, SdkError, type SectionBlock, type SelectOption, type SocialIcon, type SocialIconSize, type SocialIconStyle, type SocialIconsBlock, type SocialPlatform, type SpacerBlock, type SpacingValue, type SyntaxPreset, type SyntaxPresetName, TABLE_BLOCK_DEFAULTS, TEXT_BLOCK_DEFAULTS, type TableBlock, type TableCellData, type TableRowData, type Template, type TemplateContent, type TemplateDefaults, type TemplateSettings, type TemplateSnapshot, type TemplaticalConfig, type TemplaticalInstance, type TestEmailConfig, type TextBlock, type ThemeOverrides, type TokenData, type UpdateCommentData, type UserConfig, VIDEO_BLOCK_DEFAULTS, type VideoBlock, type ViewportSize, type WebSocketServerConfig, cloneBlock, containsMergeTag, createBlock, createButtonBlock, createCountdownBlock, createCustomBlock, createDefaultTemplateContent, createDividerBlock, createHtmlBlock, createImageBlock, createMenuBlock, createSectionBlock, createSocialIconsBlock, createSpacerBlock, createTableBlock, createTextBlock, createVideoBlock, deepMergeDefaults, generateId, getLogicMergeTagKeyword, getMergeTagLabel, isButton, isCountdown, isCustomBlock, isDivider, isHtml, isImage, isLogicMergeTagValue, isMenu, isMergeTagValue, isSection, isSocialIcons, isSpacer, isTable, isText, isVideo, resolveHtmlLogicMergeTagLabels, resolveHtmlMergeTagLabels, resolveSyntax, restoreMergeTagMarkup };
765
+ export { type AiChatMessage, type AiConfig, type AiGenerateOptions, type AiScoreOptions, type AiStreamEvent, type ApiError, type ApiResponse, type AuthConfig, type AuthRequestOptions, BUTTON_BLOCK_DEFAULTS, type BaseBlock, type Block, type BlockDefaults, type BlockStyles, type BlockType, type BlockVisibility, type ButtonBlock, COUNTDOWN_BLOCK_DEFAULTS, type CategoryScore, type CollaborationConfig, type Collaborator, type ColumnLayout, type Comment, type CommentEvent, type CommentEventType, type CommentThread, type CountdownBlock, type CreateCommentData, type CustomBlock, type CustomBlockBooleanField, type CustomBlockColorField, type CustomBlockDefinition, type CustomBlockField, type CustomBlockFieldBase, type CustomBlockFieldType, type CustomBlockImageField, type CustomBlockNumberField, type CustomBlockRepeatableField, type CustomBlockSelectField, type CustomBlockTextField, type CustomBlockTextareaField, type CustomFont, DEFAULT_BLOCK_DEFAULTS, DEFAULT_TEMPLATE_DEFAULTS, DIVIDER_BLOCK_DEFAULTS, type DataSourceConfig, type DataSourceFetchContext, type DirectAuthConfig, type DisplayCondition, type DisplayConditionsConfig, type DividerBlock, type EditorState, EventEmitter, type ExportResult, type FindingSeverity, type FontsConfig, HEADING_LEVEL_FONT_SIZE, HTML_BLOCK_DEFAULTS, type HeadingLevel, type HealthCheckResult, type HtmlBlock, IMAGE_BLOCK_DEFAULTS, type ImageBlock, MENU_BLOCK_DEFAULTS, type McpConfig, type McpOperation, type McpOperationPayload, type MediaResult, type MenuBlock, type MenuItemData, type MergeTag, type MergeTagsConfig, PARAGRAPH_BLOCK_DEFAULTS, type ParagraphBlock, type PlanConfig, type PlanFeatures, type PlanLimits, type ProxyAuthConfig, type ResponsiveStyles, type RewriteData, SECTION_BLOCK_DEFAULTS, SOCIAL_ICONS_BLOCK_DEFAULTS, SPACER_BLOCK_DEFAULTS, SYNTAX_PRESETS, type SaveResult, type SavedModule, type ScoringCategory, type ScoringFinding, type ScoringResult, type SdkAuthConfig, SdkError, type SectionBlock, type SelectOption, type SocialIcon, type SocialIconSize, type SocialIconStyle, type SocialIconsBlock, type SocialPlatform, type SpacerBlock, type SpacingValue, type SyntaxPreset, type SyntaxPresetName, TABLE_BLOCK_DEFAULTS, TITLE_BLOCK_DEFAULTS, type TableBlock, type TableCellData, type TableRowData, type Template, type TemplateContent, type TemplateDefaults, type TemplateSettings, type TemplateSnapshot, type TemplaticalConfig, type TemplaticalInstance, type TestEmailConfig, type ThemeOverrides, type TitleBlock, type TokenData, type UiTheme, type UpdateCommentData, type UserConfig, VIDEO_BLOCK_DEFAULTS, type VideoBlock, type ViewportSize, type WebSocketServerConfig, cloneBlock, containsMergeTag, createBlock, createButtonBlock, createCountdownBlock, createCustomBlock, createDefaultTemplateContent, createDividerBlock, createHtmlBlock, createImageBlock, createMenuBlock, createParagraphBlock, createSectionBlock, createSocialIconsBlock, createSpacerBlock, createTableBlock, createTitleBlock, createVideoBlock, deepMergeDefaults, generateId, getLogicMergeTagKeyword, getMergeTagLabel, isButton, isCountdown, isCustomBlock, isDivider, isHtml, isImage, isLogicMergeTagValue, isMenu, isMergeTagValue, isParagraph, isSection, isSocialIcons, isSpacer, isTable, isTitle, isVideo, resolveHtmlLogicMergeTagLabels, resolveHtmlMergeTagLabels, resolveSyntax, restoreMergeTagMarkup };
package/dist/index.d.ts CHANGED
@@ -39,15 +39,20 @@ interface SectionBlock extends BaseBlock {
39
39
  columns: ColumnLayout;
40
40
  children: Block[][];
41
41
  }
42
- interface TextBlock extends BaseBlock {
43
- type: "text";
42
+ type HeadingLevel = 1 | 2 | 3 | 4;
43
+ declare const HEADING_LEVEL_FONT_SIZE: Record<HeadingLevel, number>;
44
+ interface TitleBlock extends BaseBlock {
45
+ type: "title";
44
46
  content: string;
45
- fontSize: number;
47
+ level: HeadingLevel;
46
48
  color: string;
47
49
  textAlign: "left" | "center" | "right";
48
- fontWeight: "normal" | "bold";
49
50
  fontFamily?: string;
50
51
  }
52
+ interface ParagraphBlock extends BaseBlock {
53
+ type: "paragraph";
54
+ content: string;
55
+ }
51
56
  interface ImageBlock extends BaseBlock {
52
57
  type: "image";
53
58
  src: string;
@@ -183,11 +188,12 @@ interface CustomBlock extends BaseBlock {
183
188
  renderedHtml?: string;
184
189
  dataSourceFetched?: boolean;
185
190
  }
186
- type Block = SectionBlock | TextBlock | ImageBlock | ButtonBlock | DividerBlock | VideoBlock | SocialIconsBlock | SpacerBlock | HtmlBlock | MenuBlock | TableBlock | CountdownBlock | CustomBlock;
191
+ type Block = SectionBlock | TitleBlock | ParagraphBlock | ImageBlock | ButtonBlock | DividerBlock | VideoBlock | SocialIconsBlock | SpacerBlock | HtmlBlock | MenuBlock | TableBlock | CountdownBlock | CustomBlock;
187
192
  type BlockType = Block["type"];
188
193
 
189
194
  declare function isSection(block: Block): block is SectionBlock;
190
- declare function isText(block: Block): block is TextBlock;
195
+ declare function isTitle(block: Block): block is TitleBlock;
196
+ declare function isParagraph(block: Block): block is ParagraphBlock;
191
197
  declare function isImage(block: Block): block is ImageBlock;
192
198
  declare function isButton(block: Block): block is ButtonBlock;
193
199
  declare function isDivider(block: Block): block is DividerBlock;
@@ -202,7 +208,8 @@ declare function isCustomBlock(block: Block): block is CustomBlock;
202
208
 
203
209
  type BlockDefaultsFor<T> = Partial<Omit<T, "id" | "type">>;
204
210
  interface BlockDefaults {
205
- text?: BlockDefaultsFor<TextBlock>;
211
+ title?: BlockDefaultsFor<TitleBlock>;
212
+ paragraph?: BlockDefaultsFor<ParagraphBlock>;
206
213
  image?: BlockDefaultsFor<ImageBlock>;
207
214
  button?: BlockDefaultsFor<ButtonBlock>;
208
215
  divider?: BlockDefaultsFor<DividerBlock>;
@@ -216,7 +223,8 @@ interface BlockDefaults {
216
223
  countdown?: BlockDefaultsFor<CountdownBlock>;
217
224
  }
218
225
  type TemplateDefaults = Partial<TemplateSettings>;
219
- declare const TEXT_BLOCK_DEFAULTS: BlockDefaultsFor<TextBlock>;
226
+ declare const TITLE_BLOCK_DEFAULTS: BlockDefaultsFor<TitleBlock>;
227
+ declare const PARAGRAPH_BLOCK_DEFAULTS: BlockDefaultsFor<ParagraphBlock>;
220
228
  declare const IMAGE_BLOCK_DEFAULTS: BlockDefaultsFor<ImageBlock>;
221
229
  declare const BUTTON_BLOCK_DEFAULTS: BlockDefaultsFor<ButtonBlock>;
222
230
  declare const DIVIDER_BLOCK_DEFAULTS: BlockDefaultsFor<DividerBlock>;
@@ -230,7 +238,7 @@ declare const TABLE_BLOCK_DEFAULTS: BlockDefaultsFor<TableBlock>;
230
238
  declare const COUNTDOWN_BLOCK_DEFAULTS: BlockDefaultsFor<CountdownBlock>;
231
239
  declare const DEFAULT_BLOCK_DEFAULTS: Required<BlockDefaults>;
232
240
  declare const DEFAULT_TEMPLATE_DEFAULTS: TemplateDefaults;
233
- declare function deepMergeDefaults<T extends Record<string, unknown>>(base: T, overrides: Partial<T>): T;
241
+ declare function deepMergeDefaults<T extends object>(base: T, overrides: Partial<T>): T;
234
242
 
235
243
  interface TemplateSettings {
236
244
  width: number;
@@ -316,7 +324,8 @@ interface DataSourceConfig {
316
324
  }
317
325
 
318
326
  declare function generateId(): string;
319
- declare function createTextBlock(partial?: Partial<TextBlock>): TextBlock;
327
+ declare function createTitleBlock(partial?: Partial<TitleBlock>): TitleBlock;
328
+ declare function createParagraphBlock(partial?: Partial<ParagraphBlock>): ParagraphBlock;
320
329
  declare function createImageBlock(partial?: Partial<ImageBlock>): ImageBlock;
321
330
  declare function createButtonBlock(partial?: Partial<ButtonBlock>): ButtonBlock;
322
331
  declare function createDividerBlock(partial?: Partial<DividerBlock>): DividerBlock;
@@ -342,6 +351,7 @@ declare class EventEmitter<TEvents extends Record<string, unknown> = Record<stri
342
351
  }
343
352
 
344
353
  type ViewportSize = "desktop" | "tablet" | "mobile";
354
+ type UiTheme = "light" | "dark" | "auto";
345
355
  interface CustomFont {
346
356
  name: string;
347
357
  url: string;
@@ -403,6 +413,7 @@ interface ThemeOverrides {
403
413
  danger?: string;
404
414
  dangerLight?: string;
405
415
  canvasBg?: string;
416
+ dark?: Omit<ThemeOverrides, "dark">;
406
417
  }
407
418
  declare class SdkError extends Error {
408
419
  readonly statusCode?: number | undefined;
@@ -674,6 +685,7 @@ interface EditorState {
674
685
  isDirty: boolean;
675
686
  isSaving: boolean;
676
687
  isLoading: boolean;
688
+ uiTheme: UiTheme;
677
689
  }
678
690
  interface ApiResponse<T> {
679
691
  data: T;
@@ -750,4 +762,4 @@ interface AiScoreOptions {
750
762
  fixFindingId?: string;
751
763
  }
752
764
 
753
- export { type AiChatMessage, type AiConfig, type AiGenerateOptions, type AiScoreOptions, type AiStreamEvent, type ApiError, type ApiResponse, type AuthConfig, type AuthRequestOptions, BUTTON_BLOCK_DEFAULTS, type BaseBlock, type Block, type BlockDefaults, type BlockStyles, type BlockType, type BlockVisibility, type ButtonBlock, COUNTDOWN_BLOCK_DEFAULTS, type CategoryScore, type CollaborationConfig, type Collaborator, type ColumnLayout, type Comment, type CommentEvent, type CommentEventType, type CommentThread, type CountdownBlock, type CreateCommentData, type CustomBlock, type CustomBlockBooleanField, type CustomBlockColorField, type CustomBlockDefinition, type CustomBlockField, type CustomBlockFieldBase, type CustomBlockFieldType, type CustomBlockImageField, type CustomBlockNumberField, type CustomBlockRepeatableField, type CustomBlockSelectField, type CustomBlockTextField, type CustomBlockTextareaField, type CustomFont, DEFAULT_BLOCK_DEFAULTS, DEFAULT_TEMPLATE_DEFAULTS, DIVIDER_BLOCK_DEFAULTS, type DataSourceConfig, type DataSourceFetchContext, type DirectAuthConfig, type DisplayCondition, type DisplayConditionsConfig, type DividerBlock, type EditorState, EventEmitter, type ExportResult, type FindingSeverity, type FontsConfig, HTML_BLOCK_DEFAULTS, type HealthCheckResult, type HtmlBlock, IMAGE_BLOCK_DEFAULTS, type ImageBlock, MENU_BLOCK_DEFAULTS, type McpConfig, type McpOperation, type McpOperationPayload, type MediaResult, type MenuBlock, type MenuItemData, type MergeTag, type MergeTagsConfig, type PlanConfig, type PlanFeatures, type PlanLimits, type ProxyAuthConfig, type ResponsiveStyles, type RewriteData, SECTION_BLOCK_DEFAULTS, SOCIAL_ICONS_BLOCK_DEFAULTS, SPACER_BLOCK_DEFAULTS, SYNTAX_PRESETS, type SaveResult, type SavedModule, type ScoringCategory, type ScoringFinding, type ScoringResult, type SdkAuthConfig, SdkError, type SectionBlock, type SelectOption, type SocialIcon, type SocialIconSize, type SocialIconStyle, type SocialIconsBlock, type SocialPlatform, type SpacerBlock, type SpacingValue, type SyntaxPreset, type SyntaxPresetName, TABLE_BLOCK_DEFAULTS, TEXT_BLOCK_DEFAULTS, type TableBlock, type TableCellData, type TableRowData, type Template, type TemplateContent, type TemplateDefaults, type TemplateSettings, type TemplateSnapshot, type TemplaticalConfig, type TemplaticalInstance, type TestEmailConfig, type TextBlock, type ThemeOverrides, type TokenData, type UpdateCommentData, type UserConfig, VIDEO_BLOCK_DEFAULTS, type VideoBlock, type ViewportSize, type WebSocketServerConfig, cloneBlock, containsMergeTag, createBlock, createButtonBlock, createCountdownBlock, createCustomBlock, createDefaultTemplateContent, createDividerBlock, createHtmlBlock, createImageBlock, createMenuBlock, createSectionBlock, createSocialIconsBlock, createSpacerBlock, createTableBlock, createTextBlock, createVideoBlock, deepMergeDefaults, generateId, getLogicMergeTagKeyword, getMergeTagLabel, isButton, isCountdown, isCustomBlock, isDivider, isHtml, isImage, isLogicMergeTagValue, isMenu, isMergeTagValue, isSection, isSocialIcons, isSpacer, isTable, isText, isVideo, resolveHtmlLogicMergeTagLabels, resolveHtmlMergeTagLabels, resolveSyntax, restoreMergeTagMarkup };
765
+ export { type AiChatMessage, type AiConfig, type AiGenerateOptions, type AiScoreOptions, type AiStreamEvent, type ApiError, type ApiResponse, type AuthConfig, type AuthRequestOptions, BUTTON_BLOCK_DEFAULTS, type BaseBlock, type Block, type BlockDefaults, type BlockStyles, type BlockType, type BlockVisibility, type ButtonBlock, COUNTDOWN_BLOCK_DEFAULTS, type CategoryScore, type CollaborationConfig, type Collaborator, type ColumnLayout, type Comment, type CommentEvent, type CommentEventType, type CommentThread, type CountdownBlock, type CreateCommentData, type CustomBlock, type CustomBlockBooleanField, type CustomBlockColorField, type CustomBlockDefinition, type CustomBlockField, type CustomBlockFieldBase, type CustomBlockFieldType, type CustomBlockImageField, type CustomBlockNumberField, type CustomBlockRepeatableField, type CustomBlockSelectField, type CustomBlockTextField, type CustomBlockTextareaField, type CustomFont, DEFAULT_BLOCK_DEFAULTS, DEFAULT_TEMPLATE_DEFAULTS, DIVIDER_BLOCK_DEFAULTS, type DataSourceConfig, type DataSourceFetchContext, type DirectAuthConfig, type DisplayCondition, type DisplayConditionsConfig, type DividerBlock, type EditorState, EventEmitter, type ExportResult, type FindingSeverity, type FontsConfig, HEADING_LEVEL_FONT_SIZE, HTML_BLOCK_DEFAULTS, type HeadingLevel, type HealthCheckResult, type HtmlBlock, IMAGE_BLOCK_DEFAULTS, type ImageBlock, MENU_BLOCK_DEFAULTS, type McpConfig, type McpOperation, type McpOperationPayload, type MediaResult, type MenuBlock, type MenuItemData, type MergeTag, type MergeTagsConfig, PARAGRAPH_BLOCK_DEFAULTS, type ParagraphBlock, type PlanConfig, type PlanFeatures, type PlanLimits, type ProxyAuthConfig, type ResponsiveStyles, type RewriteData, SECTION_BLOCK_DEFAULTS, SOCIAL_ICONS_BLOCK_DEFAULTS, SPACER_BLOCK_DEFAULTS, SYNTAX_PRESETS, type SaveResult, type SavedModule, type ScoringCategory, type ScoringFinding, type ScoringResult, type SdkAuthConfig, SdkError, type SectionBlock, type SelectOption, type SocialIcon, type SocialIconSize, type SocialIconStyle, type SocialIconsBlock, type SocialPlatform, type SpacerBlock, type SpacingValue, type SyntaxPreset, type SyntaxPresetName, TABLE_BLOCK_DEFAULTS, TITLE_BLOCK_DEFAULTS, type TableBlock, type TableCellData, type TableRowData, type Template, type TemplateContent, type TemplateDefaults, type TemplateSettings, type TemplateSnapshot, type TemplaticalConfig, type TemplaticalInstance, type TestEmailConfig, type ThemeOverrides, type TitleBlock, type TokenData, type UiTheme, type UpdateCommentData, type UserConfig, VIDEO_BLOCK_DEFAULTS, type VideoBlock, type ViewportSize, type WebSocketServerConfig, cloneBlock, containsMergeTag, createBlock, createButtonBlock, createCountdownBlock, createCustomBlock, createDefaultTemplateContent, createDividerBlock, createHtmlBlock, createImageBlock, createMenuBlock, createParagraphBlock, createSectionBlock, createSocialIconsBlock, createSpacerBlock, createTableBlock, createTitleBlock, createVideoBlock, deepMergeDefaults, generateId, getLogicMergeTagKeyword, getMergeTagLabel, isButton, isCountdown, isCustomBlock, isDivider, isHtml, isImage, isLogicMergeTagValue, isMenu, isMergeTagValue, isParagraph, isSection, isSocialIcons, isSpacer, isTable, isTitle, isVideo, resolveHtmlLogicMergeTagLabels, resolveHtmlMergeTagLabels, resolveSyntax, restoreMergeTagMarkup };
package/dist/index.js CHANGED
@@ -1,9 +1,20 @@
1
+ // src/blocks.ts
2
+ var HEADING_LEVEL_FONT_SIZE = {
3
+ 1: 36,
4
+ 2: 28,
5
+ 3: 22,
6
+ 4: 18
7
+ };
8
+
1
9
  // src/guards.ts
2
10
  function isSection(block) {
3
11
  return block.type === "section";
4
12
  }
5
- function isText(block) {
6
- return block.type === "text";
13
+ function isTitle(block) {
14
+ return block.type === "title";
15
+ }
16
+ function isParagraph(block) {
17
+ return block.type === "paragraph";
7
18
  }
8
19
  function isImage(block) {
9
20
  return block.type === "image";
@@ -40,12 +51,14 @@ function isCustomBlock(block) {
40
51
  }
41
52
 
42
53
  // src/defaults.ts
43
- var TEXT_BLOCK_DEFAULTS = {
44
- content: "<p>Enter your text here</p>",
45
- fontSize: 16,
54
+ var TITLE_BLOCK_DEFAULTS = {
55
+ content: "<p>Enter your title</p>",
56
+ level: 2,
46
57
  color: "#1a1a1a",
47
- textAlign: "left",
48
- fontWeight: "normal"
58
+ textAlign: "left"
59
+ };
60
+ var PARAGRAPH_BLOCK_DEFAULTS = {
61
+ content: "<p>Enter your text here</p>"
49
62
  };
50
63
  var IMAGE_BLOCK_DEFAULTS = {
51
64
  src: "",
@@ -129,7 +142,8 @@ var COUNTDOWN_BLOCK_DEFAULTS = {
129
142
  hideOnExpiry: false
130
143
  };
131
144
  var DEFAULT_BLOCK_DEFAULTS = {
132
- text: TEXT_BLOCK_DEFAULTS,
145
+ title: TITLE_BLOCK_DEFAULTS,
146
+ paragraph: PARAGRAPH_BLOCK_DEFAULTS,
133
147
  image: IMAGE_BLOCK_DEFAULTS,
134
148
  button: BUTTON_BLOCK_DEFAULTS,
135
149
  divider: DIVIDER_BLOCK_DEFAULTS,
@@ -145,7 +159,7 @@ var DEFAULT_BLOCK_DEFAULTS = {
145
159
  var DEFAULT_TEMPLATE_DEFAULTS = {
146
160
  width: 600,
147
161
  backgroundColor: "#ffffff",
148
- fontFamily: "Arial, sans-serif"
162
+ fontFamily: "Arial"
149
163
  };
150
164
  function isPlainObject(value) {
151
165
  return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
@@ -171,7 +185,7 @@ function deepMergeDefaults(base, overrides) {
171
185
  }
172
186
 
173
187
  // src/template.ts
174
- function createDefaultTemplateContent(defaultFontFamily = "Arial, sans-serif", templateDefaults) {
188
+ function createDefaultTemplateContent(defaultFontFamily = "Arial", templateDefaults) {
175
189
  return {
176
190
  blocks: [],
177
191
  settings: {
@@ -185,10 +199,7 @@ function createDefaultTemplateContent(defaultFontFamily = "Arial, sans-serif", t
185
199
  // src/factory.ts
186
200
  function applyDefaults(base, partial) {
187
201
  if (!partial || Object.keys(partial).length === 0) return base;
188
- return deepMergeDefaults(
189
- base,
190
- partial
191
- );
202
+ return deepMergeDefaults(base, partial);
192
203
  }
193
204
  function generateId() {
194
205
  return crypto.randomUUID();
@@ -202,11 +213,20 @@ function createDefaultStyles(padding = 10) {
202
213
  margin: createDefaultSpacing(0)
203
214
  };
204
215
  }
205
- function createTextBlock(partial = {}) {
216
+ function createTitleBlock(partial = {}) {
206
217
  const base = {
207
218
  id: generateId(),
208
- type: "text",
209
- ...TEXT_BLOCK_DEFAULTS,
219
+ type: "title",
220
+ ...TITLE_BLOCK_DEFAULTS,
221
+ styles: createDefaultStyles()
222
+ };
223
+ return applyDefaults(base, partial);
224
+ }
225
+ function createParagraphBlock(partial = {}) {
226
+ const base = {
227
+ id: generateId(),
228
+ type: "paragraph",
229
+ ...PARAGRAPH_BLOCK_DEFAULTS,
210
230
  styles: createDefaultStyles()
211
231
  };
212
232
  return applyDefaults(base, partial);
@@ -356,8 +376,10 @@ function createBlock(type, blockDefaults) {
356
376
  switch (type) {
357
377
  case "section":
358
378
  return createSectionBlock(blockDefaults?.section);
359
- case "text":
360
- return createTextBlock(blockDefaults?.text);
379
+ case "title":
380
+ return createTitleBlock(blockDefaults?.title);
381
+ case "paragraph":
382
+ return createParagraphBlock(blockDefaults?.paragraph);
361
383
  case "image":
362
384
  return createImageBlock(blockDefaults?.image);
363
385
  case "button":
@@ -395,9 +417,7 @@ function cloneBlock(block) {
395
417
 
396
418
  // src/events.ts
397
419
  var EventEmitter = class {
398
- constructor() {
399
- this.handlers = /* @__PURE__ */ new Map();
400
- }
420
+ handlers = /* @__PURE__ */ new Map();
401
421
  on(event, handler) {
402
422
  if (!this.handlers.has(event)) {
403
423
  this.handlers.set(event, /* @__PURE__ */ new Set());
@@ -559,16 +579,18 @@ export {
559
579
  DEFAULT_TEMPLATE_DEFAULTS,
560
580
  DIVIDER_BLOCK_DEFAULTS,
561
581
  EventEmitter,
582
+ HEADING_LEVEL_FONT_SIZE,
562
583
  HTML_BLOCK_DEFAULTS,
563
584
  IMAGE_BLOCK_DEFAULTS,
564
585
  MENU_BLOCK_DEFAULTS,
586
+ PARAGRAPH_BLOCK_DEFAULTS,
565
587
  SECTION_BLOCK_DEFAULTS,
566
588
  SOCIAL_ICONS_BLOCK_DEFAULTS,
567
589
  SPACER_BLOCK_DEFAULTS,
568
590
  SYNTAX_PRESETS,
569
591
  SdkError,
570
592
  TABLE_BLOCK_DEFAULTS,
571
- TEXT_BLOCK_DEFAULTS,
593
+ TITLE_BLOCK_DEFAULTS,
572
594
  VIDEO_BLOCK_DEFAULTS,
573
595
  cloneBlock,
574
596
  containsMergeTag,
@@ -581,11 +603,12 @@ export {
581
603
  createHtmlBlock,
582
604
  createImageBlock,
583
605
  createMenuBlock,
606
+ createParagraphBlock,
584
607
  createSectionBlock,
585
608
  createSocialIconsBlock,
586
609
  createSpacerBlock,
587
610
  createTableBlock,
588
- createTextBlock,
611
+ createTitleBlock,
589
612
  createVideoBlock,
590
613
  deepMergeDefaults,
591
614
  generateId,
@@ -600,11 +623,12 @@ export {
600
623
  isLogicMergeTagValue,
601
624
  isMenu,
602
625
  isMergeTagValue,
626
+ isParagraph,
603
627
  isSection,
604
628
  isSocialIcons,
605
629
  isSpacer,
606
630
  isTable,
607
- isText,
631
+ isTitle,
608
632
  isVideo,
609
633
  resolveHtmlLogicMergeTagLabels,
610
634
  resolveHtmlMergeTagLabels,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/guards.ts","../src/defaults.ts","../src/template.ts","../src/factory.ts","../src/events.ts","../src/merge-tags.ts","../src/config.ts"],"sourcesContent":["import type {\n Block,\n ButtonBlock,\n CountdownBlock,\n CustomBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n TableBlock,\n TextBlock,\n VideoBlock,\n} from \"./blocks\";\n\nexport function isSection(block: Block): block is SectionBlock {\n return block.type === \"section\";\n}\n\nexport function isText(block: Block): block is TextBlock {\n return block.type === \"text\";\n}\n\nexport function isImage(block: Block): block is ImageBlock {\n return block.type === \"image\";\n}\n\nexport function isButton(block: Block): block is ButtonBlock {\n return block.type === \"button\";\n}\n\nexport function isDivider(block: Block): block is DividerBlock {\n return block.type === \"divider\";\n}\n\nexport function isVideo(block: Block): block is VideoBlock {\n return block.type === \"video\";\n}\n\nexport function isSocialIcons(block: Block): block is SocialIconsBlock {\n return block.type === \"social\";\n}\n\nexport function isSpacer(block: Block): block is SpacerBlock {\n return block.type === \"spacer\";\n}\n\nexport function isHtml(block: Block): block is HtmlBlock {\n return block.type === \"html\";\n}\n\nexport function isMenu(block: Block): block is MenuBlock {\n return block.type === \"menu\";\n}\n\nexport function isTable(block: Block): block is TableBlock {\n return block.type === \"table\";\n}\n\nexport function isCountdown(block: Block): block is CountdownBlock {\n return block.type === \"countdown\";\n}\n\nexport function isCustomBlock(block: Block): block is CustomBlock {\n return block.type === \"custom\";\n}\n","import type {\n ButtonBlock,\n CountdownBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n TableBlock,\n TextBlock,\n VideoBlock,\n} from \"./blocks\";\nimport type { TemplateSettings } from \"./template\";\n\ntype BlockDefaultsFor<T> = Partial<Omit<T, \"id\" | \"type\">>;\n\nexport interface BlockDefaults {\n text?: BlockDefaultsFor<TextBlock>;\n image?: BlockDefaultsFor<ImageBlock>;\n button?: BlockDefaultsFor<ButtonBlock>;\n divider?: BlockDefaultsFor<DividerBlock>;\n section?: BlockDefaultsFor<SectionBlock>;\n video?: BlockDefaultsFor<VideoBlock>;\n social?: BlockDefaultsFor<SocialIconsBlock>;\n spacer?: BlockDefaultsFor<SpacerBlock>;\n html?: BlockDefaultsFor<HtmlBlock>;\n menu?: BlockDefaultsFor<MenuBlock>;\n table?: BlockDefaultsFor<TableBlock>;\n countdown?: BlockDefaultsFor<CountdownBlock>;\n}\n\nexport type TemplateDefaults = Partial<TemplateSettings>;\n\n// ---------------------------------------------------------------------------\n// Built-in default values — single source of truth for factories & consumers\n// ---------------------------------------------------------------------------\n\nexport const TEXT_BLOCK_DEFAULTS: BlockDefaultsFor<TextBlock> = {\n content: \"<p>Enter your text here</p>\",\n fontSize: 16,\n color: \"#1a1a1a\",\n textAlign: \"left\",\n fontWeight: \"normal\",\n};\n\nexport const IMAGE_BLOCK_DEFAULTS: BlockDefaultsFor<ImageBlock> = {\n src: \"\",\n alt: \"\",\n width: \"full\",\n align: \"center\",\n};\n\nexport const BUTTON_BLOCK_DEFAULTS: BlockDefaultsFor<ButtonBlock> = {\n text: \"Click Here\",\n url: \"\",\n backgroundColor: \"#333333\",\n textColor: \"#ffffff\",\n borderRadius: 6,\n fontSize: 15,\n buttonPadding: { top: 12, right: 24, bottom: 12, left: 24 },\n};\n\nexport const DIVIDER_BLOCK_DEFAULTS: BlockDefaultsFor<DividerBlock> = {\n lineStyle: \"solid\",\n color: \"#e0e0e0\",\n thickness: 1,\n width: \"full\",\n};\n\nexport const SECTION_BLOCK_DEFAULTS: BlockDefaultsFor<SectionBlock> = {\n columns: \"1\",\n};\n\nexport const VIDEO_BLOCK_DEFAULTS: BlockDefaultsFor<VideoBlock> = {\n url: \"\",\n thumbnailUrl: \"\",\n alt: \"Video\",\n width: \"full\",\n align: \"center\",\n};\n\nexport const SOCIAL_ICONS_BLOCK_DEFAULTS: BlockDefaultsFor<SocialIconsBlock> = {\n iconStyle: \"solid\",\n iconSize: \"medium\",\n spacing: 10,\n align: \"center\",\n};\n\nexport const SPACER_BLOCK_DEFAULTS: BlockDefaultsFor<SpacerBlock> = {\n height: 24,\n};\n\nexport const HTML_BLOCK_DEFAULTS: BlockDefaultsFor<HtmlBlock> = {\n content: \"\",\n};\n\nexport const MENU_BLOCK_DEFAULTS: BlockDefaultsFor<MenuBlock> = {\n fontSize: 15,\n color: \"#1a1a1a\",\n textAlign: \"center\",\n separator: \"|\",\n separatorColor: \"#e0e0e0\",\n spacing: 10,\n};\n\nexport const TABLE_BLOCK_DEFAULTS: BlockDefaultsFor<TableBlock> = {\n hasHeaderRow: true,\n borderColor: \"#e0e0e0\",\n borderWidth: 1,\n cellPadding: 8,\n fontSize: 15,\n color: \"#1a1a1a\",\n textAlign: \"left\",\n};\n\nexport const COUNTDOWN_BLOCK_DEFAULTS: BlockDefaultsFor<CountdownBlock> = {\n targetDate: \"\",\n timezone: \"UTC\",\n showDays: true,\n showHours: true,\n showMinutes: true,\n showSeconds: true,\n separator: \":\",\n digitFontSize: 32,\n digitColor: \"#1a1a1a\",\n labelColor: \"#6b7280\",\n labelFontSize: 12,\n backgroundColor: \"#ffffff\",\n labelDays: \"Days\",\n labelHours: \"Hours\",\n labelMinutes: \"Minutes\",\n labelSeconds: \"Seconds\",\n expiredMessage: \"This offer has expired\",\n expiredImageUrl: \"\",\n hideOnExpiry: false,\n};\n\nexport const DEFAULT_BLOCK_DEFAULTS: Required<BlockDefaults> = {\n text: TEXT_BLOCK_DEFAULTS,\n image: IMAGE_BLOCK_DEFAULTS,\n button: BUTTON_BLOCK_DEFAULTS,\n divider: DIVIDER_BLOCK_DEFAULTS,\n section: SECTION_BLOCK_DEFAULTS,\n video: VIDEO_BLOCK_DEFAULTS,\n social: SOCIAL_ICONS_BLOCK_DEFAULTS,\n spacer: SPACER_BLOCK_DEFAULTS,\n html: HTML_BLOCK_DEFAULTS,\n menu: MENU_BLOCK_DEFAULTS,\n table: TABLE_BLOCK_DEFAULTS,\n countdown: COUNTDOWN_BLOCK_DEFAULTS,\n};\n\nexport const DEFAULT_TEMPLATE_DEFAULTS: TemplateDefaults = {\n width: 600,\n backgroundColor: \"#ffffff\",\n fontFamily: \"Arial, sans-serif\",\n};\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.getPrototypeOf(value) === Object.prototype\n );\n}\n\nexport function deepMergeDefaults<T extends Record<string, unknown>>(\n base: T,\n overrides: Partial<T>,\n): T {\n const result = { ...base };\n\n for (const key of Object.keys(overrides) as Array<keyof T>) {\n const baseVal = base[key];\n const overrideVal = overrides[key];\n\n if (overrideVal === undefined) {\n continue;\n }\n\n if (isPlainObject(baseVal) && isPlainObject(overrideVal)) {\n result[key] = deepMergeDefaults(\n baseVal as Record<string, unknown>,\n overrideVal as Record<string, unknown>,\n ) as T[keyof T];\n } else {\n result[key] = overrideVal as T[keyof T];\n }\n }\n\n return result;\n}\n","import type { Block } from \"./blocks\";\nimport { DEFAULT_TEMPLATE_DEFAULTS } from \"./defaults\";\nimport type { TemplateDefaults } from \"./defaults\";\n\nexport interface TemplateSettings {\n width: number;\n backgroundColor: string;\n fontFamily: string;\n preheaderText?: string;\n}\n\nexport interface TemplateContent {\n blocks: Block[];\n settings: TemplateSettings;\n}\n\nexport function createDefaultTemplateContent(\n defaultFontFamily = \"Arial, sans-serif\",\n templateDefaults?: TemplateDefaults,\n): TemplateContent {\n return {\n blocks: [],\n settings: {\n ...DEFAULT_TEMPLATE_DEFAULTS,\n fontFamily: defaultFontFamily,\n ...templateDefaults,\n } as TemplateSettings,\n };\n}\n","import type {\n Block,\n BlockStyles,\n BlockType,\n ButtonBlock,\n CountdownBlock,\n CustomBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n SpacingValue,\n TableBlock,\n TableCellData,\n TableRowData,\n TextBlock,\n VideoBlock,\n} from \"./blocks\";\nimport type { CustomBlockDefinition, CustomBlockField } from \"./custom-blocks\";\nimport type { BlockDefaults } from \"./defaults\";\nimport {\n BUTTON_BLOCK_DEFAULTS,\n COUNTDOWN_BLOCK_DEFAULTS,\n deepMergeDefaults,\n DIVIDER_BLOCK_DEFAULTS,\n HTML_BLOCK_DEFAULTS,\n IMAGE_BLOCK_DEFAULTS,\n MENU_BLOCK_DEFAULTS,\n SECTION_BLOCK_DEFAULTS,\n SOCIAL_ICONS_BLOCK_DEFAULTS,\n SPACER_BLOCK_DEFAULTS,\n TABLE_BLOCK_DEFAULTS,\n TEXT_BLOCK_DEFAULTS,\n VIDEO_BLOCK_DEFAULTS,\n} from \"./defaults\";\n\nfunction applyDefaults<T>(base: T, partial: Partial<T> | undefined): T {\n if (!partial || Object.keys(partial).length === 0) return base;\n return deepMergeDefaults(\n base as unknown as Record<string, unknown>,\n partial as unknown as Record<string, unknown>,\n ) as unknown as T;\n}\n\nexport function generateId(): string {\n return crypto.randomUUID();\n}\n\nfunction createDefaultSpacing(value = 0): SpacingValue {\n return { top: value, right: value, bottom: value, left: value };\n}\n\nfunction createDefaultStyles(padding = 10): BlockStyles {\n return {\n padding: createDefaultSpacing(padding),\n margin: createDefaultSpacing(0),\n };\n}\n\nexport function createTextBlock(partial: Partial<TextBlock> = {}): TextBlock {\n const base: TextBlock = {\n id: generateId(),\n type: \"text\",\n ...TEXT_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as TextBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createImageBlock(\n partial: Partial<ImageBlock> = {},\n): ImageBlock {\n const base: ImageBlock = {\n id: generateId(),\n type: \"image\",\n ...IMAGE_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as ImageBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createButtonBlock(\n partial: Partial<ButtonBlock> = {},\n): ButtonBlock {\n const base: ButtonBlock = {\n id: generateId(),\n type: \"button\",\n ...BUTTON_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as ButtonBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createDividerBlock(\n partial: Partial<DividerBlock> = {},\n): DividerBlock {\n const base: DividerBlock = {\n id: generateId(),\n type: \"divider\",\n ...DIVIDER_BLOCK_DEFAULTS,\n styles: createDefaultStyles(20),\n } as DividerBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSectionBlock(\n partial: Partial<SectionBlock> = {},\n): SectionBlock {\n const base: SectionBlock = {\n id: generateId(),\n type: \"section\",\n ...SECTION_BLOCK_DEFAULTS,\n children: [[]],\n styles: createDefaultStyles(20),\n } as SectionBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createVideoBlock(\n partial: Partial<VideoBlock> = {},\n): VideoBlock {\n const base: VideoBlock = {\n id: generateId(),\n type: \"video\",\n ...VIDEO_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as VideoBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSocialIconsBlock(\n partial: Partial<SocialIconsBlock> = {},\n): SocialIconsBlock {\n const base: SocialIconsBlock = {\n id: generateId(),\n type: \"social\",\n icons: [],\n ...SOCIAL_ICONS_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as SocialIconsBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSpacerBlock(\n partial: Partial<SpacerBlock> = {},\n): SpacerBlock {\n const base: SpacerBlock = {\n id: generateId(),\n type: \"spacer\",\n ...SPACER_BLOCK_DEFAULTS,\n styles: createDefaultStyles(0),\n } as SpacerBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createHtmlBlock(partial: Partial<HtmlBlock> = {}): HtmlBlock {\n const base: HtmlBlock = {\n id: generateId(),\n type: \"html\",\n ...HTML_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as HtmlBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createMenuBlock(partial: Partial<MenuBlock> = {}): MenuBlock {\n const base: MenuBlock = {\n id: generateId(),\n type: \"menu\",\n items: [],\n ...MENU_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as MenuBlock;\n return applyDefaults(base, partial);\n}\n\nfunction createDefaultTableRows(columns: number, rows: number): TableRowData[] {\n return Array.from({ length: rows }, () => ({\n id: generateId(),\n cells: Array.from(\n { length: columns },\n (): TableCellData => ({\n id: generateId(),\n content: \"\",\n }),\n ),\n }));\n}\n\nexport function createTableBlock(\n partial: Partial<TableBlock> = {},\n): TableBlock {\n const base: TableBlock = {\n id: generateId(),\n type: \"table\",\n rows: createDefaultTableRows(3, 3),\n ...TABLE_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as TableBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createCountdownBlock(\n partial: Partial<CountdownBlock> = {},\n): CountdownBlock {\n const base: CountdownBlock = {\n id: generateId(),\n type: \"countdown\",\n ...COUNTDOWN_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as CountdownBlock;\n return applyDefaults(base, partial);\n}\n\nfunction getFieldDefault(field: CustomBlockField): unknown {\n if (field.type === \"repeatable\") {\n return field.default ?? [];\n }\n if (field.type === \"boolean\") {\n return field.default ?? false;\n }\n if (field.type === \"number\") {\n return field.default ?? 0;\n }\n\n return field.default ?? \"\";\n}\n\nexport function createCustomBlock(\n definition: CustomBlockDefinition,\n): CustomBlock {\n const fieldValues: Record<string, unknown> = {};\n\n for (const field of definition.fields) {\n fieldValues[field.key] = getFieldDefault(field);\n }\n\n return {\n id: generateId(),\n type: \"custom\",\n customType: definition.type,\n fieldValues,\n styles: createDefaultStyles(),\n ...(definition.dataSource ? { dataSourceFetched: false } : {}),\n };\n}\n\nexport function createBlock(\n type: BlockType,\n blockDefaults?: BlockDefaults,\n): Block {\n switch (type) {\n case \"section\":\n return createSectionBlock(blockDefaults?.section);\n case \"text\":\n return createTextBlock(blockDefaults?.text);\n case \"image\":\n return createImageBlock(blockDefaults?.image);\n case \"button\":\n return createButtonBlock(blockDefaults?.button);\n case \"divider\":\n return createDividerBlock(blockDefaults?.divider);\n case \"video\":\n return createVideoBlock(blockDefaults?.video);\n case \"social\":\n return createSocialIconsBlock(blockDefaults?.social);\n case \"spacer\":\n return createSpacerBlock(blockDefaults?.spacer);\n case \"html\":\n return createHtmlBlock(blockDefaults?.html);\n case \"menu\":\n return createMenuBlock(blockDefaults?.menu);\n case \"table\":\n return createTableBlock(blockDefaults?.table);\n case \"countdown\":\n return createCountdownBlock(blockDefaults?.countdown);\n default:\n throw new Error(`Unknown block type: ${type}`);\n }\n}\n\nexport function cloneBlock(block: Block): Block {\n const cloned = JSON.parse(JSON.stringify(block)) as Block;\n cloned.id = generateId();\n\n if (cloned.type === \"section\") {\n cloned.children = cloned.children.map((column) =>\n column.map((child) => cloneBlock(child)),\n );\n }\n\n return cloned;\n}\n","export class EventEmitter<\n TEvents extends Record<string, unknown> = Record<string, unknown>,\n> {\n private handlers = new Map<keyof TEvents, Set<(data: never) => void>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: (data: TEvents[K]) => void,\n ): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n\n const set = this.handlers.get(event)!;\n set.add(handler as (data: never) => void);\n\n return () => {\n set.delete(handler as (data: never) => void);\n if (set.size === 0) {\n this.handlers.delete(event);\n }\n };\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: (data: TEvents[K]) => void,\n ): void {\n const set = this.handlers.get(event);\n if (!set) {\n return;\n }\n\n set.delete(handler as (data: never) => void);\n if (set.size === 0) {\n this.handlers.delete(event);\n }\n }\n\n emit<K extends keyof TEvents>(event: K, data: TEvents[K]): void {\n const set = this.handlers.get(event);\n if (!set) {\n return;\n }\n\n // Copy to avoid issues with handlers modifying the set during iteration\n for (const handler of [...set]) {\n handler(data as never);\n }\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.handlers.delete(event);\n } else {\n this.handlers.clear();\n }\n }\n\n listenerCount(event: keyof TEvents): number {\n return this.handlers.get(event)?.size ?? 0;\n }\n}\n","import type { MergeTag } from \"./config\";\n\n// --- Syntax Presets ---\n\nexport interface SyntaxPreset {\n value: RegExp;\n logic: RegExp;\n}\n\nexport type SyntaxPresetName =\n | \"liquid\"\n | \"handlebars\"\n | \"mailchimp\"\n | \"ampscript\";\n\nexport const SYNTAX_PRESETS: Record<SyntaxPresetName, SyntaxPreset> = {\n liquid: { value: /\\{\\{.+?\\}\\}/g, logic: /\\{%-?\\s*(\\w+).*?-?%\\}/g },\n handlebars: {\n value: /\\{\\{\\{?.+?\\}?\\}\\}/g,\n logic: /\\{\\{[#/](\\w+).*?\\}\\}/g,\n },\n mailchimp: { value: /\\*\\|\\w+\\|\\*/g, logic: /\\*\\|(\\w+)[:|].*?\\|\\*/g },\n ampscript: { value: /%%=.+?=%%/g, logic: /%%\\[\\s*(\\w+).*?\\]%%/g },\n};\n\nexport function resolveSyntax(\n syntax?: SyntaxPresetName | SyntaxPreset,\n): SyntaxPreset {\n if (!syntax) {\n return SYNTAX_PRESETS.liquid;\n }\n\n if (typeof syntax === \"string\") {\n return SYNTAX_PRESETS[syntax];\n }\n\n return syntax;\n}\n\n// --- Merge Tag Utilities ---\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction anchoredRegex(pattern: RegExp): RegExp {\n const source = pattern.source;\n const flags = pattern.flags.replace(\"g\", \"\");\n return new RegExp(`^${source}$`, flags);\n}\n\nexport function isMergeTagValue(value: string, syntax: SyntaxPreset): boolean {\n return anchoredRegex(syntax.value).test(value?.trim() || \"\");\n}\n\nexport function getMergeTagLabel(value: string, mergeTags: MergeTag[]): string {\n const found = mergeTags.find((p) => p.value === value);\n if (found) {\n return found.label;\n }\n return value;\n}\n\nexport function resolveHtmlMergeTagLabels(\n html: string,\n mergeTags: MergeTag[],\n): string {\n return html.replace(\n /(<span[^>]*\\sdata-merge-tag=\"([^\"]*)\"[^>]*>)(.*?)(<\\/span>)/g,\n (_match, openTag, value, _oldLabel, closeTag) => {\n const label = getMergeTagLabel(value, mergeTags);\n return `${openTag}${label}${closeTag}`;\n },\n );\n}\n\nexport function containsMergeTag(value: string, syntax: SyntaxPreset): boolean {\n if (!value) return false;\n\n const valueRegex = new RegExp(syntax.value.source, syntax.value.flags);\n const logicRegex = new RegExp(syntax.logic.source, syntax.logic.flags);\n\n return valueRegex.test(value) || logicRegex.test(value);\n}\n\nexport function restoreMergeTagMarkup(\n html: string,\n mergeTags: MergeTag[],\n syntax: SyntaxPreset,\n): string {\n let result = html;\n\n for (const tag of mergeTags) {\n const escaped = escapeRegExp(tag.value);\n const pattern = new RegExp(`(?<!data-merge-tag=\")${escaped}`, \"g\");\n result = result.replace(pattern, (match) => {\n const label = getMergeTagLabel(match, mergeTags);\n return `<span data-merge-tag=\"${match}\">${label}</span>`;\n });\n }\n\n const logicRegex = new RegExp(\n `(?<!data-logic-merge-tag=\")${syntax.logic.source}`,\n syntax.logic.flags,\n );\n result = result.replace(logicRegex, (match) => {\n const keyword = getLogicMergeTagKeyword(match, syntax);\n return `<span data-logic-merge-tag=\"${match}\">${keyword}</span>`;\n });\n\n return result;\n}\n\nexport function isLogicMergeTagValue(\n value: string,\n syntax: SyntaxPreset,\n): boolean {\n return anchoredRegex(syntax.logic).test(value?.trim() || \"\");\n}\n\nexport function getLogicMergeTagKeyword(\n value: string,\n syntax: SyntaxPreset,\n): string {\n const regex = new RegExp(\n syntax.logic.source,\n syntax.logic.flags.replace(\"g\", \"\"),\n );\n const match = value.match(regex);\n return match && match[1] ? match[1].toUpperCase() : value;\n}\n\nexport function resolveHtmlLogicMergeTagLabels(\n html: string,\n syntax: SyntaxPreset,\n): string {\n return html.replace(\n /(<span[^>]*\\sdata-logic-merge-tag=\"([^\"]*)\"[^>]*>)(.*?)(<\\/span>)/g,\n (_match, openTag, value, _oldLabel, closeTag) => {\n const keyword = getLogicMergeTagKeyword(value, syntax);\n return `${openTag}${keyword}${closeTag}`;\n },\n );\n}\n","import type { SyntaxPreset, SyntaxPresetName } from \"./merge-tags\";\n\nexport type ViewportSize = \"desktop\" | \"tablet\" | \"mobile\";\n\nexport interface CustomFont {\n name: string;\n url: string;\n fallback?: string;\n}\n\nexport interface FontsConfig {\n defaultFallback?: string;\n defaultFont?: string;\n customFonts?: CustomFont[];\n}\n\nexport interface ExportResult {\n html: string;\n mjml: string;\n}\n\nexport interface MergeTag {\n label: string;\n value: string;\n}\n\nexport interface MediaResult {\n url: string;\n alt?: string;\n}\n\nexport interface MergeTagsConfig {\n syntax?: SyntaxPresetName | SyntaxPreset;\n tags?: MergeTag[];\n onRequest?: () => Promise<MergeTag | null>;\n}\n\nexport interface DisplayCondition {\n label: string;\n before: string;\n after: string;\n group?: string;\n description?: string;\n}\n\nexport interface DisplayConditionsConfig {\n conditions: DisplayCondition[];\n allowCustom?: boolean;\n}\n\nexport interface ThemeOverrides {\n bg?: string;\n bgElevated?: string;\n bgHover?: string;\n bgActive?: string;\n border?: string;\n borderLight?: string;\n text?: string;\n textMuted?: string;\n textDim?: string;\n primary?: string;\n primaryHover?: string;\n primaryLight?: string;\n secondary?: string;\n secondaryHover?: string;\n secondaryLight?: string;\n success?: string;\n successLight?: string;\n warning?: string;\n warningLight?: string;\n danger?: string;\n dangerLight?: string;\n canvasBg?: string;\n}\n\nexport class SdkError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"SdkError\";\n }\n\n get isNotFound(): boolean {\n return this.statusCode === 404;\n }\n\n get isUnauthorized(): boolean {\n return this.statusCode === 401;\n }\n\n get isServerError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 500;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/blocks.ts","../src/guards.ts","../src/defaults.ts","../src/template.ts","../src/factory.ts","../src/events.ts","../src/merge-tags.ts","../src/config.ts"],"sourcesContent":["export interface SpacingValue {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\nexport interface ResponsiveStyles {\n tablet?: Partial<BlockStyles>;\n mobile?: Partial<BlockStyles>;\n}\n\nexport interface BlockStyles {\n padding: SpacingValue;\n margin: SpacingValue;\n backgroundColor?: string;\n responsive?: ResponsiveStyles;\n}\n\nexport interface BlockVisibility {\n desktop: boolean;\n tablet: boolean;\n mobile: boolean;\n}\n\nexport interface BaseBlock {\n id: string;\n type: string;\n styles: BlockStyles;\n customCss?: string;\n visibility?: BlockVisibility;\n displayCondition?: {\n label: string;\n before: string;\n after: string;\n group?: string;\n description?: string;\n };\n}\n\nexport type ColumnLayout = \"1\" | \"2\" | \"3\" | \"2-1\" | \"1-2\";\n\nexport interface SectionBlock extends BaseBlock {\n type: \"section\";\n columns: ColumnLayout;\n children: Block[][];\n}\n\nexport type HeadingLevel = 1 | 2 | 3 | 4;\n\nexport const HEADING_LEVEL_FONT_SIZE: Record<HeadingLevel, number> = {\n 1: 36,\n 2: 28,\n 3: 22,\n 4: 18,\n};\n\nexport interface TitleBlock extends BaseBlock {\n type: \"title\";\n content: string;\n level: HeadingLevel;\n color: string;\n textAlign: \"left\" | \"center\" | \"right\";\n fontFamily?: string;\n}\n\nexport interface ParagraphBlock extends BaseBlock {\n type: \"paragraph\";\n content: string;\n}\n\nexport interface ImageBlock extends BaseBlock {\n type: \"image\";\n src: string;\n alt: string;\n width: number | \"full\";\n align: \"left\" | \"center\" | \"right\";\n linkUrl?: string;\n linkOpenInNewTab?: boolean;\n placeholderUrl?: string;\n}\n\nexport interface ButtonBlock extends BaseBlock {\n type: \"button\";\n text: string;\n url: string;\n openInNewTab?: boolean;\n backgroundColor: string;\n textColor: string;\n borderRadius: number;\n fontSize: number;\n buttonPadding: SpacingValue;\n fontFamily?: string;\n}\n\nexport interface DividerBlock extends BaseBlock {\n type: \"divider\";\n lineStyle: \"solid\" | \"dashed\" | \"dotted\";\n color: string;\n thickness: number;\n width: number | \"full\";\n}\n\nexport interface VideoBlock extends BaseBlock {\n type: \"video\";\n url: string;\n openInNewTab?: boolean;\n thumbnailUrl: string;\n alt: string;\n width: number | \"full\";\n align: \"left\" | \"center\" | \"right\";\n placeholderUrl?: string;\n}\n\nexport type SocialPlatform =\n | \"facebook\"\n | \"twitter\"\n | \"instagram\"\n | \"linkedin\"\n | \"youtube\"\n | \"tiktok\"\n | \"pinterest\"\n | \"email\"\n | \"whatsapp\"\n | \"telegram\"\n | \"discord\"\n | \"snapchat\"\n | \"reddit\"\n | \"github\"\n | \"dribbble\"\n | \"behance\";\n\nexport type SocialIconStyle =\n | \"solid\"\n | \"outlined\"\n | \"rounded\"\n | \"square\"\n | \"circle\";\n\nexport type SocialIconSize = \"small\" | \"medium\" | \"large\";\n\nexport interface SocialIcon {\n id: string;\n platform: SocialPlatform;\n url: string;\n}\n\nexport interface SocialIconsBlock extends BaseBlock {\n type: \"social\";\n icons: SocialIcon[];\n iconStyle: SocialIconStyle;\n iconSize: SocialIconSize;\n spacing: number;\n align: \"left\" | \"center\" | \"right\";\n}\n\nexport interface SpacerBlock extends BaseBlock {\n type: \"spacer\";\n height: number;\n}\n\nexport interface HtmlBlock extends BaseBlock {\n type: \"html\";\n content: string;\n}\n\nexport interface MenuItemData {\n id: string;\n text: string;\n url: string;\n openInNewTab: boolean;\n bold: boolean;\n underline: boolean;\n color?: string;\n}\n\nexport interface MenuBlock extends BaseBlock {\n type: \"menu\";\n items: MenuItemData[];\n fontSize: number;\n fontFamily?: string;\n color: string;\n linkColor?: string;\n textAlign: \"left\" | \"center\" | \"right\";\n separator: string;\n separatorColor: string;\n spacing: number;\n}\n\nexport interface TableCellData {\n id: string;\n content: string;\n}\n\nexport interface TableRowData {\n id: string;\n cells: TableCellData[];\n}\n\nexport interface TableBlock extends BaseBlock {\n type: \"table\";\n rows: TableRowData[];\n hasHeaderRow: boolean;\n headerBackgroundColor?: string;\n borderColor: string;\n borderWidth: number;\n cellPadding: number;\n fontSize: number;\n fontFamily?: string;\n color: string;\n textAlign: \"left\" | \"center\" | \"right\";\n}\n\nexport interface CountdownBlock extends BaseBlock {\n type: \"countdown\";\n targetDate: string;\n timezone: string;\n showDays: boolean;\n showHours: boolean;\n showMinutes: boolean;\n showSeconds: boolean;\n separator: \":\" | \"-\" | \" \";\n digitFontSize: number;\n digitColor: string;\n labelColor: string;\n labelFontSize: number;\n backgroundColor: string;\n fontFamily?: string;\n labelDays: string;\n labelHours: string;\n labelMinutes: string;\n labelSeconds: string;\n expiredMessage: string;\n expiredImageUrl: string;\n hideOnExpiry: boolean;\n}\n\nexport interface CustomBlock extends BaseBlock {\n type: \"custom\";\n customType: string;\n fieldValues: Record<string, unknown>;\n renderedHtml?: string;\n dataSourceFetched?: boolean;\n}\n\nexport type Block =\n | SectionBlock\n | TitleBlock\n | ParagraphBlock\n | ImageBlock\n | ButtonBlock\n | DividerBlock\n | VideoBlock\n | SocialIconsBlock\n | SpacerBlock\n | HtmlBlock\n | MenuBlock\n | TableBlock\n | CountdownBlock\n | CustomBlock;\n\nexport type BlockType = Block[\"type\"];\n","import type {\n Block,\n ButtonBlock,\n CountdownBlock,\n CustomBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n ParagraphBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n TableBlock,\n TitleBlock,\n VideoBlock,\n} from \"./blocks\";\n\nexport function isSection(block: Block): block is SectionBlock {\n return block.type === \"section\";\n}\n\nexport function isTitle(block: Block): block is TitleBlock {\n return block.type === \"title\";\n}\n\nexport function isParagraph(block: Block): block is ParagraphBlock {\n return block.type === \"paragraph\";\n}\n\nexport function isImage(block: Block): block is ImageBlock {\n return block.type === \"image\";\n}\n\nexport function isButton(block: Block): block is ButtonBlock {\n return block.type === \"button\";\n}\n\nexport function isDivider(block: Block): block is DividerBlock {\n return block.type === \"divider\";\n}\n\nexport function isVideo(block: Block): block is VideoBlock {\n return block.type === \"video\";\n}\n\nexport function isSocialIcons(block: Block): block is SocialIconsBlock {\n return block.type === \"social\";\n}\n\nexport function isSpacer(block: Block): block is SpacerBlock {\n return block.type === \"spacer\";\n}\n\nexport function isHtml(block: Block): block is HtmlBlock {\n return block.type === \"html\";\n}\n\nexport function isMenu(block: Block): block is MenuBlock {\n return block.type === \"menu\";\n}\n\nexport function isTable(block: Block): block is TableBlock {\n return block.type === \"table\";\n}\n\nexport function isCountdown(block: Block): block is CountdownBlock {\n return block.type === \"countdown\";\n}\n\nexport function isCustomBlock(block: Block): block is CustomBlock {\n return block.type === \"custom\";\n}\n","import type {\n ButtonBlock,\n CountdownBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n ParagraphBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n TableBlock,\n TitleBlock,\n VideoBlock,\n} from \"./blocks\";\nimport type { TemplateSettings } from \"./template\";\n\ntype BlockDefaultsFor<T> = Partial<Omit<T, \"id\" | \"type\">>;\n\nexport interface BlockDefaults {\n title?: BlockDefaultsFor<TitleBlock>;\n paragraph?: BlockDefaultsFor<ParagraphBlock>;\n image?: BlockDefaultsFor<ImageBlock>;\n button?: BlockDefaultsFor<ButtonBlock>;\n divider?: BlockDefaultsFor<DividerBlock>;\n section?: BlockDefaultsFor<SectionBlock>;\n video?: BlockDefaultsFor<VideoBlock>;\n social?: BlockDefaultsFor<SocialIconsBlock>;\n spacer?: BlockDefaultsFor<SpacerBlock>;\n html?: BlockDefaultsFor<HtmlBlock>;\n menu?: BlockDefaultsFor<MenuBlock>;\n table?: BlockDefaultsFor<TableBlock>;\n countdown?: BlockDefaultsFor<CountdownBlock>;\n}\n\nexport type TemplateDefaults = Partial<TemplateSettings>;\n\n// ---------------------------------------------------------------------------\n// Built-in default values — single source of truth for factories & consumers\n// ---------------------------------------------------------------------------\n\nexport const TITLE_BLOCK_DEFAULTS: BlockDefaultsFor<TitleBlock> = {\n content: \"<p>Enter your title</p>\",\n level: 2,\n color: \"#1a1a1a\",\n textAlign: \"left\",\n};\n\nexport const PARAGRAPH_BLOCK_DEFAULTS: BlockDefaultsFor<ParagraphBlock> = {\n content: \"<p>Enter your text here</p>\",\n};\n\nexport const IMAGE_BLOCK_DEFAULTS: BlockDefaultsFor<ImageBlock> = {\n src: \"\",\n alt: \"\",\n width: \"full\",\n align: \"center\",\n};\n\nexport const BUTTON_BLOCK_DEFAULTS: BlockDefaultsFor<ButtonBlock> = {\n text: \"Click Here\",\n url: \"\",\n backgroundColor: \"#333333\",\n textColor: \"#ffffff\",\n borderRadius: 6,\n fontSize: 15,\n buttonPadding: { top: 12, right: 24, bottom: 12, left: 24 },\n};\n\nexport const DIVIDER_BLOCK_DEFAULTS: BlockDefaultsFor<DividerBlock> = {\n lineStyle: \"solid\",\n color: \"#e0e0e0\",\n thickness: 1,\n width: \"full\",\n};\n\nexport const SECTION_BLOCK_DEFAULTS: BlockDefaultsFor<SectionBlock> = {\n columns: \"1\",\n};\n\nexport const VIDEO_BLOCK_DEFAULTS: BlockDefaultsFor<VideoBlock> = {\n url: \"\",\n thumbnailUrl: \"\",\n alt: \"Video\",\n width: \"full\",\n align: \"center\",\n};\n\nexport const SOCIAL_ICONS_BLOCK_DEFAULTS: BlockDefaultsFor<SocialIconsBlock> = {\n iconStyle: \"solid\",\n iconSize: \"medium\",\n spacing: 10,\n align: \"center\",\n};\n\nexport const SPACER_BLOCK_DEFAULTS: BlockDefaultsFor<SpacerBlock> = {\n height: 24,\n};\n\nexport const HTML_BLOCK_DEFAULTS: BlockDefaultsFor<HtmlBlock> = {\n content: \"\",\n};\n\nexport const MENU_BLOCK_DEFAULTS: BlockDefaultsFor<MenuBlock> = {\n fontSize: 15,\n color: \"#1a1a1a\",\n textAlign: \"center\",\n separator: \"|\",\n separatorColor: \"#e0e0e0\",\n spacing: 10,\n};\n\nexport const TABLE_BLOCK_DEFAULTS: BlockDefaultsFor<TableBlock> = {\n hasHeaderRow: true,\n borderColor: \"#e0e0e0\",\n borderWidth: 1,\n cellPadding: 8,\n fontSize: 15,\n color: \"#1a1a1a\",\n textAlign: \"left\",\n};\n\nexport const COUNTDOWN_BLOCK_DEFAULTS: BlockDefaultsFor<CountdownBlock> = {\n targetDate: \"\",\n timezone: \"UTC\",\n showDays: true,\n showHours: true,\n showMinutes: true,\n showSeconds: true,\n separator: \":\",\n digitFontSize: 32,\n digitColor: \"#1a1a1a\",\n labelColor: \"#6b7280\",\n labelFontSize: 12,\n backgroundColor: \"#ffffff\",\n labelDays: \"Days\",\n labelHours: \"Hours\",\n labelMinutes: \"Minutes\",\n labelSeconds: \"Seconds\",\n expiredMessage: \"This offer has expired\",\n expiredImageUrl: \"\",\n hideOnExpiry: false,\n};\n\nexport const DEFAULT_BLOCK_DEFAULTS: Required<BlockDefaults> = {\n title: TITLE_BLOCK_DEFAULTS,\n paragraph: PARAGRAPH_BLOCK_DEFAULTS,\n image: IMAGE_BLOCK_DEFAULTS,\n button: BUTTON_BLOCK_DEFAULTS,\n divider: DIVIDER_BLOCK_DEFAULTS,\n section: SECTION_BLOCK_DEFAULTS,\n video: VIDEO_BLOCK_DEFAULTS,\n social: SOCIAL_ICONS_BLOCK_DEFAULTS,\n spacer: SPACER_BLOCK_DEFAULTS,\n html: HTML_BLOCK_DEFAULTS,\n menu: MENU_BLOCK_DEFAULTS,\n table: TABLE_BLOCK_DEFAULTS,\n countdown: COUNTDOWN_BLOCK_DEFAULTS,\n};\n\nexport const DEFAULT_TEMPLATE_DEFAULTS: TemplateDefaults = {\n width: 600,\n backgroundColor: \"#ffffff\",\n fontFamily: \"Arial\",\n};\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.getPrototypeOf(value) === Object.prototype\n );\n}\n\nexport function deepMergeDefaults<T extends object>(\n base: T,\n overrides: Partial<T>,\n): T {\n const result = { ...base };\n\n for (const key of Object.keys(overrides) as Array<keyof T>) {\n const baseVal = base[key];\n const overrideVal = overrides[key];\n\n if (overrideVal === undefined) {\n continue;\n }\n\n if (isPlainObject(baseVal) && isPlainObject(overrideVal)) {\n result[key] = deepMergeDefaults(\n baseVal,\n overrideVal as Partial<typeof baseVal>,\n ) as T[keyof T];\n } else {\n result[key] = overrideVal as T[keyof T];\n }\n }\n\n return result;\n}\n","import type { Block } from \"./blocks\";\nimport { DEFAULT_TEMPLATE_DEFAULTS } from \"./defaults\";\nimport type { TemplateDefaults } from \"./defaults\";\n\nexport interface TemplateSettings {\n width: number;\n backgroundColor: string;\n fontFamily: string;\n preheaderText?: string;\n}\n\nexport interface TemplateContent {\n blocks: Block[];\n settings: TemplateSettings;\n}\n\nexport function createDefaultTemplateContent(\n defaultFontFamily = \"Arial\",\n templateDefaults?: TemplateDefaults,\n): TemplateContent {\n return {\n blocks: [],\n settings: {\n ...DEFAULT_TEMPLATE_DEFAULTS,\n fontFamily: defaultFontFamily,\n ...templateDefaults,\n } as TemplateSettings,\n };\n}\n","import type {\n Block,\n BlockStyles,\n BlockType,\n ButtonBlock,\n CountdownBlock,\n CustomBlock,\n DividerBlock,\n HtmlBlock,\n ImageBlock,\n MenuBlock,\n ParagraphBlock,\n SectionBlock,\n SocialIconsBlock,\n SpacerBlock,\n SpacingValue,\n TableBlock,\n TableCellData,\n TableRowData,\n TitleBlock,\n VideoBlock,\n} from \"./blocks\";\nimport type { CustomBlockDefinition, CustomBlockField } from \"./custom-blocks\";\nimport type { BlockDefaults } from \"./defaults\";\nimport {\n BUTTON_BLOCK_DEFAULTS,\n COUNTDOWN_BLOCK_DEFAULTS,\n deepMergeDefaults,\n DIVIDER_BLOCK_DEFAULTS,\n HTML_BLOCK_DEFAULTS,\n IMAGE_BLOCK_DEFAULTS,\n MENU_BLOCK_DEFAULTS,\n PARAGRAPH_BLOCK_DEFAULTS,\n SECTION_BLOCK_DEFAULTS,\n SOCIAL_ICONS_BLOCK_DEFAULTS,\n SPACER_BLOCK_DEFAULTS,\n TABLE_BLOCK_DEFAULTS,\n TITLE_BLOCK_DEFAULTS,\n VIDEO_BLOCK_DEFAULTS,\n} from \"./defaults\";\n\nfunction applyDefaults<T extends object>(\n base: T,\n partial: Partial<T> | undefined,\n): T {\n if (!partial || Object.keys(partial).length === 0) return base;\n return deepMergeDefaults(base, partial);\n}\n\nexport function generateId(): string {\n return crypto.randomUUID();\n}\n\nfunction createDefaultSpacing(value = 0): SpacingValue {\n return { top: value, right: value, bottom: value, left: value };\n}\n\nfunction createDefaultStyles(padding = 10): BlockStyles {\n return {\n padding: createDefaultSpacing(padding),\n margin: createDefaultSpacing(0),\n };\n}\n\nexport function createTitleBlock(\n partial: Partial<TitleBlock> = {},\n): TitleBlock {\n const base: TitleBlock = {\n id: generateId(),\n type: \"title\",\n ...TITLE_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as TitleBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createParagraphBlock(\n partial: Partial<ParagraphBlock> = {},\n): ParagraphBlock {\n const base: ParagraphBlock = {\n id: generateId(),\n type: \"paragraph\",\n ...PARAGRAPH_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as ParagraphBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createImageBlock(\n partial: Partial<ImageBlock> = {},\n): ImageBlock {\n const base: ImageBlock = {\n id: generateId(),\n type: \"image\",\n ...IMAGE_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as ImageBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createButtonBlock(\n partial: Partial<ButtonBlock> = {},\n): ButtonBlock {\n const base: ButtonBlock = {\n id: generateId(),\n type: \"button\",\n ...BUTTON_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as ButtonBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createDividerBlock(\n partial: Partial<DividerBlock> = {},\n): DividerBlock {\n const base: DividerBlock = {\n id: generateId(),\n type: \"divider\",\n ...DIVIDER_BLOCK_DEFAULTS,\n styles: createDefaultStyles(20),\n } as DividerBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSectionBlock(\n partial: Partial<SectionBlock> = {},\n): SectionBlock {\n const base: SectionBlock = {\n id: generateId(),\n type: \"section\",\n ...SECTION_BLOCK_DEFAULTS,\n children: [[]],\n styles: createDefaultStyles(20),\n } as SectionBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createVideoBlock(\n partial: Partial<VideoBlock> = {},\n): VideoBlock {\n const base: VideoBlock = {\n id: generateId(),\n type: \"video\",\n ...VIDEO_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as VideoBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSocialIconsBlock(\n partial: Partial<SocialIconsBlock> = {},\n): SocialIconsBlock {\n const base: SocialIconsBlock = {\n id: generateId(),\n type: \"social\",\n icons: [],\n ...SOCIAL_ICONS_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as SocialIconsBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createSpacerBlock(\n partial: Partial<SpacerBlock> = {},\n): SpacerBlock {\n const base: SpacerBlock = {\n id: generateId(),\n type: \"spacer\",\n ...SPACER_BLOCK_DEFAULTS,\n styles: createDefaultStyles(0),\n } as SpacerBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createHtmlBlock(partial: Partial<HtmlBlock> = {}): HtmlBlock {\n const base: HtmlBlock = {\n id: generateId(),\n type: \"html\",\n ...HTML_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as HtmlBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createMenuBlock(partial: Partial<MenuBlock> = {}): MenuBlock {\n const base: MenuBlock = {\n id: generateId(),\n type: \"menu\",\n items: [],\n ...MENU_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as MenuBlock;\n return applyDefaults(base, partial);\n}\n\nfunction createDefaultTableRows(columns: number, rows: number): TableRowData[] {\n return Array.from({ length: rows }, () => ({\n id: generateId(),\n cells: Array.from(\n { length: columns },\n (): TableCellData => ({\n id: generateId(),\n content: \"\",\n }),\n ),\n }));\n}\n\nexport function createTableBlock(\n partial: Partial<TableBlock> = {},\n): TableBlock {\n const base: TableBlock = {\n id: generateId(),\n type: \"table\",\n rows: createDefaultTableRows(3, 3),\n ...TABLE_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as TableBlock;\n return applyDefaults(base, partial);\n}\n\nexport function createCountdownBlock(\n partial: Partial<CountdownBlock> = {},\n): CountdownBlock {\n const base: CountdownBlock = {\n id: generateId(),\n type: \"countdown\",\n ...COUNTDOWN_BLOCK_DEFAULTS,\n styles: createDefaultStyles(),\n } as CountdownBlock;\n return applyDefaults(base, partial);\n}\n\nfunction getFieldDefault(field: CustomBlockField): unknown {\n if (field.type === \"repeatable\") {\n return field.default ?? [];\n }\n if (field.type === \"boolean\") {\n return field.default ?? false;\n }\n if (field.type === \"number\") {\n return field.default ?? 0;\n }\n\n return field.default ?? \"\";\n}\n\nexport function createCustomBlock(\n definition: CustomBlockDefinition,\n): CustomBlock {\n const fieldValues: Record<string, unknown> = {};\n\n for (const field of definition.fields) {\n fieldValues[field.key] = getFieldDefault(field);\n }\n\n return {\n id: generateId(),\n type: \"custom\",\n customType: definition.type,\n fieldValues,\n styles: createDefaultStyles(),\n ...(definition.dataSource ? { dataSourceFetched: false } : {}),\n };\n}\n\nexport function createBlock(\n type: BlockType,\n blockDefaults?: BlockDefaults,\n): Block {\n switch (type) {\n case \"section\":\n return createSectionBlock(blockDefaults?.section);\n case \"title\":\n return createTitleBlock(blockDefaults?.title);\n case \"paragraph\":\n return createParagraphBlock(blockDefaults?.paragraph);\n case \"image\":\n return createImageBlock(blockDefaults?.image);\n case \"button\":\n return createButtonBlock(blockDefaults?.button);\n case \"divider\":\n return createDividerBlock(blockDefaults?.divider);\n case \"video\":\n return createVideoBlock(blockDefaults?.video);\n case \"social\":\n return createSocialIconsBlock(blockDefaults?.social);\n case \"spacer\":\n return createSpacerBlock(blockDefaults?.spacer);\n case \"html\":\n return createHtmlBlock(blockDefaults?.html);\n case \"menu\":\n return createMenuBlock(blockDefaults?.menu);\n case \"table\":\n return createTableBlock(blockDefaults?.table);\n case \"countdown\":\n return createCountdownBlock(blockDefaults?.countdown);\n default:\n throw new Error(`Unknown block type: ${type}`);\n }\n}\n\nexport function cloneBlock(block: Block): Block {\n const cloned = JSON.parse(JSON.stringify(block)) as Block;\n cloned.id = generateId();\n\n if (cloned.type === \"section\") {\n cloned.children = cloned.children.map((column) =>\n column.map((child) => cloneBlock(child)),\n );\n }\n\n return cloned;\n}\n","export class EventEmitter<\n TEvents extends Record<string, unknown> = Record<string, unknown>,\n> {\n private handlers = new Map<keyof TEvents, Set<(data: never) => void>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: (data: TEvents[K]) => void,\n ): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n\n const set = this.handlers.get(event)!;\n set.add(handler as (data: never) => void);\n\n return () => {\n set.delete(handler as (data: never) => void);\n if (set.size === 0) {\n this.handlers.delete(event);\n }\n };\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: (data: TEvents[K]) => void,\n ): void {\n const set = this.handlers.get(event);\n if (!set) {\n return;\n }\n\n set.delete(handler as (data: never) => void);\n if (set.size === 0) {\n this.handlers.delete(event);\n }\n }\n\n emit<K extends keyof TEvents>(event: K, data: TEvents[K]): void {\n const set = this.handlers.get(event);\n if (!set) {\n return;\n }\n\n // Copy to avoid issues with handlers modifying the set during iteration\n for (const handler of [...set]) {\n handler(data as never);\n }\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.handlers.delete(event);\n } else {\n this.handlers.clear();\n }\n }\n\n listenerCount(event: keyof TEvents): number {\n return this.handlers.get(event)?.size ?? 0;\n }\n}\n","import type { MergeTag } from \"./config\";\n\n// --- Syntax Presets ---\n\nexport interface SyntaxPreset {\n value: RegExp;\n logic: RegExp;\n}\n\nexport type SyntaxPresetName =\n | \"liquid\"\n | \"handlebars\"\n | \"mailchimp\"\n | \"ampscript\";\n\nexport const SYNTAX_PRESETS: Record<SyntaxPresetName, SyntaxPreset> = {\n liquid: { value: /\\{\\{.+?\\}\\}/g, logic: /\\{%-?\\s*(\\w+).*?-?%\\}/g },\n handlebars: {\n value: /\\{\\{\\{?.+?\\}?\\}\\}/g,\n logic: /\\{\\{[#/](\\w+).*?\\}\\}/g,\n },\n mailchimp: { value: /\\*\\|\\w+\\|\\*/g, logic: /\\*\\|(\\w+)[:|].*?\\|\\*/g },\n ampscript: { value: /%%=.+?=%%/g, logic: /%%\\[\\s*(\\w+).*?\\]%%/g },\n};\n\nexport function resolveSyntax(\n syntax?: SyntaxPresetName | SyntaxPreset,\n): SyntaxPreset {\n if (!syntax) {\n return SYNTAX_PRESETS.liquid;\n }\n\n if (typeof syntax === \"string\") {\n return SYNTAX_PRESETS[syntax];\n }\n\n return syntax;\n}\n\n// --- Merge Tag Utilities ---\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction anchoredRegex(pattern: RegExp): RegExp {\n const source = pattern.source;\n const flags = pattern.flags.replace(\"g\", \"\");\n return new RegExp(`^${source}$`, flags);\n}\n\nexport function isMergeTagValue(value: string, syntax: SyntaxPreset): boolean {\n return anchoredRegex(syntax.value).test(value?.trim() || \"\");\n}\n\nexport function getMergeTagLabel(value: string, mergeTags: MergeTag[]): string {\n const found = mergeTags.find((p) => p.value === value);\n if (found) {\n return found.label;\n }\n return value;\n}\n\nexport function resolveHtmlMergeTagLabels(\n html: string,\n mergeTags: MergeTag[],\n): string {\n return html.replace(\n /(<span[^>]*\\sdata-merge-tag=\"([^\"]*)\"[^>]*>)(.*?)(<\\/span>)/g,\n (_match, openTag, value, _oldLabel, closeTag) => {\n const label = getMergeTagLabel(value, mergeTags);\n return `${openTag}${label}${closeTag}`;\n },\n );\n}\n\nexport function containsMergeTag(value: string, syntax: SyntaxPreset): boolean {\n if (!value) return false;\n\n const valueRegex = new RegExp(syntax.value.source, syntax.value.flags);\n const logicRegex = new RegExp(syntax.logic.source, syntax.logic.flags);\n\n return valueRegex.test(value) || logicRegex.test(value);\n}\n\nexport function restoreMergeTagMarkup(\n html: string,\n mergeTags: MergeTag[],\n syntax: SyntaxPreset,\n): string {\n let result = html;\n\n for (const tag of mergeTags) {\n const escaped = escapeRegExp(tag.value);\n const pattern = new RegExp(`(?<!data-merge-tag=\")${escaped}`, \"g\");\n result = result.replace(pattern, (match) => {\n const label = getMergeTagLabel(match, mergeTags);\n return `<span data-merge-tag=\"${match}\">${label}</span>`;\n });\n }\n\n const logicRegex = new RegExp(\n `(?<!data-logic-merge-tag=\")${syntax.logic.source}`,\n syntax.logic.flags,\n );\n result = result.replace(logicRegex, (match) => {\n const keyword = getLogicMergeTagKeyword(match, syntax);\n return `<span data-logic-merge-tag=\"${match}\">${keyword}</span>`;\n });\n\n return result;\n}\n\nexport function isLogicMergeTagValue(\n value: string,\n syntax: SyntaxPreset,\n): boolean {\n return anchoredRegex(syntax.logic).test(value?.trim() || \"\");\n}\n\nexport function getLogicMergeTagKeyword(\n value: string,\n syntax: SyntaxPreset,\n): string {\n const regex = new RegExp(\n syntax.logic.source,\n syntax.logic.flags.replace(\"g\", \"\"),\n );\n const match = value.match(regex);\n return match && match[1] ? match[1].toUpperCase() : value;\n}\n\nexport function resolveHtmlLogicMergeTagLabels(\n html: string,\n syntax: SyntaxPreset,\n): string {\n return html.replace(\n /(<span[^>]*\\sdata-logic-merge-tag=\"([^\"]*)\"[^>]*>)(.*?)(<\\/span>)/g,\n (_match, openTag, value, _oldLabel, closeTag) => {\n const keyword = getLogicMergeTagKeyword(value, syntax);\n return `${openTag}${keyword}${closeTag}`;\n },\n );\n}\n","import type { SyntaxPreset, SyntaxPresetName } from \"./merge-tags\";\n\nexport type ViewportSize = \"desktop\" | \"tablet\" | \"mobile\";\n\nexport type UiTheme = \"light\" | \"dark\" | \"auto\";\n\nexport interface CustomFont {\n name: string;\n url: string;\n fallback?: string;\n}\n\nexport interface FontsConfig {\n defaultFallback?: string;\n defaultFont?: string;\n customFonts?: CustomFont[];\n}\n\nexport interface ExportResult {\n html: string;\n mjml: string;\n}\n\nexport interface MergeTag {\n label: string;\n value: string;\n}\n\nexport interface MediaResult {\n url: string;\n alt?: string;\n}\n\nexport interface MergeTagsConfig {\n syntax?: SyntaxPresetName | SyntaxPreset;\n tags?: MergeTag[];\n onRequest?: () => Promise<MergeTag | null>;\n}\n\nexport interface DisplayCondition {\n label: string;\n before: string;\n after: string;\n group?: string;\n description?: string;\n}\n\nexport interface DisplayConditionsConfig {\n conditions: DisplayCondition[];\n allowCustom?: boolean;\n}\n\nexport interface ThemeOverrides {\n bg?: string;\n bgElevated?: string;\n bgHover?: string;\n bgActive?: string;\n border?: string;\n borderLight?: string;\n text?: string;\n textMuted?: string;\n textDim?: string;\n primary?: string;\n primaryHover?: string;\n primaryLight?: string;\n secondary?: string;\n secondaryHover?: string;\n secondaryLight?: string;\n success?: string;\n successLight?: string;\n warning?: string;\n warningLight?: string;\n danger?: string;\n dangerLight?: string;\n canvasBg?: string;\n dark?: Omit<ThemeOverrides, \"dark\">;\n}\n\nexport class SdkError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"SdkError\";\n }\n\n get isNotFound(): boolean {\n return this.statusCode === 404;\n }\n\n get isUnauthorized(): boolean {\n return this.statusCode === 401;\n }\n\n get isServerError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 500;\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "name": "@templatical/types",
3
- "version": "0.0.1",
4
- "publishConfig": { "access": "public" },
3
+ "version": "0.0.3",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
5
7
  "description": "Shared TypeScript types, block factory functions, and event emitter for Templatical email editor",
6
8
  "license": "MIT",
7
9
  "type": "module",
@@ -25,8 +27,8 @@
25
27
  },
26
28
  "devDependencies": {
27
29
  "@templatical/media-library": "workspace:*",
28
- "tsup": "^8.0.0",
29
- "typescript": "^5.7.0",
30
- "vitest": "^3.0.0"
30
+ "tsup": "^8.5.0",
31
+ "typescript": "^6.0.0",
32
+ "vitest": "^4.0.0"
31
33
  }
32
34
  }