@kgalexander/mcreate 1.0.12 → 1.0.13
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.
|
@@ -14719,6 +14719,7 @@ import { useEffect as useEffect15, useState as useState16, useRef as useRef11 }
|
|
|
14719
14719
|
|
|
14720
14720
|
// src/validate/helpers.ts
|
|
14721
14721
|
var MERGE_FIELD_REGEX2 = /\{\{([a-zA-Z_][a-zA-Z0-9_]*)\}\}/g;
|
|
14722
|
+
var HREF_REGEX = /<a[^>]+href=["']([^"']+)["'][^>]*>(.*?)<\/a>/gi;
|
|
14722
14723
|
function extractMergeFields(node) {
|
|
14723
14724
|
const fields = [];
|
|
14724
14725
|
if (!node || typeof node !== "object") return fields;
|
|
@@ -14764,6 +14765,77 @@ function extractEmptyLinks(node) {
|
|
|
14764
14765
|
}
|
|
14765
14766
|
return results;
|
|
14766
14767
|
}
|
|
14768
|
+
var PROPERTY_TYPES = /* @__PURE__ */ new Set(["property-card", "property-card-single-two", "property-card-triple-item"]);
|
|
14769
|
+
function getLinkType(node) {
|
|
14770
|
+
if (node.type === "button") return "button";
|
|
14771
|
+
if (node.type === "social-item") return "social";
|
|
14772
|
+
if (node.type === "image") return "image";
|
|
14773
|
+
if (PROPERTY_TYPES.has(node.type)) return "property";
|
|
14774
|
+
if (node.type === "text") return "text";
|
|
14775
|
+
return "unknown";
|
|
14776
|
+
}
|
|
14777
|
+
function getLinkText(node) {
|
|
14778
|
+
if (node.type === "button") return node.data?.value?.content || "Button";
|
|
14779
|
+
if (node.type === "social-item") return node.data?.value?.socialType || node.attributes?.alt || "Social";
|
|
14780
|
+
if (node.type === "image") return node.attributes?.alt || "Image";
|
|
14781
|
+
if (PROPERTY_TYPES.has(node.type)) return node.attributes?.address || node.attributes?.city || "Property";
|
|
14782
|
+
return "";
|
|
14783
|
+
}
|
|
14784
|
+
function extractLinks(template) {
|
|
14785
|
+
const seen = /* @__PURE__ */ new Map();
|
|
14786
|
+
const results = [];
|
|
14787
|
+
let position = 0;
|
|
14788
|
+
function addLink(url, linkType, linkText) {
|
|
14789
|
+
if (!url || !url.trim()) return;
|
|
14790
|
+
if (url.startsWith("mailto:")) return;
|
|
14791
|
+
if (url.startsWith("data:")) return;
|
|
14792
|
+
const trimmed = url.trim();
|
|
14793
|
+
if (seen.has(trimmed)) return;
|
|
14794
|
+
position++;
|
|
14795
|
+
seen.set(trimmed, results.length);
|
|
14796
|
+
results.push({
|
|
14797
|
+
url: trimmed,
|
|
14798
|
+
link_type: linkType,
|
|
14799
|
+
link_text: linkText || "",
|
|
14800
|
+
link_position: position
|
|
14801
|
+
});
|
|
14802
|
+
}
|
|
14803
|
+
function walk(node, isCompanyFooter) {
|
|
14804
|
+
if (!node || typeof node !== "object") return;
|
|
14805
|
+
const nodeIsFooter = isCompanyFooter || node.data?.value?.isCompanyFooter === true;
|
|
14806
|
+
const href = node.attributes?.href;
|
|
14807
|
+
if (href && node.type) {
|
|
14808
|
+
const linkType = nodeIsFooter ? "company_brand" : getLinkType(node);
|
|
14809
|
+
const linkText = getLinkText(node);
|
|
14810
|
+
addLink(href, linkType, linkText);
|
|
14811
|
+
}
|
|
14812
|
+
if (node.type === "text") {
|
|
14813
|
+
const content = node.data?.value?.content;
|
|
14814
|
+
if (typeof content === "string") {
|
|
14815
|
+
HREF_REGEX.lastIndex = 0;
|
|
14816
|
+
let match;
|
|
14817
|
+
while ((match = HREF_REGEX.exec(content)) !== null) {
|
|
14818
|
+
const [, linkUrl, linkText] = match;
|
|
14819
|
+
if (linkUrl) {
|
|
14820
|
+
addLink(linkUrl, nodeIsFooter ? "company_brand" : "text", linkText?.replace(/<[^>]*>/g, "") || "");
|
|
14821
|
+
}
|
|
14822
|
+
}
|
|
14823
|
+
}
|
|
14824
|
+
}
|
|
14825
|
+
if (Array.isArray(node.children)) {
|
|
14826
|
+
for (const child of node.children) {
|
|
14827
|
+
walk(child, nodeIsFooter);
|
|
14828
|
+
}
|
|
14829
|
+
}
|
|
14830
|
+
if (Array.isArray(node.content)) {
|
|
14831
|
+
for (const page of node.content) {
|
|
14832
|
+
walk(page, false);
|
|
14833
|
+
}
|
|
14834
|
+
}
|
|
14835
|
+
}
|
|
14836
|
+
walk(template, false);
|
|
14837
|
+
return results;
|
|
14838
|
+
}
|
|
14767
14839
|
|
|
14768
14840
|
// src/validate/index.ts
|
|
14769
14841
|
var PROPERTY_CARD_TYPES = /* @__PURE__ */ new Set(["property-card", "property-card-single-two", "property-card-triple-item"]);
|
|
@@ -16186,6 +16258,7 @@ export {
|
|
|
16186
16258
|
SidebarProvider,
|
|
16187
16259
|
useSidebarContext,
|
|
16188
16260
|
Textarea,
|
|
16261
|
+
extractLinks,
|
|
16189
16262
|
validate_editor_onPreview,
|
|
16190
16263
|
validate_campaign_onCreate,
|
|
16191
16264
|
campaign_validation_warnings,
|
package/dist/index.d.mts
CHANGED
|
@@ -343,6 +343,13 @@ interface PreviewValidationType {
|
|
|
343
343
|
is_over_size_limit: boolean;
|
|
344
344
|
placeholder_property_images: number;
|
|
345
345
|
}
|
|
346
|
+
type LinkType = 'social' | 'property' | 'button' | 'text' | 'image' | 'company_brand' | 'unknown';
|
|
347
|
+
interface ExtractedLink {
|
|
348
|
+
url: string;
|
|
349
|
+
link_type: LinkType;
|
|
350
|
+
link_text: string;
|
|
351
|
+
link_position: number;
|
|
352
|
+
}
|
|
346
353
|
|
|
347
354
|
/**
|
|
348
355
|
* Validate a template when the user previews the template
|
|
@@ -361,6 +368,13 @@ declare function campaign_validation_warnings(): {
|
|
|
361
368
|
missing_links: boolean;
|
|
362
369
|
};
|
|
363
370
|
|
|
371
|
+
/**
|
|
372
|
+
* Recursively extract all links from template JSON.
|
|
373
|
+
* Link type is derived from the element type — no HTML parsing needed
|
|
374
|
+
* (except for inline <a> tags in text elements).
|
|
375
|
+
*/
|
|
376
|
+
declare function extractLinks(template: TemplateJSON): ExtractedLink[];
|
|
377
|
+
|
|
364
378
|
/**
|
|
365
379
|
* JSON to MJML Converter
|
|
366
380
|
* Converts template JSON to MJML string for rendering
|
|
@@ -380,4 +394,4 @@ interface RenderOptions {
|
|
|
380
394
|
*/
|
|
381
395
|
declare function json2mjml(template: TemplateJSON, mode?: RenderMode, options?: RenderOptions): string;
|
|
382
396
|
|
|
383
|
-
export { Editor, type ImageData, MAX_TEMPLATE_SIZE, type MergeField, type MergeFieldType, type MissingLinkType, type OnDeleteCallback, type OnDuplicateCallback, type OnExitCallback, type OnImageUploadCallback, type OnSaveCallback, type OnToastCallback, OtherFonts, type PaidLevel, type PreviewValidationType, type TemplateJSON, TemplatePage, type ToastOptions, type ToastType, campaign_validation_warnings, emailSafeFonts, json2mjml, validate_campaign_onCreate, validate_editor_onPreview };
|
|
397
|
+
export { Editor, type ExtractedLink, type ImageData, type LinkType, MAX_TEMPLATE_SIZE, type MergeField, type MergeFieldType, type MissingLinkType, type OnDeleteCallback, type OnDuplicateCallback, type OnExitCallback, type OnImageUploadCallback, type OnSaveCallback, type OnToastCallback, OtherFonts, type PaidLevel, type PreviewValidationType, type TemplateJSON, TemplatePage, type ToastOptions, type ToastType, campaign_validation_warnings, emailSafeFonts, extractLinks, json2mjml, validate_campaign_onCreate, validate_editor_onPreview };
|
package/dist/index.d.ts
CHANGED
|
@@ -343,6 +343,13 @@ interface PreviewValidationType {
|
|
|
343
343
|
is_over_size_limit: boolean;
|
|
344
344
|
placeholder_property_images: number;
|
|
345
345
|
}
|
|
346
|
+
type LinkType = 'social' | 'property' | 'button' | 'text' | 'image' | 'company_brand' | 'unknown';
|
|
347
|
+
interface ExtractedLink {
|
|
348
|
+
url: string;
|
|
349
|
+
link_type: LinkType;
|
|
350
|
+
link_text: string;
|
|
351
|
+
link_position: number;
|
|
352
|
+
}
|
|
346
353
|
|
|
347
354
|
/**
|
|
348
355
|
* Validate a template when the user previews the template
|
|
@@ -361,6 +368,13 @@ declare function campaign_validation_warnings(): {
|
|
|
361
368
|
missing_links: boolean;
|
|
362
369
|
};
|
|
363
370
|
|
|
371
|
+
/**
|
|
372
|
+
* Recursively extract all links from template JSON.
|
|
373
|
+
* Link type is derived from the element type — no HTML parsing needed
|
|
374
|
+
* (except for inline <a> tags in text elements).
|
|
375
|
+
*/
|
|
376
|
+
declare function extractLinks(template: TemplateJSON): ExtractedLink[];
|
|
377
|
+
|
|
364
378
|
/**
|
|
365
379
|
* JSON to MJML Converter
|
|
366
380
|
* Converts template JSON to MJML string for rendering
|
|
@@ -380,4 +394,4 @@ interface RenderOptions {
|
|
|
380
394
|
*/
|
|
381
395
|
declare function json2mjml(template: TemplateJSON, mode?: RenderMode, options?: RenderOptions): string;
|
|
382
396
|
|
|
383
|
-
export { Editor, type ImageData, MAX_TEMPLATE_SIZE, type MergeField, type MergeFieldType, type MissingLinkType, type OnDeleteCallback, type OnDuplicateCallback, type OnExitCallback, type OnImageUploadCallback, type OnSaveCallback, type OnToastCallback, OtherFonts, type PaidLevel, type PreviewValidationType, type TemplateJSON, TemplatePage, type ToastOptions, type ToastType, campaign_validation_warnings, emailSafeFonts, json2mjml, validate_campaign_onCreate, validate_editor_onPreview };
|
|
397
|
+
export { Editor, type ExtractedLink, type ImageData, type LinkType, MAX_TEMPLATE_SIZE, type MergeField, type MergeFieldType, type MissingLinkType, type OnDeleteCallback, type OnDuplicateCallback, type OnExitCallback, type OnImageUploadCallback, type OnSaveCallback, type OnToastCallback, OtherFonts, type PaidLevel, type PreviewValidationType, type TemplateJSON, TemplatePage, type ToastOptions, type ToastType, campaign_validation_warnings, emailSafeFonts, extractLinks, json2mjml, validate_campaign_onCreate, validate_editor_onPreview };
|
package/dist/index.js
CHANGED
|
@@ -15473,11 +15473,83 @@ function extractEmptyLinks(node) {
|
|
|
15473
15473
|
}
|
|
15474
15474
|
return results;
|
|
15475
15475
|
}
|
|
15476
|
-
|
|
15476
|
+
function getLinkType(node) {
|
|
15477
|
+
if (node.type === "button") return "button";
|
|
15478
|
+
if (node.type === "social-item") return "social";
|
|
15479
|
+
if (node.type === "image") return "image";
|
|
15480
|
+
if (PROPERTY_TYPES.has(node.type)) return "property";
|
|
15481
|
+
if (node.type === "text") return "text";
|
|
15482
|
+
return "unknown";
|
|
15483
|
+
}
|
|
15484
|
+
function getLinkText(node) {
|
|
15485
|
+
if (node.type === "button") return node.data?.value?.content || "Button";
|
|
15486
|
+
if (node.type === "social-item") return node.data?.value?.socialType || node.attributes?.alt || "Social";
|
|
15487
|
+
if (node.type === "image") return node.attributes?.alt || "Image";
|
|
15488
|
+
if (PROPERTY_TYPES.has(node.type)) return node.attributes?.address || node.attributes?.city || "Property";
|
|
15489
|
+
return "";
|
|
15490
|
+
}
|
|
15491
|
+
function extractLinks(template) {
|
|
15492
|
+
const seen = /* @__PURE__ */ new Map();
|
|
15493
|
+
const results = [];
|
|
15494
|
+
let position = 0;
|
|
15495
|
+
function addLink(url, linkType, linkText) {
|
|
15496
|
+
if (!url || !url.trim()) return;
|
|
15497
|
+
if (url.startsWith("mailto:")) return;
|
|
15498
|
+
if (url.startsWith("data:")) return;
|
|
15499
|
+
const trimmed = url.trim();
|
|
15500
|
+
if (seen.has(trimmed)) return;
|
|
15501
|
+
position++;
|
|
15502
|
+
seen.set(trimmed, results.length);
|
|
15503
|
+
results.push({
|
|
15504
|
+
url: trimmed,
|
|
15505
|
+
link_type: linkType,
|
|
15506
|
+
link_text: linkText || "",
|
|
15507
|
+
link_position: position
|
|
15508
|
+
});
|
|
15509
|
+
}
|
|
15510
|
+
function walk(node, isCompanyFooter) {
|
|
15511
|
+
if (!node || typeof node !== "object") return;
|
|
15512
|
+
const nodeIsFooter = isCompanyFooter || node.data?.value?.isCompanyFooter === true;
|
|
15513
|
+
const href = node.attributes?.href;
|
|
15514
|
+
if (href && node.type) {
|
|
15515
|
+
const linkType = nodeIsFooter ? "company_brand" : getLinkType(node);
|
|
15516
|
+
const linkText = getLinkText(node);
|
|
15517
|
+
addLink(href, linkType, linkText);
|
|
15518
|
+
}
|
|
15519
|
+
if (node.type === "text") {
|
|
15520
|
+
const content = node.data?.value?.content;
|
|
15521
|
+
if (typeof content === "string") {
|
|
15522
|
+
HREF_REGEX.lastIndex = 0;
|
|
15523
|
+
let match;
|
|
15524
|
+
while ((match = HREF_REGEX.exec(content)) !== null) {
|
|
15525
|
+
const [, linkUrl, linkText] = match;
|
|
15526
|
+
if (linkUrl) {
|
|
15527
|
+
addLink(linkUrl, nodeIsFooter ? "company_brand" : "text", linkText?.replace(/<[^>]*>/g, "") || "");
|
|
15528
|
+
}
|
|
15529
|
+
}
|
|
15530
|
+
}
|
|
15531
|
+
}
|
|
15532
|
+
if (Array.isArray(node.children)) {
|
|
15533
|
+
for (const child of node.children) {
|
|
15534
|
+
walk(child, nodeIsFooter);
|
|
15535
|
+
}
|
|
15536
|
+
}
|
|
15537
|
+
if (Array.isArray(node.content)) {
|
|
15538
|
+
for (const page of node.content) {
|
|
15539
|
+
walk(page, false);
|
|
15540
|
+
}
|
|
15541
|
+
}
|
|
15542
|
+
}
|
|
15543
|
+
walk(template, false);
|
|
15544
|
+
return results;
|
|
15545
|
+
}
|
|
15546
|
+
var MERGE_FIELD_REGEX2, HREF_REGEX, PROPERTY_TYPES;
|
|
15477
15547
|
var init_helpers2 = __esm({
|
|
15478
15548
|
"src/validate/helpers.ts"() {
|
|
15479
15549
|
"use strict";
|
|
15480
15550
|
MERGE_FIELD_REGEX2 = /\{\{([a-zA-Z_][a-zA-Z0-9_]*)\}\}/g;
|
|
15551
|
+
HREF_REGEX = /<a[^>]+href=["']([^"']+)["'][^>]*>(.*?)<\/a>/gi;
|
|
15552
|
+
PROPERTY_TYPES = /* @__PURE__ */ new Set(["property-card", "property-card-single-two", "property-card-triple-item"]);
|
|
15481
15553
|
}
|
|
15482
15554
|
});
|
|
15483
15555
|
|
|
@@ -16921,6 +16993,7 @@ __export(index_exports, {
|
|
|
16921
16993
|
TemplatePage: () => TemplatePage,
|
|
16922
16994
|
campaign_validation_warnings: () => campaign_validation_warnings,
|
|
16923
16995
|
emailSafeFonts: () => emailSafeFonts,
|
|
16996
|
+
extractLinks: () => extractLinks,
|
|
16924
16997
|
json2mjml: () => json2mjml,
|
|
16925
16998
|
validate_campaign_onCreate: () => validate_campaign_onCreate,
|
|
16926
16999
|
validate_editor_onPreview: () => validate_editor_onPreview
|
|
@@ -29507,6 +29580,7 @@ function TemplatePage({
|
|
|
29507
29580
|
init_configuration();
|
|
29508
29581
|
init_fonts();
|
|
29509
29582
|
init_validate();
|
|
29583
|
+
init_helpers2();
|
|
29510
29584
|
init_json2mjml();
|
|
29511
29585
|
// Annotate the CommonJS export names for ESM import in node:
|
|
29512
29586
|
0 && (module.exports = {
|
|
@@ -29516,6 +29590,7 @@ init_json2mjml();
|
|
|
29516
29590
|
TemplatePage,
|
|
29517
29591
|
campaign_validation_warnings,
|
|
29518
29592
|
emailSafeFonts,
|
|
29593
|
+
extractLinks,
|
|
29519
29594
|
json2mjml,
|
|
29520
29595
|
validate_campaign_onCreate,
|
|
29521
29596
|
validate_editor_onPreview
|
package/dist/index.mjs
CHANGED
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
campaign_validation_warnings,
|
|
52
52
|
cn,
|
|
53
53
|
emailSafeFonts,
|
|
54
|
+
extractLinks,
|
|
54
55
|
formatBorder,
|
|
55
56
|
getElementDisplayName,
|
|
56
57
|
getParentByIdx,
|
|
@@ -64,7 +65,7 @@ import {
|
|
|
64
65
|
useSidebarContext,
|
|
65
66
|
validate_campaign_onCreate,
|
|
66
67
|
validate_editor_onPreview
|
|
67
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-JDECYTJI.mjs";
|
|
68
69
|
|
|
69
70
|
// src/core/editor/components/email-template-v2/header.tsx
|
|
70
71
|
import { ArrowLeftIcon, CopyIcon, MegaphoneIcon, MoreHorizontalIcon, PencilIcon, SendIcon, TrashIcon } from "lucide-react";
|
|
@@ -12283,7 +12284,7 @@ function useAutoSave() {
|
|
|
12283
12284
|
// src/core/editor/components/email-template-v2/template-page.tsx
|
|
12284
12285
|
import "react-json-view-lite/dist/index.css";
|
|
12285
12286
|
import { jsx as jsx75, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
12286
|
-
var Editor2 = lazy(() => import("./core-
|
|
12287
|
+
var Editor2 = lazy(() => import("./core-IZXIUSSS.mjs").then((module) => ({
|
|
12287
12288
|
default: module.Editor
|
|
12288
12289
|
})));
|
|
12289
12290
|
function TemplatePage({
|
|
@@ -12369,6 +12370,7 @@ export {
|
|
|
12369
12370
|
TemplatePage,
|
|
12370
12371
|
campaign_validation_warnings,
|
|
12371
12372
|
emailSafeFonts,
|
|
12373
|
+
extractLinks,
|
|
12372
12374
|
json2mjml,
|
|
12373
12375
|
validate_campaign_onCreate,
|
|
12374
12376
|
validate_editor_onPreview
|