@templatical/import-beefree 0.0.1

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.js ADDED
@@ -0,0 +1,556 @@
1
+ // src/converter.ts
2
+ import {
3
+ createSectionBlock,
4
+ createDefaultTemplateContent
5
+ } from "@templatical/types";
6
+
7
+ // src/block-mapper.ts
8
+ import {
9
+ createTextBlock,
10
+ createImageBlock,
11
+ createButtonBlock,
12
+ createDividerBlock,
13
+ createSpacerBlock,
14
+ createHtmlBlock,
15
+ createSocialIconsBlock,
16
+ createMenuBlock,
17
+ createTableBlock,
18
+ createVideoBlock,
19
+ generateId
20
+ } from "@templatical/types";
21
+
22
+ // src/style-parser.ts
23
+ function parsePxValue(value) {
24
+ if (!value) return 0;
25
+ const match = value.match(/^(-?\d+(?:\.\d+)?)\s*px/);
26
+ return match ? Math.round(parseFloat(match[1])) : 0;
27
+ }
28
+ function parseColor(value) {
29
+ if (!value || value === "transparent") return "";
30
+ const trimmed = value.trim();
31
+ if (/^#[0-9a-fA-F]{6}$/.test(trimmed)) return trimmed.toLowerCase();
32
+ if (/^#[0-9a-fA-F]{3}$/.test(trimmed)) {
33
+ const r = trimmed[1];
34
+ const g = trimmed[2];
35
+ const b = trimmed[3];
36
+ return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();
37
+ }
38
+ return trimmed;
39
+ }
40
+ function parseBorderTop(value) {
41
+ if (!value) return { width: 0, style: "solid", color: "#000000" };
42
+ const parts = value.trim().split(/\s+/);
43
+ return {
44
+ width: parsePxValue(parts[0]),
45
+ style: parts[1] || "solid",
46
+ color: parseColor(parts[2]) || "#000000"
47
+ };
48
+ }
49
+ function extractPadding(style) {
50
+ if (!style) return { top: 0, right: 0, bottom: 0, left: 0 };
51
+ if (style.padding) {
52
+ return parseShorthandPadding(style.padding);
53
+ }
54
+ return {
55
+ top: parsePxValue(style["padding-top"]),
56
+ right: parsePxValue(style["padding-right"]),
57
+ bottom: parsePxValue(style["padding-bottom"]),
58
+ left: parsePxValue(style["padding-left"])
59
+ };
60
+ }
61
+ function parseShorthandPadding(value) {
62
+ const parts = value.trim().split(/\s+/);
63
+ const values = parts.map((p) => parsePxValue(p));
64
+ switch (values.length) {
65
+ case 1:
66
+ return {
67
+ top: values[0],
68
+ right: values[0],
69
+ bottom: values[0],
70
+ left: values[0]
71
+ };
72
+ case 2:
73
+ return {
74
+ top: values[0],
75
+ right: values[1],
76
+ bottom: values[0],
77
+ left: values[1]
78
+ };
79
+ case 3:
80
+ return {
81
+ top: values[0],
82
+ right: values[1],
83
+ bottom: values[2],
84
+ left: values[1]
85
+ };
86
+ default:
87
+ return {
88
+ top: values[0],
89
+ right: values[1],
90
+ bottom: values[2],
91
+ left: values[3]
92
+ };
93
+ }
94
+ }
95
+ function parseWidthPercent(value) {
96
+ if (!value) return 100;
97
+ const match = value.match(/^(\d+(?:\.\d+)?)\s*%/);
98
+ if (match) return Math.round(parseFloat(match[1]));
99
+ return 100;
100
+ }
101
+ function parseFontFamily(value) {
102
+ if (!value) return "";
103
+ return value.split(",")[0].trim().replace(/['"]/g, "");
104
+ }
105
+
106
+ // src/block-mapper.ts
107
+ var MODULE_TYPE_MAP = {
108
+ "mailup-bee-newsletter-modules-text": "text",
109
+ "mailup-bee-newsletter-modules-paragraph": "text",
110
+ "mailup-bee-newsletter-modules-heading": "heading",
111
+ "mailup-bee-newsletter-modules-list": "list",
112
+ "mailup-bee-newsletter-modules-image": "image",
113
+ "mailup-bee-newsletter-modules-button": "button",
114
+ "mailup-bee-newsletter-modules-divider": "divider",
115
+ "mailup-bee-newsletter-modules-spacer": "spacer",
116
+ "mailup-bee-newsletter-modules-html": "html",
117
+ "mailup-bee-newsletter-modules-social": "social",
118
+ "mailup-bee-newsletter-modules-video": "video",
119
+ "mailup-bee-newsletter-modules-menu": "menu",
120
+ "mailup-bee-newsletter-modules-table": "table"
121
+ };
122
+ var SOCIAL_PLATFORM_MAP = {
123
+ facebook: "facebook",
124
+ twitter: "twitter",
125
+ x: "twitter",
126
+ instagram: "instagram",
127
+ linkedin: "linkedin",
128
+ youtube: "youtube",
129
+ tiktok: "tiktok",
130
+ pinterest: "pinterest",
131
+ email: "email",
132
+ whatsapp: "whatsapp",
133
+ telegram: "telegram",
134
+ discord: "discord",
135
+ snapchat: "snapchat",
136
+ reddit: "reddit",
137
+ github: "github",
138
+ dribbble: "dribbble",
139
+ behance: "behance"
140
+ };
141
+ function toAlign(value, fallback = "left") {
142
+ if (value === "left" || value === "center" || value === "right") return value;
143
+ return fallback;
144
+ }
145
+ function toFontWeight(value, fallback = "normal") {
146
+ if (value === "bold") return "bold";
147
+ return fallback;
148
+ }
149
+ function toLineStyle(value, fallback = "solid") {
150
+ if (value === "solid" || value === "dashed" || value === "dotted")
151
+ return value;
152
+ return fallback;
153
+ }
154
+ function defaultMargin() {
155
+ return { top: 0, right: 0, bottom: 0, left: 0 };
156
+ }
157
+ function makeStyles(descriptor) {
158
+ const padding = extractPadding(descriptor.style);
159
+ const bg = parseColor(descriptor.style?.["background-color"]);
160
+ return {
161
+ padding,
162
+ margin: defaultMargin(),
163
+ ...bg ? { backgroundColor: bg } : {}
164
+ };
165
+ }
166
+ function convertText(descriptor) {
167
+ const textContent = descriptor.text ?? descriptor.paragraph ?? descriptor.list;
168
+ const html = textContent?.html ?? "";
169
+ const style = textContent?.style ?? {};
170
+ return createTextBlock({
171
+ content: html,
172
+ fontSize: parsePxValue(style["font-size"]) || 16,
173
+ color: parseColor(style.color) || "#1a1a1a",
174
+ textAlign: toAlign(style["text-align"]),
175
+ fontWeight: toFontWeight(style["font-weight"]),
176
+ fontFamily: parseFontFamily(style["font-family"]) || void 0,
177
+ styles: makeStyles(descriptor)
178
+ });
179
+ }
180
+ function convertHeading(descriptor) {
181
+ const heading = descriptor.heading;
182
+ if (!heading) return convertText(descriptor);
183
+ const style = heading.style ?? {};
184
+ const tag = heading.title ?? "h2";
185
+ const text = heading.text ?? "";
186
+ const content = text.startsWith("<") ? text : `<${tag}>${text}</${tag}>`;
187
+ return createTextBlock({
188
+ content,
189
+ fontSize: parsePxValue(style["font-size"]) || 24,
190
+ color: parseColor(style.color) || "#1a1a1a",
191
+ textAlign: toAlign(style["text-align"]),
192
+ fontWeight: toFontWeight(style["font-weight"], "bold"),
193
+ fontFamily: parseFontFamily(style["font-family"]) || void 0,
194
+ styles: makeStyles(descriptor)
195
+ });
196
+ }
197
+ function convertImage(descriptor) {
198
+ const image = descriptor.image;
199
+ if (!image) {
200
+ return createImageBlock({ styles: makeStyles(descriptor) });
201
+ }
202
+ return createImageBlock({
203
+ src: image.src || "",
204
+ alt: image.alt || "",
205
+ width: parsePxValue(image.width) || 600,
206
+ align: toAlign(image.style?.["text-align"], "center"),
207
+ linkUrl: image.href || void 0,
208
+ styles: makeStyles(descriptor)
209
+ });
210
+ }
211
+ function convertButton(descriptor) {
212
+ const button = descriptor.button;
213
+ if (!button) {
214
+ return createButtonBlock({ styles: makeStyles(descriptor) });
215
+ }
216
+ const style = button.style ?? {};
217
+ const label = button.label?.replace(/<[^>]*>/g, "") ?? "Button";
218
+ return createButtonBlock({
219
+ text: label,
220
+ url: button.href || "#",
221
+ backgroundColor: parseColor(style["background-color"]) || "#4f46e5",
222
+ textColor: parseColor(style.color) || "#ffffff",
223
+ borderRadius: parsePxValue(style["border-radius"]),
224
+ fontSize: parsePxValue(style["font-size"]) || 16,
225
+ fontFamily: parseFontFamily(style["font-family"]) || void 0,
226
+ buttonPadding: {
227
+ top: parsePxValue(style["padding-top"]) || 12,
228
+ right: parsePxValue(style["padding-right"]) || 24,
229
+ bottom: parsePxValue(style["padding-bottom"]) || 12,
230
+ left: parsePxValue(style["padding-left"]) || 24
231
+ },
232
+ styles: makeStyles(descriptor)
233
+ });
234
+ }
235
+ function convertDivider(descriptor) {
236
+ const divider = descriptor.divider;
237
+ const style = divider?.style ?? {};
238
+ const border = parseBorderTop(style["border-top"]);
239
+ return createDividerBlock({
240
+ lineStyle: toLineStyle(border.style),
241
+ color: border.color,
242
+ thickness: border.width || 1,
243
+ width: parseWidthPercent(style.width),
244
+ styles: makeStyles(descriptor)
245
+ });
246
+ }
247
+ function convertSpacer(descriptor) {
248
+ const spacer = descriptor.spacer;
249
+ const height = parsePxValue(spacer?.style?.height) || 24;
250
+ return createSpacerBlock({
251
+ height,
252
+ styles: makeStyles(descriptor)
253
+ });
254
+ }
255
+ function convertHtml(descriptor) {
256
+ const html = descriptor.html?.html ?? "";
257
+ return createHtmlBlock({
258
+ content: html,
259
+ styles: makeStyles(descriptor)
260
+ });
261
+ }
262
+ function convertSocial(descriptor, warnings) {
263
+ const iconsList = descriptor.iconsList;
264
+ if (!iconsList?.icons) {
265
+ return createSocialIconsBlock({ styles: makeStyles(descriptor) });
266
+ }
267
+ const icons = [];
268
+ for (const beeIcon of iconsList.icons) {
269
+ const id = (beeIcon.id ?? beeIcon.name ?? "").toLowerCase();
270
+ const platform = SOCIAL_PLATFORM_MAP[id];
271
+ if (!platform) {
272
+ warnings.push(
273
+ `Unrecognized social icon "${beeIcon.name || id}" was skipped.`
274
+ );
275
+ continue;
276
+ }
277
+ icons.push({
278
+ id: generateId(),
279
+ platform,
280
+ url: beeIcon.image?.href || "#"
281
+ });
282
+ }
283
+ return createSocialIconsBlock({
284
+ icons,
285
+ styles: makeStyles(descriptor)
286
+ });
287
+ }
288
+ function convertVideo(descriptor) {
289
+ const video = descriptor.video;
290
+ if (!video) {
291
+ return createVideoBlock({ styles: makeStyles(descriptor) });
292
+ }
293
+ return createVideoBlock({
294
+ url: video.src || "",
295
+ thumbnailUrl: video.thumbnail || "",
296
+ alt: video.alt || "",
297
+ width: parsePxValue(video.style?.width) || 600,
298
+ align: toAlign(video.style?.["text-align"], "center"),
299
+ styles: makeStyles(descriptor)
300
+ });
301
+ }
302
+ function convertMenu(descriptor) {
303
+ const menu = descriptor.menu;
304
+ if (!menu) {
305
+ return createMenuBlock({ styles: makeStyles(descriptor) });
306
+ }
307
+ const style = menu.style ?? {};
308
+ const items = (menu.items ?? []).map((item) => ({
309
+ id: generateId(),
310
+ text: item.text || "",
311
+ url: item.link || item.href || "#",
312
+ openInNewTab: item.target === "_blank",
313
+ bold: false,
314
+ underline: false
315
+ }));
316
+ return createMenuBlock({
317
+ items,
318
+ separator: menu.separator || "|",
319
+ separatorColor: parseColor(menu.separatorColor) || "#999999",
320
+ fontSize: parsePxValue(style["font-size"]) || 14,
321
+ color: parseColor(style.color) || "#1a1a1a",
322
+ fontFamily: parseFontFamily(style["font-family"]) || void 0,
323
+ textAlign: toAlign(style["text-align"], "center"),
324
+ styles: makeStyles(descriptor)
325
+ });
326
+ }
327
+ function convertTable(descriptor) {
328
+ const table = descriptor.table;
329
+ if (!table) {
330
+ return createTableBlock({ styles: makeStyles(descriptor) });
331
+ }
332
+ const style = table.style ?? {};
333
+ const rows = (table.rows ?? []).map((row) => ({
334
+ id: generateId(),
335
+ cells: (row.cells ?? []).map(
336
+ (cell) => ({
337
+ id: generateId(),
338
+ content: cell.content ?? cell.html ?? ""
339
+ })
340
+ )
341
+ }));
342
+ return createTableBlock({
343
+ rows,
344
+ hasHeaderRow: table.hasHeaderRow ?? false,
345
+ headerBackgroundColor: parseColor(table.headerBackgroundColor) || void 0,
346
+ borderColor: parseColor(style["border-color"]) || "#dddddd",
347
+ borderWidth: parsePxValue(style["border-width"]) || 1,
348
+ cellPadding: typeof table.cellPadding === "number" ? table.cellPadding : parsePxValue(table.cellPadding) || 8,
349
+ fontSize: parsePxValue(style["font-size"]) || 14,
350
+ color: parseColor(style.color) || "#1a1a1a",
351
+ textAlign: toAlign(style["text-align"]),
352
+ styles: makeStyles(descriptor)
353
+ });
354
+ }
355
+ function convertHtmlFallback(module) {
356
+ const descriptor = module.descriptor;
357
+ let html = "";
358
+ if (descriptor.text?.html) html = descriptor.text.html;
359
+ else if (descriptor.html?.html) html = descriptor.html.html;
360
+ else if (descriptor.heading?.text) html = descriptor.heading.text;
361
+ else html = `<!-- Unsupported BeeFree module: ${module.type} -->`;
362
+ return createHtmlBlock({
363
+ content: html,
364
+ styles: makeStyles(descriptor)
365
+ });
366
+ }
367
+ function convertModule(module, warnings) {
368
+ const mappedType = MODULE_TYPE_MAP[module.type];
369
+ const descriptor = module.descriptor;
370
+ if (!mappedType) {
371
+ return {
372
+ block: convertHtmlFallback(module),
373
+ entry: {
374
+ beeFreeModuleType: module.type,
375
+ templaticalBlockType: "html",
376
+ status: "html-fallback",
377
+ note: `Unknown module type "${module.type}" converted to HTML block.`
378
+ }
379
+ };
380
+ }
381
+ let block;
382
+ let isApproximation = false;
383
+ switch (mappedType) {
384
+ case "text":
385
+ case "list":
386
+ block = convertText(descriptor);
387
+ break;
388
+ case "heading":
389
+ block = convertHeading(descriptor);
390
+ break;
391
+ case "image":
392
+ block = convertImage(descriptor);
393
+ break;
394
+ case "button":
395
+ block = convertButton(descriptor);
396
+ break;
397
+ case "divider":
398
+ block = convertDivider(descriptor);
399
+ break;
400
+ case "spacer":
401
+ block = convertSpacer(descriptor);
402
+ break;
403
+ case "html":
404
+ block = convertHtml(descriptor);
405
+ break;
406
+ case "social":
407
+ block = convertSocial(descriptor, warnings);
408
+ break;
409
+ case "video":
410
+ block = convertVideo(descriptor);
411
+ break;
412
+ case "menu":
413
+ block = convertMenu(descriptor);
414
+ isApproximation = true;
415
+ break;
416
+ case "table":
417
+ block = convertTable(descriptor);
418
+ break;
419
+ default:
420
+ block = convertHtmlFallback(module);
421
+ return {
422
+ block,
423
+ entry: {
424
+ beeFreeModuleType: module.type,
425
+ templaticalBlockType: "html",
426
+ status: "html-fallback"
427
+ }
428
+ };
429
+ }
430
+ return {
431
+ block,
432
+ entry: {
433
+ beeFreeModuleType: module.type,
434
+ templaticalBlockType: block.type,
435
+ status: isApproximation ? "approximated" : "converted"
436
+ }
437
+ };
438
+ }
439
+
440
+ // src/converter.ts
441
+ function resolveColumnLayout(columns, warnings) {
442
+ if (columns.length === 1) return null;
443
+ if (columns.length === 3) return "3";
444
+ if (columns.length === 2) {
445
+ const left = columns[0]["grid-columns"] ?? 6;
446
+ const right = columns[1]["grid-columns"] ?? 6;
447
+ const total = left + right;
448
+ const ratio = left / total;
449
+ if (ratio > 0.58) return "2-1";
450
+ if (ratio < 0.42) return "1-2";
451
+ return "2";
452
+ }
453
+ if (columns.length >= 4) {
454
+ warnings.push(
455
+ `Row with ${columns.length} columns was flattened to a single column. BeeFree supports arbitrary columns, but Templatical supports up to 3.`
456
+ );
457
+ return null;
458
+ }
459
+ return "2";
460
+ }
461
+ function convertColumnModules(column, entries, warnings) {
462
+ const blocks = [];
463
+ for (const module of column.modules) {
464
+ const { block, entry } = convertModule(module, warnings);
465
+ blocks.push(block);
466
+ entries.push(entry);
467
+ }
468
+ return blocks;
469
+ }
470
+ function processRow(row, entries, warnings) {
471
+ const columns = row.columns;
472
+ if (!columns || columns.length === 0) return [];
473
+ if (row.locked) {
474
+ warnings.push(
475
+ "A locked row was imported. Lock metadata was dropped; content is preserved."
476
+ );
477
+ }
478
+ if (row.synced) {
479
+ warnings.push(
480
+ "A synced row was imported. Sync metadata was dropped; content is preserved."
481
+ );
482
+ }
483
+ const layout = resolveColumnLayout(columns, warnings);
484
+ if (!layout) {
485
+ const blocks = [];
486
+ for (const column of columns) {
487
+ blocks.push(...convertColumnModules(column, entries, warnings));
488
+ }
489
+ return blocks;
490
+ }
491
+ const children = columns.map(
492
+ (col) => convertColumnModules(col, entries, warnings)
493
+ );
494
+ const rowBg = parseColor(row.content?.style?.["background-color"]);
495
+ const section = createSectionBlock({
496
+ columns: layout,
497
+ children,
498
+ styles: {
499
+ padding: { top: 0, right: 0, bottom: 0, left: 0 },
500
+ margin: { top: 0, right: 0, bottom: 0, left: 0 },
501
+ ...rowBg ? { backgroundColor: rowBg } : {}
502
+ }
503
+ });
504
+ return [section];
505
+ }
506
+ function extractSettings(template) {
507
+ const body = template.page.body;
508
+ const contentStyle = body?.content?.style ?? {};
509
+ const containerStyle = body?.container?.style ?? {};
510
+ const width = parsePxValue(contentStyle["width"] ?? contentStyle.width);
511
+ const bgColor = parseColor(contentStyle["background-color"]) || parseColor(containerStyle["background-color"]) || "#ffffff";
512
+ const fontFamily = parseFontFamily(contentStyle["font-family"]) || "Arial";
513
+ return {
514
+ width: width || 600,
515
+ backgroundColor: bgColor,
516
+ fontFamily
517
+ };
518
+ }
519
+ function convertBeeFreeTemplate(template) {
520
+ if (!template?.page?.rows) {
521
+ throw new Error(
522
+ "Invalid BeeFree template: missing page.rows. Ensure you are passing a valid BeeFree JSON export."
523
+ );
524
+ }
525
+ const entries = [];
526
+ const warnings = [];
527
+ const blocks = [];
528
+ const webFonts = template.page.body?.webFonts;
529
+ if (webFonts && webFonts.length > 1) {
530
+ warnings.push(
531
+ `Template uses ${webFonts.length} web fonts. Only the primary font is preserved; additional fonts may need to be configured via the fonts option.`
532
+ );
533
+ }
534
+ for (const row of template.page.rows) {
535
+ if (row.empty) continue;
536
+ blocks.push(...processRow(row, entries, warnings));
537
+ }
538
+ const content = {
539
+ ...createDefaultTemplateContent(),
540
+ blocks,
541
+ settings: extractSettings(template)
542
+ };
543
+ const summary = {
544
+ total: entries.length,
545
+ converted: entries.filter((e) => e.status === "converted").length,
546
+ approximated: entries.filter((e) => e.status === "approximated").length,
547
+ htmlFallback: entries.filter((e) => e.status === "html-fallback").length,
548
+ skipped: entries.filter((e) => e.status === "skipped").length
549
+ };
550
+ const report = { entries, warnings, summary };
551
+ return { content, report };
552
+ }
553
+ export {
554
+ convertBeeFreeTemplate
555
+ };
556
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/converter.ts","../src/block-mapper.ts","../src/style-parser.ts"],"sourcesContent":["import {\n createSectionBlock,\n createDefaultTemplateContent,\n} from \"@templatical/types\";\nimport type { Block, ColumnLayout, TemplateContent } from \"@templatical/types\";\nimport type {\n BeeFreeTemplate,\n BeeFreeeRow,\n BeeFreeeColumn,\n ImportResult,\n ImportReport,\n ImportReportEntry,\n} from \"./types\";\nimport { convertModule } from \"./block-mapper\";\nimport { parsePxValue, parseColor, parseFontFamily } from \"./style-parser\";\n\n/**\n * Determines the Templatical ColumnLayout from BeeFree column grid values.\n */\nfunction resolveColumnLayout(\n columns: BeeFreeeColumn[],\n warnings: string[],\n): ColumnLayout | null {\n if (columns.length === 1) return null; // Single column — no section wrapper needed\n if (columns.length === 3) return \"3\";\n\n if (columns.length === 2) {\n const left = columns[0][\"grid-columns\"] ?? 6;\n const right = columns[1][\"grid-columns\"] ?? 6;\n const total = left + right;\n const ratio = left / total;\n\n if (ratio > 0.58) return \"2-1\";\n if (ratio < 0.42) return \"1-2\";\n return \"2\";\n }\n\n if (columns.length >= 4) {\n warnings.push(\n `Row with ${columns.length} columns was flattened to a single column. BeeFree supports arbitrary columns, but Templatical supports up to 3.`,\n );\n return null; // Flatten to single column\n }\n\n return \"2\";\n}\n\n/**\n * Converts all modules in a column to Templatical blocks.\n */\nfunction convertColumnModules(\n column: BeeFreeeColumn,\n entries: ImportReportEntry[],\n warnings: string[],\n): Block[] {\n const blocks: Block[] = [];\n\n for (const module of column.modules) {\n const { block, entry } = convertModule(module, warnings);\n blocks.push(block);\n entries.push(entry);\n }\n\n return blocks;\n}\n\n/**\n * Processes a single BeeFree row into one or more Templatical blocks.\n */\nfunction processRow(\n row: BeeFreeeRow,\n entries: ImportReportEntry[],\n warnings: string[],\n): Block[] {\n const columns = row.columns;\n if (!columns || columns.length === 0) return [];\n\n // Track locked/synced metadata\n if (row.locked) {\n warnings.push(\n \"A locked row was imported. Lock metadata was dropped; content is preserved.\",\n );\n }\n if (row.synced) {\n warnings.push(\n \"A synced row was imported. Sync metadata was dropped; content is preserved.\",\n );\n }\n\n const layout = resolveColumnLayout(columns, warnings);\n\n if (!layout) {\n // Single column (or flattened 4+ columns) — return modules directly\n const blocks: Block[] = [];\n for (const column of columns) {\n blocks.push(...convertColumnModules(column, entries, warnings));\n }\n return blocks;\n }\n\n // Multi-column — wrap in a SectionBlock\n const children: Block[][] = columns.map((col) =>\n convertColumnModules(col, entries, warnings),\n );\n\n // Extract section-level background from row content styles\n const rowBg = parseColor(row.content?.style?.[\"background-color\"]);\n\n const section = createSectionBlock({\n columns: layout,\n children,\n styles: {\n padding: { top: 0, right: 0, bottom: 0, left: 0 },\n margin: { top: 0, right: 0, bottom: 0, left: 0 },\n ...(rowBg ? { backgroundColor: rowBg } : {}),\n },\n });\n\n return [section];\n}\n\n/**\n * Extracts template-level settings from the BeeFree body.\n */\nfunction extractSettings(\n template: BeeFreeTemplate,\n): TemplateContent[\"settings\"] {\n const body = template.page.body;\n const contentStyle = body?.content?.style ?? {};\n const containerStyle = body?.container?.style ?? {};\n\n const width = parsePxValue(contentStyle[\"width\"] ?? contentStyle.width);\n const bgColor =\n parseColor(contentStyle[\"background-color\"]) ||\n parseColor(containerStyle[\"background-color\"]) ||\n \"#ffffff\";\n const fontFamily = parseFontFamily(contentStyle[\"font-family\"]) || \"Arial\";\n\n return {\n width: width || 600,\n backgroundColor: bgColor,\n fontFamily,\n };\n}\n\n/**\n * Converts a BeeFree template JSON to Templatical TemplateContent.\n *\n * @param template - The parsed BeeFree JSON object\n * @returns An ImportResult with the converted content and a detailed report\n *\n * @example\n * ```ts\n * import { convertBeeFreeTemplate } from '@templatical/import-beefree';\n *\n * const beeFreeJson = JSON.parse(fileContent);\n * const { content, report } = convertBeeFreeTemplate(beeFreeJson);\n *\n * // Use the content with the editor\n * const editor = init({ container: '#editor', content });\n *\n * // Check the report for any issues\n * console.log(report.summary);\n * console.log(report.warnings);\n * ```\n */\nexport function convertBeeFreeTemplate(\n template: BeeFreeTemplate,\n): ImportResult {\n // Validate structure\n if (!template?.page?.rows) {\n throw new Error(\n \"Invalid BeeFree template: missing page.rows. Ensure you are passing a valid BeeFree JSON export.\",\n );\n }\n\n const entries: ImportReportEntry[] = [];\n const warnings: string[] = [];\n const blocks: Block[] = [];\n\n // Extract web font warnings\n const webFonts = template.page.body?.webFonts;\n if (webFonts && webFonts.length > 1) {\n warnings.push(\n `Template uses ${webFonts.length} web fonts. Only the primary font is preserved; additional fonts may need to be configured via the fonts option.`,\n );\n }\n\n // Process rows\n for (const row of template.page.rows) {\n if (row.empty) continue;\n blocks.push(...processRow(row, entries, warnings));\n }\n\n // Build template content\n const content: TemplateContent = {\n ...createDefaultTemplateContent(),\n blocks,\n settings: extractSettings(template),\n };\n\n // Build report summary\n const summary = {\n total: entries.length,\n converted: entries.filter((e) => e.status === \"converted\").length,\n approximated: entries.filter((e) => e.status === \"approximated\").length,\n htmlFallback: entries.filter((e) => e.status === \"html-fallback\").length,\n skipped: entries.filter((e) => e.status === \"skipped\").length,\n };\n\n const report: ImportReport = { entries, warnings, summary };\n\n return { content, report };\n}\n","import {\n createTextBlock,\n createImageBlock,\n createButtonBlock,\n createDividerBlock,\n createSpacerBlock,\n createHtmlBlock,\n createSocialIconsBlock,\n createMenuBlock,\n createTableBlock,\n createVideoBlock,\n generateId,\n} from \"@templatical/types\";\nimport type {\n Block,\n SocialPlatform,\n SocialIcon,\n MenuItemData,\n TableRowData,\n TableCellData,\n SpacingValue,\n} from \"@templatical/types\";\nimport type {\n BeeFreeeModule,\n BeeFreeeModuleDescriptor,\n ImportReportEntry,\n} from \"./types\";\nimport {\n parsePxValue,\n parseColor,\n parseBorderTop,\n extractPadding,\n parseWidthPercent,\n parseFontFamily,\n} from \"./style-parser\";\n\n/**\n * Maps BeeFree module type strings to short keys.\n */\nconst MODULE_TYPE_MAP: Record<string, string> = {\n \"mailup-bee-newsletter-modules-text\": \"text\",\n \"mailup-bee-newsletter-modules-paragraph\": \"text\",\n \"mailup-bee-newsletter-modules-heading\": \"heading\",\n \"mailup-bee-newsletter-modules-list\": \"list\",\n \"mailup-bee-newsletter-modules-image\": \"image\",\n \"mailup-bee-newsletter-modules-button\": \"button\",\n \"mailup-bee-newsletter-modules-divider\": \"divider\",\n \"mailup-bee-newsletter-modules-spacer\": \"spacer\",\n \"mailup-bee-newsletter-modules-html\": \"html\",\n \"mailup-bee-newsletter-modules-social\": \"social\",\n \"mailup-bee-newsletter-modules-video\": \"video\",\n \"mailup-bee-newsletter-modules-menu\": \"menu\",\n \"mailup-bee-newsletter-modules-table\": \"table\",\n};\n\nconst SOCIAL_PLATFORM_MAP: Record<string, SocialPlatform> = {\n facebook: \"facebook\",\n twitter: \"twitter\",\n x: \"twitter\",\n instagram: \"instagram\",\n linkedin: \"linkedin\",\n youtube: \"youtube\",\n tiktok: \"tiktok\",\n pinterest: \"pinterest\",\n email: \"email\",\n whatsapp: \"whatsapp\",\n telegram: \"telegram\",\n discord: \"discord\",\n snapchat: \"snapchat\",\n reddit: \"reddit\",\n github: \"github\",\n dribbble: \"dribbble\",\n behance: \"behance\",\n};\n\ntype Align = \"left\" | \"center\" | \"right\";\ntype FontWeight = \"normal\" | \"bold\";\ntype LineStyle = \"solid\" | \"dashed\" | \"dotted\";\n\nfunction toAlign(value: string | undefined, fallback: Align = \"left\"): Align {\n if (value === \"left\" || value === \"center\" || value === \"right\") return value;\n return fallback;\n}\n\nfunction toFontWeight(\n value: string | undefined,\n fallback: FontWeight = \"normal\",\n): FontWeight {\n if (value === \"bold\") return \"bold\";\n return fallback;\n}\n\nfunction toLineStyle(\n value: string | undefined,\n fallback: LineStyle = \"solid\",\n): LineStyle {\n if (value === \"solid\" || value === \"dashed\" || value === \"dotted\")\n return value;\n return fallback;\n}\n\nfunction defaultMargin(): SpacingValue {\n return { top: 0, right: 0, bottom: 0, left: 0 };\n}\n\nfunction makeStyles(descriptor: BeeFreeeModuleDescriptor): Block[\"styles\"] {\n const padding = extractPadding(descriptor.style);\n const bg = parseColor(descriptor.style?.[\"background-color\"]);\n return {\n padding,\n margin: defaultMargin(),\n ...(bg ? { backgroundColor: bg } : {}),\n };\n}\n\nfunction convertText(descriptor: BeeFreeeModuleDescriptor): Block {\n const textContent =\n descriptor.text ?? descriptor.paragraph ?? descriptor.list;\n const html = textContent?.html ?? \"\";\n const style = textContent?.style ?? {};\n\n return createTextBlock({\n content: html,\n fontSize: parsePxValue(style[\"font-size\"]) || 16,\n color: parseColor(style.color) || \"#1a1a1a\",\n textAlign: toAlign(style[\"text-align\"]),\n fontWeight: toFontWeight(style[\"font-weight\"]),\n fontFamily: parseFontFamily(style[\"font-family\"]) || undefined,\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertHeading(descriptor: BeeFreeeModuleDescriptor): Block {\n const heading = descriptor.heading;\n if (!heading) return convertText(descriptor);\n\n const style = heading.style ?? {};\n const tag = heading.title ?? \"h2\";\n const text = heading.text ?? \"\";\n const content = text.startsWith(\"<\") ? text : `<${tag}>${text}</${tag}>`;\n\n return createTextBlock({\n content,\n fontSize: parsePxValue(style[\"font-size\"]) || 24,\n color: parseColor(style.color) || \"#1a1a1a\",\n textAlign: toAlign(style[\"text-align\"]),\n fontWeight: toFontWeight(style[\"font-weight\"], \"bold\"),\n fontFamily: parseFontFamily(style[\"font-family\"]) || undefined,\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertImage(descriptor: BeeFreeeModuleDescriptor): Block {\n const image = descriptor.image;\n if (!image) {\n return createImageBlock({ styles: makeStyles(descriptor) });\n }\n\n return createImageBlock({\n src: image.src || \"\",\n alt: image.alt || \"\",\n width: parsePxValue(image.width) || 600,\n align: toAlign(image.style?.[\"text-align\"], \"center\"),\n linkUrl: image.href || undefined,\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertButton(descriptor: BeeFreeeModuleDescriptor): Block {\n const button = descriptor.button;\n if (!button) {\n return createButtonBlock({ styles: makeStyles(descriptor) });\n }\n\n const style = button.style ?? {};\n const label = button.label?.replace(/<[^>]*>/g, \"\") ?? \"Button\";\n\n return createButtonBlock({\n text: label,\n url: button.href || \"#\",\n backgroundColor: parseColor(style[\"background-color\"]) || \"#4f46e5\",\n textColor: parseColor(style.color) || \"#ffffff\",\n borderRadius: parsePxValue(style[\"border-radius\"]),\n fontSize: parsePxValue(style[\"font-size\"]) || 16,\n fontFamily: parseFontFamily(style[\"font-family\"]) || undefined,\n buttonPadding: {\n top: parsePxValue(style[\"padding-top\"]) || 12,\n right: parsePxValue(style[\"padding-right\"]) || 24,\n bottom: parsePxValue(style[\"padding-bottom\"]) || 12,\n left: parsePxValue(style[\"padding-left\"]) || 24,\n },\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertDivider(descriptor: BeeFreeeModuleDescriptor): Block {\n const divider = descriptor.divider;\n const style = divider?.style ?? {};\n const border = parseBorderTop(style[\"border-top\"]);\n\n return createDividerBlock({\n lineStyle: toLineStyle(border.style),\n color: border.color,\n thickness: border.width || 1,\n width: parseWidthPercent(style.width),\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertSpacer(descriptor: BeeFreeeModuleDescriptor): Block {\n const spacer = descriptor.spacer;\n const height = parsePxValue(spacer?.style?.height) || 24;\n\n return createSpacerBlock({\n height,\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertHtml(descriptor: BeeFreeeModuleDescriptor): Block {\n const html = descriptor.html?.html ?? \"\";\n\n return createHtmlBlock({\n content: html,\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertSocial(\n descriptor: BeeFreeeModuleDescriptor,\n warnings: string[],\n): Block {\n const iconsList = descriptor.iconsList;\n if (!iconsList?.icons) {\n return createSocialIconsBlock({ styles: makeStyles(descriptor) });\n }\n\n const icons: SocialIcon[] = [];\n\n for (const beeIcon of iconsList.icons) {\n const id = (beeIcon.id ?? beeIcon.name ?? \"\").toLowerCase();\n const platform = SOCIAL_PLATFORM_MAP[id];\n\n if (!platform) {\n warnings.push(\n `Unrecognized social icon \"${beeIcon.name || id}\" was skipped.`,\n );\n continue;\n }\n\n icons.push({\n id: generateId(),\n platform,\n url: beeIcon.image?.href || \"#\",\n });\n }\n\n return createSocialIconsBlock({\n icons,\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertVideo(descriptor: BeeFreeeModuleDescriptor): Block {\n const video = descriptor.video;\n if (!video) {\n return createVideoBlock({ styles: makeStyles(descriptor) });\n }\n\n return createVideoBlock({\n url: video.src || \"\",\n thumbnailUrl: video.thumbnail || \"\",\n alt: video.alt || \"\",\n width: parsePxValue(video.style?.width) || 600,\n align: toAlign(video.style?.[\"text-align\"], \"center\"),\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertMenu(descriptor: BeeFreeeModuleDescriptor): Block {\n const menu = descriptor.menu;\n if (!menu) {\n return createMenuBlock({ styles: makeStyles(descriptor) });\n }\n\n const style = menu.style ?? {};\n\n const items: MenuItemData[] = (menu.items ?? []).map((item) => ({\n id: generateId(),\n text: item.text || \"\",\n url: item.link || item.href || \"#\",\n openInNewTab: item.target === \"_blank\",\n bold: false,\n underline: false,\n }));\n\n return createMenuBlock({\n items,\n separator: menu.separator || \"|\",\n separatorColor: parseColor(menu.separatorColor) || \"#999999\",\n fontSize: parsePxValue(style[\"font-size\"]) || 14,\n color: parseColor(style.color) || \"#1a1a1a\",\n fontFamily: parseFontFamily(style[\"font-family\"]) || undefined,\n textAlign: toAlign(style[\"text-align\"], \"center\"),\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertTable(descriptor: BeeFreeeModuleDescriptor): Block {\n const table = descriptor.table;\n if (!table) {\n return createTableBlock({ styles: makeStyles(descriptor) });\n }\n\n const style = table.style ?? {};\n\n const rows: TableRowData[] = (table.rows ?? []).map((row) => ({\n id: generateId(),\n cells: (row.cells ?? []).map(\n (cell): TableCellData => ({\n id: generateId(),\n content: cell.content ?? cell.html ?? \"\",\n }),\n ),\n }));\n\n return createTableBlock({\n rows,\n hasHeaderRow: table.hasHeaderRow ?? false,\n headerBackgroundColor: parseColor(table.headerBackgroundColor) || undefined,\n borderColor: parseColor(style[\"border-color\"]) || \"#dddddd\",\n borderWidth: parsePxValue(style[\"border-width\"]) || 1,\n cellPadding:\n typeof table.cellPadding === \"number\"\n ? table.cellPadding\n : parsePxValue(table.cellPadding as string) || 8,\n fontSize: parsePxValue(style[\"font-size\"]) || 14,\n color: parseColor(style.color) || \"#1a1a1a\",\n textAlign: toAlign(style[\"text-align\"]),\n styles: makeStyles(descriptor),\n });\n}\n\nfunction convertHtmlFallback(module: BeeFreeeModule): Block {\n // Attempt to extract any HTML content from the descriptor\n const descriptor = module.descriptor;\n let html = \"\";\n\n // Try common content fields\n if (descriptor.text?.html) html = descriptor.text.html;\n else if (descriptor.html?.html) html = descriptor.html.html;\n else if (descriptor.heading?.text) html = descriptor.heading.text;\n else html = `<!-- Unsupported BeeFree module: ${module.type} -->`;\n\n return createHtmlBlock({\n content: html,\n styles: makeStyles(descriptor),\n });\n}\n\n/**\n * Converts a single BeeFree module to a Templatical block.\n * Returns the block and a report entry.\n */\nexport function convertModule(\n module: BeeFreeeModule,\n warnings: string[],\n): { block: Block; entry: ImportReportEntry } {\n const mappedType = MODULE_TYPE_MAP[module.type];\n const descriptor = module.descriptor;\n\n if (!mappedType) {\n return {\n block: convertHtmlFallback(module),\n entry: {\n beeFreeModuleType: module.type,\n templaticalBlockType: \"html\",\n status: \"html-fallback\",\n note: `Unknown module type \"${module.type}\" converted to HTML block.`,\n },\n };\n }\n\n let block: Block;\n let isApproximation = false;\n\n switch (mappedType) {\n case \"text\":\n case \"list\":\n block = convertText(descriptor);\n break;\n case \"heading\":\n block = convertHeading(descriptor);\n break;\n case \"image\":\n block = convertImage(descriptor);\n break;\n case \"button\":\n block = convertButton(descriptor);\n break;\n case \"divider\":\n block = convertDivider(descriptor);\n break;\n case \"spacer\":\n block = convertSpacer(descriptor);\n break;\n case \"html\":\n block = convertHtml(descriptor);\n break;\n case \"social\":\n block = convertSocial(descriptor, warnings);\n break;\n case \"video\":\n block = convertVideo(descriptor);\n break;\n case \"menu\":\n block = convertMenu(descriptor);\n isApproximation = true; // menu styles are approximate\n break;\n case \"table\":\n block = convertTable(descriptor);\n break;\n default:\n block = convertHtmlFallback(module);\n return {\n block,\n entry: {\n beeFreeModuleType: module.type,\n templaticalBlockType: \"html\",\n status: \"html-fallback\",\n },\n };\n }\n\n return {\n block,\n entry: {\n beeFreeModuleType: module.type,\n templaticalBlockType: block.type,\n status: isApproximation ? \"approximated\" : \"converted\",\n },\n };\n}\n","import type { SpacingValue } from \"@templatical/types\";\n\n/**\n * Parses CSS-like style values from BeeFree descriptors.\n */\n\nexport function parsePxValue(value: string | undefined): number {\n if (!value) return 0;\n const match = value.match(/^(-?\\d+(?:\\.\\d+)?)\\s*px/);\n return match ? Math.round(parseFloat(match[1])) : 0;\n}\n\nexport function parseColor(value: string | undefined): string {\n if (!value || value === \"transparent\") return \"\";\n\n const trimmed = value.trim();\n\n // Already a valid hex color\n if (/^#[0-9a-fA-F]{6}$/.test(trimmed)) return trimmed.toLowerCase();\n\n // 3-digit hex → 6-digit\n if (/^#[0-9a-fA-F]{3}$/.test(trimmed)) {\n const r = trimmed[1];\n const g = trimmed[2];\n const b = trimmed[3];\n return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();\n }\n\n // Return as-is for rgb(), named colors, etc.\n return trimmed;\n}\n\nexport function parseBorderTop(value: string | undefined): {\n width: number;\n style: string;\n color: string;\n} {\n if (!value) return { width: 0, style: \"solid\", color: \"#000000\" };\n\n // \"2px solid #cccccc\"\n const parts = value.trim().split(/\\s+/);\n return {\n width: parsePxValue(parts[0]),\n style: parts[1] || \"solid\",\n color: parseColor(parts[2]) || \"#000000\",\n };\n}\n\nexport function extractPadding(\n style: Record<string, string> | undefined,\n): SpacingValue {\n if (!style) return { top: 0, right: 0, bottom: 0, left: 0 };\n\n // Check for shorthand `padding` first\n if (style.padding) {\n return parseShorthandPadding(style.padding);\n }\n\n return {\n top: parsePxValue(style[\"padding-top\"]),\n right: parsePxValue(style[\"padding-right\"]),\n bottom: parsePxValue(style[\"padding-bottom\"]),\n left: parsePxValue(style[\"padding-left\"]),\n };\n}\n\nfunction parseShorthandPadding(value: string): SpacingValue {\n const parts = value.trim().split(/\\s+/);\n const values = parts.map((p) => parsePxValue(p));\n\n switch (values.length) {\n case 1:\n return {\n top: values[0],\n right: values[0],\n bottom: values[0],\n left: values[0],\n };\n case 2:\n return {\n top: values[0],\n right: values[1],\n bottom: values[0],\n left: values[1],\n };\n case 3:\n return {\n top: values[0],\n right: values[1],\n bottom: values[2],\n left: values[1],\n };\n default:\n return {\n top: values[0],\n right: values[1],\n bottom: values[2],\n left: values[3],\n };\n }\n}\n\nexport function parseWidthPercent(value: string | undefined): number {\n if (!value) return 100;\n const match = value.match(/^(\\d+(?:\\.\\d+)?)\\s*%/);\n if (match) return Math.round(parseFloat(match[1]));\n // Might be px — return 100 as default\n return 100;\n}\n\nexport function parseFontFamily(value: string | undefined): string {\n if (!value) return \"\";\n // Take the first font in the stack\n return value.split(\",\")[0].trim().replace(/['\"]/g, \"\");\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,OACK;;;ACHP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACNA,SAAS,aAAa,OAAmC;AAC9D,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,MAAM,MAAM,yBAAyB;AACnD,SAAO,QAAQ,KAAK,MAAM,WAAW,MAAM,CAAC,CAAC,CAAC,IAAI;AACpD;AAEO,SAAS,WAAW,OAAmC;AAC5D,MAAI,CAAC,SAAS,UAAU,cAAe,QAAO;AAE9C,QAAM,UAAU,MAAM,KAAK;AAG3B,MAAI,oBAAoB,KAAK,OAAO,EAAG,QAAO,QAAQ,YAAY;AAGlE,MAAI,oBAAoB,KAAK,OAAO,GAAG;AACrC,UAAM,IAAI,QAAQ,CAAC;AACnB,UAAM,IAAI,QAAQ,CAAC;AACnB,UAAM,IAAI,QAAQ,CAAC;AACnB,WAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY;AAAA,EACjD;AAGA,SAAO;AACT;AAEO,SAAS,eAAe,OAI7B;AACA,MAAI,CAAC,MAAO,QAAO,EAAE,OAAO,GAAG,OAAO,SAAS,OAAO,UAAU;AAGhE,QAAM,QAAQ,MAAM,KAAK,EAAE,MAAM,KAAK;AACtC,SAAO;AAAA,IACL,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,IAC5B,OAAO,MAAM,CAAC,KAAK;AAAA,IACnB,OAAO,WAAW,MAAM,CAAC,CAAC,KAAK;AAAA,EACjC;AACF;AAEO,SAAS,eACd,OACc;AACd,MAAI,CAAC,MAAO,QAAO,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,EAAE;AAG1D,MAAI,MAAM,SAAS;AACjB,WAAO,sBAAsB,MAAM,OAAO;AAAA,EAC5C;AAEA,SAAO;AAAA,IACL,KAAK,aAAa,MAAM,aAAa,CAAC;AAAA,IACtC,OAAO,aAAa,MAAM,eAAe,CAAC;AAAA,IAC1C,QAAQ,aAAa,MAAM,gBAAgB,CAAC;AAAA,IAC5C,MAAM,aAAa,MAAM,cAAc,CAAC;AAAA,EAC1C;AACF;AAEA,SAAS,sBAAsB,OAA6B;AAC1D,QAAM,QAAQ,MAAM,KAAK,EAAE,MAAM,KAAK;AACtC,QAAM,SAAS,MAAM,IAAI,CAAC,MAAM,aAAa,CAAC,CAAC;AAE/C,UAAQ,OAAO,QAAQ;AAAA,IACrB,KAAK;AACH,aAAO;AAAA,QACL,KAAK,OAAO,CAAC;AAAA,QACb,OAAO,OAAO,CAAC;AAAA,QACf,QAAQ,OAAO,CAAC;AAAA,QAChB,MAAM,OAAO,CAAC;AAAA,MAChB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,OAAO,CAAC;AAAA,QACb,OAAO,OAAO,CAAC;AAAA,QACf,QAAQ,OAAO,CAAC;AAAA,QAChB,MAAM,OAAO,CAAC;AAAA,MAChB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,OAAO,CAAC;AAAA,QACb,OAAO,OAAO,CAAC;AAAA,QACf,QAAQ,OAAO,CAAC;AAAA,QAChB,MAAM,OAAO,CAAC;AAAA,MAChB;AAAA,IACF;AACE,aAAO;AAAA,QACL,KAAK,OAAO,CAAC;AAAA,QACb,OAAO,OAAO,CAAC;AAAA,QACf,QAAQ,OAAO,CAAC;AAAA,QAChB,MAAM,OAAO,CAAC;AAAA,MAChB;AAAA,EACJ;AACF;AAEO,SAAS,kBAAkB,OAAmC;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,MAAM,MAAM,sBAAsB;AAChD,MAAI,MAAO,QAAO,KAAK,MAAM,WAAW,MAAM,CAAC,CAAC,CAAC;AAEjD,SAAO;AACT;AAEO,SAAS,gBAAgB,OAAmC;AACjE,MAAI,CAAC,MAAO,QAAO;AAEnB,SAAO,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,SAAS,EAAE;AACvD;;;AD3EA,IAAM,kBAA0C;AAAA,EAC9C,sCAAsC;AAAA,EACtC,2CAA2C;AAAA,EAC3C,yCAAyC;AAAA,EACzC,sCAAsC;AAAA,EACtC,uCAAuC;AAAA,EACvC,wCAAwC;AAAA,EACxC,yCAAyC;AAAA,EACzC,wCAAwC;AAAA,EACxC,sCAAsC;AAAA,EACtC,wCAAwC;AAAA,EACxC,uCAAuC;AAAA,EACvC,sCAAsC;AAAA,EACtC,uCAAuC;AACzC;AAEA,IAAM,sBAAsD;AAAA,EAC1D,UAAU;AAAA,EACV,SAAS;AAAA,EACT,GAAG;AAAA,EACH,WAAW;AAAA,EACX,UAAU;AAAA,EACV,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,OAAO;AAAA,EACP,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS;AACX;AAMA,SAAS,QAAQ,OAA2B,WAAkB,QAAe;AAC3E,MAAI,UAAU,UAAU,UAAU,YAAY,UAAU,QAAS,QAAO;AACxE,SAAO;AACT;AAEA,SAAS,aACP,OACA,WAAuB,UACX;AACZ,MAAI,UAAU,OAAQ,QAAO;AAC7B,SAAO;AACT;AAEA,SAAS,YACP,OACA,WAAsB,SACX;AACX,MAAI,UAAU,WAAW,UAAU,YAAY,UAAU;AACvD,WAAO;AACT,SAAO;AACT;AAEA,SAAS,gBAA8B;AACrC,SAAO,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,EAAE;AAChD;AAEA,SAAS,WAAW,YAAuD;AACzE,QAAM,UAAU,eAAe,WAAW,KAAK;AAC/C,QAAM,KAAK,WAAW,WAAW,QAAQ,kBAAkB,CAAC;AAC5D,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,cAAc;AAAA,IACtB,GAAI,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;AAAA,EACtC;AACF;AAEA,SAAS,YAAY,YAA6C;AAChE,QAAM,cACJ,WAAW,QAAQ,WAAW,aAAa,WAAW;AACxD,QAAM,OAAO,aAAa,QAAQ;AAClC,QAAM,QAAQ,aAAa,SAAS,CAAC;AAErC,SAAO,gBAAgB;AAAA,IACrB,SAAS;AAAA,IACT,UAAU,aAAa,MAAM,WAAW,CAAC,KAAK;AAAA,IAC9C,OAAO,WAAW,MAAM,KAAK,KAAK;AAAA,IAClC,WAAW,QAAQ,MAAM,YAAY,CAAC;AAAA,IACtC,YAAY,aAAa,MAAM,aAAa,CAAC;AAAA,IAC7C,YAAY,gBAAgB,MAAM,aAAa,CAAC,KAAK;AAAA,IACrD,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,eAAe,YAA6C;AACnE,QAAM,UAAU,WAAW;AAC3B,MAAI,CAAC,QAAS,QAAO,YAAY,UAAU;AAE3C,QAAM,QAAQ,QAAQ,SAAS,CAAC;AAChC,QAAM,MAAM,QAAQ,SAAS;AAC7B,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,UAAU,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,GAAG,IAAI,IAAI,KAAK,GAAG;AAErE,SAAO,gBAAgB;AAAA,IACrB;AAAA,IACA,UAAU,aAAa,MAAM,WAAW,CAAC,KAAK;AAAA,IAC9C,OAAO,WAAW,MAAM,KAAK,KAAK;AAAA,IAClC,WAAW,QAAQ,MAAM,YAAY,CAAC;AAAA,IACtC,YAAY,aAAa,MAAM,aAAa,GAAG,MAAM;AAAA,IACrD,YAAY,gBAAgB,MAAM,aAAa,CAAC,KAAK;AAAA,IACrD,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,aAAa,YAA6C;AACjE,QAAM,QAAQ,WAAW;AACzB,MAAI,CAAC,OAAO;AACV,WAAO,iBAAiB,EAAE,QAAQ,WAAW,UAAU,EAAE,CAAC;AAAA,EAC5D;AAEA,SAAO,iBAAiB;AAAA,IACtB,KAAK,MAAM,OAAO;AAAA,IAClB,KAAK,MAAM,OAAO;AAAA,IAClB,OAAO,aAAa,MAAM,KAAK,KAAK;AAAA,IACpC,OAAO,QAAQ,MAAM,QAAQ,YAAY,GAAG,QAAQ;AAAA,IACpD,SAAS,MAAM,QAAQ;AAAA,IACvB,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,cAAc,YAA6C;AAClE,QAAM,SAAS,WAAW;AAC1B,MAAI,CAAC,QAAQ;AACX,WAAO,kBAAkB,EAAE,QAAQ,WAAW,UAAU,EAAE,CAAC;AAAA,EAC7D;AAEA,QAAM,QAAQ,OAAO,SAAS,CAAC;AAC/B,QAAM,QAAQ,OAAO,OAAO,QAAQ,YAAY,EAAE,KAAK;AAEvD,SAAO,kBAAkB;AAAA,IACvB,MAAM;AAAA,IACN,KAAK,OAAO,QAAQ;AAAA,IACpB,iBAAiB,WAAW,MAAM,kBAAkB,CAAC,KAAK;AAAA,IAC1D,WAAW,WAAW,MAAM,KAAK,KAAK;AAAA,IACtC,cAAc,aAAa,MAAM,eAAe,CAAC;AAAA,IACjD,UAAU,aAAa,MAAM,WAAW,CAAC,KAAK;AAAA,IAC9C,YAAY,gBAAgB,MAAM,aAAa,CAAC,KAAK;AAAA,IACrD,eAAe;AAAA,MACb,KAAK,aAAa,MAAM,aAAa,CAAC,KAAK;AAAA,MAC3C,OAAO,aAAa,MAAM,eAAe,CAAC,KAAK;AAAA,MAC/C,QAAQ,aAAa,MAAM,gBAAgB,CAAC,KAAK;AAAA,MACjD,MAAM,aAAa,MAAM,cAAc,CAAC,KAAK;AAAA,IAC/C;AAAA,IACA,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,eAAe,YAA6C;AACnE,QAAM,UAAU,WAAW;AAC3B,QAAM,QAAQ,SAAS,SAAS,CAAC;AACjC,QAAM,SAAS,eAAe,MAAM,YAAY,CAAC;AAEjD,SAAO,mBAAmB;AAAA,IACxB,WAAW,YAAY,OAAO,KAAK;AAAA,IACnC,OAAO,OAAO;AAAA,IACd,WAAW,OAAO,SAAS;AAAA,IAC3B,OAAO,kBAAkB,MAAM,KAAK;AAAA,IACpC,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,cAAc,YAA6C;AAClE,QAAM,SAAS,WAAW;AAC1B,QAAM,SAAS,aAAa,QAAQ,OAAO,MAAM,KAAK;AAEtD,SAAO,kBAAkB;AAAA,IACvB;AAAA,IACA,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,YAAY,YAA6C;AAChE,QAAM,OAAO,WAAW,MAAM,QAAQ;AAEtC,SAAO,gBAAgB;AAAA,IACrB,SAAS;AAAA,IACT,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,cACP,YACA,UACO;AACP,QAAM,YAAY,WAAW;AAC7B,MAAI,CAAC,WAAW,OAAO;AACrB,WAAO,uBAAuB,EAAE,QAAQ,WAAW,UAAU,EAAE,CAAC;AAAA,EAClE;AAEA,QAAM,QAAsB,CAAC;AAE7B,aAAW,WAAW,UAAU,OAAO;AACrC,UAAM,MAAM,QAAQ,MAAM,QAAQ,QAAQ,IAAI,YAAY;AAC1D,UAAM,WAAW,oBAAoB,EAAE;AAEvC,QAAI,CAAC,UAAU;AACb,eAAS;AAAA,QACP,6BAA6B,QAAQ,QAAQ,EAAE;AAAA,MACjD;AACA;AAAA,IACF;AAEA,UAAM,KAAK;AAAA,MACT,IAAI,WAAW;AAAA,MACf;AAAA,MACA,KAAK,QAAQ,OAAO,QAAQ;AAAA,IAC9B,CAAC;AAAA,EACH;AAEA,SAAO,uBAAuB;AAAA,IAC5B;AAAA,IACA,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,aAAa,YAA6C;AACjE,QAAM,QAAQ,WAAW;AACzB,MAAI,CAAC,OAAO;AACV,WAAO,iBAAiB,EAAE,QAAQ,WAAW,UAAU,EAAE,CAAC;AAAA,EAC5D;AAEA,SAAO,iBAAiB;AAAA,IACtB,KAAK,MAAM,OAAO;AAAA,IAClB,cAAc,MAAM,aAAa;AAAA,IACjC,KAAK,MAAM,OAAO;AAAA,IAClB,OAAO,aAAa,MAAM,OAAO,KAAK,KAAK;AAAA,IAC3C,OAAO,QAAQ,MAAM,QAAQ,YAAY,GAAG,QAAQ;AAAA,IACpD,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,YAAY,YAA6C;AAChE,QAAM,OAAO,WAAW;AACxB,MAAI,CAAC,MAAM;AACT,WAAO,gBAAgB,EAAE,QAAQ,WAAW,UAAU,EAAE,CAAC;AAAA,EAC3D;AAEA,QAAM,QAAQ,KAAK,SAAS,CAAC;AAE7B,QAAM,SAAyB,KAAK,SAAS,CAAC,GAAG,IAAI,CAAC,UAAU;AAAA,IAC9D,IAAI,WAAW;AAAA,IACf,MAAM,KAAK,QAAQ;AAAA,IACnB,KAAK,KAAK,QAAQ,KAAK,QAAQ;AAAA,IAC/B,cAAc,KAAK,WAAW;AAAA,IAC9B,MAAM;AAAA,IACN,WAAW;AAAA,EACb,EAAE;AAEF,SAAO,gBAAgB;AAAA,IACrB;AAAA,IACA,WAAW,KAAK,aAAa;AAAA,IAC7B,gBAAgB,WAAW,KAAK,cAAc,KAAK;AAAA,IACnD,UAAU,aAAa,MAAM,WAAW,CAAC,KAAK;AAAA,IAC9C,OAAO,WAAW,MAAM,KAAK,KAAK;AAAA,IAClC,YAAY,gBAAgB,MAAM,aAAa,CAAC,KAAK;AAAA,IACrD,WAAW,QAAQ,MAAM,YAAY,GAAG,QAAQ;AAAA,IAChD,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,aAAa,YAA6C;AACjE,QAAM,QAAQ,WAAW;AACzB,MAAI,CAAC,OAAO;AACV,WAAO,iBAAiB,EAAE,QAAQ,WAAW,UAAU,EAAE,CAAC;AAAA,EAC5D;AAEA,QAAM,QAAQ,MAAM,SAAS,CAAC;AAE9B,QAAM,QAAwB,MAAM,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS;AAAA,IAC5D,IAAI,WAAW;AAAA,IACf,QAAQ,IAAI,SAAS,CAAC,GAAG;AAAA,MACvB,CAAC,UAAyB;AAAA,QACxB,IAAI,WAAW;AAAA,QACf,SAAS,KAAK,WAAW,KAAK,QAAQ;AAAA,MACxC;AAAA,IACF;AAAA,EACF,EAAE;AAEF,SAAO,iBAAiB;AAAA,IACtB;AAAA,IACA,cAAc,MAAM,gBAAgB;AAAA,IACpC,uBAAuB,WAAW,MAAM,qBAAqB,KAAK;AAAA,IAClE,aAAa,WAAW,MAAM,cAAc,CAAC,KAAK;AAAA,IAClD,aAAa,aAAa,MAAM,cAAc,CAAC,KAAK;AAAA,IACpD,aACE,OAAO,MAAM,gBAAgB,WACzB,MAAM,cACN,aAAa,MAAM,WAAqB,KAAK;AAAA,IACnD,UAAU,aAAa,MAAM,WAAW,CAAC,KAAK;AAAA,IAC9C,OAAO,WAAW,MAAM,KAAK,KAAK;AAAA,IAClC,WAAW,QAAQ,MAAM,YAAY,CAAC;AAAA,IACtC,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAEA,SAAS,oBAAoB,QAA+B;AAE1D,QAAM,aAAa,OAAO;AAC1B,MAAI,OAAO;AAGX,MAAI,WAAW,MAAM,KAAM,QAAO,WAAW,KAAK;AAAA,WACzC,WAAW,MAAM,KAAM,QAAO,WAAW,KAAK;AAAA,WAC9C,WAAW,SAAS,KAAM,QAAO,WAAW,QAAQ;AAAA,MACxD,QAAO,oCAAoC,OAAO,IAAI;AAE3D,SAAO,gBAAgB;AAAA,IACrB,SAAS;AAAA,IACT,QAAQ,WAAW,UAAU;AAAA,EAC/B,CAAC;AACH;AAMO,SAAS,cACd,QACA,UAC4C;AAC5C,QAAM,aAAa,gBAAgB,OAAO,IAAI;AAC9C,QAAM,aAAa,OAAO;AAE1B,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,MACL,OAAO,oBAAoB,MAAM;AAAA,MACjC,OAAO;AAAA,QACL,mBAAmB,OAAO;AAAA,QAC1B,sBAAsB;AAAA,QACtB,QAAQ;AAAA,QACR,MAAM,wBAAwB,OAAO,IAAI;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,kBAAkB;AAEtB,UAAQ,YAAY;AAAA,IAClB,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,YAAY,UAAU;AAC9B;AAAA,IACF,KAAK;AACH,cAAQ,eAAe,UAAU;AACjC;AAAA,IACF,KAAK;AACH,cAAQ,aAAa,UAAU;AAC/B;AAAA,IACF,KAAK;AACH,cAAQ,cAAc,UAAU;AAChC;AAAA,IACF,KAAK;AACH,cAAQ,eAAe,UAAU;AACjC;AAAA,IACF,KAAK;AACH,cAAQ,cAAc,UAAU;AAChC;AAAA,IACF,KAAK;AACH,cAAQ,YAAY,UAAU;AAC9B;AAAA,IACF,KAAK;AACH,cAAQ,cAAc,YAAY,QAAQ;AAC1C;AAAA,IACF,KAAK;AACH,cAAQ,aAAa,UAAU;AAC/B;AAAA,IACF,KAAK;AACH,cAAQ,YAAY,UAAU;AAC9B,wBAAkB;AAClB;AAAA,IACF,KAAK;AACH,cAAQ,aAAa,UAAU;AAC/B;AAAA,IACF;AACE,cAAQ,oBAAoB,MAAM;AAClC,aAAO;AAAA,QACL;AAAA,QACA,OAAO;AAAA,UACL,mBAAmB,OAAO;AAAA,UAC1B,sBAAsB;AAAA,UACtB,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,EACJ;AAEA,SAAO;AAAA,IACL;AAAA,IACA,OAAO;AAAA,MACL,mBAAmB,OAAO;AAAA,MAC1B,sBAAsB,MAAM;AAAA,MAC5B,QAAQ,kBAAkB,iBAAiB;AAAA,IAC7C;AAAA,EACF;AACF;;;ADvaA,SAAS,oBACP,SACA,UACqB;AACrB,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,OAAO,QAAQ,CAAC,EAAE,cAAc,KAAK;AAC3C,UAAM,QAAQ,QAAQ,CAAC,EAAE,cAAc,KAAK;AAC5C,UAAM,QAAQ,OAAO;AACrB,UAAM,QAAQ,OAAO;AAErB,QAAI,QAAQ,KAAM,QAAO;AACzB,QAAI,QAAQ,KAAM,QAAO;AACzB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,UAAU,GAAG;AACvB,aAAS;AAAA,MACP,YAAY,QAAQ,MAAM;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKA,SAAS,qBACP,QACA,SACA,UACS;AACT,QAAM,SAAkB,CAAC;AAEzB,aAAW,UAAU,OAAO,SAAS;AACnC,UAAM,EAAE,OAAO,MAAM,IAAI,cAAc,QAAQ,QAAQ;AACvD,WAAO,KAAK,KAAK;AACjB,YAAQ,KAAK,KAAK;AAAA,EACpB;AAEA,SAAO;AACT;AAKA,SAAS,WACP,KACA,SACA,UACS;AACT,QAAM,UAAU,IAAI;AACpB,MAAI,CAAC,WAAW,QAAQ,WAAW,EAAG,QAAO,CAAC;AAG9C,MAAI,IAAI,QAAQ;AACd,aAAS;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACA,MAAI,IAAI,QAAQ;AACd,aAAS;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,oBAAoB,SAAS,QAAQ;AAEpD,MAAI,CAAC,QAAQ;AAEX,UAAM,SAAkB,CAAC;AACzB,eAAW,UAAU,SAAS;AAC5B,aAAO,KAAK,GAAG,qBAAqB,QAAQ,SAAS,QAAQ,CAAC;AAAA,IAChE;AACA,WAAO;AAAA,EACT;AAGA,QAAM,WAAsB,QAAQ;AAAA,IAAI,CAAC,QACvC,qBAAqB,KAAK,SAAS,QAAQ;AAAA,EAC7C;AAGA,QAAM,QAAQ,WAAW,IAAI,SAAS,QAAQ,kBAAkB,CAAC;AAEjE,QAAM,UAAU,mBAAmB;AAAA,IACjC,SAAS;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,MACN,SAAS,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,EAAE;AAAA,MAChD,QAAQ,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,EAAE;AAAA,MAC/C,GAAI,QAAQ,EAAE,iBAAiB,MAAM,IAAI,CAAC;AAAA,IAC5C;AAAA,EACF,CAAC;AAED,SAAO,CAAC,OAAO;AACjB;AAKA,SAAS,gBACP,UAC6B;AAC7B,QAAM,OAAO,SAAS,KAAK;AAC3B,QAAM,eAAe,MAAM,SAAS,SAAS,CAAC;AAC9C,QAAM,iBAAiB,MAAM,WAAW,SAAS,CAAC;AAElD,QAAM,QAAQ,aAAa,aAAa,OAAO,KAAK,aAAa,KAAK;AACtE,QAAM,UACJ,WAAW,aAAa,kBAAkB,CAAC,KAC3C,WAAW,eAAe,kBAAkB,CAAC,KAC7C;AACF,QAAM,aAAa,gBAAgB,aAAa,aAAa,CAAC,KAAK;AAEnE,SAAO;AAAA,IACL,OAAO,SAAS;AAAA,IAChB,iBAAiB;AAAA,IACjB;AAAA,EACF;AACF;AAuBO,SAAS,uBACd,UACc;AAEd,MAAI,CAAC,UAAU,MAAM,MAAM;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAA+B,CAAC;AACtC,QAAM,WAAqB,CAAC;AAC5B,QAAM,SAAkB,CAAC;AAGzB,QAAM,WAAW,SAAS,KAAK,MAAM;AACrC,MAAI,YAAY,SAAS,SAAS,GAAG;AACnC,aAAS;AAAA,MACP,iBAAiB,SAAS,MAAM;AAAA,IAClC;AAAA,EACF;AAGA,aAAW,OAAO,SAAS,KAAK,MAAM;AACpC,QAAI,IAAI,MAAO;AACf,WAAO,KAAK,GAAG,WAAW,KAAK,SAAS,QAAQ,CAAC;AAAA,EACnD;AAGA,QAAM,UAA2B;AAAA,IAC/B,GAAG,6BAA6B;AAAA,IAChC;AAAA,IACA,UAAU,gBAAgB,QAAQ;AAAA,EACpC;AAGA,QAAM,UAAU;AAAA,IACd,OAAO,QAAQ;AAAA,IACf,WAAW,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,WAAW,EAAE;AAAA,IAC3D,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,cAAc,EAAE;AAAA,IACjE,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,eAAe,EAAE;AAAA,IAClE,SAAS,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE;AAAA,EACzD;AAEA,QAAM,SAAuB,EAAE,SAAS,UAAU,QAAQ;AAE1D,SAAO,EAAE,SAAS,OAAO;AAC3B;","names":[]}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@templatical/import-beefree",
3
+ "version": "0.0.1",
4
+ "publishConfig": { "access": "public" },
5
+ "description": "Convert BeeFree email templates to Templatical format",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.cjs"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "test": "vitest run --config vitest.config.ts",
24
+ "typecheck": "tsc --noEmit"
25
+ },
26
+ "dependencies": {
27
+ "@templatical/types": "workspace:*"
28
+ },
29
+ "devDependencies": {
30
+ "tsup": "^8.0.0",
31
+ "typescript": "^5.7.0",
32
+ "vitest": "^3.0.0"
33
+ }
34
+ }