@salesmind-ai/design-system 0.1.7 → 0.1.9
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/audit-CiyPkxk1.d.cts +194 -0
- package/dist/audit-CiyPkxk1.d.ts +194 -0
- package/dist/core/index.cjs +1 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.css.map +1 -1
- package/dist/core/index.d.cts +5 -4
- package/dist/core/index.d.ts +5 -4
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +426 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +66 -21
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +405 -14
- package/dist/index.js.map +1 -1
- package/dist/marketing/index.cjs +136 -12
- package/dist/marketing/index.cjs.map +1 -1
- package/dist/marketing/index.css +26 -1
- package/dist/marketing/index.css.map +1 -1
- package/dist/marketing/index.js +138 -14
- package/dist/marketing/index.js.map +1 -1
- package/dist/report/index.cjs +1 -1
- package/dist/report/index.cjs.map +1 -1
- package/dist/report/index.css.map +1 -1
- package/dist/report/index.js +1 -1
- package/dist/report/index.js.map +1 -1
- package/dist/styles/styles.css +7 -4
- package/dist/web/index.cjs +427 -10
- package/dist/web/index.cjs.map +1 -1
- package/dist/web/index.css.map +1 -1
- package/dist/web/index.d.cts +28 -2
- package/dist/web/index.d.ts +28 -2
- package/dist/web/index.js +405 -12
- package/dist/web/index.js.map +1 -1
- package/package.json +14 -12
package/dist/styles/styles.css
CHANGED
|
@@ -115,9 +115,9 @@
|
|
|
115
115
|
--text-secondary: rgba(255, 255, 255, 0.8);
|
|
116
116
|
--text-tertiary: rgba(255, 255, 255, 0.6);
|
|
117
117
|
--text-disabled: rgba(255, 255, 255, 0.3);
|
|
118
|
-
--glass-base: rgba(255, 255, 255, 0.
|
|
119
|
-
--glass-base-hover: rgba(255, 255, 255, 0.
|
|
120
|
-
--glass-base-active: rgba(255, 255, 255, 0.
|
|
118
|
+
--glass-base: rgba(255, 255, 255, 0.06);
|
|
119
|
+
--glass-base-hover: rgba(255, 255, 255, 0.09);
|
|
120
|
+
--glass-base-active: rgba(255, 255, 255, 0.12);
|
|
121
121
|
--glass-blur: 40px;
|
|
122
122
|
--glass-saturate: 160%;
|
|
123
123
|
--glass-brightness: 90%;
|
|
@@ -2984,11 +2984,14 @@ a:hover {
|
|
|
2984
2984
|
flex-shrink: 0;
|
|
2985
2985
|
margin-left: var(--space-3);
|
|
2986
2986
|
}
|
|
2987
|
-
@media (max-width:
|
|
2987
|
+
@media (max-width: 1399px) {
|
|
2988
2988
|
.ds-locale-dropdown__trigger {
|
|
2989
2989
|
padding: var(--space-1-5) var(--space-2);
|
|
2990
2990
|
gap: var(--space-1);
|
|
2991
2991
|
}
|
|
2992
|
+
.ds-locale-dropdown__trigger-flag {
|
|
2993
|
+
display: none;
|
|
2994
|
+
}
|
|
2992
2995
|
.ds-locale-dropdown__trigger-chevron {
|
|
2993
2996
|
display: none;
|
|
2994
2997
|
}
|
package/dist/web/index.cjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
'use strict';
|
|
2
3
|
|
|
3
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -656,23 +657,146 @@ var Button = React__default.default.forwardRef(
|
|
|
656
657
|
}
|
|
657
658
|
);
|
|
658
659
|
Button.displayName = "Button";
|
|
660
|
+
var UtmContext = React.createContext(null);
|
|
661
|
+
|
|
662
|
+
// src/web/utm/useUtmDefaults.ts
|
|
663
|
+
function useUtmDefaults() {
|
|
664
|
+
return React.useContext(UtmContext);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// src/web/utm/builders.ts
|
|
668
|
+
var PLACEHOLDER_ORIGIN = "https://__placeholder__.internal";
|
|
669
|
+
function buildUtmUrl(baseUrl, params) {
|
|
670
|
+
const isRelative = baseUrl.startsWith("/");
|
|
671
|
+
let url;
|
|
672
|
+
try {
|
|
673
|
+
url = isRelative ? new URL(baseUrl, PLACEHOLDER_ORIGIN) : new URL(baseUrl);
|
|
674
|
+
} catch {
|
|
675
|
+
return baseUrl;
|
|
676
|
+
}
|
|
677
|
+
const existingParams = [];
|
|
678
|
+
url.searchParams.forEach((value, key) => {
|
|
679
|
+
existingParams.push([key, value]);
|
|
680
|
+
});
|
|
681
|
+
for (const [key] of existingParams) {
|
|
682
|
+
url.searchParams.delete(key);
|
|
683
|
+
}
|
|
684
|
+
for (const [key, value] of existingParams) {
|
|
685
|
+
if (!key.startsWith("utm_")) {
|
|
686
|
+
url.searchParams.set(key, value);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
url.searchParams.set("utm_source", params.source);
|
|
690
|
+
url.searchParams.set("utm_medium", params.medium);
|
|
691
|
+
url.searchParams.set("utm_campaign", params.campaign);
|
|
692
|
+
if (params.term !== void 0) {
|
|
693
|
+
url.searchParams.set("utm_term", params.term);
|
|
694
|
+
}
|
|
695
|
+
if (params.content !== void 0) {
|
|
696
|
+
url.searchParams.set("utm_content", params.content);
|
|
697
|
+
}
|
|
698
|
+
if (isRelative) {
|
|
699
|
+
return url.href.replace(PLACEHOLDER_ORIGIN, "");
|
|
700
|
+
}
|
|
701
|
+
return url.href;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// src/web/utm/classifiers.ts
|
|
705
|
+
var INTERNAL_PATTERNS = [
|
|
706
|
+
/^\/(?!\/)/,
|
|
707
|
+
// Relative paths
|
|
708
|
+
/^https?:\/\/(www\.)?sales-mind\.ai/i,
|
|
709
|
+
// Marketing site
|
|
710
|
+
/^https?:\/\/app\.sales-mind\.ai/i,
|
|
711
|
+
// Web app
|
|
712
|
+
/^https?:\/\/apps\.sales-mind\.ai/i,
|
|
713
|
+
// Web app (legacy)
|
|
714
|
+
/^https?:\/\/meet\.sales-mind\.ai/i,
|
|
715
|
+
// Booking
|
|
716
|
+
/^https?:\/\/docs\.sales-mind\.ai/i
|
|
717
|
+
// Docs
|
|
718
|
+
];
|
|
719
|
+
var SYSTEM_PATTERNS = [
|
|
720
|
+
/^https?:\/\/.*\/api\//i,
|
|
721
|
+
// API endpoints
|
|
722
|
+
/^https?:\/\/.*\/webhook/i,
|
|
723
|
+
// Webhooks
|
|
724
|
+
/^https?:\/\/.*\/oauth/i,
|
|
725
|
+
// OAuth callbacks
|
|
726
|
+
/^https?:\/\/.*\/callback/i,
|
|
727
|
+
// Callbacks
|
|
728
|
+
/^https?:\/\/.*\.supabase\.(co|com)/i,
|
|
729
|
+
// Supabase
|
|
730
|
+
/^https?:\/\/.*\.firebaseapp\.com/i,
|
|
731
|
+
// Firebase
|
|
732
|
+
/^https?:\/\/.*\.cloudfunctions\.net/i
|
|
733
|
+
// Cloud Functions
|
|
734
|
+
];
|
|
735
|
+
var ASSET_PATTERNS = [
|
|
736
|
+
/\.(css|js|mjs|map|woff2?|ttf|eot|svg|png|jpe?g|gif|webp|avif|ico|pdf)(\?.*)?$/i
|
|
737
|
+
];
|
|
738
|
+
var CONVERSION_PATTERNS = [
|
|
739
|
+
/^https?:\/\/(www\.)?calendly\.com/i,
|
|
740
|
+
/^https?:\/\/(checkout\.)?stripe\.com/i,
|
|
741
|
+
/^https?:\/\/buy\.stripe\.com/i,
|
|
742
|
+
/^https?:\/\/chromewebstore\.google\.com/i,
|
|
743
|
+
/^https?:\/\/meet\.sales-mind\.ai/i
|
|
744
|
+
];
|
|
745
|
+
var PROTOCOL_EXEMPT = [
|
|
746
|
+
/^mailto:/i,
|
|
747
|
+
/^tel:/i,
|
|
748
|
+
/^#/,
|
|
749
|
+
/^javascript:/i
|
|
750
|
+
];
|
|
751
|
+
function classifyUrl(url) {
|
|
752
|
+
if (PROTOCOL_EXEMPT.some((p) => p.test(url))) return "protocol";
|
|
753
|
+
if (ASSET_PATTERNS.some((p) => p.test(url))) return "asset";
|
|
754
|
+
if (SYSTEM_PATTERNS.some((p) => p.test(url))) return "system";
|
|
755
|
+
if (CONVERSION_PATTERNS.some((p) => p.test(url))) return "conversion";
|
|
756
|
+
if (INTERNAL_PATTERNS.some((p) => p.test(url))) return "internal";
|
|
757
|
+
return "external";
|
|
758
|
+
}
|
|
759
|
+
function requiresUtm(url) {
|
|
760
|
+
const classification = classifyUrl(url);
|
|
761
|
+
return classification === "external" || classification === "conversion";
|
|
762
|
+
}
|
|
763
|
+
function isUtmExempt(url) {
|
|
764
|
+
const classification = classifyUrl(url);
|
|
765
|
+
return classification === "protocol" || classification === "asset" || classification === "system" || classification === "internal";
|
|
766
|
+
}
|
|
659
767
|
|
|
660
768
|
// src/components/OutboundLink/outbound-link-utils.ts
|
|
661
|
-
var
|
|
769
|
+
var LEGACY_UTM_SOURCE = "salesmind";
|
|
662
770
|
var EXEMPT_PATTERNS = [
|
|
663
771
|
/^https?:\/\/(www\.)?(stripe\.com|checkout\.stripe\.com|paypal\.com)/i,
|
|
664
772
|
/^https?:\/\/(www\.)?github\.com\/login\/oauth/i
|
|
665
773
|
];
|
|
666
774
|
var isExemptUrl = (urlStr) => {
|
|
667
775
|
if (urlStr.startsWith("mailto:") || urlStr.startsWith("tel:")) return true;
|
|
776
|
+
const classification = classifyUrl(urlStr);
|
|
777
|
+
if (classification === "system" || classification === "protocol" || classification === "asset") {
|
|
778
|
+
return true;
|
|
779
|
+
}
|
|
668
780
|
return EXEMPT_PATTERNS.some((pattern) => pattern.test(urlStr));
|
|
669
781
|
};
|
|
782
|
+
var appendGovernedUTMs = (href, params, preserveExisting = true) => {
|
|
783
|
+
try {
|
|
784
|
+
const url = new URL(href);
|
|
785
|
+
if (preserveExisting) {
|
|
786
|
+
const hasAll = url.searchParams.has("utm_source") && url.searchParams.has("utm_medium") && url.searchParams.has("utm_campaign");
|
|
787
|
+
if (hasAll) return href;
|
|
788
|
+
}
|
|
789
|
+
return buildUtmUrl(href, params);
|
|
790
|
+
} catch {
|
|
791
|
+
return href;
|
|
792
|
+
}
|
|
793
|
+
};
|
|
670
794
|
var appendUTMs = (href, context, pageSlug, options) => {
|
|
671
795
|
try {
|
|
672
796
|
const url = new URL(href);
|
|
673
797
|
const { mediumOverride = "outbound_link", campaignOverride, preserveExisting = true } = options;
|
|
674
798
|
const utms = {
|
|
675
|
-
utm_source:
|
|
799
|
+
utm_source: LEGACY_UTM_SOURCE,
|
|
676
800
|
utm_medium: mediumOverride,
|
|
677
801
|
utm_campaign: campaignOverride || pageSlug,
|
|
678
802
|
utm_content: context
|
|
@@ -699,10 +823,13 @@ var OutboundLink = React.forwardRef(
|
|
|
699
823
|
preserveExistingUTM = true,
|
|
700
824
|
openInNewTab = true,
|
|
701
825
|
disableTracking = false,
|
|
826
|
+
utmParams,
|
|
702
827
|
onClick,
|
|
703
828
|
children,
|
|
704
829
|
...props
|
|
705
830
|
}, ref) => {
|
|
831
|
+
const contextParams = useUtmDefaults();
|
|
832
|
+
const resolvedUtmParams = utmParams ?? contextParams;
|
|
706
833
|
let hostname = "";
|
|
707
834
|
try {
|
|
708
835
|
const url = new URL(href);
|
|
@@ -727,16 +854,20 @@ var OutboundLink = React.forwardRef(
|
|
|
727
854
|
}
|
|
728
855
|
const isExempt = isExemptUrl(href) || disableTracking;
|
|
729
856
|
if (isExternal && !isExempt) {
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
857
|
+
if (resolvedUtmParams) {
|
|
858
|
+
setFinalHref(appendGovernedUTMs(href, resolvedUtmParams, preserveExistingUTM));
|
|
859
|
+
} else {
|
|
860
|
+
const pageSlug = window.location.pathname.replace(/^\/|\/$/g, "") || "home";
|
|
861
|
+
setFinalHref(appendUTMs(href, context, pageSlug, {
|
|
862
|
+
mediumOverride: currentMedium,
|
|
863
|
+
campaignOverride,
|
|
864
|
+
preserveExisting: preserveExistingUTM
|
|
865
|
+
}));
|
|
866
|
+
}
|
|
736
867
|
} else {
|
|
737
868
|
setFinalHref(href);
|
|
738
869
|
}
|
|
739
|
-
}, [href, context, mediumOverride, campaignOverride, preserveExistingUTM, disableTracking]);
|
|
870
|
+
}, [href, context, mediumOverride, campaignOverride, preserveExistingUTM, disableTracking, resolvedUtmParams]);
|
|
740
871
|
const handleClick = (e) => {
|
|
741
872
|
if (typeof window === "undefined" || disableTracking) {
|
|
742
873
|
onClick?.(e);
|
|
@@ -909,20 +1040,306 @@ function useAnalytics() {
|
|
|
909
1040
|
return React.useContext(AnalyticsContext) ?? NOOP_VALUE;
|
|
910
1041
|
}
|
|
911
1042
|
|
|
1043
|
+
// src/web/utm/constants.ts
|
|
1044
|
+
var UTM_SOURCES = [
|
|
1045
|
+
"linkedin",
|
|
1046
|
+
"whatsapp",
|
|
1047
|
+
"intercom",
|
|
1048
|
+
"email",
|
|
1049
|
+
"website",
|
|
1050
|
+
"app",
|
|
1051
|
+
"chromeStore",
|
|
1052
|
+
"stripe",
|
|
1053
|
+
"direct"
|
|
1054
|
+
];
|
|
1055
|
+
var UTM_MEDIUMS_MESSAGING = [
|
|
1056
|
+
"dm",
|
|
1057
|
+
"group",
|
|
1058
|
+
"email",
|
|
1059
|
+
"inAppChat",
|
|
1060
|
+
"organicPost",
|
|
1061
|
+
"paidAd",
|
|
1062
|
+
"qrCode",
|
|
1063
|
+
"redirect",
|
|
1064
|
+
"storeListing"
|
|
1065
|
+
];
|
|
1066
|
+
var UTM_MEDIUMS_APP = [
|
|
1067
|
+
"appHome",
|
|
1068
|
+
"appDashboard",
|
|
1069
|
+
"appInbox",
|
|
1070
|
+
"appContacts",
|
|
1071
|
+
"appCampaigns",
|
|
1072
|
+
"appSettings",
|
|
1073
|
+
"appBilling",
|
|
1074
|
+
"appCheckout",
|
|
1075
|
+
"appOnboarding",
|
|
1076
|
+
"appSupport",
|
|
1077
|
+
"appCalendar"
|
|
1078
|
+
];
|
|
1079
|
+
var UTM_MEDIUMS_WEB = [
|
|
1080
|
+
"webHome",
|
|
1081
|
+
"webDemo",
|
|
1082
|
+
"webPricing",
|
|
1083
|
+
"webFeatures",
|
|
1084
|
+
"webUseCase",
|
|
1085
|
+
"webSolution",
|
|
1086
|
+
"webIndustry",
|
|
1087
|
+
"webIntegrations",
|
|
1088
|
+
"webBlog",
|
|
1089
|
+
"webBlogPost",
|
|
1090
|
+
"webLanding",
|
|
1091
|
+
"webComparison",
|
|
1092
|
+
"webCaseStudy",
|
|
1093
|
+
"webAbout",
|
|
1094
|
+
"webContact",
|
|
1095
|
+
"webCareers",
|
|
1096
|
+
"webLegal",
|
|
1097
|
+
"webDocs",
|
|
1098
|
+
"webAffiliate"
|
|
1099
|
+
];
|
|
1100
|
+
var UTM_MEDIUMS_ALL = [
|
|
1101
|
+
...UTM_MEDIUMS_MESSAGING,
|
|
1102
|
+
...UTM_MEDIUMS_APP,
|
|
1103
|
+
...UTM_MEDIUMS_WEB
|
|
1104
|
+
];
|
|
1105
|
+
var UTM_CAMPAIGNS = [
|
|
1106
|
+
"discoveryCall",
|
|
1107
|
+
"demo",
|
|
1108
|
+
"trial",
|
|
1109
|
+
"onboarding",
|
|
1110
|
+
"upgrade",
|
|
1111
|
+
"renewal",
|
|
1112
|
+
"retention",
|
|
1113
|
+
"accountSupport",
|
|
1114
|
+
"supportCall",
|
|
1115
|
+
"partnerCall",
|
|
1116
|
+
"hiring",
|
|
1117
|
+
"interviewCall"
|
|
1118
|
+
];
|
|
1119
|
+
var UTM_TERMS = [
|
|
1120
|
+
"julienGadea",
|
|
1121
|
+
"bramSmith",
|
|
1122
|
+
"florentDupont",
|
|
1123
|
+
"sawLin",
|
|
1124
|
+
"evaSupport",
|
|
1125
|
+
"team",
|
|
1126
|
+
"auto"
|
|
1127
|
+
];
|
|
1128
|
+
var UTM_CONTENTS = [
|
|
1129
|
+
"ctaPrimary",
|
|
1130
|
+
"ctaSecondary",
|
|
1131
|
+
"ctaHeader",
|
|
1132
|
+
"ctaFooter",
|
|
1133
|
+
"ctaInline",
|
|
1134
|
+
"buttonPrimary",
|
|
1135
|
+
"buttonSecondary",
|
|
1136
|
+
"banner",
|
|
1137
|
+
"popup",
|
|
1138
|
+
"variantA",
|
|
1139
|
+
"variantB",
|
|
1140
|
+
"variantC"
|
|
1141
|
+
];
|
|
1142
|
+
var UTM_SOURCES_REQUIRING_SELLER = [
|
|
1143
|
+
"linkedin",
|
|
1144
|
+
"whatsapp",
|
|
1145
|
+
"intercom",
|
|
1146
|
+
"email"
|
|
1147
|
+
];
|
|
1148
|
+
|
|
1149
|
+
// src/web/utm/validators.ts
|
|
1150
|
+
function validateUtmField(field, value) {
|
|
1151
|
+
switch (field) {
|
|
1152
|
+
case "source":
|
|
1153
|
+
return UTM_SOURCES.includes(value);
|
|
1154
|
+
case "medium":
|
|
1155
|
+
return UTM_MEDIUMS_ALL.includes(value);
|
|
1156
|
+
case "campaign":
|
|
1157
|
+
return UTM_CAMPAIGNS.includes(value);
|
|
1158
|
+
case "term":
|
|
1159
|
+
return UTM_TERMS.includes(value);
|
|
1160
|
+
case "content":
|
|
1161
|
+
return UTM_CONTENTS.includes(value);
|
|
1162
|
+
default:
|
|
1163
|
+
return false;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
function isValidUtmParams(params) {
|
|
1167
|
+
if (!params.source || !params.medium || !params.campaign) {
|
|
1168
|
+
return false;
|
|
1169
|
+
}
|
|
1170
|
+
if (!validateUtmField("source", params.source)) return false;
|
|
1171
|
+
if (!validateUtmField("medium", params.medium)) return false;
|
|
1172
|
+
if (!validateUtmField("campaign", params.campaign)) return false;
|
|
1173
|
+
if (params.term !== void 0 && !validateUtmField("term", params.term)) return false;
|
|
1174
|
+
if (params.content !== void 0 && !validateUtmField("content", params.content)) return false;
|
|
1175
|
+
return true;
|
|
1176
|
+
}
|
|
1177
|
+
function validateCompliance(url, params) {
|
|
1178
|
+
const errors = [];
|
|
1179
|
+
const classification = classifyUrl(url);
|
|
1180
|
+
const needsUtm = requiresUtm(url);
|
|
1181
|
+
if (!needsUtm) {
|
|
1182
|
+
return {
|
|
1183
|
+
status: "compliant",
|
|
1184
|
+
url,
|
|
1185
|
+
params: params ?? null,
|
|
1186
|
+
errors: []
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
if (!params) {
|
|
1190
|
+
return {
|
|
1191
|
+
status: "blocked",
|
|
1192
|
+
url,
|
|
1193
|
+
params: null,
|
|
1194
|
+
errors: [`URL classified as '${classification}' requires UTM parameters but none provided`]
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
if (!params.source) errors.push("Missing required field: utm_source");
|
|
1198
|
+
if (!params.medium) errors.push("Missing required field: utm_medium");
|
|
1199
|
+
if (!params.campaign) errors.push("Missing required field: utm_campaign");
|
|
1200
|
+
if (params.source && !validateUtmField("source", params.source)) {
|
|
1201
|
+
errors.push(`Invalid utm_source: '${params.source}'. Must be one of: ${UTM_SOURCES.join(", ")}`);
|
|
1202
|
+
}
|
|
1203
|
+
if (params.medium && !validateUtmField("medium", params.medium)) {
|
|
1204
|
+
errors.push(`Invalid utm_medium: '${params.medium}'. Must be one of governed enum values`);
|
|
1205
|
+
}
|
|
1206
|
+
if (params.campaign && !validateUtmField("campaign", params.campaign)) {
|
|
1207
|
+
errors.push(`Invalid utm_campaign: '${params.campaign}'. Must be one of: ${UTM_CAMPAIGNS.join(", ")}`);
|
|
1208
|
+
}
|
|
1209
|
+
if (params.term !== void 0 && params.term && !validateUtmField("term", params.term)) {
|
|
1210
|
+
errors.push(`Invalid utm_term: '${params.term}'. Must be one of: ${UTM_TERMS.join(", ")}`);
|
|
1211
|
+
}
|
|
1212
|
+
if (params.content !== void 0 && params.content && !validateUtmField("content", params.content)) {
|
|
1213
|
+
errors.push(`Invalid utm_content: '${params.content}'. Must be one of: ${UTM_CONTENTS.join(", ")}`);
|
|
1214
|
+
}
|
|
1215
|
+
const allValues = [];
|
|
1216
|
+
if (params.source) allValues.push(params.source);
|
|
1217
|
+
if (params.medium) allValues.push(params.medium);
|
|
1218
|
+
if (params.campaign) allValues.push(params.campaign);
|
|
1219
|
+
if (params.term) allValues.push(params.term);
|
|
1220
|
+
if (params.content) allValues.push(params.content);
|
|
1221
|
+
for (const value of allValues) {
|
|
1222
|
+
if (/\s/.test(value)) errors.push(`Value '${value}' contains spaces`);
|
|
1223
|
+
if (/_/.test(value)) errors.push(`Value '${value}' contains underscores`);
|
|
1224
|
+
if (/-/.test(value)) errors.push(`Value '${value}' contains hyphens`);
|
|
1225
|
+
if (/[^\x20-\x7E]/.test(value)) errors.push(`Value '${value}' contains non-ASCII characters`);
|
|
1226
|
+
if (value === value.toUpperCase() && value.length > 1) errors.push(`Value '${value}' is ALL CAPS`);
|
|
1227
|
+
}
|
|
1228
|
+
const status = errors.length === 0 ? "compliant" : "blocked";
|
|
1229
|
+
return { status, url, params, errors };
|
|
1230
|
+
}
|
|
1231
|
+
function classifyAndEnforce(url, params) {
|
|
1232
|
+
return validateCompliance(url, params);
|
|
1233
|
+
}
|
|
1234
|
+
function buildBlockedError(reason, url) {
|
|
1235
|
+
return {
|
|
1236
|
+
status: "UTM_COMPLIANCE_BLOCKED",
|
|
1237
|
+
reason,
|
|
1238
|
+
requiredFix: reason,
|
|
1239
|
+
correctedExample: url ?? null
|
|
1240
|
+
};
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
// src/web/utm/attribution.ts
|
|
1244
|
+
function parseUtmParams(search) {
|
|
1245
|
+
if (!search) return {};
|
|
1246
|
+
const params = new URLSearchParams(search);
|
|
1247
|
+
const result = {};
|
|
1248
|
+
const source = params.get("utm_source");
|
|
1249
|
+
if (source && UTM_SOURCES.includes(source)) {
|
|
1250
|
+
result.source = source;
|
|
1251
|
+
}
|
|
1252
|
+
const medium = params.get("utm_medium");
|
|
1253
|
+
if (medium) {
|
|
1254
|
+
result.medium = medium;
|
|
1255
|
+
}
|
|
1256
|
+
const campaign = params.get("utm_campaign");
|
|
1257
|
+
if (campaign && UTM_CAMPAIGNS.includes(campaign)) {
|
|
1258
|
+
result.campaign = campaign;
|
|
1259
|
+
}
|
|
1260
|
+
const term = params.get("utm_term");
|
|
1261
|
+
if (term && UTM_TERMS.includes(term)) {
|
|
1262
|
+
result.term = term;
|
|
1263
|
+
}
|
|
1264
|
+
const content = params.get("utm_content");
|
|
1265
|
+
if (content && UTM_CONTENTS.includes(content)) {
|
|
1266
|
+
result.content = content;
|
|
1267
|
+
}
|
|
1268
|
+
return result;
|
|
1269
|
+
}
|
|
1270
|
+
function toFirstTouchAttribution(params) {
|
|
1271
|
+
return {
|
|
1272
|
+
firstTouchSource: params.source,
|
|
1273
|
+
firstTouchMedium: params.medium,
|
|
1274
|
+
firstTouchCampaign: params.campaign,
|
|
1275
|
+
firstTouchSeller: params.term ?? null
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1278
|
+
function requiresSellerAttribution(source) {
|
|
1279
|
+
return UTM_SOURCES_REQUIRING_SELLER.includes(source);
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
// src/web/utm/audit.ts
|
|
1283
|
+
function createAuditEntry(url, params, generatorContext, confidence) {
|
|
1284
|
+
const utmParts = [];
|
|
1285
|
+
if (params) {
|
|
1286
|
+
if (params.source) utmParts.push(`utm_source=${params.source}`);
|
|
1287
|
+
if (params.medium) utmParts.push(`utm_medium=${params.medium}`);
|
|
1288
|
+
if (params.campaign) utmParts.push(`utm_campaign=${params.campaign}`);
|
|
1289
|
+
if (params.term) utmParts.push(`utm_term=${params.term}`);
|
|
1290
|
+
if (params.content) utmParts.push(`utm_content=${params.content}`);
|
|
1291
|
+
}
|
|
1292
|
+
return {
|
|
1293
|
+
url,
|
|
1294
|
+
utmString: utmParts.join("&"),
|
|
1295
|
+
generatorContext,
|
|
1296
|
+
sellerAttribution: params?.term ?? null,
|
|
1297
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1298
|
+
confidence
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
function UtmProvider({ params, children }) {
|
|
1302
|
+
return /* @__PURE__ */ jsxRuntime.jsx(UtmContext.Provider, { value: params, children });
|
|
1303
|
+
}
|
|
1304
|
+
|
|
912
1305
|
exports.AnalyticsProvider = AnalyticsProvider;
|
|
913
1306
|
exports.COOKIE_CONSENT_EVENT = COOKIE_CONSENT_EVENT;
|
|
914
1307
|
exports.COOKIE_CONSENT_KEY = COOKIE_CONSENT_KEY;
|
|
915
1308
|
exports.CookieConsent = CookieConsent;
|
|
916
1309
|
exports.JsonLd = JsonLd;
|
|
1310
|
+
exports.UTM_CAMPAIGNS = UTM_CAMPAIGNS;
|
|
1311
|
+
exports.UTM_CONTENTS = UTM_CONTENTS;
|
|
1312
|
+
exports.UTM_MEDIUMS_ALL = UTM_MEDIUMS_ALL;
|
|
1313
|
+
exports.UTM_MEDIUMS_APP = UTM_MEDIUMS_APP;
|
|
1314
|
+
exports.UTM_MEDIUMS_MESSAGING = UTM_MEDIUMS_MESSAGING;
|
|
1315
|
+
exports.UTM_MEDIUMS_WEB = UTM_MEDIUMS_WEB;
|
|
1316
|
+
exports.UTM_SOURCES = UTM_SOURCES;
|
|
1317
|
+
exports.UTM_SOURCES_REQUIRING_SELLER = UTM_SOURCES_REQUIRING_SELLER;
|
|
1318
|
+
exports.UTM_TERMS = UTM_TERMS;
|
|
1319
|
+
exports.UtmProvider = UtmProvider;
|
|
917
1320
|
exports.aggregateRatingFromTestimonials = aggregateRatingFromTestimonials;
|
|
1321
|
+
exports.buildBlockedError = buildBlockedError;
|
|
918
1322
|
exports.buildPageGraph = buildPageGraph;
|
|
1323
|
+
exports.buildUtmUrl = buildUtmUrl;
|
|
919
1324
|
exports.canonicalUrl = canonicalUrl;
|
|
1325
|
+
exports.classifyAndEnforce = classifyAndEnforce;
|
|
1326
|
+
exports.classifyUrl = classifyUrl;
|
|
920
1327
|
exports.createAnalyticsLoader = createAnalyticsLoader;
|
|
1328
|
+
exports.createAuditEntry = createAuditEntry;
|
|
921
1329
|
exports.createEntityIds = createEntityIds;
|
|
922
1330
|
exports.createSchemaGenerators = createSchemaGenerators;
|
|
1331
|
+
exports.isUtmExempt = isUtmExempt;
|
|
1332
|
+
exports.isValidUtmParams = isValidUtmParams;
|
|
923
1333
|
exports.loadClarity = loadClarity;
|
|
924
1334
|
exports.loadGoogleAnalytics = loadGoogleAnalytics;
|
|
1335
|
+
exports.parseUtmParams = parseUtmParams;
|
|
1336
|
+
exports.requiresSellerAttribution = requiresSellerAttribution;
|
|
1337
|
+
exports.requiresUtm = requiresUtm;
|
|
1338
|
+
exports.toFirstTouchAttribution = toFirstTouchAttribution;
|
|
925
1339
|
exports.useAnalytics = useAnalytics;
|
|
926
1340
|
exports.useCookieConsent = useCookieConsent;
|
|
927
|
-
|
|
1341
|
+
exports.useUtmDefaults = useUtmDefaults;
|
|
1342
|
+
exports.validateCompliance = validateCompliance;
|
|
1343
|
+
exports.validateUtmField = validateUtmField;
|
|
1344
|
+
//# sourceMappingURL=out.js.map
|
|
928
1345
|
//# sourceMappingURL=index.cjs.map
|