@jmp-technologies/analytics 0.1.24 → 0.1.26
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 +22 -1
- package/dist/astro/client.cjs +103 -0
- package/dist/astro/client.cjs.map +1 -1
- package/dist/astro/client.d.cts +2 -2
- package/dist/astro/client.d.ts +2 -2
- package/dist/astro/client.js +5 -3
- package/dist/astro/client.js.map +1 -1
- package/dist/astro/content.cjs +185 -1
- 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 +4 -3
- package/dist/astro/integration.cjs +56 -10
- package/dist/astro/integration.cjs.map +1 -1
- package/dist/astro/integration.js +4 -3
- package/dist/astro/integration.js.map +1 -1
- 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 +56 -10
- package/dist/astro/register.cjs.map +1 -1
- package/dist/astro/register.js +4 -3
- package/dist/chunk-2KAGOVRZ.js +45 -0
- package/dist/chunk-2KAGOVRZ.js.map +1 -0
- package/dist/{chunk-MOX7RJUU.js → chunk-A4RRTY5D.js} +1 -1
- package/dist/{chunk-MOX7RJUU.js.map → chunk-A4RRTY5D.js.map} +1 -1
- package/dist/{chunk-7MLPSL6T.js → chunk-HODG4NJQ.js} +2 -2
- package/dist/{chunk-CDORZ2YJ.js → chunk-PKGUBYZR.js} +3 -24
- package/dist/chunk-PKGUBYZR.js.map +1 -0
- package/dist/{chunk-2AUF7ENL.js → chunk-RCOHQAGL.js} +160 -157
- package/dist/chunk-RCOHQAGL.js.map +1 -0
- package/dist/chunk-TCZ6TC2L.js +149 -0
- package/dist/chunk-TCZ6TC2L.js.map +1 -0
- package/dist/{chunk-WCI6VOVY.js → chunk-TFHOTBOL.js} +3 -3
- package/dist/{chunk-ZP4L5DCM.js → chunk-WFTTIRDJ.js} +2 -2
- package/dist/{chunk-GPPQ3TYI.js → chunk-XQZOGWF2.js} +3 -3
- package/dist/chunk-YCVHRMM6.js +28 -0
- package/dist/chunk-YCVHRMM6.js.map +1 -0
- package/dist/{create-jmp-analytics-BdGOgPxl.d.ts → create-jmp-analytics-JKAsJAWb.d.ts} +1 -1
- package/dist/{create-jmp-analytics-DxhHOmtR.d.cts → create-jmp-analytics-Mau-oxji.d.cts} +1 -1
- package/dist/index.cjs +157 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -7
- package/dist/index.d.ts +13 -7
- package/dist/index.js +13 -3
- package/dist/next/content.cjs +185 -1
- package/dist/next/content.cjs.map +1 -1
- package/dist/next/content.d.cts +2 -2
- package/dist/next/content.d.ts +2 -2
- package/dist/next/content.js +4 -3
- package/dist/next/content.js.map +1 -1
- package/dist/next/google-tag.cjs +80 -0
- package/dist/next/google-tag.cjs.map +1 -0
- package/dist/next/google-tag.d.cts +17 -0
- package/dist/next/google-tag.d.ts +17 -0
- package/dist/next/google-tag.js +8 -0
- package/dist/next/google-tag.js.map +1 -0
- package/dist/next/instrumentation.cjs +56 -10
- package/dist/next/instrumentation.cjs.map +1 -1
- package/dist/next/instrumentation.js +3 -2
- package/dist/next/instrumentation.js.map +1 -1
- package/dist/next/landing-capture-script-server.cjs +61 -0
- package/dist/next/landing-capture-script-server.cjs.map +1 -0
- package/dist/next/landing-capture-script-server.d.cts +14 -0
- package/dist/next/landing-capture-script-server.d.ts +14 -0
- package/dist/next/landing-capture-script-server.js +8 -0
- package/dist/next/landing-capture-script-server.js.map +1 -0
- 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/site-root-server.cjs +351 -82
- package/dist/next/site-root-server.cjs.map +1 -1
- package/dist/next/site-root-server.d.cts +9 -1
- package/dist/next/site-root-server.d.ts +9 -1
- package/dist/next/site-root-server.js +51 -16
- package/dist/next/site-root-server.js.map +1 -1
- package/dist/next.cjs +210 -85
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +8 -15
- package/dist/next.d.ts +8 -15
- package/dist/next.js +11 -7
- package/dist/react.cjs +103 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +4 -3
- package/dist/{site-config-DpMgrfeN.d.ts → site-config-CXUdGLqw.d.cts} +6 -3
- package/dist/{site-config-BXs91Yex.d.cts → site-config-w_Db9YSk.d.ts} +6 -3
- package/dist/{track-page-view-Cr8I4Unm.d.cts → track-page-view-CkuSYuco.d.cts} +1 -1
- package/dist/{track-page-view-CcPlzQNB.d.ts → track-page-view-QRSk8vap.d.ts} +1 -1
- package/dist/{types-BtiK_Acj.d.cts → types-C1eq8E5u.d.cts} +14 -4
- package/dist/{types-BtiK_Acj.d.ts → types-C1eq8E5u.d.ts} +14 -4
- package/docs/astro-integration.md +1 -1
- package/package.json +7 -2
- package/dist/chunk-2AUF7ENL.js.map +0 -1
- package/dist/chunk-CDORZ2YJ.js.map +0 -1
- /package/dist/{chunk-7MLPSL6T.js.map → chunk-HODG4NJQ.js.map} +0 -0
- /package/dist/{chunk-WCI6VOVY.js.map → chunk-TFHOTBOL.js.map} +0 -0
- /package/dist/{chunk-ZP4L5DCM.js.map → chunk-WFTTIRDJ.js.map} +0 -0
- /package/dist/{chunk-GPPQ3TYI.js.map → chunk-XQZOGWF2.js.map} +0 -0
|
@@ -34,6 +34,235 @@ __export(site_root_server_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(site_root_server_exports);
|
|
36
36
|
|
|
37
|
+
// src/constants.ts
|
|
38
|
+
var JMP_ANALYTICS_SDK_VERSION = "0.1.25";
|
|
39
|
+
var JMP_TRACKING_CONSENT_STORAGE_KEY = "jmp_analytics_consent_v1";
|
|
40
|
+
var DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS = 2500;
|
|
41
|
+
|
|
42
|
+
// src/http.ts
|
|
43
|
+
function responseLooksLikeHtml(body) {
|
|
44
|
+
const s = body.trimStart();
|
|
45
|
+
return s.startsWith("<!") || s.toLowerCase().startsWith("<html") || s.startsWith("<") && /<html[\s>]/i.test(s.slice(0, 500));
|
|
46
|
+
}
|
|
47
|
+
function normalizeBaseUrl(baseUrl) {
|
|
48
|
+
return baseUrl.replace(/\/$/, "");
|
|
49
|
+
}
|
|
50
|
+
function resolveFetch(fetchImpl, context) {
|
|
51
|
+
const resolved = fetchImpl ?? (typeof globalThis !== "undefined" && globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
52
|
+
if (!resolved) {
|
|
53
|
+
throw new Error(`${context}: fetch is not available; pass fetchImpl in config`);
|
|
54
|
+
}
|
|
55
|
+
return resolved;
|
|
56
|
+
}
|
|
57
|
+
function formatApiErrorMessage(status, text, prefix) {
|
|
58
|
+
if (responseLooksLikeHtml(text)) {
|
|
59
|
+
return `${prefix} HTTP ${status} \u2014 response was HTML (not the JSON API). Check baseUrl points at the JMP Analytics dashboard.`;
|
|
60
|
+
}
|
|
61
|
+
let parsed = {};
|
|
62
|
+
try {
|
|
63
|
+
parsed = JSON.parse(text);
|
|
64
|
+
} catch {
|
|
65
|
+
parsed = { error: text };
|
|
66
|
+
}
|
|
67
|
+
const detail = parsed.error ?? text;
|
|
68
|
+
return [
|
|
69
|
+
`${prefix} HTTP ${status}`,
|
|
70
|
+
parsed.code ? `[${parsed.code}]` : null,
|
|
71
|
+
detail,
|
|
72
|
+
parsed.hint ? `Hint: ${parsed.hint}` : null,
|
|
73
|
+
parsed.expectedDomain ? `Domain in JMP admin: ${parsed.expectedDomain}` : null
|
|
74
|
+
].filter(Boolean).join(" \u2014 ");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/content/fetch.ts
|
|
78
|
+
async function getContent(config, path) {
|
|
79
|
+
const text = await getContentText(config, path);
|
|
80
|
+
try {
|
|
81
|
+
return JSON.parse(text);
|
|
82
|
+
} catch {
|
|
83
|
+
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
84
|
+
const url = `${baseUrl}${path}`;
|
|
85
|
+
throw new Error(`JMP content HTTP 200 \u2014 ${url} returned invalid JSON.`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async function getContentText(config, path) {
|
|
89
|
+
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
90
|
+
const resolvedFetch = config.fetchImpl ?? (typeof globalThis !== "undefined" && globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
91
|
+
if (!resolvedFetch) {
|
|
92
|
+
throw new Error("JMP content: fetch is not available; pass fetchImpl in config");
|
|
93
|
+
}
|
|
94
|
+
const url = `${baseUrl}${path}`;
|
|
95
|
+
if (config.debug) {
|
|
96
|
+
console.debug("[@jmp-technologies/analytics]", "GET", url);
|
|
97
|
+
}
|
|
98
|
+
const res = await resolvedFetch(url, {
|
|
99
|
+
method: "GET",
|
|
100
|
+
headers: {
|
|
101
|
+
"X-JMP-Tracking-Key": config.trackingKey
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
const text = await res.text();
|
|
105
|
+
if (!res.ok) {
|
|
106
|
+
if (responseLooksLikeHtml(text)) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`JMP content HTTP ${res.status} \u2014 ${url} returned HTML (not the JSON API). Set baseUrl to your JMP Analytics dashboard origin.`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
let parsed = {};
|
|
112
|
+
try {
|
|
113
|
+
parsed = JSON.parse(text);
|
|
114
|
+
} catch {
|
|
115
|
+
parsed = { error: text };
|
|
116
|
+
}
|
|
117
|
+
throw new Error(
|
|
118
|
+
[`JMP content HTTP ${res.status}`, parsed.error, parsed.hint].filter(Boolean).join(" \u2014 ")
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
return text;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/content/wrapper-discovery.ts
|
|
125
|
+
var WRAPPER_SLOT_ORDER = [
|
|
126
|
+
"blog",
|
|
127
|
+
"faq",
|
|
128
|
+
"contact",
|
|
129
|
+
"trust",
|
|
130
|
+
"trust.summary",
|
|
131
|
+
"trust.testimonials",
|
|
132
|
+
"trust.reviews",
|
|
133
|
+
"trust.stats",
|
|
134
|
+
"trust.logos",
|
|
135
|
+
"trust.credentials"
|
|
136
|
+
];
|
|
137
|
+
var discovered = /* @__PURE__ */ new Set();
|
|
138
|
+
var syncTimer = null;
|
|
139
|
+
var pendingSyncConfig = null;
|
|
140
|
+
var reportedDedupeKeys = /* @__PURE__ */ new Set();
|
|
141
|
+
var syncHandler = null;
|
|
142
|
+
function markContentWrapper(slot) {
|
|
143
|
+
const normalized = slot.trim().toLowerCase();
|
|
144
|
+
if (!normalized) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
discovered.add(normalized);
|
|
148
|
+
}
|
|
149
|
+
function getDiscoveredContentWrappers() {
|
|
150
|
+
return sortWrapperSlots([...discovered]);
|
|
151
|
+
}
|
|
152
|
+
function resolveContentWrappersForReport(config) {
|
|
153
|
+
const explicit = config.contentWrappers ?? [];
|
|
154
|
+
const auto = getDiscoveredContentWrappers();
|
|
155
|
+
if (config.contentWrapperMode === "manual") {
|
|
156
|
+
return sortWrapperSlots([...explicit]);
|
|
157
|
+
}
|
|
158
|
+
if (config.contentWrapperMode === "explicit-only") {
|
|
159
|
+
return sortWrapperSlots([...explicit]);
|
|
160
|
+
}
|
|
161
|
+
const merged = /* @__PURE__ */ new Set([...explicit, ...auto]);
|
|
162
|
+
return sortWrapperSlots([...merged]);
|
|
163
|
+
}
|
|
164
|
+
function hasReportedContentWrappers(dedupeKey) {
|
|
165
|
+
return reportedDedupeKeys.has(dedupeKey);
|
|
166
|
+
}
|
|
167
|
+
function rememberReportedContentWrappers(dedupeKey) {
|
|
168
|
+
reportedDedupeKeys.add(dedupeKey);
|
|
169
|
+
}
|
|
170
|
+
function setContentWrapperSyncHandler(handler) {
|
|
171
|
+
syncHandler = handler;
|
|
172
|
+
}
|
|
173
|
+
function scheduleContentWrapperSync(config) {
|
|
174
|
+
if (!syncHandler) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
pendingSyncConfig = config;
|
|
178
|
+
if (syncTimer) {
|
|
179
|
+
clearTimeout(syncTimer);
|
|
180
|
+
}
|
|
181
|
+
syncTimer = setTimeout(() => {
|
|
182
|
+
syncTimer = null;
|
|
183
|
+
const cfg = pendingSyncConfig;
|
|
184
|
+
pendingSyncConfig = null;
|
|
185
|
+
if (!cfg || !syncHandler) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
void syncHandler(cfg).catch(() => {
|
|
189
|
+
});
|
|
190
|
+
}, 750);
|
|
191
|
+
}
|
|
192
|
+
function sortWrapperSlots(slots) {
|
|
193
|
+
const order = new Map(WRAPPER_SLOT_ORDER.map((slot, index) => [slot, index]));
|
|
194
|
+
return [...new Set(slots)].sort((a, b) => {
|
|
195
|
+
const ai = order.get(a) ?? 999;
|
|
196
|
+
const bi = order.get(b) ?? 999;
|
|
197
|
+
if (ai !== bi) {
|
|
198
|
+
return ai - bi;
|
|
199
|
+
}
|
|
200
|
+
return a.localeCompare(b);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// src/content/api.ts
|
|
205
|
+
function afterContentWrapperUse(config) {
|
|
206
|
+
scheduleContentWrapperSync(config);
|
|
207
|
+
}
|
|
208
|
+
async function getJmpSiteProfile(config) {
|
|
209
|
+
const data = await getContent(
|
|
210
|
+
config,
|
|
211
|
+
"/api/content/site"
|
|
212
|
+
);
|
|
213
|
+
markContentWrapper("contact");
|
|
214
|
+
afterContentWrapperUse(config);
|
|
215
|
+
return data.site;
|
|
216
|
+
}
|
|
217
|
+
async function registerJmpContentWrappers(config) {
|
|
218
|
+
const wrappers = resolveContentWrappersForReport(config);
|
|
219
|
+
if (!wrappers.length) {
|
|
220
|
+
return { ok: false, skipped: true };
|
|
221
|
+
}
|
|
222
|
+
const dedupeKey = `${config.trackingKey}:${[...wrappers].sort().join(",")}`;
|
|
223
|
+
if (hasReportedContentWrappers(dedupeKey)) {
|
|
224
|
+
return { ok: true, wrappers };
|
|
225
|
+
}
|
|
226
|
+
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
227
|
+
const resolvedFetch = config.fetchImpl ?? (typeof globalThis !== "undefined" && globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
228
|
+
if (!resolvedFetch) {
|
|
229
|
+
throw new Error(
|
|
230
|
+
"JMP content wrappers: fetch is not available; pass fetchImpl in config"
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
const url = `${baseUrl}/api/content/capabilities`;
|
|
234
|
+
if (config.debug) {
|
|
235
|
+
console.debug("[@jmp-technologies/analytics]", "POST", url, { wrappers });
|
|
236
|
+
}
|
|
237
|
+
const res = await resolvedFetch(url, {
|
|
238
|
+
method: "POST",
|
|
239
|
+
headers: {
|
|
240
|
+
"Content-Type": "application/json",
|
|
241
|
+
"X-JMP-Tracking-Key": config.trackingKey
|
|
242
|
+
},
|
|
243
|
+
body: JSON.stringify({
|
|
244
|
+
wrappers,
|
|
245
|
+
sdkVersion: JMP_ANALYTICS_SDK_VERSION
|
|
246
|
+
})
|
|
247
|
+
});
|
|
248
|
+
const text = await res.text();
|
|
249
|
+
if (!res.ok) {
|
|
250
|
+
let parsed = {};
|
|
251
|
+
try {
|
|
252
|
+
parsed = JSON.parse(text);
|
|
253
|
+
} catch {
|
|
254
|
+
parsed = { error: text };
|
|
255
|
+
}
|
|
256
|
+
throw new Error(
|
|
257
|
+
[`JMP content wrappers HTTP ${res.status}`, parsed.error, parsed.hint].filter(Boolean).join(" \u2014 ")
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
rememberReportedContentWrappers(dedupeKey);
|
|
261
|
+
const data = JSON.parse(text);
|
|
262
|
+
return { ok: true, wrappers: data.wrappers ?? wrappers };
|
|
263
|
+
}
|
|
264
|
+
setContentWrapperSyncHandler(registerJmpContentWrappers);
|
|
265
|
+
|
|
37
266
|
// src/env-public.ts
|
|
38
267
|
function firstDefined(...values) {
|
|
39
268
|
for (const v of values) {
|
|
@@ -84,11 +313,22 @@ var registeredSite = null;
|
|
|
84
313
|
function getJmpSiteDefinition() {
|
|
85
314
|
return registeredSite;
|
|
86
315
|
}
|
|
316
|
+
function getJmpContentConfig() {
|
|
317
|
+
const { analyticsUrl, trackingKey } = readJmpPublicEnvFromProcess();
|
|
318
|
+
if (!analyticsUrl || !trackingKey) {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
const site = getJmpSiteDefinition();
|
|
322
|
+
return {
|
|
323
|
+
baseUrl: analyticsUrl,
|
|
324
|
+
trackingKey,
|
|
325
|
+
contentWrappers: site?.contentWrappers ?? void 0
|
|
326
|
+
};
|
|
327
|
+
}
|
|
87
328
|
|
|
88
329
|
// src/next.tsx
|
|
89
|
-
var
|
|
90
|
-
var
|
|
91
|
-
var import_navigation = require("next/navigation");
|
|
330
|
+
var import_react3 = require("react");
|
|
331
|
+
var import_navigation2 = require("next/navigation");
|
|
92
332
|
|
|
93
333
|
// src/landing-capture.ts
|
|
94
334
|
var JMP_SESSION_ID_KEY = "jmp_analytics_sid";
|
|
@@ -232,10 +472,6 @@ function buildLandingCaptureInlineScript() {
|
|
|
232
472
|
return `(function(){try{var h=location.hostname;var ref=document.referrer||'';function rh(u){try{return new URL(u).hostname.replace(/^www\\./i,'').toLowerCase()}catch(e){try{return new URL('https://'+u).hostname.replace(/^www\\./i,'').toLowerCase()}catch(e2){return null}}}function ext(r){var x=rh(r);if(!x)return false;var s=h.replace(/^www\\./i,'').toLowerCase();return x!==s&&x.slice(-('.'+s).length)!==('.'+s)}function apexDom(hn){var s=hn.replace(/^www\\./i,'').toLowerCase();if(!s||s==='localhost'||/\\.local$/i.test(s)||s.indexOf('.')<0)return null;return s}function readCk(hn){var apex=apexDom(hn);if(!apex)return '';var pre='${JMP_LANDING_REFERER_COOKIE}=';var parts=document.cookie.split(';');for(var i=0;i<parts.length;i++){var t=parts[i].trim();if(t.indexOf(pre)===0){try{return decodeURIComponent(t.slice(pre.length)).trim()}catch(e){return ''}}}return ''}function writeCk(r,hn){var apex=apexDom(hn);if(!apex)return;var sec=location.protocol==='https:'?'; Secure':'';document.cookie='${JMP_LANDING_REFERER_COOKIE}='+encodeURIComponent(r.slice(0,2048))+'; Domain=.'+apex+'; Path=/; Max-Age=${cookieMaxAge}; SameSite=Lax'+sec}var stored=sessionStorage.getItem('${JMP_LANDING_REFERER_KEY}')||'';var ck=readCk(h);var preserved=stored||ck;var lr='';if(ref&&ext(ref)){sessionStorage.setItem('${JMP_LANDING_REFERER_KEY}',ref);writeCk(ref,h);lr=ref}else{lr=preserved||'';if(lr&&!stored)sessionStorage.setItem('${JMP_LANDING_REFERER_KEY}',lr)}var sid=sessionStorage.getItem('${JMP_SESSION_ID_KEY}');if(!sid&&crypto&&crypto.randomUUID){sid=crypto.randomUUID();sessionStorage.setItem('${JMP_SESSION_ID_KEY}',sid)}try{var sp=new URLSearchParams(location.search);var utm={};var updated=false;['utm_source','utm_medium','utm_campaign','utm_content','utm_term'].forEach(function(n){var v=sp.get(n);if(v){utm[n]=v;updated=true}});if(updated)sessionStorage.setItem('${JMP_UTM_SESSION_KEY}',JSON.stringify(utm))}catch(e){}}catch(e){}})();`;
|
|
233
473
|
}
|
|
234
474
|
|
|
235
|
-
// src/constants.ts
|
|
236
|
-
var JMP_TRACKING_CONSENT_STORAGE_KEY = "jmp_analytics_consent_v1";
|
|
237
|
-
var DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS = 2500;
|
|
238
|
-
|
|
239
475
|
// src/tracker/page-view-dedupe.ts
|
|
240
476
|
var JMP_PAGE_VIEW_DEDUPE_STORAGE_KEY = "jmp_analytics_last_pv";
|
|
241
477
|
var moduleLastPath = "";
|
|
@@ -433,41 +669,6 @@ function setJmpTrackingConsent(granted) {
|
|
|
433
669
|
}
|
|
434
670
|
}
|
|
435
671
|
|
|
436
|
-
// src/http.ts
|
|
437
|
-
function responseLooksLikeHtml(body) {
|
|
438
|
-
const s = body.trimStart();
|
|
439
|
-
return s.startsWith("<!") || s.toLowerCase().startsWith("<html") || s.startsWith("<") && /<html[\s>]/i.test(s.slice(0, 500));
|
|
440
|
-
}
|
|
441
|
-
function normalizeBaseUrl(baseUrl) {
|
|
442
|
-
return baseUrl.replace(/\/$/, "");
|
|
443
|
-
}
|
|
444
|
-
function resolveFetch(fetchImpl, context) {
|
|
445
|
-
const resolved = fetchImpl ?? (typeof globalThis !== "undefined" && globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
446
|
-
if (!resolved) {
|
|
447
|
-
throw new Error(`${context}: fetch is not available; pass fetchImpl in config`);
|
|
448
|
-
}
|
|
449
|
-
return resolved;
|
|
450
|
-
}
|
|
451
|
-
function formatApiErrorMessage(status, text, prefix) {
|
|
452
|
-
if (responseLooksLikeHtml(text)) {
|
|
453
|
-
return `${prefix} HTTP ${status} \u2014 response was HTML (not the JSON API). Check baseUrl points at the JMP Analytics dashboard.`;
|
|
454
|
-
}
|
|
455
|
-
let parsed = {};
|
|
456
|
-
try {
|
|
457
|
-
parsed = JSON.parse(text);
|
|
458
|
-
} catch {
|
|
459
|
-
parsed = { error: text };
|
|
460
|
-
}
|
|
461
|
-
const detail = parsed.error ?? text;
|
|
462
|
-
return [
|
|
463
|
-
`${prefix} HTTP ${status}`,
|
|
464
|
-
parsed.code ? `[${parsed.code}]` : null,
|
|
465
|
-
detail,
|
|
466
|
-
parsed.hint ? `Hint: ${parsed.hint}` : null,
|
|
467
|
-
parsed.expectedDomain ? `Domain in JMP admin: ${parsed.expectedDomain}` : null
|
|
468
|
-
].filter(Boolean).join(" \u2014 ");
|
|
469
|
-
}
|
|
470
|
-
|
|
471
672
|
// src/tracker/helpers.ts
|
|
472
673
|
function captureAndGetLandingReferer() {
|
|
473
674
|
if (typeof window === "undefined") {
|
|
@@ -875,33 +1076,57 @@ function getOrCreateJmpAnalyticsForNextApp(overrides) {
|
|
|
875
1076
|
var import_react = require("react");
|
|
876
1077
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
877
1078
|
|
|
878
|
-
// src/next.tsx
|
|
1079
|
+
// src/next/google-tag.tsx
|
|
1080
|
+
var import_script = __toESM(require("next/script"), 1);
|
|
1081
|
+
var import_navigation = require("next/navigation");
|
|
1082
|
+
var import_react2 = require("react");
|
|
879
1083
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
880
|
-
function
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
import_script.default,
|
|
888
|
-
{
|
|
889
|
-
id: "jmp-landing-capture",
|
|
890
|
-
strategy: "beforeInteractive",
|
|
891
|
-
dangerouslySetInnerHTML: {
|
|
892
|
-
__html: buildLandingCaptureInlineScript()
|
|
1084
|
+
function JmpGoogleTag({ gaId }) {
|
|
1085
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
1086
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1087
|
+
import_script.default,
|
|
1088
|
+
{
|
|
1089
|
+
src: `https://www.googletagmanager.com/gtag/js?id=${gaId}`,
|
|
1090
|
+
strategy: "lazyOnload"
|
|
893
1091
|
}
|
|
1092
|
+
),
|
|
1093
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "jmp-ga4-init", strategy: "lazyOnload", children: `
|
|
1094
|
+
window.dataLayer = window.dataLayer || [];
|
|
1095
|
+
function gtag(){dataLayer.push(arguments);}
|
|
1096
|
+
gtag('js', new Date());
|
|
1097
|
+
gtag('config', '${gaId}', { send_page_view: true });
|
|
1098
|
+
` }),
|
|
1099
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(JmpGoogleTagPagePath, { gaId })
|
|
1100
|
+
] });
|
|
1101
|
+
}
|
|
1102
|
+
function JmpGoogleTagPagePath({ gaId }) {
|
|
1103
|
+
const pathname = (0, import_navigation.usePathname)();
|
|
1104
|
+
const isFirstNavigation = (0, import_react2.useRef)(true);
|
|
1105
|
+
(0, import_react2.useEffect)(() => {
|
|
1106
|
+
if (isFirstNavigation.current) {
|
|
1107
|
+
isFirstNavigation.current = false;
|
|
1108
|
+
return;
|
|
894
1109
|
}
|
|
895
|
-
|
|
1110
|
+
const report = () => {
|
|
1111
|
+
window.gtag?.("config", gaId, { page_path: pathname || "/" });
|
|
1112
|
+
};
|
|
1113
|
+
report();
|
|
1114
|
+
const timer = window.setTimeout(report, 100);
|
|
1115
|
+
return () => window.clearTimeout(timer);
|
|
1116
|
+
}, [gaId, pathname]);
|
|
1117
|
+
return null;
|
|
896
1118
|
}
|
|
1119
|
+
|
|
1120
|
+
// src/next.tsx
|
|
1121
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
897
1122
|
function JmpNextPageViewTrackerInner({
|
|
898
1123
|
configOverrides
|
|
899
1124
|
}) {
|
|
900
|
-
const pathname = (0,
|
|
901
|
-
const searchParams = (0,
|
|
1125
|
+
const pathname = (0, import_navigation2.usePathname)();
|
|
1126
|
+
const searchParams = (0, import_navigation2.useSearchParams)();
|
|
902
1127
|
const query = searchParams?.toString() ?? "";
|
|
903
1128
|
const path = query ? `${pathname}?${query}` : pathname;
|
|
904
|
-
(0,
|
|
1129
|
+
(0, import_react3.useLayoutEffect)(() => {
|
|
905
1130
|
const client = getOrCreateJmpAnalyticsForNextApp(configOverrides);
|
|
906
1131
|
void client?.trackPageView({ path });
|
|
907
1132
|
}, [path, configOverrides]);
|
|
@@ -910,10 +1135,10 @@ function JmpNextPageViewTrackerInner({
|
|
|
910
1135
|
function JmpNextPageViewTracker({
|
|
911
1136
|
configOverrides
|
|
912
1137
|
}) {
|
|
913
|
-
return /* @__PURE__ */ (0,
|
|
1138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react3.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(JmpNextPageViewTrackerInner, { configOverrides }) });
|
|
914
1139
|
}
|
|
915
1140
|
function useJmpTrackingActive(deferUntilConsent) {
|
|
916
|
-
const consentGranted = (0,
|
|
1141
|
+
const consentGranted = (0, import_react3.useSyncExternalStore)(
|
|
917
1142
|
subscribeJmpTrackingConsent,
|
|
918
1143
|
() => isJmpTrackingConsentGranted(),
|
|
919
1144
|
() => false
|
|
@@ -933,7 +1158,7 @@ function jmpConfigOverridesFromProps(props) {
|
|
|
933
1158
|
function JmpNextAnalyticsBootstrap({
|
|
934
1159
|
configOverrides
|
|
935
1160
|
}) {
|
|
936
|
-
(0,
|
|
1161
|
+
(0, import_react3.useLayoutEffect)(() => {
|
|
937
1162
|
getOrCreateJmpAnalyticsForNextApp(configOverrides);
|
|
938
1163
|
}, [configOverrides]);
|
|
939
1164
|
return null;
|
|
@@ -944,17 +1169,16 @@ function JmpNextAnalytics({
|
|
|
944
1169
|
trackingKey
|
|
945
1170
|
} = {}) {
|
|
946
1171
|
const active = useJmpTrackingActive(deferUntilConsent);
|
|
947
|
-
const configOverrides = (0,
|
|
1172
|
+
const configOverrides = (0, import_react3.useMemo)(
|
|
948
1173
|
() => jmpConfigOverridesFromProps({ analyticsUrl, trackingKey }),
|
|
949
1174
|
[analyticsUrl, trackingKey]
|
|
950
1175
|
);
|
|
951
1176
|
if (!active) {
|
|
952
1177
|
return null;
|
|
953
1178
|
}
|
|
954
|
-
return /* @__PURE__ */ (0,
|
|
955
|
-
/* @__PURE__ */ (0,
|
|
956
|
-
/* @__PURE__ */ (0,
|
|
957
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(JmpNextPageViewTracker, { configOverrides })
|
|
1179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1180
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(JmpNextAnalyticsBootstrap, { configOverrides }),
|
|
1181
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(JmpNextPageViewTracker, { configOverrides })
|
|
958
1182
|
] });
|
|
959
1183
|
}
|
|
960
1184
|
function JmpSiteRoot({
|
|
@@ -963,8 +1187,8 @@ function JmpSiteRoot({
|
|
|
963
1187
|
analyticsUrl,
|
|
964
1188
|
trackingKey
|
|
965
1189
|
}) {
|
|
966
|
-
return /* @__PURE__ */ (0,
|
|
967
|
-
/* @__PURE__ */ (0,
|
|
1190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1191
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
968
1192
|
JmpNextAnalytics,
|
|
969
1193
|
{
|
|
970
1194
|
deferUntilConsent,
|
|
@@ -976,23 +1200,68 @@ function JmpSiteRoot({
|
|
|
976
1200
|
] });
|
|
977
1201
|
}
|
|
978
1202
|
|
|
1203
|
+
// src/next/landing-capture-script-server.tsx
|
|
1204
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1205
|
+
function JmpLandingCaptureScriptServer({
|
|
1206
|
+
trackingKey
|
|
1207
|
+
} = {}) {
|
|
1208
|
+
if (!trackingKey?.trim()) {
|
|
1209
|
+
return null;
|
|
1210
|
+
}
|
|
1211
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1212
|
+
"script",
|
|
1213
|
+
{
|
|
1214
|
+
dangerouslySetInnerHTML: {
|
|
1215
|
+
__html: buildLandingCaptureInlineScript()
|
|
1216
|
+
},
|
|
1217
|
+
id: "jmp-landing-capture",
|
|
1218
|
+
suppressHydrationWarning: true
|
|
1219
|
+
}
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1222
|
+
|
|
979
1223
|
// src/next/site-root-server.tsx
|
|
980
|
-
var
|
|
981
|
-
function
|
|
1224
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1225
|
+
async function resolveGaMeasurementId(gaFromPortal) {
|
|
1226
|
+
const fromEnv = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID?.trim();
|
|
1227
|
+
if (fromEnv) {
|
|
1228
|
+
return fromEnv;
|
|
1229
|
+
}
|
|
1230
|
+
if (!gaFromPortal) {
|
|
1231
|
+
return null;
|
|
1232
|
+
}
|
|
1233
|
+
const config = getJmpContentConfig();
|
|
1234
|
+
if (!config) {
|
|
1235
|
+
return null;
|
|
1236
|
+
}
|
|
1237
|
+
try {
|
|
1238
|
+
const profile = await getJmpSiteProfile(config);
|
|
1239
|
+
return profile.ga_measurement_id?.trim() || null;
|
|
1240
|
+
} catch {
|
|
1241
|
+
return null;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
async function JmpSiteRootServer({
|
|
982
1245
|
children,
|
|
983
|
-
deferUntilConsent
|
|
1246
|
+
deferUntilConsent,
|
|
1247
|
+
gaFromPortal = true
|
|
984
1248
|
}) {
|
|
985
1249
|
const pub = readJmpPublicEnvFromProcess();
|
|
986
1250
|
const site = getJmpSiteDefinition();
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
{
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1251
|
+
const gaId = await resolveGaMeasurementId(gaFromPortal);
|
|
1252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1253
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(JmpLandingCaptureScriptServer, { trackingKey: pub.trackingKey }),
|
|
1254
|
+
gaId ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(JmpGoogleTag, { gaId }) : null,
|
|
1255
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1256
|
+
JmpSiteRoot,
|
|
1257
|
+
{
|
|
1258
|
+
analyticsUrl: pub.analyticsUrl ?? site?.analyticsPortalUrl,
|
|
1259
|
+
trackingKey: pub.trackingKey,
|
|
1260
|
+
deferUntilConsent,
|
|
1261
|
+
children
|
|
1262
|
+
}
|
|
1263
|
+
)
|
|
1264
|
+
] });
|
|
996
1265
|
}
|
|
997
1266
|
// Annotate the CommonJS export names for ESM import in node:
|
|
998
1267
|
0 && (module.exports = {
|