@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/README.md
CHANGED
|
@@ -136,7 +136,11 @@ export async function GET() {
|
|
|
136
136
|
}
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
Place that in `app/robots.txt/route.ts` for Next.js App Router sites.
|
|
139
|
+
Place that in `app/robots.txt/route.ts` for Next.js App Router sites. Use `mergeJmpRobotsTxt()` if the site also needs private-path disallows and a sitemap line. Pass `ensureAiCrawlerDisallows: true` only when this site should always list AI `Disallow` rules even if the JMP dashboard toggle is off. The policy uses robots.txt `Disallow` rules for known AI crawler user agents.
|
|
140
|
+
|
|
141
|
+
**Enforcement:** robots.txt is advisory. When this JMP setting is on, also add a `vercel.json` WAF deny (`jmpAiCrawlerVercelWafRoute()` or `create-jmp-client --block-ai-crawlers`) and set Vercel **AI Bots** to **deny**. Crawlers that spoof a normal browser or use undisclosed names may still access public pages. Generic Applebot is not WAF-denied so Apple Search can still crawl; `Applebot-Extended` is denied.
|
|
142
|
+
|
|
143
|
+
Use **≥ 0.1.40** for the shared crawler list, robots merge helper, and WAF route helper.
|
|
140
144
|
|
|
141
145
|
---
|
|
142
146
|
|
|
@@ -355,6 +359,6 @@ After publish, on client sites:
|
|
|
355
359
|
npm install @jmp-technologies/analytics@latest
|
|
356
360
|
```
|
|
357
361
|
|
|
358
|
-
Use **≥ 0.1.8** for `getJmpSiteProfile` / `extras`. Use **≥ 0.1.10** for `email_click` tracking and `JmpTrackedMailtoLink`. Use **≥ 0.1.37** so server content fetches and server page views send `Origin` from `siteUrl` / `NEXT_PUBLIC_SITE_URL` (required for capabilities writes after the matching dashboard deploy). Use **≥ 0.1.38** so `contentManifest.routes` with wrapper `legal` or `pages` reports page URLs to the dashboard Pages tab.
|
|
362
|
+
Use **≥ 0.1.8** for `getJmpSiteProfile` / `extras`. Use **≥ 0.1.10** for `email_click` tracking and `JmpTrackedMailtoLink`. Use **≥ 0.1.37** so server content fetches and server page views send `Origin` from `siteUrl` / `NEXT_PUBLIC_SITE_URL` (required for capabilities writes after the matching dashboard deploy). Use **≥ 0.1.38** so `contentManifest.routes` with wrapper `legal` or `pages` reports page URLs to the dashboard Pages tab. Use **≥ 0.1.39** so JMP content `fetch` uses the `jmp-content` cache tag (client webhooks revalidate it). Use **≥ 0.1.40** for AI crawler robots helpers and the Vercel WAF route helper.
|
|
359
363
|
|
|
360
364
|
Ensure the **dashboard** is deployed with migrations **020** and **021** and `/api/content/site` is live before relying on `getJmpSiteProfile` in production.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"robotsUserAgents": [
|
|
3
|
+
"GPTBot",
|
|
4
|
+
"ChatGPT-User",
|
|
5
|
+
"OAI-SearchBot",
|
|
6
|
+
"OAI-AdsBot",
|
|
7
|
+
"ClaudeBot",
|
|
8
|
+
"Claude-User",
|
|
9
|
+
"Claude-SearchBot",
|
|
10
|
+
"Claude-Web",
|
|
11
|
+
"PerplexityBot",
|
|
12
|
+
"Perplexity-User",
|
|
13
|
+
"Google-Extended",
|
|
14
|
+
"GoogleOther",
|
|
15
|
+
"GoogleOther-Image",
|
|
16
|
+
"GoogleOther-Video",
|
|
17
|
+
"Google-CloudVertexBot",
|
|
18
|
+
"Meta-ExternalAgent",
|
|
19
|
+
"Meta-ExternalFetcher",
|
|
20
|
+
"FacebookBot",
|
|
21
|
+
"Applebot",
|
|
22
|
+
"Applebot-Extended",
|
|
23
|
+
"CCBot",
|
|
24
|
+
"Bytespider",
|
|
25
|
+
"cohere-ai",
|
|
26
|
+
"cohere-training-data-crawler",
|
|
27
|
+
"YouBot",
|
|
28
|
+
"MistralAI-User",
|
|
29
|
+
"GrokBot",
|
|
30
|
+
"Grok-DeepSearch",
|
|
31
|
+
"xAI-Grok",
|
|
32
|
+
"xAI-Bot"
|
|
33
|
+
],
|
|
34
|
+
"wafUserAgents": [
|
|
35
|
+
"GPTBot",
|
|
36
|
+
"ChatGPT-User",
|
|
37
|
+
"OAI-SearchBot",
|
|
38
|
+
"OAI-AdsBot",
|
|
39
|
+
"ClaudeBot",
|
|
40
|
+
"Claude-User",
|
|
41
|
+
"Claude-SearchBot",
|
|
42
|
+
"Claude-Web",
|
|
43
|
+
"PerplexityBot",
|
|
44
|
+
"Perplexity-User",
|
|
45
|
+
"Google-Extended",
|
|
46
|
+
"GoogleOther",
|
|
47
|
+
"Google-CloudVertexBot",
|
|
48
|
+
"Meta-ExternalAgent",
|
|
49
|
+
"Meta-ExternalFetcher",
|
|
50
|
+
"FacebookBot",
|
|
51
|
+
"Applebot-Extended",
|
|
52
|
+
"CCBot",
|
|
53
|
+
"Bytespider",
|
|
54
|
+
"cohere-ai",
|
|
55
|
+
"cohere-training-data-crawler",
|
|
56
|
+
"YouBot",
|
|
57
|
+
"MistralAI-User",
|
|
58
|
+
"GrokBot",
|
|
59
|
+
"Grok-DeepSearch",
|
|
60
|
+
"xAI-Grok",
|
|
61
|
+
"xAI-Bot"
|
|
62
|
+
]
|
|
63
|
+
}
|
package/dist/astro/client.cjs
CHANGED
|
@@ -308,7 +308,7 @@ function extractMailtoTarget(href) {
|
|
|
308
308
|
}
|
|
309
309
|
|
|
310
310
|
// package.json
|
|
311
|
-
var version = "0.1.
|
|
311
|
+
var version = "0.1.40";
|
|
312
312
|
|
|
313
313
|
// src/constants.ts
|
|
314
314
|
var JMP_ANALYTICS_SDK_VERSION = version;
|
|
@@ -951,7 +951,8 @@ function normalizeJmpContentManifest(input) {
|
|
|
951
951
|
const externalSources = normalizeExternalSources(input.externalSources);
|
|
952
952
|
const trust = normalizeTrust(input.trust);
|
|
953
953
|
const contact = normalizeContact(input.contact);
|
|
954
|
-
|
|
954
|
+
const defaults = normalizeManifestDefaults(input.defaults);
|
|
955
|
+
if (routes.length === 0 && !externalSources && !trust && !contact && !defaults) {
|
|
955
956
|
return null;
|
|
956
957
|
}
|
|
957
958
|
return {
|
|
@@ -959,7 +960,8 @@ function normalizeJmpContentManifest(input) {
|
|
|
959
960
|
...routes.length > 0 ? { routes } : {},
|
|
960
961
|
...externalSources ? { externalSources } : {},
|
|
961
962
|
...trust ? { trust } : {},
|
|
962
|
-
...contact ? { contact } : {}
|
|
963
|
+
...contact ? { contact } : {},
|
|
964
|
+
...defaults ? { defaults } : {}
|
|
963
965
|
};
|
|
964
966
|
}
|
|
965
967
|
function normalizeRoutes(routes) {
|
|
@@ -1023,10 +1025,132 @@ function normalizeTrustLabels(labels) {
|
|
|
1023
1025
|
}
|
|
1024
1026
|
return Object.keys(out).length > 0 ? out : null;
|
|
1025
1027
|
}
|
|
1028
|
+
function readDefaultText(value, max = 500) {
|
|
1029
|
+
if (typeof value !== "string") return void 0;
|
|
1030
|
+
const trimmed = value.trim();
|
|
1031
|
+
if (!trimmed) return void 0;
|
|
1032
|
+
return trimmed.slice(0, max);
|
|
1033
|
+
}
|
|
1034
|
+
function normalizeManifestDefaults(defaults) {
|
|
1035
|
+
if (!defaults || typeof defaults !== "object") return null;
|
|
1036
|
+
const contactRaw = defaults.contact;
|
|
1037
|
+
const contact = {};
|
|
1038
|
+
if (contactRaw && typeof contactRaw === "object") {
|
|
1039
|
+
const displayName = readDefaultText(contactRaw.displayName, 120);
|
|
1040
|
+
const email = readDefaultText(contactRaw.email, 200);
|
|
1041
|
+
const phone = readDefaultText(contactRaw.phone, 40);
|
|
1042
|
+
const address = readDefaultText(contactRaw.address, 400);
|
|
1043
|
+
const hours = readDefaultText(contactRaw.hours, 400);
|
|
1044
|
+
const serviceArea = readDefaultText(contactRaw.serviceArea, 200);
|
|
1045
|
+
const googleMapsUrl = readDefaultText(contactRaw.googleMapsUrl, 2048);
|
|
1046
|
+
const linkedinUrl = readDefaultText(contactRaw.linkedinUrl, 2048);
|
|
1047
|
+
const instagramUrl = readDefaultText(contactRaw.instagramUrl, 2048);
|
|
1048
|
+
const facebookUrl = readDefaultText(contactRaw.facebookUrl, 2048);
|
|
1049
|
+
const xUrl = readDefaultText(contactRaw.xUrl, 2048);
|
|
1050
|
+
const youtubeUrl = readDefaultText(contactRaw.youtubeUrl, 2048);
|
|
1051
|
+
if (displayName) contact.displayName = displayName;
|
|
1052
|
+
if (email) contact.email = email;
|
|
1053
|
+
if (phone) contact.phone = phone;
|
|
1054
|
+
if (address) contact.address = address;
|
|
1055
|
+
if (hours) contact.hours = hours;
|
|
1056
|
+
if (serviceArea) contact.serviceArea = serviceArea;
|
|
1057
|
+
if (googleMapsUrl) contact.googleMapsUrl = googleMapsUrl;
|
|
1058
|
+
if (linkedinUrl) contact.linkedinUrl = linkedinUrl;
|
|
1059
|
+
if (instagramUrl) contact.instagramUrl = instagramUrl;
|
|
1060
|
+
if (facebookUrl) contact.facebookUrl = facebookUrl;
|
|
1061
|
+
if (xUrl) contact.xUrl = xUrl;
|
|
1062
|
+
if (youtubeUrl) contact.youtubeUrl = youtubeUrl;
|
|
1063
|
+
if (contactRaw.extras && typeof contactRaw.extras === "object") {
|
|
1064
|
+
const extras = {};
|
|
1065
|
+
for (const [rawKey, rawValue] of Object.entries(contactRaw.extras)) {
|
|
1066
|
+
if (Object.keys(extras).length >= 10) break;
|
|
1067
|
+
const key = normalizeKey(rawKey);
|
|
1068
|
+
const value = readDefaultText(rawValue, 200);
|
|
1069
|
+
if (key && isValidExtraKey(key) && value) extras[key] = value;
|
|
1070
|
+
}
|
|
1071
|
+
if (Object.keys(extras).length > 0) contact.extras = extras;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
const faq = [];
|
|
1075
|
+
if (Array.isArray(defaults.faq)) {
|
|
1076
|
+
for (const raw of defaults.faq) {
|
|
1077
|
+
if (!raw || typeof raw !== "object" || faq.length >= 40) continue;
|
|
1078
|
+
const question = readDefaultText(raw.question, 300);
|
|
1079
|
+
const answer = readDefaultText(raw.answer, 8e3);
|
|
1080
|
+
if (!question || !answer) continue;
|
|
1081
|
+
const category = readDefaultText(raw.category, 80);
|
|
1082
|
+
faq.push({ question, answer, ...category ? { category } : {} });
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
const trustRaw = defaults.trust;
|
|
1086
|
+
const trust = {};
|
|
1087
|
+
if (trustRaw && typeof trustRaw === "object") {
|
|
1088
|
+
const assign = (key, max) => {
|
|
1089
|
+
const value = readDefaultText(trustRaw[key], max);
|
|
1090
|
+
if (value) trust[key] = value;
|
|
1091
|
+
};
|
|
1092
|
+
assign("googleReviewsUrl", 2048);
|
|
1093
|
+
assign("googlePlaceId", 128);
|
|
1094
|
+
assign("yelpUrl", 2048);
|
|
1095
|
+
assign("trustpilotUrl", 2048);
|
|
1096
|
+
assign("disclaimer", 1e3);
|
|
1097
|
+
}
|
|
1098
|
+
const hasContact = Object.keys(contact).length > 0;
|
|
1099
|
+
const hasTrust = Object.keys(trust).length > 0;
|
|
1100
|
+
if (!hasContact && faq.length === 0 && !hasTrust) return null;
|
|
1101
|
+
return {
|
|
1102
|
+
...hasContact ? { contact } : {},
|
|
1103
|
+
...faq.length > 0 ? { faq } : {},
|
|
1104
|
+
...hasTrust ? { trust } : {}
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1026
1107
|
function normalizeContact(contact) {
|
|
1027
1108
|
if (!contact || typeof contact !== "object") return null;
|
|
1028
1109
|
const extras = normalizeContactExtras(contact.extras);
|
|
1029
|
-
|
|
1110
|
+
const leadInbox = normalizeLeadInbox(contact.leadInbox);
|
|
1111
|
+
if (extras.length === 0 && !leadInbox) return null;
|
|
1112
|
+
return {
|
|
1113
|
+
...extras.length > 0 ? { extras } : {},
|
|
1114
|
+
...leadInbox ? { leadInbox } : {}
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
function normalizeLeadInbox(raw) {
|
|
1118
|
+
if (!raw || typeof raw !== "object") return null;
|
|
1119
|
+
const list = normalizeInboxKeyList(raw.list, 8);
|
|
1120
|
+
const detail = normalizeInboxKeyList(raw.detail, 24);
|
|
1121
|
+
const labels = normalizeInboxLabels(raw.labels);
|
|
1122
|
+
if (!list && !detail && !labels) return null;
|
|
1123
|
+
return {
|
|
1124
|
+
...list ? { list } : {},
|
|
1125
|
+
...detail ? { detail } : {},
|
|
1126
|
+
...labels ? { labels } : {}
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
function normalizeInboxKeyList(raw, max) {
|
|
1130
|
+
if (!Array.isArray(raw)) return void 0;
|
|
1131
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1132
|
+
const out = [];
|
|
1133
|
+
for (const item of raw) {
|
|
1134
|
+
if (typeof item !== "string" || out.length >= max) continue;
|
|
1135
|
+
const key = item.trim();
|
|
1136
|
+
const token = key.replace(/[^a-zA-Z0-9]+/g, "").toLowerCase();
|
|
1137
|
+
if (!key || !token || seen.has(token)) continue;
|
|
1138
|
+
seen.add(token);
|
|
1139
|
+
out.push(key);
|
|
1140
|
+
}
|
|
1141
|
+
return out.length > 0 ? out : void 0;
|
|
1142
|
+
}
|
|
1143
|
+
function normalizeInboxLabels(raw) {
|
|
1144
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
1145
|
+
const out = {};
|
|
1146
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
1147
|
+
if (typeof value !== "string") continue;
|
|
1148
|
+
const label = value.trim().slice(0, 60);
|
|
1149
|
+
const token = key.trim();
|
|
1150
|
+
if (!token || !label) continue;
|
|
1151
|
+
out[token] = label;
|
|
1152
|
+
}
|
|
1153
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
1030
1154
|
}
|
|
1031
1155
|
function normalizeContactExtras(extras) {
|
|
1032
1156
|
if (!Array.isArray(extras)) return [];
|
|
@@ -1056,7 +1180,7 @@ function inferWrapperSlotsFromManifest(manifest) {
|
|
|
1056
1180
|
slots.add(`trust.${block.section}`);
|
|
1057
1181
|
slots.add("trust");
|
|
1058
1182
|
}
|
|
1059
|
-
if (manifest?.contact?.extras?.length) {
|
|
1183
|
+
if (manifest?.contact?.extras?.length || manifest?.contact?.leadInbox) {
|
|
1060
1184
|
slots.add("contact");
|
|
1061
1185
|
}
|
|
1062
1186
|
return [...slots];
|
|
@@ -1090,7 +1214,65 @@ function getDiscoveredContentWrappers() {
|
|
|
1090
1214
|
return sortWrapperSlots([...discovered]);
|
|
1091
1215
|
}
|
|
1092
1216
|
function resolveContentManifestForReport(config) {
|
|
1093
|
-
|
|
1217
|
+
const site = getJmpSiteDefinition();
|
|
1218
|
+
const fallback = site?.contactFallback;
|
|
1219
|
+
const existing = config.contentManifest;
|
|
1220
|
+
const fromFallback = fallbackToManifestDefaults(fallback);
|
|
1221
|
+
if (!existing && !fromFallback) {
|
|
1222
|
+
return null;
|
|
1223
|
+
}
|
|
1224
|
+
const merged = {
|
|
1225
|
+
...existing ?? {},
|
|
1226
|
+
defaults: {
|
|
1227
|
+
...fromFallback ?? {},
|
|
1228
|
+
...existing?.defaults ?? {},
|
|
1229
|
+
contact: {
|
|
1230
|
+
...fromFallback?.contact ?? {},
|
|
1231
|
+
...existing?.defaults?.contact ?? {},
|
|
1232
|
+
extras: {
|
|
1233
|
+
...fromFallback?.contact?.extras ?? {},
|
|
1234
|
+
...existing?.defaults?.contact?.extras ?? {}
|
|
1235
|
+
}
|
|
1236
|
+
},
|
|
1237
|
+
trust: {
|
|
1238
|
+
...fromFallback?.trust ?? {},
|
|
1239
|
+
...existing?.defaults?.trust ?? {}
|
|
1240
|
+
},
|
|
1241
|
+
faq: existing?.defaults?.faq?.length ? existing.defaults.faq : fromFallback?.faq
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
return normalizeJmpContentManifest(merged);
|
|
1245
|
+
}
|
|
1246
|
+
function fallbackToManifestDefaults(fallback) {
|
|
1247
|
+
if (!fallback) return null;
|
|
1248
|
+
const contact = {};
|
|
1249
|
+
if (fallback.displayName?.trim()) contact.displayName = fallback.displayName.trim();
|
|
1250
|
+
if (fallback.email?.trim()) contact.email = fallback.email.trim();
|
|
1251
|
+
if (typeof fallback.phone === "string" && fallback.phone.trim()) {
|
|
1252
|
+
contact.phone = fallback.phone.trim();
|
|
1253
|
+
}
|
|
1254
|
+
if (fallback.address?.trim()) contact.address = fallback.address.trim();
|
|
1255
|
+
if (fallback.hours?.trim()) contact.hours = fallback.hours.trim();
|
|
1256
|
+
if (fallback.serviceArea?.trim()) contact.serviceArea = fallback.serviceArea.trim();
|
|
1257
|
+
if (fallback.googleMapsUrl?.trim()) {
|
|
1258
|
+
contact.googleMapsUrl = fallback.googleMapsUrl.trim();
|
|
1259
|
+
}
|
|
1260
|
+
if (fallback.linkedin?.trim()) contact.linkedinUrl = fallback.linkedin.trim();
|
|
1261
|
+
if (fallback.instagram?.trim()) contact.instagramUrl = fallback.instagram.trim();
|
|
1262
|
+
if (fallback.facebook?.trim()) contact.facebookUrl = fallback.facebook.trim();
|
|
1263
|
+
if (fallback.x?.trim()) contact.xUrl = fallback.x.trim();
|
|
1264
|
+
if (fallback.youtube?.trim()) contact.youtubeUrl = fallback.youtube.trim();
|
|
1265
|
+
const trust = {};
|
|
1266
|
+
if (fallback.googleMapsUrl?.trim()) {
|
|
1267
|
+
trust.googleReviewsUrl = fallback.googleMapsUrl.trim();
|
|
1268
|
+
}
|
|
1269
|
+
const hasContact = Object.keys(contact).length > 0;
|
|
1270
|
+
const hasTrust = Object.keys(trust).length > 0;
|
|
1271
|
+
if (!hasContact && !hasTrust) return null;
|
|
1272
|
+
return {
|
|
1273
|
+
...hasContact ? { contact } : {},
|
|
1274
|
+
...hasTrust ? { trust } : {}
|
|
1275
|
+
};
|
|
1094
1276
|
}
|
|
1095
1277
|
function resolveContentWrappersForReport(config) {
|
|
1096
1278
|
const explicit = config.contentWrappers ?? [];
|
|
@@ -1186,6 +1368,75 @@ async function registerJmpContentWrappers(config) {
|
|
|
1186
1368
|
}
|
|
1187
1369
|
setContentWrapperSyncHandler(registerJmpContentWrappers);
|
|
1188
1370
|
|
|
1371
|
+
// ai-crawler-agents.json
|
|
1372
|
+
var ai_crawler_agents_default = {
|
|
1373
|
+
robotsUserAgents: [
|
|
1374
|
+
"GPTBot",
|
|
1375
|
+
"ChatGPT-User",
|
|
1376
|
+
"OAI-SearchBot",
|
|
1377
|
+
"OAI-AdsBot",
|
|
1378
|
+
"ClaudeBot",
|
|
1379
|
+
"Claude-User",
|
|
1380
|
+
"Claude-SearchBot",
|
|
1381
|
+
"Claude-Web",
|
|
1382
|
+
"PerplexityBot",
|
|
1383
|
+
"Perplexity-User",
|
|
1384
|
+
"Google-Extended",
|
|
1385
|
+
"GoogleOther",
|
|
1386
|
+
"GoogleOther-Image",
|
|
1387
|
+
"GoogleOther-Video",
|
|
1388
|
+
"Google-CloudVertexBot",
|
|
1389
|
+
"Meta-ExternalAgent",
|
|
1390
|
+
"Meta-ExternalFetcher",
|
|
1391
|
+
"FacebookBot",
|
|
1392
|
+
"Applebot",
|
|
1393
|
+
"Applebot-Extended",
|
|
1394
|
+
"CCBot",
|
|
1395
|
+
"Bytespider",
|
|
1396
|
+
"cohere-ai",
|
|
1397
|
+
"cohere-training-data-crawler",
|
|
1398
|
+
"YouBot",
|
|
1399
|
+
"MistralAI-User",
|
|
1400
|
+
"GrokBot",
|
|
1401
|
+
"Grok-DeepSearch",
|
|
1402
|
+
"xAI-Grok",
|
|
1403
|
+
"xAI-Bot"
|
|
1404
|
+
],
|
|
1405
|
+
wafUserAgents: [
|
|
1406
|
+
"GPTBot",
|
|
1407
|
+
"ChatGPT-User",
|
|
1408
|
+
"OAI-SearchBot",
|
|
1409
|
+
"OAI-AdsBot",
|
|
1410
|
+
"ClaudeBot",
|
|
1411
|
+
"Claude-User",
|
|
1412
|
+
"Claude-SearchBot",
|
|
1413
|
+
"Claude-Web",
|
|
1414
|
+
"PerplexityBot",
|
|
1415
|
+
"Perplexity-User",
|
|
1416
|
+
"Google-Extended",
|
|
1417
|
+
"GoogleOther",
|
|
1418
|
+
"Google-CloudVertexBot",
|
|
1419
|
+
"Meta-ExternalAgent",
|
|
1420
|
+
"Meta-ExternalFetcher",
|
|
1421
|
+
"FacebookBot",
|
|
1422
|
+
"Applebot-Extended",
|
|
1423
|
+
"CCBot",
|
|
1424
|
+
"Bytespider",
|
|
1425
|
+
"cohere-ai",
|
|
1426
|
+
"cohere-training-data-crawler",
|
|
1427
|
+
"YouBot",
|
|
1428
|
+
"MistralAI-User",
|
|
1429
|
+
"GrokBot",
|
|
1430
|
+
"Grok-DeepSearch",
|
|
1431
|
+
"xAI-Grok",
|
|
1432
|
+
"xAI-Bot"
|
|
1433
|
+
]
|
|
1434
|
+
};
|
|
1435
|
+
|
|
1436
|
+
// src/ai-crawlers.ts
|
|
1437
|
+
var AI_CRAWLER_ROBOTS_USER_AGENTS = ai_crawler_agents_default.robotsUserAgents;
|
|
1438
|
+
var JMP_AI_CRAWLER_WAF_USER_AGENTS = ai_crawler_agents_default.wafUserAgents;
|
|
1439
|
+
|
|
1189
1440
|
// src/astro/client.ts
|
|
1190
1441
|
var import_meta = {};
|
|
1191
1442
|
var jmpAnalyticsSingleton = null;
|