@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/web/index.d.cts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
+
import { U as UtmParams } from '../audit-CiyPkxk1.cjs';
|
|
4
|
+
export { F as FirstTouchAttribution, a as UTM_CAMPAIGNS, b as UTM_CONTENTS, c as UTM_MEDIUMS_ALL, d as UTM_MEDIUMS_APP, e as UTM_MEDIUMS_MESSAGING, f as UTM_MEDIUMS_WEB, g as UTM_SOURCES, h as UTM_SOURCES_REQUIRING_SELLER, i as UTM_TERMS, j as UrlClassification, k as UtmAuditEntry, l as UtmBlockedError, m as UtmCampaign, n as UtmComplianceResult, o as UtmComplianceStatus, p as UtmConfidence, q as UtmContent, r as UtmMedium, s as UtmMediumAppPage, t as UtmMediumMessaging, u as UtmMediumWebPage, v as UtmOverrides, w as UtmSource, x as UtmSourceRequiringSeller, y as UtmTerm, z as buildBlockedError, A as buildUtmUrl, B as classifyAndEnforce, C as classifyUrl, D as createAuditEntry, E as isUtmExempt, G as isValidUtmParams, H as parseUtmParams, I as requiresSellerAttribution, J as requiresUtm, K as toFirstTouchAttribution, L as validateCompliance, M as validateUtmField } from '../audit-CiyPkxk1.cjs';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Schema.org SEO Generator Types
|
|
@@ -407,7 +409,7 @@ declare function createSchemaGenerators(brand: BrandConfig, supportedLanguages?:
|
|
|
407
409
|
inLanguage: string;
|
|
408
410
|
worksFor: {
|
|
409
411
|
name: string;
|
|
410
|
-
'@id'?: string;
|
|
412
|
+
'@id'?: string | undefined;
|
|
411
413
|
} | {
|
|
412
414
|
'@type': string;
|
|
413
415
|
'@id': `${string}/#organization`;
|
|
@@ -887,4 +889,28 @@ declare function AnalyticsProvider({ onTrack, debug, children }: AnalyticsProvid
|
|
|
887
889
|
*/
|
|
888
890
|
declare function useAnalytics(): AnalyticsContextValue;
|
|
889
891
|
|
|
890
|
-
|
|
892
|
+
interface UtmProviderProps {
|
|
893
|
+
/** Default UTM parameters for all descendants. */
|
|
894
|
+
params: UtmParams;
|
|
895
|
+
children: ReactNode;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Provides governed UTM defaults to all `OutboundLink` and UTM-aware
|
|
899
|
+
* components in the subtree.
|
|
900
|
+
*
|
|
901
|
+
* @example
|
|
902
|
+
* ```tsx
|
|
903
|
+
* <UtmProvider params={{ source: 'website', medium: 'webBlogPost', campaign: 'demo' }}>
|
|
904
|
+
* <BlogPostPage />
|
|
905
|
+
* </UtmProvider>
|
|
906
|
+
* ```
|
|
907
|
+
*/
|
|
908
|
+
declare function UtmProvider({ params, children }: UtmProviderProps): react_jsx_runtime.JSX.Element;
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* Read the nearest UtmProvider's default params.
|
|
912
|
+
* Returns `null` when no provider is present (callers should fall back gracefully).
|
|
913
|
+
*/
|
|
914
|
+
declare function useUtmDefaults(): UtmParams | null;
|
|
915
|
+
|
|
916
|
+
export { type AnalyticsContextValue, type AnalyticsEventProps, type AnalyticsLoaderConfig, AnalyticsProvider, type AnalyticsProviderProps, type ArticleMeta, type BrandConfig, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, type CareerForSchema, type ConsentStatus, CookieConsent, type CookieConsentLabels, type CookieConsentProps, type CustomerOrganizationMeta, type FAQItem, type GlossaryTermForSchema, type HowToMeta, type HowToStep, type ItemForList, JsonLd, type JsonLdProps, type PersonMeta, type PricingPlan, type BreadcrumbItem as SeoBreadcrumbItem, type ServiceMotion, type TestimonialForSchema, type TrackFn, type TranscriptForSchema, UtmParams, UtmProvider, type UtmProviderProps, type VideoObjectMeta, aggregateRatingFromTestimonials, buildPageGraph, canonicalUrl, createAnalyticsLoader, createEntityIds, createSchemaGenerators, loadClarity, loadGoogleAnalytics, useAnalytics, useCookieConsent, useUtmDefaults };
|
package/dist/web/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
+
import { U as UtmParams } from '../audit-CiyPkxk1.js';
|
|
4
|
+
export { F as FirstTouchAttribution, a as UTM_CAMPAIGNS, b as UTM_CONTENTS, c as UTM_MEDIUMS_ALL, d as UTM_MEDIUMS_APP, e as UTM_MEDIUMS_MESSAGING, f as UTM_MEDIUMS_WEB, g as UTM_SOURCES, h as UTM_SOURCES_REQUIRING_SELLER, i as UTM_TERMS, j as UrlClassification, k as UtmAuditEntry, l as UtmBlockedError, m as UtmCampaign, n as UtmComplianceResult, o as UtmComplianceStatus, p as UtmConfidence, q as UtmContent, r as UtmMedium, s as UtmMediumAppPage, t as UtmMediumMessaging, u as UtmMediumWebPage, v as UtmOverrides, w as UtmSource, x as UtmSourceRequiringSeller, y as UtmTerm, z as buildBlockedError, A as buildUtmUrl, B as classifyAndEnforce, C as classifyUrl, D as createAuditEntry, E as isUtmExempt, G as isValidUtmParams, H as parseUtmParams, I as requiresSellerAttribution, J as requiresUtm, K as toFirstTouchAttribution, L as validateCompliance, M as validateUtmField } from '../audit-CiyPkxk1.js';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Schema.org SEO Generator Types
|
|
@@ -407,7 +409,7 @@ declare function createSchemaGenerators(brand: BrandConfig, supportedLanguages?:
|
|
|
407
409
|
inLanguage: string;
|
|
408
410
|
worksFor: {
|
|
409
411
|
name: string;
|
|
410
|
-
'@id'?: string;
|
|
412
|
+
'@id'?: string | undefined;
|
|
411
413
|
} | {
|
|
412
414
|
'@type': string;
|
|
413
415
|
'@id': `${string}/#organization`;
|
|
@@ -887,4 +889,28 @@ declare function AnalyticsProvider({ onTrack, debug, children }: AnalyticsProvid
|
|
|
887
889
|
*/
|
|
888
890
|
declare function useAnalytics(): AnalyticsContextValue;
|
|
889
891
|
|
|
890
|
-
|
|
892
|
+
interface UtmProviderProps {
|
|
893
|
+
/** Default UTM parameters for all descendants. */
|
|
894
|
+
params: UtmParams;
|
|
895
|
+
children: ReactNode;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Provides governed UTM defaults to all `OutboundLink` and UTM-aware
|
|
899
|
+
* components in the subtree.
|
|
900
|
+
*
|
|
901
|
+
* @example
|
|
902
|
+
* ```tsx
|
|
903
|
+
* <UtmProvider params={{ source: 'website', medium: 'webBlogPost', campaign: 'demo' }}>
|
|
904
|
+
* <BlogPostPage />
|
|
905
|
+
* </UtmProvider>
|
|
906
|
+
* ```
|
|
907
|
+
*/
|
|
908
|
+
declare function UtmProvider({ params, children }: UtmProviderProps): react_jsx_runtime.JSX.Element;
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* Read the nearest UtmProvider's default params.
|
|
912
|
+
* Returns `null` when no provider is present (callers should fall back gracefully).
|
|
913
|
+
*/
|
|
914
|
+
declare function useUtmDefaults(): UtmParams | null;
|
|
915
|
+
|
|
916
|
+
export { type AnalyticsContextValue, type AnalyticsEventProps, type AnalyticsLoaderConfig, AnalyticsProvider, type AnalyticsProviderProps, type ArticleMeta, type BrandConfig, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, type CareerForSchema, type ConsentStatus, CookieConsent, type CookieConsentLabels, type CookieConsentProps, type CustomerOrganizationMeta, type FAQItem, type GlossaryTermForSchema, type HowToMeta, type HowToStep, type ItemForList, JsonLd, type JsonLdProps, type PersonMeta, type PricingPlan, type BreadcrumbItem as SeoBreadcrumbItem, type ServiceMotion, type TestimonialForSchema, type TrackFn, type TranscriptForSchema, UtmParams, UtmProvider, type UtmProviderProps, type VideoObjectMeta, aggregateRatingFromTestimonials, buildPageGraph, canonicalUrl, createAnalyticsLoader, createEntityIds, createSchemaGenerators, loadClarity, loadGoogleAnalytics, useAnalytics, useCookieConsent, useUtmDefaults };
|
package/dist/web/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import React, { forwardRef, useState, useEffect,
|
|
3
|
+
import React, { createContext, forwardRef, useState, useEffect, useContext, useCallback, useMemo } from 'react';
|
|
3
4
|
import { Slot } from '@radix-ui/react-slot';
|
|
4
5
|
import clsx from 'clsx';
|
|
5
6
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
@@ -649,23 +650,146 @@ var Button = React.forwardRef(
|
|
|
649
650
|
}
|
|
650
651
|
);
|
|
651
652
|
Button.displayName = "Button";
|
|
653
|
+
var UtmContext = createContext(null);
|
|
654
|
+
|
|
655
|
+
// src/web/utm/useUtmDefaults.ts
|
|
656
|
+
function useUtmDefaults() {
|
|
657
|
+
return useContext(UtmContext);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// src/web/utm/builders.ts
|
|
661
|
+
var PLACEHOLDER_ORIGIN = "https://__placeholder__.internal";
|
|
662
|
+
function buildUtmUrl(baseUrl, params) {
|
|
663
|
+
const isRelative = baseUrl.startsWith("/");
|
|
664
|
+
let url;
|
|
665
|
+
try {
|
|
666
|
+
url = isRelative ? new URL(baseUrl, PLACEHOLDER_ORIGIN) : new URL(baseUrl);
|
|
667
|
+
} catch {
|
|
668
|
+
return baseUrl;
|
|
669
|
+
}
|
|
670
|
+
const existingParams = [];
|
|
671
|
+
url.searchParams.forEach((value, key) => {
|
|
672
|
+
existingParams.push([key, value]);
|
|
673
|
+
});
|
|
674
|
+
for (const [key] of existingParams) {
|
|
675
|
+
url.searchParams.delete(key);
|
|
676
|
+
}
|
|
677
|
+
for (const [key, value] of existingParams) {
|
|
678
|
+
if (!key.startsWith("utm_")) {
|
|
679
|
+
url.searchParams.set(key, value);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
url.searchParams.set("utm_source", params.source);
|
|
683
|
+
url.searchParams.set("utm_medium", params.medium);
|
|
684
|
+
url.searchParams.set("utm_campaign", params.campaign);
|
|
685
|
+
if (params.term !== void 0) {
|
|
686
|
+
url.searchParams.set("utm_term", params.term);
|
|
687
|
+
}
|
|
688
|
+
if (params.content !== void 0) {
|
|
689
|
+
url.searchParams.set("utm_content", params.content);
|
|
690
|
+
}
|
|
691
|
+
if (isRelative) {
|
|
692
|
+
return url.href.replace(PLACEHOLDER_ORIGIN, "");
|
|
693
|
+
}
|
|
694
|
+
return url.href;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// src/web/utm/classifiers.ts
|
|
698
|
+
var INTERNAL_PATTERNS = [
|
|
699
|
+
/^\/(?!\/)/,
|
|
700
|
+
// Relative paths
|
|
701
|
+
/^https?:\/\/(www\.)?sales-mind\.ai/i,
|
|
702
|
+
// Marketing site
|
|
703
|
+
/^https?:\/\/app\.sales-mind\.ai/i,
|
|
704
|
+
// Web app
|
|
705
|
+
/^https?:\/\/apps\.sales-mind\.ai/i,
|
|
706
|
+
// Web app (legacy)
|
|
707
|
+
/^https?:\/\/meet\.sales-mind\.ai/i,
|
|
708
|
+
// Booking
|
|
709
|
+
/^https?:\/\/docs\.sales-mind\.ai/i
|
|
710
|
+
// Docs
|
|
711
|
+
];
|
|
712
|
+
var SYSTEM_PATTERNS = [
|
|
713
|
+
/^https?:\/\/.*\/api\//i,
|
|
714
|
+
// API endpoints
|
|
715
|
+
/^https?:\/\/.*\/webhook/i,
|
|
716
|
+
// Webhooks
|
|
717
|
+
/^https?:\/\/.*\/oauth/i,
|
|
718
|
+
// OAuth callbacks
|
|
719
|
+
/^https?:\/\/.*\/callback/i,
|
|
720
|
+
// Callbacks
|
|
721
|
+
/^https?:\/\/.*\.supabase\.(co|com)/i,
|
|
722
|
+
// Supabase
|
|
723
|
+
/^https?:\/\/.*\.firebaseapp\.com/i,
|
|
724
|
+
// Firebase
|
|
725
|
+
/^https?:\/\/.*\.cloudfunctions\.net/i
|
|
726
|
+
// Cloud Functions
|
|
727
|
+
];
|
|
728
|
+
var ASSET_PATTERNS = [
|
|
729
|
+
/\.(css|js|mjs|map|woff2?|ttf|eot|svg|png|jpe?g|gif|webp|avif|ico|pdf)(\?.*)?$/i
|
|
730
|
+
];
|
|
731
|
+
var CONVERSION_PATTERNS = [
|
|
732
|
+
/^https?:\/\/(www\.)?calendly\.com/i,
|
|
733
|
+
/^https?:\/\/(checkout\.)?stripe\.com/i,
|
|
734
|
+
/^https?:\/\/buy\.stripe\.com/i,
|
|
735
|
+
/^https?:\/\/chromewebstore\.google\.com/i,
|
|
736
|
+
/^https?:\/\/meet\.sales-mind\.ai/i
|
|
737
|
+
];
|
|
738
|
+
var PROTOCOL_EXEMPT = [
|
|
739
|
+
/^mailto:/i,
|
|
740
|
+
/^tel:/i,
|
|
741
|
+
/^#/,
|
|
742
|
+
/^javascript:/i
|
|
743
|
+
];
|
|
744
|
+
function classifyUrl(url) {
|
|
745
|
+
if (PROTOCOL_EXEMPT.some((p) => p.test(url))) return "protocol";
|
|
746
|
+
if (ASSET_PATTERNS.some((p) => p.test(url))) return "asset";
|
|
747
|
+
if (SYSTEM_PATTERNS.some((p) => p.test(url))) return "system";
|
|
748
|
+
if (CONVERSION_PATTERNS.some((p) => p.test(url))) return "conversion";
|
|
749
|
+
if (INTERNAL_PATTERNS.some((p) => p.test(url))) return "internal";
|
|
750
|
+
return "external";
|
|
751
|
+
}
|
|
752
|
+
function requiresUtm(url) {
|
|
753
|
+
const classification = classifyUrl(url);
|
|
754
|
+
return classification === "external" || classification === "conversion";
|
|
755
|
+
}
|
|
756
|
+
function isUtmExempt(url) {
|
|
757
|
+
const classification = classifyUrl(url);
|
|
758
|
+
return classification === "protocol" || classification === "asset" || classification === "system" || classification === "internal";
|
|
759
|
+
}
|
|
652
760
|
|
|
653
761
|
// src/components/OutboundLink/outbound-link-utils.ts
|
|
654
|
-
var
|
|
762
|
+
var LEGACY_UTM_SOURCE = "salesmind";
|
|
655
763
|
var EXEMPT_PATTERNS = [
|
|
656
764
|
/^https?:\/\/(www\.)?(stripe\.com|checkout\.stripe\.com|paypal\.com)/i,
|
|
657
765
|
/^https?:\/\/(www\.)?github\.com\/login\/oauth/i
|
|
658
766
|
];
|
|
659
767
|
var isExemptUrl = (urlStr) => {
|
|
660
768
|
if (urlStr.startsWith("mailto:") || urlStr.startsWith("tel:")) return true;
|
|
769
|
+
const classification = classifyUrl(urlStr);
|
|
770
|
+
if (classification === "system" || classification === "protocol" || classification === "asset") {
|
|
771
|
+
return true;
|
|
772
|
+
}
|
|
661
773
|
return EXEMPT_PATTERNS.some((pattern) => pattern.test(urlStr));
|
|
662
774
|
};
|
|
775
|
+
var appendGovernedUTMs = (href, params, preserveExisting = true) => {
|
|
776
|
+
try {
|
|
777
|
+
const url = new URL(href);
|
|
778
|
+
if (preserveExisting) {
|
|
779
|
+
const hasAll = url.searchParams.has("utm_source") && url.searchParams.has("utm_medium") && url.searchParams.has("utm_campaign");
|
|
780
|
+
if (hasAll) return href;
|
|
781
|
+
}
|
|
782
|
+
return buildUtmUrl(href, params);
|
|
783
|
+
} catch {
|
|
784
|
+
return href;
|
|
785
|
+
}
|
|
786
|
+
};
|
|
663
787
|
var appendUTMs = (href, context, pageSlug, options) => {
|
|
664
788
|
try {
|
|
665
789
|
const url = new URL(href);
|
|
666
790
|
const { mediumOverride = "outbound_link", campaignOverride, preserveExisting = true } = options;
|
|
667
791
|
const utms = {
|
|
668
|
-
utm_source:
|
|
792
|
+
utm_source: LEGACY_UTM_SOURCE,
|
|
669
793
|
utm_medium: mediumOverride,
|
|
670
794
|
utm_campaign: campaignOverride || pageSlug,
|
|
671
795
|
utm_content: context
|
|
@@ -692,10 +816,13 @@ var OutboundLink = forwardRef(
|
|
|
692
816
|
preserveExistingUTM = true,
|
|
693
817
|
openInNewTab = true,
|
|
694
818
|
disableTracking = false,
|
|
819
|
+
utmParams,
|
|
695
820
|
onClick,
|
|
696
821
|
children,
|
|
697
822
|
...props
|
|
698
823
|
}, ref) => {
|
|
824
|
+
const contextParams = useUtmDefaults();
|
|
825
|
+
const resolvedUtmParams = utmParams ?? contextParams;
|
|
699
826
|
let hostname = "";
|
|
700
827
|
try {
|
|
701
828
|
const url = new URL(href);
|
|
@@ -720,16 +847,20 @@ var OutboundLink = forwardRef(
|
|
|
720
847
|
}
|
|
721
848
|
const isExempt = isExemptUrl(href) || disableTracking;
|
|
722
849
|
if (isExternal && !isExempt) {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
850
|
+
if (resolvedUtmParams) {
|
|
851
|
+
setFinalHref(appendGovernedUTMs(href, resolvedUtmParams, preserveExistingUTM));
|
|
852
|
+
} else {
|
|
853
|
+
const pageSlug = window.location.pathname.replace(/^\/|\/$/g, "") || "home";
|
|
854
|
+
setFinalHref(appendUTMs(href, context, pageSlug, {
|
|
855
|
+
mediumOverride: currentMedium,
|
|
856
|
+
campaignOverride,
|
|
857
|
+
preserveExisting: preserveExistingUTM
|
|
858
|
+
}));
|
|
859
|
+
}
|
|
729
860
|
} else {
|
|
730
861
|
setFinalHref(href);
|
|
731
862
|
}
|
|
732
|
-
}, [href, context, mediumOverride, campaignOverride, preserveExistingUTM, disableTracking]);
|
|
863
|
+
}, [href, context, mediumOverride, campaignOverride, preserveExistingUTM, disableTracking, resolvedUtmParams]);
|
|
733
864
|
const handleClick = (e) => {
|
|
734
865
|
if (typeof window === "undefined" || disableTracking) {
|
|
735
866
|
onClick?.(e);
|
|
@@ -902,6 +1033,268 @@ function useAnalytics() {
|
|
|
902
1033
|
return useContext(AnalyticsContext) ?? NOOP_VALUE;
|
|
903
1034
|
}
|
|
904
1035
|
|
|
905
|
-
|
|
906
|
-
|
|
1036
|
+
// src/web/utm/constants.ts
|
|
1037
|
+
var UTM_SOURCES = [
|
|
1038
|
+
"linkedin",
|
|
1039
|
+
"whatsapp",
|
|
1040
|
+
"intercom",
|
|
1041
|
+
"email",
|
|
1042
|
+
"website",
|
|
1043
|
+
"app",
|
|
1044
|
+
"chromeStore",
|
|
1045
|
+
"stripe",
|
|
1046
|
+
"direct"
|
|
1047
|
+
];
|
|
1048
|
+
var UTM_MEDIUMS_MESSAGING = [
|
|
1049
|
+
"dm",
|
|
1050
|
+
"group",
|
|
1051
|
+
"email",
|
|
1052
|
+
"inAppChat",
|
|
1053
|
+
"organicPost",
|
|
1054
|
+
"paidAd",
|
|
1055
|
+
"qrCode",
|
|
1056
|
+
"redirect",
|
|
1057
|
+
"storeListing"
|
|
1058
|
+
];
|
|
1059
|
+
var UTM_MEDIUMS_APP = [
|
|
1060
|
+
"appHome",
|
|
1061
|
+
"appDashboard",
|
|
1062
|
+
"appInbox",
|
|
1063
|
+
"appContacts",
|
|
1064
|
+
"appCampaigns",
|
|
1065
|
+
"appSettings",
|
|
1066
|
+
"appBilling",
|
|
1067
|
+
"appCheckout",
|
|
1068
|
+
"appOnboarding",
|
|
1069
|
+
"appSupport",
|
|
1070
|
+
"appCalendar"
|
|
1071
|
+
];
|
|
1072
|
+
var UTM_MEDIUMS_WEB = [
|
|
1073
|
+
"webHome",
|
|
1074
|
+
"webDemo",
|
|
1075
|
+
"webPricing",
|
|
1076
|
+
"webFeatures",
|
|
1077
|
+
"webUseCase",
|
|
1078
|
+
"webSolution",
|
|
1079
|
+
"webIndustry",
|
|
1080
|
+
"webIntegrations",
|
|
1081
|
+
"webBlog",
|
|
1082
|
+
"webBlogPost",
|
|
1083
|
+
"webLanding",
|
|
1084
|
+
"webComparison",
|
|
1085
|
+
"webCaseStudy",
|
|
1086
|
+
"webAbout",
|
|
1087
|
+
"webContact",
|
|
1088
|
+
"webCareers",
|
|
1089
|
+
"webLegal",
|
|
1090
|
+
"webDocs",
|
|
1091
|
+
"webAffiliate"
|
|
1092
|
+
];
|
|
1093
|
+
var UTM_MEDIUMS_ALL = [
|
|
1094
|
+
...UTM_MEDIUMS_MESSAGING,
|
|
1095
|
+
...UTM_MEDIUMS_APP,
|
|
1096
|
+
...UTM_MEDIUMS_WEB
|
|
1097
|
+
];
|
|
1098
|
+
var UTM_CAMPAIGNS = [
|
|
1099
|
+
"discoveryCall",
|
|
1100
|
+
"demo",
|
|
1101
|
+
"trial",
|
|
1102
|
+
"onboarding",
|
|
1103
|
+
"upgrade",
|
|
1104
|
+
"renewal",
|
|
1105
|
+
"retention",
|
|
1106
|
+
"accountSupport",
|
|
1107
|
+
"supportCall",
|
|
1108
|
+
"partnerCall",
|
|
1109
|
+
"hiring",
|
|
1110
|
+
"interviewCall"
|
|
1111
|
+
];
|
|
1112
|
+
var UTM_TERMS = [
|
|
1113
|
+
"julienGadea",
|
|
1114
|
+
"bramSmith",
|
|
1115
|
+
"florentDupont",
|
|
1116
|
+
"sawLin",
|
|
1117
|
+
"evaSupport",
|
|
1118
|
+
"team",
|
|
1119
|
+
"auto"
|
|
1120
|
+
];
|
|
1121
|
+
var UTM_CONTENTS = [
|
|
1122
|
+
"ctaPrimary",
|
|
1123
|
+
"ctaSecondary",
|
|
1124
|
+
"ctaHeader",
|
|
1125
|
+
"ctaFooter",
|
|
1126
|
+
"ctaInline",
|
|
1127
|
+
"buttonPrimary",
|
|
1128
|
+
"buttonSecondary",
|
|
1129
|
+
"banner",
|
|
1130
|
+
"popup",
|
|
1131
|
+
"variantA",
|
|
1132
|
+
"variantB",
|
|
1133
|
+
"variantC"
|
|
1134
|
+
];
|
|
1135
|
+
var UTM_SOURCES_REQUIRING_SELLER = [
|
|
1136
|
+
"linkedin",
|
|
1137
|
+
"whatsapp",
|
|
1138
|
+
"intercom",
|
|
1139
|
+
"email"
|
|
1140
|
+
];
|
|
1141
|
+
|
|
1142
|
+
// src/web/utm/validators.ts
|
|
1143
|
+
function validateUtmField(field, value) {
|
|
1144
|
+
switch (field) {
|
|
1145
|
+
case "source":
|
|
1146
|
+
return UTM_SOURCES.includes(value);
|
|
1147
|
+
case "medium":
|
|
1148
|
+
return UTM_MEDIUMS_ALL.includes(value);
|
|
1149
|
+
case "campaign":
|
|
1150
|
+
return UTM_CAMPAIGNS.includes(value);
|
|
1151
|
+
case "term":
|
|
1152
|
+
return UTM_TERMS.includes(value);
|
|
1153
|
+
case "content":
|
|
1154
|
+
return UTM_CONTENTS.includes(value);
|
|
1155
|
+
default:
|
|
1156
|
+
return false;
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
function isValidUtmParams(params) {
|
|
1160
|
+
if (!params.source || !params.medium || !params.campaign) {
|
|
1161
|
+
return false;
|
|
1162
|
+
}
|
|
1163
|
+
if (!validateUtmField("source", params.source)) return false;
|
|
1164
|
+
if (!validateUtmField("medium", params.medium)) return false;
|
|
1165
|
+
if (!validateUtmField("campaign", params.campaign)) return false;
|
|
1166
|
+
if (params.term !== void 0 && !validateUtmField("term", params.term)) return false;
|
|
1167
|
+
if (params.content !== void 0 && !validateUtmField("content", params.content)) return false;
|
|
1168
|
+
return true;
|
|
1169
|
+
}
|
|
1170
|
+
function validateCompliance(url, params) {
|
|
1171
|
+
const errors = [];
|
|
1172
|
+
const classification = classifyUrl(url);
|
|
1173
|
+
const needsUtm = requiresUtm(url);
|
|
1174
|
+
if (!needsUtm) {
|
|
1175
|
+
return {
|
|
1176
|
+
status: "compliant",
|
|
1177
|
+
url,
|
|
1178
|
+
params: params ?? null,
|
|
1179
|
+
errors: []
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
if (!params) {
|
|
1183
|
+
return {
|
|
1184
|
+
status: "blocked",
|
|
1185
|
+
url,
|
|
1186
|
+
params: null,
|
|
1187
|
+
errors: [`URL classified as '${classification}' requires UTM parameters but none provided`]
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1190
|
+
if (!params.source) errors.push("Missing required field: utm_source");
|
|
1191
|
+
if (!params.medium) errors.push("Missing required field: utm_medium");
|
|
1192
|
+
if (!params.campaign) errors.push("Missing required field: utm_campaign");
|
|
1193
|
+
if (params.source && !validateUtmField("source", params.source)) {
|
|
1194
|
+
errors.push(`Invalid utm_source: '${params.source}'. Must be one of: ${UTM_SOURCES.join(", ")}`);
|
|
1195
|
+
}
|
|
1196
|
+
if (params.medium && !validateUtmField("medium", params.medium)) {
|
|
1197
|
+
errors.push(`Invalid utm_medium: '${params.medium}'. Must be one of governed enum values`);
|
|
1198
|
+
}
|
|
1199
|
+
if (params.campaign && !validateUtmField("campaign", params.campaign)) {
|
|
1200
|
+
errors.push(`Invalid utm_campaign: '${params.campaign}'. Must be one of: ${UTM_CAMPAIGNS.join(", ")}`);
|
|
1201
|
+
}
|
|
1202
|
+
if (params.term !== void 0 && params.term && !validateUtmField("term", params.term)) {
|
|
1203
|
+
errors.push(`Invalid utm_term: '${params.term}'. Must be one of: ${UTM_TERMS.join(", ")}`);
|
|
1204
|
+
}
|
|
1205
|
+
if (params.content !== void 0 && params.content && !validateUtmField("content", params.content)) {
|
|
1206
|
+
errors.push(`Invalid utm_content: '${params.content}'. Must be one of: ${UTM_CONTENTS.join(", ")}`);
|
|
1207
|
+
}
|
|
1208
|
+
const allValues = [];
|
|
1209
|
+
if (params.source) allValues.push(params.source);
|
|
1210
|
+
if (params.medium) allValues.push(params.medium);
|
|
1211
|
+
if (params.campaign) allValues.push(params.campaign);
|
|
1212
|
+
if (params.term) allValues.push(params.term);
|
|
1213
|
+
if (params.content) allValues.push(params.content);
|
|
1214
|
+
for (const value of allValues) {
|
|
1215
|
+
if (/\s/.test(value)) errors.push(`Value '${value}' contains spaces`);
|
|
1216
|
+
if (/_/.test(value)) errors.push(`Value '${value}' contains underscores`);
|
|
1217
|
+
if (/-/.test(value)) errors.push(`Value '${value}' contains hyphens`);
|
|
1218
|
+
if (/[^\x20-\x7E]/.test(value)) errors.push(`Value '${value}' contains non-ASCII characters`);
|
|
1219
|
+
if (value === value.toUpperCase() && value.length > 1) errors.push(`Value '${value}' is ALL CAPS`);
|
|
1220
|
+
}
|
|
1221
|
+
const status = errors.length === 0 ? "compliant" : "blocked";
|
|
1222
|
+
return { status, url, params, errors };
|
|
1223
|
+
}
|
|
1224
|
+
function classifyAndEnforce(url, params) {
|
|
1225
|
+
return validateCompliance(url, params);
|
|
1226
|
+
}
|
|
1227
|
+
function buildBlockedError(reason, url) {
|
|
1228
|
+
return {
|
|
1229
|
+
status: "UTM_COMPLIANCE_BLOCKED",
|
|
1230
|
+
reason,
|
|
1231
|
+
requiredFix: reason,
|
|
1232
|
+
correctedExample: url ?? null
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// src/web/utm/attribution.ts
|
|
1237
|
+
function parseUtmParams(search) {
|
|
1238
|
+
if (!search) return {};
|
|
1239
|
+
const params = new URLSearchParams(search);
|
|
1240
|
+
const result = {};
|
|
1241
|
+
const source = params.get("utm_source");
|
|
1242
|
+
if (source && UTM_SOURCES.includes(source)) {
|
|
1243
|
+
result.source = source;
|
|
1244
|
+
}
|
|
1245
|
+
const medium = params.get("utm_medium");
|
|
1246
|
+
if (medium) {
|
|
1247
|
+
result.medium = medium;
|
|
1248
|
+
}
|
|
1249
|
+
const campaign = params.get("utm_campaign");
|
|
1250
|
+
if (campaign && UTM_CAMPAIGNS.includes(campaign)) {
|
|
1251
|
+
result.campaign = campaign;
|
|
1252
|
+
}
|
|
1253
|
+
const term = params.get("utm_term");
|
|
1254
|
+
if (term && UTM_TERMS.includes(term)) {
|
|
1255
|
+
result.term = term;
|
|
1256
|
+
}
|
|
1257
|
+
const content = params.get("utm_content");
|
|
1258
|
+
if (content && UTM_CONTENTS.includes(content)) {
|
|
1259
|
+
result.content = content;
|
|
1260
|
+
}
|
|
1261
|
+
return result;
|
|
1262
|
+
}
|
|
1263
|
+
function toFirstTouchAttribution(params) {
|
|
1264
|
+
return {
|
|
1265
|
+
firstTouchSource: params.source,
|
|
1266
|
+
firstTouchMedium: params.medium,
|
|
1267
|
+
firstTouchCampaign: params.campaign,
|
|
1268
|
+
firstTouchSeller: params.term ?? null
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1271
|
+
function requiresSellerAttribution(source) {
|
|
1272
|
+
return UTM_SOURCES_REQUIRING_SELLER.includes(source);
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
// src/web/utm/audit.ts
|
|
1276
|
+
function createAuditEntry(url, params, generatorContext, confidence) {
|
|
1277
|
+
const utmParts = [];
|
|
1278
|
+
if (params) {
|
|
1279
|
+
if (params.source) utmParts.push(`utm_source=${params.source}`);
|
|
1280
|
+
if (params.medium) utmParts.push(`utm_medium=${params.medium}`);
|
|
1281
|
+
if (params.campaign) utmParts.push(`utm_campaign=${params.campaign}`);
|
|
1282
|
+
if (params.term) utmParts.push(`utm_term=${params.term}`);
|
|
1283
|
+
if (params.content) utmParts.push(`utm_content=${params.content}`);
|
|
1284
|
+
}
|
|
1285
|
+
return {
|
|
1286
|
+
url,
|
|
1287
|
+
utmString: utmParts.join("&"),
|
|
1288
|
+
generatorContext,
|
|
1289
|
+
sellerAttribution: params?.term ?? null,
|
|
1290
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1291
|
+
confidence
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
function UtmProvider({ params, children }) {
|
|
1295
|
+
return /* @__PURE__ */ jsx(UtmContext.Provider, { value: params, children });
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
export { AnalyticsProvider, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, CookieConsent, JsonLd, UTM_CAMPAIGNS, UTM_CONTENTS, UTM_MEDIUMS_ALL, UTM_MEDIUMS_APP, UTM_MEDIUMS_MESSAGING, UTM_MEDIUMS_WEB, UTM_SOURCES, UTM_SOURCES_REQUIRING_SELLER, UTM_TERMS, UtmProvider, aggregateRatingFromTestimonials, buildBlockedError, buildPageGraph, buildUtmUrl, canonicalUrl, classifyAndEnforce, classifyUrl, createAnalyticsLoader, createAuditEntry, createEntityIds, createSchemaGenerators, isUtmExempt, isValidUtmParams, loadClarity, loadGoogleAnalytics, parseUtmParams, requiresSellerAttribution, requiresUtm, toFirstTouchAttribution, useAnalytics, useCookieConsent, useUtmDefaults, validateCompliance, validateUtmField };
|
|
1299
|
+
//# sourceMappingURL=out.js.map
|
|
907
1300
|
//# sourceMappingURL=index.js.map
|