@tokenoftrust/storefront-runner 1.4.1 → 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 +17 -1
- package/apps/storefront/env.d.ts +54 -5
- package/apps/storefront/integrations/materialize-guard.mjs +54 -0
- package/apps/storefront/migrations-apps/0002_good_switch.sql +26 -0
- package/apps/storefront/migrations-apps/0003_mute_marauders.sql +12 -0
- 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/0002_snapshot.json +1160 -0
- package/apps/storefront/migrations-apps/meta/0003_snapshot.json +1235 -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 +56 -0
- package/apps/storefront/public/apps/tot.demo.analytics/0.1.0/entry.js +42 -0
- package/apps/storefront/public/js/dashboard-team.js +38 -2
- 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/Seo.astro +65 -1
- package/apps/storefront/src/components/admin/AdminBlogDetailRail.astro +878 -0
- package/apps/storefront/src/components/admin/AdminBlogTab.astro +1435 -0
- package/apps/storefront/src/components/admin/AdminCustomersTab.astro +3 -7
- package/apps/storefront/src/components/admin/AdminIntegrationsTab.astro +105 -0
- package/apps/storefront/src/components/admin/AdminPublishTab.astro +1980 -2564
- package/apps/storefront/src/components/admin/AdminSettingsTab.astro +2 -2
- package/apps/storefront/src/components/admin/AdminSubscriptionsTab.astro +1 -3
- package/apps/storefront/src/components/admin/orders/OrdersWorkspace.astro +5 -5
- package/apps/storefront/src/components/blog/BlogPaywall.astro +87 -0
- package/apps/storefront/src/components/blog/PostAccessBadge.astro +43 -0
- package/apps/storefront/src/components/blog/PostGrid.astro +57 -0
- package/apps/storefront/src/components/blog/ReactionBar.astro +214 -0
- 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 +146 -21
- package/apps/storefront/src/lib/activity/alerts.ts +17 -19
- package/apps/storefront/src/lib/activity/candidateSubmitLease.ts +87 -0
- package/apps/storefront/src/lib/activity/changeActorAttribution.ts +89 -9
- package/apps/storefront/src/lib/activity/deployVersion.ts +20 -27
- package/apps/storefront/src/lib/activity/ingest.ts +8 -8
- package/apps/storefront/src/lib/activity/ingestAuth.ts +1 -1
- package/apps/storefront/src/lib/activity/killSwitch.ts +6 -6
- package/apps/storefront/src/lib/activity/query.ts +9 -9
- package/apps/storefront/src/lib/activity/recordActivity.ts +11 -15
- package/apps/storefront/src/lib/activity/store.ts +4 -6
- package/apps/storefront/src/lib/activity/uiActor.ts +12 -12
- package/apps/storefront/src/lib/activity/workerCommit.ts +6 -6
- package/apps/storefront/src/lib/admin/adminShell.ts +292 -0
- package/apps/storefront/src/lib/admin/ai/approvalMode.ts +2 -3
- package/apps/storefront/src/lib/admin/ai/audit.ts +3 -5
- package/apps/storefront/src/lib/admin/checkoutStyleInput.ts +7 -7
- package/apps/storefront/src/lib/admin/checkoutStyleTarget.ts +3 -3
- package/apps/storefront/src/lib/admin/envelope.ts +1 -2
- package/apps/storefront/src/lib/admin/orderClient.ts +3 -5
- package/apps/storefront/src/lib/admin/services/orders.ts +17 -19
- package/apps/storefront/src/lib/admin/viewmodels/aiWorkflows.ts +4 -6
- package/apps/storefront/src/lib/admin/viewmodels/settings.ts +1 -1
- package/apps/storefront/src/lib/apps/adminService.ts +14 -4
- package/apps/storefront/src/lib/apps/adminSession.ts +54 -45
- package/apps/storefront/src/lib/apps/apiAuth.ts +2 -2
- package/apps/storefront/src/lib/apps/apiRoute.ts +2 -2
- package/apps/storefront/src/lib/apps/appVersionStore.ts +281 -0
- package/apps/storefront/src/lib/apps/catalogMapper.ts +1 -1
- package/apps/storefront/src/lib/apps/consentConfigStore.ts +228 -0
- package/apps/storefront/src/lib/apps/credentials.ts +2 -2
- package/apps/storefront/src/lib/apps/gatewayKeys.ts +4 -4
- 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/healthAggregate.ts +5 -5
- 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/attributionService.ts +2 -2
- package/apps/storefront/src/lib/apps/orders/customerHash.ts +1 -1
- package/apps/storefront/src/lib/apps/orders/foxyOrderClient.ts +12 -12
- package/apps/storefront/src/lib/apps/orders/idempotency.ts +7 -7
- package/apps/storefront/src/lib/apps/orders/orderConversionD1.ts +150 -0
- package/apps/storefront/src/lib/apps/orders/orderForwardReceiver.ts +9 -1
- package/apps/storefront/src/lib/apps/orders/orderMapper.ts +2 -2
- package/apps/storefront/src/lib/apps/orders/ordersStore.ts +7 -7
- package/apps/storefront/src/lib/apps/orders/verifiedProviderMeasurement.ts +117 -0
- package/apps/storefront/src/lib/apps/registryService.ts +270 -16
- package/apps/storefront/src/lib/apps/scopes.ts +2 -2
- package/apps/storefront/src/lib/apps/tenantIntegrationMaterialization.ts +170 -0
- package/apps/storefront/src/lib/apps/tokenIssuer.ts +4 -4
- package/apps/storefront/src/lib/apps/tokenVerifier.ts +6 -6
- 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/widgets/eligibility.ts +2 -2
- package/apps/storefront/src/lib/apps/widgets/frameProps.ts +3 -3
- package/apps/storefront/src/lib/apps/widgets/launchToken.ts +4 -4
- package/apps/storefront/src/lib/apps/widgets/placements.ts +2 -2
- package/apps/storefront/src/lib/apps/widgets/renderSlot.ts +1 -1
- 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 +11 -11
- package/apps/storefront/src/lib/auth/adminLanding.ts +88 -0
- package/apps/storefront/src/lib/auth/identityToken.ts +6 -14
- package/apps/storefront/src/lib/auth/loginGate.ts +75 -13
- package/apps/storefront/src/lib/auth/mcpClientAssertion.ts +2 -4
- package/apps/storefront/src/lib/auth/operatorSession.ts +113 -0
- package/apps/storefront/src/lib/auth/session.ts +7 -8
- package/apps/storefront/src/lib/auth/totAccessClient.ts +8 -18
- package/apps/storefront/src/lib/basePath.ts +9 -2
- package/apps/storefront/src/lib/blog/access.ts +29 -0
- package/apps/storefront/src/lib/blog/collection.ts +400 -0
- package/apps/storefront/src/lib/blog/markdown.ts +174 -0
- package/apps/storefront/src/lib/blog/provider.ts +62 -3
- package/apps/storefront/src/lib/blog/reactions.ts +87 -0
- package/apps/storefront/src/lib/blog/rss.ts +92 -0
- package/apps/storefront/src/lib/blog/teaser.ts +83 -0
- package/apps/storefront/src/lib/blog/types.ts +34 -0
- package/apps/storefront/src/lib/blog/viewCounts.ts +243 -0
- 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 +14 -2
- package/apps/storefront/src/lib/d1/schema-apps.ts +372 -17
- package/apps/storefront/src/lib/dev/activityIngestToken.ts +2 -4
- package/apps/storefront/src/lib/dev/activityStore.ts +3 -5
- package/apps/storefront/src/lib/dev/apiBase.ts +1 -4
- 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/cockpitStore.ts +1 -9
- package/apps/storefront/src/lib/dev/devDraft.ts +1 -1
- package/apps/storefront/src/lib/dev/previewStatus.ts +9 -21
- package/apps/storefront/src/lib/dev/rendezvousBroker.ts +9 -24
- package/apps/storefront/src/lib/dev/runtimeStore.ts +1 -1
- package/apps/storefront/src/lib/edgeCache.ts +34 -5
- package/apps/storefront/src/lib/email/candidateConflictEmail.ts +80 -0
- package/apps/storefront/src/lib/http/fetchTransport.ts +63 -0
- package/apps/storefront/src/lib/i18n.ts +25 -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/jsonld.ts +118 -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/monitoring/manifest.ts +11 -11
- package/apps/storefront/src/lib/newsletter/confirmationEmail.ts +30 -0
- package/apps/storefront/src/lib/newsletter/consent.ts +23 -0
- package/apps/storefront/src/lib/newsletter/digest.ts +117 -0
- package/apps/storefront/src/lib/newsletter/resendClient.ts +79 -0
- package/apps/storefront/src/lib/newsletter/send.ts +265 -0
- package/apps/storefront/src/lib/newsletter/subscribers.ts +156 -0
- package/apps/storefront/src/lib/previewReload.ts +57 -1
- package/apps/storefront/src/lib/publish/adminPublishTab.ts +4625 -0
- package/apps/storefront/src/lib/publish/apex-readiness.ts +41 -18
- 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/dispatchHealth.ts +5 -7
- package/apps/storefront/src/lib/publish/domainState.ts +22 -13
- 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/panelPolling.ts +78 -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 +121 -51
- package/apps/storefront/src/lib/publish/sseRoute.ts +119 -0
- package/apps/storefront/src/lib/publish/stageBundleUpload.ts +215 -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/rate/kvWindow.ts +53 -0
- package/apps/storefront/src/lib/rawChrome.ts +125 -47
- package/apps/storefront/src/lib/rawMarketingHtml.ts +74 -3
- package/apps/storefront/src/lib/search/index.ts +2 -2
- package/apps/storefront/src/lib/seo/alternates.ts +42 -0
- package/apps/storefront/src/lib/seo/meta.ts +65 -0
- package/apps/storefront/src/lib/social/golive.ts +212 -0
- package/apps/storefront/src/lib/social/notify.ts +32 -0
- package/apps/storefront/src/lib/social/tokenStore.ts +171 -0
- 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 +32 -0
- package/apps/storefront/src/lib/the-build/readingTime.ts +35 -0
- package/apps/storefront/src/lib/the-build/toc.ts +95 -0
- package/apps/storefront/src/lib/tot/ToTClient.ts +1 -1
- package/apps/storefront/src/lib/tot/d1Client.ts +2 -2
- package/apps/storefront/src/lib/tot/totClientInterface.ts +3 -4
- package/apps/storefront/src/lib/webhooks/deliveryStore.ts +16 -17
- package/apps/storefront/src/middleware/index.ts +385 -52
- 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 +25 -1313
- 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/blog/[collection]/[slug]/react.ts +104 -0
- 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/newsletter/[collection]/subscribe.ts +146 -0
- package/apps/storefront/src/pages/api/newsletter/confirm.ts +75 -0
- package/apps/storefront/src/pages/api/newsletter/unsubscribe.ts +90 -0
- package/apps/storefront/src/pages/api/publish/stage-bundle.ts +70 -0
- package/apps/storefront/src/pages/api/rum/vitals.ts +20 -2
- package/apps/storefront/src/pages/blog/[slug].astro +99 -19
- package/apps/storefront/src/pages/blog/author/[author].astro +140 -0
- package/apps/storefront/src/pages/blog/category/[category].astro +67 -0
- package/apps/storefront/src/pages/blog/index.astro +4 -2
- package/apps/storefront/src/pages/blog/tag/[tag].astro +65 -0
- package/apps/storefront/src/pages/cockpit.astro +77 -1353
- package/apps/storefront/src/pages/dashboard/[appDomain]/team.astro +15 -11
- 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/search.astro +1 -1
- package/apps/storefront/src/pages/sitemap.xml.ts +21 -1
- 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 +129 -0
- package/apps/storefront/src/pages/the-build/index.astro +146 -0
- package/apps/storefront/src/pages/the-build/rss.xml.ts +33 -0
- package/apps/storefront/src/styles/admin.css +1106 -0
- package/apps/storefront/tsconfig.json +6 -1
- package/package.json +1 -1
- package/packages/public-runtime/package.json +3 -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 +89 -33
- 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/catalog-d1.ts +1 -1
- 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-preview.ts +25 -2
- package/packages/public-runtime/src/customization-runtime.ts +156 -3
- package/packages/public-runtime/src/customization-versioning.ts +10 -0
- 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 +17 -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 +357 -0
- package/packages/public-runtime/src/tenant-assets.ts +143 -4
- package/packages/public-runtime/src/tenant.ts +81 -17
- 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/build/copy-tenant-assets.mjs +14 -4
- package/scripts/dev/ai-edit.mjs +1 -1
- package/scripts/dev/checkout-watch.mjs +2 -2
- package/scripts/dev/file-browser.mjs +4 -6
- package/scripts/dev/file-writer.mjs +3 -3
- package/scripts/dev/git-status.mjs +2 -2
- package/scripts/dev/integration-guardrails.mjs +498 -0
- package/scripts/dev/locate-handler.mjs +3 -3
- package/scripts/dev/port-check.mjs +3 -3
- package/scripts/dev/publish.mjs +5 -9
- package/scripts/dev/safe-path.mjs +2 -2
- package/scripts/dev/shot.mjs +1 -1
- package/scripts/dev/tenant-source-root.mjs +1 -1
- package/scripts/dev/unified-diff.mjs +8 -3
- package/scripts/tot-dev.mjs +8 -11
- package/apps/storefront/src/lib/dev/vcBinding.ts +0 -80
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy the one command. Two behaviours:
|
|
3
|
+
* · fastpath (signed-in dev): mint a single-use `tot login --code … && tot start` from
|
|
4
|
+
* /api/dev/cli-signin-code, reveal it (textContent, never innerHTML — it carries a
|
|
5
|
+
* live code), and copy the whole thing.
|
|
6
|
+
* · otherwise: copy the generic install-and-run command directly.
|
|
7
|
+
*
|
|
8
|
+
* Also drives rendezvous approval: after a command is generated, the
|
|
9
|
+
* terminal ATTACHES its own PKCE key and prints a fingerprint; the developer
|
|
10
|
+
* confirms it here — the load-bearing anti-interception step, since
|
|
11
|
+
* approving the wrong fingerprint is how a hijack is caught.
|
|
12
|
+
*
|
|
13
|
+
* Imported from a processed `<script>` in cockpit.astro. The values below are
|
|
14
|
+
* carried as data-attrs on #copyCmd because this module runs standalone (not
|
|
15
|
+
* inside the same closure as hostedActivity.ts's basePath).
|
|
16
|
+
*/
|
|
17
|
+
export function initCopyCommand(): void {
|
|
18
|
+
const btn: any = document.getElementById("copyCmd");
|
|
19
|
+
const textEl = document.getElementById("cli-cmd-text");
|
|
20
|
+
const note = document.getElementById("cli-cmd-note");
|
|
21
|
+
const toast = document.getElementById("toast");
|
|
22
|
+
const toastMsg = document.getElementById("toastMsg");
|
|
23
|
+
const copyIcon: any = document.getElementById("copyIcon");
|
|
24
|
+
if (!btn || !textEl) return;
|
|
25
|
+
const generic = btn.getAttribute("data-generic") || "";
|
|
26
|
+
const fastpath = btn.getAttribute("data-fastpath") === "1";
|
|
27
|
+
// The request's tenant prefix ("" host-routed, "/<tenant>" path-routed). Carried
|
|
28
|
+
// as a data-attr because `basePath` is otherwise defined only inside the SEPARATE
|
|
29
|
+
// hostedActivity module (hostedActivity.ts) — referencing it here (the
|
|
30
|
+
// cli-signin-code / -status / -approve fetches below) was a ReferenceError that
|
|
31
|
+
// the mint's catch surfaced as the opaque "Couldn't reach the sign-in service"
|
|
32
|
+
// with no request ever sent.
|
|
33
|
+
const basePath = btn.getAttribute("data-base-path") || "";
|
|
34
|
+
let tT: ReturnType<typeof setTimeout>;
|
|
35
|
+
function ping(m: string) {
|
|
36
|
+
if (!toast) return;
|
|
37
|
+
if (toastMsg) toastMsg.textContent = m;
|
|
38
|
+
toast.classList.add("show");
|
|
39
|
+
clearTimeout(tT); tT = setTimeout(() => { toast.classList.remove("show"); }, 1900);
|
|
40
|
+
}
|
|
41
|
+
function copy(text: string): Promise<boolean> {
|
|
42
|
+
if (navigator.clipboard) return navigator.clipboard.writeText(text).then(() => true).catch(() => false);
|
|
43
|
+
return Promise.resolve(false);
|
|
44
|
+
}
|
|
45
|
+
function label(s: string) { btn.childNodes[btn.childNodes.length - 1].textContent = s; }
|
|
46
|
+
|
|
47
|
+
// Standard copy-icon affordance on the terminal box. Once the command is
|
|
48
|
+
// revealed, this is the obvious, always-there way to (re)copy it — the
|
|
49
|
+
// icon→check swap is its own inline confirmation, so copying no longer
|
|
50
|
+
// depends on the transient toast being noticed.
|
|
51
|
+
let iconT: ReturnType<typeof setTimeout>;
|
|
52
|
+
function flashCopied() {
|
|
53
|
+
if (!copyIcon) return;
|
|
54
|
+
copyIcon.setAttribute("data-copied", "1");
|
|
55
|
+
copyIcon.setAttribute("aria-label", "Copied");
|
|
56
|
+
copyIcon.setAttribute("title", "Copied");
|
|
57
|
+
clearTimeout(iconT);
|
|
58
|
+
iconT = setTimeout(() => {
|
|
59
|
+
copyIcon.removeAttribute("data-copied");
|
|
60
|
+
copyIcon.setAttribute("aria-label", "Copy the command");
|
|
61
|
+
copyIcon.setAttribute("title", "Copy the command");
|
|
62
|
+
}, 1600);
|
|
63
|
+
}
|
|
64
|
+
function revealIcon() {
|
|
65
|
+
if (copyIcon) copyIcon.hidden = false;
|
|
66
|
+
}
|
|
67
|
+
if (copyIcon) {
|
|
68
|
+
copyIcon.addEventListener("click", () => {
|
|
69
|
+
copy(textEl.textContent || "").then((ok) => {
|
|
70
|
+
if (ok) { flashCopied(); ping("Copied — paste & press Enter"); }
|
|
71
|
+
else ping("Select the command above to copy");
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ── Rendezvous approval: after a command is generated, the terminal ATTACHES
|
|
77
|
+
// its own PKCE key and prints a fingerprint; the developer confirms it HERE. This
|
|
78
|
+
// is the load-bearing anti-interception step — approving the wrong fingerprint is
|
|
79
|
+
// how a hijack is caught, so the confirm is an explicit, human decision.
|
|
80
|
+
const rzvRoot: any = document.getElementById("rzvApprove");
|
|
81
|
+
const rzvWait: any = document.getElementById("rzvWait");
|
|
82
|
+
const rzvConfirm: any = document.getElementById("rzvConfirm");
|
|
83
|
+
const rzvFp: any = document.getElementById("rzvFp");
|
|
84
|
+
const rzvApproveBtn: any = document.getElementById("rzvApproveBtn");
|
|
85
|
+
const rzvDenyBtn: any = document.getElementById("rzvDenyBtn");
|
|
86
|
+
const rzvDone: any = document.getElementById("rzvDone");
|
|
87
|
+
let rzvTimer: ReturnType<typeof setTimeout> | null = null;
|
|
88
|
+
let rzvCode: string | null = null;
|
|
89
|
+
let rzvDecided = false;
|
|
90
|
+
function rzvShow(el: any) { if (el) el.hidden = false; }
|
|
91
|
+
function rzvHide(el: any) { if (el) el.hidden = true; }
|
|
92
|
+
// Once the terminal has ATTACHED, the command has plainly been pasted and
|
|
93
|
+
// run — hide the copy affordances so the approve prompt is the page's
|
|
94
|
+
// single focus (DZ 2026-08-18). An EXPIRED sign-in restores the generate
|
|
95
|
+
// button (a fresh mint is needed); the stale command's copy icon stays gone.
|
|
96
|
+
function rzvHideCopyCtas() {
|
|
97
|
+
if (btn) btn.hidden = true;
|
|
98
|
+
if (copyIcon) copyIcon.hidden = true;
|
|
99
|
+
}
|
|
100
|
+
function rzvRestoreGenerate() {
|
|
101
|
+
if (btn) btn.hidden = false;
|
|
102
|
+
}
|
|
103
|
+
function rzvStopPoll() { if (rzvTimer) { clearTimeout(rzvTimer); rzvTimer = null; } }
|
|
104
|
+
function rzvFinish(msg: string) {
|
|
105
|
+
rzvStopPoll(); rzvDecided = true;
|
|
106
|
+
rzvHide(rzvWait); rzvHide(rzvConfirm);
|
|
107
|
+
if (rzvDone) { rzvDone.textContent = msg; rzvDone.hidden = false; }
|
|
108
|
+
}
|
|
109
|
+
async function rzvPoll(): Promise<void> {
|
|
110
|
+
if (rzvDecided) return;
|
|
111
|
+
let r: Response, b: any;
|
|
112
|
+
try {
|
|
113
|
+
r = await fetch(basePath + "/api/dev/cli-signin-status", {
|
|
114
|
+
method: "POST", headers: { "content-type": "application/json" },
|
|
115
|
+
body: JSON.stringify({ rendezvousCode: rzvCode }),
|
|
116
|
+
});
|
|
117
|
+
b = await r.json().catch(() => ({}));
|
|
118
|
+
} catch (e) { rzvTimer = setTimeout(rzvPoll, 2800); return; }
|
|
119
|
+
if (!r || !r.ok) { rzvTimer = setTimeout(rzvPoll, 3200); return; }
|
|
120
|
+
if (b.state === "attached" && b.fingerprint) {
|
|
121
|
+
rzvHideCopyCtas();
|
|
122
|
+
rzvHide(rzvWait); rzvShow(rzvConfirm);
|
|
123
|
+
if (rzvFp) { rzvFp.textContent = b.fingerprint; rzvFp.setAttribute("data-fp", b.fingerprint); }
|
|
124
|
+
return; // stop polling — wait for the human decision
|
|
125
|
+
}
|
|
126
|
+
if (b.state === "approved") { rzvHideCopyCtas(); rzvFinish("Signed in ✓ — your terminal is good to go."); return; }
|
|
127
|
+
if (b.state === "denied") { rzvHideCopyCtas(); rzvFinish("Rejected — that terminal wasn't approved. You're safe; generate a fresh command to try again."); return; }
|
|
128
|
+
if (b.state === "expired") { rzvRestoreGenerate(); rzvFinish("This sign-in expired. Generate a fresh setup command above."); return; }
|
|
129
|
+
rzvTimer = setTimeout(rzvPoll, 2500); // pending → keep watching
|
|
130
|
+
}
|
|
131
|
+
function rzvStart(code: string) {
|
|
132
|
+
rzvCode = code; rzvDecided = false;
|
|
133
|
+
if (rzvApproveBtn) rzvApproveBtn.disabled = false;
|
|
134
|
+
if (rzvDenyBtn) rzvDenyBtn.disabled = false;
|
|
135
|
+
rzvShow(rzvRoot); rzvShow(rzvWait); rzvHide(rzvConfirm); rzvHide(rzvDone);
|
|
136
|
+
rzvStopPoll(); rzvPoll();
|
|
137
|
+
}
|
|
138
|
+
async function rzvDecide(decision: string): Promise<void> {
|
|
139
|
+
if (rzvDecided) return;
|
|
140
|
+
const fp = rzvFp ? (rzvFp.getAttribute("data-fp") || "") : "";
|
|
141
|
+
if (rzvApproveBtn) rzvApproveBtn.disabled = true;
|
|
142
|
+
if (rzvDenyBtn) rzvDenyBtn.disabled = true;
|
|
143
|
+
let r: Response;
|
|
144
|
+
try {
|
|
145
|
+
r = await fetch(basePath + "/api/dev/cli-signin-approve", {
|
|
146
|
+
method: "POST", headers: { "content-type": "application/json" },
|
|
147
|
+
body: JSON.stringify({ rendezvousCode: rzvCode, fingerprint: fp, decision: decision }),
|
|
148
|
+
});
|
|
149
|
+
} catch (e) {
|
|
150
|
+
if (rzvApproveBtn) rzvApproveBtn.disabled = false;
|
|
151
|
+
if (rzvDenyBtn) rzvDenyBtn.disabled = false;
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (decision === "deny") { rzvFinish("Rejected — that terminal wasn't approved."); return; }
|
|
155
|
+
if (r.ok) { rzvFinish("Signed in ✓ — your terminal is good to go."); return; }
|
|
156
|
+
if (rzvApproveBtn) rzvApproveBtn.disabled = false;
|
|
157
|
+
if (rzvDenyBtn) rzvDenyBtn.disabled = false;
|
|
158
|
+
const m = r.status === 403 ? "That didn't match your identity — generate a fresh command and try again."
|
|
159
|
+
: r.status === 409 ? "That code didn't match a waiting terminal — re-check it, or generate a fresh command."
|
|
160
|
+
: "Couldn't complete approval — try again.";
|
|
161
|
+
if (rzvDone) { rzvDone.textContent = m; rzvDone.hidden = false; }
|
|
162
|
+
}
|
|
163
|
+
if (rzvApproveBtn) rzvApproveBtn.addEventListener("click", () => { rzvDecide("approve"); });
|
|
164
|
+
if (rzvDenyBtn) rzvDenyBtn.addEventListener("click", () => { rzvDecide("deny"); });
|
|
165
|
+
|
|
166
|
+
if (!fastpath) {
|
|
167
|
+
btn.addEventListener("click", () => {
|
|
168
|
+
copy(generic).then((ok) => {
|
|
169
|
+
label(ok ? " Copied — paste & press Enter" : " Copy the command");
|
|
170
|
+
ping(ok ? "Copied the command" : "Select the command to copy");
|
|
171
|
+
setTimeout(() => { label(" Copy the command"); }, 2600);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
let busy = false;
|
|
178
|
+
btn.addEventListener("click", async () => {
|
|
179
|
+
if (busy) return;
|
|
180
|
+
busy = true;
|
|
181
|
+
label(" …"); btn.disabled = true;
|
|
182
|
+
let res: Response, body: any;
|
|
183
|
+
try {
|
|
184
|
+
res = await fetch(basePath + "/api/dev/cli-signin-code", {
|
|
185
|
+
method: "POST",
|
|
186
|
+
headers: { "content-type": "application/json" },
|
|
187
|
+
body: "{}",
|
|
188
|
+
});
|
|
189
|
+
body = await res.json().catch(() => ({}));
|
|
190
|
+
} catch (err) {
|
|
191
|
+
if (note) note.textContent = "Couldn't reach the sign-in service — try again in a moment.";
|
|
192
|
+
label(" Copy the command"); btn.disabled = false; busy = false;
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (!res.ok || !body.command) {
|
|
196
|
+
const byStatus: Record<number, string> = {
|
|
197
|
+
401: "Your session expired — reload the page and sign in again.",
|
|
198
|
+
403: "This account doesn't have developer access to a store yet.",
|
|
199
|
+
409: "Your store isn't set up yet — reload this page for its status.",
|
|
200
|
+
502: "The sign-in service is having a moment — try again.",
|
|
201
|
+
503: "Terminal sign-in isn't configured on this environment.",
|
|
202
|
+
};
|
|
203
|
+
if (note) note.textContent = byStatus[res.status] || "Couldn't mint a sign-in command — try again.";
|
|
204
|
+
label(" Copy the command"); btn.disabled = false; busy = false;
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
// Reveal the real command (carries the non-secret rendezvous handle) as a pure
|
|
208
|
+
// text node, then copy it.
|
|
209
|
+
textEl.textContent = body.command;
|
|
210
|
+
textEl.classList.remove("is-placeholder");
|
|
211
|
+
revealIcon();
|
|
212
|
+
// Start watching for the terminal to attach so we can prompt for approval.
|
|
213
|
+
if (body.rendezvousCode) rzvStart(body.rendezvousCode);
|
|
214
|
+
const ok = await copy(body.command);
|
|
215
|
+
if (ok) flashCopied();
|
|
216
|
+
label(ok ? " Copied ✓" : " Select & copy");
|
|
217
|
+
ping(ok ? "Copied — paste & press Enter" : "Select the command above to copy");
|
|
218
|
+
if (note) {
|
|
219
|
+
note.textContent = ok
|
|
220
|
+
? "Copied. Paste into your terminal and press Enter — it signs you in, runs your store, and opens your browser. Single-use, short-lived code."
|
|
221
|
+
: "Select the command above and copy it, then paste into your terminal and press Enter. Single-use, short-lived code.";
|
|
222
|
+
}
|
|
223
|
+
btn.disabled = false;
|
|
224
|
+
setTimeout(() => { label(" Copy the command"); }, 4000);
|
|
225
|
+
busy = false;
|
|
226
|
+
});
|
|
227
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Files tab — in-browser file tree + LIVE EDITOR. Rendered only when
|
|
3
|
+
* isLocalDevLoop; reads /__tot/tree + /__tot/file and writes /__tot/write
|
|
4
|
+
* (dev-plugins/dev-file-browser + dev-write). Writable files (content HTML +
|
|
5
|
+
* theme.json) become an editable textarea with ~600ms debounce autosave +
|
|
6
|
+
* Cmd/Ctrl+S; the save carries the baseVersion so a concurrent
|
|
7
|
+
* $EDITOR/git change is caught (409) instead of clobbered. Dynamic values go
|
|
8
|
+
* through .value / textContent (never innerHTML).
|
|
9
|
+
* Imported from a processed `<script>` in cockpit.astro (ADR 0013). apiBase
|
|
10
|
+
* and isDev are read from `document.body.dataset` (cp-env: same client JS,
|
|
11
|
+
* environment-aware endpoint base — see resolveDevApiBase).
|
|
12
|
+
*/
|
|
13
|
+
export function initFiles(): void {
|
|
14
|
+
const apiBase = document.body.dataset.cockpitApiBase || "";
|
|
15
|
+
const isDev = document.body.dataset.cockpitIsDev === "true";
|
|
16
|
+
const offlineMsg = isDev ? "Could not reach the dev server." : "Not available on the hosted panel yet — check back soon.";
|
|
17
|
+
const treeEl: any = document.getElementById("filesTree");
|
|
18
|
+
const viewEl: any = document.getElementById("filesView");
|
|
19
|
+
const pathEl = document.getElementById("filesPath");
|
|
20
|
+
const editbar = document.getElementById("filesEditbar");
|
|
21
|
+
const statusEl: any = document.getElementById("filesStatus");
|
|
22
|
+
const conflictEl = document.getElementById("filesConflict");
|
|
23
|
+
const reloadBtn = document.getElementById("filesReload");
|
|
24
|
+
const forceBtn = document.getElementById("filesForce");
|
|
25
|
+
const diffBtn: any = document.getElementById("filesDiffBtn");
|
|
26
|
+
const diffEl: any = document.getElementById("filesDiff");
|
|
27
|
+
const publishBtn: any = document.getElementById("filesPublishBtn");
|
|
28
|
+
if (!treeEl || !viewEl) return;
|
|
29
|
+
let selected: any = null;
|
|
30
|
+
let cur: { path: string; baseVersion: number | null; writable: boolean } | null = null;
|
|
31
|
+
let saveTimer: ReturnType<typeof setTimeout> | null = null;
|
|
32
|
+
let diffOn = false;
|
|
33
|
+
let rowByPath: Record<string, any> = {}; // path -> tree row element, for programmatic open
|
|
34
|
+
|
|
35
|
+
function setStatus(txt: string, cls?: string) {
|
|
36
|
+
if (!statusEl) return;
|
|
37
|
+
statusEl.textContent = txt || "";
|
|
38
|
+
statusEl.className = "df-status" + (cls ? " " + cls : "");
|
|
39
|
+
}
|
|
40
|
+
function showConflict(show: boolean) { if (conflictEl) (conflictEl as any).hidden = !show; }
|
|
41
|
+
function showBar(show: boolean) { if (editbar) (editbar as any).hidden = !show; }
|
|
42
|
+
|
|
43
|
+
function openFile(path: string, row: any, afterLoad?: () => void) {
|
|
44
|
+
if (selected) selected.classList.remove("sel");
|
|
45
|
+
selected = row; row.classList.add("sel");
|
|
46
|
+
if (pathEl) pathEl.textContent = path;
|
|
47
|
+
showConflict(false); showBar(true);
|
|
48
|
+
setDiffMode(false); if (diffBtn) diffBtn.hidden = true;
|
|
49
|
+
if (publishBtn) publishBtn.hidden = true;
|
|
50
|
+
viewEl.readOnly = true;
|
|
51
|
+
setStatus("Loading…");
|
|
52
|
+
fetch(apiBase + "/file?path=" + encodeURIComponent(path))
|
|
53
|
+
.then((r) => r.json())
|
|
54
|
+
.then((d) => {
|
|
55
|
+
if (!d || !d.ok) { viewEl.value = ""; cur = null; setStatus((d && d.message) || "Could not open that file.", "warn"); return; }
|
|
56
|
+
if (d.binary) { viewEl.value = "(binary file — " + (d.size || 0) + " bytes)"; cur = null; setStatus("Binary — not editable"); return; }
|
|
57
|
+
if (d.tooBig) { viewEl.value = "(file too large to show — " + (d.size || 0) + " bytes)"; cur = null; setStatus("Too large — not editable"); return; }
|
|
58
|
+
viewEl.value = d.content == null ? "" : d.content;
|
|
59
|
+
cur = { path: path, baseVersion: (typeof d.mtimeMs === "number" ? d.mtimeMs : null), writable: !!d.writable };
|
|
60
|
+
viewEl.readOnly = !cur.writable;
|
|
61
|
+
if (diffBtn) diffBtn.hidden = false;
|
|
62
|
+
if (publishBtn) publishBtn.hidden = !cur.writable;
|
|
63
|
+
setStatus(cur.writable ? "Editable — edits save + reload your store" : "Read-only");
|
|
64
|
+
if (typeof afterLoad === "function") afterLoad();
|
|
65
|
+
})
|
|
66
|
+
.catch(() => { viewEl.value = ""; cur = null; setStatus(offlineMsg, "warn"); });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Place the textarea caret at a 1-based line:col and scroll it into view. Used by
|
|
70
|
+
// the click-to-source jump; a textarea has no CodeMirror EditorView, so we map
|
|
71
|
+
// (line,col) to a character offset + setSelectionRange, then center by scrollTop.
|
|
72
|
+
function placeCursor(line: number, col: number) {
|
|
73
|
+
const text = viewEl.value;
|
|
74
|
+
const lines = text.split("\n");
|
|
75
|
+
const ln = Math.min(Math.max(1, line || 1), lines.length);
|
|
76
|
+
let offset = 0;
|
|
77
|
+
for (let i = 0; i < ln - 1; i++) offset += lines[i].length + 1; // +1 for the newline
|
|
78
|
+
offset += Math.min(Math.max(1, col || 1), (lines[ln - 1] || "").length + 1) - 1;
|
|
79
|
+
viewEl.focus();
|
|
80
|
+
try { viewEl.setSelectionRange(offset, offset); } catch (e) { /* not focusable yet */ }
|
|
81
|
+
// Center the target line: approximate line height from the rendered content.
|
|
82
|
+
const lh = viewEl.scrollHeight / Math.max(1, lines.length);
|
|
83
|
+
viewEl.scrollTop = Math.max(0, (ln - 1) * lh - viewEl.clientHeight / 2);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Capstone entry point: open <path> and drop the caret at line:col. Invoked by
|
|
87
|
+
// the cockpit's origin-checked tot:locate listener when a click lands in the
|
|
88
|
+
// live-preview iframe. Finds the file's tree row (built by renderNodes); if the
|
|
89
|
+
// tree hasn't loaded yet, no-ops gracefully.
|
|
90
|
+
(window as any).__totOpenFileAt = function (path: string, line: number, col: number) {
|
|
91
|
+
const row = rowByPath[path];
|
|
92
|
+
if (!row) return false;
|
|
93
|
+
if (typeof row.scrollIntoView === "function") row.scrollIntoView({ block: "nearest" });
|
|
94
|
+
openFile(path, row, () => { placeCursor(line, col); });
|
|
95
|
+
return true;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
function doSave(force?: boolean) {
|
|
99
|
+
if (!cur || !cur.writable) return;
|
|
100
|
+
setStatus("Saving…");
|
|
101
|
+
const body: any = { path: cur.path, content: viewEl.value };
|
|
102
|
+
if (!force && typeof cur.baseVersion === "number") body.baseVersion = cur.baseVersion;
|
|
103
|
+
fetch(apiBase + "/write", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body) })
|
|
104
|
+
.then((r) => r.json().then((j) => ({ s: r.status, j: j })))
|
|
105
|
+
.then((res) => {
|
|
106
|
+
if (res.s === 200 && res.j && res.j.ok) { cur!.baseVersion = res.j.mtimeMs; showConflict(false); setStatus("Saved ✓", "ok"); return; }
|
|
107
|
+
if (res.s === 409) { showConflict(true); setStatus("Changed on disk since you opened it", "warn"); return; }
|
|
108
|
+
if (res.s === 403) { setStatus("This file isn't editable.", "warn"); return; }
|
|
109
|
+
setStatus((res.j && res.j.message) || "Save failed", "warn");
|
|
110
|
+
})
|
|
111
|
+
.catch(() => { setStatus(isDev ? "Save failed — dev server unreachable" : offlineMsg, "warn"); });
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
viewEl.addEventListener("input", () => {
|
|
115
|
+
if (!cur || !cur.writable) return;
|
|
116
|
+
setStatus("Editing…");
|
|
117
|
+
if (saveTimer) clearTimeout(saveTimer);
|
|
118
|
+
saveTimer = setTimeout(() => { doSave(false); }, 600);
|
|
119
|
+
});
|
|
120
|
+
viewEl.addEventListener("keydown", (e: KeyboardEvent) => {
|
|
121
|
+
if ((e.metaKey || e.ctrlKey) && (e.key === "s" || e.key === "S")) {
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
if (saveTimer) clearTimeout(saveTimer);
|
|
124
|
+
doSave(false);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
if (reloadBtn) reloadBtn.addEventListener("click", () => { if (cur && selected) openFile(cur.path, selected); });
|
|
128
|
+
if (forceBtn) forceBtn.addEventListener("click", () => { showConflict(false); doSave(true); });
|
|
129
|
+
|
|
130
|
+
function setDiffMode(on: boolean) {
|
|
131
|
+
diffOn = on;
|
|
132
|
+
if (diffEl) diffEl.hidden = !on;
|
|
133
|
+
viewEl.hidden = on;
|
|
134
|
+
if (diffBtn) diffBtn.textContent = on ? "Edit" : "Diff";
|
|
135
|
+
}
|
|
136
|
+
function renderDiffText(t: string) { if (diffEl) diffEl.textContent = t; }
|
|
137
|
+
function lineDiff(before: string, after: string): [string, string][] | null {
|
|
138
|
+
const a = before.split("\n"), b = after.split("\n");
|
|
139
|
+
const m = a.length, n = b.length;
|
|
140
|
+
if (m * n > 4000000) return null;
|
|
141
|
+
const dp: number[][] = []; for (let i = 0; i <= m; i++) { dp.push(new Array(n + 1).fill(0)); }
|
|
142
|
+
for (let i = m - 1; i >= 0; i--) for (let j = n - 1; j >= 0; j--) dp[i]![j] = a[i] === b[j] ? dp[i + 1]![j + 1]! + 1 : (dp[i + 1]![j]! >= dp[i]![j + 1]! ? dp[i + 1]![j]! : dp[i]![j + 1]!);
|
|
143
|
+
const out: [string, string][] = []; let x = 0, y = 0;
|
|
144
|
+
while (x < m && y < n) {
|
|
145
|
+
if (a[x] === b[y]) { out.push([" ", a[x]!]); x++; y++; }
|
|
146
|
+
else if (dp[x + 1]![y]! >= dp[x]![y + 1]!) { out.push(["-", a[x]!]); x++; }
|
|
147
|
+
else { out.push(["+", b[y]!]); y++; }
|
|
148
|
+
}
|
|
149
|
+
while (x < m) { out.push(["-", a[x]!]); x++; }
|
|
150
|
+
while (y < n) { out.push(["+", b[y]!]); y++; }
|
|
151
|
+
return out;
|
|
152
|
+
}
|
|
153
|
+
function renderDiff(before: string, after: string) {
|
|
154
|
+
if (!diffEl) return;
|
|
155
|
+
diffEl.textContent = "";
|
|
156
|
+
const rows = lineDiff(before, after);
|
|
157
|
+
if (!rows) { renderDiffText("(file too large to diff)"); return; }
|
|
158
|
+
const frag = document.createDocumentFragment();
|
|
159
|
+
rows.forEach((row) => {
|
|
160
|
+
const ln = document.createElement("span");
|
|
161
|
+
ln.className = "dl " + (row[0] === "+" ? "add" : row[0] === "-" ? "del" : "ctx");
|
|
162
|
+
ln.textContent = row[0] + " " + row[1];
|
|
163
|
+
frag.appendChild(ln);
|
|
164
|
+
});
|
|
165
|
+
diffEl.appendChild(frag);
|
|
166
|
+
}
|
|
167
|
+
function doDiff() {
|
|
168
|
+
if (!cur) return;
|
|
169
|
+
if (diffOn) { setDiffMode(false); setStatus(cur.writable ? "Editable" : "Read-only"); return; }
|
|
170
|
+
setStatus("Loading diff…");
|
|
171
|
+
fetch(apiBase + "/diff?path=" + encodeURIComponent(cur.path))
|
|
172
|
+
.then((r) => r.json())
|
|
173
|
+
.then((d) => {
|
|
174
|
+
if (!d || !d.ok) { setStatus((d && d.message) || "Could not diff.", "warn"); return; }
|
|
175
|
+
if (!d.shown) { renderDiffText("(diff not shown — " + (d.reason || "") + ")"); setDiffMode(true); setStatus(d.status); return; }
|
|
176
|
+
renderDiff(d.before || "", d.after || "");
|
|
177
|
+
setDiffMode(true);
|
|
178
|
+
setStatus(d.status === "unchanged" ? "No changes vs your last commit" : (d.status + " vs HEAD"));
|
|
179
|
+
})
|
|
180
|
+
.catch(() => { setStatus(offlineMsg, "warn"); });
|
|
181
|
+
}
|
|
182
|
+
if (diffBtn) diffBtn.addEventListener("click", doDiff);
|
|
183
|
+
|
|
184
|
+
// cp-publish: draft -> PR-backed candidate for review — never straight to
|
|
185
|
+
// live, and no longer straight to the test channel either; it opens/updates
|
|
186
|
+
// a pull request an owner reviews and accepts. Confirm-before-submit.
|
|
187
|
+
function doPublish() {
|
|
188
|
+
if (!cur || !cur.writable || !publishBtn) return;
|
|
189
|
+
if (!window.confirm("Submit your saved edit for review? (Opens/updates a pull request — not your live site.)")) return;
|
|
190
|
+
const prevLabel = publishBtn.textContent;
|
|
191
|
+
publishBtn.disabled = true;
|
|
192
|
+
setStatus("Submitting…");
|
|
193
|
+
fetch(apiBase + "/publish", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ path: cur.path }) })
|
|
194
|
+
.then((r) => r.json().then((j) => ({ s: r.status, j: j })))
|
|
195
|
+
.then((res) => {
|
|
196
|
+
if (res.s === 200 && res.j && res.j.ok) { setStatus("Submitted for review ✓" + (res.j.prNumber ? " (PR #" + res.j.prNumber + ")" : ""), "ok"); return; }
|
|
197
|
+
if (res.s === 409 && res.j && res.j.status === "no_draft") { setStatus("No unpublished edit to submit.", "warn"); return; }
|
|
198
|
+
setStatus((res.j && res.j.message) || "Submit failed", "warn");
|
|
199
|
+
})
|
|
200
|
+
.catch(() => { setStatus(offlineMsg, "warn"); })
|
|
201
|
+
.then(() => { publishBtn.disabled = false; publishBtn.textContent = prevLabel; });
|
|
202
|
+
}
|
|
203
|
+
if (publishBtn) publishBtn.addEventListener("click", doPublish);
|
|
204
|
+
|
|
205
|
+
function renderNodes(nodes: any[], parentUl: any, depth: number) {
|
|
206
|
+
nodes.forEach((n) => {
|
|
207
|
+
const li = document.createElement("li");
|
|
208
|
+
li.className = "ft-" + n.type;
|
|
209
|
+
const row: any = document.createElement("div");
|
|
210
|
+
row.className = "ft-row";
|
|
211
|
+
row.style.paddingLeft = (depth * 12 + 10) + "px";
|
|
212
|
+
const icon = document.createElement("span");
|
|
213
|
+
icon.className = "ft-ic";
|
|
214
|
+
icon.textContent = n.type === "dir" ? "📁" : "📄";
|
|
215
|
+
const label = document.createElement("span");
|
|
216
|
+
label.className = "ft-name";
|
|
217
|
+
label.textContent = n.name;
|
|
218
|
+
row.appendChild(icon); row.appendChild(label); li.appendChild(row);
|
|
219
|
+
if (n.type === "dir") {
|
|
220
|
+
const childUl = document.createElement("ul");
|
|
221
|
+
childUl.className = "ft-children";
|
|
222
|
+
renderNodes(n.children || [], childUl, depth + 1);
|
|
223
|
+
li.appendChild(childUl);
|
|
224
|
+
} else {
|
|
225
|
+
row.tabIndex = 0;
|
|
226
|
+
rowByPath[n.path] = row; // for the programmatic jump
|
|
227
|
+
row.addEventListener("click", () => { openFile(n.path, row); });
|
|
228
|
+
row.addEventListener("keydown", (e: KeyboardEvent) => { if (e.key === "Enter") { e.preventDefault(); openFile(n.path, row); } });
|
|
229
|
+
}
|
|
230
|
+
parentUl.appendChild(li);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function load() {
|
|
235
|
+
fetch(apiBase + "/tree")
|
|
236
|
+
.then((r) => r.json())
|
|
237
|
+
.then((d) => {
|
|
238
|
+
treeEl.textContent = "";
|
|
239
|
+
rowByPath = {}; // rebuild the path→row index for this fresh tree
|
|
240
|
+
if (!d || !d.ok) { treeEl.textContent = (d && d.message) || "Could not load your files."; return; }
|
|
241
|
+
const ul = document.createElement("ul");
|
|
242
|
+
ul.className = "ft-root";
|
|
243
|
+
renderNodes(d.tree || [], ul, 0);
|
|
244
|
+
treeEl.appendChild(ul);
|
|
245
|
+
})
|
|
246
|
+
.catch(() => { treeEl.textContent = offlineMsg; });
|
|
247
|
+
}
|
|
248
|
+
load();
|
|
249
|
+
}
|