@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.
@@ -0,0 +1,194 @@
1
+ type UtmSource = 'linkedin' | 'whatsapp' | 'intercom' | 'email' | 'website' | 'app' | 'chromeStore' | 'stripe' | 'direct';
2
+ type UtmMediumMessaging = 'dm' | 'group' | 'email' | 'inAppChat' | 'organicPost' | 'paidAd' | 'qrCode' | 'redirect' | 'storeListing';
3
+ type UtmMediumAppPage = 'appHome' | 'appDashboard' | 'appInbox' | 'appContacts' | 'appCampaigns' | 'appSettings' | 'appBilling' | 'appCheckout' | 'appOnboarding' | 'appSupport' | 'appCalendar';
4
+ type UtmMediumWebPage = 'webHome' | 'webDemo' | 'webPricing' | 'webFeatures' | 'webUseCase' | 'webSolution' | 'webIndustry' | 'webIntegrations' | 'webBlog' | 'webBlogPost' | 'webLanding' | 'webComparison' | 'webCaseStudy' | 'webAbout' | 'webContact' | 'webCareers' | 'webLegal' | 'webDocs' | 'webAffiliate';
5
+ type UtmMedium = UtmMediumMessaging | UtmMediumAppPage | UtmMediumWebPage;
6
+ type UtmCampaign = 'discoveryCall' | 'demo' | 'trial' | 'onboarding' | 'upgrade' | 'renewal' | 'retention' | 'accountSupport' | 'supportCall' | 'partnerCall' | 'hiring' | 'interviewCall';
7
+ type UtmTerm = 'julienGadea' | 'bramSmith' | 'florentDupont' | 'sawLin' | 'evaSupport' | 'team' | 'auto';
8
+ type UtmContent = 'ctaPrimary' | 'ctaSecondary' | 'ctaHeader' | 'ctaFooter' | 'ctaInline' | 'buttonPrimary' | 'buttonSecondary' | 'banner' | 'popup' | 'variantA' | 'variantB' | 'variantC';
9
+ /** Core UTM parameter set. source + medium + campaign are always required. */
10
+ interface UtmParams {
11
+ source: UtmSource;
12
+ medium: UtmMedium;
13
+ campaign: UtmCampaign;
14
+ term?: UtmTerm;
15
+ content?: UtmContent;
16
+ }
17
+ /** Partial overrides for UTM params (used when merging context). */
18
+ type UtmOverrides = Partial<UtmParams>;
19
+ /** Sources that require seller attribution (utm_term) for outbound manual sharing. */
20
+ type UtmSourceRequiringSeller = 'linkedin' | 'whatsapp' | 'intercom' | 'email';
21
+ /** CRM first-touch fields. Once set, these must never be overwritten. */
22
+ interface FirstTouchAttribution {
23
+ firstTouchSource: UtmSource;
24
+ firstTouchMedium: UtmMedium;
25
+ firstTouchCampaign: UtmCampaign;
26
+ firstTouchSeller: UtmTerm | null;
27
+ }
28
+ type UrlClassification = 'internal' | 'external' | 'system' | 'asset' | 'protocol' | 'conversion';
29
+ type UtmConfidence = 'valid' | 'corrected' | 'blocked';
30
+ type UtmComplianceStatus = 'compliant' | 'corrected' | 'blocked';
31
+ interface UtmAuditEntry {
32
+ url: string;
33
+ utmString: string;
34
+ generatorContext: string;
35
+ sellerAttribution: string | null;
36
+ timestamp: string;
37
+ confidence: UtmConfidence;
38
+ }
39
+ interface UtmComplianceResult {
40
+ status: UtmComplianceStatus;
41
+ url: string;
42
+ params: Partial<UtmParams> | null;
43
+ errors: string[];
44
+ }
45
+ interface UtmBlockedError {
46
+ status: 'UTM_COMPLIANCE_BLOCKED';
47
+ reason: string;
48
+ requiredFix: string;
49
+ correctedExample: string | null;
50
+ }
51
+
52
+ declare const UTM_SOURCES: readonly UtmSource[];
53
+ declare const UTM_MEDIUMS_MESSAGING: readonly UtmMediumMessaging[];
54
+ declare const UTM_MEDIUMS_APP: readonly UtmMediumAppPage[];
55
+ declare const UTM_MEDIUMS_WEB: readonly UtmMediumWebPage[];
56
+ declare const UTM_MEDIUMS_ALL: readonly UtmMedium[];
57
+ declare const UTM_CAMPAIGNS: readonly UtmCampaign[];
58
+ declare const UTM_TERMS: readonly UtmTerm[];
59
+ declare const UTM_CONTENTS: readonly UtmContent[];
60
+ declare const UTM_SOURCES_REQUIRING_SELLER: readonly UtmSourceRequiringSeller[];
61
+
62
+ /**
63
+ * Build a URL with UTM parameters appended.
64
+ *
65
+ * - Supports both absolute and relative URLs.
66
+ * - Preserves existing query parameters and hash fragments.
67
+ * - Always emits params in canonical order: source → medium → campaign → term → content.
68
+ * - Omits optional params (term, content) when undefined.
69
+ *
70
+ * @example
71
+ * buildUtmUrl('https://app.sales-mind.ai/register', { source: 'linkedin', medium: 'dm', campaign: 'discoveryCall' })
72
+ * // → 'https://app.sales-mind.ai/register?utm_source=linkedin&utm_medium=dm&utm_campaign=discoveryCall'
73
+ *
74
+ * buildUtmUrl('/pricing', { source: 'website', medium: 'webHome', campaign: 'trial' })
75
+ * // → '/pricing?utm_source=website&utm_medium=webHome&utm_campaign=trial'
76
+ */
77
+ declare function buildUtmUrl(baseUrl: string, params: UtmParams): string;
78
+
79
+ /**
80
+ * Validate a single UTM field name + value pair against the governed enums.
81
+ *
82
+ * @param field - The UTM field name (e.g., 'source', 'medium', 'campaign', 'term', 'content')
83
+ * @param value - The value to validate
84
+ * @returns true if the value is in the corresponding enum
85
+ */
86
+ declare function validateUtmField(field: string, value: string): boolean;
87
+ /**
88
+ * Validate a complete or partial UtmParams object.
89
+ *
90
+ * Returns true only if:
91
+ * - source, medium, and campaign are all present
92
+ * - All present values match their respective enums
93
+ * - Optional fields (term, content) match their enums if provided
94
+ */
95
+ declare function isValidUtmParams(params: Partial<UtmParams>): boolean;
96
+ /**
97
+ * Full compliance validation for a URL + UTM params combination.
98
+ *
99
+ * Checks:
100
+ * 1. URL classification (does it require UTMs?)
101
+ * 2. All required params present
102
+ * 3. All values match governed enums
103
+ * 4. No illegal characters (spaces, underscores, hyphens, emojis, ALL CAPS)
104
+ * 5. camelCase format enforcement
105
+ */
106
+ declare function validateCompliance(url: string, params?: Partial<UtmParams> | null): UtmComplianceResult;
107
+ /**
108
+ * Classify a URL and enforce UTM compliance in a single call.
109
+ */
110
+ declare function classifyAndEnforce(url: string, params?: Partial<UtmParams>): UtmComplianceResult;
111
+ /**
112
+ * Build a structured blocked-error response.
113
+ */
114
+ declare function buildBlockedError(reason: string, url?: string): UtmBlockedError;
115
+
116
+ /**
117
+ * Classify a URL to determine its type.
118
+ *
119
+ * Classification order (first match wins):
120
+ * 1. Protocol links (mailto, tel, anchor)
121
+ * 2. Static assets
122
+ * 3. System endpoints (API, webhooks, OAuth)
123
+ * 4. Conversion destinations (Calendly, Stripe, Chrome Store)
124
+ * 5. Internal (*.sales-mind.ai)
125
+ * 6. External (everything else)
126
+ */
127
+ declare function classifyUrl(url: string): UrlClassification;
128
+ /**
129
+ * Determine whether a URL requires UTM parameters.
130
+ *
131
+ * UTMs are mandatory for:
132
+ * - External third-party destinations
133
+ * - Conversion destinations (Calendly, Stripe, Chrome Web Store)
134
+ *
135
+ * UTMs are NOT required for:
136
+ * - Internal navigation
137
+ * - System endpoints
138
+ * - Static assets
139
+ * - Protocol links
140
+ */
141
+ declare function requiresUtm(url: string): boolean;
142
+ /**
143
+ * Check if a URL is explicitly exempt from UTM requirements.
144
+ */
145
+ declare function isUtmExempt(url: string): boolean;
146
+
147
+ /**
148
+ * Parse UTM parameters from a URL search string.
149
+ *
150
+ * Validates each field against governed enums:
151
+ * - source: must be in UTM_SOURCES (invalid → excluded)
152
+ * - medium: accepted as-is (no enum validation — medium is loosely parsed)
153
+ * - campaign: must be in UTM_CAMPAIGNS (invalid → excluded)
154
+ * - term: must be in UTM_TERMS (invalid → excluded)
155
+ * - content: must be in UTM_CONTENTS (invalid → excluded)
156
+ *
157
+ * @param search - URL search string, with or without leading '?'
158
+ * @returns Partial<UtmParams> with only valid fields included
159
+ */
160
+ declare function parseUtmParams(search: string): Partial<UtmParams>;
161
+ /**
162
+ * Map UTM params to CRM first-touch attribution fields.
163
+ *
164
+ * On first lead capture:
165
+ * - utm_source → firstTouchSource
166
+ * - utm_medium → firstTouchMedium
167
+ * - utm_campaign → firstTouchCampaign
168
+ * - utm_term → firstTouchSeller (null if absent)
169
+ *
170
+ * utm_content is intentionally excluded from attribution.
171
+ * These fields must be persisted permanently and never overwritten.
172
+ */
173
+ declare function toFirstTouchAttribution(params: UtmParams): FirstTouchAttribution;
174
+ /**
175
+ * Check if a source requires seller attribution (utm_term).
176
+ *
177
+ * Sources requiring seller: linkedin, whatsapp, intercom, email
178
+ * These are manual outbound channels where individual seller tracking matters.
179
+ */
180
+ declare function requiresSellerAttribution(source: UtmSource): boolean;
181
+
182
+ /**
183
+ * Create a structured audit log entry for a generated/validated link.
184
+ *
185
+ * Every time a link is generated, an audit entry should be logged with:
186
+ * - URL and full UTM string
187
+ * - Generator context (component, agent, or tool that created the link)
188
+ * - Seller attribution (from utm_term)
189
+ * - Timestamp
190
+ * - Confidence flag (valid / corrected / blocked)
191
+ */
192
+ declare function createAuditEntry(url: string, params: Partial<UtmParams> | null, generatorContext: string, confidence: UtmConfidence): UtmAuditEntry;
193
+
194
+ export { buildUtmUrl as A, classifyAndEnforce as B, classifyUrl as C, createAuditEntry as D, isUtmExempt as E, type FirstTouchAttribution as F, isValidUtmParams as G, parseUtmParams as H, requiresSellerAttribution as I, requiresUtm as J, toFirstTouchAttribution as K, validateCompliance as L, validateUtmField as M, type UtmParams as U, UTM_CAMPAIGNS as a, UTM_CONTENTS as b, UTM_MEDIUMS_ALL as c, UTM_MEDIUMS_APP as d, UTM_MEDIUMS_MESSAGING as e, UTM_MEDIUMS_WEB as f, UTM_SOURCES as g, UTM_SOURCES_REQUIRING_SELLER as h, UTM_TERMS as i, type UrlClassification as j, type UtmAuditEntry as k, type UtmBlockedError as l, type UtmCampaign as m, type UtmComplianceResult as n, type UtmComplianceStatus as o, type UtmConfidence as p, type UtmContent as q, type UtmMedium as r, type UtmMediumAppPage as s, type UtmMediumMessaging as t, type UtmMediumWebPage as u, type UtmOverrides as v, type UtmSource as w, type UtmSourceRequiringSeller as x, type UtmTerm as y, buildBlockedError as z };
@@ -0,0 +1,194 @@
1
+ type UtmSource = 'linkedin' | 'whatsapp' | 'intercom' | 'email' | 'website' | 'app' | 'chromeStore' | 'stripe' | 'direct';
2
+ type UtmMediumMessaging = 'dm' | 'group' | 'email' | 'inAppChat' | 'organicPost' | 'paidAd' | 'qrCode' | 'redirect' | 'storeListing';
3
+ type UtmMediumAppPage = 'appHome' | 'appDashboard' | 'appInbox' | 'appContacts' | 'appCampaigns' | 'appSettings' | 'appBilling' | 'appCheckout' | 'appOnboarding' | 'appSupport' | 'appCalendar';
4
+ type UtmMediumWebPage = 'webHome' | 'webDemo' | 'webPricing' | 'webFeatures' | 'webUseCase' | 'webSolution' | 'webIndustry' | 'webIntegrations' | 'webBlog' | 'webBlogPost' | 'webLanding' | 'webComparison' | 'webCaseStudy' | 'webAbout' | 'webContact' | 'webCareers' | 'webLegal' | 'webDocs' | 'webAffiliate';
5
+ type UtmMedium = UtmMediumMessaging | UtmMediumAppPage | UtmMediumWebPage;
6
+ type UtmCampaign = 'discoveryCall' | 'demo' | 'trial' | 'onboarding' | 'upgrade' | 'renewal' | 'retention' | 'accountSupport' | 'supportCall' | 'partnerCall' | 'hiring' | 'interviewCall';
7
+ type UtmTerm = 'julienGadea' | 'bramSmith' | 'florentDupont' | 'sawLin' | 'evaSupport' | 'team' | 'auto';
8
+ type UtmContent = 'ctaPrimary' | 'ctaSecondary' | 'ctaHeader' | 'ctaFooter' | 'ctaInline' | 'buttonPrimary' | 'buttonSecondary' | 'banner' | 'popup' | 'variantA' | 'variantB' | 'variantC';
9
+ /** Core UTM parameter set. source + medium + campaign are always required. */
10
+ interface UtmParams {
11
+ source: UtmSource;
12
+ medium: UtmMedium;
13
+ campaign: UtmCampaign;
14
+ term?: UtmTerm;
15
+ content?: UtmContent;
16
+ }
17
+ /** Partial overrides for UTM params (used when merging context). */
18
+ type UtmOverrides = Partial<UtmParams>;
19
+ /** Sources that require seller attribution (utm_term) for outbound manual sharing. */
20
+ type UtmSourceRequiringSeller = 'linkedin' | 'whatsapp' | 'intercom' | 'email';
21
+ /** CRM first-touch fields. Once set, these must never be overwritten. */
22
+ interface FirstTouchAttribution {
23
+ firstTouchSource: UtmSource;
24
+ firstTouchMedium: UtmMedium;
25
+ firstTouchCampaign: UtmCampaign;
26
+ firstTouchSeller: UtmTerm | null;
27
+ }
28
+ type UrlClassification = 'internal' | 'external' | 'system' | 'asset' | 'protocol' | 'conversion';
29
+ type UtmConfidence = 'valid' | 'corrected' | 'blocked';
30
+ type UtmComplianceStatus = 'compliant' | 'corrected' | 'blocked';
31
+ interface UtmAuditEntry {
32
+ url: string;
33
+ utmString: string;
34
+ generatorContext: string;
35
+ sellerAttribution: string | null;
36
+ timestamp: string;
37
+ confidence: UtmConfidence;
38
+ }
39
+ interface UtmComplianceResult {
40
+ status: UtmComplianceStatus;
41
+ url: string;
42
+ params: Partial<UtmParams> | null;
43
+ errors: string[];
44
+ }
45
+ interface UtmBlockedError {
46
+ status: 'UTM_COMPLIANCE_BLOCKED';
47
+ reason: string;
48
+ requiredFix: string;
49
+ correctedExample: string | null;
50
+ }
51
+
52
+ declare const UTM_SOURCES: readonly UtmSource[];
53
+ declare const UTM_MEDIUMS_MESSAGING: readonly UtmMediumMessaging[];
54
+ declare const UTM_MEDIUMS_APP: readonly UtmMediumAppPage[];
55
+ declare const UTM_MEDIUMS_WEB: readonly UtmMediumWebPage[];
56
+ declare const UTM_MEDIUMS_ALL: readonly UtmMedium[];
57
+ declare const UTM_CAMPAIGNS: readonly UtmCampaign[];
58
+ declare const UTM_TERMS: readonly UtmTerm[];
59
+ declare const UTM_CONTENTS: readonly UtmContent[];
60
+ declare const UTM_SOURCES_REQUIRING_SELLER: readonly UtmSourceRequiringSeller[];
61
+
62
+ /**
63
+ * Build a URL with UTM parameters appended.
64
+ *
65
+ * - Supports both absolute and relative URLs.
66
+ * - Preserves existing query parameters and hash fragments.
67
+ * - Always emits params in canonical order: source → medium → campaign → term → content.
68
+ * - Omits optional params (term, content) when undefined.
69
+ *
70
+ * @example
71
+ * buildUtmUrl('https://app.sales-mind.ai/register', { source: 'linkedin', medium: 'dm', campaign: 'discoveryCall' })
72
+ * // → 'https://app.sales-mind.ai/register?utm_source=linkedin&utm_medium=dm&utm_campaign=discoveryCall'
73
+ *
74
+ * buildUtmUrl('/pricing', { source: 'website', medium: 'webHome', campaign: 'trial' })
75
+ * // → '/pricing?utm_source=website&utm_medium=webHome&utm_campaign=trial'
76
+ */
77
+ declare function buildUtmUrl(baseUrl: string, params: UtmParams): string;
78
+
79
+ /**
80
+ * Validate a single UTM field name + value pair against the governed enums.
81
+ *
82
+ * @param field - The UTM field name (e.g., 'source', 'medium', 'campaign', 'term', 'content')
83
+ * @param value - The value to validate
84
+ * @returns true if the value is in the corresponding enum
85
+ */
86
+ declare function validateUtmField(field: string, value: string): boolean;
87
+ /**
88
+ * Validate a complete or partial UtmParams object.
89
+ *
90
+ * Returns true only if:
91
+ * - source, medium, and campaign are all present
92
+ * - All present values match their respective enums
93
+ * - Optional fields (term, content) match their enums if provided
94
+ */
95
+ declare function isValidUtmParams(params: Partial<UtmParams>): boolean;
96
+ /**
97
+ * Full compliance validation for a URL + UTM params combination.
98
+ *
99
+ * Checks:
100
+ * 1. URL classification (does it require UTMs?)
101
+ * 2. All required params present
102
+ * 3. All values match governed enums
103
+ * 4. No illegal characters (spaces, underscores, hyphens, emojis, ALL CAPS)
104
+ * 5. camelCase format enforcement
105
+ */
106
+ declare function validateCompliance(url: string, params?: Partial<UtmParams> | null): UtmComplianceResult;
107
+ /**
108
+ * Classify a URL and enforce UTM compliance in a single call.
109
+ */
110
+ declare function classifyAndEnforce(url: string, params?: Partial<UtmParams>): UtmComplianceResult;
111
+ /**
112
+ * Build a structured blocked-error response.
113
+ */
114
+ declare function buildBlockedError(reason: string, url?: string): UtmBlockedError;
115
+
116
+ /**
117
+ * Classify a URL to determine its type.
118
+ *
119
+ * Classification order (first match wins):
120
+ * 1. Protocol links (mailto, tel, anchor)
121
+ * 2. Static assets
122
+ * 3. System endpoints (API, webhooks, OAuth)
123
+ * 4. Conversion destinations (Calendly, Stripe, Chrome Store)
124
+ * 5. Internal (*.sales-mind.ai)
125
+ * 6. External (everything else)
126
+ */
127
+ declare function classifyUrl(url: string): UrlClassification;
128
+ /**
129
+ * Determine whether a URL requires UTM parameters.
130
+ *
131
+ * UTMs are mandatory for:
132
+ * - External third-party destinations
133
+ * - Conversion destinations (Calendly, Stripe, Chrome Web Store)
134
+ *
135
+ * UTMs are NOT required for:
136
+ * - Internal navigation
137
+ * - System endpoints
138
+ * - Static assets
139
+ * - Protocol links
140
+ */
141
+ declare function requiresUtm(url: string): boolean;
142
+ /**
143
+ * Check if a URL is explicitly exempt from UTM requirements.
144
+ */
145
+ declare function isUtmExempt(url: string): boolean;
146
+
147
+ /**
148
+ * Parse UTM parameters from a URL search string.
149
+ *
150
+ * Validates each field against governed enums:
151
+ * - source: must be in UTM_SOURCES (invalid → excluded)
152
+ * - medium: accepted as-is (no enum validation — medium is loosely parsed)
153
+ * - campaign: must be in UTM_CAMPAIGNS (invalid → excluded)
154
+ * - term: must be in UTM_TERMS (invalid → excluded)
155
+ * - content: must be in UTM_CONTENTS (invalid → excluded)
156
+ *
157
+ * @param search - URL search string, with or without leading '?'
158
+ * @returns Partial<UtmParams> with only valid fields included
159
+ */
160
+ declare function parseUtmParams(search: string): Partial<UtmParams>;
161
+ /**
162
+ * Map UTM params to CRM first-touch attribution fields.
163
+ *
164
+ * On first lead capture:
165
+ * - utm_source → firstTouchSource
166
+ * - utm_medium → firstTouchMedium
167
+ * - utm_campaign → firstTouchCampaign
168
+ * - utm_term → firstTouchSeller (null if absent)
169
+ *
170
+ * utm_content is intentionally excluded from attribution.
171
+ * These fields must be persisted permanently and never overwritten.
172
+ */
173
+ declare function toFirstTouchAttribution(params: UtmParams): FirstTouchAttribution;
174
+ /**
175
+ * Check if a source requires seller attribution (utm_term).
176
+ *
177
+ * Sources requiring seller: linkedin, whatsapp, intercom, email
178
+ * These are manual outbound channels where individual seller tracking matters.
179
+ */
180
+ declare function requiresSellerAttribution(source: UtmSource): boolean;
181
+
182
+ /**
183
+ * Create a structured audit log entry for a generated/validated link.
184
+ *
185
+ * Every time a link is generated, an audit entry should be logged with:
186
+ * - URL and full UTM string
187
+ * - Generator context (component, agent, or tool that created the link)
188
+ * - Seller attribution (from utm_term)
189
+ * - Timestamp
190
+ * - Confidence flag (valid / corrected / blocked)
191
+ */
192
+ declare function createAuditEntry(url: string, params: Partial<UtmParams> | null, generatorContext: string, confidence: UtmConfidence): UtmAuditEntry;
193
+
194
+ export { buildUtmUrl as A, classifyAndEnforce as B, classifyUrl as C, createAuditEntry as D, isUtmExempt as E, type FirstTouchAttribution as F, isValidUtmParams as G, parseUtmParams as H, requiresSellerAttribution as I, requiresUtm as J, toFirstTouchAttribution as K, validateCompliance as L, validateUtmField as M, type UtmParams as U, UTM_CAMPAIGNS as a, UTM_CONTENTS as b, UTM_MEDIUMS_ALL as c, UTM_MEDIUMS_APP as d, UTM_MEDIUMS_MESSAGING as e, UTM_MEDIUMS_WEB as f, UTM_SOURCES as g, UTM_SOURCES_REQUIRING_SELLER as h, UTM_TERMS as i, type UrlClassification as j, type UtmAuditEntry as k, type UtmBlockedError as l, type UtmCampaign as m, type UtmComplianceResult as n, type UtmComplianceStatus as o, type UtmConfidence as p, type UtmContent as q, type UtmMedium as r, type UtmMediumAppPage as s, type UtmMediumMessaging as t, type UtmMediumWebPage as u, type UtmOverrides as v, type UtmSource as w, type UtmSourceRequiringSeller as x, type UtmTerm as y, buildBlockedError as z };
@@ -4199,5 +4199,5 @@ exports.useNumberFormat = useNumberFormat;
4199
4199
  exports.useRelativeTime = useRelativeTime;
4200
4200
  exports.useTextDirection = useTextDirection;
4201
4201
  exports.useToast = useToast;
4202
- //# sourceMappingURL=index.cjs.map
4202
+ //# sourceMappingURL=out.js.map
4203
4203
  //# sourceMappingURL=index.cjs.map