@jmp-technologies/analytics 0.1.26 → 0.1.30
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 +43 -0
- package/bin/jmp-init.mjs +34 -0
- package/dist/astro/client.cjs +227 -10
- 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 +2 -2
- package/dist/astro/content.cjs +340 -14
- package/dist/astro/content.cjs.map +1 -1
- package/dist/astro/content.d.cts +16 -3
- package/dist/astro/content.d.ts +16 -3
- package/dist/astro/content.js +11 -3
- package/dist/astro/integration.cjs +229 -11
- package/dist/astro/integration.cjs.map +1 -1
- package/dist/astro/integration.js +3 -3
- package/dist/astro/middleware.cjs +2 -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 +229 -11
- package/dist/astro/register.cjs.map +1 -1
- package/dist/astro/register.js +3 -3
- package/dist/{chunk-A4RRTY5D.js → chunk-AIFJ7DVO.js} +3 -2
- package/dist/{chunk-A4RRTY5D.js.map → chunk-AIFJ7DVO.js.map} +1 -1
- package/dist/{chunk-TFHOTBOL.js → chunk-FS4BZ7DR.js} +66 -6
- package/dist/chunk-FS4BZ7DR.js.map +1 -0
- package/dist/{chunk-RCOHQAGL.js → chunk-GTPKRBFR.js} +284 -12
- package/dist/chunk-GTPKRBFR.js.map +1 -0
- package/dist/{chunk-HODG4NJQ.js → chunk-HFLU7HQE.js} +2 -2
- package/dist/{chunk-WFTTIRDJ.js → chunk-LLTB7ZFC.js} +2 -2
- package/dist/{chunk-PKGUBYZR.js → chunk-LTPLLPOR.js} +3 -3
- package/dist/{chunk-XQZOGWF2.js → chunk-ZEC22LFP.js} +3 -3
- package/dist/{create-jmp-analytics-JKAsJAWb.d.ts → create-jmp-analytics-BeuuU6as.d.ts} +1 -1
- package/dist/{create-jmp-analytics-Mau-oxji.d.cts → create-jmp-analytics-Ce2CrhhR.d.cts} +1 -1
- package/dist/index.cjs +289 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -7
- package/dist/index.d.ts +16 -7
- package/dist/index.js +12 -2
- package/dist/next/content.cjs +343 -14
- package/dist/next/content.cjs.map +1 -1
- package/dist/next/content.d.cts +8 -5
- package/dist/next/content.d.ts +8 -5
- package/dist/next/content.js +14 -3
- package/dist/next/content.js.map +1 -1
- package/dist/next/instrumentation.cjs +229 -11
- package/dist/next/instrumentation.cjs.map +1 -1
- package/dist/next/instrumentation.js +2 -2
- package/dist/next/landing-pages.cjs +875 -0
- package/dist/next/landing-pages.cjs.map +1 -0
- package/dist/next/landing-pages.d.cts +103 -0
- package/dist/next/landing-pages.d.ts +103 -0
- package/dist/next/landing-pages.js +297 -0
- package/dist/next/landing-pages.js.map +1 -0
- package/dist/next/middleware.cjs +2 -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 +2 -2
- package/dist/next/site-root-server.cjs +229 -11
- package/dist/next/site-root-server.cjs.map +1 -1
- package/dist/next/site-root-server.js +4 -4
- package/dist/next.cjs +227 -10
- 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 +4 -4
- package/dist/react.cjs +227 -10
- 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 +3 -3
- package/dist/{site-config-CXUdGLqw.d.cts → site-config-B4uEj4xX.d.ts} +22 -2
- package/dist/{site-config-w_Db9YSk.d.ts → site-config-DIFmnwqv.d.cts} +22 -2
- package/dist/{track-page-view-CkuSYuco.d.cts → track-page-view-Bv0BAvxG.d.cts} +1 -1
- package/dist/{track-page-view-QRSk8vap.d.ts → track-page-view-CkgIp9-j.d.ts} +1 -1
- package/dist/{types-C1eq8E5u.d.ts → types-B2iP79lb.d.cts} +99 -2
- package/dist/{types-C1eq8E5u.d.cts → types-B2iP79lb.d.ts} +99 -2
- package/package.json +11 -2
- package/dist/chunk-RCOHQAGL.js.map +0 -1
- package/dist/chunk-TFHOTBOL.js.map +0 -1
- /package/dist/{chunk-HODG4NJQ.js.map → chunk-HFLU7HQE.js.map} +0 -0
- /package/dist/{chunk-WFTTIRDJ.js.map → chunk-LLTB7ZFC.js.map} +0 -0
- /package/dist/{chunk-PKGUBYZR.js.map → chunk-LTPLLPOR.js.map} +0 -0
- /package/dist/{chunk-XQZOGWF2.js.map → chunk-ZEC22LFP.js.map} +0 -0
package/dist/astro/content.cjs
CHANGED
|
@@ -24,10 +24,14 @@ __export(content_exports, {
|
|
|
24
24
|
filterFeaturedTrustQuotes: () => filterFeaturedTrustQuotes,
|
|
25
25
|
getJmpContentConfig: () => getJmpContentConfig,
|
|
26
26
|
getResolvedSiteContact: () => getResolvedSiteContact,
|
|
27
|
+
listResolvedSocialUrls: () => listResolvedSocialUrls,
|
|
27
28
|
loadBlogPost: () => loadBlogPost,
|
|
28
29
|
loadBlogPosts: () => loadBlogPosts,
|
|
29
30
|
loadFaqBySlug: () => loadFaqBySlug,
|
|
30
31
|
loadFaqs: () => loadFaqs,
|
|
32
|
+
loadLandingPageDetail: () => loadLandingPageDetail,
|
|
33
|
+
loadLandingPageSitemap: () => loadLandingPageSitemap,
|
|
34
|
+
loadLandingPages: () => loadLandingPages,
|
|
31
35
|
loadSiteProfile: () => loadSiteProfile,
|
|
32
36
|
loadTrustBundle: () => loadTrustBundle,
|
|
33
37
|
resolveSiteContact: () => resolveSiteContact
|
|
@@ -38,7 +42,7 @@ module.exports = __toCommonJS(content_exports);
|
|
|
38
42
|
var LANDING_REFERER_COOKIE_MAX_AGE_SEC = 30 * 60;
|
|
39
43
|
|
|
40
44
|
// src/constants.ts
|
|
41
|
-
var JMP_ANALYTICS_SDK_VERSION = "0.1.
|
|
45
|
+
var JMP_ANALYTICS_SDK_VERSION = "0.1.26";
|
|
42
46
|
|
|
43
47
|
// src/http.ts
|
|
44
48
|
function responseLooksLikeHtml(body) {
|
|
@@ -49,6 +53,209 @@ function normalizeBaseUrl(baseUrl) {
|
|
|
49
53
|
return baseUrl.replace(/\/$/, "");
|
|
50
54
|
}
|
|
51
55
|
|
|
56
|
+
// src/content/manifest.ts
|
|
57
|
+
var JMP_CONTENT_MANIFEST_VERSION = 1;
|
|
58
|
+
var TRUST_SECTIONS = /* @__PURE__ */ new Set([
|
|
59
|
+
"summary",
|
|
60
|
+
"testimonials",
|
|
61
|
+
"reviews",
|
|
62
|
+
"stats",
|
|
63
|
+
"logos",
|
|
64
|
+
"credentials"
|
|
65
|
+
]);
|
|
66
|
+
function normalizeKey(value) {
|
|
67
|
+
return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
68
|
+
}
|
|
69
|
+
function isValidExtraKey(key) {
|
|
70
|
+
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(key);
|
|
71
|
+
}
|
|
72
|
+
var MAX_EXTERNAL_ADMIN_LINKS = 10;
|
|
73
|
+
var MAX_EXTERNAL_ADMIN_LINK_LABEL_LENGTH = 80;
|
|
74
|
+
var EXTERNAL_ADMIN_LINK_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
75
|
+
function tryNormalizeHttpUrl(input) {
|
|
76
|
+
if (typeof input !== "string" || !input.trim()) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const url = new URL(input.trim());
|
|
81
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return url.toString().replace(/\/$/, "");
|
|
85
|
+
} catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function normalizeShopifyExternalSource(shopify) {
|
|
90
|
+
if (!shopify || typeof shopify !== "object") {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
const adminUrl = tryNormalizeHttpUrl(shopify.adminUrl);
|
|
94
|
+
const storeUrl = tryNormalizeHttpUrl(shopify.storeUrl);
|
|
95
|
+
if (!adminUrl && !storeUrl) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
...adminUrl ? { adminUrl } : {},
|
|
100
|
+
...storeUrl ? { storeUrl } : {}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function normalizeExternalAdminLinkEntries(links) {
|
|
104
|
+
if (!Array.isArray(links)) {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
108
|
+
const out = [];
|
|
109
|
+
for (const raw of links) {
|
|
110
|
+
if (!raw || typeof raw !== "object" || out.length >= MAX_EXTERNAL_ADMIN_LINKS) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const id = typeof raw.id === "string" ? raw.id.trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") : "";
|
|
114
|
+
const label = typeof raw.label === "string" ? raw.label.trim().slice(0, MAX_EXTERNAL_ADMIN_LINK_LABEL_LENGTH) : "";
|
|
115
|
+
const url = tryNormalizeHttpUrl(raw.url);
|
|
116
|
+
if (!id || !label || !url || !EXTERNAL_ADMIN_LINK_ID_PATTERN.test(id) || seenIds.has(id)) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
seenIds.add(id);
|
|
120
|
+
out.push({ id, label, url });
|
|
121
|
+
}
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
function normalizeExternalSources(externalSources) {
|
|
125
|
+
if (!externalSources || typeof externalSources !== "object") {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
const studioUrl = tryNormalizeHttpUrl(externalSources.sanity?.studioUrl);
|
|
129
|
+
const shopify = normalizeShopifyExternalSource(externalSources.shopify);
|
|
130
|
+
const links = normalizeExternalAdminLinkEntries(externalSources.links);
|
|
131
|
+
if (!studioUrl && !shopify && links.length === 0) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
...studioUrl ? { sanity: { studioUrl } } : {},
|
|
136
|
+
...shopify ? { shopify } : {},
|
|
137
|
+
...links.length > 0 ? { links } : {}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function normalizeJmpContentManifest(input) {
|
|
141
|
+
if (!input || typeof input !== "object") {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
const routes = normalizeRoutes(input.routes);
|
|
145
|
+
const externalSources = normalizeExternalSources(input.externalSources);
|
|
146
|
+
const trust = normalizeTrust(input.trust);
|
|
147
|
+
const contact = normalizeContact(input.contact);
|
|
148
|
+
if (routes.length === 0 && !externalSources && !trust && !contact) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
version: JMP_CONTENT_MANIFEST_VERSION,
|
|
153
|
+
...routes.length > 0 ? { routes } : {},
|
|
154
|
+
...externalSources ? { externalSources } : {},
|
|
155
|
+
...trust ? { trust } : {},
|
|
156
|
+
...contact ? { contact } : {}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function normalizeRoutes(routes) {
|
|
160
|
+
if (!Array.isArray(routes)) {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
const seen = /* @__PURE__ */ new Set();
|
|
164
|
+
const out = [];
|
|
165
|
+
for (const raw of routes) {
|
|
166
|
+
if (!raw || typeof raw !== "object") continue;
|
|
167
|
+
const wrapper = typeof raw.wrapper === "string" ? raw.wrapper.trim().toLowerCase() : "";
|
|
168
|
+
const pattern = typeof raw.pattern === "string" ? raw.pattern.trim() : "";
|
|
169
|
+
if (!wrapper || !pattern) continue;
|
|
170
|
+
const dedupe = `${wrapper}:${pattern}`;
|
|
171
|
+
if (seen.has(dedupe)) continue;
|
|
172
|
+
seen.add(dedupe);
|
|
173
|
+
out.push({
|
|
174
|
+
wrapper,
|
|
175
|
+
pattern,
|
|
176
|
+
...typeof raw.index === "string" && raw.index.trim() ? { index: raw.index.trim() } : {},
|
|
177
|
+
...typeof raw.label === "string" && raw.label.trim() ? { label: raw.label.trim() } : {}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return out;
|
|
181
|
+
}
|
|
182
|
+
function normalizeTrust(trust) {
|
|
183
|
+
if (!trust || typeof trust !== "object") return null;
|
|
184
|
+
const blocks = normalizeTrustBlocks(trust.blocks);
|
|
185
|
+
const labels = normalizeTrustLabels(trust.labels);
|
|
186
|
+
const mergeTestimonialsReviews = trust.mergeTestimonialsReviews === true;
|
|
187
|
+
if (blocks.length === 0 && !labels && !mergeTestimonialsReviews) return null;
|
|
188
|
+
return {
|
|
189
|
+
...blocks.length > 0 ? { blocks } : {},
|
|
190
|
+
...labels ? { labels } : {},
|
|
191
|
+
...mergeTestimonialsReviews ? { mergeTestimonialsReviews: true } : {}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function normalizeTrustBlocks(blocks) {
|
|
195
|
+
if (!Array.isArray(blocks)) return [];
|
|
196
|
+
const seen = /* @__PURE__ */ new Set();
|
|
197
|
+
const out = [];
|
|
198
|
+
for (const raw of blocks) {
|
|
199
|
+
if (!raw || typeof raw !== "object") continue;
|
|
200
|
+
const section = typeof raw.section === "string" ? raw.section.trim().toLowerCase() : "";
|
|
201
|
+
if (!TRUST_SECTIONS.has(section) || seen.has(section)) continue;
|
|
202
|
+
seen.add(section);
|
|
203
|
+
out.push({
|
|
204
|
+
section,
|
|
205
|
+
...typeof raw.label === "string" && raw.label.trim() ? { label: raw.label.trim() } : {}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
210
|
+
function normalizeTrustLabels(labels) {
|
|
211
|
+
if (!labels || typeof labels !== "object") return null;
|
|
212
|
+
const out = {};
|
|
213
|
+
for (const [key, value] of Object.entries(labels)) {
|
|
214
|
+
if (TRUST_SECTIONS.has(key) && typeof value === "string" && value.trim()) {
|
|
215
|
+
out[key] = value.trim();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
219
|
+
}
|
|
220
|
+
function normalizeContact(contact) {
|
|
221
|
+
if (!contact || typeof contact !== "object") return null;
|
|
222
|
+
const extras = normalizeContactExtras(contact.extras);
|
|
223
|
+
return extras.length > 0 ? { extras } : null;
|
|
224
|
+
}
|
|
225
|
+
function normalizeContactExtras(extras) {
|
|
226
|
+
if (!Array.isArray(extras)) return [];
|
|
227
|
+
const seen = /* @__PURE__ */ new Set();
|
|
228
|
+
const out = [];
|
|
229
|
+
for (const raw of extras) {
|
|
230
|
+
if (!raw || typeof raw !== "object") continue;
|
|
231
|
+
const label = typeof raw.label === "string" ? raw.label.trim() : "";
|
|
232
|
+
const key = normalizeKey(
|
|
233
|
+
typeof raw.key === "string" && raw.key.trim() ? raw.key : label
|
|
234
|
+
);
|
|
235
|
+
if (!key || !label || !isValidExtraKey(key) || seen.has(key)) continue;
|
|
236
|
+
seen.add(key);
|
|
237
|
+
out.push({ key, label });
|
|
238
|
+
}
|
|
239
|
+
return out;
|
|
240
|
+
}
|
|
241
|
+
function stableJmpManifestFingerprint(manifest) {
|
|
242
|
+
return manifest ? JSON.stringify(manifest) : "";
|
|
243
|
+
}
|
|
244
|
+
function inferWrapperSlotsFromManifest(manifest) {
|
|
245
|
+
const slots = /* @__PURE__ */ new Set();
|
|
246
|
+
for (const route of manifest?.routes ?? []) {
|
|
247
|
+
slots.add(route.wrapper);
|
|
248
|
+
}
|
|
249
|
+
for (const block of manifest?.trust?.blocks ?? []) {
|
|
250
|
+
slots.add(`trust.${block.section}`);
|
|
251
|
+
slots.add("trust");
|
|
252
|
+
}
|
|
253
|
+
if (manifest?.contact?.extras?.length) {
|
|
254
|
+
slots.add("contact");
|
|
255
|
+
}
|
|
256
|
+
return [...slots];
|
|
257
|
+
}
|
|
258
|
+
|
|
52
259
|
// src/content/fetch.ts
|
|
53
260
|
async function getContent(config, path) {
|
|
54
261
|
const text = await getContentText(config, path);
|
|
@@ -163,16 +370,22 @@ function inferTrustWrapperSlots(bundle) {
|
|
|
163
370
|
function getDiscoveredContentWrappers() {
|
|
164
371
|
return sortWrapperSlots([...discovered]);
|
|
165
372
|
}
|
|
373
|
+
function resolveContentManifestForReport(config) {
|
|
374
|
+
return normalizeJmpContentManifest(config.contentManifest);
|
|
375
|
+
}
|
|
166
376
|
function resolveContentWrappersForReport(config) {
|
|
167
377
|
const explicit = config.contentWrappers ?? [];
|
|
168
378
|
const auto = getDiscoveredContentWrappers();
|
|
379
|
+
const fromManifest = inferWrapperSlotsFromManifest(
|
|
380
|
+
resolveContentManifestForReport(config)
|
|
381
|
+
);
|
|
169
382
|
if (config.contentWrapperMode === "manual") {
|
|
170
|
-
return sortWrapperSlots([...explicit]);
|
|
383
|
+
return sortWrapperSlots([...explicit, ...fromManifest]);
|
|
171
384
|
}
|
|
172
385
|
if (config.contentWrapperMode === "explicit-only") {
|
|
173
|
-
return sortWrapperSlots([...explicit]);
|
|
386
|
+
return sortWrapperSlots([...explicit, ...fromManifest]);
|
|
174
387
|
}
|
|
175
|
-
const merged = /* @__PURE__ */ new Set([...explicit, ...auto]);
|
|
388
|
+
const merged = /* @__PURE__ */ new Set([...explicit, ...auto, ...fromManifest]);
|
|
176
389
|
return sortWrapperSlots([...merged]);
|
|
177
390
|
}
|
|
178
391
|
function hasReportedContentWrappers(dedupeKey) {
|
|
@@ -253,6 +466,53 @@ async function getJmpFaqs(config) {
|
|
|
253
466
|
afterContentWrapperUse(config);
|
|
254
467
|
return data.faqs;
|
|
255
468
|
}
|
|
469
|
+
async function getJmpLandingPages(config, filters) {
|
|
470
|
+
const params = new URLSearchParams();
|
|
471
|
+
if (filters?.kind) {
|
|
472
|
+
params.set("kind", filters.kind);
|
|
473
|
+
}
|
|
474
|
+
if (filters?.locale) {
|
|
475
|
+
params.set("locale", filters.locale);
|
|
476
|
+
}
|
|
477
|
+
const query = params.toString();
|
|
478
|
+
const data = await getContent(
|
|
479
|
+
config,
|
|
480
|
+
`/api/content/landing-pages${query ? `?${query}` : ""}`
|
|
481
|
+
);
|
|
482
|
+
markContentWrapper("landing");
|
|
483
|
+
afterContentWrapperUse(config);
|
|
484
|
+
return data.pages;
|
|
485
|
+
}
|
|
486
|
+
async function getJmpLandingPageDetail(config, kind, slug, locale) {
|
|
487
|
+
const params = new URLSearchParams();
|
|
488
|
+
if (locale) {
|
|
489
|
+
params.set("locale", locale);
|
|
490
|
+
}
|
|
491
|
+
const query = params.toString();
|
|
492
|
+
try {
|
|
493
|
+
const detail = await getContent(
|
|
494
|
+
config,
|
|
495
|
+
`/api/content/landing-pages/${encodeURIComponent(kind)}/${encodeURIComponent(slug)}${query ? `?${query}` : ""}`
|
|
496
|
+
);
|
|
497
|
+
markContentWrapper("landing");
|
|
498
|
+
afterContentWrapperUse(config);
|
|
499
|
+
return detail;
|
|
500
|
+
} catch (error) {
|
|
501
|
+
if (error instanceof Error && error.message.includes("HTTP 404")) {
|
|
502
|
+
return null;
|
|
503
|
+
}
|
|
504
|
+
throw error;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
async function getJmpLandingPageSitemap(config) {
|
|
508
|
+
const data = await getContent(
|
|
509
|
+
config,
|
|
510
|
+
"/api/content/landing-pages/sitemap"
|
|
511
|
+
);
|
|
512
|
+
markContentWrapper("landing");
|
|
513
|
+
afterContentWrapperUse(config);
|
|
514
|
+
return data.entries;
|
|
515
|
+
}
|
|
256
516
|
async function getJmpTrustBundle(config) {
|
|
257
517
|
const bundle = await getContent(config, "/api/content/trust");
|
|
258
518
|
markTrustBundleWrappers(bundle);
|
|
@@ -273,7 +533,8 @@ async function registerJmpContentWrappers(config) {
|
|
|
273
533
|
if (!wrappers.length) {
|
|
274
534
|
return { ok: false, skipped: true };
|
|
275
535
|
}
|
|
276
|
-
const
|
|
536
|
+
const manifest = resolveContentManifestForReport(config);
|
|
537
|
+
const dedupeKey = `${config.trackingKey}:${[...wrappers].sort().join(",")}:${stableJmpManifestFingerprint(manifest)}`;
|
|
277
538
|
if (hasReportedContentWrappers(dedupeKey)) {
|
|
278
539
|
return { ok: true, wrappers };
|
|
279
540
|
}
|
|
@@ -286,7 +547,17 @@ async function registerJmpContentWrappers(config) {
|
|
|
286
547
|
}
|
|
287
548
|
const url = `${baseUrl}/api/content/capabilities`;
|
|
288
549
|
if (config.debug) {
|
|
289
|
-
console.debug("[@jmp-technologies/analytics]", "POST", url, {
|
|
550
|
+
console.debug("[@jmp-technologies/analytics]", "POST", url, {
|
|
551
|
+
wrappers,
|
|
552
|
+
manifest
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
const body = {
|
|
556
|
+
wrappers,
|
|
557
|
+
sdkVersion: JMP_ANALYTICS_SDK_VERSION
|
|
558
|
+
};
|
|
559
|
+
if (manifest) {
|
|
560
|
+
body.manifest = manifest;
|
|
290
561
|
}
|
|
291
562
|
const res = await resolvedFetch(url, {
|
|
292
563
|
method: "POST",
|
|
@@ -294,10 +565,7 @@ async function registerJmpContentWrappers(config) {
|
|
|
294
565
|
"Content-Type": "application/json",
|
|
295
566
|
"X-JMP-Tracking-Key": config.trackingKey
|
|
296
567
|
},
|
|
297
|
-
body: JSON.stringify(
|
|
298
|
-
wrappers,
|
|
299
|
-
sdkVersion: JMP_ANALYTICS_SDK_VERSION
|
|
300
|
-
})
|
|
568
|
+
body: JSON.stringify(body)
|
|
301
569
|
});
|
|
302
570
|
const text = await res.text();
|
|
303
571
|
if (!res.ok) {
|
|
@@ -376,7 +644,8 @@ function getJmpContentConfig() {
|
|
|
376
644
|
return {
|
|
377
645
|
baseUrl: analyticsUrl,
|
|
378
646
|
trackingKey,
|
|
379
|
-
contentWrappers: site?.contentWrappers ?? void 0
|
|
647
|
+
contentWrappers: site?.contentWrappers ?? void 0,
|
|
648
|
+
contentManifest: site?.contentManifest ?? void 0
|
|
380
649
|
};
|
|
381
650
|
}
|
|
382
651
|
|
|
@@ -386,7 +655,8 @@ var DEFAULT_EXTRA_KEYS = {
|
|
|
386
655
|
dashboardDemoUrl: ["dashboard-demo-url", "sample-dashboard-url"],
|
|
387
656
|
profilePhotoSrc: ["profile-photo-url", "profile_photo_url"],
|
|
388
657
|
hours: ["hours", "business-hours"],
|
|
389
|
-
serviceArea: ["service-area", "service_area", "service-area-text"]
|
|
658
|
+
serviceArea: ["service-area", "service_area", "service-area-text"],
|
|
659
|
+
googleMapsEmbedUrl: ["google-maps-embed-url", "google_maps_embed_url"]
|
|
390
660
|
};
|
|
391
661
|
function sortBlogPosts(posts) {
|
|
392
662
|
return [...posts].sort((a, b) => {
|
|
@@ -437,7 +707,13 @@ function resolveSiteContact(profile) {
|
|
|
437
707
|
...site?.contactExtraKeys
|
|
438
708
|
};
|
|
439
709
|
const email = profile?.email?.trim() || fallback.email || "";
|
|
440
|
-
const
|
|
710
|
+
const social = {
|
|
711
|
+
linkedin: profile?.social?.linkedin?.trim() || fallback.linkedin || null,
|
|
712
|
+
instagram: profile?.social?.instagram?.trim() || fallback.instagram || null,
|
|
713
|
+
facebook: profile?.social?.facebook?.trim() || fallback.facebook || null,
|
|
714
|
+
x: profile?.social?.x?.trim() || fallback.x || null,
|
|
715
|
+
youtube: profile?.social?.youtube?.trim() || fallback.youtube || null
|
|
716
|
+
};
|
|
441
717
|
const phone = profile?.phone?.trim() || fallback.phone || null;
|
|
442
718
|
return {
|
|
443
719
|
displayName: profile?.display_name?.trim() || profile?.name?.trim() || fallback.displayName || "",
|
|
@@ -445,8 +721,12 @@ function resolveSiteContact(profile) {
|
|
|
445
721
|
dashboardDemoUrl: readProfileExtra(profile, extraKeys.dashboardDemoUrl ?? []) || fallback.dashboardDemoUrl || "",
|
|
446
722
|
profilePhotoSrc: readProfileExtra(profile, extraKeys.profilePhotoSrc ?? []) || fallback.profilePhotoSrc || "",
|
|
447
723
|
email,
|
|
448
|
-
linkedin,
|
|
724
|
+
linkedin: social.linkedin,
|
|
725
|
+
social,
|
|
449
726
|
phone,
|
|
727
|
+
address: profile?.address?.trim() || fallback.address || null,
|
|
728
|
+
googleMapsUrl: profile?.google_maps_url?.trim() || fallback.googleMapsUrl || null,
|
|
729
|
+
googleMapsEmbedUrl: readProfileExtra(profile, extraKeys.googleMapsEmbedUrl ?? []) || fallback.googleMapsEmbedUrl || null,
|
|
450
730
|
hours: readProfileExtra(profile, extraKeys.hours ?? []) || fallback.hours || null,
|
|
451
731
|
serviceArea: readProfileExtra(profile, extraKeys.serviceArea ?? []) || fallback.serviceArea || null,
|
|
452
732
|
privacyUrl: profile?.legal?.privacy_policy_url?.trim() || fallback.privacyUrl || "/privacy",
|
|
@@ -461,6 +741,15 @@ async function getResolvedSiteContact() {
|
|
|
461
741
|
const profile = await loadSiteProfile();
|
|
462
742
|
return resolveSiteContact(profile);
|
|
463
743
|
}
|
|
744
|
+
function listResolvedSocialUrls(social) {
|
|
745
|
+
return [
|
|
746
|
+
social.linkedin,
|
|
747
|
+
social.instagram,
|
|
748
|
+
social.facebook,
|
|
749
|
+
social.x,
|
|
750
|
+
social.youtube
|
|
751
|
+
].filter((url) => Boolean(url));
|
|
752
|
+
}
|
|
464
753
|
async function loadBlogPosts() {
|
|
465
754
|
const c = getJmpContentConfig();
|
|
466
755
|
if (!c) {
|
|
@@ -504,6 +793,39 @@ async function loadFaqBySlug(slug) {
|
|
|
504
793
|
const items = await loadFaqs();
|
|
505
794
|
return items.find((item) => item.slug === normalized || item.id === normalized) ?? null;
|
|
506
795
|
}
|
|
796
|
+
async function loadLandingPages(filters) {
|
|
797
|
+
const c = getJmpContentConfig();
|
|
798
|
+
if (!c) {
|
|
799
|
+
return [];
|
|
800
|
+
}
|
|
801
|
+
try {
|
|
802
|
+
return await getJmpLandingPages(c, filters);
|
|
803
|
+
} catch {
|
|
804
|
+
return [];
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
async function loadLandingPageDetail(kind, slug, locale) {
|
|
808
|
+
const c = getJmpContentConfig();
|
|
809
|
+
if (!c) {
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
try {
|
|
813
|
+
return await getJmpLandingPageDetail(c, kind, slug, locale);
|
|
814
|
+
} catch {
|
|
815
|
+
return null;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
async function loadLandingPageSitemap() {
|
|
819
|
+
const c = getJmpContentConfig();
|
|
820
|
+
if (!c) {
|
|
821
|
+
return [];
|
|
822
|
+
}
|
|
823
|
+
try {
|
|
824
|
+
return await getJmpLandingPageSitemap(c);
|
|
825
|
+
} catch {
|
|
826
|
+
return [];
|
|
827
|
+
}
|
|
828
|
+
}
|
|
507
829
|
async function loadTrustBundle() {
|
|
508
830
|
const c = getJmpContentConfig();
|
|
509
831
|
if (!c) {
|
|
@@ -533,10 +855,14 @@ function filterFeaturedTrustQuotes(testimonials, placement, limit = 2) {
|
|
|
533
855
|
filterFeaturedTrustQuotes,
|
|
534
856
|
getJmpContentConfig,
|
|
535
857
|
getResolvedSiteContact,
|
|
858
|
+
listResolvedSocialUrls,
|
|
536
859
|
loadBlogPost,
|
|
537
860
|
loadBlogPosts,
|
|
538
861
|
loadFaqBySlug,
|
|
539
862
|
loadFaqs,
|
|
863
|
+
loadLandingPageDetail,
|
|
864
|
+
loadLandingPageSitemap,
|
|
865
|
+
loadLandingPages,
|
|
540
866
|
loadSiteProfile,
|
|
541
867
|
loadTrustBundle,
|
|
542
868
|
resolveSiteContact
|