@tokenoftrust/storefront-runner 1.4.2-rc.0 → 2.0.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.
- package/apps/storefront/astro.config.mjs +3 -3
- package/apps/storefront/env.d.ts +54 -5
- package/apps/storefront/integrations/materialize-guard.mjs +12 -14
- package/apps/storefront/migrations-apps/0004_deep_morph.sql +36 -0
- package/apps/storefront/migrations-apps/0005_common_mystique.sql +23 -0
- package/apps/storefront/migrations-apps/0006_broad_microchip.sql +16 -0
- package/apps/storefront/migrations-apps/0007_brave_outlaw_kid.sql +15 -0
- package/apps/storefront/migrations-apps/0008_blue_dazzler.sql +11 -0
- package/apps/storefront/migrations-apps/0009_bored_shinobi_shaw.sql +15 -0
- package/apps/storefront/migrations-apps/0010_ws4_verified_provider_measurement.sql +35 -0
- package/apps/storefront/migrations-apps/meta/0004_snapshot.json +1474 -0
- package/apps/storefront/migrations-apps/meta/0005_snapshot.json +1617 -0
- package/apps/storefront/migrations-apps/meta/0006_snapshot.json +1716 -0
- package/apps/storefront/migrations-apps/meta/0007_snapshot.json +1812 -0
- package/apps/storefront/migrations-apps/meta/0008_snapshot.json +1881 -0
- package/apps/storefront/migrations-apps/meta/0009_snapshot.json +1979 -0
- package/apps/storefront/migrations-apps/meta/_journal.json +42 -0
- package/apps/storefront/public/apps/tot.demo.analytics/0.1.0/entry.js +42 -0
- package/apps/storefront/public/platform/amplitude-http/v1/entry.mjs +19 -0
- package/apps/storefront/public/platform/google-measurement/v1/entry.mjs +19 -0
- package/apps/storefront/public/shared/commerce-chrome.css +20 -2
- package/apps/storefront/scripts/build-v84-clean-clone-standalone.mjs +68 -0
- package/apps/storefront/scripts/deny-v84-clean-clone-standalone-capabilities.mjs +111 -0
- package/apps/storefront/scripts/deny-v84-dogfood-capabilities.mjs +2 -0
- package/apps/storefront/scripts/deny-v84-lifecycle-capabilities.mjs +247 -0
- package/apps/storefront/scripts/dogfood-v84-nonportable-routes.ts +73 -0
- package/apps/storefront/scripts/fixed-v84-native-install-producer.ts +79 -0
- package/apps/storefront/scripts/generated/v84-clean-clone-replay.bundle.mjs +10982 -0
- package/apps/storefront/scripts/import-v84-through-ws2.ts +38 -0
- package/apps/storefront/scripts/initialize-v84-lifecycle-tooling-dependency.ts +2 -0
- package/apps/storefront/scripts/initialize-v84-lifecycle-tooling.ts +4 -0
- package/apps/storefront/scripts/install-v84-native-through-ws1.ts +185 -0
- package/apps/storefront/scripts/prove-clone-isolation.ts +506 -0
- package/apps/storefront/scripts/replay-v84-clean-clone-pass.ts +148 -0
- package/apps/storefront/scripts/replay-v84-clean-clone-standalone.ts +35 -0
- package/apps/storefront/scripts/replay-v84-clean-clone.ts +214 -0
- package/apps/storefront/scripts/run-fixed-v84-native-install-producer.mjs +18 -0
- package/apps/storefront/scripts/run-v84-clone-isolation-proof.mjs +18 -0
- package/apps/storefront/scripts/run-v84-clone-lifecycle-proof.mjs +18 -0
- package/apps/storefront/scripts/run-v84-import-through-ws2-proof.mjs +17 -0
- package/apps/storefront/scripts/run-v84-nonportable-route-dogfood.mjs +15 -0
- package/apps/storefront/scripts/sanitize-v84-proof-environment.mjs +21 -0
- package/apps/storefront/scripts/v84CleanCloneGraphPin.ts +42 -0
- package/apps/storefront/scripts/v84CleanCloneSourceGraph.ts +145 -0
- package/apps/storefront/scripts/validate-v84-clone-lifecycle.ts +18 -0
- package/apps/storefront/src/components/Img.astro +1 -1
- package/apps/storefront/src/components/admin/AdminBlogTab.astro +19 -16
- package/apps/storefront/src/components/admin/AdminIntegrationsTab.astro +105 -0
- package/apps/storefront/src/components/admin/AdminPublishTab.astro +1057 -412
- package/apps/storefront/src/components/admin/AdminSettingsTab.astro +2 -2
- package/apps/storefront/src/components/admin/orders/OrdersWorkspace.astro +5 -5
- package/apps/storefront/src/components/chrome/NavDropdown.astro +12 -0
- package/apps/storefront/src/components/chrome/SiteFooter.astro +7 -2
- package/apps/storefront/src/components/chrome/SiteHeader.astro +46 -10
- package/apps/storefront/src/components/compliance/AdultSignatureNotice.astro +1 -1
- package/apps/storefront/src/components/compliance/ComplianceNotice.astro +1 -2
- package/apps/storefront/src/components/compliance/ExciseTaxNotice.astro +1 -2
- package/apps/storefront/src/components/compliance/PactActNotice.astro +1 -1
- package/apps/storefront/src/components/compliance/Prop65Warning.astro +1 -2
- package/apps/storefront/src/components/compliance/PurchaseLimitNotice.astro +2 -3
- package/apps/storefront/src/components/compliance/ShippingRestrictionNotice.astro +2 -2
- package/apps/storefront/src/components/compliance/StateEligibilityNotice.astro +2 -3
- package/apps/storefront/src/components/content/TrustStrip.astro +4 -4
- package/apps/storefront/src/components/islands/MobileNav.tsx +26 -1
- package/apps/storefront/src/components/islands/VariantSelector.tsx +27 -2
- package/apps/storefront/src/components/islands/useCheckoutHandoffCorrelation.ts +75 -0
- package/apps/storefront/src/components/membership/IllustrativeLabel.astro +1 -2
- package/apps/storefront/src/components/membership/TierCards.astro +2 -2
- package/apps/storefront/src/components/membership/TierComparisonTable.astro +2 -2
- package/apps/storefront/src/components/subscription/SavingsExplainer.astro +2 -2
- package/apps/storefront/src/config/adminTenantLookup.ts +35 -0
- package/apps/storefront/src/config/devTenantSeed.ts +9 -9
- package/apps/storefront/src/config/resolver.ts +4 -4
- package/apps/storefront/src/layouts/Layout.astro +100 -20
- package/apps/storefront/src/lib/activity/candidateSubmitLease.ts +87 -0
- package/apps/storefront/src/lib/activity/changeActorAttribution.ts +86 -6
- package/apps/storefront/src/lib/activity/deployVersion.ts +1 -1
- package/apps/storefront/src/lib/admin/adminShell.ts +2 -0
- package/apps/storefront/src/lib/admin/envelope.ts +1 -2
- package/apps/storefront/src/lib/apps/adminService.ts +10 -0
- package/apps/storefront/src/lib/apps/adminSession.ts +1 -1
- package/apps/storefront/src/lib/apps/appVersionStore.ts +281 -0
- package/apps/storefront/src/lib/apps/consentConfigStore.ts +228 -0
- package/apps/storefront/src/lib/apps/gtmMigrationInstall.ts +447 -0
- package/apps/storefront/src/lib/apps/gtmMigrationReport.ts +367 -0
- package/apps/storefront/src/lib/apps/gtmMigrationTab.ts +315 -0
- package/apps/storefront/src/lib/apps/integrationLifecycle.ts +614 -0
- package/apps/storefront/src/lib/apps/integrationLifecycleController.ts +125 -0
- package/apps/storefront/src/lib/apps/integrationReadModel.ts +563 -0
- package/apps/storefront/src/lib/apps/integrationsTab.ts +547 -0
- package/apps/storefront/src/lib/apps/integrationsView.ts +106 -0
- package/apps/storefront/src/lib/apps/managedAnalyticsService.ts +599 -0
- package/apps/storefront/src/lib/apps/orders/orderConversionD1.ts +150 -0
- package/apps/storefront/src/lib/apps/orders/orderForwardReceiver.ts +8 -0
- package/apps/storefront/src/lib/apps/orders/ordersStore.ts +1 -1
- package/apps/storefront/src/lib/apps/orders/verifiedProviderMeasurement.ts +117 -0
- package/apps/storefront/src/lib/apps/registryService.ts +264 -10
- package/apps/storefront/src/lib/apps/tenantIntegrationMaterialization.ts +170 -0
- package/apps/storefront/src/lib/apps/v84CleanCloneReplayContext.ts +16 -0
- package/apps/storefront/src/lib/apps/v84CloneLifecycleCacheEvidence.ts +105 -0
- package/apps/storefront/src/lib/apps/v84CloneLifecycleEvidence.ts +177 -0
- package/apps/storefront/src/lib/apps/v84CloneLifecycleMaterialization.ts +251 -0
- package/apps/storefront/src/lib/apps/v84CloneLifecycleSemantics.ts +241 -0
- package/apps/storefront/src/lib/apps/v84CloneMigrationEvidence.ts +211 -0
- package/apps/storefront/src/lib/apps/v84CloneNativeInstallEvidence.ts +409 -0
- package/apps/storefront/src/lib/apps/v84NonportableCodeCoaching.ts +368 -0
- package/apps/storefront/src/lib/apps/v84NonportableRouteContract.ts +188 -0
- package/apps/storefront/src/lib/apps/v84NonportableRouteDogfood.ts +291 -0
- package/apps/storefront/src/lib/apps/ws1ManagedAnalyticsClient.ts +95 -0
- package/apps/storefront/src/lib/auth/adminApiGuard.ts +66 -0
- package/apps/storefront/src/lib/auth/adminEntry.ts +2 -2
- package/apps/storefront/src/lib/auth/adminLanding.ts +88 -0
- package/apps/storefront/src/lib/blog/collection.ts +97 -10
- package/apps/storefront/src/lib/blog/markdown.ts +1 -1
- package/apps/storefront/src/lib/blog/provider.ts +57 -3
- package/apps/storefront/src/lib/blog/types.ts +9 -9
- package/apps/storefront/src/lib/chrome/examples/tokenoftrust.chrome-assignments.example.json +6 -0
- package/apps/storefront/src/lib/chrome/examples/tokenoftrust.chrome.example.json +79 -0
- package/apps/storefront/src/lib/chrome/model.ts +48 -253
- package/apps/storefront/src/lib/chrome/navCurrent.ts +29 -0
- package/apps/storefront/src/lib/chrome/parseConfig.ts +18 -32
- package/apps/storefront/src/lib/chrome/variant.ts +39 -0
- package/apps/storefront/src/lib/commerce/checkoutHandoffCorrelation.ts +105 -0
- package/apps/storefront/src/lib/compliance/tamper-sentinel-boot.ts +152 -0
- package/apps/storefront/src/lib/compliance/tamper-sentinel.ts +327 -0
- package/apps/storefront/src/lib/content/index.ts +5 -5
- package/apps/storefront/src/lib/content-edit/applyDiff.ts +1 -1
- package/apps/storefront/src/lib/content-edit/route.ts +1 -1
- package/apps/storefront/src/lib/d1/catalog.ts +12 -0
- package/apps/storefront/src/lib/d1/schema-apps.ts +276 -0
- package/apps/storefront/src/lib/dev/cockpit/ask.ts +49 -0
- package/apps/storefront/src/lib/dev/cockpit/clickToSource.ts +71 -0
- package/apps/storefront/src/lib/dev/cockpit/copyCommand.ts +227 -0
- package/apps/storefront/src/lib/dev/cockpit/files.ts +249 -0
- package/apps/storefront/src/lib/dev/cockpit/hostedActivity.ts +500 -0
- package/apps/storefront/src/lib/dev/cockpit/infoPopover.ts +12 -0
- package/apps/storefront/src/lib/dev/cockpit/mcpCopy.ts +34 -0
- package/apps/storefront/src/lib/dev/cockpit/monitor.ts +107 -0
- package/apps/storefront/src/lib/dev/cockpit/stepper.ts +116 -0
- package/apps/storefront/src/lib/dev/cockpit/themeToggle.ts +23 -0
- package/apps/storefront/src/lib/dev/runtimeStore.ts +1 -1
- package/apps/storefront/src/lib/edgeCache.ts +18 -6
- package/apps/storefront/src/lib/email/candidateConflictEmail.ts +80 -0
- package/apps/storefront/src/lib/integration/browserEnvironment.ts +137 -0
- package/apps/storefront/src/lib/integration/managedInstallDeclarations.ts +72 -0
- package/apps/storefront/src/lib/integration/nonceStamp.ts +49 -0
- package/apps/storefront/src/lib/integration/tenantDeclarations.ts +116 -0
- package/apps/storefront/src/lib/membership/eligibility.ts +1 -1
- package/apps/storefront/src/lib/membership/model.ts +1 -2
- package/apps/storefront/src/lib/newsletter/confirmationEmail.ts +2 -2
- package/apps/storefront/src/lib/newsletter/consent.ts +2 -2
- package/apps/storefront/src/lib/newsletter/send.ts +3 -3
- package/apps/storefront/src/lib/previewReload.ts +57 -1
- package/apps/storefront/src/lib/publish/adminPublishTab.ts +1775 -669
- package/apps/storefront/src/lib/publish/buildStream.ts +269 -0
- package/apps/storefront/src/lib/publish/collapsePersistence.ts +72 -0
- package/apps/storefront/src/lib/publish/lifecycleState.ts +369 -0
- package/apps/storefront/src/lib/publish/liveReleaseSummary.ts +29 -0
- package/apps/storefront/src/lib/publish/mergeDoctorOnFailure.ts +78 -0
- package/apps/storefront/src/lib/publish/mergeHealthBanner.ts +62 -0
- package/apps/storefront/src/lib/publish/mergeRowFindings.ts +124 -0
- package/apps/storefront/src/lib/publish/mergeSupportEscalation.ts +75 -0
- package/apps/storefront/src/lib/publish/publish-guard.ts +88 -0
- package/apps/storefront/src/lib/publish/publishFormat.ts +165 -0
- package/apps/storefront/src/lib/publish/publishHero.ts +177 -0
- package/apps/storefront/src/lib/publish/reviewRelease/changeState.ts +66 -0
- package/apps/storefront/src/lib/publish/reviewRelease/copy.ts +141 -0
- package/apps/storefront/src/lib/publish/reviewRelease/index.ts +41 -0
- package/apps/storefront/src/lib/publish/reviewRelease/permissions.ts +47 -0
- package/apps/storefront/src/lib/publish/reviewRelease/releaseState.ts +42 -0
- package/apps/storefront/src/lib/publish/reviewRelease/types.ts +59 -0
- package/apps/storefront/src/lib/publish/reviewRelease/viewModel.ts +440 -0
- package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/actions.ts +161 -0
- package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/controller.ts +325 -0
- package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/render.ts +241 -0
- package/apps/storefront/src/lib/publish/shipWorkspace.ts +22 -3
- package/apps/storefront/src/lib/publish/sseRoute.ts +119 -0
- package/apps/storefront/src/lib/publish/streamLogConsole.ts +142 -0
- package/apps/storefront/src/lib/publish/versionNumber.ts +52 -0
- package/apps/storefront/src/lib/rawChrome.ts +125 -47
- package/apps/storefront/src/lib/rawMarketingHtml.ts +74 -3
- package/apps/storefront/src/lib/seo/alternates.ts +1 -1
- package/apps/storefront/src/lib/social/notify.ts +4 -4
- package/apps/storefront/src/lib/storyblok/content-model.ts +7 -33
- package/apps/storefront/src/lib/storyblok/provider.ts +168 -60
- package/apps/storefront/src/lib/subscription/model.ts +4 -4
- package/apps/storefront/src/lib/the-build/provider.ts +9 -4
- package/apps/storefront/src/middleware/index.ts +273 -51
- package/apps/storefront/src/pages/[...slug].astro +9 -4
- package/apps/storefront/src/pages/admin/review-release.astro +265 -0
- package/apps/storefront/src/pages/admin/select.astro +96 -0
- package/apps/storefront/src/pages/admin.astro +16 -2
- package/apps/storefront/src/pages/api/activity.ts +8 -8
- package/apps/storefront/src/pages/api/admin/activity-alerts.ts +5 -20
- package/apps/storefront/src/pages/api/admin/orders/[id].ts +7 -2
- package/apps/storefront/src/pages/api/admin/orders.ts +8 -2
- package/apps/storefront/src/pages/api/apps/admin/gtm-migration-install.ts +174 -0
- package/apps/storefront/src/pages/api/apps/admin/gtm-migration.ts +96 -0
- package/apps/storefront/src/pages/api/apps/admin/integration-lifecycle.ts +118 -0
- package/apps/storefront/src/pages/api/apps/admin/integrations.ts +89 -0
- package/apps/storefront/src/pages/api/apps/admin/platform-adapters.ts +85 -0
- package/apps/storefront/src/pages/api/apps/internal/order-forward.ts +74 -2
- package/apps/storefront/src/pages/api/commerce/checkout-handoff.ts +77 -0
- package/apps/storefront/src/pages/api/compliance/tamper.ts +88 -0
- package/apps/storefront/src/pages/api/integrations/v1/[operation].ts +108 -0
- package/apps/storefront/src/pages/api/rum/vitals.ts +1 -2
- package/apps/storefront/src/pages/blog/[slug].astro +5 -5
- package/apps/storefront/src/pages/blog/author/[author].astro +3 -3
- package/apps/storefront/src/pages/blog/category/[category].astro +2 -2
- package/apps/storefront/src/pages/blog/index.astro +2 -2
- package/apps/storefront/src/pages/blog/tag/[tag].astro +2 -2
- package/apps/storefront/src/pages/cockpit.astro +61 -1362
- package/apps/storefront/src/pages/index.astro +10 -5
- package/apps/storefront/src/pages/llms.txt.ts +1 -1
- package/apps/storefront/src/pages/products/[handle].astro +7 -6
- package/apps/storefront/src/pages/sitemap.xml.ts +2 -2
- package/apps/storefront/src/pages/style-guide/[tenant]/[theme].astro +31 -27
- package/apps/storefront/src/pages/style-guide/[tenant]/chrome/[theme].astro +1 -1
- package/apps/storefront/src/pages/tenants/[id]/[...path].ts +38 -2
- package/apps/storefront/src/pages/the-build/[slug].astro +4 -4
- package/apps/storefront/src/pages/the-build/index.astro +2 -2
- package/apps/storefront/src/pages/the-build/rss.xml.ts +2 -2
- package/apps/storefront/src/styles/admin.css +27 -1
- package/apps/storefront/tsconfig.json +1 -1
- package/package.json +1 -1
- package/packages/public-runtime/package.json +2 -1
- package/packages/public-runtime/schemas/managed-analytics/v1/adapter-definition.schema.json +427 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/create-integration-install-request.schema.json +161 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/create-migration-draft-request.schema.json +157 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/delete-integration-install-request.schema.json +84 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/delete-migration-draft-request.schema.json +84 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/error-envelope.schema.json +180 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/get-adapter-definition-request.schema.json +52 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/get-integration-install-request.schema.json +52 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/get-integration-revision-request.schema.json +79 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/get-migration-draft-request.schema.json +52 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/integration-install.schema.json +167 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/integration-revision.schema.json +208 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/list-adapter-definitions-request.schema.json +53 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/list-integration-installs-request.schema.json +53 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/list-integration-revisions-request.schema.json +82 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/migration-draft.schema.json +218 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/mutation-request.schema.json +52 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/mutation-success-envelope.schema.json +49 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/read-request.schema.json +20 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/read-success-envelope.schema.json +45 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/revise-integration-install-request.schema.json +156 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/set-integration-install-status-request.schema.json +92 -0
- package/packages/public-runtime/schemas/managed-analytics/v1/update-migration-draft-request.schema.json +184 -0
- package/packages/public-runtime/scripts/generate-managed-analytics-api-v1-schemas.mjs +13 -0
- package/packages/public-runtime/src/activity/catalog.ts +41 -37
- package/packages/public-runtime/src/activity/event.ts +6 -6
- package/packages/public-runtime/src/activity/index.ts +2 -2
- package/packages/public-runtime/src/activity/redaction.ts +4 -4
- package/packages/public-runtime/src/candidate-index.ts +42 -8
- package/packages/public-runtime/src/checkout-orders.ts +2 -2
- package/packages/public-runtime/src/checkout-style-publish.ts +2 -2
- package/packages/public-runtime/src/checkout-style.ts +7 -7
- package/packages/public-runtime/src/checkout.ts +3 -3
- package/packages/public-runtime/src/chrome.ts +777 -0
- package/packages/public-runtime/src/compliance-obligations.ts +310 -0
- package/packages/public-runtime/src/csp.ts +99 -0
- package/packages/public-runtime/src/customization-runtime.ts +32 -1
- package/packages/public-runtime/src/destination-webhook/contract.ts +353 -0
- package/packages/public-runtime/src/embed-catalog.d.mts +9 -0
- package/packages/public-runtime/src/embed-catalog.mjs +40 -0
- package/packages/public-runtime/src/evidence.ts +288 -0
- package/packages/public-runtime/src/gtm-migration/bounds.ts +138 -0
- package/packages/public-runtime/src/gtm-migration/disposition-rules.ts +361 -0
- package/packages/public-runtime/src/gtm-migration/dispositions.ts +181 -0
- package/packages/public-runtime/src/gtm-migration/draft-generator.ts +400 -0
- package/packages/public-runtime/src/gtm-migration/graph.ts +468 -0
- package/packages/public-runtime/src/gtm-migration/index.ts +95 -0
- package/packages/public-runtime/src/gtm-migration/parse.ts +410 -0
- package/packages/public-runtime/src/gtm-migration/references.ts +266 -0
- package/packages/public-runtime/src/gtm-migration/types.ts +86 -0
- package/packages/public-runtime/src/index.ts +16 -1
- package/packages/public-runtime/src/integration/assurance-decision.ts +259 -0
- package/packages/public-runtime/src/integration/assurance.ts +228 -0
- package/packages/public-runtime/src/integration/candidate-evidence.ts +377 -0
- package/packages/public-runtime/src/integration/commerce-broker.ts +497 -0
- package/packages/public-runtime/src/integration/consent-broker.ts +337 -0
- package/packages/public-runtime/src/integration/consent-cmp-demand.ts +115 -0
- package/packages/public-runtime/src/integration/consent-config.ts +260 -0
- package/packages/public-runtime/src/integration/consent-preview.ts +125 -0
- package/packages/public-runtime/src/integration/correlation-token.ts +444 -0
- package/packages/public-runtime/src/integration/csp-compiler.ts +267 -0
- package/packages/public-runtime/src/integration/csp.ts +105 -0
- package/packages/public-runtime/src/integration/digest.ts +43 -0
- package/packages/public-runtime/src/integration/environment.ts +228 -0
- package/packages/public-runtime/src/integration/events-catalog.ts +186 -0
- package/packages/public-runtime/src/integration/events.ts +701 -0
- package/packages/public-runtime/src/integration/g2-action-boundary.ts +106 -0
- package/packages/public-runtime/src/integration/index.ts +90 -0
- package/packages/public-runtime/src/integration/interim-bridge.ts +138 -0
- package/packages/public-runtime/src/integration/lifecycle-boot.ts +317 -0
- package/packages/public-runtime/src/integration/lifecycle-runtime.ts +393 -0
- package/packages/public-runtime/src/integration/lifecycle.ts +94 -0
- package/packages/public-runtime/src/integration/managed-analytics-api-v1-safety.d.mts +2 -0
- package/packages/public-runtime/src/integration/managed-analytics-api-v1-safety.mjs +10 -0
- package/packages/public-runtime/src/integration/managed-analytics-api-v1.schemas.ts +382 -0
- package/packages/public-runtime/src/integration/managed-analytics-api-v1.ts +684 -0
- package/packages/public-runtime/src/integration/managed-analytics-bridge.ts +383 -0
- package/packages/public-runtime/src/integration/managed-analytics-value-safety.ts +14 -0
- package/packages/public-runtime/src/integration/managed-analytics.ts +277 -0
- package/packages/public-runtime/src/integration/manifest.ts +470 -0
- package/packages/public-runtime/src/integration/native-amplitude.ts +362 -0
- package/packages/public-runtime/src/integration/native-ga4.ts +352 -0
- package/packages/public-runtime/src/integration/observability.ts +451 -0
- package/packages/public-runtime/src/integration/order-conversion.ts +0 -0
- package/packages/public-runtime/src/integration/phases.ts +182 -0
- package/packages/public-runtime/src/integration/plan.ts +112 -0
- package/packages/public-runtime/src/integration/platform-adapter-runtime.ts +146 -0
- package/packages/public-runtime/src/integration/platform-adapters.ts +671 -0
- package/packages/public-runtime/src/integration/promotion-gate.ts +451 -0
- package/packages/public-runtime/src/integration/provider-checkout-extension.ts +425 -0
- package/packages/public-runtime/src/integration/receipt-measurement.ts +370 -0
- package/packages/public-runtime/src/integration/regulated-parent-cert.ts +311 -0
- package/packages/public-runtime/src/integration/render-phases.ts +267 -0
- package/packages/public-runtime/src/integration/resolve.ts +465 -0
- package/packages/public-runtime/src/integration/result.ts +239 -0
- package/packages/public-runtime/src/integration/secrets.ts +92 -0
- package/packages/public-runtime/src/integration/tamper-evidence.ts +205 -0
- package/packages/public-runtime/src/integration/tamper-recovery.ts +127 -0
- package/packages/public-runtime/src/integration/version.ts +92 -0
- package/packages/public-runtime/src/integration-capabilities.ts +520 -0
- package/packages/public-runtime/src/membership.ts +2 -2
- package/packages/public-runtime/src/raw-html-policy.ts +2 -4
- package/packages/public-runtime/src/regulated-commerce/broker/consent-dedupe.ts +144 -0
- package/packages/public-runtime/src/regulated-commerce/correlation/contract.ts +177 -0
- package/packages/public-runtime/src/regulated-commerce/diagnostics/local-dispatch.ts +24 -0
- package/packages/public-runtime/src/regulated-commerce/diagnostics/read-model.ts +69 -0
- package/packages/public-runtime/src/regulated-commerce/dispatch/core.ts +134 -0
- package/packages/public-runtime/src/regulated-commerce/events/contract.ts +113 -0
- package/packages/public-runtime/src/regulated-commerce/ledger/core.ts +81 -0
- package/packages/public-runtime/src/regulated-commerce/mappings/ga4-ads.ts +87 -0
- package/packages/public-runtime/src/regulated-commerce/provider-order/bridge.ts +52 -0
- package/packages/public-runtime/src/regulated-commerce/purchase-truth/contract.ts +252 -0
- package/packages/public-runtime/src/regulated-commerce/sources/accepted-browser-operation.ts +67 -0
- package/packages/public-runtime/src/regulated-commerce/testing/fake-destination.ts +93 -0
- package/packages/public-runtime/src/static-bundle.ts +5 -5
- package/packages/public-runtime/src/tenant-assets.ts +143 -4
- package/packages/public-runtime/src/tenant.ts +45 -9
- package/packages/public-runtime/tests/fixtures/integration/browser-environment.example.json +8 -0
- package/packages/public-runtime/tests/fixtures/integration/commerce-event.example.json +44 -0
- package/packages/public-runtime/tests/fixtures/integration/commerce-order-event.example.json +44 -0
- package/packages/public-runtime/tests/fixtures/integration/compliance-assurance-record.example.json +50 -0
- package/packages/public-runtime/tests/fixtures/integration/integration-manifest-v2.example.json +120 -0
- package/packages/public-runtime/tests/fixtures/integration/managed-analytics-v1/fake-adapter-catalog.json +35 -0
- package/packages/public-runtime/tests/fixtures/integration/tenant-action-registry.example.json +11 -0
- package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/README.md +22 -0
- package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/entry.js +30 -0
- package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/manifest.json +75 -0
- package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/public-config.json +3 -0
- package/packages/public-runtime/tests/fixtures/regulated-commerce/fake-destinations.ts +38 -0
- package/packages/public-runtime/tests/gtm-migration/fixtures/gtm-sample-container-v84.provenance.json +29 -0
- package/packages/public-runtime/tests/gtm-migration/fixtures/gtm-sample-container-v84.redacted.json +3397 -0
- package/scripts/dev/file-browser.mjs +2 -2
- package/scripts/dev/file-writer.mjs +2 -2
- package/scripts/dev/integration-guardrails.mjs +498 -0
- package/scripts/dev/safe-path.mjs +2 -2
- package/scripts/dev/tenant-source-root.mjs +1 -1
- package/scripts/tot-dev.mjs +2 -2
|
@@ -57,8 +57,13 @@ if (rawHtml && rawHtmlPolicy(tenant).allowed) {
|
|
|
57
57
|
// Shared chrome: if the tenant ships a chrome.html wrapper AND this home is a
|
|
58
58
|
// body-only fragment, rawHtmlResponse splices it in; a full document serves
|
|
59
59
|
// verbatim (backward-compatible).
|
|
60
|
-
const chromeWrapper = await content.getChromeHtml();
|
|
61
|
-
return rawHtmlResponse(rawHtml, {
|
|
60
|
+
const chromeWrapper = await content.getChromeHtml("/");
|
|
61
|
+
return rawHtmlResponse(rawHtml, {
|
|
62
|
+
nonce: Astro.locals.cspNonce,
|
|
63
|
+
basePath,
|
|
64
|
+
chromeWrapper,
|
|
65
|
+
plan: Astro.locals.integrationPlan,
|
|
66
|
+
});
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
const home = await content.getHome();
|
|
@@ -143,9 +148,9 @@ for (const block of marketing ? [] : home.blocks) {
|
|
|
143
148
|
}
|
|
144
149
|
}
|
|
145
150
|
|
|
146
|
-
// Private-app widgets
|
|
151
|
+
// Private-app widgets — home.section slot. Commerce-home only; marketing-
|
|
147
152
|
// tenant homes (raw HTML, above, and the marketing-block home) are out of
|
|
148
|
-
// scope
|
|
153
|
+
// scope (deferred). No dark-mode preference infra exists yet — "light"
|
|
149
154
|
// is the only theme hint until that lands.
|
|
150
155
|
const homeSectionWidgets = marketing
|
|
151
156
|
? []
|
|
@@ -326,7 +331,7 @@ const homeSectionWidgets = marketing
|
|
|
326
331
|
return null;
|
|
327
332
|
})
|
|
328
333
|
}
|
|
329
|
-
{/* Private-app widgets (
|
|
334
|
+
{/* Private-app widgets (home.section) — sandboxed per install. */}
|
|
330
335
|
{homeSectionWidgets.map((w) => (
|
|
331
336
|
<Section>
|
|
332
337
|
<AppWidgetFrame
|
|
@@ -34,7 +34,7 @@ export async function GET(context: APIContext): Promise<Response> {
|
|
|
34
34
|
content.listPages(),
|
|
35
35
|
tot.getFeatured(12),
|
|
36
36
|
content.getHome().catch(() => null),
|
|
37
|
-
listBlogPosts(tenant.tenant_id),
|
|
37
|
+
listBlogPosts(tenant.tenant_id, content),
|
|
38
38
|
]);
|
|
39
39
|
// Empty synthesized collections (no active members) never make the guide —
|
|
40
40
|
// an LLM shouldn't be pointed at a URL that resolves to zero products.
|
|
@@ -60,7 +60,7 @@ if (!product || product.status === "archived") {
|
|
|
60
60
|
}
|
|
61
61
|
const isDraft = product.status !== "active";
|
|
62
62
|
|
|
63
|
-
// Private-app widgets
|
|
63
|
+
// Private-app widgets — product.aside slot, one iframe per live install.
|
|
64
64
|
// No dark-mode preference is resolved anywhere in the storefront yet; "light"
|
|
65
65
|
// is the only theme hint until that infra exists.
|
|
66
66
|
const productAsideWidgets = await renderWidgetSlot(
|
|
@@ -111,7 +111,7 @@ const mf = (ns: string, key: string) =>
|
|
|
111
111
|
product.metafields.find((m) => m.namespace === ns && m.key === key)?.value;
|
|
112
112
|
|
|
113
113
|
// Reviews — REAL aggregate from the store's reviews app, mirrored to metafields.
|
|
114
|
-
// readReviewAggregate is the single, real-or-absent reader
|
|
114
|
+
// readReviewAggregate is the single, real-or-absent reader: it parses both
|
|
115
115
|
// the bare and JSON-blob rating forms and the real count key, and returns {0,0}
|
|
116
116
|
// unless BOTH numbers are real positives — so no fabricated rating can render.
|
|
117
117
|
const { average: reviewAvg, count: reviewCount } = readReviewAggregate(product);
|
|
@@ -181,7 +181,7 @@ const available = isAvailable(product);
|
|
|
181
181
|
// side so the island can render a signed, tamper-proof form. In `signed` mode a
|
|
182
182
|
// missing secret means we render NO cart (never a tamperable form); the
|
|
183
183
|
// `unsigned-demo` mode needs no secret. Drafts still get a cart (preview links).
|
|
184
|
-
// Membership + Autopilot mechanics
|
|
184
|
+
// Membership + Autopilot mechanics. Member pricing renders only once a
|
|
185
185
|
// real eligibility signal flows through resolveMemberContext (Phase 2); Phase 1
|
|
186
186
|
// is anonymous. Autopilot (subscription options) is hidden when the tenant has
|
|
187
187
|
// set commerce.autopilot.enabled = false (hide-at-launch).
|
|
@@ -198,7 +198,7 @@ const pricing: {
|
|
|
198
198
|
? { membershipRule, stacking: membershipProgram?.stacking ?? DEFAULT_STACKING_POLICY }
|
|
199
199
|
: undefined;
|
|
200
200
|
const autopilotEnabled = isAutopilotEnabled(tenant.commerce?.autopilot);
|
|
201
|
-
// Server-side pricing context
|
|
201
|
+
// Server-side pricing context. The SIGNED price is the member-adjusted
|
|
202
202
|
// effective price for THIS request's resolved eligibility — never the list price,
|
|
203
203
|
// and never re-derived client-side. Phase 1 resolves anonymous, so this yields the
|
|
204
204
|
// list/subscription price; a Phase-2 member request signs their member price.
|
|
@@ -366,8 +366,9 @@ const jsonLd = [productJsonLd, breadcrumbLd(crumbs, canonicalBase)];
|
|
|
366
366
|
productTitle={product.title}
|
|
367
367
|
checkoutCart={checkoutCart}
|
|
368
368
|
pricing={pricing}
|
|
369
|
+
handoffUrl={withBase(basePath, "/api/commerce/checkout-handoff")}
|
|
369
370
|
/>
|
|
370
|
-
{/* Regulated-tenant checkout ENFORCEMENT gate
|
|
371
|
+
{/* Regulated-tenant checkout ENFORCEMENT gate. Intercepts the
|
|
371
372
|
managed-cart handoff to clear age + ship-to compliance server-side
|
|
372
373
|
before the external checkout. Only mounts when a store is wired AND
|
|
373
374
|
the tenant is regulated. */}
|
|
@@ -392,7 +393,7 @@ const jsonLd = [productJsonLd, breadcrumbLd(crumbs, canonicalBase)];
|
|
|
392
393
|
</button>
|
|
393
394
|
</div>
|
|
394
395
|
|
|
395
|
-
{/* Private-app widgets (
|
|
396
|
+
{/* Private-app widgets (product.aside) — sandboxed per install. */}
|
|
396
397
|
{productAsideWidgets.map((w) => (
|
|
397
398
|
<div class="mt-7">
|
|
398
399
|
<AppWidgetFrame
|
|
@@ -67,7 +67,7 @@ export async function GET(context: APIContext): Promise<Response> {
|
|
|
67
67
|
urls.push({ loc: `${base}/${page.slug}` });
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const blogPosts = await listBlogPosts(tenant.tenant_id);
|
|
70
|
+
const blogPosts = await listBlogPosts(tenant.tenant_id, content);
|
|
71
71
|
if (blogPosts.length > 0) {
|
|
72
72
|
urls.push({ loc: `${base}/blog/` });
|
|
73
73
|
for (const post of blogPosts) {
|
|
@@ -85,7 +85,7 @@ export async function GET(context: APIContext): Promise<Response> {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const buildPosts = await listBuildPosts(tenant.tenant_id);
|
|
88
|
+
const buildPosts = await listBuildPosts(tenant.tenant_id, { content });
|
|
89
89
|
if (buildPosts.length > 0) {
|
|
90
90
|
urls.push({ loc: `${base}/the-build/` });
|
|
91
91
|
for (const post of buildPosts) {
|
|
@@ -88,26 +88,27 @@ const cspNonce = Astro.locals.cspNonce;
|
|
|
88
88
|
|
|
89
89
|
// --- Sample chrome data (preview-only; no live tenant content) ----------------
|
|
90
90
|
const sampleNav: ChromeNavItem[] = [
|
|
91
|
-
{ label: "New", href: "#", flag: true, badge: "NEW" },
|
|
91
|
+
{ id: "nav-new", label: "New", href: "#", flag: true, badge: "NEW" },
|
|
92
92
|
{
|
|
93
|
+
id: "nav-shop",
|
|
93
94
|
label: "Shop",
|
|
94
95
|
href: "#",
|
|
95
96
|
columns: [
|
|
96
|
-
{ title: "Category", links: [{ label: "Disposables", href: "#" }, { label: "E-Liquid", href: "#" }, { label: "Devices", href: "#" }] },
|
|
97
|
-
{ title: "Featured", links: [{ label: "Best Sellers", href: "#" }, { label: "On Sale", href: "#", badge: "%" }] },
|
|
98
|
-
{ title: "Brands", links: [{ label: "Northwind", href: "#" }, { label: "Summit Co.", href: "#" }] },
|
|
97
|
+
{ title: "Category", links: [{ id: "nav-shop-disposables", label: "Disposables", href: "#" }, { id: "nav-shop-eliquid", label: "E-Liquid", href: "#" }, { id: "nav-shop-devices", label: "Devices", href: "#" }] },
|
|
98
|
+
{ title: "Featured", links: [{ id: "nav-shop-bestsellers", label: "Best Sellers", href: "#" }, { id: "nav-shop-onsale", label: "On Sale", href: "#", badge: "%" }] },
|
|
99
|
+
{ title: "Brands", links: [{ id: "nav-shop-northwind", label: "Northwind", href: "#" }, { id: "nav-shop-summit", label: "Summit Co.", href: "#" }] },
|
|
99
100
|
],
|
|
100
101
|
},
|
|
101
|
-
{ label: "Coils & Parts", href: "#", children: [{ label: "Coils", href: "#" }, { label: "Pods", href: "#" }, { label: "Batteries", href: "#" }] },
|
|
102
|
-
{ label: "On Sale", href: "#" },
|
|
102
|
+
{ id: "nav-coils", label: "Coils & Parts", href: "#", children: [{ id: "nav-coils-coils", label: "Coils", href: "#" }, { id: "nav-coils-pods", label: "Pods", href: "#" }, { id: "nav-coils-batteries", label: "Batteries", href: "#" }] },
|
|
103
|
+
{ id: "nav-sale", label: "On Sale", href: "#" },
|
|
103
104
|
];
|
|
104
105
|
const sampleSocial = [
|
|
105
106
|
{ label: "X", href: "#", iconPath: "M18.9 2H22l-7.1 8.1L23 22h-6.6l-5-6.6L5.7 22H2.6l7.6-8.7L1.5 2h6.8l4.5 6 5.1-6z" },
|
|
106
107
|
];
|
|
107
108
|
const sampleFooterCols = [
|
|
108
|
-
{ title: "Shop", links: [{ label: "Disposables", href: "#" }, { label: "E-Liquid", href: "#" }, { label: "Devices", href: "#" }] },
|
|
109
|
-
{ title: "Support", links: [{ label: "Contact", href: "#" }, { label: "Shipping", href: "#" }, { label: "Returns", href: "#" }] },
|
|
110
|
-
{ title: "Company", links: [{ label: "About", href: "#" }, { label: "Blog", href: "#" }] },
|
|
109
|
+
{ title: "Shop", links: [{ id: "ftr-shop-disposables", label: "Disposables", href: "#" }, { id: "ftr-shop-eliquid", label: "E-Liquid", href: "#" }, { id: "ftr-shop-devices", label: "Devices", href: "#" }] },
|
|
110
|
+
{ title: "Support", links: [{ id: "ftr-support-contact", label: "Contact", href: "#" }, { id: "ftr-support-shipping", label: "Shipping", href: "#" }, { id: "ftr-support-returns", label: "Returns", href: "#" }] },
|
|
111
|
+
{ title: "Company", links: [{ id: "ftr-company-about", label: "About", href: "#" }, { id: "ftr-company-blog", label: "Blog", href: "#" }] },
|
|
111
112
|
];
|
|
112
113
|
// BrandGrid samples: text-wordmark tiles and logo-image tiles (Img renders
|
|
113
114
|
// deterministic placeholders offline so the image code path is exercised
|
|
@@ -125,7 +126,7 @@ const sampleBrandsLogo: Brand[] = [
|
|
|
125
126
|
{ label: "Pod King", href: "#", logoSrc: "#", logoWidth: 200, logoHeight: 100 },
|
|
126
127
|
{ label: "Flavor Beast", href: "#", logoSrc: "#", logoWidth: 200, logoHeight: 100 },
|
|
127
128
|
];
|
|
128
|
-
// Review/UGC samples
|
|
129
|
+
// Review/UGC samples: illustrative fixture reviews
|
|
129
130
|
// ONLY, for previewing ReviewSummary/ReviewList token styling in isolation —
|
|
130
131
|
// never sourced from or rendered on a live product page (see
|
|
131
132
|
// docs/architecture/review-markup-policy.md; real callers pass tot.getReviews()
|
|
@@ -135,7 +136,7 @@ const sampleReviews: Review[] = [
|
|
|
135
136
|
{ author: "Priya K.", rating: 4, body: "Good overall, battery life could be a bit longer.", date: "2026-05-18", verifiedBuyer: true },
|
|
136
137
|
{ author: "T. Nguyen", rating: 3, title: "Decent, not amazing", body: "Does the job but nothing stands out versus similar devices.", date: "2026-04-30" },
|
|
137
138
|
];
|
|
138
|
-
// Blog/article samples
|
|
139
|
+
// Blog/article samples: featured-image cards (Img renders deterministic
|
|
139
140
|
// placeholders offline so the image path is exercised) + one image-less card
|
|
140
141
|
// (token-tinted placeholder band). Meta is illustrative example copy only.
|
|
141
142
|
const sampleArticles: Article[] = [
|
|
@@ -236,7 +237,7 @@ const sampleComparisonRows: ComparisonRow[] = [
|
|
|
236
237
|
{ label: "Cancel anytime", cells: [null, true, true] },
|
|
237
238
|
];
|
|
238
239
|
|
|
239
|
-
// --- Sample structured content
|
|
240
|
+
// --- Sample structured content — the DATA a policy page is driven by,
|
|
240
241
|
// replacing a hand-authored HTML/CSS fragment. Exercises headings (TOC),
|
|
241
242
|
// rich-text links, lists, a definition glossary, tone callouts, a contact
|
|
242
243
|
// block, and a needs-review flag (reviewer-only). ---------------------------
|
|
@@ -293,13 +294,13 @@ const sampleProseSections: ProseSection[] = [
|
|
|
293
294
|
},
|
|
294
295
|
];
|
|
295
296
|
|
|
296
|
-
// Trust strip
|
|
297
|
+
// Trust strip: mixes real claims + a real rating with
|
|
297
298
|
// fabrication vectors that MUST be dropped — the guide proves real-or-absent.
|
|
298
299
|
const sampleTrustStrip: TrustStripItem[] = [
|
|
299
300
|
{ kind: "claim", label: "Ships from USA" },
|
|
300
301
|
{ kind: "claim", label: "Lab-tested" },
|
|
301
302
|
{ kind: "rating", average: 4.9, count: 369, label: "avg rating" },
|
|
302
|
-
{ kind: "claim", label: "Based on 369 reviews" }, // fabricated → dropped
|
|
303
|
+
{ kind: "claim", label: "Based on 369 reviews" }, // fabricated → dropped
|
|
303
304
|
{ kind: "rating", average: 5, count: 0 }, // half-populated → dropped
|
|
304
305
|
];
|
|
305
306
|
|
|
@@ -469,8 +470,8 @@ const t = Object.entries(themeModules)
|
|
|
469
470
|
|
|
470
471
|
if (!t) return new Response(null, { status: 404 });
|
|
471
472
|
|
|
472
|
-
// Has this tenant adopted the canonical shared chrome
|
|
473
|
-
// longer ships its own mkt.css (retired at integration
|
|
473
|
+
// Has this tenant adopted the canonical shared chrome? If so it no
|
|
474
|
+
// longer ships its own mkt.css (retired at integration) — link the
|
|
474
475
|
// platform /shared/commerce-chrome.css instead so the marketing-component
|
|
475
476
|
// samples below still render in-brand.
|
|
476
477
|
const chromeModules = import.meta.glob<Record<string, any>>(
|
|
@@ -479,7 +480,10 @@ const chromeModules = import.meta.glob<Record<string, any>>(
|
|
|
479
480
|
);
|
|
480
481
|
const chromeSeg = `/tenants/${tenant}/content/chrome.json`;
|
|
481
482
|
const chromeConfig = Object.entries(chromeModules).find(([path]) => path.includes(chromeSeg))?.[1];
|
|
482
|
-
|
|
483
|
+
// Adoption is now "does chrome.json carry the consolidated header/footer
|
|
484
|
+
// shape" (lib/chrome/model.ts ChromeConfig) — the old `sharedChrome: true`
|
|
485
|
+
// opt-in flag is retired; a successfully-shaped config IS the adopted signal.
|
|
486
|
+
const usesSharedChrome = !!chromeConfig?.header && !!chromeConfig?.footer;
|
|
483
487
|
|
|
484
488
|
const tk = t.tokens ?? {};
|
|
485
489
|
const storyboard = t.storyboard ?? null;
|
|
@@ -492,7 +496,7 @@ const REFERENCE_COMPONENT_VARS: Record<string, string> = {
|
|
|
492
496
|
"--color-muted": "#5c6663", "--color-primary": "#1f3a34", "--color-primary-contrast": "#f4f1ea",
|
|
493
497
|
"--color-accent": "#b5612f", "--color-border": "#dcd6c9", "--color-success": "#3f6b4f",
|
|
494
498
|
"--color-sale": "#9e3b2e",
|
|
495
|
-
//
|
|
499
|
+
// Semantic + quality-bar interaction tokens — reference (Northwind)
|
|
496
500
|
// values so the text/icon-token samples render concretely and re-skin when a
|
|
497
501
|
// descriptor overrides them via preview.componentVars.
|
|
498
502
|
"--color-warning": "#8a5717", "--color-error": "#a22014", "--color-info": "#2c5b73",
|
|
@@ -610,7 +614,7 @@ const componentVarsInline = Object.entries(componentVars)
|
|
|
610
614
|
.sg-commerce .sg-h { color: var(--color-primary); }
|
|
611
615
|
.sg-commerce .sg-block { border-top-color: var(--color-border); }
|
|
612
616
|
|
|
613
|
-
/* Semantic text & icon token samples (v1.1
|
|
617
|
+
/* Semantic text & icon token samples (v1.1). Each swatch reads
|
|
614
618
|
ONE contract token so the guide proves text/icon roles resolve + re-skin
|
|
615
619
|
from tokens alone — never a hard-coded color. */
|
|
616
620
|
.sg-tok-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
|
|
@@ -952,7 +956,7 @@ const componentVarsInline = Object.entries(componentVars)
|
|
|
952
956
|
</div>
|
|
953
957
|
</section>
|
|
954
958
|
|
|
955
|
-
{/* ── Semantic text & icon tokens (v1.1
|
|
959
|
+
{/* ── Semantic text & icon tokens (v1.1) ──────────────────────────────
|
|
956
960
|
The quality-bar coverage sample: every text role, icon tint, and
|
|
957
961
|
interaction state renders from a NAMED contract token — nothing here
|
|
958
962
|
hard-codes a color or borrows `accent`. Swap the theme (or a
|
|
@@ -1138,7 +1142,7 @@ const componentVarsInline = Object.entries(componentVars)
|
|
|
1138
1142
|
<section class="sg-block">
|
|
1139
1143
|
<p class="sg-h">Chrome — UtilityNav</p>
|
|
1140
1144
|
<UtilityNav
|
|
1141
|
-
links={[{ label: "News", href: "#" }, { label: "About", href: "#" }, { label: "Contact", href: "#" }]}
|
|
1145
|
+
links={[{ id: "util-news", label: "News", href: "#" }, { id: "util-about", label: "About", href: "#" }, { id: "util-contact", label: "Contact", href: "#" }]}
|
|
1142
1146
|
locale="English"
|
|
1143
1147
|
currency="United States (USD $)"
|
|
1144
1148
|
social={sampleSocial}
|
|
@@ -1283,8 +1287,8 @@ const componentVarsInline = Object.entries(componentVars)
|
|
|
1283
1287
|
— no pricing/checkout/subscription mechanics. Figures are ILLUSTRATIVE
|
|
1284
1288
|
by default: unless a tier asserts real:true the widget renders a
|
|
1285
1289
|
first-class "Illustrative figures" affordance (badge + "e.g." + note)
|
|
1286
|
-
so an example number is never shown as a live offer
|
|
1287
|
-
|
|
1290
|
+
so an example number is never shown as a live offer. Fed sample
|
|
1291
|
+
tiers here; a tenant
|
|
1288
1292
|
supplies its own on a membership page. */}
|
|
1289
1293
|
<section class="sg-block">
|
|
1290
1294
|
<p class="sg-h">Membership tiers — <code>components/membership/</code></p>
|
|
@@ -1307,13 +1311,13 @@ const componentVarsInline = Object.entries(componentVars)
|
|
|
1307
1311
|
/>
|
|
1308
1312
|
</section>
|
|
1309
1313
|
|
|
1310
|
-
{/* ── Structured content widgets (components/content
|
|
1314
|
+
{/* ── Structured content widgets (components/content/) ───────
|
|
1311
1315
|
The DATA-driven promotion of repeated raw-page patterns. A tenant
|
|
1312
1316
|
authors a policy/about/compliance page as structured `sections`
|
|
1313
1317
|
(JSON) instead of copying an HTML/CSS fragment; these components
|
|
1314
1318
|
render it with the a11y (headings, <dl>, <address>, roles, tap
|
|
1315
|
-
targets) baked in and every color from
|
|
1316
|
-
|
|
1319
|
+
targets) baked in and every color from tokens. The trust strip is
|
|
1320
|
+
guarded — real-or-absent, fabricated proof dropped. */}
|
|
1317
1321
|
<section class="sg-block">
|
|
1318
1322
|
<p class="sg-h">Structured content — <code>components/content/</code></p>
|
|
1319
1323
|
<p class="lede" style="font-size:.95rem;color:var(--color-muted)">Data-driven framework widgets (F4): a policy page rendered from structured <code>sections</code> with no HTML/CSS to copy. Accessibility lives in the components; tenant content is pure data.</p>
|
|
@@ -1374,7 +1378,7 @@ const componentVarsInline = Object.entries(componentVars)
|
|
|
1374
1378
|
{/* ── Interactive islands (components/islands/) ─────────────────────
|
|
1375
1379
|
Client-hydrated Preact islands. Each is tenant-agnostic and reads
|
|
1376
1380
|
only fixture/localStorage data here — no live catalog, cart, or ToT
|
|
1377
|
-
calls
|
|
1381
|
+
calls. */}
|
|
1378
1382
|
<section class="sg-block">
|
|
1379
1383
|
<p class="sg-h">Islands — <code>components/islands/</code></p>
|
|
1380
1384
|
<p class="lede" style="font-size:.95rem;color:var(--color-muted)">Client-hydrated Preact islands exercised with fixture data — no live catalog, cart, or ToT calls.</p>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
/**
|
|
3
3
|
* Preview/dev-only SHARED RAW-CHROME STYLE GUIDE —
|
|
4
|
-
* `/_style-guide/<tenant>/chrome/<theme-id
|
|
4
|
+
* `/_style-guide/<tenant>/chrome/<theme-id>/`.
|
|
5
5
|
*
|
|
6
6
|
* Renders the platform-shipped raw chrome set — the `/shared/commerce-chrome.css`
|
|
7
7
|
* class vocabulary (announcement + utility bar, header + search + actions, primary
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* GET /tenants/<id>/<path> — serve a tenant's versioned static asset from R2.
|
|
3
3
|
*
|
|
4
4
|
* The version-scoped replacement for the build-time `copy-tenant-assets.mjs`
|
|
5
|
-
* baking
|
|
5
|
+
* baking. Resolves the tenant's active
|
|
6
6
|
* channel→snapshot versionId from the `cust:assets-pointer:<id>` KV record and
|
|
7
7
|
* streams `tenants/<id>/<versionId>/<rel>` from the TENANT_ASSETS R2 bucket with
|
|
8
8
|
* the right content-type + a revalidating cache header + a versionId ETag.
|
|
@@ -17,12 +17,36 @@
|
|
|
17
17
|
import type { APIContext } from "astro";
|
|
18
18
|
import {
|
|
19
19
|
serveTenantAsset,
|
|
20
|
+
verifyPreviewToken,
|
|
20
21
|
type R2BucketLike,
|
|
21
22
|
} from "@tot/public-runtime";
|
|
22
|
-
import { readR2, readKv } from "@/lib/env";
|
|
23
|
+
import { readR2, readKv, readEnv } from "@/lib/env";
|
|
23
24
|
|
|
24
25
|
export const prerender = false;
|
|
25
26
|
|
|
27
|
+
/** A versionId is a content sha — restrict to a safe R2 key segment (no traversal). */
|
|
28
|
+
const SAFE_VERSION_ID = /^[A-Za-z0-9._-]{1,128}$/;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a CANDIDATE-preview version override for this asset request, or null.
|
|
32
|
+
* A candidate/revision page sets `tot_preview_version` (its versionId) + the
|
|
33
|
+
* `tot_preview` capability token; when the token verifies for THIS tenant, we serve
|
|
34
|
+
* that exact snapshot (`tenants/<id>/<versionId>/…`) instead of the channel pointer,
|
|
35
|
+
* so a candidate's NEW assets — unreachable via the never-flipped channel — resolve.
|
|
36
|
+
* Token-gated + tenant-matched so it can never serve another tenant's snapshot.
|
|
37
|
+
*/
|
|
38
|
+
async function resolvePreviewVersion(context: APIContext, urlTenant: string): Promise<string | null> {
|
|
39
|
+
const versionId = context.cookies.get("tot_preview_version")?.value ?? null;
|
|
40
|
+
const token = context.cookies.get("tot_preview")?.value ?? null;
|
|
41
|
+
if (!versionId || !token || !urlTenant) return null;
|
|
42
|
+
if (!SAFE_VERSION_ID.test(versionId) || versionId.includes("..")) return null;
|
|
43
|
+
const secret = (await readEnv("CUSTOMIZATION_PREVIEW_SECRET")) ?? null;
|
|
44
|
+
if (!secret) return null;
|
|
45
|
+
const verified = await verifyPreviewToken(secret, token, Math.floor(Date.now() / 1000));
|
|
46
|
+
if (!verified.ok || verified.claims.tenantId !== urlTenant) return null;
|
|
47
|
+
return versionId;
|
|
48
|
+
}
|
|
49
|
+
|
|
26
50
|
export async function GET(context: APIContext): Promise<Response> {
|
|
27
51
|
const [bucket, kv] = await Promise.all([
|
|
28
52
|
readR2("TENANT_ASSETS"),
|
|
@@ -36,17 +60,29 @@ export async function GET(context: APIContext): Promise<Response> {
|
|
|
36
60
|
});
|
|
37
61
|
}
|
|
38
62
|
|
|
63
|
+
const previewVersionId = await resolvePreviewVersion(context, context.params.id ?? "");
|
|
64
|
+
|
|
39
65
|
const res = await serveTenantAsset(
|
|
40
66
|
{
|
|
41
67
|
// Runtime binding structurally satisfies the shared-runtime R2 seam.
|
|
42
68
|
bucket: bucket as unknown as R2BucketLike,
|
|
43
69
|
kvGet: (key) => kv.get(key),
|
|
44
70
|
channel: context.locals.customizationEnv ?? "live",
|
|
71
|
+
...(previewVersionId ? { versionId: previewVersionId } : {}),
|
|
45
72
|
ifNoneMatch: context.request.headers.get("if-none-match"),
|
|
46
73
|
},
|
|
47
74
|
new URL(context.request.url).pathname,
|
|
48
75
|
);
|
|
49
76
|
|
|
77
|
+
// A candidate-preview asset must NEVER be edge/CDN-cached under its tokenless URL
|
|
78
|
+
// (that would poison the public asset with candidate bytes, and Vary doesn't cover
|
|
79
|
+
// the auth cookie). Force no-store for the preview-version path; the normal
|
|
80
|
+
// channel-served asset keeps its revalidating cache header.
|
|
81
|
+
if (res && previewVersionId) {
|
|
82
|
+
res.headers.set("cache-control", "no-store");
|
|
83
|
+
res.headers.set("x-robots-tag", "noindex, nofollow");
|
|
84
|
+
}
|
|
85
|
+
|
|
50
86
|
return (
|
|
51
87
|
res ??
|
|
52
88
|
new Response("Not found", {
|
|
@@ -11,11 +11,11 @@ import { getTranslations } from "@/lib/blog/collection.js";
|
|
|
11
11
|
import { buildAlternates } from "@/lib/seo/alternates.js";
|
|
12
12
|
import { breadcrumbLd } from "@/lib/jsonld.js";
|
|
13
13
|
|
|
14
|
-
const { tenant, canonicalBase, basePath } = Astro.locals;
|
|
14
|
+
const { tenant, canonicalBase, basePath, content } = Astro.locals;
|
|
15
15
|
const slug = Astro.params.slug ?? "";
|
|
16
|
-
const post = await getBuildPost(tenant.tenant_id, slug);
|
|
16
|
+
const post = await getBuildPost(tenant.tenant_id, slug, { content });
|
|
17
17
|
if (!post) {
|
|
18
|
-
const redirect = await resolveBuildRedirect(tenant.tenant_id, slug);
|
|
18
|
+
const redirect = await resolveBuildRedirect(tenant.tenant_id, slug, content);
|
|
19
19
|
if (redirect) return Astro.redirect(`${basePath}/the-build/${redirect}/`, 301);
|
|
20
20
|
return new Response(null, { status: 404 });
|
|
21
21
|
}
|
|
@@ -45,7 +45,7 @@ const buildHref = `${basePath}/the-build/`;
|
|
|
45
45
|
// the live-visible variant set (self + siblings); `buildAlternates` yields [] for
|
|
46
46
|
// a singleton, so a non-translated post gets no alternates and no `lang` override
|
|
47
47
|
// (byte-identical to today).
|
|
48
|
-
const translations = await getTranslations(tenant.tenant_id, THE_BUILD.id, post.slug);
|
|
48
|
+
const translations = await getTranslations(tenant.tenant_id, THE_BUILD.id, post.slug, { content });
|
|
49
49
|
const alternates = buildAlternates(translations, (s) =>
|
|
50
50
|
new URL(`/the-build/${s}/`, canonicalBase + "/").toString(),
|
|
51
51
|
);
|
|
@@ -8,8 +8,8 @@ import Layout from "@/layouts/Layout.astro";
|
|
|
8
8
|
import PostAccessBadge from "@/components/blog/PostAccessBadge.astro";
|
|
9
9
|
import { listBuildPosts } from "@/lib/the-build/provider.js";
|
|
10
10
|
|
|
11
|
-
const { tenant, basePath, canonicalBase } = Astro.locals;
|
|
12
|
-
const posts = await listBuildPosts(tenant.tenant_id);
|
|
11
|
+
const { tenant, basePath, canonicalBase, content } = Astro.locals;
|
|
12
|
+
const posts = await listBuildPosts(tenant.tenant_id, { content });
|
|
13
13
|
if (posts.length === 0) return new Response(null, { status: 404 });
|
|
14
14
|
|
|
15
15
|
const href = (path: string) => `${basePath}${path}` || "/";
|
|
@@ -11,8 +11,8 @@ import { listBuildPosts, THE_BUILD } from "@/lib/the-build/provider.js";
|
|
|
11
11
|
import { renderRssFeed } from "@/lib/blog/rss.js";
|
|
12
12
|
|
|
13
13
|
export async function GET(context: APIContext): Promise<Response> {
|
|
14
|
-
const { tenant, canonicalBase } = context.locals;
|
|
15
|
-
const posts = await listBuildPosts(tenant.tenant_id);
|
|
14
|
+
const { tenant, canonicalBase, content } = context.locals;
|
|
15
|
+
const posts = await listBuildPosts(tenant.tenant_id, { content });
|
|
16
16
|
if (posts.length === 0) return new Response(null, { status: 404 });
|
|
17
17
|
|
|
18
18
|
const body = renderRssFeed({
|
|
@@ -518,6 +518,7 @@ html.admin-tabs-ready[data-admin-mode="work-area"][data-admin-tab="reporting"] #
|
|
|
518
518
|
html.admin-tabs-ready[data-admin-mode="work-area"][data-admin-tab="ai-workflows"] #ai-workflows,
|
|
519
519
|
html.admin-tabs-ready[data-admin-mode="work-area"][data-admin-tab="blog"] #blog,
|
|
520
520
|
html.admin-tabs-ready[data-admin-mode="work-area"][data-admin-tab="publish"] #publish,
|
|
521
|
+
html.admin-tabs-ready[data-admin-mode="work-area"][data-admin-tab="integrations"] #integrations,
|
|
521
522
|
html.admin-tabs-ready[data-admin-mode="work-area"][data-admin-tab="settings"] #settings {
|
|
522
523
|
display: grid;
|
|
523
524
|
}
|
|
@@ -642,6 +643,14 @@ html[data-internal-admin-guide="false"] [data-admin-internal-only] {
|
|
|
642
643
|
white-space: nowrap;
|
|
643
644
|
}
|
|
644
645
|
|
|
646
|
+
/* The leading state glyph (✓ / ⚠ / ✕ / ●) on a status chip — decorative, so
|
|
647
|
+
status reads as icon + text and never relies on the tone colour alone. The
|
|
648
|
+
chip's own inline-flex `gap` spaces it from the word. */
|
|
649
|
+
.chip-glyph {
|
|
650
|
+
font-weight: 800;
|
|
651
|
+
line-height: 1;
|
|
652
|
+
}
|
|
653
|
+
|
|
645
654
|
.chip.green {
|
|
646
655
|
background: var(--admin-green-soft);
|
|
647
656
|
color: var(--admin-green);
|
|
@@ -921,6 +930,12 @@ tr:last-child td {
|
|
|
921
930
|
border-bottom: 1px solid var(--admin-line);
|
|
922
931
|
}
|
|
923
932
|
|
|
933
|
+
/* Author-provided display wins over the user-agent [hidden] rule unless we
|
|
934
|
+
restate it. A green release must never show the failed-build retry action. */
|
|
935
|
+
.check-row[hidden] {
|
|
936
|
+
display: none;
|
|
937
|
+
}
|
|
938
|
+
|
|
924
939
|
.check-row:last-child {
|
|
925
940
|
border-bottom: 0;
|
|
926
941
|
}
|
|
@@ -1015,9 +1030,14 @@ tr:last-child td {
|
|
|
1015
1030
|
|
|
1016
1031
|
.sidebar {
|
|
1017
1032
|
position: static;
|
|
1033
|
+
box-sizing: border-box;
|
|
1034
|
+
width: 100%;
|
|
1035
|
+
max-width: 100vw;
|
|
1018
1036
|
height: auto;
|
|
1019
|
-
overflow:
|
|
1037
|
+
overflow-x: hidden;
|
|
1038
|
+
overflow-y: visible;
|
|
1020
1039
|
flex-direction: row;
|
|
1040
|
+
flex-wrap: wrap;
|
|
1021
1041
|
align-items: center;
|
|
1022
1042
|
}
|
|
1023
1043
|
|
|
@@ -1029,12 +1049,18 @@ tr:last-child td {
|
|
|
1029
1049
|
position: sticky;
|
|
1030
1050
|
top: 0;
|
|
1031
1051
|
z-index: 29;
|
|
1052
|
+
box-sizing: border-box;
|
|
1053
|
+
width: 100%;
|
|
1032
1054
|
display: flex;
|
|
1033
1055
|
padding-inline: 16px;
|
|
1034
1056
|
background: rgba(245, 247, 246, 0.94);
|
|
1035
1057
|
backdrop-filter: blur(16px);
|
|
1036
1058
|
}
|
|
1037
1059
|
|
|
1060
|
+
.integrations-tab {
|
|
1061
|
+
overflow-x: hidden;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1038
1064
|
.topbar,
|
|
1039
1065
|
.ship-gate,
|
|
1040
1066
|
.risk-alert,
|
|
@@ -16,6 +16,6 @@
|
|
|
16
16
|
"@/*": ["src/*"]
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
|
-
"include": [".astro/types.d.ts", "src/**/*", "perf/**/*.ts", "*.config.mjs", "env.d.ts"],
|
|
19
|
+
"include": [".astro/types.d.ts", "src/**/*", "scripts/**/*.ts", "perf/**/*.ts", "*.config.mjs", "env.d.ts"],
|
|
20
20
|
"exclude": ["dist", "node_modules"]
|
|
21
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/storefront-runner",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "World-shareable storefront runner: multi-tenant renderer on Astro/Cloudflare. No control plane.",
|
|
6
6
|
"packageManager": "pnpm@11.9.0",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"typecheck": "tsc --noEmit",
|
|
15
15
|
"build": "tsc",
|
|
16
16
|
"test": "vitest run",
|
|
17
|
-
"test:watch": "vitest"
|
|
17
|
+
"test:watch": "vitest",
|
|
18
|
+
"generate:managed-analytics-schemas": "node --experimental-strip-types scripts/generate-managed-analytics-api-v1-schemas.mjs"
|
|
18
19
|
},
|
|
19
20
|
"devDependencies": {
|
|
20
21
|
"typescript": "^5.6.3",
|