@tokenoftrust/storefront-runner 1.3.2

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 (310) hide show
  1. package/LICENSE +58 -0
  2. package/README.md +42 -0
  3. package/apps/storefront/astro.config.mjs +66 -0
  4. package/apps/storefront/dev-plugins/dev-loop-state.mjs +147 -0
  5. package/apps/storefront/dev-plugins/tenant-hot-reload.mjs +238 -0
  6. package/apps/storefront/env.d.ts +162 -0
  7. package/apps/storefront/migrations/0000_baseline.sql +54 -0
  8. package/apps/storefront/migrations/0001_products_fts.sql +9 -0
  9. package/apps/storefront/migrations/README.md +54 -0
  10. package/apps/storefront/migrations/meta/0000_snapshot.json +347 -0
  11. package/apps/storefront/migrations/meta/0001_snapshot.json +347 -0
  12. package/apps/storefront/migrations/meta/_journal.json +20 -0
  13. package/apps/storefront/package.json +42 -0
  14. package/apps/storefront/public/brand/northwind-logo-dark.svg +4 -0
  15. package/apps/storefront/public/brand/northwind-logo-light.svg +4 -0
  16. package/apps/storefront/public/brand/northwind-og.svg +13 -0
  17. package/apps/storefront/public/favicon.svg +5 -0
  18. package/apps/storefront/public/js/dashboard-team.js +147 -0
  19. package/apps/storefront/public/js/dashboard-vendor-search.js +115 -0
  20. package/apps/storefront/public/shared/commerce-chrome.css +369 -0
  21. package/apps/storefront/src/components/Badge.astro +34 -0
  22. package/apps/storefront/src/components/Breadcrumbs.astro +45 -0
  23. package/apps/storefront/src/components/CollectionCard.astro +56 -0
  24. package/apps/storefront/src/components/EmptyState.astro +55 -0
  25. package/apps/storefront/src/components/Img.astro +68 -0
  26. package/apps/storefront/src/components/ProductCard.astro +228 -0
  27. package/apps/storefront/src/components/Section.astro +39 -0
  28. package/apps/storefront/src/components/Seo.astro +70 -0
  29. package/apps/storefront/src/components/WidgetFrame.astro +34 -0
  30. package/apps/storefront/src/components/admin/AdminAIWorkflowsTab.astro +531 -0
  31. package/apps/storefront/src/components/admin/AdminCustomersTab.astro +597 -0
  32. package/apps/storefront/src/components/admin/AdminFoxyCartSettingsPanel.astro +227 -0
  33. package/apps/storefront/src/components/admin/AdminFulfillmentTab.astro +465 -0
  34. package/apps/storefront/src/components/admin/AdminProductsTab.astro +901 -0
  35. package/apps/storefront/src/components/admin/AdminReportingTab.astro +435 -0
  36. package/apps/storefront/src/components/admin/AdminSettingsTab.astro +782 -0
  37. package/apps/storefront/src/components/admin/orders/OrdersWorkspace.astro +1223 -0
  38. package/apps/storefront/src/components/auth/AuthBadge.astro +44 -0
  39. package/apps/storefront/src/components/chrome/AnnouncementBar.astro +108 -0
  40. package/apps/storefront/src/components/chrome/MegaMenu.astro +26 -0
  41. package/apps/storefront/src/components/chrome/NavDropdown.astro +201 -0
  42. package/apps/storefront/src/components/chrome/SiteFooter.astro +201 -0
  43. package/apps/storefront/src/components/chrome/SiteHeader.astro +234 -0
  44. package/apps/storefront/src/components/chrome/UtilityNav.astro +79 -0
  45. package/apps/storefront/src/components/commerce/ArticleCard.astro +242 -0
  46. package/apps/storefront/src/components/commerce/BrandGrid.astro +175 -0
  47. package/apps/storefront/src/components/commerce/FoxyLoader.astro +23 -0
  48. package/apps/storefront/src/components/commerce/FoxySidecartStyles.astro +61 -0
  49. package/apps/storefront/src/components/commerce/PriceDisplay.astro +91 -0
  50. package/apps/storefront/src/components/commerce/ProductCarousel.astro +197 -0
  51. package/apps/storefront/src/components/commerce/ProductGrid.astro +75 -0
  52. package/apps/storefront/src/components/commerce/RatingStars.astro +58 -0
  53. package/apps/storefront/src/components/commerce/ReviewList.astro +54 -0
  54. package/apps/storefront/src/components/commerce/ReviewSummary.astro +44 -0
  55. package/apps/storefront/src/components/commerce/TagFilterCloud.astro +149 -0
  56. package/apps/storefront/src/components/compliance/AdultSignatureNotice.astro +37 -0
  57. package/apps/storefront/src/components/compliance/ComplianceNotice.astro +99 -0
  58. package/apps/storefront/src/components/compliance/ExciseTaxNotice.astro +45 -0
  59. package/apps/storefront/src/components/compliance/NicotineWarning.astro +33 -0
  60. package/apps/storefront/src/components/compliance/PactActNotice.astro +35 -0
  61. package/apps/storefront/src/components/compliance/Prop65Warning.astro +80 -0
  62. package/apps/storefront/src/components/compliance/PurchaseLimitNotice.astro +38 -0
  63. package/apps/storefront/src/components/compliance/ShippingRestrictionNotice.astro +35 -0
  64. package/apps/storefront/src/components/compliance/StateEligibilityNotice.astro +53 -0
  65. package/apps/storefront/src/components/home/Hero.astro +164 -0
  66. package/apps/storefront/src/components/islands/AgeGate.tsx +109 -0
  67. package/apps/storefront/src/components/islands/ImageGallery.tsx +237 -0
  68. package/apps/storefront/src/components/islands/IsolatedAgeGate.tsx +73 -0
  69. package/apps/storefront/src/components/islands/MobileNav.tsx +239 -0
  70. package/apps/storefront/src/components/islands/QuickView.tsx +138 -0
  71. package/apps/storefront/src/components/islands/RecentlyViewed.tsx +122 -0
  72. package/apps/storefront/src/components/islands/SavedList.tsx +99 -0
  73. package/apps/storefront/src/components/islands/SearchTypeahead.tsx +248 -0
  74. package/apps/storefront/src/components/islands/VariantSelector.tsx +375 -0
  75. package/apps/storefront/src/components/marketing/CardGrid.astro +72 -0
  76. package/apps/storefront/src/components/marketing/CodeSample.astro +20 -0
  77. package/apps/storefront/src/components/marketing/CtaBand.astro +24 -0
  78. package/apps/storefront/src/components/marketing/Faq.astro +37 -0
  79. package/apps/storefront/src/components/marketing/Integrations.astro +63 -0
  80. package/apps/storefront/src/components/marketing/MarketingBlocks.astro +53 -0
  81. package/apps/storefront/src/components/marketing/MarketingCtas.astro +48 -0
  82. package/apps/storefront/src/components/marketing/MarketingHero.astro +72 -0
  83. package/apps/storefront/src/components/marketing/ProofStrip.astro +37 -0
  84. package/apps/storefront/src/components/marketing/SplitCompare.astro +53 -0
  85. package/apps/storefront/src/components/marketing/Steps.astro +36 -0
  86. package/apps/storefront/src/components/marketing/Testimonials.astro +38 -0
  87. package/apps/storefront/src/components/marketing/TrustBar.astro +22 -0
  88. package/apps/storefront/src/components/membership/IllustrativeLabel.astro +56 -0
  89. package/apps/storefront/src/components/membership/TierCards.astro +164 -0
  90. package/apps/storefront/src/components/membership/TierComparisonTable.astro +148 -0
  91. package/apps/storefront/src/components/plp/ActiveFilters.astro +79 -0
  92. package/apps/storefront/src/components/plp/FacetSidebar.astro +199 -0
  93. package/apps/storefront/src/components/plp/Pagination.astro +99 -0
  94. package/apps/storefront/src/components/plp/SortSelect.astro +64 -0
  95. package/apps/storefront/src/components/style-guide/StyleGuideNav.astro +95 -0
  96. package/apps/storefront/src/components/subscription/HowItWorksSteps.astro +67 -0
  97. package/apps/storefront/src/components/subscription/ManageSubscriptionEntry.astro +67 -0
  98. package/apps/storefront/src/components/subscription/SavingsExplainer.astro +101 -0
  99. package/apps/storefront/src/config/adminTargetTenant.ts +28 -0
  100. package/apps/storefront/src/config/devTenantSeed.ts +78 -0
  101. package/apps/storefront/src/config/devTenants.ts +16 -0
  102. package/apps/storefront/src/config/kvTenantResolver.ts +87 -0
  103. package/apps/storefront/src/config/resolver.ts +102 -0
  104. package/apps/storefront/src/config/tenants.ts +87 -0
  105. package/apps/storefront/src/layouts/Layout.astro +368 -0
  106. package/apps/storefront/src/lib/admin/README.md +122 -0
  107. package/apps/storefront/src/lib/admin/ai/approvalMode.ts +21 -0
  108. package/apps/storefront/src/lib/admin/ai/askEnvelope.ts +48 -0
  109. package/apps/storefront/src/lib/admin/ai/audit.ts +14 -0
  110. package/apps/storefront/src/lib/admin/ai/index.ts +6 -0
  111. package/apps/storefront/src/lib/admin/ai/operationalRuns.ts +155 -0
  112. package/apps/storefront/src/lib/admin/ai/recommendation.ts +20 -0
  113. package/apps/storefront/src/lib/admin/checkoutStyleInput.ts +172 -0
  114. package/apps/storefront/src/lib/admin/checkoutStyleTarget.ts +65 -0
  115. package/apps/storefront/src/lib/admin/envelope.ts +10 -0
  116. package/apps/storefront/src/lib/admin/evidence/evidenceReference.ts +32 -0
  117. package/apps/storefront/src/lib/admin/memoizeByEnvelope.ts +27 -0
  118. package/apps/storefront/src/lib/admin/orderClient.ts +146 -0
  119. package/apps/storefront/src/lib/admin/seed.ts +54 -0
  120. package/apps/storefront/src/lib/admin/services/mock/aiWorkflows.ts +59 -0
  121. package/apps/storefront/src/lib/admin/services/mock/customers.ts +86 -0
  122. package/apps/storefront/src/lib/admin/services/mock/evidence.ts +99 -0
  123. package/apps/storefront/src/lib/admin/services/mock/foxyCartSettings.ts +78 -0
  124. package/apps/storefront/src/lib/admin/services/mock/fulfillment.ts +62 -0
  125. package/apps/storefront/src/lib/admin/services/mock/index.ts +12 -0
  126. package/apps/storefront/src/lib/admin/services/mock/orders.ts +184 -0
  127. package/apps/storefront/src/lib/admin/services/mock/products.ts +105 -0
  128. package/apps/storefront/src/lib/admin/services/mock/reporting.ts +51 -0
  129. package/apps/storefront/src/lib/admin/services/mock/settings.ts +70 -0
  130. package/apps/storefront/src/lib/admin/services/mock/tenants.ts +29 -0
  131. package/apps/storefront/src/lib/admin/services/orders.ts +300 -0
  132. package/apps/storefront/src/lib/admin/viewmodels/aiWorkflows.ts +67 -0
  133. package/apps/storefront/src/lib/admin/viewmodels/customers.ts +56 -0
  134. package/apps/storefront/src/lib/admin/viewmodels/fulfillment.ts +49 -0
  135. package/apps/storefront/src/lib/admin/viewmodels/orders.ts +92 -0
  136. package/apps/storefront/src/lib/admin/viewmodels/products.ts +74 -0
  137. package/apps/storefront/src/lib/admin/viewmodels/reporting.ts +34 -0
  138. package/apps/storefront/src/lib/admin/viewmodels/settings.ts +64 -0
  139. package/apps/storefront/src/lib/adminTenantEnvelope.ts +90 -0
  140. package/apps/storefront/src/lib/analytics/index.ts +47 -0
  141. package/apps/storefront/src/lib/auth/brokerAssertion.ts +136 -0
  142. package/apps/storefront/src/lib/auth/devAuth.ts +90 -0
  143. package/apps/storefront/src/lib/auth/gatePage.ts +81 -0
  144. package/apps/storefront/src/lib/auth/identityToken.ts +341 -0
  145. package/apps/storefront/src/lib/auth/loginGate.ts +119 -0
  146. package/apps/storefront/src/lib/auth/route.ts +146 -0
  147. package/apps/storefront/src/lib/auth/session.ts +203 -0
  148. package/apps/storefront/src/lib/auth/totAccessClient.ts +503 -0
  149. package/apps/storefront/src/lib/basePath.ts +41 -0
  150. package/apps/storefront/src/lib/cfImage.ts +55 -0
  151. package/apps/storefront/src/lib/chrome/model.ts +244 -0
  152. package/apps/storefront/src/lib/chrome/parseConfig.ts +34 -0
  153. package/apps/storefront/src/lib/colors.ts +97 -0
  154. package/apps/storefront/src/lib/commerce/foxyCartSettings.ts +253 -0
  155. package/apps/storefront/src/lib/content-edit/applyDiff.ts +91 -0
  156. package/apps/storefront/src/lib/content-edit/client.ts +230 -0
  157. package/apps/storefront/src/lib/content-edit/index.ts +14 -0
  158. package/apps/storefront/src/lib/content-edit/route.ts +25 -0
  159. package/apps/storefront/src/lib/content-edit/types.ts +19 -0
  160. package/apps/storefront/src/lib/cspStaticHashes.ts +24 -0
  161. package/apps/storefront/src/lib/d1/catalog.ts +366 -0
  162. package/apps/storefront/src/lib/dashboard/staffAdmission.ts +43 -0
  163. package/apps/storefront/src/lib/dashboard/staffVendorAccess.ts +449 -0
  164. package/apps/storefront/src/lib/dashboard/tenantSelection.ts +136 -0
  165. package/apps/storefront/src/lib/dashboard/vendorQuery.ts +61 -0
  166. package/apps/storefront/src/lib/demoGate.ts +113 -0
  167. package/apps/storefront/src/lib/dev/activityIngestToken.ts +78 -0
  168. package/apps/storefront/src/lib/dev/activityStore.ts +72 -0
  169. package/apps/storefront/src/lib/dev/ai-widget-client.js +308 -0
  170. package/apps/storefront/src/lib/dev/apiBase.ts +14 -0
  171. package/apps/storefront/src/lib/dev/cliSignInCode.ts +155 -0
  172. package/apps/storefront/src/lib/dev/devDraft.ts +133 -0
  173. package/apps/storefront/src/lib/dev/hostedCockpit.ts +169 -0
  174. package/apps/storefront/src/lib/dev/livePreview.ts +77 -0
  175. package/apps/storefront/src/lib/dev/runtimeStore.ts +120 -0
  176. package/apps/storefront/src/lib/dev/storeStatus.ts +142 -0
  177. package/apps/storefront/src/lib/diag/redact.ts +20 -0
  178. package/apps/storefront/src/lib/edgeCache.ts +128 -0
  179. package/apps/storefront/src/lib/email/magicLinkInviteEmail.ts +62 -0
  180. package/apps/storefront/src/lib/env.ts +60 -0
  181. package/apps/storefront/src/lib/fixtures/sampleProducts.ts +130 -0
  182. package/apps/storefront/src/lib/format.ts +38 -0
  183. package/apps/storefront/src/lib/foxyCommerce.ts +49 -0
  184. package/apps/storefront/src/lib/imageAttrs.ts +55 -0
  185. package/apps/storefront/src/lib/jsonld.ts +166 -0
  186. package/apps/storefront/src/lib/maintenance.ts +71 -0
  187. package/apps/storefront/src/lib/membership/model.ts +97 -0
  188. package/apps/storefront/src/lib/memoryKv.ts +32 -0
  189. package/apps/storefront/src/lib/messaging/messagesClient.ts +143 -0
  190. package/apps/storefront/src/lib/placeholder.ts +99 -0
  191. package/apps/storefront/src/lib/previewReload.ts +125 -0
  192. package/apps/storefront/src/lib/priceBuckets.ts +33 -0
  193. package/apps/storefront/src/lib/rawChrome.ts +505 -0
  194. package/apps/storefront/src/lib/rawMarketingHtml.ts +136 -0
  195. package/apps/storefront/src/lib/search/index.ts +74 -0
  196. package/apps/storefront/src/lib/sections.ts +129 -0
  197. package/apps/storefront/src/lib/securityHeaders.ts +31 -0
  198. package/apps/storefront/src/lib/storyblok/content-model.ts +289 -0
  199. package/apps/storefront/src/lib/storyblok/provider.ts +607 -0
  200. package/apps/storefront/src/lib/subscription/model.ts +68 -0
  201. package/apps/storefront/src/lib/tenantRouting.ts +91 -0
  202. package/apps/storefront/src/lib/tot/ToTClient.ts +177 -0
  203. package/apps/storefront/src/lib/tot/d1Client.ts +62 -0
  204. package/apps/storefront/src/lib/tot/query.ts +249 -0
  205. package/apps/storefront/src/lib/tot/totClientInterface.ts +30 -0
  206. package/apps/storefront/src/lib/url.ts +142 -0
  207. package/apps/storefront/src/lib/wishlist.ts +63 -0
  208. package/apps/storefront/src/middleware/index.ts +455 -0
  209. package/apps/storefront/src/pages/404.astro +61 -0
  210. package/apps/storefront/src/pages/[...slug].astro +90 -0
  211. package/apps/storefront/src/pages/admin.astro +1675 -0
  212. package/apps/storefront/src/pages/api/admin/orders/[id].ts +53 -0
  213. package/apps/storefront/src/pages/api/admin/orders.ts +71 -0
  214. package/apps/storefront/src/pages/api/auth/logout.ts +21 -0
  215. package/apps/storefront/src/pages/api/auth/magic-exchange.ts +107 -0
  216. package/apps/storefront/src/pages/api/auth/send.ts +85 -0
  217. package/apps/storefront/src/pages/api/auth/verify.ts +135 -0
  218. package/apps/storefront/src/pages/api/cache-purge.ts +44 -0
  219. package/apps/storefront/src/pages/api/checkout-style.css.ts +43 -0
  220. package/apps/storefront/src/pages/api/cli/policy.ts +70 -0
  221. package/apps/storefront/src/pages/api/content-edit/ai-edit.ts +164 -0
  222. package/apps/storefront/src/pages/api/csp-report.ts +25 -0
  223. package/apps/storefront/src/pages/api/dashboard/enter-vendor.ts +124 -0
  224. package/apps/storefront/src/pages/api/dashboard/vendor-search.ts +120 -0
  225. package/apps/storefront/src/pages/api/dev/activity.ts +124 -0
  226. package/apps/storefront/src/pages/api/dev/cli-signin-code.ts +73 -0
  227. package/apps/storefront/src/pages/api/dev/diff.ts +68 -0
  228. package/apps/storefront/src/pages/api/dev/file.ts +57 -0
  229. package/apps/storefront/src/pages/api/dev/locate.ts +125 -0
  230. package/apps/storefront/src/pages/api/dev/publish.ts +128 -0
  231. package/apps/storefront/src/pages/api/dev/tree.ts +70 -0
  232. package/apps/storefront/src/pages/api/dev/write.ts +116 -0
  233. package/apps/storefront/src/pages/api/newsletter.ts +104 -0
  234. package/apps/storefront/src/pages/api/request-access.ts +172 -0
  235. package/apps/storefront/src/pages/auth/login.astro +149 -0
  236. package/apps/storefront/src/pages/auth/magic.astro +105 -0
  237. package/apps/storefront/src/pages/capabilities.astro +292 -0
  238. package/apps/storefront/src/pages/collections/[handle].astro +177 -0
  239. package/apps/storefront/src/pages/collections/index.astro +59 -0
  240. package/apps/storefront/src/pages/dashboard/[appDomain]/index.astro +100 -0
  241. package/apps/storefront/src/pages/dashboard/[appDomain]/team.astro +154 -0
  242. package/apps/storefront/src/pages/dashboard/index.astro +160 -0
  243. package/apps/storefront/src/pages/index.astro +290 -0
  244. package/apps/storefront/src/pages/llms.txt.ts +92 -0
  245. package/apps/storefront/src/pages/products/[handle].astro +402 -0
  246. package/apps/storefront/src/pages/robots.txt.ts +24 -0
  247. package/apps/storefront/src/pages/saved.astro +35 -0
  248. package/apps/storefront/src/pages/search.astro +150 -0
  249. package/apps/storefront/src/pages/sitemap.xml.ts +78 -0
  250. package/apps/storefront/src/pages/style-guide/[tenant]/[theme].astro +1280 -0
  251. package/apps/storefront/src/pages/style-guide/[tenant]/chrome/[theme].astro +229 -0
  252. package/apps/storefront/src/pages/style-guide/[tenant]/guide/[theme].astro +144 -0
  253. package/apps/storefront/src/pages/style-guide/[tenant]/index.astro +116 -0
  254. package/apps/storefront/src/pages/style-guide/index.astro +98 -0
  255. package/apps/storefront/src/pages/tenants/[id]/[...path].ts +57 -0
  256. package/apps/storefront/src/styles/global.css +292 -0
  257. package/apps/storefront/src/themes/reference.ts +68 -0
  258. package/apps/storefront/src/themes/schema.ts +111 -0
  259. package/apps/storefront/src/themes/tenants/index.ts +51 -0
  260. package/apps/storefront/tsconfig.json +16 -0
  261. package/apps/storefront/vitest.config.ts +22 -0
  262. package/package.json +26 -0
  263. package/packages/public-runtime/LICENSE +58 -0
  264. package/packages/public-runtime/package.json +22 -0
  265. package/packages/public-runtime/src/binary-path.ts +68 -0
  266. package/packages/public-runtime/src/capabilities.ts +89 -0
  267. package/packages/public-runtime/src/catalog-api.ts +81 -0
  268. package/packages/public-runtime/src/catalog-d1.ts +192 -0
  269. package/packages/public-runtime/src/checkout-style-publish.ts +200 -0
  270. package/packages/public-runtime/src/checkout-style.ts +375 -0
  271. package/packages/public-runtime/src/csp.ts +109 -0
  272. package/packages/public-runtime/src/customization-preview.ts +197 -0
  273. package/packages/public-runtime/src/customization-reconcile.ts +63 -0
  274. package/packages/public-runtime/src/customization-runtime.ts +157 -0
  275. package/packages/public-runtime/src/customization-scripts.ts +64 -0
  276. package/packages/public-runtime/src/customization-versioning.ts +95 -0
  277. package/packages/public-runtime/src/foxy-orders.ts +136 -0
  278. package/packages/public-runtime/src/foxy.ts +196 -0
  279. package/packages/public-runtime/src/hot-standby-readiness.ts +140 -0
  280. package/packages/public-runtime/src/index.ts +34 -0
  281. package/packages/public-runtime/src/product.ts +159 -0
  282. package/packages/public-runtime/src/search.ts +45 -0
  283. package/packages/public-runtime/src/tenant-assets.ts +444 -0
  284. package/packages/public-runtime/src/tenant.ts +384 -0
  285. package/packages/public-runtime/tsconfig.json +8 -0
  286. package/packages/public-runtime/vitest.config.ts +8 -0
  287. package/pnpm-workspace.yaml +7 -0
  288. package/scripts/build/copy-tenant-assets.mjs +69 -0
  289. package/scripts/dev/ai-edit.mjs +183 -0
  290. package/scripts/dev/checkout-watch.mjs +116 -0
  291. package/scripts/dev/file-browser.mjs +159 -0
  292. package/scripts/dev/file-writer.mjs +141 -0
  293. package/scripts/dev/git-status.mjs +171 -0
  294. package/scripts/dev/locate-handler.mjs +163 -0
  295. package/scripts/dev/locate.mjs +112 -0
  296. package/scripts/dev/port-check.mjs +48 -0
  297. package/scripts/dev/safe-path.mjs +109 -0
  298. package/scripts/dev/shot.mjs +46 -0
  299. package/scripts/dev/tenant-source-root.mjs +76 -0
  300. package/scripts/dev/unified-diff.mjs +81 -0
  301. package/scripts/tot-dev.mjs +376 -0
  302. package/tenants/README.md +14 -0
  303. package/tenants/home/content/chrome.json +7 -0
  304. package/tenants/home/content/home.html +58 -0
  305. package/tenants/home/content/home.json +11 -0
  306. package/tenants/home/public/js/storefront.js +210 -0
  307. package/tenants/home/public/logo-wordmark.png +0 -0
  308. package/tenants/home/public/pages/storefront.css +212 -0
  309. package/tenants/home/theme.json +6 -0
  310. package/tsconfig.base.json +20 -0
@@ -0,0 +1,162 @@
1
+ /// <reference path="./.astro/types.d.ts" />
2
+ /// <reference types="astro/client" />
3
+
4
+ import type {
5
+ TenantConfig,
6
+ CustomizationEnv,
7
+ TenantFeatures,
8
+ ResolvedFoxyCommerce,
9
+ CapabilityConfig,
10
+ } from "@tot/public-runtime";
11
+ import type { ToTClient } from "@/lib/tot/ToTClient";
12
+ import type { ContentProvider } from "@/lib/storyblok/provider";
13
+
14
+ /**
15
+ * Minimal binding shapes. We intentionally do NOT depend on
16
+ * @cloudflare/workers-types (not installed); these cover what Phase 1 touches.
17
+ * Widen them when real KV/R2 calls are added.
18
+ */
19
+ interface KVNamespaceLike {
20
+ get(key: string, opts?: { cacheTtl?: number }): Promise<string | null>;
21
+ put(key: string, value: string, opts?: Record<string, unknown>): Promise<void>;
22
+ list(opts?: { prefix?: string; cursor?: string; limit?: number }): Promise<{
23
+ keys: { name: string }[];
24
+ list_complete: boolean;
25
+ cursor?: string;
26
+ }>;
27
+ delete(key: string): Promise<void>;
28
+ }
29
+ interface R2BucketLike {
30
+ get(key: string): Promise<unknown>;
31
+ put(key: string, value: unknown): Promise<unknown>;
32
+ }
33
+
34
+ interface CloudflareEnv {
35
+ /** Astro session store (adapter default). */
36
+ SESSION?: KVNamespaceLike;
37
+ /** Tenant config + catalog cache KV. */
38
+ TENANT_CACHE?: KVNamespaceLike;
39
+ /** Rehosted product images. */
40
+ PRODUCT_IMAGES?: R2BucketLike;
41
+ /**
42
+ * Versioned tenant static assets (`public/**`), keyed
43
+ * `tenants/<id>/<versionId>/<rel>`. Served by src/pages/tenants/[id]/[...path].
44
+ */
45
+ TENANT_ASSETS?: R2BucketLike;
46
+ // Secrets / vars surfaced at runtime.
47
+ TOT_CATALOG_BASE_URL?: string;
48
+ TOT_API_KEY?: string;
49
+ TOT_SECRET_KEY?: string;
50
+ TOT_ACCESS_TOKEN?: string;
51
+ PUBLIC_CF_ANALYTICS_TOKEN?: string;
52
+ /** HMAC secret for signing/verifying customization preview tokens (D4). */
53
+ CUSTOMIZATION_PREVIEW_SECRET?: string;
54
+ /**
55
+ * FoxyCart (Track A). `FOXY_STORE_SUBDOMAIN` overrides the tenant's default
56
+ * demo store subdomain (swap the demo store with zero code change).
57
+ * `FOXY_CART_SECRET` is the store's cart-validation secret for signed mode —
58
+ * absent in the unsigned demo (validation OFF), present on preview/live.
59
+ */
60
+ FOXY_STORE_SUBDOMAIN?: string;
61
+ /** Branded custom checkout domain override (e.g. checkout.preview.tokenoftrust.com). */
62
+ FOXY_STORE_DOMAIN?: string;
63
+ FOXY_CART_SECRET?: string;
64
+ /**
65
+ * Order READ API bearer (U2) — the tenant's ToT `partnerApi.apiKey`, sent as
66
+ * `Authorization: Bearer` to tot-foxycart `GET /commerce/orders`. Server-side
67
+ * only (never shipped to the browser). Absent → the Orders route reports
68
+ * `not_provisioned` (503).
69
+ */
70
+ FOXY_ORDER_API_KEY?: string;
71
+ }
72
+
73
+ declare global {
74
+ // Alias used elsewhere.
75
+ type KVNamespace = KVNamespaceLike;
76
+ type R2Bucket = R2BucketLike;
77
+
78
+ namespace App {
79
+ interface Locals {
80
+ /** Tenant resolved from the request Host by src/middleware. */
81
+ tenant: TenantConfig;
82
+ /**
83
+ * Effective capability flags for the resolved tenant (commerce defaults
84
+ * unless siteType:"marketing"/explicit features). Chrome, layout islands,
85
+ * sitemap, and commerce routes gate on these — no tenant-identity checks.
86
+ */
87
+ features: TenantFeatures;
88
+ /** Catalog client bound to the resolved tenant's data scope. */
89
+ tot: ToTClient;
90
+ /**
91
+ * Content provider for this request — overlays any published "Own Your
92
+ * Look" content for the resolved customizationEnv over Storyblok/local.
93
+ */
94
+ content: ContentProvider;
95
+ /** Inline CSS-variable theme block already serialized for <head>. */
96
+ themeStyle: string;
97
+ /** Absolute canonical base for this request. */
98
+ canonicalBase: string;
99
+ /**
100
+ * Path prefix the request was routed under: "" for host-routed requests,
101
+ * or "/<domain>" when a `/<domain>/*` path segment selected the tenant
102
+ * (DNS-free local/preview routing). The Layout keeps root-absolute links
103
+ * inside this prefix on the client.
104
+ */
105
+ basePath: string;
106
+ /**
107
+ * Which customization environment to serve (D4). "live" on production
108
+ * hosts; "test" only behind a valid, tenant-bound preview token on a
109
+ * preview host. Downstream theme/content selection reads this.
110
+ */
111
+ customizationEnv: CustomizationEnv;
112
+ /**
113
+ * Per-request CSP nonce (D2). Placed on the platform's own inline
114
+ * <style>/<script is:inline> tags so a strict CSP can allow them without
115
+ * `unsafe-inline`.
116
+ */
117
+ cspNonce: string;
118
+ /**
119
+ * Resolved FoxyCart cart/checkout facts for this request (loader src, cart
120
+ * URL, mode). Present only for commerce tenants with a FoxyCart store;
121
+ * undefined for marketing tenants or when no store is configured.
122
+ */
123
+ commerce?: ResolvedFoxyCommerce;
124
+ /**
125
+ * Effective, per-environment capability switches (cart/checkout, age
126
+ * verification, excise tax) for this request. Resolved from the tenant's
127
+ * build-time default overridden by the published capabilities artifact for
128
+ * the current customizationEnv — so the value reflects exactly what a PR
129
+ * promoted to THIS environment.
130
+ */
131
+ capabilities: CapabilityConfig;
132
+ /**
133
+ * Signed-in viewer for a login-gated preview host (set by the demo login
134
+ * gate once a valid, resource-bound `tot_session` cookie is present). Carries
135
+ * the email + the role(s)/capability tot20 resolved on this tenant, so chrome
136
+ * can show "signed in as … — owner/developer/staff". Absent on open or
137
+ * password-gated hosts.
138
+ */
139
+ viewer?: {
140
+ email: string;
141
+ roles: string[];
142
+ capability: string;
143
+ };
144
+ /** Cloudflare runtime (env bindings) — provided by the adapter on Workers. */
145
+ runtime?: { env: CloudflareEnv };
146
+ }
147
+ }
148
+ }
149
+
150
+ interface ImportMetaEnv {
151
+ readonly TOT_CATALOG_BASE_URL?: string;
152
+ readonly TOT_API_KEY?: string;
153
+ readonly TOT_SECRET_KEY?: string;
154
+ readonly TOT_ACCESS_TOKEN?: string;
155
+ readonly PUBLIC_CF_ANALYTICS_TOKEN?: string;
156
+ readonly CUSTOMIZATION_PREVIEW_SECRET?: string;
157
+ }
158
+ interface ImportMeta {
159
+ readonly env: ImportMetaEnv;
160
+ }
161
+
162
+ export {};
@@ -0,0 +1,54 @@
1
+ CREATE TABLE `collections` (
2
+ `handle` text PRIMARY KEY NOT NULL,
3
+ `title` text NOT NULL,
4
+ `position` integer DEFAULT 99 NOT NULL,
5
+ `data` text NOT NULL
6
+ );
7
+ --> statement-breakpoint
8
+ CREATE TABLE `customization_pointers` (
9
+ `tenant_id` text PRIMARY KEY NOT NULL,
10
+ `rev` integer NOT NULL,
11
+ `live` text NOT NULL,
12
+ `test` text NOT NULL
13
+ );
14
+ --> statement-breakpoint
15
+ CREATE TABLE `customization_versions` (
16
+ `tenant_id` text NOT NULL,
17
+ `path` text NOT NULL,
18
+ `version_id` text NOT NULL,
19
+ `size` integer NOT NULL,
20
+ `created_at` text NOT NULL,
21
+ `content` text NOT NULL,
22
+ PRIMARY KEY(`tenant_id`, `path`, `version_id`)
23
+ );
24
+ --> statement-breakpoint
25
+ CREATE TABLE `product_collections` (
26
+ `handle` text NOT NULL,
27
+ `collection` text NOT NULL
28
+ );
29
+ --> statement-breakpoint
30
+ CREATE INDEX `idx_pc_collection` ON `product_collections` (`collection`);--> statement-breakpoint
31
+ CREATE TABLE `product_facets` (
32
+ `handle` text NOT NULL,
33
+ `name` text NOT NULL,
34
+ `value` text NOT NULL
35
+ );
36
+ --> statement-breakpoint
37
+ CREATE INDEX `idx_pf_name` ON `product_facets` (`name`,`value`);--> statement-breakpoint
38
+ CREATE TABLE `products` (
39
+ `handle` text PRIMARY KEY NOT NULL,
40
+ `title` text NOT NULL,
41
+ `vendor` text,
42
+ `product_type` text,
43
+ `tags` text DEFAULT '[]' NOT NULL,
44
+ `description_text` text DEFAULT '' NOT NULL,
45
+ `price_min` real NOT NULL,
46
+ `price_max` real NOT NULL,
47
+ `currency` text NOT NULL,
48
+ `image` text,
49
+ `available` integer DEFAULT 0 NOT NULL,
50
+ `status` text NOT NULL,
51
+ `position` integer DEFAULT 0 NOT NULL,
52
+ `created_at` text,
53
+ `data` text NOT NULL
54
+ );
@@ -0,0 +1,9 @@
1
+ -- Custom SQL migration file, put your code below! --
2
+ -- FTS5 (trigram) virtual table for typo-tolerant product search. Drizzle can't model
3
+ -- CREATE VIRTUAL TABLE, so this is hand-maintained — keep it in step with
4
+ -- CATALOG_D1_SCHEMA in @tot/private-controlplane (the structural equivalence test in
5
+ -- src/lib/d1/schema.test.ts enforces that the migrations reproduce that contract).
6
+ CREATE VIRTUAL TABLE IF NOT EXISTS products_fts USING fts5 (
7
+ handle UNINDEXED, title, vendor, product_type, tags, description_text,
8
+ tokenize = 'trigram'
9
+ );
@@ -0,0 +1,54 @@
1
+ # D1 provision migrations (Drizzle Kit)
2
+
3
+ The catalog + customization D1 schema as numbered migrations, applied by `provision.sh`
4
+ (the **provision** lifecycle phase — never `deploy`, never runtime). Generated by
5
+ **Drizzle Kit** (ADR-0002), applied by `wrangler d1 migrations apply`.
6
+
7
+ ## Source of truth
8
+
9
+ - **`src/lib/d1/schema.ts`** (Drizzle schema) is the source of truth for migration
10
+ *generation*. `drizzle-kit generate` diffs it into numbered `migrations/*.sql`
11
+ (+ `meta/` journal) and owns the SQLite table-rebuild logic for `ALTER`s.
12
+ - **`products_fts`** (FTS5 virtual table) can't be modelled by Drizzle — it's a custom
13
+ migration (`0001_products_fts.sql`), hand-maintained.
14
+ - The raw-SQL read model + ETL still consume `CATALOG_D1_SCHEMA`/`CUSTOMIZATION_D1_SCHEMA`
15
+ (`@tot/private-controlplane`). A **structural** equivalence test (`src/lib/d1/schema.test.ts`,
16
+ PRAGMA-based) asserts the migrations reproduce that contract, so generator and read
17
+ model can't drift.
18
+
19
+ ## Safety (D1 has no rollback)
20
+
21
+ `src/lib/d1/migrationSafety.ts` + its test **fail CI** on any unmarked `DROP TABLE` /
22
+ `DROP COLUMN` (which also catches SQLite column-dropping rebuilds), because the
23
+ equivalence test only proves *end-state* correctness, not a safe transition. An
24
+ *intended* destructive change must opt in, in the migration file:
25
+
26
+ ```sql
27
+ -- allow-destructive: <why this data loss is intended>
28
+ ```
29
+
30
+ ## Workflows
31
+
32
+ **Regular change (add/alter a column, table):**
33
+ 1. Edit `src/lib/d1/schema.ts`.
34
+ 2. `pnpm --filter @tot/storefront gen:migrations` (Drizzle emits the next numbered SQL,
35
+ including SQLite table-rebuilds for unsupported `ALTER`s).
36
+ 3. If a column was removed, add `-- allow-destructive: <reason>` to the generated file.
37
+ 4. Update the matching `@tot/private-controlplane` const so the equivalence test stays green; commit
38
+ schema + generated `.sql` + journal together.
39
+
40
+ **Custom SQL (e.g. a new FTS table, trigger):**
41
+ `pnpm --filter @tot/storefront gen:migrations:custom` → fill in the emitted file.
42
+
43
+ Never renumber or rewrite a *shipped* id (`wrangler` tracks applied ids); only append.
44
+
45
+ ## Applying
46
+
47
+ `provision.sh --env=<env>` runs, after creating the D1 database:
48
+
49
+ ```sh
50
+ wrangler d1 migrations apply CATALOG_DB --env <env> [--remote|--local]
51
+ ```
52
+
53
+ > Catalog + customization tables share the **one** `CATALOG_DB` binding (one edge DB),
54
+ > per `src/lib/customization/d1Store.ts`.
@@ -0,0 +1,347 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "3667f8d8-a1ba-49ac-809a-c06004bad5d6",
5
+ "prevId": "00000000-0000-0000-0000-000000000000",
6
+ "tables": {
7
+ "collections": {
8
+ "name": "collections",
9
+ "columns": {
10
+ "handle": {
11
+ "name": "handle",
12
+ "type": "text",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "title": {
18
+ "name": "title",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "position": {
25
+ "name": "position",
26
+ "type": "integer",
27
+ "primaryKey": false,
28
+ "notNull": true,
29
+ "autoincrement": false,
30
+ "default": 99
31
+ },
32
+ "data": {
33
+ "name": "data",
34
+ "type": "text",
35
+ "primaryKey": false,
36
+ "notNull": true,
37
+ "autoincrement": false
38
+ }
39
+ },
40
+ "indexes": {},
41
+ "foreignKeys": {},
42
+ "compositePrimaryKeys": {},
43
+ "uniqueConstraints": {},
44
+ "checkConstraints": {}
45
+ },
46
+ "customization_pointers": {
47
+ "name": "customization_pointers",
48
+ "columns": {
49
+ "tenant_id": {
50
+ "name": "tenant_id",
51
+ "type": "text",
52
+ "primaryKey": true,
53
+ "notNull": true,
54
+ "autoincrement": false
55
+ },
56
+ "rev": {
57
+ "name": "rev",
58
+ "type": "integer",
59
+ "primaryKey": false,
60
+ "notNull": true,
61
+ "autoincrement": false
62
+ },
63
+ "live": {
64
+ "name": "live",
65
+ "type": "text",
66
+ "primaryKey": false,
67
+ "notNull": true,
68
+ "autoincrement": false
69
+ },
70
+ "test": {
71
+ "name": "test",
72
+ "type": "text",
73
+ "primaryKey": false,
74
+ "notNull": true,
75
+ "autoincrement": false
76
+ }
77
+ },
78
+ "indexes": {},
79
+ "foreignKeys": {},
80
+ "compositePrimaryKeys": {},
81
+ "uniqueConstraints": {},
82
+ "checkConstraints": {}
83
+ },
84
+ "customization_versions": {
85
+ "name": "customization_versions",
86
+ "columns": {
87
+ "tenant_id": {
88
+ "name": "tenant_id",
89
+ "type": "text",
90
+ "primaryKey": false,
91
+ "notNull": true,
92
+ "autoincrement": false
93
+ },
94
+ "path": {
95
+ "name": "path",
96
+ "type": "text",
97
+ "primaryKey": false,
98
+ "notNull": true,
99
+ "autoincrement": false
100
+ },
101
+ "version_id": {
102
+ "name": "version_id",
103
+ "type": "text",
104
+ "primaryKey": false,
105
+ "notNull": true,
106
+ "autoincrement": false
107
+ },
108
+ "size": {
109
+ "name": "size",
110
+ "type": "integer",
111
+ "primaryKey": false,
112
+ "notNull": true,
113
+ "autoincrement": false
114
+ },
115
+ "created_at": {
116
+ "name": "created_at",
117
+ "type": "text",
118
+ "primaryKey": false,
119
+ "notNull": true,
120
+ "autoincrement": false
121
+ },
122
+ "content": {
123
+ "name": "content",
124
+ "type": "text",
125
+ "primaryKey": false,
126
+ "notNull": true,
127
+ "autoincrement": false
128
+ }
129
+ },
130
+ "indexes": {},
131
+ "foreignKeys": {},
132
+ "compositePrimaryKeys": {
133
+ "customization_versions_tenant_id_path_version_id_pk": {
134
+ "columns": [
135
+ "tenant_id",
136
+ "path",
137
+ "version_id"
138
+ ],
139
+ "name": "customization_versions_tenant_id_path_version_id_pk"
140
+ }
141
+ },
142
+ "uniqueConstraints": {},
143
+ "checkConstraints": {}
144
+ },
145
+ "product_collections": {
146
+ "name": "product_collections",
147
+ "columns": {
148
+ "handle": {
149
+ "name": "handle",
150
+ "type": "text",
151
+ "primaryKey": false,
152
+ "notNull": true,
153
+ "autoincrement": false
154
+ },
155
+ "collection": {
156
+ "name": "collection",
157
+ "type": "text",
158
+ "primaryKey": false,
159
+ "notNull": true,
160
+ "autoincrement": false
161
+ }
162
+ },
163
+ "indexes": {
164
+ "idx_pc_collection": {
165
+ "name": "idx_pc_collection",
166
+ "columns": [
167
+ "collection"
168
+ ],
169
+ "isUnique": false
170
+ }
171
+ },
172
+ "foreignKeys": {},
173
+ "compositePrimaryKeys": {},
174
+ "uniqueConstraints": {},
175
+ "checkConstraints": {}
176
+ },
177
+ "product_facets": {
178
+ "name": "product_facets",
179
+ "columns": {
180
+ "handle": {
181
+ "name": "handle",
182
+ "type": "text",
183
+ "primaryKey": false,
184
+ "notNull": true,
185
+ "autoincrement": false
186
+ },
187
+ "name": {
188
+ "name": "name",
189
+ "type": "text",
190
+ "primaryKey": false,
191
+ "notNull": true,
192
+ "autoincrement": false
193
+ },
194
+ "value": {
195
+ "name": "value",
196
+ "type": "text",
197
+ "primaryKey": false,
198
+ "notNull": true,
199
+ "autoincrement": false
200
+ }
201
+ },
202
+ "indexes": {
203
+ "idx_pf_name": {
204
+ "name": "idx_pf_name",
205
+ "columns": [
206
+ "name",
207
+ "value"
208
+ ],
209
+ "isUnique": false
210
+ }
211
+ },
212
+ "foreignKeys": {},
213
+ "compositePrimaryKeys": {},
214
+ "uniqueConstraints": {},
215
+ "checkConstraints": {}
216
+ },
217
+ "products": {
218
+ "name": "products",
219
+ "columns": {
220
+ "handle": {
221
+ "name": "handle",
222
+ "type": "text",
223
+ "primaryKey": true,
224
+ "notNull": true,
225
+ "autoincrement": false
226
+ },
227
+ "title": {
228
+ "name": "title",
229
+ "type": "text",
230
+ "primaryKey": false,
231
+ "notNull": true,
232
+ "autoincrement": false
233
+ },
234
+ "vendor": {
235
+ "name": "vendor",
236
+ "type": "text",
237
+ "primaryKey": false,
238
+ "notNull": false,
239
+ "autoincrement": false
240
+ },
241
+ "product_type": {
242
+ "name": "product_type",
243
+ "type": "text",
244
+ "primaryKey": false,
245
+ "notNull": false,
246
+ "autoincrement": false
247
+ },
248
+ "tags": {
249
+ "name": "tags",
250
+ "type": "text",
251
+ "primaryKey": false,
252
+ "notNull": true,
253
+ "autoincrement": false,
254
+ "default": "'[]'"
255
+ },
256
+ "description_text": {
257
+ "name": "description_text",
258
+ "type": "text",
259
+ "primaryKey": false,
260
+ "notNull": true,
261
+ "autoincrement": false,
262
+ "default": "''"
263
+ },
264
+ "price_min": {
265
+ "name": "price_min",
266
+ "type": "real",
267
+ "primaryKey": false,
268
+ "notNull": true,
269
+ "autoincrement": false
270
+ },
271
+ "price_max": {
272
+ "name": "price_max",
273
+ "type": "real",
274
+ "primaryKey": false,
275
+ "notNull": true,
276
+ "autoincrement": false
277
+ },
278
+ "currency": {
279
+ "name": "currency",
280
+ "type": "text",
281
+ "primaryKey": false,
282
+ "notNull": true,
283
+ "autoincrement": false
284
+ },
285
+ "image": {
286
+ "name": "image",
287
+ "type": "text",
288
+ "primaryKey": false,
289
+ "notNull": false,
290
+ "autoincrement": false
291
+ },
292
+ "available": {
293
+ "name": "available",
294
+ "type": "integer",
295
+ "primaryKey": false,
296
+ "notNull": true,
297
+ "autoincrement": false,
298
+ "default": 0
299
+ },
300
+ "status": {
301
+ "name": "status",
302
+ "type": "text",
303
+ "primaryKey": false,
304
+ "notNull": true,
305
+ "autoincrement": false
306
+ },
307
+ "position": {
308
+ "name": "position",
309
+ "type": "integer",
310
+ "primaryKey": false,
311
+ "notNull": true,
312
+ "autoincrement": false,
313
+ "default": 0
314
+ },
315
+ "created_at": {
316
+ "name": "created_at",
317
+ "type": "text",
318
+ "primaryKey": false,
319
+ "notNull": false,
320
+ "autoincrement": false
321
+ },
322
+ "data": {
323
+ "name": "data",
324
+ "type": "text",
325
+ "primaryKey": false,
326
+ "notNull": true,
327
+ "autoincrement": false
328
+ }
329
+ },
330
+ "indexes": {},
331
+ "foreignKeys": {},
332
+ "compositePrimaryKeys": {},
333
+ "uniqueConstraints": {},
334
+ "checkConstraints": {}
335
+ }
336
+ },
337
+ "views": {},
338
+ "enums": {},
339
+ "_meta": {
340
+ "schemas": {},
341
+ "tables": {},
342
+ "columns": {}
343
+ },
344
+ "internal": {
345
+ "indexes": {}
346
+ }
347
+ }