@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.cjs
CHANGED
|
@@ -44,6 +44,7 @@ __export(index_exports, {
|
|
|
44
44
|
isJmpBrowserAnalyticsEnvConfigured: () => isJmpBrowserAnalyticsEnvConfigured,
|
|
45
45
|
isJmpServerContentEnvConfigured: () => isJmpServerContentEnvConfigured,
|
|
46
46
|
isJmpTrackingConsentGranted: () => isJmpTrackingConsentGranted,
|
|
47
|
+
readJmpPublicEnvFromProcess: () => readJmpPublicEnvFromProcess,
|
|
47
48
|
registerJmpContentWrappers: () => registerJmpContentWrappers,
|
|
48
49
|
setJmpTrackingConsent: () => setJmpTrackingConsent,
|
|
49
50
|
subscribeJmpTrackingConsent: () => subscribeJmpTrackingConsent,
|
|
@@ -312,72 +313,12 @@ function classifyContactHref(href) {
|
|
|
312
313
|
return null;
|
|
313
314
|
}
|
|
314
315
|
|
|
315
|
-
// src/
|
|
316
|
-
|
|
317
|
-
if (typeof process === "undefined" || !process.env) return void 0;
|
|
318
|
-
const v = process.env[name];
|
|
319
|
-
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
320
|
-
}
|
|
321
|
-
function firstDefined(...values) {
|
|
322
|
-
for (const v of values) {
|
|
323
|
-
if (v) return v;
|
|
324
|
-
}
|
|
325
|
-
return void 0;
|
|
326
|
-
}
|
|
327
|
-
function readJmpPublicEnvFromProcess(overrides) {
|
|
328
|
-
const analyticsUrl = firstDefined(
|
|
329
|
-
overrides?.analyticsUrl,
|
|
330
|
-
readProcessEnv("NEXT_PUBLIC_JMP_ANALYTICS_URL"),
|
|
331
|
-
readProcessEnv("PUBLIC_JMP_ANALYTICS_URL")
|
|
332
|
-
);
|
|
333
|
-
const trackingKey = firstDefined(
|
|
334
|
-
overrides?.trackingKey,
|
|
335
|
-
readProcessEnv("NEXT_PUBLIC_JMP_TRACKING_KEY"),
|
|
336
|
-
readProcessEnv("PUBLIC_JMP_TRACKING_KEY")
|
|
337
|
-
);
|
|
338
|
-
const requireConsentRaw = firstDefined(
|
|
339
|
-
overrides?.requireConsent !== void 0 ? String(overrides.requireConsent) : void 0,
|
|
340
|
-
readProcessEnv("NEXT_PUBLIC_JMP_ANALYTICS_REQUIRE_CONSENT"),
|
|
341
|
-
readProcessEnv("PUBLIC_JMP_ANALYTICS_REQUIRE_CONSENT")
|
|
342
|
-
);
|
|
343
|
-
const autoContactRaw = firstDefined(
|
|
344
|
-
overrides?.autoContactLinks !== void 0 ? String(overrides.autoContactLinks) : void 0,
|
|
345
|
-
readProcessEnv("NEXT_PUBLIC_JMP_AUTO_CONTACT_LINKS"),
|
|
346
|
-
readProcessEnv("PUBLIC_JMP_AUTO_CONTACT_LINKS")
|
|
347
|
-
);
|
|
348
|
-
return {
|
|
349
|
-
analyticsUrl,
|
|
350
|
-
trackingKey,
|
|
351
|
-
requireConsent: requireConsentRaw === "true",
|
|
352
|
-
autoContactLinks: autoContactRaw === "true"
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// src/site-config.ts
|
|
357
|
-
var registeredSite = null;
|
|
358
|
-
function defineJmpSite(definition) {
|
|
359
|
-
registeredSite = definition;
|
|
360
|
-
return definition;
|
|
361
|
-
}
|
|
362
|
-
function getJmpSiteDefinition() {
|
|
363
|
-
return registeredSite;
|
|
364
|
-
}
|
|
365
|
-
function getJmpContentConfig() {
|
|
366
|
-
const { analyticsUrl, trackingKey } = readJmpPublicEnvFromProcess();
|
|
367
|
-
if (!analyticsUrl || !trackingKey) {
|
|
368
|
-
return null;
|
|
369
|
-
}
|
|
370
|
-
const site = getJmpSiteDefinition();
|
|
371
|
-
return {
|
|
372
|
-
baseUrl: analyticsUrl,
|
|
373
|
-
trackingKey,
|
|
374
|
-
contentWrappers: site?.contentWrappers ?? void 0
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// src/index.ts
|
|
379
|
-
var JMP_ANALYTICS_SDK_VERSION = "0.1.20";
|
|
316
|
+
// src/constants.ts
|
|
317
|
+
var JMP_ANALYTICS_SDK_VERSION = "0.1.21";
|
|
380
318
|
var JMP_TRACKING_CONSENT_STORAGE_KEY = "jmp_analytics_consent_v1";
|
|
319
|
+
var DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS = 800;
|
|
320
|
+
|
|
321
|
+
// src/consent.ts
|
|
381
322
|
var moduleTrackingConsentGranted = true;
|
|
382
323
|
var trackingConsentListeners = /* @__PURE__ */ new Set();
|
|
383
324
|
function readStoredTrackingConsent() {
|
|
@@ -390,6 +331,9 @@ function readStoredTrackingConsent() {
|
|
|
390
331
|
return false;
|
|
391
332
|
}
|
|
392
333
|
}
|
|
334
|
+
function initJmpTrackingConsent(requireConsent) {
|
|
335
|
+
moduleTrackingConsentGranted = requireConsent ? readStoredTrackingConsent() : true;
|
|
336
|
+
}
|
|
393
337
|
function isJmpTrackingConsentGranted() {
|
|
394
338
|
return moduleTrackingConsentGranted;
|
|
395
339
|
}
|
|
@@ -420,33 +364,8 @@ function setJmpTrackingConsent(granted) {
|
|
|
420
364
|
listener();
|
|
421
365
|
}
|
|
422
366
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
return null;
|
|
426
|
-
}
|
|
427
|
-
return captureLandingAttribution(window.location.hostname).landingReferer;
|
|
428
|
-
}
|
|
429
|
-
function mergeSessionUtms(metadata) {
|
|
430
|
-
if (typeof window === "undefined") {
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
|
-
const { utm } = captureLandingAttribution(window.location.hostname);
|
|
434
|
-
for (const key of JMP_UTM_PARAM_KEYS) {
|
|
435
|
-
if (metadata[key] === void 0 && utm[key]) {
|
|
436
|
-
metadata[key] = utm[key];
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
function splitPathAndSearch(pathInput) {
|
|
441
|
-
const qIndex = pathInput.indexOf("?");
|
|
442
|
-
if (qIndex === -1) {
|
|
443
|
-
return { pathname: pathInput || "/", search: "" };
|
|
444
|
-
}
|
|
445
|
-
return {
|
|
446
|
-
pathname: pathInput.slice(0, qIndex) || "/",
|
|
447
|
-
search: pathInput.slice(qIndex + 1)
|
|
448
|
-
};
|
|
449
|
-
}
|
|
367
|
+
|
|
368
|
+
// src/http.ts
|
|
450
369
|
function responseLooksLikeHtml(body) {
|
|
451
370
|
const s = body.trimStart();
|
|
452
371
|
return s.startsWith("<!") || s.toLowerCase().startsWith("<html") || s.startsWith("<") && /<html[\s>]/i.test(s.slice(0, 500));
|
|
@@ -479,24 +398,75 @@ function pathFromRequestUrl(url) {
|
|
|
479
398
|
return url.startsWith("/") ? url : "/";
|
|
480
399
|
}
|
|
481
400
|
}
|
|
401
|
+
function resolveFetch(fetchImpl, context) {
|
|
402
|
+
const resolved = fetchImpl ?? (typeof globalThis !== "undefined" && globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
403
|
+
if (!resolved) {
|
|
404
|
+
throw new Error(`${context}: fetch is not available; pass fetchImpl in config`);
|
|
405
|
+
}
|
|
406
|
+
return resolved;
|
|
407
|
+
}
|
|
408
|
+
function formatApiErrorMessage(status, text, prefix) {
|
|
409
|
+
if (responseLooksLikeHtml(text)) {
|
|
410
|
+
return `${prefix} HTTP ${status} \u2014 response was HTML (not the JSON API). Check baseUrl points at the JMP Analytics dashboard.`;
|
|
411
|
+
}
|
|
412
|
+
let parsed = {};
|
|
413
|
+
try {
|
|
414
|
+
parsed = JSON.parse(text);
|
|
415
|
+
} catch {
|
|
416
|
+
parsed = { error: text };
|
|
417
|
+
}
|
|
418
|
+
const detail = parsed.error ?? text;
|
|
419
|
+
return [
|
|
420
|
+
`${prefix} HTTP ${status}`,
|
|
421
|
+
parsed.code ? `[${parsed.code}]` : null,
|
|
422
|
+
detail,
|
|
423
|
+
parsed.hint ? `Hint: ${parsed.hint}` : null,
|
|
424
|
+
parsed.expectedDomain ? `Domain in JMP admin: ${parsed.expectedDomain}` : null
|
|
425
|
+
].filter(Boolean).join(" \u2014 ");
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// src/tracker/helpers.ts
|
|
429
|
+
function captureAndGetLandingReferer() {
|
|
430
|
+
if (typeof window === "undefined") {
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
return captureLandingAttribution(window.location.hostname).landingReferer;
|
|
434
|
+
}
|
|
435
|
+
function mergeSessionUtms(metadata) {
|
|
436
|
+
if (typeof window === "undefined") {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
const { utm } = captureLandingAttribution(window.location.hostname);
|
|
440
|
+
for (const key of JMP_UTM_PARAM_KEYS) {
|
|
441
|
+
if (metadata[key] === void 0 && utm[key]) {
|
|
442
|
+
metadata[key] = utm[key];
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
function splitPathAndSearch(pathInput) {
|
|
447
|
+
const qIndex = pathInput.indexOf("?");
|
|
448
|
+
if (qIndex === -1) {
|
|
449
|
+
return { pathname: pathInput || "/", search: "" };
|
|
450
|
+
}
|
|
451
|
+
return {
|
|
452
|
+
pathname: pathInput.slice(0, qIndex) || "/",
|
|
453
|
+
search: pathInput.slice(qIndex + 1)
|
|
454
|
+
};
|
|
455
|
+
}
|
|
482
456
|
function inferDevice() {
|
|
483
457
|
if (typeof window === "undefined") {
|
|
484
458
|
return "unknown";
|
|
485
459
|
}
|
|
486
460
|
return window.innerWidth < 768 ? "mobile" : "desktop";
|
|
487
461
|
}
|
|
462
|
+
|
|
463
|
+
// src/tracker/create-jmp-analytics.ts
|
|
488
464
|
function createJmpAnalytics(config) {
|
|
489
465
|
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
490
|
-
const
|
|
491
|
-
|
|
492
|
-
throw new Error(
|
|
493
|
-
"createJmpAnalytics: fetch is not available; pass fetchImpl in config"
|
|
494
|
-
);
|
|
495
|
-
}
|
|
496
|
-
const fetchFn = resolvedFetch;
|
|
497
|
-
moduleTrackingConsentGranted = config.requireConsent ? readStoredTrackingConsent() : true;
|
|
466
|
+
const fetchFn = resolveFetch(config.fetchImpl, "createJmpAnalytics");
|
|
467
|
+
initJmpTrackingConsent(config.requireConsent);
|
|
498
468
|
function canSend() {
|
|
499
|
-
return
|
|
469
|
+
return isJmpTrackingConsentGranted();
|
|
500
470
|
}
|
|
501
471
|
let lastDedupePath = "";
|
|
502
472
|
let lastDedupeAt = 0;
|
|
@@ -528,32 +498,9 @@ function createJmpAnalytics(config) {
|
|
|
528
498
|
});
|
|
529
499
|
if (!res.ok) {
|
|
530
500
|
const text = await res.text();
|
|
531
|
-
|
|
532
|
-
throw new Error(
|
|
533
|
-
`JMP Analytics HTTP ${res.status} \u2014 ${url} returned HTML (not the JSON API). Set baseUrl / NEXT_PUBLIC_JMP_ANALYTICS_URL to your JMP Analytics dashboard origin (the deployment that includes POST /api/events), not a marketing or client site unless that codebase ships the same API route.`
|
|
534
|
-
);
|
|
535
|
-
}
|
|
536
|
-
let parsed = {};
|
|
537
|
-
try {
|
|
538
|
-
parsed = JSON.parse(text);
|
|
539
|
-
} catch {
|
|
540
|
-
parsed = { error: text };
|
|
541
|
-
}
|
|
542
|
-
const detail = parsed.error ?? text;
|
|
543
|
-
const segments = [
|
|
544
|
-
`JMP Analytics HTTP ${res.status}`,
|
|
545
|
-
parsed.code ? `[${parsed.code}]` : null,
|
|
546
|
-
detail,
|
|
547
|
-
parsed.hint ? `Hint: ${parsed.hint}` : null,
|
|
548
|
-
parsed.expectedDomain ? `Domain in JMP admin: ${parsed.expectedDomain}` : null
|
|
549
|
-
].filter(Boolean);
|
|
550
|
-
const message = segments.join(" \u2014 ");
|
|
501
|
+
const message = formatApiErrorMessage(res.status, text, "JMP Analytics");
|
|
551
502
|
if (config.debug) {
|
|
552
|
-
console.debug("[@jmp-technologies/analytics]", "error response", {
|
|
553
|
-
status: res.status,
|
|
554
|
-
...parsed,
|
|
555
|
-
raw: text
|
|
556
|
-
});
|
|
503
|
+
console.debug("[@jmp-technologies/analytics]", "error response", { status: res.status, raw: text });
|
|
557
504
|
}
|
|
558
505
|
throw new Error(message);
|
|
559
506
|
}
|
|
@@ -580,32 +527,9 @@ function createJmpAnalytics(config) {
|
|
|
580
527
|
});
|
|
581
528
|
if (!res.ok) {
|
|
582
529
|
const text = await res.text();
|
|
583
|
-
|
|
584
|
-
throw new Error(
|
|
585
|
-
`JMP Analytics HTTP ${res.status} \u2014 ${url} returned HTML (not the JSON API). Set baseUrl / NEXT_PUBLIC_JMP_ANALYTICS_URL to your JMP Analytics dashboard origin (the deployment that includes POST /api/leads).`
|
|
586
|
-
);
|
|
587
|
-
}
|
|
588
|
-
let parsed = {};
|
|
589
|
-
try {
|
|
590
|
-
parsed = JSON.parse(text);
|
|
591
|
-
} catch {
|
|
592
|
-
parsed = { error: text };
|
|
593
|
-
}
|
|
594
|
-
const detail = parsed.error ?? text;
|
|
595
|
-
const segments = [
|
|
596
|
-
`JMP Analytics HTTP ${res.status}`,
|
|
597
|
-
parsed.code ? `[${parsed.code}]` : null,
|
|
598
|
-
detail,
|
|
599
|
-
parsed.hint ? `Hint: ${parsed.hint}` : null,
|
|
600
|
-
parsed.expectedDomain ? `Domain in JMP admin: ${parsed.expectedDomain}` : null
|
|
601
|
-
].filter(Boolean);
|
|
602
|
-
const message = segments.join(" \u2014 ");
|
|
530
|
+
const message = formatApiErrorMessage(res.status, text, "JMP Analytics");
|
|
603
531
|
if (config.debug) {
|
|
604
|
-
console.debug("[@jmp-technologies/analytics]", "error response", {
|
|
605
|
-
status: res.status,
|
|
606
|
-
...parsed,
|
|
607
|
-
raw: text
|
|
608
|
-
});
|
|
532
|
+
console.debug("[@jmp-technologies/analytics]", "error response", { status: res.status, raw: text });
|
|
609
533
|
}
|
|
610
534
|
throw new Error(message);
|
|
611
535
|
}
|
|
@@ -869,6 +793,8 @@ function createJmpAnalytics(config) {
|
|
|
869
793
|
isTrackingConsentGranted: isJmpTrackingConsentGranted
|
|
870
794
|
};
|
|
871
795
|
}
|
|
796
|
+
|
|
797
|
+
// src/server/page-view.ts
|
|
872
798
|
async function trackJmpServerPageView(config, options = {}) {
|
|
873
799
|
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
874
800
|
const resolvedFetch = config.fetchImpl ?? (typeof globalThis !== "undefined" && globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
@@ -910,6 +836,55 @@ async function trackJmpServerPageView(config, options = {}) {
|
|
|
910
836
|
throw new Error(`JMP server analytics HTTP ${res.status} \u2014 ${text}`);
|
|
911
837
|
}
|
|
912
838
|
}
|
|
839
|
+
|
|
840
|
+
// src/content/fetch.ts
|
|
841
|
+
async function getContent(config, path) {
|
|
842
|
+
const text = await getContentText(config, path);
|
|
843
|
+
try {
|
|
844
|
+
return JSON.parse(text);
|
|
845
|
+
} catch {
|
|
846
|
+
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
847
|
+
const url = `${baseUrl}${path}`;
|
|
848
|
+
throw new Error(`JMP content HTTP 200 \u2014 ${url} returned invalid JSON.`);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
async function getContentText(config, path) {
|
|
852
|
+
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
853
|
+
const resolvedFetch = config.fetchImpl ?? (typeof globalThis !== "undefined" && globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
854
|
+
if (!resolvedFetch) {
|
|
855
|
+
throw new Error("JMP content: fetch is not available; pass fetchImpl in config");
|
|
856
|
+
}
|
|
857
|
+
const url = `${baseUrl}${path}`;
|
|
858
|
+
if (config.debug) {
|
|
859
|
+
console.debug("[@jmp-technologies/analytics]", "GET", url);
|
|
860
|
+
}
|
|
861
|
+
const res = await resolvedFetch(url, {
|
|
862
|
+
method: "GET",
|
|
863
|
+
headers: {
|
|
864
|
+
"X-JMP-Tracking-Key": config.trackingKey
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
const text = await res.text();
|
|
868
|
+
if (!res.ok) {
|
|
869
|
+
if (responseLooksLikeHtml(text)) {
|
|
870
|
+
throw new Error(
|
|
871
|
+
`JMP content HTTP ${res.status} \u2014 ${url} returned HTML (not the JSON API). Set baseUrl to your JMP Analytics dashboard origin.`
|
|
872
|
+
);
|
|
873
|
+
}
|
|
874
|
+
let parsed = {};
|
|
875
|
+
try {
|
|
876
|
+
parsed = JSON.parse(text);
|
|
877
|
+
} catch {
|
|
878
|
+
parsed = { error: text };
|
|
879
|
+
}
|
|
880
|
+
throw new Error(
|
|
881
|
+
[`JMP content HTTP ${res.status}`, parsed.error, parsed.hint].filter(Boolean).join(" \u2014 ")
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
return text;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
// src/content/api.ts
|
|
913
888
|
async function getJmpBlogPosts(config) {
|
|
914
889
|
const data = await getContent(
|
|
915
890
|
config,
|
|
@@ -1005,6 +980,8 @@ async function registerJmpContentWrappers(config) {
|
|
|
1005
980
|
const data = JSON.parse(text);
|
|
1006
981
|
return { ok: true, wrappers: data.wrappers ?? wrappers };
|
|
1007
982
|
}
|
|
983
|
+
|
|
984
|
+
// src/content/client.ts
|
|
1008
985
|
function createJmpContentClient(config) {
|
|
1009
986
|
return {
|
|
1010
987
|
getBlogPosts: () => getJmpBlogPosts(config),
|
|
@@ -1016,58 +993,61 @@ function createJmpContentClient(config) {
|
|
|
1016
993
|
registerContentWrappers: () => registerJmpContentWrappers(config)
|
|
1017
994
|
};
|
|
1018
995
|
}
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
1025
|
-
const url = `${baseUrl}${path}`;
|
|
1026
|
-
throw new Error(`JMP content HTTP 200 \u2014 ${url} returned invalid JSON.`);
|
|
996
|
+
|
|
997
|
+
// src/env-public.ts
|
|
998
|
+
function firstDefined(...values) {
|
|
999
|
+
for (const v of values) {
|
|
1000
|
+
if (v) return v;
|
|
1027
1001
|
}
|
|
1002
|
+
return void 0;
|
|
1028
1003
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
if (!resolvedFetch) {
|
|
1033
|
-
throw new Error("JMP content: fetch is not available; pass fetchImpl in config");
|
|
1034
|
-
}
|
|
1035
|
-
const url = `${baseUrl}${path}`;
|
|
1036
|
-
if (config.debug) {
|
|
1037
|
-
console.debug("[@jmp-technologies/analytics]", "GET", url);
|
|
1004
|
+
function readJmpPublicEnvFromProcessEnv() {
|
|
1005
|
+
if (typeof process === "undefined" || !process.env) {
|
|
1006
|
+
return {};
|
|
1038
1007
|
}
|
|
1039
|
-
const
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
}
|
|
1062
|
-
return text;
|
|
1008
|
+
const { env } = process;
|
|
1009
|
+
const analyticsUrl = firstDefined(
|
|
1010
|
+
env.NEXT_PUBLIC_JMP_ANALYTICS_URL,
|
|
1011
|
+
env.PUBLIC_JMP_ANALYTICS_URL
|
|
1012
|
+
);
|
|
1013
|
+
const trackingKey = firstDefined(
|
|
1014
|
+
env.NEXT_PUBLIC_JMP_TRACKING_KEY,
|
|
1015
|
+
env.PUBLIC_JMP_TRACKING_KEY
|
|
1016
|
+
);
|
|
1017
|
+
const requireConsentRaw = firstDefined(
|
|
1018
|
+
env.NEXT_PUBLIC_JMP_ANALYTICS_REQUIRE_CONSENT,
|
|
1019
|
+
env.PUBLIC_JMP_ANALYTICS_REQUIRE_CONSENT
|
|
1020
|
+
);
|
|
1021
|
+
const autoContactRaw = firstDefined(
|
|
1022
|
+
env.NEXT_PUBLIC_JMP_AUTO_CONTACT_LINKS,
|
|
1023
|
+
env.PUBLIC_JMP_AUTO_CONTACT_LINKS
|
|
1024
|
+
);
|
|
1025
|
+
return {
|
|
1026
|
+
analyticsUrl,
|
|
1027
|
+
trackingKey,
|
|
1028
|
+
requireConsent: requireConsentRaw === "true",
|
|
1029
|
+
autoContactLinks: autoContactRaw === "true"
|
|
1030
|
+
};
|
|
1063
1031
|
}
|
|
1064
|
-
|
|
1032
|
+
function readJmpPublicEnvFromProcess(overrides) {
|
|
1033
|
+
const fromEnv = readJmpPublicEnvFromProcessEnv();
|
|
1034
|
+
return {
|
|
1035
|
+
analyticsUrl: firstDefined(overrides?.analyticsUrl, fromEnv.analyticsUrl),
|
|
1036
|
+
trackingKey: firstDefined(overrides?.trackingKey, fromEnv.trackingKey),
|
|
1037
|
+
requireConsent: overrides?.requireConsent ?? fromEnv.requireConsent,
|
|
1038
|
+
autoContactLinks: overrides?.autoContactLinks ?? fromEnv.autoContactLinks
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
// src/env/browser.ts
|
|
1065
1043
|
function getJmpBrowserAnalyticsConfigFromEnv(overrides) {
|
|
1066
1044
|
const pub = readJmpPublicEnvFromProcess();
|
|
1067
|
-
|
|
1045
|
+
const baseUrl = overrides?.baseUrl ?? pub.analyticsUrl;
|
|
1046
|
+
const trackingKey = overrides?.trackingKey ?? pub.trackingKey;
|
|
1047
|
+
if (!baseUrl || !trackingKey) return null;
|
|
1068
1048
|
return {
|
|
1069
|
-
baseUrl
|
|
1070
|
-
trackingKey
|
|
1049
|
+
baseUrl,
|
|
1050
|
+
trackingKey,
|
|
1071
1051
|
pageViewDedupeMs: DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS,
|
|
1072
1052
|
...overrides,
|
|
1073
1053
|
requireConsent: overrides?.requireConsent ?? pub.requireConsent,
|
|
@@ -1076,8 +1056,10 @@ function getJmpBrowserAnalyticsConfigFromEnv(overrides) {
|
|
|
1076
1056
|
}
|
|
1077
1057
|
function getJmpServerContentConfigFromEnv(overrides) {
|
|
1078
1058
|
const pub = readJmpPublicEnvFromProcess();
|
|
1079
|
-
|
|
1080
|
-
|
|
1059
|
+
const baseUrl = overrides?.baseUrl ?? pub.analyticsUrl;
|
|
1060
|
+
const trackingKey = overrides?.trackingKey ?? pub.trackingKey;
|
|
1061
|
+
if (!baseUrl || !trackingKey) return null;
|
|
1062
|
+
return { baseUrl, trackingKey, ...overrides };
|
|
1081
1063
|
}
|
|
1082
1064
|
function isJmpBrowserAnalyticsEnvConfigured() {
|
|
1083
1065
|
const pub = readJmpPublicEnvFromProcess();
|
|
@@ -1100,6 +1082,28 @@ function createJmpContentClientFromServerEnv(overrides) {
|
|
|
1100
1082
|
if (!config) return null;
|
|
1101
1083
|
return createJmpContentClient(config);
|
|
1102
1084
|
}
|
|
1085
|
+
|
|
1086
|
+
// src/site-config.ts
|
|
1087
|
+
var registeredSite = null;
|
|
1088
|
+
function defineJmpSite(definition) {
|
|
1089
|
+
registeredSite = definition;
|
|
1090
|
+
return definition;
|
|
1091
|
+
}
|
|
1092
|
+
function getJmpSiteDefinition() {
|
|
1093
|
+
return registeredSite;
|
|
1094
|
+
}
|
|
1095
|
+
function getJmpContentConfig() {
|
|
1096
|
+
const { analyticsUrl, trackingKey } = readJmpPublicEnvFromProcess();
|
|
1097
|
+
if (!analyticsUrl || !trackingKey) {
|
|
1098
|
+
return null;
|
|
1099
|
+
}
|
|
1100
|
+
const site = getJmpSiteDefinition();
|
|
1101
|
+
return {
|
|
1102
|
+
baseUrl: analyticsUrl,
|
|
1103
|
+
trackingKey,
|
|
1104
|
+
contentWrappers: site?.contentWrappers ?? void 0
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1103
1107
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1104
1108
|
0 && (module.exports = {
|
|
1105
1109
|
BOOKING_LINK_HOSTS,
|
|
@@ -1126,6 +1130,7 @@ function createJmpContentClientFromServerEnv(overrides) {
|
|
|
1126
1130
|
isJmpBrowserAnalyticsEnvConfigured,
|
|
1127
1131
|
isJmpServerContentEnvConfigured,
|
|
1128
1132
|
isJmpTrackingConsentGranted,
|
|
1133
|
+
readJmpPublicEnvFromProcess,
|
|
1129
1134
|
registerJmpContentWrappers,
|
|
1130
1135
|
setJmpTrackingConsent,
|
|
1131
1136
|
subscribeJmpTrackingConsent,
|