@tokenoftrust/storefront-runner 0.1.0

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 (337) hide show
  1. package/LICENSE +58 -0
  2. package/README.md +40 -0
  3. package/apps/storefront/.dev.vars.example +41 -0
  4. package/apps/storefront/.env.example +24 -0
  5. package/apps/storefront/astro.config.mjs +245 -0
  6. package/apps/storefront/env.d.ts +155 -0
  7. package/apps/storefront/lib/ensure-preview-reconcile-secret.sh +31 -0
  8. package/apps/storefront/lib/resolve-cf-token.sh +48 -0
  9. package/apps/storefront/lib/resolve-tot-credentials.sh +69 -0
  10. package/apps/storefront/migrations/0000_baseline.sql +54 -0
  11. package/apps/storefront/migrations/0001_products_fts.sql +9 -0
  12. package/apps/storefront/migrations/README.md +54 -0
  13. package/apps/storefront/migrations/meta/0000_snapshot.json +347 -0
  14. package/apps/storefront/migrations/meta/0001_snapshot.json +347 -0
  15. package/apps/storefront/migrations/meta/_journal.json +20 -0
  16. package/apps/storefront/package.json +41 -0
  17. package/apps/storefront/public/brand/northwind-logo-dark.svg +4 -0
  18. package/apps/storefront/public/brand/northwind-logo-light.svg +4 -0
  19. package/apps/storefront/public/brand/northwind-og.svg +13 -0
  20. package/apps/storefront/public/favicon.svg +5 -0
  21. package/apps/storefront/public/js/dashboard-team.js +147 -0
  22. package/apps/storefront/public/js/dashboard-vendor-search.js +115 -0
  23. package/apps/storefront/src/components/Badge.astro +34 -0
  24. package/apps/storefront/src/components/Breadcrumbs.astro +45 -0
  25. package/apps/storefront/src/components/CollectionCard.astro +56 -0
  26. package/apps/storefront/src/components/EmptyState.astro +35 -0
  27. package/apps/storefront/src/components/Img.astro +68 -0
  28. package/apps/storefront/src/components/ProductCard.astro +228 -0
  29. package/apps/storefront/src/components/Section.astro +39 -0
  30. package/apps/storefront/src/components/Seo.astro +70 -0
  31. package/apps/storefront/src/components/WidgetFrame.astro +34 -0
  32. package/apps/storefront/src/components/auth/AuthBadge.astro +44 -0
  33. package/apps/storefront/src/components/chrome/AnnouncementBar.astro +108 -0
  34. package/apps/storefront/src/components/chrome/MegaMenu.astro +26 -0
  35. package/apps/storefront/src/components/chrome/NavDropdown.astro +116 -0
  36. package/apps/storefront/src/components/chrome/SiteFooter.astro +181 -0
  37. package/apps/storefront/src/components/chrome/SiteHeader.astro +181 -0
  38. package/apps/storefront/src/components/chrome/UtilityNav.astro +79 -0
  39. package/apps/storefront/src/components/commerce/FoxyLoader.astro +23 -0
  40. package/apps/storefront/src/components/commerce/PriceDisplay.astro +91 -0
  41. package/apps/storefront/src/components/commerce/ProductCarousel.astro +197 -0
  42. package/apps/storefront/src/components/commerce/ProductGrid.astro +75 -0
  43. package/apps/storefront/src/components/commerce/RatingStars.astro +58 -0
  44. package/apps/storefront/src/components/compliance/NicotineWarning.astro +33 -0
  45. package/apps/storefront/src/components/home/Hero.astro +164 -0
  46. package/apps/storefront/src/components/islands/AgeGate.tsx +105 -0
  47. package/apps/storefront/src/components/islands/ImageGallery.tsx +237 -0
  48. package/apps/storefront/src/components/islands/IsolatedAgeGate.tsx +73 -0
  49. package/apps/storefront/src/components/islands/MobileNav.tsx +239 -0
  50. package/apps/storefront/src/components/islands/QuickView.tsx +138 -0
  51. package/apps/storefront/src/components/islands/RecentlyViewed.tsx +122 -0
  52. package/apps/storefront/src/components/islands/SavedList.tsx +99 -0
  53. package/apps/storefront/src/components/islands/SearchTypeahead.tsx +248 -0
  54. package/apps/storefront/src/components/islands/VariantSelector.tsx +378 -0
  55. package/apps/storefront/src/components/marketing/CardGrid.astro +72 -0
  56. package/apps/storefront/src/components/marketing/CodeSample.astro +20 -0
  57. package/apps/storefront/src/components/marketing/CtaBand.astro +24 -0
  58. package/apps/storefront/src/components/marketing/Faq.astro +37 -0
  59. package/apps/storefront/src/components/marketing/Integrations.astro +63 -0
  60. package/apps/storefront/src/components/marketing/MarketingBlocks.astro +53 -0
  61. package/apps/storefront/src/components/marketing/MarketingCtas.astro +48 -0
  62. package/apps/storefront/src/components/marketing/MarketingHero.astro +72 -0
  63. package/apps/storefront/src/components/marketing/ProofStrip.astro +37 -0
  64. package/apps/storefront/src/components/marketing/SplitCompare.astro +53 -0
  65. package/apps/storefront/src/components/marketing/Steps.astro +36 -0
  66. package/apps/storefront/src/components/marketing/Testimonials.astro +38 -0
  67. package/apps/storefront/src/components/marketing/TrustBar.astro +22 -0
  68. package/apps/storefront/src/components/nav/Footer.astro +148 -0
  69. package/apps/storefront/src/components/nav/Header.astro +190 -0
  70. package/apps/storefront/src/components/plp/ActiveFilters.astro +79 -0
  71. package/apps/storefront/src/components/plp/FacetSidebar.astro +146 -0
  72. package/apps/storefront/src/components/plp/Pagination.astro +99 -0
  73. package/apps/storefront/src/components/plp/SortSelect.astro +64 -0
  74. package/apps/storefront/src/config/devTenants.ts +16 -0
  75. package/apps/storefront/src/config/kvTenantResolver.ts +87 -0
  76. package/apps/storefront/src/config/resolver.ts +46 -0
  77. package/apps/storefront/src/config/tenants.ts +193 -0
  78. package/apps/storefront/src/layouts/Layout.astro +303 -0
  79. package/apps/storefront/src/lib/analytics/index.ts +47 -0
  80. package/apps/storefront/src/lib/auth/brokerAssertion.ts +136 -0
  81. package/apps/storefront/src/lib/auth/devAuth.ts +90 -0
  82. package/apps/storefront/src/lib/auth/gatePage.ts +81 -0
  83. package/apps/storefront/src/lib/auth/identityToken.ts +341 -0
  84. package/apps/storefront/src/lib/auth/loginGate.ts +107 -0
  85. package/apps/storefront/src/lib/auth/route.ts +146 -0
  86. package/apps/storefront/src/lib/auth/session.ts +203 -0
  87. package/apps/storefront/src/lib/auth/totAccessClient.ts +503 -0
  88. package/apps/storefront/src/lib/basePath.ts +41 -0
  89. package/apps/storefront/src/lib/cfImage.ts +55 -0
  90. package/apps/storefront/src/lib/chrome/model.ts +65 -0
  91. package/apps/storefront/src/lib/colors.ts +97 -0
  92. package/apps/storefront/src/lib/content-edit/client.ts +230 -0
  93. package/apps/storefront/src/lib/content-edit/index.ts +14 -0
  94. package/apps/storefront/src/lib/content-edit/route.ts +25 -0
  95. package/apps/storefront/src/lib/content-edit/types.ts +19 -0
  96. package/apps/storefront/src/lib/cspStaticHashes.ts +24 -0
  97. package/apps/storefront/src/lib/d1/catalog.ts +289 -0
  98. package/apps/storefront/src/lib/dashboard/staffAdmission.ts +43 -0
  99. package/apps/storefront/src/lib/dashboard/staffVendorAccess.ts +449 -0
  100. package/apps/storefront/src/lib/dashboard/tenantSelection.ts +136 -0
  101. package/apps/storefront/src/lib/dashboard/vendorQuery.ts +61 -0
  102. package/apps/storefront/src/lib/demoGate.ts +113 -0
  103. package/apps/storefront/src/lib/dev/ai-widget-client.js +127 -0
  104. package/apps/storefront/src/lib/dev/cliSignInCode.ts +132 -0
  105. package/apps/storefront/src/lib/diag/redact.ts +20 -0
  106. package/apps/storefront/src/lib/edgeCache.ts +128 -0
  107. package/apps/storefront/src/lib/email/magicLinkInviteEmail.ts +62 -0
  108. package/apps/storefront/src/lib/env.ts +60 -0
  109. package/apps/storefront/src/lib/fixtures/sampleProducts.ts +130 -0
  110. package/apps/storefront/src/lib/format.ts +29 -0
  111. package/apps/storefront/src/lib/foxyCommerce.ts +49 -0
  112. package/apps/storefront/src/lib/imageAttrs.ts +55 -0
  113. package/apps/storefront/src/lib/jsonld.ts +136 -0
  114. package/apps/storefront/src/lib/maintenance.ts +71 -0
  115. package/apps/storefront/src/lib/memoryKv.ts +32 -0
  116. package/apps/storefront/src/lib/messaging/messagesClient.ts +143 -0
  117. package/apps/storefront/src/lib/placeholder.ts +99 -0
  118. package/apps/storefront/src/lib/previewReload.ts +125 -0
  119. package/apps/storefront/src/lib/rawMarketingHtml.ts +133 -0
  120. package/apps/storefront/src/lib/search/index.ts +74 -0
  121. package/apps/storefront/src/lib/sections.ts +129 -0
  122. package/apps/storefront/src/lib/securityHeaders.ts +31 -0
  123. package/apps/storefront/src/lib/storyblok/content-model.ts +289 -0
  124. package/apps/storefront/src/lib/storyblok/provider.ts +524 -0
  125. package/apps/storefront/src/lib/tenantRouting.ts +91 -0
  126. package/apps/storefront/src/lib/tot/ToTClient.ts +177 -0
  127. package/apps/storefront/src/lib/tot/d1Client.ts +62 -0
  128. package/apps/storefront/src/lib/tot/query.ts +187 -0
  129. package/apps/storefront/src/lib/tot/totClientInterface.ts +30 -0
  130. package/apps/storefront/src/lib/url.ts +119 -0
  131. package/apps/storefront/src/lib/wishlist.ts +63 -0
  132. package/apps/storefront/src/middleware/index.ts +413 -0
  133. package/apps/storefront/src/pages/404.astro +61 -0
  134. package/apps/storefront/src/pages/[...slug].astro +90 -0
  135. package/apps/storefront/src/pages/api/auth/logout.ts +21 -0
  136. package/apps/storefront/src/pages/api/auth/magic-exchange.ts +107 -0
  137. package/apps/storefront/src/pages/api/auth/send.ts +85 -0
  138. package/apps/storefront/src/pages/api/auth/verify.ts +135 -0
  139. package/apps/storefront/src/pages/api/cache-purge.ts +44 -0
  140. package/apps/storefront/src/pages/api/content-edit/ai-edit.ts +64 -0
  141. package/apps/storefront/src/pages/api/csp-report.ts +25 -0
  142. package/apps/storefront/src/pages/api/dashboard/enter-vendor.ts +124 -0
  143. package/apps/storefront/src/pages/api/dashboard/vendor-search.ts +120 -0
  144. package/apps/storefront/src/pages/api/dev/cli-signin-code.ts +44 -0
  145. package/apps/storefront/src/pages/api/newsletter.ts +104 -0
  146. package/apps/storefront/src/pages/api/request-access.ts +172 -0
  147. package/apps/storefront/src/pages/auth/login.astro +149 -0
  148. package/apps/storefront/src/pages/auth/magic.astro +105 -0
  149. package/apps/storefront/src/pages/capabilities.astro +292 -0
  150. package/apps/storefront/src/pages/collections/[handle].astro +154 -0
  151. package/apps/storefront/src/pages/collections/index.astro +59 -0
  152. package/apps/storefront/src/pages/dashboard/[appDomain]/index.astro +100 -0
  153. package/apps/storefront/src/pages/dashboard/[appDomain]/team.astro +154 -0
  154. package/apps/storefront/src/pages/dashboard/index.astro +160 -0
  155. package/apps/storefront/src/pages/dev.astro +653 -0
  156. package/apps/storefront/src/pages/index.astro +290 -0
  157. package/apps/storefront/src/pages/llms.txt.ts +92 -0
  158. package/apps/storefront/src/pages/products/[handle].astro +443 -0
  159. package/apps/storefront/src/pages/robots.txt.ts +24 -0
  160. package/apps/storefront/src/pages/saved.astro +35 -0
  161. package/apps/storefront/src/pages/search.astro +150 -0
  162. package/apps/storefront/src/pages/sitemap.xml.ts +78 -0
  163. package/apps/storefront/src/pages/style-guide/[tenant]/[theme].astro +646 -0
  164. package/apps/storefront/src/pages/style-guide/[tenant]/index.astro +85 -0
  165. package/apps/storefront/src/pages/style-guide/index.astro +94 -0
  166. package/apps/storefront/src/pages/tenants/[id]/[...path].ts +57 -0
  167. package/apps/storefront/src/styles/global.css +277 -0
  168. package/apps/storefront/src/themes/reference.ts +61 -0
  169. package/apps/storefront/src/themes/schema.ts +111 -0
  170. package/apps/storefront/src/themes/tenants/index.ts +51 -0
  171. package/apps/storefront/tsconfig.json +16 -0
  172. package/apps/storefront/vitest.config.ts +22 -0
  173. package/apps/storefront/wrangler.toml +175 -0
  174. package/package.json +23 -0
  175. package/packages/public-runtime/LICENSE +58 -0
  176. package/packages/public-runtime/package.json +22 -0
  177. package/packages/public-runtime/src/binary-path.ts +68 -0
  178. package/packages/public-runtime/src/capabilities.ts +89 -0
  179. package/packages/public-runtime/src/catalog-api.ts +81 -0
  180. package/packages/public-runtime/src/catalog-d1.ts +192 -0
  181. package/packages/public-runtime/src/csp.ts +109 -0
  182. package/packages/public-runtime/src/customization-preview.ts +197 -0
  183. package/packages/public-runtime/src/customization-reconcile.ts +63 -0
  184. package/packages/public-runtime/src/customization-runtime.ts +157 -0
  185. package/packages/public-runtime/src/customization-scripts.ts +64 -0
  186. package/packages/public-runtime/src/customization-versioning.ts +95 -0
  187. package/packages/public-runtime/src/foxy.ts +184 -0
  188. package/packages/public-runtime/src/index.ts +30 -0
  189. package/packages/public-runtime/src/product.ts +159 -0
  190. package/packages/public-runtime/src/search.ts +45 -0
  191. package/packages/public-runtime/src/tenant-assets.ts +444 -0
  192. package/packages/public-runtime/src/tenant.ts +243 -0
  193. package/packages/public-runtime/tsconfig.json +8 -0
  194. package/packages/public-runtime/vitest.config.ts +8 -0
  195. package/pnpm-workspace.yaml +7 -0
  196. package/scripts/build/copy-tenant-assets.mjs +69 -0
  197. package/scripts/tot-dev.mjs +439 -0
  198. package/tenants/bigdvapor/content/blog.json +52 -0
  199. package/tenants/bigdvapor/content/chrome.html +149 -0
  200. package/tenants/bigdvapor/content/chrome.json +47 -0
  201. package/tenants/bigdvapor/content/home.html +463 -0
  202. package/tenants/bigdvapor/content/home.json +73 -0
  203. package/tenants/bigdvapor/content/pages/about.json +5 -0
  204. package/tenants/bigdvapor/content/pages/privacy.json +6 -0
  205. package/tenants/bigdvapor/content/pages/shipping-returns.json +6 -0
  206. package/tenants/bigdvapor/content/pages-html/blogs/news.html +86 -0
  207. package/tenants/bigdvapor/content/pages-html/pages/about-us.html +106 -0
  208. package/tenants/bigdvapor/content/pages-html/pages/contact-us.html +61 -0
  209. package/tenants/bigdvapor/content/pages-html/pages/privacy-policy.html +72 -0
  210. package/tenants/bigdvapor/content/pages-html/pages/shipping-returns.html +172 -0
  211. package/tenants/bigdvapor/content/themes/bigd-navy.json +109 -0
  212. package/tenants/bigdvapor/public/img/brands/adjust-vape-disposable.png +0 -0
  213. package/tenants/bigdvapor/public/img/brands/again-vape-disposable.png +0 -0
  214. package/tenants/bigdvapor/public/img/brands/al-fakher-vape-disposable.png +0 -0
  215. package/tenants/bigdvapor/public/img/brands/arro-vape-disposable.png +0 -0
  216. package/tenants/bigdvapor/public/img/brands/cookies-vape-disposable.png +0 -0
  217. package/tenants/bigdvapor/public/img/brands/core-vape-disposable.png +0 -0
  218. package/tenants/bigdvapor/public/img/brands/cyclone-vape-disposable.png +0 -0
  219. package/tenants/bigdvapor/public/img/brands/dinner-lady-vape-disposable.png +0 -0
  220. package/tenants/bigdvapor/public/img/brands/extre-bar-vape-disposable.png +0 -0
  221. package/tenants/bigdvapor/public/img/brands/fifty-bar-vape-disposable.jpg +0 -0
  222. package/tenants/bigdvapor/public/img/brands/firerose-vape-disposable.jpg +0 -0
  223. package/tenants/bigdvapor/public/img/brands/flavor-beast-vape-disposable.jpg +0 -0
  224. package/tenants/bigdvapor/public/img/brands/foger-vape-disposable.png +0 -0
  225. package/tenants/bigdvapor/public/img/brands/kk-energy-vape-disposable.png +0 -0
  226. package/tenants/bigdvapor/public/img/brands/kumi-vape-disposable.png +0 -0
  227. package/tenants/bigdvapor/public/img/brands/lost-vape-dispoable.png +0 -0
  228. package/tenants/bigdvapor/public/img/brands/melo-labs-vape-disposable.png +0 -0
  229. package/tenants/bigdvapor/public/img/brands/mixo-vape-disposable.webp +0 -0
  230. package/tenants/bigdvapor/public/img/brands/one-tank-vape-disposable.jpg +0 -0
  231. package/tenants/bigdvapor/public/img/brands/oxbar-vape-disposable.webp +0 -0
  232. package/tenants/bigdvapor/public/img/brands/pillow-talk-vape-disposable.jpg +0 -0
  233. package/tenants/bigdvapor/public/img/brands/pod-king-vape-disposable.jpg +0 -0
  234. package/tenants/bigdvapor/public/img/brands/raz-vape-disposable.png +0 -0
  235. package/tenants/bigdvapor/public/img/hero-texas.jpg +0 -0
  236. package/tenants/bigdvapor/public/img/og.jpg +0 -0
  237. package/tenants/bigdvapor/public/img/pages/AdobeStock_202106312_web.jpg +0 -0
  238. package/tenants/bigdvapor/public/img/pages/CREW_web.jpg +0 -0
  239. package/tenants/bigdvapor/public/img/pages/Hero-Image.jpg +0 -0
  240. package/tenants/bigdvapor/public/img/tiles/adjust.png +0 -0
  241. package/tenants/bigdvapor/public/img/tiles/again.png +0 -0
  242. package/tenants/bigdvapor/public/img/tiles/al-fakher.png +0 -0
  243. package/tenants/bigdvapor/public/img/tiles/arro.png +0 -0
  244. package/tenants/bigdvapor/public/img/tiles/cookies.png +0 -0
  245. package/tenants/bigdvapor/public/img/tiles/core.png +0 -0
  246. package/tenants/bigdvapor/public/img/tiles/cyclone.png +0 -0
  247. package/tenants/bigdvapor/public/img/tiles/disposables.svg +23 -0
  248. package/tenants/bigdvapor/public/logo-wordmark.png +0 -0
  249. package/tenants/bigdvapor/public/pages/home.css +118 -0
  250. package/tenants/bigdvapor/public/pages/mkt.css +185 -0
  251. package/tenants/bigdvapor/public/pages/page.css +148 -0
  252. package/tenants/bigdvapor/public/themes/bigd-navy.css +73 -0
  253. package/tenants/bigdvapor/theme.json +12 -0
  254. package/tenants/giantvapes/content/chrome.html +152 -0
  255. package/tenants/giantvapes/content/chrome.json +94 -0
  256. package/tenants/giantvapes/content/home.html +194 -0
  257. package/tenants/giantvapes/content/home.json +50 -0
  258. package/tenants/giantvapes/content/pages/about.json +10 -0
  259. package/tenants/giantvapes/content/pages/privacy.json +6 -0
  260. package/tenants/giantvapes/content/pages/shipping-returns.json +6 -0
  261. package/tenants/giantvapes/content/pages-html/blogs/news.html +68 -0
  262. package/tenants/giantvapes/content/pages-html/pages/about-us.html +95 -0
  263. package/tenants/giantvapes/content/pages-html/pages/contact-us.html +68 -0
  264. package/tenants/giantvapes/content/pages-html/pages/privacy-policy.html +65 -0
  265. package/tenants/giantvapes/content/pages-html/pages/shipping-returns.html +77 -0
  266. package/tenants/giantvapes/content/themes/giant-navy.json +73 -0
  267. package/tenants/giantvapes/public/img/hero-suicide-bunny.jpg +0 -0
  268. package/tenants/giantvapes/public/img/hero.webp +0 -0
  269. package/tenants/giantvapes/public/img/og.jpg +0 -0
  270. package/tenants/giantvapes/public/logo-wordmark.png +0 -0
  271. package/tenants/giantvapes/public/pages/home.css +120 -0
  272. package/tenants/giantvapes/public/pages/mkt.css +185 -0
  273. package/tenants/giantvapes/public/pages/page.css +155 -0
  274. package/tenants/giantvapes/public/themes/giant-navy.css +76 -0
  275. package/tenants/giantvapes/theme.json +39 -0
  276. package/tenants/home/content/chrome.json +11 -0
  277. package/tenants/home/content/home.html +304 -0
  278. package/tenants/home/content/home.json +13 -0
  279. package/tenants/home/public/js/storefront.js +210 -0
  280. package/tenants/home/public/logo-wordmark.png +0 -0
  281. package/tenants/home/public/pages/storefront.css +212 -0
  282. package/tenants/home/theme.json +6 -0
  283. package/tenants/tokenoftrust/.tot/config.json +9 -0
  284. package/tenants/tokenoftrust/content/chrome.json +55 -0
  285. package/tenants/tokenoftrust/content/home.html +723 -0
  286. package/tenants/tokenoftrust/content/home.json +233 -0
  287. package/tenants/tokenoftrust/content/pages-html/careers.html +231 -0
  288. package/tenants/tokenoftrust/content/pages-html/company.html +275 -0
  289. package/tenants/tokenoftrust/content/pages-html/contact/contact-sales.html +188 -0
  290. package/tenants/tokenoftrust/content/pages-html/contact/startup-apply.html +206 -0
  291. package/tenants/tokenoftrust/content/pages-html/contact.html +178 -0
  292. package/tenants/tokenoftrust/content/pages-html/industries/adult-content-age-verification.html +286 -0
  293. package/tenants/tokenoftrust/content/pages-html/industries/cannabis.html +277 -0
  294. package/tenants/tokenoftrust/content/pages-html/pact-act-pricing.html +289 -0
  295. package/tenants/tokenoftrust/content/pages-html/pricing.html +483 -0
  296. package/tenants/tokenoftrust/content/pages-html/product/age-assurance/age-estimation.html +278 -0
  297. package/tenants/tokenoftrust/content/pages-html/product/age-assurance/age-gate.html +279 -0
  298. package/tenants/tokenoftrust/content/pages-html/product/age-assurance/age-verification.html +265 -0
  299. package/tenants/tokenoftrust/content/pages-html/product/age-assurance.html +173 -0
  300. package/tenants/tokenoftrust/content/pages-html/product/compliance/aml.html +214 -0
  301. package/tenants/tokenoftrust/content/pages-html/product/compliance/pact-act.html +226 -0
  302. package/tenants/tokenoftrust/content/pages-html/product/fraud-prevention.html +254 -0
  303. package/tenants/tokenoftrust/content/pages-html/product/social-profile-verification.html +212 -0
  304. package/tenants/tokenoftrust/content/pages-html/product/tax/excise-tax.html +213 -0
  305. package/tenants/tokenoftrust/content/pages-html/product/verification/aml.html +259 -0
  306. package/tenants/tokenoftrust/content/pages-html/product/verification/biometric-selfie.html +305 -0
  307. package/tenants/tokenoftrust/content/pages-html/product/verification/coverage.html +254 -0
  308. package/tenants/tokenoftrust/content/pages-html/product/verification/document-verification.html +306 -0
  309. package/tenants/tokenoftrust/content/pages-html/product/verification/electronic-identity-verification.html +304 -0
  310. package/tenants/tokenoftrust/content/pages-html/product/verification/government-id-verification.html +308 -0
  311. package/tenants/tokenoftrust/content/pages-html/product/verification.html +183 -0
  312. package/tenants/tokenoftrust/content/pages-html/product.html +228 -0
  313. package/tenants/tokenoftrust/content/pages-html/resources/integrations/bigcommerce-integration.html +220 -0
  314. package/tenants/tokenoftrust/content/pages-html/resources/integrations/shopify-integration.html +221 -0
  315. package/tenants/tokenoftrust/content/pages-html/resources/integrations/wordpress.html +220 -0
  316. package/tenants/tokenoftrust/content/pages-html/resources/integrations.html +172 -0
  317. package/tenants/tokenoftrust/content/pages-html/resources/refer-a-friend-program.html +317 -0
  318. package/tenants/tokenoftrust/content/pages-html/resources.html +177 -0
  319. package/tenants/tokenoftrust/content/pages-html/reviews.html +273 -0
  320. package/tenants/tokenoftrust/content/pages-html/solutions.html +292 -0
  321. package/tenants/tokenoftrust/content/pages-html/vlp-alcohol.html +289 -0
  322. package/tenants/tokenoftrust/content/pages-html/vlp-cigars-and-tobacco.html +286 -0
  323. package/tenants/tokenoftrust/content/pages-html/vlp-firearm-accessories.html +267 -0
  324. package/tenants/tokenoftrust/content/pages-html/vlp-peptides.html +273 -0
  325. package/tenants/tokenoftrust/content/themes/tot-navy.json +88 -0
  326. package/tenants/tokenoftrust/public/favicon.png +0 -0
  327. package/tenants/tokenoftrust/public/logo-icon.png +0 -0
  328. package/tenants/tokenoftrust/public/logo-wordmark.png +0 -0
  329. package/tenants/tokenoftrust/public/pages/company.css +108 -0
  330. package/tenants/tokenoftrust/public/pages/home.css +457 -0
  331. package/tenants/tokenoftrust/public/pages/mkt.css +482 -0
  332. package/tenants/tokenoftrust/public/pages/pricing.css +214 -0
  333. package/tenants/tokenoftrust/public/pages/solutions.css +66 -0
  334. package/tenants/tokenoftrust/public/themes/tot-navy-1.0.0.css +136 -0
  335. package/tenants/tokenoftrust/public/themes/tot-navy.css +358 -0
  336. package/tenants/tokenoftrust/theme.json +31 -0
  337. package/tsconfig.base.json +20 -0
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Tenant configuration + theme token contract.
3
+ *
4
+ * Phase 1 resolves tenants from a static config map/KV by hostname. The lookup
5
+ * interface (resolveTenant) is intentionally async + many-ready so the same seam
6
+ * scales to Cloudflare-for-SaaS custom hostnames later without a rewrite.
7
+ */
8
+ import type { FoxyCommerceConfig } from "./foxy.js";
9
+ import type { CapabilityConfig } from "./capabilities.js";
10
+
11
+ export interface ThemeColorTokens {
12
+ bg: string;
13
+ surface: string;
14
+ text: string;
15
+ muted: string;
16
+ primary: string;
17
+ "primary-contrast": string;
18
+ accent: string;
19
+ border: string;
20
+ success: string;
21
+ sale: string;
22
+ }
23
+
24
+ export interface ThemeFontFamily {
25
+ family: string;
26
+ weights: number[];
27
+ }
28
+
29
+ export interface ThemeTypeTokens {
30
+ display: ThemeFontFamily;
31
+ body: ThemeFontFamily;
32
+ mono?: ThemeFontFamily;
33
+ /** Type scale ratio, e.g. 1.25 (major third). */
34
+ scale: number;
35
+ tracking?: string;
36
+ }
37
+
38
+ export interface ThemeSpaceTokens {
39
+ /** Base spacing unit in px. */
40
+ base: number;
41
+ /** Multiplier scale, e.g. [0, 0.25, 0.5, 1, 1.5, 2, 3, 4, 6, 8]. */
42
+ scale: number[];
43
+ containerMaxWidth: string;
44
+ sectionRhythm: string;
45
+ }
46
+
47
+ export interface ThemeShapeTokens {
48
+ radius: { sm: string; md: string; lg: string; full: string };
49
+ borderWeights: { thin: string; medium: string; thick: string };
50
+ shadow: { sm: string; md: string; lg: string };
51
+ }
52
+
53
+ export interface ThemeBrandTokens {
54
+ logoLight: string;
55
+ logoDark: string;
56
+ favicon: string;
57
+ ogImage: string;
58
+ /** "full" | "reduced" — tenant-level default motion preference. */
59
+ motion: "full" | "reduced";
60
+ /**
61
+ * Header treatment. "dark" renders the bar in the primary color carrying the
62
+ * light logo (matches brands whose header is dark + white logo, e.g. vape
63
+ * stores); "light" (default) is a light bar with the dark logo/wordmark.
64
+ */
65
+ headerVariant?: "light" | "dark";
66
+ /**
67
+ * Hero treatment. "bold" (default) paints the hero full-bleed in the primary
68
+ * color (one signature moment). "light" renders the hero on the page
69
+ * background with the brand color used only as an accent on the headline/CTA —
70
+ * matches merchants whose own site is a light page with color accents. The
71
+ * brand adopter sets "light" when it captures a real hero image.
72
+ */
73
+ heroVariant?: "bold" | "light";
74
+ }
75
+
76
+ export interface ThemeTokens {
77
+ color: ThemeColorTokens;
78
+ type: ThemeTypeTokens;
79
+ space: ThemeSpaceTokens;
80
+ shape: ThemeShapeTokens;
81
+ brand: ThemeBrandTokens;
82
+ }
83
+
84
+ /**
85
+ * Regulated-commerce compliance (e.g. vape/nicotine). Browse-surface only —
86
+ * the actual identity/age VERIFICATION is Token of Trust's product and is wired
87
+ * in a later phase; this config drives storefront affordances (FDA warning, the
88
+ * soft 21+ affirmation gate, shipping-restriction notices). Omit/undefined for
89
+ * unregulated tenants and none of it renders.
90
+ */
91
+ export interface ComplianceConfig {
92
+ /** Minimum age to enter. Drives the soft affirmation gate (e.g. 21). */
93
+ minAge?: number;
94
+ /** Render the FDA nicotine warning sitewide + reinforced on PDP. */
95
+ nicotineWarning?: boolean;
96
+ /** Short PACT-Act / no-ship-states / adult-signature notice (plain text). */
97
+ shippingRestriction?: string;
98
+ }
99
+
100
+ /**
101
+ * What a tenant's site is FOR. "commerce" (default) is the browse/discover
102
+ * ecommerce storefront the platform was born as. "marketing" is a non-commerce
103
+ * B2B/SaaS site — chrome, rich page composition, and conversion CTAs, with the
104
+ * catalog/cart affordances switched off. The mode picks feature DEFAULTS
105
+ * (see resolveTenantFeatures); `features` overrides individual flags.
106
+ */
107
+ export type SiteType = "commerce" | "marketing";
108
+
109
+ /**
110
+ * Per-tenant capability switches. These gate whole surfaces so the same
111
+ * component library renders both a store and a marketing site without any
112
+ * tenant-specific `if` in shared code. Every flag has a sensible default keyed
113
+ * off `siteType`; a tenant only lists the ones it wants to flip.
114
+ */
115
+ export interface TenantFeatures {
116
+ /** Catalog surfaces: /collections, /products/*, listing grids, PDPs. */
117
+ catalog: boolean;
118
+ /** Header search typeahead island. */
119
+ productSearch: boolean;
120
+ /** Wishlist / "saved items" surface + header heart control. */
121
+ savedItems: boolean;
122
+ /** Product quick-view dialog island. */
123
+ quickView: boolean;
124
+ /** Newsletter capture forms (footer + homepage block). */
125
+ newsletter: boolean;
126
+ /** Product/collection URLs in the XML sitemap. */
127
+ commerceSitemap: boolean;
128
+ /** Product-offer JSON-LD on product/collection pages. */
129
+ productJsonLd: boolean;
130
+ /** Soft age-affirmation gate + regulated-commerce chrome (also needs `compliance`). */
131
+ ageGate: boolean;
132
+ }
133
+
134
+ const COMMERCE_FEATURES: TenantFeatures = {
135
+ catalog: true,
136
+ productSearch: true,
137
+ savedItems: true,
138
+ quickView: true,
139
+ newsletter: true,
140
+ commerceSitemap: true,
141
+ productJsonLd: true,
142
+ ageGate: true,
143
+ };
144
+
145
+ const MARKETING_FEATURES: TenantFeatures = {
146
+ catalog: false,
147
+ productSearch: false,
148
+ savedItems: false,
149
+ quickView: false,
150
+ newsletter: false,
151
+ commerceSitemap: false,
152
+ productJsonLd: false,
153
+ ageGate: false,
154
+ };
155
+
156
+ /** Feature defaults for a site type (returns a fresh copy — safe to mutate). */
157
+ export function siteTypeDefaults(siteType: SiteType): TenantFeatures {
158
+ return { ...(siteType === "marketing" ? MARKETING_FEATURES : COMMERCE_FEATURES) };
159
+ }
160
+
161
+ /**
162
+ * Resolve a tenant's effective features: siteType defaults, with any explicit
163
+ * `features` overrides layered on top (undefined entries ignored, so a tenant
164
+ * can flip one flag without restating the rest). Unset `siteType` == "commerce",
165
+ * preserving the platform's original behavior for existing tenants.
166
+ */
167
+ export function resolveTenantFeatures(
168
+ tenant: Pick<TenantConfig, "siteType" | "features">,
169
+ ): TenantFeatures {
170
+ const base = siteTypeDefaults(tenant.siteType ?? "commerce");
171
+ if (!tenant.features) return base;
172
+ for (const [k, v] of Object.entries(tenant.features)) {
173
+ if (v !== undefined) base[k as keyof TenantFeatures] = v;
174
+ }
175
+ return base;
176
+ }
177
+
178
+ export interface TenantConfig {
179
+ tenant_id: string;
180
+ /** ToT-side merchant identifier (appDomain), e.g. "pilot.tokenoftrust.com". */
181
+ appDomain: string;
182
+ /** The hostname(s) that resolve to this tenant. */
183
+ domains: string[];
184
+ /** Primary canonical domain for SEO/canonical URLs. */
185
+ canonicalDomain: string;
186
+ displayName: string;
187
+ /** Storyblok delivery token for this tenant's child space. */
188
+ storyblok_space_token: string;
189
+ /** Data scope passed to the ToT catalog API (usually == appDomain). */
190
+ tot_data_scope: string;
191
+ /** Per-tenant theme overrides; merged over the reference theme defaults. */
192
+ theme_tokens: DeepPartial<ThemeTokens>;
193
+ /** Currency for display formatting. */
194
+ currency: string;
195
+ locale: string;
196
+ /**
197
+ * What the site is for: "commerce" (default) or "marketing". Drives feature
198
+ * defaults (resolveTenantFeatures) and non-commerce chrome. Omitted == commerce.
199
+ */
200
+ siteType?: SiteType;
201
+ /** Explicit feature overrides layered atop the siteType defaults. */
202
+ features?: Partial<TenantFeatures>;
203
+ /** Regulated-commerce affordances; undefined for unregulated tenants. */
204
+ compliance?: ComplianceConfig;
205
+ /**
206
+ * Cart/checkout engine wiring (FoxyCart, Track A). Present on commerce tenants
207
+ * that have a FoxyCart store; drives the loader + signed add-to-cart. The
208
+ * `storeSubDomain` here is a default — middleware may override it from env
209
+ * (FOXY_STORE_SUBDOMAIN) so the demo store swaps with zero code change. The
210
+ * signing SECRET is never stored on the tenant; it's an env Worker binding.
211
+ */
212
+ commerce?: {
213
+ foxy?: FoxyCommerceConfig;
214
+ };
215
+ /**
216
+ * PR-gated capability switches (cart/checkout, age/identity verification,
217
+ * excise tax). Source of truth is the tenant repo's `.tot/config.json`; this
218
+ * build-time default is overridden per environment by the published
219
+ * capabilities artifact (localhost=working tree, preview=PR head, live=promoted).
220
+ * Undefined entries default from siteType/compliance — see resolveCapabilities.
221
+ */
222
+ capabilities?: Partial<CapabilityConfig>;
223
+ }
224
+
225
+ export type DeepPartial<T> = {
226
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
227
+ };
228
+
229
+ /** The interface the tenant-resolution middleware implements. */
230
+ export interface TenantResolver {
231
+ /**
232
+ * Resolve a tenant for a hostname, falling back to a default tenant for
233
+ * unknown hosts (Phase 1 convenience so preview/local hosts still render).
234
+ */
235
+ resolveByHost(host: string): Promise<TenantConfig | null>;
236
+ /**
237
+ * Strict match: return the tenant that explicitly claims `host` in its
238
+ * `domains`, or null. Unlike resolveByHost it never falls back to a default,
239
+ * so callers can detect "this host/segment owns no tenant" — used by the
240
+ * `/<domain>/*` path-prefix routing fallback.
241
+ */
242
+ resolveStrict(host: string): Promise<TenantConfig | null>;
243
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "src"
6
+ },
7
+ "include": ["src/**/*"]
8
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ include: ["tests/**/*.test.ts"],
6
+ environment: "node",
7
+ },
8
+ });
@@ -0,0 +1,7 @@
1
+ packages:
2
+ - "apps/*"
3
+ - "packages/*"
4
+ onlyBuiltDependencies:
5
+ - esbuild
6
+ - sharp
7
+ - workerd
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Prebuild step for the colocated tenant layout.
4
+ *
5
+ * A tenant IS the repo-root directory `tenants/<id>/` (holding content, public,
6
+ * theme.json). Astro serves static assets from `apps/storefront/public/`, so a
7
+ * tenant's public files must land at `apps/storefront/public/tenants/<id>/`
8
+ * for the `/tenants/<id>/...` URLs to resolve. This script mirrors every tenant's
9
+ * public directory into that generated location.
10
+ *
11
+ * The destination (`apps/storefront/public/tenants/`) is a BUILD ARTIFACT
12
+ * (gitignored) — the source of truth is `tenants/<id>/public/`. Wired into the
13
+ * storefront `prebuild`/`predev` lifecycle (package.json) and invoked directly by
14
+ * `scripts/tot-dev.mjs` before it boots `astro dev`.
15
+ *
16
+ * Idempotent: it wipes+rewrites the destination on every run. `TENANT_ASSETS_DEST`
17
+ * overrides the destination (used by tests / spikes).
18
+ *
19
+ * VERSIONED TENANTS (decision `assets-r2-versioned`): a tenant whose assets are
20
+ * served version-scoped from R2 (src/pages/tenants/[id]/[...path].ts) must NOT be
21
+ * baked here — otherwise the static file would shadow the R2 route. Opt a tenant
22
+ * out by adding a `tenants/<id>/.tot/assets-versioned` marker file, or by listing
23
+ * its id in the `TENANT_ASSETS_VERSIONED` env (comma-separated). Non-versioned
24
+ * tenants keep the baked path unchanged (back-compat).
25
+ */
26
+ import { cp, mkdir, readdir, rm } from "node:fs/promises";
27
+ import { existsSync } from "node:fs";
28
+ import { join, resolve, dirname } from "node:path";
29
+ import { fileURLToPath } from "node:url";
30
+
31
+ const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
32
+ const src = resolve(repoRoot, "tenants");
33
+ const dest = process.env.TENANT_ASSETS_DEST
34
+ ? resolve(process.env.TENANT_ASSETS_DEST)
35
+ : resolve(repoRoot, "apps/storefront/public/tenants");
36
+
37
+ if (!existsSync(src)) process.exit(0);
38
+
39
+ await rm(dest, { recursive: true, force: true });
40
+
41
+ const versionedEnv = new Set(
42
+ (process.env.TENANT_ASSETS_VERSIONED ?? "")
43
+ .split(",")
44
+ .map((s) => s.trim())
45
+ .filter(Boolean),
46
+ );
47
+ const isVersioned = (id) =>
48
+ versionedEnv.has(id) ||
49
+ existsSync(join(src, id, ".tot", "assets-versioned"));
50
+
51
+ let copied = 0;
52
+ let skipped = 0;
53
+ for (const id of await readdir(src)) {
54
+ const pub = join(src, id, "public");
55
+ if (!existsSync(pub)) continue;
56
+ // Versioned tenants are served from R2 — baking would shadow the R2 route.
57
+ if (isVersioned(id)) {
58
+ skipped++;
59
+ continue;
60
+ }
61
+ await mkdir(join(dest, id), { recursive: true });
62
+ await cp(pub, join(dest, id), { recursive: true });
63
+ copied++;
64
+ }
65
+
66
+ const skipNote = skipped ? ` (skipped ${skipped} versioned → R2)` : "";
67
+ console.log(
68
+ `copy-tenant-assets: mirrored ${copied} tenant public/ tree(s) → ${dest}${skipNote}`,
69
+ );