@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.
Files changed (86) hide show
  1. package/README.md +43 -0
  2. package/bin/jmp-init.mjs +34 -0
  3. package/dist/astro/client.cjs +227 -10
  4. package/dist/astro/client.cjs.map +1 -1
  5. package/dist/astro/client.d.cts +2 -2
  6. package/dist/astro/client.d.ts +2 -2
  7. package/dist/astro/client.js +2 -2
  8. package/dist/astro/content.cjs +340 -14
  9. package/dist/astro/content.cjs.map +1 -1
  10. package/dist/astro/content.d.cts +16 -3
  11. package/dist/astro/content.d.ts +16 -3
  12. package/dist/astro/content.js +11 -3
  13. package/dist/astro/integration.cjs +229 -11
  14. package/dist/astro/integration.cjs.map +1 -1
  15. package/dist/astro/integration.js +3 -3
  16. package/dist/astro/middleware.cjs +2 -1
  17. package/dist/astro/middleware.cjs.map +1 -1
  18. package/dist/astro/middleware.d.cts +2 -2
  19. package/dist/astro/middleware.d.ts +2 -2
  20. package/dist/astro/middleware.js +2 -2
  21. package/dist/astro/register.cjs +229 -11
  22. package/dist/astro/register.cjs.map +1 -1
  23. package/dist/astro/register.js +3 -3
  24. package/dist/{chunk-A4RRTY5D.js → chunk-AIFJ7DVO.js} +3 -2
  25. package/dist/{chunk-A4RRTY5D.js.map → chunk-AIFJ7DVO.js.map} +1 -1
  26. package/dist/{chunk-TFHOTBOL.js → chunk-FS4BZ7DR.js} +66 -6
  27. package/dist/chunk-FS4BZ7DR.js.map +1 -0
  28. package/dist/{chunk-RCOHQAGL.js → chunk-GTPKRBFR.js} +284 -12
  29. package/dist/chunk-GTPKRBFR.js.map +1 -0
  30. package/dist/{chunk-HODG4NJQ.js → chunk-HFLU7HQE.js} +2 -2
  31. package/dist/{chunk-WFTTIRDJ.js → chunk-LLTB7ZFC.js} +2 -2
  32. package/dist/{chunk-PKGUBYZR.js → chunk-LTPLLPOR.js} +3 -3
  33. package/dist/{chunk-XQZOGWF2.js → chunk-ZEC22LFP.js} +3 -3
  34. package/dist/{create-jmp-analytics-JKAsJAWb.d.ts → create-jmp-analytics-BeuuU6as.d.ts} +1 -1
  35. package/dist/{create-jmp-analytics-Mau-oxji.d.cts → create-jmp-analytics-Ce2CrhhR.d.cts} +1 -1
  36. package/dist/index.cjs +289 -11
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.cts +16 -7
  39. package/dist/index.d.ts +16 -7
  40. package/dist/index.js +12 -2
  41. package/dist/next/content.cjs +343 -14
  42. package/dist/next/content.cjs.map +1 -1
  43. package/dist/next/content.d.cts +8 -5
  44. package/dist/next/content.d.ts +8 -5
  45. package/dist/next/content.js +14 -3
  46. package/dist/next/content.js.map +1 -1
  47. package/dist/next/instrumentation.cjs +229 -11
  48. package/dist/next/instrumentation.cjs.map +1 -1
  49. package/dist/next/instrumentation.js +2 -2
  50. package/dist/next/landing-pages.cjs +875 -0
  51. package/dist/next/landing-pages.cjs.map +1 -0
  52. package/dist/next/landing-pages.d.cts +103 -0
  53. package/dist/next/landing-pages.d.ts +103 -0
  54. package/dist/next/landing-pages.js +297 -0
  55. package/dist/next/landing-pages.js.map +1 -0
  56. package/dist/next/middleware.cjs +2 -1
  57. package/dist/next/middleware.cjs.map +1 -1
  58. package/dist/next/middleware.d.cts +2 -2
  59. package/dist/next/middleware.d.ts +2 -2
  60. package/dist/next/middleware.js +2 -2
  61. package/dist/next/site-root-server.cjs +229 -11
  62. package/dist/next/site-root-server.cjs.map +1 -1
  63. package/dist/next/site-root-server.js +4 -4
  64. package/dist/next.cjs +227 -10
  65. package/dist/next.cjs.map +1 -1
  66. package/dist/next.d.cts +3 -3
  67. package/dist/next.d.ts +3 -3
  68. package/dist/next.js +4 -4
  69. package/dist/react.cjs +227 -10
  70. package/dist/react.cjs.map +1 -1
  71. package/dist/react.d.cts +2 -2
  72. package/dist/react.d.ts +2 -2
  73. package/dist/react.js +3 -3
  74. package/dist/{site-config-CXUdGLqw.d.cts → site-config-B4uEj4xX.d.ts} +22 -2
  75. package/dist/{site-config-w_Db9YSk.d.ts → site-config-DIFmnwqv.d.cts} +22 -2
  76. package/dist/{track-page-view-CkuSYuco.d.cts → track-page-view-Bv0BAvxG.d.cts} +1 -1
  77. package/dist/{track-page-view-QRSk8vap.d.ts → track-page-view-CkgIp9-j.d.ts} +1 -1
  78. package/dist/{types-C1eq8E5u.d.ts → types-B2iP79lb.d.cts} +99 -2
  79. package/dist/{types-C1eq8E5u.d.cts → types-B2iP79lb.d.ts} +99 -2
  80. package/package.json +11 -2
  81. package/dist/chunk-RCOHQAGL.js.map +0 -1
  82. package/dist/chunk-TFHOTBOL.js.map +0 -1
  83. /package/dist/{chunk-HODG4NJQ.js.map → chunk-HFLU7HQE.js.map} +0 -0
  84. /package/dist/{chunk-WFTTIRDJ.js.map → chunk-LLTB7ZFC.js.map} +0 -0
  85. /package/dist/{chunk-PKGUBYZR.js.map → chunk-LTPLLPOR.js.map} +0 -0
  86. /package/dist/{chunk-XQZOGWF2.js.map → chunk-ZEC22LFP.js.map} +0 -0
@@ -2,13 +2,16 @@ import {
2
2
  getJmpBlogPost,
3
3
  getJmpBlogPosts,
4
4
  getJmpFaqs,
5
+ getJmpLandingPageDetail,
6
+ getJmpLandingPageSitemap,
7
+ getJmpLandingPages,
5
8
  getJmpSiteProfile,
6
9
  getJmpTrustBundle
7
- } from "./chunk-RCOHQAGL.js";
10
+ } from "./chunk-GTPKRBFR.js";
8
11
  import {
9
12
  getJmpContentConfig,
10
13
  getJmpSiteDefinition
11
- } from "./chunk-A4RRTY5D.js";
14
+ } from "./chunk-AIFJ7DVO.js";
12
15
 
13
16
  // src/content/site-content.ts
14
17
  var DEFAULT_EXTRA_KEYS = {
@@ -16,7 +19,8 @@ var DEFAULT_EXTRA_KEYS = {
16
19
  dashboardDemoUrl: ["dashboard-demo-url", "sample-dashboard-url"],
17
20
  profilePhotoSrc: ["profile-photo-url", "profile_photo_url"],
18
21
  hours: ["hours", "business-hours"],
19
- serviceArea: ["service-area", "service_area", "service-area-text"]
22
+ serviceArea: ["service-area", "service_area", "service-area-text"],
23
+ googleMapsEmbedUrl: ["google-maps-embed-url", "google_maps_embed_url"]
20
24
  };
21
25
  function sortBlogPosts(posts) {
22
26
  return [...posts].sort((a, b) => {
@@ -67,7 +71,13 @@ function resolveSiteContact(profile) {
67
71
  ...site?.contactExtraKeys
68
72
  };
69
73
  const email = profile?.email?.trim() || fallback.email || "";
70
- const linkedin = profile?.social?.linkedin?.trim() || fallback.linkedin || null;
74
+ const social = {
75
+ linkedin: profile?.social?.linkedin?.trim() || fallback.linkedin || null,
76
+ instagram: profile?.social?.instagram?.trim() || fallback.instagram || null,
77
+ facebook: profile?.social?.facebook?.trim() || fallback.facebook || null,
78
+ x: profile?.social?.x?.trim() || fallback.x || null,
79
+ youtube: profile?.social?.youtube?.trim() || fallback.youtube || null
80
+ };
71
81
  const phone = profile?.phone?.trim() || fallback.phone || null;
72
82
  return {
73
83
  displayName: profile?.display_name?.trim() || profile?.name?.trim() || fallback.displayName || "",
@@ -75,8 +85,12 @@ function resolveSiteContact(profile) {
75
85
  dashboardDemoUrl: readProfileExtra(profile, extraKeys.dashboardDemoUrl ?? []) || fallback.dashboardDemoUrl || "",
76
86
  profilePhotoSrc: readProfileExtra(profile, extraKeys.profilePhotoSrc ?? []) || fallback.profilePhotoSrc || "",
77
87
  email,
78
- linkedin,
88
+ linkedin: social.linkedin,
89
+ social,
79
90
  phone,
91
+ address: profile?.address?.trim() || fallback.address || null,
92
+ googleMapsUrl: profile?.google_maps_url?.trim() || fallback.googleMapsUrl || null,
93
+ googleMapsEmbedUrl: readProfileExtra(profile, extraKeys.googleMapsEmbedUrl ?? []) || fallback.googleMapsEmbedUrl || null,
80
94
  hours: readProfileExtra(profile, extraKeys.hours ?? []) || fallback.hours || null,
81
95
  serviceArea: readProfileExtra(profile, extraKeys.serviceArea ?? []) || fallback.serviceArea || null,
82
96
  privacyUrl: profile?.legal?.privacy_policy_url?.trim() || fallback.privacyUrl || "/privacy",
@@ -91,6 +105,15 @@ async function getResolvedSiteContact() {
91
105
  const profile = await loadSiteProfile();
92
106
  return resolveSiteContact(profile);
93
107
  }
108
+ function listResolvedSocialUrls(social) {
109
+ return [
110
+ social.linkedin,
111
+ social.instagram,
112
+ social.facebook,
113
+ social.x,
114
+ social.youtube
115
+ ].filter((url) => Boolean(url));
116
+ }
94
117
  async function loadBlogPosts() {
95
118
  const c = getJmpContentConfig();
96
119
  if (!c) {
@@ -134,6 +157,39 @@ async function loadFaqBySlug(slug) {
134
157
  const items = await loadFaqs();
135
158
  return items.find((item) => item.slug === normalized || item.id === normalized) ?? null;
136
159
  }
160
+ async function loadLandingPages(filters) {
161
+ const c = getJmpContentConfig();
162
+ if (!c) {
163
+ return [];
164
+ }
165
+ try {
166
+ return await getJmpLandingPages(c, filters);
167
+ } catch {
168
+ return [];
169
+ }
170
+ }
171
+ async function loadLandingPageDetail(kind, slug, locale) {
172
+ const c = getJmpContentConfig();
173
+ if (!c) {
174
+ return null;
175
+ }
176
+ try {
177
+ return await getJmpLandingPageDetail(c, kind, slug, locale);
178
+ } catch {
179
+ return null;
180
+ }
181
+ }
182
+ async function loadLandingPageSitemap() {
183
+ const c = getJmpContentConfig();
184
+ if (!c) {
185
+ return [];
186
+ }
187
+ try {
188
+ return await getJmpLandingPageSitemap(c);
189
+ } catch {
190
+ return [];
191
+ }
192
+ }
137
193
  async function loadTrustBundle() {
138
194
  const c = getJmpContentConfig();
139
195
  if (!c) {
@@ -163,11 +219,15 @@ export {
163
219
  loadSiteProfile,
164
220
  resolveSiteContact,
165
221
  getResolvedSiteContact,
222
+ listResolvedSocialUrls,
166
223
  loadBlogPosts,
167
224
  loadBlogPost,
168
225
  loadFaqs,
169
226
  loadFaqBySlug,
227
+ loadLandingPages,
228
+ loadLandingPageDetail,
229
+ loadLandingPageSitemap,
170
230
  loadTrustBundle,
171
231
  filterFeaturedTrustQuotes
172
232
  };
173
- //# sourceMappingURL=chunk-TFHOTBOL.js.map
233
+ //# sourceMappingURL=chunk-FS4BZ7DR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/content/site-content.ts"],"sourcesContent":["import {\n getJmpBlogPost,\n getJmpBlogPosts,\n getJmpFaqs,\n getJmpLandingPageDetail,\n getJmpLandingPageSitemap,\n getJmpLandingPages,\n getJmpSiteProfile,\n getJmpTrustBundle,\n type JmpBlogPost,\n type JmpFaqItem,\n type JmpLandingPage,\n type JmpLandingPageDetail,\n type JmpLandingPageKind,\n type JmpLandingPageSitemapEntry,\n type JmpSiteProfile,\n type JmpTestimonial,\n type JmpTrustBundle,\n} from \"../index\"\nimport {\n getJmpContentConfig,\n getJmpSiteDefinition,\n type JmpSiteSocialLinks,\n} from \"../site-config\"\n\nexport type {\n JmpBlogPost,\n JmpFaqItem,\n JmpLandingPage,\n JmpLandingPageDetail,\n JmpLandingPageKind,\n JmpLandingPageSitemapEntry,\n JmpSiteProfile,\n JmpTestimonial,\n JmpTrustBundle,\n}\n\nexport { getJmpContentConfig } from \"../site-config\"\n\nexport type { JmpSiteSocialLinks } from \"../site-config\"\n\nexport type ResolvedSiteContact = {\n displayName: string\n email: string\n founderName: string\n dashboardDemoUrl: string\n profilePhotoSrc: string\n linkedin: string | null\n social: JmpSiteSocialLinks\n phone: string | null\n address: string | null\n googleMapsUrl: string | null\n googleMapsEmbedUrl: string | null\n hours: string | null\n serviceArea: string | null\n privacyUrl: string\n termsUrl: string\n cta: { label: string | null; url: string | null }\n}\n\nconst DEFAULT_EXTRA_KEYS = {\n founderName: [\"founder-name\", \"founder_name\"],\n dashboardDemoUrl: [\"dashboard-demo-url\", \"sample-dashboard-url\"],\n profilePhotoSrc: [\"profile-photo-url\", \"profile_photo_url\"],\n hours: [\"hours\", \"business-hours\"],\n serviceArea: [\"service-area\", \"service_area\", \"service-area-text\"],\n googleMapsEmbedUrl: [\"google-maps-embed-url\", \"google_maps_embed_url\"],\n} as const\n\nfunction sortBlogPosts(posts: JmpBlogPost[]): JmpBlogPost[] {\n return [...posts].sort((a, b) => {\n const da = a.published_at ?? a.updated_at\n const db = b.published_at ?? b.updated_at\n return db.localeCompare(da)\n })\n}\n\nfunction sortFaqs(items: JmpFaqItem[]): JmpFaqItem[] {\n return [...items].sort((a, b) => a.sort_order - b.sort_order)\n}\n\nfunction readProfileExtra(\n profile: JmpSiteProfile | null,\n keys: readonly string[],\n): string | null {\n for (const key of keys) {\n const value = profile?.extras?.[key]?.trim()\n if (value) {\n return value\n }\n }\n return null\n}\n\n/** Resolve a path or URL against {@link defineJmpSite}'s `siteUrl`. */\nexport function absoluteSiteAssetUrl(src: string): string {\n const trimmed = src.trim()\n if (trimmed.startsWith(\"http://\") || trimmed.startsWith(\"https://\")) {\n return trimmed\n }\n const siteUrl = getJmpSiteDefinition()?.siteUrl?.replace(/\\/$/, \"\")\n if (!siteUrl) {\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`\n }\n return `${siteUrl}${trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`}`\n}\n\nexport async function loadSiteProfile(): Promise<JmpSiteProfile | null> {\n const config = getJmpContentConfig()\n if (!config) {\n return null\n }\n try {\n return await getJmpSiteProfile(config)\n } catch {\n return null\n }\n}\n\nexport function resolveSiteContact(profile: JmpSiteProfile | null): ResolvedSiteContact {\n const site = getJmpSiteDefinition()\n const fallback = site?.contactFallback ?? {}\n const extraKeys = {\n ...DEFAULT_EXTRA_KEYS,\n ...site?.contactExtraKeys,\n }\n\n const email = profile?.email?.trim() || fallback.email || \"\"\n const social: JmpSiteSocialLinks = {\n linkedin:\n profile?.social?.linkedin?.trim() || fallback.linkedin || null,\n instagram:\n profile?.social?.instagram?.trim() || fallback.instagram || null,\n facebook:\n profile?.social?.facebook?.trim() || fallback.facebook || null,\n x: profile?.social?.x?.trim() || fallback.x || null,\n youtube:\n profile?.social?.youtube?.trim() || fallback.youtube || null,\n }\n const phone = profile?.phone?.trim() || fallback.phone || null\n\n return {\n displayName:\n profile?.display_name?.trim() ||\n profile?.name?.trim() ||\n fallback.displayName ||\n \"\",\n founderName:\n readProfileExtra(profile, extraKeys.founderName ?? []) ||\n fallback.founderName ||\n \"\",\n dashboardDemoUrl:\n readProfileExtra(profile, extraKeys.dashboardDemoUrl ?? []) ||\n fallback.dashboardDemoUrl ||\n \"\",\n profilePhotoSrc:\n readProfileExtra(profile, extraKeys.profilePhotoSrc ?? []) ||\n fallback.profilePhotoSrc ||\n \"\",\n email,\n linkedin: social.linkedin,\n social,\n phone,\n address: profile?.address?.trim() || fallback.address || null,\n googleMapsUrl:\n profile?.google_maps_url?.trim() || fallback.googleMapsUrl || null,\n googleMapsEmbedUrl:\n readProfileExtra(profile, extraKeys.googleMapsEmbedUrl ?? []) ||\n fallback.googleMapsEmbedUrl ||\n null,\n hours:\n readProfileExtra(profile, extraKeys.hours ?? []) || fallback.hours || null,\n serviceArea:\n readProfileExtra(profile, extraKeys.serviceArea ?? []) ||\n fallback.serviceArea ||\n null,\n privacyUrl: profile?.legal?.privacy_policy_url?.trim() || fallback.privacyUrl || \"/privacy\",\n termsUrl: profile?.legal?.terms_url?.trim() || fallback.termsUrl || \"/terms\",\n cta: {\n label: profile?.cta?.label?.trim() || null,\n url: profile?.cta?.url?.trim() || null,\n },\n }\n}\n\nexport async function getResolvedSiteContact(): Promise<ResolvedSiteContact> {\n const profile = await loadSiteProfile()\n return resolveSiteContact(profile)\n}\n\n/** Non-null social profile URLs in a stable order for JSON-LD `sameAs`. */\nexport function listResolvedSocialUrls(social: JmpSiteSocialLinks): string[] {\n return [\n social.linkedin,\n social.instagram,\n social.facebook,\n social.x,\n social.youtube,\n ].filter((url): url is string => Boolean(url))\n}\n\nexport async function loadBlogPosts(): Promise<JmpBlogPost[]> {\n const c = getJmpContentConfig()\n if (!c) {\n return []\n }\n try {\n const posts = await getJmpBlogPosts(c)\n return sortBlogPosts(posts)\n } catch {\n return []\n }\n}\n\nexport async function loadBlogPost(slug: string): Promise<JmpBlogPost | null> {\n const c = getJmpContentConfig()\n if (!c) {\n return null\n }\n try {\n return await getJmpBlogPost(c, slug)\n } catch {\n return null\n }\n}\n\nexport async function loadFaqs(): Promise<JmpFaqItem[]> {\n const c = getJmpContentConfig()\n if (!c) {\n return []\n }\n try {\n const faqs = await getJmpFaqs(c)\n return sortFaqs(faqs)\n } catch {\n return []\n }\n}\n\nexport async function loadFaqBySlug(slug: string): Promise<JmpFaqItem | null> {\n const normalized = slug.trim()\n if (!normalized) {\n return null\n }\n const items = await loadFaqs()\n return (\n items.find((item) => item.slug === normalized || item.id === normalized) ?? null\n )\n}\n\nexport async function loadLandingPages(filters?: {\n kind?: JmpLandingPageKind\n locale?: string\n}): Promise<JmpLandingPage[]> {\n const c = getJmpContentConfig()\n if (!c) {\n return []\n }\n try {\n return await getJmpLandingPages(c, filters)\n } catch {\n return []\n }\n}\n\nexport async function loadLandingPageDetail(\n kind: JmpLandingPageKind,\n slug: string,\n locale?: string\n): Promise<JmpLandingPageDetail | null> {\n const c = getJmpContentConfig()\n if (!c) {\n return null\n }\n try {\n return await getJmpLandingPageDetail(c, kind, slug, locale)\n } catch {\n return null\n }\n}\n\nexport async function loadLandingPageSitemap(): Promise<JmpLandingPageSitemapEntry[]> {\n const c = getJmpContentConfig()\n if (!c) {\n return []\n }\n try {\n return await getJmpLandingPageSitemap(c)\n } catch {\n return []\n }\n}\n\nexport async function loadTrustBundle(): Promise<JmpTrustBundle | null> {\n const c = getJmpContentConfig()\n if (!c) {\n return null\n }\n try {\n return await getJmpTrustBundle(c)\n } catch {\n return null\n }\n}\n\nexport function filterFeaturedTrustQuotes(\n testimonials: JmpTestimonial[],\n placement: \"testimonials\" | \"reviews\",\n limit = 2,\n): JmpTestimonial[] {\n return testimonials\n .filter((item) => {\n if (!item.featured) {\n return false\n }\n const bucket = item.placement?.trim().toLowerCase()\n if (placement === \"reviews\") {\n return bucket === \"reviews\"\n }\n return !bucket || bucket === \"testimonials\"\n })\n .sort((a, b) => a.sort_order - b.sort_order)\n .slice(0, limit)\n}\n"],"mappings":"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","names":[]}
@@ -10,7 +10,7 @@ import {
10
10
  readJmpPublicEnvFromProcess,
11
11
  resolveFetch,
12
12
  responseLooksLikeHtml
13
- } from "./chunk-A4RRTY5D.js";
13
+ } from "./chunk-AIFJ7DVO.js";
14
14
 
15
15
  // src/contact-link-classifier.ts
16
16
  var BOOKING_LINK_HOSTS = [
@@ -132,7 +132,7 @@ function classifyContactHref(href) {
132
132
  }
133
133
 
134
134
  // src/constants.ts
135
- var JMP_ANALYTICS_SDK_VERSION = "0.1.25";
135
+ var JMP_ANALYTICS_SDK_VERSION = "0.1.26";
136
136
  var JMP_TRACKING_CONSENT_STORAGE_KEY = "jmp_analytics_consent_v1";
137
137
  var DEFAULT_JMP_BROWSER_PAGE_VIEW_DEDUPE_MS = 2500;
138
138
 
@@ -570,6 +570,209 @@ function createJmpAnalytics(config) {
570
570
  };
571
571
  }
572
572
 
573
+ // src/content/manifest.ts
574
+ var JMP_CONTENT_MANIFEST_VERSION = 1;
575
+ var TRUST_SECTIONS = /* @__PURE__ */ new Set([
576
+ "summary",
577
+ "testimonials",
578
+ "reviews",
579
+ "stats",
580
+ "logos",
581
+ "credentials"
582
+ ]);
583
+ function normalizeKey(value) {
584
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
585
+ }
586
+ function isValidExtraKey(key) {
587
+ return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(key);
588
+ }
589
+ var MAX_EXTERNAL_ADMIN_LINKS = 10;
590
+ var MAX_EXTERNAL_ADMIN_LINK_LABEL_LENGTH = 80;
591
+ var EXTERNAL_ADMIN_LINK_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
592
+ function tryNormalizeHttpUrl(input) {
593
+ if (typeof input !== "string" || !input.trim()) {
594
+ return null;
595
+ }
596
+ try {
597
+ const url = new URL(input.trim());
598
+ if (url.protocol !== "https:" && url.protocol !== "http:") {
599
+ return null;
600
+ }
601
+ return url.toString().replace(/\/$/, "");
602
+ } catch {
603
+ return null;
604
+ }
605
+ }
606
+ function normalizeShopifyExternalSource(shopify) {
607
+ if (!shopify || typeof shopify !== "object") {
608
+ return null;
609
+ }
610
+ const adminUrl = tryNormalizeHttpUrl(shopify.adminUrl);
611
+ const storeUrl = tryNormalizeHttpUrl(shopify.storeUrl);
612
+ if (!adminUrl && !storeUrl) {
613
+ return null;
614
+ }
615
+ return {
616
+ ...adminUrl ? { adminUrl } : {},
617
+ ...storeUrl ? { storeUrl } : {}
618
+ };
619
+ }
620
+ function normalizeExternalAdminLinkEntries(links) {
621
+ if (!Array.isArray(links)) {
622
+ return [];
623
+ }
624
+ const seenIds = /* @__PURE__ */ new Set();
625
+ const out = [];
626
+ for (const raw of links) {
627
+ if (!raw || typeof raw !== "object" || out.length >= MAX_EXTERNAL_ADMIN_LINKS) {
628
+ continue;
629
+ }
630
+ const id = typeof raw.id === "string" ? raw.id.trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") : "";
631
+ const label = typeof raw.label === "string" ? raw.label.trim().slice(0, MAX_EXTERNAL_ADMIN_LINK_LABEL_LENGTH) : "";
632
+ const url = tryNormalizeHttpUrl(raw.url);
633
+ if (!id || !label || !url || !EXTERNAL_ADMIN_LINK_ID_PATTERN.test(id) || seenIds.has(id)) {
634
+ continue;
635
+ }
636
+ seenIds.add(id);
637
+ out.push({ id, label, url });
638
+ }
639
+ return out;
640
+ }
641
+ function normalizeExternalSources(externalSources) {
642
+ if (!externalSources || typeof externalSources !== "object") {
643
+ return null;
644
+ }
645
+ const studioUrl = tryNormalizeHttpUrl(externalSources.sanity?.studioUrl);
646
+ const shopify = normalizeShopifyExternalSource(externalSources.shopify);
647
+ const links = normalizeExternalAdminLinkEntries(externalSources.links);
648
+ if (!studioUrl && !shopify && links.length === 0) {
649
+ return null;
650
+ }
651
+ return {
652
+ ...studioUrl ? { sanity: { studioUrl } } : {},
653
+ ...shopify ? { shopify } : {},
654
+ ...links.length > 0 ? { links } : {}
655
+ };
656
+ }
657
+ function normalizeJmpContentManifest(input) {
658
+ if (!input || typeof input !== "object") {
659
+ return null;
660
+ }
661
+ const routes = normalizeRoutes(input.routes);
662
+ const externalSources = normalizeExternalSources(input.externalSources);
663
+ const trust = normalizeTrust(input.trust);
664
+ const contact = normalizeContact(input.contact);
665
+ if (routes.length === 0 && !externalSources && !trust && !contact) {
666
+ return null;
667
+ }
668
+ return {
669
+ version: JMP_CONTENT_MANIFEST_VERSION,
670
+ ...routes.length > 0 ? { routes } : {},
671
+ ...externalSources ? { externalSources } : {},
672
+ ...trust ? { trust } : {},
673
+ ...contact ? { contact } : {}
674
+ };
675
+ }
676
+ function normalizeRoutes(routes) {
677
+ if (!Array.isArray(routes)) {
678
+ return [];
679
+ }
680
+ const seen = /* @__PURE__ */ new Set();
681
+ const out = [];
682
+ for (const raw of routes) {
683
+ if (!raw || typeof raw !== "object") continue;
684
+ const wrapper = typeof raw.wrapper === "string" ? raw.wrapper.trim().toLowerCase() : "";
685
+ const pattern = typeof raw.pattern === "string" ? raw.pattern.trim() : "";
686
+ if (!wrapper || !pattern) continue;
687
+ const dedupe = `${wrapper}:${pattern}`;
688
+ if (seen.has(dedupe)) continue;
689
+ seen.add(dedupe);
690
+ out.push({
691
+ wrapper,
692
+ pattern,
693
+ ...typeof raw.index === "string" && raw.index.trim() ? { index: raw.index.trim() } : {},
694
+ ...typeof raw.label === "string" && raw.label.trim() ? { label: raw.label.trim() } : {}
695
+ });
696
+ }
697
+ return out;
698
+ }
699
+ function normalizeTrust(trust) {
700
+ if (!trust || typeof trust !== "object") return null;
701
+ const blocks = normalizeTrustBlocks(trust.blocks);
702
+ const labels = normalizeTrustLabels(trust.labels);
703
+ const mergeTestimonialsReviews = trust.mergeTestimonialsReviews === true;
704
+ if (blocks.length === 0 && !labels && !mergeTestimonialsReviews) return null;
705
+ return {
706
+ ...blocks.length > 0 ? { blocks } : {},
707
+ ...labels ? { labels } : {},
708
+ ...mergeTestimonialsReviews ? { mergeTestimonialsReviews: true } : {}
709
+ };
710
+ }
711
+ function normalizeTrustBlocks(blocks) {
712
+ if (!Array.isArray(blocks)) return [];
713
+ const seen = /* @__PURE__ */ new Set();
714
+ const out = [];
715
+ for (const raw of blocks) {
716
+ if (!raw || typeof raw !== "object") continue;
717
+ const section = typeof raw.section === "string" ? raw.section.trim().toLowerCase() : "";
718
+ if (!TRUST_SECTIONS.has(section) || seen.has(section)) continue;
719
+ seen.add(section);
720
+ out.push({
721
+ section,
722
+ ...typeof raw.label === "string" && raw.label.trim() ? { label: raw.label.trim() } : {}
723
+ });
724
+ }
725
+ return out;
726
+ }
727
+ function normalizeTrustLabels(labels) {
728
+ if (!labels || typeof labels !== "object") return null;
729
+ const out = {};
730
+ for (const [key, value] of Object.entries(labels)) {
731
+ if (TRUST_SECTIONS.has(key) && typeof value === "string" && value.trim()) {
732
+ out[key] = value.trim();
733
+ }
734
+ }
735
+ return Object.keys(out).length > 0 ? out : null;
736
+ }
737
+ function normalizeContact(contact) {
738
+ if (!contact || typeof contact !== "object") return null;
739
+ const extras = normalizeContactExtras(contact.extras);
740
+ return extras.length > 0 ? { extras } : null;
741
+ }
742
+ function normalizeContactExtras(extras) {
743
+ if (!Array.isArray(extras)) return [];
744
+ const seen = /* @__PURE__ */ new Set();
745
+ const out = [];
746
+ for (const raw of extras) {
747
+ if (!raw || typeof raw !== "object") continue;
748
+ const label = typeof raw.label === "string" ? raw.label.trim() : "";
749
+ const key = normalizeKey(
750
+ typeof raw.key === "string" && raw.key.trim() ? raw.key : label
751
+ );
752
+ if (!key || !label || !isValidExtraKey(key) || seen.has(key)) continue;
753
+ seen.add(key);
754
+ out.push({ key, label });
755
+ }
756
+ return out;
757
+ }
758
+ function stableJmpManifestFingerprint(manifest) {
759
+ return manifest ? JSON.stringify(manifest) : "";
760
+ }
761
+ function inferWrapperSlotsFromManifest(manifest) {
762
+ const slots = /* @__PURE__ */ new Set();
763
+ for (const route of manifest?.routes ?? []) {
764
+ slots.add(route.wrapper);
765
+ }
766
+ for (const block of manifest?.trust?.blocks ?? []) {
767
+ slots.add(`trust.${block.section}`);
768
+ slots.add("trust");
769
+ }
770
+ if (manifest?.contact?.extras?.length) {
771
+ slots.add("contact");
772
+ }
773
+ return [...slots];
774
+ }
775
+
573
776
  // src/content/fetch.ts
574
777
  async function getContent(config, path) {
575
778
  const text = await getContentText(config, path);
@@ -684,16 +887,22 @@ function inferTrustWrapperSlots(bundle) {
684
887
  function getDiscoveredContentWrappers() {
685
888
  return sortWrapperSlots([...discovered]);
686
889
  }
890
+ function resolveContentManifestForReport(config) {
891
+ return normalizeJmpContentManifest(config.contentManifest);
892
+ }
687
893
  function resolveContentWrappersForReport(config) {
688
894
  const explicit = config.contentWrappers ?? [];
689
895
  const auto = getDiscoveredContentWrappers();
896
+ const fromManifest = inferWrapperSlotsFromManifest(
897
+ resolveContentManifestForReport(config)
898
+ );
690
899
  if (config.contentWrapperMode === "manual") {
691
- return sortWrapperSlots([...explicit]);
900
+ return sortWrapperSlots([...explicit, ...fromManifest]);
692
901
  }
693
902
  if (config.contentWrapperMode === "explicit-only") {
694
- return sortWrapperSlots([...explicit]);
903
+ return sortWrapperSlots([...explicit, ...fromManifest]);
695
904
  }
696
- const merged = /* @__PURE__ */ new Set([...explicit, ...auto]);
905
+ const merged = /* @__PURE__ */ new Set([...explicit, ...auto, ...fromManifest]);
697
906
  return sortWrapperSlots([...merged]);
698
907
  }
699
908
  function hasReportedContentWrappers(dedupeKey) {
@@ -784,6 +993,53 @@ async function getJmpFaqs(config) {
784
993
  afterContentWrapperUse(config);
785
994
  return data.faqs;
786
995
  }
996
+ async function getJmpLandingPages(config, filters) {
997
+ const params = new URLSearchParams();
998
+ if (filters?.kind) {
999
+ params.set("kind", filters.kind);
1000
+ }
1001
+ if (filters?.locale) {
1002
+ params.set("locale", filters.locale);
1003
+ }
1004
+ const query = params.toString();
1005
+ const data = await getContent(
1006
+ config,
1007
+ `/api/content/landing-pages${query ? `?${query}` : ""}`
1008
+ );
1009
+ markContentWrapper("landing");
1010
+ afterContentWrapperUse(config);
1011
+ return data.pages;
1012
+ }
1013
+ async function getJmpLandingPageDetail(config, kind, slug, locale) {
1014
+ const params = new URLSearchParams();
1015
+ if (locale) {
1016
+ params.set("locale", locale);
1017
+ }
1018
+ const query = params.toString();
1019
+ try {
1020
+ const detail = await getContent(
1021
+ config,
1022
+ `/api/content/landing-pages/${encodeURIComponent(kind)}/${encodeURIComponent(slug)}${query ? `?${query}` : ""}`
1023
+ );
1024
+ markContentWrapper("landing");
1025
+ afterContentWrapperUse(config);
1026
+ return detail;
1027
+ } catch (error) {
1028
+ if (error instanceof Error && error.message.includes("HTTP 404")) {
1029
+ return null;
1030
+ }
1031
+ throw error;
1032
+ }
1033
+ }
1034
+ async function getJmpLandingPageSitemap(config) {
1035
+ const data = await getContent(
1036
+ config,
1037
+ "/api/content/landing-pages/sitemap"
1038
+ );
1039
+ markContentWrapper("landing");
1040
+ afterContentWrapperUse(config);
1041
+ return data.entries;
1042
+ }
787
1043
  async function getJmpTrustBundle(config) {
788
1044
  const bundle = await getContent(config, "/api/content/trust");
789
1045
  markTrustBundleWrappers(bundle);
@@ -807,7 +1063,8 @@ async function registerJmpContentWrappers(config) {
807
1063
  if (!wrappers.length) {
808
1064
  return { ok: false, skipped: true };
809
1065
  }
810
- const dedupeKey = `${config.trackingKey}:${[...wrappers].sort().join(",")}`;
1066
+ const manifest = resolveContentManifestForReport(config);
1067
+ const dedupeKey = `${config.trackingKey}:${[...wrappers].sort().join(",")}:${stableJmpManifestFingerprint(manifest)}`;
811
1068
  if (hasReportedContentWrappers(dedupeKey)) {
812
1069
  return { ok: true, wrappers };
813
1070
  }
@@ -820,7 +1077,17 @@ async function registerJmpContentWrappers(config) {
820
1077
  }
821
1078
  const url = `${baseUrl}/api/content/capabilities`;
822
1079
  if (config.debug) {
823
- console.debug("[@jmp-technologies/analytics]", "POST", url, { wrappers });
1080
+ console.debug("[@jmp-technologies/analytics]", "POST", url, {
1081
+ wrappers,
1082
+ manifest
1083
+ });
1084
+ }
1085
+ const body = {
1086
+ wrappers,
1087
+ sdkVersion: JMP_ANALYTICS_SDK_VERSION
1088
+ };
1089
+ if (manifest) {
1090
+ body.manifest = manifest;
824
1091
  }
825
1092
  const res = await resolvedFetch(url, {
826
1093
  method: "POST",
@@ -828,10 +1095,7 @@ async function registerJmpContentWrappers(config) {
828
1095
  "Content-Type": "application/json",
829
1096
  "X-JMP-Tracking-Key": config.trackingKey
830
1097
  },
831
- body: JSON.stringify({
832
- wrappers,
833
- sdkVersion: JMP_ANALYTICS_SDK_VERSION
834
- })
1098
+ body: JSON.stringify(body)
835
1099
  });
836
1100
  const text = await res.text();
837
1101
  if (!res.ok) {
@@ -857,6 +1121,9 @@ function createJmpContentClient(config) {
857
1121
  getBlogPosts: () => getJmpBlogPosts(config),
858
1122
  getBlogPost: (slug) => getJmpBlogPost(config, slug),
859
1123
  getFaqs: () => getJmpFaqs(config),
1124
+ getLandingPages: (filters) => getJmpLandingPages(config, filters),
1125
+ getLandingPageDetail: (kind, slug, locale) => getJmpLandingPageDetail(config, kind, slug, locale),
1126
+ getLandingPageSitemap: () => getJmpLandingPageSitemap(config),
860
1127
  getTrustBundle: () => getJmpTrustBundle(config),
861
1128
  getSiteProfile: () => getJmpSiteProfile(config),
862
1129
  getRobotsTxt: () => getJmpRobotsTxt(config),
@@ -919,6 +1186,8 @@ export {
919
1186
  subscribeJmpTrackingConsent,
920
1187
  setJmpTrackingConsent,
921
1188
  createJmpAnalytics,
1189
+ normalizeJmpContentManifest,
1190
+ stableJmpManifestFingerprint,
922
1191
  markContentWrapper,
923
1192
  inferTrustWrapperSlots,
924
1193
  getDiscoveredContentWrappers,
@@ -926,6 +1195,9 @@ export {
926
1195
  getJmpBlogPosts,
927
1196
  getJmpBlogPost,
928
1197
  getJmpFaqs,
1198
+ getJmpLandingPages,
1199
+ getJmpLandingPageDetail,
1200
+ getJmpLandingPageSitemap,
929
1201
  getJmpTrustBundle,
930
1202
  getJmpSiteProfile,
931
1203
  getJmpRobotsTxt,
@@ -938,4 +1210,4 @@ export {
938
1210
  getOrCreateJmpAnalyticsFromBrowserEnv,
939
1211
  createJmpContentClientFromServerEnv
940
1212
  };
941
- //# sourceMappingURL=chunk-RCOHQAGL.js.map
1213
+ //# sourceMappingURL=chunk-GTPKRBFR.js.map