@jmp-technologies/analytics 0.1.27 → 0.1.32

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 (100) hide show
  1. package/dist/astro/client.cjs +256 -11
  2. package/dist/astro/client.cjs.map +1 -1
  3. package/dist/astro/client.d.cts +2 -2
  4. package/dist/astro/client.d.ts +2 -2
  5. package/dist/astro/client.js +2 -2
  6. package/dist/astro/content.cjs +308 -13
  7. package/dist/astro/content.cjs.map +1 -1
  8. package/dist/astro/content.d.cts +12 -3
  9. package/dist/astro/content.d.ts +12 -3
  10. package/dist/astro/content.js +9 -3
  11. package/dist/astro/integration.cjs +228 -10
  12. package/dist/astro/integration.cjs.map +1 -1
  13. package/dist/astro/integration.js +3 -3
  14. package/dist/astro/middleware.cjs +2 -1
  15. package/dist/astro/middleware.cjs.map +1 -1
  16. package/dist/astro/middleware.d.cts +2 -2
  17. package/dist/astro/middleware.d.ts +2 -2
  18. package/dist/astro/middleware.js +2 -2
  19. package/dist/astro/register.cjs +228 -10
  20. package/dist/astro/register.cjs.map +1 -1
  21. package/dist/astro/register.js +3 -3
  22. package/dist/{chunk-KZ4WVDGL.js → chunk-7623G3XL.js} +3 -3
  23. package/dist/{chunk-A4RRTY5D.js → chunk-AIFJ7DVO.js} +3 -2
  24. package/dist/{chunk-A4RRTY5D.js.map → chunk-AIFJ7DVO.js.map} +1 -1
  25. package/dist/{chunk-YCVHRMM6.js → chunk-G5BMWPQ6.js} +2 -3
  26. package/dist/{chunk-YCVHRMM6.js.map → chunk-G5BMWPQ6.js.map} +1 -1
  27. package/dist/{chunk-HODG4NJQ.js → chunk-HFLU7HQE.js} +2 -2
  28. package/dist/{chunk-PG3IOI5O.js → chunk-HKMDWTA2.js} +53 -6
  29. package/dist/chunk-HKMDWTA2.js.map +1 -0
  30. package/dist/{chunk-DNYJF7BG.js → chunk-KPTMZQCY.js} +3 -3
  31. package/dist/{chunk-FNWE2DT5.js → chunk-NDSPSAWQ.js} +18 -8
  32. package/dist/chunk-NDSPSAWQ.js.map +1 -0
  33. package/dist/{chunk-UVYF33XE.js → chunk-NI7R6QZQ.js} +293 -13
  34. package/dist/chunk-NI7R6QZQ.js.map +1 -0
  35. package/dist/chunk-RI3KKDPX.js +75 -0
  36. package/dist/chunk-RI3KKDPX.js.map +1 -0
  37. package/dist/{create-jmp-analytics-D4Qw_d6o.d.cts → create-jmp-analytics-D1dUsqCQ.d.cts} +1 -2
  38. package/dist/{create-jmp-analytics-DpG5Hdl5.d.ts → create-jmp-analytics-htx2oOEf.d.ts} +1 -2
  39. package/dist/index.cjs +295 -12
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +8 -6
  42. package/dist/index.d.ts +8 -6
  43. package/dist/index.js +10 -2
  44. package/dist/next/content.cjs +310 -13
  45. package/dist/next/content.cjs.map +1 -1
  46. package/dist/next/content.d.cts +7 -5
  47. package/dist/next/content.d.ts +7 -5
  48. package/dist/next/content.js +11 -3
  49. package/dist/next/content.js.map +1 -1
  50. package/dist/next/instrumentation.cjs +228 -10
  51. package/dist/next/instrumentation.cjs.map +1 -1
  52. package/dist/next/instrumentation.js +2 -2
  53. package/dist/next/landing-capture-script-server.cjs +1 -2
  54. package/dist/next/landing-capture-script-server.cjs.map +1 -1
  55. package/dist/next/landing-capture-script-server.js +1 -1
  56. package/dist/next/landing-pages.cjs +228 -12
  57. package/dist/next/landing-pages.cjs.map +1 -1
  58. package/dist/next/landing-pages.d.cts +4 -16
  59. package/dist/next/landing-pages.d.ts +4 -16
  60. package/dist/next/landing-pages.js +13 -67
  61. package/dist/next/landing-pages.js.map +1 -1
  62. package/dist/next/locations.cjs +737 -0
  63. package/dist/next/locations.cjs.map +1 -0
  64. package/dist/next/locations.d.cts +55 -0
  65. package/dist/next/locations.d.ts +55 -0
  66. package/dist/next/locations.js +158 -0
  67. package/dist/next/locations.js.map +1 -0
  68. package/dist/next/middleware.cjs +2 -1
  69. package/dist/next/middleware.cjs.map +1 -1
  70. package/dist/next/middleware.d.cts +2 -2
  71. package/dist/next/middleware.d.ts +2 -2
  72. package/dist/next/middleware.js +2 -2
  73. package/dist/next/site-root-server.cjs +259 -14
  74. package/dist/next/site-root-server.cjs.map +1 -1
  75. package/dist/next/site-root-server.js +5 -5
  76. package/dist/next.cjs +270 -17
  77. package/dist/next.cjs.map +1 -1
  78. package/dist/next.d.cts +3 -3
  79. package/dist/next.d.ts +3 -3
  80. package/dist/next.js +4 -4
  81. package/dist/react.cjs +389 -136
  82. package/dist/react.cjs.map +1 -1
  83. package/dist/react.d.cts +2 -2
  84. package/dist/react.d.ts +2 -2
  85. package/dist/react.js +3 -3
  86. package/dist/{site-config-UTzDG-UG.d.ts → site-config-B7USGGzu.d.cts} +22 -2
  87. package/dist/{site-config-CJqYnZm7.d.cts → site-config-C4bcUoLI.d.ts} +22 -2
  88. package/dist/{track-page-view-tX0Magkd.d.cts → track-page-view-C4TbbULE.d.cts} +1 -1
  89. package/dist/{track-page-view-CMAqyhD_.d.ts → track-page-view-RiB-xgIx.d.ts} +1 -1
  90. package/dist/{types-B-111Wht.d.ts → types-DRljY1Yy.d.cts} +92 -2
  91. package/dist/{types-B-111Wht.d.cts → types-DRljY1Yy.d.ts} +92 -2
  92. package/dist/utils-BajG58pj.d.cts +15 -0
  93. package/dist/utils-CHT3SQFv.d.ts +15 -0
  94. package/package.json +7 -2
  95. package/dist/chunk-FNWE2DT5.js.map +0 -1
  96. package/dist/chunk-PG3IOI5O.js.map +0 -1
  97. package/dist/chunk-UVYF33XE.js.map +0 -1
  98. /package/dist/{chunk-KZ4WVDGL.js.map → chunk-7623G3XL.js.map} +0 -0
  99. /package/dist/{chunk-HODG4NJQ.js.map → chunk-HFLU7HQE.js.map} +0 -0
  100. /package/dist/{chunk-DNYJF7BG.js.map → chunk-KPTMZQCY.js.map} +0 -0
@@ -66,6 +66,209 @@ function normalizeBaseUrl(baseUrl) {
66
66
  return baseUrl.replace(/\/$/, "");
67
67
  }
68
68
 
69
+ // src/content/manifest.ts
70
+ var JMP_CONTENT_MANIFEST_VERSION = 1;
71
+ var TRUST_SECTIONS = /* @__PURE__ */ new Set([
72
+ "summary",
73
+ "testimonials",
74
+ "reviews",
75
+ "stats",
76
+ "logos",
77
+ "credentials"
78
+ ]);
79
+ function normalizeKey(value) {
80
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
81
+ }
82
+ function isValidExtraKey(key) {
83
+ return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(key);
84
+ }
85
+ var MAX_EXTERNAL_ADMIN_LINKS = 10;
86
+ var MAX_EXTERNAL_ADMIN_LINK_LABEL_LENGTH = 80;
87
+ var EXTERNAL_ADMIN_LINK_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
88
+ function tryNormalizeHttpUrl(input) {
89
+ if (typeof input !== "string" || !input.trim()) {
90
+ return null;
91
+ }
92
+ try {
93
+ const url = new URL(input.trim());
94
+ if (url.protocol !== "https:" && url.protocol !== "http:") {
95
+ return null;
96
+ }
97
+ return url.toString().replace(/\/$/, "");
98
+ } catch {
99
+ return null;
100
+ }
101
+ }
102
+ function normalizeShopifyExternalSource(shopify) {
103
+ if (!shopify || typeof shopify !== "object") {
104
+ return null;
105
+ }
106
+ const adminUrl = tryNormalizeHttpUrl(shopify.adminUrl);
107
+ const storeUrl = tryNormalizeHttpUrl(shopify.storeUrl);
108
+ if (!adminUrl && !storeUrl) {
109
+ return null;
110
+ }
111
+ return {
112
+ ...adminUrl ? { adminUrl } : {},
113
+ ...storeUrl ? { storeUrl } : {}
114
+ };
115
+ }
116
+ function normalizeExternalAdminLinkEntries(links) {
117
+ if (!Array.isArray(links)) {
118
+ return [];
119
+ }
120
+ const seenIds = /* @__PURE__ */ new Set();
121
+ const out = [];
122
+ for (const raw of links) {
123
+ if (!raw || typeof raw !== "object" || out.length >= MAX_EXTERNAL_ADMIN_LINKS) {
124
+ continue;
125
+ }
126
+ const id = typeof raw.id === "string" ? raw.id.trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") : "";
127
+ const label = typeof raw.label === "string" ? raw.label.trim().slice(0, MAX_EXTERNAL_ADMIN_LINK_LABEL_LENGTH) : "";
128
+ const url = tryNormalizeHttpUrl(raw.url);
129
+ if (!id || !label || !url || !EXTERNAL_ADMIN_LINK_ID_PATTERN.test(id) || seenIds.has(id)) {
130
+ continue;
131
+ }
132
+ seenIds.add(id);
133
+ out.push({ id, label, url });
134
+ }
135
+ return out;
136
+ }
137
+ function normalizeExternalSources(externalSources) {
138
+ if (!externalSources || typeof externalSources !== "object") {
139
+ return null;
140
+ }
141
+ const studioUrl = tryNormalizeHttpUrl(externalSources.sanity?.studioUrl);
142
+ const shopify = normalizeShopifyExternalSource(externalSources.shopify);
143
+ const links = normalizeExternalAdminLinkEntries(externalSources.links);
144
+ if (!studioUrl && !shopify && links.length === 0) {
145
+ return null;
146
+ }
147
+ return {
148
+ ...studioUrl ? { sanity: { studioUrl } } : {},
149
+ ...shopify ? { shopify } : {},
150
+ ...links.length > 0 ? { links } : {}
151
+ };
152
+ }
153
+ function normalizeJmpContentManifest(input) {
154
+ if (!input || typeof input !== "object") {
155
+ return null;
156
+ }
157
+ const routes = normalizeRoutes(input.routes);
158
+ const externalSources = normalizeExternalSources(input.externalSources);
159
+ const trust = normalizeTrust(input.trust);
160
+ const contact = normalizeContact(input.contact);
161
+ if (routes.length === 0 && !externalSources && !trust && !contact) {
162
+ return null;
163
+ }
164
+ return {
165
+ version: JMP_CONTENT_MANIFEST_VERSION,
166
+ ...routes.length > 0 ? { routes } : {},
167
+ ...externalSources ? { externalSources } : {},
168
+ ...trust ? { trust } : {},
169
+ ...contact ? { contact } : {}
170
+ };
171
+ }
172
+ function normalizeRoutes(routes) {
173
+ if (!Array.isArray(routes)) {
174
+ return [];
175
+ }
176
+ const seen = /* @__PURE__ */ new Set();
177
+ const out = [];
178
+ for (const raw of routes) {
179
+ if (!raw || typeof raw !== "object") continue;
180
+ const wrapper = typeof raw.wrapper === "string" ? raw.wrapper.trim().toLowerCase() : "";
181
+ const pattern = typeof raw.pattern === "string" ? raw.pattern.trim() : "";
182
+ if (!wrapper || !pattern) continue;
183
+ const dedupe = `${wrapper}:${pattern}`;
184
+ if (seen.has(dedupe)) continue;
185
+ seen.add(dedupe);
186
+ out.push({
187
+ wrapper,
188
+ pattern,
189
+ ...typeof raw.index === "string" && raw.index.trim() ? { index: raw.index.trim() } : {},
190
+ ...typeof raw.label === "string" && raw.label.trim() ? { label: raw.label.trim() } : {}
191
+ });
192
+ }
193
+ return out;
194
+ }
195
+ function normalizeTrust(trust) {
196
+ if (!trust || typeof trust !== "object") return null;
197
+ const blocks = normalizeTrustBlocks(trust.blocks);
198
+ const labels = normalizeTrustLabels(trust.labels);
199
+ const mergeTestimonialsReviews = trust.mergeTestimonialsReviews === true;
200
+ if (blocks.length === 0 && !labels && !mergeTestimonialsReviews) return null;
201
+ return {
202
+ ...blocks.length > 0 ? { blocks } : {},
203
+ ...labels ? { labels } : {},
204
+ ...mergeTestimonialsReviews ? { mergeTestimonialsReviews: true } : {}
205
+ };
206
+ }
207
+ function normalizeTrustBlocks(blocks) {
208
+ if (!Array.isArray(blocks)) return [];
209
+ const seen = /* @__PURE__ */ new Set();
210
+ const out = [];
211
+ for (const raw of blocks) {
212
+ if (!raw || typeof raw !== "object") continue;
213
+ const section = typeof raw.section === "string" ? raw.section.trim().toLowerCase() : "";
214
+ if (!TRUST_SECTIONS.has(section) || seen.has(section)) continue;
215
+ seen.add(section);
216
+ out.push({
217
+ section,
218
+ ...typeof raw.label === "string" && raw.label.trim() ? { label: raw.label.trim() } : {}
219
+ });
220
+ }
221
+ return out;
222
+ }
223
+ function normalizeTrustLabels(labels) {
224
+ if (!labels || typeof labels !== "object") return null;
225
+ const out = {};
226
+ for (const [key, value] of Object.entries(labels)) {
227
+ if (TRUST_SECTIONS.has(key) && typeof value === "string" && value.trim()) {
228
+ out[key] = value.trim();
229
+ }
230
+ }
231
+ return Object.keys(out).length > 0 ? out : null;
232
+ }
233
+ function normalizeContact(contact) {
234
+ if (!contact || typeof contact !== "object") return null;
235
+ const extras = normalizeContactExtras(contact.extras);
236
+ return extras.length > 0 ? { extras } : null;
237
+ }
238
+ function normalizeContactExtras(extras) {
239
+ if (!Array.isArray(extras)) return [];
240
+ const seen = /* @__PURE__ */ new Set();
241
+ const out = [];
242
+ for (const raw of extras) {
243
+ if (!raw || typeof raw !== "object") continue;
244
+ const label = typeof raw.label === "string" ? raw.label.trim() : "";
245
+ const key = normalizeKey(
246
+ typeof raw.key === "string" && raw.key.trim() ? raw.key : label
247
+ );
248
+ if (!key || !label || !isValidExtraKey(key) || seen.has(key)) continue;
249
+ seen.add(key);
250
+ out.push({ key, label });
251
+ }
252
+ return out;
253
+ }
254
+ function stableJmpManifestFingerprint(manifest) {
255
+ return manifest ? JSON.stringify(manifest) : "";
256
+ }
257
+ function inferWrapperSlotsFromManifest(manifest) {
258
+ const slots = /* @__PURE__ */ new Set();
259
+ for (const route of manifest?.routes ?? []) {
260
+ slots.add(route.wrapper);
261
+ }
262
+ for (const block of manifest?.trust?.blocks ?? []) {
263
+ slots.add(`trust.${block.section}`);
264
+ slots.add("trust");
265
+ }
266
+ if (manifest?.contact?.extras?.length) {
267
+ slots.add("contact");
268
+ }
269
+ return [...slots];
270
+ }
271
+
69
272
  // src/content/fetch.ts
70
273
  async function getContent(config, path) {
71
274
  const text = await getContentText(config, path);
@@ -141,16 +344,22 @@ function markContentWrapper(slot) {
141
344
  function getDiscoveredContentWrappers() {
142
345
  return sortWrapperSlots([...discovered]);
143
346
  }
347
+ function resolveContentManifestForReport(config) {
348
+ return normalizeJmpContentManifest(config.contentManifest);
349
+ }
144
350
  function resolveContentWrappersForReport(config) {
145
351
  const explicit = config.contentWrappers ?? [];
146
352
  const auto = getDiscoveredContentWrappers();
353
+ const fromManifest = inferWrapperSlotsFromManifest(
354
+ resolveContentManifestForReport(config)
355
+ );
147
356
  if (config.contentWrapperMode === "manual") {
148
- return sortWrapperSlots([...explicit]);
357
+ return sortWrapperSlots([...explicit, ...fromManifest]);
149
358
  }
150
359
  if (config.contentWrapperMode === "explicit-only") {
151
- return sortWrapperSlots([...explicit]);
360
+ return sortWrapperSlots([...explicit, ...fromManifest]);
152
361
  }
153
- const merged = /* @__PURE__ */ new Set([...explicit, ...auto]);
362
+ const merged = /* @__PURE__ */ new Set([...explicit, ...auto, ...fromManifest]);
154
363
  return sortWrapperSlots([...merged]);
155
364
  }
156
365
  function hasReportedContentWrappers(dedupeKey) {
@@ -240,7 +449,8 @@ async function registerJmpContentWrappers(config) {
240
449
  if (!wrappers.length) {
241
450
  return { ok: false, skipped: true };
242
451
  }
243
- const dedupeKey = `${config.trackingKey}:${[...wrappers].sort().join(",")}`;
452
+ const manifest = resolveContentManifestForReport(config);
453
+ const dedupeKey = `${config.trackingKey}:${[...wrappers].sort().join(",")}:${stableJmpManifestFingerprint(manifest)}`;
244
454
  if (hasReportedContentWrappers(dedupeKey)) {
245
455
  return { ok: true, wrappers };
246
456
  }
@@ -253,7 +463,17 @@ async function registerJmpContentWrappers(config) {
253
463
  }
254
464
  const url = `${baseUrl}/api/content/capabilities`;
255
465
  if (config.debug) {
256
- console.debug("[@jmp-technologies/analytics]", "POST", url, { wrappers });
466
+ console.debug("[@jmp-technologies/analytics]", "POST", url, {
467
+ wrappers,
468
+ manifest
469
+ });
470
+ }
471
+ const body = {
472
+ wrappers,
473
+ sdkVersion: JMP_ANALYTICS_SDK_VERSION
474
+ };
475
+ if (manifest) {
476
+ body.manifest = manifest;
257
477
  }
258
478
  const res = await resolvedFetch(url, {
259
479
  method: "POST",
@@ -261,10 +481,7 @@ async function registerJmpContentWrappers(config) {
261
481
  "Content-Type": "application/json",
262
482
  "X-JMP-Tracking-Key": config.trackingKey
263
483
  },
264
- body: JSON.stringify({
265
- wrappers,
266
- sdkVersion: JMP_ANALYTICS_SDK_VERSION
267
- })
484
+ body: JSON.stringify(body)
268
485
  });
269
486
  const text = await res.text();
270
487
  if (!res.ok) {
@@ -343,7 +560,8 @@ function getJmpContentConfig() {
343
560
  return {
344
561
  baseUrl: analyticsUrl,
345
562
  trackingKey,
346
- contentWrappers: site?.contentWrappers ?? void 0
563
+ contentWrappers: site?.contentWrappers ?? void 0,
564
+ contentManifest: site?.contentManifest ?? void 0
347
565
  };
348
566
  }
349
567
 
@@ -425,7 +643,6 @@ function filterJmpLandingPagesForLocalizedRoutes(pages, kind) {
425
643
  });
426
644
  }
427
645
  function jmpLocalizedLandingStaticParams(pages, kind) {
428
- const segment = jmpLandingKindSegment(kind);
429
646
  return filterJmpLandingPagesForLocalizedRoutes(pages, kind).map((page) => {
430
647
  const [locale, , slug] = page.path.split("/").filter(Boolean);
431
648
  return { locale, slug };
@@ -612,7 +829,6 @@ async function JmpLandingDetailPage({
612
829
  }
613
830
  async function JmpLandingIndexPage({
614
831
  kind,
615
- siteUrl,
616
832
  components,
617
833
  className,
618
834
  classNames