@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,97 @@
1
+ /**
2
+ * Map human color-option values to swatch fills for product cards.
3
+ *
4
+ * Merchants name colors in their own vernacular ("Oatmeal", "Spruce"), not hex.
5
+ * We resolve a known palette first, fall back to a CSS named color when the
6
+ * value happens to be one, and otherwise render an "unknown" swatch (neutral
7
+ * with a slash) rather than guessing wrong. Tenant-agnostic: this is product
8
+ * data, not theme.
9
+ */
10
+
11
+ /** Curated names common to apparel/home catalogs (lowercased keys). */
12
+ const PALETTE: Record<string, string> = {
13
+ black: "#1a1a1a",
14
+ charcoal: "#36393b",
15
+ graphite: "#3a3a3a",
16
+ slate: "#556770",
17
+ grey: "#8a8d91",
18
+ gray: "#8a8d91",
19
+ silver: "#c7c9cc",
20
+ white: "#f6f5f1",
21
+ ivory: "#f3efe4",
22
+ cream: "#efe9d8",
23
+ ecru: "#e8e1cd",
24
+ oatmeal: "#ddd3bf",
25
+ natural: "#e3d9c2",
26
+ sand: "#d8c6a3",
27
+ stone: "#cbbfa9",
28
+ tan: "#c5a980",
29
+ camel: "#b48a5e",
30
+ rust: "#a4512f",
31
+ terracotta: "#bf6a4a",
32
+ brick: "#8f4334",
33
+ olive: "#6f6f3a",
34
+ forest: "#2f4a36",
35
+ spruce: "#23413a",
36
+ sage: "#9aa583",
37
+ teal: "#2a6f72",
38
+ navy: "#1f2a44",
39
+ indigo: "#2c3a63",
40
+ denim: "#41597d",
41
+ blue: "#2f5e8f",
42
+ burgundy: "#5e2230",
43
+ wine: "#5e2230",
44
+ plum: "#5a3a55",
45
+ blush: "#e7c7c0",
46
+ pink: "#e3a6ad",
47
+ mustard: "#c79a3a",
48
+ amber: "#b5612f",
49
+ brown: "#5f4733",
50
+ chocolate: "#46342a",
51
+ khaki: "#9a8b66",
52
+ };
53
+
54
+ /** CSS named colors we accept as a fallback when not in PALETTE. */
55
+ const CSS_NAMED = new Set([
56
+ "red", "orange", "yellow", "green", "blue", "purple", "pink", "brown",
57
+ "black", "white", "gray", "grey", "beige", "ivory", "navy", "teal",
58
+ "maroon", "olive", "coral", "salmon", "khaki", "tan", "gold",
59
+ ]);
60
+
61
+ export interface Swatch {
62
+ /** Original option value, e.g. "Oatmeal". */
63
+ label: string;
64
+ /** CSS color for the dot, or null when unknown. */
65
+ fill: string | null;
66
+ }
67
+
68
+ export function resolveSwatch(value: string): Swatch {
69
+ const key = value.trim().toLowerCase();
70
+ if (key in PALETTE) return { label: value, fill: PALETTE[key]! };
71
+ // Two-word names: try the last token ("Heather Grey" -> "grey").
72
+ const last = key.split(/\s+/).pop()!;
73
+ if (last in PALETTE) return { label: value, fill: PALETTE[last]! };
74
+ if (CSS_NAMED.has(key)) return { label: value, fill: key };
75
+ if (CSS_NAMED.has(last)) return { label: value, fill: last };
76
+ return { label: value, fill: null };
77
+ }
78
+
79
+ /** The product option that holds colors, if any (Color / Colour / Shade). */
80
+ export function colorOptionValues(
81
+ options: { name: string; values: string[] }[],
82
+ ): string[] {
83
+ const opt = options.find((o) => /colou?r|shade|finish/i.test(o.name));
84
+ return opt ? opt.values : [];
85
+ }
86
+
87
+ /** True when a fill is light enough to need a ring so it reads on a light bg. */
88
+ export function isLightFill(fill: string): boolean {
89
+ const m = /^#([0-9a-f]{6})$/i.exec(fill);
90
+ if (!m) return false;
91
+ const n = parseInt(m[1]!, 16);
92
+ const r = (n >> 16) & 255,
93
+ g = (n >> 8) & 255,
94
+ b = n & 255;
95
+ // Perceived luminance.
96
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b > 200;
97
+ }
@@ -0,0 +1,230 @@
1
+ /**
2
+ * JsonRpcContentEditClient — the storefront's server-to-server caller for
3
+ * tot-mcp's `content_edit` tool (the inline-AI edit loop, WS5 G1). Mirrors
4
+ * {@link JsonRpcChangeClient} exactly (same transport, same session-validation,
5
+ * same tool-result unwrap, same typed errors) — reusing the forge seam's
6
+ * exported transport + error types so there is ONE wire contract, not two.
7
+ *
8
+ * AUTH SHAPE (G4 design note, `pending beta/WS2 confirmation`): the storefront
9
+ * backend calls `content_edit` as the TENANT OPERATOR (`credential_validate`
10
+ * with storefront's own TOT_API_KEY/TOT_SECRET_KEY — the SAME credential
11
+ * change/accept already uses), not as the individual signed-in developer.
12
+ * Developer-level authorization is the caller's job (`/dev`'s own
13
+ * `readViewerSession()` + capability check, BEFORE this client is ever
14
+ * constructed) — this client only proves "a legitimate storefront backend is
15
+ * asking", the same trust boundary `/api/changes/accept` already relies on.
16
+ */
17
+ import {
18
+ FetchTransport,
19
+ ForgeAuthError,
20
+ ForgeConfigError,
21
+ ForgeTransportError,
22
+ SESSION_HEADER,
23
+ type McpTransport,
24
+ type JsonRpcRequest,
25
+ type TotCredentials,
26
+ type TransportResponse,
27
+ } from "@/lib/forge";
28
+ import { mapForgeError } from "@/lib/forge/errors.js";
29
+ import { readEnv } from "@/lib/env";
30
+ import type { ContentEditFile, ContentEditResult } from "./types.js";
31
+
32
+ export const CONTENT_EDIT_TOOL = {
33
+ validate: "credential_validate",
34
+ edit: "content_edit",
35
+ } as const;
36
+
37
+ export { SESSION_HEADER } from "@/lib/forge";
38
+
39
+ // --- MCP tool-result envelope (mirrors the change client) -------------------
40
+
41
+ interface McpToolResult {
42
+ content?: Array<{ type?: string; text?: string }>;
43
+ structuredContent?: unknown;
44
+ isError?: boolean;
45
+ }
46
+
47
+ function parseTextContent(content: McpToolResult["content"]): unknown {
48
+ const text = content?.find((c) => c.type === "text" || c.text != null)?.text;
49
+ if (text == null) return undefined;
50
+ try {
51
+ return JSON.parse(text);
52
+ } catch {
53
+ return text;
54
+ }
55
+ }
56
+
57
+ function unwrapToolResult<T>(result: unknown): T {
58
+ const env = (result ?? {}) as McpToolResult;
59
+ const payload =
60
+ env.structuredContent !== undefined
61
+ ? env.structuredContent
62
+ : parseTextContent(env.content);
63
+
64
+ if (env.isError) {
65
+ const p = (payload ?? {}) as Record<string, unknown>;
66
+ throw mapForgeError({
67
+ code: typeof p.code === "number" ? p.code : undefined,
68
+ message: typeof p.message === "string" ? p.message : "content_edit tool error",
69
+ data: (p.data as Record<string, unknown>) ?? p,
70
+ });
71
+ }
72
+ return payload as T;
73
+ }
74
+
75
+ // --- Config -------------------------------------------------------------
76
+
77
+ export interface JsonRpcContentEditClientConfig {
78
+ /** MCP base URL (the `POST /mcp` endpoint). */
79
+ baseUrl: string;
80
+ /** Storefront's ToT operator credentials for `credential_validate`. */
81
+ credentials: TotCredentials;
82
+ /** Transport override (defaults to fetch). Injected by tests. */
83
+ transport?: McpTransport;
84
+ }
85
+
86
+ // --- The client -----------------------------------------------------------
87
+
88
+ export class JsonRpcContentEditClient {
89
+ private readonly baseUrl: string;
90
+ private readonly credentials: TotCredentials;
91
+ private readonly transport: McpTransport;
92
+ private nextId = 1;
93
+ /** Cached session validation — validate once, reuse (lazily). */
94
+ private sessionPromise?: Promise<string | undefined>;
95
+
96
+ constructor(config: JsonRpcContentEditClientConfig) {
97
+ if (!config.baseUrl) {
98
+ throw new ForgeConfigError("content-edit: MCP_BASE_URL is not configured");
99
+ }
100
+ if (!config.credentials?.apiKey) {
101
+ throw new ForgeConfigError(
102
+ "content-edit: storefront ToT credentials are not configured",
103
+ );
104
+ }
105
+ this.baseUrl = config.baseUrl;
106
+ this.credentials = config.credentials;
107
+ this.transport = config.transport ?? new FetchTransport(config.baseUrl);
108
+ }
109
+
110
+ async editContent(
111
+ prompt: string,
112
+ files: readonly ContentEditFile[],
113
+ ): Promise<ContentEditResult> {
114
+ const sessionId = await this.ensureSession();
115
+ const result = await this.rpc(
116
+ "tools/call",
117
+ { name: CONTENT_EDIT_TOOL.edit, arguments: { prompt, files } },
118
+ sessionId,
119
+ );
120
+ return unwrapToolResult<ContentEditResult>(result);
121
+ }
122
+
123
+ // --- internals (mirror JsonRpcChangeClient) --------------------------------
124
+
125
+ private ensureSession(): Promise<string | undefined> {
126
+ this.sessionPromise ??= this.validateSession();
127
+ return this.sessionPromise;
128
+ }
129
+
130
+ private async validateSession(): Promise<string | undefined> {
131
+ const args = this.credentialArgs();
132
+ let res: TransportResponse;
133
+ try {
134
+ res = await this.rpcRaw(
135
+ "tools/call",
136
+ { name: CONTENT_EDIT_TOOL.validate, arguments: args },
137
+ undefined,
138
+ );
139
+ } catch (err) {
140
+ this.sessionPromise = undefined; // let a later call retry
141
+ throw err;
142
+ }
143
+ if (res.body.error) {
144
+ this.sessionPromise = undefined;
145
+ throw new ForgeAuthError(
146
+ res.body.error.message ?? "content-edit: credential validation failed",
147
+ );
148
+ }
149
+ try {
150
+ const validated = unwrapToolResult<{ session?: string; sessionId?: string }>(
151
+ res.body.result,
152
+ );
153
+ return (
154
+ res.sessionId ?? validated?.session ?? validated?.sessionId ?? undefined
155
+ );
156
+ } catch (err) {
157
+ this.sessionPromise = undefined;
158
+ throw err instanceof ForgeAuthError
159
+ ? err
160
+ : new ForgeAuthError("content-edit: credential validation was rejected", {
161
+ cause: err,
162
+ });
163
+ }
164
+ }
165
+
166
+ /** Build the credential payload; omits absent secrets. Never logged. */
167
+ private credentialArgs(): Record<string, unknown> {
168
+ const c = this.credentials;
169
+ const out: Record<string, unknown> = { apiKey: c.apiKey };
170
+ if (c.secretKey) out.secretKey = c.secretKey;
171
+ if (c.accessToken) out.accessToken = c.accessToken;
172
+ return out;
173
+ }
174
+
175
+ private async rpc(
176
+ method: string,
177
+ params: unknown,
178
+ sessionId: string | undefined,
179
+ ): Promise<unknown> {
180
+ const res = await this.rpcRaw(method, params, sessionId);
181
+ if (res.body.error) throw mapForgeError(res.body.error);
182
+ return res.body.result;
183
+ }
184
+
185
+ private async rpcRaw(
186
+ method: string,
187
+ params: unknown,
188
+ sessionId: string | undefined,
189
+ ): Promise<TransportResponse> {
190
+ const headers: Record<string, string> = {};
191
+ if (sessionId) headers[SESSION_HEADER] = sessionId;
192
+ const body: JsonRpcRequest = {
193
+ jsonrpc: "2.0",
194
+ id: this.nextId++,
195
+ method,
196
+ params,
197
+ };
198
+ try {
199
+ return await this.transport.post({ body, headers });
200
+ } catch (err) {
201
+ if (err instanceof ForgeTransportError) throw err;
202
+ throw new ForgeTransportError(
203
+ `content-edit: transport failure calling ${method}`,
204
+ { cause: err },
205
+ );
206
+ }
207
+ }
208
+ }
209
+
210
+ // --- Factory ----------------------------------------------------------------
211
+
212
+ /**
213
+ * Build a {@link JsonRpcContentEditClient} from the runtime env — the SAME env
214
+ * the change client reads (`MCP_BASE_URL` + storefront's own ToT credentials).
215
+ * Throws {@link ForgeConfigError} when the base URL or api key is missing.
216
+ * Secrets are read via {@link readEnv} and never logged.
217
+ */
218
+ export async function createContentEditClient(
219
+ overrides: Partial<JsonRpcContentEditClientConfig> = {},
220
+ ): Promise<JsonRpcContentEditClient> {
221
+ const baseUrl = overrides.baseUrl ?? (await readEnv("MCP_BASE_URL")) ?? "";
222
+ const credentials =
223
+ overrides.credentials ??
224
+ ({
225
+ apiKey: (await readEnv("TOT_API_KEY")) ?? "",
226
+ secretKey: await readEnv("TOT_SECRET_KEY"),
227
+ accessToken: await readEnv("TOT_ACCESS_TOKEN"),
228
+ } satisfies TotCredentials);
229
+ return new JsonRpcContentEditClient({ ...overrides, baseUrl, credentials });
230
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * content_edit integration — public barrel. Import the typed client and its
3
+ * route helper from here (`@/lib/content-edit`) so call sites never reach into
4
+ * individual files.
5
+ */
6
+ export type { ContentEditFile, ContentEditFileDiff, ContentEditResult } from "./types.js";
7
+ export {
8
+ JsonRpcContentEditClient,
9
+ createContentEditClient,
10
+ CONTENT_EDIT_TOOL,
11
+ SESSION_HEADER,
12
+ } from "./client.js";
13
+ export type { JsonRpcContentEditClientConfig } from "./client.js";
14
+ export { getContentEditClient } from "./route.js";
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Route helper for `/api/content-edit/ai-edit` — mirrors `@/lib/change/route.ts`'s
3
+ * `getChangeClient`: build the env-configured client, or a 503 Response when
4
+ * the MCP integration isn't configured (missing `MCP_BASE_URL`/credentials).
5
+ */
6
+ import { ForgeError } from "@/lib/forge";
7
+ import { createContentEditClient } from "./client.js";
8
+ import { json } from "@/lib/grants/route.js";
9
+
10
+ /**
11
+ * Build a content-edit client over the real MCP from env, or return a 503
12
+ * Response when the integration is not configured. Never leaks secret values.
13
+ */
14
+ export async function getContentEditClient(): Promise<
15
+ Awaited<ReturnType<typeof createContentEditClient>> | Response
16
+ > {
17
+ try {
18
+ return await createContentEditClient();
19
+ } catch (err) {
20
+ if (err instanceof ForgeError && err.kind === "config") {
21
+ return json({ error: "content_edit integration not configured" }, 503);
22
+ }
23
+ throw err;
24
+ }
25
+ }
@@ -0,0 +1,19 @@
1
+ /** Wire shape for tot-mcp's `content_edit` tool — mirrors tot-mcp's own
2
+ * ContentFile/ContentFileDiff/ContentEditResult (src/services/content-editor.ts). */
3
+
4
+ export interface ContentEditFile {
5
+ /** e.g. "content/home.html" or "theme.json" — content_edit's own allowlist. */
6
+ path: string;
7
+ content: string;
8
+ }
9
+
10
+ export interface ContentEditFileDiff {
11
+ path: string;
12
+ /** Unified diff (`--- a/<path>` / `+++ b/<path>`) against the given content. */
13
+ diff: string;
14
+ }
15
+
16
+ export interface ContentEditResult {
17
+ diffs: ContentEditFileDiff[];
18
+ summary: string;
19
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * CSP hashes for the **static** inline `<script>`/`<style>` that Astro emits in
3
+ * the production build — the `client:load|idle|only` hydration directive
4
+ * loaders, the `<astro-island>` definition, the `astro-island{display:contents}`
5
+ * style, and bundled Layout scripts. These are identical across tenants and
6
+ * requests (no dynamic data), so hashes (not nonces) are the correct, strict
7
+ * tool for them.
8
+ *
9
+ * They change only when Astro or our bundled scripts change (e.g. an Astro
10
+ * upgrade). A drift check re-extracts them from a fresh build and fails if this
11
+ * list is stale — see `scripts/check-csp-hashes.mjs`. Regenerate with:
12
+ * node scripts/check-csp-hashes.mjs --print
13
+ */
14
+ export const STATIC_SCRIPT_HASHES: readonly string[] = [
15
+ "'sha256-BF0290pkb3jxQsE7z00xR8Imp8X34FLC88L0lkMnrGw='",
16
+ "'sha256-SaCkFfPruIdTXT8/97JArQmGxiJAL2o4bBDvSgJ5y3Q='",
17
+ "'sha256-QzWFZi+FLIx23tnm9SBU4aEgx4x8DsuASP07mfqol/c='",
18
+ "'sha256-YicfxUFBkKrQapZ/tzZKlaKTdNHgwVfv7y2Wa0NC6/k='",
19
+ "'sha256-eIXWvAmxkr251LJZkjniEK5LcPF3NkapbJepohwYRIc='",
20
+ ];
21
+
22
+ export const STATIC_STYLE_HASHES: readonly string[] = [
23
+ "'sha256-vv9IoKo7BSLbWcUHr3tNmfNVmm5L/9Cfn2H6LMk7/ow='",
24
+ ];