@jmp-technologies/analytics 0.1.20 → 0.1.22

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.
Files changed (83) hide show
  1. package/README.md +7 -7
  2. package/dist/astro/client.cjs +93 -108
  3. package/dist/astro/client.cjs.map +1 -1
  4. package/dist/astro/client.d.cts +3 -12
  5. package/dist/astro/client.d.ts +3 -12
  6. package/dist/astro/client.js +4 -2
  7. package/dist/astro/client.js.map +1 -1
  8. package/dist/astro/content.cjs +106 -98
  9. package/dist/astro/content.cjs.map +1 -1
  10. package/dist/astro/content.d.cts +2 -2
  11. package/dist/astro/content.d.ts +2 -2
  12. package/dist/astro/content.js +3 -2
  13. package/dist/astro/integration.cjs +68 -60
  14. package/dist/astro/integration.cjs.map +1 -1
  15. package/dist/astro/integration.js +3 -2
  16. package/dist/astro/integration.js.map +1 -1
  17. package/dist/astro/middleware.cjs +66 -63
  18. package/dist/astro/middleware.cjs.map +1 -1
  19. package/dist/astro/middleware.d.cts +2 -2
  20. package/dist/astro/middleware.d.ts +2 -2
  21. package/dist/astro/middleware.js +2 -2
  22. package/dist/astro/register.cjs +68 -60
  23. package/dist/astro/register.cjs.map +1 -1
  24. package/dist/astro/register.js +3 -2
  25. package/dist/{chunk-UDNKWFBM.js → chunk-3U2BSIYX.js} +5 -3
  26. package/dist/{chunk-UDNKWFBM.js.map → chunk-3U2BSIYX.js.map} +1 -1
  27. package/dist/chunk-4OOWA55U.js +215 -0
  28. package/dist/chunk-4OOWA55U.js.map +1 -0
  29. package/dist/{chunk-GFCBZN6S.js → chunk-AHRVNEFV.js} +80 -276
  30. package/dist/chunk-AHRVNEFV.js.map +1 -0
  31. package/dist/{chunk-ALTSW5DB.js → chunk-DQ6A6HTY.js} +12 -8
  32. package/dist/chunk-DQ6A6HTY.js.map +1 -0
  33. package/dist/{chunk-QIWGUF7V.js → chunk-IYFVJ2EY.js} +6 -4
  34. package/dist/{chunk-QIWGUF7V.js.map → chunk-IYFVJ2EY.js.map} +1 -1
  35. package/dist/{chunk-NZS4M3V3.js → chunk-TEFKM3GW.js} +2 -2
  36. package/dist/chunk-TEFKM3GW.js.map +1 -0
  37. package/dist/create-jmp-analytics-BdGOgPxl.d.ts +70 -0
  38. package/dist/create-jmp-analytics-DxhHOmtR.d.cts +70 -0
  39. package/dist/env-public-B6Y0DG68.d.cts +14 -0
  40. package/dist/env-public-B6Y0DG68.d.ts +14 -0
  41. package/dist/index.cjs +203 -198
  42. package/dist/index.cjs.map +1 -1
  43. package/dist/index.d.cts +16 -340
  44. package/dist/index.d.ts +16 -340
  45. package/dist/index.js +9 -5
  46. package/dist/landing-capture-C8pyZWuF.d.cts +4 -0
  47. package/dist/landing-capture-C8pyZWuF.d.ts +4 -0
  48. package/dist/next/content.cjs +106 -98
  49. package/dist/next/content.cjs.map +1 -1
  50. package/dist/next/content.d.cts +2 -1
  51. package/dist/next/content.d.ts +2 -1
  52. package/dist/next/content.js +3 -2
  53. package/dist/next/content.js.map +1 -1
  54. package/dist/next/instrumentation.cjs +68 -60
  55. package/dist/next/instrumentation.cjs.map +1 -1
  56. package/dist/next/instrumentation.js +4 -2
  57. package/dist/next/instrumentation.js.map +1 -1
  58. package/dist/next/middleware.cjs +66 -63
  59. package/dist/next/middleware.cjs.map +1 -1
  60. package/dist/next/middleware.d.cts +2 -2
  61. package/dist/next/middleware.d.ts +2 -2
  62. package/dist/next/middleware.js +2 -2
  63. package/dist/next.cjs +152 -123
  64. package/dist/next.cjs.map +1 -1
  65. package/dist/next.d.cts +15 -3
  66. package/dist/next.d.ts +15 -3
  67. package/dist/next.js +45 -7
  68. package/dist/next.js.map +1 -1
  69. package/dist/react.cjs +115 -118
  70. package/dist/react.cjs.map +1 -1
  71. package/dist/react.d.cts +2 -1
  72. package/dist/react.d.ts +2 -1
  73. package/dist/react.js +3 -2
  74. package/dist/site-config-BRuZWGSW.d.cts +46 -0
  75. package/dist/site-config-hkGMSeT7.d.ts +46 -0
  76. package/dist/{track-page-view-CoYo96n0.d.cts → track-page-view-BLS0YfL-.d.ts} +1 -1
  77. package/dist/{track-page-view-DAy0I0Vb.d.ts → track-page-view-DfCyWHqe.d.cts} +1 -1
  78. package/dist/types-BtiK_Acj.d.cts +224 -0
  79. package/dist/types-BtiK_Acj.d.ts +224 -0
  80. package/package.json +2 -4
  81. package/dist/chunk-ALTSW5DB.js.map +0 -1
  82. package/dist/chunk-GFCBZN6S.js.map +0 -1
  83. package/dist/chunk-NZS4M3V3.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,344 +1,20 @@
1
- /**
2
- * Classify outbound contact links for auto-tracking.
3
- *
4
- * Keep channel set in sync with `lib/ingest/contact-click.ts` on the dashboard side.
5
- *
6
- * Channels detected from `href` alone (no widget / iframe detection):
7
- *
8
- * - `call` — `tel:` (delegates to existing `trackCallClick`)
9
- * - `email` — `mailto:` (delegates to existing `trackEmailClick`)
10
- * - `sms` — `sms:` / `smsto:`
11
- * - `whatsapp` — `wa.me`, `api.whatsapp.com`, `whatsapp.com/send`
12
- * - `maps` — Google Maps, Apple Maps, `maps.app.goo.gl`, `geo:`
13
- * - `booking` — fixed allowlist of common scheduling hosts (see {@link BOOKING_LINK_HOSTS})
14
- *
15
- * `linkHost` returned in `contact_click` results is the hostname only — never the full URL
16
- * (avoids leaking phone numbers in `tel:`/`sms:` URLs and PII-laden booking query strings).
17
- */
18
- type ContactLinkChannel = "sms" | "whatsapp" | "maps" | "booking";
19
- type ClassifiedContactLink = {
20
- kind: "call";
21
- } | {
22
- kind: "email";
23
- } | {
24
- kind: "contact_click";
25
- channel: ContactLinkChannel;
26
- linkHost: string | null;
27
- };
28
- /** v1 booking hosts (~80%+ SMB coverage). Add hosts here when a client uses something rare. */
29
- declare const BOOKING_LINK_HOSTS: readonly ["calendly.com", "cal.com", "acuityscheduling.com", "calendar.google.com", "calendar.app.google", "bookings.microsoft.com", "outlook.office.com", "outlook.office365.com", "book.ms", "setmore.com", "simplybook.me", "oncehub.com", "scheduleonce.com", "youcanbook.me", "savvycal.com", "tidycal.com", "zohobookings.com", "square.site", "squareup.com", "meetings.hubspot.com", "jobber.com", "housecallpro.com", "servicetitan.com", "thryv.com", "honeybook.com", "dubsado.com", "fresha.com", "booksy.com", "vagaro.com", "mindbodyonline.com", "mindbody.io", "janeapp.com", "cliniko.com", "practicebetter.io"];
30
- /** Returns `null` when the link should not be tracked as a contact link. */
31
- declare function classifyContactHref(href: string): ClassifiedContactLink | null;
32
-
33
- /** Inline script for Next.js `beforeInteractive` — capture referrer/UTM only (no network). */
34
- declare function buildLandingCaptureInlineScript(): string;
35
-
36
- /** Per-site values used when the dashboard profile is missing or fields are empty. */
37
- type JmpSiteContactFallback = {
38
- displayName?: string;
39
- founderName?: string;
40
- email?: string;
41
- phone?: string | null;
42
- linkedin?: string | null;
43
- hours?: string | null;
44
- serviceArea?: string | null;
45
- dashboardDemoUrl?: string;
46
- profilePhotoSrc?: string;
47
- privacyUrl?: string;
48
- termsUrl?: string;
49
- };
50
- type JmpSiteDefinition = {
51
- /** Content tabs this site uses — reported via instrumentation capabilities. */
52
- contentWrappers: JmpContentWrapper[];
53
- /**
54
- * Public site origin (no trailing slash), e.g. `https://example.com`.
55
- * Used to resolve relative profile image paths in structured data.
56
- */
57
- siteUrl?: string;
58
- contactFallback?: JmpSiteContactFallback;
59
- /**
60
- * `extras` keys to read from the dashboard site profile (hyphenated keys from admin).
61
- */
62
- contactExtraKeys?: {
63
- founderName?: readonly string[];
64
- dashboardDemoUrl?: readonly string[];
65
- profilePhotoSrc?: readonly string[];
66
- hours?: readonly string[];
67
- serviceArea?: readonly string[];
68
- };
69
- };
70
- /**
71
- * Register site-specific JMP integration options once (typically from `jmp.config.ts`).
72
- * Call at module load time before server content or instrumentation runs.
73
- */
74
- declare function defineJmpSite(definition: JmpSiteDefinition): JmpSiteDefinition;
75
- declare function getJmpSiteDefinition(): JmpSiteDefinition | null;
76
- /** Server content + lead config: env vars + wrappers from {@link defineJmpSite}. */
77
- declare function getJmpContentConfig(): JmpContentConfig | null;
1
+ export { b as buildLandingCaptureInlineScript } from './landing-capture-C8pyZWuF.js';
2
+ import { J as JmpAnalytics } from './create-jmp-analytics-BdGOgPxl.js';
3
+ export { B as BOOKING_LINK_HOSTS, C as ClassifiedContactLink, b as ContactLinkChannel, c as classifyContactHref, d as createJmpAnalytics, i as isJmpTrackingConsentGranted, s as setJmpTrackingConsent, a as subscribeJmpTrackingConsent } from './create-jmp-analytics-BdGOgPxl.js';
4
+ import { f as JmpContentConfig, k as TrackServerPageViewOptions, J as JmpBlogPost, a as JmpFaqItem, b as JmpSiteProfile, d as JmpTrustBundle, h as JmpAnalyticsConfig } from './types-BtiK_Acj.js';
5
+ export { e as JmpContentWrapper, l as JmpCredential, i as JmpEventType, m as JmpPartnerLogo, g as JmpServerRequestLike, c as JmpTestimonial, n as JmpTrustStat, o as JmpTrustSummary, L as LeadMetadata, p as LeadMetadataValue, j as TrackLeadOptions, T as TrackPageViewOptions } from './types-BtiK_Acj.js';
6
+ export { J as JmpPublicEnv, r as readJmpPublicEnvFromProcess } from './env-public-B6Y0DG68.js';
7
+ export { J as JmpSiteContactFallback, a as JmpSiteDefinition, d as defineJmpSite, g as getJmpContentConfig, b as getJmpSiteDefinition } from './site-config-hkGMSeT7.js';
78
8
 
79
9
  /** Published package version — sent with capabilities for admin readiness. */
80
- declare const JMP_ANALYTICS_SDK_VERSION = "0.1.20";
10
+ declare const JMP_ANALYTICS_SDK_VERSION = "0.1.21";
81
11
  /** `localStorage` key when {@link JmpAnalyticsConfig.requireConsent} is enabled. */
82
12
  declare const JMP_TRACKING_CONSENT_STORAGE_KEY = "jmp_analytics_consent_v1";
83
- /** Whether analytics events may be sent (after CMP / cookie banner). */
84
- declare function isJmpTrackingConsentGranted(): boolean;
85
- /** Subscribe to consent changes (for React `useSyncExternalStore`). */
86
- declare function subscribeJmpTrackingConsent(listener: () => void): () => void;
87
- /**
88
- * Grant or deny analytics. Persists in `localStorage` when `requireConsent` is used.
89
- * Call from your cookie banner before tracking runs.
90
- */
91
- declare function setJmpTrackingConsent(granted: boolean): void;
92
- type JmpEventType = "page_view" | "form_submit" | "call_click" | "email_click" | "contact_click";
93
- type JmpAnalyticsConfig = {
94
- /** Dashboard origin, e.g. https://analytics.example.com (no trailing slash) */
95
- baseUrl: string;
96
- /** Per-website key from JMP admin */
97
- trackingKey: string;
98
- /** Log requests to console */
99
- debug?: boolean;
100
- /** Override fetch (tests, React Native) */
101
- fetchImpl?: typeof fetch;
102
- /**
103
- * Suppress duplicate `page_view` for the same path within this window (ms).
104
- * Helps with React Strict Mode double-mount; typical: 500–1000.
105
- */
106
- pageViewDedupeMs?: number;
107
- /**
108
- * When true, no events are sent until {@link setJmpTrackingConsent}(true).
109
- * Pair with your cookie banner; see `NEXT_PUBLIC_JMP_ANALYTICS_REQUIRE_CONSENT`.
110
- */
111
- requireConsent?: boolean;
112
- /**
113
- * When true, register a single delegated `click` listener that classifies links
114
- * (SMS, WhatsApp, maps, scheduling) and records them via {@link trackContactClick}.
115
- *
116
- * Off by default — pair with privacy disclosure / consent before enabling.
117
- * `tel:` / `mailto:` continue to use {@link trackCallClick} / {@link trackEmailClick}.
118
- *
119
- * Opt out per-link with `data-jmp-no-track` on an `<a>` (or an ancestor).
120
- */
121
- autoTrackContactLinks?: boolean;
122
- };
123
- type JmpContentConfig = Pick<JmpAnalyticsConfig, "baseUrl" | "trackingKey" | "debug" | "fetchImpl"> & {
124
- /**
125
- * Content wrappers wired in this site's template (blog, faq, trust.*, contact).
126
- * Reported via POST /api/content/capabilities so unused dashboard tabs stay hidden.
127
- * Call {@link registerJmpContentWrappers} at startup / deploy.
128
- */
129
- contentWrappers?: JmpContentWrapper[];
130
- };
131
- /** Top-level and trust sub-wrappers the client can declare. */
132
- type JmpContentWrapper = "blog" | "faq" | "contact" | "trust" | "trust.summary" | "trust.testimonials" | "trust.reviews" | "trust.stats" | "trust.logos" | "trust.credentials";
133
- type JmpBlogPost = {
134
- id: string;
135
- title: string;
136
- slug: string;
137
- excerpt: string | null;
138
- body: string;
139
- seo_title: string | null;
140
- meta_description: string | null;
141
- featured_image_url: string | null;
142
- published_at: string | null;
143
- updated_at: string;
144
- };
145
- type JmpFaqItem = {
146
- id: string;
147
- slug: string;
148
- question: string;
149
- answer: string;
150
- category?: string | null;
151
- sort_order: number;
152
- updated_at: string;
153
- };
154
- type JmpTrustSummary = {
155
- google_rating: number | null;
156
- google_review_count: number | null;
157
- google_reviews_url: string | null;
158
- yelp_url: string | null;
159
- trustpilot_url: string | null;
160
- disclaimer: string | null;
161
- };
162
- type JmpTestimonial = {
163
- id: string;
164
- slug: string;
165
- body: string;
166
- author_name: string;
167
- author_descriptor: string | null;
168
- location: string | null;
169
- /** 1–10 (half-star steps on a 5-star scale; 10 = 5.0 stars). */
170
- rating: number | null;
171
- image_url: string | null;
172
- video_url: string | null;
173
- /** Optional topic or service line (e.g. roofing). */
174
- category: string | null;
175
- /** Site section key — filter like FAQ `category` (e.g. testimonials, reviews). */
176
- placement: string | null;
177
- source: string | null;
178
- /** Optional link to the original review on Google, Yelp, etc. */
179
- source_url: string | null;
180
- featured: boolean;
181
- sort_order: number;
182
- updated_at: string;
183
- };
184
- type JmpTrustStat = {
185
- id: string;
186
- slug: string;
187
- label: string;
188
- value: string;
189
- sort_order: number;
190
- updated_at: string;
191
- };
192
- type JmpPartnerLogo = {
193
- id: string;
194
- slug: string;
195
- name: string;
196
- image_url: string | null;
197
- link_url: string | null;
198
- sort_order: number;
199
- updated_at: string;
200
- };
201
- type JmpCredential = {
202
- id: string;
203
- slug: string;
204
- title: string;
205
- issuer: string | null;
206
- year: string | null;
207
- image_url: string | null;
208
- category: string | null;
209
- sort_order: number;
210
- updated_at: string;
211
- };
212
- type JmpTrustBundle = {
213
- summary: JmpTrustSummary;
214
- testimonials: JmpTestimonial[];
215
- stats: JmpTrustStat[];
216
- logos: JmpPartnerLogo[];
217
- credentials: JmpCredential[];
218
- };
219
- type JmpSiteProfile = {
220
- name: string;
221
- display_name: string | null;
222
- email: string | null;
223
- phone: string | null;
224
- address: string | null;
225
- hours: string | null;
226
- service_area: string | null;
227
- google_maps_url: string | null;
228
- social: {
229
- linkedin: string | null;
230
- instagram: string | null;
231
- facebook: string | null;
232
- x: string | null;
233
- youtube: string | null;
234
- };
235
- cta: {
236
- label: string | null;
237
- url: string | null;
238
- };
239
- legal: {
240
- privacy_policy_url: string | null;
241
- terms_url: string | null;
242
- };
243
- /** Developer-defined keys; values filled by the client. */
244
- extras: Record<string, string | null>;
245
- };
246
- type TrackPageViewOptions = {
247
- path?: string;
248
- source?: string;
249
- device?: string;
250
- country?: string;
251
- metadata?: Record<string, unknown>;
252
- };
253
- type TrackLeadOptions = {
254
- /** Path where the lead was submitted, e.g. /contact */
255
- path?: string;
256
- name?: string;
257
- email?: string;
258
- phone?: string;
259
- company?: string;
260
- website?: string;
261
- subject?: string;
262
- message?: string;
263
- /**
264
- * Optional flexible metadata for dynamic lead forms.
265
- * Prefer the normalized envelope (formId/formVersion/answers/derived/attribution),
266
- * but unknown keys are also accepted by the API.
267
- */
268
- metadata?: LeadMetadata;
269
- /**
270
- * Optional session id (from createJmpAnalytics internal session) if your app wants to pass it explicitly.
271
- * Most callers should omit this.
272
- */
273
- sessionId?: string;
274
- };
275
- type LeadMetadataValue = string | number | boolean | null | undefined | LeadMetadataValue[] | {
276
- [key: string]: LeadMetadataValue;
277
- };
278
- type LeadMetadata = {
279
- formId?: string;
280
- formVersion?: string;
281
- leadKind?: string;
282
- answers?: Record<string, LeadMetadataValue>;
283
- derived?: Record<string, LeadMetadataValue>;
284
- attribution?: {
285
- utm_source?: string;
286
- utm_medium?: string;
287
- utm_campaign?: string;
288
- utm_content?: string;
289
- utm_term?: string;
290
- gclid?: string;
291
- fbclid?: string;
292
- msclkid?: string;
293
- ttclid?: string;
294
- [key: string]: LeadMetadataValue | undefined;
295
- };
296
- tags?: string[];
297
- [key: string]: LeadMetadataValue | undefined;
298
- };
299
- type JmpServerRequestLike = {
300
- url?: string;
301
- headers: Pick<Headers, "get"> | Record<string, string | string[] | undefined | null>;
302
- };
303
- type TrackServerPageViewOptions = {
304
- request?: JmpServerRequestLike;
305
- /** Overrides request URL path. Use pathname + search when possible. */
306
- path?: string;
307
- /** Original visitor user agent. Useful when not passing `request`. */
308
- userAgent?: string | null;
309
- /** Original visitor referrer. Useful when not passing `request`. */
310
- referer?: string | null;
311
- metadata?: Record<string, unknown>;
312
- sessionId?: string;
313
- };
314
- /**
315
- * Create a tracker instance. Safe to call once per app and reuse.
316
- */
317
- declare function createJmpAnalytics(config: JmpAnalyticsConfig): {
318
- track: (type: JmpEventType, payload: {
319
- path: string;
320
- metadata?: Record<string, unknown>;
321
- source?: string;
322
- device?: string;
323
- country?: string;
324
- }) => Promise<void>;
325
- trackPageView: (options?: TrackPageViewOptions) => Promise<void>;
326
- trackFormSubmit: (path: string, metadata?: Record<string, unknown>) => Promise<void>;
327
- trackCallClick: (path: string, metadata?: Record<string, unknown>) => Promise<void>;
328
- trackEmailClick: (path: string, metadata?: Record<string, unknown>) => Promise<void>;
329
- trackContactClick: (path: string, options: {
330
- channel: ContactLinkChannel;
331
- linkHost?: string | null;
332
- metadata?: Record<string, unknown>;
333
- }) => Promise<void>;
334
- trackLead: (options?: TrackLeadOptions) => Promise<void>;
335
- subscribeToSpaNavigation: () => () => void;
336
- subscribeContactLinkAutoTrack: () => () => void;
337
- setTrackingConsent: typeof setJmpTrackingConsent;
338
- isTrackingConsentGranted: typeof isJmpTrackingConsentGranted;
339
- };
340
- type JmpAnalytics = ReturnType<typeof createJmpAnalytics>;
13
+ /** Default `pageViewDedupeMs` when resolving browser config from env (Strict Mode / SPA). */
14
+ declare const DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS = 800;
15
+
341
16
  declare function trackJmpServerPageView(config: JmpContentConfig, options?: TrackServerPageViewOptions): Promise<void>;
17
+
342
18
  declare function getJmpBlogPosts(config: JmpContentConfig): Promise<JmpBlogPost[]>;
343
19
  declare function getJmpBlogPost(config: JmpContentConfig, slug: string): Promise<JmpBlogPost | null>;
344
20
  declare function getJmpFaqs(config: JmpContentConfig): Promise<JmpFaqItem[]>;
@@ -356,6 +32,7 @@ declare function registerJmpContentWrappers(config: JmpContentConfig): Promise<{
356
32
  ok: false;
357
33
  skipped: true;
358
34
  }>;
35
+
359
36
  declare function createJmpContentClient(config: JmpContentConfig): {
360
37
  getBlogPosts: () => Promise<JmpBlogPost[]>;
361
38
  getBlogPost: (slug: string) => Promise<JmpBlogPost | null>;
@@ -371,8 +48,8 @@ declare function createJmpContentClient(config: JmpContentConfig): {
371
48
  skipped: true;
372
49
  }>;
373
50
  };
374
- /** Default `pageViewDedupeMs` when resolving browser config from env (Strict Mode / SPA). */
375
- declare const DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS = 800;
51
+ type JmpContentClient = ReturnType<typeof createJmpContentClient>;
52
+
376
53
  /**
377
54
  * Browser / client bundle: reads `NEXT_PUBLIC_*` or Astro `PUBLIC_*` vars.
378
55
  * Use for `createJmpAnalytics` on the client. Returns `null` if incomplete.
@@ -392,10 +69,9 @@ declare function isJmpServerContentEnvConfigured(): boolean;
392
69
  * Returns `null` on the server or when public env vars are missing.
393
70
  */
394
71
  declare function getOrCreateJmpAnalyticsFromBrowserEnv(overrides?: Partial<JmpAnalyticsConfig>): JmpAnalytics | null;
395
- type JmpContentClient = ReturnType<typeof createJmpContentClient>;
396
72
  /**
397
73
  * `createJmpContentClient` using server env resolution. Returns `null` if env is incomplete.
398
74
  */
399
75
  declare function createJmpContentClientFromServerEnv(overrides?: Partial<JmpContentConfig>): JmpContentClient | null;
400
76
 
401
- export { BOOKING_LINK_HOSTS, type ClassifiedContactLink, type ContactLinkChannel, DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS, JMP_ANALYTICS_SDK_VERSION, JMP_TRACKING_CONSENT_STORAGE_KEY, type JmpAnalytics, type JmpAnalyticsConfig, type JmpBlogPost, type JmpContentClient, type JmpContentConfig, type JmpContentWrapper, type JmpCredential, type JmpEventType, type JmpFaqItem, type JmpPartnerLogo, type JmpServerRequestLike, type JmpSiteContactFallback, type JmpSiteDefinition, type JmpSiteProfile, type JmpTestimonial, type JmpTrustBundle, type JmpTrustStat, type JmpTrustSummary, type LeadMetadata, type LeadMetadataValue, type TrackLeadOptions, type TrackPageViewOptions, type TrackServerPageViewOptions, buildLandingCaptureInlineScript, classifyContactHref, createJmpAnalytics, createJmpContentClient, createJmpContentClientFromServerEnv, defineJmpSite, getJmpBlogPost, getJmpBlogPosts, getJmpBrowserAnalyticsConfigFromEnv, getJmpContentConfig, getJmpFaqs, getJmpRobotsTxt, getJmpServerContentConfigFromEnv, getJmpSiteDefinition, getJmpSiteProfile, getJmpTrustBundle, getOrCreateJmpAnalyticsFromBrowserEnv, isJmpBrowserAnalyticsEnvConfigured, isJmpServerContentEnvConfigured, isJmpTrackingConsentGranted, registerJmpContentWrappers, setJmpTrackingConsent, subscribeJmpTrackingConsent, trackJmpServerPageView };
77
+ export { DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS, JMP_ANALYTICS_SDK_VERSION, JMP_TRACKING_CONSENT_STORAGE_KEY, JmpAnalytics, JmpAnalyticsConfig, JmpBlogPost, type JmpContentClient, JmpContentConfig, JmpFaqItem, JmpSiteProfile, JmpTrustBundle, TrackServerPageViewOptions, createJmpContentClient, createJmpContentClientFromServerEnv, getJmpBlogPost, getJmpBlogPosts, getJmpBrowserAnalyticsConfigFromEnv, getJmpFaqs, getJmpRobotsTxt, getJmpServerContentConfigFromEnv, getJmpSiteProfile, getJmpTrustBundle, getOrCreateJmpAnalyticsFromBrowserEnv, isJmpBrowserAnalyticsEnvConfigured, isJmpServerContentEnvConfigured, registerJmpContentWrappers, trackJmpServerPageView };
package/dist/index.js CHANGED
@@ -8,15 +8,12 @@ import {
8
8
  createJmpAnalytics,
9
9
  createJmpContentClient,
10
10
  createJmpContentClientFromServerEnv,
11
- defineJmpSite,
12
11
  getJmpBlogPost,
13
12
  getJmpBlogPosts,
14
13
  getJmpBrowserAnalyticsConfigFromEnv,
15
- getJmpContentConfig,
16
14
  getJmpFaqs,
17
15
  getJmpRobotsTxt,
18
16
  getJmpServerContentConfigFromEnv,
19
- getJmpSiteDefinition,
20
17
  getJmpSiteProfile,
21
18
  getJmpTrustBundle,
22
19
  getOrCreateJmpAnalyticsFromBrowserEnv,
@@ -25,9 +22,15 @@ import {
25
22
  isJmpTrackingConsentGranted,
26
23
  registerJmpContentWrappers,
27
24
  setJmpTrackingConsent,
28
- subscribeJmpTrackingConsent,
25
+ subscribeJmpTrackingConsent
26
+ } from "./chunk-AHRVNEFV.js";
27
+ import {
28
+ defineJmpSite,
29
+ getJmpContentConfig,
30
+ getJmpSiteDefinition,
31
+ readJmpPublicEnvFromProcess,
29
32
  trackJmpServerPageView
30
- } from "./chunk-GFCBZN6S.js";
33
+ } from "./chunk-4OOWA55U.js";
31
34
  export {
32
35
  BOOKING_LINK_HOSTS,
33
36
  DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS,
@@ -53,6 +56,7 @@ export {
53
56
  isJmpBrowserAnalyticsEnvConfigured,
54
57
  isJmpServerContentEnvConfigured,
55
58
  isJmpTrackingConsentGranted,
59
+ readJmpPublicEnvFromProcess,
56
60
  registerJmpContentWrappers,
57
61
  setJmpTrackingConsent,
58
62
  subscribeJmpTrackingConsent,
@@ -0,0 +1,4 @@
1
+ /** Inline script for Next.js `beforeInteractive` — capture referrer/UTM only (no network). */
2
+ declare function buildLandingCaptureInlineScript(): string;
3
+
4
+ export { buildLandingCaptureInlineScript as b };
@@ -0,0 +1,4 @@
1
+ /** Inline script for Next.js `beforeInteractive` — capture referrer/UTM only (no network). */
2
+ declare function buildLandingCaptureInlineScript(): string;
3
+
4
+ export { buildLandingCaptureInlineScript as b };
@@ -38,66 +38,7 @@ var import_react = require("react");
38
38
  // src/landing-capture.ts
39
39
  var LANDING_REFERER_COOKIE_MAX_AGE_SEC = 30 * 60;
40
40
 
41
- // src/env-public.ts
42
- function readProcessEnv(name) {
43
- if (typeof process === "undefined" || !process.env) return void 0;
44
- const v = process.env[name];
45
- return typeof v === "string" && v.length > 0 ? v : void 0;
46
- }
47
- function firstDefined(...values) {
48
- for (const v of values) {
49
- if (v) return v;
50
- }
51
- return void 0;
52
- }
53
- function readJmpPublicEnvFromProcess(overrides) {
54
- const analyticsUrl = firstDefined(
55
- overrides?.analyticsUrl,
56
- readProcessEnv("NEXT_PUBLIC_JMP_ANALYTICS_URL"),
57
- readProcessEnv("PUBLIC_JMP_ANALYTICS_URL")
58
- );
59
- const trackingKey = firstDefined(
60
- overrides?.trackingKey,
61
- readProcessEnv("NEXT_PUBLIC_JMP_TRACKING_KEY"),
62
- readProcessEnv("PUBLIC_JMP_TRACKING_KEY")
63
- );
64
- const requireConsentRaw = firstDefined(
65
- overrides?.requireConsent !== void 0 ? String(overrides.requireConsent) : void 0,
66
- readProcessEnv("NEXT_PUBLIC_JMP_ANALYTICS_REQUIRE_CONSENT"),
67
- readProcessEnv("PUBLIC_JMP_ANALYTICS_REQUIRE_CONSENT")
68
- );
69
- const autoContactRaw = firstDefined(
70
- overrides?.autoContactLinks !== void 0 ? String(overrides.autoContactLinks) : void 0,
71
- readProcessEnv("NEXT_PUBLIC_JMP_AUTO_CONTACT_LINKS"),
72
- readProcessEnv("PUBLIC_JMP_AUTO_CONTACT_LINKS")
73
- );
74
- return {
75
- analyticsUrl,
76
- trackingKey,
77
- requireConsent: requireConsentRaw === "true",
78
- autoContactLinks: autoContactRaw === "true"
79
- };
80
- }
81
-
82
- // src/site-config.ts
83
- var registeredSite = null;
84
- function getJmpSiteDefinition() {
85
- return registeredSite;
86
- }
87
- function getJmpContentConfig() {
88
- const { analyticsUrl, trackingKey } = readJmpPublicEnvFromProcess();
89
- if (!analyticsUrl || !trackingKey) {
90
- return null;
91
- }
92
- const site = getJmpSiteDefinition();
93
- return {
94
- baseUrl: analyticsUrl,
95
- trackingKey,
96
- contentWrappers: site?.contentWrappers ?? void 0
97
- };
98
- }
99
-
100
- // src/index.ts
41
+ // src/http.ts
101
42
  function responseLooksLikeHtml(body) {
102
43
  const s = body.trimStart();
103
44
  return s.startsWith("<!") || s.toLowerCase().startsWith("<html") || s.startsWith("<") && /<html[\s>]/i.test(s.slice(0, 500));
@@ -105,44 +46,8 @@ function responseLooksLikeHtml(body) {
105
46
  function normalizeBaseUrl(baseUrl) {
106
47
  return baseUrl.replace(/\/$/, "");
107
48
  }
108
- async function getJmpBlogPosts(config) {
109
- const data = await getContent(
110
- config,
111
- "/api/content/blog"
112
- );
113
- return data.posts;
114
- }
115
- async function getJmpBlogPost(config, slug) {
116
- try {
117
- const data = await getContent(
118
- config,
119
- `/api/content/blog/${encodeURIComponent(slug)}`
120
- );
121
- return data.post;
122
- } catch (error) {
123
- if (error instanceof Error && error.message.includes("HTTP 404")) {
124
- return null;
125
- }
126
- throw error;
127
- }
128
- }
129
- async function getJmpFaqs(config) {
130
- const data = await getContent(
131
- config,
132
- "/api/content/faqs"
133
- );
134
- return data.faqs;
135
- }
136
- async function getJmpTrustBundle(config) {
137
- return getContent(config, "/api/content/trust");
138
- }
139
- async function getJmpSiteProfile(config) {
140
- const data = await getContent(
141
- config,
142
- "/api/content/site"
143
- );
144
- return data.site;
145
- }
49
+
50
+ // src/content/fetch.ts
146
51
  async function getContent(config, path) {
147
52
  const text = await getContentText(config, path);
148
53
  try {
@@ -189,6 +94,109 @@ async function getContentText(config, path) {
189
94
  return text;
190
95
  }
191
96
 
97
+ // src/content/api.ts
98
+ async function getJmpBlogPosts(config) {
99
+ const data = await getContent(
100
+ config,
101
+ "/api/content/blog"
102
+ );
103
+ return data.posts;
104
+ }
105
+ async function getJmpBlogPost(config, slug) {
106
+ try {
107
+ const data = await getContent(
108
+ config,
109
+ `/api/content/blog/${encodeURIComponent(slug)}`
110
+ );
111
+ return data.post;
112
+ } catch (error) {
113
+ if (error instanceof Error && error.message.includes("HTTP 404")) {
114
+ return null;
115
+ }
116
+ throw error;
117
+ }
118
+ }
119
+ async function getJmpFaqs(config) {
120
+ const data = await getContent(
121
+ config,
122
+ "/api/content/faqs"
123
+ );
124
+ return data.faqs;
125
+ }
126
+ async function getJmpTrustBundle(config) {
127
+ return getContent(config, "/api/content/trust");
128
+ }
129
+ async function getJmpSiteProfile(config) {
130
+ const data = await getContent(
131
+ config,
132
+ "/api/content/site"
133
+ );
134
+ return data.site;
135
+ }
136
+
137
+ // src/env-public.ts
138
+ function firstDefined(...values) {
139
+ for (const v of values) {
140
+ if (v) return v;
141
+ }
142
+ return void 0;
143
+ }
144
+ function readJmpPublicEnvFromProcessEnv() {
145
+ if (typeof process === "undefined" || !process.env) {
146
+ return {};
147
+ }
148
+ const { env } = process;
149
+ const analyticsUrl = firstDefined(
150
+ env.NEXT_PUBLIC_JMP_ANALYTICS_URL,
151
+ env.PUBLIC_JMP_ANALYTICS_URL
152
+ );
153
+ const trackingKey = firstDefined(
154
+ env.NEXT_PUBLIC_JMP_TRACKING_KEY,
155
+ env.PUBLIC_JMP_TRACKING_KEY
156
+ );
157
+ const requireConsentRaw = firstDefined(
158
+ env.NEXT_PUBLIC_JMP_ANALYTICS_REQUIRE_CONSENT,
159
+ env.PUBLIC_JMP_ANALYTICS_REQUIRE_CONSENT
160
+ );
161
+ const autoContactRaw = firstDefined(
162
+ env.NEXT_PUBLIC_JMP_AUTO_CONTACT_LINKS,
163
+ env.PUBLIC_JMP_AUTO_CONTACT_LINKS
164
+ );
165
+ return {
166
+ analyticsUrl,
167
+ trackingKey,
168
+ requireConsent: requireConsentRaw === "true",
169
+ autoContactLinks: autoContactRaw === "true"
170
+ };
171
+ }
172
+ function readJmpPublicEnvFromProcess(overrides) {
173
+ const fromEnv = readJmpPublicEnvFromProcessEnv();
174
+ return {
175
+ analyticsUrl: firstDefined(overrides?.analyticsUrl, fromEnv.analyticsUrl),
176
+ trackingKey: firstDefined(overrides?.trackingKey, fromEnv.trackingKey),
177
+ requireConsent: overrides?.requireConsent ?? fromEnv.requireConsent,
178
+ autoContactLinks: overrides?.autoContactLinks ?? fromEnv.autoContactLinks
179
+ };
180
+ }
181
+
182
+ // src/site-config.ts
183
+ var registeredSite = null;
184
+ function getJmpSiteDefinition() {
185
+ return registeredSite;
186
+ }
187
+ function getJmpContentConfig() {
188
+ const { analyticsUrl, trackingKey } = readJmpPublicEnvFromProcess();
189
+ if (!analyticsUrl || !trackingKey) {
190
+ return null;
191
+ }
192
+ const site = getJmpSiteDefinition();
193
+ return {
194
+ baseUrl: analyticsUrl,
195
+ trackingKey,
196
+ contentWrappers: site?.contentWrappers ?? void 0
197
+ };
198
+ }
199
+
192
200
  // src/content/site-content.ts
193
201
  var DEFAULT_EXTRA_KEYS = {
194
202
  founderName: ["founder-name", "founder_name"],