@adcp/sdk 12.0.0 → 12.0.2
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/dist/lib/adapters/content-standards-adapter.mjs +0 -6
- package/dist/lib/adapters/content-standards-adapter.mjs.map +1 -1
- package/dist/lib/adapters/derived-account-store.mjs +0 -6
- package/dist/lib/adapters/derived-account-store.mjs.map +1 -1
- package/dist/lib/adapters/governance-adapter.mjs +0 -6
- package/dist/lib/adapters/governance-adapter.mjs.map +1 -1
- package/dist/lib/adapters/implicit-account-store.mjs +0 -6
- package/dist/lib/adapters/implicit-account-store.mjs.map +1 -1
- package/dist/lib/adapters/index.mjs +0 -6
- package/dist/lib/adapters/index.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/get_products.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/get_products.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/index.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/index.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs.map +1 -1
- package/dist/lib/adapters/legacy/v2-5/types.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs +0 -6
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs.map +1 -1
- package/dist/lib/adapters/oauth-passthrough-resolver.mjs +0 -6
- package/dist/lib/adapters/oauth-passthrough-resolver.mjs.map +1 -1
- package/dist/lib/adapters/property-list-adapter.mjs +0 -6
- package/dist/lib/adapters/property-list-adapter.mjs.map +1 -1
- package/dist/lib/adapters/roster-account-store.mjs +0 -6
- package/dist/lib/adapters/roster-account-store.mjs.map +1 -1
- package/dist/lib/adapters/si-session-manager.mjs +0 -6
- package/dist/lib/adapters/si-session-manager.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/brand-fields.mjs +0 -6
- package/dist/lib/adapters/version/3.0/brand-fields.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/get-products.mjs +0 -6
- package/dist/lib/adapters/version/3.0/get-products.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/index.mjs +0 -6
- package/dist/lib/adapters/version/3.0/index.mjs.map +1 -1
- package/dist/lib/adapters/version/3.0/sync-accounts.mjs +0 -6
- package/dist/lib/adapters/version/3.0/sync-accounts.mjs.map +1 -1
- package/dist/lib/adapters/version/index.mjs +0 -6
- package/dist/lib/adapters/version/index.mjs.map +1 -1
- package/dist/lib/adapters/version/types.mjs +0 -6
- package/dist/lib/advanced.mjs +0 -6
- package/dist/lib/advanced.mjs.map +1 -1
- package/dist/lib/agents/index.generated.mjs +0 -6
- package/dist/lib/agents/index.generated.mjs.map +1 -1
- package/dist/lib/auth/index.mjs +0 -6
- package/dist/lib/auth/index.mjs.map +1 -1
- package/dist/lib/auth/oauth/CLIFlowHandler.mjs +0 -6
- package/dist/lib/auth/oauth/CLIFlowHandler.mjs.map +1 -1
- package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs +0 -6
- package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs.map +1 -1
- package/dist/lib/auth/oauth/MCPOAuthProvider.mjs +0 -6
- package/dist/lib/auth/oauth/MCPOAuthProvider.mjs.map +1 -1
- package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs +0 -6
- package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs.map +1 -1
- package/dist/lib/auth/oauth/authorization-required.mjs +0 -6
- package/dist/lib/auth/oauth/authorization-required.mjs.map +1 -1
- package/dist/lib/auth/oauth/diagnose.mjs +0 -6
- package/dist/lib/auth/oauth/diagnose.mjs.map +1 -1
- package/dist/lib/auth/oauth/diagnostics.mjs +0 -6
- package/dist/lib/auth/oauth/diagnostics.mjs.map +1 -1
- package/dist/lib/auth/oauth/discovery.mjs +0 -6
- package/dist/lib/auth/oauth/discovery.mjs.map +1 -1
- package/dist/lib/auth/oauth/file-storage.mjs +0 -6
- package/dist/lib/auth/oauth/file-storage.mjs.map +1 -1
- package/dist/lib/auth/oauth/index.mjs +0 -6
- package/dist/lib/auth/oauth/index.mjs.map +1 -1
- package/dist/lib/auth/oauth/secret-resolver.mjs +0 -6
- package/dist/lib/auth/oauth/secret-resolver.mjs.map +1 -1
- package/dist/lib/auth/oauth/storage-registry.mjs +0 -6
- package/dist/lib/auth/oauth/storage-registry.mjs.map +1 -1
- package/dist/lib/auth/oauth/types.mjs +0 -6
- package/dist/lib/auth/oauth/types.mjs.map +1 -1
- package/dist/lib/auth/oauth/web-flow.mjs +0 -6
- package/dist/lib/auth/oauth/web-flow.mjs.map +1 -1
- package/dist/lib/brand/index.mjs +0 -6
- package/dist/lib/brand/index.mjs.map +1 -1
- package/dist/lib/canonical-references/index.mjs +6 -7
- package/dist/lib/canonical-references/index.mjs.map +1 -1
- package/dist/lib/client/index.mjs +0 -6
- package/dist/lib/client/index.mjs.map +1 -1
- package/dist/lib/compliance/index.mjs +0 -6
- package/dist/lib/compliance/index.mjs.map +1 -1
- package/dist/lib/compliance-fixtures/index.mjs +0 -6
- package/dist/lib/compliance-fixtures/index.mjs.map +1 -1
- package/dist/lib/compliance-fixtures/test-authorization-server.mjs +0 -6
- package/dist/lib/compliance-fixtures/test-authorization-server.mjs.map +1 -1
- package/dist/lib/conformance/index.mjs +0 -6
- package/dist/lib/conformance/index.mjs.map +1 -1
- package/dist/lib/conformance/invariants/uniformError.mjs +0 -6
- package/dist/lib/conformance/invariants/uniformError.mjs.map +1 -1
- package/dist/lib/conformance/invariants/uniformErrorComparator.mjs +0 -6
- package/dist/lib/conformance/invariants/uniformErrorComparator.mjs.map +1 -1
- package/dist/lib/conformance/oracle.mjs +0 -6
- package/dist/lib/conformance/oracle.mjs.map +1 -1
- package/dist/lib/conformance/runConformance.mjs +0 -6
- package/dist/lib/conformance/runConformance.mjs.map +1 -1
- package/dist/lib/conformance/runners.mjs +0 -6
- package/dist/lib/conformance/runners.mjs.map +1 -1
- package/dist/lib/conformance/schemaArbitrary.mjs +0 -6
- package/dist/lib/conformance/schemaArbitrary.mjs.map +1 -1
- package/dist/lib/conformance/schemaLoader.mjs +5 -6
- package/dist/lib/conformance/schemaLoader.mjs.map +1 -1
- package/dist/lib/conformance/seeder.mjs +0 -6
- package/dist/lib/conformance/seeder.mjs.map +1 -1
- package/dist/lib/conformance/types.mjs +0 -6
- package/dist/lib/conformance/types.mjs.map +1 -1
- package/dist/lib/conformance/webhook.mjs +0 -6
- package/dist/lib/conformance/webhook.mjs.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.mjs +0 -6
- package/dist/lib/core/ADCPMultiAgentClient.mjs.map +1 -1
- package/dist/lib/core/AgentClient.mjs +0 -6
- package/dist/lib/core/AgentClient.mjs.map +1 -1
- package/dist/lib/core/AsyncHandler.mjs +0 -6
- package/dist/lib/core/AsyncHandler.mjs.map +1 -1
- package/dist/lib/core/ConfigurationManager.mjs +0 -6
- package/dist/lib/core/ConfigurationManager.mjs.map +1 -1
- package/dist/lib/core/ConversationTypes.mjs +0 -6
- package/dist/lib/core/CreativeAgentClient.mjs +0 -6
- package/dist/lib/core/CreativeAgentClient.mjs.map +1 -1
- package/dist/lib/core/GovernanceMiddleware.mjs +0 -6
- package/dist/lib/core/GovernanceMiddleware.mjs.map +1 -1
- package/dist/lib/core/GovernanceTypes.mjs +0 -6
- package/dist/lib/core/GovernanceTypes.mjs.map +1 -1
- package/dist/lib/core/ProtocolResponseParser.mjs +0 -6
- package/dist/lib/core/ProtocolResponseParser.mjs.map +1 -1
- package/dist/lib/core/ResponseValidator.mjs +0 -6
- package/dist/lib/core/ResponseValidator.mjs.map +1 -1
- package/dist/lib/core/SingleAgentClient.mjs +0 -6
- package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
- package/dist/lib/core/TaskEventTypes.mjs +0 -6
- package/dist/lib/core/TaskEventTypes.mjs.map +1 -1
- package/dist/lib/core/TaskExecutor.mjs +0 -6
- package/dist/lib/core/TaskExecutor.mjs.map +1 -1
- package/dist/lib/core/match.mjs +0 -6
- package/dist/lib/core/match.mjs.map +1 -1
- package/dist/lib/core/task-status.mjs +0 -6
- package/dist/lib/core/task-status.mjs.map +1 -1
- package/dist/lib/core/webhook-url.mjs +0 -6
- package/dist/lib/core/webhook-url.mjs.map +1 -1
- package/dist/lib/discovery/adagents-redirects.mjs +0 -6
- package/dist/lib/discovery/adagents-redirects.mjs.map +1 -1
- package/dist/lib/discovery/agent-directory.mjs +0 -6
- package/dist/lib/discovery/agent-directory.mjs.map +1 -1
- package/dist/lib/discovery/inline-publisher-properties.mjs +0 -6
- package/dist/lib/discovery/inline-publisher-properties.mjs.map +1 -1
- package/dist/lib/discovery/network-consistency-checker.mjs +0 -6
- package/dist/lib/discovery/network-consistency-checker.mjs.map +1 -1
- package/dist/lib/discovery/property-crawler.mjs +0 -6
- package/dist/lib/discovery/property-crawler.mjs.map +1 -1
- package/dist/lib/discovery/property-index.mjs +0 -6
- package/dist/lib/discovery/property-index.mjs.map +1 -1
- package/dist/lib/discovery/publisher-property-selector.mjs +0 -6
- package/dist/lib/discovery/publisher-property-selector.mjs.map +1 -1
- package/dist/lib/discovery/resolve-agent-properties.mjs +0 -6
- package/dist/lib/discovery/resolve-agent-properties.mjs.map +1 -1
- package/dist/lib/discovery/types.mjs +0 -6
- package/dist/lib/discovery/validate-adagents.mjs +0 -6
- package/dist/lib/discovery/validate-adagents.mjs.map +1 -1
- package/dist/lib/enums.mjs +0 -6
- package/dist/lib/enums.mjs.map +1 -1
- package/dist/lib/errors/index.mjs +0 -6
- package/dist/lib/errors/index.mjs.map +1 -1
- package/dist/lib/express-mcp/index.mjs +0 -6
- package/dist/lib/express-mcp/index.mjs.map +1 -1
- package/dist/lib/governance/index.mjs +0 -6
- package/dist/lib/governance/index.mjs.map +1 -1
- package/dist/lib/handlers/types.mjs +0 -6
- package/dist/lib/handlers/types.mjs.map +1 -1
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +0 -6
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/media-buy/available-actions.mjs +0 -6
- package/dist/lib/media-buy/available-actions.mjs.map +1 -1
- package/dist/lib/media-buy/index.mjs +0 -6
- package/dist/lib/media-buy/index.mjs.map +1 -1
- package/dist/lib/media-buy/preflight.mjs +0 -6
- package/dist/lib/media-buy/preflight.mjs.map +1 -1
- package/dist/lib/media-buy/property-policy.mjs +0 -6
- package/dist/lib/media-buy/property-policy.mjs.map +1 -1
- package/dist/lib/media-buy/types.mjs +0 -6
- package/dist/lib/media-buy/types.mjs.map +1 -1
- package/dist/lib/media-buy/update-fields.generated.mjs +0 -6
- package/dist/lib/media-buy/update-fields.generated.mjs.map +1 -1
- package/dist/lib/mock-server/creative-ad-server/seed-data.mjs +0 -6
- package/dist/lib/mock-server/creative-ad-server/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/creative-ad-server/server.mjs +0 -6
- package/dist/lib/mock-server/creative-ad-server/server.mjs.map +1 -1
- package/dist/lib/mock-server/creative-template/seed-data.mjs +0 -6
- package/dist/lib/mock-server/creative-template/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/creative-template/server.mjs +0 -6
- package/dist/lib/mock-server/creative-template/server.mjs.map +1 -1
- package/dist/lib/mock-server/index.mjs +0 -6
- package/dist/lib/mock-server/index.mjs.map +1 -1
- package/dist/lib/mock-server/sales-guaranteed/recipe.mjs +0 -6
- package/dist/lib/mock-server/sales-guaranteed/recipe.mjs.map +1 -1
- package/dist/lib/mock-server/sales-guaranteed/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sales-guaranteed/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sales-guaranteed/server.mjs +0 -6
- package/dist/lib/mock-server/sales-guaranteed/server.mjs.map +1 -1
- package/dist/lib/mock-server/sales-non-guaranteed/recipe.mjs +0 -6
- package/dist/lib/mock-server/sales-non-guaranteed/recipe.mjs.map +1 -1
- package/dist/lib/mock-server/sales-non-guaranteed/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sales-non-guaranteed/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sales-non-guaranteed/server.mjs +0 -6
- package/dist/lib/mock-server/sales-non-guaranteed/server.mjs.map +1 -1
- package/dist/lib/mock-server/sales-social/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sales-social/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sales-social/server.mjs +0 -6
- package/dist/lib/mock-server/sales-social/server.mjs.map +1 -1
- package/dist/lib/mock-server/scenario.mjs +0 -6
- package/dist/lib/mock-server/scenario.mjs.map +1 -1
- package/dist/lib/mock-server/signal-marketplace/seed-data.mjs +0 -6
- package/dist/lib/mock-server/signal-marketplace/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/signal-marketplace/server.mjs +0 -6
- package/dist/lib/mock-server/signal-marketplace/server.mjs.map +1 -1
- package/dist/lib/mock-server/sponsored-intelligence/seed-data.mjs +0 -6
- package/dist/lib/mock-server/sponsored-intelligence/seed-data.mjs.map +1 -1
- package/dist/lib/mock-server/sponsored-intelligence/server.mjs +0 -6
- package/dist/lib/mock-server/sponsored-intelligence/server.mjs.map +1 -1
- package/dist/lib/net/address-guards.mjs +0 -6
- package/dist/lib/net/address-guards.mjs.map +1 -1
- package/dist/lib/net/index.mjs +0 -6
- package/dist/lib/net/index.mjs.map +1 -1
- package/dist/lib/net/ssrf-fetch.mjs +0 -6
- package/dist/lib/net/ssrf-fetch.mjs.map +1 -1
- package/dist/lib/observability/index.mjs +0 -6
- package/dist/lib/observability/index.mjs.map +1 -1
- package/dist/lib/observability/tracing.mjs +6 -7
- package/dist/lib/observability/tracing.mjs.map +1 -1
- package/dist/lib/protocols/a2a.mjs +0 -6
- package/dist/lib/protocols/a2a.mjs.map +1 -1
- package/dist/lib/protocols/abort.mjs +0 -6
- package/dist/lib/protocols/abort.mjs.map +1 -1
- package/dist/lib/protocols/index.mjs +0 -6
- package/dist/lib/protocols/index.mjs.map +1 -1
- package/dist/lib/protocols/mcp-modern.mjs +0 -6
- package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
- package/dist/lib/protocols/mcp-tasks.mjs +0 -6
- package/dist/lib/protocols/mcp-tasks.mjs.map +1 -1
- package/dist/lib/protocols/mcp.mjs +0 -6
- package/dist/lib/protocols/mcp.mjs.map +1 -1
- package/dist/lib/protocols/rawResponseCapture.mjs +0 -6
- package/dist/lib/protocols/rawResponseCapture.mjs.map +1 -1
- package/dist/lib/protocols/responseSizeLimit.mjs +0 -6
- package/dist/lib/protocols/responseSizeLimit.mjs.map +1 -1
- package/dist/lib/protocols/transportDiagnostics.mjs +0 -6
- package/dist/lib/protocols/transportDiagnostics.mjs.map +1 -1
- package/dist/lib/registry/cursor-store.mjs +0 -6
- package/dist/lib/registry/cursor-store.mjs.map +1 -1
- package/dist/lib/registry/feed-stream.mjs +0 -6
- package/dist/lib/registry/feed-stream.mjs.map +1 -1
- package/dist/lib/registry/index.mjs +0 -6
- package/dist/lib/registry/index.mjs.map +1 -1
- package/dist/lib/registry/property-registry.mjs +0 -6
- package/dist/lib/registry/property-registry.mjs.map +1 -1
- package/dist/lib/registry/sync.mjs +0 -6
- package/dist/lib/registry/sync.mjs.map +1 -1
- package/dist/lib/registry/types.generated.mjs +0 -6
- package/dist/lib/registry/types.mjs +0 -6
- package/dist/lib/schemas/index.mjs +0 -6
- package/dist/lib/schemas/index.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/a2a-adapter.mjs +0 -6
- package/dist/lib/server/a2a-adapter.mjs.map +1 -1
- package/dist/lib/server/account-mode.mjs +0 -6
- package/dist/lib/server/account-mode.mjs.map +1 -1
- package/dist/lib/server/adcp-server.mjs +0 -6
- package/dist/lib/server/adcp-server.mjs.map +1 -1
- package/dist/lib/server/auth-introspection.mjs +0 -6
- package/dist/lib/server/auth-introspection.mjs.map +1 -1
- package/dist/lib/server/auth-signature.mjs +0 -6
- package/dist/lib/server/auth-signature.mjs.map +1 -1
- package/dist/lib/server/auth.mjs +0 -6
- package/dist/lib/server/auth.mjs.map +1 -1
- package/dist/lib/server/create-adcp-server.d.mts +13 -0
- package/dist/lib/server/create-adcp-server.d.ts +13 -0
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +3 -2
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/create-adcp-server.mjs +3 -8
- package/dist/lib/server/create-adcp-server.mjs.map +1 -1
- package/dist/lib/server/credential-policy.mjs +0 -6
- package/dist/lib/server/credential-policy.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/backends/memory.mjs +0 -6
- package/dist/lib/server/ctx-metadata/backends/memory.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/backends/pg.mjs +0 -6
- package/dist/lib/server/ctx-metadata/backends/pg.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/backends/redis.mjs +0 -6
- package/dist/lib/server/ctx-metadata/backends/redis.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/index.mjs +0 -6
- package/dist/lib/server/ctx-metadata/index.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/store.mjs +0 -6
- package/dist/lib/server/ctx-metadata/store.mjs.map +1 -1
- package/dist/lib/server/ctx-metadata/wire-shape.mjs +0 -6
- package/dist/lib/server/ctx-metadata/wire-shape.mjs.map +1 -1
- package/dist/lib/server/decisioning/account.mjs +0 -6
- package/dist/lib/server/decisioning/account.mjs.map +1 -1
- package/dist/lib/server/decisioning/admin-router.mjs +0 -6
- package/dist/lib/server/decisioning/admin-router.mjs.map +1 -1
- package/dist/lib/server/decisioning/assembly-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/assembly-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/async-outcome.mjs +0 -6
- package/dist/lib/server/decisioning/async-outcome.mjs.map +1 -1
- package/dist/lib/server/decisioning/buyer-agent.mjs +0 -6
- package/dist/lib/server/decisioning/buyer-agent.mjs.map +1 -1
- package/dist/lib/server/decisioning/capabilities.mjs +0 -6
- package/dist/lib/server/decisioning/capabilities.mjs.map +1 -1
- package/dist/lib/server/decisioning/compose.mjs +0 -6
- package/dist/lib/server/decisioning/compose.mjs.map +1 -1
- package/dist/lib/server/decisioning/context.mjs +0 -6
- package/dist/lib/server/decisioning/errors-typed.mjs +0 -6
- package/dist/lib/server/decisioning/errors-typed.mjs.map +1 -1
- package/dist/lib/server/decisioning/helpers.mjs +0 -6
- package/dist/lib/server/decisioning/helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/index.mjs +0 -6
- package/dist/lib/server/decisioning/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/list-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/list-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/manifest-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/manifest-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/pagination.mjs +0 -6
- package/dist/lib/server/decisioning/platform-helpers.mjs +0 -6
- package/dist/lib/server/decisioning/platform-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/platform.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/dispatch.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/dispatch.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/index.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/lifecycle.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/lifecycle.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/mock-manager.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/mock-manager.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/store.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/store.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/types.mjs +0 -6
- package/dist/lib/server/decisioning/proposal/types.mjs.map +1 -1
- package/dist/lib/server/decisioning/resolve-presets.mjs +0 -6
- package/dist/lib/server/decisioning/resolve-presets.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/entity-hydration.generated.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/entity-hydration.generated.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/observed-modes.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/observed-modes.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/protocol-for-tool.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/protocol-for-tool.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/task-registry.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/task-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/to-context.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/to-context.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/validate-platform.mjs +0 -6
- package/dist/lib/server/decisioning/runtime/validate-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/specialisms/audiences.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/brand-rights.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/campaign-governance.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/content-standards.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/creative.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/lists.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/sales.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/signals.mjs +0 -6
- package/dist/lib/server/decisioning/specialisms/sponsored-intelligence.mjs +0 -6
- package/dist/lib/server/decisioning/start-time.mjs +0 -6
- package/dist/lib/server/decisioning/start-time.mjs.map +1 -1
- package/dist/lib/server/decisioning/status-changes.mjs +0 -6
- package/dist/lib/server/decisioning/status-changes.mjs.map +1 -1
- package/dist/lib/server/decisioning/status-mappers.mjs +0 -6
- package/dist/lib/server/decisioning/status-mappers.mjs.map +1 -1
- package/dist/lib/server/decisioning/tenant-registry.mjs +0 -6
- package/dist/lib/server/decisioning/tenant-registry.mjs.map +1 -1
- package/dist/lib/server/decisioning/tenant-store.mjs +0 -6
- package/dist/lib/server/decisioning/tenant-store.mjs.map +1 -1
- package/dist/lib/server/decisioning/validate-specialisms.mjs +0 -6
- package/dist/lib/server/decisioning/validate-specialisms.mjs.map +1 -1
- package/dist/lib/server/dynamic-registry.mjs +0 -6
- package/dist/lib/server/dynamic-registry.mjs.map +1 -1
- package/dist/lib/server/envelope-allowlist.mjs +0 -6
- package/dist/lib/server/envelope-allowlist.mjs.map +1 -1
- package/dist/lib/server/error-arm-tools.mjs +5 -6
- package/dist/lib/server/error-arm-tools.mjs.map +1 -1
- package/dist/lib/server/errors.mjs +0 -6
- package/dist/lib/server/errors.mjs.map +1 -1
- package/dist/lib/server/example-tld-guard.mjs +0 -6
- package/dist/lib/server/example-tld-guard.mjs.map +1 -1
- package/dist/lib/server/express-adapter.mjs +0 -6
- package/dist/lib/server/express-adapter.mjs.map +1 -1
- package/dist/lib/server/governance.mjs +0 -6
- package/dist/lib/server/governance.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/lazy.mjs +0 -6
- package/dist/lib/server/idempotency/backends/lazy.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/memory.mjs +0 -6
- package/dist/lib/server/idempotency/backends/memory.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/pg.mjs +0 -6
- package/dist/lib/server/idempotency/backends/pg.mjs.map +1 -1
- package/dist/lib/server/idempotency/backends/redis.mjs +0 -6
- package/dist/lib/server/idempotency/backends/redis.mjs.map +1 -1
- package/dist/lib/server/idempotency/index.mjs +0 -6
- package/dist/lib/server/idempotency/index.mjs.map +1 -1
- package/dist/lib/server/idempotency/store.mjs +0 -6
- package/dist/lib/server/idempotency/store.mjs.map +1 -1
- package/dist/lib/server/index.d.mts +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/index.mjs +0 -6
- package/dist/lib/server/index.mjs.map +1 -1
- package/dist/lib/server/legacy/v5/index.d.mts +1 -1
- package/dist/lib/server/legacy/v5/index.d.ts +1 -1
- package/dist/lib/server/legacy/v5/index.d.ts.map +1 -1
- package/dist/lib/server/legacy/v5/index.js.map +1 -1
- package/dist/lib/server/legacy/v5/index.mjs +0 -6
- package/dist/lib/server/legacy/v5/index.mjs.map +1 -1
- package/dist/lib/server/mcp-modern-server.mjs +0 -6
- package/dist/lib/server/mcp-modern-server.mjs.map +1 -1
- package/dist/lib/server/media-buy-actions.mjs +0 -6
- package/dist/lib/server/media-buy-actions.mjs.map +1 -1
- package/dist/lib/server/media-buy-helpers.mjs +0 -6
- package/dist/lib/server/media-buy-helpers.mjs.map +1 -1
- package/dist/lib/server/media-buy-store.mjs +0 -6
- package/dist/lib/server/media-buy-store.mjs.map +1 -1
- package/dist/lib/server/normalize-errors.mjs +0 -6
- package/dist/lib/server/normalize-errors.mjs.map +1 -1
- package/dist/lib/server/operational-platform.mjs +0 -6
- package/dist/lib/server/operational-platform.mjs.map +1 -1
- package/dist/lib/server/pick-safe-details.mjs +0 -6
- package/dist/lib/server/pick-safe-details.mjs.map +1 -1
- package/dist/lib/server/pin-and-bind-fetch.mjs +0 -6
- package/dist/lib/server/pin-and-bind-fetch.mjs.map +1 -1
- package/dist/lib/server/postgres-state-store.mjs +0 -6
- package/dist/lib/server/postgres-state-store.mjs.map +1 -1
- package/dist/lib/server/postgres-task-store.mjs +0 -6
- package/dist/lib/server/postgres-task-store.mjs.map +1 -1
- package/dist/lib/server/product-defaults.mjs +0 -6
- package/dist/lib/server/product-defaults.mjs.map +1 -1
- package/dist/lib/server/redact.mjs +0 -6
- package/dist/lib/server/redact.mjs.map +1 -1
- package/dist/lib/server/responses.mjs +0 -6
- package/dist/lib/server/responses.mjs.map +1 -1
- package/dist/lib/server/serve.mjs +0 -6
- package/dist/lib/server/serve.mjs.map +1 -1
- package/dist/lib/server/socket-mode/conformance-client.mjs +0 -6
- package/dist/lib/server/socket-mode/conformance-client.mjs.map +1 -1
- package/dist/lib/server/socket-mode/index.mjs +0 -6
- package/dist/lib/server/socket-mode/index.mjs.map +1 -1
- package/dist/lib/server/socket-mode/ws-transport.mjs +0 -6
- package/dist/lib/server/socket-mode/ws-transport.mjs.map +1 -1
- package/dist/lib/server/state-machine.mjs +0 -6
- package/dist/lib/server/state-machine.mjs.map +1 -1
- package/dist/lib/server/state-store.mjs +0 -6
- package/dist/lib/server/state-store.mjs.map +1 -1
- package/dist/lib/server/structured-serialize.mjs +0 -6
- package/dist/lib/server/structured-serialize.mjs.map +1 -1
- package/dist/lib/server/targeting-helpers.mjs +0 -6
- package/dist/lib/server/targeting-helpers.mjs.map +1 -1
- package/dist/lib/server/tasks.mjs +0 -6
- package/dist/lib/server/tasks.mjs.map +1 -1
- package/dist/lib/server/test-controller-bridge.mjs +0 -6
- package/dist/lib/server/test-controller-bridge.mjs.map +1 -1
- package/dist/lib/server/test-controller.mjs +0 -6
- package/dist/lib/server/test-controller.mjs.map +1 -1
- package/dist/lib/server/upstream-helpers.mjs +0 -6
- package/dist/lib/server/upstream-helpers.mjs.map +1 -1
- package/dist/lib/server/webhook-emitter.mjs +0 -6
- package/dist/lib/server/webhook-emitter.mjs.map +1 -1
- package/dist/lib/server/wire-safe.mjs +0 -6
- package/dist/lib/server/wire-safe.mjs.map +1 -1
- package/dist/lib/server/wire-spec-fields.generated.mjs +0 -6
- package/dist/lib/server/wire-spec-fields.generated.mjs.map +1 -1
- package/dist/lib/server/wrap-envelope.mjs +0 -6
- package/dist/lib/server/wrap-envelope.mjs.map +1 -1
- package/dist/lib/signing/agent-context.mjs +0 -6
- package/dist/lib/signing/agent-context.mjs.map +1 -1
- package/dist/lib/signing/agent-fetch.mjs +0 -6
- package/dist/lib/signing/agent-fetch.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/canonicalize.mjs +0 -6
- package/dist/lib/signing/agent-resolver/canonicalize.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/capabilities-types.mjs +0 -6
- package/dist/lib/signing/agent-resolver/capabilities-types.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/consistency.mjs +0 -6
- package/dist/lib/signing/agent-resolver/consistency.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/errors.mjs +0 -6
- package/dist/lib/signing/agent-resolver/errors.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/etld.mjs +0 -6
- package/dist/lib/signing/agent-resolver/etld.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +0 -6
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/index.mjs +0 -6
- package/dist/lib/signing/agent-resolver/index.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/jwks-set.mjs +0 -6
- package/dist/lib/signing/agent-resolver/jwks-set.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs +0 -6
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/select-agent.mjs +0 -6
- package/dist/lib/signing/agent-resolver/select-agent.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/strict-json.mjs +0 -6
- package/dist/lib/signing/agent-resolver/strict-json.mjs.map +1 -1
- package/dist/lib/signing/brand-jwks.mjs +0 -6
- package/dist/lib/signing/brand-jwks.mjs.map +1 -1
- package/dist/lib/signing/canonicalize.mjs +0 -6
- package/dist/lib/signing/canonicalize.mjs.map +1 -1
- package/dist/lib/signing/capability-cache.mjs +0 -6
- package/dist/lib/signing/capability-cache.mjs.map +1 -1
- package/dist/lib/signing/capability-priming.mjs +0 -6
- package/dist/lib/signing/capability-priming.mjs.map +1 -1
- package/dist/lib/signing/client.mjs +0 -6
- package/dist/lib/signing/client.mjs.map +1 -1
- package/dist/lib/signing/content-digest.mjs +0 -6
- package/dist/lib/signing/content-digest.mjs.map +1 -1
- package/dist/lib/signing/crypto.mjs +0 -6
- package/dist/lib/signing/crypto.mjs.map +1 -1
- package/dist/lib/signing/ecdsa-encoding.mjs +0 -6
- package/dist/lib/signing/ecdsa-encoding.mjs.map +1 -1
- package/dist/lib/signing/errors.mjs +0 -6
- package/dist/lib/signing/errors.mjs.map +1 -1
- package/dist/lib/signing/fetch-async.mjs +0 -6
- package/dist/lib/signing/fetch-async.mjs.map +1 -1
- package/dist/lib/signing/fetch.mjs +0 -6
- package/dist/lib/signing/fetch.mjs.map +1 -1
- package/dist/lib/signing/index.mjs +0 -6
- package/dist/lib/signing/index.mjs.map +1 -1
- package/dist/lib/signing/jwks-helpers.mjs +0 -6
- package/dist/lib/signing/jwks-helpers.mjs.map +1 -1
- package/dist/lib/signing/jwks-https.mjs +0 -6
- package/dist/lib/signing/jwks-https.mjs.map +1 -1
- package/dist/lib/signing/jwks.mjs +0 -6
- package/dist/lib/signing/jwks.mjs.map +1 -1
- package/dist/lib/signing/middleware.mjs +0 -6
- package/dist/lib/signing/middleware.mjs.map +1 -1
- package/dist/lib/signing/parser.mjs +0 -6
- package/dist/lib/signing/parser.mjs.map +1 -1
- package/dist/lib/signing/postgres-replay-store.mjs +0 -6
- package/dist/lib/signing/postgres-replay-store.mjs.map +1 -1
- package/dist/lib/signing/protocol-response.mjs +0 -6
- package/dist/lib/signing/protocol-response.mjs.map +1 -1
- package/dist/lib/signing/provider.mjs +0 -6
- package/dist/lib/signing/redis-replay-store.mjs +0 -6
- package/dist/lib/signing/redis-replay-store.mjs.map +1 -1
- package/dist/lib/signing/replay.mjs +0 -6
- package/dist/lib/signing/replay.mjs.map +1 -1
- package/dist/lib/signing/request-context.mjs +0 -6
- package/dist/lib/signing/request-context.mjs.map +1 -1
- package/dist/lib/signing/revocation-https.mjs +0 -6
- package/dist/lib/signing/revocation-https.mjs.map +1 -1
- package/dist/lib/signing/revocation.mjs +0 -6
- package/dist/lib/signing/revocation.mjs.map +1 -1
- package/dist/lib/signing/server.mjs +0 -6
- package/dist/lib/signing/server.mjs.map +1 -1
- package/dist/lib/signing/signer-async.mjs +0 -6
- package/dist/lib/signing/signer-async.mjs.map +1 -1
- package/dist/lib/signing/signer.mjs +0 -6
- package/dist/lib/signing/signer.mjs.map +1 -1
- package/dist/lib/signing/testing.mjs +0 -6
- package/dist/lib/signing/testing.mjs.map +1 -1
- package/dist/lib/signing/types.mjs +0 -6
- package/dist/lib/signing/types.mjs.map +1 -1
- package/dist/lib/signing/verifier.mjs +0 -6
- package/dist/lib/signing/verifier.mjs.map +1 -1
- package/dist/lib/signing/webhook-auth-detection.mjs +0 -6
- package/dist/lib/signing/webhook-auth-detection.mjs.map +1 -1
- package/dist/lib/signing/webhook-verifier.mjs +0 -6
- package/dist/lib/signing/webhook-verifier.mjs.map +1 -1
- package/dist/lib/storage/MemoryStorage.mjs +0 -6
- package/dist/lib/storage/MemoryStorage.mjs.map +1 -1
- package/dist/lib/storage/interfaces.mjs +0 -6
- package/dist/lib/substitution/encoder/SubstitutionEncoder.mjs +0 -6
- package/dist/lib/substitution/encoder/SubstitutionEncoder.mjs.map +1 -1
- package/dist/lib/substitution/encoder/index.mjs +0 -6
- package/dist/lib/substitution/encoder/index.mjs.map +1 -1
- package/dist/lib/substitution/index.mjs +0 -6
- package/dist/lib/substitution/index.mjs.map +1 -1
- package/dist/lib/substitution/observer/SubstitutionObserver.mjs +0 -6
- package/dist/lib/substitution/observer/SubstitutionObserver.mjs.map +1 -1
- package/dist/lib/substitution/observer/alignment.mjs +0 -6
- package/dist/lib/substitution/observer/alignment.mjs.map +1 -1
- package/dist/lib/substitution/observer/assertions.mjs +0 -6
- package/dist/lib/substitution/observer/assertions.mjs.map +1 -1
- package/dist/lib/substitution/observer/html-parser.mjs +0 -6
- package/dist/lib/substitution/observer/html-parser.mjs.map +1 -1
- package/dist/lib/substitution/observer/index.mjs +0 -6
- package/dist/lib/substitution/observer/index.mjs.map +1 -1
- package/dist/lib/substitution/observer/ssrf.mjs +0 -6
- package/dist/lib/substitution/observer/ssrf.mjs.map +1 -1
- package/dist/lib/substitution/rfc3986.mjs +0 -6
- package/dist/lib/substitution/rfc3986.mjs.map +1 -1
- package/dist/lib/substitution/translate.mjs +0 -6
- package/dist/lib/substitution/translate.mjs.map +1 -1
- package/dist/lib/substitution/types.mjs +0 -6
- package/dist/lib/substitution/vectors.mjs +0 -6
- package/dist/lib/substitution/vectors.mjs.map +1 -1
- package/dist/lib/testing/agent-tester.mjs +0 -6
- package/dist/lib/testing/agent-tester.mjs.map +1 -1
- package/dist/lib/testing/client.mjs +0 -6
- package/dist/lib/testing/client.mjs.map +1 -1
- package/dist/lib/testing/compliance/briefs.mjs +0 -6
- package/dist/lib/testing/compliance/briefs.mjs.map +1 -1
- package/dist/lib/testing/compliance/comply.mjs +0 -6
- package/dist/lib/testing/compliance/comply.mjs.map +1 -1
- package/dist/lib/testing/compliance/index.mjs +0 -6
- package/dist/lib/testing/compliance/index.mjs.map +1 -1
- package/dist/lib/testing/compliance/spec-conformance.mjs +0 -6
- package/dist/lib/testing/compliance/spec-conformance.mjs.map +1 -1
- package/dist/lib/testing/compliance/storyboard-tracks.mjs +0 -6
- package/dist/lib/testing/compliance/storyboard-tracks.mjs.map +1 -1
- package/dist/lib/testing/compliance/summary.mjs +0 -6
- package/dist/lib/testing/compliance/summary.mjs.map +1 -1
- package/dist/lib/testing/compliance/types.mjs +0 -6
- package/dist/lib/testing/comply-controller.mjs +0 -6
- package/dist/lib/testing/comply-controller.mjs.map +1 -1
- package/dist/lib/testing/controller-assertions.mjs +0 -6
- package/dist/lib/testing/controller-assertions.mjs.map +1 -1
- package/dist/lib/testing/formatter.mjs +0 -6
- package/dist/lib/testing/formatter.mjs.map +1 -1
- package/dist/lib/testing/index.mjs +0 -6
- package/dist/lib/testing/index.mjs.map +1 -1
- package/dist/lib/testing/local-agent-runner.mjs +0 -6
- package/dist/lib/testing/local-agent-runner.mjs.map +1 -1
- package/dist/lib/testing/orchestrator.mjs +0 -6
- package/dist/lib/testing/orchestrator.mjs.map +1 -1
- package/dist/lib/testing/personas/index.mjs +0 -6
- package/dist/lib/testing/personas/index.mjs.map +1 -1
- package/dist/lib/testing/scenarios/brand-rights.mjs +0 -6
- package/dist/lib/testing/scenarios/brand-rights.mjs.map +1 -1
- package/dist/lib/testing/scenarios/capabilities.mjs +0 -6
- package/dist/lib/testing/scenarios/capabilities.mjs.map +1 -1
- package/dist/lib/testing/scenarios/creative.mjs +0 -6
- package/dist/lib/testing/scenarios/creative.mjs.map +1 -1
- package/dist/lib/testing/scenarios/deterministic.mjs +0 -6
- package/dist/lib/testing/scenarios/deterministic.mjs.map +1 -1
- package/dist/lib/testing/scenarios/discovery.mjs +0 -6
- package/dist/lib/testing/scenarios/discovery.mjs.map +1 -1
- package/dist/lib/testing/scenarios/edge-cases.mjs +0 -6
- package/dist/lib/testing/scenarios/edge-cases.mjs.map +1 -1
- package/dist/lib/testing/scenarios/error-compliance.mjs +0 -6
- package/dist/lib/testing/scenarios/error-compliance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/governance.mjs +0 -6
- package/dist/lib/testing/scenarios/governance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/health.mjs +0 -6
- package/dist/lib/testing/scenarios/health.mjs.map +1 -1
- package/dist/lib/testing/scenarios/index.mjs +0 -6
- package/dist/lib/testing/scenarios/index.mjs.map +1 -1
- package/dist/lib/testing/scenarios/media-buy.mjs +0 -6
- package/dist/lib/testing/scenarios/media-buy.mjs.map +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.mjs +0 -6
- package/dist/lib/testing/scenarios/schema-compliance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/signals.mjs +0 -6
- package/dist/lib/testing/scenarios/signals.mjs.map +1 -1
- package/dist/lib/testing/scenarios/sponsored-intelligence.mjs +0 -6
- package/dist/lib/testing/scenarios/sponsored-intelligence.mjs.map +1 -1
- package/dist/lib/testing/scenarios/trusted-match.mjs +0 -6
- package/dist/lib/testing/scenarios/trusted-match.mjs.map +1 -1
- package/dist/lib/testing/seed-merge.mjs +0 -6
- package/dist/lib/testing/seed-merge.mjs.map +1 -1
- package/dist/lib/testing/storyboard/agent-routing.mjs +0 -6
- package/dist/lib/testing/storyboard/agent-routing.mjs.map +1 -1
- package/dist/lib/testing/storyboard/assertions.mjs +0 -6
- package/dist/lib/testing/storyboard/assertions.mjs.map +1 -1
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +0 -6
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs.map +1 -1
- package/dist/lib/testing/storyboard/compliance.mjs +5 -6
- package/dist/lib/testing/storyboard/compliance.mjs.map +1 -1
- package/dist/lib/testing/storyboard/context.mjs +0 -6
- package/dist/lib/testing/storyboard/context.mjs.map +1 -1
- package/dist/lib/testing/storyboard/default-invariants.mjs +0 -6
- package/dist/lib/testing/storyboard/default-invariants.mjs.map +1 -1
- package/dist/lib/testing/storyboard/index.mjs +0 -6
- package/dist/lib/testing/storyboard/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/junit.mjs +0 -6
- package/dist/lib/testing/storyboard/junit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/loader.mjs +0 -6
- package/dist/lib/testing/storyboard/loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/parallel-dispatch.mjs +0 -6
- package/dist/lib/testing/storyboard/parallel-dispatch.mjs.map +1 -1
- package/dist/lib/testing/storyboard/path.mjs +0 -6
- package/dist/lib/testing/storyboard/path.mjs.map +1 -1
- package/dist/lib/testing/storyboard/probes.mjs +0 -6
- package/dist/lib/testing/storyboard/probes.mjs.map +1 -1
- package/dist/lib/testing/storyboard/rate-limit-trip.mjs +0 -6
- package/dist/lib/testing/storyboard/rate-limit-trip.mjs.map +1 -1
- package/dist/lib/testing/storyboard/rejection-hints.mjs +0 -6
- package/dist/lib/testing/storyboard/rejection-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.mjs +0 -6
- package/dist/lib/testing/storyboard/request-builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/grader.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/grader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/index.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/probe.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/synthesize.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/synthesize.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/test-kit.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/test-kit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/types.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +0 -6
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +0 -6
- package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
- package/dist/lib/testing/storyboard/sandbox-entities.mjs +0 -6
- package/dist/lib/testing/storyboard/sandbox-entities.mjs.map +1 -1
- package/dist/lib/testing/storyboard/seeding.mjs +0 -6
- package/dist/lib/testing/storyboard/seeding.mjs.map +1 -1
- package/dist/lib/testing/storyboard/shape-drift-hints.mjs +0 -6
- package/dist/lib/testing/storyboard/shape-drift-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/signer-grader/grader.mjs +0 -6
- package/dist/lib/testing/storyboard/signer-grader/grader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/signer-grader/index.mjs +0 -6
- package/dist/lib/testing/storyboard/signer-grader/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/signer-grader/types.mjs +0 -6
- package/dist/lib/testing/storyboard/strict-validation-hints.mjs +0 -6
- package/dist/lib/testing/storyboard/strict-validation-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/task-map.mjs +0 -6
- package/dist/lib/testing/storyboard/task-map.mjs.map +1 -1
- package/dist/lib/testing/storyboard/test-kit.mjs +0 -6
- package/dist/lib/testing/storyboard/test-kit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/types.mjs +0 -6
- package/dist/lib/testing/storyboard/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/validations.mjs +0 -6
- package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
- package/dist/lib/testing/storyboard/webhook-assertions.mjs +0 -6
- package/dist/lib/testing/storyboard/webhook-assertions.mjs.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.mjs +0 -6
- package/dist/lib/testing/storyboard/webhook-receiver.mjs.map +1 -1
- package/dist/lib/testing/stubs/governance-agent-stub.mjs +0 -6
- package/dist/lib/testing/stubs/governance-agent-stub.mjs.map +1 -1
- package/dist/lib/testing/stubs/index.mjs +0 -6
- package/dist/lib/testing/stubs/index.mjs.map +1 -1
- package/dist/lib/testing/test-controller.mjs +0 -6
- package/dist/lib/testing/test-controller.mjs.map +1 -1
- package/dist/lib/testing/test-helpers.mjs +0 -6
- package/dist/lib/testing/test-helpers.mjs.map +1 -1
- package/dist/lib/testing/types.mjs +0 -6
- package/dist/lib/types/adcp.mjs +0 -6
- package/dist/lib/types/adcp.mjs.map +1 -1
- package/dist/lib/types/asset-instances.mjs +0 -6
- package/dist/lib/types/compat.mjs +0 -6
- package/dist/lib/types/compat.mjs.map +1 -1
- package/dist/lib/types/core.generated.mjs +0 -6
- package/dist/lib/types/enums.generated.mjs +0 -6
- package/dist/lib/types/enums.generated.mjs.map +1 -1
- package/dist/lib/types/error-codes.mjs +0 -6
- package/dist/lib/types/error-codes.mjs.map +1 -1
- package/dist/lib/types/error-details.aliases.mjs +0 -6
- package/dist/lib/types/error-details.aliases.mjs.map +1 -1
- package/dist/lib/types/format-asset-slots.mjs +0 -6
- package/dist/lib/types/forward-compat-error-codes.mjs +0 -6
- package/dist/lib/types/forward-compat-error-codes.mjs.map +1 -1
- package/dist/lib/types/index.mjs +0 -6
- package/dist/lib/types/index.mjs.map +1 -1
- package/dist/lib/types/inline-enums.aliases.mjs +0 -6
- package/dist/lib/types/inline-enums.aliases.mjs.map +1 -1
- package/dist/lib/types/inline-enums.generated.mjs +0 -6
- package/dist/lib/types/inline-enums.generated.mjs.map +1 -1
- package/dist/lib/types/manifest.generated.mjs +0 -6
- package/dist/lib/types/manifest.generated.mjs.map +1 -1
- package/dist/lib/types/schemas.generated.mjs +0 -6
- package/dist/lib/types/schemas.generated.mjs.map +1 -1
- package/dist/lib/types/server-payload-aliases.mjs +0 -6
- package/dist/lib/types/server-payload.mjs +0 -6
- package/dist/lib/types/sync-rows.mjs +0 -6
- package/dist/lib/types/tools.generated.mjs +0 -6
- package/dist/lib/types/v2-5/index.mjs +0 -6
- package/dist/lib/types/v2-5/index.mjs.map +1 -1
- package/dist/lib/types/v2-5/tools.generated.mjs +0 -6
- package/dist/lib/types/v3-1-beta/index.mjs +0 -6
- package/dist/lib/types/v3-1-beta/index.mjs.map +1 -1
- package/dist/lib/types/v3-1-beta/tools.generated.mjs +0 -6
- package/dist/lib/types/wellknown-schemas.generated.mjs +0 -6
- package/dist/lib/types/wellknown-schemas.generated.mjs.map +1 -1
- package/dist/lib/upstream-recorder/constants.mjs +0 -6
- package/dist/lib/upstream-recorder/constants.mjs.map +1 -1
- package/dist/lib/upstream-recorder/index.mjs +0 -6
- package/dist/lib/upstream-recorder/index.mjs.map +1 -1
- package/dist/lib/upstream-recorder/recorder.mjs +0 -6
- package/dist/lib/upstream-recorder/recorder.mjs.map +1 -1
- package/dist/lib/upstream-recorder/types.mjs +0 -6
- package/dist/lib/upstream-recorder/types.mjs.map +1 -1
- package/dist/lib/utils/a2a-artifacts.mjs +0 -6
- package/dist/lib/utils/a2a-artifacts.mjs.map +1 -1
- package/dist/lib/utils/a2a-discovery.mjs +0 -6
- package/dist/lib/utils/a2a-discovery.mjs.map +1 -1
- package/dist/lib/utils/activation-key-builders.mjs +0 -6
- package/dist/lib/utils/activation-key-builders.mjs.map +1 -1
- package/dist/lib/utils/adcp-version-config.mjs +0 -6
- package/dist/lib/utils/adcp-version-config.mjs.map +1 -1
- package/dist/lib/utils/asset-builders.mjs +0 -6
- package/dist/lib/utils/asset-builders.mjs.map +1 -1
- package/dist/lib/utils/build-creative-return-builders.mjs +0 -6
- package/dist/lib/utils/build-creative-return-builders.mjs.map +1 -1
- package/dist/lib/utils/buyer-retry-policy.mjs +0 -6
- package/dist/lib/utils/buyer-retry-policy.mjs.map +1 -1
- package/dist/lib/utils/capabilities.mjs +0 -6
- package/dist/lib/utils/capabilities.mjs.map +1 -1
- package/dist/lib/utils/capability-rollups.mjs +0 -6
- package/dist/lib/utils/capability-rollups.mjs.map +1 -1
- package/dist/lib/utils/creative-adapter.mjs +0 -6
- package/dist/lib/utils/creative-adapter.mjs.map +1 -1
- package/dist/lib/utils/creative-delivery.mjs +0 -6
- package/dist/lib/utils/creative-delivery.mjs.map +1 -1
- package/dist/lib/utils/deprecation.mjs +0 -6
- package/dist/lib/utils/deprecation.mjs.map +1 -1
- package/dist/lib/utils/envelope-status-compat.mjs +0 -6
- package/dist/lib/utils/envelope-status-compat.mjs.map +1 -1
- package/dist/lib/utils/error-extraction.mjs +0 -6
- package/dist/lib/utils/error-extraction.mjs.map +1 -1
- package/dist/lib/utils/extract-result.mjs +0 -6
- package/dist/lib/utils/extract-result.mjs.map +1 -1
- package/dist/lib/utils/format-asset-slot-builders.mjs +0 -6
- package/dist/lib/utils/format-asset-slot-builders.mjs.map +1 -1
- package/dist/lib/utils/format-assets.mjs +0 -6
- package/dist/lib/utils/format-assets.mjs.map +1 -1
- package/dist/lib/utils/format-render-builders.mjs +0 -6
- package/dist/lib/utils/format-render-builders.mjs.map +1 -1
- package/dist/lib/utils/format-renders.mjs +0 -6
- package/dist/lib/utils/format-renders.mjs.map +1 -1
- package/dist/lib/utils/get-products-cache-scope.mjs +0 -6
- package/dist/lib/utils/get-products-cache-scope.mjs.map +1 -1
- package/dist/lib/utils/glob.mjs +0 -6
- package/dist/lib/utils/glob.mjs.map +1 -1
- package/dist/lib/utils/global-async-local-storage.mjs +0 -6
- package/dist/lib/utils/global-async-local-storage.mjs.map +1 -1
- package/dist/lib/utils/idempotency.mjs +0 -6
- package/dist/lib/utils/idempotency.mjs.map +1 -1
- package/dist/lib/utils/index.mjs +0 -6
- package/dist/lib/utils/index.mjs.map +1 -1
- package/dist/lib/utils/jcs.mjs +0 -6
- package/dist/lib/utils/jcs.mjs.map +1 -1
- package/dist/lib/utils/json-depth.mjs +0 -6
- package/dist/lib/utils/json-depth.mjs.map +1 -1
- package/dist/lib/utils/logger.mjs +0 -6
- package/dist/lib/utils/logger.mjs.map +1 -1
- package/dist/lib/utils/media-buy-delivery-notification-builders.mjs +0 -6
- package/dist/lib/utils/media-buy-delivery-notification-builders.mjs.map +1 -1
- package/dist/lib/utils/media-buy-status.mjs +0 -6
- package/dist/lib/utils/media-buy-status.mjs.map +1 -1
- package/dist/lib/utils/pagination.mjs +0 -6
- package/dist/lib/utils/pagination.mjs.map +1 -1
- package/dist/lib/utils/preview-creative-builders.mjs +0 -6
- package/dist/lib/utils/preview-creative-builders.mjs.map +1 -1
- package/dist/lib/utils/preview-normalizer.mjs +0 -6
- package/dist/lib/utils/preview-normalizer.mjs.map +1 -1
- package/dist/lib/utils/preview-utils.mjs +0 -6
- package/dist/lib/utils/preview-utils.mjs.map +1 -1
- package/dist/lib/utils/pricing-adapter.mjs +0 -6
- package/dist/lib/utils/pricing-adapter.mjs.map +1 -1
- package/dist/lib/utils/probe-policy.mjs +0 -6
- package/dist/lib/utils/probe-policy.mjs.map +1 -1
- package/dist/lib/utils/protocol-detection.mjs +0 -6
- package/dist/lib/utils/protocol-detection.mjs.map +1 -1
- package/dist/lib/utils/redact-secrets.mjs +0 -6
- package/dist/lib/utils/redact-secrets.mjs.map +1 -1
- package/dist/lib/utils/redis-default-prefix-warn.mjs +0 -6
- package/dist/lib/utils/redis-default-prefix-warn.mjs.map +1 -1
- package/dist/lib/utils/render-builders.mjs +0 -6
- package/dist/lib/utils/render-builders.mjs.map +1 -1
- package/dist/lib/utils/request-normalizer.mjs +0 -6
- package/dist/lib/utils/request-normalizer.mjs.map +1 -1
- package/dist/lib/utils/response-schemas.mjs +0 -6
- package/dist/lib/utils/response-schemas.mjs.map +1 -1
- package/dist/lib/utils/response-unwrapper.mjs +0 -6
- package/dist/lib/utils/response-unwrapper.mjs.map +1 -1
- package/dist/lib/utils/retry.mjs +0 -6
- package/dist/lib/utils/retry.mjs.map +1 -1
- package/dist/lib/utils/signal-discovery-helpers.mjs +0 -6
- package/dist/lib/utils/signal-discovery-helpers.mjs.map +1 -1
- package/dist/lib/utils/signal-id-builders.mjs +0 -6
- package/dist/lib/utils/signal-id-builders.mjs.map +1 -1
- package/dist/lib/utils/sync-creatives-adapter.mjs +0 -6
- package/dist/lib/utils/sync-creatives-adapter.mjs.map +1 -1
- package/dist/lib/utils/task-state.mjs +0 -6
- package/dist/lib/utils/task-state.mjs.map +1 -1
- package/dist/lib/utils/tool-request-schemas.mjs +0 -6
- package/dist/lib/utils/tool-request-schemas.mjs.map +1 -1
- package/dist/lib/utils/typeGuards.mjs +0 -6
- package/dist/lib/utils/typeGuards.mjs.map +1 -1
- package/dist/lib/utils/union-errors.mjs +0 -6
- package/dist/lib/utils/union-errors.mjs.map +1 -1
- package/dist/lib/utils/validate-user-agent.mjs +0 -6
- package/dist/lib/utils/validate-user-agent.mjs.map +1 -1
- package/dist/lib/v2/format-schema/fetch.mjs +0 -6
- package/dist/lib/v2/format-schema/fetch.mjs.map +1 -1
- package/dist/lib/v2/format-schema/index.mjs +0 -6
- package/dist/lib/v2/format-schema/index.mjs.map +1 -1
- package/dist/lib/v2/format-schema/regex-safety.mjs +0 -6
- package/dist/lib/v2/format-schema/regex-safety.mjs.map +1 -1
- package/dist/lib/v2/format-schema/resolver.mjs +7 -8
- package/dist/lib/v2/format-schema/resolver.mjs.map +1 -1
- package/dist/lib/v2/format-schema/sandbox-refs.mjs +0 -6
- package/dist/lib/v2/format-schema/sandbox-refs.mjs.map +1 -1
- package/dist/lib/v2/projection/augment-response.mjs +0 -6
- package/dist/lib/v2/projection/augment-response.mjs.map +1 -1
- package/dist/lib/v2/projection/builders.mjs +0 -6
- package/dist/lib/v2/projection/builders.mjs.map +1 -1
- package/dist/lib/v2/projection/cache-versions.mjs +0 -6
- package/dist/lib/v2/projection/cache-versions.mjs.map +1 -1
- package/dist/lib/v2/projection/canonical-properties.mjs +5 -6
- package/dist/lib/v2/projection/canonical-properties.mjs.map +1 -1
- package/dist/lib/v2/projection/catalog.mjs +5 -6
- package/dist/lib/v2/projection/catalog.mjs.map +1 -1
- package/dist/lib/v2/projection/constants.mjs +0 -6
- package/dist/lib/v2/projection/constants.mjs.map +1 -1
- package/dist/lib/v2/projection/index.mjs +0 -6
- package/dist/lib/v2/projection/index.mjs.map +1 -1
- package/dist/lib/v2/projection/registry.mjs +5 -6
- package/dist/lib/v2/projection/registry.mjs.map +1 -1
- package/dist/lib/v2/projection/types.mjs +0 -6
- package/dist/lib/v2/projection/v1-to-v2.mjs +0 -6
- package/dist/lib/v2/projection/v1-to-v2.mjs.map +1 -1
- package/dist/lib/v2/projection/v2-to-v1.mjs +0 -6
- package/dist/lib/v2/projection/v2-to-v1.mjs.map +1 -1
- package/dist/lib/v2/projection/write-side.mjs +0 -6
- package/dist/lib/v2/projection/write-side.mjs.map +1 -1
- package/dist/lib/v2/publisher-catalog/formats.mjs +0 -6
- package/dist/lib/v2/publisher-catalog/formats.mjs.map +1 -1
- package/dist/lib/v2/publisher-catalog/index.mjs +0 -6
- package/dist/lib/v2/publisher-catalog/index.mjs.map +1 -1
- package/dist/lib/validation/client-hooks.mjs +0 -6
- package/dist/lib/validation/client-hooks.mjs.map +1 -1
- package/dist/lib/validation/hints.mjs +0 -6
- package/dist/lib/validation/hints.mjs.map +1 -1
- package/dist/lib/validation/index.mjs +0 -6
- package/dist/lib/validation/index.mjs.map +1 -1
- package/dist/lib/validation/schema-errors.mjs +0 -6
- package/dist/lib/validation/schema-errors.mjs.map +1 -1
- package/dist/lib/validation/schema-loader.mjs +5 -6
- package/dist/lib/validation/schema-loader.mjs.map +1 -1
- package/dist/lib/validation/schema-validator.mjs +0 -6
- package/dist/lib/validation/schema-validator.mjs.map +1 -1
- package/dist/lib/validation/sync-creatives.mjs +0 -6
- package/dist/lib/validation/sync-creatives.mjs.map +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -9
- package/dist/lib/version.mjs.map +1 -1
- package/dist/lib/webhooks/index.mjs +0 -6
- package/dist/lib/webhooks/index.mjs.map +1 -1
- package/dist/lib/wholesale-feed-sync/index.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/index.mjs.map +1 -1
- package/dist/lib/wholesale-feed-sync/sync.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/sync.mjs.map +1 -1
- package/dist/lib/wholesale-feed-sync/types.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/webhook-notification.mjs +0 -6
- package/dist/lib/wholesale-feed-sync/webhook-notification.mjs.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/mock-server/sales-social/server.ts"],"sourcesContent":["import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { createHash, randomUUID } from 'node:crypto';\nimport {\n ACCESS_TOKEN_TTL_SECONDS,\n ADVERTISERS,\n OAUTH_CLIENTS,\n REFRESH_TOKEN_TTL_SECONDS,\n type MockAdvertiser,\n type MockOAuthClient,\n} from './seed-data';\nimport {\n createMockScenarioController,\n idempotencyKeyFromBody,\n stableFingerprint,\n writeCachedResponse,\n type MockScenarioHandle,\n} from '../scenario';\n\nexport interface BootOptions {\n port: number;\n /** Override seed data. */\n advertisers?: MockAdvertiser[];\n oauthClients?: MockOAuthClient[];\n /** Force-set access-token TTL for testing the refresh path. Defaults to\n * the seed value (3600s). Set to a small number (e.g. 5) to make every\n * subsequent request require a refresh. */\n accessTokenTtlSeconds?: number;\n}\n\nexport interface BootResult {\n url: string;\n close: () => Promise<void>;\n scenario: MockScenarioHandle;\n}\n\ninterface IssuedAccessToken {\n access_token: string;\n refresh_token: string;\n client_id: string;\n expires_at_ms: number;\n refresh_expires_at_ms: number;\n}\n\ninterface AudienceState {\n audience_id: string;\n advertiser_id: string;\n name: string;\n description?: string;\n source_type: string;\n member_count: number;\n status: 'building' | 'active' | 'expired' | 'error';\n created_at: string;\n updated_at: string;\n body_fingerprint: string;\n}\n\ninterface CatalogState {\n catalog_id: string;\n advertiser_id: string;\n name: string;\n vertical: string;\n status: 'active' | 'processing' | 'error';\n item_count: number;\n body_fingerprint: string;\n}\n\ninterface CreativeState {\n creative_id: string;\n advertiser_id: string;\n name: string;\n format_id: string;\n primary_text: string;\n cta_label?: string;\n landing_page_url: string;\n media_url: string;\n status: 'pending_review' | 'approved' | 'rejected' | 'archived';\n created_at: string;\n body_fingerprint: string;\n}\n\ninterface PixelState {\n pixel_id: string;\n advertiser_id: string;\n name: string;\n domain?: string;\n status: 'active' | 'paused';\n events_received_24h: number;\n created_at: string;\n body_fingerprint: string;\n}\n\nexport async function bootSalesSocial(options: BootOptions): Promise<BootResult> {\n const advertisers = options.advertisers ?? ADVERTISERS;\n const oauthClients = options.oauthClients ?? OAUTH_CLIENTS;\n const accessTtl = options.accessTokenTtlSeconds ?? ACCESS_TOKEN_TTL_SECONDS;\n\n const tokensByAccess = new Map<string, IssuedAccessToken>();\n const tokensByRefresh = new Map<string, IssuedAccessToken>();\n\n // Per-advertiser resource state.\n const audiences = new Map<string, AudienceState>();\n const catalogs = new Map<string, CatalogState>();\n const creatives = new Map<string, CreativeState>();\n const pixels = new Map<string, PixelState>();\n\n // Idempotency tables — keyed `<advertiser_id>::<resource_kind>::<client_request_id>`\n // so cross-advertiser collisions are isolated.\n const idempotency = new Map<string, string>();\n\n // Traffic counters keyed by `<METHOD> <route-template>`. The harness queries\n // `GET /_debug/traffic` after a storyboard run and asserts the headline\n // endpoints (custom_audience/upload, event/track, etc.) were called ≥1 time.\n // Façade adapters that never call upstream produce zero counters and fail\n // the assertion — façade detection without depending on storyboard data\n // shape. See adcontextprotocol/adcp-client#1225.\n const traffic = new Map<string, number>();\n function bump(routeTemplate: string): void {\n traffic.set(routeTemplate, (traffic.get(routeTemplate) ?? 0) + 1);\n }\n const scenario = createMockScenarioController({\n specialism: 'sales-social',\n snapshot: () => ({\n audiences: audiences.size,\n catalogs: catalogs.size,\n creatives: creatives.size,\n pixels: pixels.size,\n idempotency: idempotency.size,\n tokens: tokensByAccess.size,\n traffic: Object.fromEntries(traffic),\n }),\n reset: () => {\n tokensByAccess.clear();\n tokensByRefresh.clear();\n audiences.clear();\n catalogs.clear();\n creatives.clear();\n pixels.clear();\n idempotency.clear();\n traffic.clear();\n },\n });\n\n function issueTokens(client: MockOAuthClient): IssuedAccessToken {\n const now = Date.now();\n const t: IssuedAccessToken = {\n access_token: `tok_${randomUUID().replace(/-/g, '').slice(0, 24)}`,\n refresh_token: `rfr_${randomUUID().replace(/-/g, '').slice(0, 24)}`,\n client_id: client.client_id,\n expires_at_ms: now + accessTtl * 1000,\n refresh_expires_at_ms: now + REFRESH_TOKEN_TTL_SECONDS * 1000,\n };\n tokensByAccess.set(t.access_token, t);\n tokensByRefresh.set(t.refresh_token, t);\n return t;\n }\n\n function authenticatedClient(req: IncomingMessage): MockOAuthClient | null {\n const auth = req.headers['authorization'];\n if (!auth || !auth.startsWith('Bearer ')) return null;\n const accessToken = auth.slice(7);\n const issued = tokensByAccess.get(accessToken);\n if (!issued) return null;\n if (issued.expires_at_ms < Date.now()) return null;\n return oauthClients.find(c => c.client_id === issued.client_id) ?? null;\n }\n\n const server = createServer((req, res) => {\n handleRequest(req, res).catch(err => {\n const requestId = (req.headers['x-request-id'] as string | undefined) ?? randomUUID();\n writeJson(res, 500, {\n code: 'internal_error',\n message: err?.message ?? 'unexpected error',\n request_id: requestId,\n });\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(options.port, '127.0.0.1', () => {\n server.removeListener('error', reject);\n resolve();\n });\n });\n\n const addr = server.address();\n const boundPort = typeof addr === 'object' && addr ? addr.port : options.port;\n const url = `http://127.0.0.1:${boundPort}`;\n\n return {\n url,\n scenario: scenario.handle,\n close: () =>\n new Promise<void>((resolve, reject) => {\n server.close(err => (err ? reject(err) : resolve()));\n }),\n };\n\n // ────────────────────────────────────────────────────────────\n // Top-level request dispatcher\n // ────────────────────────────────────────────────────────────\n async function handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url ?? '/', `http://127.0.0.1`);\n const path = url.pathname;\n const method = req.method ?? 'GET';\n\n if (await scenario.handleControlRequest(req, res, method, path)) return;\n\n // Façade-detection traffic dump — harness-only, no auth required.\n // Returns per-endpoint hit counts for assertion in the matrix runner.\n if (method === 'GET' && path === '/_debug/traffic') {\n writeJson(res, 200, { traffic: Object.fromEntries(traffic) });\n return;\n }\n\n // OAuth token endpoint — no Bearer required.\n if (method === 'POST' && path === '/oauth/token') {\n bump('POST /oauth/token');\n return handleOauthToken(req, res);\n }\n\n // Discovery endpoint — replaces the hardcoded principal-mapping table\n // the harness used to inline into Claude's prompt. Adapters look up the\n // upstream advertiser_id at runtime by querying with the AdCP-side\n // identifier they receive from buyers (`account.advertiser`,\n // `account.brand.domain`, etc.). No auth required — discovery is the\n // entry point before the agent has any account context. Issue #1225.\n if (method === 'GET' && path === '/_lookup/advertiser') {\n bump('GET /_lookup/advertiser');\n const adcpAdvertiser = url.searchParams.get('adcp_advertiser');\n if (!adcpAdvertiser) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'adcp_advertiser query parameter is required.',\n });\n return;\n }\n const match = advertisers.find(a => a.adcp_advertiser === adcpAdvertiser);\n if (!match) {\n writeJson(res, 404, {\n code: 'advertiser_not_found',\n message: `No upstream advertiser registered for adcp_advertiser=${adcpAdvertiser}.`,\n });\n return;\n }\n writeJson(res, 200, {\n adcp_advertiser: match.adcp_advertiser,\n advertiser_id: match.advertiser_id,\n display_name: match.display_name,\n });\n return;\n }\n\n // Everything else requires a valid access token.\n const client = authenticatedClient(req);\n if (!client) {\n writeJson(res, 401, {\n code: 'unauthorized',\n message: 'Missing, invalid, or expired bearer token. Acquire one via POST /oauth/token.',\n });\n return;\n }\n\n // Path-based advertiser scoping.\n const advMatch = path.match(/^\\/v1\\.3\\/advertiser\\/([^/]+)(\\/.*)?$/);\n if (!advMatch || !advMatch[1]) {\n writeJson(res, 404, { code: 'not_found', message: `No route for ${method} ${path}` });\n return;\n }\n const advertiserId = decodeURIComponent(advMatch[1]);\n const subPath = advMatch[2] ?? '/';\n const advertiser = advertisers.find(a => a.advertiser_id === advertiserId);\n if (!advertiser) {\n writeJson(res, 404, {\n code: 'advertiser_not_found',\n message: `Advertiser ${advertiserId} not found.`,\n });\n return;\n }\n if (!client.authorized_advertiser_ids.includes(advertiserId)) {\n writeJson(res, 404, {\n code: 'advertiser_not_authorized',\n message: `Advertiser ${advertiserId} not visible to this OAuth client.`,\n });\n return;\n }\n\n if (await scenario.handleScriptedResponse(res, method, path, (m, p) => bump(`${m} ${p}`))) return;\n\n // Sub-path routing — bump traffic counters on each route hit so\n // /_debug/traffic can later report which endpoints the adapter actually\n // exercised. Façade adapters return shape-valid AdCP responses without\n // calling these endpoints; the harness's post-run check catches that.\n if (method === 'GET' && subPath === '/info') {\n bump('GET /v1.3/advertiser/{id}/info');\n return handleGetAdvertiser(advertiser, res);\n }\n\n // Audiences\n if (method === 'GET' && subPath === '/custom_audience/list') {\n bump('GET /v1.3/advertiser/{id}/custom_audience/list');\n return handleListAudiences(advertiser, res);\n }\n if (method === 'POST' && subPath === '/custom_audience/create') {\n bump('POST /v1.3/advertiser/{id}/custom_audience/create');\n return handleCreateAudience(req, advertiser, res);\n }\n if (method === 'POST' && subPath === '/custom_audience/upload') {\n bump('POST /v1.3/advertiser/{id}/custom_audience/upload');\n return handleUploadAudience(req, advertiser, res);\n }\n\n // Catalogs\n if (method === 'GET' && subPath === '/catalog/list') {\n bump('GET /v1.3/advertiser/{id}/catalog/list');\n return handleListCatalogs(advertiser, res);\n }\n if (method === 'POST' && subPath === '/catalog/create') {\n bump('POST /v1.3/advertiser/{id}/catalog/create');\n return handleCreateCatalog(req, advertiser, res);\n }\n if (method === 'POST' && subPath === '/catalog/upload') {\n bump('POST /v1.3/advertiser/{id}/catalog/upload');\n return handleUploadCatalog(req, advertiser, res);\n }\n\n // Creatives\n if (method === 'GET' && subPath === '/creative/list') {\n bump('GET /v1.3/advertiser/{id}/creative/list');\n return handleListCreatives(advertiser, res);\n }\n if (method === 'POST' && subPath === '/creative/create') {\n bump('POST /v1.3/advertiser/{id}/creative/create');\n return handleCreateCreative(req, advertiser, res);\n }\n\n // Pixels (event sources)\n if (method === 'GET' && subPath === '/pixel/list') {\n bump('GET /v1.3/advertiser/{id}/pixel/list');\n return handleListPixels(advertiser, res);\n }\n if (method === 'POST' && subPath === '/pixel/create') {\n bump('POST /v1.3/advertiser/{id}/pixel/create');\n return handleCreatePixel(req, advertiser, res);\n }\n\n // Conversion API\n if (method === 'POST' && subPath === '/event/track') {\n bump('POST /v1.3/advertiser/{id}/event/track');\n return handleTrackEvents(req, advertiser, res);\n }\n\n // Planning surface — Meta/TikTok-style delivery + reach forecasts.\n // adcontextprotocol/adcp-client#1378.\n if (method === 'POST' && subPath === '/delivery_estimate') {\n bump('POST /v1.3/advertiser/{id}/delivery_estimate');\n return handleDeliveryEstimate(req, advertiser, res);\n }\n if (method === 'POST' && subPath === '/audience_reach_estimate') {\n bump('POST /v1.3/advertiser/{id}/audience_reach_estimate');\n return handleAudienceReachEstimate(req, advertiser, res);\n }\n const lookalikeMatch = subPath.match(/^\\/audience\\/([^/]+)\\/lookalike$/);\n if (method === 'POST' && lookalikeMatch && lookalikeMatch[1]) {\n bump('POST /v1.3/advertiser/{id}/audience/{audience_id}/lookalike');\n return handleLookalikeEstimate(req, advertiser, decodeURIComponent(lookalikeMatch[1]), res);\n }\n\n writeJson(res, 404, { code: 'not_found', message: `No route for ${method} ${path}` });\n }\n\n // ────────────────────────────────────────────────────────────\n // OAuth handler\n // ────────────────────────────────────────────────────────────\n async function handleOauthToken(req: IncomingMessage, res: ServerResponse): Promise<void> {\n let body: Record<string, string>;\n try {\n body = await readForm(req);\n } catch {\n writeJson(res, 400, { code: 'invalid_request', message: 'Body must be application/x-www-form-urlencoded.' });\n return;\n }\n const grantType = body.grant_type;\n if (grantType === 'client_credentials') {\n const client = oauthClients.find(c => c.client_id === body.client_id);\n if (!client || client.client_secret !== body.client_secret) {\n writeJson(res, 400, { code: 'invalid_client', message: 'Unknown client_id or wrong client_secret.' });\n return;\n }\n const t = issueTokens(client);\n writeJson(res, 200, {\n access_token: t.access_token,\n refresh_token: t.refresh_token,\n token_type: 'bearer',\n expires_in: Math.max(0, Math.floor((t.expires_at_ms - Date.now()) / 1000)),\n });\n return;\n }\n if (grantType === 'refresh_token') {\n const refreshToken = body.refresh_token;\n const issued = refreshToken ? tokensByRefresh.get(refreshToken) : undefined;\n if (!issued || issued.refresh_expires_at_ms < Date.now()) {\n writeJson(res, 400, { code: 'invalid_grant', message: 'Unknown or expired refresh_token.' });\n return;\n }\n const client = oauthClients.find(c => c.client_id === issued.client_id);\n if (!client) {\n writeJson(res, 400, { code: 'invalid_grant', message: 'Refresh token references a vanished client.' });\n return;\n }\n // Rotate: invalidate old refresh, issue new pair.\n tokensByRefresh.delete(refreshToken!);\n tokensByAccess.delete(issued.access_token);\n const t = issueTokens(client);\n writeJson(res, 200, {\n access_token: t.access_token,\n refresh_token: t.refresh_token,\n token_type: 'bearer',\n expires_in: Math.max(0, Math.floor((t.expires_at_ms - Date.now()) / 1000)),\n });\n return;\n }\n writeJson(res, 400, {\n code: 'unsupported_grant_type',\n message: `grant_type must be one of: client_credentials, refresh_token. Got: ${grantType}`,\n });\n }\n\n // ────────────────────────────────────────────────────────────\n // Advertiser handler\n // ────────────────────────────────────────────────────────────\n function handleGetAdvertiser(advertiser: MockAdvertiser, res: ServerResponse): void {\n writeJson(res, 200, advertiser);\n }\n\n // ────────────────────────────────────────────────────────────\n // Audience handlers\n // ────────────────────────────────────────────────────────────\n function handleListAudiences(advertiser: MockAdvertiser, res: ServerResponse): void {\n const list = Array.from(audiences.values()).filter(a => a.advertiser_id === advertiser.advertiser_id);\n writeJson(res, 200, { audiences: list.map(stripBodyFingerprint) });\n }\n\n async function handleCreateAudience(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const exactReplay = scenario.idempotency.check(\n `${advertiser.advertiser_id}::audience`,\n idempotencyKeyFromBody(body),\n stableFingerprint(body)\n );\n if (exactReplay.kind === 'replay' || exactReplay.kind === 'conflict') {\n writeCachedResponse(res, exactReplay.response);\n return;\n }\n const { name, description, source_type, client_request_id } = body as Record<string, unknown>;\n if (typeof name !== 'string' || typeof source_type !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'name and source_type are required strings.' });\n return;\n }\n const validSources = ['customer_file', 'website_traffic', 'app_activity', 'lookalike', 'engagement'];\n if (!validSources.includes(source_type)) {\n writeJson(res, 400, {\n code: 'invalid_source_type',\n message: `source_type must be one of ${validSources.join(', ')}.`,\n });\n return;\n }\n const fingerprint = JSON.stringify({ name, description, source_type });\n const replay = checkIdempotentReplay(advertiser.advertiser_id, 'audience', client_request_id, fingerprint);\n if (replay.kind === 'conflict') {\n writeJson(res, 409, { code: 'idempotency_conflict', message: replay.message });\n return;\n }\n if (replay.kind === 'replay') {\n const existing = audiences.get(replay.id);\n if (existing) {\n writeJson(res, 200, stripBodyFingerprint(existing));\n return;\n }\n }\n const id = `ca_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n const now = new Date().toISOString();\n const audience: AudienceState = {\n audience_id: id,\n advertiser_id: advertiser.advertiser_id,\n name,\n description: typeof description === 'string' ? description : undefined,\n source_type,\n member_count: 0,\n status: 'building',\n created_at: now,\n updated_at: now,\n body_fingerprint: fingerprint,\n };\n audiences.set(id, audience);\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n idempotency.set(`${advertiser.advertiser_id}::audience::${client_request_id}`, id);\n }\n const responseBody = stripBodyFingerprint(audience);\n if (exactReplay.kind === 'fresh') exactReplay.record({ status: 201, body: responseBody });\n writeJson(res, 201, responseBody);\n }\n\n async function handleUploadAudience(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const { audience_id, identifier_type, members } = body as Record<string, unknown>;\n if (typeof audience_id !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'audience_id is required.' });\n return;\n }\n const aud = audiences.get(audience_id);\n if (!aud || aud.advertiser_id !== advertiser.advertiser_id) {\n writeJson(res, 404, { code: 'audience_not_found', message: `Audience ${audience_id} not found.` });\n return;\n }\n const validIds = [\n 'hashed_email_sha256',\n 'hashed_phone_sha256',\n 'hashed_email_or_phone_sha256',\n 'mobile_advertising_id',\n ];\n if (typeof identifier_type !== 'string' || !validIds.includes(identifier_type)) {\n writeJson(res, 400, {\n code: 'invalid_identifier_type',\n message: `identifier_type must be one of ${validIds.join(', ')}.`,\n });\n return;\n }\n if (!Array.isArray(members) || members.length === 0) {\n writeJson(res, 400, { code: 'empty_members', message: 'members must be a non-empty array.' });\n return;\n }\n if (identifier_type.startsWith('hashed_')) {\n const hashRe = /^[0-9a-f]{64}$/;\n const malformed = members.filter(m => typeof m !== 'string' || !hashRe.test(m));\n if (malformed.length > 0) {\n // Real walled gardens reject silently per-row in batch but for the\n // test fixture we hard-fail on any malformed — adapter bugs that\n // pass raw PII or wrong-cased hex get surfaced loudly.\n writeJson(res, 400, {\n code: 'invalid_hash_format',\n message:\n `${malformed.length} member(s) are not 64-char lowercase hex. Walled gardens require ` +\n `client-side SHA-256 hashing of the lowercased trimmed identifier; uploading raw PII is rejected.`,\n });\n return;\n }\n }\n aud.member_count += members.length;\n aud.status = 'active';\n aud.updated_at = new Date().toISOString();\n writeJson(res, 202, {\n audience_id,\n status: aud.status,\n batch_size: members.length,\n });\n }\n\n // ────────────────────────────────────────────────────────────\n // Catalog handlers\n // ────────────────────────────────────────────────────────────\n function handleListCatalogs(advertiser: MockAdvertiser, res: ServerResponse): void {\n const list = Array.from(catalogs.values()).filter(c => c.advertiser_id === advertiser.advertiser_id);\n writeJson(res, 200, { catalogs: list.map(stripBodyFingerprint) });\n }\n\n async function handleCreateCatalog(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const exactReplay = scenario.idempotency.check(\n `${advertiser.advertiser_id}::catalog`,\n idempotencyKeyFromBody(body),\n stableFingerprint(body)\n );\n if (exactReplay.kind === 'replay' || exactReplay.kind === 'conflict') {\n writeCachedResponse(res, exactReplay.response);\n return;\n }\n const { name, vertical, client_request_id } = body as Record<string, unknown>;\n if (typeof name !== 'string' || typeof vertical !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'name and vertical are required.' });\n return;\n }\n const fingerprint = JSON.stringify({ name, vertical });\n const replay = checkIdempotentReplay(advertiser.advertiser_id, 'catalog', client_request_id, fingerprint);\n if (replay.kind === 'conflict') {\n writeJson(res, 409, { code: 'idempotency_conflict', message: replay.message });\n return;\n }\n if (replay.kind === 'replay') {\n const existing = catalogs.get(replay.id);\n if (existing) {\n writeJson(res, 200, stripBodyFingerprint(existing));\n return;\n }\n }\n const id = `cat_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n const cat: CatalogState = {\n catalog_id: id,\n advertiser_id: advertiser.advertiser_id,\n name,\n vertical,\n status: 'active',\n item_count: 0,\n body_fingerprint: fingerprint,\n };\n catalogs.set(id, cat);\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n idempotency.set(`${advertiser.advertiser_id}::catalog::${client_request_id}`, id);\n }\n const responseBody = stripBodyFingerprint(cat);\n if (exactReplay.kind === 'fresh') exactReplay.record({ status: 201, body: responseBody });\n writeJson(res, 201, responseBody);\n }\n\n async function handleUploadCatalog(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const { catalog_id, items } = body as Record<string, unknown>;\n if (typeof catalog_id !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'catalog_id is required.' });\n return;\n }\n const cat = catalogs.get(catalog_id);\n if (!cat || cat.advertiser_id !== advertiser.advertiser_id) {\n writeJson(res, 404, { code: 'catalog_not_found', message: `Catalog ${catalog_id} not found.` });\n return;\n }\n if (!Array.isArray(items) || items.length === 0) {\n writeJson(res, 400, { code: 'empty_items', message: 'items must be a non-empty array.' });\n return;\n }\n cat.item_count += items.length;\n writeJson(res, 202, { catalog_id, batch_size: items.length });\n }\n\n // ────────────────────────────────────────────────────────────\n // Creative handlers\n // ────────────────────────────────────────────────────────────\n function handleListCreatives(advertiser: MockAdvertiser, res: ServerResponse): void {\n const list = Array.from(creatives.values()).filter(c => c.advertiser_id === advertiser.advertiser_id);\n writeJson(res, 200, { creatives: list.map(stripBodyFingerprint) });\n }\n\n async function handleCreateCreative(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const exactReplay = scenario.idempotency.check(\n `${advertiser.advertiser_id}::creative`,\n idempotencyKeyFromBody(body),\n stableFingerprint(body)\n );\n if (exactReplay.kind === 'replay' || exactReplay.kind === 'conflict') {\n writeCachedResponse(res, exactReplay.response);\n return;\n }\n const { name, format_id, primary_text, cta_label, landing_page_url, media_url, client_request_id } = body as Record<\n string,\n unknown\n >;\n if (\n typeof name !== 'string' ||\n typeof format_id !== 'string' ||\n typeof primary_text !== 'string' ||\n typeof landing_page_url !== 'string' ||\n typeof media_url !== 'string'\n ) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'name, format_id, primary_text, landing_page_url, media_url are all required strings.',\n });\n return;\n }\n const validFormats = ['native_feed', 'story_video', 'vertical_video', 'carousel_image'];\n if (!validFormats.includes(format_id)) {\n writeJson(res, 400, { code: 'invalid_format', message: `format_id must be one of ${validFormats.join(', ')}.` });\n return;\n }\n const fingerprint = JSON.stringify({ name, format_id, primary_text, cta_label, landing_page_url, media_url });\n const replay = checkIdempotentReplay(advertiser.advertiser_id, 'creative', client_request_id, fingerprint);\n if (replay.kind === 'conflict') {\n writeJson(res, 409, { code: 'idempotency_conflict', message: replay.message });\n return;\n }\n if (replay.kind === 'replay') {\n const existing = creatives.get(replay.id);\n if (existing) {\n writeJson(res, 200, stripBodyFingerprint(existing));\n return;\n }\n }\n const id = `cr_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n const cr: CreativeState = {\n creative_id: id,\n advertiser_id: advertiser.advertiser_id,\n name,\n format_id,\n primary_text,\n cta_label: typeof cta_label === 'string' ? cta_label : undefined,\n landing_page_url,\n media_url,\n status: 'pending_review',\n created_at: new Date().toISOString(),\n body_fingerprint: fingerprint,\n };\n creatives.set(id, cr);\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n idempotency.set(`${advertiser.advertiser_id}::creative::${client_request_id}`, id);\n }\n const responseBody = stripBodyFingerprint(cr);\n if (exactReplay.kind === 'fresh') exactReplay.record({ status: 201, body: responseBody });\n writeJson(res, 201, responseBody);\n }\n\n // ────────────────────────────────────────────────────────────\n // Pixel handlers\n // ────────────────────────────────────────────────────────────\n function handleListPixels(advertiser: MockAdvertiser, res: ServerResponse): void {\n const list = Array.from(pixels.values()).filter(p => p.advertiser_id === advertiser.advertiser_id);\n writeJson(res, 200, { pixels: list.map(stripBodyFingerprint) });\n }\n\n async function handleCreatePixel(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const exactReplay = scenario.idempotency.check(\n `${advertiser.advertiser_id}::pixel`,\n idempotencyKeyFromBody(body),\n stableFingerprint(body)\n );\n if (exactReplay.kind === 'replay' || exactReplay.kind === 'conflict') {\n writeCachedResponse(res, exactReplay.response);\n return;\n }\n const { name, domain, client_request_id } = body as Record<string, unknown>;\n if (typeof name !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'name is required.' });\n return;\n }\n const fingerprint = JSON.stringify({ name, domain });\n const replay = checkIdempotentReplay(advertiser.advertiser_id, 'pixel', client_request_id, fingerprint);\n if (replay.kind === 'conflict') {\n writeJson(res, 409, { code: 'idempotency_conflict', message: replay.message });\n return;\n }\n if (replay.kind === 'replay') {\n const existing = pixels.get(replay.id);\n if (existing) {\n writeJson(res, 200, stripBodyFingerprint(existing));\n return;\n }\n }\n const id = `px_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n const px: PixelState = {\n pixel_id: id,\n advertiser_id: advertiser.advertiser_id,\n name,\n domain: typeof domain === 'string' ? domain : undefined,\n status: 'active',\n events_received_24h: 0,\n created_at: new Date().toISOString(),\n body_fingerprint: fingerprint,\n };\n pixels.set(id, px);\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n idempotency.set(`${advertiser.advertiser_id}::pixel::${client_request_id}`, id);\n }\n const responseBody = stripBodyFingerprint(px);\n if (exactReplay.kind === 'fresh') exactReplay.record({ status: 201, body: responseBody });\n writeJson(res, 201, responseBody);\n }\n\n // ────────────────────────────────────────────────────────────\n // Conversion API (events) handler\n // ────────────────────────────────────────────────────────────\n async function handleTrackEvents(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const { pixel_id, events } = body as Record<string, unknown>;\n if (typeof pixel_id !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'pixel_id is required.' });\n return;\n }\n const px = pixels.get(pixel_id);\n if (!px || px.advertiser_id !== advertiser.advertiser_id) {\n writeJson(res, 404, { code: 'pixel_not_found', message: `Pixel ${pixel_id} not found.` });\n return;\n }\n if (!Array.isArray(events) || events.length === 0) {\n writeJson(res, 400, { code: 'empty_events', message: 'events must be a non-empty array.' });\n return;\n }\n let received = 0;\n let dropped = 0;\n const hashRe = /^[0-9a-f]{64}$/;\n for (const ev of events) {\n if (!ev || typeof ev !== 'object') {\n dropped++;\n continue;\n }\n const event = ev as Record<string, unknown>;\n if (typeof event.event_name !== 'string' || typeof event.event_time !== 'number') {\n dropped++;\n continue;\n }\n const userData = event.user_data as Record<string, unknown> | undefined;\n const hasMatchableId = !!(\n userData &&\n ((typeof userData.email_sha256 === 'string' && hashRe.test(userData.email_sha256)) ||\n (typeof userData.phone_sha256 === 'string' && hashRe.test(userData.phone_sha256)) ||\n (typeof userData.external_id_sha256 === 'string' && hashRe.test(userData.external_id_sha256)))\n );\n if (!hasMatchableId) {\n // Walled gardens reject events without a matchable identifier.\n dropped++;\n continue;\n }\n received++;\n }\n if (received === 0) {\n writeJson(res, 400, {\n code: 'no_matchable_events',\n message:\n `All ${events.length} events were dropped — none carried a hashed identifier ` +\n `(email_sha256, phone_sha256, or external_id_sha256). Walled-garden CAPI requires ` +\n `at least one matchable identifier per event.`,\n });\n return;\n }\n px.events_received_24h += received;\n writeJson(res, 200, { pixel_id, events_received: received, events_dropped: dropped });\n }\n\n // ────────────────────────────────────────────────────────────\n // Planning surface (Meta/TikTok-style forecast endpoints)\n // adcontextprotocol/adcp-client#1378\n // ────────────────────────────────────────────────────────────\n async function handleDeliveryEstimate(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const { targeting, optimization_goal, budget, target_outcome, flight_dates } = body as Record<string, unknown>;\n if (typeof optimization_goal !== 'string') {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'optimization_goal is required (e.g. \"reach\", \"conversions\", \"clicks\", \"video_views\").',\n });\n return;\n }\n if (budget === undefined && target_outcome === undefined) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'Provide either budget (forward forecast) or target_outcome (reverse / goal-based forecast).',\n });\n return;\n }\n if (budget !== undefined && (typeof budget !== 'number' || !Number.isFinite(budget) || budget <= 0)) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'budget must be a positive number.',\n });\n return;\n }\n if (\n target_outcome !== undefined &&\n (typeof target_outcome !== 'number' || !Number.isFinite(target_outcome) || target_outcome <= 0)\n ) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'target_outcome must be a positive number.',\n });\n return;\n }\n const targetingKey = serializeTargeting(targeting);\n const dates = isObject(flight_dates) ? flight_dates : {};\n const estimate = synthDeliveryEstimate({\n advertiserId: advertiser.advertiser_id,\n currency: advertiser.currency,\n targeting: targetingKey,\n optimizationGoal: optimization_goal,\n budget: typeof budget === 'number' ? budget : undefined,\n targetOutcome: typeof target_outcome === 'number' ? target_outcome : undefined,\n flightStart: typeof dates.start === 'string' ? dates.start : undefined,\n flightEnd: typeof dates.end === 'string' ? dates.end : undefined,\n });\n writeJson(res, 200, estimate);\n }\n\n async function handleAudienceReachEstimate(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const { targeting } = body as Record<string, unknown>;\n if (!isObject(targeting)) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'targeting (object) is required — geo, age, interests, custom audiences, etc.',\n });\n return;\n }\n const targetingKey = serializeTargeting(targeting);\n const estimate = synthAudienceReach({\n advertiserId: advertiser.advertiser_id,\n targeting: targetingKey,\n });\n writeJson(res, 200, estimate);\n }\n\n async function handleLookalikeEstimate(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n audienceId: string,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const seed = audiences.get(audienceId);\n if (!seed || seed.advertiser_id !== advertiser.advertiser_id) {\n writeJson(res, 404, {\n code: 'audience_not_found',\n message: `Seed audience ${audienceId} not found for advertiser ${advertiser.advertiser_id}.`,\n });\n return;\n }\n const { similarity_pct, country } = body as Record<string, unknown>;\n if (typeof similarity_pct !== 'number' || similarity_pct < 1 || similarity_pct > 10) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'similarity_pct must be a number between 1 (closest) and 10 (broadest).',\n });\n return;\n }\n if (typeof country !== 'string' || country.length === 0) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'country (ISO 3166-1 alpha-2) is required — lookalikes are country-scoped.',\n });\n return;\n }\n const estimate = synthLookalikeEstimate({\n advertiserId: advertiser.advertiser_id,\n seedAudienceId: audienceId,\n seedSize: seed.member_count,\n similarityPct: similarity_pct,\n country,\n });\n writeJson(res, 200, estimate);\n }\n\n // ────────────────────────────────────────────────────────────\n // Helpers\n // ────────────────────────────────────────────────────────────\n function checkIdempotentReplay(\n advertiserId: string,\n resourceKind: string,\n clientRequestId: unknown,\n fingerprint: string\n ): { kind: 'replay'; id: string } | { kind: 'conflict'; message: string } | { kind: 'fresh' } {\n if (typeof clientRequestId !== 'string' || clientRequestId.length === 0) return { kind: 'fresh' };\n const key = `${advertiserId}::${resourceKind}::${clientRequestId}`;\n const existingId = idempotency.get(key);\n if (!existingId) return { kind: 'fresh' };\n const stored = lookupResource(resourceKind, existingId);\n if (!stored) return { kind: 'fresh' };\n if (stored.body_fingerprint !== fingerprint) {\n return {\n kind: 'conflict',\n message: `client_request_id ${clientRequestId} was previously used with a different body. Use a fresh idempotency key for distinct requests.`,\n };\n }\n return { kind: 'replay', id: existingId };\n }\n\n function lookupResource(kind: string, id: string): { body_fingerprint: string } | undefined {\n switch (kind) {\n case 'audience':\n return audiences.get(id);\n case 'catalog':\n return catalogs.get(id);\n case 'creative':\n return creatives.get(id);\n case 'pixel':\n return pixels.get(id);\n default:\n return undefined;\n }\n }\n}\n\nfunction stripBodyFingerprint<T extends { body_fingerprint?: string }>(record: T): Omit<T, 'body_fingerprint'> {\n const { body_fingerprint, ...rest } = record;\n return rest;\n}\n\nfunction readForm(req: IncomingMessage): Promise<Record<string, string>> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', c => chunks.push(c));\n req.on('error', reject);\n req.on('end', () => {\n const raw = Buffer.concat(chunks).toString('utf8');\n const out: Record<string, string> = {};\n for (const pair of raw.split('&')) {\n if (!pair) continue;\n const [k, v = ''] = pair.split('=');\n if (k === undefined) continue;\n out[decodeURIComponent(k)] = decodeURIComponent(v.replace(/\\+/g, ' '));\n }\n resolve(out);\n });\n });\n}\n\nasync function readJsonObject(req: IncomingMessage, res: ServerResponse): Promise<Record<string, unknown> | null> {\n let body: unknown;\n try {\n body = await readJson(req);\n } catch {\n writeJson(res, 400, { code: 'invalid_json', message: 'Request body must be valid JSON.' });\n return null;\n }\n if (!body || typeof body !== 'object' || Array.isArray(body)) {\n writeJson(res, 400, { code: 'invalid_request', message: 'Body must be a JSON object.' });\n return null;\n }\n return body as Record<string, unknown>;\n}\n\nfunction readJson(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', c => chunks.push(c));\n req.on('error', reject);\n req.on('end', () => {\n const raw = Buffer.concat(chunks).toString('utf8');\n if (!raw) {\n resolve({});\n return;\n }\n try {\n resolve(JSON.parse(raw));\n } catch (err) {\n reject(err);\n }\n });\n });\n}\n\nfunction writeJson(res: ServerResponse, status: number, body: unknown): void {\n const json = JSON.stringify(body);\n res.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'content-length': Buffer.byteLength(json),\n });\n res.end(json);\n}\n\n// ────────────────────────────────────────────────────────────\n// Deterministic forecast generators (#1378)\n// ────────────────────────────────────────────────────────────\n\ninterface RangeMinMax {\n min: number;\n max: number;\n}\ninterface DeliveryEstimateResponse {\n optimization_goal: string;\n currency: string;\n forecast_range_unit: 'spend' | 'conversions' | 'reach_freq' | 'clicks';\n estimated_daily_reach: RangeMinMax;\n estimated_daily_impressions: RangeMinMax;\n estimated_daily_clicks: RangeMinMax;\n estimated_daily_conversions: RangeMinMax;\n estimated_cpm: { min: number; median: number; max: number };\n bid_recommendation: { low: number; median: number; high: number };\n daily_budget_recommendation: RangeMinMax;\n delivery_curve: Array<{\n daily_budget: number;\n estimated_daily_reach: RangeMinMax;\n estimated_daily_conversions: RangeMinMax;\n }>;\n required_budget?: RangeMinMax;\n /** When the inferred budget falls below the platform learning-phase floor\n * for the chosen optimization_goal, the platform clamps and surfaces a\n * warning. Real Meta enforces $1.05/day for impressions, $5.05/day for\n * clicks, ~$40/day for conversion campaigns; TikTok floors $20/day. The\n * mock surfaces the warning so adopters wire the path before they hit it\n * in production. */\n min_budget_warning?: { floor: number; reason: string };\n generated_at: string;\n}\n\n/** Daily-budget learning-phase floors typical of walled-garden platforms.\n * Bid_strategy and platform vary; these are mid-range defaults adopters\n * can override per-tenant. */\nfunction dailyBudgetFloor(goal: string): number {\n switch (goal) {\n case 'reach':\n case 'awareness':\n case 'video_views':\n case 'thru_play':\n return 5;\n case 'clicks':\n case 'link_clicks':\n case 'traffic':\n case 'engagement':\n case 'follows':\n case 'profile_visits':\n return 10;\n case 'conversions':\n case 'purchase':\n case 'app_install':\n return 40;\n default:\n return 10;\n }\n}\n\nfunction synthDeliveryEstimate(input: {\n advertiserId: string;\n currency: string;\n targeting: string | null;\n optimizationGoal: string;\n budget?: number;\n targetOutcome?: number;\n flightStart?: string;\n flightEnd?: string;\n}): DeliveryEstimateResponse {\n const seedKey = stableStringify({\n advertiserId: input.advertiserId,\n targeting: input.targeting,\n goal: input.optimizationGoal,\n flight: { start: input.flightStart, end: input.flightEnd },\n });\n const seed = seedFromString(seedKey);\n\n // Audience pool size derived from targeting hash. Real Marketing APIs\n // base everything on this number; we anchor here too.\n const audiencePool = 500_000 + (seed.next() % 50_000_000);\n // Saturation rate — what fraction of pool you can reach at infinite spend.\n const saturationCap = 0.55 + (seed.next() % 4001) / 10_000; // [0.55, 0.95]\n // Goal-specific CPM band.\n const cpmBase = goalCpm(input.optimizationGoal, seed);\n\n // Funnel parameters. CTR varies by goal: reach campaigns don't optimize\n // for clicks; clicks campaigns over-index. Conversion rate likewise.\n // Applying a single conversion rate across all goals (the prior shape)\n // produced wrong reverse-forecast budgets for non-conversion goals.\n const ctr = ctrForGoal(input.optimizationGoal, seed);\n const conversionRate = conversionRateForGoal(input.optimizationGoal, seed);\n\n const floor = dailyBudgetFloor(input.optimizationGoal);\n\n // Budget anchor. Forward: caller's budget. Reverse: derive from\n // target_outcome — but the math depends on which goal is being targeted.\n let dailyBudget = input.budget ?? 0;\n let requiredBudget: RangeMinMax | undefined;\n let preClampBudget = 0;\n if (dailyBudget === 0 && input.targetOutcome !== undefined) {\n const goal = input.optimizationGoal;\n let requiredImpressions: number;\n if (goal === 'reach' || goal === 'awareness') {\n // Reverse for reach: invert the saturating curve to find the spend\n // level that hits target_outcome unique users.\n const cap = audiencePool * saturationCap;\n const targetReach = Math.min(input.targetOutcome, cap * 0.99);\n // reach = cap × (1 − e^−impressions/cap) ⇒ impressions = −cap × ln(1 − reach/cap)\n requiredImpressions = -cap * Math.log(1 - targetReach / cap);\n } else if (goal === 'video_views' || goal === 'thru_play') {\n // Roughly 35% completion rate at the goal level; impressions ≈ views/.35\n requiredImpressions = input.targetOutcome / 0.35;\n } else if (goal === 'clicks' || goal === 'link_clicks' || goal === 'traffic') {\n requiredImpressions = input.targetOutcome / Math.max(0.001, ctr);\n } else {\n // conversions / purchase / app_install / engagement etc.\n requiredImpressions = input.targetOutcome / Math.max(ctr * conversionRate * 8, 0.0001);\n }\n dailyBudget = (requiredImpressions / 1000) * cpmBase.median;\n preClampBudget = dailyBudget;\n if (dailyBudget < floor) dailyBudget = floor;\n requiredBudget = { min: Math.floor(dailyBudget * 0.85), max: Math.ceil(dailyBudget * 1.2) };\n }\n if (dailyBudget === 0) dailyBudget = Math.max(floor, 100);\n\n // Saturating-curve: reach grows fast then plateaus at saturationCap × pool.\n const reachAt = (b: number): number => {\n const impressions = (b / cpmBase.median) * 1000;\n const cap = audiencePool * saturationCap;\n const ratePer = impressions / Math.max(1, cap);\n return Math.floor(cap * (1 - Math.exp(-ratePer)));\n };\n\n const dailyReach = reachAt(dailyBudget);\n const dailyImpressions = Math.floor((dailyBudget / cpmBase.median) * 1000);\n const dailyClicks = Math.floor(dailyImpressions * ctr);\n const dailyConversions = Math.floor(dailyClicks * conversionRate * 8); // post-click + view-through\n const rangeUnit: DeliveryEstimateResponse['forecast_range_unit'] =\n input.targetOutcome !== undefined && input.budget === undefined\n ? input.optimizationGoal === 'clicks' ||\n input.optimizationGoal === 'link_clicks' ||\n input.optimizationGoal === 'traffic'\n ? 'clicks'\n : 'conversions' // Reach-goal reverse fits the conversions enum better than reach_freq, which is broadcast-shaped per the AdCP schema.\n : 'spend';\n\n const tiers = [0.5, 1.0, 1.5, 2.5, 4.0].map(m => Math.round(dailyBudget * m));\n // Tighten ranges to ±15-30% (was ±60% min / ±10% max) — real walled-garden\n // delivery_estimate ranges are ±25-35% per recent benchmarks.\n const deliveryCurve = tiers.map(t => ({\n daily_budget: t,\n estimated_daily_reach: { min: Math.floor(reachAt(t) * 0.78), max: Math.floor(reachAt(t) * 1.18) },\n estimated_daily_conversions: {\n min: Math.floor((t / cpmBase.median) * 1000 * ctr * conversionRate * 8 * 0.78),\n max: Math.floor((t / cpmBase.median) * 1000 * ctr * conversionRate * 8 * 1.22),\n },\n }));\n\n const minBudgetWarning =\n preClampBudget > 0 && preClampBudget < floor\n ? {\n floor,\n reason: `Inferred budget ${round2(preClampBudget)} ${input.currency}/day below platform learning-phase floor for ${input.optimizationGoal} (${floor} ${input.currency}/day); clamped.`,\n }\n : undefined;\n\n return {\n optimization_goal: input.optimizationGoal,\n currency: input.currency,\n forecast_range_unit: rangeUnit,\n estimated_daily_reach: { min: Math.floor(dailyReach * 0.78), max: Math.floor(dailyReach * 1.18) },\n estimated_daily_impressions: {\n min: Math.floor(dailyImpressions * 0.78),\n max: Math.floor(dailyImpressions * 1.18),\n },\n estimated_daily_clicks: { min: Math.floor(dailyClicks * 0.78), max: Math.floor(dailyClicks * 1.22) },\n estimated_daily_conversions: {\n min: Math.floor(dailyConversions * 0.75),\n max: Math.floor(dailyConversions * 1.25),\n },\n estimated_cpm: cpmBase,\n bid_recommendation: {\n low: round2(cpmBase.median * 0.75),\n median: round2(cpmBase.median),\n high: round2(cpmBase.median * 1.35),\n },\n daily_budget_recommendation: {\n min: Math.max(floor, Math.floor(dailyBudget * 0.5)),\n max: Math.ceil(dailyBudget * 2),\n },\n delivery_curve: deliveryCurve,\n ...(requiredBudget && { required_budget: requiredBudget }),\n ...(minBudgetWarning && { min_budget_warning: minBudgetWarning }),\n generated_at: '2026-04-01T00:00:00.000Z',\n };\n}\n\nfunction ctrForGoal(goal: string, seed: DeterministicSeed): number {\n const base = (() => {\n switch (goal) {\n case 'reach':\n case 'awareness':\n return 0.003; // 0.3% — reach campaigns don't optimize for clicks\n case 'video_views':\n case 'thru_play':\n return 0.005;\n case 'clicks':\n case 'link_clicks':\n case 'traffic':\n return 0.013; // 1.3% — performance-optimized\n case 'conversions':\n case 'purchase':\n case 'app_install':\n return 0.011;\n case 'engagement':\n case 'follows':\n case 'profile_visits':\n return 0.018; // engagement campaigns get high CTR\n default:\n return 0.008;\n }\n })();\n // ±15% wobble so storyboards stay deterministic but inputs perturb output.\n return base * (0.85 + (seed.next() % 3001) / 10_000);\n}\n\nfunction conversionRateForGoal(goal: string, seed: DeterministicSeed): number {\n const base = (() => {\n switch (goal) {\n case 'conversions':\n case 'purchase':\n return 0.022; // optimization toward purchase tightens funnel\n case 'app_install':\n return 0.028;\n case 'reach':\n case 'awareness':\n return 0.004; // upper-funnel — conversions are incidental\n default:\n return 0.012;\n }\n })();\n return base * (0.85 + (seed.next() % 3001) / 10_000);\n}\n\nfunction goalCpm(goal: string, seed: DeterministicSeed): { min: number; median: number; max: number } {\n // Approximate CPM bands typical of social Marketing APIs in 2024-2026.\n // Reach is cheaper than video (in-stream/feed video CPMs run $8-15);\n // clicks and conversions are top of the band because they buy auction\n // priority for the most contested inventory.\n // Calibrated to 2024-2026 walled-garden benchmarks: reach is cheaper than\n // video CPMs (Meta in-stream/Reels run $11-16; mock weighted toward feed\n // video). Conversions tops the band as auction priority spikes.\n const base = (() => {\n switch (goal) {\n case 'reach':\n case 'awareness':\n return 7;\n case 'video_views':\n case 'thru_play':\n return 10;\n case 'engagement':\n case 'follows':\n case 'profile_visits':\n return 6;\n case 'clicks':\n case 'link_clicks':\n case 'traffic':\n return 11;\n case 'conversions':\n case 'purchase':\n case 'app_install':\n return 18;\n default:\n return 10;\n }\n })();\n // ±15% wobble — narrower than the original ±15% min / 60% max range,\n // matching real walled-garden delivery_estimate jitter (~±10-15% on CPM\n // medians, ±50-60% on min/max bounds).\n const wobble = 0.88 + (seed.next() % 2401) / 10_000; // [0.88, 1.12]\n const median = round2(base * wobble);\n return { min: round2(median * 0.7), median, max: round2(median * 1.45) };\n}\n\ninterface AudienceReachResponse {\n estimated_audience_size: RangeMinMax;\n matchable_size_at_platform: RangeMinMax;\n reach_quality: 'narrow' | 'specific' | 'broad';\n generated_at: string;\n}\n\nfunction synthAudienceReach(input: { advertiserId: string; targeting: string | null }): AudienceReachResponse {\n const seed = seedFromString(stableStringify({ adv: input.advertiserId, t: input.targeting, kind: 'audience_reach' }));\n // Audience pool varies dramatically by targeting tightness.\n const pool = 50_000 + (seed.next() % 80_000_000);\n const matchRate = 0.55 + (seed.next() % 3501) / 10_000; // platform match ~55–90%\n const matchable = Math.floor(pool * matchRate);\n const quality: AudienceReachResponse['reach_quality'] =\n pool < 1_000_000 ? 'narrow' : pool < 10_000_000 ? 'specific' : 'broad';\n return {\n estimated_audience_size: { min: Math.floor(pool * 0.8), max: Math.floor(pool * 1.2) },\n matchable_size_at_platform: { min: Math.floor(matchable * 0.8), max: Math.floor(matchable * 1.2) },\n reach_quality: quality,\n generated_at: '2026-04-01T00:00:00.000Z',\n };\n}\n\ninterface LookalikeResponse {\n seed_audience_id: string;\n similarity_pct: number;\n country: string;\n estimated_size: RangeMinMax;\n activation_eta_hours: number;\n generated_at: string;\n}\n\n/**\n * Approximate adult-internet population by country (rough order-of-magnitude\n * for top markets; default for unmatched). Used to clamp lookalike sizing\n * so a large seed doesn't produce a lookalike larger than the country.\n * Real walled-garden APIs gate lookalikes at country-share boundaries\n * (Meta caps LAL audiences at country_pop × similarity_pct/100).\n */\nfunction countryPopulation(country: string): number {\n // Adult-internet population estimates (mid-2020s, rounded). Numbers don't\n // need to be precise — they only anchor the lookalike sizing cap so the\n // mock doesn't produce 19M LAL audiences from 1M seeds.\n const c = country.toUpperCase();\n switch (c) {\n case 'US':\n return 260_000_000;\n case 'CA':\n return 32_000_000;\n case 'GB':\n case 'UK':\n return 55_000_000;\n case 'DE':\n return 70_000_000;\n case 'FR':\n return 55_000_000;\n case 'JP':\n return 85_000_000;\n case 'AU':\n return 22_000_000;\n case 'BR':\n return 140_000_000;\n case 'IN':\n return 625_000_000;\n case 'MX':\n return 100_000_000;\n default:\n return 25_000_000; // default for smaller markets\n }\n}\n\nfunction synthLookalikeEstimate(input: {\n advertiserId: string;\n seedAudienceId: string;\n seedSize: number;\n similarityPct: number;\n country: string;\n}): LookalikeResponse {\n const seed = seedFromString(\n stableStringify({\n adv: input.advertiserId,\n aud: input.seedAudienceId,\n country: input.country,\n pct: input.similarityPct,\n })\n );\n const pop = countryPopulation(input.country);\n // Meta's LAL math: country_pop × (similarity_pct / 100) is the upper cap.\n // A 1% LAL in the US ≈ 2.6M; a 10% LAL ≈ 26M. We hold sizing well below the\n // cap (`cap * 0.6` × `wobble ∈ [0.85, 1.15]` → max ≈ `cap * 0.69`) so the\n // mock is conservatively realistic — real walled gardens rarely hit the\n // theoretical cap on first generation.\n const cap = Math.floor(pop * (input.similarityPct / 100));\n // Seed-driven contribution as a fallback for small seeds — never exceeds\n // the platform cap.\n const seedContribution = Math.floor(Math.max(1000, input.seedSize) * (8 + input.similarityPct * 8));\n const wobble = 0.85 + (seed.next() % 3001) / 10_000;\n const size = Math.floor(Math.min(cap * 0.6, seedContribution) * wobble);\n // ETA varies by platform: TikTok 1-6h, Meta 4-24h. Mock spans both.\n const eta = 4 + (seed.next() % 21); // 4–24h\n return {\n seed_audience_id: input.seedAudienceId,\n similarity_pct: input.similarityPct,\n country: input.country.toUpperCase(),\n estimated_size: { min: Math.floor(size * 0.85), max: Math.floor(size * 1.15) },\n activation_eta_hours: eta,\n generated_at: '2026-04-01T00:00:00.000Z',\n };\n}\n\nfunction round2(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return Boolean(v) && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction serializeTargeting(t: unknown): string | null {\n if (t === null || t === undefined) return null;\n if (typeof t === 'string') return t;\n try {\n return stableStringify(t);\n } catch {\n return null;\n }\n}\n\n/**\n * Recursive deterministic JSON stringifier — sorts object keys at every\n * depth so two equivalent payloads with different key insertion orders\n * hash identically. Plain `JSON.stringify(t, keys.sort())` only sorts the\n * top level AND treats the array as a key allowlist (silently dropping\n * nested fields).\n */\nfunction stableStringify(v: unknown): string {\n if (v === null || typeof v !== 'object') return JSON.stringify(v);\n if (Array.isArray(v)) return `[${v.map(stableStringify).join(',')}]`;\n const obj = v as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const parts = keys.map(k => `${JSON.stringify(k)}:${stableStringify(obj[k])}`);\n return `{${parts.join(',')}}`;\n}\n\ninterface DeterministicSeed {\n next: () => number;\n}\n\nfunction seedFromString(key: string): DeterministicSeed {\n // SHA-256 → 4-byte uint32 stream. Stable across Node versions; storyboards\n // can assert exact numbers without flake.\n const digest = createHash('sha256').update(key).digest();\n let offset = 0;\n return {\n next: () => {\n if (offset + 4 > digest.length) {\n const extended = createHash('sha256').update(digest).digest();\n digest.set(extended);\n offset = 0;\n }\n const v = digest.readUInt32BE(offset);\n offset += 4;\n return v;\n },\n };\n}\n"],"mappings":"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","names":["url"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/mock-server/sales-social/server.ts"],"sourcesContent":["import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { createHash, randomUUID } from 'node:crypto';\nimport {\n ACCESS_TOKEN_TTL_SECONDS,\n ADVERTISERS,\n OAUTH_CLIENTS,\n REFRESH_TOKEN_TTL_SECONDS,\n type MockAdvertiser,\n type MockOAuthClient,\n} from './seed-data';\nimport {\n createMockScenarioController,\n idempotencyKeyFromBody,\n stableFingerprint,\n writeCachedResponse,\n type MockScenarioHandle,\n} from '../scenario';\n\nexport interface BootOptions {\n port: number;\n /** Override seed data. */\n advertisers?: MockAdvertiser[];\n oauthClients?: MockOAuthClient[];\n /** Force-set access-token TTL for testing the refresh path. Defaults to\n * the seed value (3600s). Set to a small number (e.g. 5) to make every\n * subsequent request require a refresh. */\n accessTokenTtlSeconds?: number;\n}\n\nexport interface BootResult {\n url: string;\n close: () => Promise<void>;\n scenario: MockScenarioHandle;\n}\n\ninterface IssuedAccessToken {\n access_token: string;\n refresh_token: string;\n client_id: string;\n expires_at_ms: number;\n refresh_expires_at_ms: number;\n}\n\ninterface AudienceState {\n audience_id: string;\n advertiser_id: string;\n name: string;\n description?: string;\n source_type: string;\n member_count: number;\n status: 'building' | 'active' | 'expired' | 'error';\n created_at: string;\n updated_at: string;\n body_fingerprint: string;\n}\n\ninterface CatalogState {\n catalog_id: string;\n advertiser_id: string;\n name: string;\n vertical: string;\n status: 'active' | 'processing' | 'error';\n item_count: number;\n body_fingerprint: string;\n}\n\ninterface CreativeState {\n creative_id: string;\n advertiser_id: string;\n name: string;\n format_id: string;\n primary_text: string;\n cta_label?: string;\n landing_page_url: string;\n media_url: string;\n status: 'pending_review' | 'approved' | 'rejected' | 'archived';\n created_at: string;\n body_fingerprint: string;\n}\n\ninterface PixelState {\n pixel_id: string;\n advertiser_id: string;\n name: string;\n domain?: string;\n status: 'active' | 'paused';\n events_received_24h: number;\n created_at: string;\n body_fingerprint: string;\n}\n\nexport async function bootSalesSocial(options: BootOptions): Promise<BootResult> {\n const advertisers = options.advertisers ?? ADVERTISERS;\n const oauthClients = options.oauthClients ?? OAUTH_CLIENTS;\n const accessTtl = options.accessTokenTtlSeconds ?? ACCESS_TOKEN_TTL_SECONDS;\n\n const tokensByAccess = new Map<string, IssuedAccessToken>();\n const tokensByRefresh = new Map<string, IssuedAccessToken>();\n\n // Per-advertiser resource state.\n const audiences = new Map<string, AudienceState>();\n const catalogs = new Map<string, CatalogState>();\n const creatives = new Map<string, CreativeState>();\n const pixels = new Map<string, PixelState>();\n\n // Idempotency tables — keyed `<advertiser_id>::<resource_kind>::<client_request_id>`\n // so cross-advertiser collisions are isolated.\n const idempotency = new Map<string, string>();\n\n // Traffic counters keyed by `<METHOD> <route-template>`. The harness queries\n // `GET /_debug/traffic` after a storyboard run and asserts the headline\n // endpoints (custom_audience/upload, event/track, etc.) were called ≥1 time.\n // Façade adapters that never call upstream produce zero counters and fail\n // the assertion — façade detection without depending on storyboard data\n // shape. See adcontextprotocol/adcp-client#1225.\n const traffic = new Map<string, number>();\n function bump(routeTemplate: string): void {\n traffic.set(routeTemplate, (traffic.get(routeTemplate) ?? 0) + 1);\n }\n const scenario = createMockScenarioController({\n specialism: 'sales-social',\n snapshot: () => ({\n audiences: audiences.size,\n catalogs: catalogs.size,\n creatives: creatives.size,\n pixels: pixels.size,\n idempotency: idempotency.size,\n tokens: tokensByAccess.size,\n traffic: Object.fromEntries(traffic),\n }),\n reset: () => {\n tokensByAccess.clear();\n tokensByRefresh.clear();\n audiences.clear();\n catalogs.clear();\n creatives.clear();\n pixels.clear();\n idempotency.clear();\n traffic.clear();\n },\n });\n\n function issueTokens(client: MockOAuthClient): IssuedAccessToken {\n const now = Date.now();\n const t: IssuedAccessToken = {\n access_token: `tok_${randomUUID().replace(/-/g, '').slice(0, 24)}`,\n refresh_token: `rfr_${randomUUID().replace(/-/g, '').slice(0, 24)}`,\n client_id: client.client_id,\n expires_at_ms: now + accessTtl * 1000,\n refresh_expires_at_ms: now + REFRESH_TOKEN_TTL_SECONDS * 1000,\n };\n tokensByAccess.set(t.access_token, t);\n tokensByRefresh.set(t.refresh_token, t);\n return t;\n }\n\n function authenticatedClient(req: IncomingMessage): MockOAuthClient | null {\n const auth = req.headers['authorization'];\n if (!auth || !auth.startsWith('Bearer ')) return null;\n const accessToken = auth.slice(7);\n const issued = tokensByAccess.get(accessToken);\n if (!issued) return null;\n if (issued.expires_at_ms < Date.now()) return null;\n return oauthClients.find(c => c.client_id === issued.client_id) ?? null;\n }\n\n const server = createServer((req, res) => {\n handleRequest(req, res).catch(err => {\n const requestId = (req.headers['x-request-id'] as string | undefined) ?? randomUUID();\n writeJson(res, 500, {\n code: 'internal_error',\n message: err?.message ?? 'unexpected error',\n request_id: requestId,\n });\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(options.port, '127.0.0.1', () => {\n server.removeListener('error', reject);\n resolve();\n });\n });\n\n const addr = server.address();\n const boundPort = typeof addr === 'object' && addr ? addr.port : options.port;\n const url = `http://127.0.0.1:${boundPort}`;\n\n return {\n url,\n scenario: scenario.handle,\n close: () =>\n new Promise<void>((resolve, reject) => {\n server.close(err => (err ? reject(err) : resolve()));\n }),\n };\n\n // ────────────────────────────────────────────────────────────\n // Top-level request dispatcher\n // ────────────────────────────────────────────────────────────\n async function handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url ?? '/', `http://127.0.0.1`);\n const path = url.pathname;\n const method = req.method ?? 'GET';\n\n if (await scenario.handleControlRequest(req, res, method, path)) return;\n\n // Façade-detection traffic dump — harness-only, no auth required.\n // Returns per-endpoint hit counts for assertion in the matrix runner.\n if (method === 'GET' && path === '/_debug/traffic') {\n writeJson(res, 200, { traffic: Object.fromEntries(traffic) });\n return;\n }\n\n // OAuth token endpoint — no Bearer required.\n if (method === 'POST' && path === '/oauth/token') {\n bump('POST /oauth/token');\n return handleOauthToken(req, res);\n }\n\n // Discovery endpoint — replaces the hardcoded principal-mapping table\n // the harness used to inline into Claude's prompt. Adapters look up the\n // upstream advertiser_id at runtime by querying with the AdCP-side\n // identifier they receive from buyers (`account.advertiser`,\n // `account.brand.domain`, etc.). No auth required — discovery is the\n // entry point before the agent has any account context. Issue #1225.\n if (method === 'GET' && path === '/_lookup/advertiser') {\n bump('GET /_lookup/advertiser');\n const adcpAdvertiser = url.searchParams.get('adcp_advertiser');\n if (!adcpAdvertiser) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'adcp_advertiser query parameter is required.',\n });\n return;\n }\n const match = advertisers.find(a => a.adcp_advertiser === adcpAdvertiser);\n if (!match) {\n writeJson(res, 404, {\n code: 'advertiser_not_found',\n message: `No upstream advertiser registered for adcp_advertiser=${adcpAdvertiser}.`,\n });\n return;\n }\n writeJson(res, 200, {\n adcp_advertiser: match.adcp_advertiser,\n advertiser_id: match.advertiser_id,\n display_name: match.display_name,\n });\n return;\n }\n\n // Everything else requires a valid access token.\n const client = authenticatedClient(req);\n if (!client) {\n writeJson(res, 401, {\n code: 'unauthorized',\n message: 'Missing, invalid, or expired bearer token. Acquire one via POST /oauth/token.',\n });\n return;\n }\n\n // Path-based advertiser scoping.\n const advMatch = path.match(/^\\/v1\\.3\\/advertiser\\/([^/]+)(\\/.*)?$/);\n if (!advMatch || !advMatch[1]) {\n writeJson(res, 404, { code: 'not_found', message: `No route for ${method} ${path}` });\n return;\n }\n const advertiserId = decodeURIComponent(advMatch[1]);\n const subPath = advMatch[2] ?? '/';\n const advertiser = advertisers.find(a => a.advertiser_id === advertiserId);\n if (!advertiser) {\n writeJson(res, 404, {\n code: 'advertiser_not_found',\n message: `Advertiser ${advertiserId} not found.`,\n });\n return;\n }\n if (!client.authorized_advertiser_ids.includes(advertiserId)) {\n writeJson(res, 404, {\n code: 'advertiser_not_authorized',\n message: `Advertiser ${advertiserId} not visible to this OAuth client.`,\n });\n return;\n }\n\n if (await scenario.handleScriptedResponse(res, method, path, (m, p) => bump(`${m} ${p}`))) return;\n\n // Sub-path routing — bump traffic counters on each route hit so\n // /_debug/traffic can later report which endpoints the adapter actually\n // exercised. Façade adapters return shape-valid AdCP responses without\n // calling these endpoints; the harness's post-run check catches that.\n if (method === 'GET' && subPath === '/info') {\n bump('GET /v1.3/advertiser/{id}/info');\n return handleGetAdvertiser(advertiser, res);\n }\n\n // Audiences\n if (method === 'GET' && subPath === '/custom_audience/list') {\n bump('GET /v1.3/advertiser/{id}/custom_audience/list');\n return handleListAudiences(advertiser, res);\n }\n if (method === 'POST' && subPath === '/custom_audience/create') {\n bump('POST /v1.3/advertiser/{id}/custom_audience/create');\n return handleCreateAudience(req, advertiser, res);\n }\n if (method === 'POST' && subPath === '/custom_audience/upload') {\n bump('POST /v1.3/advertiser/{id}/custom_audience/upload');\n return handleUploadAudience(req, advertiser, res);\n }\n\n // Catalogs\n if (method === 'GET' && subPath === '/catalog/list') {\n bump('GET /v1.3/advertiser/{id}/catalog/list');\n return handleListCatalogs(advertiser, res);\n }\n if (method === 'POST' && subPath === '/catalog/create') {\n bump('POST /v1.3/advertiser/{id}/catalog/create');\n return handleCreateCatalog(req, advertiser, res);\n }\n if (method === 'POST' && subPath === '/catalog/upload') {\n bump('POST /v1.3/advertiser/{id}/catalog/upload');\n return handleUploadCatalog(req, advertiser, res);\n }\n\n // Creatives\n if (method === 'GET' && subPath === '/creative/list') {\n bump('GET /v1.3/advertiser/{id}/creative/list');\n return handleListCreatives(advertiser, res);\n }\n if (method === 'POST' && subPath === '/creative/create') {\n bump('POST /v1.3/advertiser/{id}/creative/create');\n return handleCreateCreative(req, advertiser, res);\n }\n\n // Pixels (event sources)\n if (method === 'GET' && subPath === '/pixel/list') {\n bump('GET /v1.3/advertiser/{id}/pixel/list');\n return handleListPixels(advertiser, res);\n }\n if (method === 'POST' && subPath === '/pixel/create') {\n bump('POST /v1.3/advertiser/{id}/pixel/create');\n return handleCreatePixel(req, advertiser, res);\n }\n\n // Conversion API\n if (method === 'POST' && subPath === '/event/track') {\n bump('POST /v1.3/advertiser/{id}/event/track');\n return handleTrackEvents(req, advertiser, res);\n }\n\n // Planning surface — Meta/TikTok-style delivery + reach forecasts.\n // adcontextprotocol/adcp-client#1378.\n if (method === 'POST' && subPath === '/delivery_estimate') {\n bump('POST /v1.3/advertiser/{id}/delivery_estimate');\n return handleDeliveryEstimate(req, advertiser, res);\n }\n if (method === 'POST' && subPath === '/audience_reach_estimate') {\n bump('POST /v1.3/advertiser/{id}/audience_reach_estimate');\n return handleAudienceReachEstimate(req, advertiser, res);\n }\n const lookalikeMatch = subPath.match(/^\\/audience\\/([^/]+)\\/lookalike$/);\n if (method === 'POST' && lookalikeMatch && lookalikeMatch[1]) {\n bump('POST /v1.3/advertiser/{id}/audience/{audience_id}/lookalike');\n return handleLookalikeEstimate(req, advertiser, decodeURIComponent(lookalikeMatch[1]), res);\n }\n\n writeJson(res, 404, { code: 'not_found', message: `No route for ${method} ${path}` });\n }\n\n // ────────────────────────────────────────────────────────────\n // OAuth handler\n // ────────────────────────────────────────────────────────────\n async function handleOauthToken(req: IncomingMessage, res: ServerResponse): Promise<void> {\n let body: Record<string, string>;\n try {\n body = await readForm(req);\n } catch {\n writeJson(res, 400, { code: 'invalid_request', message: 'Body must be application/x-www-form-urlencoded.' });\n return;\n }\n const grantType = body.grant_type;\n if (grantType === 'client_credentials') {\n const client = oauthClients.find(c => c.client_id === body.client_id);\n if (!client || client.client_secret !== body.client_secret) {\n writeJson(res, 400, { code: 'invalid_client', message: 'Unknown client_id or wrong client_secret.' });\n return;\n }\n const t = issueTokens(client);\n writeJson(res, 200, {\n access_token: t.access_token,\n refresh_token: t.refresh_token,\n token_type: 'bearer',\n expires_in: Math.max(0, Math.floor((t.expires_at_ms - Date.now()) / 1000)),\n });\n return;\n }\n if (grantType === 'refresh_token') {\n const refreshToken = body.refresh_token;\n const issued = refreshToken ? tokensByRefresh.get(refreshToken) : undefined;\n if (!issued || issued.refresh_expires_at_ms < Date.now()) {\n writeJson(res, 400, { code: 'invalid_grant', message: 'Unknown or expired refresh_token.' });\n return;\n }\n const client = oauthClients.find(c => c.client_id === issued.client_id);\n if (!client) {\n writeJson(res, 400, { code: 'invalid_grant', message: 'Refresh token references a vanished client.' });\n return;\n }\n // Rotate: invalidate old refresh, issue new pair.\n tokensByRefresh.delete(refreshToken!);\n tokensByAccess.delete(issued.access_token);\n const t = issueTokens(client);\n writeJson(res, 200, {\n access_token: t.access_token,\n refresh_token: t.refresh_token,\n token_type: 'bearer',\n expires_in: Math.max(0, Math.floor((t.expires_at_ms - Date.now()) / 1000)),\n });\n return;\n }\n writeJson(res, 400, {\n code: 'unsupported_grant_type',\n message: `grant_type must be one of: client_credentials, refresh_token. Got: ${grantType}`,\n });\n }\n\n // ────────────────────────────────────────────────────────────\n // Advertiser handler\n // ────────────────────────────────────────────────────────────\n function handleGetAdvertiser(advertiser: MockAdvertiser, res: ServerResponse): void {\n writeJson(res, 200, advertiser);\n }\n\n // ────────────────────────────────────────────────────────────\n // Audience handlers\n // ────────────────────────────────────────────────────────────\n function handleListAudiences(advertiser: MockAdvertiser, res: ServerResponse): void {\n const list = Array.from(audiences.values()).filter(a => a.advertiser_id === advertiser.advertiser_id);\n writeJson(res, 200, { audiences: list.map(stripBodyFingerprint) });\n }\n\n async function handleCreateAudience(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const exactReplay = scenario.idempotency.check(\n `${advertiser.advertiser_id}::audience`,\n idempotencyKeyFromBody(body),\n stableFingerprint(body)\n );\n if (exactReplay.kind === 'replay' || exactReplay.kind === 'conflict') {\n writeCachedResponse(res, exactReplay.response);\n return;\n }\n const { name, description, source_type, client_request_id } = body as Record<string, unknown>;\n if (typeof name !== 'string' || typeof source_type !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'name and source_type are required strings.' });\n return;\n }\n const validSources = ['customer_file', 'website_traffic', 'app_activity', 'lookalike', 'engagement'];\n if (!validSources.includes(source_type)) {\n writeJson(res, 400, {\n code: 'invalid_source_type',\n message: `source_type must be one of ${validSources.join(', ')}.`,\n });\n return;\n }\n const fingerprint = JSON.stringify({ name, description, source_type });\n const replay = checkIdempotentReplay(advertiser.advertiser_id, 'audience', client_request_id, fingerprint);\n if (replay.kind === 'conflict') {\n writeJson(res, 409, { code: 'idempotency_conflict', message: replay.message });\n return;\n }\n if (replay.kind === 'replay') {\n const existing = audiences.get(replay.id);\n if (existing) {\n writeJson(res, 200, stripBodyFingerprint(existing));\n return;\n }\n }\n const id = `ca_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n const now = new Date().toISOString();\n const audience: AudienceState = {\n audience_id: id,\n advertiser_id: advertiser.advertiser_id,\n name,\n description: typeof description === 'string' ? description : undefined,\n source_type,\n member_count: 0,\n status: 'building',\n created_at: now,\n updated_at: now,\n body_fingerprint: fingerprint,\n };\n audiences.set(id, audience);\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n idempotency.set(`${advertiser.advertiser_id}::audience::${client_request_id}`, id);\n }\n const responseBody = stripBodyFingerprint(audience);\n if (exactReplay.kind === 'fresh') exactReplay.record({ status: 201, body: responseBody });\n writeJson(res, 201, responseBody);\n }\n\n async function handleUploadAudience(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const { audience_id, identifier_type, members } = body as Record<string, unknown>;\n if (typeof audience_id !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'audience_id is required.' });\n return;\n }\n const aud = audiences.get(audience_id);\n if (!aud || aud.advertiser_id !== advertiser.advertiser_id) {\n writeJson(res, 404, { code: 'audience_not_found', message: `Audience ${audience_id} not found.` });\n return;\n }\n const validIds = [\n 'hashed_email_sha256',\n 'hashed_phone_sha256',\n 'hashed_email_or_phone_sha256',\n 'mobile_advertising_id',\n ];\n if (typeof identifier_type !== 'string' || !validIds.includes(identifier_type)) {\n writeJson(res, 400, {\n code: 'invalid_identifier_type',\n message: `identifier_type must be one of ${validIds.join(', ')}.`,\n });\n return;\n }\n if (!Array.isArray(members) || members.length === 0) {\n writeJson(res, 400, { code: 'empty_members', message: 'members must be a non-empty array.' });\n return;\n }\n if (identifier_type.startsWith('hashed_')) {\n const hashRe = /^[0-9a-f]{64}$/;\n const malformed = members.filter(m => typeof m !== 'string' || !hashRe.test(m));\n if (malformed.length > 0) {\n // Real walled gardens reject silently per-row in batch but for the\n // test fixture we hard-fail on any malformed — adapter bugs that\n // pass raw PII or wrong-cased hex get surfaced loudly.\n writeJson(res, 400, {\n code: 'invalid_hash_format',\n message:\n `${malformed.length} member(s) are not 64-char lowercase hex. Walled gardens require ` +\n `client-side SHA-256 hashing of the lowercased trimmed identifier; uploading raw PII is rejected.`,\n });\n return;\n }\n }\n aud.member_count += members.length;\n aud.status = 'active';\n aud.updated_at = new Date().toISOString();\n writeJson(res, 202, {\n audience_id,\n status: aud.status,\n batch_size: members.length,\n });\n }\n\n // ────────────────────────────────────────────────────────────\n // Catalog handlers\n // ────────────────────────────────────────────────────────────\n function handleListCatalogs(advertiser: MockAdvertiser, res: ServerResponse): void {\n const list = Array.from(catalogs.values()).filter(c => c.advertiser_id === advertiser.advertiser_id);\n writeJson(res, 200, { catalogs: list.map(stripBodyFingerprint) });\n }\n\n async function handleCreateCatalog(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const exactReplay = scenario.idempotency.check(\n `${advertiser.advertiser_id}::catalog`,\n idempotencyKeyFromBody(body),\n stableFingerprint(body)\n );\n if (exactReplay.kind === 'replay' || exactReplay.kind === 'conflict') {\n writeCachedResponse(res, exactReplay.response);\n return;\n }\n const { name, vertical, client_request_id } = body as Record<string, unknown>;\n if (typeof name !== 'string' || typeof vertical !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'name and vertical are required.' });\n return;\n }\n const fingerprint = JSON.stringify({ name, vertical });\n const replay = checkIdempotentReplay(advertiser.advertiser_id, 'catalog', client_request_id, fingerprint);\n if (replay.kind === 'conflict') {\n writeJson(res, 409, { code: 'idempotency_conflict', message: replay.message });\n return;\n }\n if (replay.kind === 'replay') {\n const existing = catalogs.get(replay.id);\n if (existing) {\n writeJson(res, 200, stripBodyFingerprint(existing));\n return;\n }\n }\n const id = `cat_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n const cat: CatalogState = {\n catalog_id: id,\n advertiser_id: advertiser.advertiser_id,\n name,\n vertical,\n status: 'active',\n item_count: 0,\n body_fingerprint: fingerprint,\n };\n catalogs.set(id, cat);\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n idempotency.set(`${advertiser.advertiser_id}::catalog::${client_request_id}`, id);\n }\n const responseBody = stripBodyFingerprint(cat);\n if (exactReplay.kind === 'fresh') exactReplay.record({ status: 201, body: responseBody });\n writeJson(res, 201, responseBody);\n }\n\n async function handleUploadCatalog(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const { catalog_id, items } = body as Record<string, unknown>;\n if (typeof catalog_id !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'catalog_id is required.' });\n return;\n }\n const cat = catalogs.get(catalog_id);\n if (!cat || cat.advertiser_id !== advertiser.advertiser_id) {\n writeJson(res, 404, { code: 'catalog_not_found', message: `Catalog ${catalog_id} not found.` });\n return;\n }\n if (!Array.isArray(items) || items.length === 0) {\n writeJson(res, 400, { code: 'empty_items', message: 'items must be a non-empty array.' });\n return;\n }\n cat.item_count += items.length;\n writeJson(res, 202, { catalog_id, batch_size: items.length });\n }\n\n // ────────────────────────────────────────────────────────────\n // Creative handlers\n // ────────────────────────────────────────────────────────────\n function handleListCreatives(advertiser: MockAdvertiser, res: ServerResponse): void {\n const list = Array.from(creatives.values()).filter(c => c.advertiser_id === advertiser.advertiser_id);\n writeJson(res, 200, { creatives: list.map(stripBodyFingerprint) });\n }\n\n async function handleCreateCreative(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const exactReplay = scenario.idempotency.check(\n `${advertiser.advertiser_id}::creative`,\n idempotencyKeyFromBody(body),\n stableFingerprint(body)\n );\n if (exactReplay.kind === 'replay' || exactReplay.kind === 'conflict') {\n writeCachedResponse(res, exactReplay.response);\n return;\n }\n const { name, format_id, primary_text, cta_label, landing_page_url, media_url, client_request_id } = body as Record<\n string,\n unknown\n >;\n if (\n typeof name !== 'string' ||\n typeof format_id !== 'string' ||\n typeof primary_text !== 'string' ||\n typeof landing_page_url !== 'string' ||\n typeof media_url !== 'string'\n ) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'name, format_id, primary_text, landing_page_url, media_url are all required strings.',\n });\n return;\n }\n const validFormats = ['native_feed', 'story_video', 'vertical_video', 'carousel_image'];\n if (!validFormats.includes(format_id)) {\n writeJson(res, 400, { code: 'invalid_format', message: `format_id must be one of ${validFormats.join(', ')}.` });\n return;\n }\n const fingerprint = JSON.stringify({ name, format_id, primary_text, cta_label, landing_page_url, media_url });\n const replay = checkIdempotentReplay(advertiser.advertiser_id, 'creative', client_request_id, fingerprint);\n if (replay.kind === 'conflict') {\n writeJson(res, 409, { code: 'idempotency_conflict', message: replay.message });\n return;\n }\n if (replay.kind === 'replay') {\n const existing = creatives.get(replay.id);\n if (existing) {\n writeJson(res, 200, stripBodyFingerprint(existing));\n return;\n }\n }\n const id = `cr_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n const cr: CreativeState = {\n creative_id: id,\n advertiser_id: advertiser.advertiser_id,\n name,\n format_id,\n primary_text,\n cta_label: typeof cta_label === 'string' ? cta_label : undefined,\n landing_page_url,\n media_url,\n status: 'pending_review',\n created_at: new Date().toISOString(),\n body_fingerprint: fingerprint,\n };\n creatives.set(id, cr);\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n idempotency.set(`${advertiser.advertiser_id}::creative::${client_request_id}`, id);\n }\n const responseBody = stripBodyFingerprint(cr);\n if (exactReplay.kind === 'fresh') exactReplay.record({ status: 201, body: responseBody });\n writeJson(res, 201, responseBody);\n }\n\n // ────────────────────────────────────────────────────────────\n // Pixel handlers\n // ────────────────────────────────────────────────────────────\n function handleListPixels(advertiser: MockAdvertiser, res: ServerResponse): void {\n const list = Array.from(pixels.values()).filter(p => p.advertiser_id === advertiser.advertiser_id);\n writeJson(res, 200, { pixels: list.map(stripBodyFingerprint) });\n }\n\n async function handleCreatePixel(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const exactReplay = scenario.idempotency.check(\n `${advertiser.advertiser_id}::pixel`,\n idempotencyKeyFromBody(body),\n stableFingerprint(body)\n );\n if (exactReplay.kind === 'replay' || exactReplay.kind === 'conflict') {\n writeCachedResponse(res, exactReplay.response);\n return;\n }\n const { name, domain, client_request_id } = body as Record<string, unknown>;\n if (typeof name !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'name is required.' });\n return;\n }\n const fingerprint = JSON.stringify({ name, domain });\n const replay = checkIdempotentReplay(advertiser.advertiser_id, 'pixel', client_request_id, fingerprint);\n if (replay.kind === 'conflict') {\n writeJson(res, 409, { code: 'idempotency_conflict', message: replay.message });\n return;\n }\n if (replay.kind === 'replay') {\n const existing = pixels.get(replay.id);\n if (existing) {\n writeJson(res, 200, stripBodyFingerprint(existing));\n return;\n }\n }\n const id = `px_${randomUUID().replace(/-/g, '').slice(0, 16)}`;\n const px: PixelState = {\n pixel_id: id,\n advertiser_id: advertiser.advertiser_id,\n name,\n domain: typeof domain === 'string' ? domain : undefined,\n status: 'active',\n events_received_24h: 0,\n created_at: new Date().toISOString(),\n body_fingerprint: fingerprint,\n };\n pixels.set(id, px);\n if (typeof client_request_id === 'string' && client_request_id.length > 0) {\n idempotency.set(`${advertiser.advertiser_id}::pixel::${client_request_id}`, id);\n }\n const responseBody = stripBodyFingerprint(px);\n if (exactReplay.kind === 'fresh') exactReplay.record({ status: 201, body: responseBody });\n writeJson(res, 201, responseBody);\n }\n\n // ────────────────────────────────────────────────────────────\n // Conversion API (events) handler\n // ────────────────────────────────────────────────────────────\n async function handleTrackEvents(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const { pixel_id, events } = body as Record<string, unknown>;\n if (typeof pixel_id !== 'string') {\n writeJson(res, 400, { code: 'invalid_request', message: 'pixel_id is required.' });\n return;\n }\n const px = pixels.get(pixel_id);\n if (!px || px.advertiser_id !== advertiser.advertiser_id) {\n writeJson(res, 404, { code: 'pixel_not_found', message: `Pixel ${pixel_id} not found.` });\n return;\n }\n if (!Array.isArray(events) || events.length === 0) {\n writeJson(res, 400, { code: 'empty_events', message: 'events must be a non-empty array.' });\n return;\n }\n let received = 0;\n let dropped = 0;\n const hashRe = /^[0-9a-f]{64}$/;\n for (const ev of events) {\n if (!ev || typeof ev !== 'object') {\n dropped++;\n continue;\n }\n const event = ev as Record<string, unknown>;\n if (typeof event.event_name !== 'string' || typeof event.event_time !== 'number') {\n dropped++;\n continue;\n }\n const userData = event.user_data as Record<string, unknown> | undefined;\n const hasMatchableId = !!(\n userData &&\n ((typeof userData.email_sha256 === 'string' && hashRe.test(userData.email_sha256)) ||\n (typeof userData.phone_sha256 === 'string' && hashRe.test(userData.phone_sha256)) ||\n (typeof userData.external_id_sha256 === 'string' && hashRe.test(userData.external_id_sha256)))\n );\n if (!hasMatchableId) {\n // Walled gardens reject events without a matchable identifier.\n dropped++;\n continue;\n }\n received++;\n }\n if (received === 0) {\n writeJson(res, 400, {\n code: 'no_matchable_events',\n message:\n `All ${events.length} events were dropped — none carried a hashed identifier ` +\n `(email_sha256, phone_sha256, or external_id_sha256). Walled-garden CAPI requires ` +\n `at least one matchable identifier per event.`,\n });\n return;\n }\n px.events_received_24h += received;\n writeJson(res, 200, { pixel_id, events_received: received, events_dropped: dropped });\n }\n\n // ────────────────────────────────────────────────────────────\n // Planning surface (Meta/TikTok-style forecast endpoints)\n // adcontextprotocol/adcp-client#1378\n // ────────────────────────────────────────────────────────────\n async function handleDeliveryEstimate(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const { targeting, optimization_goal, budget, target_outcome, flight_dates } = body as Record<string, unknown>;\n if (typeof optimization_goal !== 'string') {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'optimization_goal is required (e.g. \"reach\", \"conversions\", \"clicks\", \"video_views\").',\n });\n return;\n }\n if (budget === undefined && target_outcome === undefined) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'Provide either budget (forward forecast) or target_outcome (reverse / goal-based forecast).',\n });\n return;\n }\n if (budget !== undefined && (typeof budget !== 'number' || !Number.isFinite(budget) || budget <= 0)) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'budget must be a positive number.',\n });\n return;\n }\n if (\n target_outcome !== undefined &&\n (typeof target_outcome !== 'number' || !Number.isFinite(target_outcome) || target_outcome <= 0)\n ) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'target_outcome must be a positive number.',\n });\n return;\n }\n const targetingKey = serializeTargeting(targeting);\n const dates = isObject(flight_dates) ? flight_dates : {};\n const estimate = synthDeliveryEstimate({\n advertiserId: advertiser.advertiser_id,\n currency: advertiser.currency,\n targeting: targetingKey,\n optimizationGoal: optimization_goal,\n budget: typeof budget === 'number' ? budget : undefined,\n targetOutcome: typeof target_outcome === 'number' ? target_outcome : undefined,\n flightStart: typeof dates.start === 'string' ? dates.start : undefined,\n flightEnd: typeof dates.end === 'string' ? dates.end : undefined,\n });\n writeJson(res, 200, estimate);\n }\n\n async function handleAudienceReachEstimate(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const { targeting } = body as Record<string, unknown>;\n if (!isObject(targeting)) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'targeting (object) is required — geo, age, interests, custom audiences, etc.',\n });\n return;\n }\n const targetingKey = serializeTargeting(targeting);\n const estimate = synthAudienceReach({\n advertiserId: advertiser.advertiser_id,\n targeting: targetingKey,\n });\n writeJson(res, 200, estimate);\n }\n\n async function handleLookalikeEstimate(\n req: IncomingMessage,\n advertiser: MockAdvertiser,\n audienceId: string,\n res: ServerResponse\n ): Promise<void> {\n const body = await readJsonObject(req, res);\n if (!body) return;\n const seed = audiences.get(audienceId);\n if (!seed || seed.advertiser_id !== advertiser.advertiser_id) {\n writeJson(res, 404, {\n code: 'audience_not_found',\n message: `Seed audience ${audienceId} not found for advertiser ${advertiser.advertiser_id}.`,\n });\n return;\n }\n const { similarity_pct, country } = body as Record<string, unknown>;\n if (typeof similarity_pct !== 'number' || similarity_pct < 1 || similarity_pct > 10) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'similarity_pct must be a number between 1 (closest) and 10 (broadest).',\n });\n return;\n }\n if (typeof country !== 'string' || country.length === 0) {\n writeJson(res, 400, {\n code: 'invalid_request',\n message: 'country (ISO 3166-1 alpha-2) is required — lookalikes are country-scoped.',\n });\n return;\n }\n const estimate = synthLookalikeEstimate({\n advertiserId: advertiser.advertiser_id,\n seedAudienceId: audienceId,\n seedSize: seed.member_count,\n similarityPct: similarity_pct,\n country,\n });\n writeJson(res, 200, estimate);\n }\n\n // ────────────────────────────────────────────────────────────\n // Helpers\n // ────────────────────────────────────────────────────────────\n function checkIdempotentReplay(\n advertiserId: string,\n resourceKind: string,\n clientRequestId: unknown,\n fingerprint: string\n ): { kind: 'replay'; id: string } | { kind: 'conflict'; message: string } | { kind: 'fresh' } {\n if (typeof clientRequestId !== 'string' || clientRequestId.length === 0) return { kind: 'fresh' };\n const key = `${advertiserId}::${resourceKind}::${clientRequestId}`;\n const existingId = idempotency.get(key);\n if (!existingId) return { kind: 'fresh' };\n const stored = lookupResource(resourceKind, existingId);\n if (!stored) return { kind: 'fresh' };\n if (stored.body_fingerprint !== fingerprint) {\n return {\n kind: 'conflict',\n message: `client_request_id ${clientRequestId} was previously used with a different body. Use a fresh idempotency key for distinct requests.`,\n };\n }\n return { kind: 'replay', id: existingId };\n }\n\n function lookupResource(kind: string, id: string): { body_fingerprint: string } | undefined {\n switch (kind) {\n case 'audience':\n return audiences.get(id);\n case 'catalog':\n return catalogs.get(id);\n case 'creative':\n return creatives.get(id);\n case 'pixel':\n return pixels.get(id);\n default:\n return undefined;\n }\n }\n}\n\nfunction stripBodyFingerprint<T extends { body_fingerprint?: string }>(record: T): Omit<T, 'body_fingerprint'> {\n const { body_fingerprint, ...rest } = record;\n return rest;\n}\n\nfunction readForm(req: IncomingMessage): Promise<Record<string, string>> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', c => chunks.push(c));\n req.on('error', reject);\n req.on('end', () => {\n const raw = Buffer.concat(chunks).toString('utf8');\n const out: Record<string, string> = {};\n for (const pair of raw.split('&')) {\n if (!pair) continue;\n const [k, v = ''] = pair.split('=');\n if (k === undefined) continue;\n out[decodeURIComponent(k)] = decodeURIComponent(v.replace(/\\+/g, ' '));\n }\n resolve(out);\n });\n });\n}\n\nasync function readJsonObject(req: IncomingMessage, res: ServerResponse): Promise<Record<string, unknown> | null> {\n let body: unknown;\n try {\n body = await readJson(req);\n } catch {\n writeJson(res, 400, { code: 'invalid_json', message: 'Request body must be valid JSON.' });\n return null;\n }\n if (!body || typeof body !== 'object' || Array.isArray(body)) {\n writeJson(res, 400, { code: 'invalid_request', message: 'Body must be a JSON object.' });\n return null;\n }\n return body as Record<string, unknown>;\n}\n\nfunction readJson(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', c => chunks.push(c));\n req.on('error', reject);\n req.on('end', () => {\n const raw = Buffer.concat(chunks).toString('utf8');\n if (!raw) {\n resolve({});\n return;\n }\n try {\n resolve(JSON.parse(raw));\n } catch (err) {\n reject(err);\n }\n });\n });\n}\n\nfunction writeJson(res: ServerResponse, status: number, body: unknown): void {\n const json = JSON.stringify(body);\n res.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'content-length': Buffer.byteLength(json),\n });\n res.end(json);\n}\n\n// ────────────────────────────────────────────────────────────\n// Deterministic forecast generators (#1378)\n// ────────────────────────────────────────────────────────────\n\ninterface RangeMinMax {\n min: number;\n max: number;\n}\ninterface DeliveryEstimateResponse {\n optimization_goal: string;\n currency: string;\n forecast_range_unit: 'spend' | 'conversions' | 'reach_freq' | 'clicks';\n estimated_daily_reach: RangeMinMax;\n estimated_daily_impressions: RangeMinMax;\n estimated_daily_clicks: RangeMinMax;\n estimated_daily_conversions: RangeMinMax;\n estimated_cpm: { min: number; median: number; max: number };\n bid_recommendation: { low: number; median: number; high: number };\n daily_budget_recommendation: RangeMinMax;\n delivery_curve: Array<{\n daily_budget: number;\n estimated_daily_reach: RangeMinMax;\n estimated_daily_conversions: RangeMinMax;\n }>;\n required_budget?: RangeMinMax;\n /** When the inferred budget falls below the platform learning-phase floor\n * for the chosen optimization_goal, the platform clamps and surfaces a\n * warning. Real Meta enforces $1.05/day for impressions, $5.05/day for\n * clicks, ~$40/day for conversion campaigns; TikTok floors $20/day. The\n * mock surfaces the warning so adopters wire the path before they hit it\n * in production. */\n min_budget_warning?: { floor: number; reason: string };\n generated_at: string;\n}\n\n/** Daily-budget learning-phase floors typical of walled-garden platforms.\n * Bid_strategy and platform vary; these are mid-range defaults adopters\n * can override per-tenant. */\nfunction dailyBudgetFloor(goal: string): number {\n switch (goal) {\n case 'reach':\n case 'awareness':\n case 'video_views':\n case 'thru_play':\n return 5;\n case 'clicks':\n case 'link_clicks':\n case 'traffic':\n case 'engagement':\n case 'follows':\n case 'profile_visits':\n return 10;\n case 'conversions':\n case 'purchase':\n case 'app_install':\n return 40;\n default:\n return 10;\n }\n}\n\nfunction synthDeliveryEstimate(input: {\n advertiserId: string;\n currency: string;\n targeting: string | null;\n optimizationGoal: string;\n budget?: number;\n targetOutcome?: number;\n flightStart?: string;\n flightEnd?: string;\n}): DeliveryEstimateResponse {\n const seedKey = stableStringify({\n advertiserId: input.advertiserId,\n targeting: input.targeting,\n goal: input.optimizationGoal,\n flight: { start: input.flightStart, end: input.flightEnd },\n });\n const seed = seedFromString(seedKey);\n\n // Audience pool size derived from targeting hash. Real Marketing APIs\n // base everything on this number; we anchor here too.\n const audiencePool = 500_000 + (seed.next() % 50_000_000);\n // Saturation rate — what fraction of pool you can reach at infinite spend.\n const saturationCap = 0.55 + (seed.next() % 4001) / 10_000; // [0.55, 0.95]\n // Goal-specific CPM band.\n const cpmBase = goalCpm(input.optimizationGoal, seed);\n\n // Funnel parameters. CTR varies by goal: reach campaigns don't optimize\n // for clicks; clicks campaigns over-index. Conversion rate likewise.\n // Applying a single conversion rate across all goals (the prior shape)\n // produced wrong reverse-forecast budgets for non-conversion goals.\n const ctr = ctrForGoal(input.optimizationGoal, seed);\n const conversionRate = conversionRateForGoal(input.optimizationGoal, seed);\n\n const floor = dailyBudgetFloor(input.optimizationGoal);\n\n // Budget anchor. Forward: caller's budget. Reverse: derive from\n // target_outcome — but the math depends on which goal is being targeted.\n let dailyBudget = input.budget ?? 0;\n let requiredBudget: RangeMinMax | undefined;\n let preClampBudget = 0;\n if (dailyBudget === 0 && input.targetOutcome !== undefined) {\n const goal = input.optimizationGoal;\n let requiredImpressions: number;\n if (goal === 'reach' || goal === 'awareness') {\n // Reverse for reach: invert the saturating curve to find the spend\n // level that hits target_outcome unique users.\n const cap = audiencePool * saturationCap;\n const targetReach = Math.min(input.targetOutcome, cap * 0.99);\n // reach = cap × (1 − e^−impressions/cap) ⇒ impressions = −cap × ln(1 − reach/cap)\n requiredImpressions = -cap * Math.log(1 - targetReach / cap);\n } else if (goal === 'video_views' || goal === 'thru_play') {\n // Roughly 35% completion rate at the goal level; impressions ≈ views/.35\n requiredImpressions = input.targetOutcome / 0.35;\n } else if (goal === 'clicks' || goal === 'link_clicks' || goal === 'traffic') {\n requiredImpressions = input.targetOutcome / Math.max(0.001, ctr);\n } else {\n // conversions / purchase / app_install / engagement etc.\n requiredImpressions = input.targetOutcome / Math.max(ctr * conversionRate * 8, 0.0001);\n }\n dailyBudget = (requiredImpressions / 1000) * cpmBase.median;\n preClampBudget = dailyBudget;\n if (dailyBudget < floor) dailyBudget = floor;\n requiredBudget = { min: Math.floor(dailyBudget * 0.85), max: Math.ceil(dailyBudget * 1.2) };\n }\n if (dailyBudget === 0) dailyBudget = Math.max(floor, 100);\n\n // Saturating-curve: reach grows fast then plateaus at saturationCap × pool.\n const reachAt = (b: number): number => {\n const impressions = (b / cpmBase.median) * 1000;\n const cap = audiencePool * saturationCap;\n const ratePer = impressions / Math.max(1, cap);\n return Math.floor(cap * (1 - Math.exp(-ratePer)));\n };\n\n const dailyReach = reachAt(dailyBudget);\n const dailyImpressions = Math.floor((dailyBudget / cpmBase.median) * 1000);\n const dailyClicks = Math.floor(dailyImpressions * ctr);\n const dailyConversions = Math.floor(dailyClicks * conversionRate * 8); // post-click + view-through\n const rangeUnit: DeliveryEstimateResponse['forecast_range_unit'] =\n input.targetOutcome !== undefined && input.budget === undefined\n ? input.optimizationGoal === 'clicks' ||\n input.optimizationGoal === 'link_clicks' ||\n input.optimizationGoal === 'traffic'\n ? 'clicks'\n : 'conversions' // Reach-goal reverse fits the conversions enum better than reach_freq, which is broadcast-shaped per the AdCP schema.\n : 'spend';\n\n const tiers = [0.5, 1.0, 1.5, 2.5, 4.0].map(m => Math.round(dailyBudget * m));\n // Tighten ranges to ±15-30% (was ±60% min / ±10% max) — real walled-garden\n // delivery_estimate ranges are ±25-35% per recent benchmarks.\n const deliveryCurve = tiers.map(t => ({\n daily_budget: t,\n estimated_daily_reach: { min: Math.floor(reachAt(t) * 0.78), max: Math.floor(reachAt(t) * 1.18) },\n estimated_daily_conversions: {\n min: Math.floor((t / cpmBase.median) * 1000 * ctr * conversionRate * 8 * 0.78),\n max: Math.floor((t / cpmBase.median) * 1000 * ctr * conversionRate * 8 * 1.22),\n },\n }));\n\n const minBudgetWarning =\n preClampBudget > 0 && preClampBudget < floor\n ? {\n floor,\n reason: `Inferred budget ${round2(preClampBudget)} ${input.currency}/day below platform learning-phase floor for ${input.optimizationGoal} (${floor} ${input.currency}/day); clamped.`,\n }\n : undefined;\n\n return {\n optimization_goal: input.optimizationGoal,\n currency: input.currency,\n forecast_range_unit: rangeUnit,\n estimated_daily_reach: { min: Math.floor(dailyReach * 0.78), max: Math.floor(dailyReach * 1.18) },\n estimated_daily_impressions: {\n min: Math.floor(dailyImpressions * 0.78),\n max: Math.floor(dailyImpressions * 1.18),\n },\n estimated_daily_clicks: { min: Math.floor(dailyClicks * 0.78), max: Math.floor(dailyClicks * 1.22) },\n estimated_daily_conversions: {\n min: Math.floor(dailyConversions * 0.75),\n max: Math.floor(dailyConversions * 1.25),\n },\n estimated_cpm: cpmBase,\n bid_recommendation: {\n low: round2(cpmBase.median * 0.75),\n median: round2(cpmBase.median),\n high: round2(cpmBase.median * 1.35),\n },\n daily_budget_recommendation: {\n min: Math.max(floor, Math.floor(dailyBudget * 0.5)),\n max: Math.ceil(dailyBudget * 2),\n },\n delivery_curve: deliveryCurve,\n ...(requiredBudget && { required_budget: requiredBudget }),\n ...(minBudgetWarning && { min_budget_warning: minBudgetWarning }),\n generated_at: '2026-04-01T00:00:00.000Z',\n };\n}\n\nfunction ctrForGoal(goal: string, seed: DeterministicSeed): number {\n const base = (() => {\n switch (goal) {\n case 'reach':\n case 'awareness':\n return 0.003; // 0.3% — reach campaigns don't optimize for clicks\n case 'video_views':\n case 'thru_play':\n return 0.005;\n case 'clicks':\n case 'link_clicks':\n case 'traffic':\n return 0.013; // 1.3% — performance-optimized\n case 'conversions':\n case 'purchase':\n case 'app_install':\n return 0.011;\n case 'engagement':\n case 'follows':\n case 'profile_visits':\n return 0.018; // engagement campaigns get high CTR\n default:\n return 0.008;\n }\n })();\n // ±15% wobble so storyboards stay deterministic but inputs perturb output.\n return base * (0.85 + (seed.next() % 3001) / 10_000);\n}\n\nfunction conversionRateForGoal(goal: string, seed: DeterministicSeed): number {\n const base = (() => {\n switch (goal) {\n case 'conversions':\n case 'purchase':\n return 0.022; // optimization toward purchase tightens funnel\n case 'app_install':\n return 0.028;\n case 'reach':\n case 'awareness':\n return 0.004; // upper-funnel — conversions are incidental\n default:\n return 0.012;\n }\n })();\n return base * (0.85 + (seed.next() % 3001) / 10_000);\n}\n\nfunction goalCpm(goal: string, seed: DeterministicSeed): { min: number; median: number; max: number } {\n // Approximate CPM bands typical of social Marketing APIs in 2024-2026.\n // Reach is cheaper than video (in-stream/feed video CPMs run $8-15);\n // clicks and conversions are top of the band because they buy auction\n // priority for the most contested inventory.\n // Calibrated to 2024-2026 walled-garden benchmarks: reach is cheaper than\n // video CPMs (Meta in-stream/Reels run $11-16; mock weighted toward feed\n // video). Conversions tops the band as auction priority spikes.\n const base = (() => {\n switch (goal) {\n case 'reach':\n case 'awareness':\n return 7;\n case 'video_views':\n case 'thru_play':\n return 10;\n case 'engagement':\n case 'follows':\n case 'profile_visits':\n return 6;\n case 'clicks':\n case 'link_clicks':\n case 'traffic':\n return 11;\n case 'conversions':\n case 'purchase':\n case 'app_install':\n return 18;\n default:\n return 10;\n }\n })();\n // ±15% wobble — narrower than the original ±15% min / 60% max range,\n // matching real walled-garden delivery_estimate jitter (~±10-15% on CPM\n // medians, ±50-60% on min/max bounds).\n const wobble = 0.88 + (seed.next() % 2401) / 10_000; // [0.88, 1.12]\n const median = round2(base * wobble);\n return { min: round2(median * 0.7), median, max: round2(median * 1.45) };\n}\n\ninterface AudienceReachResponse {\n estimated_audience_size: RangeMinMax;\n matchable_size_at_platform: RangeMinMax;\n reach_quality: 'narrow' | 'specific' | 'broad';\n generated_at: string;\n}\n\nfunction synthAudienceReach(input: { advertiserId: string; targeting: string | null }): AudienceReachResponse {\n const seed = seedFromString(stableStringify({ adv: input.advertiserId, t: input.targeting, kind: 'audience_reach' }));\n // Audience pool varies dramatically by targeting tightness.\n const pool = 50_000 + (seed.next() % 80_000_000);\n const matchRate = 0.55 + (seed.next() % 3501) / 10_000; // platform match ~55–90%\n const matchable = Math.floor(pool * matchRate);\n const quality: AudienceReachResponse['reach_quality'] =\n pool < 1_000_000 ? 'narrow' : pool < 10_000_000 ? 'specific' : 'broad';\n return {\n estimated_audience_size: { min: Math.floor(pool * 0.8), max: Math.floor(pool * 1.2) },\n matchable_size_at_platform: { min: Math.floor(matchable * 0.8), max: Math.floor(matchable * 1.2) },\n reach_quality: quality,\n generated_at: '2026-04-01T00:00:00.000Z',\n };\n}\n\ninterface LookalikeResponse {\n seed_audience_id: string;\n similarity_pct: number;\n country: string;\n estimated_size: RangeMinMax;\n activation_eta_hours: number;\n generated_at: string;\n}\n\n/**\n * Approximate adult-internet population by country (rough order-of-magnitude\n * for top markets; default for unmatched). Used to clamp lookalike sizing\n * so a large seed doesn't produce a lookalike larger than the country.\n * Real walled-garden APIs gate lookalikes at country-share boundaries\n * (Meta caps LAL audiences at country_pop × similarity_pct/100).\n */\nfunction countryPopulation(country: string): number {\n // Adult-internet population estimates (mid-2020s, rounded). Numbers don't\n // need to be precise — they only anchor the lookalike sizing cap so the\n // mock doesn't produce 19M LAL audiences from 1M seeds.\n const c = country.toUpperCase();\n switch (c) {\n case 'US':\n return 260_000_000;\n case 'CA':\n return 32_000_000;\n case 'GB':\n case 'UK':\n return 55_000_000;\n case 'DE':\n return 70_000_000;\n case 'FR':\n return 55_000_000;\n case 'JP':\n return 85_000_000;\n case 'AU':\n return 22_000_000;\n case 'BR':\n return 140_000_000;\n case 'IN':\n return 625_000_000;\n case 'MX':\n return 100_000_000;\n default:\n return 25_000_000; // default for smaller markets\n }\n}\n\nfunction synthLookalikeEstimate(input: {\n advertiserId: string;\n seedAudienceId: string;\n seedSize: number;\n similarityPct: number;\n country: string;\n}): LookalikeResponse {\n const seed = seedFromString(\n stableStringify({\n adv: input.advertiserId,\n aud: input.seedAudienceId,\n country: input.country,\n pct: input.similarityPct,\n })\n );\n const pop = countryPopulation(input.country);\n // Meta's LAL math: country_pop × (similarity_pct / 100) is the upper cap.\n // A 1% LAL in the US ≈ 2.6M; a 10% LAL ≈ 26M. We hold sizing well below the\n // cap (`cap * 0.6` × `wobble ∈ [0.85, 1.15]` → max ≈ `cap * 0.69`) so the\n // mock is conservatively realistic — real walled gardens rarely hit the\n // theoretical cap on first generation.\n const cap = Math.floor(pop * (input.similarityPct / 100));\n // Seed-driven contribution as a fallback for small seeds — never exceeds\n // the platform cap.\n const seedContribution = Math.floor(Math.max(1000, input.seedSize) * (8 + input.similarityPct * 8));\n const wobble = 0.85 + (seed.next() % 3001) / 10_000;\n const size = Math.floor(Math.min(cap * 0.6, seedContribution) * wobble);\n // ETA varies by platform: TikTok 1-6h, Meta 4-24h. Mock spans both.\n const eta = 4 + (seed.next() % 21); // 4–24h\n return {\n seed_audience_id: input.seedAudienceId,\n similarity_pct: input.similarityPct,\n country: input.country.toUpperCase(),\n estimated_size: { min: Math.floor(size * 0.85), max: Math.floor(size * 1.15) },\n activation_eta_hours: eta,\n generated_at: '2026-04-01T00:00:00.000Z',\n };\n}\n\nfunction round2(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return Boolean(v) && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction serializeTargeting(t: unknown): string | null {\n if (t === null || t === undefined) return null;\n if (typeof t === 'string') return t;\n try {\n return stableStringify(t);\n } catch {\n return null;\n }\n}\n\n/**\n * Recursive deterministic JSON stringifier — sorts object keys at every\n * depth so two equivalent payloads with different key insertion orders\n * hash identically. Plain `JSON.stringify(t, keys.sort())` only sorts the\n * top level AND treats the array as a key allowlist (silently dropping\n * nested fields).\n */\nfunction stableStringify(v: unknown): string {\n if (v === null || typeof v !== 'object') return JSON.stringify(v);\n if (Array.isArray(v)) return `[${v.map(stableStringify).join(',')}]`;\n const obj = v as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const parts = keys.map(k => `${JSON.stringify(k)}:${stableStringify(obj[k])}`);\n return `{${parts.join(',')}}`;\n}\n\ninterface DeterministicSeed {\n next: () => number;\n}\n\nfunction seedFromString(key: string): DeterministicSeed {\n // SHA-256 → 4-byte uint32 stream. Stable across Node versions; storyboards\n // can assert exact numbers without flake.\n const digest = createHash('sha256').update(key).digest();\n let offset = 0;\n return {\n next: () => {\n if (offset + 4 > digest.length) {\n const extended = createHash('sha256').update(digest).digest();\n digest.set(extended);\n offset = 0;\n }\n const v = digest.readUInt32BE(offset);\n offset += 4;\n return v;\n },\n };\n}\n"],"mappings":"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","names":["url"]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath as __adcpFileURLToPath } from 'node:url';
|
|
2
|
-
import { dirname as __adcpDirname } from 'node:path';
|
|
3
|
-
import { createRequire as __adcpCreateRequire } from 'node:module';
|
|
4
|
-
const __filename = __adcpFileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = __adcpDirname(__filename);
|
|
6
|
-
const require = __adcpCreateRequire(import.meta.url);
|
|
7
1
|
import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
|
|
8
2
|
import { validateHeaderName, validateHeaderValue } from "node:http";
|
|
9
3
|
const WEBHOOK_FETCH_TIMEOUT_MS = 5e3;
|