@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.
- package/README.md +7 -7
- package/dist/astro/client.cjs +93 -108
- package/dist/astro/client.cjs.map +1 -1
- package/dist/astro/client.d.cts +3 -12
- package/dist/astro/client.d.ts +3 -12
- package/dist/astro/client.js +4 -2
- package/dist/astro/client.js.map +1 -1
- package/dist/astro/content.cjs +106 -98
- package/dist/astro/content.cjs.map +1 -1
- package/dist/astro/content.d.cts +2 -2
- package/dist/astro/content.d.ts +2 -2
- package/dist/astro/content.js +3 -2
- package/dist/astro/integration.cjs +68 -60
- package/dist/astro/integration.cjs.map +1 -1
- package/dist/astro/integration.js +3 -2
- package/dist/astro/integration.js.map +1 -1
- package/dist/astro/middleware.cjs +66 -63
- package/dist/astro/middleware.cjs.map +1 -1
- package/dist/astro/middleware.d.cts +2 -2
- package/dist/astro/middleware.d.ts +2 -2
- package/dist/astro/middleware.js +2 -2
- package/dist/astro/register.cjs +68 -60
- package/dist/astro/register.cjs.map +1 -1
- package/dist/astro/register.js +3 -2
- package/dist/{chunk-UDNKWFBM.js → chunk-3U2BSIYX.js} +5 -3
- package/dist/{chunk-UDNKWFBM.js.map → chunk-3U2BSIYX.js.map} +1 -1
- package/dist/chunk-4OOWA55U.js +215 -0
- package/dist/chunk-4OOWA55U.js.map +1 -0
- package/dist/{chunk-GFCBZN6S.js → chunk-AHRVNEFV.js} +80 -276
- package/dist/chunk-AHRVNEFV.js.map +1 -0
- package/dist/{chunk-ALTSW5DB.js → chunk-DQ6A6HTY.js} +12 -8
- package/dist/chunk-DQ6A6HTY.js.map +1 -0
- package/dist/{chunk-QIWGUF7V.js → chunk-IYFVJ2EY.js} +6 -4
- package/dist/{chunk-QIWGUF7V.js.map → chunk-IYFVJ2EY.js.map} +1 -1
- package/dist/{chunk-NZS4M3V3.js → chunk-TEFKM3GW.js} +2 -2
- package/dist/chunk-TEFKM3GW.js.map +1 -0
- package/dist/create-jmp-analytics-BdGOgPxl.d.ts +70 -0
- package/dist/create-jmp-analytics-DxhHOmtR.d.cts +70 -0
- package/dist/env-public-B6Y0DG68.d.cts +14 -0
- package/dist/env-public-B6Y0DG68.d.ts +14 -0
- package/dist/index.cjs +203 -198
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -340
- package/dist/index.d.ts +16 -340
- package/dist/index.js +9 -5
- package/dist/landing-capture-C8pyZWuF.d.cts +4 -0
- package/dist/landing-capture-C8pyZWuF.d.ts +4 -0
- package/dist/next/content.cjs +106 -98
- package/dist/next/content.cjs.map +1 -1
- package/dist/next/content.d.cts +2 -1
- package/dist/next/content.d.ts +2 -1
- package/dist/next/content.js +3 -2
- package/dist/next/content.js.map +1 -1
- package/dist/next/instrumentation.cjs +68 -60
- package/dist/next/instrumentation.cjs.map +1 -1
- package/dist/next/instrumentation.js +4 -2
- package/dist/next/instrumentation.js.map +1 -1
- package/dist/next/middleware.cjs +66 -63
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.d.cts +2 -2
- package/dist/next/middleware.d.ts +2 -2
- package/dist/next/middleware.js +2 -2
- package/dist/next.cjs +152 -123
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +15 -3
- package/dist/next.d.ts +15 -3
- package/dist/next.js +45 -7
- package/dist/next.js.map +1 -1
- package/dist/react.cjs +115 -118
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -1
- package/dist/react.d.ts +2 -1
- package/dist/react.js +3 -2
- package/dist/site-config-BRuZWGSW.d.cts +46 -0
- package/dist/site-config-hkGMSeT7.d.ts +46 -0
- package/dist/{track-page-view-CoYo96n0.d.cts → track-page-view-BLS0YfL-.d.ts} +1 -1
- package/dist/{track-page-view-DAy0I0Vb.d.ts → track-page-view-DfCyWHqe.d.cts} +1 -1
- package/dist/types-BtiK_Acj.d.cts +224 -0
- package/dist/types-BtiK_Acj.d.ts +224 -0
- package/package.json +2 -4
- package/dist/chunk-ALTSW5DB.js.map +0 -1
- package/dist/chunk-GFCBZN6S.js.map +0 -1
- package/dist/chunk-NZS4M3V3.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,344 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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.
|
|
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
|
-
/**
|
|
84
|
-
declare
|
|
85
|
-
|
|
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
|
-
|
|
375
|
-
|
|
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 {
|
|
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-
|
|
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,
|
package/dist/next/content.cjs
CHANGED
|
@@ -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/
|
|
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
|
-
|
|
109
|
-
|
|
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"],
|