@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/server/decisioning/account.ts"],"sourcesContent":["/**\n * Account model. Single-level (matches AdCP wire's AccountReference).\n * Platform-internal hierarchies (GAM Network → Advertiser → Order;\n * Spotify Brand → Campaign) are encoded in `metadata`, not in the typed\n * shape. Generic `TCtxMeta` lets platforms type their metadata at the call site.\n *\n * Tenant scoping is expressed by what `accounts.resolve()` returns, not via\n * a multi-level type. Note that resolve is NOT an isolation gate by default:\n * `createTenantStore` resolves the ref the buyer supplies regardless of the\n * caller unless `refAccess: 'auth-scoped'` is set (or a `resolve-presets`\n * guard is composed). See `createTenantStore` and `resolve-presets.ts`.\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\n\nimport type {\n Account as WireAccount,\n AccountAuthorization,\n AccountScope,\n BillingParty,\n BrandReference,\n AccountReference,\n BusinessEntity,\n ExtensionObject,\n PaymentTerms,\n ListAccountsResponse,\n ReportUsageRequest,\n ReportUsageResponse,\n SyncAccountsResponse,\n SyncAccountsSuccess,\n SyncGovernanceRequest,\n SyncGovernanceResponse,\n SyncGovernanceSuccess,\n GetAccountFinancialsRequest,\n GetAccountFinancialsResponse,\n GetAccountFinancialsSuccess,\n} from '../../types/tools.generated';\nimport type { ServerPayload } from '../../types/server-payload';\nimport type { NotificationConfig } from '../../types/v3-1-beta';\nimport type { CursorPage, CursorRequest } from './pagination';\nimport type { AdcpStructuredError } from './async-outcome';\nimport type { AdcpCredential, BuyerAgent } from './buyer-agent';\n\nexport const ACCOUNT_AUTHORIZATION_WIRE_KEYS = [\n 'allowed_tasks',\n 'field_scopes',\n 'scope_name',\n 'read_only',\n] as const satisfies readonly (keyof AccountAuthorization)[];\n\ntype MissingAccountAuthorizationWireKey = Exclude<\n keyof AccountAuthorization,\n (typeof ACCOUNT_AUTHORIZATION_WIRE_KEYS)[number]\n>;\nconst ACCOUNT_AUTHORIZATION_WIRE_KEY_COVERAGE: Record<MissingAccountAuthorizationWireKey, never> = {};\nvoid ACCOUNT_AUTHORIZATION_WIRE_KEY_COVERAGE;\n\ntype WireNotificationConfig = Omit<NotificationConfig, 'authentication'> & {\n authentication?: Omit<NonNullable<NotificationConfig['authentication']>, 'credentials'>;\n};\n\ntype SyncAccountError = Pick<AdcpStructuredError, 'code' | 'message'> &\n Partial<Omit<AdcpStructuredError, 'code' | 'message'>>;\n\nexport type ListAccountsPayload = ServerPayload<ListAccountsResponse>;\nexport type SyncAccountsPayload = ServerPayload<SyncAccountsResponse>;\nexport type SyncAccountsSuccessPayload = ServerPayload<SyncAccountsSuccess>;\nexport type SyncAccountsRow = SyncAccountsSuccess['accounts'][number];\nexport type SyncGovernancePayload = ServerPayload<SyncGovernanceResponse>;\nexport type SyncGovernanceSuccessPayload = ServerPayload<SyncGovernanceSuccess>;\nexport type SyncGovernanceRow = SyncGovernanceSuccess['accounts'][number];\nexport type ReportUsagePayload = ServerPayload<ReportUsageResponse>;\nexport type GetAccountFinancialsPayload = ServerPayload<GetAccountFinancialsResponse>;\nexport type GetAccountFinancialsSuccessPayload = ServerPayload<GetAccountFinancialsSuccess>;\nexport type ListAccountsHandlerResult<TCtxMeta = Record<string, unknown>> = CursorPage<Account<TCtxMeta>>;\nexport type SyncAccountsHandlerResult = SyncAccountsResultRow[];\nexport type SyncGovernanceHandlerResult = SyncGovernanceRow[];\nexport type ReportUsageHandlerResult = ReportUsagePayload;\nexport type GetAccountFinancialsHandlerResult = GetAccountFinancialsSuccessPayload;\n\n/**\n * Account — framework's rich representation. A strict superset of the wire\n * `Account` shape (from `list_accounts` / response envelopes):\n *\n * - Adds `metadata: TCtxMeta` (platform-internal fields the framework doesn't\n * read but adopters use to thread platform-specific data)\n * - Adds `authInfo: AuthPrincipal` (auth context for the request — MUST NOT\n * leak to the wire)\n * - All wire-required fields (`id`/`account_id`, `name`, `status`) are\n * required here too.\n *\n * Framework projects to wire shape via `toWireAccount`: strips `metadata` +\n * `authInfo`, renames `id` → `account_id`. ~10 lines, no `as never` casts.\n */\nexport interface Account<TCtxMeta = Record<string, unknown>> {\n /** Your platform's account_id. Maps to wire `Account.account_id`. */\n id: string;\n\n /** Human-readable account name (e.g., 'Acme', 'Acme c/o Pinnacle'). Required on the wire. */\n name: string;\n\n /** Account status. Maps to wire `Account.status`. */\n status: AdcpAccountStatus;\n\n /** Canonical brand reference. Either id OR (brand+operator) identifies the account. */\n brand?: BrandReference;\n\n /** Operator domain (agency / managed-services). Pairs with `brand`. */\n operator?: string;\n\n /**\n * The advertiser whose rates apply to this account. Maps to wire\n * `Account.advertiser`. Use when the account is operated by an agency on\n * behalf of an advertiser whose rates differ from the operator's.\n */\n advertiser?: string;\n\n /**\n * Optional intermediary who receives invoices on behalf of the advertiser\n * (e.g., agency holdco). Distinct from `advertiser` (whose rates apply)\n * and from `billing.invoicedTo` (the legal billing party). Use when the\n * invoice recipient differs from both — common in agency-handled flows.\n */\n billing_proxy?: string;\n\n /**\n * Settlement boundary for operator-billed retail-media platforms.\n * `'agent'` = pass-through (buyer's agent settles directly with the platform).\n * `'operator'` = retail-media model (operator pays publisher, bills brand).\n * `BrandReference` = invoice routes to a third party (Amazon DSP returning\n * a different invoice principal than the requester is the canonical case).\n *\n * Optional — most platforms don't need this; comply storyboards use it to\n * assert the right party is billed.\n */\n billing?: { invoicedTo: 'agent' | 'operator' | BrandReference };\n\n /**\n * Business entity invoiced on this account. Carries legal name, tax IDs,\n * address, contacts, and (write-only) bank details for B2B invoicing.\n *\n * **`bank` is write-only.** The wire schema marks `BusinessEntity.bank` as\n * MUST NOT be echoed in responses (sellers store and confirm receipt\n * without returning the details). `toWireAccount` strips it on emit, so\n * adopters who store the full entity here will not leak bank details to\n * buyers — but DO NOT rely on the strip for anything beyond response\n * projection. Adopters loading the entity from their own DB SHOULD apply\n * the same rule at retrieval time, especially for non-list endpoints.\n */\n billing_entity?: BusinessEntity;\n\n /**\n * Identifier for the rate card applied to this account. Opaque seller-side\n * string; emitted unchanged on the wire.\n */\n rate_card?: string;\n\n /** Payment terms applied to this account. */\n payment_terms?: PaymentTerms;\n\n /** Maximum outstanding balance allowed on this account. */\n credit_limit?: WireAccount['credit_limit'];\n\n /**\n * Setup payload for accounts in `pending_approval`. Carries the URL/message\n * the buyer surfaces to a human to complete activation (credit-app, legal\n * agreement, fund-add). Required-shape: `message` is mandatory; `url` and\n * `expires_at` are optional.\n *\n * The framework does NOT validate that `setup` is populated when status is\n * `pending_approval` — that's an adopter contract with the spec. It also\n * does NOT clear `setup` when status leaves `pending_approval`; adopters\n * who echo the same `Account` across status transitions should drop the\n * field themselves.\n */\n setup?: WireAccount['setup'];\n\n /** Account scope (operator / brand / operator_brand / agent). */\n account_scope?: AccountScope;\n\n /**\n * Governance agent endpoints registered on this account. Auth credentials\n * are write-only on the wire and not modeled here — adopters set/update\n * via `sync_governance`, not by re-emitting the Account.\n */\n governance_agents?: WireAccount['governance_agents'];\n\n /**\n * Cloud storage bucket for offline reporting delivery. Only present when\n * the seller's capabilities advertise `reporting_delivery_methods`\n * including `'offline'`. Per-account access MUST be IAM-scoped — see the\n * schema description for security constraints.\n */\n reporting_bucket?: WireAccount['reporting_bucket'];\n\n /**\n * Account-level webhook subscriptions registered through `sync_accounts`.\n * Beta 3 adds wholesale product/signal feed webhooks here. The framework\n * strips legacy `authentication.credentials` before emitting accounts on\n * `list_accounts`; adopters must still persist credentials server-side if\n * they accept legacy webhook auth.\n */\n notification_configs?: NotificationConfig[];\n\n /**\n * Caller-specific authorization metadata for this account. Emitted only on\n * `list_accounts` / account response surfaces that use the\n * `AccountWithAuthorization` wire shape. Use this for platform adapters\n * that can introspect what the authenticated buyer agent may do on this\n * account, including downstream grants such as advertiser-account access\n * plus publisher identity/post authorization.\n *\n * Absence is silence, not denial: it means the adapter does not expose\n * introspectable account authorization for this caller/account tuple.\n */\n authorization?: AccountAuthorization;\n\n /**\n * Sandbox account marker. For implicit accounts the wire schema treats\n * this as part of the natural key — the same brand/operator pair can have\n * separate production and sandbox accounts. For explicit accounts, sandbox\n * accounts are pre-existing test accounts the seller surfaces via\n * `list_accounts`.\n *\n * @deprecated Use {@link Account.mode} instead. As of AdCP 6.7+ the\n * three-mode `mode: 'live' | 'sandbox' | 'mock'` field is the canonical\n * signal the framework gate consults — see\n * `docs/proposals/lifecycle-state-and-sandbox-authority.md`. Adopters\n * stamping this `sandbox` flag continue to work via\n * `getAccountMode`'s legacy fallback (`sandbox: true` reads as\n * `mode: 'sandbox'`); new code should set `mode` directly. This\n * field will be removed in the next major version.\n *\n * The wire-side `AccountReference.sandbox` flag (per\n * `core/account-ref.json`) stays — it's part of the spec's natural-key\n * disambiguation for implicit accounts. The deprecation is on the\n * SERVER-side resolved `Account.sandbox` only.\n */\n sandbox?: boolean;\n\n /**\n * Wire `ext` extension hatch. Carries forward-compatible additions the\n * codegen'd type doesn't model yet. Adopters who don't need extensions\n * leave this undefined.\n */\n ext?: ExtensionObject;\n\n /**\n * Adapter-internal opaque state. Framework doesn't read this; **stripped\n * before emitting on the wire**. GAM puts `{ networkId, advertiserId }`;\n * Spotify puts `{ brandId, businessId }`; Criteo puts `{ customerId }`.\n * Each platform's choice.\n *\n * Same field name (`ctx_metadata`) used across every DecisioningPlatform\n * resource (Product, MediaBuy, Package, Creative, Audience, Signal,\n * Account) for naming consistency. Account is special operationally:\n * `accounts.resolve()` is called per-request, so the publisher is the\n * canonical source of truth and the SDK does NOT round-trip Account\n * `ctx_metadata` through the cache (unlike Product / MediaBuy / etc.,\n * where the SDK bridges between `getProducts` and `createMediaBuy`).\n * Put adapter state in `ctx_metadata`; treat it as fresh from your\n * `accounts.resolve()` on every request.\n *\n * **DO NOT put credentials here.** The wire-strip protects buyer\n * responses but does NOT protect server-side log lines, error\n * envelopes (when `exposeErrorDetails: true`), heap dumps, or\n * adopter-generated strings (`JSON.stringify(account)` in an error\n * message). Bearer tokens, OAuth refresh tokens, API keys, and\n * client secrets belong on `authInfo` (which the framework\n * round-trips through `refreshToken`) or in your own per-principal\n * token cache — NOT in `ctx_metadata`. See\n * [`docs/guides/CTX-METADATA-SAFETY.md`](../../../../docs/guides/CTX-METADATA-SAFETY.md)\n * for the full guidance and the recommended re-derive-per-request\n * pattern.\n */\n ctx_metadata: TCtxMeta;\n\n /**\n * Caller's authenticated principal. **Stripped before emitting on the wire.**\n *\n * Optional from the adopter's perspective: when `accounts.resolve` returns\n * an `Account` without `authInfo`, the framework auto-attaches the\n * principal from `ctx.authInfo` (the auth shape extracted by\n * `serve({ authenticate })`). Adopters that need to *transform* the\n * principal — e.g. derive a tenant-scoped sub-principal from the OAuth\n * client — set it explicitly; adopters that just want the\n * `serve({ authenticate })` principal threaded through resource handlers\n * can omit the field and rely on the framework default.\n */\n authInfo?: AuthPrincipal;\n}\n\n/**\n * The OAuth-style auth shape extracted by `serve({ authenticate })`. Threaded\n * to `accounts.resolve(ref, ctx)` and to the `tasks_get` custom-tool handler\n * so adopters can authorize the resolution against the principal.\n *\n * Distinct from {@link AuthPrincipal} — `ResolvedAuthInfo` is the RAW\n * transport-level auth the framework hands to the resolver; `AuthPrincipal`\n * is what the resolver chooses to persist on the resolved `Account`. The\n * resolver decides what to keep / drop / re-shape.\n *\n * @public\n */\nexport interface ResolvedAuthInfo {\n /**\n * Kind-discriminated credential — Phase 1 Stage 3 of #1269. Populated by\n * the framework's built-in authenticators (`verifyApiKey`, `verifyBearer`,\n * `verifySignatureAsAuthenticator`); custom `authenticate` callbacks can\n * stamp this directly on the returned `AuthPrincipal` to opt into the\n * discriminated-credential surface. The framework propagates it from\n * `req.auth.extra.credential` to this top-level field on every request.\n *\n * **Verified vs. claimed.** `credential.kind === 'http_sig'` carries an\n * `agent_url` that is cryptographically verified by the framework's\n * signature verifier (per adcontextprotocol/adcp#3831). The framework\n * brands verified credentials with a module-private symbol that\n * `BuyerAgentRegistry` factories check before treating the credential\n * as authentic — a literal-shape `{ kind: 'http_sig', ... }` synthesized\n * by a custom authenticator is rejected at the registry layer. Adopters\n * making security-relevant decisions on `agent_url` MUST read it from\n * the credential variant; framework-stamped registry-derived URLs are\n * exposed via `ctx.agent.agent_url` only.\n */\n credential?: AdcpCredential;\n\n /**\n * Optional operator seat within the buyer agent. Stamped only when the\n * authenticator's claims include a `sub` / `oid` / equivalent identifying\n * a sub-principal within the agent. Reserved for future use; v1 of\n * `BuyerAgentRegistry` doesn't consume it.\n */\n operator?: string;\n\n /**\n * @deprecated Use `credential.kind === 'oauth' ? credential.client_id : ...`\n * for the discriminated shape. Optional in N+1 of the deprecation cycle\n * per #1269; framework continues to populate it for adopter compatibility\n * through the cycle. Removed in N+2.\n */\n token?: string;\n\n /**\n * @deprecated Use `credential.client_id` (oauth) or `credential.key_id`\n * (api_key) instead.\n */\n clientId?: string;\n\n /** @deprecated Use `credential.scopes` (oauth) instead. */\n scopes?: string[];\n\n expiresAt?: number;\n extra?: Record<string, unknown>;\n}\n\nexport interface ResolveContext {\n /** Authenticated principal extracted by `serve({ authenticate })`. Undefined when no `authenticate` is configured. */\n authInfo?: ResolvedAuthInfo;\n /** Tool the buyer is calling — useful for tool-aware tenant routing. */\n toolName?: string;\n /**\n * Resolved buyer agent from `BuyerAgentRegistry.resolve()`, when an\n * `agentRegistry` is configured (Phase 1 of #1269). The framework calls\n * the registry once per request before `accounts.resolve` and threads the\n * resolved record here so adopters can route tenant resolution against\n * the durable buyer-agent identity rather than re-deriving it from\n * `authInfo`. Undefined when no registry is configured OR when the\n * registry returns null for the request's credential.\n */\n agent?: BuyerAgent;\n /**\n * Un-destructured wire request envelope. Set by the framework so account\n * tool handlers (`syncAccounts`, `syncGovernance`, `listAccounts`,\n * `reportUsage`, `getAccountFinancials`) can read request fields the\n * typed signature doesn't model — e.g. `sync_accounts.delete_missing`\n * and `sync_accounts.dry_run`, which the framework destructures the\n * payload array out of before calling the handler.\n *\n * Same shape and read-site cast pattern as `RequestContext.input` (see\n * `decisioning/context.ts`). Same caveats:\n *\n * - **Identical reference to the typed payload arg.** This is the same\n * request body object the platform method's first positional arg\n * projects from. Framework auto-hydrate seams mutate this object\n * before the platform method runs; treat fields the buyer sent as\n * authoritative, but expect framework-injected entities (e.g.\n * hydrated product / media-buy refs) to be visible here too.\n * - **Buyer-controlled untrusted data.** Free-text fields (`brief`,\n * `message`, creative snippets, etc.) are attacker-controlled.\n * Don't log `ctx.input` wholesale — secret fields like\n * `push_notification_config.token` are present on mutating requests.\n * When templating into LLM prompts, validate or fence the field\n * rather than string-interpolating.\n *\n * @public\n */\n input?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Context passed to AccountStore tool methods that operate on a single\n * resolved Account (today: `getAccountFinancials`). Threads the resolved\n * `Account<TCtxMeta>` through so adopters can read `ctx.account.ctx_metadata`\n * (auth tokens, upstream IDs, etc.) without re-resolving from the request.\n *\n * Strict superset of `ResolveContext`: same `authInfo` / `toolName` fields,\n * plus the resolved account. Distinct type because `accounts.resolve()`\n * produces the account and therefore cannot receive it on input.\n *\n * **NOT applicable to `reportUsage`.** `ReportUsageRequest.usage[]` carries\n * a per-row `account: AccountReference`; a request can span multiple\n * accounts. Pre-resolving a single `ctx.account` would misrepresent that\n * shape. `reportUsage` keeps `ResolveContext` and per-row resolution is\n * the adopter's responsibility (call `accounts.resolve` from inside the\n * impl, once per row).\n *\n * @public\n */\nexport interface AccountToolContext<TCtxMeta = Record<string, unknown>> extends ResolveContext {\n /** Resolved Account from `accounts.resolve()`. Populated by the framework before dispatch. */\n account: Account<TCtxMeta>;\n}\n\n/**\n * Request context for tools whose wire request does not carry an `account`\n * field — `preview_creative`, `list_creative_formats`, and\n * `provide_performance_feedback`. The framework calls\n * `accounts.resolve(undefined, ctx)` for these, accepting a `null` return; if\n * `null`, `ctx.account` is undefined when the handler runs.\n *\n * Adopter handlers MUST handle the `undefined` case explicitly. Choose one of:\n *\n * 1. **Singleton fallback** — return a non-null synthetic `Account` from\n * `accounts.resolve(undefined, ctx)` for the publisher-wide tenant\n * (e.g., format catalog, performance feedback aggregation). Inside the\n * handler, narrow with `if (!ctx.account) throw ...` once and treat\n * `ctx.account` as defined for the rest.\n * 2. **Auth-derived lookup** — in `accounts.resolve(undefined, ctx)`, look\n * up by `ctx.authInfo.clientId` (or whichever principal field your auth\n * wires) and return the matching account.\n * 3. **Error out** — throw `AdcpError({ code: 'ACCOUNT_NOT_FOUND' })` from\n * within the handler when `ctx.account == null` and the operation\n * requires tenant scoping.\n *\n * The narrowed type catches the mismatch at authorship time — adopters who\n * forget to handle `ctx.account === undefined` get a TS error, not a runtime\n * `Cannot read properties of undefined` deep in their upstream call. Same\n * shape as the `definePlatformWithCompliance` invariant: convert a runtime\n * gate into a compile-time one.\n *\n * @public\n */\n// Inline type-import on `RequestContext` instead of a top-level\n// `import type { RequestContext } from './context'` — `context.ts` already\n// imports `Account` from this file, so a top-level import would form a\n// circular type dependency.\nexport type NoAccountCtx<TCtxMeta = Record<string, unknown>> = Omit<\n import('./context').RequestContext<Account<TCtxMeta>>,\n 'account'\n> & {\n /**\n * Resolved account, OR `undefined` when the wire request didn't carry an\n * account ref AND `accounts.resolve(undefined, ctx)` returned null. Always\n * narrow before reading `ctx_metadata` / `id`.\n */\n account: Account<TCtxMeta> | undefined;\n};\n\nexport interface AuthPrincipal {\n /** Stable identifier for the calling agent (e.g., `https://buyer.example.com/mcp`). */\n agent_url?: string;\n /** Token kind: API key, OAuth bearer, signed-request claim. */\n kind: 'api_key' | 'oauth' | 'signature' | 'public';\n /** Bearer token / API key value. Platform-side don't log this. */\n token?: string;\n /** Token expiry (ms since epoch). Set by `accounts.refreshToken` after a successful refresh. */\n expiresAt?: number;\n /** OAuth scopes / API-key principal name. */\n principal?: string;\n /** Additional claims (jwt sub, kid, etc.). */\n claims?: Record<string, unknown>;\n}\n\nexport interface AccountStore<TCtxMeta = Record<string, unknown>> {\n /**\n * How buyers reference accounts on this platform.\n * - `'explicit'` — buyer passes `account_id` inline on every request (Snap,\n * Meta, GAM via Network/Company id). The default.\n * - `'implicit'` — buyer must `sync_accounts` first; subsequent requests are\n * resolved from the auth principal's pre-synced linkage (LinkedIn, some\n * retail-media operators). Framework refuses inline `account_id` references\n * for these platforms — emits `AdcpError('INVALID_REQUEST', { field:\n * 'account.account_id' })` before reaching `accounts.resolve`. The\n * brand+operator union arm is permitted (used during the initial\n * `sync_accounts` flow); only `account_id`-shaped references are rejected.\n * - `'derived'` — single-tenant agents where there is no account_id on the\n * wire at all and the auth principal alone identifies the tenant. Most\n * self-hosted broadcasters and retail-media operators in proxy mode.\n * Framework refuses inline `account_id` references for these platforms —\n * same `AdcpError('INVALID_REQUEST', { field: 'account.account_id' })`\n * shape as `'implicit'`, but with a single-tenant message instead of the\n * `sync_accounts`-first guidance (no `sync_accounts` step exists in\n * derived mode). The brand+operator union arm is permitted.\n *\n * Defaults to `'explicit'` when omitted.\n */\n readonly resolution?: 'explicit' | 'implicit' | 'derived';\n\n /**\n * Resolve buyer's AccountReference into the platform's tenant model.\n *\n * `ref` is `undefined` when the wire request didn't carry an account\n * field — `provide_performance_feedback` and `list_creative_formats` are\n * the canonical examples. Per `resolution` mode:\n * - `'derived'` (single-tenant): return the singleton account regardless.\n * - `'implicit'`: look up the account from the auth principal.\n * - `'explicit'` (default): no account is available; either throw\n * `AccountNotFoundError` to signal \"tool requires account\" OR return\n * a synthetic singleton if the tool legitimately doesn't need\n * tenant scoping (e.g., publisher-wide format catalog from\n * `list_creative_formats`).\n *\n * `ctx.authInfo` is the caller's authenticated principal (when\n * `serve({ authenticate })` is wired). Adapters fronting an upstream\n * platform API (Snap, Meta, retail-media) translate auth to tenant ID:\n *\n * ```ts\n * resolve: async (ref, ctx) => {\n * if (ref?.account_id) return await this.db.findById(ref.account_id);\n * const cred = ctx?.authInfo?.credential;\n * const clientKey = cred?.kind === 'oauth' ? cred.client_id\n * : cred?.kind === 'api_key' ? cred.key_id\n * : undefined;\n * const platformAcct = clientKey ? await myUpstream.findByClientKey(clientKey) : null;\n * return platformAcct ? this.toAccount(platformAcct) : null;\n * }\n * ```\n *\n * Two failure shapes:\n * - **Unknown / cross-tenant reference**: return `null` (canonical) — OR\n * throw `AccountNotFoundError` if your codebase already throws a\n * not-found exception class. Framework emits the spec's fixed\n * `ACCOUNT_NOT_FOUND` envelope either way. The buyer learns no detail\n * beyond \"not found\" — guarding against principal-enumeration.\n * - **Transient upstream failure** (DB outage, identity-provider 5xx):\n * throw a generic exception. Framework maps to `SERVICE_UNAVAILABLE`\n * so the buyer can retry.\n */\n resolve(ref: AccountReference | undefined, ctx?: ResolveContext): Promise<Account<TCtxMeta> | null>;\n\n /**\n * sync_accounts API surface. Framework normalizes the wire request; platform\n * upserts and returns per-account result rows. `throw new AdcpError(...)`\n * for buyer-facing rejection.\n *\n * In AdCP 3.1 beta, adopters that need settings-update entries with\n * `notification_configs[]` can read the full wire body from `ctx.input`\n * or supply a top-level `accounts.syncAccounts` handler.\n *\n * **Optional.** Stateless platforms (creative-template, signal-marketplace\n * proxies) that don't manage account lifecycle can omit this; framework\n * surfaces `UNSUPPORTED_FEATURE` to buyers calling `sync_accounts`.\n *\n * `ctx.authInfo` carries the caller's authenticated principal (when\n * `serve({ authenticate })` is wired); `ctx.agent` carries the resolved\n * `BuyerAgent` record (when an `agentRegistry` is configured). Adopters\n * implementing principal-keyed gates (e.g., per-buyer-agent\n * `BILLING_NOT_PERMITTED_FOR_AGENT` on the spec's billing surfaces) read\n * the principal here — same threading as `accounts.resolve`.\n *\n * **Prefer `ctx.agent` over `ctx.authInfo.credential` for commercial-\n * relationship decisions.** `ctx.agent` is the registry-resolved durable\n * identity (status, billing capabilities, default account terms);\n * `ctx.authInfo.credential` is the raw transport-level credential. For\n * billing gates the registry-resolved identity is canonical. Use\n * `credential` only for transport-level branching (e.g., reading the\n * verified `agent_url` from `credential.kind === 'http_sig'` when\n * `agentRegistry` is not configured).\n */\n upsert?(refs: AccountReference[], ctx?: ResolveContext): Promise<SyncAccountsHandlerResult>;\n\n /**\n * sync_governance API surface. Buyers register governance agent endpoints\n * per-account; the seller persists the binding and consults the agents\n * during media buy lifecycle events via `check_governance`.\n *\n * **Optional.** Adopters that don't model buyer-supplied governance agents\n * (most direct sellers) leave this unimplemented and the framework returns\n * `UNSUPPORTED_FEATURE`.\n *\n * `entries` is the wire request's `accounts[]` — each entry pairs an\n * `AccountReference` with its `governance_agents[]`. The framework has\n * already deduped on `idempotency_key` and stripped wire metadata\n * (`adcp_major_version`, `context`, `ext`) before invoking this method.\n *\n * **Replace semantics, per spec.** Each call REPLACES the previously\n * synced governance agents for the referenced account. An entry whose\n * `governance_agents` is empty clears the binding for that account.\n *\n * **Write-only credentials.** Each `governance_agents[i].authentication.credentials`\n * is the bearer the seller presents to that governance agent on outbound\n * `check_governance` calls. Persist them — silently dropping ships\n * unauthenticated requests once cross-agent calls are wired. The framework\n * strips `authentication` from each `governance_agents[i]` of every row\n * before serialization (`toWireSyncGovernanceRow`), so credentials never\n * reach the response wire OR the idempotency replay cache, even if an\n * adopter returns a loosely-typed row that spreads the input. Do not rely\n * on TypeScript narrowing alone — the strip is enforced at the dispatcher.\n *\n * `ctx.authInfo` and `ctx.agent` carry the caller's principal — same\n * threading as `upsert`. Adopters MUST gate per-entry persistence by the\n * caller's tenant: each entry's `account.operator` (or `account_id`) must\n * map to the same tenant the auth principal authorizes; otherwise return a\n * `'failed'` row carrying `errors: [{code: 'PERMISSION_DENIED', ...}]` for\n * that entry. (Operation-level rejection — `throw new AdcpError(...)` —\n * fails the whole batch, which is the wrong shape when a single entry\n * fails the gate.)\n */\n syncGovernance?(\n entries: SyncGovernanceRequest['accounts'],\n ctx?: ResolveContext\n ): Promise<SyncGovernanceHandlerResult>;\n\n /**\n * list_accounts API surface. Framework wraps with cursor envelope.\n *\n * **Optional.** Same rationale as `upsert` — stateless platforms can omit.\n *\n * `ctx.authInfo` and `ctx.agent` carry the caller's principal — adopters\n * scope the listing per-principal (e.g., return only accounts visible to\n * the calling buyer agent) without re-deriving identity from the request.\n */\n list?(filter: AccountFilter & CursorRequest, ctx?: ResolveContext): Promise<ListAccountsHandlerResult<TCtxMeta>>;\n\n /**\n * report_usage API surface. Operator-billed platforms accept usage rows\n * (often impressions / spend by media_buy + period) for billing\n * reconciliation. Optional — adopters that don't run billing through the\n * agent leave this unimplemented and the framework returns\n * UNSUPPORTED_FEATURE.\n *\n * Idempotent on `(account, period_start, period_end, line_item_id)` —\n * platform must dedupe replays under the framework's idempotency key.\n *\n * `ctx.authInfo` carries the caller's OAuth principal (when\n * `serve({ authenticate })` is wired); `ctx.agent` carries the resolved\n * `BuyerAgent` record (when an `agentRegistry` is configured). Platforms\n * fronting an upstream billing API (Snap, Meta, retail-media) use them\n * to authorize the usage post against the principal's tenant — same\n * pattern as `accounts.resolve`. Prefer `ctx.agent` for principal-keyed\n * commercial gates; see `upsert?` for the rationale.\n */\n reportUsage?(req: ReportUsageRequest, ctx?: ResolveContext): Promise<ReportUsageHandlerResult>;\n\n /**\n * get_account_financials API surface. Operator-billed platforms expose\n * spend / credit / payment status per the wire shape. Optional — agent-\n * billed platforms (where the buyer settles directly with the publisher)\n * leave this unimplemented.\n *\n * Read tool — no idempotency requirement. Throw `AdcpError` for buyer-\n * fixable rejection (`'PERMISSION_DENIED'` if the principal can't see\n * financials for the requested account).\n *\n * `ctx.account` is the resolved `Account<TCtxMeta>` (framework calls\n * `accounts.resolve(req.account)` first and threads the result in).\n * Adopters fronting an upstream platform read tokens / upstream IDs from\n * `ctx.account.ctx_metadata` without re-resolving.\n *\n * `ctx.authInfo` carries the caller's OAuth principal (when\n * `serve({ authenticate })` is wired); `ctx.agent` carries the resolved\n * `BuyerAgent` record (when an `agentRegistry` is configured). Platforms\n * that guard financials per-principal use them to authorize the read —\n * same pattern as `accounts.resolve`. Prefer `ctx.agent` for principal-\n * keyed commercial gates; see `upsert?` for the rationale.\n */\n getAccountFinancials?(\n req: GetAccountFinancialsRequest,\n ctx: AccountToolContext<TCtxMeta>\n ): Promise<GetAccountFinancialsHandlerResult>;\n\n /**\n * Mid-request token refresh hook. Optional. Called by the framework when\n * a platform method throws a refreshable token-auth code (`AUTH_REQUIRED`\n * for legacy compatibility or `AUTH_MISSING` for an AdCP 3.1-native\n * missing request credential) AND `refreshToken` is defined — the\n * framework refreshes via this hook, mutates or creates `account.authInfo`\n * with the returned token, and retries the failing platform method exactly\n * once.\n *\n * The reason string lets adopters distinguish trigger conditions:\n * - `'auth_required'` — platform method threw refreshable auth in flight.\n *\n * Treat as an open string union: future values may be added. Adopters\n * SHOULD switch exhaustively (`default: throw`) so behavior drift on\n * minor SDK bumps fails loud rather than silently no-oping.\n *\n * **In-flight only.** The refreshed token is scoped to the current\n * request — the framework does NOT echo it back to the buyer. Use this\n * for adapters that front an upstream platform API (Snap, Meta,\n * retail-media OAuth flows) where the SDK caches an upstream token\n * server-side and the buyer's auth-to-this-agent is separate.\n *\n * **Account-object identity contract.** The framework mutates a\n * request-local Account clone before retrying, creating an OAuth-shaped\n * auth principal if the resolver omitted one. The resolver-returned object\n * is not written back. Adopters should still avoid caching secret-bearing\n * `Account.authInfo` objects across unrelated callers, but SDK refresh\n * retry does not mutate a cached resolver object in place.\n *\n * **Concurrency.** `refreshToken` MUST be safe under concurrent\n * invocation on the same account — two parallel in-flight calls hitting\n * refreshable auth at once will both call this hook. Adopters whose\n * upstream provider rate-limits refresh should coalesce internally\n * (e.g., a per-account in-flight refresh promise). The framework does\n * not coalesce.\n *\n * **Failure surfaces correctable AUTH_REQUIRED.** If `refreshToken`\n * itself throws, the framework projects to `AUTH_REQUIRED` with\n * `recovery: 'correctable'` and a fixed message (the inner exception\n * text is NOT echoed on the wire — refresh failures routinely include\n * upstream details that should not cross the trust boundary). Log inner\n * details server-side. Don't use SERVICE_UNAVAILABLE — refresh failure\n * means the upstream authorization is gone, not that the service is\n * transiently down.\n *\n * **Expiry timestamp** (`expiresAt`, ms since epoch) is optional. When\n * returned, the framework writes it to `account.authInfo.expiresAt` so\n * adopters reading the resolved Account can branch on it (proactive\n * refresh is not yet wired; reactive-only in v6.x).\n */\n refreshToken?(account: Account<TCtxMeta>, reason: 'auth_required'): Promise<{ token: string; expiresAt?: number }>;\n}\n\n/**\n * Optional throw-class for `AccountStore.resolve` not-found signaling. Returning\n * `null` from `resolve` is canonical and equivalent; throw this only if your\n * codebase already throws a typed not-found exception elsewhere.\n *\n * **Throwable only from `AccountStore.resolve()`.** Throwing it from a\n * specialism method (`createMediaBuy`, `getProducts`, etc.) bypasses the\n * framework's not-found mapping and surfaces as `SERVICE_UNAVAILABLE`.\n *\n * The constructor's `message` is for server-side operator diagnostics only.\n * The framework emits a fixed `ACCOUNT_NOT_FOUND` envelope regardless; the\n * message never reaches the buyer. Operator-side log pipelines may aggregate\n * this string, so MUST NOT include caller-supplied identifiers (echoed account\n * refs, request args) — those leak across operator / buyer trust boundaries.\n *\n * Use ONLY for the narrow not-found case. Upstream-API outages, misconfigured\n * env vars, and schema-validation failures should propagate as generic\n * exceptions and surface to the buyer as `SERVICE_UNAVAILABLE`.\n */\nexport class AccountNotFoundError extends Error {\n readonly name = 'AccountNotFoundError' as const;\n constructor(message = 'Account not found') {\n super(message);\n }\n}\n\nexport interface AccountFilter {\n /** Filter by brand domain across all operators. */\n brand_domain?: string;\n /** Filter by operator across all brands. */\n operator?: string;\n /** Filter by status. */\n status?: AdcpAccountStatus[];\n}\n\n/**\n * Per-account result row returned by an adopter's `accounts.upsert`\n * implementation. Maps to one element of the wire `sync_accounts` response's\n * `accounts[]` array.\n *\n * Carries the same optional commercial / lifecycle fields as the wire shape\n * so adopters can echo `setup` (for `pending_approval` accounts), `billing`,\n * `billing_entity`, `payment_terms`, caller-specific `authorization`, etc. on creation. The framework\n * projects these through `toWireSyncAccountRow` before emit, applying the\n * same `billing_entity.bank` strip as `toWireAccount` (write-only contract).\n *\n * **MUST NOT carry `authInfo` or other auth-derived fields.** This shape is\n * emitted on the `sync_accounts` response wire. The framework's projector\n * does not read `authInfo`, but adopters MUST NOT add an `authInfo` key on\n * returned rows — same MUST-NOT-LEAK rule the framework enforces on\n * `Account.authInfo`.\n */\nexport interface SyncAccountsResultRow {\n account_id?: string;\n brand: BrandReference;\n operator: string;\n /** Human-readable account name assigned by the seller. */\n name?: string;\n action: 'created' | 'updated' | 'unchanged' | 'failed';\n status: AdcpAccountStatus;\n /** Invoiced-to party. Echoes the request's `billing` after seller acceptance. */\n billing?: BillingParty;\n /** Business entity invoiced. `bank` is stripped on emit (write-only). */\n billing_entity?: BusinessEntity;\n account_scope?: AccountScope;\n /** Setup payload for `pending_approval` accounts (URL/message/expiry). */\n setup?: WireAccount['setup'];\n rate_card?: string;\n payment_terms?: PaymentTerms;\n credit_limit?: WireAccount['credit_limit'];\n /** Applied account-level webhook subscriptions; credentials are stripped on emit. */\n notification_configs?: NotificationConfig[];\n /**\n * Caller-specific authorization metadata for this synced account, including\n * downstream grants such as advertiser-account access plus publisher\n * identity/post authorization.\n */\n authorization?: AccountAuthorization;\n errors?: SyncAccountError[];\n warnings?: string[];\n sandbox?: boolean;\n}\n\nexport type AdcpAccountStatus =\n | 'active'\n | 'pending_approval'\n | 'rejected'\n | 'payment_required'\n | 'suspended'\n | 'closed';\n\n// ---------------------------------------------------------------------------\n// Wire projection — strip framework-internal fields before emit\n// ---------------------------------------------------------------------------\n\n/**\n * Project a framework `Account<TCtxMeta>` to the wire `Account` shape.\n *\n * Strips `ctx_metadata` and `authInfo` (framework-internal); renames `id` →\n * `account_id`; passes through wire-shaped fields. Strips\n * `billing_entity.bank` per the schema's write-only constraint — bank\n * coordinates flow buyer→seller in `sync_accounts` requests but MUST NOT\n * appear in any response payload.\n *\n * Used by the framework when emitting `list_accounts` and other wire\n * responses that include account data. Adopters never call this directly —\n * they return `Account<TCtxMeta>` from `accounts.resolve` / `accounts.list`\n * and the framework projects.\n */\nexport function toWireAccount<TCtxMeta>(account: Account<TCtxMeta>): WireAccount {\n const wire: WireAccount = {\n account_id: account.id,\n name: account.name,\n status: account.status,\n };\n if (account.brand !== undefined) wire.brand = account.brand;\n if (account.operator !== undefined) wire.operator = account.operator;\n if (account.advertiser !== undefined) wire.advertiser = account.advertiser;\n if (account.billing_proxy !== undefined) wire.billing_proxy = account.billing_proxy;\n if (account.billing !== undefined) {\n // Wire `Account.billing: 'operator' | 'agent' | 'advertiser'` is the\n // invoiced-to party. Internal `billing.invoicedTo` collapses string +\n // BrandReference; a BrandReference indicates a third-party advertiser\n // (Amazon DSP-shaped flow), which projects to `'advertiser'`.\n const t = account.billing.invoicedTo;\n wire.billing = typeof t === 'string' ? t : 'advertiser';\n }\n const projectedEntity = projectBillingEntity(account.billing_entity);\n if (projectedEntity !== undefined) wire.billing_entity = projectedEntity;\n if (account.rate_card !== undefined) wire.rate_card = account.rate_card;\n if (account.payment_terms !== undefined) wire.payment_terms = account.payment_terms;\n if (account.credit_limit !== undefined) wire.credit_limit = account.credit_limit;\n if (account.setup !== undefined) wire.setup = account.setup;\n if (account.account_scope !== undefined) wire.account_scope = account.account_scope;\n if (account.governance_agents !== undefined) {\n wire.governance_agents = account.governance_agents.map(projectGovernanceAgent);\n }\n if (account.reporting_bucket !== undefined) wire.reporting_bucket = account.reporting_bucket;\n if (account.notification_configs !== undefined) {\n (wire as unknown as { notification_configs?: WireNotificationConfig[] }).notification_configs =\n account.notification_configs.map(projectNotificationConfig);\n }\n if (account.authorization !== undefined) {\n (wire as WireAccount & { authorization?: AccountAuthorization }).authorization = projectAccountAuthorization(\n account.authorization\n );\n }\n if (account.sandbox !== undefined) wire.sandbox = account.sandbox;\n if (account.ext !== undefined) wire.ext = account.ext;\n return wire;\n}\n\nfunction projectAccountAuthorization(authorization: AccountAuthorization): AccountAuthorization {\n const projected: AccountAuthorization = {\n allowed_tasks: [...authorization.allowed_tasks],\n };\n if (authorization.field_scopes !== undefined) {\n projected.field_scopes = Object.fromEntries(\n Object.entries(authorization.field_scopes)\n .filter((entry): entry is [string, string[]] => Array.isArray(entry[1]))\n .map(([task, fields]) => [task, [...fields]])\n );\n }\n if (authorization.scope_name !== undefined) projected.scope_name = authorization.scope_name;\n if (authorization.read_only !== undefined) projected.read_only = authorization.read_only;\n return projected;\n}\n\ntype WireSyncAccountRow = SyncAccountsSuccess['accounts'][number];\n\n/**\n * Project an adopter `SyncAccountsResultRow` to the wire shape returned by\n * `sync_accounts`. Applies the same `billing_entity.bank` strip as\n * `toWireAccount` — the wire schema marks bank coordinates write-only on\n * EVERY response, not just `list_accounts`. Adopters returning a row that\n * spreads a DB record carrying `bank` (e.g.,\n * `{ ...db.findByBrand(r.brand), action: 'updated' }`) have it stripped\n * before emit.\n *\n * Used by the framework when emitting `sync_accounts` responses. Adopters\n * never call this directly — they return `SyncAccountsResultRow[]` from\n * `accounts.upsert` and the framework projects.\n */\nexport function toWireSyncAccountRow(row: SyncAccountsResultRow): WireSyncAccountRow {\n const wire: WireSyncAccountRow = {\n brand: row.brand,\n operator: row.operator,\n action: row.action,\n status: row.status,\n };\n if (row.account_id !== undefined) wire.account_id = row.account_id;\n if (row.name !== undefined) wire.name = row.name;\n if (row.billing !== undefined) wire.billing = row.billing;\n const projectedEntity = projectBillingEntity(row.billing_entity);\n if (projectedEntity !== undefined) wire.billing_entity = projectedEntity;\n if (row.account_scope !== undefined) wire.account_scope = row.account_scope;\n if (row.setup !== undefined) wire.setup = row.setup;\n if (row.rate_card !== undefined) wire.rate_card = row.rate_card;\n if (row.payment_terms !== undefined) wire.payment_terms = row.payment_terms;\n if (row.credit_limit !== undefined) wire.credit_limit = row.credit_limit;\n if (row.notification_configs !== undefined) {\n (wire as unknown as { notification_configs?: WireNotificationConfig[] }).notification_configs =\n row.notification_configs.map(projectNotificationConfig);\n }\n if (row.authorization !== undefined) {\n (wire as WireSyncAccountRow & { authorization?: AccountAuthorization }).authorization = projectAccountAuthorization(\n row.authorization\n );\n }\n if (row.errors !== undefined) wire.errors = row.errors;\n if (row.warnings !== undefined) wire.warnings = row.warnings;\n if (row.sandbox !== undefined) wire.sandbox = row.sandbox;\n return wire;\n}\n\nfunction projectNotificationConfig(config: NotificationConfig): WireNotificationConfig {\n const { authentication, ...rest } = config;\n if (!authentication) return rest;\n const { credentials: _credentials, ...authenticationWithoutCredentials } = authentication;\n return { ...rest, authentication: authenticationWithoutCredentials };\n}\n\ntype WireSyncGovernanceRow = SyncGovernanceSuccess['accounts'][number];\n\n/**\n * Project a `sync_governance` response row to the wire shape, stripping\n * any fields the buyer is NOT entitled to receive. Critically: each\n * `governance_agents[i]` is reduced to `{url, categories?}` only — the\n * spec marks `authentication.credentials` write-only (the buyer sends\n * the bearer; the seller persists it for outbound `check_governance`\n * calls but MUST NOT echo it back). The natural `{ ...entry.governance_agents[i] }`\n * echo idiom would compile silently against the typed return shape and\n * ship credentials over the wire AND into the idempotency replay cache,\n * arming the buyer (and any subsequent caller hitting the same key) to\n * impersonate the seller against the governance agent.\n *\n * Defense-in-depth: this dispatcher-level strip runs even if an adopter\n * returns a loosely-typed row, and even if a future codegen change\n * loosens the response Zod schema's `.passthrough()` for governance\n * agents.\n */\nexport function toWireSyncGovernanceRow(row: WireSyncGovernanceRow): WireSyncGovernanceRow {\n const wire: WireSyncGovernanceRow = {\n account: row.account,\n status: row.status,\n };\n if (row.governance_agents !== undefined) {\n // AdCP 3.1.0-beta.2 removed `categories` from the governance_agents\n // wire shape. The schema is now `{ url }` only; per-agent category\n // signaling moved out of band. The projection still strips\n // authentication.credentials (write-only) by only naming `url`.\n wire.governance_agents = row.governance_agents.map(a => ({ url: a.url }));\n }\n if (row.errors !== undefined) wire.errors = row.errors;\n return wire;\n}\n\n/**\n * Strip `BusinessEntity.bank` per the schema's write-only constraint, and\n * skip emission entirely when nothing else is populated. Bank-only inputs\n * project to `undefined`, signaling the caller to omit `billing_entity`\n * rather than emit an empty object that would fail `legal_name` validation.\n *\n * Destructure-and-rest excludes `bank` regardless of source shape: own\n * non-enumerable, getter, prototype-chain, and Proxy-backed bank fields\n * are all excluded by the ES rest-spread evaluation order\n * (`CopyDataProperties` walks own-enumerable keys and skips the\n * destructured names).\n */\nfunction projectBillingEntity(entity: BusinessEntity | undefined): BusinessEntity | undefined {\n if (entity === undefined) return undefined;\n const { bank: _bank, ...rest } = entity;\n return Object.keys(rest).length > 0 ? rest : undefined;\n}\n\ntype WireGovernanceAgent = NonNullable<WireAccount['governance_agents']>[number];\n\n/**\n * Project a governance-agent element to the wire shape, dropping any keys\n * the wire schema doesn't model. The schema notes that authentication\n * credentials are write-only and not included in responses; AdCP 3.1.0-beta.2\n * also removed `categories` from the wire shape. The current shape is\n * `{ url }` only — TS is erased at runtime so adopters using JS or `as any`\n * could otherwise smuggle a `credentials` or `categories` field straight\n * to the wire. Explicit projection closes that gap.\n */\nfunction projectGovernanceAgent(agent: WireGovernanceAgent): WireGovernanceAgent {\n return { url: agent.url };\n}\n\n// ---------------------------------------------------------------------------\n// AccountReference helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extract `account_id` from an `AccountReference` discriminated union without\n * casting. Returns `undefined` when `ref` is absent or the union arm doesn't\n * carry an `account_id` (e.g., `{ brand, operator }` or sandbox variants).\n *\n * Typical use in `accounts.resolve` implementations:\n *\n * ```ts\n * resolve: async (ref, ctx) => {\n * const id = refAccountId(ref);\n * if (id) return this.db.findById(id);\n * const cred = ctx?.authInfo?.credential;\n * const key = cred?.kind === 'oauth' ? cred.client_id : cred?.kind === 'api_key' ? cred.key_id : undefined;\n * return key ? this.db.findByClientKey(key) : null;\n * }\n * ```\n *\n * @public\n */\nexport function refAccountId(ref?: AccountReference): string | undefined {\n return ref && 'account_id' in ref ? (ref as { account_id?: string }).account_id : undefined;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/server/decisioning/account.ts"],"sourcesContent":["/**\n * Account model. Single-level (matches AdCP wire's AccountReference).\n * Platform-internal hierarchies (GAM Network → Advertiser → Order;\n * Spotify Brand → Campaign) are encoded in `metadata`, not in the typed\n * shape. Generic `TCtxMeta` lets platforms type their metadata at the call site.\n *\n * Tenant scoping is expressed by what `accounts.resolve()` returns, not via\n * a multi-level type. Note that resolve is NOT an isolation gate by default:\n * `createTenantStore` resolves the ref the buyer supplies regardless of the\n * caller unless `refAccess: 'auth-scoped'` is set (or a `resolve-presets`\n * guard is composed). See `createTenantStore` and `resolve-presets.ts`.\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\n\nimport type {\n Account as WireAccount,\n AccountAuthorization,\n AccountScope,\n BillingParty,\n BrandReference,\n AccountReference,\n BusinessEntity,\n ExtensionObject,\n PaymentTerms,\n ListAccountsResponse,\n ReportUsageRequest,\n ReportUsageResponse,\n SyncAccountsResponse,\n SyncAccountsSuccess,\n SyncGovernanceRequest,\n SyncGovernanceResponse,\n SyncGovernanceSuccess,\n GetAccountFinancialsRequest,\n GetAccountFinancialsResponse,\n GetAccountFinancialsSuccess,\n} from '../../types/tools.generated';\nimport type { ServerPayload } from '../../types/server-payload';\nimport type { NotificationConfig } from '../../types/v3-1-beta';\nimport type { CursorPage, CursorRequest } from './pagination';\nimport type { AdcpStructuredError } from './async-outcome';\nimport type { AdcpCredential, BuyerAgent } from './buyer-agent';\n\nexport const ACCOUNT_AUTHORIZATION_WIRE_KEYS = [\n 'allowed_tasks',\n 'field_scopes',\n 'scope_name',\n 'read_only',\n] as const satisfies readonly (keyof AccountAuthorization)[];\n\ntype MissingAccountAuthorizationWireKey = Exclude<\n keyof AccountAuthorization,\n (typeof ACCOUNT_AUTHORIZATION_WIRE_KEYS)[number]\n>;\nconst ACCOUNT_AUTHORIZATION_WIRE_KEY_COVERAGE: Record<MissingAccountAuthorizationWireKey, never> = {};\nvoid ACCOUNT_AUTHORIZATION_WIRE_KEY_COVERAGE;\n\ntype WireNotificationConfig = Omit<NotificationConfig, 'authentication'> & {\n authentication?: Omit<NonNullable<NotificationConfig['authentication']>, 'credentials'>;\n};\n\ntype SyncAccountError = Pick<AdcpStructuredError, 'code' | 'message'> &\n Partial<Omit<AdcpStructuredError, 'code' | 'message'>>;\n\nexport type ListAccountsPayload = ServerPayload<ListAccountsResponse>;\nexport type SyncAccountsPayload = ServerPayload<SyncAccountsResponse>;\nexport type SyncAccountsSuccessPayload = ServerPayload<SyncAccountsSuccess>;\nexport type SyncAccountsRow = SyncAccountsSuccess['accounts'][number];\nexport type SyncGovernancePayload = ServerPayload<SyncGovernanceResponse>;\nexport type SyncGovernanceSuccessPayload = ServerPayload<SyncGovernanceSuccess>;\nexport type SyncGovernanceRow = SyncGovernanceSuccess['accounts'][number];\nexport type ReportUsagePayload = ServerPayload<ReportUsageResponse>;\nexport type GetAccountFinancialsPayload = ServerPayload<GetAccountFinancialsResponse>;\nexport type GetAccountFinancialsSuccessPayload = ServerPayload<GetAccountFinancialsSuccess>;\nexport type ListAccountsHandlerResult<TCtxMeta = Record<string, unknown>> = CursorPage<Account<TCtxMeta>>;\nexport type SyncAccountsHandlerResult = SyncAccountsResultRow[];\nexport type SyncGovernanceHandlerResult = SyncGovernanceRow[];\nexport type ReportUsageHandlerResult = ReportUsagePayload;\nexport type GetAccountFinancialsHandlerResult = GetAccountFinancialsSuccessPayload;\n\n/**\n * Account — framework's rich representation. A strict superset of the wire\n * `Account` shape (from `list_accounts` / response envelopes):\n *\n * - Adds `metadata: TCtxMeta` (platform-internal fields the framework doesn't\n * read but adopters use to thread platform-specific data)\n * - Adds `authInfo: AuthPrincipal` (auth context for the request — MUST NOT\n * leak to the wire)\n * - All wire-required fields (`id`/`account_id`, `name`, `status`) are\n * required here too.\n *\n * Framework projects to wire shape via `toWireAccount`: strips `metadata` +\n * `authInfo`, renames `id` → `account_id`. ~10 lines, no `as never` casts.\n */\nexport interface Account<TCtxMeta = Record<string, unknown>> {\n /** Your platform's account_id. Maps to wire `Account.account_id`. */\n id: string;\n\n /** Human-readable account name (e.g., 'Acme', 'Acme c/o Pinnacle'). Required on the wire. */\n name: string;\n\n /** Account status. Maps to wire `Account.status`. */\n status: AdcpAccountStatus;\n\n /** Canonical brand reference. Either id OR (brand+operator) identifies the account. */\n brand?: BrandReference;\n\n /** Operator domain (agency / managed-services). Pairs with `brand`. */\n operator?: string;\n\n /**\n * The advertiser whose rates apply to this account. Maps to wire\n * `Account.advertiser`. Use when the account is operated by an agency on\n * behalf of an advertiser whose rates differ from the operator's.\n */\n advertiser?: string;\n\n /**\n * Optional intermediary who receives invoices on behalf of the advertiser\n * (e.g., agency holdco). Distinct from `advertiser` (whose rates apply)\n * and from `billing.invoicedTo` (the legal billing party). Use when the\n * invoice recipient differs from both — common in agency-handled flows.\n */\n billing_proxy?: string;\n\n /**\n * Settlement boundary for operator-billed retail-media platforms.\n * `'agent'` = pass-through (buyer's agent settles directly with the platform).\n * `'operator'` = retail-media model (operator pays publisher, bills brand).\n * `BrandReference` = invoice routes to a third party (Amazon DSP returning\n * a different invoice principal than the requester is the canonical case).\n *\n * Optional — most platforms don't need this; comply storyboards use it to\n * assert the right party is billed.\n */\n billing?: { invoicedTo: 'agent' | 'operator' | BrandReference };\n\n /**\n * Business entity invoiced on this account. Carries legal name, tax IDs,\n * address, contacts, and (write-only) bank details for B2B invoicing.\n *\n * **`bank` is write-only.** The wire schema marks `BusinessEntity.bank` as\n * MUST NOT be echoed in responses (sellers store and confirm receipt\n * without returning the details). `toWireAccount` strips it on emit, so\n * adopters who store the full entity here will not leak bank details to\n * buyers — but DO NOT rely on the strip for anything beyond response\n * projection. Adopters loading the entity from their own DB SHOULD apply\n * the same rule at retrieval time, especially for non-list endpoints.\n */\n billing_entity?: BusinessEntity;\n\n /**\n * Identifier for the rate card applied to this account. Opaque seller-side\n * string; emitted unchanged on the wire.\n */\n rate_card?: string;\n\n /** Payment terms applied to this account. */\n payment_terms?: PaymentTerms;\n\n /** Maximum outstanding balance allowed on this account. */\n credit_limit?: WireAccount['credit_limit'];\n\n /**\n * Setup payload for accounts in `pending_approval`. Carries the URL/message\n * the buyer surfaces to a human to complete activation (credit-app, legal\n * agreement, fund-add). Required-shape: `message` is mandatory; `url` and\n * `expires_at` are optional.\n *\n * The framework does NOT validate that `setup` is populated when status is\n * `pending_approval` — that's an adopter contract with the spec. It also\n * does NOT clear `setup` when status leaves `pending_approval`; adopters\n * who echo the same `Account` across status transitions should drop the\n * field themselves.\n */\n setup?: WireAccount['setup'];\n\n /** Account scope (operator / brand / operator_brand / agent). */\n account_scope?: AccountScope;\n\n /**\n * Governance agent endpoints registered on this account. Auth credentials\n * are write-only on the wire and not modeled here — adopters set/update\n * via `sync_governance`, not by re-emitting the Account.\n */\n governance_agents?: WireAccount['governance_agents'];\n\n /**\n * Cloud storage bucket for offline reporting delivery. Only present when\n * the seller's capabilities advertise `reporting_delivery_methods`\n * including `'offline'`. Per-account access MUST be IAM-scoped — see the\n * schema description for security constraints.\n */\n reporting_bucket?: WireAccount['reporting_bucket'];\n\n /**\n * Account-level webhook subscriptions registered through `sync_accounts`.\n * Beta 3 adds wholesale product/signal feed webhooks here. The framework\n * strips legacy `authentication.credentials` before emitting accounts on\n * `list_accounts`; adopters must still persist credentials server-side if\n * they accept legacy webhook auth.\n */\n notification_configs?: NotificationConfig[];\n\n /**\n * Caller-specific authorization metadata for this account. Emitted only on\n * `list_accounts` / account response surfaces that use the\n * `AccountWithAuthorization` wire shape. Use this for platform adapters\n * that can introspect what the authenticated buyer agent may do on this\n * account, including downstream grants such as advertiser-account access\n * plus publisher identity/post authorization.\n *\n * Absence is silence, not denial: it means the adapter does not expose\n * introspectable account authorization for this caller/account tuple.\n */\n authorization?: AccountAuthorization;\n\n /**\n * Sandbox account marker. For implicit accounts the wire schema treats\n * this as part of the natural key — the same brand/operator pair can have\n * separate production and sandbox accounts. For explicit accounts, sandbox\n * accounts are pre-existing test accounts the seller surfaces via\n * `list_accounts`.\n *\n * @deprecated Use {@link Account.mode} instead. As of AdCP 6.7+ the\n * three-mode `mode: 'live' | 'sandbox' | 'mock'` field is the canonical\n * signal the framework gate consults — see\n * `docs/proposals/lifecycle-state-and-sandbox-authority.md`. Adopters\n * stamping this `sandbox` flag continue to work via\n * `getAccountMode`'s legacy fallback (`sandbox: true` reads as\n * `mode: 'sandbox'`); new code should set `mode` directly. This\n * field will be removed in the next major version.\n *\n * The wire-side `AccountReference.sandbox` flag (per\n * `core/account-ref.json`) stays — it's part of the spec's natural-key\n * disambiguation for implicit accounts. The deprecation is on the\n * SERVER-side resolved `Account.sandbox` only.\n */\n sandbox?: boolean;\n\n /**\n * Wire `ext` extension hatch. Carries forward-compatible additions the\n * codegen'd type doesn't model yet. Adopters who don't need extensions\n * leave this undefined.\n */\n ext?: ExtensionObject;\n\n /**\n * Adapter-internal opaque state. Framework doesn't read this; **stripped\n * before emitting on the wire**. GAM puts `{ networkId, advertiserId }`;\n * Spotify puts `{ brandId, businessId }`; Criteo puts `{ customerId }`.\n * Each platform's choice.\n *\n * Same field name (`ctx_metadata`) used across every DecisioningPlatform\n * resource (Product, MediaBuy, Package, Creative, Audience, Signal,\n * Account) for naming consistency. Account is special operationally:\n * `accounts.resolve()` is called per-request, so the publisher is the\n * canonical source of truth and the SDK does NOT round-trip Account\n * `ctx_metadata` through the cache (unlike Product / MediaBuy / etc.,\n * where the SDK bridges between `getProducts` and `createMediaBuy`).\n * Put adapter state in `ctx_metadata`; treat it as fresh from your\n * `accounts.resolve()` on every request.\n *\n * **DO NOT put credentials here.** The wire-strip protects buyer\n * responses but does NOT protect server-side log lines, error\n * envelopes (when `exposeErrorDetails: true`), heap dumps, or\n * adopter-generated strings (`JSON.stringify(account)` in an error\n * message). Bearer tokens, OAuth refresh tokens, API keys, and\n * client secrets belong on `authInfo` (which the framework\n * round-trips through `refreshToken`) or in your own per-principal\n * token cache — NOT in `ctx_metadata`. See\n * [`docs/guides/CTX-METADATA-SAFETY.md`](../../../../docs/guides/CTX-METADATA-SAFETY.md)\n * for the full guidance and the recommended re-derive-per-request\n * pattern.\n */\n ctx_metadata: TCtxMeta;\n\n /**\n * Caller's authenticated principal. **Stripped before emitting on the wire.**\n *\n * Optional from the adopter's perspective: when `accounts.resolve` returns\n * an `Account` without `authInfo`, the framework auto-attaches the\n * principal from `ctx.authInfo` (the auth shape extracted by\n * `serve({ authenticate })`). Adopters that need to *transform* the\n * principal — e.g. derive a tenant-scoped sub-principal from the OAuth\n * client — set it explicitly; adopters that just want the\n * `serve({ authenticate })` principal threaded through resource handlers\n * can omit the field and rely on the framework default.\n */\n authInfo?: AuthPrincipal;\n}\n\n/**\n * The OAuth-style auth shape extracted by `serve({ authenticate })`. Threaded\n * to `accounts.resolve(ref, ctx)` and to the `tasks_get` custom-tool handler\n * so adopters can authorize the resolution against the principal.\n *\n * Distinct from {@link AuthPrincipal} — `ResolvedAuthInfo` is the RAW\n * transport-level auth the framework hands to the resolver; `AuthPrincipal`\n * is what the resolver chooses to persist on the resolved `Account`. The\n * resolver decides what to keep / drop / re-shape.\n *\n * @public\n */\nexport interface ResolvedAuthInfo {\n /**\n * Kind-discriminated credential — Phase 1 Stage 3 of #1269. Populated by\n * the framework's built-in authenticators (`verifyApiKey`, `verifyBearer`,\n * `verifySignatureAsAuthenticator`); custom `authenticate` callbacks can\n * stamp this directly on the returned `AuthPrincipal` to opt into the\n * discriminated-credential surface. The framework propagates it from\n * `req.auth.extra.credential` to this top-level field on every request.\n *\n * **Verified vs. claimed.** `credential.kind === 'http_sig'` carries an\n * `agent_url` that is cryptographically verified by the framework's\n * signature verifier (per adcontextprotocol/adcp#3831). The framework\n * brands verified credentials with a module-private symbol that\n * `BuyerAgentRegistry` factories check before treating the credential\n * as authentic — a literal-shape `{ kind: 'http_sig', ... }` synthesized\n * by a custom authenticator is rejected at the registry layer. Adopters\n * making security-relevant decisions on `agent_url` MUST read it from\n * the credential variant; framework-stamped registry-derived URLs are\n * exposed via `ctx.agent.agent_url` only.\n */\n credential?: AdcpCredential;\n\n /**\n * Optional operator seat within the buyer agent. Stamped only when the\n * authenticator's claims include a `sub` / `oid` / equivalent identifying\n * a sub-principal within the agent. Reserved for future use; v1 of\n * `BuyerAgentRegistry` doesn't consume it.\n */\n operator?: string;\n\n /**\n * @deprecated Use `credential.kind === 'oauth' ? credential.client_id : ...`\n * for the discriminated shape. Optional in N+1 of the deprecation cycle\n * per #1269; framework continues to populate it for adopter compatibility\n * through the cycle. Removed in N+2.\n */\n token?: string;\n\n /**\n * @deprecated Use `credential.client_id` (oauth) or `credential.key_id`\n * (api_key) instead.\n */\n clientId?: string;\n\n /** @deprecated Use `credential.scopes` (oauth) instead. */\n scopes?: string[];\n\n expiresAt?: number;\n extra?: Record<string, unknown>;\n}\n\nexport interface ResolveContext {\n /** Authenticated principal extracted by `serve({ authenticate })`. Undefined when no `authenticate` is configured. */\n authInfo?: ResolvedAuthInfo;\n /** Tool the buyer is calling — useful for tool-aware tenant routing. */\n toolName?: string;\n /**\n * Resolved buyer agent from `BuyerAgentRegistry.resolve()`, when an\n * `agentRegistry` is configured (Phase 1 of #1269). The framework calls\n * the registry once per request before `accounts.resolve` and threads the\n * resolved record here so adopters can route tenant resolution against\n * the durable buyer-agent identity rather than re-deriving it from\n * `authInfo`. Undefined when no registry is configured OR when the\n * registry returns null for the request's credential.\n */\n agent?: BuyerAgent;\n /**\n * Un-destructured wire request envelope. Set by the framework so account\n * tool handlers (`syncAccounts`, `syncGovernance`, `listAccounts`,\n * `reportUsage`, `getAccountFinancials`) can read request fields the\n * typed signature doesn't model — e.g. `sync_accounts.delete_missing`\n * and `sync_accounts.dry_run`, which the framework destructures the\n * payload array out of before calling the handler.\n *\n * Same shape and read-site cast pattern as `RequestContext.input` (see\n * `decisioning/context.ts`). Same caveats:\n *\n * - **Identical reference to the typed payload arg.** This is the same\n * request body object the platform method's first positional arg\n * projects from. Framework auto-hydrate seams mutate this object\n * before the platform method runs; treat fields the buyer sent as\n * authoritative, but expect framework-injected entities (e.g.\n * hydrated product / media-buy refs) to be visible here too.\n * - **Buyer-controlled untrusted data.** Free-text fields (`brief`,\n * `message`, creative snippets, etc.) are attacker-controlled.\n * Don't log `ctx.input` wholesale — secret fields like\n * `push_notification_config.token` are present on mutating requests.\n * When templating into LLM prompts, validate or fence the field\n * rather than string-interpolating.\n *\n * @public\n */\n input?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Context passed to AccountStore tool methods that operate on a single\n * resolved Account (today: `getAccountFinancials`). Threads the resolved\n * `Account<TCtxMeta>` through so adopters can read `ctx.account.ctx_metadata`\n * (auth tokens, upstream IDs, etc.) without re-resolving from the request.\n *\n * Strict superset of `ResolveContext`: same `authInfo` / `toolName` fields,\n * plus the resolved account. Distinct type because `accounts.resolve()`\n * produces the account and therefore cannot receive it on input.\n *\n * **NOT applicable to `reportUsage`.** `ReportUsageRequest.usage[]` carries\n * a per-row `account: AccountReference`; a request can span multiple\n * accounts. Pre-resolving a single `ctx.account` would misrepresent that\n * shape. `reportUsage` keeps `ResolveContext` and per-row resolution is\n * the adopter's responsibility (call `accounts.resolve` from inside the\n * impl, once per row).\n *\n * @public\n */\nexport interface AccountToolContext<TCtxMeta = Record<string, unknown>> extends ResolveContext {\n /** Resolved Account from `accounts.resolve()`. Populated by the framework before dispatch. */\n account: Account<TCtxMeta>;\n}\n\n/**\n * Request context for tools whose wire request does not carry an `account`\n * field — `preview_creative`, `list_creative_formats`, and\n * `provide_performance_feedback`. The framework calls\n * `accounts.resolve(undefined, ctx)` for these, accepting a `null` return; if\n * `null`, `ctx.account` is undefined when the handler runs.\n *\n * Adopter handlers MUST handle the `undefined` case explicitly. Choose one of:\n *\n * 1. **Singleton fallback** — return a non-null synthetic `Account` from\n * `accounts.resolve(undefined, ctx)` for the publisher-wide tenant\n * (e.g., format catalog, performance feedback aggregation). Inside the\n * handler, narrow with `if (!ctx.account) throw ...` once and treat\n * `ctx.account` as defined for the rest.\n * 2. **Auth-derived lookup** — in `accounts.resolve(undefined, ctx)`, look\n * up by `ctx.authInfo.clientId` (or whichever principal field your auth\n * wires) and return the matching account.\n * 3. **Error out** — throw `AdcpError({ code: 'ACCOUNT_NOT_FOUND' })` from\n * within the handler when `ctx.account == null` and the operation\n * requires tenant scoping.\n *\n * The narrowed type catches the mismatch at authorship time — adopters who\n * forget to handle `ctx.account === undefined` get a TS error, not a runtime\n * `Cannot read properties of undefined` deep in their upstream call. Same\n * shape as the `definePlatformWithCompliance` invariant: convert a runtime\n * gate into a compile-time one.\n *\n * @public\n */\n// Inline type-import on `RequestContext` instead of a top-level\n// `import type { RequestContext } from './context'` — `context.ts` already\n// imports `Account` from this file, so a top-level import would form a\n// circular type dependency.\nexport type NoAccountCtx<TCtxMeta = Record<string, unknown>> = Omit<\n import('./context').RequestContext<Account<TCtxMeta>>,\n 'account'\n> & {\n /**\n * Resolved account, OR `undefined` when the wire request didn't carry an\n * account ref AND `accounts.resolve(undefined, ctx)` returned null. Always\n * narrow before reading `ctx_metadata` / `id`.\n */\n account: Account<TCtxMeta> | undefined;\n};\n\nexport interface AuthPrincipal {\n /** Stable identifier for the calling agent (e.g., `https://buyer.example.com/mcp`). */\n agent_url?: string;\n /** Token kind: API key, OAuth bearer, signed-request claim. */\n kind: 'api_key' | 'oauth' | 'signature' | 'public';\n /** Bearer token / API key value. Platform-side don't log this. */\n token?: string;\n /** Token expiry (ms since epoch). Set by `accounts.refreshToken` after a successful refresh. */\n expiresAt?: number;\n /** OAuth scopes / API-key principal name. */\n principal?: string;\n /** Additional claims (jwt sub, kid, etc.). */\n claims?: Record<string, unknown>;\n}\n\nexport interface AccountStore<TCtxMeta = Record<string, unknown>> {\n /**\n * How buyers reference accounts on this platform.\n * - `'explicit'` — buyer passes `account_id` inline on every request (Snap,\n * Meta, GAM via Network/Company id). The default.\n * - `'implicit'` — buyer must `sync_accounts` first; subsequent requests are\n * resolved from the auth principal's pre-synced linkage (LinkedIn, some\n * retail-media operators). Framework refuses inline `account_id` references\n * for these platforms — emits `AdcpError('INVALID_REQUEST', { field:\n * 'account.account_id' })` before reaching `accounts.resolve`. The\n * brand+operator union arm is permitted (used during the initial\n * `sync_accounts` flow); only `account_id`-shaped references are rejected.\n * - `'derived'` — single-tenant agents where there is no account_id on the\n * wire at all and the auth principal alone identifies the tenant. Most\n * self-hosted broadcasters and retail-media operators in proxy mode.\n * Framework refuses inline `account_id` references for these platforms —\n * same `AdcpError('INVALID_REQUEST', { field: 'account.account_id' })`\n * shape as `'implicit'`, but with a single-tenant message instead of the\n * `sync_accounts`-first guidance (no `sync_accounts` step exists in\n * derived mode). The brand+operator union arm is permitted.\n *\n * Defaults to `'explicit'` when omitted.\n */\n readonly resolution?: 'explicit' | 'implicit' | 'derived';\n\n /**\n * Resolve buyer's AccountReference into the platform's tenant model.\n *\n * `ref` is `undefined` when the wire request didn't carry an account\n * field — `provide_performance_feedback` and `list_creative_formats` are\n * the canonical examples. Per `resolution` mode:\n * - `'derived'` (single-tenant): return the singleton account regardless.\n * - `'implicit'`: look up the account from the auth principal.\n * - `'explicit'` (default): no account is available; either throw\n * `AccountNotFoundError` to signal \"tool requires account\" OR return\n * a synthetic singleton if the tool legitimately doesn't need\n * tenant scoping (e.g., publisher-wide format catalog from\n * `list_creative_formats`).\n *\n * `ctx.authInfo` is the caller's authenticated principal (when\n * `serve({ authenticate })` is wired). Adapters fronting an upstream\n * platform API (Snap, Meta, retail-media) translate auth to tenant ID:\n *\n * ```ts\n * resolve: async (ref, ctx) => {\n * if (ref?.account_id) return await this.db.findById(ref.account_id);\n * const cred = ctx?.authInfo?.credential;\n * const clientKey = cred?.kind === 'oauth' ? cred.client_id\n * : cred?.kind === 'api_key' ? cred.key_id\n * : undefined;\n * const platformAcct = clientKey ? await myUpstream.findByClientKey(clientKey) : null;\n * return platformAcct ? this.toAccount(platformAcct) : null;\n * }\n * ```\n *\n * Two failure shapes:\n * - **Unknown / cross-tenant reference**: return `null` (canonical) — OR\n * throw `AccountNotFoundError` if your codebase already throws a\n * not-found exception class. Framework emits the spec's fixed\n * `ACCOUNT_NOT_FOUND` envelope either way. The buyer learns no detail\n * beyond \"not found\" — guarding against principal-enumeration.\n * - **Transient upstream failure** (DB outage, identity-provider 5xx):\n * throw a generic exception. Framework maps to `SERVICE_UNAVAILABLE`\n * so the buyer can retry.\n */\n resolve(ref: AccountReference | undefined, ctx?: ResolveContext): Promise<Account<TCtxMeta> | null>;\n\n /**\n * sync_accounts API surface. Framework normalizes the wire request; platform\n * upserts and returns per-account result rows. `throw new AdcpError(...)`\n * for buyer-facing rejection.\n *\n * In AdCP 3.1 beta, adopters that need settings-update entries with\n * `notification_configs[]` can read the full wire body from `ctx.input`\n * or supply a top-level `accounts.syncAccounts` handler.\n *\n * **Optional.** Stateless platforms (creative-template, signal-marketplace\n * proxies) that don't manage account lifecycle can omit this; framework\n * surfaces `UNSUPPORTED_FEATURE` to buyers calling `sync_accounts`.\n *\n * `ctx.authInfo` carries the caller's authenticated principal (when\n * `serve({ authenticate })` is wired); `ctx.agent` carries the resolved\n * `BuyerAgent` record (when an `agentRegistry` is configured). Adopters\n * implementing principal-keyed gates (e.g., per-buyer-agent\n * `BILLING_NOT_PERMITTED_FOR_AGENT` on the spec's billing surfaces) read\n * the principal here — same threading as `accounts.resolve`.\n *\n * **Prefer `ctx.agent` over `ctx.authInfo.credential` for commercial-\n * relationship decisions.** `ctx.agent` is the registry-resolved durable\n * identity (status, billing capabilities, default account terms);\n * `ctx.authInfo.credential` is the raw transport-level credential. For\n * billing gates the registry-resolved identity is canonical. Use\n * `credential` only for transport-level branching (e.g., reading the\n * verified `agent_url` from `credential.kind === 'http_sig'` when\n * `agentRegistry` is not configured).\n */\n upsert?(refs: AccountReference[], ctx?: ResolveContext): Promise<SyncAccountsHandlerResult>;\n\n /**\n * sync_governance API surface. Buyers register governance agent endpoints\n * per-account; the seller persists the binding and consults the agents\n * during media buy lifecycle events via `check_governance`.\n *\n * **Optional.** Adopters that don't model buyer-supplied governance agents\n * (most direct sellers) leave this unimplemented and the framework returns\n * `UNSUPPORTED_FEATURE`.\n *\n * `entries` is the wire request's `accounts[]` — each entry pairs an\n * `AccountReference` with its `governance_agents[]`. The framework has\n * already deduped on `idempotency_key` and stripped wire metadata\n * (`adcp_major_version`, `context`, `ext`) before invoking this method.\n *\n * **Replace semantics, per spec.** Each call REPLACES the previously\n * synced governance agents for the referenced account. An entry whose\n * `governance_agents` is empty clears the binding for that account.\n *\n * **Write-only credentials.** Each `governance_agents[i].authentication.credentials`\n * is the bearer the seller presents to that governance agent on outbound\n * `check_governance` calls. Persist them — silently dropping ships\n * unauthenticated requests once cross-agent calls are wired. The framework\n * strips `authentication` from each `governance_agents[i]` of every row\n * before serialization (`toWireSyncGovernanceRow`), so credentials never\n * reach the response wire OR the idempotency replay cache, even if an\n * adopter returns a loosely-typed row that spreads the input. Do not rely\n * on TypeScript narrowing alone — the strip is enforced at the dispatcher.\n *\n * `ctx.authInfo` and `ctx.agent` carry the caller's principal — same\n * threading as `upsert`. Adopters MUST gate per-entry persistence by the\n * caller's tenant: each entry's `account.operator` (or `account_id`) must\n * map to the same tenant the auth principal authorizes; otherwise return a\n * `'failed'` row carrying `errors: [{code: 'PERMISSION_DENIED', ...}]` for\n * that entry. (Operation-level rejection — `throw new AdcpError(...)` —\n * fails the whole batch, which is the wrong shape when a single entry\n * fails the gate.)\n */\n syncGovernance?(\n entries: SyncGovernanceRequest['accounts'],\n ctx?: ResolveContext\n ): Promise<SyncGovernanceHandlerResult>;\n\n /**\n * list_accounts API surface. Framework wraps with cursor envelope.\n *\n * **Optional.** Same rationale as `upsert` — stateless platforms can omit.\n *\n * `ctx.authInfo` and `ctx.agent` carry the caller's principal — adopters\n * scope the listing per-principal (e.g., return only accounts visible to\n * the calling buyer agent) without re-deriving identity from the request.\n */\n list?(filter: AccountFilter & CursorRequest, ctx?: ResolveContext): Promise<ListAccountsHandlerResult<TCtxMeta>>;\n\n /**\n * report_usage API surface. Operator-billed platforms accept usage rows\n * (often impressions / spend by media_buy + period) for billing\n * reconciliation. Optional — adopters that don't run billing through the\n * agent leave this unimplemented and the framework returns\n * UNSUPPORTED_FEATURE.\n *\n * Idempotent on `(account, period_start, period_end, line_item_id)` —\n * platform must dedupe replays under the framework's idempotency key.\n *\n * `ctx.authInfo` carries the caller's OAuth principal (when\n * `serve({ authenticate })` is wired); `ctx.agent` carries the resolved\n * `BuyerAgent` record (when an `agentRegistry` is configured). Platforms\n * fronting an upstream billing API (Snap, Meta, retail-media) use them\n * to authorize the usage post against the principal's tenant — same\n * pattern as `accounts.resolve`. Prefer `ctx.agent` for principal-keyed\n * commercial gates; see `upsert?` for the rationale.\n */\n reportUsage?(req: ReportUsageRequest, ctx?: ResolveContext): Promise<ReportUsageHandlerResult>;\n\n /**\n * get_account_financials API surface. Operator-billed platforms expose\n * spend / credit / payment status per the wire shape. Optional — agent-\n * billed platforms (where the buyer settles directly with the publisher)\n * leave this unimplemented.\n *\n * Read tool — no idempotency requirement. Throw `AdcpError` for buyer-\n * fixable rejection (`'PERMISSION_DENIED'` if the principal can't see\n * financials for the requested account).\n *\n * `ctx.account` is the resolved `Account<TCtxMeta>` (framework calls\n * `accounts.resolve(req.account)` first and threads the result in).\n * Adopters fronting an upstream platform read tokens / upstream IDs from\n * `ctx.account.ctx_metadata` without re-resolving.\n *\n * `ctx.authInfo` carries the caller's OAuth principal (when\n * `serve({ authenticate })` is wired); `ctx.agent` carries the resolved\n * `BuyerAgent` record (when an `agentRegistry` is configured). Platforms\n * that guard financials per-principal use them to authorize the read —\n * same pattern as `accounts.resolve`. Prefer `ctx.agent` for principal-\n * keyed commercial gates; see `upsert?` for the rationale.\n */\n getAccountFinancials?(\n req: GetAccountFinancialsRequest,\n ctx: AccountToolContext<TCtxMeta>\n ): Promise<GetAccountFinancialsHandlerResult>;\n\n /**\n * Mid-request token refresh hook. Optional. Called by the framework when\n * a platform method throws a refreshable token-auth code (`AUTH_REQUIRED`\n * for legacy compatibility or `AUTH_MISSING` for an AdCP 3.1-native\n * missing request credential) AND `refreshToken` is defined — the\n * framework refreshes via this hook, mutates or creates `account.authInfo`\n * with the returned token, and retries the failing platform method exactly\n * once.\n *\n * The reason string lets adopters distinguish trigger conditions:\n * - `'auth_required'` — platform method threw refreshable auth in flight.\n *\n * Treat as an open string union: future values may be added. Adopters\n * SHOULD switch exhaustively (`default: throw`) so behavior drift on\n * minor SDK bumps fails loud rather than silently no-oping.\n *\n * **In-flight only.** The refreshed token is scoped to the current\n * request — the framework does NOT echo it back to the buyer. Use this\n * for adapters that front an upstream platform API (Snap, Meta,\n * retail-media OAuth flows) where the SDK caches an upstream token\n * server-side and the buyer's auth-to-this-agent is separate.\n *\n * **Account-object identity contract.** The framework mutates a\n * request-local Account clone before retrying, creating an OAuth-shaped\n * auth principal if the resolver omitted one. The resolver-returned object\n * is not written back. Adopters should still avoid caching secret-bearing\n * `Account.authInfo` objects across unrelated callers, but SDK refresh\n * retry does not mutate a cached resolver object in place.\n *\n * **Concurrency.** `refreshToken` MUST be safe under concurrent\n * invocation on the same account — two parallel in-flight calls hitting\n * refreshable auth at once will both call this hook. Adopters whose\n * upstream provider rate-limits refresh should coalesce internally\n * (e.g., a per-account in-flight refresh promise). The framework does\n * not coalesce.\n *\n * **Failure surfaces correctable AUTH_REQUIRED.** If `refreshToken`\n * itself throws, the framework projects to `AUTH_REQUIRED` with\n * `recovery: 'correctable'` and a fixed message (the inner exception\n * text is NOT echoed on the wire — refresh failures routinely include\n * upstream details that should not cross the trust boundary). Log inner\n * details server-side. Don't use SERVICE_UNAVAILABLE — refresh failure\n * means the upstream authorization is gone, not that the service is\n * transiently down.\n *\n * **Expiry timestamp** (`expiresAt`, ms since epoch) is optional. When\n * returned, the framework writes it to `account.authInfo.expiresAt` so\n * adopters reading the resolved Account can branch on it (proactive\n * refresh is not yet wired; reactive-only in v6.x).\n */\n refreshToken?(account: Account<TCtxMeta>, reason: 'auth_required'): Promise<{ token: string; expiresAt?: number }>;\n}\n\n/**\n * Optional throw-class for `AccountStore.resolve` not-found signaling. Returning\n * `null` from `resolve` is canonical and equivalent; throw this only if your\n * codebase already throws a typed not-found exception elsewhere.\n *\n * **Throwable only from `AccountStore.resolve()`.** Throwing it from a\n * specialism method (`createMediaBuy`, `getProducts`, etc.) bypasses the\n * framework's not-found mapping and surfaces as `SERVICE_UNAVAILABLE`.\n *\n * The constructor's `message` is for server-side operator diagnostics only.\n * The framework emits a fixed `ACCOUNT_NOT_FOUND` envelope regardless; the\n * message never reaches the buyer. Operator-side log pipelines may aggregate\n * this string, so MUST NOT include caller-supplied identifiers (echoed account\n * refs, request args) — those leak across operator / buyer trust boundaries.\n *\n * Use ONLY for the narrow not-found case. Upstream-API outages, misconfigured\n * env vars, and schema-validation failures should propagate as generic\n * exceptions and surface to the buyer as `SERVICE_UNAVAILABLE`.\n */\nexport class AccountNotFoundError extends Error {\n readonly name = 'AccountNotFoundError' as const;\n constructor(message = 'Account not found') {\n super(message);\n }\n}\n\nexport interface AccountFilter {\n /** Filter by brand domain across all operators. */\n brand_domain?: string;\n /** Filter by operator across all brands. */\n operator?: string;\n /** Filter by status. */\n status?: AdcpAccountStatus[];\n}\n\n/**\n * Per-account result row returned by an adopter's `accounts.upsert`\n * implementation. Maps to one element of the wire `sync_accounts` response's\n * `accounts[]` array.\n *\n * Carries the same optional commercial / lifecycle fields as the wire shape\n * so adopters can echo `setup` (for `pending_approval` accounts), `billing`,\n * `billing_entity`, `payment_terms`, caller-specific `authorization`, etc. on creation. The framework\n * projects these through `toWireSyncAccountRow` before emit, applying the\n * same `billing_entity.bank` strip as `toWireAccount` (write-only contract).\n *\n * **MUST NOT carry `authInfo` or other auth-derived fields.** This shape is\n * emitted on the `sync_accounts` response wire. The framework's projector\n * does not read `authInfo`, but adopters MUST NOT add an `authInfo` key on\n * returned rows — same MUST-NOT-LEAK rule the framework enforces on\n * `Account.authInfo`.\n */\nexport interface SyncAccountsResultRow {\n account_id?: string;\n brand: BrandReference;\n operator: string;\n /** Human-readable account name assigned by the seller. */\n name?: string;\n action: 'created' | 'updated' | 'unchanged' | 'failed';\n status: AdcpAccountStatus;\n /** Invoiced-to party. Echoes the request's `billing` after seller acceptance. */\n billing?: BillingParty;\n /** Business entity invoiced. `bank` is stripped on emit (write-only). */\n billing_entity?: BusinessEntity;\n account_scope?: AccountScope;\n /** Setup payload for `pending_approval` accounts (URL/message/expiry). */\n setup?: WireAccount['setup'];\n rate_card?: string;\n payment_terms?: PaymentTerms;\n credit_limit?: WireAccount['credit_limit'];\n /** Applied account-level webhook subscriptions; credentials are stripped on emit. */\n notification_configs?: NotificationConfig[];\n /**\n * Caller-specific authorization metadata for this synced account, including\n * downstream grants such as advertiser-account access plus publisher\n * identity/post authorization.\n */\n authorization?: AccountAuthorization;\n errors?: SyncAccountError[];\n warnings?: string[];\n sandbox?: boolean;\n}\n\nexport type AdcpAccountStatus =\n | 'active'\n | 'pending_approval'\n | 'rejected'\n | 'payment_required'\n | 'suspended'\n | 'closed';\n\n// ---------------------------------------------------------------------------\n// Wire projection — strip framework-internal fields before emit\n// ---------------------------------------------------------------------------\n\n/**\n * Project a framework `Account<TCtxMeta>` to the wire `Account` shape.\n *\n * Strips `ctx_metadata` and `authInfo` (framework-internal); renames `id` →\n * `account_id`; passes through wire-shaped fields. Strips\n * `billing_entity.bank` per the schema's write-only constraint — bank\n * coordinates flow buyer→seller in `sync_accounts` requests but MUST NOT\n * appear in any response payload.\n *\n * Used by the framework when emitting `list_accounts` and other wire\n * responses that include account data. Adopters never call this directly —\n * they return `Account<TCtxMeta>` from `accounts.resolve` / `accounts.list`\n * and the framework projects.\n */\nexport function toWireAccount<TCtxMeta>(account: Account<TCtxMeta>): WireAccount {\n const wire: WireAccount = {\n account_id: account.id,\n name: account.name,\n status: account.status,\n };\n if (account.brand !== undefined) wire.brand = account.brand;\n if (account.operator !== undefined) wire.operator = account.operator;\n if (account.advertiser !== undefined) wire.advertiser = account.advertiser;\n if (account.billing_proxy !== undefined) wire.billing_proxy = account.billing_proxy;\n if (account.billing !== undefined) {\n // Wire `Account.billing: 'operator' | 'agent' | 'advertiser'` is the\n // invoiced-to party. Internal `billing.invoicedTo` collapses string +\n // BrandReference; a BrandReference indicates a third-party advertiser\n // (Amazon DSP-shaped flow), which projects to `'advertiser'`.\n const t = account.billing.invoicedTo;\n wire.billing = typeof t === 'string' ? t : 'advertiser';\n }\n const projectedEntity = projectBillingEntity(account.billing_entity);\n if (projectedEntity !== undefined) wire.billing_entity = projectedEntity;\n if (account.rate_card !== undefined) wire.rate_card = account.rate_card;\n if (account.payment_terms !== undefined) wire.payment_terms = account.payment_terms;\n if (account.credit_limit !== undefined) wire.credit_limit = account.credit_limit;\n if (account.setup !== undefined) wire.setup = account.setup;\n if (account.account_scope !== undefined) wire.account_scope = account.account_scope;\n if (account.governance_agents !== undefined) {\n wire.governance_agents = account.governance_agents.map(projectGovernanceAgent);\n }\n if (account.reporting_bucket !== undefined) wire.reporting_bucket = account.reporting_bucket;\n if (account.notification_configs !== undefined) {\n (wire as unknown as { notification_configs?: WireNotificationConfig[] }).notification_configs =\n account.notification_configs.map(projectNotificationConfig);\n }\n if (account.authorization !== undefined) {\n (wire as WireAccount & { authorization?: AccountAuthorization }).authorization = projectAccountAuthorization(\n account.authorization\n );\n }\n if (account.sandbox !== undefined) wire.sandbox = account.sandbox;\n if (account.ext !== undefined) wire.ext = account.ext;\n return wire;\n}\n\nfunction projectAccountAuthorization(authorization: AccountAuthorization): AccountAuthorization {\n const projected: AccountAuthorization = {\n allowed_tasks: [...authorization.allowed_tasks],\n };\n if (authorization.field_scopes !== undefined) {\n projected.field_scopes = Object.fromEntries(\n Object.entries(authorization.field_scopes)\n .filter((entry): entry is [string, string[]] => Array.isArray(entry[1]))\n .map(([task, fields]) => [task, [...fields]])\n );\n }\n if (authorization.scope_name !== undefined) projected.scope_name = authorization.scope_name;\n if (authorization.read_only !== undefined) projected.read_only = authorization.read_only;\n return projected;\n}\n\ntype WireSyncAccountRow = SyncAccountsSuccess['accounts'][number];\n\n/**\n * Project an adopter `SyncAccountsResultRow` to the wire shape returned by\n * `sync_accounts`. Applies the same `billing_entity.bank` strip as\n * `toWireAccount` — the wire schema marks bank coordinates write-only on\n * EVERY response, not just `list_accounts`. Adopters returning a row that\n * spreads a DB record carrying `bank` (e.g.,\n * `{ ...db.findByBrand(r.brand), action: 'updated' }`) have it stripped\n * before emit.\n *\n * Used by the framework when emitting `sync_accounts` responses. Adopters\n * never call this directly — they return `SyncAccountsResultRow[]` from\n * `accounts.upsert` and the framework projects.\n */\nexport function toWireSyncAccountRow(row: SyncAccountsResultRow): WireSyncAccountRow {\n const wire: WireSyncAccountRow = {\n brand: row.brand,\n operator: row.operator,\n action: row.action,\n status: row.status,\n };\n if (row.account_id !== undefined) wire.account_id = row.account_id;\n if (row.name !== undefined) wire.name = row.name;\n if (row.billing !== undefined) wire.billing = row.billing;\n const projectedEntity = projectBillingEntity(row.billing_entity);\n if (projectedEntity !== undefined) wire.billing_entity = projectedEntity;\n if (row.account_scope !== undefined) wire.account_scope = row.account_scope;\n if (row.setup !== undefined) wire.setup = row.setup;\n if (row.rate_card !== undefined) wire.rate_card = row.rate_card;\n if (row.payment_terms !== undefined) wire.payment_terms = row.payment_terms;\n if (row.credit_limit !== undefined) wire.credit_limit = row.credit_limit;\n if (row.notification_configs !== undefined) {\n (wire as unknown as { notification_configs?: WireNotificationConfig[] }).notification_configs =\n row.notification_configs.map(projectNotificationConfig);\n }\n if (row.authorization !== undefined) {\n (wire as WireSyncAccountRow & { authorization?: AccountAuthorization }).authorization = projectAccountAuthorization(\n row.authorization\n );\n }\n if (row.errors !== undefined) wire.errors = row.errors;\n if (row.warnings !== undefined) wire.warnings = row.warnings;\n if (row.sandbox !== undefined) wire.sandbox = row.sandbox;\n return wire;\n}\n\nfunction projectNotificationConfig(config: NotificationConfig): WireNotificationConfig {\n const { authentication, ...rest } = config;\n if (!authentication) return rest;\n const { credentials: _credentials, ...authenticationWithoutCredentials } = authentication;\n return { ...rest, authentication: authenticationWithoutCredentials };\n}\n\ntype WireSyncGovernanceRow = SyncGovernanceSuccess['accounts'][number];\n\n/**\n * Project a `sync_governance` response row to the wire shape, stripping\n * any fields the buyer is NOT entitled to receive. Critically: each\n * `governance_agents[i]` is reduced to `{url, categories?}` only — the\n * spec marks `authentication.credentials` write-only (the buyer sends\n * the bearer; the seller persists it for outbound `check_governance`\n * calls but MUST NOT echo it back). The natural `{ ...entry.governance_agents[i] }`\n * echo idiom would compile silently against the typed return shape and\n * ship credentials over the wire AND into the idempotency replay cache,\n * arming the buyer (and any subsequent caller hitting the same key) to\n * impersonate the seller against the governance agent.\n *\n * Defense-in-depth: this dispatcher-level strip runs even if an adopter\n * returns a loosely-typed row, and even if a future codegen change\n * loosens the response Zod schema's `.passthrough()` for governance\n * agents.\n */\nexport function toWireSyncGovernanceRow(row: WireSyncGovernanceRow): WireSyncGovernanceRow {\n const wire: WireSyncGovernanceRow = {\n account: row.account,\n status: row.status,\n };\n if (row.governance_agents !== undefined) {\n // AdCP 3.1.0-beta.2 removed `categories` from the governance_agents\n // wire shape. The schema is now `{ url }` only; per-agent category\n // signaling moved out of band. The projection still strips\n // authentication.credentials (write-only) by only naming `url`.\n wire.governance_agents = row.governance_agents.map(a => ({ url: a.url }));\n }\n if (row.errors !== undefined) wire.errors = row.errors;\n return wire;\n}\n\n/**\n * Strip `BusinessEntity.bank` per the schema's write-only constraint, and\n * skip emission entirely when nothing else is populated. Bank-only inputs\n * project to `undefined`, signaling the caller to omit `billing_entity`\n * rather than emit an empty object that would fail `legal_name` validation.\n *\n * Destructure-and-rest excludes `bank` regardless of source shape: own\n * non-enumerable, getter, prototype-chain, and Proxy-backed bank fields\n * are all excluded by the ES rest-spread evaluation order\n * (`CopyDataProperties` walks own-enumerable keys and skips the\n * destructured names).\n */\nfunction projectBillingEntity(entity: BusinessEntity | undefined): BusinessEntity | undefined {\n if (entity === undefined) return undefined;\n const { bank: _bank, ...rest } = entity;\n return Object.keys(rest).length > 0 ? rest : undefined;\n}\n\ntype WireGovernanceAgent = NonNullable<WireAccount['governance_agents']>[number];\n\n/**\n * Project a governance-agent element to the wire shape, dropping any keys\n * the wire schema doesn't model. The schema notes that authentication\n * credentials are write-only and not included in responses; AdCP 3.1.0-beta.2\n * also removed `categories` from the wire shape. The current shape is\n * `{ url }` only — TS is erased at runtime so adopters using JS or `as any`\n * could otherwise smuggle a `credentials` or `categories` field straight\n * to the wire. Explicit projection closes that gap.\n */\nfunction projectGovernanceAgent(agent: WireGovernanceAgent): WireGovernanceAgent {\n return { url: agent.url };\n}\n\n// ---------------------------------------------------------------------------\n// AccountReference helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extract `account_id` from an `AccountReference` discriminated union without\n * casting. Returns `undefined` when `ref` is absent or the union arm doesn't\n * carry an `account_id` (e.g., `{ brand, operator }` or sandbox variants).\n *\n * Typical use in `accounts.resolve` implementations:\n *\n * ```ts\n * resolve: async (ref, ctx) => {\n * const id = refAccountId(ref);\n * if (id) return this.db.findById(id);\n * const cred = ctx?.authInfo?.credential;\n * const key = cred?.kind === 'oauth' ? cred.client_id : cred?.kind === 'api_key' ? cred.key_id : undefined;\n * return key ? this.db.findByClientKey(key) : null;\n * }\n * ```\n *\n * @public\n */\nexport function refAccountId(ref?: AccountReference): string | undefined {\n return ref && 'account_id' in ref ? (ref as { account_id?: string }).account_id : undefined;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -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 { redactCredentialPatterns } from "../redact.mjs";
|
|
8
2
|
function createTenantAdminHandlers(registry) {
|
|
9
3
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/server/decisioning/admin-router.ts"],"sourcesContent":["/**\n * Admin Express router for the v6.0 TenantRegistry.\n *\n * Mounted on a separate port / path from the public agent endpoint so\n * tenant traffic and ops surface stay independent. Adopters wire it\n * behind their existing auth (basic auth, mTLS, OAuth introspection):\n *\n * ```ts\n * import express from 'express';\n * import { createTenantAdminRouter } from '@adcp/sdk/server/decisioning';\n *\n * const adminApp = express();\n * adminApp.use('/admin', requireOpsAuth, createTenantAdminRouter(registry));\n * adminApp.listen(9090);\n * ```\n *\n * Endpoints:\n *\n * - `GET /tenants` — list all tenants with health status\n * - `GET /tenants/:id` — single tenant status (404 if unknown)\n * - `POST /tenants/:id/recheck` — force JWKS revalidation (returns new status)\n * - `DELETE /tenants/:id` — unregister (idempotent; 204 either way)\n *\n * All responses are JSON. Missing tenants return 404 + `{ error: 'tenant_not_found' }`.\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\n\nimport type { Request, Response, NextFunction, IRouter } from 'express';\nimport type { TenantRegistry } from './tenant-registry';\nimport { redactCredentialPatterns } from '../redact';\n\n/**\n * Minimal Express-router-shaped object so we don't need a hard dependency\n * on the Express types in this file. Adopters who use a different framework\n * (Koa, Fastify) can mount the same handler functions via the framework's\n * adapter — `createTenantAdminHandlers(registry)` returns the bare handlers.\n */\nexport interface RouterLike {\n get(path: string, handler: (req: Request, res: Response, next?: NextFunction) => void): unknown;\n post(path: string, handler: (req: Request, res: Response, next?: NextFunction) => void): unknown;\n delete(path: string, handler: (req: Request, res: Response, next?: NextFunction) => void): unknown;\n}\n\nexport interface TenantAdminHandlers {\n listTenants(req: Request, res: Response): void;\n getTenant(req: Request, res: Response): void;\n recheckTenant(req: Request, res: Response): Promise<void>;\n unregisterTenant(req: Request, res: Response): void;\n}\n\n/**\n * Bare handlers — for adopters running a non-Express framework. The router\n * helper below mounts these on the standard paths.\n */\nexport function createTenantAdminHandlers(registry: TenantRegistry): TenantAdminHandlers {\n return {\n listTenants(_req: Request, res: Response): void {\n res.json({ tenants: registry.list() });\n },\n\n getTenant(req: Request, res: Response): void {\n const id = req.params.id;\n if (!id) {\n res.status(400).json({ error: 'tenant_id_required' });\n return;\n }\n const status = registry.getStatus(id);\n if (!status) {\n res.status(404).json({ error: 'tenant_not_found', tenant_id: id });\n return;\n }\n res.json(status);\n },\n\n async recheckTenant(req: Request, res: Response): Promise<void> {\n const id = req.params.id;\n if (!id) {\n res.status(400).json({ error: 'tenant_id_required' });\n return;\n }\n try {\n const status = await registry.recheck(id);\n res.json(status);\n } catch (err) {\n if (err instanceof Error && /not registered/.test(err.message)) {\n res.status(404).json({ error: 'tenant_not_found', tenant_id: id });\n return;\n }\n // Redact credential patterns before exposing on the wire (#1330).\n // The recheck path can throw with upstream errors that echo\n // basic-auth URLs or other credential bytes.\n res.status(500).json({\n error: 'recheck_failed',\n tenant_id: id,\n reason: redactCredentialPatterns(err instanceof Error ? err.message : String(err)),\n });\n }\n },\n\n unregisterTenant(req: Request, res: Response): void {\n const id = req.params.id;\n if (!id) {\n res.status(400).json({ error: 'tenant_id_required' });\n return;\n }\n registry.unregister(id);\n res.status(204).end();\n },\n };\n}\n\n/**\n * Build an Express router with the standard admin endpoints mounted.\n * Pass an `express.Router()` instance to mount on (so we don't need an\n * Express dependency in this file).\n */\nexport function mountTenantAdmin(router: RouterLike, registry: TenantRegistry): RouterLike {\n const handlers = createTenantAdminHandlers(registry);\n router.get('/tenants', handlers.listTenants);\n router.get('/tenants/:id', handlers.getTenant);\n router.post('/tenants/:id/recheck', handlers.recheckTenant);\n router.delete('/tenants/:id', handlers.unregisterTenant);\n return router;\n}\n\n/**\n * Convenience: takes an `express` import and a registry, returns a\n * mounted `Router` ready to attach. Usage:\n *\n * ```ts\n * import express from 'express';\n * import { createTenantAdminRouter } from '@adcp/sdk/server/decisioning';\n * adminApp.use('/admin', createTenantAdminRouter(express.Router(), registry));\n * ```\n *\n * The `routerFactory` argument lets adopters pre-configure middleware\n * (auth, logging) on the router before passing it in.\n */\nexport function createTenantAdminRouter<R extends RouterLike>(routerFactory: R, registry: TenantRegistry): R {\n mountTenantAdmin(routerFactory, registry);\n return routerFactory;\n}\n\nexport type { IRouter };\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/server/decisioning/admin-router.ts"],"sourcesContent":["/**\n * Admin Express router for the v6.0 TenantRegistry.\n *\n * Mounted on a separate port / path from the public agent endpoint so\n * tenant traffic and ops surface stay independent. Adopters wire it\n * behind their existing auth (basic auth, mTLS, OAuth introspection):\n *\n * ```ts\n * import express from 'express';\n * import { createTenantAdminRouter } from '@adcp/sdk/server/decisioning';\n *\n * const adminApp = express();\n * adminApp.use('/admin', requireOpsAuth, createTenantAdminRouter(registry));\n * adminApp.listen(9090);\n * ```\n *\n * Endpoints:\n *\n * - `GET /tenants` — list all tenants with health status\n * - `GET /tenants/:id` — single tenant status (404 if unknown)\n * - `POST /tenants/:id/recheck` — force JWKS revalidation (returns new status)\n * - `DELETE /tenants/:id` — unregister (idempotent; 204 either way)\n *\n * All responses are JSON. Missing tenants return 404 + `{ error: 'tenant_not_found' }`.\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\n\nimport type { Request, Response, NextFunction, IRouter } from 'express';\nimport type { TenantRegistry } from './tenant-registry';\nimport { redactCredentialPatterns } from '../redact';\n\n/**\n * Minimal Express-router-shaped object so we don't need a hard dependency\n * on the Express types in this file. Adopters who use a different framework\n * (Koa, Fastify) can mount the same handler functions via the framework's\n * adapter — `createTenantAdminHandlers(registry)` returns the bare handlers.\n */\nexport interface RouterLike {\n get(path: string, handler: (req: Request, res: Response, next?: NextFunction) => void): unknown;\n post(path: string, handler: (req: Request, res: Response, next?: NextFunction) => void): unknown;\n delete(path: string, handler: (req: Request, res: Response, next?: NextFunction) => void): unknown;\n}\n\nexport interface TenantAdminHandlers {\n listTenants(req: Request, res: Response): void;\n getTenant(req: Request, res: Response): void;\n recheckTenant(req: Request, res: Response): Promise<void>;\n unregisterTenant(req: Request, res: Response): void;\n}\n\n/**\n * Bare handlers — for adopters running a non-Express framework. The router\n * helper below mounts these on the standard paths.\n */\nexport function createTenantAdminHandlers(registry: TenantRegistry): TenantAdminHandlers {\n return {\n listTenants(_req: Request, res: Response): void {\n res.json({ tenants: registry.list() });\n },\n\n getTenant(req: Request, res: Response): void {\n const id = req.params.id;\n if (!id) {\n res.status(400).json({ error: 'tenant_id_required' });\n return;\n }\n const status = registry.getStatus(id);\n if (!status) {\n res.status(404).json({ error: 'tenant_not_found', tenant_id: id });\n return;\n }\n res.json(status);\n },\n\n async recheckTenant(req: Request, res: Response): Promise<void> {\n const id = req.params.id;\n if (!id) {\n res.status(400).json({ error: 'tenant_id_required' });\n return;\n }\n try {\n const status = await registry.recheck(id);\n res.json(status);\n } catch (err) {\n if (err instanceof Error && /not registered/.test(err.message)) {\n res.status(404).json({ error: 'tenant_not_found', tenant_id: id });\n return;\n }\n // Redact credential patterns before exposing on the wire (#1330).\n // The recheck path can throw with upstream errors that echo\n // basic-auth URLs or other credential bytes.\n res.status(500).json({\n error: 'recheck_failed',\n tenant_id: id,\n reason: redactCredentialPatterns(err instanceof Error ? err.message : String(err)),\n });\n }\n },\n\n unregisterTenant(req: Request, res: Response): void {\n const id = req.params.id;\n if (!id) {\n res.status(400).json({ error: 'tenant_id_required' });\n return;\n }\n registry.unregister(id);\n res.status(204).end();\n },\n };\n}\n\n/**\n * Build an Express router with the standard admin endpoints mounted.\n * Pass an `express.Router()` instance to mount on (so we don't need an\n * Express dependency in this file).\n */\nexport function mountTenantAdmin(router: RouterLike, registry: TenantRegistry): RouterLike {\n const handlers = createTenantAdminHandlers(registry);\n router.get('/tenants', handlers.listTenants);\n router.get('/tenants/:id', handlers.getTenant);\n router.post('/tenants/:id/recheck', handlers.recheckTenant);\n router.delete('/tenants/:id', handlers.unregisterTenant);\n return router;\n}\n\n/**\n * Convenience: takes an `express` import and a registry, returns a\n * mounted `Router` ready to attach. Usage:\n *\n * ```ts\n * import express from 'express';\n * import { createTenantAdminRouter } from '@adcp/sdk/server/decisioning';\n * adminApp.use('/admin', createTenantAdminRouter(express.Router(), registry));\n * ```\n *\n * The `routerFactory` argument lets adopters pre-configure middleware\n * (auth, logging) on the router before passing it in.\n */\nexport function createTenantAdminRouter<R extends RouterLike>(routerFactory: R, registry: TenantRegistry): R {\n mountTenantAdmin(routerFactory, registry);\n return routerFactory;\n}\n\nexport type { IRouter };\n"],"mappings":"AAgCA,SAAS,gCAAgC;AAyBlC,SAAS,0BAA0B,UAA+C;AACvF,SAAO;AAAA,IACL,YAAY,MAAe,KAAqB;AAC9C,UAAI,KAAK,EAAE,SAAS,SAAS,KAAK,EAAE,CAAC;AAAA,IACvC;AAAA,IAEA,UAAU,KAAc,KAAqB;AAC3C,YAAM,KAAK,IAAI,OAAO;AACtB,UAAI,CAAC,IAAI;AACP,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,qBAAqB,CAAC;AACpD;AAAA,MACF;AACA,YAAM,SAAS,SAAS,UAAU,EAAE;AACpC,UAAI,CAAC,QAAQ;AACX,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,oBAAoB,WAAW,GAAG,CAAC;AACjE;AAAA,MACF;AACA,UAAI,KAAK,MAAM;AAAA,IACjB;AAAA,IAEA,MAAM,cAAc,KAAc,KAA8B;AAC9D,YAAM,KAAK,IAAI,OAAO;AACtB,UAAI,CAAC,IAAI;AACP,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,qBAAqB,CAAC;AACpD;AAAA,MACF;AACA,UAAI;AACF,cAAM,SAAS,MAAM,SAAS,QAAQ,EAAE;AACxC,YAAI,KAAK,MAAM;AAAA,MACjB,SAAS,KAAK;AACZ,YAAI,eAAe,SAAS,iBAAiB,KAAK,IAAI,OAAO,GAAG;AAC9D,cAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,oBAAoB,WAAW,GAAG,CAAC;AACjE;AAAA,QACF;AAIA,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,OAAO;AAAA,UACP,WAAW;AAAA,UACX,QAAQ,yBAAyB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACnF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAEA,iBAAiB,KAAc,KAAqB;AAClD,YAAM,KAAK,IAAI,OAAO;AACtB,UAAI,CAAC,IAAI;AACP,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,qBAAqB,CAAC;AACpD;AAAA,MACF;AACA,eAAS,WAAW,EAAE;AACtB,UAAI,OAAO,GAAG,EAAE,IAAI;AAAA,IACtB;AAAA,EACF;AACF;AAOO,SAAS,iBAAiB,QAAoB,UAAsC;AACzF,QAAM,WAAW,0BAA0B,QAAQ;AACnD,SAAO,IAAI,YAAY,SAAS,WAAW;AAC3C,SAAO,IAAI,gBAAgB,SAAS,SAAS;AAC7C,SAAO,KAAK,wBAAwB,SAAS,aAAa;AAC1D,SAAO,OAAO,gBAAgB,SAAS,gBAAgB;AACvD,SAAO;AACT;AAeO,SAAS,wBAA8C,eAAkB,UAA6B;AAC3G,mBAAiB,eAAe,QAAQ;AACxC,SAAO;AACT;","names":[]}
|
|
@@ -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
|
const DEFAULT_REPORTING_CAPABILITIES = {
|
|
8
2
|
available_reporting_frequencies: ["hourly", "daily"],
|
|
9
3
|
expected_delay_minutes: 60,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/server/decisioning/assembly-helpers.ts"],"sourcesContent":["/**\n * Wire-shape assembly helpers.\n *\n * AdCP wire shapes carry many required fields (Product needs 8 required\n * properties; PricingOption needs at least 3 plus model-specific extras).\n * Building them by hand is the largest single source of validation\n * cascades in LLM-generated platforms (Emma matrix v18: a single missed\n * `format_ids[0].id` shape error swallowed 30+ storyboard steps).\n *\n * These helpers emit correct wire shapes from a flatter, intent-shaped\n * input. Adopters opt in — anything you don't pass in gets a sensible\n * default; anything required gets a clear TS error if you omit it.\n *\n * @public\n */\n\nimport type { Product, PricingOption, ReportingCapabilities } from '../../types/tools.generated';\n\n// ---------------------------------------------------------------------------\n// buildProduct\n// ---------------------------------------------------------------------------\n\nexport interface BuildProductInput {\n /** Unique product id. */\n id: string;\n\n /** Human-readable name surfaced to buyers. */\n name: string;\n\n /** Description surfaced to buyers. Defaults to `name`. */\n description?: string;\n\n /**\n * Format ids accepted on creatives bound to this product.\n *\n * Pass either:\n * - Array of strings → SDK wraps each as `{ id, agent_url }` using the\n * `agentUrl` you pass alongside (required for string-form formats —\n * wire schema requires `agent_url` per AdCP 3.0.1)\n * - Array of `{ id, agent_url }` for cross-agent format references\n * (each entry carries its own agent_url)\n */\n formats: ReadonlyArray<string | { id: string; agent_url?: string }>;\n\n /**\n * Your agent's URL (e.g., `'http://127.0.0.1:4200/mcp'` in tests, your\n * production MCP endpoint live). Required when any entry in `formats` is\n * a bare string (so the helper can build `{ id, agent_url }`). Ignored\n * when every entry is `{ id, agent_url }`.\n *\n * Per AdCP 3.0.1, `format_ids[i].agent_url` is required on the wire shape\n * — every format reference must point at the agent that defines that\n * format. Pass once per `buildProduct` call and the helper threads it\n * into each format ref.\n */\n agentUrl?: string;\n\n /** `'guaranteed'` (reserved inventory) or `'non_guaranteed'` (auction / remnant). */\n delivery_type: 'guaranteed' | 'non_guaranteed';\n\n /**\n * One or more pricing options. Pass strings for \"default CPM with floor\"\n * convenience, or full `PricingOption` objects for fine-grained control.\n *\n * Convenience shortcut: `pricing: { model: 'cpm', floor: 5, currency: 'USD' }`\n * builds a single CPM auction pricing option with the given floor.\n */\n pricing?:\n | {\n model: 'cpm' | 'vcpm' | 'cpc' | 'cpcv' | 'cpv' | 'cpp' | 'cpa' | 'flat_rate' | 'time';\n floor?: number;\n fixed?: number;\n currency?: string;\n pricing_option_id?: string;\n }\n | ReadonlyArray<PricingOption>;\n\n /**\n * Shortcut for the common single-publisher case: pass the domain (e.g.,\n * `'sports.example'`) and the helper builds `publisher_properties: [{\n * publisher_domain: '<domain>', selection_type: 'all' }]`.\n *\n * Use `publisher_properties` directly for multi-domain or by-id / by-tag\n * selection.\n */\n publisher_domain?: string;\n\n /**\n * Publisher properties this product covers. Required (per AdCP 3.0.1\n * product schema) — pass `publisher_domain` for the common single-domain\n * shortcut, OR pass this directly for fine-grained selection.\n *\n * Each entry is a discriminated union by `selection_type`:\n * - `'all'` — select all properties at the publisher_domain\n * - `'by_id'` — select specific property_ids[]\n * - `'by_tag'` — select by property_tags[]\n */\n publisher_properties?: ReadonlyArray<\n | { publisher_domain: string; selection_type: 'all' }\n | {\n publisher_domain: string;\n selection_type: 'by_id';\n property_ids: ReadonlyArray<{ property_type: string; identifier: string; [k: string]: unknown }>;\n }\n | { publisher_domain: string; selection_type: 'by_tag'; property_tags: ReadonlyArray<string> }\n >;\n\n /** Reporting capabilities. Defaults to hourly+daily impressions/spend/clicks. */\n reporting_capabilities?: ReportingCapabilities;\n\n /** Channels this product targets (`'display'`, `'video'`, etc.). */\n channels?: ReadonlyArray<string>;\n\n /** Adapter-internal opaque blob round-tripped by the SDK. */\n ctx_metadata?: unknown;\n\n /** Anything else on the wire shape (escape hatch). */\n extra?: Record<string, unknown>;\n}\n\nconst DEFAULT_REPORTING_CAPABILITIES: ReportingCapabilities = {\n available_reporting_frequencies: ['hourly', 'daily'],\n expected_delay_minutes: 60,\n timezone: 'UTC',\n supports_webhooks: false,\n available_metrics: ['impressions', 'spend', 'clicks'],\n date_range_support: 'date_range',\n} as ReportingCapabilities;\n\nfunction resolvePublisherProperties(input: BuildProductInput): ReadonlyArray<unknown> {\n if (input.publisher_properties && input.publisher_properties.length > 0) {\n return input.publisher_properties;\n }\n if (input.publisher_domain) {\n return [{ publisher_domain: input.publisher_domain, selection_type: 'all' }];\n }\n throw new Error(\n `buildProduct: ${input.id} requires either \\`publisher_domain\\` (single-publisher shortcut) ` +\n `or \\`publisher_properties\\` (multi-domain / by-id / by-tag selection). The wire schema requires ` +\n `at least one publisher_property entry per product.`\n );\n}\n\n/**\n * Build a wire-correct `Product` from intent-shaped input. Required fields\n * (per AdCP 3.0.1 product.json) are filled in with sensible defaults when\n * omitted; the caller can override any of them.\n *\n * @example Catalog product (minimal)\n * ```ts\n * const product = buildProduct({\n * id: 'sports_display_auction',\n * name: 'Sports Display Auction',\n * formats: ['display_300x250', 'display_728x90'],\n * delivery_type: 'non_guaranteed',\n * pricing: { model: 'cpm', floor: 5.0, currency: 'USD' },\n * ctx_metadata: { gam: { ad_unit_ids: ['au_123'] } },\n * });\n * ```\n *\n * @example Multi-pricing-option product\n * ```ts\n * const product = buildProduct({\n * id: 'premium_homepage',\n * name: 'Premium Homepage Takeover',\n * formats: [{ id: 'display_970x250' }],\n * delivery_type: 'guaranteed',\n * pricing: [\n * buildPricingOption({ id: 'po_cpm', model: 'cpm', fixed: 25.0, currency: 'USD' }),\n * buildPricingOption({ id: 'po_flat', model: 'flat_rate', fixed: 50000, currency: 'USD' }),\n * ],\n * });\n * ```\n */\nexport function buildProduct(input: BuildProductInput): Product {\n const formats = input.formats.map(f => {\n if (typeof f === 'string') {\n if (!input.agentUrl) {\n throw new Error(\n `buildProduct: ${input.id} declares format '${f}' as a bare string, but \\`agentUrl\\` is required ` +\n `to build the wire \\`{ id, agent_url }\\` shape. Pass \\`agentUrl\\` on the input, OR pass each format ` +\n `as \\`{ id, agent_url }\\` directly.`\n );\n }\n return { id: f, agent_url: input.agentUrl };\n }\n if (f.agent_url) return f;\n if (input.agentUrl) return { ...f, agent_url: input.agentUrl };\n throw new Error(\n `buildProduct: ${input.id} format '${f.id}' has no agent_url and no \\`agentUrl\\` was passed on the input.`\n );\n });\n\n let pricing_options: PricingOption[];\n if (Array.isArray(input.pricing)) {\n pricing_options = [...input.pricing];\n } else if (input.pricing) {\n // Narrow: not an array, so it's the BuildPricingOptionInput shorthand object.\n pricing_options = [buildPricingOption(input.pricing as BuildPricingOptionInput)];\n } else {\n // No pricing supplied — emit a single CPM placeholder so the wire shape\n // validates. Adopters who skip pricing usually don't realize it's required.\n pricing_options = [buildPricingOption({ model: 'cpm', floor: 0.01, currency: 'USD' })];\n }\n\n const product = {\n product_id: input.id,\n name: input.name,\n description: input.description ?? input.name,\n publisher_properties: resolvePublisherProperties(input),\n format_ids: formats,\n delivery_type: input.delivery_type,\n pricing_options,\n reporting_capabilities: input.reporting_capabilities ?? DEFAULT_REPORTING_CAPABILITIES,\n ...(input.channels && input.channels.length > 0 && { channels: [...input.channels] }),\n ...(input.ctx_metadata !== undefined && { ctx_metadata: input.ctx_metadata }),\n ...(input.extra ?? {}),\n } as unknown as Product;\n\n return product;\n}\n\n// ---------------------------------------------------------------------------\n// buildPricingOption\n// ---------------------------------------------------------------------------\n\nexport interface BuildPricingOptionInput {\n /** Pricing option id, unique within the product. Defaults to `${model}_${floor||fixed||'default'}`. */\n id?: string;\n\n /** Pricing model. */\n model: 'cpm' | 'vcpm' | 'cpc' | 'cpcv' | 'cpv' | 'cpp' | 'cpa' | 'flat_rate' | 'time';\n\n /** Fixed price per unit. Mutually exclusive with `floor`. */\n fixed?: number;\n\n /** Auction floor price. Mutually exclusive with `fixed`. */\n floor?: number;\n\n /** ISO 4217 currency code (e.g., `'USD'`, `'EUR'`). Defaults to `'USD'`. */\n currency?: string;\n\n /** Minimum spend requirement per package using this pricing option. */\n min_spend_per_package?: number;\n}\n\n/**\n * Build a wire-correct `PricingOption` from intent-shaped input. Use the\n * shortcut on `buildProduct({ pricing })` for the common case; call\n * `buildPricingOption` directly when you need multiple options on a product.\n *\n * @example\n * ```ts\n * const cpm = buildPricingOption({ model: 'cpm', floor: 5.0, currency: 'USD' });\n * const flat = buildPricingOption({ id: 'po_flat', model: 'flat_rate', fixed: 50000, currency: 'USD' });\n * ```\n */\nexport function buildPricingOption(input: BuildPricingOptionInput): PricingOption {\n if (input.fixed !== undefined && input.floor !== undefined) {\n throw new Error(\n 'buildPricingOption: `fixed` and `floor` are mutually exclusive (CPM/etc. is either fixed-price or auction).'\n );\n }\n const currency = input.currency ?? 'USD';\n const idHint =\n input.fixed != null ? `fixed_${input.fixed}` : input.floor != null ? `floor_${input.floor}` : 'default';\n const opt = {\n pricing_option_id: input.id ?? `${input.model}_${idHint}`,\n pricing_model: input.model,\n currency,\n ...(input.fixed !== undefined && { fixed_price: input.fixed }),\n ...(input.floor !== undefined && { floor_price: input.floor }),\n ...(input.min_spend_per_package !== undefined && { min_spend_per_package: input.min_spend_per_package }),\n } as unknown as PricingOption;\n return opt;\n}\n\n// ---------------------------------------------------------------------------\n// buildPackage (createMediaBuy / getMediaBuys response packages)\n// ---------------------------------------------------------------------------\n\nexport interface BuildPackageInput {\n id: string;\n /** Buyer-supplied client-side reference (echoed from the request). */\n buyer_ref?: string;\n /** AdCP package status. Defaults to `'pending_creatives'` (just-created buys). */\n status?:\n | 'draft'\n | 'pending_creatives'\n | 'pending_start'\n | 'active'\n | 'paused'\n | 'completed'\n | 'canceled'\n | 'rejected';\n /** product_id this package was bound to. */\n product_id?: string;\n /** pricing_option_id selected for this package. */\n pricing_option_id?: string;\n /** Adapter-internal opaque blob round-tripped by the SDK. */\n ctx_metadata?: unknown;\n /** Anything else on the wire shape. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Build a wire-correct package shape for a media buy response.\n *\n * @example\n * ```ts\n * createMediaBuy: async (req, ctx) => {\n * const order = await this.gam.createOrder(req);\n * return {\n * media_buy_id: order.id,\n * status: 'pending_creatives',\n * packages: order.lineItems.map(li => buildPackage({\n * id: li.id,\n * buyer_ref: li.buyerRef,\n * status: 'pending_creatives',\n * ctx_metadata: { gam_line_item_id: li.gamLineItemId },\n * })),\n * };\n * }\n * ```\n */\nexport function buildPackage(input: BuildPackageInput): Record<string, unknown> {\n return {\n package_id: input.id,\n status: input.status ?? 'pending_creatives',\n ...(input.buyer_ref !== undefined && { buyer_ref: input.buyer_ref }),\n ...(input.product_id !== undefined && { product_id: input.product_id }),\n ...(input.pricing_option_id !== undefined && { pricing_option_id: input.pricing_option_id }),\n ...(input.ctx_metadata !== undefined && { ctx_metadata: input.ctx_metadata }),\n ...(input.extra ?? {}),\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/server/decisioning/assembly-helpers.ts"],"sourcesContent":["/**\n * Wire-shape assembly helpers.\n *\n * AdCP wire shapes carry many required fields (Product needs 8 required\n * properties; PricingOption needs at least 3 plus model-specific extras).\n * Building them by hand is the largest single source of validation\n * cascades in LLM-generated platforms (Emma matrix v18: a single missed\n * `format_ids[0].id` shape error swallowed 30+ storyboard steps).\n *\n * These helpers emit correct wire shapes from a flatter, intent-shaped\n * input. Adopters opt in — anything you don't pass in gets a sensible\n * default; anything required gets a clear TS error if you omit it.\n *\n * @public\n */\n\nimport type { Product, PricingOption, ReportingCapabilities } from '../../types/tools.generated';\n\n// ---------------------------------------------------------------------------\n// buildProduct\n// ---------------------------------------------------------------------------\n\nexport interface BuildProductInput {\n /** Unique product id. */\n id: string;\n\n /** Human-readable name surfaced to buyers. */\n name: string;\n\n /** Description surfaced to buyers. Defaults to `name`. */\n description?: string;\n\n /**\n * Format ids accepted on creatives bound to this product.\n *\n * Pass either:\n * - Array of strings → SDK wraps each as `{ id, agent_url }` using the\n * `agentUrl` you pass alongside (required for string-form formats —\n * wire schema requires `agent_url` per AdCP 3.0.1)\n * - Array of `{ id, agent_url }` for cross-agent format references\n * (each entry carries its own agent_url)\n */\n formats: ReadonlyArray<string | { id: string; agent_url?: string }>;\n\n /**\n * Your agent's URL (e.g., `'http://127.0.0.1:4200/mcp'` in tests, your\n * production MCP endpoint live). Required when any entry in `formats` is\n * a bare string (so the helper can build `{ id, agent_url }`). Ignored\n * when every entry is `{ id, agent_url }`.\n *\n * Per AdCP 3.0.1, `format_ids[i].agent_url` is required on the wire shape\n * — every format reference must point at the agent that defines that\n * format. Pass once per `buildProduct` call and the helper threads it\n * into each format ref.\n */\n agentUrl?: string;\n\n /** `'guaranteed'` (reserved inventory) or `'non_guaranteed'` (auction / remnant). */\n delivery_type: 'guaranteed' | 'non_guaranteed';\n\n /**\n * One or more pricing options. Pass strings for \"default CPM with floor\"\n * convenience, or full `PricingOption` objects for fine-grained control.\n *\n * Convenience shortcut: `pricing: { model: 'cpm', floor: 5, currency: 'USD' }`\n * builds a single CPM auction pricing option with the given floor.\n */\n pricing?:\n | {\n model: 'cpm' | 'vcpm' | 'cpc' | 'cpcv' | 'cpv' | 'cpp' | 'cpa' | 'flat_rate' | 'time';\n floor?: number;\n fixed?: number;\n currency?: string;\n pricing_option_id?: string;\n }\n | ReadonlyArray<PricingOption>;\n\n /**\n * Shortcut for the common single-publisher case: pass the domain (e.g.,\n * `'sports.example'`) and the helper builds `publisher_properties: [{\n * publisher_domain: '<domain>', selection_type: 'all' }]`.\n *\n * Use `publisher_properties` directly for multi-domain or by-id / by-tag\n * selection.\n */\n publisher_domain?: string;\n\n /**\n * Publisher properties this product covers. Required (per AdCP 3.0.1\n * product schema) — pass `publisher_domain` for the common single-domain\n * shortcut, OR pass this directly for fine-grained selection.\n *\n * Each entry is a discriminated union by `selection_type`:\n * - `'all'` — select all properties at the publisher_domain\n * - `'by_id'` — select specific property_ids[]\n * - `'by_tag'` — select by property_tags[]\n */\n publisher_properties?: ReadonlyArray<\n | { publisher_domain: string; selection_type: 'all' }\n | {\n publisher_domain: string;\n selection_type: 'by_id';\n property_ids: ReadonlyArray<{ property_type: string; identifier: string; [k: string]: unknown }>;\n }\n | { publisher_domain: string; selection_type: 'by_tag'; property_tags: ReadonlyArray<string> }\n >;\n\n /** Reporting capabilities. Defaults to hourly+daily impressions/spend/clicks. */\n reporting_capabilities?: ReportingCapabilities;\n\n /** Channels this product targets (`'display'`, `'video'`, etc.). */\n channels?: ReadonlyArray<string>;\n\n /** Adapter-internal opaque blob round-tripped by the SDK. */\n ctx_metadata?: unknown;\n\n /** Anything else on the wire shape (escape hatch). */\n extra?: Record<string, unknown>;\n}\n\nconst DEFAULT_REPORTING_CAPABILITIES: ReportingCapabilities = {\n available_reporting_frequencies: ['hourly', 'daily'],\n expected_delay_minutes: 60,\n timezone: 'UTC',\n supports_webhooks: false,\n available_metrics: ['impressions', 'spend', 'clicks'],\n date_range_support: 'date_range',\n} as ReportingCapabilities;\n\nfunction resolvePublisherProperties(input: BuildProductInput): ReadonlyArray<unknown> {\n if (input.publisher_properties && input.publisher_properties.length > 0) {\n return input.publisher_properties;\n }\n if (input.publisher_domain) {\n return [{ publisher_domain: input.publisher_domain, selection_type: 'all' }];\n }\n throw new Error(\n `buildProduct: ${input.id} requires either \\`publisher_domain\\` (single-publisher shortcut) ` +\n `or \\`publisher_properties\\` (multi-domain / by-id / by-tag selection). The wire schema requires ` +\n `at least one publisher_property entry per product.`\n );\n}\n\n/**\n * Build a wire-correct `Product` from intent-shaped input. Required fields\n * (per AdCP 3.0.1 product.json) are filled in with sensible defaults when\n * omitted; the caller can override any of them.\n *\n * @example Catalog product (minimal)\n * ```ts\n * const product = buildProduct({\n * id: 'sports_display_auction',\n * name: 'Sports Display Auction',\n * formats: ['display_300x250', 'display_728x90'],\n * delivery_type: 'non_guaranteed',\n * pricing: { model: 'cpm', floor: 5.0, currency: 'USD' },\n * ctx_metadata: { gam: { ad_unit_ids: ['au_123'] } },\n * });\n * ```\n *\n * @example Multi-pricing-option product\n * ```ts\n * const product = buildProduct({\n * id: 'premium_homepage',\n * name: 'Premium Homepage Takeover',\n * formats: [{ id: 'display_970x250' }],\n * delivery_type: 'guaranteed',\n * pricing: [\n * buildPricingOption({ id: 'po_cpm', model: 'cpm', fixed: 25.0, currency: 'USD' }),\n * buildPricingOption({ id: 'po_flat', model: 'flat_rate', fixed: 50000, currency: 'USD' }),\n * ],\n * });\n * ```\n */\nexport function buildProduct(input: BuildProductInput): Product {\n const formats = input.formats.map(f => {\n if (typeof f === 'string') {\n if (!input.agentUrl) {\n throw new Error(\n `buildProduct: ${input.id} declares format '${f}' as a bare string, but \\`agentUrl\\` is required ` +\n `to build the wire \\`{ id, agent_url }\\` shape. Pass \\`agentUrl\\` on the input, OR pass each format ` +\n `as \\`{ id, agent_url }\\` directly.`\n );\n }\n return { id: f, agent_url: input.agentUrl };\n }\n if (f.agent_url) return f;\n if (input.agentUrl) return { ...f, agent_url: input.agentUrl };\n throw new Error(\n `buildProduct: ${input.id} format '${f.id}' has no agent_url and no \\`agentUrl\\` was passed on the input.`\n );\n });\n\n let pricing_options: PricingOption[];\n if (Array.isArray(input.pricing)) {\n pricing_options = [...input.pricing];\n } else if (input.pricing) {\n // Narrow: not an array, so it's the BuildPricingOptionInput shorthand object.\n pricing_options = [buildPricingOption(input.pricing as BuildPricingOptionInput)];\n } else {\n // No pricing supplied — emit a single CPM placeholder so the wire shape\n // validates. Adopters who skip pricing usually don't realize it's required.\n pricing_options = [buildPricingOption({ model: 'cpm', floor: 0.01, currency: 'USD' })];\n }\n\n const product = {\n product_id: input.id,\n name: input.name,\n description: input.description ?? input.name,\n publisher_properties: resolvePublisherProperties(input),\n format_ids: formats,\n delivery_type: input.delivery_type,\n pricing_options,\n reporting_capabilities: input.reporting_capabilities ?? DEFAULT_REPORTING_CAPABILITIES,\n ...(input.channels && input.channels.length > 0 && { channels: [...input.channels] }),\n ...(input.ctx_metadata !== undefined && { ctx_metadata: input.ctx_metadata }),\n ...(input.extra ?? {}),\n } as unknown as Product;\n\n return product;\n}\n\n// ---------------------------------------------------------------------------\n// buildPricingOption\n// ---------------------------------------------------------------------------\n\nexport interface BuildPricingOptionInput {\n /** Pricing option id, unique within the product. Defaults to `${model}_${floor||fixed||'default'}`. */\n id?: string;\n\n /** Pricing model. */\n model: 'cpm' | 'vcpm' | 'cpc' | 'cpcv' | 'cpv' | 'cpp' | 'cpa' | 'flat_rate' | 'time';\n\n /** Fixed price per unit. Mutually exclusive with `floor`. */\n fixed?: number;\n\n /** Auction floor price. Mutually exclusive with `fixed`. */\n floor?: number;\n\n /** ISO 4217 currency code (e.g., `'USD'`, `'EUR'`). Defaults to `'USD'`. */\n currency?: string;\n\n /** Minimum spend requirement per package using this pricing option. */\n min_spend_per_package?: number;\n}\n\n/**\n * Build a wire-correct `PricingOption` from intent-shaped input. Use the\n * shortcut on `buildProduct({ pricing })` for the common case; call\n * `buildPricingOption` directly when you need multiple options on a product.\n *\n * @example\n * ```ts\n * const cpm = buildPricingOption({ model: 'cpm', floor: 5.0, currency: 'USD' });\n * const flat = buildPricingOption({ id: 'po_flat', model: 'flat_rate', fixed: 50000, currency: 'USD' });\n * ```\n */\nexport function buildPricingOption(input: BuildPricingOptionInput): PricingOption {\n if (input.fixed !== undefined && input.floor !== undefined) {\n throw new Error(\n 'buildPricingOption: `fixed` and `floor` are mutually exclusive (CPM/etc. is either fixed-price or auction).'\n );\n }\n const currency = input.currency ?? 'USD';\n const idHint =\n input.fixed != null ? `fixed_${input.fixed}` : input.floor != null ? `floor_${input.floor}` : 'default';\n const opt = {\n pricing_option_id: input.id ?? `${input.model}_${idHint}`,\n pricing_model: input.model,\n currency,\n ...(input.fixed !== undefined && { fixed_price: input.fixed }),\n ...(input.floor !== undefined && { floor_price: input.floor }),\n ...(input.min_spend_per_package !== undefined && { min_spend_per_package: input.min_spend_per_package }),\n } as unknown as PricingOption;\n return opt;\n}\n\n// ---------------------------------------------------------------------------\n// buildPackage (createMediaBuy / getMediaBuys response packages)\n// ---------------------------------------------------------------------------\n\nexport interface BuildPackageInput {\n id: string;\n /** Buyer-supplied client-side reference (echoed from the request). */\n buyer_ref?: string;\n /** AdCP package status. Defaults to `'pending_creatives'` (just-created buys). */\n status?:\n | 'draft'\n | 'pending_creatives'\n | 'pending_start'\n | 'active'\n | 'paused'\n | 'completed'\n | 'canceled'\n | 'rejected';\n /** product_id this package was bound to. */\n product_id?: string;\n /** pricing_option_id selected for this package. */\n pricing_option_id?: string;\n /** Adapter-internal opaque blob round-tripped by the SDK. */\n ctx_metadata?: unknown;\n /** Anything else on the wire shape. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Build a wire-correct package shape for a media buy response.\n *\n * @example\n * ```ts\n * createMediaBuy: async (req, ctx) => {\n * const order = await this.gam.createOrder(req);\n * return {\n * media_buy_id: order.id,\n * status: 'pending_creatives',\n * packages: order.lineItems.map(li => buildPackage({\n * id: li.id,\n * buyer_ref: li.buyerRef,\n * status: 'pending_creatives',\n * ctx_metadata: { gam_line_item_id: li.gamLineItemId },\n * })),\n * };\n * }\n * ```\n */\nexport function buildPackage(input: BuildPackageInput): Record<string, unknown> {\n return {\n package_id: input.id,\n status: input.status ?? 'pending_creatives',\n ...(input.buyer_ref !== undefined && { buyer_ref: input.buyer_ref }),\n ...(input.product_id !== undefined && { product_id: input.product_id }),\n ...(input.pricing_option_id !== undefined && { pricing_option_id: input.pricing_option_id }),\n ...(input.ctx_metadata !== undefined && { ctx_metadata: input.ctx_metadata }),\n ...(input.extra ?? {}),\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -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 { getErrorRecovery, STANDARD_ERROR_CODES } from "../../types/error-codes.mjs";
|
|
8
2
|
const KNOWN_ERROR_CODES = Object.keys(STANDARD_ERROR_CODES);
|
|
9
3
|
const KNOWN_ERROR_CODE_SET = new Set(KNOWN_ERROR_CODES);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/server/decisioning/async-outcome.ts"],"sourcesContent":["/**\n * Error vocabulary + structured error class for `DecisioningPlatform`.\n *\n * Adopters write per-tool methods (sync OR `*Task` HITL variant), return\n * the success value, or `throw new AdcpError(...)` for structured rejection.\n * The framework projects the structured fields onto the wire `adcp_error`\n * envelope; generic thrown errors map to `SERVICE_UNAVAILABLE`.\n *\n * `AsyncOutcome<T>` and the `ok` / `submitted` / `rejected` constructors\n * remain as the framework's internal projection vocabulary; adopter code\n * doesn't return them.\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\n\nimport { getErrorRecovery, STANDARD_ERROR_CODES, type StandardErrorCode } from '../../types/error-codes';\n\n/**\n * Error code vocabulary the SDK recognizes. Uses the same runtime table as\n * `isStandardErrorCode` / `getErrorRecovery` so decisioning warnings cannot\n * drift from the SDK's standard-code lookup when manifest-derived codes or\n * forward-compat overlay entries are refreshed independently.\n */\nexport const KNOWN_ERROR_CODES = Object.keys(STANDARD_ERROR_CODES) as readonly string[];\n\nexport type ErrorCode = StandardErrorCode;\n\nconst KNOWN_ERROR_CODE_SET: ReadonlySet<string> = new Set<string>(KNOWN_ERROR_CODES);\n\n/**\n * Detect typoed error codes in `AdcpError` constructor calls. The\n * `code: ErrorCode | (string & {})` escape hatch keeps platform-specific\n * codes available, but it also defeats autocomplete on misspellings —\n * `'BUDGET_TO_LOW'` (typo) compiles fine. The runtime warns once per\n * unknown code so `npm run dev` log review surfaces typos before they\n * ship to a buyer who can't pattern-match `recovery`.\n *\n * Set `ADCP_DECISIONING_ALLOW_CUSTOM_CODES=1` to silence the warn for\n * platforms that intentionally mint vendor-specific codes\n * (`'GAM_INTERNAL_QUOTA_EXCEEDED'` etc.).\n */\nconst warnedUnknownCodes = new Set<string>();\nfunction maybeWarnUnknownErrorCode(code: string): void {\n if (KNOWN_ERROR_CODE_SET.has(code)) return;\n if (process.env.ADCP_DECISIONING_ALLOW_CUSTOM_CODES === '1') return;\n if (warnedUnknownCodes.has(code)) return;\n warnedUnknownCodes.add(code);\n // eslint-disable-next-line no-console\n console.warn(\n `[adcp/decisioning] AdcpError code \"${code}\" is not in the known ErrorCode set ` +\n `(${KNOWN_ERROR_CODES.length} standard codes in the SDK runtime table). ` +\n `If this is intentional (vendor-specific code), set ADCP_DECISIONING_ALLOW_CUSTOM_CODES=1. ` +\n `Otherwise check spelling against the ErrorCode union.`\n );\n}\n\n/**\n * Structured error envelope. Mirrors `schemas/cache/3.0.0/core/error.json`.\n *\n * `recovery` is REQUIRED at this interface level. The wire schema makes it\n * optional; we tighten because every adopter needs to declare buyer-recovery\n * intent on every rejection — implicit \"terminal\" by absence has historically\n * caused buyers to misroute retries.\n *\n * Adopter code throws `AdcpError` (the class wrapper); the framework catches\n * and projects the structured fields onto the wire envelope.\n */\nexport interface AdcpStructuredError {\n code: ErrorCode | (string & {});\n recovery: 'transient' | 'correctable' | 'terminal';\n message: string;\n /** Field path associated with the error (e.g., `'packages[0].targeting'`). */\n field?: string;\n /** Suggested fix surfaced to the buyer. */\n suggestion?: string;\n /**\n * Seconds to wait before retrying. REQUIRED by the spec for `RATE_LIMITED`\n * and `SERVICE_UNAVAILABLE`; framework auto-fills if omitted.\n * Adopters MUST clamp to [1, 3600] per spec.\n */\n retry_after?: number;\n details?: Record<string, unknown>;\n}\n\n/**\n * Throwable structured error. Adopter code throws this to fail a specialism\n * method with a buyer-facing wire envelope.\n *\n * ```ts\n * createMediaBuy: async (req, ctx) => {\n * if (req.total_budget.amount < this.floor) {\n * throw new AdcpError('BUDGET_TOO_LOW', {\n * recovery: 'correctable',\n * message: `Floor is $${this.floor} CPM`,\n * field: 'total_budget.amount',\n * });\n * }\n * return await this.gam.createOrder(req);\n * }\n * ```\n *\n * Framework catches `AdcpError` from any specialism method and projects\n * the structured fields onto the wire `adcp_error` envelope.\n * Generic thrown errors map to `SERVICE_UNAVAILABLE` with `recovery: 'transient'`.\n */\nexport class AdcpError extends Error {\n readonly name = 'AdcpError' as const;\n readonly code: ErrorCode | (string & {});\n readonly recovery: 'transient' | 'correctable' | 'terminal';\n readonly field?: string;\n readonly suggestion?: string;\n readonly retry_after?: number;\n readonly details?: Record<string, unknown>;\n\n constructor(\n code: ErrorCode | (string & {}),\n options: {\n /**\n * Recovery classification. Optional — defaults to the spec-correct\n * value for any standard `code` (via `getErrorRecovery`). Pass an\n * explicit value only to override the spec default for a vendor-\n * specific reason; for non-standard codes the default is `correctable`.\n */\n recovery?: 'transient' | 'correctable' | 'terminal';\n message: string;\n field?: string;\n suggestion?: string;\n retry_after?: number;\n details?: Record<string, unknown>;\n }\n ) {\n super(options.message);\n this.code = code;\n // For non-standard `(string & {})` codes the fallback is `'terminal'`,\n // matching `adcpError(...)`'s factory behavior in `errors.ts` — buyer\n // can't pattern-match on an unknown code, so the conservative default\n // tells them to escalate rather than auto-retry.\n this.recovery = options.recovery ?? getErrorRecovery(code) ?? 'terminal';\n maybeWarnUnknownErrorCode(code);\n if (options.field !== undefined) this.field = options.field;\n if (options.suggestion !== undefined) this.suggestion = options.suggestion;\n if (options.retry_after !== undefined) this.retry_after = options.retry_after;\n if (options.details !== undefined) this.details = options.details;\n }\n\n /** Coerce to the structured envelope shape the framework projects to the wire. */\n toStructuredError(): AdcpStructuredError {\n return {\n code: this.code,\n recovery: this.recovery,\n message: this.message,\n ...(this.field !== undefined && { field: this.field }),\n ...(this.suggestion !== undefined && { suggestion: this.suggestion }),\n ...(this.retry_after !== undefined && { retry_after: this.retry_after }),\n ...(this.details !== undefined && { details: this.details }),\n };\n }\n\n /**\n * Override `Error.toString` so default `console.error(err)` /\n * CloudWatch / structured-log adopters see the `code` and `recovery`\n * alongside the message rather than the bare `AdcpError: <message>`\n * default. Triage in operator dashboards needs the code more than\n * the stack.\n */\n override toString(): string {\n return `AdcpError [${this.code}, ${this.recovery}]: ${this.message}`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// TaskHandoff — unified hybrid-seller shape\n// ---------------------------------------------------------------------------\n\n/**\n * Brand value framework checks at the dispatch seam to detect \"this method\n * is handing off to a task.\" Module-level constant so adopters can't construct\n * one without going through `ctx.handoffToTask(fn)`.\n */\nconst TASK_HANDOFF_BRAND: unique symbol = Symbol.for('@adcp/decisioning/task-handoff');\n\n/**\n * Optional overrides for `ctx.handoffToTask`.\n *\n * @public\n */\nexport interface TaskHandoffOptions {\n /**\n * Use this exact string as the `task_id` instead of letting the framework\n * mint a fresh one. Required when an upstream system (or a test-controller\n * directive such as `force_create_media_buy_arm`) has already issued the ID\n * and the spec contract demands the response echoes it verbatim.\n *\n * Constraints: non-empty, ≤ 128 characters. Throws if violated.\n * The caller is responsible for uniqueness within the account.\n */\n task_id?: string;\n}\n\ntype TaskHandoffEntry = {\n fn: (taskCtx: TaskHandoffContext) => Promise<unknown>;\n options?: TaskHandoffOptions;\n};\n\n/**\n * The handoff fn and options live in a WeakMap keyed by the `TaskHandoff`\n * marker object — NOT on the marker itself. Both are stored atomically in a\n * single entry so `isTaskHandoff` and `_extractHandoffEntry` always see a\n * consistent pair. Closes round-6 CR-3 / Protocol-L2: `_taskFn` was\n * previously a type-visible field that adopters could forge with their own\n * `Symbol.for(...)` call.\n */\nconst taskHandoffEntries = new WeakMap<object, TaskHandoffEntry>();\n\n/**\n * Marker the framework recognizes as \"promote this call to a task.\"\n * Returned from `ctx.handoffToTask(fn)`. Type parameter `TResult` is the\n * eventual terminal artifact `fn` resolves to.\n *\n * Adopters never construct this directly — `ctx.handoffToTask(fn)` is the\n * only sanctioned producer. The framework's dispatch layer detects the\n * brand, allocates a `task_id`, returns the spec-defined `Submitted`\n * envelope to the buyer, and runs `fn` in the background. `fn`'s return\n * value becomes the task's terminal artifact; `throw AdcpError` becomes\n * the terminal error.\n *\n * The opaque `_taskFn` field exists only at the type level — at runtime\n * the function is stored in a module-private WeakMap keyed by the\n * marker, so adopters who try to invoke `handoff._taskFn(ctx)` directly\n * get `undefined`. The only way to run the handoff body is to return\n * the marker from a specialism method and let the framework dispatch.\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\nexport interface TaskHandoff<TResult> {\n readonly [TASK_HANDOFF_BRAND]: true;\n /**\n * Phantom field — exists only at the type level so `TResult` is\n * preserved for inference. At runtime the slot is `undefined`; the\n * actual function lives in the framework's private WeakMap.\n *\n * @internal\n */\n readonly _taskResult?: TResult;\n}\n\n/**\n * Context the framework supplies to the handoff function. Mirrors\n * `RequestContext.task` from the deprecated `*Task` shape — `id` is the\n * framework-issued task id, `update`/`heartbeat` are the same affordances.\n *\n * @public\n */\nexport interface TaskHandoffContext {\n readonly id: string;\n update(progress: TaskHandoffProgress): Promise<void>;\n heartbeat(): Promise<void>;\n}\n\nexport interface TaskHandoffProgress {\n message?: string;\n percentage?: number;\n step_number?: number;\n total_steps?: number;\n current_step?: string;\n}\n\n/**\n * Construct a `TaskHandoff<T>` marker. The framework's `ctx.handoffToTask`\n * helper invokes this; adopters don't call it directly.\n *\n * The `fn` and `options` are stashed atomically in a module-private WeakMap\n * keyed by the marker object. Adopters can hold the marker and pass it through\n * return values, but cannot extract or invoke `fn` themselves — only the\n * framework's `_extractHandoffEntry` can.\n *\n * @internal\n */\nexport function _createTaskHandoff<TResult>(\n fn: (taskCtx: TaskHandoffContext) => Promise<TResult>,\n options?: TaskHandoffOptions\n): TaskHandoff<TResult> {\n // Frozen object so adopters can't mutate the brand field. Even if\n // they did, the dispatch seam keys on identity (WeakMap), not on\n // mutable structure.\n const marker = Object.freeze({ [TASK_HANDOFF_BRAND]: true as const });\n taskHandoffEntries.set(marker, {\n fn: fn as (taskCtx: TaskHandoffContext) => Promise<unknown>,\n options,\n });\n return marker as TaskHandoff<TResult>;\n}\n\n/**\n * Type guard — does the value the adopter returned mark a task handoff?\n *\n * Checks both the symbol brand AND WeakMap presence. An adopter who\n * forges `{ [TASK_HANDOFF_BRAND]: true }` without going through\n * `_createTaskHandoff` won't be in the WeakMap and the guard returns\n * false. Belt-and-suspenders against forgery.\n *\n * @internal\n */\nexport function isTaskHandoff<TResult>(value: unknown): value is TaskHandoff<TResult> {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<symbol, unknown>)[TASK_HANDOFF_BRAND] === true &&\n taskHandoffEntries.has(value as object)\n );\n}\n\n/**\n * Extract the handoff fn and options from a marker. Framework-only — the\n * dispatch seam in `from-platform.ts` calls this after `isTaskHandoff`.\n * Returns `undefined` if the marker wasn't created by `_createTaskHandoff`\n * (forgery).\n *\n * @internal\n */\nexport function _extractHandoffEntry<TResult>(\n handoff: TaskHandoff<TResult>\n): { fn: (taskCtx: TaskHandoffContext) => Promise<TResult>; options?: TaskHandoffOptions } | undefined {\n const entry = taskHandoffEntries.get(handoff as unknown as object);\n if (!entry) return undefined;\n return entry as { fn: (taskCtx: TaskHandoffContext) => Promise<TResult>; options?: TaskHandoffOptions };\n}\n"],"mappings":";;;;;;AAiBA,SAAS,kBAAkB,4BAAoD;AAQxE,MAAM,oBAAoB,OAAO,KAAK,oBAAoB;AAIjE,MAAM,uBAA4C,IAAI,IAAY,iBAAiB;AAcnF,MAAM,qBAAqB,oBAAI,IAAY;AAC3C,SAAS,0BAA0B,MAAoB;AACrD,MAAI,qBAAqB,IAAI,IAAI,EAAG;AACpC,MAAI,QAAQ,IAAI,wCAAwC,IAAK;AAC7D,MAAI,mBAAmB,IAAI,IAAI,EAAG;AAClC,qBAAmB,IAAI,IAAI;AAE3B,UAAQ;AAAA,IACN,sCAAsC,IAAI,wCACpC,kBAAkB,MAAM;AAAA,EAGhC;AACF;AAmDO,MAAM,kBAAkB,MAAM;AAAA,EAC1B,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,MACA,SAcA;AACA,UAAM,QAAQ,OAAO;AACrB,SAAK,OAAO;AAKZ,SAAK,WAAW,QAAQ,YAAY,iBAAiB,IAAI,KAAK;AAC9D,8BAA0B,IAAI;AAC9B,QAAI,QAAQ,UAAU,OAAW,MAAK,QAAQ,QAAQ;AACtD,QAAI,QAAQ,eAAe,OAAW,MAAK,aAAa,QAAQ;AAChE,QAAI,QAAQ,gBAAgB,OAAW,MAAK,cAAc,QAAQ;AAClE,QAAI,QAAQ,YAAY,OAAW,MAAK,UAAU,QAAQ;AAAA,EAC5D;AAAA;AAAA,EAGA,oBAAyC;AACvC,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,SAAS,KAAK;AAAA,MACd,GAAI,KAAK,UAAU,UAAa,EAAE,OAAO,KAAK,MAAM;AAAA,MACpD,GAAI,KAAK,eAAe,UAAa,EAAE,YAAY,KAAK,WAAW;AAAA,MACnE,GAAI,KAAK,gBAAgB,UAAa,EAAE,aAAa,KAAK,YAAY;AAAA,MACtE,GAAI,KAAK,YAAY,UAAa,EAAE,SAAS,KAAK,QAAQ;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASS,WAAmB;AAC1B,WAAO,cAAc,KAAK,IAAI,KAAK,KAAK,QAAQ,MAAM,KAAK,OAAO;AAAA,EACpE;AACF;AAWA,MAAM,qBAAoC,uBAAO,IAAI,gCAAgC;AAiCrF,MAAM,qBAAqB,oBAAI,QAAkC;AAoE1D,SAAS,mBACd,IACA,SACsB;AAItB,QAAM,SAAS,OAAO,OAAO,EAAE,CAAC,kBAAkB,GAAG,KAAc,CAAC;AACpE,qBAAmB,IAAI,QAAQ;AAAA,IAC7B;AAAA,IACA;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAYO,SAAS,cAAuB,OAA+C;AACpF,SACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,kBAAkB,MAAM,QAC3D,mBAAmB,IAAI,KAAe;AAE1C;AAUO,SAAS,qBACd,SACqG;AACrG,QAAM,QAAQ,mBAAmB,IAAI,OAA4B;AACjE,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO;AACT;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/server/decisioning/async-outcome.ts"],"sourcesContent":["/**\n * Error vocabulary + structured error class for `DecisioningPlatform`.\n *\n * Adopters write per-tool methods (sync OR `*Task` HITL variant), return\n * the success value, or `throw new AdcpError(...)` for structured rejection.\n * The framework projects the structured fields onto the wire `adcp_error`\n * envelope; generic thrown errors map to `SERVICE_UNAVAILABLE`.\n *\n * `AsyncOutcome<T>` and the `ok` / `submitted` / `rejected` constructors\n * remain as the framework's internal projection vocabulary; adopter code\n * doesn't return them.\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\n\nimport { getErrorRecovery, STANDARD_ERROR_CODES, type StandardErrorCode } from '../../types/error-codes';\n\n/**\n * Error code vocabulary the SDK recognizes. Uses the same runtime table as\n * `isStandardErrorCode` / `getErrorRecovery` so decisioning warnings cannot\n * drift from the SDK's standard-code lookup when manifest-derived codes or\n * forward-compat overlay entries are refreshed independently.\n */\nexport const KNOWN_ERROR_CODES = Object.keys(STANDARD_ERROR_CODES) as readonly string[];\n\nexport type ErrorCode = StandardErrorCode;\n\nconst KNOWN_ERROR_CODE_SET: ReadonlySet<string> = new Set<string>(KNOWN_ERROR_CODES);\n\n/**\n * Detect typoed error codes in `AdcpError` constructor calls. The\n * `code: ErrorCode | (string & {})` escape hatch keeps platform-specific\n * codes available, but it also defeats autocomplete on misspellings —\n * `'BUDGET_TO_LOW'` (typo) compiles fine. The runtime warns once per\n * unknown code so `npm run dev` log review surfaces typos before they\n * ship to a buyer who can't pattern-match `recovery`.\n *\n * Set `ADCP_DECISIONING_ALLOW_CUSTOM_CODES=1` to silence the warn for\n * platforms that intentionally mint vendor-specific codes\n * (`'GAM_INTERNAL_QUOTA_EXCEEDED'` etc.).\n */\nconst warnedUnknownCodes = new Set<string>();\nfunction maybeWarnUnknownErrorCode(code: string): void {\n if (KNOWN_ERROR_CODE_SET.has(code)) return;\n if (process.env.ADCP_DECISIONING_ALLOW_CUSTOM_CODES === '1') return;\n if (warnedUnknownCodes.has(code)) return;\n warnedUnknownCodes.add(code);\n // eslint-disable-next-line no-console\n console.warn(\n `[adcp/decisioning] AdcpError code \"${code}\" is not in the known ErrorCode set ` +\n `(${KNOWN_ERROR_CODES.length} standard codes in the SDK runtime table). ` +\n `If this is intentional (vendor-specific code), set ADCP_DECISIONING_ALLOW_CUSTOM_CODES=1. ` +\n `Otherwise check spelling against the ErrorCode union.`\n );\n}\n\n/**\n * Structured error envelope. Mirrors `schemas/cache/3.0.0/core/error.json`.\n *\n * `recovery` is REQUIRED at this interface level. The wire schema makes it\n * optional; we tighten because every adopter needs to declare buyer-recovery\n * intent on every rejection — implicit \"terminal\" by absence has historically\n * caused buyers to misroute retries.\n *\n * Adopter code throws `AdcpError` (the class wrapper); the framework catches\n * and projects the structured fields onto the wire envelope.\n */\nexport interface AdcpStructuredError {\n code: ErrorCode | (string & {});\n recovery: 'transient' | 'correctable' | 'terminal';\n message: string;\n /** Field path associated with the error (e.g., `'packages[0].targeting'`). */\n field?: string;\n /** Suggested fix surfaced to the buyer. */\n suggestion?: string;\n /**\n * Seconds to wait before retrying. REQUIRED by the spec for `RATE_LIMITED`\n * and `SERVICE_UNAVAILABLE`; framework auto-fills if omitted.\n * Adopters MUST clamp to [1, 3600] per spec.\n */\n retry_after?: number;\n details?: Record<string, unknown>;\n}\n\n/**\n * Throwable structured error. Adopter code throws this to fail a specialism\n * method with a buyer-facing wire envelope.\n *\n * ```ts\n * createMediaBuy: async (req, ctx) => {\n * if (req.total_budget.amount < this.floor) {\n * throw new AdcpError('BUDGET_TOO_LOW', {\n * recovery: 'correctable',\n * message: `Floor is $${this.floor} CPM`,\n * field: 'total_budget.amount',\n * });\n * }\n * return await this.gam.createOrder(req);\n * }\n * ```\n *\n * Framework catches `AdcpError` from any specialism method and projects\n * the structured fields onto the wire `adcp_error` envelope.\n * Generic thrown errors map to `SERVICE_UNAVAILABLE` with `recovery: 'transient'`.\n */\nexport class AdcpError extends Error {\n readonly name = 'AdcpError' as const;\n readonly code: ErrorCode | (string & {});\n readonly recovery: 'transient' | 'correctable' | 'terminal';\n readonly field?: string;\n readonly suggestion?: string;\n readonly retry_after?: number;\n readonly details?: Record<string, unknown>;\n\n constructor(\n code: ErrorCode | (string & {}),\n options: {\n /**\n * Recovery classification. Optional — defaults to the spec-correct\n * value for any standard `code` (via `getErrorRecovery`). Pass an\n * explicit value only to override the spec default for a vendor-\n * specific reason; for non-standard codes the default is `correctable`.\n */\n recovery?: 'transient' | 'correctable' | 'terminal';\n message: string;\n field?: string;\n suggestion?: string;\n retry_after?: number;\n details?: Record<string, unknown>;\n }\n ) {\n super(options.message);\n this.code = code;\n // For non-standard `(string & {})` codes the fallback is `'terminal'`,\n // matching `adcpError(...)`'s factory behavior in `errors.ts` — buyer\n // can't pattern-match on an unknown code, so the conservative default\n // tells them to escalate rather than auto-retry.\n this.recovery = options.recovery ?? getErrorRecovery(code) ?? 'terminal';\n maybeWarnUnknownErrorCode(code);\n if (options.field !== undefined) this.field = options.field;\n if (options.suggestion !== undefined) this.suggestion = options.suggestion;\n if (options.retry_after !== undefined) this.retry_after = options.retry_after;\n if (options.details !== undefined) this.details = options.details;\n }\n\n /** Coerce to the structured envelope shape the framework projects to the wire. */\n toStructuredError(): AdcpStructuredError {\n return {\n code: this.code,\n recovery: this.recovery,\n message: this.message,\n ...(this.field !== undefined && { field: this.field }),\n ...(this.suggestion !== undefined && { suggestion: this.suggestion }),\n ...(this.retry_after !== undefined && { retry_after: this.retry_after }),\n ...(this.details !== undefined && { details: this.details }),\n };\n }\n\n /**\n * Override `Error.toString` so default `console.error(err)` /\n * CloudWatch / structured-log adopters see the `code` and `recovery`\n * alongside the message rather than the bare `AdcpError: <message>`\n * default. Triage in operator dashboards needs the code more than\n * the stack.\n */\n override toString(): string {\n return `AdcpError [${this.code}, ${this.recovery}]: ${this.message}`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// TaskHandoff — unified hybrid-seller shape\n// ---------------------------------------------------------------------------\n\n/**\n * Brand value framework checks at the dispatch seam to detect \"this method\n * is handing off to a task.\" Module-level constant so adopters can't construct\n * one without going through `ctx.handoffToTask(fn)`.\n */\nconst TASK_HANDOFF_BRAND: unique symbol = Symbol.for('@adcp/decisioning/task-handoff');\n\n/**\n * Optional overrides for `ctx.handoffToTask`.\n *\n * @public\n */\nexport interface TaskHandoffOptions {\n /**\n * Use this exact string as the `task_id` instead of letting the framework\n * mint a fresh one. Required when an upstream system (or a test-controller\n * directive such as `force_create_media_buy_arm`) has already issued the ID\n * and the spec contract demands the response echoes it verbatim.\n *\n * Constraints: non-empty, ≤ 128 characters. Throws if violated.\n * The caller is responsible for uniqueness within the account.\n */\n task_id?: string;\n}\n\ntype TaskHandoffEntry = {\n fn: (taskCtx: TaskHandoffContext) => Promise<unknown>;\n options?: TaskHandoffOptions;\n};\n\n/**\n * The handoff fn and options live in a WeakMap keyed by the `TaskHandoff`\n * marker object — NOT on the marker itself. Both are stored atomically in a\n * single entry so `isTaskHandoff` and `_extractHandoffEntry` always see a\n * consistent pair. Closes round-6 CR-3 / Protocol-L2: `_taskFn` was\n * previously a type-visible field that adopters could forge with their own\n * `Symbol.for(...)` call.\n */\nconst taskHandoffEntries = new WeakMap<object, TaskHandoffEntry>();\n\n/**\n * Marker the framework recognizes as \"promote this call to a task.\"\n * Returned from `ctx.handoffToTask(fn)`. Type parameter `TResult` is the\n * eventual terminal artifact `fn` resolves to.\n *\n * Adopters never construct this directly — `ctx.handoffToTask(fn)` is the\n * only sanctioned producer. The framework's dispatch layer detects the\n * brand, allocates a `task_id`, returns the spec-defined `Submitted`\n * envelope to the buyer, and runs `fn` in the background. `fn`'s return\n * value becomes the task's terminal artifact; `throw AdcpError` becomes\n * the terminal error.\n *\n * The opaque `_taskFn` field exists only at the type level — at runtime\n * the function is stored in a module-private WeakMap keyed by the\n * marker, so adopters who try to invoke `handoff._taskFn(ctx)` directly\n * get `undefined`. The only way to run the handoff body is to return\n * the marker from a specialism method and let the framework dispatch.\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\nexport interface TaskHandoff<TResult> {\n readonly [TASK_HANDOFF_BRAND]: true;\n /**\n * Phantom field — exists only at the type level so `TResult` is\n * preserved for inference. At runtime the slot is `undefined`; the\n * actual function lives in the framework's private WeakMap.\n *\n * @internal\n */\n readonly _taskResult?: TResult;\n}\n\n/**\n * Context the framework supplies to the handoff function. Mirrors\n * `RequestContext.task` from the deprecated `*Task` shape — `id` is the\n * framework-issued task id, `update`/`heartbeat` are the same affordances.\n *\n * @public\n */\nexport interface TaskHandoffContext {\n readonly id: string;\n update(progress: TaskHandoffProgress): Promise<void>;\n heartbeat(): Promise<void>;\n}\n\nexport interface TaskHandoffProgress {\n message?: string;\n percentage?: number;\n step_number?: number;\n total_steps?: number;\n current_step?: string;\n}\n\n/**\n * Construct a `TaskHandoff<T>` marker. The framework's `ctx.handoffToTask`\n * helper invokes this; adopters don't call it directly.\n *\n * The `fn` and `options` are stashed atomically in a module-private WeakMap\n * keyed by the marker object. Adopters can hold the marker and pass it through\n * return values, but cannot extract or invoke `fn` themselves — only the\n * framework's `_extractHandoffEntry` can.\n *\n * @internal\n */\nexport function _createTaskHandoff<TResult>(\n fn: (taskCtx: TaskHandoffContext) => Promise<TResult>,\n options?: TaskHandoffOptions\n): TaskHandoff<TResult> {\n // Frozen object so adopters can't mutate the brand field. Even if\n // they did, the dispatch seam keys on identity (WeakMap), not on\n // mutable structure.\n const marker = Object.freeze({ [TASK_HANDOFF_BRAND]: true as const });\n taskHandoffEntries.set(marker, {\n fn: fn as (taskCtx: TaskHandoffContext) => Promise<unknown>,\n options,\n });\n return marker as TaskHandoff<TResult>;\n}\n\n/**\n * Type guard — does the value the adopter returned mark a task handoff?\n *\n * Checks both the symbol brand AND WeakMap presence. An adopter who\n * forges `{ [TASK_HANDOFF_BRAND]: true }` without going through\n * `_createTaskHandoff` won't be in the WeakMap and the guard returns\n * false. Belt-and-suspenders against forgery.\n *\n * @internal\n */\nexport function isTaskHandoff<TResult>(value: unknown): value is TaskHandoff<TResult> {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<symbol, unknown>)[TASK_HANDOFF_BRAND] === true &&\n taskHandoffEntries.has(value as object)\n );\n}\n\n/**\n * Extract the handoff fn and options from a marker. Framework-only — the\n * dispatch seam in `from-platform.ts` calls this after `isTaskHandoff`.\n * Returns `undefined` if the marker wasn't created by `_createTaskHandoff`\n * (forgery).\n *\n * @internal\n */\nexport function _extractHandoffEntry<TResult>(\n handoff: TaskHandoff<TResult>\n): { fn: (taskCtx: TaskHandoffContext) => Promise<TResult>; options?: TaskHandoffOptions } | undefined {\n const entry = taskHandoffEntries.get(handoff as unknown as object);\n if (!entry) return undefined;\n return entry as { fn: (taskCtx: TaskHandoffContext) => Promise<TResult>; options?: TaskHandoffOptions };\n}\n"],"mappings":"AAiBA,SAAS,kBAAkB,4BAAoD;AAQxE,MAAM,oBAAoB,OAAO,KAAK,oBAAoB;AAIjE,MAAM,uBAA4C,IAAI,IAAY,iBAAiB;AAcnF,MAAM,qBAAqB,oBAAI,IAAY;AAC3C,SAAS,0BAA0B,MAAoB;AACrD,MAAI,qBAAqB,IAAI,IAAI,EAAG;AACpC,MAAI,QAAQ,IAAI,wCAAwC,IAAK;AAC7D,MAAI,mBAAmB,IAAI,IAAI,EAAG;AAClC,qBAAmB,IAAI,IAAI;AAE3B,UAAQ;AAAA,IACN,sCAAsC,IAAI,wCACpC,kBAAkB,MAAM;AAAA,EAGhC;AACF;AAmDO,MAAM,kBAAkB,MAAM;AAAA,EAC1B,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,MACA,SAcA;AACA,UAAM,QAAQ,OAAO;AACrB,SAAK,OAAO;AAKZ,SAAK,WAAW,QAAQ,YAAY,iBAAiB,IAAI,KAAK;AAC9D,8BAA0B,IAAI;AAC9B,QAAI,QAAQ,UAAU,OAAW,MAAK,QAAQ,QAAQ;AACtD,QAAI,QAAQ,eAAe,OAAW,MAAK,aAAa,QAAQ;AAChE,QAAI,QAAQ,gBAAgB,OAAW,MAAK,cAAc,QAAQ;AAClE,QAAI,QAAQ,YAAY,OAAW,MAAK,UAAU,QAAQ;AAAA,EAC5D;AAAA;AAAA,EAGA,oBAAyC;AACvC,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,SAAS,KAAK;AAAA,MACd,GAAI,KAAK,UAAU,UAAa,EAAE,OAAO,KAAK,MAAM;AAAA,MACpD,GAAI,KAAK,eAAe,UAAa,EAAE,YAAY,KAAK,WAAW;AAAA,MACnE,GAAI,KAAK,gBAAgB,UAAa,EAAE,aAAa,KAAK,YAAY;AAAA,MACtE,GAAI,KAAK,YAAY,UAAa,EAAE,SAAS,KAAK,QAAQ;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASS,WAAmB;AAC1B,WAAO,cAAc,KAAK,IAAI,KAAK,KAAK,QAAQ,MAAM,KAAK,OAAO;AAAA,EACpE;AACF;AAWA,MAAM,qBAAoC,uBAAO,IAAI,gCAAgC;AAiCrF,MAAM,qBAAqB,oBAAI,QAAkC;AAoE1D,SAAS,mBACd,IACA,SACsB;AAItB,QAAM,SAAS,OAAO,OAAO,EAAE,CAAC,kBAAkB,GAAG,KAAc,CAAC;AACpE,qBAAmB,IAAI,QAAQ;AAAA,IAC7B;AAAA,IACA;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAYO,SAAS,cAAuB,OAA+C;AACpF,SACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,kBAAkB,MAAM,QAC3D,mBAAmB,IAAI,KAAe;AAE1C;AAUO,SAAS,qBACd,SACqG;AACrG,QAAM,QAAQ,mBAAmB,IAAI,OAA4B;AACjE,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO;AACT;","names":[]}
|
|
@@ -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
|
const BILLING_SUGGESTION_ORDER = ["operator", "advertiser", "agent"];
|
|
8
2
|
function suggestBilling(billingCapabilities, rejected) {
|
|
9
3
|
for (const mode of BILLING_SUGGESTION_ORDER) {
|