@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
|
@@ -1,255 +1,50 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Chrome model —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
2
|
+
* Chrome model — re-export of `@tot/public-runtime`'s chrome schema
|
|
3
|
+
* (packages/public-runtime/src/chrome.ts). Moved there so
|
|
4
|
+
* `@tot/private-controlplane`'s write-side `ArtifactValidator` for
|
|
5
|
+
* `tenants/<id>/content/chrome.json`
|
|
6
|
+
* (packages/private-controlplane/src/customization-chrome.ts) can validate
|
|
7
|
+
* against the SAME schema without the renderer importing the control-plane
|
|
8
|
+
* package (the `renderer-no-controlplane` fence,
|
|
9
|
+
* apps/storefront/.dependency-cruiser.cjs, runs the other way: packages may
|
|
10
|
+
* depend on `@tot/public-runtime`, the renderer must never import
|
|
11
|
+
* `@tot/private-controlplane`). This file is kept as the renderer's stable
|
|
12
|
+
* import path — every existing `./model.js` import keeps resolving unchanged.
|
|
8
13
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
src: string;
|
|
47
|
-
alt: string;
|
|
48
|
-
width?: number;
|
|
49
|
-
height?: number;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** A marketing conversion CTA (header-actions / footer, non-commerce tenants). */
|
|
53
|
-
export interface ChromeCta {
|
|
54
|
-
label: string;
|
|
55
|
-
href: string;
|
|
56
|
-
variant?: "primary" | "secondary" | "ghost";
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface FooterColumn {
|
|
60
|
-
title: string;
|
|
61
|
-
links: ChromeLink[];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface FooterNewsletter {
|
|
65
|
-
title?: string;
|
|
66
|
-
body?: string;
|
|
67
|
-
/** Form action (defaults to /api/newsletter). */
|
|
68
|
-
action?: string;
|
|
69
|
-
placeholder?: string;
|
|
70
|
-
/** Hidden `source` field value (e.g. "footer"). */
|
|
71
|
-
source?: string;
|
|
72
|
-
/** When true, render the "I confirm I am 21+" age-attestation checkbox (regulated tenants). */
|
|
73
|
-
ageAttestation?: boolean;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// ---------------------------------------------------------------------------
|
|
77
|
-
// TenantChrome — the FULL per-tenant chrome config (content only) that drives the
|
|
78
|
-
// canonical RAW chrome wrapper (unit F3, see lib/rawChrome.ts). It is the superset
|
|
79
|
-
// the three vape tenants need: bigd/giant (marquee announce + flat nav + utility
|
|
80
|
-
// social) and PVC (dismissible rotating bar + mega panels + member cue + age gate +
|
|
81
|
-
// trust marks). A tenant authors this as `chrome.json`; the renderer turns it into
|
|
82
|
-
// the wrapper document that the rawMarketingHtml splice pipeline surrounds body-only
|
|
83
|
-
// page fragments with. CONTENT ONLY — every color/space/type comes from theme
|
|
84
|
-
// tokens via the platform-shipped stylesheet (decision raw-chrome-single-stylesheet);
|
|
85
|
-
// this config carries no styling. The same file also feeds SiteChrome (getChrome);
|
|
86
|
-
// the two consumers read overlapping-but-distinct field subsets.
|
|
87
|
-
// ---------------------------------------------------------------------------
|
|
88
|
-
|
|
89
|
-
/** A brand identity: an image wordmark/logo, OR a text wordmark of styled spans. */
|
|
90
|
-
export interface ChromeBrand {
|
|
91
|
-
/** Link target (defaults to "/"). */
|
|
92
|
-
href?: string;
|
|
93
|
-
/** Accessible name (aria-label / img alt), e.g. "Prime Vapor Club". */
|
|
94
|
-
label: string;
|
|
95
|
-
/** Image wordmark. Preferred when present and a valid src. */
|
|
96
|
-
logo?: ChromeLogo;
|
|
97
|
-
/**
|
|
98
|
-
* Text wordmark rendered as inline spans (e.g. PVC's `Prime`/`Vapor`/`Club`),
|
|
99
|
-
* each span optionally given a class the theme styles. Used when there's no logo
|
|
100
|
-
* image (placeholder brand — brief §9 Q15).
|
|
101
|
-
*/
|
|
102
|
-
wordmark?: { text: string; className?: string }[];
|
|
103
|
-
/** Marks the brand as a stand-in for a pending real logo (adds data-placeholder). */
|
|
104
|
-
placeholder?: boolean;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** Header search affordance (progressive GET form). Omit to hide search. */
|
|
108
|
-
export interface ChromeSearch {
|
|
109
|
-
/** Form action (defaults to "/search"). */
|
|
110
|
-
action?: string;
|
|
111
|
-
placeholder?: string;
|
|
112
|
-
/** sr-only label (defaults to "Search"). */
|
|
113
|
-
label?: string;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/** The persistent member-price cue for guests (regulated/membership tenants). */
|
|
117
|
-
export interface ChromeMemberCue {
|
|
118
|
-
label: string;
|
|
119
|
-
href: string;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/** The thin utility bar above the header: minor links, locale chips, social, cue. */
|
|
123
|
-
export interface ChromeUtilityNav {
|
|
124
|
-
links?: ChromeLink[];
|
|
125
|
-
/** Locale/currency chips shown on the right (e.g. "English", "United States (USD $)"). */
|
|
126
|
-
locale?: string[];
|
|
127
|
-
social?: SocialLink[];
|
|
128
|
-
/** Optional right-aligned member-price cue link. */
|
|
129
|
-
memberCue?: ChromeMemberCue;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Announcement banner. Three variants map to the F2 stylesheet's classes:
|
|
134
|
-
* - "marquee": infinite horizontal scroll (bigd/giant `.announce-marquee`);
|
|
135
|
-
* - "bar": dismissible + optionally message-rotating promo bar (PVC `.announce-bar`);
|
|
136
|
-
* - "solid": a static single-line solid bar (`.announce`).
|
|
137
|
-
*/
|
|
138
|
-
export interface ChromeAnnouncement {
|
|
139
|
-
variant: "marquee" | "bar" | "solid";
|
|
140
|
-
/** One or more messages. "bar" rotates through them when >1 and rotateMs set. */
|
|
141
|
-
messages: string[];
|
|
142
|
-
/** aria-label for the region (defaults to the first message). */
|
|
143
|
-
label?: string;
|
|
144
|
-
/** "bar" only — show a dismiss button (remembered via storageKey). */
|
|
145
|
-
dismissible?: boolean;
|
|
146
|
-
/** "bar" only — rotate messages every N ms (needs messages.length > 1). */
|
|
147
|
-
rotateMs?: number;
|
|
148
|
-
/** localStorage key remembering a dismissal (defaults to a stable derived key). */
|
|
149
|
-
storageKey?: string;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* 21+ age-gate interstitial config (regulated tenants). The F3 renderer (rawChrome.ts)
|
|
154
|
-
* embeds this as JSON; the shared behavior JS mounts the gate inside a closed shadow
|
|
155
|
-
* root — the same tamper-resistance pattern components/islands/IsolatedAgeGate.tsx
|
|
156
|
-
* uses for component pages (unit C1) — so tenant CSS/JS can't reach the dialog.
|
|
157
|
-
* Per decision compliance-widgets-platform-owned.
|
|
158
|
-
*/
|
|
159
|
-
export interface ChromeAgeGate {
|
|
160
|
-
minAge: number;
|
|
161
|
-
/** localStorage key remembering a pass (defaults to a stable derived key). */
|
|
162
|
-
storageKey?: string;
|
|
163
|
-
title?: string;
|
|
164
|
-
lede?: string;
|
|
165
|
-
yesLabel?: string;
|
|
166
|
-
noLabel?: string;
|
|
167
|
-
denyText?: string;
|
|
168
|
-
/** Fine-print warning under the actions (e.g. the FDA nicotine line). */
|
|
169
|
-
fineText?: string;
|
|
170
|
-
/** Optional styled wordmark above the title (spans, like ChromeBrand.wordmark). */
|
|
171
|
-
mark?: { text: string; className?: string }[];
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/** Footer brand block: identity + tagline/contact + optional inline newsletter. */
|
|
175
|
-
export interface ChromeFooterBrand {
|
|
176
|
-
logo?: ChromeLogo;
|
|
177
|
-
wordmark?: { text: string; className?: string }[];
|
|
178
|
-
/** Tagline / contact HTML-free text (rendered with <br> on newlines). */
|
|
179
|
-
text?: string;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/** A footer trust mark: a small inline-SVG cue + label (e.g. "Secure checkout"). */
|
|
183
|
-
export interface ChromeTrustMark {
|
|
184
|
-
/** Inner SVG markup (paths/rects/circles), viewBox 0 0 24 24. */
|
|
185
|
-
icon: string;
|
|
186
|
-
label: string;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/** The full footer content. */
|
|
190
|
-
export interface ChromeFooter {
|
|
191
|
-
brand?: ChromeFooterBrand;
|
|
192
|
-
columns: FooterColumn[];
|
|
193
|
-
newsletter?: FooterNewsletter;
|
|
194
|
-
trustMarks?: ChromeTrustMark[];
|
|
195
|
-
/** Accepted-payment marks (text tokens, e.g. "VISA"). */
|
|
196
|
-
payments?: string[];
|
|
197
|
-
social?: SocialLink[];
|
|
198
|
-
/** The bold compliance/nicotine warning block. */
|
|
199
|
-
warning?: string;
|
|
200
|
-
/** Bottom bar: copyright + a legal note line. */
|
|
201
|
-
bottom?: { copyright?: string; note?: string };
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/** Per-tenant <head> extras the wrapper links (the shared css is ALWAYS linked). */
|
|
205
|
-
export interface ChromeHead {
|
|
206
|
-
/** Favicon href (image/png). */
|
|
207
|
-
favicon?: string;
|
|
208
|
-
/** Tenant theme stylesheet hrefs (token definitions), e.g. the *-navy.css theme. */
|
|
209
|
-
themeStylesheets?: string[];
|
|
210
|
-
/** <meta name="theme-color"> — a deliberately brand-fixed surface color. */
|
|
211
|
-
themeColor?: string;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
export interface TenantChrome {
|
|
215
|
-
/**
|
|
216
|
-
* OPT-IN: render the canonical shared chrome for this tenant's RAW page
|
|
217
|
-
* fragments. Absent/false ⇒ the tenant keeps serving its hand-authored
|
|
218
|
-
* chrome.html (or a full document) unchanged — so a shipped tenant never flips
|
|
219
|
-
* to shared chrome until it explicitly adopts (units I1/I2/I3). Required so the
|
|
220
|
-
* cutover of a SHIPPED tenant stays a deliberate, gated step.
|
|
221
|
-
*/
|
|
222
|
-
sharedChrome?: boolean;
|
|
223
|
-
/**
|
|
224
|
-
* OPT-IN: also link the shared commerce-MARKETING stylesheet
|
|
225
|
-
* (/shared/commerce-marketing.css, unit F5) into this tenant's wrapper — the
|
|
226
|
-
* raw-page BODY layer (page-hero / prose / callouts / value & tier cards /
|
|
227
|
-
* contact form / FAQ / CTA band) its content fragments repeat. Linked AFTER the
|
|
228
|
-
* chrome sheet so its page-level variants win. Absent/false ⇒ not linked, so a
|
|
229
|
-
* SHIPPED tenant that still carries its own page-local <style> never
|
|
230
|
-
* double-loads or silently flips until its integration unit strips that CSS and
|
|
231
|
-
* adopts (same gated-cutover discipline as `sharedChrome`).
|
|
232
|
-
*/
|
|
233
|
-
sharedMarketingCss?: boolean;
|
|
234
|
-
/** <html lang> (defaults to "en"). */
|
|
235
|
-
lang?: string;
|
|
236
|
-
head?: ChromeHead;
|
|
237
|
-
/** Skip-link target/label overrides (defaults to "#main" / "Skip to main content"). */
|
|
238
|
-
skipLink?: { href?: string; label?: string };
|
|
239
|
-
/** FDA/compliance warning strip at the very top (e.g. the nicotine line). */
|
|
240
|
-
warningBar?: string;
|
|
241
|
-
announcement?: ChromeAnnouncement;
|
|
242
|
-
utilityNav?: ChromeUtilityNav;
|
|
243
|
-
brand: ChromeBrand;
|
|
244
|
-
search?: ChromeSearch;
|
|
245
|
-
/** Header-actions member-price cue (in addition to any utility-nav cue). */
|
|
246
|
-
memberCue?: ChromeMemberCue;
|
|
247
|
-
accountHref?: string;
|
|
248
|
-
cartHref?: string;
|
|
249
|
-
/** Primary nav — flat links and/or mega panels (ChromeNavItem.columns). */
|
|
250
|
-
nav: ChromeNavItem[];
|
|
251
|
-
ageGate?: ChromeAgeGate;
|
|
252
|
-
/** The compliance strip below the page body (e.g. the nicotine warning). */
|
|
253
|
-
complianceStrip?: string;
|
|
254
|
-
footer: ChromeFooter;
|
|
255
|
-
}
|
|
14
|
+
export {
|
|
15
|
+
type ChromeLink,
|
|
16
|
+
type MegaColumn,
|
|
17
|
+
type ChromeNavItem,
|
|
18
|
+
type SocialLink,
|
|
19
|
+
type ChromeLogo,
|
|
20
|
+
type ChromeCta,
|
|
21
|
+
type ChromeActionLink,
|
|
22
|
+
type FooterColumn,
|
|
23
|
+
type FooterNewsletter,
|
|
24
|
+
type ChromeBrand,
|
|
25
|
+
type ChromeSearch,
|
|
26
|
+
type ChromeUtilityNav,
|
|
27
|
+
type ChromeAnnouncement,
|
|
28
|
+
type ChromeAgeGate,
|
|
29
|
+
type ChromeFooterBrand,
|
|
30
|
+
type ChromeTrustMark,
|
|
31
|
+
type ChromeHead,
|
|
32
|
+
HEADER_VARIANTS,
|
|
33
|
+
type HeaderVariant,
|
|
34
|
+
FOOTER_VARIANTS,
|
|
35
|
+
type FooterVariant,
|
|
36
|
+
isHeaderVariant,
|
|
37
|
+
isFooterVariant,
|
|
38
|
+
InvalidChromeVariantError,
|
|
39
|
+
type ChromeHeader,
|
|
40
|
+
type ChromeFooter,
|
|
41
|
+
type ChromeConfig,
|
|
42
|
+
type ChromeAssignmentEntry,
|
|
43
|
+
type ChromeAssignments,
|
|
44
|
+
type ChromeAssignmentsValidationResult,
|
|
45
|
+
type ValidateChromeAssignmentsOptions,
|
|
46
|
+
normalizeChromePagePath,
|
|
47
|
+
validateChromeAssignments,
|
|
48
|
+
parseChromeAssignments,
|
|
49
|
+
resolveChromeAssignment,
|
|
50
|
+
} from "@tot/public-runtime";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exact-match "is this nav link the current page" check, for aria-current="page".
|
|
3
|
+
*
|
|
4
|
+
* Deliberately NOT prefix/startsWith matching: a parent section link (e.g.
|
|
5
|
+
* "/shop") must never be marked current just because the visitor is on a page
|
|
6
|
+
* nested under it (e.g. "/shop/widget") — only an exact path match counts.
|
|
7
|
+
* External links and hash-only in-page anchors (a nav href containing "#")
|
|
8
|
+
* never match: aria-current="page" identifies a distinct page, not a scroll
|
|
9
|
+
* position on the page already open.
|
|
10
|
+
*
|
|
11
|
+
* Both `currentPathname` and `href` are expected to already carry the same
|
|
12
|
+
* tenant base-path prefix (i.e. compare `Astro.url.pathname` against an
|
|
13
|
+
* href already run through `withBase`) — this function only normalizes
|
|
14
|
+
* trailing slashes, it does not resolve base paths itself.
|
|
15
|
+
*/
|
|
16
|
+
export function isCurrentNavHref(
|
|
17
|
+
currentPathname: string,
|
|
18
|
+
href: string,
|
|
19
|
+
external?: boolean,
|
|
20
|
+
): boolean {
|
|
21
|
+
if (external || href.includes("#")) return false;
|
|
22
|
+
const hrefPath = href.split("?")[0] ?? href;
|
|
23
|
+
return normalizeNavPath(currentPathname) === normalizeNavPath(hrefPath);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function normalizeNavPath(pathname: string): string {
|
|
27
|
+
if (pathname.length > 1 && pathname.endsWith("/")) return pathname.slice(0, -1);
|
|
28
|
+
return pathname || "/";
|
|
29
|
+
}
|
|
@@ -1,34 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
2
|
+
* Fail-closed schema validation for a tenant's `chrome.json` — the ONE gate
|
|
3
|
+
* every consumer (the raw-chrome wrapper renderer, the token-styled
|
|
4
|
+
* <SiteHeader>/<SiteFooter> fallback) now parses through.
|
|
5
|
+
*
|
|
6
|
+
* Re-exports `@tot/public-runtime`'s {@link validateChromeConfig} /
|
|
7
|
+
* {@link parseChromeConfig} (packages/public-runtime/src/chrome.ts) — the
|
|
8
|
+
* validation logic itself lives there so
|
|
9
|
+
* `@tot/private-controlplane`'s write-side `ArtifactValidator` for
|
|
10
|
+
* `tenants/<id>/content/chrome.json`
|
|
11
|
+
* (packages/private-controlplane/src/customization-chrome.ts) can call the
|
|
12
|
+
* SAME check without the renderer importing the control-plane package. This
|
|
13
|
+
* file is kept as the renderer's stable import path — every existing
|
|
14
|
+
* `./parseConfig.js` import keeps resolving unchanged.
|
|
10
15
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Coerce parsed chrome.json into a `TenantChrome`, or null if it isn't an opted-in,
|
|
19
|
-
* minimally-complete raw-chrome config. Trusts the authored (first-party) field
|
|
20
|
-
* shapes beyond the required-key check — the renderer is defensive (escapes values,
|
|
21
|
-
* guards every optional section), so a missing optional degrades rather than breaks.
|
|
22
|
-
*/
|
|
23
|
-
export function parseChromeConfig(raw: unknown): TenantChrome | null {
|
|
24
|
-
if (!isObject(raw)) return null;
|
|
25
|
-
// Opt-in switch — absent/false means "not adopted; keep legacy chrome".
|
|
26
|
-
if (raw.sharedChrome !== true) return null;
|
|
27
|
-
// Minimum a wrapper needs to render something coherent.
|
|
28
|
-
const brand = raw.brand;
|
|
29
|
-
if (!isObject(brand) || typeof brand.label !== "string") return null;
|
|
30
|
-
if (!Array.isArray(raw.nav)) return null;
|
|
31
|
-
const footer = raw.footer;
|
|
32
|
-
if (!isObject(footer) || !Array.isArray(footer.columns)) return null;
|
|
33
|
-
return raw as unknown as TenantChrome;
|
|
34
|
-
}
|
|
16
|
+
export {
|
|
17
|
+
type ChromeConfigValidationResult,
|
|
18
|
+
validateChromeConfig,
|
|
19
|
+
parseChromeConfig,
|
|
20
|
+
} from "@tot/public-runtime";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Explicit header/footer variant assignment (fail-closed).
|
|
3
|
+
*
|
|
4
|
+
* A page declares its `headerVariant`/`footerVariant` via a Layout.astro prop
|
|
5
|
+
* (see layouts/Layout.astro) — NEVER inferred from the route, a CSS class, or
|
|
6
|
+
* the page title. `resolveHeaderVariant`/`resolveFooterVariant` apply the
|
|
7
|
+
* page's override over the tenant's chrome-config default and assert the
|
|
8
|
+
* result is a known variant, throwing `InvalidChromeVariantError` (actionable
|
|
9
|
+
* message, not a silent fallback) when it isn't.
|
|
10
|
+
*/
|
|
11
|
+
import {
|
|
12
|
+
FOOTER_VARIANTS,
|
|
13
|
+
HEADER_VARIANTS,
|
|
14
|
+
InvalidChromeVariantError,
|
|
15
|
+
isFooterVariant,
|
|
16
|
+
isHeaderVariant,
|
|
17
|
+
type FooterVariant,
|
|
18
|
+
type HeaderVariant,
|
|
19
|
+
} from "./model.js";
|
|
20
|
+
|
|
21
|
+
export function assertHeaderVariant(v: unknown): HeaderVariant {
|
|
22
|
+
if (!isHeaderVariant(v)) throw new InvalidChromeVariantError("header", v, HEADER_VARIANTS);
|
|
23
|
+
return v;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function assertFooterVariant(v: unknown): FooterVariant {
|
|
27
|
+
if (!isFooterVariant(v)) throw new InvalidChromeVariantError("footer", v, FOOTER_VARIANTS);
|
|
28
|
+
return v;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The page's explicit override, if given and valid; else the chrome config's
|
|
32
|
+
* own declared variant. Always fails closed — never falls back silently. */
|
|
33
|
+
export function resolveHeaderVariant(pageOverride: unknown, configDefault: unknown): HeaderVariant {
|
|
34
|
+
return assertHeaderVariant(pageOverride ?? configDefault);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function resolveFooterVariant(pageOverride: unknown, configDefault: unknown): FooterVariant {
|
|
38
|
+
return assertFooterVariant(pageOverride ?? configDefault);
|
|
39
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request-scoped mint of the checkout-correlation token at the checkout handoff
|
|
3
|
+
* (ext-commerce-10). This is the browser-`checkout.handoff` counterpart of the
|
|
4
|
+
* server-side order join (ext-commerce-04, `orderConversionD1.ts`): it calls the
|
|
5
|
+
* ext-commerce-03 mint (`correlationForHandoff`) so a token is carried through the
|
|
6
|
+
* managed (Foxy) checkout and echoed back on the verified order webhook, threading
|
|
7
|
+
* the browser handoff to its authoritative conversion end-to-end.
|
|
8
|
+
*
|
|
9
|
+
* Three properties hold by construction:
|
|
10
|
+
*
|
|
11
|
+
* - ANALYTICS CONSENT IS REQUIRED (ADR 0023 Q3 `gate-legal-q3-correlation-token`).
|
|
12
|
+
* The consent gate runs FIRST: when the shopper is not analytics-eligible the
|
|
13
|
+
* token is never minted (the secret is not even read) and the handoff proceeds
|
|
14
|
+
* UNATTRIBUTED. The correlation is never smuggled past a withheld consent.
|
|
15
|
+
*
|
|
16
|
+
* - ENV-CONSISTENT. The token binds the request's own {@link IntegrationEnvironment}
|
|
17
|
+
* stage (the renderer-owned `BrowserEnvironment.environment`, server-supplied,
|
|
18
|
+
* never client-set), so a token minted here can only ever verify against an order
|
|
19
|
+
* in the SAME tenant/stage — a candidate/staged token can never attribute a live
|
|
20
|
+
* order, and the reverse.
|
|
21
|
+
*
|
|
22
|
+
* - FAIL-SAFE TO UNATTRIBUTED. With no signing key configured
|
|
23
|
+
* (`COMMERCE_CORRELATION_SECRET` unset — the expected state on any tier that has
|
|
24
|
+
* not provisioned it, incl. preview) this returns an explicit unattributed
|
|
25
|
+
* outcome. It NEVER throws and NEVER blocks checkout; an unattributed order is
|
|
26
|
+
* recorded, not dropped.
|
|
27
|
+
*/
|
|
28
|
+
import {
|
|
29
|
+
correlationForHandoff,
|
|
30
|
+
CORRELATION_CONSENT_PURPOSE,
|
|
31
|
+
isPurposeEligible,
|
|
32
|
+
type ConsentSnapshot,
|
|
33
|
+
type HandoffCorrelation,
|
|
34
|
+
type IntegrationEnvironment,
|
|
35
|
+
} from "@tot/public-runtime";
|
|
36
|
+
import { readEnv } from "@/lib/env";
|
|
37
|
+
|
|
38
|
+
/** The server-only correlation-signing key binding — distinct from the cart secret
|
|
39
|
+
* (key separation), and the SAME binding the order join verifies against. */
|
|
40
|
+
export const CORRELATION_SECRET_ENV = "COMMERCE_CORRELATION_SECRET";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The handoff mint outcome. The attributed branch is exactly the mint's
|
|
44
|
+
* {@link HandoffCorrelation} attributed shape (token + cart field + event
|
|
45
|
+
* correlation); the unattributed branch adds `secret-unavailable` to the pure gate's
|
|
46
|
+
* `analytics-consent-required`, so the caller can tell "consent withheld" from
|
|
47
|
+
* "no signing key" without either ever throwing.
|
|
48
|
+
*/
|
|
49
|
+
export type CheckoutHandoffCorrelation =
|
|
50
|
+
| Extract<HandoffCorrelation, { attributed: true }>
|
|
51
|
+
| { attributed: false; reason: "analytics-consent-required" | "secret-unavailable" };
|
|
52
|
+
|
|
53
|
+
export interface CheckoutHandoffCorrelationInput {
|
|
54
|
+
/** The tenant, from trusted server execution context — never a client value. */
|
|
55
|
+
tenant: string;
|
|
56
|
+
/**
|
|
57
|
+
* The request's stage, from the renderer-owned `BrowserEnvironment.environment`.
|
|
58
|
+
* Server-supplied for env-consistency: the token can only verify against an order
|
|
59
|
+
* in this same stage.
|
|
60
|
+
*/
|
|
61
|
+
environment: IntegrationEnvironment;
|
|
62
|
+
/** The shopper's live consent snapshot (parsed fail-closed by the caller). */
|
|
63
|
+
consent: ConsentSnapshot;
|
|
64
|
+
/** The opaque logical handoff event id the order join threads back to. */
|
|
65
|
+
eventId: string;
|
|
66
|
+
/** Bounded token lifetime; defaults to the mint's `DEFAULT_CORRELATION_TTL_SECONDS`. */
|
|
67
|
+
ttlSeconds?: number;
|
|
68
|
+
/** Injectable wall clock in ms (defaults to `Date.now()`) for deterministic tests. */
|
|
69
|
+
now?: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Resolve the correlation carry for one checkout handoff. Gates on analytics consent,
|
|
74
|
+
* then mints under the server-only secret. `readSecret` is injected (defaults to the
|
|
75
|
+
* env binding) so the mint is exercised in node with no Worker runtime. Never throws.
|
|
76
|
+
*/
|
|
77
|
+
export async function resolveCheckoutHandoffCorrelation(
|
|
78
|
+
input: CheckoutHandoffCorrelationInput,
|
|
79
|
+
readSecret: () => Promise<string | undefined> = () => readEnv(CORRELATION_SECRET_ENV),
|
|
80
|
+
): Promise<CheckoutHandoffCorrelation> {
|
|
81
|
+
// Consent gate FIRST: a shopper who is not analytics-eligible is unattributed, and
|
|
82
|
+
// the signing secret is never even read for them.
|
|
83
|
+
if (!isPurposeEligible(input.consent, CORRELATION_CONSENT_PURPOSE)) {
|
|
84
|
+
return { attributed: false, reason: "analytics-consent-required" };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Fail-safe: no signing key → the handoff proceeds UNATTRIBUTED. Expected wherever
|
|
88
|
+
// COMMERCE_CORRELATION_SECRET is unset (incl. preview); never a thrown error.
|
|
89
|
+
const secret = await readSecret();
|
|
90
|
+
if (!secret) return { attributed: false, reason: "secret-unavailable" };
|
|
91
|
+
|
|
92
|
+
// Consent is eligible and the secret is present, so the mint's own gate always
|
|
93
|
+
// takes the attributed branch here; the return is the token + cart field to carry.
|
|
94
|
+
return (await correlationForHandoff(
|
|
95
|
+
{
|
|
96
|
+
tenant: input.tenant,
|
|
97
|
+
environment: input.environment,
|
|
98
|
+
eventId: input.eventId,
|
|
99
|
+
ttlSeconds: input.ttlSeconds,
|
|
100
|
+
now: input.now,
|
|
101
|
+
},
|
|
102
|
+
input.consent,
|
|
103
|
+
secret,
|
|
104
|
+
)) as CheckoutHandoffCorrelation;
|
|
105
|
+
}
|