@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
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The DISABLED MigrationDraft v1 generator: map a CLASSIFIED GTM migration result
|
|
3
|
+
* into an inert, always-disabled managed-analytics migration draft plus a complete
|
|
4
|
+
* unresolved inventory — a pure, deterministic DATA transform with no I/O.
|
|
5
|
+
*
|
|
6
|
+
* SECURITY / PRODUCT CONTRACT (a reviewer WILL reject violations):
|
|
7
|
+
* - Consumes ONLY the pinned PUBLIC managed-analytics v1 contract
|
|
8
|
+
* (`../integration/managed-analytics-api-v1.js`). It never reimplements those
|
|
9
|
+
* schemas, never imports a private module, never touches a database, config,
|
|
10
|
+
* tenant, or materializer, and never calls a live API.
|
|
11
|
+
* - The produced `MigrationDraftV1` is ALWAYS disabled and inert: `status:"draft"`,
|
|
12
|
+
* `enabled:false`, `publishes:false`. It carries NO credentials/secrets, NO
|
|
13
|
+
* executable code/markup/selectors/loaders, NO wildcard origins, NO legacy UA
|
|
14
|
+
* ids, NO GTM container ids, and NO live/publish/activate authority — only an
|
|
15
|
+
* approved adapter selection, primitive config values, and redacted finding
|
|
16
|
+
* codes, exactly as the pinned contract permits. Every produced draft is run
|
|
17
|
+
* THROUGH the pinned `validateMigrationDraftV1` validator; an invalid draft is a
|
|
18
|
+
* hard error and is NEVER emitted as valid.
|
|
19
|
+
* - Pure and deterministic: no I/O, no `eval`, no globals, no `Date.now` (the
|
|
20
|
+
* `generatedAt` timestamp is supplied by the caller). Same input → same draft.
|
|
21
|
+
*
|
|
22
|
+
* MAPPING BOUNDARY: only `automatically-portable` objects convert into the draft's
|
|
23
|
+
* accounting; the confidently-supported GA4 objects among them (GA4 config
|
|
24
|
+
* `googtag`/`gaawc`, GA4 events `gaawe`) drive the selected managed-analytics
|
|
25
|
+
* adapter and its primitive configuration. Every object in the other four
|
|
26
|
+
* disposition classes (`portable-with-review`, `requires-redesign`,
|
|
27
|
+
* `unsupported-by-design`, `retire`) lands in the unresolved inventory so nothing
|
|
28
|
+
* is dropped and a human sees exactly what did NOT convert and why.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import type { GtmContainer } from "./types.js";
|
|
32
|
+
import type { MigrationGraph, GtmObjectKind } from "./graph.js";
|
|
33
|
+
import type { DispositionReport, ObjectDisposition, DispositionClass } from "./dispositions.js";
|
|
34
|
+
import {
|
|
35
|
+
validateMigrationDraftV1,
|
|
36
|
+
MANAGED_ANALYTICS_SCHEMA_VERSION,
|
|
37
|
+
validateManagedAnalyticsSafePayload,
|
|
38
|
+
type MigrationDraftV1,
|
|
39
|
+
type AdapterConfigValue,
|
|
40
|
+
type AdapterDefinition,
|
|
41
|
+
type OpaquePublicId,
|
|
42
|
+
type MigrationFindingCode,
|
|
43
|
+
} from "../integration/managed-analytics-api-v1.js";
|
|
44
|
+
import type { ContractResult } from "../integration/result.js";
|
|
45
|
+
import { digestValue } from "../integration/digest.js";
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The canonical WS1 shared-catalog adapter id that confidently-supported GA4
|
|
49
|
+
* objects map to (the Google Measurement destination). WS1 is canonical — this is
|
|
50
|
+
* exactly the vocabulary WS1's pinned `validateCreateIntegrationInstallRequest`
|
|
51
|
+
* accepts. A stable opaque handle: no secret, no container id, no execution
|
|
52
|
+
* authority. Used as the DEFAULT when no adapter catalog is supplied, so the
|
|
53
|
+
* emitted vocabulary always matches WS1.
|
|
54
|
+
*/
|
|
55
|
+
export const WS1_GOOGLE_MEASUREMENT_ADAPTER_ID: OpaquePublicId = "platform.google-measurement";
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The canonical WS1 config field key the google-measurement adapter declares for
|
|
59
|
+
* its destination id. Used as the DEFAULT config key when no catalog is supplied.
|
|
60
|
+
*/
|
|
61
|
+
export const WS1_GOOGLE_MEASUREMENT_DESTINATION_KEY = "destinationId";
|
|
62
|
+
|
|
63
|
+
/** The opaque adapter handle used when a container has no supported GA4 concept. */
|
|
64
|
+
export const NO_ADAPTER_SELECTED_ID: OpaquePublicId = "none-selected";
|
|
65
|
+
|
|
66
|
+
/** The consent purpose GA4 analytics maps to by default (GA4 consent-mode key). */
|
|
67
|
+
const GA4_DEFAULT_CONSENT_PURPOSE = "analytics_storage";
|
|
68
|
+
|
|
69
|
+
/** GTM tag `type` codes that are a GA4 CONFIG object. */
|
|
70
|
+
const GA4_CONFIG_TYPES = new Set(["googtag", "gaawc"]);
|
|
71
|
+
/** GTM tag `type` code that is a GA4 EVENT object. */
|
|
72
|
+
const GA4_EVENT_TYPE = "gaawe";
|
|
73
|
+
|
|
74
|
+
/** A literal Google measurement destination id (e.g. `G-ABCDE12345`). Never a secret. */
|
|
75
|
+
const GA4_DESTINATION_ID_VALUE = /^G-[A-Z0-9]{4,}$/;
|
|
76
|
+
|
|
77
|
+
/** The role a mapped object plays in the produced draft. */
|
|
78
|
+
export type MappedConceptRole = "ga4-config" | "ga4-event" | "native-portable";
|
|
79
|
+
|
|
80
|
+
/** One `automatically-portable` object accounted for by the draft. */
|
|
81
|
+
export interface MappedConcept {
|
|
82
|
+
readonly nodeKey: string;
|
|
83
|
+
readonly kind: GtmObjectKind;
|
|
84
|
+
readonly id: string | null;
|
|
85
|
+
readonly name: string | null;
|
|
86
|
+
readonly type: string | null;
|
|
87
|
+
readonly reasonCode: string;
|
|
88
|
+
readonly role: MappedConceptRole;
|
|
89
|
+
/** Clean semantic event name derived from a GA4 event tag; null when unavailable or templated. */
|
|
90
|
+
readonly semanticEventName: string | null;
|
|
91
|
+
/** Consent purposes derived for a GA4 object (empty for non-GA4 native-portable objects). */
|
|
92
|
+
readonly consentPurposes: string[];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** One object that did NOT convert — the complete unresolved/unsupported inventory. */
|
|
96
|
+
export interface UnresolvedInventoryItem {
|
|
97
|
+
readonly nodeKey: string;
|
|
98
|
+
readonly kind: GtmObjectKind;
|
|
99
|
+
readonly id: string | null;
|
|
100
|
+
readonly name: string | null;
|
|
101
|
+
readonly type: string | null;
|
|
102
|
+
readonly disposition: DispositionClass;
|
|
103
|
+
readonly reasonCode: string;
|
|
104
|
+
readonly explanation: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Caller-supplied provenance — the timestamp and opaque ids the draft needs (no `Date.now`). */
|
|
108
|
+
export interface DraftProvenanceInput {
|
|
109
|
+
/** Opaque id for the produced draft (an OpaquePublicId). */
|
|
110
|
+
readonly draftId: OpaquePublicId;
|
|
111
|
+
/** ISO-8601 timestamp used for the draft's `createdAt`/`updatedAt` and the digest record. */
|
|
112
|
+
readonly generatedAt: string;
|
|
113
|
+
/** CAS token for the draft; defaults to 0. */
|
|
114
|
+
readonly revision?: number;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** The provenance/digest record attached to the result. */
|
|
118
|
+
export interface DraftProvenanceRecord {
|
|
119
|
+
readonly sourceContainerPublicId: string | null;
|
|
120
|
+
readonly sourceContainerId: string | null;
|
|
121
|
+
readonly generatedAt: string;
|
|
122
|
+
readonly objectCounts: {
|
|
123
|
+
readonly totalObjects: number;
|
|
124
|
+
readonly mapped: number;
|
|
125
|
+
readonly unresolved: number;
|
|
126
|
+
readonly dangling: number;
|
|
127
|
+
readonly byClass: Record<DispositionClass, number>;
|
|
128
|
+
};
|
|
129
|
+
/** Content digest (FNV-1a-128) of the produced draft. */
|
|
130
|
+
readonly draftDigest: string;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** The complete result of generating a disabled migration draft. */
|
|
134
|
+
export interface DisabledDraftResult {
|
|
135
|
+
readonly draft: MigrationDraftV1;
|
|
136
|
+
readonly mappedConcepts: MappedConcept[];
|
|
137
|
+
readonly unresolvedInventory: UnresolvedInventoryItem[];
|
|
138
|
+
readonly provenance: DraftProvenanceRecord;
|
|
139
|
+
/** The result of running the produced draft through the pinned validator (always `ok` when returned). */
|
|
140
|
+
readonly validation: ContractResult<MigrationDraftV1>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface GenerateDisabledMigrationDraftArgs {
|
|
144
|
+
readonly container: GtmContainer;
|
|
145
|
+
readonly graph: MigrationGraph;
|
|
146
|
+
readonly disposition: DispositionReport;
|
|
147
|
+
readonly provenance: DraftProvenanceInput;
|
|
148
|
+
/**
|
|
149
|
+
* The shared WS1 adapter catalog, when available. When present, the GA4 mapping
|
|
150
|
+
* SELECTS the canonical google-measurement adapter FROM it (matched by the
|
|
151
|
+
* canonical adapter id) and keys the produced config off THAT adapter's declared
|
|
152
|
+
* config fields — so the draft speaks WS1's exact vocabulary. A catalog that is
|
|
153
|
+
* present but lacks the adapter is a safe "no adapter selected" outcome (never
|
|
154
|
+
* invent one). When ABSENT, the canonical WS1 constants are used as the default,
|
|
155
|
+
* so the emitted vocabulary still matches WS1.
|
|
156
|
+
*/
|
|
157
|
+
readonly adapterCatalog?: readonly AdapterDefinition[];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Select the canonical google-measurement adapter from a WS1 catalog, or undefined. */
|
|
161
|
+
function selectGoogleMeasurementAdapter(
|
|
162
|
+
catalog: readonly AdapterDefinition[] | undefined,
|
|
163
|
+
): AdapterDefinition | undefined {
|
|
164
|
+
return catalog?.find((a) => a.adapterId === WS1_GOOGLE_MEASUREMENT_ADAPTER_ID);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** The config field key an adapter declares for its Google measurement destination id. */
|
|
168
|
+
function destinationKeyFor(adapter: AdapterDefinition): string {
|
|
169
|
+
const declared =
|
|
170
|
+
adapter.configuration.find((f) => f.key === WS1_GOOGLE_MEASUREMENT_DESTINATION_KEY) ??
|
|
171
|
+
adapter.configuration.find((f) => f.kind === "string");
|
|
172
|
+
return declared?.key ?? WS1_GOOGLE_MEASUREMENT_DESTINATION_KEY;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function normalizeType(type: string | null): string {
|
|
176
|
+
return typeof type === "string" ? type.trim().toLowerCase() : "";
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Read a null-prototype-safe own value off a `raw` bag (missing → undefined). */
|
|
180
|
+
function own(raw: Record<string, unknown>, key: string): unknown {
|
|
181
|
+
return Object.prototype.hasOwnProperty.call(raw, key) ? raw[key] : undefined;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** The parameter list off an inert GTM record, as `{ key, value }` string pairs. */
|
|
185
|
+
function readParameters(raw: Record<string, unknown>): Array<{ key: string; value: string }> {
|
|
186
|
+
const params = own(raw, "parameter");
|
|
187
|
+
if (!Array.isArray(params)) return [];
|
|
188
|
+
const out: Array<{ key: string; value: string }> = [];
|
|
189
|
+
for (const p of params) {
|
|
190
|
+
if (p === null || typeof p !== "object") continue;
|
|
191
|
+
const key = (p as Record<string, unknown>)["key"];
|
|
192
|
+
const value = (p as Record<string, unknown>)["value"];
|
|
193
|
+
if (typeof key === "string" && typeof value === "string") out.push({ key, value });
|
|
194
|
+
}
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** True only when a value is safe to carry verbatim into the draft (per the pinned validator). */
|
|
199
|
+
function isSafeToCarry(value: string): boolean {
|
|
200
|
+
return validateManagedAnalyticsSafePayload(value).ok;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Extract a LITERAL Google measurement destination id from a config record, or
|
|
205
|
+
* null. Scans the record's parameter VALUES for a literal `G-…` destination id
|
|
206
|
+
* (matched by value shape, independent of GTM's own key names). A templated
|
|
207
|
+
* `{{...}}` value or any secret/PII/executable-shaped value is deliberately
|
|
208
|
+
* dropped (never carried) — the reviewed install path resolves the real value
|
|
209
|
+
* later.
|
|
210
|
+
*/
|
|
211
|
+
function extractDestinationId(raw: Record<string, unknown>): string | null {
|
|
212
|
+
for (const { value } of readParameters(raw)) {
|
|
213
|
+
const trimmed = value.trim();
|
|
214
|
+
if (GA4_DESTINATION_ID_VALUE.test(trimmed) && isSafeToCarry(trimmed)) return trimmed;
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Derive a clean semantic event name from a GA4 event tag; null when absent or templated. */
|
|
220
|
+
function deriveSemanticEventName(raw: Record<string, unknown>): string | null {
|
|
221
|
+
for (const { key, value } of readParameters(raw)) {
|
|
222
|
+
if (key !== "eventName") continue;
|
|
223
|
+
const trimmed = value.trim();
|
|
224
|
+
// Skip dynamic template expressions ({{...}}); keep only a clean literal name.
|
|
225
|
+
if (trimmed.length === 0 || trimmed.includes("{{") || trimmed.includes("}}")) return null;
|
|
226
|
+
if (!isSafeToCarry(trimmed)) return null;
|
|
227
|
+
return trimmed;
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Derive GA4 consent purposes: the GA4 default, plus any explicit, safe `consentType` values. */
|
|
233
|
+
function deriveConsentPurposes(raw: Record<string, unknown>): string[] {
|
|
234
|
+
const purposes = new Set<string>([GA4_DEFAULT_CONSENT_PURPOSE]);
|
|
235
|
+
const consent = own(raw, "consentSettings");
|
|
236
|
+
if (consent !== null && typeof consent === "object") {
|
|
237
|
+
const consentType = (consent as Record<string, unknown>)["consentType"];
|
|
238
|
+
if (Array.isArray(consentType)) {
|
|
239
|
+
for (const entry of consentType) {
|
|
240
|
+
if (typeof entry === "string" && entry.length > 0 && isSafeToCarry(entry)) purposes.add(entry);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// Deterministic order: the GA4 default first, then any extras in sorted order.
|
|
245
|
+
const extras = [...purposes].filter((p) => p !== GA4_DEFAULT_CONSENT_PURPOSE).sort();
|
|
246
|
+
return [GA4_DEFAULT_CONSENT_PURPOSE, ...extras];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function roleFor(disp: ObjectDisposition): MappedConceptRole {
|
|
250
|
+
if (disp.kind === "tag" && disp.reasonCode === "ga4-native") {
|
|
251
|
+
const type = normalizeType(disp.type);
|
|
252
|
+
if (GA4_CONFIG_TYPES.has(type)) return "ga4-config";
|
|
253
|
+
if (type === GA4_EVENT_TYPE) return "ga4-event";
|
|
254
|
+
}
|
|
255
|
+
return "native-portable";
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Generate a DISABLED, inert MigrationDraft v1 from a classified GTM migration.
|
|
260
|
+
*
|
|
261
|
+
* Pure and deterministic. Maps only confidently-supported GA4 objects into the
|
|
262
|
+
* selected managed-analytics adapter + primitive config; everything not
|
|
263
|
+
* automatically-portable lands in the unresolved inventory. The produced draft is
|
|
264
|
+
* validated against the pinned schema — an invalid draft throws (never emitted).
|
|
265
|
+
*/
|
|
266
|
+
export function generateDisabledMigrationDraft(
|
|
267
|
+
args: GenerateDisabledMigrationDraftArgs,
|
|
268
|
+
): DisabledDraftResult {
|
|
269
|
+
const { container, graph, disposition, provenance } = args;
|
|
270
|
+
|
|
271
|
+
// Index graph nodes by key so each classified object can read its inert `raw` bag.
|
|
272
|
+
const nodeByKey = new Map<string, (typeof graph.nodes)[number]>();
|
|
273
|
+
for (const node of graph.nodes) nodeByKey.set(node.key, node);
|
|
274
|
+
|
|
275
|
+
const mappedConcepts: MappedConcept[] = [];
|
|
276
|
+
const unresolvedInventory: UnresolvedInventoryItem[] = [];
|
|
277
|
+
|
|
278
|
+
for (const obj of disposition.objects) {
|
|
279
|
+
if (obj.disposition === "automatically-portable") {
|
|
280
|
+
const role = roleFor(obj);
|
|
281
|
+
const raw = nodeByKey.get(obj.nodeKey)?.record.raw ?? {};
|
|
282
|
+
const isGa4 = role === "ga4-config" || role === "ga4-event";
|
|
283
|
+
mappedConcepts.push({
|
|
284
|
+
nodeKey: obj.nodeKey,
|
|
285
|
+
kind: obj.kind,
|
|
286
|
+
id: obj.id,
|
|
287
|
+
name: obj.name,
|
|
288
|
+
type: obj.type,
|
|
289
|
+
reasonCode: obj.reasonCode,
|
|
290
|
+
role,
|
|
291
|
+
semanticEventName: role === "ga4-event" ? deriveSemanticEventName(raw) : null,
|
|
292
|
+
consentPurposes: isGa4 ? deriveConsentPurposes(raw) : [],
|
|
293
|
+
});
|
|
294
|
+
} else {
|
|
295
|
+
unresolvedInventory.push({
|
|
296
|
+
nodeKey: obj.nodeKey,
|
|
297
|
+
kind: obj.kind,
|
|
298
|
+
id: obj.id,
|
|
299
|
+
name: obj.name,
|
|
300
|
+
type: obj.type,
|
|
301
|
+
disposition: obj.disposition,
|
|
302
|
+
reasonCode: obj.reasonCode,
|
|
303
|
+
explanation: obj.explanation,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// --- Adapter selection + primitive config from the mapped GA4 objects. -------
|
|
309
|
+
const ga4Configs = mappedConcepts.filter((c) => c.role === "ga4-config");
|
|
310
|
+
const ga4Events = mappedConcepts.filter((c) => c.role === "ga4-event");
|
|
311
|
+
const hasGa4 = ga4Configs.length > 0 || ga4Events.length > 0;
|
|
312
|
+
|
|
313
|
+
// Select the canonical google-measurement adapter. With a catalog, adopt ITS
|
|
314
|
+
// exact adapter id + declared destination config key. Without one, fall back to
|
|
315
|
+
// the canonical WS1 constants so the default vocabulary still matches WS1. A
|
|
316
|
+
// catalog that is present but lacks the adapter is a safe "no adapter selected"
|
|
317
|
+
// outcome — never invent one.
|
|
318
|
+
const catalogAdapter = selectGoogleMeasurementAdapter(args.adapterCatalog);
|
|
319
|
+
const catalogProvided = args.adapterCatalog !== undefined;
|
|
320
|
+
|
|
321
|
+
let proposedAdapterId: OpaquePublicId;
|
|
322
|
+
let destinationKey: string;
|
|
323
|
+
if (!hasGa4 || (catalogProvided && catalogAdapter === undefined)) {
|
|
324
|
+
proposedAdapterId = NO_ADAPTER_SELECTED_ID;
|
|
325
|
+
destinationKey = WS1_GOOGLE_MEASUREMENT_DESTINATION_KEY;
|
|
326
|
+
} else if (catalogAdapter !== undefined) {
|
|
327
|
+
proposedAdapterId = catalogAdapter.adapterId;
|
|
328
|
+
destinationKey = destinationKeyFor(catalogAdapter);
|
|
329
|
+
} else {
|
|
330
|
+
proposedAdapterId = WS1_GOOGLE_MEASUREMENT_ADAPTER_ID;
|
|
331
|
+
destinationKey = WS1_GOOGLE_MEASUREMENT_DESTINATION_KEY;
|
|
332
|
+
}
|
|
333
|
+
const adapterSelected = proposedAdapterId !== NO_ADAPTER_SELECTED_ID;
|
|
334
|
+
|
|
335
|
+
const proposedConfiguration: Record<string, AdapterConfigValue> = {};
|
|
336
|
+
let destinationId: string | null = null;
|
|
337
|
+
if (adapterSelected) {
|
|
338
|
+
for (const config of ga4Configs) {
|
|
339
|
+
const raw = nodeByKey.get(config.nodeKey)?.record.raw ?? {};
|
|
340
|
+
const found = extractDestinationId(raw);
|
|
341
|
+
if (found !== null) {
|
|
342
|
+
destinationId = found;
|
|
343
|
+
break; // deterministic: first config carrying a literal id wins.
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (destinationId !== null) proposedConfiguration[destinationKey] = destinationId;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// --- Redacted finding codes (no source text; stable, sorted-by-construction). -
|
|
350
|
+
const findings: MigrationFindingCode[] = [];
|
|
351
|
+
if (ga4Configs.length > 0) findings.push("ga4-config-detected");
|
|
352
|
+
if (ga4Events.length > 0) findings.push("ga4-events-detected");
|
|
353
|
+
findings.push(destinationId !== null ? "ga4-destination-id-configured" : "ga4-destination-id-deferred");
|
|
354
|
+
if (!hasGa4) findings.push("no-automatically-portable-analytics");
|
|
355
|
+
if (unresolvedInventory.length > 0) findings.push("unresolved-objects-inventoried");
|
|
356
|
+
|
|
357
|
+
const draft: MigrationDraftV1 = {
|
|
358
|
+
schemaVersion: MANAGED_ANALYTICS_SCHEMA_VERSION,
|
|
359
|
+
draftId: provenance.draftId,
|
|
360
|
+
revision: provenance.revision ?? 0,
|
|
361
|
+
source: "approved-migration",
|
|
362
|
+
status: "draft",
|
|
363
|
+
enabled: false,
|
|
364
|
+
publishes: false,
|
|
365
|
+
proposedAdapterId,
|
|
366
|
+
proposedConfiguration,
|
|
367
|
+
findings,
|
|
368
|
+
createdAt: provenance.generatedAt,
|
|
369
|
+
updatedAt: provenance.generatedAt,
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// --- Validate the produced draft through the PINNED validator. ---------------
|
|
373
|
+
// A draft that fails the pinned schema is a generator bug: throw loudly, never
|
|
374
|
+
// emit it as valid.
|
|
375
|
+
const validation = validateMigrationDraftV1(draft);
|
|
376
|
+
if (!validation.ok) {
|
|
377
|
+
throw new Error(
|
|
378
|
+
`generateDisabledMigrationDraft produced an invalid MigrationDraft v1: ${JSON.stringify(
|
|
379
|
+
validation.violations,
|
|
380
|
+
)}`,
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const cv = container.containerVersion;
|
|
385
|
+
const provenanceRecord: DraftProvenanceRecord = {
|
|
386
|
+
sourceContainerPublicId: cv.publicId,
|
|
387
|
+
sourceContainerId: cv.containerId,
|
|
388
|
+
generatedAt: provenance.generatedAt,
|
|
389
|
+
objectCounts: {
|
|
390
|
+
totalObjects: disposition.objects.length,
|
|
391
|
+
mapped: mappedConcepts.length,
|
|
392
|
+
unresolved: unresolvedInventory.length,
|
|
393
|
+
dangling: disposition.dangling.length,
|
|
394
|
+
byClass: disposition.summary.byClass,
|
|
395
|
+
},
|
|
396
|
+
draftDigest: digestValue(draft),
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
return { draft, mappedConcepts, unresolvedInventory, provenance: provenanceRecord, validation };
|
|
400
|
+
}
|