@jmp-technologies/analytics 0.1.38 → 0.1.40
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 +6 -2
- package/ai-crawler-agents.json +63 -0
- package/dist/astro/client.cjs +257 -6
- 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 +1 -1
- package/dist/astro/content.cjs +264 -7
- package/dist/astro/content.cjs.map +1 -1
- package/dist/astro/content.d.cts +3 -3
- package/dist/astro/content.d.ts +3 -3
- package/dist/astro/content.js +2 -2
- package/dist/astro/integration.cjs +257 -6
- package/dist/astro/integration.cjs.map +1 -1
- package/dist/astro/integration.js +2 -2
- package/dist/astro/middleware.d.cts +2 -2
- package/dist/astro/middleware.d.ts +2 -2
- package/dist/astro/register.cjs +257 -6
- package/dist/astro/register.cjs.map +1 -1
- package/dist/astro/register.js +2 -2
- package/dist/{chunk-WHUHCTBQ.js → chunk-34LFIP3R.js} +2 -2
- package/dist/{chunk-NCF3J4HV.js → chunk-BRLCGVFJ.js} +2 -2
- package/dist/{chunk-PQOTEV6O.js → chunk-IY6Y636W.js} +2 -2
- package/dist/{chunk-EBU4DKHW.js → chunk-JC3G4XNR.js} +333 -8
- package/dist/chunk-JC3G4XNR.js.map +1 -0
- package/dist/{chunk-JVFN7MF2.js → chunk-VSZRQSUN.js} +2 -2
- package/dist/constants-DTZMYgi4.d.cts +12 -0
- package/dist/constants-DTZMYgi4.d.ts +12 -0
- package/dist/{create-jmp-analytics-DMSXmVIH.d.cts → create-jmp-analytics-B7VqQJca.d.cts} +1 -1
- package/dist/{create-jmp-analytics-JZ3pqNBQ.d.ts → create-jmp-analytics-BGt16QGY.d.ts} +1 -1
- package/dist/index.cjs +340 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -13
- package/dist/index.d.ts +31 -13
- package/dist/index.js +17 -1
- package/dist/next/content.cjs +268 -7
- package/dist/next/content.cjs.map +1 -1
- package/dist/next/content.d.cts +3 -2
- package/dist/next/content.d.ts +3 -2
- package/dist/next/content.js +7 -2
- package/dist/next/content.js.map +1 -1
- package/dist/next/instrumentation.cjs +257 -6
- package/dist/next/instrumentation.cjs.map +1 -1
- package/dist/next/instrumentation.js +1 -1
- package/dist/next/landing-pages.cjs +264 -7
- package/dist/next/landing-pages.cjs.map +1 -1
- package/dist/next/landing-pages.d.cts +2 -2
- package/dist/next/landing-pages.d.ts +2 -2
- package/dist/next/landing-pages.js +2 -2
- package/dist/next/locations.cjs +265 -8
- package/dist/next/locations.cjs.map +1 -1
- package/dist/next/locations.d.cts +3 -3
- package/dist/next/locations.d.ts +3 -3
- package/dist/next/locations.js +3 -3
- package/dist/next/locations.js.map +1 -1
- 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.map +1 -1
- package/dist/next/site-root-server.cjs +264 -7
- package/dist/next/site-root-server.cjs.map +1 -1
- package/dist/next/site-root-server.d.cts +1 -1
- package/dist/next/site-root-server.d.ts +1 -1
- package/dist/next/site-root-server.js +3 -3
- package/dist/next/site-root-server.js.map +1 -1
- package/dist/next.cjs +257 -6
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +3 -3
- package/dist/next.d.ts +3 -3
- package/dist/next.js +3 -3
- package/dist/react.cjs +257 -6
- 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 +2 -2
- package/dist/{site-config-BZJS8Hp_.d.cts → site-config-CZl4PIbg.d.cts} +1 -1
- package/dist/{site-config-BLnwuRC2.d.ts → site-config-Cq5K8hUp.d.ts} +1 -1
- package/dist/{track-page-view-DGKRUIxm.d.ts → track-page-view-BSlE0yI9.d.ts} +1 -1
- package/dist/{track-page-view-BJQqn2Bg.d.cts → track-page-view-M9y_5WqT.d.cts} +1 -1
- package/dist/{types-CYrgEwUF.d.ts → types-DH_8sBu9.d.cts} +35 -0
- package/dist/{types-CYrgEwUF.d.cts → types-DH_8sBu9.d.ts} +35 -0
- package/dist/{utils-B1Nt3sBU.d.ts → utils-C2JRomti.d.ts} +1 -1
- package/dist/{utils-U6TGMIAB.d.cts → utils-JfjoqC-z.d.cts} +1 -1
- package/package.json +2 -1
- package/dist/chunk-EBU4DKHW.js.map +0 -1
- /package/dist/{chunk-WHUHCTBQ.js.map → chunk-34LFIP3R.js.map} +0 -0
- /package/dist/{chunk-NCF3J4HV.js.map → chunk-BRLCGVFJ.js.map} +0 -0
- /package/dist/{chunk-PQOTEV6O.js.map → chunk-IY6Y636W.js.map} +0 -0
- /package/dist/{chunk-JVFN7MF2.js.map → chunk-VSZRQSUN.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -20,10 +20,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
AI_CRAWLER_ROBOTS_USER_AGENTS: () => AI_CRAWLER_ROBOTS_USER_AGENTS,
|
|
23
24
|
BOOKING_LINK_HOSTS: () => BOOKING_LINK_HOSTS,
|
|
24
25
|
DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS: () => DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS,
|
|
26
|
+
JMP_AI_CRAWLER_WAF_USER_AGENTS: () => JMP_AI_CRAWLER_WAF_USER_AGENTS,
|
|
25
27
|
JMP_ANALYTICS_SDK_VERSION: () => JMP_ANALYTICS_SDK_VERSION,
|
|
28
|
+
JMP_CONTENT_CACHE_TAG: () => JMP_CONTENT_CACHE_TAG,
|
|
29
|
+
JMP_CONTENT_REVALIDATE_SECONDS: () => JMP_CONTENT_REVALIDATE_SECONDS,
|
|
26
30
|
JMP_TRACKING_CONSENT_STORAGE_KEY: () => JMP_TRACKING_CONSENT_STORAGE_KEY,
|
|
31
|
+
buildAiCrawlerRobotsTxt: () => buildAiCrawlerRobotsTxt,
|
|
27
32
|
buildLandingCaptureInlineScript: () => buildLandingCaptureInlineScript,
|
|
28
33
|
classifyContactHref: () => classifyContactHref,
|
|
29
34
|
createJmpAnalytics: () => createJmpAnalytics,
|
|
@@ -56,7 +61,10 @@ __export(index_exports, {
|
|
|
56
61
|
isJmpBrowserAnalyticsEnvConfigured: () => isJmpBrowserAnalyticsEnvConfigured,
|
|
57
62
|
isJmpServerContentEnvConfigured: () => isJmpServerContentEnvConfigured,
|
|
58
63
|
isJmpTrackingConsentGranted: () => isJmpTrackingConsentGranted,
|
|
64
|
+
jmpAiCrawlerVercelWafRoute: () => jmpAiCrawlerVercelWafRoute,
|
|
65
|
+
jmpAiCrawlerWafUserAgentPattern: () => jmpAiCrawlerWafUserAgentPattern,
|
|
59
66
|
markContentWrapper: () => markContentWrapper,
|
|
67
|
+
mergeJmpRobotsTxt: () => mergeJmpRobotsTxt,
|
|
60
68
|
normalizeJmpContentManifest: () => normalizeJmpContentManifest,
|
|
61
69
|
readJmpPublicEnvFromProcess: () => readJmpPublicEnvFromProcess,
|
|
62
70
|
registerJmpContentWrappers: () => registerJmpContentWrappers,
|
|
@@ -350,12 +358,14 @@ function extractMailtoTarget(href) {
|
|
|
350
358
|
}
|
|
351
359
|
|
|
352
360
|
// package.json
|
|
353
|
-
var version = "0.1.
|
|
361
|
+
var version = "0.1.40";
|
|
354
362
|
|
|
355
363
|
// src/constants.ts
|
|
356
364
|
var JMP_ANALYTICS_SDK_VERSION = version;
|
|
357
365
|
var JMP_TRACKING_CONSENT_STORAGE_KEY = "jmp_analytics_consent_v1";
|
|
358
366
|
var DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS = 2500;
|
|
367
|
+
var JMP_CONTENT_CACHE_TAG = "jmp-content";
|
|
368
|
+
var JMP_CONTENT_REVALIDATE_SECONDS = 3600;
|
|
359
369
|
|
|
360
370
|
// src/consent.ts
|
|
361
371
|
var moduleTrackingConsentGranted = true;
|
|
@@ -1092,7 +1102,8 @@ function normalizeJmpContentManifest(input) {
|
|
|
1092
1102
|
const externalSources = normalizeExternalSources(input.externalSources);
|
|
1093
1103
|
const trust = normalizeTrust(input.trust);
|
|
1094
1104
|
const contact = normalizeContact(input.contact);
|
|
1095
|
-
|
|
1105
|
+
const defaults = normalizeManifestDefaults(input.defaults);
|
|
1106
|
+
if (routes.length === 0 && !externalSources && !trust && !contact && !defaults) {
|
|
1096
1107
|
return null;
|
|
1097
1108
|
}
|
|
1098
1109
|
return {
|
|
@@ -1100,7 +1111,8 @@ function normalizeJmpContentManifest(input) {
|
|
|
1100
1111
|
...routes.length > 0 ? { routes } : {},
|
|
1101
1112
|
...externalSources ? { externalSources } : {},
|
|
1102
1113
|
...trust ? { trust } : {},
|
|
1103
|
-
...contact ? { contact } : {}
|
|
1114
|
+
...contact ? { contact } : {},
|
|
1115
|
+
...defaults ? { defaults } : {}
|
|
1104
1116
|
};
|
|
1105
1117
|
}
|
|
1106
1118
|
function normalizeRoutes(routes) {
|
|
@@ -1164,10 +1176,132 @@ function normalizeTrustLabels(labels) {
|
|
|
1164
1176
|
}
|
|
1165
1177
|
return Object.keys(out).length > 0 ? out : null;
|
|
1166
1178
|
}
|
|
1179
|
+
function readDefaultText(value, max = 500) {
|
|
1180
|
+
if (typeof value !== "string") return void 0;
|
|
1181
|
+
const trimmed = value.trim();
|
|
1182
|
+
if (!trimmed) return void 0;
|
|
1183
|
+
return trimmed.slice(0, max);
|
|
1184
|
+
}
|
|
1185
|
+
function normalizeManifestDefaults(defaults) {
|
|
1186
|
+
if (!defaults || typeof defaults !== "object") return null;
|
|
1187
|
+
const contactRaw = defaults.contact;
|
|
1188
|
+
const contact = {};
|
|
1189
|
+
if (contactRaw && typeof contactRaw === "object") {
|
|
1190
|
+
const displayName = readDefaultText(contactRaw.displayName, 120);
|
|
1191
|
+
const email = readDefaultText(contactRaw.email, 200);
|
|
1192
|
+
const phone = readDefaultText(contactRaw.phone, 40);
|
|
1193
|
+
const address = readDefaultText(contactRaw.address, 400);
|
|
1194
|
+
const hours = readDefaultText(contactRaw.hours, 400);
|
|
1195
|
+
const serviceArea = readDefaultText(contactRaw.serviceArea, 200);
|
|
1196
|
+
const googleMapsUrl = readDefaultText(contactRaw.googleMapsUrl, 2048);
|
|
1197
|
+
const linkedinUrl = readDefaultText(contactRaw.linkedinUrl, 2048);
|
|
1198
|
+
const instagramUrl = readDefaultText(contactRaw.instagramUrl, 2048);
|
|
1199
|
+
const facebookUrl = readDefaultText(contactRaw.facebookUrl, 2048);
|
|
1200
|
+
const xUrl = readDefaultText(contactRaw.xUrl, 2048);
|
|
1201
|
+
const youtubeUrl = readDefaultText(contactRaw.youtubeUrl, 2048);
|
|
1202
|
+
if (displayName) contact.displayName = displayName;
|
|
1203
|
+
if (email) contact.email = email;
|
|
1204
|
+
if (phone) contact.phone = phone;
|
|
1205
|
+
if (address) contact.address = address;
|
|
1206
|
+
if (hours) contact.hours = hours;
|
|
1207
|
+
if (serviceArea) contact.serviceArea = serviceArea;
|
|
1208
|
+
if (googleMapsUrl) contact.googleMapsUrl = googleMapsUrl;
|
|
1209
|
+
if (linkedinUrl) contact.linkedinUrl = linkedinUrl;
|
|
1210
|
+
if (instagramUrl) contact.instagramUrl = instagramUrl;
|
|
1211
|
+
if (facebookUrl) contact.facebookUrl = facebookUrl;
|
|
1212
|
+
if (xUrl) contact.xUrl = xUrl;
|
|
1213
|
+
if (youtubeUrl) contact.youtubeUrl = youtubeUrl;
|
|
1214
|
+
if (contactRaw.extras && typeof contactRaw.extras === "object") {
|
|
1215
|
+
const extras = {};
|
|
1216
|
+
for (const [rawKey, rawValue] of Object.entries(contactRaw.extras)) {
|
|
1217
|
+
if (Object.keys(extras).length >= 10) break;
|
|
1218
|
+
const key = normalizeKey(rawKey);
|
|
1219
|
+
const value = readDefaultText(rawValue, 200);
|
|
1220
|
+
if (key && isValidExtraKey(key) && value) extras[key] = value;
|
|
1221
|
+
}
|
|
1222
|
+
if (Object.keys(extras).length > 0) contact.extras = extras;
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
const faq = [];
|
|
1226
|
+
if (Array.isArray(defaults.faq)) {
|
|
1227
|
+
for (const raw of defaults.faq) {
|
|
1228
|
+
if (!raw || typeof raw !== "object" || faq.length >= 40) continue;
|
|
1229
|
+
const question = readDefaultText(raw.question, 300);
|
|
1230
|
+
const answer = readDefaultText(raw.answer, 8e3);
|
|
1231
|
+
if (!question || !answer) continue;
|
|
1232
|
+
const category = readDefaultText(raw.category, 80);
|
|
1233
|
+
faq.push({ question, answer, ...category ? { category } : {} });
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
const trustRaw = defaults.trust;
|
|
1237
|
+
const trust = {};
|
|
1238
|
+
if (trustRaw && typeof trustRaw === "object") {
|
|
1239
|
+
const assign = (key, max) => {
|
|
1240
|
+
const value = readDefaultText(trustRaw[key], max);
|
|
1241
|
+
if (value) trust[key] = value;
|
|
1242
|
+
};
|
|
1243
|
+
assign("googleReviewsUrl", 2048);
|
|
1244
|
+
assign("googlePlaceId", 128);
|
|
1245
|
+
assign("yelpUrl", 2048);
|
|
1246
|
+
assign("trustpilotUrl", 2048);
|
|
1247
|
+
assign("disclaimer", 1e3);
|
|
1248
|
+
}
|
|
1249
|
+
const hasContact = Object.keys(contact).length > 0;
|
|
1250
|
+
const hasTrust = Object.keys(trust).length > 0;
|
|
1251
|
+
if (!hasContact && faq.length === 0 && !hasTrust) return null;
|
|
1252
|
+
return {
|
|
1253
|
+
...hasContact ? { contact } : {},
|
|
1254
|
+
...faq.length > 0 ? { faq } : {},
|
|
1255
|
+
...hasTrust ? { trust } : {}
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1167
1258
|
function normalizeContact(contact) {
|
|
1168
1259
|
if (!contact || typeof contact !== "object") return null;
|
|
1169
1260
|
const extras = normalizeContactExtras(contact.extras);
|
|
1170
|
-
|
|
1261
|
+
const leadInbox = normalizeLeadInbox(contact.leadInbox);
|
|
1262
|
+
if (extras.length === 0 && !leadInbox) return null;
|
|
1263
|
+
return {
|
|
1264
|
+
...extras.length > 0 ? { extras } : {},
|
|
1265
|
+
...leadInbox ? { leadInbox } : {}
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
function normalizeLeadInbox(raw) {
|
|
1269
|
+
if (!raw || typeof raw !== "object") return null;
|
|
1270
|
+
const list = normalizeInboxKeyList(raw.list, 8);
|
|
1271
|
+
const detail = normalizeInboxKeyList(raw.detail, 24);
|
|
1272
|
+
const labels = normalizeInboxLabels(raw.labels);
|
|
1273
|
+
if (!list && !detail && !labels) return null;
|
|
1274
|
+
return {
|
|
1275
|
+
...list ? { list } : {},
|
|
1276
|
+
...detail ? { detail } : {},
|
|
1277
|
+
...labels ? { labels } : {}
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
function normalizeInboxKeyList(raw, max) {
|
|
1281
|
+
if (!Array.isArray(raw)) return void 0;
|
|
1282
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1283
|
+
const out = [];
|
|
1284
|
+
for (const item of raw) {
|
|
1285
|
+
if (typeof item !== "string" || out.length >= max) continue;
|
|
1286
|
+
const key = item.trim();
|
|
1287
|
+
const token = key.replace(/[^a-zA-Z0-9]+/g, "").toLowerCase();
|
|
1288
|
+
if (!key || !token || seen.has(token)) continue;
|
|
1289
|
+
seen.add(token);
|
|
1290
|
+
out.push(key);
|
|
1291
|
+
}
|
|
1292
|
+
return out.length > 0 ? out : void 0;
|
|
1293
|
+
}
|
|
1294
|
+
function normalizeInboxLabels(raw) {
|
|
1295
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
1296
|
+
const out = {};
|
|
1297
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
1298
|
+
if (typeof value !== "string") continue;
|
|
1299
|
+
const label = value.trim().slice(0, 60);
|
|
1300
|
+
const token = key.trim();
|
|
1301
|
+
if (!token || !label) continue;
|
|
1302
|
+
out[token] = label;
|
|
1303
|
+
}
|
|
1304
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
1171
1305
|
}
|
|
1172
1306
|
function normalizeContactExtras(extras) {
|
|
1173
1307
|
if (!Array.isArray(extras)) return [];
|
|
@@ -1197,7 +1331,7 @@ function inferWrapperSlotsFromManifest(manifest) {
|
|
|
1197
1331
|
slots.add(`trust.${block.section}`);
|
|
1198
1332
|
slots.add("trust");
|
|
1199
1333
|
}
|
|
1200
|
-
if (manifest?.contact?.extras?.length) {
|
|
1334
|
+
if (manifest?.contact?.extras?.length || manifest?.contact?.leadInbox) {
|
|
1201
1335
|
slots.add("contact");
|
|
1202
1336
|
}
|
|
1203
1337
|
return [...slots];
|
|
@@ -1231,7 +1365,11 @@ async function getContentText(config, path) {
|
|
|
1231
1365
|
}
|
|
1232
1366
|
const res = await resolvedFetch(url, {
|
|
1233
1367
|
method: "GET",
|
|
1234
|
-
headers: jmpContentRequestHeaders(config)
|
|
1368
|
+
headers: jmpContentRequestHeaders(config),
|
|
1369
|
+
next: {
|
|
1370
|
+
revalidate: JMP_CONTENT_REVALIDATE_SECONDS,
|
|
1371
|
+
tags: [JMP_CONTENT_CACHE_TAG]
|
|
1372
|
+
}
|
|
1235
1373
|
});
|
|
1236
1374
|
const text = await res.text();
|
|
1237
1375
|
if (!res.ok) {
|
|
@@ -1322,7 +1460,65 @@ function getDiscoveredContentWrappers() {
|
|
|
1322
1460
|
return sortWrapperSlots([...discovered]);
|
|
1323
1461
|
}
|
|
1324
1462
|
function resolveContentManifestForReport(config) {
|
|
1325
|
-
|
|
1463
|
+
const site = getJmpSiteDefinition();
|
|
1464
|
+
const fallback = site?.contactFallback;
|
|
1465
|
+
const existing = config.contentManifest;
|
|
1466
|
+
const fromFallback = fallbackToManifestDefaults(fallback);
|
|
1467
|
+
if (!existing && !fromFallback) {
|
|
1468
|
+
return null;
|
|
1469
|
+
}
|
|
1470
|
+
const merged = {
|
|
1471
|
+
...existing ?? {},
|
|
1472
|
+
defaults: {
|
|
1473
|
+
...fromFallback ?? {},
|
|
1474
|
+
...existing?.defaults ?? {},
|
|
1475
|
+
contact: {
|
|
1476
|
+
...fromFallback?.contact ?? {},
|
|
1477
|
+
...existing?.defaults?.contact ?? {},
|
|
1478
|
+
extras: {
|
|
1479
|
+
...fromFallback?.contact?.extras ?? {},
|
|
1480
|
+
...existing?.defaults?.contact?.extras ?? {}
|
|
1481
|
+
}
|
|
1482
|
+
},
|
|
1483
|
+
trust: {
|
|
1484
|
+
...fromFallback?.trust ?? {},
|
|
1485
|
+
...existing?.defaults?.trust ?? {}
|
|
1486
|
+
},
|
|
1487
|
+
faq: existing?.defaults?.faq?.length ? existing.defaults.faq : fromFallback?.faq
|
|
1488
|
+
}
|
|
1489
|
+
};
|
|
1490
|
+
return normalizeJmpContentManifest(merged);
|
|
1491
|
+
}
|
|
1492
|
+
function fallbackToManifestDefaults(fallback) {
|
|
1493
|
+
if (!fallback) return null;
|
|
1494
|
+
const contact = {};
|
|
1495
|
+
if (fallback.displayName?.trim()) contact.displayName = fallback.displayName.trim();
|
|
1496
|
+
if (fallback.email?.trim()) contact.email = fallback.email.trim();
|
|
1497
|
+
if (typeof fallback.phone === "string" && fallback.phone.trim()) {
|
|
1498
|
+
contact.phone = fallback.phone.trim();
|
|
1499
|
+
}
|
|
1500
|
+
if (fallback.address?.trim()) contact.address = fallback.address.trim();
|
|
1501
|
+
if (fallback.hours?.trim()) contact.hours = fallback.hours.trim();
|
|
1502
|
+
if (fallback.serviceArea?.trim()) contact.serviceArea = fallback.serviceArea.trim();
|
|
1503
|
+
if (fallback.googleMapsUrl?.trim()) {
|
|
1504
|
+
contact.googleMapsUrl = fallback.googleMapsUrl.trim();
|
|
1505
|
+
}
|
|
1506
|
+
if (fallback.linkedin?.trim()) contact.linkedinUrl = fallback.linkedin.trim();
|
|
1507
|
+
if (fallback.instagram?.trim()) contact.instagramUrl = fallback.instagram.trim();
|
|
1508
|
+
if (fallback.facebook?.trim()) contact.facebookUrl = fallback.facebook.trim();
|
|
1509
|
+
if (fallback.x?.trim()) contact.xUrl = fallback.x.trim();
|
|
1510
|
+
if (fallback.youtube?.trim()) contact.youtubeUrl = fallback.youtube.trim();
|
|
1511
|
+
const trust = {};
|
|
1512
|
+
if (fallback.googleMapsUrl?.trim()) {
|
|
1513
|
+
trust.googleReviewsUrl = fallback.googleMapsUrl.trim();
|
|
1514
|
+
}
|
|
1515
|
+
const hasContact = Object.keys(contact).length > 0;
|
|
1516
|
+
const hasTrust = Object.keys(trust).length > 0;
|
|
1517
|
+
if (!hasContact && !hasTrust) return null;
|
|
1518
|
+
return {
|
|
1519
|
+
...hasContact ? { contact } : {},
|
|
1520
|
+
...hasTrust ? { trust } : {}
|
|
1521
|
+
};
|
|
1326
1522
|
}
|
|
1327
1523
|
function resolveContentWrappersForReport(config) {
|
|
1328
1524
|
const explicit = config.contentWrappers ?? [];
|
|
@@ -1681,6 +1877,135 @@ async function registerJmpContentWrappers(config) {
|
|
|
1681
1877
|
}
|
|
1682
1878
|
setContentWrapperSyncHandler(registerJmpContentWrappers);
|
|
1683
1879
|
|
|
1880
|
+
// ai-crawler-agents.json
|
|
1881
|
+
var ai_crawler_agents_default = {
|
|
1882
|
+
robotsUserAgents: [
|
|
1883
|
+
"GPTBot",
|
|
1884
|
+
"ChatGPT-User",
|
|
1885
|
+
"OAI-SearchBot",
|
|
1886
|
+
"OAI-AdsBot",
|
|
1887
|
+
"ClaudeBot",
|
|
1888
|
+
"Claude-User",
|
|
1889
|
+
"Claude-SearchBot",
|
|
1890
|
+
"Claude-Web",
|
|
1891
|
+
"PerplexityBot",
|
|
1892
|
+
"Perplexity-User",
|
|
1893
|
+
"Google-Extended",
|
|
1894
|
+
"GoogleOther",
|
|
1895
|
+
"GoogleOther-Image",
|
|
1896
|
+
"GoogleOther-Video",
|
|
1897
|
+
"Google-CloudVertexBot",
|
|
1898
|
+
"Meta-ExternalAgent",
|
|
1899
|
+
"Meta-ExternalFetcher",
|
|
1900
|
+
"FacebookBot",
|
|
1901
|
+
"Applebot",
|
|
1902
|
+
"Applebot-Extended",
|
|
1903
|
+
"CCBot",
|
|
1904
|
+
"Bytespider",
|
|
1905
|
+
"cohere-ai",
|
|
1906
|
+
"cohere-training-data-crawler",
|
|
1907
|
+
"YouBot",
|
|
1908
|
+
"MistralAI-User",
|
|
1909
|
+
"GrokBot",
|
|
1910
|
+
"Grok-DeepSearch",
|
|
1911
|
+
"xAI-Grok",
|
|
1912
|
+
"xAI-Bot"
|
|
1913
|
+
],
|
|
1914
|
+
wafUserAgents: [
|
|
1915
|
+
"GPTBot",
|
|
1916
|
+
"ChatGPT-User",
|
|
1917
|
+
"OAI-SearchBot",
|
|
1918
|
+
"OAI-AdsBot",
|
|
1919
|
+
"ClaudeBot",
|
|
1920
|
+
"Claude-User",
|
|
1921
|
+
"Claude-SearchBot",
|
|
1922
|
+
"Claude-Web",
|
|
1923
|
+
"PerplexityBot",
|
|
1924
|
+
"Perplexity-User",
|
|
1925
|
+
"Google-Extended",
|
|
1926
|
+
"GoogleOther",
|
|
1927
|
+
"Google-CloudVertexBot",
|
|
1928
|
+
"Meta-ExternalAgent",
|
|
1929
|
+
"Meta-ExternalFetcher",
|
|
1930
|
+
"FacebookBot",
|
|
1931
|
+
"Applebot-Extended",
|
|
1932
|
+
"CCBot",
|
|
1933
|
+
"Bytespider",
|
|
1934
|
+
"cohere-ai",
|
|
1935
|
+
"cohere-training-data-crawler",
|
|
1936
|
+
"YouBot",
|
|
1937
|
+
"MistralAI-User",
|
|
1938
|
+
"GrokBot",
|
|
1939
|
+
"Grok-DeepSearch",
|
|
1940
|
+
"xAI-Grok",
|
|
1941
|
+
"xAI-Bot"
|
|
1942
|
+
]
|
|
1943
|
+
};
|
|
1944
|
+
|
|
1945
|
+
// src/ai-crawlers.ts
|
|
1946
|
+
var AI_CRAWLER_ROBOTS_USER_AGENTS = ai_crawler_agents_default.robotsUserAgents;
|
|
1947
|
+
var JMP_AI_CRAWLER_WAF_USER_AGENTS = ai_crawler_agents_default.wafUserAgents;
|
|
1948
|
+
function buildAiCrawlerRobotsTxt(blockAiCrawlers) {
|
|
1949
|
+
if (!blockAiCrawlers) {
|
|
1950
|
+
return [
|
|
1951
|
+
"# JMP AI crawler policy",
|
|
1952
|
+
"# AI crawler blocking is disabled for this website.",
|
|
1953
|
+
""
|
|
1954
|
+
].join("\n");
|
|
1955
|
+
}
|
|
1956
|
+
return [
|
|
1957
|
+
"# JMP AI crawler policy",
|
|
1958
|
+
"# Blocks known AI training, answer, and fetch bots that honor robots.txt.",
|
|
1959
|
+
...AI_CRAWLER_ROBOTS_USER_AGENTS.flatMap((agent) => [
|
|
1960
|
+
`User-agent: ${agent}`,
|
|
1961
|
+
"Disallow: /",
|
|
1962
|
+
""
|
|
1963
|
+
])
|
|
1964
|
+
].join("\n");
|
|
1965
|
+
}
|
|
1966
|
+
function jmpAiCrawlerWafUserAgentPattern() {
|
|
1967
|
+
return JMP_AI_CRAWLER_WAF_USER_AGENTS.map(escapeRegExp).join("|");
|
|
1968
|
+
}
|
|
1969
|
+
function jmpAiCrawlerVercelWafRoute() {
|
|
1970
|
+
return {
|
|
1971
|
+
src: "/(.*)",
|
|
1972
|
+
has: [
|
|
1973
|
+
{
|
|
1974
|
+
type: "header",
|
|
1975
|
+
key: "user-agent",
|
|
1976
|
+
value: `(?i).*(${jmpAiCrawlerWafUserAgentPattern()}).*`
|
|
1977
|
+
}
|
|
1978
|
+
],
|
|
1979
|
+
mitigate: { action: "deny" }
|
|
1980
|
+
};
|
|
1981
|
+
}
|
|
1982
|
+
function mergeJmpRobotsTxt(jmpBody, options) {
|
|
1983
|
+
const trimmed = jmpBody.trim();
|
|
1984
|
+
const sitemapLine = `Sitemap: ${options.siteUrl.replace(/\/$/, "")}/sitemap.xml`;
|
|
1985
|
+
const hasSitemap = /(?:^|\n)\s*Sitemap:/i.test(trimmed);
|
|
1986
|
+
const prefixes = options.privatePathPrefixes ?? [];
|
|
1987
|
+
const missingDisallows = prefixes.filter(
|
|
1988
|
+
(prefix) => !trimmed.includes(`Disallow: ${prefix}`)
|
|
1989
|
+
);
|
|
1990
|
+
const parts = [trimmed];
|
|
1991
|
+
if (options.ensureAiCrawlerDisallows && !/User-agent:\s*GPTBot/i.test(trimmed)) {
|
|
1992
|
+
parts.unshift(buildAiCrawlerRobotsTxt(true).trim());
|
|
1993
|
+
}
|
|
1994
|
+
if (missingDisallows.length > 0) {
|
|
1995
|
+
const lines = prefixes.map((prefix) => `Disallow: ${prefix}`);
|
|
1996
|
+
parts.push(`User-agent: *
|
|
1997
|
+
${lines.join("\n")}`);
|
|
1998
|
+
}
|
|
1999
|
+
if (!hasSitemap) {
|
|
2000
|
+
parts.push(sitemapLine);
|
|
2001
|
+
}
|
|
2002
|
+
return `${parts.join("\n\n")}
|
|
2003
|
+
`;
|
|
2004
|
+
}
|
|
2005
|
+
function escapeRegExp(value) {
|
|
2006
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2007
|
+
}
|
|
2008
|
+
|
|
1684
2009
|
// src/content/client.ts
|
|
1685
2010
|
function createJmpContentClient(config) {
|
|
1686
2011
|
return {
|
|
@@ -1746,10 +2071,15 @@ function createJmpContentClientFromServerEnv(overrides) {
|
|
|
1746
2071
|
}
|
|
1747
2072
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1748
2073
|
0 && (module.exports = {
|
|
2074
|
+
AI_CRAWLER_ROBOTS_USER_AGENTS,
|
|
1749
2075
|
BOOKING_LINK_HOSTS,
|
|
1750
2076
|
DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS,
|
|
2077
|
+
JMP_AI_CRAWLER_WAF_USER_AGENTS,
|
|
1751
2078
|
JMP_ANALYTICS_SDK_VERSION,
|
|
2079
|
+
JMP_CONTENT_CACHE_TAG,
|
|
2080
|
+
JMP_CONTENT_REVALIDATE_SECONDS,
|
|
1752
2081
|
JMP_TRACKING_CONSENT_STORAGE_KEY,
|
|
2082
|
+
buildAiCrawlerRobotsTxt,
|
|
1753
2083
|
buildLandingCaptureInlineScript,
|
|
1754
2084
|
classifyContactHref,
|
|
1755
2085
|
createJmpAnalytics,
|
|
@@ -1782,7 +2112,10 @@ function createJmpContentClientFromServerEnv(overrides) {
|
|
|
1782
2112
|
isJmpBrowserAnalyticsEnvConfigured,
|
|
1783
2113
|
isJmpServerContentEnvConfigured,
|
|
1784
2114
|
isJmpTrackingConsentGranted,
|
|
2115
|
+
jmpAiCrawlerVercelWafRoute,
|
|
2116
|
+
jmpAiCrawlerWafUserAgentPattern,
|
|
1785
2117
|
markContentWrapper,
|
|
2118
|
+
mergeJmpRobotsTxt,
|
|
1786
2119
|
normalizeJmpContentManifest,
|
|
1787
2120
|
readJmpPublicEnvFromProcess,
|
|
1788
2121
|
registerJmpContentWrappers,
|