@tokenoftrust/storefront-runner 2.4.87 → 2.4.88

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 (195) hide show
  1. package/apps/storefront/dev-plugins/tenant-hot-reload.mjs +1 -1
  2. package/apps/storefront/env.d.ts +1 -1
  3. package/apps/storefront/perf/README.md +1 -1
  4. package/apps/storefront/public/shared/commerce-chrome.css +1 -1
  5. package/apps/storefront/public/shared/commerce-marketing.css +1 -1
  6. package/apps/storefront/src/components/catalog/storefront/CollectionCard.astro +1 -1
  7. package/apps/storefront/src/components/catalog/storefront/ProductCard.astro +4 -4
  8. package/apps/storefront/src/components/catalog/storefront/commerce/BrandGrid.astro +1 -1
  9. package/apps/storefront/src/components/catalog/storefront/commerce/PriceDisplay.astro +2 -2
  10. package/apps/storefront/src/components/catalog/storefront/commerce/ProductCarousel.astro +2 -2
  11. package/apps/storefront/src/components/catalog/storefront/commerce/ProductGrid.astro +3 -3
  12. package/apps/storefront/src/components/catalog/storefront/commerce/ReviewList.astro +1 -1
  13. package/apps/storefront/src/components/catalog/storefront/islands/ImageGallery.tsx +1 -1
  14. package/apps/storefront/src/components/catalog/storefront/islands/QuickView.tsx +2 -2
  15. package/apps/storefront/src/components/catalog/storefront/islands/RecentlyViewed.tsx +2 -2
  16. package/apps/storefront/src/components/catalog/storefront/islands/SearchTypeahead.tsx +2 -2
  17. package/apps/storefront/src/components/catalog/storefront/islands/VariantSelector.tsx +1 -1
  18. package/apps/storefront/src/components/compliance/storefront/islands/AgeGate.tsx +2 -2
  19. package/apps/storefront/src/components/compliance/storefront/islands/IsolatedAgeGate.tsx +1 -1
  20. package/apps/storefront/src/components/{AsyncStylesheet.astro → content/storefront/AsyncStylesheet.astro} +2 -2
  21. package/apps/storefront/src/components/{Breadcrumbs.astro → content/storefront/Breadcrumbs.astro} +3 -3
  22. package/apps/storefront/src/components/{Seo.astro → content/storefront/Seo.astro} +5 -5
  23. package/apps/storefront/src/components/{blog → content/storefront/blog}/BlogIndexView.astro +6 -6
  24. package/apps/storefront/src/components/{blog → content/storefront/blog}/BlogPaywall.astro +1 -1
  25. package/apps/storefront/src/components/{blog → content/storefront/blog}/BlogPostArticle.astro +7 -7
  26. package/apps/storefront/src/components/{blog → content/storefront/blog}/PostAccessBadge.astro +1 -1
  27. package/apps/storefront/src/components/{blog → content/storefront/blog}/PostGrid.astro +3 -3
  28. package/apps/storefront/src/components/{blog → content/storefront/blog}/ReactionBar.astro +1 -1
  29. package/apps/storefront/src/components/{blog → content/storefront/blog}/ShareRow.astro +1 -1
  30. package/apps/storefront/src/components/{chrome → content/storefront/chrome}/MegaMenu.astro +3 -3
  31. package/apps/storefront/src/components/{chrome → content/storefront/chrome}/NavDropdown.astro +2 -2
  32. package/apps/storefront/src/components/{chrome → content/storefront/chrome}/SiteFooter.astro +5 -5
  33. package/apps/storefront/src/components/{chrome → content/storefront/chrome}/SiteHeader.astro +8 -8
  34. package/apps/storefront/src/components/{chrome → content/storefront/chrome}/UtilityNav.astro +2 -2
  35. package/apps/storefront/src/components/content/{Callout.astro → storefront/content/Callout.astro} +1 -1
  36. package/apps/storefront/src/components/content/{PromoTiles.astro → storefront/content/PromoTiles.astro} +3 -3
  37. package/apps/storefront/src/components/content/{ProseSections.astro → storefront/content/ProseSections.astro} +3 -3
  38. package/apps/storefront/src/components/{home → content/storefront/home}/Hero.astro +4 -4
  39. package/apps/storefront/src/components/{islands → content/storefront/islands}/MobileNav.tsx +2 -2
  40. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/CardGrid.astro +2 -2
  41. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/CodeSample.astro +1 -1
  42. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/CtaBand.astro +2 -2
  43. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/Faq.astro +5 -5
  44. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/Integrations.astro +3 -3
  45. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/MarketingBlocks.astro +11 -11
  46. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/MarketingCtas.astro +1 -1
  47. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/MarketingHero.astro +2 -2
  48. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/ProofStrip.astro +1 -1
  49. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/SplitCompare.astro +2 -2
  50. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/Steps.astro +2 -2
  51. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/Testimonials.astro +2 -2
  52. package/apps/storefront/src/components/{marketing → content/storefront/marketing}/TrustBar.astro +1 -1
  53. package/apps/storefront/src/components/{style-guide → content/storefront/style-guide}/StyleGuideNav.astro +1 -1
  54. package/apps/storefront/src/components/{the-build → content/storefront/the-build}/TheBuildIndexView.astro +5 -5
  55. package/apps/storefront/src/components/customers/storefront/islands/SavedList.tsx +2 -2
  56. package/apps/storefront/src/layouts/Layout.astro +24 -24
  57. package/apps/storefront/src/lib/assets/shared/imageAttrs.ts +1 -1
  58. package/apps/storefront/src/lib/basePath.ts +1 -1
  59. package/apps/storefront/src/lib/catalog/shared/featuredProductsPresentation.ts +1 -1
  60. package/apps/storefront/src/lib/catalog/tot/tenantCatalog.ts +1 -1
  61. package/apps/storefront/src/lib/{blog → content/blog}/collection.ts +9 -9
  62. package/apps/storefront/src/lib/{blog → content/blog}/postView.ts +3 -3
  63. package/apps/storefront/src/lib/{blog → content/blog}/provider.ts +7 -7
  64. package/apps/storefront/src/lib/{chrome → content/chrome}/footerLegal.ts +2 -2
  65. package/apps/storefront/src/lib/{chrome → content/chrome}/trackingPlacements.ts +1 -1
  66. package/apps/storefront/src/lib/{seo → content/seo}/faqItems.ts +1 -1
  67. package/apps/storefront/src/lib/{seo → content/seo}/structuredData.ts +1 -1
  68. package/apps/storefront/src/lib/{breadcrumbs.ts → content/shared/breadcrumbs.ts} +1 -1
  69. package/apps/storefront/src/lib/{heroSlideshow.ts → content/shared/heroSlideshow.ts} +1 -1
  70. package/apps/storefront/src/lib/{homeVisualParity.ts → content/shared/homeVisualParity.ts} +1 -1
  71. package/apps/storefront/src/lib/{jsonld.ts → content/shared/jsonld.ts} +1 -1
  72. package/apps/storefront/src/lib/{rawChrome.ts → content/shared/rawChrome.ts} +12 -12
  73. package/apps/storefront/src/lib/{rawMarketingHtml.ts → content/shared/rawMarketingHtml.ts} +3 -3
  74. package/apps/storefront/src/lib/{styleGuideThemes.ts → content/shared/styleGuideThemes.ts} +3 -3
  75. package/apps/storefront/src/lib/{storyblok → content/storyblok}/content-model.ts +1 -1
  76. package/apps/storefront/src/lib/{storyblok → content/storyblok}/provider.ts +26 -26
  77. package/apps/storefront/src/lib/{the-build → content/the-build}/provider.ts +1 -1
  78. package/apps/storefront/src/lib/{the-build → content/the-build}/toc.ts +1 -1
  79. package/apps/storefront/src/lib/d1/schema-apps.ts +2 -2
  80. package/apps/storefront/src/lib/email/candidateConflictEmail.ts +1 -1
  81. package/apps/storefront/src/lib/email/magicLinkInviteEmail.ts +1 -1
  82. package/apps/storefront/src/lib/{newsletter → engagement/newsletter}/digest.ts +2 -2
  83. package/apps/storefront/src/lib/{newsletter → engagement/newsletter}/resendClient.ts +1 -1
  84. package/apps/storefront/src/lib/{newsletter → engagement/newsletter}/send.ts +2 -2
  85. package/apps/storefront/src/lib/{newsletter → engagement/newsletter}/subscribers.ts +1 -1
  86. package/apps/storefront/src/lib/{social → engagement/social}/golive.ts +2 -2
  87. package/apps/storefront/src/lib/{social → engagement/social}/notify.ts +1 -1
  88. package/apps/storefront/src/lib/{social → engagement/social}/tokenStore.ts +3 -3
  89. package/apps/storefront/src/lib/{apps → measurement/consent}/consentConfigRead.ts +1 -1
  90. package/apps/storefront/src/lib/{tracking → measurement/tracking}/d1Control.ts +2 -2
  91. package/apps/storefront/src/lib/{tracking → measurement/tracking}/interactionCollector.ts +2 -2
  92. package/apps/storefront/src/lib/{tracking → measurement/tracking}/interactionStore.ts +0 -0
  93. package/apps/storefront/src/lib/{tracking → measurement/tracking}/pruneRollup.ts +2 -2
  94. package/apps/storefront/src/lib/{tracking → measurement/tracking}/publishSafetyNet.ts +1 -1
  95. package/apps/storefront/src/lib/{tracking → measurement/tracking}/tenantD1Registry.ts +2 -2
  96. package/apps/storefront/src/lib/previewReload.ts +1 -1
  97. package/apps/storefront/src/lib/publication/contentProvider.ts +7 -7
  98. package/apps/storefront/src/lib/publication/mountedDiscovery.ts +1 -1
  99. package/apps/storefront/src/lib/publication/rootDiscovery.ts +4 -4
  100. package/apps/storefront/src/middleware/controlPlane.ts +1 -1
  101. package/apps/storefront/src/middleware/renderChain.ts +1 -1
  102. package/apps/storefront/src/pages/[...slug].astro +13 -13
  103. package/apps/storefront/src/pages/api/admin/interaction-insights.ts +3 -3
  104. package/apps/storefront/src/pages/api/blog/[collection]/[slug]/react.ts +1 -1
  105. package/apps/storefront/src/pages/api/newsletter/[collection]/subscribe.ts +3 -3
  106. package/apps/storefront/src/pages/api/newsletter/confirm.ts +1 -1
  107. package/apps/storefront/src/pages/api/newsletter/unsubscribe.ts +1 -1
  108. package/apps/storefront/src/pages/api/rum/vitals.ts +1 -1
  109. package/apps/storefront/src/pages/api/tracking/interaction.ts +5 -5
  110. package/apps/storefront/src/pages/blog/[slug].astro +2 -2
  111. package/apps/storefront/src/pages/blog/author/[author].astro +8 -8
  112. package/apps/storefront/src/pages/blog/category/[category].astro +8 -8
  113. package/apps/storefront/src/pages/blog/index.astro +4 -4
  114. package/apps/storefront/src/pages/blog/page/[n].astro +4 -4
  115. package/apps/storefront/src/pages/blog/tag/[tag].astro +8 -8
  116. package/apps/storefront/src/pages/cart.ts +1 -1
  117. package/apps/storefront/src/pages/collections/[handle].astro +7 -7
  118. package/apps/storefront/src/pages/collections/index.astro +4 -4
  119. package/apps/storefront/src/pages/index.astro +10 -10
  120. package/apps/storefront/src/pages/llms.txt.ts +2 -2
  121. package/apps/storefront/src/pages/products/[handle].astro +11 -11
  122. package/apps/storefront/src/pages/saved.astro +2 -2
  123. package/apps/storefront/src/pages/search.astro +5 -5
  124. package/apps/storefront/src/pages/sitemap.xml.ts +8 -8
  125. package/apps/storefront/src/pages/style-guide/[tenant]/[theme].astro +24 -24
  126. package/apps/storefront/src/pages/style-guide/[tenant]/chrome/[theme].astro +2 -2
  127. package/apps/storefront/src/pages/style-guide/[tenant]/guide/[theme].astro +3 -3
  128. package/apps/storefront/src/pages/style-guide/[tenant]/index.astro +3 -3
  129. package/apps/storefront/src/pages/style-guide/index.astro +1 -1
  130. package/apps/storefront/src/pages/the-build/[slug].astro +10 -10
  131. package/apps/storefront/src/pages/the-build/index.astro +5 -5
  132. package/apps/storefront/src/pages/the-build/page/[n].astro +5 -5
  133. package/apps/storefront/src/pages/the-build/rss.xml.ts +4 -4
  134. package/docs/widget-library-guide.md +36 -36
  135. package/package.json +1 -1
  136. package/packages/public-runtime/src/chrome.ts +4 -4
  137. package/packages/public-runtime/src/tracking-id-derivation.ts +1 -1
  138. /package/apps/storefront/src/components/{Badge.astro → content/storefront/Badge.astro} +0 -0
  139. /package/apps/storefront/src/components/{EmptyState.astro → content/storefront/EmptyState.astro} +0 -0
  140. /package/apps/storefront/src/components/{Section.astro → content/storefront/Section.astro} +0 -0
  141. /package/apps/storefront/src/components/{chrome → content/storefront/chrome}/AnnouncementBar.astro +0 -0
  142. /package/apps/storefront/src/components/{commerce → content/storefront/commerce}/ArticleCard.astro +0 -0
  143. /package/apps/storefront/src/components/content/{NeedsReviewCallout.astro → storefront/content/NeedsReviewCallout.astro} +0 -0
  144. /package/apps/storefront/src/components/content/{ProseToc.astro → storefront/content/ProseToc.astro} +0 -0
  145. /package/apps/storefront/src/components/content/{RichText.astro → storefront/content/RichText.astro} +0 -0
  146. /package/apps/storefront/src/components/content/{TrustStrip.astro → storefront/content/TrustStrip.astro} +0 -0
  147. /package/apps/storefront/src/lib/{blog → content/blog}/access.ts +0 -0
  148. /package/apps/storefront/src/lib/{blog → content/blog}/collectionPaths.ts +0 -0
  149. /package/apps/storefront/src/lib/{blog → content/blog}/markdown.ts +0 -0
  150. /package/apps/storefront/src/lib/{blog → content/blog}/pagination.ts +0 -0
  151. /package/apps/storefront/src/lib/{blog → content/blog}/presentation.ts +0 -0
  152. /package/apps/storefront/src/lib/{blog → content/blog}/reactions.ts +0 -0
  153. /package/apps/storefront/src/lib/{blog → content/blog}/rss.ts +0 -0
  154. /package/apps/storefront/src/lib/{blog → content/blog}/teaser.ts +0 -0
  155. /package/apps/storefront/src/lib/{blog → content/blog}/types.ts +0 -0
  156. /package/apps/storefront/src/lib/{blog → content/blog}/viewCounts.ts +0 -0
  157. /package/apps/storefront/src/lib/{chrome → content/chrome}/ctaIdentity.ts +0 -0
  158. /package/apps/storefront/src/lib/{chrome → content/chrome}/examples/tokenoftrust.chrome-assignments.example.json +0 -0
  159. /package/apps/storefront/src/lib/{chrome → content/chrome}/examples/tokenoftrust.chrome.example.json +0 -0
  160. /package/apps/storefront/src/lib/{chrome → content/chrome}/managedCart.ts +0 -0
  161. /package/apps/storefront/src/lib/{chrome → content/chrome}/model.ts +0 -0
  162. /package/apps/storefront/src/lib/{chrome → content/chrome}/navCurrent.ts +0 -0
  163. /package/apps/storefront/src/lib/{chrome → content/chrome}/newsletterAgeAttestation.ts +0 -0
  164. /package/apps/storefront/src/lib/{chrome → content/chrome}/parseConfig.ts +0 -0
  165. /package/apps/storefront/src/lib/{chrome → content/chrome}/variant.ts +0 -0
  166. /package/apps/storefront/src/lib/{commerce → content/policies}/shippingPolicy.ts +0 -0
  167. /package/apps/storefront/src/lib/{seo → content/seo}/alternates.ts +0 -0
  168. /package/apps/storefront/src/lib/{seo → content/seo}/documentTitle.ts +0 -0
  169. /package/apps/storefront/src/lib/{seo → content/seo}/meta.ts +0 -0
  170. /package/apps/storefront/src/lib/{seo → content/seo}/urlForm.ts +0 -0
  171. /package/apps/storefront/src/lib/{asyncCss.ts → content/shared/asyncCss.ts} +0 -0
  172. /package/apps/storefront/src/lib/{colors.ts → content/shared/colors.ts} +0 -0
  173. /package/apps/storefront/src/lib/{format.ts → content/shared/format.ts} +0 -0
  174. /package/apps/storefront/src/lib/{i18n.ts → content/shared/i18n.ts} +0 -0
  175. /package/apps/storefront/src/lib/{jsonScript.ts → content/shared/jsonScript.ts} +0 -0
  176. /package/apps/storefront/src/lib/{placeholder.ts → content/shared/placeholder.ts} +0 -0
  177. /package/apps/storefront/src/lib/{sections.ts → content/shared/sections.ts} +0 -0
  178. /package/apps/storefront/src/lib/{styleGuidePaths.ts → content/shared/styleGuidePaths.ts} +0 -0
  179. /package/apps/storefront/src/lib/{the-build → content/the-build}/pagination.ts +0 -0
  180. /package/apps/storefront/src/lib/{the-build → content/the-build}/readingTime.ts +0 -0
  181. /package/apps/storefront/src/lib/{messaging → engagement/messaging}/messagesClient.ts +0 -0
  182. /package/apps/storefront/src/lib/{newsletter → engagement/newsletter}/confirmationEmail.ts +0 -0
  183. /package/apps/storefront/src/lib/{newsletter → engagement/newsletter}/consent.ts +0 -0
  184. /package/apps/storefront/src/lib/{admin → measurement/admin}/consentSettingsClient.ts +0 -0
  185. /package/apps/storefront/src/lib/{analytics → measurement/analytics}/index.ts +0 -0
  186. /package/apps/storefront/src/lib/{apps/orders → measurement/attribution}/attributionService.ts +0 -0
  187. /package/apps/storefront/src/lib/{apps/orders → measurement/attribution}/orderConversionD1.ts +0 -0
  188. /package/apps/storefront/src/lib/{apps/orders → measurement/attribution}/verifiedProviderMeasurement.ts +0 -0
  189. /package/apps/storefront/src/lib/{tracking → measurement/tracking}/collectorAllowlist.ts +0 -0
  190. /package/apps/storefront/src/lib/{tracking → measurement/tracking}/collectorIngest.ts +0 -0
  191. /package/apps/storefront/src/lib/{tracking → measurement/tracking}/interactionHealth.ts +0 -0
  192. /package/apps/storefront/src/lib/{tracking → measurement/tracking}/interactionSchema.ts +0 -0
  193. /package/apps/storefront/src/lib/{tracking → measurement/tracking}/tenantReadAccess.ts +0 -0
  194. /package/apps/storefront/src/lib/{tracking-writeback → measurement/tracking-writeback}/rewriteTrackingIds.ts +0 -0
  195. /package/apps/storefront/src/lib/{tracking-writeback → measurement/tracking-writeback}/writebackCandidate.ts +0 -0
@@ -1,5 +1,5 @@
1
1
  import { tenantDirSegment } from "@tot/public-runtime";
2
- import type { ContentProvider } from "@/lib/storyblok/provider";
2
+ import type { ContentProvider } from "@/lib/content/storyblok/provider";
3
3
 
4
4
  export type StyleGuideTheme = Record<string, unknown> & {
5
5
  id: string;
@@ -11,8 +11,8 @@ export type StyleGuideTheme = Record<string, unknown> & {
11
11
 
12
12
  const localThemeModules = import.meta.glob<Record<string, unknown>>(
13
13
  [
14
- "../../../../tenants/*/content/themes/*.json",
15
- "../../../../tenants/e2e/*/content/themes/*.json",
14
+ "../../../../../../tenants/*/content/themes/*.json",
15
+ "../../../../../../tenants/e2e/*/content/themes/*.json",
16
16
  ],
17
17
  { eager: true, import: "default" },
18
18
  );
@@ -354,6 +354,6 @@ export interface EditorialPage {
354
354
  }
355
355
 
356
356
  // Site chrome (header/footer) is the ONE consolidated schema in
357
- // lib/chrome/model.ts (`ChromeConfig`) — see that file's header comment for
357
+ // lib/content/chrome/model.ts (`ChromeConfig`) — see that file's header comment for
358
358
  // why the old `SiteChrome`/`SiteNavItem` pair that used to live here was
359
359
  // retired.
@@ -33,10 +33,10 @@ import {
33
33
  tenantDirRelative,
34
34
  tenantDirSegment,
35
35
  } from "@tot/public-runtime";
36
- import { renderRawChrome } from "../rawChrome.js";
36
+ import { renderRawChrome } from "../shared/rawChrome.js";
37
37
  import { parseChromeConfig } from "../chrome/parseConfig.js";
38
38
  import { parseChromeAssignments } from "../chrome/model.js";
39
- import { stampTrackingIdsAtPublish } from "../tracking/publishSafetyNet.js";
39
+ import { stampTrackingIdsAtPublish } from "../../measurement/tracking/publishSafetyNet.js";
40
40
  import { readWithImagePreviewRewriteOverlay } from "@tot/public-runtime/image-preview-rewrite-overlay";
41
41
 
42
42
  /** Safe, always-valid fallback when neither the tenant's own chrome.json nor
@@ -67,7 +67,7 @@ export interface ContentProvider {
67
67
  /**
68
68
  * The tenant's shared-chrome WRAPPER document (raw HTML), or null. A full
69
69
  * document containing the CHROME_BODY_MARKER where a body-only page fragment is
70
- * spliced in (see lib/rawMarketingHtml.ts). Lets raw pages stop duplicating
70
+ * spliced in (see lib/content/shared/rawMarketingHtml.ts). Lets raw pages stop duplicating
71
71
  * chrome: chrome lives once here, pages become fragments. File:
72
72
  * `content/<tenant>/chrome.html`. Tenant-owned (no cross-tenant fallback).
73
73
  *
@@ -110,17 +110,17 @@ export interface DerivedArtifact {
110
110
  // Per-tenant local content lives under the colocated repo-root layout
111
111
  // tenants/<tenant_id>/content/. Vite globs bundle every tenant's JSON at build
112
112
  // time; a file missing for a tenant falls back to the default scope, so a
113
- // partially-adopted tenant still renders. Depth: from src/lib/storyblok/ the
114
- // repo root is five levels up (storyblok→lib→src→storefront→apps→root).
113
+ // partially-adopted tenant still renders. Depth: from src/lib/content/storyblok/ the
114
+ // repo root is six levels up (storyblok→content→lib→src→storefront→apps→root).
115
115
  const homeGlobs = import.meta.glob<HomeContent>([
116
- "../../../../../tenants/*/content/home.json",
117
- "../../../../../tenants/e2e/*/content/home.json",
116
+ "../../../../../../tenants/*/content/home.json",
117
+ "../../../../../../tenants/e2e/*/content/home.json",
118
118
  ], {
119
119
  import: "default",
120
120
  });
121
121
  const chromeGlobs = import.meta.glob<unknown>([
122
- "../../../../../tenants/*/content/chrome.json",
123
- "../../../../../tenants/e2e/*/content/chrome.json",
122
+ "../../../../../../tenants/*/content/chrome.json",
123
+ "../../../../../../tenants/e2e/*/content/chrome.json",
124
124
  ], {
125
125
  import: "default",
126
126
  });
@@ -129,22 +129,22 @@ const chromeGlobs = import.meta.glob<unknown>([
129
129
  // convention as chromeGlobs above.
130
130
  const chromeAssignmentGlobs = import.meta.glob<unknown>(
131
131
  [
132
- "../../../../../tenants/*/content/chrome-assignments.json",
133
- "../../../../../tenants/e2e/*/content/chrome-assignments.json",
132
+ "../../../../../../tenants/*/content/chrome-assignments.json",
133
+ "../../../../../../tenants/e2e/*/content/chrome-assignments.json",
134
134
  ],
135
135
  { import: "default" },
136
136
  );
137
137
  const pageGlobs = import.meta.glob<EditorialPage>([
138
- "../../../../../tenants/*/content/pages/*.json",
139
- "../../../../../tenants/e2e/*/content/pages/*.json",
138
+ "../../../../../../tenants/*/content/pages/*.json",
139
+ "../../../../../../tenants/e2e/*/content/pages/*.json",
140
140
  ], {
141
141
  import: "default",
142
142
  });
143
143
  // Raw self-authored home documents (marketing tenants). `?raw` bundles the file
144
144
  // as a string; a tenant with no home.html simply has no entry here.
145
145
  const homeHtmlGlobs = import.meta.glob<string>([
146
- "../../../../../tenants/*/content/home.html",
147
- "../../../../../tenants/e2e/*/content/home.html",
146
+ "../../../../../../tenants/*/content/home.html",
147
+ "../../../../../../tenants/e2e/*/content/home.html",
148
148
  ], {
149
149
  query: "?raw",
150
150
  import: "default",
@@ -152,8 +152,8 @@ const homeHtmlGlobs = import.meta.glob<string>([
152
152
  // Raw self-authored SUBPAGE documents: tenants/<tenant>/content/pages-html/<slug>.html
153
153
  // (e.g. pages-html/pricing.html -> /pricing/). `**` supports nested slugs.
154
154
  const pageHtmlGlobs = import.meta.glob<string>([
155
- "../../../../../tenants/*/content/pages-html/**/*.html",
156
- "../../../../../tenants/e2e/*/content/pages-html/**/*.html",
155
+ "../../../../../../tenants/*/content/pages-html/**/*.html",
156
+ "../../../../../../tenants/e2e/*/content/pages-html/**/*.html",
157
157
  ], {
158
158
  query: "?raw",
159
159
  import: "default",
@@ -161,15 +161,15 @@ const pageHtmlGlobs = import.meta.glob<string>([
161
161
  // Shared-chrome wrapper document (marketing tenants that author body-only page
162
162
  // fragments). One per tenant; a tenant without it keeps serving full documents.
163
163
  const chromeHtmlGlobs = import.meta.glob<string>([
164
- "../../../../../tenants/*/content/chrome.html",
165
- "../../../../../tenants/e2e/*/content/chrome.html",
164
+ "../../../../../../tenants/*/content/chrome.html",
165
+ "../../../../../../tenants/e2e/*/content/chrome.html",
166
166
  ], {
167
167
  query: "?raw",
168
168
  import: "default",
169
169
  });
170
170
  const artifactGlobs = import.meta.glob<string>([
171
- "../../../../../tenants/*/content/**/*",
172
- "../../../../../tenants/e2e/*/content/**/*",
171
+ "../../../../../../tenants/*/content/**/*",
172
+ "../../../../../../tenants/e2e/*/content/**/*",
173
173
  ], {
174
174
  query: "?raw",
175
175
  import: "default",
@@ -251,10 +251,10 @@ async function readRawDevFile(scope: string, relative: string): Promise<string |
251
251
  import("node:url"),
252
252
  import("node:path"),
253
253
  ]);
254
- // provider.ts lives at apps/storefront/src/lib/storyblok/ — the repo root is five
255
- // levels up, mirroring the import.meta.glob prefix ("../../../../../tenants/...").
254
+ // provider.ts lives at apps/storefront/src/lib/content/storyblok/ — the repo root is six
255
+ // levels up, mirroring the import.meta.glob prefix ("../../../../../../tenants/...").
256
256
  const here = dirname(fileURLToPath(import.meta.url));
257
- const abs = resolve(here, "../../../../..", ...tenantDirRelative(scope).split("/"), "content", relative);
257
+ const abs = resolve(here, "../../../../../..", ...tenantDirRelative(scope).split("/"), "content", relative);
258
258
  return await readFile(abs, "utf8");
259
259
  } catch {
260
260
  return null;
@@ -305,7 +305,7 @@ export class LocalContentProvider implements ContentProvider {
305
305
  if (loader) return loader();
306
306
  // (2) No chrome.html: render the CANONICAL shared chrome from the
307
307
  // tenant's chrome.json — but only when it validates whole against the
308
- // consolidated ChromeConfig schema (lib/chrome/parseConfig.ts). Tenant-
308
+ // consolidated ChromeConfig schema (lib/content/chrome/parseConfig.ts). Tenant-
309
309
  // owned only, like the raw HTML above (no cross-tenant fallback).
310
310
  const config = await this.loadChromeConfig();
311
311
  if (!config) return null;
@@ -708,7 +708,7 @@ export class PublishedContentProvider implements ContentProvider {
708
708
  }
709
709
  async getChrome(): Promise<ChromeConfig> {
710
710
  // Runs through the SAME fail-closed schema validator as getChromeHtml's
711
- // chrome.json branch (lib/chrome/parseConfig.ts) — a published artifact is
711
+ // chrome.json branch (lib/content/chrome/parseConfig.ts) — a published artifact is
712
712
  // no longer trusted blind (was: JSON.parse + a raw cast to SiteChrome).
713
713
  const config = parseChromeConfig(await this.published<unknown>("chrome.json"));
714
714
  return config ?? ((await this.usesVersionedContent()) ? EMPTY_CHROME_CONFIG : this.base.getChrome());
@@ -1,5 +1,5 @@
1
1
  // Thin wrapper binding the generic blog engine to the "the-build" collection.
2
- // The engine (src/lib/blog/collection.ts) is the single implementation; this
2
+ // The engine (src/lib/content/blog/collection.ts) is the single implementation; this
3
3
  // module only fixes the collection id so existing/downstream callers can import
4
4
  // collection-bound helpers.
5
5
  import { getIndexSettings, getPost, listPosts, resolveRedirect, type Collection } from "../blog/collection.js";
@@ -5,7 +5,7 @@
5
5
  // (`annotate`), so a render path can feed `htmlWithHeadingIds(post.contentHtml)`
6
6
  // to `set:html` and `toc(post.contentHtml)` to the aside and the anchors line up.
7
7
  import { parseFragment, serialize } from "parse5";
8
- import { slugifyHeading } from "../content/prose.js";
8
+ import { slugifyHeading } from "../prose.js";
9
9
 
10
10
  /** Minimal structural view of a parse5 node (duck-typed, as scripts/dev/locate.mjs does). */
11
11
  interface P5Node {
@@ -151,7 +151,7 @@ export const activityEvents = sqliteTable(
151
151
 
152
152
  // --- Per-tenant raw-interaction store directory ------------------------------
153
153
  // The DIRECTORY of per-tenant D1 databases that hold raw declarative-tracking
154
- // interaction rows — one database per tenant (`lib/tracking/interactionSchema.ts`
154
+ // interaction rows — one database per tenant (`lib/measurement/tracking/interactionSchema.ts`
155
155
  // is that database's schema). This table holds NO interaction data: only the
156
156
  // `tenant_id → (database_name, database_uuid)` mapping the Worker needs to
157
157
  // address a tenant's own database over the D1 REST API, since Worker bindings
@@ -177,7 +177,7 @@ export const trackingTenantDatabases = sqliteTable(
177
177
  {
178
178
  tenantId: text("tenant_id").primaryKey(),
179
179
  // The Cloudflare D1 database name, derived deterministically from the tenant
180
- // id (`lib/tracking/tenantD1Registry.ts`) — recorded so an operator can find
180
+ // id (`lib/measurement/tracking/tenantD1Registry.ts`) — recorded so an operator can find
181
181
  // it in the dashboard without re-deriving.
182
182
  databaseName: text("database_name").notNull(),
183
183
  // The D1 UUID — what the REST data plane actually addresses.
@@ -6,7 +6,7 @@
6
6
  * notification for that case — the author is pinged the MOMENT their change actually
7
7
  * conflicts with someone else's merge, not at their own accept attempt.
8
8
  *
9
- * Rendered here (our brand), transmitted by tot20 (see lib/messaging/messagesClient.ts).
9
+ * Rendered here (our brand), transmitted by tot20 (see lib/engagement/messaging/messagesClient.ts).
10
10
  * Email HTML rules: inline styles only, table-free simple layout, a visible fallback URL
11
11
  * under the button.
12
12
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * The storefront's OWN branded developer-invite email (magic-link flow). The storefront
3
3
  * owns presentation now — this is our template, our brand, rendered here and handed to
4
- * tot20 only for transport (see lib/messaging/messagesClient.ts). A single primary CTA
4
+ * tot20 only for transport (see lib/engagement/messaging/messagesClient.ts). A single primary CTA
5
5
  * links to the GET-safe /auth/magic landing carrying the one-time token.
6
6
  *
7
7
  * Email HTML rules: inline styles only (no <style>/external CSS — mail clients strip them),
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Hand-rolled newsletter digest HTML builder — the email analogue of
3
- * `renderRssFeed` (src/lib/blog/rss.ts): pure string concatenation, no
3
+ * `renderRssFeed` (src/lib/content/blog/rss.ts): pure string concatenation, no
4
4
  * templating dependency. Fed the engine's live-visible post list, so drafts /
5
5
  * unlisted / not-yet-scheduled posts can never reach an inbox.
6
6
  *
@@ -10,7 +10,7 @@
10
10
  * ESP (see send.ts). The RFC 8058 `List-Unsubscribe` headers are set on the
11
11
  * SEND call, not in this HTML body.
12
12
  */
13
- import type { BlogPostSummary } from "../blog/types.js";
13
+ import type { BlogPostSummary } from "../../content/blog/types.js";
14
14
 
15
15
  /** Replaced per-recipient with the subscriber's opaque token at send time. */
16
16
  export const UNSUBSCRIBE_TOKEN_PLACEHOLDER = "{{unsubscribe_token}}";
@@ -5,7 +5,7 @@
5
5
  * (`POST /emails/batch`, up to 100 messages/call); audience/consent/unsubscribe
6
6
  * state stays first-party in our D1, never in a vendor list.
7
7
  */
8
- import { readEnv } from "../env.js";
8
+ import { readEnv } from "../../env.js";
9
9
 
10
10
  /** Resend's batch limit: at most 100 messages per `/emails/batch` call. */
11
11
  export const RESEND_BATCH_LIMIT = 100;
@@ -18,8 +18,8 @@
18
18
  * per-subscriber diff. "New since last send" is computed once from the previous
19
19
  * ledger row's `sent_at`, not per-subscriber.
20
20
  */
21
- import type { Queryable } from "../catalog/d1/catalog.js";
22
- import type { BlogPostSummary } from "../blog/types.js";
21
+ import type { Queryable } from "../../catalog/d1/catalog.js";
22
+ import type { BlogPostSummary } from "../../content/blog/types.js";
23
23
  import {
24
24
  sendBatch as realSendBatch,
25
25
  RESEND_BATCH_LIMIT,
@@ -9,7 +9,7 @@
9
9
  * caller is responsible for resolving `tenantId` from the request host/session
10
10
  * (NEVER a client body) — that is the multi-tenant isolation boundary.
11
11
  */
12
- import type { Queryable } from "../catalog/d1/catalog.js";
12
+ import type { Queryable } from "../../catalog/d1/catalog.js";
13
13
 
14
14
  export type SubscriberStatus = "pending" | "confirmed" | "unsubscribed" | "bounced";
15
15
 
@@ -25,8 +25,8 @@
25
25
  * so the first ship after this hook deploys does NOT retro-announce the tenant's
26
26
  * whole back-catalog.
27
27
  */
28
- import { isVisibleOnLive } from "../blog/collection.js";
29
- import type { BlogPost, PostStatus } from "../blog/types.js";
28
+ import { isVisibleOnLive } from "../../content/blog/collection.js";
29
+ import type { BlogPost, PostStatus } from "../../content/blog/types.js";
30
30
  import { notifyPostPublished } from "./notify.js";
31
31
 
32
32
  /**
@@ -1,4 +1,4 @@
1
- import type { BlogPost } from "../blog/types.js";
1
+ import type { BlogPost } from "../../content/blog/types.js";
2
2
 
3
3
  /** Swallow-and-log a soft failure — logging itself must never throw (mirrors `webhooks/emit.ts`). */
4
4
  function logDiag(fields: Record<string, unknown>): void {
@@ -18,8 +18,8 @@
18
18
  * root that wires the real bindings (mirrors `getDispatcher()`); it returns
19
19
  * `null` when either binding is absent so callers degrade rather than throw.
20
20
  */
21
- import type { Queryable } from "../catalog/d1/catalog.js";
22
- import { readD1, readEnv } from "../env.js";
21
+ import type { Queryable } from "../../catalog/d1/catalog.js";
22
+ import { readD1, readEnv } from "../../env.js";
23
23
 
24
24
  /** The decrypted token material we persist as one JSON blob under AES-GCM. */
25
25
  export interface SocialTokenPayload {
@@ -162,7 +162,7 @@ export async function rotateSocialToken(
162
162
  */
163
163
  export async function resolveSocialTokenStore(): Promise<SocialTokenStoreDeps | null> {
164
164
  const [{ fromD1 }, d1, rawKek] = await Promise.all([
165
- import("../catalog/d1/catalog.js"),
165
+ import("../../catalog/d1/catalog.js"),
166
166
  readD1("STOREFRONT_APPS_DB"),
167
167
  readEnv("SOCIAL_TOKEN_KEK"),
168
168
  ]);
@@ -5,7 +5,7 @@
5
5
  * latest validated configuration and none of the authoring or history surface.
6
6
  */
7
7
  import type { TenantConsentConfig } from "@tot/public-runtime";
8
- import type { Queryable } from "../catalog/d1/catalog.js";
8
+ import type { Queryable } from "../../catalog/d1/catalog.js";
9
9
 
10
10
  interface CurrentConsentConfigRow {
11
11
  config: string;
@@ -21,8 +21,8 @@
21
21
  * stores use (`d1/catalog.ts`), so the insert code in `interactionStore.ts` is
22
22
  * transport-agnostic and unit-testable against an in-memory sqlite.
23
23
  */
24
- import { readEnv } from "../env.js";
25
- import type { Queryable, QueryStatement } from "../catalog/d1/catalog.js";
24
+ import { readEnv } from "../../env.js";
25
+ import type { Queryable, QueryStatement } from "../../catalog/d1/catalog.js";
26
26
 
27
27
  const CF_API_BASE = "https://api.cloudflare.com/client/v4";
28
28
 
@@ -9,7 +9,7 @@
9
9
  * e.g. `dt-consent-environment-gate`):
10
10
  *
11
11
  * import { onInteraction } from "@tot/public-runtime";
12
- * import { collectInteraction } from "@/lib/tracking/interactionCollector";
12
+ * import { collectInteraction } from "@/lib/measurement/tracking/interactionCollector";
13
13
  * onInteraction((interaction) => {
14
14
  * if (consentAndEnvironmentAllow()) collectInteraction(interaction);
15
15
  * });
@@ -38,7 +38,7 @@ export const MAX_QUEUE_SIZE = 20;
38
38
  /** The wire shape POSTed to `INTERACTION_BEACON_PATH` — `TotInteraction`'s five
39
39
  * fields plus this module's own synthesized correlation fields. Must stay in
40
40
  * lockstep with `INTERACTION_WIRE_ALLOWLIST`
41
- * (`apps/storefront/src/lib/tracking/collectorAllowlist.ts`). */
41
+ * (`apps/storefront/src/lib/measurement/tracking/collectorAllowlist.ts`). */
42
42
  export interface InteractionWireEvent {
43
43
  type: TotInteraction["type"];
44
44
  el: string;
@@ -44,8 +44,8 @@
44
44
  * transient D1 fault) is caught, logged, and recorded in that tenant's
45
45
  * outcome — it never aborts the rest of the batch.
46
46
  */
47
- import type { Queryable } from "../catalog/d1/catalog.js";
48
- import type { AnalyticsEngineLike } from "../activity/store.js";
47
+ import type { Queryable } from "../../catalog/d1/catalog.js";
48
+ import type { AnalyticsEngineLike } from "../../activity/store.js";
49
49
  import { fromD1Rest, type D1ControlConfig } from "./d1Control.js";
50
50
  import { aggregateInteractions, writeInteractionAnalytics } from "./interactionStore.js";
51
51
  import type { StampedInteractionEvent } from "./collectorIngest.js";
@@ -6,7 +6,7 @@
6
6
  * that proposes `data-tot-el` for git-tracked tenant content and writes it
7
7
  * back to source as a reviewable diff. This module exists for everything
8
8
  * that bypasses that review — AI-edit drafts materialized into
9
- * `dev-draft:` KV (see `DevDraftContentProvider`, lib/storyblok/provider.ts)
9
+ * `dev-draft:` KV (see `DevDraftContentProvider`, lib/content/storyblok/provider.ts)
10
10
  * and direct KV-published edits (`PublishedContentProvider`'s overlay over
11
11
  * the customization store). Content sourced from `LocalContentProvider`
12
12
  * (build-bundled from git-tracked `tenants/<id>/content/*`) is explicitly
@@ -31,8 +31,8 @@
31
31
  * never fail because storage is unconfigured.
32
32
  */
33
33
  import { sha256Hex } from "@tot/public-runtime";
34
- import { readEnv } from "../env.js";
35
- import type { Queryable } from "../catalog/d1/catalog.js";
34
+ import { readEnv } from "../../env.js";
35
+ import type { Queryable } from "../../catalog/d1/catalog.js";
36
36
  import {
37
37
  ensureDatabase,
38
38
  fromD1Rest,
@@ -108,7 +108,7 @@ export function buildPreviewReloadScript(opts: {
108
108
  */
109
109
  export function buildCspViolationBannerScript(basePath = ""): string {
110
110
  // A style-guide surface is `/_style-guide/…` or `/style-guide/…`, under the tenant
111
- // prefix when path-routed (lib/styleGuidePaths.ts).
111
+ // prefix when path-routed (lib/content/shared/styleGuidePaths.ts).
112
112
  return `(() => {
113
113
  if (window.__totCspBanner) return; window.__totCspBanner = true;
114
114
  const seen = new Set();
@@ -2,13 +2,13 @@ import type {
2
2
  OpenPublicationArtifactV1,
3
3
  PublicationRouteRenderPlanV1,
4
4
  } from "@tot/public-runtime";
5
- import { hasHomeContentShape, type EditorialPage, type HomeContent } from "@/lib/storyblok/content-model.js";
6
- import type { ChromeConfig } from "@/lib/chrome/model.js";
7
- import { parseChromeConfig } from "@/lib/chrome/parseConfig.js";
8
- import { parseChromeAssignments } from "@/lib/chrome/model.js";
9
- import { renderRawChrome } from "@/lib/rawChrome.js";
10
- import { stampTrackingIdsAtPublish } from "@/lib/tracking/publishSafetyNet.js";
11
- import type { ContentProvider } from "@/lib/storyblok/provider.js";
5
+ import { hasHomeContentShape, type EditorialPage, type HomeContent } from "@/lib/content/storyblok/content-model.js";
6
+ import type { ChromeConfig } from "@/lib/content/chrome/model.js";
7
+ import { parseChromeConfig } from "@/lib/content/chrome/parseConfig.js";
8
+ import { parseChromeAssignments } from "@/lib/content/chrome/model.js";
9
+ import { renderRawChrome } from "@/lib/content/shared/rawChrome.js";
10
+ import { stampTrackingIdsAtPublish } from "@/lib/measurement/tracking/publishSafetyNet.js";
11
+ import type { ContentProvider } from "@/lib/content/storyblok/provider.js";
12
12
 
13
13
  const EMPTY_CHROME_CONFIG: ChromeConfig = {
14
14
  header: { variant: "primary", brand: { label: "" }, nav: [] },
@@ -29,7 +29,7 @@ import {
29
29
  type PublicationDiscoveryEntryKindV1,
30
30
  } from "@tot/public-runtime";
31
31
  import { publicationRecoveryActiveV1, publicationRecoveryKeyV1 } from "@tot/public-runtime/publication-recovery";
32
- import { rawPageCanonicalUrl } from "../rawMarketingHtml.js";
32
+ import { rawPageCanonicalUrl } from "../content/shared/rawMarketingHtml.js";
33
33
 
34
34
  export type DiscoverySurfaceV1 = "sitemap" | "feeds" | "publicSearch" | "llms";
35
35
 
@@ -5,10 +5,10 @@
5
5
  * Paths are spelled exactly as the root sitemap lists them.
6
6
  */
7
7
  import type { APIContext } from "astro";
8
- import { getBlogSettings, listBlogPosts } from "@/lib/blog/provider.js";
9
- import { listBuildPosts } from "@/lib/the-build/provider.js";
10
- import { isIndexableHtml, rawPageCanonicalUrl } from "@/lib/rawMarketingHtml.js";
11
- import { collectionPathsV1, blogPathOptsV1 } from "@/lib/blog/collectionPaths.js";
8
+ import { getBlogSettings, listBlogPosts } from "@/lib/content/blog/provider.js";
9
+ import { listBuildPosts } from "@/lib/content/the-build/provider.js";
10
+ import { isIndexableHtml, rawPageCanonicalUrl } from "@/lib/content/shared/rawMarketingHtml.js";
11
+ import { collectionPathsV1, blogPathOptsV1 } from "@/lib/content/blog/collectionPaths.js";
12
12
 
13
13
  export interface RootDiscoveryDocumentV1 {
14
14
  kind: "home" | "page" | "post";
@@ -9,7 +9,7 @@
9
9
  import type { APIContext, MiddlewareNext } from "astro";
10
10
  import { readEnv, readD1, readKv } from "@/lib/env";
11
11
  import { fromD1, type D1Like } from "@/lib/catalog/d1/catalog";
12
- import { readCurrentTenantConsentConfig } from "@/lib/apps/consentConfigRead";
12
+ import { readCurrentTenantConsentConfig } from "@/lib/measurement/consent/consentConfigRead";
13
13
  import { loadActiveManagedInstallDeclarations } from "@/lib/integrations/integration/managedInstallDeclarations";
14
14
  import { buildTenantConsentBroker, verifyPreviewToken } from "@tot/public-runtime";
15
15
  import { tenantIsDeclaredPublic } from "@/config/tenants";
@@ -16,7 +16,7 @@ import { readEnv, readR2 } from "@/lib/runtimeEnv";
16
16
  import { tryServeStaticBundle } from "./staticBundle.js";
17
17
  import { isPlatformPublicDiscoveryPath } from "./routeBranch.js";
18
18
  import { resolveCandidateContentPin, type CandidateContentPin } from "./candidatePin.js";
19
- import { createContentProvider, DevDraftContentProvider } from "@/lib/storyblok/provider";
19
+ import { createContentProvider, DevDraftContentProvider } from "@/lib/content/storyblok/provider";
20
20
  import { bindPublicationSpaceContentProviderV1 } from "@/lib/publication/contentProvider.js";
21
21
  import { resolvePublicationRuntimeSourceV1 } from "@/lib/publication/runtimeSource.js";
22
22
  import { DEV_DRAFT_COOKIE, devDraftKey, verifyDevDraftToken } from "@/lib/dev/devDraft";
@@ -6,19 +6,19 @@
6
6
  * prefixes so a stray slug can never shadow a real route.
7
7
  */
8
8
  import Layout from "@/layouts/Layout.astro";
9
- import Breadcrumbs from "@/components/Breadcrumbs.astro";
10
- import { homeCrumbLabel, siteTrail } from "@/lib/breadcrumbs";
11
- import ProseSections from "@/components/content/ProseSections.astro";
12
- import ProseToc from "@/components/content/ProseToc.astro";
13
- import { breadcrumbLd } from "@/lib/jsonld";
14
- import { truncate } from "@/lib/format";
15
- import { faqFromHtml, faqFromSections } from "@/lib/seo/faqItems";
16
- import { rawHtmlPolicy, rawHtmlResponse, rawPageCanonicalUrl } from "@/lib/rawMarketingHtml";
9
+ import Breadcrumbs from "@/components/content/storefront/Breadcrumbs.astro";
10
+ import { homeCrumbLabel, siteTrail } from "@/lib/content/shared/breadcrumbs";
11
+ import ProseSections from "@/components/content/storefront/content/ProseSections.astro";
12
+ import ProseToc from "@/components/content/storefront/content/ProseToc.astro";
13
+ import { breadcrumbLd } from "@/lib/content/shared/jsonld";
14
+ import { truncate } from "@/lib/content/shared/format";
15
+ import { faqFromHtml, faqFromSections } from "@/lib/content/seo/faqItems";
16
+ import { rawHtmlPolicy, rawHtmlResponse, rawPageCanonicalUrl } from "@/lib/content/shared/rawMarketingHtml";
17
17
  import { renderRawComplianceTop, renderRawComplianceBottom } from "@/lib/compliance/rawComplianceNotices";
18
- import { styleGuideAliasRewrite } from "@/lib/styleGuidePaths";
19
- import { getBlogSettings } from "@/lib/blog/provider.js";
20
- import { loadBlogPostViewV1, type BlogPostViewPropsV1 } from "@/lib/blog/postView.js";
21
- import BlogPostArticle from "@/components/blog/BlogPostArticle.astro";
18
+ import { styleGuideAliasRewrite } from "@/lib/content/shared/styleGuidePaths";
19
+ import { getBlogSettings } from "@/lib/content/blog/provider.js";
20
+ import { loadBlogPostViewV1, type BlogPostViewPropsV1 } from "@/lib/content/blog/postView.js";
21
+ import BlogPostArticle from "@/components/content/storefront/blog/BlogPostArticle.astro";
22
22
 
23
23
  const { tenant, canonicalBase, content, basePath, apiBasePath, capabilities, features } =
24
24
  Astro.locals;
@@ -45,7 +45,7 @@ if (styleGuideTarget !== undefined) {
45
45
  return Astro.rewrite(styleGuideTarget);
46
46
  }
47
47
 
48
- // A tenant that declares `BlogSettings.postsAtRoot` (see lib/blog/types.ts) serves its
48
+ // A tenant that declares `BlogSettings.postsAtRoot` (see lib/content/blog/types.ts) serves its
49
49
  // individual posts at the site root — a single-segment slug tries the blog collection
50
50
  // before falling through to a raw marketing page or a CMS page. Multi-segment slugs are
51
51
  // never posts, so this never shadows a nested marketing/CMS path.
@@ -31,9 +31,9 @@ import type { APIContext } from "astro";
31
31
  import { requireAdminApiEntry } from "@/lib/auth/adminApiGuard";
32
32
  import { readD1 } from "@/lib/env";
33
33
  import { fromD1 } from "@/lib/catalog/d1/catalog";
34
- import { resolveTenantStore, trackingNamePrefix } from "@/lib/tracking/tenantD1Registry";
35
- import { readD1Control } from "@/lib/tracking/d1Control";
36
- import { readTenantInteractionInsights } from "@/lib/tracking/tenantReadAccess";
34
+ import { resolveTenantStore, trackingNamePrefix } from "@/lib/measurement/tracking/tenantD1Registry";
35
+ import { readD1Control } from "@/lib/measurement/tracking/d1Control";
36
+ import { readTenantInteractionInsights } from "@/lib/measurement/tracking/tenantReadAccess";
37
37
 
38
38
  export const prerender = false;
39
39
 
@@ -18,7 +18,7 @@ import {
18
18
  isReaction,
19
19
  recordReaction,
20
20
  type Reaction,
21
- } from "@/lib/blog/reactions";
21
+ } from "@/lib/content/blog/reactions";
22
22
  import { checkRateLimit } from "@/lib/rate/kvWindow";
23
23
 
24
24
  export const prerender = false;
@@ -18,9 +18,9 @@ import type { APIRoute } from "astro";
18
18
  import { readD1, readKv, readEnv } from "@/lib/env";
19
19
  import { fromD1 } from "@/lib/catalog/d1/catalog";
20
20
  import { checkRateLimit } from "@/lib/rate/kvWindow";
21
- import { NewsletterSubscribersStore } from "@/lib/newsletter/subscribers";
22
- import { randomToken, hashConsentIp } from "@/lib/newsletter/consent";
23
- import { sendConfirmationEmail } from "@/lib/newsletter/confirmationEmail";
21
+ import { NewsletterSubscribersStore } from "@/lib/engagement/newsletter/subscribers";
22
+ import { randomToken, hashConsentIp } from "@/lib/engagement/newsletter/consent";
23
+ import { sendConfirmationEmail } from "@/lib/engagement/newsletter/confirmationEmail";
24
24
 
25
25
  export const prerender = false;
26
26
 
@@ -12,7 +12,7 @@
12
12
  import type { APIRoute } from "astro";
13
13
  import { readD1 } from "@/lib/env";
14
14
  import { fromD1 } from "@/lib/catalog/d1/catalog";
15
- import { NewsletterSubscribersStore } from "@/lib/newsletter/subscribers";
15
+ import { NewsletterSubscribersStore } from "@/lib/engagement/newsletter/subscribers";
16
16
 
17
17
  export const prerender = false;
18
18
 
@@ -21,7 +21,7 @@
21
21
  import type { APIContext } from "astro";
22
22
  import { readD1 } from "@/lib/env";
23
23
  import { fromD1 } from "@/lib/catalog/d1/catalog";
24
- import { unsubscribeByToken } from "@/lib/newsletter/subscribers";
24
+ import { unsubscribeByToken } from "@/lib/engagement/newsletter/subscribers";
25
25
 
26
26
  export const prerender = false;
27
27
 
@@ -15,7 +15,7 @@
15
15
  import type { APIRoute } from "astro";
16
16
  import { rateMetric, type WebVitalName, type WebVitalsSample } from "@/lib/analytics/webVitals";
17
17
  import { readKv, runAfterResponse, type CfExecutionContextLike } from "@/lib/env";
18
- import { recordBlogView } from "@/lib/blog/viewCounts";
18
+ import { recordBlogView } from "@/lib/content/blog/viewCounts";
19
19
 
20
20
  export const prerender = false;
21
21
 
@@ -2,7 +2,7 @@
2
2
  * POST /api/tracking/interaction (dt-collector-v1) — the beacon sink for
3
3
  * declarative interaction tracking.
4
4
  *
5
- * The browser collector (`@/lib/tracking/interactionCollector`) batches
5
+ * The browser collector (`@/lib/measurement/tracking/interactionCollector`) batches
6
6
  * `TotInteraction`s captured off `installInteractionTracking` /
7
7
  * `onInteraction` (`@tot/public-runtime`) — via `dt-consent-environment-gate`'s
8
8
  * consent/environment wrapper in front of it — and POSTs them here with
@@ -39,10 +39,10 @@
39
39
  import type { APIContext } from "astro";
40
40
  import { readD1, readAnalytics, runAfterResponse, type CfExecutionContextLike } from "@/lib/env";
41
41
  import { fromD1 } from "@/lib/catalog/d1/catalog";
42
- import { ingestInteractions, type StampedInteractionEvent } from "@/lib/tracking/collectorIngest";
43
- import { readD1Control } from "@/lib/tracking/d1Control";
44
- import { resolveTenantStore, trackingNamePrefix } from "@/lib/tracking/tenantD1Registry";
45
- import { persistInteractions } from "@/lib/tracking/interactionStore";
42
+ import { ingestInteractions, type StampedInteractionEvent } from "@/lib/measurement/tracking/collectorIngest";
43
+ import { readD1Control } from "@/lib/measurement/tracking/d1Control";
44
+ import { resolveTenantStore, trackingNamePrefix } from "@/lib/measurement/tracking/tenantD1Registry";
45
+ import { persistInteractions } from "@/lib/measurement/tracking/interactionStore";
46
46
  import type { AnalyticsEngineLike } from "@/lib/activity/store";
47
47
 
48
48
  export const prerender = false;